aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar reed <reed@google.com>2016-03-18 12:42:26 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-03-18 12:42:26 -0700
commit58fc94e55fb52704f86aa6fde97719131a3c9ed4 (patch)
treedc8074968cc98643982438862d46acb7032a738a
parentd2497f35ce9e9e70ab6c7acd82b212c80cb86d3a (diff)
allow more options for shader blitprocs
-rw-r--r--include/core/SkShader.h31
-rw-r--r--src/core/SkBlitter_PM4f.cpp45
-rw-r--r--src/core/SkColorShader.h4
-rw-r--r--src/core/SkShader.cpp36
-rw-r--r--src/effects/gradients/Sk4fLinearGradient.cpp24
-rw-r--r--src/effects/gradients/Sk4fLinearGradient.h8
6 files changed, 88 insertions, 60 deletions
diff --git a/include/core/SkShader.h b/include/core/SkShader.h
index 39ffd86f3a..c9c760d06d 100644
--- a/include/core/SkShader.h
+++ b/include/core/SkShader.h
@@ -142,18 +142,35 @@ public:
virtual void shadeSpan4f(int x, int y, SkPM4f[], int count);
+ struct BlitState;
+ typedef void (*BlitBW)(BlitState*,
+ int x, int y, const SkPixmap&, int count);
+ typedef void (*BlitAA)(BlitState*,
+ int x, int y, const SkPixmap&, int count, const SkAlpha[]);
+
struct BlitState {
+ // inputs
Context* fCtx;
SkXfermode* fXfer;
+
+ // outputs
enum { N = 2 };
void* fStorage[N];
+ BlitBW fBlitBW;
+ BlitAA fBlitAA;
};
- typedef void (*BlitProc)(BlitState*,
- int x, int y, const SkPixmap&, int count, const SkAlpha[]);
- BlitProc chooseBlitProc(const SkImageInfo& info, BlitState* state) {
- return this->onChooseBlitProc(info, state);
+
+ // Returns true if one or more of the blitprocs are set in the BlitState
+ bool chooseBlitProcs(const SkImageInfo& info, BlitState* state) {
+ state->fBlitBW = nullptr;
+ state->fBlitAA = nullptr;
+ if (this->onChooseBlitProcs(info, state)) {
+ SkASSERT(state->fBlitBW || state->fBlitAA);
+ return true;
+ }
+ return false;
}
-
+
/**
* The const void* ctx is only const because all the implementations are const.
* This can be changed to non-const if a new shade proc needs to change the ctx.
@@ -188,9 +205,7 @@ public:
MatrixClass getInverseClass() const { return (MatrixClass)fTotalInverseClass; }
const SkMatrix& getCTM() const { return fCTM; }
- virtual BlitProc onChooseBlitProc(const SkImageInfo&, BlitState*) {
- return nullptr;
- }
+ virtual bool onChooseBlitProcs(const SkImageInfo&, BlitState*) { return false; }
private:
SkMatrix fCTM;
diff --git a/src/core/SkBlitter_PM4f.cpp b/src/core/SkBlitter_PM4f.cpp
index da669a2df1..b7d8e7f8d3 100644
--- a/src/core/SkBlitter_PM4f.cpp
+++ b/src/core/SkBlitter_PM4f.cpp
@@ -134,22 +134,22 @@ public:
///////////////////////////////////////////////////////////////////////////////////////////////////
-template <typename State, bool UseBProc> class SkState_Shader_Blitter : public SkShaderBlitter {
+template <typename State> class SkState_Shader_Blitter : public SkShaderBlitter {
public:
SkState_Shader_Blitter(const SkPixmap& device, const SkPaint& paint,
- const SkShader::Context::BlitState& bstate,
- SkShader::Context::BlitProc bproc)
+ const SkShader::Context::BlitState& bstate)
: INHERITED(device, paint, bstate.fCtx)
, fState(device.info(), paint, bstate.fCtx)
, fBState(bstate)
- , fBProc(bproc)
+ , fBlitBW(bstate.fBlitBW)
+ , fBlitAA(bstate.fBlitAA)
{}
void blitH(int x, int y, int width) override {
SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width());
- if (UseBProc) {
- fBProc(&fBState, x, y, fDevice, width, nullptr);
+ if (fBlitBW) {
+ fBlitBW(&fBState, x, y, fDevice, width);
return;
}
@@ -161,9 +161,9 @@ public:
void blitV(int x, int y, int height, SkAlpha alpha) override {
SkASSERT(x >= 0 && y >= 0 && y + height <= fDevice.height());
- if (UseBProc) {
+ if (fBlitAA) {
for (const int bottom = y + height; y < bottom; ++y) {
- fBProc(&fBState, x, y, fDevice, 1, &alpha);
+ fBlitAA(&fBState, x, y, fDevice, 1, &alpha);
}
return;
}
@@ -187,9 +187,9 @@ public:
SkASSERT(x >= 0 && y >= 0 &&
x + width <= fDevice.width() && y + height <= fDevice.height());
- if (UseBProc) {
+ if (fBlitBW) {
for (const int bottom = y + height; y < bottom; ++y) {
- fBProc(&fBState, x, y, fDevice, width, nullptr);
+ fBlitBW(&fBState, x, y, fDevice, width);
}
return;
}
@@ -219,8 +219,8 @@ public:
}
int aa = *antialias;
if (aa) {
- if (UseBProc && (aa == 255)) {
- fBProc(&fBState, x, y, fDevice, count, nullptr);
+ if (fBlitBW && (aa == 255)) {
+ fBlitBW(&fBState, x, y, fDevice, count);
} else {
fShaderContext->shadeSpan4f(x, y, fState.fBuffer, count);
if (aa == 255) {
@@ -282,9 +282,9 @@ public:
const uint8_t* maskRow = (const uint8_t*)mask.getAddr(x, y);
const size_t maskRB = mask.fRowBytes;
- if (UseBProc) {
+ if (fBlitAA) {
for (; y < clip.fBottom; ++y) {
- fBProc(&fBState, x, y, fDevice, width, maskRow);
+ fBlitAA(&fBState, x, y, fDevice, width, maskRow);
maskRow += maskRB;
}
return;
@@ -309,7 +309,8 @@ public:
protected:
State fState;
SkShader::Context::BlitState fBState;
- SkShader::Context::BlitProc fBProc;
+ SkShader::Context::BlitBW fBlitBW;
+ SkShader::Context::BlitAA fBlitAA;
typedef SkShaderBlitter INHERITED;
};
@@ -338,8 +339,7 @@ struct State4f {
SkAutoTMalloc<SkPM4f> fBuffer;
uint32_t fFlags;
- SkShader::Context::BlitState fBState;
- SkShader::Context::BlitProc fBProc;
+ SkShader::Context::BlitState fBState;
};
struct State32 : State4f {
@@ -413,17 +413,12 @@ template <typename State> SkBlitter* create(const SkPixmap& device, const SkPain
if (shaderContext) {
SkShader::Context::BlitState bstate;
+ sk_bzero(&bstate, sizeof(bstate));
bstate.fCtx = shaderContext;
bstate.fXfer = paint.getXfermode();
- auto bproc = shaderContext->chooseBlitProc(device.info(), &bstate);
- if (bproc) {
- return allocator->createT<SkState_Shader_Blitter<State, true>>(device, paint, bstate,
- bproc);
- } else {
- return allocator->createT<SkState_Shader_Blitter<State, false>>(device, paint, bstate,
- bproc);
- }
+ (void)shaderContext->chooseBlitProcs(device.info(), &bstate);
+ return allocator->createT<SkState_Shader_Blitter<State>>(device, paint, bstate);
} else {
SkColor color = paint.getColor();
if (0 == SkColorGetA(color)) {
diff --git a/src/core/SkColorShader.h b/src/core/SkColorShader.h
index cc3ec45e08..db71b6ef9f 100644
--- a/src/core/SkColorShader.h
+++ b/src/core/SkColorShader.h
@@ -36,8 +36,8 @@ public:
void shadeSpan4f(int x, int y, SkPM4f[], int count) override;
protected:
- BlitProc onChooseBlitProc(const SkImageInfo&, BlitState*) override;
-
+ bool onChooseBlitProcs(const SkImageInfo&, BlitState*) override;
+
private:
SkPM4f fPM4f;
SkPMColor fPMColor;
diff --git a/src/core/SkShader.cpp b/src/core/SkShader.cpp
index cb0517bf64..52d0064eb1 100644
--- a/src/core/SkShader.cpp
+++ b/src/core/SkShader.cpp
@@ -361,22 +361,36 @@ void SkColorShader::toString(SkString* str) const {
///////////////////////////////////////////////////////////////////////////////
-static void D32_BlitProc(SkShader::Context::BlitState* state, int x, int y, const SkPixmap& dst,
- int count, const SkAlpha aa[]) {
+static void D32_BlitBW(SkShader::Context::BlitState* state, int x, int y, const SkPixmap& dst,
+ int count) {
+ SkXfermode::D32Proc proc = (SkXfermode::D32Proc)state->fStorage[0];
+ const SkPM4f* src = (const SkPM4f*)state->fStorage[1];
+ proc(state->fXfer, dst.writable_addr32(x, y), src, count, nullptr);
+}
+
+static void D32_BlitAA(SkShader::Context::BlitState* state, int x, int y, const SkPixmap& dst,
+ int count, const SkAlpha aa[]) {
SkXfermode::D32Proc proc = (SkXfermode::D32Proc)state->fStorage[0];
const SkPM4f* src = (const SkPM4f*)state->fStorage[1];
proc(state->fXfer, dst.writable_addr32(x, y), src, count, aa);
}
-static void D64_BlitProc(SkShader::Context::BlitState* state, int x, int y, const SkPixmap& dst,
- int count, const SkAlpha aa[]) {
+static void D64_BlitBW(SkShader::Context::BlitState* state, int x, int y, const SkPixmap& dst,
+ int count) {
+ SkXfermode::D64Proc proc = (SkXfermode::D64Proc)state->fStorage[0];
+ const SkPM4f* src = (const SkPM4f*)state->fStorage[1];
+ proc(state->fXfer, dst.writable_addr64(x, y), src, count, nullptr);
+}
+
+static void D64_BlitAA(SkShader::Context::BlitState* state, int x, int y, const SkPixmap& dst,
+ int count, const SkAlpha aa[]) {
SkXfermode::D64Proc proc = (SkXfermode::D64Proc)state->fStorage[0];
const SkPM4f* src = (const SkPM4f*)state->fStorage[1];
proc(state->fXfer, dst.writable_addr64(x, y), src, count, aa);
}
-SkShader::Context::BlitProc
-SkColorShader::ColorShaderContext::onChooseBlitProc(const SkImageInfo& info, BlitState* state) {
+bool SkColorShader::ColorShaderContext::onChooseBlitProcs(const SkImageInfo& info,
+ BlitState* state) {
uint32_t flags = SkXfermode::kSrcIsSingle_D32Flag;
if (fPM4f.a() == 1) {
flags |= SkXfermode::kSrcIsOpaque_D32Flag;
@@ -388,14 +402,18 @@ SkColorShader::ColorShaderContext::onChooseBlitProc(const SkImageInfo& info, Bli
}
state->fStorage[0] = (void*)SkXfermode::GetD32Proc(state->fXfer, flags);
state->fStorage[1] = &fPM4f;
- return D32_BlitProc;
+ state->fBlitBW = D32_BlitBW;
+ state->fBlitAA = D32_BlitAA;
+ return true;
case kRGBA_F16_SkColorType:
flags |= SkXfermode::kDstIsFloat16_D64Flag;
state->fStorage[0] = (void*)SkXfermode::GetD64Proc(state->fXfer, flags);
state->fStorage[1] = &fPM4f;
- return D64_BlitProc;
+ state->fBlitBW = D64_BlitBW;
+ state->fBlitAA = D64_BlitAA;
+ return true;
default:
- return nullptr;
+ return false;
}
}
diff --git a/src/effects/gradients/Sk4fLinearGradient.cpp b/src/effects/gradients/Sk4fLinearGradient.cpp
index 82b2fcc69b..84b266accd 100644
--- a/src/effects/gradients/Sk4fLinearGradient.cpp
+++ b/src/effects/gradients/Sk4fLinearGradient.cpp
@@ -442,32 +442,34 @@ LinearGradient4fContext::mapTs(int x, int y, SkScalar ts[], int count) const {
}
}
-SkShader::Context::BlitProc SkLinearGradient::
-LinearGradient4fContext::onChooseBlitProc(const SkImageInfo& info, BlitState* state) {
+bool SkLinearGradient::LinearGradient4fContext::onChooseBlitProcs(const SkImageInfo& info,
+ BlitState* state) {
SkXfermode::Mode mode;
if (!SkXfermode::AsMode(state->fXfer, &mode)) {
- return nullptr;
+ return false;
}
const SkGradientShaderBase& shader = static_cast<const SkGradientShaderBase&>(fShader);
if (mode != SkXfermode::kSrc_Mode &&
!(mode == SkXfermode::kSrcOver_Mode && shader.colorsAreOpaque())) {
- return nullptr;
+ return false;
}
switch (info.colorType()) {
case kN32_SkColorType:
- return D32_BlitProc;
+ state->fBlitBW = D32_BlitBW;
+ return true;
case kRGBA_F16_SkColorType:
- return D64_BlitProc;
+ state->fBlitBW = D64_BlitBW;
+ return true;
default:
- return nullptr;
+ return false;
}
}
void SkLinearGradient::
-LinearGradient4fContext::D32_BlitProc(BlitState* state, int x, int y, const SkPixmap& dst,
- int count, const SkAlpha aa[]) {
+LinearGradient4fContext::D32_BlitBW(BlitState* state, int x, int y, const SkPixmap& dst,
+ int count) {
// FIXME: ignoring coverage for now
const LinearGradient4fContext* ctx =
static_cast<const LinearGradient4fContext*>(state->fCtx);
@@ -492,8 +494,8 @@ LinearGradient4fContext::D32_BlitProc(BlitState* state, int x, int y, const SkPi
}
void SkLinearGradient::
-LinearGradient4fContext::D64_BlitProc(BlitState* state, int x, int y, const SkPixmap& dst,
- int count, const SkAlpha aa[]) {
+LinearGradient4fContext::D64_BlitBW(BlitState* state, int x, int y, const SkPixmap& dst,
+ int count) {
// FIXME: ignoring coverage for now
const LinearGradient4fContext* ctx =
static_cast<const LinearGradient4fContext*>(state->fCtx);
diff --git a/src/effects/gradients/Sk4fLinearGradient.h b/src/effects/gradients/Sk4fLinearGradient.h
index 9bce47c33d..30292c361f 100644
--- a/src/effects/gradients/Sk4fLinearGradient.h
+++ b/src/effects/gradients/Sk4fLinearGradient.h
@@ -22,7 +22,7 @@ public:
protected:
void mapTs(int x, int y, SkScalar ts[], int count) const override;
- BlitProc onChooseBlitProc(const SkImageInfo&, BlitState*) override;
+ bool onChooseBlitProcs(const SkImageInfo&, BlitState*) override;
private:
using INHERITED = GradientShaderBase4fContext;
@@ -40,10 +40,8 @@ private:
bool isFast() const { return fDstToPosClass == kLinear_MatrixClass; }
- static void D32_BlitProc(BlitState* state, int x, int y, const SkPixmap& dst,
- int count, const SkAlpha aa[]);
- static void D64_BlitProc(BlitState*, int x, int y, const SkPixmap& dst,
- int count, const SkAlpha aa[]);
+ static void D32_BlitBW(BlitState*, int x, int y, const SkPixmap& dst, int count);
+ static void D64_BlitBW(BlitState*, int x, int y, const SkPixmap& dst, int count);
mutable const Interval* fCachedInterval;
};