summaryrefslogtreecommitdiff
path: root/core/SkPictureShader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/SkPictureShader.cpp')
-rw-r--r--core/SkPictureShader.cpp82
1 files changed, 40 insertions, 42 deletions
diff --git a/core/SkPictureShader.cpp b/core/SkPictureShader.cpp
index 466c5e12..9655e85b 100644
--- a/core/SkPictureShader.cpp
+++ b/core/SkPictureShader.cpp
@@ -18,8 +18,10 @@
#include "GrContext.h"
#endif
-SkPictureShader::SkPictureShader(SkPicture* picture, TileMode tmx, TileMode tmy)
- : fPicture(SkRef(picture))
+SkPictureShader::SkPictureShader(SkPicture* picture, TileMode tmx, TileMode tmy,
+ const SkMatrix* localMatrix)
+ : INHERITED(localMatrix)
+ , fPicture(SkRef(picture))
, fTmx(tmx)
, fTmy(tmy) { }
@@ -34,11 +36,12 @@ SkPictureShader::~SkPictureShader() {
fPicture->unref();
}
-SkPictureShader* SkPictureShader::Create(SkPicture* picture, TileMode tmx, TileMode tmy) {
+SkPictureShader* SkPictureShader::Create(SkPicture* picture, TileMode tmx, TileMode tmy,
+ const SkMatrix* localMatrix) {
if (!picture || 0 == picture->width() || 0 == picture->height()) {
return NULL;
}
- return SkNEW_ARGS(SkPictureShader, (picture, tmx, tmy));
+ return SkNEW_ARGS(SkPictureShader, (picture, tmx, tmy, localMatrix));
}
void SkPictureShader::flatten(SkWriteBuffer& buffer) const {
@@ -49,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;
@@ -58,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;
@@ -79,6 +85,7 @@ SkShader* SkPictureShader::refBitmapShader(const SkMatrix& matrix) const {
SkAutoMutexAcquire ama(fCachedBitmapShaderMutex);
+ // TODO(fmalita): remove fCachedLocalMatrix from this key after getLocalMatrix is removed.
if (!fCachedBitmapShader || tileScale != fCachedTileScale ||
this->getLocalMatrix() != fCachedLocalMatrix) {
SkBitmap bm;
@@ -106,64 +113,55 @@ SkShader* SkPictureShader::refBitmapShader(const SkMatrix& matrix) const {
return fCachedBitmapShader;
}
-SkShader* SkPictureShader::validInternal(const SkBitmap& device, const SkPaint& paint,
- const SkMatrix& matrix, SkMatrix* totalInverse) const {
- if (!this->INHERITED::validContext(device, paint, matrix, totalInverse)) {
- return NULL;
- }
+size_t SkPictureShader::contextSize() const {
+ return sizeof(PictureShaderContext);
+}
- SkAutoTUnref<SkShader> bitmapShader(this->refBitmapShader(matrix));
- if (!bitmapShader || !bitmapShader->validContext(device, paint, matrix)) {
+SkShader::Context* SkPictureShader::onCreateContext(const ContextRec& rec, void* storage) const {
+ SkAutoTUnref<SkShader> bitmapShader(this->refBitmapShader(*rec.fMatrix, rec.fLocalMatrix));
+ if (NULL == bitmapShader.get()) {
return NULL;
}
-
- return bitmapShader.detach();
+ return PictureShaderContext::Create(storage, *this, rec, bitmapShader);
}
-bool SkPictureShader::validContext(const SkBitmap& device, const SkPaint& paint,
- const SkMatrix& matrix, SkMatrix* totalInverse) const {
- SkAutoTUnref<SkShader> shader(this->validInternal(device, paint, matrix, totalInverse));
- return shader != NULL;
-}
+/////////////////////////////////////////////////////////////////////////////////////////
-SkShader::Context* SkPictureShader::createContext(const SkBitmap& device, const SkPaint& paint,
- const SkMatrix& matrix, void* storage) const {
- SkAutoTUnref<SkShader> bitmapShader(this->validInternal(device, paint, matrix, NULL));
- if (!bitmapShader) {
- return NULL;
+SkShader::Context* SkPictureShader::PictureShaderContext::Create(void* storage,
+ const SkPictureShader& shader, const ContextRec& rec, SkShader* bitmapShader) {
+ PictureShaderContext* ctx = SkNEW_PLACEMENT_ARGS(storage, PictureShaderContext,
+ (shader, rec, bitmapShader));
+ if (NULL == ctx->fBitmapShaderContext) {
+ ctx->~PictureShaderContext();
+ ctx = NULL;
}
-
- return SkNEW_PLACEMENT_ARGS(storage, PictureShaderContext,
- (*this, device, paint, matrix, bitmapShader.detach()));
-}
-
-size_t SkPictureShader::contextSize() const {
- return sizeof(PictureShaderContext);
+ return ctx;
}
SkPictureShader::PictureShaderContext::PictureShaderContext(
- const SkPictureShader& shader, const SkBitmap& device,
- const SkPaint& paint, const SkMatrix& matrix, SkShader* bitmapShader)
- : INHERITED(shader, device, paint, matrix)
- , fBitmapShader(bitmapShader)
+ const SkPictureShader& shader, const ContextRec& rec, SkShader* bitmapShader)
+ : INHERITED(shader, rec)
+ , fBitmapShader(SkRef(bitmapShader))
{
- SkASSERT(fBitmapShader);
- fBitmapShaderContextStorage = sk_malloc_throw(fBitmapShader->contextSize());
- fBitmapShaderContext = fBitmapShader->createContext(
- device, paint, matrix, fBitmapShaderContextStorage);
- SkASSERT(fBitmapShaderContext);
+ fBitmapShaderContextStorage = sk_malloc_throw(bitmapShader->contextSize());
+ fBitmapShaderContext = bitmapShader->createContext(rec, fBitmapShaderContextStorage);
+ //if fBitmapShaderContext is null, we are invalid
}
SkPictureShader::PictureShaderContext::~PictureShaderContext() {
- fBitmapShaderContext->~Context();
+ if (fBitmapShaderContext) {
+ fBitmapShaderContext->~Context();
+ }
sk_free(fBitmapShaderContextStorage);
}
uint32_t SkPictureShader::PictureShaderContext::getFlags() const {
+ SkASSERT(fBitmapShaderContext);
return fBitmapShaderContext->getFlags();
}
SkShader::Context::ShadeProc SkPictureShader::PictureShaderContext::asAShadeProc(void** ctx) {
+ SkASSERT(fBitmapShaderContext);
return fBitmapShaderContext->asAShadeProc(ctx);
}
@@ -195,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;
}