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