allow more options for shader blitprocs

BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1810383004

Review URL: https://codereview.chromium.org/1810383004
This commit is contained in:
reed 2016-03-18 12:42:26 -07:00 committed by Commit bot
parent d2497f35ce
commit 58fc94e55f
6 changed files with 88 additions and 60 deletions

View File

@ -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;

View File

@ -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)) {

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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;
};