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