Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d354d4d6 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add support for preTransform in Vulkan swapchain."

parents 698f366f c4076789
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -100,7 +100,8 @@ bool SkiaOpenGLPipeline::draw(const Frame& frame, const SkRect& screenDirty, con
            mSurfaceColorSpace, &props));

    SkiaPipeline::updateLighting(lightGeometry, lightInfo);
    renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface);
    renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface,
            SkMatrix::I());
    layerUpdateQueue->clear();

    // Draw visual debugging features
+11 −7
Original line number Diff line number Diff line
@@ -312,7 +312,8 @@ void SkiaPipeline::endCapture(SkSurface* surface) {

void SkiaPipeline::renderFrame(const LayerUpdateQueue& layers, const SkRect& clip,
                               const std::vector<sp<RenderNode>>& nodes, bool opaque,
                               const Rect& contentDrawBounds, sk_sp<SkSurface> surface) {
                               const Rect& contentDrawBounds, sk_sp<SkSurface> surface,
                               const SkMatrix& preTransform) {
    renderVectorDrawableCache();

    // draw all layers up front
@@ -323,12 +324,12 @@ void SkiaPipeline::renderFrame(const LayerUpdateQueue& layers, const SkRect& cli
    std::unique_ptr<SkPictureRecorder> recorder;
    SkCanvas* canvas = tryCapture(surface.get());

    renderFrameImpl(layers, clip, nodes, opaque, contentDrawBounds, canvas);
    renderFrameImpl(layers, clip, nodes, opaque, contentDrawBounds, canvas, preTransform);

    endCapture(surface.get());

    if (CC_UNLIKELY(Properties::debugOverdraw)) {
        renderOverdraw(layers, clip, nodes, contentDrawBounds, surface);
        renderOverdraw(layers, clip, nodes, contentDrawBounds, surface, preTransform);
    }

    ATRACE_NAME("flush commands");
@@ -344,9 +345,11 @@ static Rect nodeBounds(RenderNode& node) {

void SkiaPipeline::renderFrameImpl(const LayerUpdateQueue& layers, const SkRect& clip,
                                   const std::vector<sp<RenderNode>>& nodes, bool opaque,
                                   const Rect& contentDrawBounds, SkCanvas* canvas) {
                                   const Rect& contentDrawBounds, SkCanvas* canvas,
                                   const SkMatrix& preTransform) {
    SkAutoCanvasRestore saver(canvas, true);
    canvas->androidFramework_setDeviceClipRestriction(clip.roundOut());
    canvas->androidFramework_setDeviceClipRestriction(preTransform.mapRect(clip).roundOut());
    canvas->concat(preTransform);

    // STOPSHIP: Revert, temporary workaround to clear always F16 frame buffer for b/74976293
    if (!opaque || getSurfaceColorType() == kRGBA_F16_SkColorType) {
@@ -486,7 +489,8 @@ static const uint32_t kOverdrawColors[2][6] = {

void SkiaPipeline::renderOverdraw(const LayerUpdateQueue& layers, const SkRect& clip,
                                  const std::vector<sp<RenderNode>>& nodes,
                                  const Rect& contentDrawBounds, sk_sp<SkSurface> surface) {
                                  const Rect& contentDrawBounds, sk_sp<SkSurface> surface,
                                  const SkMatrix& preTransform) {
    // Set up the overdraw canvas.
    SkImageInfo offscreenInfo = SkImageInfo::MakeA8(surface->width(), surface->height());
    sk_sp<SkSurface> offscreen = surface->makeSurface(offscreenInfo);
@@ -496,7 +500,7 @@ void SkiaPipeline::renderOverdraw(const LayerUpdateQueue& layers, const SkRect&
    // each time a pixel would have been drawn.
    // Pass true for opaque so we skip the clear - the overdrawCanvas is already zero
    // initialized.
    renderFrameImpl(layers, clip, nodes, true, contentDrawBounds, &overdrawCanvas);
    renderFrameImpl(layers, clip, nodes, true, contentDrawBounds, &overdrawCanvas, preTransform);
    sk_sp<SkImage> counts = offscreen->makeImageSnapshot();

    // Draw overdraw colors to the canvas.  The color filter will convert counts to colors.
+5 −3
Original line number Diff line number Diff line
@@ -53,7 +53,8 @@ public:

    void renderFrame(const LayerUpdateQueue& layers, const SkRect& clip,
                     const std::vector<sp<RenderNode>>& nodes, bool opaque,
                     const Rect& contentDrawBounds, sk_sp<SkSurface> surface);
                     const Rect& contentDrawBounds, sk_sp<SkSurface> surface,
                     const SkMatrix& preTransform);

    std::vector<VectorDrawableRoot*>* getVectorDrawables() { return &mVectorDrawables; }

@@ -116,7 +117,8 @@ protected:
private:
    void renderFrameImpl(const LayerUpdateQueue& layers, const SkRect& clip,
                         const std::vector<sp<RenderNode>>& nodes, bool opaque,
                         const Rect& contentDrawBounds, SkCanvas* canvas);
                         const Rect& contentDrawBounds, SkCanvas* canvas,
                         const SkMatrix& preTransform);

    /**
     *  Debugging feature.  Draws a semi-transparent overlay on each pixel, indicating
@@ -124,7 +126,7 @@ private:
     */
    void renderOverdraw(const LayerUpdateQueue& layers, const SkRect& clip,
                        const std::vector<sp<RenderNode>>& nodes, const Rect& contentDrawBounds,
                        sk_sp<SkSurface>);
                        sk_sp<SkSurface> surface, const SkMatrix& preTransform);

    /**
     *  Render mVectorDrawables into offscreen buffers.
+4 −2
Original line number Diff line number Diff line
@@ -58,7 +58,8 @@ Frame SkiaVulkanPipeline::getFrame() {
        return Frame(-1, -1, 0);
    }

    Frame frame(backBuffer->width(), backBuffer->height(), mVkManager.getAge(mVkSurface));
    Frame frame(mVkSurface->windowWidth(), mVkSurface->windowHeight(),
                mVkManager.getAge(mVkSurface));
    return frame;
}

@@ -73,7 +74,8 @@ bool SkiaVulkanPipeline::draw(const Frame& frame, const SkRect& screenDirty, con
        return false;
    }
    SkiaPipeline::updateLighting(lightGeometry, lightInfo);
    renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, backBuffer);
    renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds,
            backBuffer, mVkSurface->preTransform());
    ShaderCache::get().onVkFrameFlushed(mRenderThread.getGrContext());
    layerUpdateQueue->clear();

+58 −5
Original line number Diff line number Diff line
@@ -480,6 +480,32 @@ VulkanSurface::BackbufferInfo* VulkanManager::getAvailableBackbuffer(VulkanSurfa
    return backbuffer;
}

static SkMatrix getPreTransformMatrix(int width, int height,
                                      VkSurfaceTransformFlagBitsKHR transform) {
    switch (transform) {
        case VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR:
            return SkMatrix::I();
        case VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR:
            return SkMatrix::MakeAll(0, -1, height, 1, 0, 0, 0, 0, 1);
        case VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR:
            return SkMatrix::MakeAll(-1, 0, width, 0, -1, height, 0, 0, 1);
        case VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR:
            return SkMatrix::MakeAll(0, 1, 0, -1, 0, width, 0, 0, 1);
        case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR:
            return SkMatrix::MakeAll(-1, 0, width, 0, 1, 0, 0, 0, 1);
        case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR:
            return SkMatrix::MakeAll(0, -1, height, -1, 0, width, 0, 0, 1);
        case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR:
            return SkMatrix::MakeAll(1, 0, 0, 0, -1, height, 0, 0, 1);
        case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR:
            return SkMatrix::MakeAll(0, 1, 0, 1, 0, 0, 0, 0, 1);
        default:
            LOG_ALWAYS_FATAL("Unsupported pre transform of swapchain.");
    }
    return SkMatrix::I();
}


SkSurface* VulkanManager::getBackbufferSurface(VulkanSurface** surfaceOut) {
    // Recreate VulkanSurface, if ANativeWindow has been resized.
    VulkanSurface* surface = *surfaceOut;
@@ -516,7 +542,7 @@ SkSurface* VulkanManager::getBackbufferSurface(VulkanSurface** surfaceOut) {
        // maybe use attach somehow? but need a Window
        return nullptr;
    }
    if (VK_ERROR_OUT_OF_DATE_KHR == res) {
    if (VK_ERROR_OUT_OF_DATE_KHR == res || VK_SUBOPTIMAL_KHR == res) {
        // tear swapchain down and try again
        if (!createSwapchain(surface)) {
            return nullptr;
@@ -595,6 +621,10 @@ SkSurface* VulkanManager::getBackbufferSurface(VulkanSurface** surfaceOut) {
    }
    backendRT.setVkImageLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);

    surface->mPreTransform = getPreTransformMatrix(surface->windowWidth(),
                                                   surface->windowHeight(),
                                                   surface->mTransform);

    surface->mBackbuffer = std::move(skSurface);
    return surface->mBackbuffer.get();
}
@@ -749,6 +779,17 @@ bool VulkanManager::createSwapchain(VulkanSurface* surface) {
        return false;
    }

    if (!SkToBool(caps.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR)) {
        return false;
    }
    VkSurfaceTransformFlagBitsKHR transform;
    if (SkToBool(caps.supportedTransforms & caps.currentTransform) &&
        !SkToBool(caps.currentTransform & VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR)) {
        transform = caps.currentTransform;
    } else {
        transform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
    }

    VkExtent2D extent = caps.currentExtent;
    // clamp width; to handle currentExtent of -1 and  protect us from broken hints
    if (extent.width < caps.minImageExtent.width) {
@@ -760,6 +801,16 @@ bool VulkanManager::createSwapchain(VulkanSurface* surface) {
        extent.height = caps.minImageExtent.height;
    }
    SkASSERT(extent.height <= caps.maxImageExtent.height);

    VkExtent2D swapExtent = extent;
    if (transform == VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR ||
        transform == VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR ||
        transform == VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR ||
        transform == VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR) {
        swapExtent.width = extent.height;
        swapExtent.height = extent.width;
    }

    surface->mWindowWidth = extent.width;
    surface->mWindowHeight = extent.height;

@@ -775,7 +826,7 @@ bool VulkanManager::createSwapchain(VulkanSurface* surface) {
                                   VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
                                   VK_IMAGE_USAGE_TRANSFER_DST_BIT;
    SkASSERT((caps.supportedUsageFlags & usageFlags) == usageFlags);
    SkASSERT(caps.supportedTransforms & caps.currentTransform);

    SkASSERT(caps.supportedCompositeAlpha &
             (VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR | VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR));
    VkCompositeAlphaFlagBitsKHR composite_alpha =
@@ -822,7 +873,7 @@ bool VulkanManager::createSwapchain(VulkanSurface* surface) {
    swapchainCreateInfo.minImageCount = imageCount;
    swapchainCreateInfo.imageFormat = surfaceFormat;
    swapchainCreateInfo.imageColorSpace = colorSpace;
    swapchainCreateInfo.imageExtent = extent;
    swapchainCreateInfo.imageExtent = swapExtent;
    swapchainCreateInfo.imageArrayLayers = 1;
    swapchainCreateInfo.imageUsage = usageFlags;

@@ -837,7 +888,7 @@ bool VulkanManager::createSwapchain(VulkanSurface* surface) {
        swapchainCreateInfo.pQueueFamilyIndices = nullptr;
    }

    swapchainCreateInfo.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
    swapchainCreateInfo.preTransform = transform;
    swapchainCreateInfo.compositeAlpha = composite_alpha;
    swapchainCreateInfo.presentMode = mode;
    swapchainCreateInfo.clipped = true;
@@ -848,6 +899,8 @@ bool VulkanManager::createSwapchain(VulkanSurface* surface) {
        return false;
    }

    surface->mTransform = transform;

    // destroy the old swapchain
    if (swapchainCreateInfo.oldSwapchain != VK_NULL_HANDLE) {
        mDeviceWaitIdle(mDevice);
@@ -857,7 +910,7 @@ bool VulkanManager::createSwapchain(VulkanSurface* surface) {
        mDestroySwapchainKHR(mDevice, swapchainCreateInfo.oldSwapchain, nullptr);
    }

    createBuffers(surface, surfaceFormat, extent);
    createBuffers(surface, surfaceFormat, swapExtent);

    // The window content is not updated (frozen) until a buffer of the window size is received.
    // This prevents temporary stretching of the window after it is resized, but before the first
Loading