• 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 <stdint.h>
20 
21 #include <array>
22 #include <functional>
23 #include <map>
24 #include <memory>
25 #include <optional>
26 #include <unordered_map>
27 #include <unordered_set>
28 
29 #include "Buffer.h"
30 #include "ColorBuffer.h"
31 #include "Compositor.h"
32 #include "Display.h"
33 #include "DisplaySurface.h"
34 #include "Hwc2.h"
35 #include "PostCommands.h"
36 #include "PostWorker.h"
37 #include "ProcessResources.h"
38 #include "ReadbackWorker.h"
39 #include "VsyncThread.h"
40 #include "aemu/base/AsyncResult.h"
41 #include "aemu/base/EventNotificationSupport.h"
42 #include "aemu/base/HealthMonitor.h"
43 #include "aemu/base/ManagedDescriptor.hpp"
44 #include "aemu/base/Metrics.h"
45 #include "aemu/base/files/Stream.h"
46 #include "aemu/base/synchronization/Lock.h"
47 #include "aemu/base/synchronization/MessageChannel.h"
48 #include "aemu/base/threads/Thread.h"
49 #include "aemu/base/threads/WorkerThread.h"
50 
51 #if GFXSTREAM_ENABLE_HOST_GLES
52 
53 #include <EGL/egl.h>
54 #include <GLES2/gl2.h>
55 #include <GLES2/gl2ext.h>
56 
57 #include "gl/BufferGl.h"
58 #include "gl/ColorBufferGl.h"
59 #include "gl/CompositorGl.h"
60 #include "gl/DisplaySurfaceGl.h"
61 #include "gl/EmulatedEglConfig.h"
62 #include "gl/EmulatedEglContext.h"
63 #include "gl/EmulatedEglImage.h"
64 #include "gl/EmulatedEglWindowSurface.h"
65 #include "gl/EmulationGl.h"
66 #include "gl/GLESVersionDetector.h"
67 #include "gl/TextureDraw.h"
68 #else
69 #include "GlesCompat.h"
70 #endif
71 
72 // values for 'param' argument of rcGetFBParam
73 #define FB_WIDTH 1
74 #define FB_HEIGHT 2
75 #define FB_XDPI 3
76 #define FB_YDPI 4
77 #define FB_FPS 5
78 #define FB_MIN_SWAP_INTERVAL 6
79 #define FB_MAX_SWAP_INTERVAL 7
80 
81 #include "render-utils/Renderer.h"
82 #include "render-utils/virtio_gpu_ops.h"
83 #include "render-utils/render_api.h"
84 #include "snapshot/common.h"
85 #include "utils/RenderDoc.h"
86 #include "vulkan/vk_util.h"
87 
88 namespace gfxstream {
89 namespace vk {
90 class DisplayVk;
91 }  // namespace vk
92 }  // namespace gfxstream
93 
94 namespace gfxstream {
95 
96 using android::base::CreateMetricsLogger;
97 using emugl::HealthMonitor;
98 using emugl::MetricsLogger;
99 
100 struct BufferRef {
101     BufferPtr buffer;
102 };
103 
104 #if GFXSTREAM_ENABLE_HOST_GLES
105 typedef std::unordered_map<uint64_t, gl::EmulatedEglWindowSurfaceSet>
106     ProcOwnedEmulatedEglWindowSurfaces;
107 
108 typedef std::unordered_map<uint64_t, gl::EmulatedEglContextSet> ProcOwnedEmulatedEglContexts;
109 typedef std::unordered_map<uint64_t, gl::EmulatedEglImageSet> ProcOwnedEmulatedEGLImages;
110 #endif
111 
112 typedef std::unordered_map<uint64_t, ColorBufferSet> ProcOwnedColorBuffers;
113 
114 typedef std::unordered_map<HandleType, BufferRef> BufferMap;
115 typedef std::unordered_multiset<HandleType> BufferSet;
116 typedef std::unordered_map<uint64_t, BufferSet> ProcOwnedBuffers;
117 
118 typedef std::unordered_map<void*, std::function<void()>> CallbackMap;
119 typedef std::unordered_map<uint64_t, CallbackMap> ProcOwnedCleanupCallbacks;
120 
121 // The FrameBuffer class holds the global state of the emulation library on
122 // top of the underlying EGL/GLES implementation. It should probably be
123 // named "Display" instead of "FrameBuffer".
124 //
125 // There is only one global instance, that can be retrieved with getFB(),
126 // and which must be previously setup by calling initialize().
127 //
128 class FrameBuffer : public android::base::EventNotificationSupport<FrameBufferChangeEvent> {
129    public:
130     // Initialize the global instance.
131     // |width| and |height| are the dimensions of the emulator GPU display
132     // in pixels. |useSubWindow| is true to indicate that the caller
133     // will use setupSubWindow() to let EmuGL display the GPU content in its
134     // own sub-windows. If false, this means the caller will use
135     // setPostCallback() instead to retrieve the content.
136     // Returns true on success, false otherwise.
137     static bool initialize(int width, int height, bool useSubWindow,
138                            bool egl2egl);
139 
140     // Finalize the instance.
141     static void finalize();
142 
143     // Setup a sub-window to display the content of the emulated GPU
144     // on-top of an existing UI window. |p_window| is the platform-specific
145     // parent window handle. |wx|, |wy|, |ww| and |wh| are the
146     // dimensions in pixels of the sub-window, relative to the parent window's
147     // coordinate. |fbw| and |fbh| are the dimensions used to initialize
148     // the framebuffer, which may be different from the dimensions of the
149     // sub-window (in which case scaling will be applied automatically).
150     // |dpr| is the device pixel ratio of the monitor, which is needed for
151     // proper panning on high-density displays (like retina)
152     // |zRot| is a rotation angle in degrees, (clockwise in the Y-upwards GL
153     // coordinate space).
154     //
155     // If a sub-window already exists, this function updates the subwindow
156     // and framebuffer properties to match the given values.
157     //
158     // Return true on success, false otherwise.
159     //
160     // NOTE: This can return false for software-only EGL engines like OSMesa.
161     bool setupSubWindow(FBNativeWindowType p_window, int wx, int wy, int ww,
162                         int wh, int fbw, int fbh, float dpr, float zRot,
163                         bool deleteExisting, bool hideWindow);
164 
165     // Remove the sub-window created by setupSubWindow(), if any.
166     // Return true on success, false otherwise.
167     bool removeSubWindow();
168 
169     // Return a pointer to the global instance. initialize() must be called
170     // previously, or this will return NULL.
getFB()171     static FrameBuffer* getFB() { return s_theFrameBuffer; }
172 
173     // Wait for a FrameBuffer instance to be initialized and ready to use.
174     // This function blocks the caller until there is a valid initialized
175     // object in getFB() and
176     static void waitUntilInitialized();
177 
178     // Return the emulated GPU display width in pixels.
getWidth()179     int getWidth() const { return m_framebufferWidth; }
180 
181     // Return the emulated GPU display height in pixels.
getHeight()182     int getHeight() const { return m_framebufferHeight; }
183 
184     // Set a callback that will be called each time the emulated GPU content
185     // is updated. This can be relatively slow with host-based GPU emulation,
186     // so only do this when you need to.
187     void setPostCallback(Renderer::OnPostCallback onPost, void* onPostContext, uint32_t displayId,
188                          bool useBgraReadback = false);
189 
190     // Create a new ColorBuffer instance from this display instance.
191     // |p_width| and |p_height| are its dimensions in pixels.
192     // |p_internalFormat| is the OpenGL format of this color buffer.
193     // |p_frameworkFormat| describes the Android frameework format of this
194     // color buffer, if differing from |p_internalFormat|.
195     // See ColorBuffer::create() for
196     // list of valid values. Note that ColorBuffer instances are reference-
197     // counted. Use openColorBuffer / closeColorBuffer to operate on the
198     // internal count.
199     HandleType createColorBuffer(int p_width, int p_height,
200                                  GLenum p_internalFormat,
201                                  FrameworkFormat p_frameworkFormat);
202     // Variant of createColorBuffer except with a particular
203     // handle already assigned. This is for use with
204     // virtio-gpu's RESOURCE_CREATE ioctl.
205     void createColorBufferWithHandle(int p_width, int p_height, GLenum p_internalFormat,
206                                      FrameworkFormat p_frameworkFormat, HandleType handle);
207 
208     // Create a new data Buffer instance from this display instance.
209     // The buffer will be backed by a VkBuffer and VkDeviceMemory (if Vulkan
210     // is available).
211     // |size| is the requested size of Buffer in bytes.
212     // |memoryProperty| is the requested memory property bits of the device
213     // memory.
214     HandleType createBuffer(uint64_t size, uint32_t memoryProperty);
215 
216     // Variant of createBuffer except with a particular handle already
217     // assigned and using device local memory. This is for use with
218     // virtio-gpu's RESOURCE_CREATE ioctl for BLOB resources.
219     void createBufferWithHandle(uint64_t size, HandleType handle);
220 
221     // Increment the reference count associated with a given ColorBuffer
222     // instance. |p_colorbuffer| is its handle value as returned by
223     // createColorBuffer().
224     int openColorBuffer(HandleType p_colorbuffer);
225 
226     // Decrement the reference count associated with a given ColorBuffer
227     // instance. |p_colorbuffer| is its handle value as returned by
228     // createColorBuffer(). Note that if the reference count reaches 0,
229     // the instance is destroyed automatically.
230     void closeColorBuffer(HandleType p_colorbuffer);
231 
232     // Destroy a Buffer created previously. |p_buffer| is its handle value as
233     // returned by createBuffer().
234     void closeBuffer(HandleType p_colorbuffer);
235 
236     // The caller mustn't refer to this puid before this function returns, i.e. the creation of the
237     // host process pipe must be blocked until this function returns.
238     void createGraphicsProcessResources(uint64_t puid);
239     // The process resource is returned so that we can destroy it on a separate thread.
240     std::unique_ptr<ProcessResources> removeGraphicsProcessResources(uint64_t puid);
241     // TODO(kaiyili): retire cleanupProcGLObjects in favor of removeGraphicsProcessResources.
242     void cleanupProcGLObjects(uint64_t puid);
243 
244     // Read the content of a given Buffer into client memory.
245     // |p_buffer| is the Buffer's handle value.
246     // |offset| and |size| are the position and size of a slice of the buffer
247     // that will be read.
248     // |bytes| is the address of a caller-provided buffer that will be filled
249     // with the buffer data.
250     void readBuffer(HandleType p_buffer, uint64_t offset, uint64_t size, void* bytes);
251 
252     // Read the content of a given ColorBuffer into client memory.
253     // |p_colorbuffer| is the ColorBuffer's handle value. Similar
254     // to glReadPixels(), this can be a slow operation.
255     // |x|, |y|, |width| and |height| are the position and dimensions of
256     // a rectangle whose pixel values will be transfered to the host.
257     // |format| indicates the format of the pixel data, e.g. GL_RGB or GL_RGBA.
258     // |type| is the type of pixel data, e.g. GL_UNSIGNED_BYTE.
259     // |pixels| is the address of a caller-provided buffer that will be filled
260     // with the pixel data.
261     void readColorBuffer(HandleType p_colorbuffer, int x, int y, int width,
262                          int height, GLenum format, GLenum type, void* pixels);
263 
264     // Read the content of a given YUV420_888 ColorBuffer into client memory.
265     // |p_colorbuffer| is the ColorBuffer's handle value. Similar
266     // to glReadPixels(), this can be a slow operation.
267     // |x|, |y|, |width| and |height| are the position and dimensions of
268     // a rectangle whose pixel values will be transfered to the host.
269     // |pixels| is the address of a caller-provided buffer that will be filled
270     // with the pixel data.
271     // |pixles_size| is the size of buffer
272     void readColorBufferYUV(HandleType p_colorbuffer, int x, int y, int width,
273                             int height, void* pixels, uint32_t pixels_size);
274 
275     // Update the content of a given Buffer from client data.
276     // |p_buffer| is the Buffer's handle value.
277     // |offset| and |size| are the position and size of a slice of the buffer
278     // that will be updated.
279     // |bytes| is the address of a caller-provided buffer containing the new
280     // buffer data.
281     bool updateBuffer(HandleType p_buffer, uint64_t offset, uint64_t size, void* pixels);
282 
283     // Update the content of a given ColorBuffer from client data.
284     // |p_colorbuffer| is the ColorBuffer's handle value. Similar
285     // to glReadPixels(), this can be a slow operation.
286     // |x|, |y|, |width| and |height| are the position and dimensions of
287     // a rectangle whose pixel values will be transfered to the GPU
288     // |format| indicates the format of the OpenGL buffer, e.g. GL_RGB or
289     // GL_RGBA. |frameworkFormat| indicates the format of the pixel data; if
290     // FRAMEWORK_FORMAT_GL_COMPATIBLE, |format| (OpenGL format) is used.
291     // Otherwise, explicit conversion to |format| is needed.
292     // |type| is the type of pixel data, e.g. GL_UNSIGNED_BYTE.
293     // |pixels| is the address of a buffer containing the new pixel data.
294     // Returns true on success, false otherwise.
295     bool updateColorBuffer(HandleType p_colorbuffer, int x, int y, int width,
296                            int height, GLenum format, GLenum type,
297                            void* pixels);
298     bool updateColorBufferFromFrameworkFormat(HandleType p_colorbuffer, int x, int y, int width,
299                                               int height, FrameworkFormat fwkFormat, GLenum format,
300                                               GLenum type, void* pixels, void* metadata = nullptr);
301 
302     bool getColorBufferInfo(HandleType p_colorbuffer, int* width, int* height,
303                             GLint* internalformat,
304                             FrameworkFormat* frameworkFormat = nullptr);
305     bool getBufferInfo(HandleType p_buffer, int* size);
306 
307     // Display the content of a given ColorBuffer into the framebuffer's
308     // sub-window. |p_colorbuffer| is a handle value.
309     // |needLockAndBind| is used to indicate whether the operation requires
310     // acquiring/releasing the FrameBuffer instance's lock and binding the
311     // contexts. It should be |false| only when called internally.
312     bool post(HandleType p_colorbuffer, bool needLockAndBind = true);
313     // The callback will always be called; however, the callback may not be called
314     // until after this function has returned. If the callback is deferred, then it
315     // will be dispatched to run on SyncThread.
316     void postWithCallback(HandleType p_colorbuffer, Post::CompletionCallback callback, bool needLockAndBind = true);
hasGuestPostedAFrame()317     bool hasGuestPostedAFrame() { return m_guestPostedAFrame; }
resetGuestPostedAFrame()318     void resetGuestPostedAFrame() { m_guestPostedAFrame = false; }
319 
320     // Runs the post callback with |pixels| (good for when the readback
321     // happens in a separate place)
322     void doPostCallback(void* pixels, uint32_t displayId);
323 
324     void getPixels(void* pixels, uint32_t bytes, uint32_t displayId);
325     void flushReadPipeline(int displayId);
326     void ensureReadbackWorker();
327 
328     bool asyncReadbackSupported();
329     Renderer::ReadPixelsCallback getReadPixelsCallback();
330     Renderer::FlushReadPixelPipeline getFlushReadPixelPipeline();
331 
332     // Re-post the last ColorBuffer that was displayed through post().
333     // This is useful if you detect that the sub-window content needs to
334     // be re-displayed for any reason.
335     bool repost(bool needLockAndBind = true);
336 
337     // Change the rotation of the displayed GPU sub-window.
setDisplayRotation(float zRot)338     void setDisplayRotation(float zRot) {
339         if (zRot != m_zRot) {
340             m_zRot = zRot;
341             repost();
342         }
343     }
344 
345     // Changes what coordinate of this framebuffer will be displayed at the
346     // corner of the GPU sub-window. Specifically, |px| and |py| = 0 means
347     // align the bottom-left of the framebuffer with the bottom-left of the
348     // sub-window, and |px| and |py| = 1 means align the top right of the
349     // framebuffer with the top right of the sub-window. Intermediate values
350     // interpolate between these states.
setDisplayTranslation(float px,float py)351     void setDisplayTranslation(float px, float py) {
352         // Sanity check the values to ensure they are between 0 and 1
353         const float x = px > 1.f ? 1.f : (px < 0.f ? 0.f : px);
354         const float y = py > 1.f ? 1.f : (py < 0.f ? 0.f : py);
355         if (x != m_px || y != m_py) {
356             m_px = x;
357             m_py = y;
358             repost();
359         }
360     }
361 
lockContextStructureRead()362     void lockContextStructureRead() { m_contextStructureLock.lockRead(); }
unlockContextStructureRead()363     void unlockContextStructureRead() { m_contextStructureLock.unlockRead(); }
364 
365     // For use with sync threads and otherwise, any time we need a GL context
366     // not specifically for drawing, but to obtain certain things about
367     // GL state.
368     // It can be unsafe / leaky to change the structure of contexts
369     // outside the facilities the FrameBuffer class provides.
370     void createTrivialContext(HandleType shared, HandleType* contextOut, HandleType* surfOut);
371 
setShuttingDown()372     void setShuttingDown() { m_shuttingDown = true; }
isShuttingDown()373     bool isShuttingDown() const { return m_shuttingDown; }
374     bool compose(uint32_t bufferSize, void* buffer, bool post = true);
375     // When false is returned, the callback won't be called. The callback will
376     // be called on the PostWorker thread without blocking the current thread.
377     AsyncResult composeWithCallback(uint32_t bufferSize, void* buffer,
378                              Post::CompletionCallback callback);
379 
380     ~FrameBuffer();
381 
382     void onSave(android::base::Stream* stream,
383                 const android::snapshot::ITextureSaverPtr& textureSaver);
384     bool onLoad(android::base::Stream* stream,
385                 const android::snapshot::ITextureLoaderPtr& textureLoader);
386 
387     // lock and unlock handles (EmulatedEglContext, ColorBuffer, EmulatedEglWindowSurface)
388     void lock();
389     void unlock();
390 
getDpr()391     float getDpr() const { return m_dpr; }
windowWidth()392     int windowWidth() const { return m_windowWidth; }
windowHeight()393     int windowHeight() const { return m_windowHeight; }
getPx()394     float getPx() const { return m_px; }
getPy()395     float getPy() const { return m_py; }
getZrot()396     int getZrot() const { return m_zRot; }
397 
isVulkanInteropSupported()398     bool isVulkanInteropSupported() const { return m_vulkanInteropSupported; }
isVulkanEnabled()399     bool isVulkanEnabled() const { return m_vulkanEnabled; }
400 
401     // Saves a screenshot of the previous frame.
402     // nChannels should be 3 (RGB) or 4 (RGBA).
403     // You must provide a pre-allocated buffer of sufficient
404     // size. Returns 0 on success. In the case of failure and if *cPixels != 0
405     // you can call this function again with a buffer of size *cPixels. cPixels
406     // should usually be at at least desiredWidth * desiredHeight * nChannels.
407     //
408     // In practice the buffer should be > desiredWidth *
409     // desiredHeight * nChannels.
410     //
411     // Note: Do not call this function again if it fails and *cPixels == 0
412     //  swiftshader_indirect does not work with 3 channels
413     //
414     // This function supports rectangle snipping by
415     // providing an |rect| parameter. The default value of {{0,0}, {0,0}}
416     // indicates the users wants to snip the entire screen instead of a
417     // partial screen.
418     // - |rect|  represents a rectangle within the screen defined by
419     // desiredWidth and desiredHeight.
420     int getScreenshot(unsigned int nChannels, unsigned int* width, unsigned int* height,
421                       uint8_t* pixels, size_t* cPixels, int displayId, int desiredWidth,
422                       int desiredHeight, int desiredRotation, Rect rect = {{0, 0}, {0, 0}});
423 
424     void onLastColorBufferRef(uint32_t handle);
425     ColorBufferPtr findColorBuffer(HandleType p_colorbuffer);
426     BufferPtr findBuffer(HandleType p_buffer);
427 
428     void registerProcessCleanupCallback(void* key,
429                                         std::function<void()> callback);
430     void unregisterProcessCleanupCallback(void* key);
431 
432     const ProcessResources* getProcessResources(uint64_t puid);
433 
434     int createDisplay(uint32_t *displayId);
435     int createDisplay(uint32_t displayId);
436     int destroyDisplay(uint32_t displayId);
437     int setDisplayColorBuffer(uint32_t displayId, uint32_t colorBuffer);
438     int getDisplayColorBuffer(uint32_t displayId, uint32_t* colorBuffer);
439     int getColorBufferDisplay(uint32_t colorBuffer, uint32_t* displayId);
440     int getDisplayPose(uint32_t displayId, int32_t* x, int32_t* y, uint32_t* w,
441                        uint32_t* h);
442     int setDisplayPose(uint32_t displayId, int32_t x, int32_t y, uint32_t w,
443                        uint32_t h, uint32_t dpi = 0);
444     void getCombinedDisplaySize(int* w, int* h);
445     struct DisplayInfo {
446         uint32_t cb;
447         int32_t pos_x;
448         int32_t pos_y;
449         uint32_t width;
450         uint32_t height;
451         uint32_t dpi;
DisplayInfoDisplayInfo452         DisplayInfo()
453             : cb(0), pos_x(0), pos_y(0), width(0), height(0), dpi(0){};
DisplayInfoDisplayInfo454         DisplayInfo(uint32_t cb, int32_t x, int32_t y, uint32_t w, uint32_t h,
455                     uint32_t d)
456             : cb(cb), pos_x(x), pos_y(y), width(w), height(h), dpi(d) {}
457     };
458     // Inline with MultiDisplay::s_invalidIdMultiDisplay
459     static const uint32_t s_invalidIdMultiDisplay = 0xFFFFFFAB;
460     static const uint32_t s_maxNumMultiDisplay = 11;
461 
getLastPostedColorBuffer()462     HandleType getLastPostedColorBuffer() { return m_lastPostedColorBuffer; }
463     void waitForGpuVulkan(uint64_t deviceHandle, uint64_t fenceHandle);
464     void asyncWaitForGpuVulkanWithCb(uint64_t deviceHandle, uint64_t fenceHandle, FenceCompletionCallback cb);
465     void asyncWaitForGpuVulkanQsriWithCb(uint64_t image, FenceCompletionCallback cb);
466     void waitForGpuVulkanQsri(uint64_t image);
467 
468     bool platformImportResource(uint32_t handle, uint32_t info, void* resource);
469 
470     void setGuestManagedColorBufferLifetime(bool guestManaged);
471 
472     std::unique_ptr<BorrowedImageInfo> borrowColorBufferForComposition(uint32_t colorBufferHandle,
473                                                                        bool colorBufferIsTarget);
474     std::unique_ptr<BorrowedImageInfo> borrowColorBufferForDisplay(uint32_t colorBufferHandle);
475 
getHealthMonitor()476     HealthMonitor<>* getHealthMonitor() { return m_healthMonitor.get(); }
477 
getMetricsLogger()478     emugl::MetricsLogger& getMetricsLogger() {
479         return *m_logger;
480     }
481 
482     void logVulkanOutOfMemory(VkResult result, const char* function, int line,
483                               std::optional<uint64_t> allocationSize = std::nullopt);
484 
485     void setVsyncHz(int vsyncHz);
486     void scheduleVsyncTask(VsyncThread::VsyncTask task);
487     void setDisplayConfigs(int configId, int w, int h, int dpiX, int dpiY);
488     void setDisplayActiveConfig(int configId);
489     const int getDisplayConfigsCount();
490     const int getDisplayConfigsParam(int configId, EGLint param);
491     const int getDisplayActiveConfig();
492 
493     bool flushColorBufferFromVk(HandleType colorBufferHandle);
494     bool flushColorBufferFromVkBytes(HandleType colorBufferHandle, const void* bytes,
495                                      size_t bytesSize);
496     bool invalidateColorBufferForVk(HandleType colorBufferHandle);
497 
498 #if GFXSTREAM_ENABLE_HOST_GLES
499     // Retrieves the color buffer handle associated with |p_surface|.
500     // Returns 0 if there is no such handle.
501     HandleType getEmulatedEglWindowSurfaceColorBufferHandle(HandleType p_surface);
502 
503     // createTrivialContext(), but with a m_pbufContext
504     // as shared, and not adding itself to the context map at all.
505     void createSharedTrivialContext(EGLContext* contextOut, EGLSurface* surfOut);
506     void destroySharedTrivialContext(EGLContext context, EGLSurface surf);
507 
508     // Attach a ColorBuffer to a EmulatedEglWindowSurface instance.
509     // See the documentation for EmulatedEglWindowSurface::setColorBuffer().
510     // |p_surface| is the target EmulatedEglWindowSurface's handle value.
511     // |p_colorbuffer| is the ColorBuffer handle value.
512     // Returns true on success, false otherwise.
513 
514     bool setEmulatedEglWindowSurfaceColorBuffer(HandleType p_surface, HandleType p_colorbuffer);
515     // Return the list of configs available from this display.
516     const gl::EmulatedEglConfigList* getConfigs() const;
517 
518     // Retrieve the GL strings of the underlying EGL/GLES implementation.
519     // On return, |*vendor|, |*renderer| and |*version| will point to strings
520     // that are owned by the instance (and must not be freed by the caller).
getGLStrings(const char ** vendor,const char ** renderer,const char ** version)521     void getGLStrings(const char** vendor, const char** renderer, const char** version) const {
522         *vendor = m_graphicsAdapterVendor.c_str();
523         *renderer = m_graphicsAdapterName.c_str();
524         *version = m_graphicsApiVersion.c_str();
525     }
526 
527     // Create a new EmulatedEglContext instance for this display instance.
528     // |p_config| is the index of one of the configs returned by getConfigs().
529     // |p_share| is either EGL_NO_CONTEXT or the handle of a shared context.
530     // |version| specifies the GLES version as a GLESApi enum.
531     // Return a new handle value, which will be 0 in case of error.
532     HandleType createEmulatedEglContext(int p_config, HandleType p_share,
533                                         gl::GLESApi version = gl::GLESApi_CM);
534 
535     // Destroy a given EmulatedEglContext instance. |p_context| is its handle
536     // value as returned by createEmulatedEglContext().
537     void destroyEmulatedEglContext(HandleType p_context);
538 
539     // Create a new EmulatedEglWindowSurface instance from this display instance.
540     // |p_config| is the index of one of the configs returned by getConfigs().
541     // |p_width| and |p_height| are the window dimensions in pixels.
542     // Return a new handle value, or 0 in case of error.
543     HandleType createEmulatedEglWindowSurface(int p_config, int p_width, int p_height);
544 
545     // Destroy a given EmulatedEglWindowSurface instance. |p_surcace| is its
546     // handle value as returned by createEmulatedEglWindowSurface().
547     void destroyEmulatedEglWindowSurface(HandleType p_surface);
548 
549     // Returns the set of ColorBuffers destroyed (for further cleanup)
550     std::vector<HandleType> destroyEmulatedEglWindowSurfaceLocked(HandleType p_surface);
551 
552     void createEmulatedEglFenceSync(EGLenum type, int destroyWhenSignaled,
553                                     uint64_t* outSync = nullptr, uint64_t* outSyncThread = nullptr);
554 
555     // Call this function when a render thread terminates to destroy all
556     // resources it created. Necessary to avoid leaking host resources
557     // when a guest application crashes, for example.
558     void drainGlRenderThreadResources();
559 
560     // Call this function when a render thread terminates to destroy all
561     // the remaining contexts it created. Necessary to avoid leaking host
562     // contexts when a guest application crashes, for example.
563     void drainGlRenderThreadContexts();
564 
565     // Call this function when a render thread terminates to destroy all
566     // remaining window surface it created. Necessary to avoid leaking
567     // host buffers when a guest application crashes, for example.
568     void drainGlRenderThreadSurfaces();
569 
570     gl::EmulationGl& getEmulationGl();
hasEmulationGl()571     bool hasEmulationGl() const { return m_emulationGl != nullptr; }
572 
573     // Return the host EGLDisplay used by this instance.
574     EGLDisplay getDisplay() const;
575     EGLSurface getWindowSurface() const;
576     EGLContext getContext() const;
577     EGLConfig getConfig() const;
578 
579     EGLContext getGlobalEGLContext() const;
580 
581     // Return a render context pointer from its handle
582     gl::EmulatedEglContextPtr getContext_locked(HandleType p_context);
583 
584     // Return a color buffer pointer from its handle
585     gl::EmulatedEglWindowSurfacePtr getWindowSurface_locked(HandleType p_windowsurface);
586 
587     // Return a TextureDraw instance that can be used with this surfaces
588     // and windows created by this instance.
589     gl::TextureDraw* getTextureDraw() const;
590 
591     bool isFastBlitSupported() const;
592     void disableFastBlitForTesting();
593 
594     // Create an eglImage and return its handle.  Reference:
595     // https://www.khronos.org/registry/egl/extensions/KHR/EGL_KHR_image_base.txt
596     HandleType createEmulatedEglImage(HandleType context, EGLenum target, GLuint buffer);
597     // Call the implementation of eglDestroyImageKHR, return if succeeds or
598     // not. Reference:
599     // https://www.khronos.org/registry/egl/extensions/KHR/EGL_KHR_image_base.txt
600     EGLBoolean destroyEmulatedEglImage(HandleType image);
601     // Copy the content of a EmulatedEglWindowSurface's Pbuffer to its attached
602     // ColorBuffer. See the documentation for
603     // EmulatedEglWindowSurface::flushColorBuffer().
604     // |p_surface| is the target WindowSurface's handle value.
605     // Returns true on success, false on failure.
606     bool flushEmulatedEglWindowSurfaceColorBuffer(HandleType p_surface);
607 
608     gl::GLESDispatchMaxVersion getMaxGLESVersion();
609 
610     // Fill GLES usage protobuf
611     void fillGLESUsages(android_studio::EmulatorGLESUsages*);
612 
613     void* platformCreateSharedEglContext(void);
614     bool platformDestroySharedEglContext(void* context);
615 
616     bool flushColorBufferFromGl(HandleType colorBufferHandle);
617 
618     bool invalidateColorBufferForGl(HandleType colorBufferHandle);
619 
620     ContextHelper* getPbufferSurfaceContextHelper() const;
621 
622     // Bind the current context's EGL_TEXTURE_2D texture to a ColorBuffer
623     // instance's EGLImage. This is intended to implement
624     // glEGLImageTargetTexture2DOES() for all GLES versions.
625     // |p_colorbuffer| is the ColorBuffer's handle value.
626     // Returns true on success, false on failure.
627     bool bindColorBufferToTexture(HandleType p_colorbuffer);
628     bool bindColorBufferToTexture2(HandleType p_colorbuffer);
629 
630     // Bind the current context's EGL_RENDERBUFFER_OES render buffer to this
631     // ColorBuffer's EGLImage. This is intended to implement
632     // glEGLImageTargetRenderbufferStorageOES() for all GLES versions.
633     // |p_colorbuffer| is the ColorBuffer's handle value.
634     // Returns true on success, false on failure.
635     bool bindColorBufferToRenderbuffer(HandleType p_colorbuffer);
636 
637     // Equivalent for eglMakeCurrent() for the current display.
638     // |p_context|, |p_drawSurface| and |p_readSurface| are the handle values
639     // of the context, the draw surface and the read surface, respectively.
640     // Returns true on success, false on failure.
641     // Note: if all handle values are 0, this is an unbind operation.
642     bool bindContext(HandleType p_context, HandleType p_drawSurface, HandleType p_readSurface);
643 
644     // create a Y texture and a UV texture with width and height, the created
645     // texture ids are stored in textures respectively
646     void createYUVTextures(uint32_t type, uint32_t count, int width, int height, uint32_t* output);
647     void destroyYUVTextures(uint32_t type, uint32_t count, uint32_t* textures);
648     void updateYUVTextures(uint32_t type, uint32_t* textures, void* privData, void* func);
649     void swapTexturesAndUpdateColorBuffer(uint32_t colorbufferhandle, int x, int y, int width,
650                                           int height, uint32_t format, uint32_t type,
651                                           uint32_t texture_type, uint32_t* textures);
652 
653     // Reads back the raw color buffer to |pixels|
654     // if |pixels| is not null.
655     // Always returns in |numBytes| how many bytes were
656     // planned to be transmitted.
657     // |numBytes| is not an input parameter;
658     // fewer or more bytes cannot be specified.
659     // If the framework format is YUV, it will read
660     // back as raw YUV data.
661     bool readColorBufferContents(HandleType p_colorbuffer, size_t* numBytes, void* pixels);
662 
663     void waitForGpu(uint64_t eglsync);
664     void asyncWaitForGpuWithCb(uint64_t eglsync, FenceCompletionCallback cb);
665 
666     const gl::EGLDispatch* getEglDispatch();
667     const gl::GLESv2Dispatch* getGles2Dispatch();
668 #endif
669 
670    private:
671     FrameBuffer(int p_width, int p_height, bool useSubWindow);
672     // Requires the caller to hold the m_colorBufferMapLock until the new handle is inserted into of
673     // the object handle maps.
674     HandleType genHandle_locked();
675 
676     bool removeSubWindow_locked();
677     // Returns the set of ColorBuffers destroyed (for further cleanup)
678     std::vector<HandleType> cleanupProcGLObjects_locked(uint64_t puid,
679                                                         bool forced = false);
680 
681     void markOpened(ColorBufferRef* cbRef);
682     // Returns true if the color buffer was erased.
683     bool closeColorBufferLocked(HandleType p_colorbuffer, bool forced = false);
684     // Returns true if this was the last ref and we need to destroy stuff.
685     bool decColorBufferRefCountLocked(HandleType p_colorbuffer);
686     // Decrease refcount but not destroy the object.
687     // Mainly used in post thread, when we need to destroy the object but cannot in post thread.
688     void decColorBufferRefCountNoDestroy(HandleType p_colorbuffer);
689     // Close all expired color buffers for real.
690     // Treat all delayed color buffers as expired if forced=true
691     void performDelayedColorBufferCloseLocked(bool forced = false);
692     void eraseDelayedCloseColorBufferLocked(HandleType cb, uint64_t ts);
693 
694     AsyncResult postImpl(HandleType p_colorbuffer, Post::CompletionCallback callback,
695                   bool needLockAndBind = true, bool repaint = false);
696     bool postImplSync(HandleType p_colorbuffer, bool needLockAndBind = true, bool repaint = false);
setGuestPostedAFrame()697     void setGuestPostedAFrame() {
698         m_guestPostedAFrame = true;
699         fireEvent({FrameBufferChange::FrameReady, mFrameNumber++});
700     }
701     HandleType createColorBufferWithHandleLocked(int p_width, int p_height, GLenum p_internalFormat,
702                                                  FrameworkFormat p_frameworkFormat,
703                                                  HandleType handle);
704     HandleType createBufferWithHandleLocked(int p_size, HandleType handle, uint32_t memoryProperty);
705 
706     void recomputeLayout();
707     void setDisplayPoseInSkinUI(int totalHeight);
708     void sweepColorBuffersLocked();
709 
710     std::future<void> blockPostWorker(std::future<void> continueSignal);
711 
712    private:
713 
714     static FrameBuffer* s_theFrameBuffer;
715     static HandleType s_nextHandle;
716     int m_x = 0;
717     int m_y = 0;
718     int m_framebufferWidth = 0;
719     int m_framebufferHeight = 0;
720     std::atomic_int m_windowWidth = 0;
721     std::atomic_int m_windowHeight = 0;
722     // When zoomed in, the size of the content is bigger than the window size, and we only
723     // display / store a portion of it.
724     int m_windowContentFullWidth = 0;
725     int m_windowContentFullHeight = 0;
726     float m_dpr = 0;
727 
728     bool m_useSubWindow = false;
729 
730     bool m_fpsStats = false;
731     bool m_perfStats = false;
732     int m_statsNumFrames = 0;
733     long long m_statsStartTime = 0;
734 
735     android::base::Thread* m_perfThread;
736     android::base::Lock m_lock;
737     android::base::ReadWriteLock m_contextStructureLock;
738     android::base::Lock m_colorBufferMapLock;
739     uint64_t mFrameNumber;
740     FBNativeWindowType m_nativeWindow = 0;
741 
742     ColorBufferMap m_colorbuffers;
743     BufferMap m_buffers;
744 
745     // A collection of color buffers that were closed without any usages
746     // (|opened| == false).
747     //
748     // If a buffer reached |refcount| == 0 while not being |opened|, instead of
749     // deleting it we remember the timestamp when this happened. Later, we
750     // check if the buffer stayed unopened long enough and if it did, we delete
751     // it permanently. On the other hand, if the color buffer was used then
752     // we don't care about timestamps anymore.
753     //
754     // Note: this collection is ordered by |ts| field.
755     struct ColorBufferCloseInfo {
756         uint64_t ts;          // when we got the close request.
757         HandleType cbHandle;  // 0 == already closed, do nothing
758     };
759     using ColorBufferDelayedClose = std::vector<ColorBufferCloseInfo>;
760     ColorBufferDelayedClose m_colorBufferDelayedCloseList;
761 
762     EGLNativeWindowType m_subWin = {};
763     HandleType m_lastPostedColorBuffer = 0;
764     float m_zRot = 0;
765     float m_px = 0;
766     float m_py = 0;
767 
768     // Async readback
769     enum class ReadbackCmd {
770         Init = 0,
771         GetPixels = 1,
772         AddRecordDisplay = 2,
773         DelRecordDisplay = 3,
774         Exit = 4,
775     };
776     struct Readback {
777         ReadbackCmd cmd;
778         uint32_t displayId;
779         void* pixelsOut;
780         uint32_t bytes;
781         uint32_t width;
782         uint32_t height;
783     };
784     android::base::WorkerProcessingResult sendReadbackWorkerCmd(
785         const Readback& readback);
786     bool m_guestPostedAFrame = false;
787 
788     struct onPost {
789         Renderer::OnPostCallback cb;
790         void* context;
791         uint32_t displayId;
792         uint32_t width;
793         uint32_t height;
794         unsigned char* img = nullptr;
795         bool readBgra;
~onPostonPost796         ~onPost() {
797             if (img) {
798                 delete[] img;
799                 img = nullptr;
800             }
801         }
802     };
803     std::map<uint32_t, onPost> m_onPost;
804     ReadbackWorker* m_readbackWorker = nullptr;
805     android::base::WorkerThread<Readback> m_readbackThread;
806     std::atomic_bool m_readbackThreadStarted = false;
807 
808     std::string m_graphicsAdapterVendor;
809     std::string m_graphicsAdapterName;
810     std::string m_graphicsApiVersion;
811     std::string m_graphicsApiExtensions;
812     std::string m_graphicsDeviceExtensions;
813     std::unordered_map<uint64_t, std::unique_ptr<ProcessResources>> m_procOwnedResources;
814 
815     // Flag set when emulator is shutting down.
816     bool m_shuttingDown = false;
817 
818     // When this feature is enabled, open/close operations from gralloc in guest
819     // will no longer control the reference counting of color buffers on host.
820     // Instead, it will be managed by a file descriptor in the guest kernel. In
821     // case all the native handles in guest are destroyed, the pipe will be
822     // automatically closed by the kernel. We only need to do reference counting
823     // for color buffers attached in window surface.
824     bool m_refCountPipeEnabled = false;
825 
826     // When this feature is enabled, and m_refCountPipeEnabled == false, color
827     // buffer close operations will immediately close the color buffer if host
828     // refcount hits 0. This is for use with guest kernels where the color
829     // buffer is already tied to a file descriptor in the guest kernel.
830     bool m_noDelayCloseColorBufferEnabled = false;
831 
832     std::unique_ptr<PostWorker> m_postWorker = {};
833     std::atomic_bool m_postThreadStarted = false;
834     android::base::WorkerThread<Post> m_postThread;
835     android::base::WorkerProcessingResult postWorkerFunc(Post& post);
836     std::future<void> sendPostWorkerCmd(Post post);
837 
838     bool m_vulkanInteropSupported = false;
839     bool m_vulkanEnabled = false;
840     bool m_guestUsesAngle = false;
841     // Whether the guest manages ColorBuffer lifetime
842     // so we don't need refcounting on the host side.
843     bool m_guestManagedColorBufferLifetime = false;
844 
845     android::base::MessageChannel<HandleType, 1024>
846         mOutstandingColorBufferDestroys;
847 
848     Compositor* m_compositor = nullptr;
849     bool m_useVulkanComposition = false;
850 
851     vk::VkEmulation* m_emulationVk = nullptr;
852     // The implementation for Vulkan native swapchain. Only initialized when useVulkan is set when
853     // calling FrameBuffer::initialize(). DisplayVk is actually owned by VkEmulation.
854     vk::DisplayVk* m_displayVk = nullptr;
855     VkInstance m_vkInstance = VK_NULL_HANDLE;
856     std::unique_ptr<emugl::RenderDoc> m_renderDoc = nullptr;
857 
858     // TODO(b/233939967): Refactor to create DisplayGl and DisplaySurfaceGl
859     // and remove usage of non-generic DisplayVk.
860     Display* m_display;
861     std::unique_ptr<DisplaySurface> m_displaySurface;
862 
863     // CompositorGl.
864     // TODO: update RenderDoc to be a DisplaySurfaceUser.
865     std::vector<DisplaySurfaceUser*> m_displaySurfaceUsers;
866 
867     // UUIDs of physical devices for Vulkan and GLES, respectively.  In most
868     // cases, this determines whether we can support zero-copy interop.
869     using VkUuid = std::array<uint8_t, VK_UUID_SIZE>;
870     VkUuid m_vulkanUUID{};
871 
872     // Tracks platform EGL contexts that have been handed out to other users,
873     // indexed by underlying native EGL context object.
874 
875     std::unique_ptr<MetricsLogger> m_logger;
876     std::unique_ptr<HealthMonitor<>> m_healthMonitor;
877 
878     int m_vsyncHz = 60;
879 
880     // Vsync thread.
881     std::unique_ptr<VsyncThread> m_vsyncThread = {};
882 
883     struct DisplayConfig{
884         int w;
885         int h;
886         int dpiX;
887         int dpiY;
DisplayConfigDisplayConfig888         DisplayConfig() {}
DisplayConfigDisplayConfig889         DisplayConfig(int w, int h, int x, int y)
890         : w(w), h(h), dpiX(x), dpiY(y) {}
891     };
892     std::map<int, DisplayConfig> mDisplayConfigs;
893     int mDisplayActiveConfigId = -1;
894 
895     std::unique_ptr<gl::EmulationGl> m_emulationGl;
896 
897     // The host associates color buffers with guest processes for memory
898     // cleanup. Guest processes are identified with a host generated unique ID.
899     // TODO(kaiyili): move all those resources to the ProcessResources struct.
900     ProcOwnedColorBuffers m_procOwnedColorBuffers;
901     ProcOwnedCleanupCallbacks m_procOwnedCleanupCallbacks;
902 
903 #if GFXSTREAM_ENABLE_HOST_GLES
904     gl::EmulatedEglContextMap m_contexts;
905     gl::EmulatedEglImageMap m_images;
906     gl::EmulatedEglWindowSurfaceMap m_windows;
907 
908     std::unordered_map<HandleType, HandleType> m_EmulatedEglWindowSurfaceToColorBuffer;
909 
910     ProcOwnedEmulatedEGLImages m_procOwnedEmulatedEglImages;
911     ProcOwnedEmulatedEglContexts m_procOwnedEmulatedEglContexts;
912     ProcOwnedEmulatedEglWindowSurfaces m_procOwnedEmulatedEglWindowSurfaces;
913     gl::DisplayGl* m_displayGl = nullptr;
914 
915     struct PlatformEglContextInfo {
916         EGLContext context;
917         EGLSurface surface;
918     };
919 
920     std::unordered_map<void*, PlatformEglContextInfo> m_platformEglContexts;
921 #endif
922 };
923 
924 }  // namespace gfxstream
925 
926 #endif
927