Switch SkPaint's color to SkColor4f
Change-Id: Ic2b83a05739720013a7c30ec014df0747b3f99a5
Reviewed-on: https://skia-review.googlesource.com/149229
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Klein <mtklein@google.com>
diff --git a/include/core/SkPaint.h b/include/core/SkPaint.h
index 46cf308..5590ebb 100644
--- a/include/core/SkPaint.h
+++ b/include/core/SkPaint.h
@@ -28,6 +28,7 @@
class GrTextBlob;
class SkAutoDescriptor;
class SkColorFilter;
+class SkColorSpace;
class SkData;
class SkDescriptor;
class SkDrawLooper;
@@ -494,7 +495,14 @@
@return unpremultiplied ARGB
*/
- SkColor getColor() const { return fColor; }
+ SkColor getColor() const { return fColor4f.toSkColor(); }
+
+ /** Retrieves alpha and RGB, unpmreultiplied, as four floating point values. RGB are
+ are extended sRGB values (sRGB gamut, and encoded with the sRGB transfer function).
+
+ @return unpremultiplied RGBA
+ */
+ SkColor4f getColor4f() const { return fColor4f; }
/** Sets alpha and RGB used when stroking and filling. The color is a 32-bit value,
unpremultiplied, packing 8-bit components for alpha, red, blue, and green.
@@ -503,11 +511,21 @@
*/
void setColor(SkColor color);
+ /** Sets alpha and RGB used when stroking and filling. The color is four floating
+ point values, unpremultiplied. The color values are interpreted as being in
+ the colorSpace. If colorSpace is nullptr, then color is assumed to be in the
+ sRGB color space.
+
+ @param color unpremultiplied RGBA
+ @param colorSpace SkColorSpace describing the encoding of color
+ */
+ void setColor4f(const SkColor4f& color, SkColorSpace* colorSpace);
+
/** Retrieves alpha from the color used when stroking and filling.
@return alpha ranging from zero, fully transparent, to 255, fully opaque
*/
- uint8_t getAlpha() const { return SkToU8(SkColorGetA(fColor)); }
+ uint8_t getAlpha() const { return sk_float_round2int(fColor4f.fA * 255); }
/** Replaces alpha, leaving RGB
unchanged. An out of range value triggers an assert in the debug
@@ -1469,7 +1487,7 @@
SkScalar fTextSize;
SkScalar fTextScaleX;
SkScalar fTextSkewX;
- SkColor fColor;
+ SkColor4f fColor4f;
SkScalar fWidth;
SkScalar fMiterLimit;
uint32_t fBlendMode; // just need 5-6 bits
diff --git a/include/core/SkPicture.h b/include/core/SkPicture.h
index 511999a..b870235 100644
--- a/include/core/SkPicture.h
+++ b/include/core/SkPicture.h
@@ -266,7 +266,7 @@
// Only SKPs within the min/current picture version range (inclusive) can be read.
static const uint32_t MIN_PICTURE_VERSION = 56; // august 2017
- static const uint32_t CURRENT_PICTURE_VERSION = 64;
+ static const uint32_t CURRENT_PICTURE_VERSION = 65;
static_assert(MIN_PICTURE_VERSION <= 62, "Remove kFontAxes_bad from SkFontDescriptor.cpp");
diff --git a/src/atlastext/SkAtlasTextTarget.cpp b/src/atlastext/SkAtlasTextTarget.cpp
index 848106a..c85e8d0 100644
--- a/src/atlastext/SkAtlasTextTarget.cpp
+++ b/src/atlastext/SkAtlasTextTarget.cpp
@@ -105,7 +105,7 @@
void makeGrPaint(GrMaskFormat, const SkPaint& skPaint, const SkMatrix&,
GrPaint* grPaint) override {
- grPaint->setColor4f(SkColorToPremulGrColor4fLegacy(skPaint.getColor()));
+ grPaint->setColor4f(SkColor4fToPremulGrColor4fLegacy(skPaint.getColor4f()));
}
GrContext* getContext() override {
diff --git a/src/core/SkGlyphRunPainter.cpp b/src/core/SkGlyphRunPainter.cpp
index 13c1e06..ee002e1 100644
--- a/src/core/SkGlyphRunPainter.cpp
+++ b/src/core/SkGlyphRunPainter.cpp
@@ -290,7 +290,7 @@
// -- GrTextContext --------------------------------------------------------------------------------
GrColor generate_filtered_color(const SkPaint& paint, const GrColorSpaceInfo& colorSpaceInfo) {
- GrColor4f filteredColor = SkColorToUnpremulGrColor4f(paint.getColor(), colorSpaceInfo);
+ GrColor4f filteredColor = SkColor4fToUnpremulGrColor4f(paint.getColor4f(), colorSpaceInfo);
if (paint.getColorFilter() != nullptr) {
filteredColor = GrColor4f::FromSkColor4f(
paint.getColorFilter()->filterColor4f(filteredColor.toSkColor4f(),
diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp
index 15aa44e..43c568b 100644
--- a/src/core/SkPaint.cpp
+++ b/src/core/SkPaint.cpp
@@ -8,6 +8,8 @@
#include "SkPaint.h"
#include "SkColorFilter.h"
+#include "SkColorSpacePriv.h"
+#include "SkColorSpaceXformSteps.h"
#include "SkData.h"
#include "SkDraw.h"
#include "SkFontDescriptor.h"
@@ -52,7 +54,7 @@
fTextSize = SkPaintDefaults_TextSize;
fTextScaleX = SK_Scalar1;
fTextSkewX = 0;
- fColor = SK_ColorBLACK;
+ fColor4f = { 0, 0, 0, 1 }; // opaque black
fWidth = 0;
fMiterLimit = SkPaintDefaults_MiterLimit;
fBlendMode = (unsigned)SkBlendMode::kSrcOver;
@@ -80,7 +82,7 @@
, COPY(fTextSize)
, COPY(fTextScaleX)
, COPY(fTextSkewX)
- , COPY(fColor)
+ , COPY(fColor4f)
, COPY(fWidth)
, COPY(fMiterLimit)
, COPY(fBlendMode)
@@ -100,7 +102,7 @@
MOVE(fTextSize);
MOVE(fTextScaleX);
MOVE(fTextSkewX);
- MOVE(fColor);
+ MOVE(fColor4f);
MOVE(fWidth);
MOVE(fMiterLimit);
MOVE(fBlendMode);
@@ -126,7 +128,7 @@
ASSIGN(fTextSize);
ASSIGN(fTextScaleX);
ASSIGN(fTextSkewX);
- ASSIGN(fColor);
+ ASSIGN(fColor4f);
ASSIGN(fWidth);
ASSIGN(fMiterLimit);
ASSIGN(fBlendMode);
@@ -152,7 +154,7 @@
MOVE(fTextSize);
MOVE(fTextScaleX);
MOVE(fTextSkewX);
- MOVE(fColor);
+ MOVE(fColor4f);
MOVE(fWidth);
MOVE(fMiterLimit);
MOVE(fBlendMode);
@@ -174,7 +176,7 @@
&& EQUAL(fTextSize)
&& EQUAL(fTextScaleX)
&& EQUAL(fTextSkewX)
- && EQUAL(fColor)
+ && EQUAL(fColor4f)
&& EQUAL(fWidth)
&& EQUAL(fMiterLimit)
&& EQUAL(fBlendMode)
@@ -257,12 +259,18 @@
}
void SkPaint::setColor(SkColor color) {
- fColor = color;
+ fColor4f = SkColor4f::FromColor(color);
+}
+
+void SkPaint::setColor4f(const SkColor4f& color, SkColorSpace* colorSpace) {
+ SkColorSpaceXformSteps steps{colorSpace, kUnpremul_SkAlphaType,
+ sk_srgb_singleton(), kUnpremul_SkAlphaType};
+ fColor4f = color;
+ steps.apply(fColor4f.vec());
}
void SkPaint::setAlpha(U8CPU a) {
- this->setColor(SkColorSetARGB(a, SkColorGetR(fColor),
- SkColorGetG(fColor), SkColorGetB(fColor)));
+ fColor4f.fA = a * (1.0f / 255);
}
void SkPaint::setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) {
@@ -1196,7 +1204,7 @@
buffer.writeScalar(paint.getTextSkewX());
buffer.writeScalar(paint.getStrokeWidth());
buffer.writeScalar(paint.getStrokeMiter());
- buffer.writeColor(paint.getColor());
+ buffer.writeColor4f(paint.getColor4f());
buffer.writeUInt(pack_paint_flags(paint.getFlags(), paint.getHinting(), paint.getTextAlign(),
paint.getFilterQuality(), flatFlags));
@@ -1225,7 +1233,13 @@
paint->setTextSkewX(buffer.readScalar());
paint->setStrokeWidth(buffer.readScalar());
paint->setStrokeMiter(buffer.readScalar());
- paint->setColor(buffer.readColor());
+ if (buffer.isVersionLT(SkReadBuffer::kFloat4PaintColor_Version)) {
+ paint->setColor(buffer.readColor());
+ } else {
+ SkColor4f color;
+ buffer.readColor4f(&color);
+ paint->setColor4f(color, sk_srgb_singleton());
+ }
unsigned flatFlags = unpack_paint_flags(paint, buffer.readUInt());
@@ -1494,9 +1508,9 @@
}
uint32_t SkPaint::getHash() const {
- // We're going to hash 7 pointers and 7 32-bit values, finishing up with fBitfields,
- // so fBitfields should be 7 pointers and 6 32-bit values from the start.
- static_assert(offsetof(SkPaint, fBitfields) == 7 * sizeof(void*) + 7 * sizeof(uint32_t),
+ // We're going to hash 7 pointers and 11 32-bit values, finishing up with fBitfields,
+ // so fBitfields should be 7 pointers and 10 32-bit values from the start.
+ static_assert(offsetof(SkPaint, fBitfields) == 7 * sizeof(void*) + 10 * sizeof(uint32_t),
"SkPaint_notPackedTightly");
return SkOpts::hash(reinterpret_cast<const uint32_t*>(this),
offsetof(SkPaint, fBitfields) + sizeof(fBitfields));
diff --git a/src/core/SkReadBuffer.h b/src/core/SkReadBuffer.h
index 4a0a263..c539d16 100644
--- a/src/core/SkReadBuffer.h
+++ b/src/core/SkReadBuffer.h
@@ -80,6 +80,7 @@
kDontNegateImageSize_Version = 62,
kStoreImageBounds_Version = 63,
kRemoveOccluderFromBlurMaskFilter = 64,
+ kFloat4PaintColor_Version = 65,
};
/**
diff --git a/src/gpu/SkGpuDevice_drawTexture.cpp b/src/gpu/SkGpuDevice_drawTexture.cpp
index 47ee36a..a29e4ec 100644
--- a/src/gpu/SkGpuDevice_drawTexture.cpp
+++ b/src/gpu/SkGpuDevice_drawTexture.cpp
@@ -134,7 +134,7 @@
color = paintColorXform ? SkColorToUnpremulGrColor(paint.getColor())
: SkColorToPremulGrColor(paint.getColor());
} else {
- color = SkColorAlphaToGrColor(paint.getColor());
+ color = GrColorPackA4(paint.getAlpha());
}
rtc->drawTexture(clip, std::move(proxy), filter, color, srcRect, dstRect, aa, constraint, ctm,
std::move(textureXform), std::move(paintColorXform));
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index 0cc2f20..b79f01f 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -257,15 +257,15 @@
GrColor4f SkColorToPremulGrColor4f(SkColor c, const GrColorSpaceInfo& colorSpaceInfo) {
// We want to premultiply after color space conversion, so this is easy:
- return SkColorToUnpremulGrColor4f(c, colorSpaceInfo).premul();
+ return SkColor4fToUnpremulGrColor4f(SkColor4f::FromColor(c), colorSpaceInfo).premul();
}
-GrColor4f SkColorToPremulGrColor4fLegacy(SkColor c) {
- return GrColor4f::FromGrColor(SkColorToUnpremulGrColor(c)).premul();
+GrColor4f SkColor4fToPremulGrColor4fLegacy(SkColor4f c) {
+ return GrColor4f::FromSkColor4f(c).premul();
}
-GrColor4f SkColorToUnpremulGrColor4f(SkColor c, const GrColorSpaceInfo& colorSpaceInfo) {
- GrColor4f color = GrColor4f::FromGrColor(SkColorToUnpremulGrColor(c));
+GrColor4f SkColor4fToUnpremulGrColor4f(SkColor4f c, const GrColorSpaceInfo& colorSpaceInfo) {
+ GrColor4f color = GrColor4f::FromSkColor4f(c);
if (auto* xform = colorSpaceInfo.colorSpaceXformFromSRGB()) {
color = xform->apply(color);
}
@@ -367,7 +367,7 @@
SkBlendMode* primColorMode,
GrPaint* grPaint) {
// Convert SkPaint color to 4f format in the destination color space
- GrColor4f origColor = SkColorToUnpremulGrColor4f(skPaint.getColor(), colorSpaceInfo);
+ GrColor4f origColor = SkColor4fToUnpremulGrColor4f(skPaint.getColor4f(), colorSpaceInfo);
const GrFPArgs fpArgs(context, &viewM, skPaint.getFilterQuality(), &colorSpaceInfo);
@@ -409,7 +409,7 @@
}
// We can ignore origColor here - alpha is unchanged by gamma
- GrColor paintAlpha = SkColorAlphaToGrColor(skPaint.getColor());
+ GrColor paintAlpha = GrColorPackA4(skPaint.getAlpha());
if (GrColor_WHITE != paintAlpha) {
// No gamut conversion - paintAlpha is a (linear) alpha value, splatted to all
// color channels. It's value should be treated as the same in ANY color space.
@@ -437,7 +437,7 @@
grPaint->setColor4f(origColor.opaque());
// We can ignore origColor here - alpha is unchanged by gamma
- GrColor paintAlpha = SkColorAlphaToGrColor(skPaint.getColor());
+ GrColor paintAlpha = GrColorPackA4(skPaint.getAlpha());
if (GrColor_WHITE != paintAlpha) {
// No gamut conversion - paintAlpha is a (linear) alpha value, splatted to all
// color channels. It's value should be treated as the same in ANY color space.
diff --git a/src/gpu/SkGr.h b/src/gpu/SkGr.h
index ec9f30a..1501f90 100644
--- a/src/gpu/SkGr.h
+++ b/src/gpu/SkGr.h
@@ -58,16 +58,11 @@
return GrColorPackRGBA(r, g, b, a);
}
-/** Transform an SkColor (sRGB bytes) to GrColor4f for the specified color space info. */
+/** Transform an SkColor (sRGB bytes) or SkColor4f (sRGB floats) to GrColor4f
+ for the specified color space info. */
GrColor4f SkColorToPremulGrColor4f(SkColor, const GrColorSpaceInfo&);
-GrColor4f SkColorToPremulGrColor4fLegacy(SkColor);
-GrColor4f SkColorToUnpremulGrColor4f(SkColor, const GrColorSpaceInfo&);
-
-/** Replicates the SkColor's alpha to all four channels of the GrColor. */
-static inline GrColor SkColorAlphaToGrColor(SkColor c) {
- U8CPU a = SkColorGetA(c);
- return GrColorPackRGBA(a, a, a, a);
-}
+GrColor4f SkColor4fToPremulGrColor4fLegacy(SkColor4f);
+GrColor4f SkColor4fToUnpremulGrColor4f(SkColor4f, const GrColorSpaceInfo&);
//////////////////////////////////////////////////////////////////////////////