Force-enable dithering in wide gamut & HDR

Fixes: 276779571
Test: SilkFX gradient sweep
Change-Id: I26907913feb216e43bbbc735878d12311735c3af
This commit is contained in:
John Reck
2023-04-04 17:44:23 -04:00
parent 0c02452b81
commit 29b1ee0718
6 changed files with 47 additions and 2 deletions

View File

@@ -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);

View File

@@ -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,

View File

@@ -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);

View File

@@ -63,6 +63,8 @@ public:
protected:
void onContextDestroyed() override;
bool shouldForceDither() const override;
private:
renderthread::VulkanManager& vulkanManager();
renderthread::VulkanSurface* mVkSurface = nullptr;

View File

@@ -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 */

View File

@@ -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