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