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