diff options
author | 2023-04-04 17:44:23 -0400 | |
---|---|---|
committer | 2023-04-05 10:05:33 -0400 | |
commit | 29b1ee0718032d9ccd3ab143df75342275ebb9b0 (patch) | |
tree | 0920a3703c9119d5579266141655cd96df33a373 | |
parent | 0c02452b81a3d896efd00ccc7fc200cd53a68f39 (diff) |
Force-enable dithering in wide gamut & HDR
Fixes: 276779571
Test: SilkFX gradient sweep
Change-Id: I26907913feb216e43bbbc735878d12311735c3af
-rw-r--r-- | libs/hwui/pipeline/skia/SkiaPipeline.cpp | 28 | ||||
-rw-r--r-- | libs/hwui/pipeline/skia/SkiaPipeline.h | 2 | ||||
-rw-r--r-- | libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp | 5 | ||||
-rw-r--r-- | libs/hwui/pipeline/skia/SkiaVulkanPipeline.h | 2 | ||||
-rw-r--r-- | libs/hwui/renderthread/VulkanSurface.cpp | 10 | ||||
-rw-r--r-- | libs/hwui/renderthread/VulkanSurface.h | 2 |
6 files changed, 47 insertions, 2 deletions
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp index 8ea71f11e2f0..1f929685b62c 100644 --- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp +++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp @@ -28,6 +28,7 @@ #include <SkMultiPictureDocument.h> #include <SkOverdrawCanvas.h> #include <SkOverdrawColorFilter.h> +#include <SkPaintFilterCanvas.h> #include <SkPicture.h> #include <SkPictureRecorder.h> #include <SkRect.h> @@ -36,15 +37,15 @@ #include <SkStream.h> #include <SkString.h> #include <SkTypeface.h> -#include "include/gpu/GpuTypes.h" // from Skia #include <android-base/properties.h> +#include <gui/TraceUtils.h> #include <unistd.h> #include <sstream> -#include <gui/TraceUtils.h> #include "LightingInfo.h" #include "VectorDrawable.h" +#include "include/gpu/GpuTypes.h" // from Skia #include "thread/CommonPool.h" #include "tools/SkSharingProc.h" #include "utils/Color.h" @@ -449,6 +450,23 @@ void SkiaPipeline::endCapture(SkSurface* surface) { } } +class ForceDitherCanvas : public SkPaintFilterCanvas { +public: + ForceDitherCanvas(SkCanvas* canvas) : SkPaintFilterCanvas(canvas) {} + +protected: + bool onFilter(SkPaint& paint) const override { + paint.setDither(true); + return true; + } + + void onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) override { + // We unroll the drawable using "this" canvas, so that draw calls contained inside will + // get dithering applied + drawable->draw(this, matrix); + } +}; + void SkiaPipeline::renderFrame(const LayerUpdateQueue& layers, const SkRect& clip, const std::vector<sp<RenderNode>>& nodes, bool opaque, const Rect& contentDrawBounds, sk_sp<SkSurface> surface, @@ -503,6 +521,12 @@ void SkiaPipeline::renderFrameImpl(const SkRect& clip, canvas->clear(SK_ColorTRANSPARENT); } + std::optional<ForceDitherCanvas> forceDitherCanvas; + if (shouldForceDither()) { + forceDitherCanvas.emplace(canvas); + canvas = &forceDitherCanvas.value(); + } + if (1 == nodes.size()) { if (!nodes[0]->nothingToDraw()) { RenderNodeDrawable root(nodes[0].get(), canvas); diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.h b/libs/hwui/pipeline/skia/SkiaPipeline.h index befee8989383..0763b06b53ef 100644 --- a/libs/hwui/pipeline/skia/SkiaPipeline.h +++ b/libs/hwui/pipeline/skia/SkiaPipeline.h @@ -98,6 +98,8 @@ protected: bool isCapturingSkp() const { return mCaptureMode != CaptureMode::None; } + virtual bool shouldForceDither() const { return mColorMode != ColorMode::Default; } + private: void renderFrameImpl(const SkRect& clip, const std::vector<sp<RenderNode>>& nodes, bool opaque, diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp index c8f2e69ae0a4..6f1b99b95bbd 100644 --- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp +++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp @@ -203,6 +203,11 @@ sk_sp<Bitmap> SkiaVulkanPipeline::allocateHardwareBitmap(renderthread::RenderThr return nullptr; } +bool SkiaVulkanPipeline::shouldForceDither() const { + if (mVkSurface && mVkSurface->isBeyond8Bit()) return false; + return SkiaPipeline::shouldForceDither(); +} + void SkiaVulkanPipeline::onContextDestroyed() { if (mVkSurface) { vulkanManager().destroySurface(mVkSurface); diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h index d921ddb0d0fb..0713e93bccde 100644 --- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h +++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h @@ -63,6 +63,8 @@ public: protected: void onContextDestroyed() override; + bool shouldForceDither() const override; + private: renderthread::VulkanManager& vulkanManager(); renderthread::VulkanSurface* mVkSurface = nullptr; diff --git a/libs/hwui/renderthread/VulkanSurface.cpp b/libs/hwui/renderthread/VulkanSurface.cpp index 21b6c44e997e..ae4f0572576e 100644 --- a/libs/hwui/renderthread/VulkanSurface.cpp +++ b/libs/hwui/renderthread/VulkanSurface.cpp @@ -530,6 +530,16 @@ void VulkanSurface::setColorSpace(sk_sp<SkColorSpace> colorSpace) { } } +bool VulkanSurface::isBeyond8Bit() const { + switch (mWindowInfo.bufferFormat) { + case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM: + case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT: + return true; + default: + return false; + } +} + } /* namespace renderthread */ } /* namespace uirenderer */ } /* namespace android */ diff --git a/libs/hwui/renderthread/VulkanSurface.h b/libs/hwui/renderthread/VulkanSurface.h index e2ddc6b07768..3b69b73bcab3 100644 --- a/libs/hwui/renderthread/VulkanSurface.h +++ b/libs/hwui/renderthread/VulkanSurface.h @@ -48,6 +48,8 @@ public: void setColorSpace(sk_sp<SkColorSpace> colorSpace); + bool isBeyond8Bit() const; + private: /* * All structs/methods in this private section are specifically for use by the VulkanManager |