diff options
-rw-r--r-- | bench/SkLinearBitmapPipelineBench.cpp | 3 | ||||
-rw-r--r-- | gm/SkLinearBitmapPipelineGM.cpp | 4 | ||||
-rw-r--r-- | include/core/SkShader.h | 19 | ||||
-rw-r--r-- | src/core/SkBlitter.cpp | 16 | ||||
-rw-r--r-- | src/core/SkBlitter.h | 2 | ||||
-rw-r--r-- | src/core/SkDraw.cpp | 3 | ||||
-rw-r--r-- | tests/SkColor4fTest.cpp | 5 |
7 files changed, 41 insertions, 11 deletions
diff --git a/bench/SkLinearBitmapPipelineBench.cpp b/bench/SkLinearBitmapPipelineBench.cpp index 8a4ba2cef9..8c44fa8511 100644 --- a/bench/SkLinearBitmapPipelineBench.cpp +++ b/bench/SkLinearBitmapPipelineBench.cpp @@ -196,7 +196,8 @@ struct SkBitmapFPOrigShader : public CommonBitmapFPBenchmark { SkAutoTMalloc<SkPMColor> buffer4b(width*height); uint32_t storage[200]; - const SkShader::ContextRec rec(fPaint, fM, nullptr); + const SkShader::ContextRec rec(fPaint, fM, nullptr, + SkShader::ContextRec::kPMColor_DstType); SkASSERT(fPaint.getShader()->contextSize(rec) <= sizeof(storage)); SkShader::Context* ctx = fPaint.getShader()->createContext(rec, storage); diff --git a/gm/SkLinearBitmapPipelineGM.cpp b/gm/SkLinearBitmapPipelineGM.cpp index fea095239a..c8fcfc9efe 100644 --- a/gm/SkLinearBitmapPipelineGM.cpp +++ b/gm/SkLinearBitmapPipelineGM.cpp @@ -6,6 +6,7 @@ */ #include "gm.h" +#include "SkBlitter.h" #include "SkCanvas.h" #include "SkColor.h" #include "SkImage.h" @@ -67,7 +68,8 @@ static void draw_rect_orig(SkCanvas* canvas, const SkRect& r, SkColor c, const S paint.setFilterQuality(SkFilterQuality::kNone_SkFilterQuality); } paint.setShader(shader)->unref(); - const SkShader::ContextRec rec(paint, *mat, nullptr); + const SkShader::ContextRec rec(paint, *mat, nullptr, + SkBlitter::PreferredShaderDest(pmsrc.info())); SkASSERT(paint.getShader()->contextSize(rec) <= sizeof(storage)); SkShader::Context* ctx = paint.getShader()->createContext(rec, storage); diff --git a/include/core/SkShader.h b/include/core/SkShader.h index 8e69fafa78..72cd4a2dbe 100644 --- a/include/core/SkShader.h +++ b/include/core/SkShader.h @@ -10,6 +10,7 @@ #include "SkBitmap.h" #include "SkFlattenable.h" +#include "SkImageInfo.h" #include "SkMask.h" #include "SkMatrix.h" #include "SkPaint.h" @@ -96,14 +97,22 @@ public: * ContextRec acts as a parameter bundle for creating Contexts. */ struct ContextRec { - ContextRec(const SkPaint& paint, const SkMatrix& matrix, const SkMatrix* localM) + enum DstType { + kPMColor_DstType, // clients prefer shading into PMColor dest + kPM4f_DstType, // clients prefer shading into PM4f dest + }; + + ContextRec(const SkPaint& paint, const SkMatrix& matrix, const SkMatrix* localM, + DstType dstType) : fPaint(&paint) , fMatrix(&matrix) - , fLocalMatrix(localM) {} + , fLocalMatrix(localM) + , fPreferredDstType(dstType) {} - const SkPaint* fPaint; // the current paint associated with the draw - const SkMatrix* fMatrix; // the current matrix in the canvas - const SkMatrix* fLocalMatrix; // optional local matrix + const SkPaint* fPaint; // the current paint associated with the draw + const SkMatrix* fMatrix; // the current matrix in the canvas + const SkMatrix* fLocalMatrix; // optional local matrix + const DstType fPreferredDstType; // the "natural" client dest type }; class Context : public ::SkNoncopyable { diff --git a/src/core/SkBlitter.cpp b/src/core/SkBlitter.cpp index 804bc813d6..c7c903dc6b 100644 --- a/src/core/SkBlitter.cpp +++ b/src/core/SkBlitter.cpp @@ -789,6 +789,16 @@ private: #include "SkCoreBlitters.h" +SkShader::ContextRec::DstType SkBlitter::PreferredShaderDest(const SkImageInfo& dstInfo) { +#ifdef SK_FORCE_PM4f_FOR_L32_BLITS + return SkShader::ContextRec::kPM4f_DstType; +#else + return (dstInfo.isSRGB() || dstInfo.colorType() == kRGBA_F16_SkColorType) + ? SkShader::ContextRec::kPM4f_DstType + : SkShader::ContextRec::kPMColor_DstType; +#endif +} + SkBlitter* SkBlitter::Choose(const SkPixmap& device, const SkMatrix& matrix, const SkPaint& origPaint, @@ -875,7 +885,8 @@ SkBlitter* SkBlitter::Choose(const SkPixmap& device, */ SkShader::Context* shaderContext = nullptr; if (shader) { - SkShader::ContextRec rec(*paint, matrix, nullptr); + const SkShader::ContextRec rec(*paint, matrix, nullptr, + PreferredShaderDest(device.info())); size_t contextSize = shader->contextSize(rec); if (contextSize) { // Try to create the ShaderContext @@ -961,7 +972,8 @@ class SkZeroShaderContext : public SkShader::Context { public: SkZeroShaderContext(const SkShader& shader, const SkShader::ContextRec& rec) // Override rec with the identity matrix, so it is guaranteed to be invertible. - : INHERITED(shader, SkShader::ContextRec(*rec.fPaint, SkMatrix::I(), nullptr)) {} + : INHERITED(shader, SkShader::ContextRec(*rec.fPaint, SkMatrix::I(), nullptr, + rec.fPreferredDstType)) {} void shadeSpan(int x, int y, SkPMColor colors[], int count) override { sk_bzero(colors, count * sizeof(SkPMColor)); diff --git a/src/core/SkBlitter.h b/src/core/SkBlitter.h index 5740a5eaed..8711f1a10f 100644 --- a/src/core/SkBlitter.h +++ b/src/core/SkBlitter.h @@ -137,6 +137,8 @@ public: SkTBlitterAllocator*); ///@} + static SkShader::ContextRec::DstType PreferredShaderDest(const SkImageInfo&); + protected: SkAutoMalloc fBlitMemory; }; diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp index b041df8f7a..0c17c94884 100644 --- a/src/core/SkDraw.cpp +++ b/src/core/SkDraw.cpp @@ -1896,7 +1896,8 @@ void SkDraw::drawVertices(SkCanvas::VertexMode vmode, int count, if (textures) { SkMatrix tempM; if (texture_to_matrix(state, vertices, textures, &tempM)) { - SkShader::ContextRec rec(p, *fMatrix, &tempM); + SkShader::ContextRec rec(p, *fMatrix, &tempM, + SkBlitter::PreferredShaderDest(fDst.info())); if (!blitter->resetShaderContext(rec)) { continue; } diff --git a/tests/SkColor4fTest.cpp b/tests/SkColor4fTest.cpp index 97ae5e3d5b..00581cc1e6 100644 --- a/tests/SkColor4fTest.cpp +++ b/tests/SkColor4fTest.cpp @@ -148,7 +148,10 @@ DEF_TEST(Color4f_shader, reporter) { for (const auto& rec : recs) { uint32_t storage[200]; paint.setShader(rec.fFact())->unref(); - const SkShader::ContextRec contextRec(paint, SkMatrix::I(), nullptr); + // Encourage 4f context selection. At some point we may need + // to instantiate two separate contexts for optimal 4b/4f selection. + const SkShader::ContextRec contextRec(paint, SkMatrix::I(), nullptr, + SkShader::ContextRec::kPM4f_DstType); SkASSERT(paint.getShader()->contextSize(contextRec) <= sizeof(storage)); SkShader::Context* ctx = paint.getShader()->createContext(contextRec, storage); REPORTER_ASSERT(reporter, ctx->supports4f() == rec.fSupports4f); |