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