aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-10-31 18:09:01 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-10-31 18:09:01 +0000
commitf94b3a4cebd4adab09c40ebe23c02a615e10c394 (patch)
treea611a0cb0e1db232fbe5a1af0312eea05428dce1
parentc1f6db86dcf478d3c067bfc3fd99174b23d81732 (diff)
Make SkShader store localM directly rather than as a separate alloc.
May cause very slight GM changes in gpu two pt radial/conical radients. Review URL: https://codereview.appspot.com/6821056 git-svn-id: http://skia.googlecode.com/svn/trunk@6221 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r--include/core/SkShader.h17
-rw-r--r--src/core/SkBitmapProcShader.cpp5
-rw-r--r--src/core/SkComposeShader.cpp3
-rw-r--r--src/core/SkDraw.cpp17
-rw-r--r--src/core/SkShader.cpp56
-rw-r--r--src/device/xps/SkXPSDevice.cpp6
-rw-r--r--src/effects/gradients/SkLinearGradient.cpp16
-rw-r--r--src/effects/gradients/SkRadialGradient.cpp14
-rw-r--r--src/effects/gradients/SkSweepGradient.cpp15
-rw-r--r--src/effects/gradients/SkTwoPointConicalGradient.cpp25
-rw-r--r--src/effects/gradients/SkTwoPointRadialGradient.cpp26
-rw-r--r--src/gpu/SkGpuDevice.cpp19
-rw-r--r--src/pdf/SkPDFShader.cpp2
13 files changed, 80 insertions, 141 deletions
diff --git a/include/core/SkShader.h b/include/core/SkShader.h
index 90d831710c..1286177271 100644
--- a/include/core/SkShader.h
+++ b/include/core/SkShader.h
@@ -39,22 +39,25 @@ public:
virtual ~SkShader();
/**
- * Return true if the shader has a non-identity local matrix.
- * @param localM Optional: If not null, return the shader's local matrix
- * @return true if the shader has a non-identity local matrix.
+ * Returns true if the local matrix is not an identity matrix.
*/
- bool getLocalMatrix(SkMatrix* localM) const;
+ bool hasLocalMatrix() const { return !fLocalMatrix.isIdentity(); }
+
+ /**
+ * Returns the local matrix.
+ */
+ const SkMatrix& getLocalMatrix() const { return fLocalMatrix; }
/**
* Set the shader's local matrix.
* @param localM The shader's new local matrix.
*/
- void setLocalMatrix(const SkMatrix& localM);
+ void setLocalMatrix(const SkMatrix& localM) { fLocalMatrix = localM; }
/**
* Reset the shader's local matrix to identity.
*/
- void resetLocalMatrix();
+ void resetLocalMatrix() { fLocalMatrix.reset(); }
enum TileMode {
/** replicate the edge color if the shader draws outside of its
@@ -347,7 +350,7 @@ protected:
SkShader(SkFlattenableReadBuffer& );
virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
private:
- SkMatrix* fLocalMatrix;
+ SkMatrix fLocalMatrix;
SkMatrix fTotalInverse;
uint8_t fPaintAlpha;
uint8_t fDeviceConfig;
diff --git a/src/core/SkBitmapProcShader.cpp b/src/core/SkBitmapProcShader.cpp
index 66d9d7645d..6ea55bc54d 100644
--- a/src/core/SkBitmapProcShader.cpp
+++ b/src/core/SkBitmapProcShader.cpp
@@ -329,10 +329,9 @@ bool SkBitmapProcShader::toDumpString(SkString* str) const {
// add the (optional) matrix
{
- SkMatrix m;
- if (this->getLocalMatrix(&m)) {
+ if (this->hasLocalMatrix()) {
SkString info;
- m.toDumpString(&info);
+ this->getLocalMatrix().toDumpString(&info);
str->appendf(" %s", info.c_str());
}
}
diff --git a/src/core/SkComposeShader.cpp b/src/core/SkComposeShader.cpp
index e925ab5627..2fe7a20980 100644
--- a/src/core/SkComposeShader.cpp
+++ b/src/core/SkComposeShader.cpp
@@ -94,8 +94,7 @@ bool SkComposeShader::setContext(const SkBitmap& device,
SkMatrix tmpM;
- (void)this->getLocalMatrix(&tmpM);
- tmpM.setConcat(matrix, tmpM);
+ tmpM.setConcat(matrix, this->getLocalMatrix());
SkAutoAlphaRestore restore(const_cast<SkPaint*>(&paint), 0xFF);
diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp
index 885a810836..2af86c086a 100644
--- a/src/core/SkDraw.cpp
+++ b/src/core/SkDraw.cpp
@@ -2374,8 +2374,11 @@ void SkDraw::drawVertices(SkCanvas::VertexMode vmode, int count,
VertState::Proc vertProc = state.chooseProc(vmode);
if (NULL != textures || NULL != colors) {
- SkMatrix localM, tempM;
- bool hasLocalM = shader && shader->getLocalMatrix(&localM);
+ SkMatrix tempM;
+ SkMatrix savedLocalM;
+ if (shader) {
+ savedLocalM = shader->getLocalMatrix();
+ }
if (NULL != colors) {
if (!triShader.setContext(*fBitmap, p, *fMatrix)) {
@@ -2386,9 +2389,7 @@ void SkDraw::drawVertices(SkCanvas::VertexMode vmode, int count,
while (vertProc(&state)) {
if (NULL != textures) {
if (texture_to_matrix(state, vertices, textures, &tempM)) {
- if (hasLocalM) {
- tempM.postConcat(localM);
- }
+ tempM.postConcat(savedLocalM);
shader->setLocalMatrix(tempM);
// need to recal setContext since we changed the local matrix
if (!shader->setContext(*fBitmap, p, *fMatrix)) {
@@ -2410,11 +2411,7 @@ void SkDraw::drawVertices(SkCanvas::VertexMode vmode, int count,
}
// now restore the shader's original local matrix
if (NULL != shader) {
- if (hasLocalM) {
- shader->setLocalMatrix(localM);
- } else {
- shader->resetLocalMatrix();
- }
+ shader->setLocalMatrix(savedLocalM);
}
} else {
// no colors[] and no texture
diff --git a/src/core/SkShader.cpp b/src/core/SkShader.cpp
index 9c9366b93a..2b20e3d31f 100644
--- a/src/core/SkShader.cpp
+++ b/src/core/SkShader.cpp
@@ -15,23 +15,24 @@
SK_DEFINE_INST_COUNT(SkShader)
-SkShader::SkShader() : fLocalMatrix(NULL) {
+SkShader::SkShader() {
+ fLocalMatrix.reset();
SkDEBUGCODE(fInSession = false;)
}
SkShader::SkShader(SkFlattenableReadBuffer& buffer)
- : INHERITED(buffer), fLocalMatrix(NULL) {
+ : INHERITED(buffer) {
if (buffer.readBool()) {
- SkMatrix matrix;
- buffer.readMatrix(&matrix);
- setLocalMatrix(matrix);
+ buffer.readMatrix(&fLocalMatrix);
+ } else {
+ fLocalMatrix.reset();
}
+
SkDEBUGCODE(fInSession = false;)
}
SkShader::~SkShader() {
SkASSERT(!fInSession);
- sk_free(fLocalMatrix);
}
void SkShader::beginSession() {
@@ -46,41 +47,10 @@ void SkShader::endSession() {
void SkShader::flatten(SkFlattenableWriteBuffer& buffer) const {
this->INHERITED::flatten(buffer);
- buffer.writeBool(fLocalMatrix != NULL);
- if (fLocalMatrix) {
- buffer.writeMatrix(*fLocalMatrix);
- }
-}
-
-bool SkShader::getLocalMatrix(SkMatrix* localM) const {
- if (fLocalMatrix) {
- if (localM) {
- *localM = *fLocalMatrix;
- }
- return true;
- } else {
- if (localM) {
- localM->reset();
- }
- return false;
- }
-}
-
-void SkShader::setLocalMatrix(const SkMatrix& localM) {
- if (localM.isIdentity()) {
- this->resetLocalMatrix();
- } else {
- if (fLocalMatrix == NULL) {
- fLocalMatrix = (SkMatrix*)sk_malloc_throw(sizeof(SkMatrix));
- }
- *fLocalMatrix = localM;
- }
-}
-
-void SkShader::resetLocalMatrix() {
- if (fLocalMatrix) {
- sk_free(fLocalMatrix);
- fLocalMatrix = NULL;
+ bool hasLocalM = this->hasLocalMatrix();
+ buffer.writeBool(hasLocalM);
+ if (hasLocalM) {
+ buffer.writeMatrix(fLocalMatrix);
}
}
@@ -92,8 +62,8 @@ bool SkShader::setContext(const SkBitmap& device,
fDeviceConfig = SkToU8(device.getConfig());
fPaintAlpha = paint.getAlpha();
- if (fLocalMatrix) {
- total.setConcat(matrix, *fLocalMatrix);
+ if (this->hasLocalMatrix()) {
+ total.setConcat(matrix, this->getLocalMatrix());
m = &total;
}
if (m->invert(&fTotalInverse)) {
diff --git a/src/device/xps/SkXPSDevice.cpp b/src/device/xps/SkXPSDevice.cpp
index 8e62d49205..e1d5eedeaa 100644
--- a/src/device/xps/SkXPSDevice.cpp
+++ b/src/device/xps/SkXPSDevice.cpp
@@ -975,8 +975,7 @@ HRESULT SkXPSDevice::createXpsBrush(const SkPaint& skPaint,
return S_OK;
}
- SkMatrix localMatrix;
- shader->getLocalMatrix(&localMatrix);
+ SkMatrix localMatrix = shader->getLocalMatrix();
if (NULL != parentTransform) {
localMatrix.preConcat(*parentTransform);
}
@@ -1022,8 +1021,7 @@ HRESULT SkXPSDevice::createXpsBrush(const SkPaint& skPaint,
break;
case SkShader::kDefault_BitmapType: {
//TODO: outMatrix??
- SkMatrix localMatrix;
- shader->getLocalMatrix(&localMatrix);
+ SkMatrix localMatrix = shader->getLocalMatrix();
if (NULL != parentTransform) {
localMatrix.preConcat(*parentTransform);
}
diff --git a/src/effects/gradients/SkLinearGradient.cpp b/src/effects/gradients/SkLinearGradient.cpp
index 524db76966..d9576565b5 100644
--- a/src/effects/gradients/SkLinearGradient.cpp
+++ b/src/effects/gradients/SkLinearGradient.cpp
@@ -569,20 +569,12 @@ void GrGLLinearGradient::emitCode(GrGLShaderBuilder* builder,
bool SkLinearGradient::asNewEffect(GrContext* context, GrEffectStage* stage) const {
SkASSERT(NULL != context && NULL != stage);
-
- SkAutoTUnref<GrEffect> effect(SkNEW_ARGS(GrLinearGradient, (context, *this, fTileMode)));
-
SkMatrix matrix;
- if (this->getLocalMatrix(&matrix)) {
- if (!matrix.invert(&matrix)) {
- return false;
- }
- matrix.postConcat(fPtsToUnit);
- stage->setEffect(effect, matrix);
- } else {
- stage->setEffect(effect, fPtsToUnit);
+ if (!this->getLocalMatrix().invert(&matrix)) {
+ return false;
}
-
+ matrix.postConcat(fPtsToUnit);
+ stage->setEffect(SkNEW_ARGS(GrLinearGradient, (context, *this, fTileMode)), matrix)->unref();
return true;
}
diff --git a/src/effects/gradients/SkRadialGradient.cpp b/src/effects/gradients/SkRadialGradient.cpp
index 4766af604b..a20ea35a1a 100644
--- a/src/effects/gradients/SkRadialGradient.cpp
+++ b/src/effects/gradients/SkRadialGradient.cpp
@@ -567,19 +567,13 @@ void GrGLRadialGradient::emitCode(GrGLShaderBuilder* builder,
bool SkRadialGradient::asNewEffect(GrContext* context, GrEffectStage* stage) const {
SkASSERT(NULL != context && NULL != stage);
- SkAutoTUnref<GrEffect> effect(SkNEW_ARGS(GrRadialGradient, (context, *this, fTileMode)));
SkMatrix matrix;
- if (this->getLocalMatrix(&matrix)) {
- if (!matrix.invert(&matrix)) {
- return false;
- }
- matrix.postConcat(fPtsToUnit);
- stage->setEffect(effect, matrix);
- } else {
- stage->setEffect(effect, fPtsToUnit);
+ if (!this->getLocalMatrix().invert(&matrix)) {
+ return false;
}
-
+ matrix.postConcat(fPtsToUnit);
+ stage->setEffect(SkNEW_ARGS(GrRadialGradient, (context, *this, fTileMode)), matrix)->unref();
return true;
}
diff --git a/src/effects/gradients/SkSweepGradient.cpp b/src/effects/gradients/SkSweepGradient.cpp
index b64e15d0c1..a783e3757c 100644
--- a/src/effects/gradients/SkSweepGradient.cpp
+++ b/src/effects/gradients/SkSweepGradient.cpp
@@ -473,19 +473,12 @@ void GrGLSweepGradient::emitCode(GrGLShaderBuilder* builder,
/////////////////////////////////////////////////////////////////////
bool SkSweepGradient::asNewEffect(GrContext* context, GrEffectStage* stage) const {
- SkAutoTUnref<GrEffect> effect(SkNEW_ARGS(GrSweepGradient, (context, *this)));
-
SkMatrix matrix;
- if (this->getLocalMatrix(&matrix)) {
- if (!matrix.invert(&matrix)) {
- return false;
- }
- matrix.postConcat(fPtsToUnit);
- stage->setEffect(effect, matrix);
- } else {
- stage->setEffect(effect, fPtsToUnit);
+ if (!this->getLocalMatrix().invert(&matrix)) {
+ return false;
}
-
+ matrix.postConcat(fPtsToUnit);
+ stage->setEffect(SkNEW_ARGS(GrSweepGradient, (context, *this)), matrix)->unref();
return true;
}
diff --git a/src/effects/gradients/SkTwoPointConicalGradient.cpp b/src/effects/gradients/SkTwoPointConicalGradient.cpp
index acd0eeedfb..f93f660837 100644
--- a/src/effects/gradients/SkTwoPointConicalGradient.cpp
+++ b/src/effects/gradients/SkTwoPointConicalGradient.cpp
@@ -677,25 +677,22 @@ GrGLEffect::EffectKey GrGLConical2Gradient::GenKey(const GrEffectStage& s, const
bool SkTwoPointConicalGradient::asNewEffect(GrContext* context,
GrEffectStage* stage) const {
SkASSERT(NULL != context && NULL != stage);
-
+ SkASSERT(fPtsToUnit.isIdentity());
+ // invert the localM, translate to center1, rotate so center2 is on x axis.
SkMatrix matrix;
+ if (!this->getLocalMatrix().invert(&matrix)) {
+ return false;
+ }
+ matrix.postTranslate(-fCenter1.fX, -fCenter1.fY);
+
SkPoint diff = fCenter2 - fCenter1;
SkScalar diffLen = diff.length();
if (0 != diffLen) {
SkScalar invDiffLen = SkScalarInvert(diffLen);
- matrix.setSinCos(-SkScalarMul(invDiffLen, diff.fY),
- SkScalarMul(invDiffLen, diff.fX));
- } else {
- matrix.reset();
- }
- matrix.preTranslate(-fCenter1.fX, -fCenter1.fY);
-
- SkMatrix localM;
- if (this->getLocalMatrix(&localM)) {
- if (!localM.invert(&localM)) {
- return false;
- }
- matrix.preConcat(localM);
+ SkMatrix rot;
+ rot.setSinCos(-SkScalarMul(invDiffLen, diff.fY),
+ SkScalarMul(invDiffLen, diff.fX));
+ matrix.postConcat(rot);
}
stage->setEffect(SkNEW_ARGS(GrConical2Gradient, (context, *this, fTileMode)), matrix)->unref();
diff --git a/src/effects/gradients/SkTwoPointRadialGradient.cpp b/src/effects/gradients/SkTwoPointRadialGradient.cpp
index 9357b11685..659bce0099 100644
--- a/src/effects/gradients/SkTwoPointRadialGradient.cpp
+++ b/src/effects/gradients/SkTwoPointRadialGradient.cpp
@@ -651,24 +651,20 @@ GrGLEffect::EffectKey GrGLRadial2Gradient::GenKey(const GrEffectStage& s, const
bool SkTwoPointRadialGradient::asNewEffect(GrContext* context,
GrEffectStage* stage) const {
SkASSERT(NULL != context && NULL != stage);
- SkScalar diffLen = fDiff.length();
+ // invert the localM, translate to center1 (fPtsToUni), rotate so center2 is on x axis.
SkMatrix matrix;
- if (0 != diffLen) {
- SkScalar invDiffLen = SkScalarInvert(diffLen);
- matrix.setSinCos(-SkScalarMul(invDiffLen, fDiff.fY),
- SkScalarMul(invDiffLen, fDiff.fX));
- } else {
- matrix.reset();
+ if (!this->getLocalMatrix().invert(&matrix)) {
+ return false;
}
+ matrix.postConcat(fPtsToUnit);
- matrix.preConcat(fPtsToUnit);
-
- SkMatrix localM;
- if (this->getLocalMatrix(&localM)) {
- if (!localM.invert(&localM)) {
- return false;
- }
- matrix.preConcat(localM);
+ SkScalar diffLen = fDiff.length();
+ if (0 != diffLen) {
+ SkScalar invDiffLen = SkScalarInvert(diffLen);
+ SkMatrix rot;
+ rot.setSinCos(-SkScalarMul(invDiffLen, fDiff.fY),
+ SkScalarMul(invDiffLen, fDiff.fX));
+ matrix.postConcat(rot);
}
stage->setEffect(SkNEW_ARGS(GrRadial2Gradient, (context, *this, fTileMode)), matrix)->unref();
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index b0f4ac188b..cdccbcd049 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -584,6 +584,16 @@ inline bool skPaint2GrPaintShader(SkGpuDevice* dev,
return false;
}
+ // since our texture coords will be in local space, we whack the texture
+ // matrix to map them back into 0...1 before we load it
+ if (shader->hasLocalMatrix()) {
+ SkMatrix inverse;
+ if (!shader->getLocalMatrix().invert(&inverse)) {
+ return false;
+ }
+ matrix.preConcat(inverse);
+ }
+
// Must set wrap and filter on the sampler before requesting a texture.
GrTextureParams params(tileModes, skPaint.isFilterBitmap());
GrTexture* texture = textures[kShaderTextureIdx].set(dev, bitmap, &params);
@@ -593,15 +603,6 @@ inline bool skPaint2GrPaintShader(SkGpuDevice* dev,
return false;
}
- // since our texture coords will be in local space, we whack the texture
- // matrix to map them back into 0...1 before we load it
- SkMatrix localM;
- if (shader->getLocalMatrix(&localM)) {
- SkMatrix inverse;
- if (localM.invert(&inverse)) {
- matrix.preConcat(inverse);
- }
- }
if (SkShader::kDefault_BitmapType == bmptype) {
GrScalar sx = SkFloatToScalar(1.f / bitmap.width());
GrScalar sy = SkFloatToScalar(1.f / bitmap.height());
diff --git a/src/pdf/SkPDFShader.cpp b/src/pdf/SkPDFShader.cpp
index ace93ea73c..db5beb8fc8 100644
--- a/src/pdf/SkPDFShader.cpp
+++ b/src/pdf/SkPDFShader.cpp
@@ -937,7 +937,7 @@ SkPDFShader::State::State(const SkShader& shader,
fInfo.fColorCount = 0;
fInfo.fColors = NULL;
fInfo.fColorOffsets = NULL;
- shader.getLocalMatrix(&fShaderTransform);
+ fShaderTransform = shader.getLocalMatrix();
fImageTileModes[0] = fImageTileModes[1] = SkShader::kClamp_TileMode;
fType = shader.asAGradient(&fInfo);