Index: src/core/SkBitmapProcShader.cpp |
diff --git a/src/core/SkBitmapProcShader.cpp b/src/core/SkBitmapProcShader.cpp |
index 38f46d18b4e7a10ddcaf94d33e4d14f198b8b4fb..895922c6b873a388210e0887d768f08dc05646c5 100644 |
--- a/src/core/SkBitmapProcShader.cpp |
+++ b/src/core/SkBitmapProcShader.cpp |
@@ -27,7 +27,8 @@ |
class BitmapProcInfoContext : public SkShader::Context { |
public: |
- // The info has been allocated elsewhere, but we are responsible for calling its destructor. |
+ // The context takes ownership of the info. It will call its destructor |
+ // but will NOT free the memory. |
BitmapProcInfoContext(const SkShader& shader, const SkShader::ContextRec& rec, |
SkBitmapProcInfo* info) |
: INHERITED(shader, rec) |
@@ -44,6 +45,8 @@ |
} |
~BitmapProcInfoContext() override { |
+ // The bitmap proc state has been created outside of the context on memory that will be freed |
+ // elsewhere. Only call the destructor but leave the freeing of the memory to the caller. |
fInfo->~SkBitmapProcInfo(); |
} |
@@ -60,6 +63,8 @@ |
class BitmapProcShaderContext : public BitmapProcInfoContext { |
public: |
+ // The context takes ownership of the state. It will call its destructor |
+ // but will NOT free the memory. |
BitmapProcShaderContext(const SkShader& shader, const SkShader::ContextRec& rec, |
SkBitmapProcState* state) |
: INHERITED(shader, rec, state) |
@@ -111,80 +116,11 @@ |
}; |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
-#include "SkLinearBitmapPipeline.h" |
-#include "SkPM4f.h" |
-#include "SkXfermode.h" |
- |
-class LinearPipelineContext : public BitmapProcInfoContext { |
-public: |
- LinearPipelineContext(const SkShader& shader, const SkShader::ContextRec& rec, |
- SkBitmapProcInfo* info) |
- : INHERITED(shader, rec, info) |
- , fPipeline(info->fInvMatrix, info->fFilterQuality, info->fTileModeX, info->fTileModeY, |
- info->fPixmap) |
- { |
- // To implement the old shadeSpan entry-point, we need to efficiently convert our native |
- // floats into SkPMColor. The SkXfermode::D32Procs do exactly that. |
- // |
- sk_sp<SkXfermode> xfer(SkXfermode::Create(SkXfermode::kSrc_Mode)); |
- fXferProc = SkXfermode::GetD32Proc(xfer.get(), 0); |
- } |
- |
- void shadeSpan4f(int x, int y, SkPM4f dstC[], int count) override { |
- fPipeline.shadeSpan4f(x, y, dstC, count); |
- } |
- |
- void shadeSpan(int x, int y, SkPMColor dstC[], int count) override { |
- const int N = 128; |
- SkPM4f tmp[N]; |
- |
- while (count > 0) { |
- const int n = SkTMin(count, N); |
- fPipeline.shadeSpan4f(x, y, tmp, n); |
- fXferProc(nullptr, dstC, tmp, n, nullptr); |
- dstC += n; |
- x += n; |
- count -= n; |
- } |
- } |
- |
-private: |
- SkLinearBitmapPipeline fPipeline; |
- SkXfermode::D32Proc fXferProc; |
- |
- typedef BitmapProcInfoContext INHERITED; |
-}; |
- |
-/////////////////////////////////////////////////////////////////////////////////////////////////// |
- |
-static bool choose_linear_pipeline(const SkShader::ContextRec& rec, const SkImageInfo& srcInfo) { |
- // These src attributes are not supported in the new 4f context (yet) |
- // |
- if (srcInfo.bytesPerPixel() < 4 || |
- kRGBA_F16_SkColorType == srcInfo.colorType()) { |
- return false; |
- } |
- |
-#if 0 // later we may opt-in to the new code even if the client hasn't requested it... |
- // These src attributes are only supported in the new 4f context |
- // |
- if (srcInfo.isSRGB() || |
- kUnpremul_SkAlphaType == srcInfo.alphaType() || |
- (4 == srcInfo.bytesPerPixel() && kN32_SkColorType != srcInfo.colorType())) |
- { |
- return true; |
- } |
-#endif |
- |
- // If we get here, we can reasonably use either context, respect the caller's preference |
- // |
- return SkShader::ContextRec::kPM4f_DstType == rec.fPreferredDstType; |
-} |
- |
-size_t SkBitmapProcShader::ContextSize(const ContextRec& rec, const SkImageInfo& srcInfo) { |
- size_t size0 = sizeof(BitmapProcShaderContext) + sizeof(SkBitmapProcState); |
- size_t size1 = sizeof(LinearPipelineContext) + sizeof(SkBitmapProcInfo); |
- return SkTMax(size0, size1); |
+ |
+size_t SkBitmapProcShader::ContextSize(const ContextRec& rec) { |
+ // The SkBitmapProcState is stored outside of the context object, with the context holding |
+ // a pointer to it. |
+ return sizeof(BitmapProcShaderContext) + sizeof(SkBitmapProcState); |
} |
SkShader::Context* SkBitmapProcShader::MakeContext(const SkShader& shader, |
@@ -197,32 +133,16 @@ |
return nullptr; |
} |
- // Decide if we can/want to use the new linear pipeine |
- bool useLinearPipeline = choose_linear_pipeline(rec, provider.info()); |
- if (SkShader::kMirror_TileMode == tmx || SkShader::kMirror_TileMode == tmy) { |
- useLinearPipeline = false; |
- } |
- if (totalInverse.hasPerspective()) { |
- useLinearPipeline = false; |
- } |
- |
- if (useLinearPipeline) { |
- void* infoStorage = (char*)storage + sizeof(LinearPipelineContext); |
- SkBitmapProcInfo* info = new (infoStorage) SkBitmapProcInfo(provider, tmx, tmy); |
- if (!info->init(totalInverse, *rec.fPaint)) { |
- info->~SkBitmapProcInfo(); |
- return nullptr; |
- } |
- return new (storage) LinearPipelineContext(shader, rec, info); |
- } else { |
- void* stateStorage = (char*)storage + sizeof(BitmapProcShaderContext); |
- SkBitmapProcState* state = new (stateStorage) SkBitmapProcState(provider, tmx, tmy); |
- if (!state->setup(totalInverse, *rec.fPaint)) { |
- state->~SkBitmapProcState(); |
- return nullptr; |
- } |
- return new (storage) BitmapProcShaderContext(shader, rec, state); |
- } |
+ void* stateStorage = (char*)storage + sizeof(BitmapProcShaderContext); |
+ SkBitmapProcState* state = new (stateStorage) SkBitmapProcState(provider, tmx, tmy); |
+ |
+ SkASSERT(state); |
+ if (!state->setup(totalInverse, *rec.fPaint)) { |
+ state->~SkBitmapProcState(); |
+ return nullptr; |
+ } |
+ |
+ return new (storage) BitmapProcShaderContext(shader, rec, state); |
} |
SkShader::Context* SkBitmapProcShader::onCreateContext(const ContextRec& rec, void* storage) const { |