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