2 * Copyright (C) 2011-2015 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 #ifndef _LIBRENDER_FRAMEBUFFER_H
17 #define _LIBRENDER_FRAMEBUFFER_H
19 #include "anbox/graphics/emugl/ColorBuffer.h"
20 #include "anbox/graphics/emugl/RenderContext.h"
21 #include "anbox/graphics/emugl/RendererConfig.h"
22 #include "anbox/graphics/emugl/TextureDraw.h"
23 #include "anbox/graphics/emugl/WindowSurface.h"
24 #include "anbox/graphics/emugl/Renderable.h"
26 #include "anbox/graphics/primitives.h"
27 #include "anbox/graphics/program_family.h"
28 #include "anbox/graphics/renderer.h"
37 // Type of handles, a.k.a. "object names" in the GL specification.
38 // These are integers used to uniquely identify a resource of a given type.
39 typedef uint32_t HandleType;
41 struct ColorBufferRef {
43 uint32_t refcount; // number of client-side references
45 typedef std::map<HandleType, RenderContextPtr> RenderContextMap;
46 typedef std::map<HandleType, std::pair<WindowSurfacePtr, HandleType>>
48 typedef std::map<HandleType, ColorBufferRef> ColorBufferMap;
50 // A structure used to list the capabilities of the underlying EGL
51 // implementation that the FrameBuffer instance depends on.
52 // |has_eglimage_texture_2d| is true iff the EGL_KHR_gl_texture_2D_image
53 // extension is supported.
54 // |has_eglimage_renderbuffer| is true iff the EGL_KHR_gl_renderbuffer_image
55 // extension is supported.
56 // |eglMajor| and |eglMinor| are the major and minor version numbers of
57 // the underlying EGL implementation.
59 bool has_eglimage_texture_2d;
60 bool has_eglimage_renderbuffer;
65 struct RendererWindow;
67 // The FrameBuffer class holds the global state of the emulation library on
68 // top of the underlying EGL/GLES implementation. It should probably be
69 // named "Display" instead of "FrameBuffer".
71 // There is only one global instance, that can be retrieved with getFB(),
72 // and which must be previously setup by calling initialize().
74 class Renderer : public anbox::graphics::Renderer {
79 // Initialize the global instance.
80 // |width| and |height| are the dimensions of the emulator GPU display
81 // in pixels. |useSubWindow| is true to indicate that the caller
82 // will use setupSubWindow() to let EmuGL display the GPU content in its
83 // own sub-windows. If false, this means the caller will use
84 // setPostCallback() instead to retrieve the content.
85 // Returns true on success, false otherwise.
86 bool initialize(EGLNativeDisplayType nativeDisplay);
88 // Finalize the instance.
91 // Return the capabilities of the underlying display.
92 const RendererCaps& getCaps() const { return m_caps; }
94 // Return the list of configs available from this display.
95 const RendererConfigList* getConfigs() const { return m_configs; }
97 // Retrieve the GL strings of the underlying EGL/GLES implementation.
98 // On return, |*vendor|, |*renderer| and |*version| will point to strings
99 // that are owned by the instance (and must not be freed by the caller).
100 void getGLStrings(const char** vendor, const char** renderer,
101 const char** version) const {
102 *vendor = m_glVendor;
103 *renderer = m_glRenderer;
104 *version = m_glVersion;
107 RendererWindow* createNativeWindow(EGLNativeWindowType native_window);
108 void destroyNativeWindow(RendererWindow* window);
109 void destroyNativeWindow(EGLNativeWindowType native_window);
111 // Create a new RenderContext instance for this display instance.
112 // |p_config| is the index of one of the configs returned by getConfigs().
113 // |p_share| is either EGL_NO_CONTEXT or the handle of a shared context.
114 // |p_isGL2| is true to create a GLES 2.x context, or false for a GLES 1.x
116 // Return a new handle value, which will be 0 in case of error.
117 HandleType createRenderContext(int p_config, HandleType p_share,
118 bool p_isGL2 = false);
120 // Create a new WindowSurface instance from this display instance.
121 // |p_config| is the index of one of the configs returned by getConfigs().
122 // |p_width| and |p_height| are the window dimensions in pixels.
123 // Return a new handle value, or 0 in case of error.
124 HandleType createWindowSurface(int p_config, int p_width, int p_height);
126 // Create a new ColorBuffer instance from this display instance.
127 // |p_width| and |p_height| are its dimensions in pixels.
128 // |p_internalFormat| is the pixel format. See ColorBuffer::create() for
129 // list of valid values. Note that ColorBuffer instances are reference-
130 // counted. Use openColorBuffer / closeColorBuffer to operate on the
132 HandleType createColorBuffer(int p_width, int p_height,
133 GLenum p_internalFormat);
135 // Call this function when a render thread terminates to destroy all
136 // the remaining contexts it created. Necessary to avoid leaking host
137 // contexts when a guest application crashes, for example.
138 void drainRenderContext();
140 // Call this function when a render thread terminates to destroy all
141 // remaining window surfqce it created. Necessary to avoid leaking
142 // host buffers when a guest application crashes, for example.
143 void drainWindowSurface();
145 // Destroy a given RenderContext instance. |p_context| is its handle
146 // value as returned by createRenderContext().
147 void DestroyRenderContext(HandleType p_context);
149 // Destroy a given WindowSurface instance. |p_surcace| is its handle
150 // value as returned by createWindowSurface().
151 void DestroyWindowSurface(HandleType p_surface);
153 // Increment the reference count associated with a given ColorBuffer
154 // instance. |p_colorbuffer| is its handle value as returned by
155 // createColorBuffer().
156 int openColorBuffer(HandleType p_colorbuffer);
158 // Decrement the reference count associated with a given ColorBuffer
159 // instance. |p_colorbuffer| is its handle value as returned by
160 // createColorBuffer(). Note that if the reference count reaches 0,
161 // the instance is destroyed automatically.
162 void closeColorBuffer(HandleType p_colorbuffer);
164 // Equivalent for eglMakeCurrent() for the current display.
165 // |p_context|, |p_drawSurface| and |p_readSurface| are the handle values
166 // of the context, the draw surface and the read surface, respectively.
167 // Returns true on success, false on failure.
168 // Note: if all handle values are 0, this is an unbind operation.
169 bool bindContext(HandleType p_context, HandleType p_drawSurface,
170 HandleType p_readSurface);
172 // Attach a ColorBuffer to a WindowSurface instance.
173 // See the documentation for WindowSurface::setColorBuffer().
174 // |p_surface| is the target WindowSurface's handle value.
175 // |p_colorbuffer| is the ColorBuffer handle value.
176 // Returns true on success, false otherwise.
177 bool setWindowSurfaceColorBuffer(HandleType p_surface,
178 HandleType p_colorbuffer);
180 // Copy the content of a WindowSurface's Pbuffer to its attached
181 // ColorBuffer. See the documentation for WindowSurface::flushColorBuffer()
182 // |p_surface| is the target WindowSurface's handle value.
183 // Returns true on success, false on failure.
184 bool flushWindowSurfaceColorBuffer(HandleType p_surface);
186 // Bind the current context's EGL_TEXTURE_2D texture to a ColorBuffer
187 // instance's EGLImage. This is intended to implement
188 // glEGLImageTargetTexture2DOES() for all GLES versions.
189 // |p_colorbuffer| is the ColorBuffer's handle value.
190 // Returns true on success, false on failure.
191 bool bindColorBufferToTexture(HandleType p_colorbuffer);
193 // Bind the current context's EGL_RENDERBUFFER_OES render buffer to this
194 // ColorBuffer's EGLImage. This is intended to implement
195 // glEGLImageTargetRenderbufferStorageOES() for all GLES versions.
196 // |p_colorbuffer| is the ColorBuffer's handle value.
197 // Returns true on success, false on failure.
198 bool bindColorBufferToRenderbuffer(HandleType p_colorbuffer);
200 // Read the content of a given ColorBuffer into client memory.
201 // |p_colorbuffer| is the ColorBuffer's handle value. Similar
202 // to glReadPixels(), this can be a slow operation.
203 // |x|, |y|, |width| and |height| are the position and dimensions of
204 // a rectangle whose pixel values will be transfered to the host.
205 // |format| indicates the format of the pixel data, e.g. GL_RGB or GL_RGBA.
206 // |type| is the type of pixel data, e.g. GL_UNSIGNED_BYTE.
207 // |pixels| is the address of a caller-provided buffer that will be filled
208 // with the pixel data.
209 void readColorBuffer(HandleType p_colorbuffer, int x, int y, int width,
210 int height, GLenum format, GLenum type, void* pixels);
212 // Update the content of a given ColorBuffer from client data.
213 // |p_colorbuffer| is the ColorBuffer's handle value. Similar
214 // to glReadPixels(), this can be a slow operation.
215 // |x|, |y|, |width| and |height| are the position and dimensions of
216 // a rectangle whose pixel values will be transfered to the GPU
217 // |format| indicates the format of the pixel data, e.g. GL_RGB or GL_RGBA.
218 // |type| is the type of pixel data, e.g. GL_UNSIGNED_BYTE.
219 // |pixels| is the address of a buffer containing the new pixel data.
220 // Returns true on success, false otherwise.
221 bool updateColorBuffer(HandleType p_colorbuffer, int x, int y, int width,
222 int height, GLenum format, GLenum type, void* pixels);
224 bool draw(EGLNativeWindowType native_window,
225 const anbox::graphics::Rect& window_frame,
226 const RenderableList& renderables) override;
228 // Return the host EGLDisplay used by this instance.
229 EGLDisplay getDisplay() const { return m_eglDisplay; }
231 // Return a TextureDraw instance that can be used with this surfaces
232 // and windows created by this instance.
233 TextureDraw* getTextureDraw() const { return m_textureDraw; }
235 HandleType createClientImage(HandleType context, EGLenum target,
237 EGLBoolean destroyClientImage(HandleType image);
241 bool unbind_locked();
244 HandleType genHandle();
246 bool bindWindow_locked(RendererWindow* window);
248 void setupViewport(RendererWindow* window, const anbox::graphics::Rect& rect);
250 void draw(RendererWindow* window, const Renderable& renderable,
251 const Program& prog);
252 void tessellate(std::vector<anbox::graphics::Primitive>& primitives,
253 const anbox::graphics::Rect& buf_size,
254 const Renderable& renderable);
257 static Renderer* s_renderer;
258 static HandleType s_nextHandle;
260 RendererConfigList* m_configs;
262 EGLDisplay m_eglDisplay;
263 RenderContextMap m_contexts;
264 WindowSurfaceMap m_windows;
265 ColorBufferMap m_colorbuffers;
266 ColorBuffer::Helper* m_colorBufferHelper;
268 EGLContext m_eglContext;
269 EGLSurface m_pbufSurface;
270 EGLContext m_pbufContext;
272 EGLContext m_prevContext;
273 EGLSurface m_prevReadSurf;
274 EGLSurface m_prevDrawSurf;
275 TextureDraw* m_textureDraw;
276 EGLConfig m_eglConfig;
277 HandleType m_lastPostedColorBuffer;
279 int m_statsNumFrames;
280 long long m_statsStartTime;
283 const char* m_glVendor;
284 const char* m_glRenderer;
285 const char* m_glVersion;
287 std::map<EGLNativeWindowType, RendererWindow*> m_nativeWindows;
289 anbox::graphics::ProgramFamily m_family;
292 GLint tex_uniform = -1;
293 GLint position_attr = -1;
294 GLint texcoord_attr = -1;
295 GLint center_uniform = -1;
296 GLint display_transform_uniform = -1;
297 GLint transform_uniform = -1;
298 GLint screen_to_gl_coords_uniform = -1;
299 GLint alpha_uniform = -1;
300 mutable long long last_used_frameno = 0;
302 Program(GLuint program_id);
305 Program m_defaultProgram, m_alphaProgram;
307 std::vector<anbox::graphics::Primitive> m_primitives;
309 static const GLchar* const vshader;
310 static const GLchar* const defaultFShader;
311 static const GLchar* const alphaFShader;