aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkBlitter.cpp
diff options
context:
space:
mode:
authorGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-12-13 21:39:56 +0000
committerGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-12-13 21:39:56 +0000
commit1adcf8859cc9414591038e440e3f22382c8e4aa0 (patch)
tree9a7326ace2054faecd8ca907e90188b412be7b54 /src/core/SkBlitter.cpp
parent9f13174da5295e88d447f29740318003b9cec9c3 (diff)
Goal: ensure we always balance lock/unlock pixels calls.
A big caller of lockPixels is setContext in the bitmapshader. This change replaces beginSession/endSession with adding endContext(), and adds debugging code to ensure that 1. setContext calls are never nested 2. endContext is always called after each setContext call. Review URL: https://codereview.appspot.com/6937046 git-svn-id: http://skia.googlecode.com/svn/trunk@6798 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/core/SkBlitter.cpp')
-rw-r--r--src/core/SkBlitter.cpp52
1 files changed, 31 insertions, 21 deletions
diff --git a/src/core/SkBlitter.cpp b/src/core/SkBlitter.cpp
index 85331c23c3..1234f43c3f 100644
--- a/src/core/SkBlitter.cpp
+++ b/src/core/SkBlitter.cpp
@@ -572,16 +572,30 @@ public:
void setMask(const SkMask* mask) { fMask = mask; }
virtual bool setContext(const SkBitmap& device, const SkPaint& paint,
- const SkMatrix& matrix) {
+ const SkMatrix& matrix) SK_OVERRIDE {
+ if (!this->INHERITED::setContext(device, paint, matrix)) {
+ return false;
+ }
if (fProxy) {
- return fProxy->setContext(device, paint, matrix);
+ if (!fProxy->setContext(device, paint, matrix)) {
+ // must keep our set/end context calls balanced
+ this->INHERITED::endContext();
+ return false;
+ }
} else {
fPMColor = SkPreMultiplyColor(paint.getColor());
- return this->INHERITED::setContext(device, paint, matrix);
}
+ return true;
+ }
+
+ virtual void endContext() SK_OVERRIDE {
+ if (fProxy) {
+ fProxy->endContext();
+ }
+ this->INHERITED::endContext();
}
- virtual void shadeSpan(int x, int y, SkPMColor span[], int count) {
+ virtual void shadeSpan(int x, int y, SkPMColor span[], int count) SK_OVERRIDE {
if (fProxy) {
fProxy->shadeSpan(x, y, span, count);
}
@@ -645,20 +659,6 @@ public:
}
}
- virtual void beginSession() {
- this->INHERITED::beginSession();
- if (fProxy) {
- fProxy->beginSession();
- }
- }
-
- virtual void endSession() {
- if (fProxy) {
- fProxy->endSession();
- }
- this->INHERITED::endSession();
- }
-
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Sk3DShader)
protected:
@@ -907,8 +907,17 @@ SkBlitter* SkBlitter::Choose(const SkBitmap& device,
// if there is one, the shader will take care of it.
}
+ /*
+ * We need to have balanced calls to the shader:
+ * setContext
+ * endContext
+ * We make the first call here, in case it fails we can abort the draw.
+ * The endContext() call is made by the blitter (assuming setContext did
+ * not fail) in its destructor.
+ */
if (shader && !shader->setContext(device, *paint, matrix)) {
- return SkNEW(SkNullBlitter);
+ SK_PLACEMENT_NEW(blitter, SkNullBlitter, storage, storageSize);
+ return blitter;
}
switch (device.getConfig()) {
@@ -978,14 +987,15 @@ SkShaderBlitter::SkShaderBlitter(const SkBitmap& device, const SkPaint& paint)
: INHERITED(device) {
fShader = paint.getShader();
SkASSERT(fShader);
+ SkASSERT(fShader->setContextHasBeenCalled());
fShader->ref();
- fShader->beginSession();
fShaderFlags = fShader->getFlags();
}
SkShaderBlitter::~SkShaderBlitter() {
- fShader->endSession();
+ SkASSERT(fShader->setContextHasBeenCalled());
+ fShader->endContext();
fShader->unref();
}