TYPE3
[iec.git] / src / type3_AndroidCloud / anbox-master / src / anbox / graphics / emugl / Renderer.h
diff --git a/src/type3_AndroidCloud/anbox-master/src/anbox/graphics/emugl/Renderer.h b/src/type3_AndroidCloud/anbox-master/src/anbox/graphics/emugl/Renderer.h
new file mode 100644 (file)
index 0000000..cfcc0b2
--- /dev/null
@@ -0,0 +1,313 @@
+/*
+* Copyright (C) 2011-2015 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+#ifndef _LIBRENDER_FRAMEBUFFER_H
+#define _LIBRENDER_FRAMEBUFFER_H
+
+#include "anbox/graphics/emugl/ColorBuffer.h"
+#include "anbox/graphics/emugl/RenderContext.h"
+#include "anbox/graphics/emugl/RendererConfig.h"
+#include "anbox/graphics/emugl/TextureDraw.h"
+#include "anbox/graphics/emugl/WindowSurface.h"
+#include "anbox/graphics/emugl/Renderable.h"
+
+#include "anbox/graphics/primitives.h"
+#include "anbox/graphics/program_family.h"
+#include "anbox/graphics/renderer.h"
+
+#include <EGL/egl.h>
+
+#include <map>
+#include <mutex>
+
+#include <stdint.h>
+
+// Type of handles, a.k.a. "object names" in the GL specification.
+// These are integers used to uniquely identify a resource of a given type.
+typedef uint32_t HandleType;
+
+struct ColorBufferRef {
+  ColorBufferPtr cb;
+  uint32_t refcount;  // number of client-side references
+};
+typedef std::map<HandleType, RenderContextPtr> RenderContextMap;
+typedef std::map<HandleType, std::pair<WindowSurfacePtr, HandleType>>
+    WindowSurfaceMap;
+typedef std::map<HandleType, ColorBufferRef> ColorBufferMap;
+
+// A structure used to list the capabilities of the underlying EGL
+// implementation that the FrameBuffer instance depends on.
+// |has_eglimage_texture_2d| is true iff the EGL_KHR_gl_texture_2D_image
+// extension is supported.
+// |has_eglimage_renderbuffer| is true iff the EGL_KHR_gl_renderbuffer_image
+// extension is supported.
+// |eglMajor| and |eglMinor| are the major and minor version numbers of
+// the underlying EGL implementation.
+struct RendererCaps {
+  bool has_eglimage_texture_2d;
+  bool has_eglimage_renderbuffer;
+  EGLint eglMajor;
+  EGLint eglMinor;
+};
+
+struct RendererWindow;
+
+// The FrameBuffer class holds the global state of the emulation library on
+// top of the underlying EGL/GLES implementation. It should probably be
+// named "Display" instead of "FrameBuffer".
+//
+// There is only one global instance, that can be retrieved with getFB(),
+// and which must be previously setup by calling initialize().
+//
+class Renderer : public anbox::graphics::Renderer {
+ public:
+  Renderer();
+  virtual ~Renderer();
+
+  // Initialize the global instance.
+  // |width| and |height| are the dimensions of the emulator GPU display
+  // in pixels. |useSubWindow| is true to indicate that the caller
+  // will use setupSubWindow() to let EmuGL display the GPU content in its
+  // own sub-windows. If false, this means the caller will use
+  // setPostCallback() instead to retrieve the content.
+  // Returns true on success, false otherwise.
+  bool initialize(EGLNativeDisplayType nativeDisplay);
+
+  // Finalize the instance.
+  void finalize();
+
+  // Return the capabilities of the underlying display.
+  const RendererCaps& getCaps() const { return m_caps; }
+
+  // Return the list of configs available from this display.
+  const RendererConfigList* getConfigs() const { return m_configs; }
+
+  // Retrieve the GL strings of the underlying EGL/GLES implementation.
+  // On return, |*vendor|, |*renderer| and |*version| will point to strings
+  // that are owned by the instance (and must not be freed by the caller).
+  void getGLStrings(const char** vendor, const char** renderer,
+                    const char** version) const {
+    *vendor = m_glVendor;
+    *renderer = m_glRenderer;
+    *version = m_glVersion;
+  }
+
+  RendererWindow* createNativeWindow(EGLNativeWindowType native_window);
+  void destroyNativeWindow(RendererWindow* window);
+  void destroyNativeWindow(EGLNativeWindowType native_window);
+
+  // Create a new RenderContext instance for this display instance.
+  // |p_config| is the index of one of the configs returned by getConfigs().
+  // |p_share| is either EGL_NO_CONTEXT or the handle of a shared context.
+  // |p_isGL2| is true to create a GLES 2.x context, or false for a GLES 1.x
+  // one.
+  // Return a new handle value, which will be 0 in case of error.
+  HandleType createRenderContext(int p_config, HandleType p_share,
+                                 bool p_isGL2 = false);
+
+  // Create a new WindowSurface instance from this display instance.
+  // |p_config| is the index of one of the configs returned by getConfigs().
+  // |p_width| and |p_height| are the window dimensions in pixels.
+  // Return a new handle value, or 0 in case of error.
+  HandleType createWindowSurface(int p_config, int p_width, int p_height);
+
+  // Create a new ColorBuffer instance from this display instance.
+  // |p_width| and |p_height| are its dimensions in pixels.
+  // |p_internalFormat| is the pixel format. See ColorBuffer::create() for
+  // list of valid values. Note that ColorBuffer instances are reference-
+  // counted. Use openColorBuffer / closeColorBuffer to operate on the
+  // internal count.
+  HandleType createColorBuffer(int p_width, int p_height,
+                               GLenum p_internalFormat);
+
+  // Call this function when a render thread terminates to destroy all
+  // the remaining contexts it created. Necessary to avoid leaking host
+  // contexts when a guest application crashes, for example.
+  void drainRenderContext();
+
+  // Call this function when a render thread terminates to destroy all
+  // remaining window surfqce it created. Necessary to avoid leaking
+  // host buffers when a guest application crashes, for example.
+  void drainWindowSurface();
+
+  // Destroy a given RenderContext instance. |p_context| is its handle
+  // value as returned by createRenderContext().
+  void DestroyRenderContext(HandleType p_context);
+
+  // Destroy a given WindowSurface instance. |p_surcace| is its handle
+  // value as returned by createWindowSurface().
+  void DestroyWindowSurface(HandleType p_surface);
+
+  // Increment the reference count associated with a given ColorBuffer
+  // instance. |p_colorbuffer| is its handle value as returned by
+  // createColorBuffer().
+  int openColorBuffer(HandleType p_colorbuffer);
+
+  // Decrement the reference count associated with a given ColorBuffer
+  // instance. |p_colorbuffer| is its handle value as returned by
+  // createColorBuffer(). Note that if the reference count reaches 0,
+  // the instance is destroyed automatically.
+  void closeColorBuffer(HandleType p_colorbuffer);
+
+  // Equivalent for eglMakeCurrent() for the current display.
+  // |p_context|, |p_drawSurface| and |p_readSurface| are the handle values
+  // of the context, the draw surface and the read surface, respectively.
+  // Returns true on success, false on failure.
+  // Note: if all handle values are 0, this is an unbind operation.
+  bool bindContext(HandleType p_context, HandleType p_drawSurface,
+                   HandleType p_readSurface);
+
+  // Attach a ColorBuffer to a WindowSurface instance.
+  // See the documentation for WindowSurface::setColorBuffer().
+  // |p_surface| is the target WindowSurface's handle value.
+  // |p_colorbuffer| is the ColorBuffer handle value.
+  // Returns true on success, false otherwise.
+  bool setWindowSurfaceColorBuffer(HandleType p_surface,
+                                   HandleType p_colorbuffer);
+
+  // Copy the content of a WindowSurface's Pbuffer to its attached
+  // ColorBuffer. See the documentation for WindowSurface::flushColorBuffer()
+  // |p_surface| is the target WindowSurface's handle value.
+  // Returns true on success, false on failure.
+  bool flushWindowSurfaceColorBuffer(HandleType p_surface);
+
+  // Bind the current context's EGL_TEXTURE_2D texture to a ColorBuffer
+  // instance's EGLImage. This is intended to implement
+  // glEGLImageTargetTexture2DOES() for all GLES versions.
+  // |p_colorbuffer| is the ColorBuffer's handle value.
+  // Returns true on success, false on failure.
+  bool bindColorBufferToTexture(HandleType p_colorbuffer);
+
+  // Bind the current context's EGL_RENDERBUFFER_OES render buffer to this
+  // ColorBuffer's EGLImage. This is intended to implement
+  // glEGLImageTargetRenderbufferStorageOES() for all GLES versions.
+  // |p_colorbuffer| is the ColorBuffer's handle value.
+  // Returns true on success, false on failure.
+  bool bindColorBufferToRenderbuffer(HandleType p_colorbuffer);
+
+  // Read the content of a given ColorBuffer into client memory.
+  // |p_colorbuffer| is the ColorBuffer's handle value. Similar
+  // to glReadPixels(), this can be a slow operation.
+  // |x|, |y|, |width| and |height| are the position and dimensions of
+  // a rectangle whose pixel values will be transfered to the host.
+  // |format| indicates the format of the pixel data, e.g. GL_RGB or GL_RGBA.
+  // |type| is the type of pixel data, e.g. GL_UNSIGNED_BYTE.
+  // |pixels| is the address of a caller-provided buffer that will be filled
+  // with the pixel data.
+  void readColorBuffer(HandleType p_colorbuffer, int x, int y, int width,
+                       int height, GLenum format, GLenum type, void* pixels);
+
+  // Update the content of a given ColorBuffer from client data.
+  // |p_colorbuffer| is the ColorBuffer's handle value. Similar
+  // to glReadPixels(), this can be a slow operation.
+  // |x|, |y|, |width| and |height| are the position and dimensions of
+  // a rectangle whose pixel values will be transfered to the GPU
+  // |format| indicates the format of the pixel data, e.g. GL_RGB or GL_RGBA.
+  // |type| is the type of pixel data, e.g. GL_UNSIGNED_BYTE.
+  // |pixels| is the address of a buffer containing the new pixel data.
+  // Returns true on success, false otherwise.
+  bool updateColorBuffer(HandleType p_colorbuffer, int x, int y, int width,
+                         int height, GLenum format, GLenum type, void* pixels);
+
+  bool draw(EGLNativeWindowType native_window,
+            const anbox::graphics::Rect& window_frame,
+            const RenderableList& renderables) override;
+
+  // Return the host EGLDisplay used by this instance.
+  EGLDisplay getDisplay() const { return m_eglDisplay; }
+
+  // Return a TextureDraw instance that can be used with this surfaces
+  // and windows created by this instance.
+  TextureDraw* getTextureDraw() const { return m_textureDraw; }
+
+  HandleType createClientImage(HandleType context, EGLenum target,
+                               GLuint buffer);
+  EGLBoolean destroyClientImage(HandleType image);
+
+  // Used internally.
+  bool bind_locked();
+  bool unbind_locked();
+
+ private:
+  HandleType genHandle();
+
+  bool bindWindow_locked(RendererWindow* window);
+
+  void setupViewport(RendererWindow* window, const anbox::graphics::Rect& rect);
+  struct Program;
+  void draw(RendererWindow* window, const Renderable& renderable,
+            const Program& prog);
+  void tessellate(std::vector<anbox::graphics::Primitive>& primitives,
+                  const anbox::graphics::Rect& buf_size,
+                  const Renderable& renderable);
+
+ private:
+  static Renderer* s_renderer;
+  static HandleType s_nextHandle;
+  std::mutex m_lock;
+  RendererConfigList* m_configs;
+  RendererCaps m_caps;
+  EGLDisplay m_eglDisplay;
+  RenderContextMap m_contexts;
+  WindowSurfaceMap m_windows;
+  ColorBufferMap m_colorbuffers;
+  ColorBuffer::Helper* m_colorBufferHelper;
+
+  EGLContext m_eglContext;
+  EGLSurface m_pbufSurface;
+  EGLContext m_pbufContext;
+
+  EGLContext m_prevContext;
+  EGLSurface m_prevReadSurf;
+  EGLSurface m_prevDrawSurf;
+  TextureDraw* m_textureDraw;
+  EGLConfig m_eglConfig;
+  HandleType m_lastPostedColorBuffer;
+
+  int m_statsNumFrames;
+  long long m_statsStartTime;
+  bool m_fpsStats;
+
+  const char* m_glVendor;
+  const char* m_glRenderer;
+  const char* m_glVersion;
+
+  std::map<EGLNativeWindowType, RendererWindow*> m_nativeWindows;
+
+  anbox::graphics::ProgramFamily m_family;
+  struct Program {
+    GLuint id = 0;
+    GLint tex_uniform = -1;
+    GLint position_attr = -1;
+    GLint texcoord_attr = -1;
+    GLint center_uniform = -1;
+    GLint display_transform_uniform = -1;
+    GLint transform_uniform = -1;
+    GLint screen_to_gl_coords_uniform = -1;
+    GLint alpha_uniform = -1;
+    mutable long long last_used_frameno = 0;
+
+    Program(GLuint program_id);
+    Program() {}
+  };
+  Program m_defaultProgram, m_alphaProgram;
+
+  std::vector<anbox::graphics::Primitive> m_primitives;
+
+  static const GLchar* const vshader;
+  static const GLchar* const defaultFShader;
+  static const GLchar* const alphaFShader;
+};
+#endif