diff options
author | herb <herb@google.com> | 2016-04-08 13:25:28 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-04-08 13:25:28 -0700 |
commit | 9e0efe57ac29b13d7f7a24ccefc456562acbad6c (patch) | |
tree | 1c287ce1e80817c272c8f92e4662c1807a2a6f99 | |
parent | c265a92741a8deee8adb62bb20c756b46672a11c (diff) |
Add clone to Stage. Rename place to mix and PolymorphicUnion to Stage. Cleanup.
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1877483002
Review URL: https://codereview.chromium.org/1877483002
-rw-r--r-- | gm/SkLinearBitmapPipelineGM.cpp | 2 | ||||
-rw-r--r-- | src/core/SkBitmapProcShader.h | 2 | ||||
-rw-r--r-- | src/core/SkLinearBitmapPipeline.cpp | 173 | ||||
-rw-r--r-- | src/core/SkLinearBitmapPipeline.h | 54 | ||||
-rw-r--r-- | src/core/SkLinearBitmapPipeline_sample.h | 77 | ||||
-rw-r--r-- | tests/SkColor4fTest.cpp | 2 |
6 files changed, 191 insertions, 119 deletions
diff --git a/gm/SkLinearBitmapPipelineGM.cpp b/gm/SkLinearBitmapPipelineGM.cpp index f5e01ca737..1bba1c56f9 100644 --- a/gm/SkLinearBitmapPipelineGM.cpp +++ b/gm/SkLinearBitmapPipelineGM.cpp @@ -59,7 +59,7 @@ static void draw_rect_orig(SkCanvas* canvas, const SkRect& r, SkColor c, const S sk_sp<SkImage> image(SkImage::MakeRasterCopy(SkPixmap(info, pmsrc.addr32(), pmsrc.rowBytes()))); SkPaint paint; - int32_t storage[300]; + int32_t storage[400]; sk_sp<SkShader> shader = image->makeShader(SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode); diff --git a/src/core/SkBitmapProcShader.h b/src/core/SkBitmapProcShader.h index 185a95de66..e2d3900a17 100644 --- a/src/core/SkBitmapProcShader.h +++ b/src/core/SkBitmapProcShader.h @@ -55,7 +55,7 @@ private: // an Sk3DBlitter in SkDraw.cpp // Note that some contexts may contain other contexts (e.g. for compose shaders), but we've not // yet found a situation where the size below isn't big enough. -typedef SkSmallAllocator<3, 2100> SkTBlitterAllocator; +typedef SkSmallAllocator<3, 2400> SkTBlitterAllocator; // If alloc is non-nullptr, it will be used to allocate the returned SkShader, and MUST outlive // the SkShader. diff --git a/src/core/SkLinearBitmapPipeline.cpp b/src/core/SkLinearBitmapPipeline.cpp index dc2ee513ca..539547af9a 100644 --- a/src/core/SkLinearBitmapPipeline.cpp +++ b/src/core/SkLinearBitmapPipeline.cpp @@ -65,21 +65,66 @@ public: class SkLinearBitmapPipeline::DestinationInterface { public: virtual ~DestinationInterface() { } + // Count is normally not needed, but in these early stages of development it is useful to + // check bounds. + // TODO(herb): 4/6/2016 - remove count when code is stable. virtual void setDestination(void* dst, int count) = 0; }; -class SkLinearBitmapPipeline::PixelPlacerInterface +class SkLinearBitmapPipeline::BlendProcessorInterface : public SkLinearBitmapPipeline::DestinationInterface { public: - virtual ~PixelPlacerInterface() { } - // Count is normally not needed, but in these early stages of development it is useful to - // check bounds. - // TODO(herb): 4/6/2016 - remove count when code is stable. - virtual void setDestination(void* dst, int count) = 0; - virtual void VECTORCALL placePixel(Sk4f pixel0) = 0; - virtual void VECTORCALL place4Pixels(Sk4f p0, Sk4f p1, Sk4f p2, Sk4f p3) = 0; + virtual void VECTORCALL blendPixel(Sk4f pixel0) = 0; + virtual void VECTORCALL blend4Pixels(Sk4f p0, Sk4f p1, Sk4f p2, Sk4f p3) = 0; }; +//////////////////////////////////////////////////////////////////////////////////////////////////// +// SkLinearBitmapPipeline::Stage +template<typename Base, size_t kSize, typename Next> +SkLinearBitmapPipeline::Stage<Base, kSize, Next>::~Stage() { + if (fIsInitialized) { + this->get()->~Base(); + } +} + +template<typename Base, size_t kSize, typename Next> +template<typename Variant, typename... Args> +void SkLinearBitmapPipeline::Stage<Base, kSize, Next>::initStage(Next* next, Args&& ... args) { + SkASSERTF(sizeof(Variant) <= sizeof(fSpace), + "Size Variant: %d, Space: %d", sizeof(Variant), sizeof(fSpace)); + + new (&fSpace) Variant(next, std::forward<Args>(args)...); + fStageCloner = [this](Next* nextClone, void* addr) { + new (addr) Variant(nextClone, (const Variant&)*this->get()); + }; + fIsInitialized = true; +}; + +template<typename Base, size_t kSize, typename Next> +template<typename Variant, typename... Args> +void SkLinearBitmapPipeline::Stage<Base, kSize, Next>::initSink(Args&& ... args) { + SkASSERTF(sizeof(Variant) <= sizeof(fSpace), + "Size Variant: %d, Space: %d", sizeof(Variant), sizeof(fSpace)); + new (&fSpace) Variant(std::forward<Args>(args)...); + fIsInitialized = true; +}; + +template<typename Base, size_t kSize, typename Next> +template <typename To, typename From> +To* SkLinearBitmapPipeline::Stage<Base, kSize, Next>::getInterface() { + From* down = static_cast<From*>(this->get()); + return static_cast<To*>(down); +} + +template<typename Base, size_t kSize, typename Next> +Base* SkLinearBitmapPipeline::Stage<Base, kSize, Next>::cloneStageTo( + Next* next, Stage* cloneToStage) const +{ + if (!fIsInitialized) return nullptr; + fStageCloner(next, &cloneToStage->fSpace); + return cloneToStage->get(); +} + namespace { //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -101,6 +146,10 @@ public: : fNext{next} , fStrategy{std::forward<Args>(args)...}{ } + MatrixStage(Next* next, const MatrixStage& stage) + : fNext{next} + , fStrategy{stage.fStrategy} { } + void VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) override { fStrategy.processPoints(&xs, &ys); fNext->pointListFew(n, xs, ys); @@ -142,7 +191,7 @@ static SkLinearBitmapPipeline::PointProcessorInterface* choose_matrix( const SkMatrix& inverse, SkLinearBitmapPipeline::MatrixStage* matrixProc) { if (inverse.hasPerspective()) { - matrixProc->Initialize<PerspectiveMatrix<>>( + matrixProc->initStage<PerspectiveMatrix<>>( next, SkVector{inverse.getTranslateX(), inverse.getTranslateY()}, SkVector{inverse.getScaleX(), inverse.getScaleY()}, @@ -150,18 +199,18 @@ static SkLinearBitmapPipeline::PointProcessorInterface* choose_matrix( SkVector{inverse.getPerspX(), inverse.getPerspY()}, inverse.get(SkMatrix::kMPersp2)); } else if (inverse.getSkewX() != 0.0f || inverse.getSkewY() != 0.0f) { - matrixProc->Initialize<AffineMatrix<>>( + matrixProc->initStage<AffineMatrix<>>( next, SkVector{inverse.getTranslateX(), inverse.getTranslateY()}, SkVector{inverse.getScaleX(), inverse.getScaleY()}, SkVector{inverse.getSkewX(), inverse.getSkewY()}); } else if (inverse.getScaleX() != 1.0f || inverse.getScaleY() != 1.0f) { - matrixProc->Initialize<ScaleMatrix<>>( + matrixProc->initStage<ScaleMatrix<>>( next, SkVector{inverse.getTranslateX(), inverse.getTranslateY()}, SkVector{inverse.getScaleX(), inverse.getScaleY()}); } else if (inverse.getTranslateX() != 0.0f || inverse.getTranslateY() != 0.0f) { - matrixProc->Initialize<TranslateMatrix<>>( + matrixProc->initStage<TranslateMatrix<>>( next, SkVector{inverse.getTranslateX(), inverse.getTranslateY()}); } else { @@ -182,6 +231,11 @@ public: , fXStrategy{dimensions.width()} , fYStrategy{dimensions.height()}{ } + NearestTileStage(Next* next, const NearestTileStage& stage) + : fNext{next} + , fXStrategy{stage.fXStrategy} + , fYStrategy{stage.fYStrategy} { } + void VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) override { fXStrategy.tileXPoints(&xs); fYStrategy.tileYPoints(&ys); @@ -218,11 +272,18 @@ class BilerpTileStage final : public SkLinearBitmapPipeline::PointProcessorInter public: template <typename... Args> BilerpTileStage(Next* next, SkISize dimensions) - : fXMax(dimensions.width()) + : fNext{next} + , fXMax(dimensions.width()) , fYMax(dimensions.height()) - , fNext{next} , fXStrategy{dimensions.width()} - , fYStrategy{dimensions.height()}{ } + , fYStrategy{dimensions.height()} { } + + BilerpTileStage(Next* next, const BilerpTileStage& stage) + : fNext{next} + , fXMax{stage.fXMax} + , fYMax{stage.fYMax} + , fXStrategy{stage.fXStrategy} + , fYStrategy{stage.fYStrategy} { } void VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) override { fXStrategy.tileXPoints(&xs); @@ -339,9 +400,9 @@ private: } } + Next* const fNext; SkScalar fXMax; SkScalar fYMax; - Next* const fNext; XStrategy fXStrategy; YStrategy fYStrategy; }; @@ -351,9 +412,9 @@ void make_tile_stage( SkFilterQuality filterQuality, SkISize dimensions, Next* next, SkLinearBitmapPipeline::TileStage* tileStage) { if (filterQuality == kNone_SkFilterQuality) { - tileStage->Initialize<NearestTileStage<XStrategy, YStrategy, Next>>(next, dimensions); + tileStage->initStage<NearestTileStage<XStrategy, YStrategy, Next>>(next, dimensions); } else { - tileStage->Initialize<BilerpTileStage<XStrategy, YStrategy, Next>>(next, dimensions); + tileStage->initStage<BilerpTileStage<XStrategy, YStrategy, Next>>(next, dimensions); } } template <typename XStrategy> @@ -413,6 +474,9 @@ public: NearestNeighborSampler(Next* next, Args&&... args) : fSampler{next, std::forward<Args>(args)...} { } + NearestNeighborSampler(Next* next, const NearestNeighborSampler& sampler) + : fSampler{next, sampler.fSampler} { } + void VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) override { fSampler.nearestListFew(n, xs, ys); } @@ -451,6 +515,9 @@ public: BilerpSampler(Next* next, Args&&... args) : fSampler{next, std::forward<Args>(args)...} { } + BilerpSampler(Next* next, const BilerpSampler& sampler) + : fSampler{next, sampler.fSampler} { } + void VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) override { fSampler.bilerpListFew(n, xs, ys); } @@ -554,34 +621,34 @@ private: uint32_t* fEnd; }; -using Placer = SkLinearBitmapPipeline::PixelPlacerInterface; +using Blender = SkLinearBitmapPipeline::BlendProcessorInterface; template<template <typename, typename> class Sampler> static SkLinearBitmapPipeline::SampleProcessorInterface* choose_pixel_sampler_base( - Placer* next, + Blender* next, const SkPixmap& srcPixmap, SkLinearBitmapPipeline::SampleStage* sampleStage) { const SkImageInfo& imageInfo = srcPixmap.info(); switch (imageInfo.colorType()) { case kRGBA_8888_SkColorType: if (imageInfo.profileType() == kSRGB_SkColorProfileType) { - sampleStage->Initialize<Sampler<Pixel8888SRGB, Placer>>(next, srcPixmap); + sampleStage->initStage<Sampler<Pixel8888SRGB, Blender>>(next, srcPixmap); } else { - sampleStage->Initialize<Sampler<Pixel8888LRGB, Placer>>(next, srcPixmap); + sampleStage->initStage<Sampler<Pixel8888LRGB, Blender>>(next, srcPixmap); } break; case kBGRA_8888_SkColorType: if (imageInfo.profileType() == kSRGB_SkColorProfileType) { - sampleStage->Initialize<Sampler<Pixel8888SBGR, Placer>>(next, srcPixmap); + sampleStage->initStage<Sampler<Pixel8888SBGR, Blender>>(next, srcPixmap); } else { - sampleStage->Initialize<Sampler<Pixel8888LBGR, Placer>>(next, srcPixmap); + sampleStage->initStage<Sampler<Pixel8888LBGR, Blender>>(next, srcPixmap); } break; case kIndex_8_SkColorType: if (imageInfo.profileType() == kSRGB_SkColorProfileType) { - sampleStage->Initialize<Sampler<PixelIndex8SRGB, Placer>>(next, srcPixmap); + sampleStage->initStage<Sampler<PixelIndex8SRGB, Blender>>(next, srcPixmap); } else { - sampleStage->Initialize<Sampler<PixelIndex8LRGB, Placer>>(next, srcPixmap); + sampleStage->initStage<Sampler<PixelIndex8LRGB, Blender>>(next, srcPixmap); } break; default: @@ -592,10 +659,11 @@ static SkLinearBitmapPipeline::SampleProcessorInterface* choose_pixel_sampler_ba } SkLinearBitmapPipeline::SampleProcessorInterface* choose_pixel_sampler( - Placer* next, + Blender* next, SkFilterQuality filterQuality, const SkPixmap& srcPixmap, - SkLinearBitmapPipeline::SampleStage* sampleStage) { + SkLinearBitmapPipeline::SampleStage* sampleStage) +{ if (filterQuality == kNone_SkFilterQuality) { return choose_pixel_sampler_base<NearestNeighborSampler>(next, srcPixmap, sampleStage); } else { @@ -604,25 +672,25 @@ SkLinearBitmapPipeline::SampleProcessorInterface* choose_pixel_sampler( } //////////////////////////////////////////////////////////////////////////////////////////////////// -// Pixel Placement Stage +// Pixel Blender Stage template <SkAlphaType alphaType> -class PlaceFPPixel final : public SkLinearBitmapPipeline::PixelPlacerInterface { +class SrcFPPixel final : public SkLinearBitmapPipeline::BlendProcessorInterface { public: - PlaceFPPixel(float postAlpha) : fPostAlpha{postAlpha} { } - - void VECTORCALL placePixel(Sk4f pixel) override { + SrcFPPixel(float postAlpha) : fPostAlpha{postAlpha} { } + SrcFPPixel(const SrcFPPixel& Blender) : fPostAlpha(Blender.fPostAlpha) {} + void VECTORCALL blendPixel(Sk4f pixel) override { SkASSERT(fDst + 1 <= fEnd ); - PlacePixel(fDst, pixel, 0); + SrcPixel(fDst, pixel, 0); fDst += 1; } - void VECTORCALL place4Pixels(Sk4f p0, Sk4f p1, Sk4f p2, Sk4f p3) override { + void VECTORCALL blend4Pixels(Sk4f p0, Sk4f p1, Sk4f p2, Sk4f p3) override { SkASSERT(fDst + 4 <= fEnd); SkPM4f* dst = fDst; - PlacePixel(dst, p0, 0); - PlacePixel(dst, p1, 1); - PlacePixel(dst, p2, 2); - PlacePixel(dst, p3, 3); + SrcPixel(dst, p0, 0); + SrcPixel(dst, p1, 1); + SrcPixel(dst, p2, 2); + SrcPixel(dst, p3, 3); fDst += 4; } @@ -632,7 +700,7 @@ public: } private: - void VECTORCALL PlacePixel(SkPM4f* dst, Sk4f pixel, int index) { + void VECTORCALL SrcPixel(SkPM4f* dst, Sk4f pixel, int index) { Sk4f newPixel = pixel; if (alphaType == kUnpremul_SkAlphaType) { newPixel = Premultiply(pixel); @@ -650,21 +718,22 @@ private: Sk4f fPostAlpha; }; -static SkLinearBitmapPipeline::PixelPlacerInterface* choose_pixel_placer( +static SkLinearBitmapPipeline::BlendProcessorInterface* choose_blender( SkAlphaType alphaType, float postAlpha, - SkLinearBitmapPipeline::PixelStage* placerStage) { + SkLinearBitmapPipeline::BlenderStage* blenderStage) { if (alphaType == kUnpremul_SkAlphaType) { - placerStage->Initialize<PlaceFPPixel<kUnpremul_SkAlphaType>>(postAlpha); + blenderStage->initSink<SrcFPPixel<kUnpremul_SkAlphaType>>(postAlpha); } else { // kOpaque_SkAlphaType is treated the same as kPremul_SkAlphaType - placerStage->Initialize<PlaceFPPixel<kPremul_SkAlphaType>>(postAlpha); + blenderStage->initSink<SrcFPPixel<kPremul_SkAlphaType>>(postAlpha); } - return placerStage->get(); + return blenderStage->get(); } } // namespace //////////////////////////////////////////////////////////////////////////////////////////////////// +// SkLinearBitmapPipeline SkLinearBitmapPipeline::~SkLinearBitmapPipeline() {} SkLinearBitmapPipeline::SkLinearBitmapPipeline( @@ -699,14 +768,12 @@ SkLinearBitmapPipeline::SkLinearBitmapPipeline( // 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 placementStage = choose_pixel_placer(alphaType, postAlpha, &fPixelStage); - auto samplerStage = choose_pixel_sampler(placementStage, - filterQuality, srcPixmap, &fSampleStage); - auto tilerStage = choose_tiler(samplerStage, - dimensions, xTile, yTile, filterQuality, dx, &fTiler); - fFirstStage = choose_matrix(tilerStage, adjustedInverse, &fMatrixStage); - fLastStage = placementStage; - + auto blenderStage = choose_blender(alphaType, postAlpha, &fBlenderStage); + auto samplerStage = choose_pixel_sampler(blenderStage, filterQuality, srcPixmap, &fSampleStage); + auto tilerStage = choose_tiler(samplerStage, dimensions, xTile, yTile, + filterQuality, dx, &fTileStage); + fFirstStage = choose_matrix(tilerStage, adjustedInverse, &fMatrixStage); + fLastStage = blenderStage; } void SkLinearBitmapPipeline::shadeSpan4f(int x, int y, SkPM4f* dst, int count) { diff --git a/src/core/SkLinearBitmapPipeline.h b/src/core/SkLinearBitmapPipeline.h index 32e464100f..548302ef9a 100644 --- a/src/core/SkLinearBitmapPipeline.h +++ b/src/core/SkLinearBitmapPipeline.h @@ -8,11 +8,9 @@ #ifndef SkLinearBitmapPipeline_DEFINED #define SkLinearBitmapPipeline_DEFINED - #include "SkColor.h" #include "SkImageInfo.h" #include "SkMatrix.h" -#include "SkNx.h" #include "SkShader.h" class SkLinearBitmapPipeline { @@ -27,31 +25,33 @@ public: void shadeSpan4f(int x, int y, SkPM4f* dst, int count); - template<typename Base, size_t kSize> - class PolymorphicUnion { + template<typename Base, size_t kSize, typename Next = void> + class Stage { public: - PolymorphicUnion() : fIsInitialized{false} {} + Stage() : fIsInitialized{false} {} + ~Stage(); - ~PolymorphicUnion() { - if (fIsInitialized) { - this->get()->~Base(); - } - } + template<typename Variant, typename... Args> + void initStage(Next* next, Args&& ... args); template<typename Variant, typename... Args> - void Initialize(Args&&... args) { - SkASSERTF(sizeof(Variant) <= sizeof(fSpace), - "Size Variant: %d, Space: %d", sizeof(Variant), sizeof(fSpace)); + void initSink(Args&& ... args); - new(&fSpace) Variant(std::forward<Args>(args)...); - fIsInitialized = true; - }; + template <typename To, typename From> + To* getInterface(); + + // Copy this stage to `cloneToStage` with `next` as its next stage + // (not necessarily the same as our next, you see), returning `cloneToStage`. + // Note: There is no cloneSinkTo method because the code usually places the top part of + // the pipeline on a new sampler. + Base* cloneStageTo(Next* next, Stage* cloneToStage) const; Base* get() const { return reinterpret_cast<Base*>(&fSpace); } Base* operator->() const { return this->get(); } Base& operator*() const { return *(this->get()); } private: + std::function<void (Next*, void*)> fStageCloner; struct SK_STRUCT_ALIGN(16) Space { char space[kSize]; }; @@ -61,22 +61,22 @@ public: class PointProcessorInterface; class SampleProcessorInterface; - class PixelPlacerInterface; + class BlendProcessorInterface; class DestinationInterface; - // These values were generated by the assert above in PolymorphicUnion. - using MatrixStage = PolymorphicUnion<PointProcessorInterface, 160>; - using TileStage = PolymorphicUnion<PointProcessorInterface, 160>; - using SampleStage = PolymorphicUnion<SampleProcessorInterface,100>; - using PixelStage = PolymorphicUnion<PixelPlacerInterface, 80>; + // These values were generated by the assert above in Stage::init{Sink|Stage}. + using MatrixStage = Stage<PointProcessorInterface, 160, PointProcessorInterface>; + using TileStage = Stage<PointProcessorInterface, 160, SampleProcessorInterface>; + using SampleStage = Stage<SampleProcessorInterface, 100, BlendProcessorInterface>; + using BlenderStage = Stage<BlendProcessorInterface, 80>; private: PointProcessorInterface* fFirstStage; - MatrixStage fMatrixStage; - TileStage fTiler; - SampleStage fSampleStage; - PixelStage fPixelStage; - DestinationInterface* fLastStage; + MatrixStage fMatrixStage; + TileStage fTileStage; + SampleStage fSampleStage; + BlenderStage fBlenderStage; + DestinationInterface* fLastStage; }; #endif // SkLinearBitmapPipeline_DEFINED diff --git a/src/core/SkLinearBitmapPipeline_sample.h b/src/core/SkLinearBitmapPipeline_sample.h index 93932247cd..7157ffc8ee 100644 --- a/src/core/SkLinearBitmapPipeline_sample.h +++ b/src/core/SkLinearBitmapPipeline_sample.h @@ -52,22 +52,26 @@ template<typename SourceStrategy, typename Next> class GeneralSampler { public: template<typename... Args> - GeneralSampler(SkLinearBitmapPipeline::PixelPlacerInterface* next, Args&& ... args) + GeneralSampler(SkLinearBitmapPipeline::BlendProcessorInterface* next, Args&& ... args) : fNext{next}, fStrategy{std::forward<Args>(args)...} { } + GeneralSampler(SkLinearBitmapPipeline::BlendProcessorInterface* next, + const GeneralSampler& sampler) + : fNext{next}, fStrategy{sampler.fStrategy} { } + void VECTORCALL nearestListFew(int n, Sk4s xs, Sk4s ys) { SkASSERT(0 < n && n < 4); Sk4f px0, px1, px2; fStrategy.getFewPixels(n, xs, ys, &px0, &px1, &px2); - if (n >= 1) fNext->placePixel(px0); - if (n >= 2) fNext->placePixel(px1); - if (n >= 3) fNext->placePixel(px2); + if (n >= 1) fNext->blendPixel(px0); + if (n >= 2) fNext->blendPixel(px1); + if (n >= 3) fNext->blendPixel(px2); } void VECTORCALL nearestList4(Sk4s xs, Sk4s ys) { Sk4f px0, px1, px2, px3; fStrategy.get4Pixels(xs, ys, &px0, &px1, &px2, &px3); - fNext->place4Pixels(px0, px1, px2, px3); + fNext->blend4Pixels(px0, px1, px2, px3); } void nearestSpan(Span span) { @@ -102,16 +106,16 @@ public: return this->bilerNonEdgePixel(xs[index], ys[index]); }; - if (n >= 1) fNext->placePixel(bilerpPixel(0)); - if (n >= 2) fNext->placePixel(bilerpPixel(1)); - if (n >= 3) fNext->placePixel(bilerpPixel(2)); + if (n >= 1) fNext->blendPixel(bilerpPixel(0)); + if (n >= 2) fNext->blendPixel(bilerpPixel(1)); + if (n >= 3) fNext->blendPixel(bilerpPixel(2)); } void VECTORCALL bilerpList4(Sk4s xs, Sk4s ys) { auto bilerpPixel = [&](int index) { return this->bilerNonEdgePixel(xs[index], ys[index]); }; - fNext->place4Pixels(bilerpPixel(0), bilerpPixel(1), bilerpPixel(2), bilerpPixel(3)); + fNext->blend4Pixels(bilerpPixel(0), bilerpPixel(1), bilerpPixel(2), bilerpPixel(3)); } void VECTORCALL bilerpEdge(Sk4s sampleXs, Sk4s sampleYs) { @@ -120,7 +124,7 @@ public: Sk4f ys = Sk4f{sampleYs[0]}; fStrategy.get4Pixels(sampleXs, sampleYs, &px00, &px10, &px01, &px11); Sk4f pixel = bilerp4(xs, ys, px00, px10, px01, px11); - fNext->placePixel(pixel); + fNext->blendPixel(pixel); } void bilerpSpan(Span span) { @@ -191,11 +195,11 @@ private: Sk4f px1 = getNextPixel(); Sk4f px2 = getNextPixel(); Sk4f px3 = getNextPixel(); - next->place4Pixels(px0, px1, px2, px3); + next->blend4Pixels(px0, px1, px2, px3); count -= 4; } while (count > 0) { - next->placePixel(getNextPixel()); + next->blendPixel(getNextPixel()); count -= 1; } } @@ -214,13 +218,13 @@ private: while (count >= 4) { Sk4f px0, px1, px2, px3; fStrategy.get4Pixels(row, ix, &px0, &px1, &px2, &px3); - next->place4Pixels(px0, px1, px2, px3); + next->blend4Pixels(px0, px1, px2, px3); ix += 4; count -= 4; } while (count > 0) { - next->placePixel(fStrategy.getPixelAt(row, ix)); + next->blendPixel(fStrategy.getPixelAt(row, ix)); ix += 1; count -= 1; } @@ -228,13 +232,13 @@ private: while (count >= 4) { Sk4f px0, px1, px2, px3; fStrategy.get4Pixels(row, ix - 3, &px3, &px2, &px1, &px0); - next->place4Pixels(px0, px1, px2, px3); + next->blend4Pixels(px0, px1, px2, px3); ix -= 4; count -= 4; } while (count > 0) { - next->placePixel(fStrategy.getPixelAt(row, ix)); + next->blendPixel(fStrategy.getPixelAt(row, ix)); ix -= 1; count -= 1; } @@ -272,11 +276,11 @@ private: Sk4f filterPixel = pixelY0 * filterY0 + pixelY1 * filterY1; int count = span.count(); while (count >= 4) { - fNext->place4Pixels(filterPixel, filterPixel, filterPixel, filterPixel); + fNext->blend4Pixels(filterPixel, filterPixel, filterPixel, filterPixel); count -= 4; } while (count > 0) { - fNext->placePixel(filterPixel); + fNext->blendPixel(filterPixel); count -= 1; } } @@ -341,12 +345,12 @@ private: Sk4f fpixel2 = getNextPixel(); Sk4f fpixel3 = getNextPixel(); - fNext->place4Pixels(fpixel0, fpixel1, fpixel2, fpixel3); + fNext->blend4Pixels(fpixel0, fpixel1, fpixel2, fpixel3); count -= 4; } while (count > 0) { - fNext->placePixel(getNextPixel()); + fNext->blendPixel(getNextPixel()); count -= 1; } @@ -416,11 +420,7 @@ private: Sk4f pxS3 = px30 + px31; Sk4f px3 = lerp(pxS2, pxS3); pxB = pxS3; - fNext->place4Pixels( - px0, - px1, - px2, - px3); + fNext->blend4Pixels(px0, px1, px2, px3); ix0 += 4; count -= 4; } @@ -428,7 +428,7 @@ private: Sk4f pixelY0 = fStrategy.getPixelAt(rowY0, ix0); Sk4f pixelY1 = fStrategy.getPixelAt(rowY1, ix0); - fNext->placePixel(lerp(pixelY0, pixelY1)); + fNext->blendPixel(lerp(pixelY0, pixelY1)); ix0 += 1; count -= 1; } @@ -448,11 +448,7 @@ private: Sk4f pxS0 = px00 + px01; Sk4f px3 = lerp(pxS0, pxS1); pxB = pxS0; - fNext->place4Pixels( - px0, - px1, - px2, - px3); + fNext->blend4Pixels(px0, px1, px2, px3); ix0 -= 4; count -= 4; } @@ -460,7 +456,7 @@ private: Sk4f pixelY0 = fStrategy.getPixelAt(rowY0, ix0); Sk4f pixelY1 = fStrategy.getPixelAt(rowY1, ix0); - fNext->placePixel(lerp(pixelY0, pixelY1)); + fNext->blendPixel(lerp(pixelY0, pixelY1)); ix0 -= 1; count -= 1; } @@ -488,7 +484,7 @@ private: fStrategy.get4Pixels(rowY0, ix, &px00, &px10, &px20, &px30); Sk4f px01, px11, px21, px31; fStrategy.get4Pixels(rowY1, ix, &px01, &px11, &px21, &px31); - fNext->place4Pixels( + fNext->blend4Pixels( lerp(&px00, &px01), lerp(&px10, &px11), lerp(&px20, &px21), lerp(&px30, &px31)); ix += 4; count -= 4; @@ -497,7 +493,7 @@ private: Sk4f pixelY0 = fStrategy.getPixelAt(rowY0, ix); Sk4f pixelY1 = fStrategy.getPixelAt(rowY1, ix); - fNext->placePixel(lerp(&pixelY0, &pixelY1)); + fNext->blendPixel(lerp(&pixelY0, &pixelY1)); ix += 1; count -= 1; } @@ -508,7 +504,7 @@ private: fStrategy.get4Pixels(rowY0, ix - 3, &px30, &px20, &px10, &px00); Sk4f px01, px11, px21, px31; fStrategy.get4Pixels(rowY1, ix - 3, &px31, &px21, &px11, &px01); - fNext->place4Pixels( + fNext->blend4Pixels( lerp(&px00, &px01), lerp(&px10, &px11), lerp(&px20, &px21), lerp(&px30, &px31)); ix -= 4; count -= 4; @@ -517,7 +513,7 @@ private: Sk4f pixelY0 = fStrategy.getPixelAt(rowY0, ix); Sk4f pixelY1 = fStrategy.getPixelAt(rowY1, ix); - fNext->placePixel(lerp(&pixelY0, &pixelY1)); + fNext->blendPixel(lerp(&pixelY0, &pixelY1)); ix -= 1; count -= 1; } @@ -657,6 +653,15 @@ public: } } + PixelIndex8(const PixelIndex8& strategy) + : fSrc{strategy.fSrc}, fWidth{strategy.fWidth} { + fColorTable = (Sk4f*)SkAlign16((intptr_t)fColorTableStorage.get()); + // TODO: figure out the count. + for (int i = 0; i < 256; i++) { + fColorTable[i] = strategy.fColorTable[i]; + } + } + void VECTORCALL getFewPixels(int n, Sk4s xs, Sk4s ys, Sk4f* px0, Sk4f* px1, Sk4f* px2) { Sk4i XIs = SkNx_cast<int, SkScalar>(xs); Sk4i YIs = SkNx_cast<int, SkScalar>(ys); diff --git a/tests/SkColor4fTest.cpp b/tests/SkColor4fTest.cpp index 239004aacb..67e8d37d24 100644 --- a/tests/SkColor4fTest.cpp +++ b/tests/SkColor4fTest.cpp @@ -153,7 +153,7 @@ DEF_TEST(Color4f_shader, reporter) { SkPaint paint; for (const auto& rec : recs) { - uint32_t storage[300]; + uint32_t storage[400]; paint.setShader(rec.fFact()); // Encourage 4f context selection. At some point we may need // to instantiate two separate contexts for optimal 4b/4f selection. |