[graphite] Apply colorSpace to the SkPaint's color
Bug: b/239959460
Change-Id: Iee9ab67f813f5f863e255b189c2a2b6f1219faf5
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/638977
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: James Godfrey-Kittle <jamesgk@google.com>
diff --git a/src/gpu/graphite/Device.cpp b/src/gpu/graphite/Device.cpp
index 02aee14..16f7ccf 100644
--- a/src/gpu/graphite/Device.cpp
+++ b/src/gpu/graphite/Device.cpp
@@ -105,16 +105,20 @@
}
/** If the paint can be reduced to a solid flood-fill, determine the correct color to fill with. */
-std::optional<SkColor4f> extract_paint_color(const SkPaint& paint) {
+std::optional<SkColor4f> extract_paint_color(const SkPaint& paint,
+ const SkColorInfo& dstColorInfo) {
SkASSERT(!paint_depends_on_dst(paint));
if (paint.getShader()) {
return std::nullopt;
}
+
+ SkColor4f dstPaintColor = PaintParams::Color4fPrepForDst(paint.getColor4f(), dstColorInfo);
+
if (SkColorFilter* filter = paint.getColorFilter()) {
- // TODO: SkColorSpace support
- return filter->filterColor4f(paint.getColor4f(), sk_srgb_singleton(), sk_srgb_singleton());
+ SkColorSpace* dstCS = dstColorInfo.colorSpace();
+ return filter->filterColor4f(dstPaintColor, dstCS, dstCS);
}
- return paint.getColor4f();
+ return dstPaintColor;
}
SkIRect rect_to_pixelbounds(const Rect& r) {
@@ -601,7 +605,7 @@
// entire final surface.
if (this->clipIsWideOpen() && !fDC->target()->isFullyLazy()) {
if (!paint_depends_on_dst(paint)) {
- if (std::optional<SkColor4f> color = extract_paint_color(paint)) {
+ if (std::optional<SkColor4f> color = extract_paint_color(paint, fDC->colorInfo())) {
// do fullscreen clear
fDC->clear(*color);
return;
diff --git a/src/gpu/graphite/DrawContext.h b/src/gpu/graphite/DrawContext.h
index fed052a..dfc5292 100644
--- a/src/gpu/graphite/DrawContext.h
+++ b/src/gpu/graphite/DrawContext.h
@@ -55,7 +55,8 @@
~DrawContext() override;
- const SkImageInfo& imageInfo() const { return fImageInfo; }
+ const SkImageInfo& imageInfo() const { return fImageInfo; }
+ const SkColorInfo& colorInfo() const { return fImageInfo.colorInfo(); }
TextureProxy* target() { return fTarget.get(); }
const TextureProxy* target() const { return fTarget.get(); }
diff --git a/src/gpu/graphite/PaintParams.cpp b/src/gpu/graphite/PaintParams.cpp
index 2a59a96..8c79372 100644
--- a/src/gpu/graphite/PaintParams.cpp
+++ b/src/gpu/graphite/PaintParams.cpp
@@ -11,6 +11,7 @@
#include "include/core/SkShader.h"
#include "src/core/SkBlenderBase.h"
#include "src/core/SkColorFilterBase.h"
+#include "src/core/SkColorSpacePriv.h"
#include "src/gpu/graphite/KeyContext.h"
#include "src/gpu/graphite/KeyHelpers.h"
#include "src/gpu/graphite/PaintParamsKey.h"
@@ -60,13 +61,25 @@
sk_sp<SkBlender> PaintParams::refPrimitiveBlender() const { return fPrimitiveBlender; }
+SkColor4f PaintParams::Color4fPrepForDst(SkColor4f srcColor, const SkColorInfo& dstColorInfo) {
+ // xform from sRGB to the destination colorspace
+ SkColorSpaceXformSteps steps(sk_srgb_singleton(), kUnpremul_SkAlphaType,
+ dstColorInfo.colorSpace(), kUnpremul_SkAlphaType);
+
+ SkColor4f result = srcColor;
+ steps.apply(result.vec());
+ return result;
+}
+
void PaintParams::toKey(const KeyContext& keyContext,
PaintParamsKeyBuilder* builder,
PipelineDataGatherer* gatherer) const {
+ SkColor4f dstPaintColor = Color4fPrepForDst(fColor, keyContext.dstColorInfo());
+
// TODO: figure out how we can omit this block when the Paint's color isn't used.
SolidColorShaderBlock::BeginBlock(keyContext, builder, gatherer,
- fColor.makeOpaque().premul());
+ dstPaintColor.makeOpaque().premul());
builder->endBlock();
if (fShader) {
@@ -79,8 +92,8 @@
}
// Apply the paint's alpha value.
- auto alphaColorFilter = SkColorFilters::Blend({0, 0, 0, fColor[3]},
- /*colorSpace*/nullptr,
+ auto alphaColorFilter = SkColorFilters::Blend({0, 0, 0, fColor.fA},
+ /* colorSpace= */ nullptr,
SkBlendMode::kDstIn);
if (alphaColorFilter) {
as_CFB(alphaColorFilter)->addToKey(keyContext, builder, gatherer);
@@ -92,7 +105,7 @@
if (fFinalBlender) {
as_BB(fFinalBlender)->addToKey(keyContext, builder, gatherer,
- /* primitiveColorBlender= */false);
+ /* primitiveColorBlender= */ false);
} else {
BlendModeBlock::BeginBlock(keyContext, builder, gatherer, SkBlendMode::kSrcOver);
builder->endBlock();
diff --git a/src/gpu/graphite/PaintParams.h b/src/gpu/graphite/PaintParams.h
index 1d16f41..d0f5b89 100644
--- a/src/gpu/graphite/PaintParams.h
+++ b/src/gpu/graphite/PaintParams.h
@@ -11,6 +11,7 @@
#include "include/core/SkColor.h"
#include "include/core/SkPaint.h"
+class SkColorInfo;
class SkShader;
namespace skgpu::graphite {
@@ -59,6 +60,9 @@
bool skipColorXform() const { return fSkipColorXform; }
+ /** Converts an SkColor4f to the destination color space. */
+ static SkColor4f Color4fPrepForDst(SkColor4f srgb, const SkColorInfo& dstColorInfo);
+
void toKey(const KeyContext&,
PaintParamsKeyBuilder*,
PipelineDataGatherer*) const;