diff options
author | reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-12-14 13:13:55 +0000 |
---|---|---|
committer | reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-12-14 13:13:55 +0000 |
commit | ea033606a06d05d2d42aa7118409fee798e53167 (patch) | |
tree | eaa1a57aaf7655745d0806d5b5290f86486f0970 /src/core | |
parent | 8234e5448bf672d332880e75dd6d8ca82c1cd521 (diff) |
add per-draw checks for lockcounts
Review URL: https://codereview.appspot.com/6943056
git-svn-id: http://skia.googlecode.com/svn/trunk@6815 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/SkBlitter.cpp | 4 | ||||
-rw-r--r-- | src/core/SkBlitter.h | 8 | ||||
-rw-r--r-- | src/core/SkCanvas.cpp | 74 | ||||
-rw-r--r-- | src/core/SkDraw.cpp | 7 |
4 files changed, 93 insertions, 0 deletions
diff --git a/src/core/SkBlitter.cpp b/src/core/SkBlitter.cpp index 1589d51d3a..efe9d11a9d 100644 --- a/src/core/SkBlitter.cpp +++ b/src/core/SkBlitter.cpp @@ -22,6 +22,8 @@ SkBlitter::~SkBlitter() {} +bool SkBlitter::isNullBlitter() const { return false; } + const SkBitmap* SkBlitter::justAnOpaqueColor(uint32_t* value) { return NULL; } @@ -236,6 +238,8 @@ const SkBitmap* SkNullBlitter::justAnOpaqueColor(uint32_t* value) { return NULL; } +bool SkNullBlitter::isNullBlitter() const { return true; } + /////////////////////////////////////////////////////////////////////////////// static int compute_anti_width(const int16_t runs[]) { diff --git a/src/core/SkBlitter.h b/src/core/SkBlitter.h index ce74a28d0e..0a075f89ad 100644 --- a/src/core/SkBlitter.h +++ b/src/core/SkBlitter.h @@ -51,6 +51,13 @@ public: */ virtual const SkBitmap* justAnOpaqueColor(uint32_t* value); + /** + * Special method just to identify the null blitter, which is returned + * from Choose() if the request cannot be fulfilled. Default impl + * returns false. + */ + virtual bool isNullBlitter() const; + ///@name non-virtual helpers void blitMaskRegion(const SkMask& mask, const SkRegion& clip); void blitRectRegion(const SkIRect& rect, const SkRegion& clip); @@ -92,6 +99,7 @@ public: virtual void blitRect(int x, int y, int width, int height) SK_OVERRIDE; virtual void blitMask(const SkMask&, const SkIRect& clip) SK_OVERRIDE; virtual const SkBitmap* justAnOpaqueColor(uint32_t* value) SK_OVERRIDE; + virtual bool isNullBlitter() const SK_OVERRIDE; }; /** Wraps another (real) blitter, and ensures that the real blitter is only diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp index 7d25c2848c..096b42dc79 100644 --- a/src/core/SkCanvas.cpp +++ b/src/core/SkCanvas.cpp @@ -55,6 +55,52 @@ SK_DEFINE_INST_COUNT(SkDrawFilter) #define dec_canvas() #endif +#ifdef SK_DEBUG +#include "SkPixelRef.h" + +class AutoCheckLockCountBalance { +public: + AutoCheckLockCountBalance(const SkBitmap& bm) : fPixelRef(bm.pixelRef()) { + fLockCount = fPixelRef ? fPixelRef->getLockCount() : 0; + } + ~AutoCheckLockCountBalance() { + const int count = fPixelRef ? fPixelRef->getLockCount() : 0; + SkASSERT(count == fLockCount); + } + +private: + const SkPixelRef* fPixelRef; + int fLockCount; +}; + +class AutoCheckNoSetContext { +public: + AutoCheckNoSetContext(const SkPaint& paint) : fPaint(paint) { + this->assertNoSetContext(fPaint); + } + ~AutoCheckNoSetContext() { + this->assertNoSetContext(fPaint); + } + +private: + const SkPaint& fPaint; + + void assertNoSetContext(const SkPaint& paint) { + SkShader* s = paint.getShader(); + if (s) { + SkASSERT(!s->setContextHasBeenCalled()); + } + } +}; + +#define CHECK_LOCKCOUNT_BALANCE(bitmap) AutoCheckLockCountBalance clcb(bitmap) +#define CHECK_SHADER_NOSETCONTEXT(paint) AutoCheckNoSetContext cshsc(paint) + +#else + #define CHECK_LOCKCOUNT_BALANCE(bitmap) + #define CHECK_SHADER_NOSETCONTEXT(paint) +#endif + typedef SkTLazy<SkPaint> SkLazyPaint; void SkCanvas::predrawNotify() { @@ -963,6 +1009,7 @@ void SkCanvas::internalDrawDevice(SkDevice* srcDev, int x, int y, void SkCanvas::drawSprite(const SkBitmap& bitmap, int x, int y, const SkPaint* paint) { SkDEBUGCODE(bitmap.validate();) + CHECK_LOCKCOUNT_BALANCE(bitmap); if (reject_bitmap(bitmap)) { return; @@ -1422,6 +1469,8 @@ void SkCanvas::drawPaint(const SkPaint& paint) { } void SkCanvas::internalDrawPaint(const SkPaint& paint) { + CHECK_SHADER_NOSETCONTEXT(paint); + LOOPER_BEGIN(paint, SkDrawFilter::kPaint_Type) while (iter.next()) { @@ -1437,6 +1486,8 @@ void SkCanvas::drawPoints(PointMode mode, size_t count, const SkPoint pts[], return; } + CHECK_SHADER_NOSETCONTEXT(paint); + if (paint.canComputeFastBounds()) { SkRect r; // special-case 2 points (common for drawing a single line) @@ -1463,6 +1514,8 @@ void SkCanvas::drawPoints(PointMode mode, size_t count, const SkPoint pts[], } void SkCanvas::drawRect(const SkRect& r, const SkPaint& paint) { + CHECK_SHADER_NOSETCONTEXT(paint); + if (paint.canComputeFastBounds()) { SkRect storage; if (this->quickReject(paint.computeFastBounds(r, &storage))) { @@ -1480,6 +1533,8 @@ void SkCanvas::drawRect(const SkRect& r, const SkPaint& paint) { } void SkCanvas::drawOval(const SkRect& oval, const SkPaint& paint) { + CHECK_SHADER_NOSETCONTEXT(paint); + if (paint.canComputeFastBounds()) { SkRect storage; if (this->quickReject(paint.computeFastBounds(oval, &storage))) { @@ -1494,6 +1549,8 @@ void SkCanvas::drawOval(const SkRect& oval, const SkPaint& paint) { } void SkCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) { + CHECK_SHADER_NOSETCONTEXT(paint); + if (paint.canComputeFastBounds()) { SkRect storage; if (this->quickReject(paint.computeFastBounds(rrect.getBounds(), &storage))) { @@ -1514,6 +1571,8 @@ void SkCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) { void SkCanvas::drawPath(const SkPath& path, const SkPaint& paint) { + CHECK_SHADER_NOSETCONTEXT(paint); + if (!path.isFinite()) { return; } @@ -1571,6 +1630,8 @@ void SkCanvas::internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, return; } + CHECK_LOCKCOUNT_BALANCE(bitmap); + if (NULL == paint || paint->canComputeFastBounds()) { SkRect storage; const SkRect* bounds = &dst; @@ -1611,6 +1672,7 @@ void SkCanvas::drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& matrix, void SkCanvas::commonDrawBitmap(const SkBitmap& bitmap, const SkIRect* srcRect, const SkMatrix& matrix, const SkPaint& paint) { SkDEBUGCODE(bitmap.validate();) + CHECK_LOCKCOUNT_BALANCE(bitmap); LOOPER_BEGIN(paint, SkDrawFilter::kBitmap_Type) @@ -1790,6 +1852,8 @@ void SkCanvas::DrawTextDecorations(const SkDraw& draw, const SkPaint& paint, void SkCanvas::drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, const SkPaint& paint) { + CHECK_SHADER_NOSETCONTEXT(paint); + LOOPER_BEGIN(paint, SkDrawFilter::kText_Type) while (iter.next()) { @@ -1804,6 +1868,8 @@ void SkCanvas::drawText(const void* text, size_t byteLength, void SkCanvas::drawPosText(const void* text, size_t byteLength, const SkPoint pos[], const SkPaint& paint) { + CHECK_SHADER_NOSETCONTEXT(paint); + LOOPER_BEGIN(paint, SkDrawFilter::kText_Type) while (iter.next()) { @@ -1818,6 +1884,8 @@ void SkCanvas::drawPosText(const void* text, size_t byteLength, void SkCanvas::drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY, const SkPaint& paint) { + CHECK_SHADER_NOSETCONTEXT(paint); + LOOPER_BEGIN(paint, SkDrawFilter::kText_Type) while (iter.next()) { @@ -1832,6 +1900,8 @@ void SkCanvas::drawPosTextH(const void* text, size_t byteLength, void SkCanvas::drawTextOnPath(const void* text, size_t byteLength, const SkPath& path, const SkMatrix* matrix, const SkPaint& paint) { + CHECK_SHADER_NOSETCONTEXT(paint); + LOOPER_BEGIN(paint, SkDrawFilter::kText_Type) while (iter.next()) { @@ -1846,6 +1916,8 @@ void SkCanvas::drawTextOnPath(const void* text, size_t byteLength, void SkCanvas::drawPosTextOnPath(const void* text, size_t byteLength, const SkPoint pos[], const SkPaint& paint, const SkPath& path, const SkMatrix* matrix) { + CHECK_SHADER_NOSETCONTEXT(paint); + LOOPER_BEGIN(paint, SkDrawFilter::kText_Type) while (iter.next()) { @@ -1862,6 +1934,8 @@ void SkCanvas::drawVertices(VertexMode vmode, int vertexCount, const SkColor colors[], SkXfermode* xmode, const uint16_t indices[], int indexCount, const SkPaint& paint) { + CHECK_SHADER_NOSETCONTEXT(paint); + LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type) while (iter.next()) { diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp index 2f748d9930..b6eb6825d6 100644 --- a/src/core/SkDraw.cpp +++ b/src/core/SkDraw.cpp @@ -2424,6 +2424,13 @@ void SkDraw::drawVertices(SkCanvas::VertexMode vmode, int count, } SkAutoBlitterChoose blitter(*fBitmap, *fMatrix, p); + // important that we abort early, as below we may manipulate the shader + // and that is only valid if the shader returned true from setContext. + // If it returned false, then our blitter will be the NullBlitter. + if (blitter->isNullBlitter()) { + return; + } + // setup our state and function pointer for iterating triangles VertState state(count, indices, indexCount); VertState::Proc vertProc = state.chooseProc(vmode); |