aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar brianosman <brianosman@google.com>2016-06-24 12:50:19 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-06-24 12:50:19 -0700
commita4535a34d1b317543307df6901debfefe7132569 (patch)
treec15e99990ff4bccd09e56e35ccf8441d55e0c83e
parente2cddc5342d5aacacce4429441c94d1e0ff67d8c (diff)
GrColor4f is yet another 4f color type, unfortunately.
- Sk4f would be my choice, but it's not allowed in include/ - SkColor4f and SkPM4f are specified to be unpremultiplied/premultiplied, whereas GrColor (and GrColor4f) are either, depending on context. This adds 12 bytes to GrPaint. Not sure if we want to pay that price. The precision loss for a single value (vs. in a gradient, etc...) may not justify changing the storage type here. Easy enough to back that part out, while still keeping the 4f intermediate type for the helper math that it adds, and for storage and parameter passing in other locations. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2088303002 Review-Url: https://codereview.chromium.org/2088303002
-rw-r--r--include/gpu/GrColor.h48
-rw-r--r--include/gpu/GrPaint.h11
-rw-r--r--src/gpu/GrPaint.cpp4
-rw-r--r--src/gpu/SkGr.cpp28
4 files changed, 80 insertions, 11 deletions
diff --git a/include/gpu/GrColor.h b/include/gpu/GrColor.h
index 77f1a6cb08..911b18fc16 100644
--- a/include/gpu/GrColor.h
+++ b/include/gpu/GrColor.h
@@ -169,6 +169,54 @@ static inline GrColor GrUnpremulColor(GrColor color) {
return GrColorPackRGBA(r, g, b, a);
}
+
+/**
+* Similarly, GrColor4f is 4 floats for R, G, B, A, in that order. And like GrColor, whether
+* the color is premultiplied or not depends on the context.
+*/
+struct GrColor4f {
+ float fRGBA[4];
+
+ GrColor4f() {}
+ GrColor4f(float r, float g, float b, float a) {
+ fRGBA[0] = r;
+ fRGBA[1] = g;
+ fRGBA[2] = b;
+ fRGBA[3] = a;
+ }
+
+ static GrColor4f FromGrColor(GrColor color) {
+ GrColor4f result;
+ GrColorToRGBAFloat(color, result.fRGBA);
+ return result;
+ }
+
+ static GrColor4f FromSkColor4f(const SkColor4f& color) {
+ return GrColor4f(color.fR, color.fG, color.fB, color.fA);
+ }
+
+ GrColor toGrColor() const {
+ return GrColorPackRGBA(
+ SkTPin<unsigned>(static_cast<unsigned>(fRGBA[0] * 255.0f + 0.5f), 0, 255),
+ SkTPin<unsigned>(static_cast<unsigned>(fRGBA[1] * 255.0f + 0.5f), 0, 255),
+ SkTPin<unsigned>(static_cast<unsigned>(fRGBA[2] * 255.0f + 0.5f), 0, 255),
+ SkTPin<unsigned>(static_cast<unsigned>(fRGBA[3] * 255.0f + 0.5f), 0, 255));
+ }
+
+ SkColor4f toSkColor4f() const {
+ return SkColor4f { fRGBA[0], fRGBA[1], fRGBA[2], fRGBA[3] };
+ }
+
+ GrColor4f opaque() const {
+ return GrColor4f(fRGBA[0], fRGBA[1], fRGBA[2], 1.0f);
+ }
+
+ GrColor4f premul() const {
+ float a = fRGBA[3];
+ return GrColor4f(fRGBA[0] * a, fRGBA[1] * a, fRGBA[2] * a, a);
+ }
+};
+
/**
* Flags used for bitfields of color components. They are defined so that the bit order reflects the
* GrColor shift order.
diff --git a/include/gpu/GrPaint.h b/include/gpu/GrPaint.h
index af408488d7..70067ae449 100644
--- a/include/gpu/GrPaint.h
+++ b/include/gpu/GrPaint.h
@@ -48,8 +48,13 @@ public:
/**
* The initial color of the drawn primitive. Defaults to solid white.
*/
- void setColor(GrColor color) { fColor = color; }
- GrColor getColor() const { return fColor; }
+ void setColor4f(const GrColor4f& color) { fColor = color; }
+ const GrColor4f& getColor4f() const { return fColor; }
+
+ /**
+ * Legacy getter, until all code handles 4f directly.
+ */
+ GrColor getColor() const { return fColor.toGrColor(); }
/**
* Should primitives be anti-aliased or not. Defaults to false.
@@ -162,7 +167,7 @@ private:
bool fDisableOutputConversionToSRGB;
bool fAllowSRGBInputs;
- GrColor fColor;
+ GrColor4f fColor;
};
#endif
diff --git a/src/gpu/GrPaint.cpp b/src/gpu/GrPaint.cpp
index fd78f9f819..02518c0464 100644
--- a/src/gpu/GrPaint.cpp
+++ b/src/gpu/GrPaint.cpp
@@ -16,7 +16,7 @@ GrPaint::GrPaint()
: fAntiAlias(false)
, fDisableOutputConversionToSRGB(false)
, fAllowSRGBInputs(false)
- , fColor(GrColor_WHITE) {}
+ , fColor(GrColor4f::FromGrColor(GrColor_WHITE)) {}
void GrPaint::setCoverageSetOpXPFactory(SkRegion::Op regionOp, bool invertCoverage) {
fXPFactory = GrCoverageSetOpXPFactory::Make(regionOp, invertCoverage);
@@ -46,7 +46,7 @@ bool GrPaint::isConstantBlendedColor(GrColor* color) const {
GrProcOptInfo colorProcInfo;
colorProcInfo.calcWithInitialValues(
sk_sp_address_as_pointer_address(fColorFragmentProcessors.begin()),
- this->numColorFragmentProcessors(), fColor, kRGBA_GrColorComponentFlags, false);
+ this->numColorFragmentProcessors(), this->getColor(), kRGBA_GrColorComponentFlags, false);
GrXPFactory::InvariantBlendedColor blendedColor;
if (fXPFactory) {
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index 1e4ff52752..bb0ef91a88 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -28,6 +28,7 @@
#include "SkMessageBus.h"
#include "SkMipMap.h"
#include "SkPixelRef.h"
+#include "SkPM4fPriv.h"
#include "SkResourceCache.h"
#include "SkTemplates.h"
#include "SkYUVPlanesCache.h"
@@ -529,6 +530,16 @@ static inline bool skpaint_to_grpaint_impl(GrContext* context,
grPaint->setAntiAlias(skPaint.isAntiAlias());
grPaint->setAllowSRGBInputs(allowSRGBInputs);
+ // Raw translation of the SkPaint color to our 4f format:
+ GrColor4f origColor = GrColor4f::FromGrColor(SkColorToUnpremulGrColor(skPaint.getColor()));
+
+ // Linearize, if the color is meant to be in sRGB gamma:
+ if (allowSRGBInputs) {
+ origColor.fRGBA[0] = exact_srgb_to_linear(origColor.fRGBA[0]);
+ origColor.fRGBA[1] = exact_srgb_to_linear(origColor.fRGBA[1]);
+ origColor.fRGBA[2] = exact_srgb_to_linear(origColor.fRGBA[2]);
+ }
+
// Setup the initial color considering the shader, the SkPaint color, and the presence or not
// of per-vertex colors.
sk_sp<GrFragmentProcessor> shaderFP;
@@ -559,8 +570,9 @@ static inline bool skpaint_to_grpaint_impl(GrContext* context,
// The geometry processor will insert the primitive color to start the color chain, so
// the GrPaint color will be ignored.
- GrColor shaderInput = SkColorToOpaqueGrColor(skPaint.getColor());
+ GrColor shaderInput = origColor.opaque().toGrColor();
+ // SRGBTODO: Preserve 4f on this code path
shaderFP = GrFragmentProcessor::OverrideInput(shaderFP, shaderInput);
if (primitiveIsSrc) {
shaderFP = GrXfermodeFragmentProcessor::MakeFromDstProcessor(std::move(shaderFP),
@@ -574,6 +586,7 @@ static inline bool skpaint_to_grpaint_impl(GrContext* context,
grPaint->addColorFragmentProcessor(shaderFP);
}
+ // We can ignore origColor here - alpha is unchanged by gamma
GrColor paintAlpha = SkColorAlphaToGrColor(skPaint.getColor());
if (GrColor_WHITE != paintAlpha) {
grPaint->addColorFragmentProcessor(GrConstColorProcessor::Make(
@@ -581,15 +594,16 @@ static inline bool skpaint_to_grpaint_impl(GrContext* context,
}
} else {
// The shader's FP sees the paint unpremul color
- grPaint->setColor(SkColorToUnpremulGrColor(skPaint.getColor()));
+ grPaint->setColor4f(origColor);
grPaint->addColorFragmentProcessor(std::move(shaderFP));
}
} else {
if (primColorMode) {
// There is a blend between the primitive color and the paint color. The blend considers
// the opaque paint color. The paint's alpha is applied to the post-blended color.
+ // SRGBTODO: Preserve 4f on this code path
sk_sp<GrFragmentProcessor> processor(
- GrConstColorProcessor::Make(SkColorToOpaqueGrColor(skPaint.getColor()),
+ GrConstColorProcessor::Make(origColor.opaque().toGrColor(),
GrConstColorProcessor::kIgnore_InputMode));
if (primitiveIsSrc) {
processor = GrXfermodeFragmentProcessor::MakeFromDstProcessor(std::move(processor),
@@ -602,8 +616,9 @@ static inline bool skpaint_to_grpaint_impl(GrContext* context,
grPaint->addColorFragmentProcessor(std::move(processor));
}
- grPaint->setColor(SkColorToOpaqueGrColor(skPaint.getColor()));
+ grPaint->setColor4f(origColor.opaque());
+ // We can ignore origColor here - alpha is unchanged by gamma
GrColor paintAlpha = SkColorAlphaToGrColor(skPaint.getColor());
if (GrColor_WHITE != paintAlpha) {
grPaint->addColorFragmentProcessor(GrConstColorProcessor::Make(
@@ -611,7 +626,7 @@ static inline bool skpaint_to_grpaint_impl(GrContext* context,
}
} else {
// No shader, no primitive color.
- grPaint->setColor(SkColorToPremulGrColor(skPaint.getColor()));
+ grPaint->setColor4f(origColor.premul());
applyColorFilterToPaintColor = true;
}
}
@@ -619,7 +634,8 @@ static inline bool skpaint_to_grpaint_impl(GrContext* context,
SkColorFilter* colorFilter = skPaint.getColorFilter();
if (colorFilter) {
if (applyColorFilterToPaintColor) {
- grPaint->setColor(SkColorToPremulGrColor(colorFilter->filterColor(skPaint.getColor())));
+ grPaint->setColor4f(GrColor4f::FromSkColor4f(
+ colorFilter->filterColor4f(origColor.toSkColor4f())).premul());
} else {
sk_sp<GrFragmentProcessor> cfFP(colorFilter->asFragmentProcessor(context));
if (cfFP) {