Update OverdrawColorFilter to clarify how it interprets its input array.
1. Document that Make() takes RGBA_premul
2. Change impl so that CPU matches this behavior/definition
3. Offer a clearer factory that takes SkColor
(perhaps migrate clients to this one in the future)
Bug: skia:9896
Change-Id: I0a81dda45834a2fbf2b28b711ba7e6b83f360aff
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/269906
Commit-Queue: Mike Reed <reed@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
diff --git a/gm/overdrawcanvas.cpp b/gm/overdrawcanvas.cpp
index e953f15..8cd6325 100644
--- a/gm/overdrawcanvas.cpp
+++ b/gm/overdrawcanvas.cpp
@@ -24,7 +24,7 @@
#define WIDTH 500
#define HEIGHT 500
-
+// These are treated as RGBA_premul
static const uint32_t kOverdrawColors[6] = {
0x00000000, 0x5f00005f, 0x2f2f0000, 0x2f002f00, 0x3f00003f, 0x7f00007f,
};
diff --git a/gm/overdrawcolorfilter.cpp b/gm/overdrawcolorfilter.cpp
index 499a047..41d2c59 100644
--- a/gm/overdrawcolorfilter.cpp
+++ b/gm/overdrawcolorfilter.cpp
@@ -35,12 +35,12 @@
SkISize onISize() override { return {200, 400}; }
void onDraw(SkCanvas* canvas) override {
- static const SkPMColor colors[SkOverdrawColorFilter::kNumColors] = {
- 0x80800000, 0x80008000, 0x80000080, 0x80808000, 0x80008080, 0x80800080,
+ static const SkColor colors[SkOverdrawColorFilter::kNumColors] = {
+ 0x80FF0000, 0x8000FF00, 0x800000FF, 0x80FFFF00, 0x8000FFFF, 0x80FF00FF,
};
SkPaint paint;
- sk_sp<SkColorFilter> colorFilter = SkOverdrawColorFilter::Make(colors);
+ sk_sp<SkColorFilter> colorFilter = SkOverdrawColorFilter::MakeWithSkColors(colors);
paint.setColorFilter(colorFilter);
SkImageInfo info = SkImageInfo::MakeA8(100, 100);
diff --git a/include/effects/SkOverdrawColorFilter.h b/include/effects/SkOverdrawColorFilter.h
index a34c376..862587b 100644
--- a/include/effects/SkOverdrawColorFilter.h
+++ b/include/effects/SkOverdrawColorFilter.h
@@ -23,9 +23,10 @@
public:
static constexpr int kNumColors = 6;
- static sk_sp<SkOverdrawColorFilter> Make(const SkPMColor colors[kNumColors]) {
- return sk_sp<SkOverdrawColorFilter>(new SkOverdrawColorFilter(colors));
- }
+ // For historical reasons, this version of Make() assumes the array is RGBA-premul
+ static sk_sp<SkColorFilter> Make(const uint32_t colors[kNumColors]);
+
+ static sk_sp<SkColorFilter> MakeWithSkColors(const SkColor colors[kNumColors]);
#if SK_SUPPORT_GPU
std::unique_ptr<GrFragmentProcessor> asFragmentProcessor(GrRecordingContext*,
@@ -40,9 +41,7 @@
private:
SK_FLATTENABLE_HOOKS(SkOverdrawColorFilter)
- SkOverdrawColorFilter(const SkPMColor colors[kNumColors]) {
- memcpy(fColors, colors, kNumColors * sizeof(SkPMColor));
- }
+ SkOverdrawColorFilter(const SkPMColor colors[kNumColors]);
bool onAppendStages(const SkStageRec&, bool) const override;
diff --git a/src/effects/SkOverdrawColorFilter.cpp b/src/effects/SkOverdrawColorFilter.cpp
index 266c5b1..83d3822 100644
--- a/src/effects/SkOverdrawColorFilter.cpp
+++ b/src/effects/SkOverdrawColorFilter.cpp
@@ -42,6 +42,36 @@
)";
#endif
+#ifdef SK_PMCOLOR_IS_BGRA
+static uint32_t swizzle_rb(uint32_t c) {
+ return SkColorSetARGB(SkColorGetA(c), SkColorGetB(c), SkColorGetG(c), SkColorGetR(c));
+}
+#endif
+
+sk_sp<SkColorFilter> SkOverdrawColorFilter::Make(const uint32_t rgba[kNumColors]) {
+ SkPMColor pm[kNumColors];
+ for (int i = 0; i < kNumColors; ++i) {
+#ifdef SK_PMCOLOR_IS_BGRA
+ pm[i] = swizzle_rb(rgba[i]);
+#else
+ pm[i] = rgba[i];
+#endif
+ }
+ return sk_sp<SkColorFilter>(new SkOverdrawColorFilter(pm));
+}
+
+sk_sp<SkColorFilter> SkOverdrawColorFilter::MakeWithSkColors(const SkColor colors[kNumColors]) {
+ SkPMColor pm[kNumColors];
+ for (int i = 0; i < kNumColors; ++i) {
+ pm[i] = SkPreMultiplyColor(colors[i]);
+ }
+ return sk_sp<SkColorFilter>(new SkOverdrawColorFilter(pm));
+}
+
+SkOverdrawColorFilter::SkOverdrawColorFilter(const SkPMColor colors[kNumColors]) {
+ memcpy(fColors, colors, kNumColors * sizeof(SkPMColor));
+}
+
bool SkOverdrawColorFilter::onAppendStages(const SkStageRec& rec, bool shader_is_opaque) const {
struct Ctx : public SkRasterPipeline_CallbackCtx {
const SkPMColor* colors;
@@ -78,7 +108,7 @@
return nullptr;
}
- return SkOverdrawColorFilter::Make(colors);
+ return sk_sp<SkColorFilter>(new SkOverdrawColorFilter(colors));
}
void SkOverdrawColorFilter::RegisterFlattenables() {
@@ -91,11 +121,11 @@
std::unique_ptr<GrFragmentProcessor> SkOverdrawColorFilter::asFragmentProcessor(
GrRecordingContext* context, const GrColorInfo&) const {
static auto effect = std::get<0>(SkRuntimeEffect::Make(SkString(SKSL_OVERDRAW_SRC)));
- SkASSERT(effect->inputSize() == (kNumColors * sizeof(SkColor4f)));
- auto inputs = SkData::MakeUninitialized(kNumColors * sizeof(SkColor4f));
- SkColor4f* floatColors = reinterpret_cast<SkColor4f*>(inputs->writable_data());
+ SkASSERT(effect->inputSize() == (kNumColors * sizeof(SkPMColor4f)));
+ auto inputs = SkData::MakeUninitialized(kNumColors * sizeof(SkPMColor4f));
+ SkPMColor4f* floatColors = reinterpret_cast<SkPMColor4f*>(inputs->writable_data());
for (int i = 0; i < kNumColors; ++i) {
- floatColors[i] = SkColor4f::FromBytes_RGBA(fColors[i]);
+ floatColors[i] = SkPMColor4f::FromPMColor(fColors[i]);
}
return GrSkSLFP::Make(context, effect, "Overdraw", std::move(inputs));
}