Loading libs/hwui/Android.bp +2 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,7 @@ cc_defaults { "libminikin", "libandroidfw", "libcrypto", "libsync", ], static_libs: [ "libEGL_blobCache", Loading Loading @@ -180,6 +181,7 @@ cc_defaults { "renderthread/EglManager.cpp", "renderthread/ReliableSurface.cpp", "renderthread/VulkanManager.cpp", "renderthread/VulkanSurface.cpp", "renderthread/RenderProxy.cpp", "renderthread/RenderTask.cpp", "renderthread/RenderThread.cpp", Loading libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp +5 −17 Original line number Diff line number Diff line Loading @@ -55,20 +55,8 @@ MakeCurrentResult SkiaVulkanPipeline::makeCurrent() { } Frame SkiaVulkanPipeline::getFrame() { LOG_ALWAYS_FATAL_IF(mVkSurface == nullptr, "drawRenderNode called on a context with no surface!"); SkSurface* backBuffer = mVkManager.getBackbufferSurface(&mVkSurface); LOG_ALWAYS_FATAL_IF(mVkSurface == nullptr, "drawRenderNode called on a context with an invalid surface"); if (backBuffer == nullptr) { SkDebugf("failed to get backbuffer"); return Frame(-1, -1, 0); } Frame frame(mVkSurface->windowWidth(), mVkSurface->windowHeight(), mVkManager.getAge(mVkSurface)); return frame; LOG_ALWAYS_FATAL_IF(mVkSurface == nullptr, "getFrame() called on a context with no surface!"); return mVkManager.dequeueNextBuffer(mVkSurface); } bool SkiaVulkanPipeline::draw(const Frame& frame, const SkRect& screenDirty, const SkRect& dirty, Loading @@ -77,13 +65,13 @@ bool SkiaVulkanPipeline::draw(const Frame& frame, const SkRect& screenDirty, con bool opaque, const LightInfo& lightInfo, const std::vector<sp<RenderNode>>& renderNodes, FrameInfoVisualizer* profiler) { sk_sp<SkSurface> backBuffer = mVkSurface->getBackBufferSurface(); sk_sp<SkSurface> backBuffer = mVkSurface->getCurrentSkSurface(); if (backBuffer.get() == nullptr) { return false; } SkiaPipeline::updateLighting(lightGeometry, lightInfo); renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, backBuffer, mVkSurface->preTransform()); backBuffer, mVkSurface->getCurrentPreTransform()); ShaderCache::get().onVkFrameFlushed(mRenderThread.getGrContext()); layerUpdateQueue->clear(); Loading Loading @@ -113,7 +101,7 @@ bool SkiaVulkanPipeline::swapBuffers(const Frame& frame, bool drew, const SkRect currentFrameInfo->markSwapBuffers(); if (*requireSwap) { mVkManager.swapBuffers(mVkSurface); mVkManager.swapBuffers(mVkSurface, screenDirty); } return *requireSwap; Loading libs/hwui/pipeline/skia/SkiaVulkanPipeline.h +1 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include "SkiaPipeline.h" #include "renderthread/VulkanManager.h" #include "renderthread/VulkanSurface.h" #include "renderstate/RenderState.h" Loading libs/hwui/renderthread/VulkanManager.cpp +86 −626 File changed.Preview size limit exceeded, changes collapsed. Show changes libs/hwui/renderthread/VulkanManager.h +8 −93 Original line number Diff line number Diff line Loading @@ -28,7 +28,9 @@ #include <ui/Fence.h> #include <utils/StrongPointer.h> #include <vk/GrVkBackendContext.h> #include "Frame.h" #include "IRenderPipeline.h" #include "VulkanSurface.h" class GrVkExtensions; Loading @@ -38,66 +40,6 @@ namespace renderthread { class RenderThread; class VulkanSurface { public: VulkanSurface(ColorMode colorMode, ANativeWindow* window, sk_sp<SkColorSpace> colorSpace, SkColorType colorType, GrContext* grContext) : mColorMode(colorMode), mNativeWindow(window), mColorSpace(colorSpace), mColorType(colorType), mGrContext(grContext) {} sk_sp<SkSurface> getBackBufferSurface() { return mBackbuffer; } // The width and height are are the logical width and height for when submitting draws to the // surface. In reality if the window is rotated the underlying VkImage may have the width and // height swapped. int windowWidth() const { return mWindowWidth; } int windowHeight() const { return mWindowHeight; } SkMatrix& preTransform() { return mPreTransform; } private: friend class VulkanManager; struct BackbufferInfo { uint32_t mImageIndex; // image this is associated with VkSemaphore mAcquireSemaphore; // we signal on this for acquisition of image VkSemaphore mRenderSemaphore; // we wait on this for rendering to be done VkCommandBuffer mTransitionCmdBuffers[2]; // to transition layout between present and render // We use these fences to make sure the above Command buffers have finished their work // before attempting to reuse them or destroy them. VkFence mUsageFences[2]; }; struct ImageInfo { VkImageLayout mImageLayout = VK_IMAGE_LAYOUT_UNDEFINED; sk_sp<SkSurface> mSurface; uint16_t mLastUsed = 0; bool mInvalid = true; }; sk_sp<SkSurface> mBackbuffer; VkSurfaceKHR mVkSurface = VK_NULL_HANDLE; VkSwapchainKHR mSwapchain = VK_NULL_HANDLE; BackbufferInfo* mBackbuffers = nullptr; uint32_t mCurrentBackbufferIndex; uint32_t mImageCount; VkImage* mImages = nullptr; ImageInfo* mImageInfos; uint16_t mCurrentTime = 0; ColorMode mColorMode; ANativeWindow* mNativeWindow; int mWindowWidth = 0; int mWindowHeight = 0; sk_sp<SkColorSpace> mColorSpace; SkColorType mColorType; VkSurfaceTransformFlagBitsKHR mTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; SkMatrix mPreTransform; GrContext* mGrContext; }; // This class contains the shared global Vulkan objects, such as VkInstance, VkDevice and VkQueue, // which are re-used by CanvasContext. This class is created once and should be used by all vulkan // windowing contexts. The VulkanManager must be initialized before use. Loading @@ -114,33 +56,19 @@ public: // Quick check to see if the VulkanManager has been initialized. bool hasVkContext() { return mDevice != VK_NULL_HANDLE; } // Given a window this creates a new VkSurfaceKHR and VkSwapchain and stores them inside a new // VulkanSurface object which is returned. // Create and destroy functions for wrapping an ANativeWindow in a VulkanSurface VulkanSurface* createSurface(ANativeWindow* window, ColorMode colorMode, sk_sp<SkColorSpace> surfaceColorSpace, SkColorType surfaceColorType, GrContext* grContext); // Destroy the VulkanSurface and all associated vulkan objects. void destroySurface(VulkanSurface* surface); Frame dequeueNextBuffer(VulkanSurface* surface); void swapBuffers(VulkanSurface* surface, const SkRect& dirtyRect); // Cleans up all the global state in the VulkanManger. void destroy(); // No work is needed to make a VulkanSurface current, and all functions require that a // VulkanSurface is passed into them so we just return true here. bool isCurrent(VulkanSurface* surface) { return true; } int getAge(VulkanSurface* surface); // Returns an SkSurface which wraps the next image returned from vkAcquireNextImageKHR. It also // will transition the VkImage from a present layout to color attachment so that it can be used // by the client for drawing. SkSurface* getBackbufferSurface(VulkanSurface** surface); // Presents the current VkImage. void swapBuffers(VulkanSurface* surface); // Inserts a wait on fence command into the Vulkan command buffer. status_t fenceWait(sp<Fence>& fence); Loading @@ -153,17 +81,10 @@ public: sk_sp<GrContext> createContext(const GrContextOptions& options); private: friend class VulkanSurface; // Sets up the VkInstance and VkDevice objects. Also fills out the passed in // VkPhysicalDeviceFeatures struct. void setupDevice(GrVkExtensions&, VkPhysicalDeviceFeatures2&); void destroyBuffers(VulkanSurface* surface); bool createSwapchain(VulkanSurface* surface); void createBuffers(VulkanSurface* surface, VkFormat format, VkExtent2D extent); VulkanSurface::BackbufferInfo* getAvailableBackbuffer(VulkanSurface* surface); bool setupDummyCommandBuffer(); // simple wrapper class that exists only to initialize a pointer to NULL Loading @@ -190,13 +111,6 @@ private: VkPtr<PFN_vkGetPhysicalDeviceSurfaceFormatsKHR> mGetPhysicalDeviceSurfaceFormatsKHR; VkPtr<PFN_vkGetPhysicalDeviceSurfacePresentModesKHR> mGetPhysicalDeviceSurfacePresentModesKHR; VkPtr<PFN_vkCreateSwapchainKHR> mCreateSwapchainKHR; VkPtr<PFN_vkDestroySwapchainKHR> mDestroySwapchainKHR; VkPtr<PFN_vkGetSwapchainImagesKHR> mGetSwapchainImagesKHR; VkPtr<PFN_vkAcquireNextImageKHR> mAcquireNextImageKHR; VkPtr<PFN_vkQueuePresentKHR> mQueuePresentKHR; VkPtr<PFN_vkCreateSharedSwapchainsKHR> mCreateSharedSwapchainsKHR; // Instance Functions VkPtr<PFN_vkEnumerateInstanceVersion> mEnumerateInstanceVersion; VkPtr<PFN_vkEnumerateInstanceExtensionProperties> mEnumerateInstanceExtensionProperties; Loading @@ -207,6 +121,7 @@ private: VkPtr<PFN_vkGetPhysicalDeviceProperties> mGetPhysicalDeviceProperties; VkPtr<PFN_vkGetPhysicalDeviceQueueFamilyProperties> mGetPhysicalDeviceQueueFamilyProperties; VkPtr<PFN_vkGetPhysicalDeviceFeatures2> mGetPhysicalDeviceFeatures2; VkPtr<PFN_vkGetPhysicalDeviceImageFormatProperties2> mGetPhysicalDeviceImageFormatProperties2; VkPtr<PFN_vkCreateDevice> mCreateDevice; VkPtr<PFN_vkEnumerateDeviceExtensionProperties> mEnumerateDeviceExtensionProperties; Loading Loading
libs/hwui/Android.bp +2 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,7 @@ cc_defaults { "libminikin", "libandroidfw", "libcrypto", "libsync", ], static_libs: [ "libEGL_blobCache", Loading Loading @@ -180,6 +181,7 @@ cc_defaults { "renderthread/EglManager.cpp", "renderthread/ReliableSurface.cpp", "renderthread/VulkanManager.cpp", "renderthread/VulkanSurface.cpp", "renderthread/RenderProxy.cpp", "renderthread/RenderTask.cpp", "renderthread/RenderThread.cpp", Loading
libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp +5 −17 Original line number Diff line number Diff line Loading @@ -55,20 +55,8 @@ MakeCurrentResult SkiaVulkanPipeline::makeCurrent() { } Frame SkiaVulkanPipeline::getFrame() { LOG_ALWAYS_FATAL_IF(mVkSurface == nullptr, "drawRenderNode called on a context with no surface!"); SkSurface* backBuffer = mVkManager.getBackbufferSurface(&mVkSurface); LOG_ALWAYS_FATAL_IF(mVkSurface == nullptr, "drawRenderNode called on a context with an invalid surface"); if (backBuffer == nullptr) { SkDebugf("failed to get backbuffer"); return Frame(-1, -1, 0); } Frame frame(mVkSurface->windowWidth(), mVkSurface->windowHeight(), mVkManager.getAge(mVkSurface)); return frame; LOG_ALWAYS_FATAL_IF(mVkSurface == nullptr, "getFrame() called on a context with no surface!"); return mVkManager.dequeueNextBuffer(mVkSurface); } bool SkiaVulkanPipeline::draw(const Frame& frame, const SkRect& screenDirty, const SkRect& dirty, Loading @@ -77,13 +65,13 @@ bool SkiaVulkanPipeline::draw(const Frame& frame, const SkRect& screenDirty, con bool opaque, const LightInfo& lightInfo, const std::vector<sp<RenderNode>>& renderNodes, FrameInfoVisualizer* profiler) { sk_sp<SkSurface> backBuffer = mVkSurface->getBackBufferSurface(); sk_sp<SkSurface> backBuffer = mVkSurface->getCurrentSkSurface(); if (backBuffer.get() == nullptr) { return false; } SkiaPipeline::updateLighting(lightGeometry, lightInfo); renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, backBuffer, mVkSurface->preTransform()); backBuffer, mVkSurface->getCurrentPreTransform()); ShaderCache::get().onVkFrameFlushed(mRenderThread.getGrContext()); layerUpdateQueue->clear(); Loading Loading @@ -113,7 +101,7 @@ bool SkiaVulkanPipeline::swapBuffers(const Frame& frame, bool drew, const SkRect currentFrameInfo->markSwapBuffers(); if (*requireSwap) { mVkManager.swapBuffers(mVkSurface); mVkManager.swapBuffers(mVkSurface, screenDirty); } return *requireSwap; Loading
libs/hwui/pipeline/skia/SkiaVulkanPipeline.h +1 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include "SkiaPipeline.h" #include "renderthread/VulkanManager.h" #include "renderthread/VulkanSurface.h" #include "renderstate/RenderState.h" Loading
libs/hwui/renderthread/VulkanManager.cpp +86 −626 File changed.Preview size limit exceeded, changes collapsed. Show changes
libs/hwui/renderthread/VulkanManager.h +8 −93 Original line number Diff line number Diff line Loading @@ -28,7 +28,9 @@ #include <ui/Fence.h> #include <utils/StrongPointer.h> #include <vk/GrVkBackendContext.h> #include "Frame.h" #include "IRenderPipeline.h" #include "VulkanSurface.h" class GrVkExtensions; Loading @@ -38,66 +40,6 @@ namespace renderthread { class RenderThread; class VulkanSurface { public: VulkanSurface(ColorMode colorMode, ANativeWindow* window, sk_sp<SkColorSpace> colorSpace, SkColorType colorType, GrContext* grContext) : mColorMode(colorMode), mNativeWindow(window), mColorSpace(colorSpace), mColorType(colorType), mGrContext(grContext) {} sk_sp<SkSurface> getBackBufferSurface() { return mBackbuffer; } // The width and height are are the logical width and height for when submitting draws to the // surface. In reality if the window is rotated the underlying VkImage may have the width and // height swapped. int windowWidth() const { return mWindowWidth; } int windowHeight() const { return mWindowHeight; } SkMatrix& preTransform() { return mPreTransform; } private: friend class VulkanManager; struct BackbufferInfo { uint32_t mImageIndex; // image this is associated with VkSemaphore mAcquireSemaphore; // we signal on this for acquisition of image VkSemaphore mRenderSemaphore; // we wait on this for rendering to be done VkCommandBuffer mTransitionCmdBuffers[2]; // to transition layout between present and render // We use these fences to make sure the above Command buffers have finished their work // before attempting to reuse them or destroy them. VkFence mUsageFences[2]; }; struct ImageInfo { VkImageLayout mImageLayout = VK_IMAGE_LAYOUT_UNDEFINED; sk_sp<SkSurface> mSurface; uint16_t mLastUsed = 0; bool mInvalid = true; }; sk_sp<SkSurface> mBackbuffer; VkSurfaceKHR mVkSurface = VK_NULL_HANDLE; VkSwapchainKHR mSwapchain = VK_NULL_HANDLE; BackbufferInfo* mBackbuffers = nullptr; uint32_t mCurrentBackbufferIndex; uint32_t mImageCount; VkImage* mImages = nullptr; ImageInfo* mImageInfos; uint16_t mCurrentTime = 0; ColorMode mColorMode; ANativeWindow* mNativeWindow; int mWindowWidth = 0; int mWindowHeight = 0; sk_sp<SkColorSpace> mColorSpace; SkColorType mColorType; VkSurfaceTransformFlagBitsKHR mTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; SkMatrix mPreTransform; GrContext* mGrContext; }; // This class contains the shared global Vulkan objects, such as VkInstance, VkDevice and VkQueue, // which are re-used by CanvasContext. This class is created once and should be used by all vulkan // windowing contexts. The VulkanManager must be initialized before use. Loading @@ -114,33 +56,19 @@ public: // Quick check to see if the VulkanManager has been initialized. bool hasVkContext() { return mDevice != VK_NULL_HANDLE; } // Given a window this creates a new VkSurfaceKHR and VkSwapchain and stores them inside a new // VulkanSurface object which is returned. // Create and destroy functions for wrapping an ANativeWindow in a VulkanSurface VulkanSurface* createSurface(ANativeWindow* window, ColorMode colorMode, sk_sp<SkColorSpace> surfaceColorSpace, SkColorType surfaceColorType, GrContext* grContext); // Destroy the VulkanSurface and all associated vulkan objects. void destroySurface(VulkanSurface* surface); Frame dequeueNextBuffer(VulkanSurface* surface); void swapBuffers(VulkanSurface* surface, const SkRect& dirtyRect); // Cleans up all the global state in the VulkanManger. void destroy(); // No work is needed to make a VulkanSurface current, and all functions require that a // VulkanSurface is passed into them so we just return true here. bool isCurrent(VulkanSurface* surface) { return true; } int getAge(VulkanSurface* surface); // Returns an SkSurface which wraps the next image returned from vkAcquireNextImageKHR. It also // will transition the VkImage from a present layout to color attachment so that it can be used // by the client for drawing. SkSurface* getBackbufferSurface(VulkanSurface** surface); // Presents the current VkImage. void swapBuffers(VulkanSurface* surface); // Inserts a wait on fence command into the Vulkan command buffer. status_t fenceWait(sp<Fence>& fence); Loading @@ -153,17 +81,10 @@ public: sk_sp<GrContext> createContext(const GrContextOptions& options); private: friend class VulkanSurface; // Sets up the VkInstance and VkDevice objects. Also fills out the passed in // VkPhysicalDeviceFeatures struct. void setupDevice(GrVkExtensions&, VkPhysicalDeviceFeatures2&); void destroyBuffers(VulkanSurface* surface); bool createSwapchain(VulkanSurface* surface); void createBuffers(VulkanSurface* surface, VkFormat format, VkExtent2D extent); VulkanSurface::BackbufferInfo* getAvailableBackbuffer(VulkanSurface* surface); bool setupDummyCommandBuffer(); // simple wrapper class that exists only to initialize a pointer to NULL Loading @@ -190,13 +111,6 @@ private: VkPtr<PFN_vkGetPhysicalDeviceSurfaceFormatsKHR> mGetPhysicalDeviceSurfaceFormatsKHR; VkPtr<PFN_vkGetPhysicalDeviceSurfacePresentModesKHR> mGetPhysicalDeviceSurfacePresentModesKHR; VkPtr<PFN_vkCreateSwapchainKHR> mCreateSwapchainKHR; VkPtr<PFN_vkDestroySwapchainKHR> mDestroySwapchainKHR; VkPtr<PFN_vkGetSwapchainImagesKHR> mGetSwapchainImagesKHR; VkPtr<PFN_vkAcquireNextImageKHR> mAcquireNextImageKHR; VkPtr<PFN_vkQueuePresentKHR> mQueuePresentKHR; VkPtr<PFN_vkCreateSharedSwapchainsKHR> mCreateSharedSwapchainsKHR; // Instance Functions VkPtr<PFN_vkEnumerateInstanceVersion> mEnumerateInstanceVersion; VkPtr<PFN_vkEnumerateInstanceExtensionProperties> mEnumerateInstanceExtensionProperties; Loading @@ -207,6 +121,7 @@ private: VkPtr<PFN_vkGetPhysicalDeviceProperties> mGetPhysicalDeviceProperties; VkPtr<PFN_vkGetPhysicalDeviceQueueFamilyProperties> mGetPhysicalDeviceQueueFamilyProperties; VkPtr<PFN_vkGetPhysicalDeviceFeatures2> mGetPhysicalDeviceFeatures2; VkPtr<PFN_vkGetPhysicalDeviceImageFormatProperties2> mGetPhysicalDeviceImageFormatProperties2; VkPtr<PFN_vkCreateDevice> mCreateDevice; VkPtr<PFN_vkEnumerateDeviceExtensionProperties> mEnumerateDeviceExtensionProperties; Loading