Index: src/core/SkBlitter_PM4f.cpp |
diff --git a/src/core/SkBlitter_PM4f.cpp b/src/core/SkBlitter_PM4f.cpp |
index 24fc4a39ddbebb732f0fca1763f4aba6d719fe36..179aec355743d62d9ce45d9dd486d212275790f1 100644 |
--- a/src/core/SkBlitter_PM4f.cpp |
+++ b/src/core/SkBlitter_PM4f.cpp |
@@ -27,7 +27,8 @@ public: |
void blitH(int x, int y, int width) override { |
SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width()); |
- fState.fProc1(fState, State::WritableAddr(fDevice, x, y), fState.fPM4f, width, nullptr); |
+ fState.fProc1(fState.fXfer, State::WritableAddr(fDevice, x, y), |
+ &fState.fPM4f, width, nullptr); |
} |
void blitV(int x, int y, int height, SkAlpha alpha) override { |
@@ -37,7 +38,7 @@ public: |
size_t deviceRB = fDevice.rowBytes(); |
for (int i = 0; i < height; ++i) { |
- fState.fProc1(fState, device, fState.fPM4f, 1, &alpha); |
+ fState.fProc1(fState.fXfer, device, &fState.fPM4f, 1, &alpha); |
device = (typename State::DstType*)((char*)device + deviceRB); |
} |
} |
@@ -50,7 +51,7 @@ public: |
size_t deviceRB = fDevice.rowBytes(); |
do { |
- fState.fProc1(fState, device, fState.fPM4f, width, nullptr); |
+ fState.fProc1(fState.fXfer, device, &fState.fPM4f, width, nullptr); |
y += 1; |
device = (typename State::DstType*)((char*)device + deviceRB); |
} while (--height > 0); |
@@ -67,10 +68,10 @@ public: |
int aa = *antialias; |
if (aa) { |
if (aa == 255) { |
- fState.fProc1(fState, device, fState.fPM4f, count, nullptr); |
+ fState.fProc1(fState.fXfer, device, &fState.fPM4f, count, nullptr); |
} else { |
for (int i = 0; i < count; ++i) { |
- fState.fProc1(fState, &device[i], fState.fPM4f, 1, antialias); |
+ fState.fProc1(fState.fXfer, &device[i], &fState.fPM4f, 1, antialias); |
} |
} |
} |
@@ -124,7 +125,7 @@ public: |
const size_t maskRB = mask.fRowBytes; |
for (int i = 0; i < height; ++i) { |
- fState.fProc1(fState, device, fState.fPM4f, width, maskRow); |
+ fState.fProc1(fState.fXfer, device, &fState.fPM4f, width, maskRow); |
device = (typename State::DstType*)((char*)device + dstRB); |
maskRow += maskRB; |
} |
@@ -146,7 +147,7 @@ public: |
typename State::DstType* device = State::WritableAddr(fDevice, x, y); |
fShaderContext->shadeSpan4f(x, y, fState.fBuffer, width); |
- fState.fProcN(fState, device, fState.fBuffer, width, nullptr); |
+ fState.fProcN(fState.fXfer, device, fState.fBuffer, width, nullptr); |
} |
void blitV(int x, int y, int height, SkAlpha alpha) override { |
@@ -163,7 +164,7 @@ public: |
if (!fConstInY) { |
fShaderContext->shadeSpan4f(x, y, fState.fBuffer, 1); |
} |
- fState.fProcN(fState, device, fState.fBuffer, 1, &alpha); |
+ fState.fProcN(fState.fXfer, device, fState.fBuffer, 1, &alpha); |
device = (typename State::DstType*)((char*)device + deviceRB); |
} |
} |
@@ -183,7 +184,7 @@ public: |
if (!fConstInY) { |
fShaderContext->shadeSpan4f(x, y, fState.fBuffer, width); |
} |
- fState.fProcN(fState, device, fState.fBuffer, width, nullptr); |
+ fState.fProcN(fState.fXfer, device, fState.fBuffer, width, nullptr); |
device = (typename State::DstType*)((char*)device + deviceRB); |
} |
} |
@@ -200,10 +201,10 @@ public: |
if (aa) { |
fShaderContext->shadeSpan4f(x, y, fState.fBuffer, count); |
if (aa == 255) { |
- fState.fProcN(fState, device, fState.fBuffer, count, nullptr); |
+ fState.fProcN(fState.fXfer, device, fState.fBuffer, count, nullptr); |
} else { |
for (int i = 0; i < count; ++i) { |
- fState.fProcN(fState, &device[i], &fState.fBuffer[i], 1, antialias); |
+ fState.fProcN(fState.fXfer, &device[i], &fState.fBuffer[i], 1, antialias); |
} |
} |
} |
@@ -267,7 +268,7 @@ public: |
if (!fConstInY) { |
fShaderContext->shadeSpan4f(x, y, fState.fBuffer, width); |
} |
- fState.fProcN(fState, device, fState.fBuffer, width, maskRow); |
+ fState.fProcN(fState.fXfer, device, fState.fBuffer, width, maskRow); |
device = (typename State::DstType*)((char*)device + deviceRB); |
maskRow += maskRB; |
} |
@@ -286,47 +287,45 @@ static bool is_opaque(const SkPaint& paint, const SkShader::Context* shaderConte |
: 0xFF == paint.getAlpha(); |
} |
-struct State32 : SkXfermode::PM4fState { |
- typedef uint32_t DstType; |
- |
- SkXfermode::PM4fProc1 fProc1; |
- SkXfermode::PM4fProcN fProcN; |
+struct State4f { |
+ State4f(const SkImageInfo& info, const SkPaint& paint, const SkShader::Context* shaderContext) { |
+ fXfer = paint.getXfermode(); |
+ if (shaderContext) { |
+ fBuffer.reset(info.width()); |
+ } else { |
+ fPM4f = SkColor4f::FromColor(paint.getColor()).premul(); |
+ } |
+ fFlags = 0; |
+ } |
+ |
+ SkXfermode* fXfer; |
SkPM4f fPM4f; |
- SkPM4f* fBuffer; |
+ SkAutoTMalloc<SkPM4f> fBuffer; |
+ uint32_t fFlags; |
+}; |
+ |
+struct State32 : State4f { |
+ typedef uint32_t DstType; |
- State32(const SkImageInfo& info, const SkPaint& paint, const SkShader::Context* shaderContext) { |
- fXfer = SkSafeRef(paint.getXfermode()); |
- fFlags = 0; |
+ SkXfermode::D32Proc fProc1; |
+ SkXfermode::D32Proc fProcN; |
+ |
+ State32(const SkImageInfo& info, const SkPaint& paint, const SkShader::Context* shaderContext) |
+ : State4f(info, paint, shaderContext) |
+ { |
if (is_opaque(paint, shaderContext)) { |
- fFlags |= SkXfermode::kSrcIsOpaque_PM4fFlag; |
+ fFlags |= SkXfermode::kSrcIsOpaque_D32Flag; |
} |
if (info.isSRGB()) { |
- fFlags |= SkXfermode::kDstIsSRGB_PM4fFlag; |
- } |
- if (fXfer) { |
- fProc1 = fXfer->getPM4fProc1(fFlags); |
- fProcN = fXfer->getPM4fProcN(fFlags); |
- } else { |
- fProc1 = SkXfermode::GetPM4fProc1(SkXfermode::kSrcOver_Mode, fFlags); |
- fProcN = SkXfermode::GetPM4fProcN(SkXfermode::kSrcOver_Mode, fFlags); |
- } |
- |
- fBuffer = nullptr; |
- if (shaderContext) { |
- fBuffer = new SkPM4f[info.width()]; |
- } else { |
- fPM4f = SkColor4f::FromColor(paint.getColor()).premul(); |
+ fFlags |= SkXfermode::kDstIsSRGB_D32Flag; |
} |
+ fProc1 = SkXfermode::GetD32Proc(fXfer, fFlags | SkXfermode::kSrcIsSingle_D32Flag); |
+ fProcN = SkXfermode::GetD32Proc(fXfer, fFlags); |
} |
- ~State32() { |
- SkSafeUnref(fXfer); |
- delete[] fBuffer; |
- } |
- |
SkXfermode::LCD32Proc getLCDProc(uint32_t oneOrManyFlag) const { |
uint32_t flags = fFlags & 1; |
- if (!(fFlags & SkXfermode::kDstIsSRGB_PM4fFlag)) { |
+ if (!(fFlags & SkXfermode::kDstIsSRGB_D32Flag)) { |
flags |= SkXfermode::kDstIsLinearInt_LCDFlag; |
} |
return SkXfermode::GetLCD32Proc(flags | oneOrManyFlag); |
@@ -337,47 +336,28 @@ struct State32 : SkXfermode::PM4fState { |
} |
}; |
-struct State64 : SkXfermode::U64State { |
- typedef uint64_t DstType; |
+struct State64 : State4f { |
+ typedef uint64_t DstType; |
- SkXfermode::U64Proc1 fProc1; |
- SkXfermode::U64ProcN fProcN; |
- SkPM4f fPM4f; |
- SkPM4f* fBuffer; |
+ SkXfermode::D64Proc fProc1; |
+ SkXfermode::D64Proc fProcN; |
- State64(const SkImageInfo& info, const SkPaint& paint, const SkShader::Context* shaderContext) { |
- fXfer = SkSafeRef(paint.getXfermode()); |
- fFlags = 0; |
+ State64(const SkImageInfo& info, const SkPaint& paint, const SkShader::Context* shaderContext) |
+ : State4f(info, paint, shaderContext) |
+ { |
if (is_opaque(paint, shaderContext)) { |
- fFlags |= SkXfermode::kSrcIsOpaque_PM4fFlag; |
+ fFlags |= SkXfermode::kSrcIsOpaque_D64Flag; |
} |
if (kRGBA_F16_SkColorType == info.colorType()) { |
- fFlags |= SkXfermode::kDstIsFloat16_U64Flag; |
- } |
- |
- SkXfermode::Mode mode; |
- if (!SkXfermode::AsMode(fXfer, &mode)) { |
- mode = SkXfermode::kSrcOver_Mode; |
- } |
- fProc1 = SkXfermode::GetU64Proc1(mode, fFlags); |
- fProcN = SkXfermode::GetU64ProcN(mode, fFlags); |
- |
- fBuffer = nullptr; |
- if (shaderContext) { |
- fBuffer = new SkPM4f[info.width()]; |
- } else { |
- fPM4f = SkColor4f::FromColor(paint.getColor()).premul(); |
+ fFlags |= SkXfermode::kDstIsFloat16_D64Flag; |
} |
+ fProc1 = SkXfermode::GetD64Proc(fXfer, fFlags | SkXfermode::kSrcIsSingle_D64Flag); |
+ fProcN = SkXfermode::GetD64Proc(fXfer, fFlags); |
} |
- |
- ~State64() { |
- SkSafeUnref(fXfer); |
- delete[] fBuffer; |
- } |
- |
+ |
SkXfermode::LCD64Proc getLCDProc(uint32_t oneOrManyFlag) const { |
uint32_t flags = fFlags & 1; |
- if (!(fFlags & SkXfermode::kDstIsFloat16_U64Flag)) { |
+ if (!(fFlags & SkXfermode::kDstIsFloat16_D64Flag)) { |
flags |= SkXfermode::kDstIsLinearInt_LCDFlag; |
} |
return SkXfermode::GetLCD64Proc(flags | oneOrManyFlag); |