aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2014-05-06 17:16:03 +0000
committerGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2014-05-06 17:16:03 +0000
commit80116dcf1e1baf9817ae42d0aca51f7eabaa2880 (patch)
treecf7e91ca4e0cd26ec0fa2b13fa75f4a7c41bd0dd
parent7418bd8cad3576294b48dd8e5015301e184c6af1 (diff)
add local-matrix to shader::context
BUG=skia: R=scroggo@google.com, dominikg@chromium.org Author: reed@google.com Review URL: https://codereview.chromium.org/263293005 git-svn-id: http://skia.googlecode.com/svn/trunk@14592 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r--include/core/SkShader.h29
-rw-r--r--src/core/SkBitmapProcShader.h5
-rw-r--r--src/core/SkBlitter.cpp13
-rw-r--r--src/core/SkBlitter.h3
-rw-r--r--src/core/SkCoreBlitters.h3
-rw-r--r--src/core/SkDraw.cpp26
-rw-r--r--src/core/SkPictureShader.cpp9
-rw-r--r--src/core/SkPictureShader.h2
-rw-r--r--src/core/SkShader.cpp8
9 files changed, 46 insertions, 52 deletions
diff --git a/include/core/SkShader.h b/include/core/SkShader.h
index 041730633a..dc93b84749 100644
--- a/include/core/SkShader.h
+++ b/include/core/SkShader.h
@@ -123,17 +123,17 @@ public:
* ContextRec acts as a parameter bundle for creating Contexts.
*/
struct ContextRec {
- ContextRec() : fDevice(NULL), fPaint(NULL), fMatrix(NULL) {}
- ContextRec(const ContextRec& other)
- : fDevice(other.fDevice), fPaint(other.fPaint), fMatrix(other.fMatrix) {}
+ ContextRec() : fDevice(NULL), fPaint(NULL), fMatrix(NULL), fLocalMatrix(NULL) {}
ContextRec(const SkBitmap& device, const SkPaint& paint, const SkMatrix& matrix)
: fDevice(&device)
, fPaint(&paint)
- , fMatrix(&matrix) {}
+ , fMatrix(&matrix)
+ , fLocalMatrix(NULL) {}
- const SkBitmap* fDevice; // the bitmap we are drawing into
- const SkPaint* fPaint; // the current paint associated with the draw
- const SkMatrix* fMatrix; // the current matrix in the canvas
+ const SkBitmap* fDevice; // the bitmap we are drawing into
+ 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
};
class Context : public ::SkNoncopyable {
@@ -200,14 +200,15 @@ public:
};
static MatrixClass ComputeMatrixClass(const SkMatrix&);
- uint8_t getPaintAlpha() const { return fPaintAlpha; }
- const SkMatrix& getTotalInverse() const { return fTotalInverse; }
- MatrixClass getInverseClass() const { return (MatrixClass)fTotalInverseClass; }
-
+ uint8_t getPaintAlpha() const { return fPaintAlpha; }
+ const SkMatrix& getTotalInverse() const { return fTotalInverse; }
+ MatrixClass getInverseClass() const { return (MatrixClass)fTotalInverseClass; }
+ const SkMatrix& getCTM() const { return fCTM; }
private:
- SkMatrix fTotalInverse;
- uint8_t fPaintAlpha;
- uint8_t fTotalInverseClass;
+ SkMatrix fCTM;
+ SkMatrix fTotalInverse;
+ uint8_t fPaintAlpha;
+ uint8_t fTotalInverseClass;
typedef SkNoncopyable INHERITED;
};
diff --git a/src/core/SkBitmapProcShader.h b/src/core/SkBitmapProcShader.h
index 0a036d3189..8d31256469 100644
--- a/src/core/SkBitmapProcShader.h
+++ b/src/core/SkBitmapProcShader.h
@@ -71,10 +71,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, sizeof(SkBitmapProcShader) +
- sizeof(SkBitmapProcShader::BitmapProcShaderContext) +
- sizeof(SkBitmapProcState) +
- sizeof(void*) * 2> SkTBlitterAllocator;
+typedef SkSmallAllocator<3, 768> SkTBlitterAllocator;
// If alloc is non-NULL, it will be used to allocate the returned SkShader, and MUST outlive
// the SkShader.
diff --git a/src/core/SkBlitter.cpp b/src/core/SkBlitter.cpp
index 0e12a627d0..81e46c5622 100644
--- a/src/core/SkBlitter.cpp
+++ b/src/core/SkBlitter.cpp
@@ -1,4 +1,3 @@
-
/*
* Copyright 2006 The Android Open Source Project
*
@@ -6,7 +5,6 @@
* found in the LICENSE file.
*/
-
#include "SkBlitter.h"
#include "SkAntiRun.h"
#include "SkColor.h"
@@ -26,8 +24,7 @@ SkBlitter::~SkBlitter() {}
bool SkBlitter::isNullBlitter() const { return false; }
-bool SkBlitter::resetShaderContext(const SkBitmap& device, const SkPaint& paint,
- const SkMatrix& matrix) {
+bool SkBlitter::resetShaderContext(const SkShader::ContextRec&) {
return true;
}
@@ -1030,10 +1027,7 @@ SkShaderBlitter::~SkShaderBlitter() {
fShader->unref();
}
-bool SkShaderBlitter::resetShaderContext(const SkBitmap& device, const SkPaint& paint,
- const SkMatrix& matrix) {
- SkShader::ContextRec rec(device, paint, matrix);
-
+bool SkShaderBlitter::resetShaderContext(const SkShader::ContextRec& rec) {
// Only destroy the old context if we have a new one. We need to ensure to have a
// live context in fShaderContext because the storage is owned by an SkSmallAllocator
// outside of this class.
@@ -1045,6 +1039,7 @@ bool SkShaderBlitter::resetShaderContext(const SkBitmap& device, const SkPaint&
// Need a valid context in fShaderContext's storage, so we can later (or our caller) call
// the in-place destructor.
SkNEW_PLACEMENT_ARGS(fShaderContext, SkTransparentShaderContext, (*fShader, rec));
+ return false;
}
- return ctx != NULL;
+ return true;
}
diff --git a/src/core/SkBlitter.h b/src/core/SkBlitter.h
index f76839e8b6..a3a2196122 100644
--- a/src/core/SkBlitter.h
+++ b/src/core/SkBlitter.h
@@ -64,8 +64,7 @@ public:
/**
* Special methods for SkShaderBlitter. On all other classes this is a no-op.
*/
- virtual bool resetShaderContext(const SkBitmap& device, const SkPaint& paint,
- const SkMatrix& matrix);
+ virtual bool resetShaderContext(const SkShader::ContextRec&);
virtual SkShader::Context* getShaderContext() const;
///@name non-virtual helpers
diff --git a/src/core/SkCoreBlitters.h b/src/core/SkCoreBlitters.h
index 2d22d38e78..20f9437ac8 100644
--- a/src/core/SkCoreBlitters.h
+++ b/src/core/SkCoreBlitters.h
@@ -41,8 +41,7 @@ public:
* Will create the context at the same location as the old one (this is safe
* because the shader itself is unchanged).
*/
- virtual bool resetShaderContext(const SkBitmap& device, const SkPaint& paint,
- const SkMatrix& matrix) SK_OVERRIDE;
+ virtual bool resetShaderContext(const SkShader::ContextRec&) SK_OVERRIDE;
virtual SkShader::Context* getShaderContext() const SK_OVERRIDE { return fShaderContext; }
diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp
index 9347efe475..24c8055716 100644
--- a/src/core/SkDraw.cpp
+++ b/src/core/SkDraw.cpp
@@ -2403,7 +2403,13 @@ bool SkTriColorShader::TriColorShaderContext::setup(const SkPoint pts[], const S
if (!m.invert(&im)) {
return false;
}
- fDstToUnit.setConcat(im, this->getTotalInverse());
+ // We can't call getTotalInverse(), because we explicitly don't want to look at the localmatrix
+ // as our interators are intrinsically tied to the vertices, and nothing else.
+ SkMatrix ctmInv;
+ if (!this->getCTM().invert(&ctmInv)) {
+ return false;
+ }
+ fDstToUnit.setConcat(im, ctmInv);
return true;
}
@@ -2556,18 +2562,13 @@ void SkDraw::drawVertices(SkCanvas::VertexMode vmode, int count,
VertState::Proc vertProc = state.chooseProc(vmode);
if (NULL != textures || NULL != colors) {
- SkMatrix tempM;
- SkMatrix savedLocalM;
- if (shader) {
- savedLocalM = shader->getLocalMatrix();
- }
-
while (vertProc(&state)) {
if (NULL != textures) {
+ SkMatrix tempM;
if (texture_to_matrix(state, vertices, textures, &tempM)) {
- tempM.postConcat(savedLocalM);
- shader->setLocalMatrix(tempM);
- if (!blitter->resetShaderContext(*fBitmap, p, *fMatrix)) {
+ SkShader::ContextRec rec(*fBitmap, p, *fMatrix);
+ rec.fLocalMatrix = &tempM;
+ if (!blitter->resetShaderContext(rec)) {
continue;
}
}
@@ -2603,11 +2604,6 @@ void SkDraw::drawVertices(SkCanvas::VertexMode vmode, int count,
};
SkScan::FillTriangle(tmp, *fRC, blitter.get());
}
-
- // now restore the shader's original local matrix
- if (NULL != shader) {
- shader->setLocalMatrix(savedLocalM);
- }
} else {
// no colors[] and no texture
HairProc hairProc = ChooseHairProc(paint.isAntiAlias());
diff --git a/src/core/SkPictureShader.cpp b/src/core/SkPictureShader.cpp
index 290baa8284..9655e85bd1 100644
--- a/src/core/SkPictureShader.cpp
+++ b/src/core/SkPictureShader.cpp
@@ -52,7 +52,7 @@ void SkPictureShader::flatten(SkWriteBuffer& buffer) const {
fPicture->flatten(buffer);
}
-SkShader* SkPictureShader::refBitmapShader(const SkMatrix& matrix) const {
+SkShader* SkPictureShader::refBitmapShader(const SkMatrix& matrix, const SkMatrix* localM) const {
SkASSERT(fPicture && fPicture->width() > 0 && fPicture->height() > 0);
SkMatrix m;
@@ -61,6 +61,9 @@ SkShader* SkPictureShader::refBitmapShader(const SkMatrix& matrix) const {
} else {
m = matrix;
}
+ if (localM) {
+ m.preConcat(*localM);
+ }
// Use a rotation-invariant scale
SkPoint scale;
@@ -115,7 +118,7 @@ size_t SkPictureShader::contextSize() const {
}
SkShader::Context* SkPictureShader::onCreateContext(const ContextRec& rec, void* storage) const {
- SkAutoTUnref<SkShader> bitmapShader(this->refBitmapShader(*rec.fMatrix));
+ SkAutoTUnref<SkShader> bitmapShader(this->refBitmapShader(*rec.fMatrix, rec.fLocalMatrix));
if (NULL == bitmapShader.get()) {
return NULL;
}
@@ -190,7 +193,7 @@ void SkPictureShader::toString(SkString* str) const {
#if SK_SUPPORT_GPU
GrEffectRef* SkPictureShader::asNewEffect(GrContext* context, const SkPaint& paint) const {
- SkAutoTUnref<SkShader> bitmapShader(this->refBitmapShader(context->getMatrix()));
+ SkAutoTUnref<SkShader> bitmapShader(this->refBitmapShader(context->getMatrix(), NULL));
if (!bitmapShader) {
return NULL;
}
diff --git a/src/core/SkPictureShader.h b/src/core/SkPictureShader.h
index 0fbfbee444..27fb674b01 100644
--- a/src/core/SkPictureShader.h
+++ b/src/core/SkPictureShader.h
@@ -41,7 +41,7 @@ protected:
private:
SkPictureShader(SkPicture*, TileMode, TileMode, const SkMatrix* = NULL);
- SkShader* refBitmapShader(const SkMatrix&) const;
+ SkShader* refBitmapShader(const SkMatrix&, const SkMatrix* localMatrix) const;
SkPicture* fPicture;
TileMode fTmx, fTmy;
diff --git a/src/core/SkShader.cpp b/src/core/SkShader.cpp
index 8e6112ae7d..0c954f869b 100644
--- a/src/core/SkShader.cpp
+++ b/src/core/SkShader.cpp
@@ -53,6 +53,10 @@ bool SkShader::computeTotalInverse(const ContextRec& rec, SkMatrix* totalInverse
total.setConcat(*m, this->getLocalMatrix());
m = &total;
}
+ if (rec.fLocalMatrix) {
+ total.setConcat(*m, *rec.fLocalMatrix);
+ m = &total;
+ }
return m->invert(totalInverse);
}
@@ -63,7 +67,7 @@ SkShader::Context* SkShader::createContext(const ContextRec& rec, void* storage)
return this->onCreateContext(rec, storage);
}
-SkShader::Context* SkShader::onCreateContext(const ContextRec&, void*) const {
+SkShader::Context* SkShader::onCreateContext(const ContextRec& rec, void*) const {
return NULL;
}
@@ -72,7 +76,7 @@ size_t SkShader::contextSize() const {
}
SkShader::Context::Context(const SkShader& shader, const ContextRec& rec)
- : fShader(shader)
+ : fShader(shader), fCTM(*rec.fMatrix)
{
// Because the context parameters must be valid at this point, we know that the matrix is
// invertible.