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
This commit is contained in:
parent
82ec6e59b8
commit
57a69dc013
@ -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;
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user