--- /dev/null
+Android Hardware OpenGLES emulation design overview
+===================================================
+
+Introduction:
+-------------
+
+Hardware GLES emulation in the Android platform is implemented with a mix
+of components, which are:
+
+ - Several host "translator" libraries. They implement the EGL, GLES 1.1 and
+ GLES 2.0 ABIs defined by Khronos, and translate the corresponding function
+ calls into calls to the appropriate desktop APIs, i.e.:
+
+ - GLX (Linux), AGL (OS X) or WGL (Windows) for EGL
+ - desktop GL 2.0 for GLES 1.1 and GLES 2.0
+
+ _________ __________ __________
+ | | | | | |
+ |TRANSLATOR |TRANSLATOR| |TRANSLATOR| HOST
+ | EGL | | GLES 1.1 | | GLES 2.0 | TRANSLATOR
+ |_________| |__________| |__________| LIBRARIES
+ | | |
+ - - - | - - - - - - - - - | - - - - - - - - - | - - - - -
+ | | |
+ ____v____ ____v_____ _____v____ HOST
+ | | | | | | SYSTEM
+ | GLX | | GL 2.0 | | GL 2.0 | LIBRARIES
+ |_________| |__________| |__________|
+
+
+
+ - Several system libraries inside the emulated guest system that implement
+ the same EGL / GLES 1.1 and GLES 2.0 ABIs.
+
+ They collect the sequence of EGL/GLES function calls and translate then
+ into a custom wire protocol stream that is sent to the emulator program
+ through a high-speed communication channel called a "QEMU Pipe".
+
+ For now, all you need to know is that the pipe is implemented with a
+ custom kernel driver, and provides for _very_ fast bandwidth. All read()
+ and writes() from/to the pipes are essentially instantaneous from the
+ guest's point of view.
+
+
+ _________ __________ __________
+ | | | | | |
+ |EMULATION| |EMULATION | |EMULATION | GUEST
+ | EGL | | GLES 1.1 | | GLES 2.0 | SYSTEM
+ |_________| |__________| |__________| LIBRARIES
+ | | |
+ - - - | - - - - - - - - - | - - - - - - - - - | - - - - -
+ | | |
+ ____v____________________v____________________v____ GUEST
+ | | KERNEL
+ | QEMU PIPE |
+ |___________________________________________________|
+ |
+ - - - - - - - - - - - - - -|- - - - - - - - - - - - - - - -
+ |
+ v
+ EMULATOR
+
+ - Specific code inside the emulator program that is capable of transmitting
+ the wire protocol stream to a special rendering library or process (called
+ the "renderer" here), which understands the format.
+
+ |
+ | PROTOCOL BYTE STREAM
+ _____v_____
+ | |
+ | EMULATOR |
+ |___________|
+ |
+ | UNMODIFIED PROTOCOL BYTE STREAM
+ _____v_____
+ | |
+ | RENDERER |
+ |___________|
+
+
+ - The renderer decodes the EGL/GLES commands from the wire
+ protocol stream, and dispatches them to the translator libraries
+ appropriately.
+
+ |
+ | PROTOCOL BYTE STREAM
+ _____v_____
+ | |
+ | RENDERER |
+ |___________|
+ | | |
+ +-----------------+ | +-----------------+
+ | | |
+ ____v____ ___v______ ____v_____
+ | | | | | | HOST
+ |TRANSLATOR |TRANSLATOR| |TRANSLATOR| HOST
+ | EGL | | GLES 1.1 | | GLES 2.0 | TRANSLATOR
+ |_________| |__________| |__________| LIBRARIES
+
+
+
+ - In reality, the protocol stream flows in both directions, even though most
+ of the commands result in data going from the guest to the host. A complete
+ picture of the emulation would thus be:
+
+
+
+
+
+ _________ __________ __________
+ | | | | | |
+ |EMULATION| |EMULATION | |EMULATION | GUEST
+ | EGL | | GLES 1.1 | | GLES 2.0 | SYSTEM
+ |_________| |__________| |__________| LIBRARIES
+ ^ ^ ^
+ | | |
+ - - - | - - - - - - - - - | - - - - - - - - - | - - - - -
+ | | |
+ ____v____________________v____________________v____ GUEST
+ | | KERNEL
+ | QEMU PIPE |
+ |___________________________________________________|
+ ^
+ |
+ - - - - - - - - - - - - - -|- - - - - - - - - - - - - - - -
+ |
+ | PROTOCOL BYTE STREAM
+ _____v_____
+ | |
+ | EMULATOR |
+ |___________|
+ ^
+ | UNMODIFIED PROTOCOL BYTE STREAM
+ _____v_____
+ | |
+ | RENDERER |
+ |___________|
+ ^ ^ ^
+ | | |
+ +-----------------+ | +-----------------+
+ | | |
+ ____v____ ___v______ ____v_____
+ | | | | | |
+ |TRANSLATOR |TRANSLATOR| |TRANSLATOR| HOST
+ | EGL | | GLES 1.1 | | GLES 2.0 | TRANSLATOR
+ |_________| |__________| |__________| LIBRARIES
+ ^ ^ ^
+ | | |
+ - - - | - - - - - - - - - | - - - - - - - - - | - - - - -
+ | | |
+ ____v____ ____v_____ _____v____ HOST
+ | | | | | | SYSTEM
+ | GLX | | GL 2.0 | | GL 2.0 | LIBRARIES
+ |_________| |__________| |__________|
+
+ (NOTE: 'GLX' is for Linux only, replace 'AGL' on OS X, and 'WGL' on Windows).
+
+
+Note that, in the above graphics, only the host system libraries at the bottom
+are _not_ provided by Android.
+
+
+Design Requirements:
+--------------------
+
+The above design comes from several important requirements that were decided
+early in the project:
+
+1 - The ability to run the renderer in a separate process from the emulator
+ itself is important.
+
+ For various practical reasons, we plan to completely separate the core QEMU
+ emulation from the UI window by using two distinct processes. As such, the
+ renderer will be implemented as a library inside the UI program, but will
+ need to receive protocol bytes from the QEMU process.
+
+ The communication channel will be either a fast Unix socket or a Win32
+ named pipe between these two. A shared memory segment with appropriate
+ synchronization primitives might also be used if performance becomes
+ an issue.
+
+ This explains why the emulator doesn't alter or even try to parse the
+ protocol byte stream. It only acts as a dumb proxy between the guest
+ system and the renderer. This also avoids adding lots of GLES-specific
+ code inside the QEMU code base which is terribly complex.
+
+2 - The ability to use vendor-specific desktop EGL/GLES libraries is
+ important.
+
+ GPU vendors like NVidia, AMD or ARM all provide host versions of the
+ EGL/GLES libraries that emulate their respectivie embedded graphics
+ chipset.
+
+ The renderer library can be configured to use these instead of the
+ translator libraries provided with this project. This can be useful to
+ more accurately emulate the behaviour of specific devices.
+
+ Moreover, these vendor libraries typically expose vendor-specific
+ extensions that are not provided by the translator libraries. We cannot
+ expose them without modifying our code, but it's important to be able
+ to do so without too much pain.
+
+
+Code organization:
+------------------
+
+All source code for the components above is spread over multiple directories
+in the Android source trees:
+
+ - The emulator sources are under $ANDROID/external/qemu, which we'll
+ call $QEMU in the rest of this document.
+
+ - The guest libraries are under
+ $ANDROID/device/generic/goldfish/opengl, which we'll call $EMUGL_GUEST
+
+ - The host renderer and translator libraries are under
+ $QEMU/distrib/android-emugl, which we'll call $EMUGL_HOST
+
+ - The QEMU Pipe kernel driver is under $KERNEL/drivers/misc/qemupipe (3.4)
+ or $KERNEL/drivers/platform/goldfish/goldfish_pipe.c (3.10)
+
+Where $ANDROID is the top of the open-source Android source tree, and
+$KERNEL is the top of the qemu-specific kernel source tree (using one
+of the android-goldfish-xxxx branches here).
+
+The emulator sources related to this projects are:
+
+ $QEMU/hw/android/goldfish/pipe.c -> implements QEMU pipe virtual hardware.
+ $QEMU/android/opengles.c -> implements GLES initialization.
+ $QEMU/android/hw-pipe-net.c -> implements the communication channel
+ between the QEMU Pipe and the renderer library
+
+The other sources are:
+
+ $EMUGL_GUEST/system -> system libraries
+ $EMUGL_GUEST/shared -> guest copy of shared libraries
+ $EMUGL_GUEST/tests -> various test programs
+
+ $EMUGL_HOST/host -> host libraries (translator + renderer)
+ $EMUGL_HOST/shared -> host copy of shared libraries
+
+The reason the shared libraries aren't actually shared is historical: at one
+point both guest and host code lived in the same place. That turned out to be
+impractical with the way the Android SDK is branched, and didn't support the
+requirement that a single emulator binary be able to run several releases
+of Android.
+
+
+Translator libraries:
+---------------------
+
+There are three translator host libraries provided by this project:
+
+ libEGL_translator -> EGL 1.2 translation
+ libGLES_CM_translator -> GLES 1.1 translation
+ libGLES_V2_translator -> GLES 2.0 translation
+
+The full name of the library will depend on the host system.
+For simplicity, only the library name suffix will change (i.e. the
+'lib' prefix is not dropped on Windows), i.e.:
+
+ libEGL_translator.so -> for Linux
+ libEGL_translator.dylib -> for OS X
+ libEGL_translator.dll -> for Windows
+
+The source code for these libraries is located under the following
+path in the Android source tree:
+
+ $EMUGL_HOST/host/libs/Translator/EGL
+ $EMUGL_HOST/host/libs/Translator/GLES_CM
+ $EMUGL_HOST/host/libs/Translator/GLES_V2
+
+The translator libraries also use a common routines defined under:
+
+ $EMUGL_HOST/host/libs/Translator/GLcommon
+
+
+Wire Protocol Overiew:
+----------------------
+
+The "wire protocol" is implemented as follows:
+
+ - EGL/GLES function calls are described through several "specification"
+ files, which describes the types, function signatures and various
+ attributes for each one of them.
+
+ - These files are read by a tool called "emugen" which generates C
+ source files and headers based on the specification. These correspond
+ to both encoding, decoding and "wrappers" (more on this later).
+
+ - System "encoder" static libraries are built using some of these generated
+ files. They contain code that can serialize EGL/GLES calls into simple
+ byte messages and send it through a generic "IOStream" object.
+
+ - Host "decoder" static libraries are also built using some of these
+ generated files. Their code retrieves byte messages from an "IOStream"
+ object, and translates them into function callbacks.
+
+IOStream abstraction:
+- - - - - - - - - - -
+
+The "IOStream" is a very simple abstract class used to send byte messages
+both in the guest and host. It is defined through a shared header under
+$EMUGL/host/include/libOpenglRender/IOStream.h
+
+Note that despite the path, this header is included by *both* host and guest
+source code. The main idea around IOStream's design is that to send a message,
+one does the following:
+
+ 1/ call stream->allocBuffer(size), which returns the address of a
+ memory buffer of at least 'size' bytes.
+
+ 2/ write the content of the serialized command (usually a header + some
+ payload) directly into the buffer
+
+ 3/ call stream->commitBuffer() to send it.
+
+Alternatively, one can also pack several commands into a single buffer with
+stream->alloc() and stream->flush(), as in:
+
+ 1/ buf1 = stream->alloc(size1)
+ 2/ write first command bytes into buf1
+ 3/ buf2 = stream->alloc(size2)
+ 4/ write second command bytes into buf2
+ 5/ stream->flush()
+
+Finally, there are also explict read/write methods like stream->readFully()
+or stream->writeFully() which can be used when you don't want an intermediate
+buffer. This is used in certain cases by the implementation, e.g. to avoid
+an intermediate memory copy when sending texture data from the guest to the
+host.
+
+The host IOStream implementations are under $EMUGL/shared/OpenglCodecCommon/,
+see in particular:
+
+ $EMUGL_HOST/shared/OpenglCodecCommon/TcpStream.cpp
+ -> using local TCP sockets
+ $EMUGL_HOST/shared/OpenglCodecCommon/UnixStream.cpp
+ -> using Unix sockets
+ $EMUGL_HOST/shared/OpenglCodecCommon/Win32PipeStream.cpp
+ -> using Win32 named pipes
+
+The guest IOStream implementation uses the TcpStream.cpp above, as well as
+an alternative QEMU-specific source:
+
+ $EMUGL_GUEST/system/OpenglSystemCommon/QemuPipeStream.cpp
+ -> uses QEMU pipe from the guest
+
+The QEMU Pipe implementation is _significantly_ faster (about 20x) due to
+several reasons:
+
+ - all succesful read() and write() operations through it are instantaneous
+ from the guest's point of view.
+
+ - all buffer/memory copies are performed directly by the emulator, and thus
+ much faster than performing the same thing inside the kernel with emulated
+ ARM instructions.
+
+ - it doesn't need to go through a kernel TCP/IP stack that will wrap the
+ data into TCP/IP/MAC packets, send them to an emulated ethernet device,
+ which is itself connected to an internal firewall implementation that
+ will unwrap the packets, re-assemble them, then send them through BSD
+ sockets to the host kernel.
+
+However, would it be necessary, you could write a guest IOStream implementation
+that uses a different transport. If you do, please look at
+$EMUGL_GUEST/system/OpenglCodecCommon/HostConnection.cpp which contains the
+code used to connect the guest to the host, on a per-thread basis.
+
+
+Source code auto-generation:
+- - - - - - - - - - - - - -
+
+The 'emugen' tool is located under $EMUGL_HOST/host/tools/emugen. There is a
+README file that explains how it works.
+
+You can also look at the following specifications files:
+
+For GLES 1.1:
+ $EMUGL_HOST/host/GLESv1_dec/gl.types
+ $EMUGL_HOST/host/GLESv1_dec/gl.in
+ $EMUGL_HOST/host/GLESv1_dec/gl.attrib
+
+For GLES 2.0:
+ $EMUGL_HOST/host/GLESv2_dec/gl2.types
+ $EMUGL_HOST/host/GLESv2_dec/gl2.in
+ $EMUGL_HOST/host/GLESv2_dec/gl2.attrib
+
+For EGL:
+ $EMUGL_HOST/host/renderControl_dec/renderControl.types
+ $EMUGL_HOST/host/renderControl_dec/renderControl.in
+ $EMUGL_HOST/host/renderControl_dec/renderControl.attrib
+
+Note that the EGL specification files are under a directory named
+"renderControl_dec" and have filenames that begin with "renderControl"
+
+This is mainly for historic reasons now, but is also related to the fact that
+this part of the wire protocol contains support functions/calls/specifications
+that are not part of the EGL specification itself, but add a few features
+required to make everything works. For example, they have calls related to
+the "gralloc" system library module used to manage graphics surfaces at a
+lower level than EGL.
+
+Generally speaking, guest encoder sources are located under directories
+named $EMUGL_GUEST/system/<name>_enc/, while the corresponding host decoder
+sources will be under $EMUGL_HOST/host/libs/<name>_dec/
+
+However, all these sources use the same spec files located under the
+decoding directories.
+
+The encoder files are built from emugen and spec files located in $EMUGL_HOST
+and copied to the encoder directories in $EMUGL_GUEST by the gen-encoder.sh
+script. They are checked in, so that a given version of Android supports a
+specific version of the protocol, even if newer versions of the renderer (and
+future Android versions) support a newer protocol version. This step needs to
+be done manually when the protocol changes; these changes also need to be
+accompanied by changes in the renderer to handle the old version of the
+protocol.
+
+
+System libraries:
+-----------------
+
+Meta EGL/GLES system libraries, and egl.cfg:
+- - - - - - - - - - - - - - - - - - - - - -
+
+It is important to understand that the emulation-specific EGL/GLES libraries
+are not directly linked by applications at runtime. Instead, the system
+provides a set of "meta" EGL/GLES libraries that will load the appropriate
+hardware-specific libraries on first use.
+
+More specifically, the system libEGL.so contains a "loader" which will try
+to load:
+
+ - hardware-specific EGL/GLES libraries
+ - the software-based rendering libraries (called "libagl")
+
+The system libEGL.so is also capable of merging the EGL configs of both the
+hardware and software libraries transparently to the application. The system
+libGLESv1_CM.so and libGLESv2.so, work with it to ensure that the thread's
+current context will be linked to either the hardware or software libraries
+depending on the config selected.
+
+For the record, the loader's source code in under
+frameworks/base/opengl/libs/EGL/Loader.cpp. It depends on a file named
+/system/lib/egl/egl.cfg which must contain two lines that look like:
+
+ 0 1 <name>
+ 0 0 android
+
+The first number in each line is a display number, and must be 0 since the
+system's EGL/GLES libraries don't support anything else.
+
+The second number must be 1 to indicate hardware libraries, and 0 to indicate
+a software one. The line corresponding to the hardware library, if any, must
+always appear before the one for the software library.
+
+The third field is a name corresponding to a shared library suffix. It really
+means that the corresponding libraries will be named libEGL_<name>.so,
+libGLESv1_CM_<name>.so and libGLESv2_<name>.so. Moreover these libraries must
+be placed under /system/lib/egl/
+
+The name "android" is reserved for the system software renderer.
+
+The egl.cfg that comes with this project uses the name "emulation" for the
+hardware libraries. This means that it provides an egl.cfg file that contains
+the following lines:
+
+ 0 1 emulation
+ 0 0 android
+
+See $EMUGL_GUEST/system/egl/egl.cfg and more generally the following build
+files:
+
+ $EMUGL_GUEST/system/egl/Android.mk
+ $EMUGL_GUEST/system/GLESv1/Android.mk
+ $EMUGL_GUEST/system/GLESv2/Android.mk
+
+to see how the libraries are named and placed under /system/lib/egl/ by the
+build system.
+
+
+Emulation libraries:
+- - - - - - - - - - -
+
+The emulator-specific libraries are under the following:
+
+ $EMUGL_GUEST/system/egl/
+ $EMUGL_GUEST/system/GLESv1/
+ $EMUGL_GUEST/system/GLESv2/
+
+The code for GLESv1 and GLESv2 is pretty small, since it mostly link against
+the static encoding libraries.
+
+The code for EGL is a bit more complex, because it needs to deal with
+extensions dynamically. I.e. if an extension is not available on the host
+it shouldn't be exposed by the library at runtime. So the EGL code queries
+the host for the list of available extensions in order to return them to
+clients. Similarly, it must query the list of valid EGLConfigs for the
+current host system.
+
+
+"gralloc" module implementation:
+- - - - - - - - - - - - - - - - -
+
+In addition to EGL/GLES libraries, the Android system requires a
+hardware-specific library to manage graphics surfaces at a level lower than
+EGL. This library must be what is called in Android land as a "HAL module".
+
+A "HAL module" must provide interfaces defined by Android's HAL
+(Hardware Abstraction Library). These interface definitions can be found
+under $ANDROID/hardware/libhardware/include/
+
+Of all possible HAL modules, the "gralloc" one is used by the system's
+SurfaceFlinger to allocate framebuffers and other graphics memory regions,
+as well as eventually lock/unlock/swap them when needed.
+
+The code under $EMUGL/system/gralloc/ implements the module required by the
+GLES emulation project. It's not very long, but there are a few things to
+notice here:
+
+- first, it will probe the guest system to determine if the emulator that
+ is running the virtual device really supports GPU emulation. In certain
+ circumstances this may not be possible.
+
+ If this is the case, then the module will redirect all calls to the
+ "default" gralloc module that is normally used by the system when
+ software-only rendering is enabled.
+
+ The probing happens in the function "fallback_init" which gets called
+ when the module is first opened. This initializes the 'sFallback' variable
+ to a pointer to the default gralloc module when required.
+
+- second, this module is used by SurfaceFlinger to display "software surfaces",
+ i.e. those that are backed by system memory pixel buffers, and written to
+ directly through the Skia graphics library (i.e. the non-accelerated ones).
+
+ the default module simply copies the pixel data from the surface to the
+ virtual framebuffer i/o memory, but this project's gralloc module sends it
+ to the renderer through the QEMU Pipe instead.
+
+ It turns out that this results in _faster_ rendering/frame-rates overall,
+ because memory copies inside the guest are slow, while QEMU pipe transfers
+ are done directly in the emulator.
+
+
+Host Renderer:
+--------------
+
+The host renderer library is located under
+$EMUGL_HOST/host/libs/libOpenglRender, and it provides an interface described
+by the headers under $EMUGL_HOST/host/libs/libOpenglRender/render_api.h
+(e.g. for use by the emulator).
+
+In a nutshell, the rendering library is responsible for the following:
+
+ - Providing a virtual off-screen video surface where everything will get
+ rendered at runtime. Its dimensions are fixed by the call to
+ initOpenglRender() that must happen just after the library is
+ initialized.
+
+ - Provide a way to display the virtual video surface on a host application's
+ UI. This is done by calling createOpenGLSubWindow() which takes as argument
+ the window ID or handle of a parent window, some display dimensions and
+ a rotation angle. This allows the surface to be scaled/rotated when it is
+ displayed, even if the dimensions of the video surface do not change.
+
+ - Provide a way to listen to incoming EGL/GLES commands from the guest.
+ This is done by providing a so-called "port number" to initOpenglRender().
+
+ By default, the port number corresponds to a local TCP port number that the
+ renderer will bind to and listen. Every new connection to this port will
+ correspond to the creation of a new guest host connection, each such
+ connection corresponding to a distinct thread in the guest system.
+
+ For performance reasons, it is possible to listen to either Unix sockets
+ (on Linux and OS X), or to a Win32 named pipe (on Windows). To do so, one
+ had to call setStreamType() between library initialization
+ (i.e. initLibrary()) and construction (i.e. initOpenglRender()).
+
+ Note that in these modes, the port number is still used to differentiate
+ between several emulator instances. These details are normally handled by
+ the emulator code so you shouldn't care too much.
+
+Note that an earlier version of the interface allowed a client of the renderer
+library to provide its own IOStream implementation. However, this wasn't very
+convenient for a number of reasons. This maybe something that could be done
+again if it makes sense, but for now the performance numbers are pretty good.
+
+
+Host emulator:
+--------------
+
+The code under $QEMU/android/opengles.c is in charge of dynamically loading
+the rendering library and initializing / constructing it properly.
+
+QEMU pipe connections to the 'opengles' service are piped through the code
+in $QEMU/android/hw-pipe-net.c. Look for the openglesPipe_init() function,
+which is in charge of creating a connection to the renderer library
+(either through a TCP socket, or a Unix pipe depending on configuration.
+support for Win32 named pipes hasn't been implemented yet in the emulator)
+whenever a guest process opens the "opengles" service through /dev/qemu_pipe.
+
+There is also some support code for the display of the GLES framebuffer
+(through the renderer library's subwindow) under $QEMU/skin/window.
+
+Note that at the moment, scaling and rotation are supported. However,
+brightness emulation (which used to modify the pixel values from the
+hardware framebuffer before displaying them) doesn't work.
+
+Another issue is that it is not possible to display anything on top of the
+GL subwindow at the moment. E.g. this will obscure the emulated trackball
+image (that is normally toggled with Ctrl-T during emulation, or enabled
+by pressing the Delete key).
+