diff options
author | 2012-12-13 21:39:56 +0000 | |
---|---|---|
committer | 2012-12-13 21:39:56 +0000 | |
commit | 1adcf8859cc9414591038e440e3f22382c8e4aa0 (patch) | |
tree | 9a7326ace2054faecd8ca907e90188b412be7b54 /src/core/SkBlitter.cpp | |
parent | 9f13174da5295e88d447f29740318003b9cec9c3 (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.cpp | 52 |
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(); } |