aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar herb <herb@google.com>2016-05-19 14:19:23 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-05-19 14:19:23 -0700
commit57a69dc013b7105a6a535e84588f9aa95397b2ee (patch)
tree3e8e8a437c73af36c770c1f30bd8a6d376c868fb /src
parent82ec6e59b8b694c128adcf8590667d37327dd1c4 (diff)
Make an embeddable container to hold linear pipelines.
Diffstat (limited to 'src')
-rw-r--r--src/core/SkBitmapProcShader.cpp52
-rw-r--r--src/core/SkLinearBitmapPipeline.cpp4
-rw-r--r--src/core/SkLinearBitmapPipeline.h52
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