aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar fmalita <fmalita@chromium.org>2016-02-22 17:19:04 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2016-02-22 17:19:04 -0800
commitd0c4e092d54d281991ecfdc2e4ddd5217e45b42a (patch)
treeb7410292954a9f95bef49d7668adb8d82a07e0f8
parent888934723db64ebecb0d6e577ba7b70689d83dd2 (diff)
Add dest type hint to SkShader::ContextRec
Let SkBlitter decide which dst type is optimal (PMColor vs PM4f), and pass that info to shaders. R=reed@google.com GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1724503002 Review URL: https://codereview.chromium.org/1724503002
-rw-r--r--bench/SkLinearBitmapPipelineBench.cpp3
-rw-r--r--gm/SkLinearBitmapPipelineGM.cpp4
-rw-r--r--include/core/SkShader.h19
-rw-r--r--src/core/SkBlitter.cpp16
-rw-r--r--src/core/SkBlitter.h2
-rw-r--r--src/core/SkDraw.cpp3
-rw-r--r--tests/SkColor4fTest.cpp5
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);