Remove SkPM4f

Bug: skia:
Change-Id: If5ed79680f215ac5087469b4c04942885bdb5fd0
Reviewed-on: https://skia-review.googlesource.com/c/159322
Reviewed-by: Mike Klein <mtklein@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
This commit is contained in:
Brian Osman 2018-10-03 15:42:47 -04:00 committed by Skia Commit-Bot
parent 712476ecdb
commit 781e35071d
16 changed files with 101 additions and 145 deletions

View File

@ -228,8 +228,6 @@ SK_API SkPMColor SkPreMultiplyARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b);
*/
SK_API SkPMColor SkPreMultiplyColor(SkColor c);
struct SkPM4f;
template <SkAlphaType kAT>
struct SkRGBA4f {
float fR;
@ -271,6 +269,8 @@ struct SkRGBA4f {
static SkRGBA4f FromColor(SkColor); // impl. depends on kAT
SkColor toSkColor() const; // impl. depends on kAT
static SkRGBA4f FromPMColor(SkPMColor); // impl. depends on kAT
SkRGBA4f<kPremul_SkAlphaType> premul() const {
static_assert(kAT == kUnpremul_SkAlphaType, "");
return { fR * fA, fG * fA, fB * fA, fA };
@ -286,9 +286,6 @@ struct SkRGBA4f {
return { fR * invAlpha, fG * invAlpha, fB * invAlpha, fA };
}
}
// TODO: remove?
SkPM4f toPM4f() const; // impl. depends on kAT
};
using SkColor4f = SkRGBA4f<kUnpremul_SkAlphaType>;

View File

@ -105,25 +105,8 @@ SkColor SkHSVToColor(U8CPU a, const SkScalar hsv[3]) {
///////////////////////////////////////////////////////////////////////////////////////////////////
#include "SkHalf.h"
#include "SkPM4f.h"
SkPM4f SkPM4f::FromPMColor(SkPMColor c) {
return From4f(swizzle_rb_if_bgra(Sk4f_fromL32(c)));
}
SkColor4f SkPM4f::unpremul() const {
float alpha = fVec[A];
if (0 == alpha) {
return { 0, 0, 0, 0 };
} else {
float invAlpha = 1 / alpha;
return { fVec[R] * invAlpha, fVec[G] * invAlpha, fVec[B] * invAlpha, alpha };
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
template <>
SkColor4f SkColor4f::FromColor(SkColor bgra) {
SkColor4f rgba;
@ -136,15 +119,16 @@ SkColor SkColor4f::toSkColor() const {
return Sk4f_toL32(swizzle_rb(Sk4f::Load(this->vec())));
}
template <>
SkPMColor4f SkPMColor4f::FromPMColor(SkPMColor c) {
SkPMColor4f color;
swizzle_rb_if_bgra(Sk4f_fromL32(c)).store(&color);
return color;
}
template <>
SkColor4f SkColor4f::Pin(float r, float g, float b, float a) {
SkColor4f c4;
Sk4f::Min(Sk4f::Max(Sk4f(r, g, b, a), Sk4f(0)), Sk4f(1)).store(c4.vec());
return c4;
}
template <>
SkPM4f SkColor4f::toPM4f() const {
auto rgba = Sk4f::Load(this->vec());
return SkPM4f::From4f(rgba * Sk4f(rgba[3], rgba[3], rgba[3], 1));
}

View File

@ -94,7 +94,7 @@ SkColor4f SkColorFilter::filterColor4f(const SkColor4f& c, SkColorSpace* colorSp
class SkComposeColorFilter : public SkColorFilter {
public:
uint32_t getFlags() const override {
// Can only claim alphaunchanged and SkPM4f support if both our proxys do.
// Can only claim alphaunchanged support if both our proxys do.
return fOuter->getFlags() & fInner->getFlags();
}

View File

@ -44,33 +44,6 @@ static inline uint32_t Sk4f_toL32(const Sk4f& px) {
return l32;
}
/*
* The float values are 0...1 premultiplied in RGBA order (regardless of SkPMColor order)
*/
struct SK_API SkPM4f {
enum {
R, G, B, A,
};
float fVec[4];
float r() const { return fVec[R]; }
float g() const { return fVec[G]; }
float b() const { return fVec[B]; }
float a() const { return fVec[A]; }
static SkPM4f From4f(const Sk4f& x) {
SkPM4f pm;
x.store(pm.fVec);
return pm;
}
static SkPM4f FromPMColor(SkPMColor);
Sk4f to4f() const { return Sk4f::Load(fVec); }
Sk4f to4f_pmorder() const { return swizzle_rb_if_bgra(this->to4f()); }
SkColor4f unpremul() const;
};
using SkPMColor4f = SkRGBA4f<kPremul_SkAlphaType>;
#endif

View File

@ -81,7 +81,7 @@ private:
float fCurrentCoverage = 0.0f;
float fDitherRate = 0.0f;
std::vector<SkPM4f> fShaderBuffer;
std::vector<SkPMColor4f> fShaderBuffer;
typedef SkBlitter INHERITED;
};

View File

@ -54,13 +54,13 @@ void SkOverdrawColorFilter::onAppendStages(SkRasterPipeline* p,
ctx->colors = fColors;
ctx->fn = [](SkJumper_CallbackCtx* arg, int active_pixels) {
auto ctx = (Ctx*)arg;
auto pixels = (SkPM4f*)ctx->rgba;
auto pixels = (SkPMColor4f*)ctx->rgba;
for (int i = 0; i < active_pixels; i++) {
uint8_t alpha = (int)(pixels[i].a() * 255);
uint8_t alpha = (int)(pixels[i].fA * 255);
if (alpha >= kNumColors) {
alpha = kNumColors - 1;
}
pixels[i] = SkPM4f::FromPMColor(ctx->colors[alpha]);
pixels[i] = SkPMColor4f::FromPMColor(ctx->colors[alpha]);
}
};
p->append(SkRasterPipeline::callback, ctx);

View File

@ -56,7 +56,7 @@ SkColorShader::ColorShaderContext::ColorShaderContext(const SkColorShader& shade
SkColor4f c4 = SkColor4f::FromColor(shader.fColor);
c4.fA *= rec.fPaint->getAlpha() / 255.0f;
fPM4f = c4.toPM4f();
fPMColor4f = c4.premul();
fFlags = kConstInY32_Flag;
if (255 == a) {
@ -68,9 +68,9 @@ void SkColorShader::ColorShaderContext::shadeSpan(int x, int y, SkPMColor span[]
sk_memset32(span, fPMColor, count);
}
void SkColorShader::ColorShaderContext::shadeSpan4f(int x, int y, SkPM4f span[], int count) {
void SkColorShader::ColorShaderContext::shadeSpan4f(int x, int y, SkPMColor4f span[], int count) {
for (int i = 0; i < count; ++i) {
span[i] = fPM4f;
span[i] = fPMColor4f;
}
}
@ -171,7 +171,7 @@ SkColor4Shader::Color4Context::Color4Context(const SkColor4Shader& shader,
SkColor4f c4 = shader.fColor4;
c4.fA *= rec.fPaint->getAlpha() * (1 / 255.0f);
fPM4f = c4.toPM4f();
fPMColor4f = c4.premul();
fFlags = kConstInY32_Flag;
if (255 == a) {
@ -183,9 +183,9 @@ void SkColor4Shader::Color4Context::shadeSpan(int x, int y, SkPMColor span[], in
sk_memset32(span, fPMColor, count);
}
void SkColor4Shader::Color4Context::shadeSpan4f(int x, int y, SkPM4f span[], int count) {
void SkColor4Shader::Color4Context::shadeSpan4f(int x, int y, SkPMColor4f span[], int count) {
for (int i = 0; i < count; ++i) {
span[i] = fPM4f;
span[i] = fPMColor4f;
}
}

View File

@ -34,10 +34,10 @@ public:
uint32_t getFlags() const override;
void shadeSpan(int x, int y, SkPMColor span[], int count) override;
void shadeSpan4f(int x, int y, SkPM4f[], int count) override;
void shadeSpan4f(int x, int y, SkPMColor4f[], int count) override;
private:
SkPM4f fPM4f;
SkPMColor4f fPMColor4f;
SkPMColor fPMColor;
uint32_t fFlags;
@ -89,10 +89,10 @@ public:
uint32_t getFlags() const override;
void shadeSpan(int x, int y, SkPMColor span[], int count) override;
void shadeSpan4f(int x, int y, SkPM4f[], int count) override;
void shadeSpan4f(int x, int y, SkPMColor4f[], int count) override;
private:
SkPM4f fPM4f;
SkPMColor4f fPMColor4f;
SkPMColor fPMColor;
uint32_t fFlags;

View File

@ -142,14 +142,14 @@ SkShaderBase::Context::Context(const SkShaderBase& shader, const ContextRec& rec
SkShaderBase::Context::~Context() {}
void SkShaderBase::Context::shadeSpan4f(int x, int y, SkPM4f dst[], int count) {
void SkShaderBase::Context::shadeSpan4f(int x, int y, SkPMColor4f dst[], int count) {
const int N = 128;
SkPMColor tmp[N];
while (count > 0) {
int n = SkTMin(count, N);
this->shadeSpan(x, y, tmp, n);
for (int i = 0; i < n; ++i) {
dst[i] = SkPM4f::FromPMColor(tmp[i]);
dst[i] = SkPMColor4f::FromPMColor(tmp[i]);
}
dst += n;
x += n;
@ -232,7 +232,7 @@ bool SkShaderBase::onAppendStages(const StageRec& rec) const {
auto c = (CallbackCtx*)self;
int x = (int)c->rgba[0],
y = (int)c->rgba[1];
c->ctx->shadeSpan4f(x,y, (SkPM4f*)c->rgba, active_pixels);
c->ctx->shadeSpan4f(x,y, (SkPMColor4f*)c->rgba, active_pixels);
};
if (cb->ctx) {

View File

@ -13,6 +13,7 @@
#include "SkMask.h"
#include "SkMatrix.h"
#include "SkNoncopyable.h"
#include "SkPM4f.h"
#include "SkShader.h"
#include "SkTLazy.h"
@ -98,7 +99,7 @@ public:
*/
virtual void shadeSpan(int x, int y, SkPMColor[], int count) = 0;
virtual void shadeSpan4f(int x, int y, SkPM4f[], int count);
virtual void shadeSpan4f(int x, int y, SkPMColor4f[], int count);
// Notification from blitter::blitMask in case we need to see the non-alpha channels
virtual void set3DMask(const SkMask*) {}

View File

@ -13,8 +13,8 @@ namespace {
Sk4f pack_color(const SkColor4f& c4f, bool premul, const Sk4f& component_scale) {
Sk4f pm4f = premul
? c4f.toPM4f().to4f()
: Sk4f{c4f.fR, c4f.fG, c4f.fB, c4f.fA};
? Sk4f::Load(c4f.premul().vec())
: Sk4f::Load(c4f.vec());
if (premul) {
// If the stops are premul, we clamp them to gamut now.
@ -133,8 +133,8 @@ Sk4fGradientInterval::Sk4fGradientInterval(const Sk4f& c0, SkScalar t0,
const Sk4f dc = SkScalarIsFinite(dt) ? (c1 - c0) / dt : 0;
const Sk4f bias = c0 - (SkScalarIsFinite(t0) ? t0 * dc : 0);
bias.store(&fCb.fVec);
dc.store(&fCg.fVec);
bias.store(fCb.vec());
dc.store(fCg.vec());
}
void Sk4fGradientIntervalBuffer::init(const SkGradientShaderBase& shader, SkColorSpace* dstCS,
@ -156,7 +156,7 @@ void Sk4fGradientIntervalBuffer::init(const SkGradientShaderBase& shader, SkColo
// this stage:
//
// 1) scale the color components depending on paint alpha and the requested
// interpolation space (note: the interval color storage is SkPM4f, but
// interpolation space (note: the interval color storage is SkPMColor4f, but
// that doesn't necessarily mean the colors are premultiplied; that
// property is tracked in fColorsArePremul)
//

View File

@ -31,8 +31,8 @@ struct Sk4fGradientInterval {
// Color bias and color gradient, such that for a t in this interval
//
// C = fCb + t * fCg;
SkPM4f fCb, fCg;
SkScalar fT0, fT1;
SkPMColor4f fCb, fCg;
SkScalar fT0, fT1;
};
class Sk4fGradientIntervalBuffer {

View File

@ -32,7 +32,7 @@ struct PremulTraits<ApplyPremul::False> {
template <>
struct PremulTraits<ApplyPremul::True> {
static Sk4f apply(const Sk4f& c) {
const float alpha = c[SkPM4f::A];
const float alpha = c[3];
// FIXME: portable swizzle?
return c * Sk4f(alpha, alpha, alpha, 1);
}
@ -40,7 +40,7 @@ struct PremulTraits<ApplyPremul::True> {
// Struct encapsulating various dest-dependent ops:
//
// - load() Load a SkPM4f value into Sk4f. Normally called once per interval
// - load() Load a SkPMColor4f value into Sk4f. Normally called once per interval
// advance. Also applies a scale and swizzle suitable for DstType.
//
// - store() Store one Sk4f to dest. Optionally handles premul, color space
@ -58,10 +58,11 @@ struct DstTraits<SkPMColor, premul> {
using PM = PremulTraits<premul>;
// For L32, prescaling by 255 saves a per-pixel multiplication when premul is not needed.
static Sk4f load(const SkPM4f& c) {
static Sk4f load(const SkPMColor4f& c) {
Sk4f c4f = swizzle_rb_if_bgra(Sk4f::Load(c.vec()));
return premul == ApplyPremul::False
? c.to4f_pmorder() * Sk4f(255)
: c.to4f_pmorder();
? c4f * Sk4f(255)
: c4f;
}
static void store(const Sk4f& c, SkPMColor* dst, const Sk4f& bias) {
@ -102,27 +103,27 @@ struct DstTraits<SkPMColor, premul> {
};
template <ApplyPremul premul>
struct DstTraits<SkPM4f, premul> {
struct DstTraits<SkPMColor4f, premul> {
using PM = PremulTraits<premul>;
static Sk4f load(const SkPM4f& c) {
return c.to4f();
static Sk4f load(const SkPMColor4f& c) {
return Sk4f::Load(c.vec());
}
static void store(const Sk4f& c, SkPM4f* dst, const Sk4f& /*bias*/) {
PM::apply(c).store(dst->fVec);
static void store(const Sk4f& c, SkPMColor4f* dst, const Sk4f& /*bias*/) {
PM::apply(c).store(dst->vec());
}
static void store(const Sk4f& c, SkPM4f* dst, int n) {
static void store(const Sk4f& c, SkPMColor4f* dst, int n) {
const Sk4f pmc = PM::apply(c);
for (int i = 0; i < n; ++i) {
pmc.store(dst[i].fVec);
pmc.store(dst[i].vec());
}
}
static void store4x(const Sk4f& c0, const Sk4f& c1,
const Sk4f& c2, const Sk4f& c3,
SkPM4f* dst,
SkPMColor4f* dst,
const Sk4f& bias0, const Sk4f& bias1) {
store(c0, dst + 0, bias0);
store(c1, dst + 1, bias1);

View File

@ -185,16 +185,16 @@ LinearGradient4fContext::shadeSpan(int x, int y, SkPMColor dst[], int count) {
}
void SkLinearGradient::
LinearGradient4fContext::shadeSpan4f(int x, int y, SkPM4f dst[], int count) {
LinearGradient4fContext::shadeSpan4f(int x, int y, SkPMColor4f dst[], int count) {
SkASSERT(count > 0);
// 4f dests are dithered at a later stage, if needed.
static constexpr float bias0 = 0,
bias1 = 0;
if (fColorsArePremul) {
this->shadePremulSpan<SkPM4f, ApplyPremul::False>(x, y, dst, count, bias0, bias1);
this->shadePremulSpan<SkPMColor4f, ApplyPremul::False>(x, y, dst, count, bias0, bias1);
} else {
this->shadePremulSpan<SkPM4f, ApplyPremul::True >(x, y, dst, count, bias0, bias1);
this->shadePremulSpan<SkPMColor4f, ApplyPremul::True >(x, y, dst, count, bias0, bias1);
}
}

View File

@ -17,7 +17,7 @@ public:
LinearGradient4fContext(const SkLinearGradient&, const ContextRec&);
void shadeSpan(int x, int y, SkPMColor dst[], int count) override;
void shadeSpan4f(int x, int y, SkPM4f dst[], int count) override;
void shadeSpan4f(int x, int y, SkPMColor4f dst[], int count) override;
private:
using INHERITED = GradientShaderBase4fContext;

View File

@ -217,58 +217,58 @@ void SkGradientShaderBase::flatten(SkWriteBuffer& buffer) const {
desc.flatten(buffer);
}
static void add_stop_color(SkJumper_GradientCtx* ctx, size_t stop, SkPM4f Fs, SkPM4f Bs) {
(ctx->fs[0])[stop] = Fs.r();
(ctx->fs[1])[stop] = Fs.g();
(ctx->fs[2])[stop] = Fs.b();
(ctx->fs[3])[stop] = Fs.a();
(ctx->bs[0])[stop] = Bs.r();
(ctx->bs[1])[stop] = Bs.g();
(ctx->bs[2])[stop] = Bs.b();
(ctx->bs[3])[stop] = Bs.a();
static void add_stop_color(SkJumper_GradientCtx* ctx, size_t stop, SkPMColor4f Fs, SkPMColor4f Bs) {
(ctx->fs[0])[stop] = Fs.fR;
(ctx->fs[1])[stop] = Fs.fG;
(ctx->fs[2])[stop] = Fs.fB;
(ctx->fs[3])[stop] = Fs.fA;
(ctx->bs[0])[stop] = Bs.fR;
(ctx->bs[1])[stop] = Bs.fG;
(ctx->bs[2])[stop] = Bs.fB;
(ctx->bs[3])[stop] = Bs.fA;
}
static void add_const_color(SkJumper_GradientCtx* ctx, size_t stop, SkPM4f color) {
add_stop_color(ctx, stop, {{ 0, 0, 0, 0 }}, color);
static void add_const_color(SkJumper_GradientCtx* ctx, size_t stop, SkPMColor4f color) {
add_stop_color(ctx, stop, { 0, 0, 0, 0 }, color);
}
// Calculate a factor F and a bias B so that color = F*t + B when t is in range of
// the stop. Assume that the distance between stops is 1/gapCount.
static void init_stop_evenly(
SkJumper_GradientCtx* ctx, float gapCount, size_t stop, SkPM4f c_l, SkPM4f c_r) {
SkJumper_GradientCtx* ctx, float gapCount, size_t stop, SkPMColor4f c_l, SkPMColor4f c_r) {
// Clankium's GCC 4.9 targeting ARMv7 is barfing when we use Sk4f math here, so go scalar...
SkPM4f Fs = {{
(c_r.r() - c_l.r()) * gapCount,
(c_r.g() - c_l.g()) * gapCount,
(c_r.b() - c_l.b()) * gapCount,
(c_r.a() - c_l.a()) * gapCount,
}};
SkPM4f Bs = {{
c_l.r() - Fs.r()*(stop/gapCount),
c_l.g() - Fs.g()*(stop/gapCount),
c_l.b() - Fs.b()*(stop/gapCount),
c_l.a() - Fs.a()*(stop/gapCount),
}};
SkPMColor4f Fs = {
(c_r.fR - c_l.fR) * gapCount,
(c_r.fG - c_l.fG) * gapCount,
(c_r.fB - c_l.fB) * gapCount,
(c_r.fA - c_l.fA) * gapCount,
};
SkPMColor4f Bs = {
c_l.fR - Fs.fR*(stop/gapCount),
c_l.fG - Fs.fG*(stop/gapCount),
c_l.fB - Fs.fB*(stop/gapCount),
c_l.fA - Fs.fA*(stop/gapCount),
};
add_stop_color(ctx, stop, Fs, Bs);
}
// For each stop we calculate a bias B and a scale factor F, such that
// for any t between stops n and n+1, the color we want is B[n] + F[n]*t.
static void init_stop_pos(
SkJumper_GradientCtx* ctx, size_t stop, float t_l, float t_r, SkPM4f c_l, SkPM4f c_r) {
SkJumper_GradientCtx* ctx, size_t stop, float t_l, float t_r, SkPMColor4f c_l, SkPMColor4f c_r) {
// See note about Clankium's old compiler in init_stop_evenly().
SkPM4f Fs = {{
(c_r.r() - c_l.r()) / (t_r - t_l),
(c_r.g() - c_l.g()) / (t_r - t_l),
(c_r.b() - c_l.b()) / (t_r - t_l),
(c_r.a() - c_l.a()) / (t_r - t_l),
}};
SkPM4f Bs = {{
c_l.r() - Fs.r()*t_l,
c_l.g() - Fs.g()*t_l,
c_l.b() - Fs.b()*t_l,
c_l.a() - Fs.a()*t_l,
}};
SkPMColor4f Fs = {
(c_r.fR - c_l.fR) / (t_r - t_l),
(c_r.fG - c_l.fG) / (t_r - t_l),
(c_r.fB - c_l.fB) / (t_r - t_l),
(c_r.fA - c_l.fA) / (t_r - t_l),
};
SkPMColor4f Bs = {
c_l.fR - Fs.fR*t_l,
c_l.fG - Fs.fG*t_l,
c_l.fB - Fs.fB*t_l,
c_l.fA - Fs.fA*t_l,
};
ctx->ts[stop] = t_l;
add_stop_color(ctx, stop, Fs, Bs);
}
@ -317,19 +317,19 @@ bool SkGradientShaderBase::onAppendStages(const StageRec& rec) const {
auto prepareColor = [premulGrad, &xformedColors](int i) {
SkColor4f c = xformedColors.fColors[i];
return premulGrad ? c.toPM4f()
: SkPM4f::From4f(Sk4f::Load(&c));
return premulGrad ? c.premul()
: SkPMColor4f{ c.fR, c.fG, c.fB, c.fA };
};
// The two-stop case with stops at 0 and 1.
if (fColorCount == 2 && fOrigPos == nullptr) {
const SkPM4f c_l = prepareColor(0),
c_r = prepareColor(1);
const SkPMColor4f c_l = prepareColor(0),
c_r = prepareColor(1);
// See F and B below.
auto ctx = alloc->make<SkJumper_EvenlySpaced2StopGradientCtx>();
(c_r.to4f() - c_l.to4f()).store(ctx->f);
( c_l.to4f()).store(ctx->b);
(Sk4f::Load(c_r.vec()) - Sk4f::Load(c_l.vec())).store(ctx->f);
( Sk4f::Load(c_l.vec())).store(ctx->b);
ctx->interpolatedInPremul = premulGrad;
p->append(SkRasterPipeline::evenly_spaced_2_stop_gradient, ctx);
@ -351,9 +351,9 @@ bool SkGradientShaderBase::onAppendStages(const StageRec& rec) const {
size_t stopCount = fColorCount;
float gapCount = stopCount - 1;
SkPM4f c_l = prepareColor(0);
SkPMColor4f c_l = prepareColor(0);
for (size_t i = 0; i < stopCount - 1; i++) {
SkPM4f c_r = prepareColor(i + 1);
SkPMColor4f c_r = prepareColor(i + 1);
init_stop_evenly(ctx, gapCount, i, c_l, c_r);
c_l = c_r;
}
@ -381,12 +381,12 @@ bool SkGradientShaderBase::onAppendStages(const StageRec& rec) const {
size_t stopCount = 0;
float t_l = fOrigPos[firstStop];
SkPM4f c_l = prepareColor(firstStop);
SkPMColor4f c_l = prepareColor(firstStop);
add_const_color(ctx, stopCount++, c_l);
// N.B. lastStop is the index of the last stop, not one after.
for (int i = firstStop; i < lastStop; i++) {
float t_r = fOrigPos[i + 1];
SkPM4f c_r = prepareColor(i + 1);
SkPMColor4f c_r = prepareColor(i + 1);
SkASSERT(t_l <= t_r);
if (t_l < t_r) {
init_stop_pos(ctx, stopCount, t_l, t_r, c_l, c_r);