• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011-2015 The Android Open Source Project
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 #ifndef _LIBRENDER_FRAMEBUFFER_H
17 #define _LIBRENDER_FRAMEBUFFER_H
18 
19 #include <EGL/egl.h>
20 #include <stdint.h>
21 
22 #include <functional>
23 #include <map>
24 #include <memory>
25 #include <unordered_map>
26 #include <unordered_set>
27 
28 #include "ColorBuffer.h"
29 #include "DisplayVk.h"
30 #include "FbConfig.h"
31 #include "GLESVersionDetector.h"
32 #include "Hwc2.h"
33 #include "PostCommands.h"
34 #include "PostWorker.h"
35 #include "ReadbackWorker.h"
36 #include "RenderContext.h"
37 #include "Renderer.h"
38 #include "TextureDraw.h"
39 #include "WindowSurface.h"
40 #include "base/Lock.h"
41 #include "base/MessageChannel.h"
42 #include "base/Stream.h"
43 #include "base/Thread.h"
44 #include "base/WorkerThread.h"
45 #include "render_api.h"
46 #include "snapshot/common.h"
47 #include "vulkan/vk_util.h"
48 
49 struct ColorBufferRef {
50     ColorBufferPtr cb;
51     uint32_t refcount;  // number of client-side references
52 
53     // Tracks whether opened at least once. In O+,
54     // color buffers can be created/closed immediately,
55     // but then registered (opened) afterwards.
56     bool opened;
57 
58     // Tracks the time when this buffer got a close request while not being
59     // opened yet.
60     uint64_t closedTs;
61 };
62 
63 struct BufferRef {
64     BufferPtr buffer;
65 };
66 
67 typedef std::unordered_map<HandleType, std::pair<WindowSurfacePtr, HandleType>>
68     WindowSurfaceMap;
69 typedef std::unordered_set<HandleType> WindowSurfaceSet;
70 typedef std::unordered_map<uint64_t, WindowSurfaceSet> ProcOwnedWindowSurfaces;
71 
72 typedef std::unordered_map<HandleType, RenderContextPtr> RenderContextMap;
73 typedef std::unordered_set<HandleType> RenderContextSet;
74 typedef std::unordered_map<uint64_t, RenderContextSet> ProcOwnedRenderContexts;
75 
76 typedef std::unordered_map<HandleType, ColorBufferRef> ColorBufferMap;
77 typedef std::unordered_multiset<HandleType> ColorBufferSet;
78 typedef std::unordered_map<uint64_t, ColorBufferSet> ProcOwnedColorBuffers;
79 
80 typedef std::unordered_map<HandleType, BufferRef> BufferMap;
81 typedef std::unordered_multiset<HandleType> BufferSet;
82 typedef std::unordered_map<uint64_t, BufferSet> ProcOwnedBuffers;
83 
84 typedef std::unordered_set<HandleType> EGLImageSet;
85 typedef std::unordered_map<uint64_t, EGLImageSet> ProcOwnedEGLImages;
86 
87 typedef std::unordered_map<void*, std::function<void()>> CallbackMap;
88 typedef std::unordered_map<uint64_t, CallbackMap> ProcOwnedCleanupCallbacks;
89 
90 typedef std::unordered_map<uint64_t, uint32_t*> ProcOwnedSequenceNumbers;
91 
92 // A structure used to list the capabilities of the underlying EGL
93 // implementation that the FrameBuffer instance depends on.
94 // |has_eglimage_texture_2d| is true iff the EGL_KHR_gl_texture_2D_image
95 // extension is supported.
96 // |has_eglimage_renderbuffer| is true iff the EGL_KHR_gl_renderbuffer_image
97 // extension is supported.
98 // |eglMajor| and |eglMinor| are the major and minor version numbers of
99 // the underlying EGL implementation.
100 struct FrameBufferCaps {
101     bool has_eglimage_texture_2d;
102     bool has_eglimage_renderbuffer;
103     EGLint eglMajor;
104     EGLint eglMinor;
105 };
106 
107 // The FrameBuffer class holds the global state of the emulation library on
108 // top of the underlying EGL/GLES implementation. It should probably be
109 // named "Display" instead of "FrameBuffer".
110 //
111 // There is only one global instance, that can be retrieved with getFB(),
112 // and which must be previously setup by calling initialize().
113 //
114 class FrameBuffer {
115    public:
116     // Initialize the global instance.
117     // |width| and |height| are the dimensions of the emulator GPU display
118     // in pixels. |useSubWindow| is true to indicate that the caller
119     // will use setupSubWindow() to let EmuGL display the GPU content in its
120     // own sub-windows. If false, this means the caller will use
121     // setPostCallback() instead to retrieve the content.
122     // Returns true on success, false otherwise.
123     static bool initialize(int width, int height, bool useSubWindow,
124                            bool egl2egl);
125 
126     // Setup a sub-window to display the content of the emulated GPU
127     // on-top of an existing UI window. |p_window| is the platform-specific
128     // parent window handle. |wx|, |wy|, |ww| and |wh| are the
129     // dimensions in pixels of the sub-window, relative to the parent window's
130     // coordinate. |fbw| and |fbh| are the dimensions used to initialize
131     // the framebuffer, which may be different from the dimensions of the
132     // sub-window (in which case scaling will be applied automatically).
133     // |dpr| is the device pixel ratio of the monitor, which is needed for
134     // proper panning on high-density displays (like retina)
135     // |zRot| is a rotation angle in degrees, (clockwise in the Y-upwards GL
136     // coordinate space).
137     //
138     // If a sub-window already exists, this function updates the subwindow
139     // and framebuffer properties to match the given values.
140     //
141     // Return true on success, false otherwise.
142     //
143     // NOTE: This can return false for software-only EGL engines like OSMesa.
144     bool setupSubWindow(FBNativeWindowType p_window, int wx, int wy, int ww,
145                         int wh, int fbw, int fbh, float dpr, float zRot,
146                         bool deleteExisting, bool hideWindow);
147 
148     // Remove the sub-window created by setupSubWindow(), if any.
149     // Return true on success, false otherwise.
150     bool removeSubWindow();
151 
152     // Finalize the instance.
153     void finalize();
154 
155     // Return a pointer to the global instance. initialize() must be called
156     // previously, or this will return NULL.
getFB()157     static FrameBuffer* getFB() { return s_theFrameBuffer; }
158 
159     // Wait for a FrameBuffer instance to be initialized and ready to use.
160     // This function blocks the caller until there is a valid initialized
161     // object in getFB() and
162     static void waitUntilInitialized();
163 
164     // Return the capabilities of the underlying display.
getCaps()165     const FrameBufferCaps& getCaps() const { return m_caps; }
166 
167     // Return the emulated GPU display width in pixels.
getWidth()168     int getWidth() const { return m_framebufferWidth; }
169 
170     // Return the emulated GPU display height in pixels.
getHeight()171     int getHeight() const { return m_framebufferHeight; }
172 
173     // Return the list of configs available from this display.
getConfigs()174     const FbConfigList* getConfigs() const { return m_configs; }
175 
176     // Set a callback that will be called each time the emulated GPU content
177     // is updated. This can be relatively slow with host-based GPU emulation,
178     // so only do this when you need to.
179     void setPostCallback(emugl::Renderer::OnPostCallback onPost,
180                          void* onPostContext, uint32_t displayId,
181                          bool useBgraReadback = false);
182 
183     // Retrieve the GL strings of the underlying EGL/GLES implementation.
184     // On return, |*vendor|, |*renderer| and |*version| will point to strings
185     // that are owned by the instance (and must not be freed by the caller).
getGLStrings(const char ** vendor,const char ** renderer,const char ** version)186     void getGLStrings(const char** vendor, const char** renderer,
187                       const char** version) const {
188         *vendor = m_glVendor.c_str();
189         *renderer = m_glRenderer.c_str();
190         *version = m_glVersion.c_str();
191     }
192 
193     // Create a new RenderContext instance for this display instance.
194     // |p_config| is the index of one of the configs returned by getConfigs().
195     // |p_share| is either EGL_NO_CONTEXT or the handle of a shared context.
196     // |version| specifies the GLES version as a GLESApi enum.
197     // Return a new handle value, which will be 0 in case of error.
198     HandleType createRenderContext(int p_config, HandleType p_share,
199                                    GLESApi version = GLESApi_CM);
200 
201     // Create a new WindowSurface instance from this display instance.
202     // |p_config| is the index of one of the configs returned by getConfigs().
203     // |p_width| and |p_height| are the window dimensions in pixels.
204     // Return a new handle value, or 0 in case of error.
205     HandleType createWindowSurface(int p_config, int p_width, int p_height);
206 
207     // Create a new ColorBuffer instance from this display instance.
208     // |p_width| and |p_height| are its dimensions in pixels.
209     // |p_internalFormat| is the OpenGL format of this color buffer.
210     // |p_frameworkFormat| describes the Android frameework format of this
211     // color buffer, if differing from |p_internalFormat|.
212     // See ColorBuffer::create() for
213     // list of valid values. Note that ColorBuffer instances are reference-
214     // counted. Use openColorBuffer / closeColorBuffer to operate on the
215     // internal count.
216     HandleType createColorBuffer(int p_width, int p_height,
217                                  GLenum p_internalFormat,
218                                  FrameworkFormat p_frameworkFormat);
219     // Variant of createColorBuffer except with a particular
220     // handle already assigned. This is for use with
221     // virtio-gpu's RESOURCE_CREATE ioctl.
222     void createColorBufferWithHandle(int p_width, int p_height,
223                                      GLenum p_internalFormat,
224                                      FrameworkFormat p_frameworkFormat,
225                                      HandleType handle);
226 
227     // Create a new data Buffer instance from this display instance.
228     // The buffer will be backed by a VkBuffer and VkDeviceMemory (if Vulkan
229     // is available).
230     // |size| is the requested size of Buffer in bytes.
231     // |memoryProperty| is the requested memory property bits of the device
232     // memory.
233     HandleType createBuffer(uint64_t size, uint32_t memoryProperty);
234 
235     // Call this function when a render thread terminates to destroy all
236     // the remaining contexts it created. Necessary to avoid leaking host
237     // contexts when a guest application crashes, for example.
238     void drainRenderContext();
239 
240     // Call this function when a render thread terminates to destroy all
241     // remaining window surfqce it created. Necessary to avoid leaking
242     // host buffers when a guest application crashes, for example.
243     void drainWindowSurface();
244 
245     // Destroy a given RenderContext instance. |p_context| is its handle
246     // value as returned by createRenderContext().
247     void DestroyRenderContext(HandleType p_context);
248 
249     // Destroy a given WindowSurface instance. |p_surcace| is its handle
250     // value as returned by createWindowSurface().
251     void DestroyWindowSurface(HandleType p_surface);
252     // Returns the set of ColorBuffers destroyed (for further cleanup)
253     std::vector<HandleType> DestroyWindowSurfaceLocked(HandleType p_surface);
254 
255     // Increment the reference count associated with a given ColorBuffer
256     // instance. |p_colorbuffer| is its handle value as returned by
257     // createColorBuffer().
258     int openColorBuffer(HandleType p_colorbuffer);
259 
260     // Decrement the reference count associated with a given ColorBuffer
261     // instance. |p_colorbuffer| is its handle value as returned by
262     // createColorBuffer(). Note that if the reference count reaches 0,
263     // the instance is destroyed automatically.
264     void closeColorBuffer(HandleType p_colorbuffer);
265 
266     // Destroy a Buffer created previously. |p_buffer| is its handle value as
267     // returned by createBuffer().
268     void closeBuffer(HandleType p_colorbuffer);
269 
270     void cleanupProcGLObjects(uint64_t puid);
271 
272     // Equivalent for eglMakeCurrent() for the current display.
273     // |p_context|, |p_drawSurface| and |p_readSurface| are the handle values
274     // of the context, the draw surface and the read surface, respectively.
275     // Returns true on success, false on failure.
276     // Note: if all handle values are 0, this is an unbind operation.
277     bool bindContext(HandleType p_context, HandleType p_drawSurface,
278                      HandleType p_readSurface);
279 
280     // Return a render context pointer from its handle
281     RenderContextPtr getContext_locked(HandleType p_context);
282 
283     // Return a color buffer pointer from its handle
284     ColorBufferPtr getColorBuffer_locked(HandleType p_colorBuffer);
285 
286     // Return a color buffer pointer from its handle
287     WindowSurfacePtr getWindowSurface_locked(HandleType p_windowsurface);
288 
289     // Attach a ColorBuffer to a WindowSurface instance.
290     // See the documentation for WindowSurface::setColorBuffer().
291     // |p_surface| is the target WindowSurface's handle value.
292     // |p_colorbuffer| is the ColorBuffer handle value.
293     // Returns true on success, false otherwise.
294     bool setWindowSurfaceColorBuffer(HandleType p_surface,
295                                      HandleType p_colorbuffer);
296 
297     // Copy the content of a WindowSurface's Pbuffer to its attached
298     // ColorBuffer. See the documentation for WindowSurface::flushColorBuffer()
299     // |p_surface| is the target WindowSurface's handle value.
300     // Returns true on success, false on failure.
301     bool flushWindowSurfaceColorBuffer(HandleType p_surface);
302 
303     // Retrieves the color buffer handle associated with |p_surface|.
304     // Returns 0 if there is no such handle.
305     HandleType getWindowSurfaceColorBufferHandle(HandleType p_surface);
306 
307     // Bind the current context's EGL_TEXTURE_2D texture to a ColorBuffer
308     // instance's EGLImage. This is intended to implement
309     // glEGLImageTargetTexture2DOES() for all GLES versions.
310     // |p_colorbuffer| is the ColorBuffer's handle value.
311     // Returns true on success, false on failure.
312     bool bindColorBufferToTexture(HandleType p_colorbuffer);
313     bool bindColorBufferToTexture2(HandleType p_colorbuffer);
314 
315     // Bind the current context's EGL_RENDERBUFFER_OES render buffer to this
316     // ColorBuffer's EGLImage. This is intended to implement
317     // glEGLImageTargetRenderbufferStorageOES() for all GLES versions.
318     // |p_colorbuffer| is the ColorBuffer's handle value.
319     // Returns true on success, false on failure.
320     bool bindColorBufferToRenderbuffer(HandleType p_colorbuffer);
321 
322     // Read the content of a given ColorBuffer into client memory.
323     // |p_colorbuffer| is the ColorBuffer's handle value. Similar
324     // to glReadPixels(), this can be a slow operation.
325     // |x|, |y|, |width| and |height| are the position and dimensions of
326     // a rectangle whose pixel values will be transfered to the host.
327     // |format| indicates the format of the pixel data, e.g. GL_RGB or GL_RGBA.
328     // |type| is the type of pixel data, e.g. GL_UNSIGNED_BYTE.
329     // |pixels| is the address of a caller-provided buffer that will be filled
330     // with the pixel data.
331     void readColorBuffer(HandleType p_colorbuffer, int x, int y, int width,
332                          int height, GLenum format, GLenum type, void* pixels);
333 
334     // Read the content of a given YUV420_888 ColorBuffer into client memory.
335     // |p_colorbuffer| is the ColorBuffer's handle value. Similar
336     // to glReadPixels(), this can be a slow operation.
337     // |x|, |y|, |width| and |height| are the position and dimensions of
338     // a rectangle whose pixel values will be transfered to the host.
339     // |pixels| is the address of a caller-provided buffer that will be filled
340     // with the pixel data.
341     // |pixles_size| is the size of buffer
342     void readColorBufferYUV(HandleType p_colorbuffer, int x, int y, int width,
343                             int height, void* pixels, uint32_t pixels_size);
344 
345     // create a Y texture and a UV texture with width and height, the created
346     // texture ids are stored in textures respectively
347     void createYUVTextures(uint32_t type, uint32_t count, int width, int height,
348                            uint32_t* output);
349     void destroyYUVTextures(uint32_t type, uint32_t count, uint32_t* textures);
350     void updateYUVTextures(uint32_t type, uint32_t* textures, void* privData,
351                            void* func);
352     void swapTexturesAndUpdateColorBuffer(uint32_t colorbufferhandle, int x,
353                                           int y, int width, int height,
354                                           uint32_t format, uint32_t type,
355                                           uint32_t texture_type,
356                                           uint32_t* textures);
357 
358     // Update the content of a given ColorBuffer from client data.
359     // |p_colorbuffer| is the ColorBuffer's handle value. Similar
360     // to glReadPixels(), this can be a slow operation.
361     // |x|, |y|, |width| and |height| are the position and dimensions of
362     // a rectangle whose pixel values will be transfered to the GPU
363     // |format| indicates the format of the OpenGL buffer, e.g. GL_RGB or
364     // GL_RGBA. |frameworkFormat| indicates the format of the pixel data; if
365     // FRAMEWORK_FORMAT_GL_COMPATIBLE, |format| (OpenGL format) is used.
366     // Otherwise, explicit conversion to |format| is needed.
367     // |type| is the type of pixel data, e.g. GL_UNSIGNED_BYTE.
368     // |pixels| is the address of a buffer containing the new pixel data.
369     // Returns true on success, false otherwise.
370     bool updateColorBuffer(HandleType p_colorbuffer, int x, int y, int width,
371                            int height, GLenum format, GLenum type,
372                            void* pixels);
373     // Replaces contents completely using the color buffer's current format,
374     // with row length equal to width of a row in bytes.
375     // The number of bytes is passed as a check.
376     bool replaceColorBufferContents(HandleType p_colorbuffer,
377                                     const void* pixels, size_t numBytes);
378     // Reads back the raw color buffer to |pixels|
379     // if |pixels| is not null.
380     // Always returns in |numBytes| how many bytes were
381     // planned to be transmitted.
382     // |numBytes| is not an input parameter;
383     // fewer or more bytes cannot be specified.
384     // If the framework format is YUV, it will read
385     // back as raw YUV data.
386     bool readColorBufferContents(HandleType p_colorbuffer, size_t* numBytes,
387                                  void* pixels);
388 
389     bool getColorBufferInfo(HandleType p_colorbuffer, int* width, int* height,
390                             GLint* internalformat,
391                             FrameworkFormat* frameworkFormat = nullptr);
392     bool getBufferInfo(HandleType p_buffer, int* size);
393 
394     // Display the content of a given ColorBuffer into the framebuffer's
395     // sub-window. |p_colorbuffer| is a handle value.
396     // |needLockAndBind| is used to indicate whether the operation requires
397     // acquiring/releasing the FrameBuffer instance's lock and binding the
398     // contexts. It should be |false| only when called internally.
399     bool post(HandleType p_colorbuffer, bool needLockAndBind = true);
hasGuestPostedAFrame()400     bool hasGuestPostedAFrame() { return m_guestPostedAFrame; }
resetGuestPostedAFrame()401     void resetGuestPostedAFrame() { m_guestPostedAFrame = false; }
402 
403     // Runs the post callback with |pixels| (good for when the readback
404     // happens in a separate place)
405     void doPostCallback(void* pixels, uint32_t displayId);
406 
407     void getPixels(void* pixels, uint32_t bytes, uint32_t displayId);
408     void flushReadPipeline(int displayId);
409     void ensureReadbackWorker();
410 
411     bool asyncReadbackSupported();
412     emugl::Renderer::ReadPixelsCallback getReadPixelsCallback();
413     emugl::Renderer::FlushReadPixelPipeline getFlushReadPixelPipeline();
414 
415     // Re-post the last ColorBuffer that was displayed through post().
416     // This is useful if you detect that the sub-window content needs to
417     // be re-displayed for any reason.
418     bool repost(bool needLockAndBind = true);
419 
420     // Return the host EGLDisplay used by this instance.
getDisplay()421     EGLDisplay getDisplay() const { return m_eglDisplay; }
getWindowSurface()422     EGLSurface getWindowSurface() const { return m_eglSurface; }
getContext()423     EGLContext getContext() const { return m_eglContext; }
getConfig()424     EGLConfig getConfig() const { return m_eglConfig; }
425 
426     // Change the rotation of the displayed GPU sub-window.
setDisplayRotation(float zRot)427     void setDisplayRotation(float zRot) {
428         if (zRot != m_zRot) {
429             m_zRot = zRot;
430             repost();
431         }
432     }
433 
434     // Changes what coordinate of this framebuffer will be displayed at the
435     // corner of the GPU sub-window. Specifically, |px| and |py| = 0 means
436     // align the bottom-left of the framebuffer with the bottom-left of the
437     // sub-window, and |px| and |py| = 1 means align the top right of the
438     // framebuffer with the top right of the sub-window. Intermediate values
439     // interpolate between these states.
setDisplayTranslation(float px,float py)440     void setDisplayTranslation(float px, float py) {
441         // Sanity check the values to ensure they are between 0 and 1
442         const float x = px > 1.f ? 1.f : (px < 0.f ? 0.f : px);
443         const float y = py > 1.f ? 1.f : (py < 0.f ? 0.f : py);
444         if (x != m_px || y != m_py) {
445             m_px = x;
446             m_py = y;
447             repost();
448         }
449     }
450 
451     // Return a TextureDraw instance that can be used with this surfaces
452     // and windows created by this instance.
getTextureDraw()453     TextureDraw* getTextureDraw() const { return m_textureDraw; }
454 
455     // Create an eglImage and return its handle.  Reference:
456     // https://www.khronos.org/registry/egl/extensions/KHR/EGL_KHR_image_base.txt
457     HandleType createClientImage(HandleType context, EGLenum target,
458                                  GLuint buffer);
459     // Call the implementation of eglDestroyImageKHR, return if succeeds or
460     // not. Reference:
461     // https://www.khronos.org/registry/egl/extensions/KHR/EGL_KHR_image_base.txt
462     EGLBoolean destroyClientImage(HandleType image);
463 
464     // Used internally.
465     bool bind_locked();
466     bool unbind_locked();
467 
lockContextStructureRead()468     void lockContextStructureRead() { m_contextStructureLock.lockRead(); }
unlockContextStructureRead()469     void unlockContextStructureRead() { m_contextStructureLock.unlockRead(); }
470 
471     // For use with sync threads and otherwise, any time we need a GL context
472     // not specifically for drawing, but to obtain certain things about
473     // GL state.
474     // It can be unsafe / leaky to change the structure of contexts
475     // outside the facilities the FrameBuffer class provides.
476     void createTrivialContext(HandleType shared, HandleType* contextOut,
477                               HandleType* surfOut);
478     // createAndBindTrivialSharedContext(), but with a m_pbufContext
479     // as shared, and not adding itself to the context map at all.
480     void createAndBindTrivialSharedContext(EGLContext* contextOut,
481                                            EGLSurface* surfOut);
482     void unbindAndDestroyTrivialSharedContext(EGLContext context,
483                                               EGLSurface surf);
484 
setShuttingDown()485     void setShuttingDown() { m_shuttingDown = true; }
isShuttingDown()486     bool isShuttingDown() const { return m_shuttingDown; }
487     bool compose(uint32_t bufferSize, void* buffer, bool post = true);
488 
489     ~FrameBuffer();
490 
491     void onSave(android::base::Stream* stream,
492                 const android::snapshot::ITextureSaverPtr& textureSaver);
493     bool onLoad(android::base::Stream* stream,
494                 const android::snapshot::ITextureLoaderPtr& textureLoader);
495 
496     // lock and unlock handles (RenderContext, ColorBuffer, WindowSurface)
497     void lock();
498     void unlock();
499 
500     static void setMaxGLESVersion(GLESDispatchMaxVersion version);
501     static GLESDispatchMaxVersion getMaxGLESVersion();
502 
getDpr()503     float getDpr() const { return m_dpr; }
windowWidth()504     int windowWidth() const { return m_windowWidth; }
windowHeight()505     int windowHeight() const { return m_windowHeight; }
getPx()506     float getPx() const { return m_px; }
getPy()507     float getPy() const { return m_py; }
getZrot()508     int getZrot() const { return m_zRot; }
509 
isFastBlitSupported()510     bool isFastBlitSupported() const { return m_fastBlitSupported; }
isVulkanInteropSupported()511     bool isVulkanInteropSupported() const { return m_vulkanInteropSupported; }
512     bool importMemoryToColorBuffer(
513 #ifdef _WIN32
514         void* handle,
515 #else
516         int handle,
517 #endif
518         uint64_t size, bool dedicated, bool linearTiling, bool vulkanOnly,
519         uint32_t colorBufferHandle, VkImage, VkFormat);
520     void setColorBufferInUse(uint32_t colorBufferHandle, bool inUse);
521 
522     // Used during tests to disable fast blit.
523     void disableFastBlit();
524 
525     // Fill GLES usage protobuf
526     void fillGLESUsages(android_studio::EmulatorGLESUsages*);
527     // Save a screenshot of the previous frame.
528     // nChannels should be 3 (RGB) or 4 (RGBA).
529     // Note: swiftshader_indirect does not work with 3 channels
530     void getScreenshot(unsigned int nChannels, unsigned int* width,
531                        unsigned int* height, std::vector<unsigned char>& pixels,
532                        int displayId, int desiredWidth, int desiredHeight,
533                        int desiredRotation);
534     void onLastColorBufferRef(uint32_t handle);
getColorBufferHelper()535     ColorBuffer::Helper* getColorBufferHelper() { return m_colorBufferHelper; }
536     ColorBufferPtr findColorBuffer(HandleType p_colorbuffer);
537 
538     void registerProcessCleanupCallback(void* key,
539                                         std::function<void()> callback);
540     void unregisterProcessCleanupCallback(void* key);
541 
542     void registerProcessSequenceNumberForPuid(uint64_t puid);
543     uint32_t* getProcessSequenceNumberPtr(uint64_t puid);
544 
545     int createDisplay(uint32_t *displayId);
546     int createDisplay(uint32_t displayId);
547     int destroyDisplay(uint32_t displayId);
548     int setDisplayColorBuffer(uint32_t displayId, uint32_t colorBuffer);
549     int getDisplayColorBuffer(uint32_t displayId, uint32_t* colorBuffer);
550     int getColorBufferDisplay(uint32_t colorBuffer, uint32_t* displayId);
551     int getDisplayPose(uint32_t displayId, int32_t* x, int32_t* y, uint32_t* w,
552                        uint32_t* h);
553     int setDisplayPose(uint32_t displayId, int32_t x, int32_t y, uint32_t w,
554                        uint32_t h, uint32_t dpi = 0);
555     void getCombinedDisplaySize(int* w, int* h);
556     struct DisplayInfo {
557         uint32_t cb;
558         int32_t pos_x;
559         int32_t pos_y;
560         uint32_t width;
561         uint32_t height;
562         uint32_t dpi;
DisplayInfoDisplayInfo563         DisplayInfo()
564             : cb(0), pos_x(0), pos_y(0), width(0), height(0), dpi(0){};
DisplayInfoDisplayInfo565         DisplayInfo(uint32_t cb, int32_t x, int32_t y, uint32_t w, uint32_t h,
566                     uint32_t d)
567             : cb(cb), pos_x(x), pos_y(y), width(w), height(h), dpi(d) {}
568     };
569     // Inline with MultiDisplay::s_invalidIdMultiDisplay
570     static const uint32_t s_invalidIdMultiDisplay = 0xFFFFFFAB;
571     static const uint32_t s_maxNumMultiDisplay = 11;
572 
getGlobalEGLContext()573     EGLContext getGlobalEGLContext() { return m_pbufContext; }
getLastPostedColorBuffer()574     HandleType getLastPostedColorBuffer() { return m_lastPostedColorBuffer; }
575     void waitForGpu(uint64_t eglsync);
576     void waitForGpuVulkan(uint64_t deviceHandle, uint64_t fenceHandle);
577 
578     void setGuestManagedColorBufferLifetime(bool guestManaged);
579 
580     VkImageLayout getVkImageLayoutForPresent() const;
581 
582    private:
583     FrameBuffer(int p_width, int p_height, bool useSubWindow);
584     HandleType genHandle_locked();
585 
586     bool bindSubwin_locked();
587     bool bindFakeWindow_locked();
588     bool removeSubWindow_locked();
589     // Returns the set of ColorBuffers destroyed (for further cleanup)
590     std::vector<HandleType> cleanupProcGLObjects_locked(uint64_t puid,
591                                                         bool forced = false);
592 
593     void markOpened(ColorBufferRef* cbRef);
594     // Returns true if the color buffer was erased.
595     bool closeColorBufferLocked(HandleType p_colorbuffer, bool forced = false);
596     // Returns true if this was the last ref and we need to destroy stuff.
597     bool decColorBufferRefCountLocked(HandleType p_colorbuffer);
598     // Close all expired color buffers for real.
599     // Treat all delayed color buffers as expired if forced=true
600     void performDelayedColorBufferCloseLocked(bool forced = false);
601     void eraseDelayedCloseColorBufferLocked(HandleType cb, uint64_t ts);
602 
603     bool postImpl(HandleType p_colorbuffer, bool needLockAndBind = true,
604                   bool repaint = false);
setGuestPostedAFrame()605     void setGuestPostedAFrame() { m_guestPostedAFrame = true; }
606     HandleType createColorBufferLocked(int p_width, int p_height,
607                                        GLenum p_internalFormat,
608                                        FrameworkFormat p_frameworkFormat);
609     HandleType createColorBufferWithHandleLocked(
610         int p_width, int p_height, GLenum p_internalFormat,
611         FrameworkFormat p_frameworkFormat, HandleType handle);
612     HandleType createBufferLocked(int p_size);
613     HandleType createBufferWithHandleLocked(int p_size, HandleType handle);
614 
615     void recomputeLayout();
616     void setDisplayPoseInSkinUI(int totalHeight);
617     void sweepColorBuffersLocked();
618 
619    private:
620     static FrameBuffer* s_theFrameBuffer;
621     static HandleType s_nextHandle;
622     int m_x = 0;
623     int m_y = 0;
624     int m_framebufferWidth = 0;
625     int m_framebufferHeight = 0;
626     int m_windowWidth = 0;
627     int m_windowHeight = 0;
628     float m_dpr = 0;
629 
630     bool m_useSubWindow = false;
631     bool m_eglContextInitialized = false;
632 
633     bool m_fpsStats = false;
634     bool m_perfStats = false;
635     int m_statsNumFrames = 0;
636     long long m_statsStartTime = 0;
637 
638     android::base::Thread* m_perfThread;
639     android::base::Lock m_lock;
640     android::base::ReadWriteLock m_contextStructureLock;
641     FbConfigList* m_configs = nullptr;
642     FBNativeWindowType m_nativeWindow = 0;
643     FrameBufferCaps m_caps = {};
644     EGLDisplay m_eglDisplay = EGL_NO_DISPLAY;
645     RenderContextMap m_contexts;
646     WindowSurfaceMap m_windows;
647     ColorBufferMap m_colorbuffers;
648     BufferMap m_buffers;
649     std::unordered_map<HandleType, HandleType> m_windowSurfaceToColorBuffer;
650 
651     // A collection of color buffers that were closed without any usages
652     // (|opened| == false).
653     //
654     // If a buffer reached |refcount| == 0 while not being |opened|, instead of
655     // deleting it we remember the timestamp when this happened. Later, we
656     // check if the buffer stayed unopened long enough and if it did, we delete
657     // it permanently. On the other hand, if the color buffer was used then
658     // we don't care about timestamps anymore.
659     //
660     // Note: this collection is ordered by |ts| field.
661     struct ColorBufferCloseInfo {
662         uint64_t ts;          // when we got the close request.
663         HandleType cbHandle;  // 0 == already closed, do nothing
664     };
665     using ColorBufferDelayedClose = std::vector<ColorBufferCloseInfo>;
666     ColorBufferDelayedClose m_colorBufferDelayedCloseList;
667 
668     ColorBuffer::Helper* m_colorBufferHelper = nullptr;
669 
670     EGLSurface m_eglSurface = EGL_NO_SURFACE;
671     EGLContext m_eglContext = EGL_NO_CONTEXT;
672     EGLSurface m_pbufSurface = EGL_NO_SURFACE;
673     EGLContext m_pbufContext = EGL_NO_CONTEXT;
674 
675     EGLSurface m_eglFakeWindowSurface = EGL_NO_SURFACE;
676     EGLContext m_eglFakeWindowContext = EGL_NO_CONTEXT;
677 
678     EGLContext m_prevContext = EGL_NO_CONTEXT;
679     EGLSurface m_prevReadSurf = EGL_NO_SURFACE;
680     EGLSurface m_prevDrawSurf = EGL_NO_SURFACE;
681     EGLNativeWindowType m_subWin = {};
682     TextureDraw* m_textureDraw = nullptr;
683     EGLConfig m_eglConfig = nullptr;
684     HandleType m_lastPostedColorBuffer = 0;
685     // With Vulkan swapchain, compose also means to post to the WSI surface.
686     // In this case, don't do anything in the subsequent resource flush.
687     bool m_justVkComposed = false;
688     float m_zRot = 0;
689     float m_px = 0;
690     float m_py = 0;
691 
692     // Async readback
693     enum class ReadbackCmd {
694         Init = 0,
695         GetPixels = 1,
696         AddRecordDisplay = 2,
697         DelRecordDisplay = 3,
698         Exit = 4,
699     };
700     struct Readback {
701         ReadbackCmd cmd;
702         uint32_t displayId;
703         GLuint bufferId;
704         void* pixelsOut;
705         uint32_t bytes;
706         uint32_t width;
707         uint32_t height;
708     };
709     android::base::WorkerProcessingResult sendReadbackWorkerCmd(
710         const Readback& readback);
711     bool m_asyncReadbackSupported = true;
712     bool m_guestPostedAFrame = false;
713 
714     struct onPost {
715         emugl::Renderer::OnPostCallback cb;
716         void* context;
717         uint32_t displayId;
718         uint32_t width;
719         uint32_t height;
720         unsigned char* img = nullptr;
721         bool readBgra;
~onPostonPost722         ~onPost() {
723             if (img) {
724                 delete[] img;
725                 img = nullptr;
726             }
727         }
728     };
729     std::map<uint32_t, onPost> m_onPost;
730     std::unique_ptr<ReadbackWorker> m_readbackWorker;
731     android::base::WorkerThread<Readback> m_readbackThread;
732 
733     std::string m_glVendor;
734     std::string m_glRenderer;
735     std::string m_glVersion;
736 
737     // The host associates color buffers with guest processes for memory
738     // cleanup. Guest processes are identified with a host generated unique ID.
739     ProcOwnedWindowSurfaces m_procOwnedWindowSurfaces;
740     ProcOwnedColorBuffers m_procOwnedColorBuffers;
741     ProcOwnedEGLImages m_procOwnedEGLImages;
742     ProcOwnedRenderContexts m_procOwnedRenderContext;
743     ProcOwnedCleanupCallbacks m_procOwnedCleanupCallbacks;
744     ProcOwnedSequenceNumbers m_procOwnedSequenceNumbers;
745 
746     // Flag set when emulator is shutting down.
747     bool m_shuttingDown = false;
748 
749     // When this feature is enabled, open/close operations from gralloc in guest
750     // will no longer control the reference counting of color buffers on host.
751     // Instead, it will be managed by a file descriptor in the guest kernel. In
752     // case all the native handles in guest are destroyed, the pipe will be
753     // automatically closed by the kernel. We only need to do reference counting
754     // for color buffers attached in window surface.
755     bool m_refCountPipeEnabled = false;
756 
757     // When this feature is enabled, and m_refCountPipeEnabled == false, color
758     // buffer close operations will immediately close the color buffer if host
759     // refcount hits 0. This is for use with guest kernels where the color
760     // buffer is already tied to a file descriptor in the guest kernel.
761     bool m_noDelayCloseColorBufferEnabled = false;
762 
763     std::unique_ptr<PostWorker> m_postWorker = {};
764     android::base::WorkerThread<Post> m_postThread;
765     android::base::WorkerProcessingResult postWorkerFunc(const Post& post);
766     void sendPostWorkerCmd(Post post);
767 
768     bool m_fastBlitSupported = false;
769     bool m_vulkanInteropSupported = false;
770     bool m_guestUsesAngle = false;
771     // Whether the guest manages ColorBuffer lifetime
772     // so we don't need refcounting on the host side.
773     bool m_guestManagedColorBufferLifetime = false;
774 
775     android::base::MessageChannel<HandleType, 1024>
776         mOutstandingColorBufferDestroys;
777 
778     // The implementation for Vulkan native swapchain. Only initialized when
779     // useVulkan is set when calling FrameBuffer::initialize().
780     std::unique_ptr<DisplayVk> m_displayVk;
781     VkInstance m_vkInstance = VK_NULL_HANDLE;
782     VkSurfaceKHR m_vkSurface = VK_NULL_HANDLE;
783 };
784 #endif
785