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