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