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:
parent
d2497f35ce
commit
58fc94e55f
@ -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;
|
||||
|
@ -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)) {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user