Use SkFixedAllocator in SkLinearPipeline and remove the embedding of
the entire pipeline.
Adjust SkFixedAlloc to allow nesting of allocation.
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=4987
Change-Id: Ieeb1b5deaae004b67cee933af9bc19bbfd5a7687
Reviewed-on: https://skia-review.googlesource.com/4987
Commit-Queue: Herb Derby <herb@google.com>
Reviewed-by: Mike Klein <mtklein@chromium.org>
diff --git a/bench/SkLinearBitmapPipelineBench.cpp b/bench/SkLinearBitmapPipelineBench.cpp
index d669ed9..8582ce9 100644
--- a/bench/SkLinearBitmapPipelineBench.cpp
+++ b/bench/SkLinearBitmapPipelineBench.cpp
@@ -6,13 +6,14 @@
*/
#include <memory>
-#include "SkColor.h"
-#include "SkLinearBitmapPipeline.h"
-#include "SkBitmapProcShader.h"
-#include "SkPM4f.h"
#include "Benchmark.h"
-#include "SkShader.h"
+#include "SkBitmapProcShader.h"
+#include "SkColor.h"
+#include "SkFixedAlloc.h"
#include "SkImage.h"
+#include "SkLinearBitmapPipeline.h"
+#include "SkPM4f.h"
+#include "SkShader.h"
struct CommonBitmapFPBenchmark : public Benchmark {
CommonBitmapFPBenchmark(
@@ -146,8 +147,12 @@
SkPixmap srcPixmap{fInfo, fBitmap.get(), static_cast<size_t>(4 * width)};
+
+ char storage[600];
+ SkFixedAlloc fixedAlloc{storage, sizeof(storage)};
+ SkFallbackAlloc allocator{&fixedAlloc};
SkLinearBitmapPipeline pipeline{
- fInvert, filterQuality, fXTile, fYTile, SK_ColorBLACK, srcPixmap};
+ fInvert, filterQuality, fXTile, fYTile, SK_ColorBLACK, srcPixmap, &allocator};
int count = 100;
diff --git a/gm/SkLinearBitmapPipelineGM.cpp b/gm/SkLinearBitmapPipelineGM.cpp
index 13f6004..bde8ee8 100644
--- a/gm/SkLinearBitmapPipelineGM.cpp
+++ b/gm/SkLinearBitmapPipelineGM.cpp
@@ -115,9 +115,13 @@
uint32_t flags = 0;
auto procN = SkXfermode::GetD32Proc(SkBlendMode::kSrcOver, flags);
+ char storage[512];
+ SkFixedAlloc fixedAlloc{storage, sizeof(storage)};
+ SkFallbackAlloc allocator{&fixedAlloc};
SkLinearBitmapPipeline pipeline{
inv, filterQuality,
- SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode, SK_ColorBLACK, pmsrc};
+ SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode,
+ SK_ColorBLACK, pmsrc, &allocator};
for (int y = 0; y < ir.height(); y++) {
pipeline.shadeSpan4f(0, y, dstBits, ir.width());
diff --git a/src/core/SkBitmapProcShader.cpp b/src/core/SkBitmapProcShader.cpp
index b17d3e3..8ec1575 100644
--- a/src/core/SkBitmapProcShader.cpp
+++ b/src/core/SkBitmapProcShader.cpp
@@ -113,16 +113,15 @@
// Save things off in case we need to build a blitter pipeline.
fSrcPixmap = info->fPixmap;
fAlpha = SkColorGetA(info->fPaintColor) / 255.0f;
- fXMode = info->fTileModeX;
- fYMode = info->fTileModeY;
fFilterQuality = info->fFilterQuality;
fMatrixTypeMask = info->fRealInvMatrix.getType();
- fShaderPipeline.init(
+ fShaderPipeline = fAllocator.make<SkLinearBitmapPipeline>(
info->fRealInvMatrix, info->fFilterQuality,
info->fTileModeX, info->fTileModeY,
info->fPaintColor,
- info->fPixmap);
+ info->fPixmap,
+ &fAllocator);
// To implement the old shadeSpan entry-point, we need to efficiently convert our native
// floats into SkPMColor. The SkXfermode::D32Procs do exactly that.
@@ -149,14 +148,13 @@
}
bool onChooseBlitProcs(const SkImageInfo& dstInfo, BlitState* state) override {
- if (SkLinearBitmapPipeline::ClonePipelineForBlitting(
- &fBlitterPipeline, *fShaderPipeline,
+ if ((fBlitterPipeline = SkLinearBitmapPipeline::ClonePipelineForBlitting(
+ *fShaderPipeline,
fMatrixTypeMask,
- fXMode, fYMode,
fFilterQuality, fSrcPixmap,
- fAlpha, state->fMode, dstInfo))
+ fAlpha, state->fMode, dstInfo, &fAllocator)))
{
- state->fStorage[0] = fBlitterPipeline.get();
+ state->fStorage[0] = fBlitterPipeline;
state->fBlitBW = &LinearPipelineContext::ForwardToPipeline;
return true;
@@ -172,15 +170,16 @@
}
private:
- SkEmbeddableLinearPipeline fShaderPipeline;
- SkEmbeddableLinearPipeline fBlitterPipeline;
- SkXfermode::D32Proc fSrcModeProc;
- SkPixmap fSrcPixmap;
- float fAlpha;
- SkShader::TileMode fXMode;
- SkShader::TileMode fYMode;
- SkMatrix::TypeMask fMatrixTypeMask;
- SkFilterQuality fFilterQuality;
+ char fStorage[512 + 96];
+ SkFixedAlloc fFixedAlloc {fStorage, sizeof(fStorage)};
+ SkFallbackAlloc fAllocator {&fFixedAlloc};
+ SkLinearBitmapPipeline* fShaderPipeline;
+ SkLinearBitmapPipeline* fBlitterPipeline;
+ SkXfermode::D32Proc fSrcModeProc;
+ SkPixmap fSrcPixmap;
+ float fAlpha;
+ SkMatrix::TypeMask fMatrixTypeMask;
+ SkFilterQuality fFilterQuality;
typedef BitmapProcInfoContext INHERITED;
};
diff --git a/src/core/SkFixedAlloc.h b/src/core/SkFixedAlloc.h
index d4e4d8f..8d55cc7 100644
--- a/src/core/SkFixedAlloc.h
+++ b/src/core/SkFixedAlloc.h
@@ -35,9 +35,8 @@
// Skip ahead until our buffer is aligned for T.
fUsed += skip;
- // Create the T.
+ // Make space for T.
auto ptr = (T*)(fBuffer+fUsed);
- new (ptr) T(std::forward<Args>(args)...);
fUsed += sizeof(T);
// Stamp a footer after the T that we can use to clean it up.
@@ -45,7 +44,8 @@
memcpy(fBuffer+fUsed, &footer, sizeof(Footer));
fUsed += sizeof(Footer);
- return ptr;
+ // Creating a T must be last for nesting to work.
+ return new (ptr) T(std::forward<Args>(args)...);
}
// Destroys the last object allocated and frees its space in the buffer.
@@ -78,9 +78,10 @@
return ptr;
}
}
- auto ptr = new T(std::forward<Args>(args)...);
- fHeapAllocs.push_back({[](void* ptr) { delete (T*)ptr; }, ptr});
- return ptr;
+
+ char* ptr = new char[sizeof(T)];
+ fHeapAllocs.push_back({[](char* ptr) { ((T*)ptr)->~T(); delete [] ptr; }, ptr});
+ return new (ptr) T(std::forward<Args>(args)...);
}
// Destroys the last object allocated and frees any space it used in the SkFixedAlloc.
@@ -91,8 +92,8 @@
private:
struct HeapAlloc {
- void (*deleter)(void*);
- void* ptr;
+ void (*deleter)(char*);
+ char* ptr;
};
SkFixedAlloc* fFixedAlloc;
diff --git a/src/core/SkLinearBitmapPipeline.cpp b/src/core/SkLinearBitmapPipeline.cpp
index b32ff2d..9e8b419 100644
--- a/src/core/SkLinearBitmapPipeline.cpp
+++ b/src/core/SkLinearBitmapPipeline.cpp
@@ -12,6 +12,7 @@
#include <limits>
#include <tuple>
+#include "SkFixedAlloc.h"
#include "SkLinearBitmapPipeline_core.h"
#include "SkLinearBitmapPipeline_matrix.h"
#include "SkLinearBitmapPipeline_tile.h"
@@ -349,7 +350,8 @@
SkFilterQuality filterQuality,
SkShader::TileMode xTile, SkShader::TileMode yTile,
SkColor paintColor,
- const SkPixmap& srcPixmap)
+ const SkPixmap& srcPixmap,
+ SkFallbackAlloc* allocator)
{
SkISize dimensions = srcPixmap.info().dimensions();
const SkImageInfo& srcImageInfo = srcPixmap.info();
@@ -377,55 +379,21 @@
float postAlpha = SkColorGetA(paintColor) * (1.0f / 255.0f);
// As the stages are built, the chooser function may skip a stage. For example, with the
// identity matrix, the matrix stage is skipped, and the tilerStage is the first stage.
- auto blenderStage = this->chooseBlenderForShading(alphaType, postAlpha);
+ auto blenderStage = this->chooseBlenderForShading(alphaType, postAlpha, allocator);
auto samplerStage = this->chooseSampler(
- blenderStage, filterQuality, xTile, yTile, srcPixmap, paintColor);
+ blenderStage, filterQuality, xTile, yTile, srcPixmap, paintColor, allocator);
auto tilerStage = this->chooseTiler(
- samplerStage, dimensions, xTile, yTile, filterQuality, dx);
- fFirstStage = this->chooseMatrix(tilerStage, adjustedInverse);
+ samplerStage, dimensions, xTile, yTile, filterQuality, dx, allocator);
+ fFirstStage = this->chooseMatrix(tilerStage, adjustedInverse, allocator);
fLastStage = blenderStage;
}
-bool SkLinearBitmapPipeline::ClonePipelineForBlitting(
- SkEmbeddableLinearPipeline* pipelineStorage,
- const SkLinearBitmapPipeline& pipeline,
- SkMatrix::TypeMask matrixMask,
- SkShader::TileMode xTileMode,
- SkShader::TileMode yTileMode,
- SkFilterQuality filterQuality,
- const SkPixmap& srcPixmap,
- float finalAlpha,
- SkBlendMode blendMode,
- const SkImageInfo& dstInfo)
-{
- if (blendMode == SkBlendMode::kSrcOver && srcPixmap.info().alphaType() == kOpaque_SkAlphaType) {
- blendMode = SkBlendMode::kSrc;
- }
-
- if (matrixMask & ~SkMatrix::kTranslate_Mask ) { return false; }
- if (filterQuality != SkFilterQuality::kNone_SkFilterQuality) { return false; }
- if (finalAlpha != 1.0f) { return false; }
- if (srcPixmap.info().colorType() != kRGBA_8888_SkColorType
- || dstInfo.colorType() != kRGBA_8888_SkColorType) { return false; }
-
- if (!srcPixmap.info().gammaCloseToSRGB() || !dstInfo.gammaCloseToSRGB()) {
- return false;
- }
-
- if (blendMode != SkBlendMode::kSrc && blendMode != SkBlendMode::kSrcOver) {
- return false;
- }
-
- pipelineStorage->init(pipeline, srcPixmap, blendMode, dstInfo);
-
- return true;
-}
-
SkLinearBitmapPipeline::SkLinearBitmapPipeline(
const SkLinearBitmapPipeline& pipeline,
const SkPixmap& srcPixmap,
SkBlendMode mode,
- const SkImageInfo& dstInfo)
+ const SkImageInfo& dstInfo,
+ SkFallbackAlloc* allocator)
{
SkASSERT(mode == SkBlendMode::kSrc || mode == SkBlendMode::kSrcOver);
SkASSERT(srcPixmap.info().colorType() == dstInfo.colorType()
@@ -433,22 +401,54 @@
SampleProcessorInterface* sampleStage;
if (mode == SkBlendMode::kSrc) {
- auto sampler = fMemory.createT<RGBA8888UnitRepeatSrc>(
+ auto sampler = allocator->make<RGBA8888UnitRepeatSrc>(
srcPixmap.writable_addr32(0, 0), srcPixmap.rowBytes() / 4);
sampleStage = sampler;
fLastStage = sampler;
} else {
- auto sampler = fMemory.createT<RGBA8888UnitRepeatSrcOver>(
+ auto sampler = allocator->make<RGBA8888UnitRepeatSrcOver>(
srcPixmap.writable_addr32(0, 0), srcPixmap.rowBytes() / 4);
sampleStage = sampler;
fLastStage = sampler;
}
- auto tilerStage = pipeline.fTileStageCloner(sampleStage, &fMemory);
- auto matrixStage = pipeline.fMatrixStageCloner(tilerStage, &fMemory);
+ auto tilerStage = pipeline.fTileStageCloner(sampleStage, allocator);
+ auto matrixStage = pipeline.fMatrixStageCloner(tilerStage, allocator);
fFirstStage = matrixStage;
}
+SkLinearBitmapPipeline* SkLinearBitmapPipeline::ClonePipelineForBlitting(
+ const SkLinearBitmapPipeline& pipeline,
+ SkMatrix::TypeMask matrixMask,
+ SkFilterQuality filterQuality,
+ const SkPixmap& srcPixmap,
+ float finalAlpha,
+ SkBlendMode blendMode,
+ const SkImageInfo& dstInfo,
+ SkFallbackAlloc* allocator)
+{
+ if (blendMode == SkBlendMode::kSrcOver && srcPixmap.info().alphaType() == kOpaque_SkAlphaType) {
+ blendMode = SkBlendMode::kSrc;
+ }
+
+ if (matrixMask & ~SkMatrix::kTranslate_Mask ) { return nullptr; }
+ if (filterQuality != SkFilterQuality::kNone_SkFilterQuality) { return nullptr; }
+ if (finalAlpha != 1.0f) { return nullptr; }
+ if (srcPixmap.info().colorType() != kRGBA_8888_SkColorType
+ || dstInfo.colorType() != kRGBA_8888_SkColorType) { return nullptr; }
+
+ if (!srcPixmap.info().gammaCloseToSRGB() || !dstInfo.gammaCloseToSRGB()) {
+ return nullptr;
+ }
+
+ if (blendMode != SkBlendMode::kSrc && blendMode != SkBlendMode::kSrcOver) {
+ return nullptr;
+ }
+
+ return allocator->make<SkLinearBitmapPipeline>(
+ pipeline, srcPixmap, blendMode, dstInfo, allocator);
+}
+
void SkLinearBitmapPipeline::shadeSpan4f(int x, int y, SkPM4f* dst, int count) {
SkASSERT(count > 0);
this->blitSpan(x, y, dst, count);
@@ -466,9 +466,13 @@
}
SkLinearBitmapPipeline::PointProcessorInterface*
-SkLinearBitmapPipeline::chooseMatrix(PointProcessorInterface* next, const SkMatrix& inverse) {
+SkLinearBitmapPipeline::chooseMatrix(
+ PointProcessorInterface* next,
+ const SkMatrix& inverse,
+ SkFallbackAlloc* allocator)
+{
if (inverse.hasPerspective()) {
- auto matrixStage = fMemory.createT<PerspectiveMatrix<>>(
+ auto matrixStage = allocator->make<PerspectiveMatrix<>>(
next,
SkVector{inverse.getTranslateX(), inverse.getTranslateY()},
SkVector{inverse.getScaleX(), inverse.getScaleY()},
@@ -476,42 +480,42 @@
SkVector{inverse.getPerspX(), inverse.getPerspY()},
inverse.get(SkMatrix::kMPersp2));
fMatrixStageCloner =
- [matrixStage](PointProcessorInterface* cloneNext, MemoryAllocator* memory) {
- return memory->createT<PerspectiveMatrix<>>(cloneNext, matrixStage);
+ [matrixStage](PointProcessorInterface* cloneNext, SkFallbackAlloc* memory) {
+ return memory->make<PerspectiveMatrix<>>(cloneNext, matrixStage);
};
return matrixStage;
} else if (inverse.getSkewX() != 0.0f || inverse.getSkewY() != 0.0f) {
- auto matrixStage = fMemory.createT<AffineMatrix<>>(
+ auto matrixStage = allocator->make<AffineMatrix<>>(
next,
SkVector{inverse.getTranslateX(), inverse.getTranslateY()},
SkVector{inverse.getScaleX(), inverse.getScaleY()},
SkVector{inverse.getSkewX(), inverse.getSkewY()});
fMatrixStageCloner =
- [matrixStage](PointProcessorInterface* cloneNext, MemoryAllocator* memory) {
- return memory->createT<AffineMatrix<>>(cloneNext, matrixStage);
+ [matrixStage](PointProcessorInterface* cloneNext, SkFallbackAlloc* memory) {
+ return memory->make<AffineMatrix<>>(cloneNext, matrixStage);
};
return matrixStage;
} else if (inverse.getScaleX() != 1.0f || inverse.getScaleY() != 1.0f) {
- auto matrixStage = fMemory.createT<ScaleMatrix<>>(
+ auto matrixStage = allocator->make<ScaleMatrix<>>(
next,
SkVector{inverse.getTranslateX(), inverse.getTranslateY()},
SkVector{inverse.getScaleX(), inverse.getScaleY()});
fMatrixStageCloner =
- [matrixStage](PointProcessorInterface* cloneNext, MemoryAllocator* memory) {
- return memory->createT<ScaleMatrix<>>(cloneNext, matrixStage);
+ [matrixStage](PointProcessorInterface* cloneNext, SkFallbackAlloc* memory) {
+ return memory->make<ScaleMatrix<>>(cloneNext, matrixStage);
};
return matrixStage;
} else if (inverse.getTranslateX() != 0.0f || inverse.getTranslateY() != 0.0f) {
- auto matrixStage = fMemory.createT<TranslateMatrix<>>(
+ auto matrixStage = allocator->make<TranslateMatrix<>>(
next,
SkVector{inverse.getTranslateX(), inverse.getTranslateY()});
fMatrixStageCloner =
- [matrixStage](PointProcessorInterface* cloneNext, MemoryAllocator* memory) {
- return memory->createT<TranslateMatrix<>>(cloneNext, matrixStage);
+ [matrixStage](PointProcessorInterface* cloneNext, SkFallbackAlloc* memory) {
+ return memory->make<TranslateMatrix<>>(cloneNext, matrixStage);
};
return matrixStage;
} else {
- fMatrixStageCloner = [](PointProcessorInterface* cloneNext, MemoryAllocator* memory) {
+ fMatrixStageCloner = [](PointProcessorInterface* cloneNext, SkFallbackAlloc* memory) {
return cloneNext;
};
return next;
@@ -520,31 +524,38 @@
template <typename Tiler>
SkLinearBitmapPipeline::PointProcessorInterface* SkLinearBitmapPipeline::createTiler(
- SampleProcessorInterface* next, SkISize dimensions) {
- auto tilerStage = fMemory.createT<Tiler>(next, dimensions);
+ SampleProcessorInterface* next,
+ SkISize dimensions,
+ SkFallbackAlloc* allocator)
+{
+ auto tilerStage = allocator->make<Tiler>(next, dimensions);
fTileStageCloner =
[tilerStage](SampleProcessorInterface* cloneNext,
- MemoryAllocator* memory) -> PointProcessorInterface* {
- return memory->createT<Tiler>(cloneNext, tilerStage);
+ SkFallbackAlloc* memory) -> PointProcessorInterface* {
+ return memory->make<Tiler>(cloneNext, tilerStage);
};
return tilerStage;
}
template <typename XStrategy>
SkLinearBitmapPipeline::PointProcessorInterface* SkLinearBitmapPipeline::chooseTilerYMode(
- SampleProcessorInterface* next, SkShader::TileMode yMode, SkISize dimensions) {
+ SampleProcessorInterface* next,
+ SkShader::TileMode yMode,
+ SkISize dimensions,
+ SkFallbackAlloc* allocator)
+{
switch (yMode) {
case SkShader::kClamp_TileMode: {
using Tiler = CombinedTileStage<XStrategy, YClampStrategy, SampleProcessorInterface>;
- return this->createTiler<Tiler>(next, dimensions);
+ return this->createTiler<Tiler>(next, dimensions, allocator);
}
case SkShader::kRepeat_TileMode: {
using Tiler = CombinedTileStage<XStrategy, YRepeatStrategy, SampleProcessorInterface>;
- return this->createTiler<Tiler>(next, dimensions);
+ return this->createTiler<Tiler>(next, dimensions, allocator);
}
case SkShader::kMirror_TileMode: {
using Tiler = CombinedTileStage<XStrategy, YMirrorStrategy, SampleProcessorInterface>;
- return this->createTiler<Tiler>(next, dimensions);
+ return this->createTiler<Tiler>(next, dimensions, allocator);
}
}
@@ -559,19 +570,22 @@
SkShader::TileMode xMode,
SkShader::TileMode yMode,
SkFilterQuality filterQuality,
- SkScalar dx)
+ SkScalar dx,
+ SkFallbackAlloc* allocator)
{
switch (xMode) {
case SkShader::kClamp_TileMode:
- return this->chooseTilerYMode<XClampStrategy>(next, yMode, dimensions);
+ return this->chooseTilerYMode<XClampStrategy>(next, yMode, dimensions, allocator);
case SkShader::kRepeat_TileMode:
if (dx == 1.0f && filterQuality == kNone_SkFilterQuality) {
- return this->chooseTilerYMode<XRepeatUnitScaleStrategy>(next, yMode, dimensions);
+ return this->chooseTilerYMode<XRepeatUnitScaleStrategy>(
+ next, yMode, dimensions, allocator);
} else {
- return this->chooseTilerYMode<XRepeatStrategy>(next, yMode, dimensions);
+ return this->chooseTilerYMode<XRepeatStrategy>(
+ next, yMode, dimensions, allocator);
}
case SkShader::kMirror_TileMode:
- return this->chooseTilerYMode<XMirrorStrategy>(next, yMode, dimensions);
+ return this->chooseTilerYMode<XMirrorStrategy>(next, yMode, dimensions, allocator);
}
// Should never get here.
@@ -582,43 +596,45 @@
template <SkColorType colorType>
SkLinearBitmapPipeline::PixelAccessorInterface*
SkLinearBitmapPipeline::chooseSpecificAccessor(
- const SkPixmap& srcPixmap)
+ const SkPixmap& srcPixmap,
+ SkFallbackAlloc* allocator)
{
if (srcPixmap.info().gammaCloseToSRGB()) {
using Accessor = PixelAccessor<colorType, kSRGB_SkGammaType>;
- return fMemory.createT<Accessor>(srcPixmap);
+ return allocator->make<Accessor>(srcPixmap);
} else {
using Accessor = PixelAccessor<colorType, kLinear_SkGammaType>;
- return fMemory.createT<Accessor>(srcPixmap);
+ return allocator->make<Accessor>(srcPixmap);
}
}
SkLinearBitmapPipeline::PixelAccessorInterface* SkLinearBitmapPipeline::choosePixelAccessor(
const SkPixmap& srcPixmap,
- const SkColor A8TintColor)
+ const SkColor A8TintColor,
+ SkFallbackAlloc* allocator)
{
const SkImageInfo& imageInfo = srcPixmap.info();
switch (imageInfo.colorType()) {
case kAlpha_8_SkColorType: {
using Accessor = PixelAccessor<kAlpha_8_SkColorType, kLinear_SkGammaType>;
- return fMemory.createT<Accessor>(srcPixmap, A8TintColor);
+ return allocator->make<Accessor>(srcPixmap, A8TintColor);
}
case kARGB_4444_SkColorType:
- return this->chooseSpecificAccessor<kARGB_4444_SkColorType>(srcPixmap);
+ return this->chooseSpecificAccessor<kARGB_4444_SkColorType>(srcPixmap, allocator);
case kRGB_565_SkColorType:
- return this->chooseSpecificAccessor<kRGB_565_SkColorType>(srcPixmap);
+ return this->chooseSpecificAccessor<kRGB_565_SkColorType>(srcPixmap, allocator);
case kRGBA_8888_SkColorType:
- return this->chooseSpecificAccessor<kRGBA_8888_SkColorType>(srcPixmap);
+ return this->chooseSpecificAccessor<kRGBA_8888_SkColorType>(srcPixmap, allocator);
case kBGRA_8888_SkColorType:
- return this->chooseSpecificAccessor<kBGRA_8888_SkColorType>(srcPixmap);
+ return this->chooseSpecificAccessor<kBGRA_8888_SkColorType>(srcPixmap, allocator);
case kIndex_8_SkColorType:
- return this->chooseSpecificAccessor<kIndex_8_SkColorType>(srcPixmap);
+ return this->chooseSpecificAccessor<kIndex_8_SkColorType>(srcPixmap, allocator);
case kGray_8_SkColorType:
- return this->chooseSpecificAccessor<kGray_8_SkColorType>(srcPixmap);
+ return this->chooseSpecificAccessor<kGray_8_SkColorType>(srcPixmap, allocator);
case kRGBA_F16_SkColorType: {
using Accessor = PixelAccessor<kRGBA_F16_SkColorType, kLinear_SkGammaType>;
- return fMemory.createT<Accessor>(srcPixmap);
+ return allocator->make<Accessor>(srcPixmap);
}
default:
// Should never get here.
@@ -632,7 +648,8 @@
SkFilterQuality filterQuality,
SkShader::TileMode xTile, SkShader::TileMode yTile,
const SkPixmap& srcPixmap,
- const SkColor A8TintColor)
+ const SkColor A8TintColor,
+ SkFallbackAlloc* allocator)
{
const SkImageInfo& imageInfo = srcPixmap.info();
SkISize dimensions = imageInfo.dimensions();
@@ -645,13 +662,13 @@
using Sampler =
NearestNeighborSampler<
PixelAccessor<kN32_SkColorType, kSRGB_SkGammaType>, Blender>;
- return fMemory.createT<Sampler>(next, srcPixmap);
+ return allocator->make<Sampler>(next, srcPixmap);
}
case kIndex_8_SkColorType: {
using Sampler =
NearestNeighborSampler<
PixelAccessor<kIndex_8_SkColorType, kSRGB_SkGammaType>, Blender>;
- return fMemory.createT<Sampler>(next, srcPixmap);
+ return allocator->make<Sampler>(next, srcPixmap);
}
default:
break;
@@ -662,13 +679,13 @@
using Sampler =
BilerpSampler<
PixelAccessor<kN32_SkColorType, kSRGB_SkGammaType>, Blender>;
- return fMemory.createT<Sampler>(next, dimensions, xTile, yTile, srcPixmap);
+ return allocator->make<Sampler>(next, dimensions, xTile, yTile, srcPixmap);
}
case kIndex_8_SkColorType: {
using Sampler =
BilerpSampler<
PixelAccessor<kIndex_8_SkColorType, kSRGB_SkGammaType>, Blender>;
- return fMemory.createT<Sampler>(next, dimensions, xTile, yTile, srcPixmap);
+ return allocator->make<Sampler>(next, dimensions, xTile, yTile, srcPixmap);
}
default:
break;
@@ -676,24 +693,26 @@
}
}
- auto pixelAccessor = this->choosePixelAccessor(srcPixmap, A8TintColor);
+ auto pixelAccessor = this->choosePixelAccessor(srcPixmap, A8TintColor, allocator);
// General cases.
if (filterQuality == kNone_SkFilterQuality) {
using Sampler = NearestNeighborSampler<PixelAccessorShim, Blender>;
- return fMemory.createT<Sampler>(next, pixelAccessor);
+ return allocator->make<Sampler>(next, pixelAccessor);
} else {
using Sampler = BilerpSampler<PixelAccessorShim, Blender>;
- return fMemory.createT<Sampler>(next, dimensions, xTile, yTile, pixelAccessor);
+ return allocator->make<Sampler>(next, dimensions, xTile, yTile, pixelAccessor);
}
}
Blender* SkLinearBitmapPipeline::chooseBlenderForShading(
SkAlphaType alphaType,
- float postAlpha) {
+ float postAlpha,
+ SkFallbackAlloc* allocator)
+{
if (alphaType == kUnpremul_SkAlphaType) {
- return fMemory.createT<SrcFPPixel<kUnpremul_SkAlphaType>>(postAlpha);
+ return allocator->make<SrcFPPixel<kUnpremul_SkAlphaType>>(postAlpha);
} else {
// kOpaque_SkAlphaType is treated the same as kPremul_SkAlphaType
- return fMemory.createT<SrcFPPixel<kPremul_SkAlphaType>>(postAlpha);
+ return allocator->make<SrcFPPixel<kPremul_SkAlphaType>>(postAlpha);
}
}
diff --git a/src/core/SkLinearBitmapPipeline.h b/src/core/SkLinearBitmapPipeline.h
index 472772e..62d2201 100644
--- a/src/core/SkLinearBitmapPipeline.h
+++ b/src/core/SkLinearBitmapPipeline.h
@@ -9,10 +9,10 @@
#define SkLinearBitmapPipeline_DEFINED
#include "SkColor.h"
+#include "SkFixedAlloc.h"
#include "SkImageInfo.h"
#include "SkMatrix.h"
#include "SkShader.h"
-#include "SkSmallAllocator.h"
class SkEmbeddableLinearPipeline;
@@ -33,25 +33,25 @@
SkFilterQuality filterQuality,
SkShader::TileMode xTile, SkShader::TileMode yTile,
SkColor paintColor,
- const SkPixmap& srcPixmap);
+ const SkPixmap& srcPixmap,
+ SkFallbackAlloc* allocator);
SkLinearBitmapPipeline(
const SkLinearBitmapPipeline& pipeline,
const SkPixmap& srcPixmap,
SkBlendMode,
- const SkImageInfo& dstInfo);
+ const SkImageInfo& dstInfo,
+ SkFallbackAlloc* allocator);
- static bool ClonePipelineForBlitting(
- SkEmbeddableLinearPipeline* pipelineStorage,
+ static SkLinearBitmapPipeline* ClonePipelineForBlitting(
const SkLinearBitmapPipeline& pipeline,
SkMatrix::TypeMask matrixMask,
- SkShader::TileMode xTileMode,
- SkShader::TileMode yTileMode,
SkFilterQuality filterQuality,
const SkPixmap& srcPixmap,
float finalAlpha,
SkBlendMode,
- const SkImageInfo& dstInfo);
+ const SkImageInfo& dstInfo,
+ SkFallbackAlloc* allocator);
~SkLinearBitmapPipeline();
@@ -64,82 +64,59 @@
class DestinationInterface;
class PixelAccessorInterface;
-private:
- using MemoryAllocator = SkSmallAllocator<5, 256>;
using MatrixCloner =
- std::function<PointProcessorInterface* (PointProcessorInterface*, MemoryAllocator*)>;
+ std::function<PointProcessorInterface* (PointProcessorInterface*, SkFallbackAlloc*)>;
using TilerCloner =
- std::function<PointProcessorInterface* (SampleProcessorInterface*, MemoryAllocator*)>;
+ std::function<PointProcessorInterface* (SampleProcessorInterface*, SkFallbackAlloc*)>;
PointProcessorInterface* chooseMatrix(
PointProcessorInterface* next,
- const SkMatrix& inverse);
+ const SkMatrix& inverse,
+ SkFallbackAlloc* allocator);
template <typename Tiler>
- PointProcessorInterface* createTiler(SampleProcessorInterface* next, SkISize dimensions);
+ PointProcessorInterface* createTiler(SampleProcessorInterface* next, SkISize dimensions,
+ SkFallbackAlloc* allocator);
template <typename XStrategy>
PointProcessorInterface* chooseTilerYMode(
- SampleProcessorInterface* next, SkShader::TileMode yMode, SkISize dimensions);
+ SampleProcessorInterface* next, SkShader::TileMode yMode, SkISize dimensions,
+ SkFallbackAlloc* allocator);
PointProcessorInterface* chooseTiler(
SampleProcessorInterface* next,
SkISize dimensions,
SkShader::TileMode xMode, SkShader::TileMode yMode,
SkFilterQuality filterQuality,
- SkScalar dx);
+ SkScalar dx,
+ SkFallbackAlloc* allocator);
template <SkColorType colorType>
- PixelAccessorInterface* chooseSpecificAccessor(const SkPixmap& srcPixmap);
+ PixelAccessorInterface* chooseSpecificAccessor(const SkPixmap& srcPixmap,
+ SkFallbackAlloc* allocator);
PixelAccessorInterface* choosePixelAccessor(
const SkPixmap& srcPixmap,
- const SkColor A8TintColor);
+ const SkColor A8TintColor,
+ SkFallbackAlloc* allocator);
SampleProcessorInterface* chooseSampler(
BlendProcessorInterface* next,
SkFilterQuality filterQuality,
SkShader::TileMode xTile, SkShader::TileMode yTile,
const SkPixmap& srcPixmap,
- const SkColor A8TintColor);
+ const SkColor A8TintColor,
+ SkFallbackAlloc* allocator);
BlendProcessorInterface* chooseBlenderForShading(
SkAlphaType alphaType,
- float postAlpha);
+ float postAlpha,
+ SkFallbackAlloc* allocator);
- MemoryAllocator fMemory;
PointProcessorInterface* fFirstStage;
MatrixCloner fMatrixStageCloner;
TilerCloner fTileStageCloner;
DestinationInterface* fLastStage;
};
-////////////////////////////////////////////////////////////////////////////////////////////////////
-// SkEmbeddableLinearPipeline - manage stricter alignment needs for SkLinearBitmapPipeline.
-class SkEmbeddableLinearPipeline {
-public:
- SkEmbeddableLinearPipeline() { }
- ~SkEmbeddableLinearPipeline() {
- if (fInitialized) {
- get()->~SkLinearBitmapPipeline();
- }
- }
-
- template <typename... Args>
- void init(Args&&... args) {
- new (fPipelineStorage) SkLinearBitmapPipeline{std::forward<Args>(args)...};
- fInitialized = true;
- }
-
- SkLinearBitmapPipeline* get() const {
- return reinterpret_cast<SkLinearBitmapPipeline*>(fPipelineStorage);
- }
- SkLinearBitmapPipeline& operator*() const { return *this->get(); }
- SkLinearBitmapPipeline* operator->() const { return this->get(); }
-
-private:
- alignas(SkLinearBitmapPipeline) mutable char fPipelineStorage[sizeof(SkLinearBitmapPipeline)];
- bool fInitialized {false};
-};
-
#endif // SkLinearBitmapPipeline_DEFINED