Use SkSmallAllocator for tiling.
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=4904
Change-Id: If401ea43454b46591d6f39492e7761b16a7e7a29
Reviewed-on: https://skia-review.googlesource.com/4904
Commit-Queue: Herb Derby <herb@google.com>
Reviewed-by: Mike Klein <mtklein@chromium.org>
diff --git a/src/core/SkLinearBitmapPipeline.cpp b/src/core/SkLinearBitmapPipeline.cpp
index ca42e02..dae6985 100644
--- a/src/core/SkLinearBitmapPipeline.cpp
+++ b/src/core/SkLinearBitmapPipeline.cpp
@@ -139,10 +139,10 @@
, fXStrategy{dimensions.width()}
, fYStrategy{dimensions.height()}{ }
- CombinedTileStage(Next* next, const CombinedTileStage& stage)
+ CombinedTileStage(Next* next, CombinedTileStage* stage)
: fNext{next}
- , fXStrategy{stage.fXStrategy}
- , fYStrategy{stage.fYStrategy} { }
+ , fXStrategy{stage->fXStrategy}
+ , fYStrategy{stage->fYStrategy} { }
void SK_VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) override {
fXStrategy.tileXPoints(&xs);
@@ -186,60 +186,6 @@
YStrategy fYStrategy;
};
-template <typename XStrategy, typename Next>
-void choose_tiler_ymode(
- SkShader::TileMode yMode, SkFilterQuality filterQuality, SkISize dimensions,
- Next* next,
- SkLinearBitmapPipeline::TileStage* tileStage) {
- switch (yMode) {
- case SkShader::kClamp_TileMode: {
- using Tiler = CombinedTileStage<XStrategy, YClampStrategy, Next>;
- tileStage->initStage<Tiler>(next, dimensions);
- break;
- }
- case SkShader::kRepeat_TileMode: {
- using Tiler = CombinedTileStage<XStrategy, YRepeatStrategy, Next>;
- tileStage->initStage<Tiler>(next, dimensions);
- break;
- }
- case SkShader::kMirror_TileMode: {
- using Tiler = CombinedTileStage<XStrategy, YMirrorStrategy, Next>;
- tileStage->initStage<Tiler>(next, dimensions);
- break;
- }
- }
-};
-
-static SkLinearBitmapPipeline::PointProcessorInterface* choose_tiler(
- SkLinearBitmapPipeline::SampleProcessorInterface* next,
- SkISize dimensions,
- SkShader::TileMode xMode,
- SkShader::TileMode yMode,
- SkFilterQuality filterQuality,
- SkScalar dx,
- SkLinearBitmapPipeline::TileStage* tileStage)
-{
- switch (xMode) {
- case SkShader::kClamp_TileMode:
- choose_tiler_ymode<XClampStrategy>(yMode, filterQuality, dimensions, next, tileStage);
- break;
- case SkShader::kRepeat_TileMode:
- if (dx == 1.0f && filterQuality == kNone_SkFilterQuality) {
- choose_tiler_ymode<XRepeatUnitScaleStrategy>(
- yMode, kNone_SkFilterQuality, dimensions, next, tileStage);
- } else {
- choose_tiler_ymode<XRepeatStrategy>(
- yMode, filterQuality, dimensions, next, tileStage);
- }
- break;
- case SkShader::kMirror_TileMode:
- choose_tiler_ymode<XMirrorStrategy>(yMode, filterQuality, dimensions, next, tileStage);
- break;
- }
-
- return tileStage->get();
-}
-
////////////////////////////////////////////////////////////////////////////////////////////////////
// Specialized Samplers
@@ -623,9 +569,9 @@
auto samplerStage = choose_pixel_sampler(
blenderStage, filterQuality, xTile, yTile,
srcPixmap, paintColor, &fSampleStage, &fAccessor);
- auto tilerStage = choose_tiler(samplerStage, dimensions, xTile, yTile,
- filterQuality, dx, &fTileStage);
- fFirstStage = ChooseMatrix(tilerStage, adjustedInverse);
+ auto tilerStage = this->chooseTiler(
+ samplerStage, dimensions, xTile, yTile, filterQuality, dx);
+ fFirstStage = this->chooseMatrix(tilerStage, adjustedInverse);
fLastStage = blenderStage;
}
@@ -685,8 +631,7 @@
}
auto sampleStage = fSampleStage.get();
- auto tilerStage = pipeline.fTileStage.cloneStageTo(sampleStage, &fTileStage);
- tilerStage = (tilerStage != nullptr) ? tilerStage : sampleStage;
+ auto tilerStage = pipeline.fTileStageCloner(sampleStage, &fMemory);
auto matrixStage = pipeline.fMatrixStageCloner(tilerStage, &fMemory);
fFirstStage = matrixStage;
}
@@ -708,7 +653,7 @@
}
SkLinearBitmapPipeline::PointProcessorInterface*
-SkLinearBitmapPipeline::ChooseMatrix(PointProcessorInterface* next, const SkMatrix& inverse) {
+SkLinearBitmapPipeline::chooseMatrix(PointProcessorInterface* next, const SkMatrix& inverse) {
if (inverse.hasPerspective()) {
auto matrixStage = fMemory.createT<PerspectiveMatrix<>>(
next,
@@ -759,3 +704,64 @@
return next;
}
}
+
+template <typename Tiler>
+SkLinearBitmapPipeline::PointProcessorInterface* SkLinearBitmapPipeline::createTiler(
+ SampleProcessorInterface* next, SkISize dimensions) {
+ auto tilerStage = fMemory.createT<Tiler>(next, dimensions);
+ fTileStageCloner =
+ [tilerStage](SampleProcessorInterface* cloneNext,
+ MemoryAllocator* memory) -> PointProcessorInterface* {
+ return memory->createT<Tiler>(cloneNext, tilerStage);
+ };
+ return tilerStage;
+}
+
+template <typename XStrategy>
+SkLinearBitmapPipeline::PointProcessorInterface* SkLinearBitmapPipeline::chooseTilerYMode(
+ SampleProcessorInterface* next, SkShader::TileMode yMode, SkISize dimensions) {
+ switch (yMode) {
+ case SkShader::kClamp_TileMode: {
+ using Tiler = CombinedTileStage<XStrategy, YClampStrategy, SampleProcessorInterface>;
+ return this->createTiler<Tiler>(next, dimensions);
+ }
+ case SkShader::kRepeat_TileMode: {
+ using Tiler = CombinedTileStage<XStrategy, YRepeatStrategy, SampleProcessorInterface>;
+ return this->createTiler<Tiler>(next, dimensions);
+ }
+ case SkShader::kMirror_TileMode: {
+ using Tiler = CombinedTileStage<XStrategy, YMirrorStrategy, SampleProcessorInterface>;
+ return this->createTiler<Tiler>(next, dimensions);
+ }
+ }
+
+ // Should never get here.
+ SkFAIL("Not all Y tile cases covered.");
+ return nullptr;
+}
+
+SkLinearBitmapPipeline::PointProcessorInterface* SkLinearBitmapPipeline::chooseTiler(
+ SampleProcessorInterface* next,
+ SkISize dimensions,
+ SkShader::TileMode xMode,
+ SkShader::TileMode yMode,
+ SkFilterQuality filterQuality,
+ SkScalar dx)
+{
+ switch (xMode) {
+ case SkShader::kClamp_TileMode:
+ return this->chooseTilerYMode<XClampStrategy>(next, yMode, dimensions);
+ case SkShader::kRepeat_TileMode:
+ if (dx == 1.0f && filterQuality == kNone_SkFilterQuality) {
+ return this->chooseTilerYMode<XRepeatUnitScaleStrategy>(next, yMode, dimensions);
+ } else {
+ return this->chooseTilerYMode<XRepeatStrategy>(next, yMode, dimensions);
+ }
+ case SkShader::kMirror_TileMode:
+ return this->chooseTilerYMode<XMirrorStrategy>(next, yMode, dimensions);
+ }
+
+ // Should never get here.
+ SkFAIL("Not all X tile cases covered.");
+ return nullptr;
+}
diff --git a/src/core/SkLinearBitmapPipeline.h b/src/core/SkLinearBitmapPipeline.h
index 3e7be5c..d5c43d9 100644
--- a/src/core/SkLinearBitmapPipeline.h
+++ b/src/core/SkLinearBitmapPipeline.h
@@ -126,24 +126,40 @@
class PixelAccessorInterface;
// These values were generated by the assert above in Stage::init{Sink|Stage}.
- using TileStage = Stage<PointProcessorInterface, 48, SampleProcessorInterface>;
using SampleStage = Stage<SampleProcessorInterface, 160, BlendProcessorInterface>;
using BlenderStage = Stage<BlendProcessorInterface, 48>;
using Accessor = PolyMemory<PixelAccessorInterface, 64>;
private:
- PointProcessorInterface* ChooseMatrix(
+ using MemoryAllocator = SkSmallAllocator<128, 2>;
+ using MatrixCloner =
+ std::function<PointProcessorInterface* (PointProcessorInterface*, MemoryAllocator*)>;
+ using TilerCloner =
+ std::function<PointProcessorInterface* (SampleProcessorInterface*, MemoryAllocator*)>;
+
+ PointProcessorInterface* chooseMatrix(
PointProcessorInterface* next,
const SkMatrix& inverse);
- using MemoryAllocator = SkSmallAllocator<64, 1>;
- using MatrixCloner =
- std::function<PointProcessorInterface* (PointProcessorInterface*, MemoryAllocator*)>;
+ template <typename Tiler>
+ PointProcessorInterface* createTiler(SampleProcessorInterface* next, SkISize dimensions);
+
+ template <typename XStrategy>
+ PointProcessorInterface* chooseTilerYMode(
+ SampleProcessorInterface* next, SkShader::TileMode yMode, SkISize dimensions);
+
+ PointProcessorInterface* chooseTiler(
+ SampleProcessorInterface* next,
+ SkISize dimensions,
+ SkShader::TileMode xMode,
+ SkShader::TileMode yMode,
+ SkFilterQuality filterQuality,
+ SkScalar dx);
MemoryAllocator fMemory;
PointProcessorInterface* fFirstStage;
MatrixCloner fMatrixStageCloner;
- TileStage fTileStage;
+ TilerCloner fTileStageCloner;
SampleStage fSampleStage;
BlenderStage fBlenderStage;
DestinationInterface* fLastStage;