TYPE3
[iec.git] / src / type3_AndroidCloud / anbox-master / external / android-emugl / DESIGN
diff --git a/src/type3_AndroidCloud/anbox-master/external/android-emugl/DESIGN b/src/type3_AndroidCloud/anbox-master/external/android-emugl/DESIGN
new file mode 100644 (file)
index 0000000..943a0e4
--- /dev/null
@@ -0,0 +1,615 @@
+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).
+