diff options
author | 2016-05-19 14:19:23 -0700 | |
---|---|---|
committer | 2016-05-19 14:19:23 -0700 | |
commit | 57a69dc013b7105a6a535e84588f9aa95397b2ee (patch) | |
tree | 3e8e8a437c73af36c770c1f30bd8a6d376c868fb /src | |
parent | 82ec6e59b8b694c128adcf8590667d37327dd1c4 (diff) |
Make an embeddable container to hold linear pipelines.
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1998793002
Review-Url: https://codereview.chromium.org/1998793002
Diffstat (limited to 'src')
-rw-r--r-- | src/core/SkBitmapProcShader.cpp | 52 | ||||
-rw-r--r-- | src/core/SkLinearBitmapPipeline.cpp | 4 | ||||
-rw-r--r-- | src/core/SkLinearBitmapPipeline.h | 52 |
3 files changed, 62 insertions, 46 deletions
diff --git a/src/core/SkBitmapProcShader.cpp b/src/core/SkBitmapProcShader.cpp index ae973a2a59..a372b51990 100644 --- a/src/core/SkBitmapProcShader.cpp +++ b/src/core/SkBitmapProcShader.cpp @@ -129,12 +129,11 @@ public: fFilterQuality = info->fFilterQuality; fMatrixTypeMask = info->fRealInvMatrix.getType(); - // Need to ensure that our pipeline is created at a 16byte aligned address - fShaderPipeline = (SkLinearBitmapPipeline*)SkAlign16((intptr_t)fShaderStorage); - new (fShaderPipeline) SkLinearBitmapPipeline(info->fRealInvMatrix, info->fFilterQuality, - info->fTileModeX, info->fTileModeY, - info->fPaintColor, - info->fPixmap); + fShaderPipeline.init( + info->fRealInvMatrix, info->fFilterQuality, + info->fTileModeX, info->fTileModeY, + info->fPaintColor, + 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. @@ -143,14 +142,6 @@ public: fXferProc = SkXfermode::GetD32Proc(xfer.get(), 0); } - ~LinearPipelineContext() override { - // since we did a manual new, we need to manually destroy as well. - fShaderPipeline->~SkLinearBitmapPipeline(); - if (fBlitterPipeline != nullptr) { - fBlitterPipeline->~SkLinearBitmapPipeline(); - } - } - void shadeSpan4f(int x, int y, SkPM4f dstC[], int count) override { fShaderPipeline->shadeSpan4f(x, y, dstC, count); } @@ -173,23 +164,19 @@ public: SkXfermode::Mode mode; if (!SkXfermode::AsMode(state->fXfer, &mode)) { return false; } - // Need to ensure that our pipeline is created at a 16byte aligned address - fBlitterPipeline = (SkLinearBitmapPipeline*)SkAlign16((intptr_t)fBlitterStorage); if (SkLinearBitmapPipeline::ClonePipelineForBlitting( - fBlitterPipeline, *fShaderPipeline, + &fBlitterPipeline, *fShaderPipeline, fMatrixTypeMask, fXMode, fYMode, fFilterQuality, fSrcPixmap, fAlpha, mode, dstInfo)) { - state->fStorage[0] = fBlitterPipeline; + state->fStorage[0] = fBlitterPipeline.get(); state->fBlitBW = &LinearPipelineContext::ForwardToPipeline; return true; } - // Did not successfully create a pipeline so don't destruct it. - fBlitterPipeline = nullptr; return false; } @@ -199,23 +186,16 @@ public: pipeline->blitSpan(x, y, addr, count); } - private: - enum { - kActualSize = sizeof(SkLinearBitmapPipeline), - kPaddedSize = SkAlignPtr(kActualSize + 12), - }; - 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; - SkMatrix::TypeMask fMatrixTypeMask; - SkFilterQuality fFilterQuality; + SkEmbeddableLinearPipeline fShaderPipeline; + SkEmbeddableLinearPipeline fBlitterPipeline; + SkXfermode::D32Proc fXferProc; + SkPixmap fSrcPixmap; + float fAlpha; + SkShader::TileMode fXMode; + SkShader::TileMode fYMode; + SkMatrix::TypeMask fMatrixTypeMask; + SkFilterQuality fFilterQuality; typedef BitmapProcInfoContext INHERITED; }; diff --git a/src/core/SkLinearBitmapPipeline.cpp b/src/core/SkLinearBitmapPipeline.cpp index dfc9aa8376..7cdeaac5ff 100644 --- a/src/core/SkLinearBitmapPipeline.cpp +++ b/src/core/SkLinearBitmapPipeline.cpp @@ -891,7 +891,7 @@ SkLinearBitmapPipeline::SkLinearBitmapPipeline( } bool SkLinearBitmapPipeline::ClonePipelineForBlitting( - void* blitterStorage, + SkEmbeddableLinearPipeline* pipelineStorage, const SkLinearBitmapPipeline& pipeline, SkMatrix::TypeMask matrixMask, SkShader::TileMode xTileMode, @@ -920,7 +920,7 @@ bool SkLinearBitmapPipeline::ClonePipelineForBlitting( return false; } - new (blitterStorage) SkLinearBitmapPipeline(pipeline, srcPixmap, xferMode, dstInfo); + pipelineStorage->init(pipeline, srcPixmap, xferMode, dstInfo); return true; } diff --git a/src/core/SkLinearBitmapPipeline.h b/src/core/SkLinearBitmapPipeline.h index 853e56fd1b..dce537aa6e 100644 --- a/src/core/SkLinearBitmapPipeline.h +++ b/src/core/SkLinearBitmapPipeline.h @@ -13,6 +13,13 @@ #include "SkMatrix.h" #include "SkShader.h" +class SkEmbeddableLinearPipeline; + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// SkLinearBitmapPipeline - encapsulates all the machinery for doing floating point pixel +// processing in a linear color space. +// Note: this class has unusual alignment requirements due to its use of SIMD instructions. The +// class SkEmbeddableLinearPipeline below manages these requirements. class SkLinearBitmapPipeline { public: SkLinearBitmapPipeline( @@ -22,10 +29,14 @@ public: SkColor paintColor, const SkPixmap& srcPixmap); - + SkLinearBitmapPipeline( + const SkLinearBitmapPipeline& pipeline, + const SkPixmap& srcPixmap, + SkXfermode::Mode xferMode, + const SkImageInfo& dstInfo); static bool ClonePipelineForBlitting( - void* blitterStorage, + SkEmbeddableLinearPipeline* pipelineStorage, const SkLinearBitmapPipeline& pipeline, SkMatrix::TypeMask matrixMask, SkShader::TileMode xTileMode, @@ -87,12 +98,6 @@ public: using BlenderStage = Stage<BlendProcessorInterface, 40>; private: - SkLinearBitmapPipeline( - const SkLinearBitmapPipeline& pipeline, - const SkPixmap& srcPixmap, - SkXfermode::Mode xferMode, - const SkImageInfo& dstInfo); - PointProcessorInterface* fFirstStage; MatrixStage fMatrixStage; TileStage fTileStage; @@ -101,4 +106,35 @@ private: DestinationInterface* fLastStage; }; +//////////////////////////////////////////////////////////////////////////////////////////////////// +// SkEmbeddableLinearPipeline - manage stricter alignment needs for SkLinearBitmapPipeline. +class SkEmbeddableLinearPipeline { +public: + SkEmbeddableLinearPipeline() { } + ~SkEmbeddableLinearPipeline() { + if (get() != nullptr) { + get()->~SkLinearBitmapPipeline(); + } + } + + template <typename... Args> + void init(Args&&... args) { + // Ensure that our pipeline is created at a 16 byte aligned address. + fPipeline = (SkLinearBitmapPipeline*)SkAlign16((intptr_t)fPipelineStorage); + new (fPipeline) SkLinearBitmapPipeline{std::forward<Args>(args)...}; + } + + SkLinearBitmapPipeline* get() const { return fPipeline; } + SkLinearBitmapPipeline& operator*() const { return *this->get(); } + SkLinearBitmapPipeline* operator->() const { return this->get(); } + +private: + enum { + kActualSize = sizeof(SkLinearBitmapPipeline), + kPaddedSize = SkAlignPtr(kActualSize + 12), + }; + void* fPipelineStorage[kPaddedSize / sizeof(void*)]; + SkLinearBitmapPipeline* fPipeline{nullptr}; +}; + #endif // SkLinearBitmapPipeline_DEFINED |