Index: src/core/SkBitmapProcShader.cpp |
diff --git a/src/core/SkBitmapProcShader.cpp b/src/core/SkBitmapProcShader.cpp |
index c9df4ce248c7c6d6b5a3f947f26aaa36b56d3065..59670da078f1e5a4ea368a0cbcd7cb4d86662dfb 100644 |
--- a/src/core/SkBitmapProcShader.cpp |
+++ b/src/core/SkBitmapProcShader.cpp |
@@ -121,12 +121,16 @@ public: |
SkBitmapProcInfo* info) |
: INHERITED(shader, rec, info) |
{ |
+ fSrcPixmap = info->fPixmap; |
+ fAlpha = SkColorGetA(info->fPaintColor) / 255.0f; |
+ fXMode = info->fTileModeX; |
+ fYMode = info->fTileModeY; |
+ fIsComplicated = info->fRealInvMatrix.getType() & ~SkMatrix::kTranslate_Mask; |
// Need to ensure that our pipeline is created at a 16byte aligned address |
- fPipeline = (SkLinearBitmapPipeline*)SkAlign16((intptr_t)fStorage); |
- float alpha = SkColorGetA(info->fPaintColor) / 255.0f; |
- new (fPipeline) SkLinearBitmapPipeline(info->fRealInvMatrix, info->fFilterQuality, |
+ fShaderPipeline = (SkLinearBitmapPipeline*)SkAlign16((intptr_t)fShaderStorage); |
+ new (fShaderPipeline) SkLinearBitmapPipeline(info->fRealInvMatrix, info->fFilterQuality, |
info->fTileModeX, info->fTileModeY, |
- alpha, |
+ fAlpha, |
info->fPixmap); |
// To implement the old shadeSpan entry-point, we need to efficiently convert our native |
@@ -138,11 +142,14 @@ public: |
~LinearPipelineContext() override { |
// since we did a manual new, we need to manually destroy as well. |
- fPipeline->~SkLinearBitmapPipeline(); |
+ fShaderPipeline->~SkLinearBitmapPipeline(); |
+ if (fBlitterPipeline != nullptr) { |
+ fBlitterPipeline->~SkLinearBitmapPipeline(); |
+ } |
} |
void shadeSpan4f(int x, int y, SkPM4f dstC[], int count) override { |
- fPipeline->shadeSpan4f(x, y, dstC, count); |
+ fShaderPipeline->shadeSpan4f(x, y, dstC, count); |
} |
void shadeSpan(int x, int y, SkPMColor dstC[], int count) override { |
@@ -151,7 +158,7 @@ public: |
while (count > 0) { |
const int n = SkTMin(count, N); |
- fPipeline->shadeSpan4f(x, y, tmp, n); |
+ fShaderPipeline->shadeSpan4f(x, y, tmp, n); |
fXferProc(nullptr, dstC, tmp, n, nullptr); |
dstC += n; |
x += n; |
@@ -159,14 +166,57 @@ public: |
} |
} |
+ bool onChooseBlitProcs(const SkImageInfo& dstInfo, BlitState* state) override { |
+ if (fIsComplicated) { return false; } |
+ SkXfermode::Mode mode; |
+ if (!SkXfermode::AsMode(state->fXfer, &mode)) { return false; } |
+ if (fAlpha != 1.0f) { return false; } |
+ if (fSrcPixmap.info().colorType() != kRGBA_8888_SkColorType |
+ || dstInfo.colorType() != kRGBA_8888_SkColorType) { return false; } |
+ |
+ if (fXMode != SkShader::kRepeat_TileMode || fYMode != SkShader::kRepeat_TileMode) { |
+ return false; |
+ } |
+ |
+ if (mode == SkXfermode::kSrcOver_Mode |
mtklein
2016/04/11 16:43:25
This section here is not a constraint on when we c
herb_g
2016/04/12 20:03:49
Done.
|
+ && fSrcPixmap.info().alphaType() == kOpaque_SkAlphaType) { |
+ mode = SkXfermode::kSrc_Mode; |
+ } |
+ |
+ if (mode != SkXfermode::kSrc_Mode) { return false; } |
+ |
+ // Need to ensure that our pipeline is created at a 16byte aligned address |
+ fBlitterPipeline = (SkLinearBitmapPipeline*)SkAlign16((intptr_t)fBlitterStorage); |
+ new (fBlitterPipeline) SkLinearBitmapPipeline(*fShaderPipeline, mode, fSrcPixmap, dstInfo); |
+ |
+ state->fStorage[0] = fBlitterPipeline; |
+ state->fBlitBW = &LinearPipelineContext::ForwardToPipeline; |
+ |
+ return true; |
+ } |
+ |
+ static void ForwardToPipeline(BlitState* state, int x, int y, const SkPixmap& dst, int count) { |
+ SkLinearBitmapPipeline* pipeline = static_cast<SkLinearBitmapPipeline*>(state->fStorage[0]); |
+ void* addr = dst.writable_addr32(x, y); |
+ pipeline->blitSpan(x, y, addr, count); |
+ } |
+ |
+ |
private: |
enum { |
kActualSize = sizeof(SkLinearBitmapPipeline), |
kPaddedSize = SkAlignPtr(kActualSize + 12), |
}; |
- void* fStorage[kPaddedSize / sizeof(void*)]; |
- SkLinearBitmapPipeline* fPipeline; |
+ void* fShaderStorage[kPaddedSize / sizeof(void*)]; |
+ SkLinearBitmapPipeline* fShaderPipeline; |
+ void* fBlitterStorage[kPaddedSize / sizeof(void*)]; |
+ SkLinearBitmapPipeline* fBlitterPipeline{nullptr}; |
SkXfermode::D32Proc fXferProc; |
+ SkPixmap fSrcPixmap; |
+ float fAlpha; |
+ SkShader::TileMode fXMode; |
+ SkShader::TileMode fYMode; |
+ bool fIsComplicated; |
typedef BitmapProcInfoContext INHERITED; |
}; |