Permalink
Browse files

egl: rewrite

As promised with f6ecaea, here is a complete rewrite of EGL. At the moment
this affects only android/amlogic/rpi.

Our previous system of inheritance was wonky, and was one hack after another.
This provides a single coherent implementation of the window life-cycle. It
also begins the process of decoupling rendering from windowing (at least for
EGL)

Each client is expected to fill in its windowing functionality outside of egl.

In theory, adding a new back-end requires only describing how to create/destroy
native structures and enumerate resolutions. If more functionality is needed, it
should be added to the EGLNativeType interface rather than hacking up the EGL
implementation itself.

Also, the back-ends are detected and tested at runtime rather than build-
time, meaning that it is not necessary to specify a back-end. It also
means that a single binary would be capable of running on multiple EGL
back-ends (for example, fbdev and X) when they're added.

Each back-end is required to provide a test-function at runtime to
determine whether it should be considered for use.

TODO: some introspect for enumerating possible back-ends before window-creation
TODO: fall-back if the first back-end fails
TODO: add rpi back-end
  • Loading branch information...
1 parent d95fd3b commit 2b49c791eb236ae4fe2be90ac7e7b8ccf0aad72f Cory Fields committed Sep 27, 2012
@@ -0,0 +1,65 @@
+include ../Makefile.include
+DEPS= ../Makefile.include Makefile
+
+LIBNAME=avahi
+VERSION=0.6.31
+SOURCE=$(LIBNAME)-$(VERSION)
+ARCHIVE=$(SOURCE).tar.gz
+BASE_URL=http://www.avahi.org/download/
+
+# configuration settings
+CONFIGURE=cp -f $(CONFIG_SUB) $(CONFIG_GUESS) .; \
+ ./configure --prefix=$(PREFIX) --host=$(HOST) --disable-shared \
+ --disable-qt3 \
+ --disable-qt4 \
+ --disable-gdbm \
+ --disable-python-dbus \
+ --disable-pygtk \
+ --disable-gtk3 \
+ --disable-gtk \
+ --disable-mono \
+ --disable-monodoc \
+ --disable-stack-protector \
+ --disable-manpages \
+ --disable-autoipd \
+ --disable-glib \
+ --disable-gobject \
+ --disable-dbus \
+ --disable-libdaemon \
+ --with-distro=none \
+ --with-avahi-user=root \
+ --with-avahi-group=root \
+ --with-autoipd-user=default \
+ --with-autoipd-group=default \
+
+
+LIBDYLIB=$(PLATFORM)/avahi-common/.libs/libavahi-common.a
+
+CLEAN_FILES=$(ARCHIVE) $(PLATFORM)
+
+all: .installed-$(PLATFORM)
+
+$(TARBALLS_LOCATION)/$(ARCHIVE):
+ $(RETRIEVE_TOOL) $(RETRIEVE_TOOL_FLAGS) $(BASE_URL)/$(ARCHIVE)
+
+$(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS)
+ rm -rf $(PLATFORM)/*; mkdir -p $(PLATFORM)
+ $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE)
+ cd $(PLATFORM); patch -p1 < ../avahi-optional-ipv6.patch
+ cd $(PLATFORM); $(CONFIGURE)
+
+$(LIBDYLIB): $(PLATFORM)
+ $(MAKE) -C $(PLATFORM)
+ touch $@
+
+.installed-$(PLATFORM): $(LIBDYLIB)
+ $(MAKE) -C $(PLATFORM) install
+ touch $@
+
+clean:
+ $(MAKE) -C $(PLATFORM) clean
+ rm -f .installed-$(PLATFORM)
+
+distclean::
+ rm -rf $(PLATFORM) .installed-$(PLATFORM)
+
@@ -0,0 +1,149 @@
+Below patch modified for android - Cory Fields
+
+[PATCH] avahi-core: make ipv6 support optional on uclibc 0.9.31+
+
+uClibc 0.9.31+ doesn't define the IPV6_* defines when IPv6 support isn't
+enabled, causing the avahi build to break. Detect this configuration, and
+comment out IPv6 code if so.
+
+Signed-off-by: Peter Korsgaard <jacmet@sunsite.dk>
+---
+ avahi-core/socket.c | 28 +++++++++++++++++++++++-----
+ 1 file changed, 23 insertions(+), 5 deletions(-)
+
+Index: avahi-0.6.23/avahi-core/socket.c
+===================================================================
+--- avahi-0.6.23.orig/avahi-core/socket.c
++++ avahi-0.6.23/avahi-core/socket.c
+@@ -47,6 +47,11 @@
+ #include <net/if_dl.h>
+ #endif
+
++#include <features.h>
++#if defined(ANDROID)
++#define NO_IPV6
++#endif
++
+ #include "dns.h"
+ #include "fdutil.h"
+ #include "socket.h"
+@@ -75,6 +80,7 @@ static void mdns_mcast_group_ipv4(struct
+ inet_pton(AF_INET, AVAHI_IPV4_MCAST_GROUP, &ret_sa->sin_addr);
+ }
+
++#ifndef NO_IPV6
+ static void mdns_mcast_group_ipv6(struct sockaddr_in6 *ret_sa) {
+ assert(ret_sa);
+
+@@ -83,6 +89,7 @@ static void mdns_mcast_group_ipv6(struct
+ ret_sa->sin6_port = htons(AVAHI_MDNS_PORT);
+ inet_pton(AF_INET6, AVAHI_IPV6_MCAST_GROUP, &ret_sa->sin6_addr);
+ }
++#endif
+
+ static void ipv4_address_to_sockaddr(struct sockaddr_in *ret_sa, const AvahiIPv4Address *a, uint16_t port) {
+ assert(ret_sa);
+@@ -95,6 +102,7 @@ static void ipv4_address_to_sockaddr(str
+ memcpy(&ret_sa->sin_addr, a, sizeof(AvahiIPv4Address));
+ }
+
++#ifndef NO_IPV6
+ static void ipv6_address_to_sockaddr(struct sockaddr_in6 *ret_sa, const AvahiIPv6Address *a, uint16_t port) {
+ assert(ret_sa);
+ assert(a);
+@@ -105,6 +113,7 @@ static void ipv6_address_to_sockaddr(str
+ ret_sa->sin6_port = htons(port);
+ memcpy(&ret_sa->sin6_addr, a, sizeof(AvahiIPv6Address));
+ }
++#endif
+
+ int avahi_mdns_mcast_join_ipv4(int fd, const AvahiIPv4Address *a, int idx, int join) {
+ #ifdef HAVE_STRUCT_IP_MREQN
+@@ -143,6 +152,7 @@ int avahi_mdns_mcast_join_ipv4(int fd, c
+ }
+
+ int avahi_mdns_mcast_join_ipv6(int fd, const AvahiIPv6Address *a, int idx, int join) {
++#ifndef NO_IPV6
+ struct ipv6_mreq mreq6;
+ struct sockaddr_in6 sa6;
+
+@@ -164,6 +174,9 @@ int avahi_mdns_mcast_join_ipv6(int fd, c
+ }
+
+ return 0;
++#else
++ return -1;
++#endif
+ }
+
+ static int reuseaddr(int fd) {
+@@ -372,6 +385,7 @@ fail:
+ }
+
+ int avahi_open_socket_ipv6(int no_reuse) {
++#ifndef NO_IPV6
+ struct sockaddr_in6 sa, local;
+ int fd = -1, yes, r;
+ int ttl;
+@@ -437,7 +451,7 @@ int avahi_open_socket_ipv6(int no_reuse)
+ fail:
+ if (fd >= 0)
+ close(fd);
+-
++#endif
+ return -1;
+ }
+
+@@ -567,7 +581,7 @@ int avahi_send_dns_packet_ipv6(
+ const AvahiIPv6Address *src_address,
+ const AvahiIPv6Address *dst_address,
+ uint16_t dst_port) {
+-
++#ifndef NO_IPV6
+ struct sockaddr_in6 sa;
+ struct msghdr msg;
+ struct iovec io;
+@@ -620,6 +634,9 @@ int avahi_send_dns_packet_ipv6(
+ }
+
+ return sendmsg_loop(fd, &msg, 0);
++#else
++ return -1;
++#endif
+ }
+
+ AvahiDnsPacket *avahi_recv_dns_packet_ipv4(
+@@ -782,7 +799,7 @@ AvahiDnsPacket *avahi_recv_dns_packet_ip
+ AvahiIPv6Address *ret_dst_address,
+ AvahiIfIndex *ret_iface,
+ uint8_t *ret_ttl) {
+-
++#ifndef NO_IPV6
+ AvahiDnsPacket *p = NULL;
+ struct msghdr msg;
+ struct iovec io;
+@@ -889,7 +906,7 @@ AvahiDnsPacket *avahi_recv_dns_packet_ip
+ fail:
+ if (p)
+ avahi_dns_packet_free(p);
+-
++#endif
+ return NULL;
+ }
+
+@@ -934,6 +951,7 @@ fail:
+ }
+
+ int avahi_open_unicast_socket_ipv6(void) {
++#ifndef NO_IPV6
+ struct sockaddr_in6 local;
+ int fd = -1, yes;
+
+@@ -974,6 +992,6 @@ int avahi_open_unicast_socket_ipv6(void)
+ fail:
+ if (fd >= 0)
+ close(fd);
+-
++#endif
+ return -1;
+ }
@@ -36,7 +36,7 @@
#include "X11/WinSystemX11GLES.h"
#elif defined(TARGET_LINUX) && defined(HAS_GLES) && defined(HAS_EGL)
-#include "egl/WinSystemGLES.h"
+#include "egl/WinSystemEGL.h"
#elif defined(TARGET_FREEBSD) && defined(HAS_GL) && defined(HAVE_X11)
#include "X11/WinSystemX11GL.h"
@@ -0,0 +1,147 @@
+#pragma once
+
+/*
+ * Copyright (C) 2011-2012 Team XBMC
+ * http://www.xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <EGL/egl.h>
+#include "guilib/Resolution.h"
+#include "EGLQuirks.h"
+
+/*!
+This class provides extra functionality on top of EGL in order to facilitate
+the implementation-dependent functionality relating to creating, maintaining,
+and destroying screens and displays.
+
+Each implementation is required to implement each function, though it can
+simply return false to signify that the functionality does not exist.
+
+Internal state should be maintained by each implementation as little as possible.
+If any information needs to be saved outside of the NativeWindow and NativeDisplay
+for later retrieval, there is most likely a bug in the implementation, or in that
+platform's EGL implementation.
+
+Each implementation will be instantiated at runtime to see if it qualifies for use
+until one is found. For this reason, each should avoid operations in its ctors and
+dtors, instead using the provided Initialize() and Destroy() functions which are
+only called once the implementation has been selected.
+*/
+
+class CEGLNativeType
+{
+public:
+
+ /*! \brief Do NOT clean up in the destructor, use the Destroy function
+ instead.
+
+ \sa: Destroy() */
+ virtual ~CEGLNativeType(){};
+
+/*! \brief Unique identifier for this EGL implementaiton.
+
+ It should be unique enough to set it apart from other possible implementations
+ on a similar platform. */
+ virtual std::string GetNativeName() const = 0;
+
+/*! \brief A function for testing whether this implementation should be used.
+
+ On platforms where several implementations are possible, it should provide a
+ stringent test to rule out false-positives. */
+ virtual bool CheckCompatibility() = 0;
+
+/*! \brief Initialize any local variables and/or structures here.
+
+ This is called after the implementation has been chosen, which is why this
+ should be used rather than the ctor. */
+ virtual void Initialize() = 0;
+
+/*! \brief Destroy any local variables and/or structures here.
+
+ This is called when the WindowSystem has been destroyed. */
+ virtual void Destroy() = 0;
+
+/*! \brief EGL implementation quirks.
+
+ Set any EGL oddities here so that they can be queried during the window's
+ life-cycle. */
+ virtual int GetQuirks() = 0;
+
+/*! \brief Create the EGL Native Display
+
+ An Implementation-dependent method should be used to create a native
+ display and store it in m_nativeDisplay. XBMC will terminate if this
+ fails */
+ virtual bool CreateNativeDisplay() = 0;
+
+/*! \brief Create the EGL Native Window
+
+ An Implementation-dependent method should be used to create a native
+ window and store it in m_nativeWindow. XBMC Will terminate if this fails.
+ If possible, the created window should use the current display's geometry
+ and allocate as needed so that it is immediately available for use.
+ If not, it must be made ready by SetNativeResolution(). */
+ virtual bool CreateNativeWindow() = 0;
+
+/*! \brief Returns the current Native Display */
+ virtual bool GetNativeDisplay(EGLNativeDisplayType **nativeDisplay) const = 0;
+
+/*! \brief Returns the current Native Window */
+ virtual bool GetNativeWindow(EGLNativeWindowType **nativeWindow) const = 0;
+
+/*! \brief Destroy the Native Window
+
+ An Implementation-dependent method should be used to destroy the current
+ Native Window */
+ virtual bool DestroyNativeWindow() = 0;
+
+/*! \brief Destroy The Native Display
+
+ An Implementation-dependent method should be used to destroy the current
+ Native Display */
+ virtual bool DestroyNativeDisplay() = 0;
+
+/*! \brief Return the current display's resolution
+
+ This is completely independent of XBMC's internal resolution */
+ virtual bool GetNativeResolution(RESOLUTION_INFO *res) const = 0;
+
+/*! \brief Set the current display's resolution
+
+ This is completely independent of XBMC's internal resolution */
+ virtual bool SetNativeResolution(const RESOLUTION_INFO &res) = 0;
+
+/*! \brief Query the display for all possible resolutions */
+ virtual bool ProbeResolutions(std::vector<RESOLUTION_INFO> &resolutions) = 0;
+
+/*! \brief Provide a fall-back resolution
+
+ If all queried resolutions fail, this one is guaranteed to be compatible
+ with the display */
+ virtual bool GetPreferredResolution(RESOLUTION_INFO *res) const = 0;
+
+/*! \brief Show/Hide the current window
+
+ A platform-independent way of hiding XBMC (for example blanking the current
+ framebuffer */
+ virtual bool ShowWindow(bool show) = 0;
+
+protected:
+ EGLNativeDisplayType m_nativeDisplay;
+ EGLNativeWindowType m_nativeWindow;
+};
Oops, something went wrong.

0 comments on commit 2b49c79

Please sign in to comment.