Chromium Code Reviews| 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; |
| }; |