Added SkDevice onAttachToCanvas & onDetachFromCanvas methods
http://codereview.appspot.com/6348100/
git-svn-id: http://skia.googlecode.com/svn/trunk@4598 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 7d1ecbf..c40275d 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -78,11 +78,11 @@
const SkMatrix* fMVMatrix;
const SkMatrix* fExtMatrix;
- DeviceCM(SkDevice* device, int x, int y, const SkPaint* paint)
+ DeviceCM(SkDevice* device, int x, int y, const SkPaint* paint, SkCanvas* canvas)
: fNext(NULL) {
if (NULL != device) {
device->ref();
- device->lockPixels();
+ device->onAttachToCanvas(canvas);
}
fDevice = device;
fPaint = paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL;
@@ -90,7 +90,7 @@
~DeviceCM() {
if (NULL != fDevice) {
- fDevice->unlockPixels();
+ fDevice->onDetachFromCanvas();
fDevice->unref();
}
SkDELETE(fPaint);
@@ -256,7 +256,7 @@
}
// fCurrLayer may be NULL now
- fCanvas->prepareForDeviceDraw(fDevice, *fMatrix, *fClip, *fClipStack);
+ fCanvas->prepareForDeviceDraw(fDevice, *fMatrix, *fClip);
return true;
}
return false;
@@ -460,7 +460,7 @@
fMCRec = (MCRec*)fMCStack.push_back();
new (fMCRec) MCRec(NULL, 0);
- fMCRec->fLayer = SkNEW_ARGS(DeviceCM, (NULL, 0, 0, NULL));
+ fMCRec->fLayer = SkNEW_ARGS(DeviceCM, (NULL, 0, 0, NULL, NULL));
fMCRec->fTopLayer = fMCRec->fLayer;
fMCRec->fNext = NULL;
@@ -558,14 +558,11 @@
return device;
}
- /* Notify the devices that they are going in/out of scope, so they can do
- things like lock/unlock their pixels, etc.
- */
if (device) {
- device->lockPixels();
+ device->onAttachToCanvas(this);
}
if (rootDevice) {
- rootDevice->unlockPixels();
+ rootDevice->onDetachFromCanvas();
}
SkRefCnt_SafeAssign(rec->fLayer->fDevice, device);
@@ -682,11 +679,10 @@
}
void SkCanvas::prepareForDeviceDraw(SkDevice* device, const SkMatrix& matrix,
- const SkRegion& clip,
- const SkClipStack& clipStack) {
+ const SkRegion& clip) {
SkASSERT(device);
if (fLastDeviceToGainFocus != device) {
- device->gainFocus(this, matrix, clip, clipStack);
+ device->gainFocus(matrix, clip);
fLastDeviceToGainFocus = device;
}
}
@@ -843,7 +839,7 @@
}
device->setOrigin(ir.fLeft, ir.fTop);
- DeviceCM* layer = SkNEW_ARGS(DeviceCM, (device, ir.fLeft, ir.fTop, paint));
+ DeviceCM* layer = SkNEW_ARGS(DeviceCM, (device, ir.fLeft, ir.fTop, paint, this));
device->unref();
layer->fNext = fMCRec->fTopLayer;
diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp
index 95664c8..4cd9310 100644
--- a/src/core/SkDevice.cpp
+++ b/src/core/SkDevice.cpp
@@ -20,12 +20,21 @@
///////////////////////////////////////////////////////////////////////////////
-SkDevice::SkDevice(const SkBitmap& bitmap) : fBitmap(bitmap) {
+SkDevice::SkDevice(const SkBitmap& bitmap)
+ : fBitmap(bitmap)
+#ifdef SK_DEBUG
+ , fAttachedToCanvas(false)
+#endif
+{
fOrigin.setZero();
fMetaData = NULL;
}
-SkDevice::SkDevice(SkBitmap::Config config, int width, int height, bool isOpaque) {
+SkDevice::SkDevice(SkBitmap::Config config, int width, int height, bool isOpaque)
+#ifdef SK_DEBUG
+ : fAttachedToCanvas(false)
+#endif
+{
fOrigin.setZero();
fMetaData = NULL;
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 1154313..6443fa2 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -165,12 +165,14 @@
}
SkGpuDevice::SkGpuDevice(GrContext* context, GrTexture* texture)
-: SkDevice(make_bitmap(context, texture->asRenderTarget())) {
+: SkDevice(make_bitmap(context, texture->asRenderTarget()))
+, fClipStack(NULL) {
this->initFromRenderTarget(context, texture->asRenderTarget());
}
SkGpuDevice::SkGpuDevice(GrContext* context, GrRenderTarget* renderTarget)
-: SkDevice(make_bitmap(context, renderTarget)) {
+: SkDevice(make_bitmap(context, renderTarget))
+, fClipStack(NULL) {
this->initFromRenderTarget(context, renderTarget);
}
@@ -211,7 +213,8 @@
SkBitmap::Config config,
int width,
int height)
- : SkDevice(config, width, height, false /*isOpaque*/) {
+ : SkDevice(config, width, height, false /*isOpaque*/)
+ , fClipStack(NULL) {
fNeedPrepareRenderTarget = false;
fDrawProcs = NULL;
@@ -342,6 +345,19 @@
config, bitmap.getPixels(), bitmap.rowBytes());
}
+void SkGpuDevice::onAttachToCanvas(SkCanvas* canvas) {
+ INHERITED::onAttachToCanvas(canvas);
+
+ // Canvas promises that this ptr is valid until onDetachFromCanvas is called
+ fClipStack = canvas->getClipStack();
+}
+
+void SkGpuDevice::onDetachFromCanvas() {
+ INHERITED::onDetachFromCanvas();
+
+ fClipStack = NULL;
+}
+
///////////////////////////////////////////////////////////////////////////////
static void convert_matrixclip(GrContext* context, const SkMatrix& matrix,
@@ -366,13 +382,15 @@
// call this ever each draw call, to ensure that the context reflects our state,
// and not the state from some other canvas/device
void SkGpuDevice::prepareRenderTarget(const SkDraw& draw) {
+ GrAssert(NULL != fClipStack);
+
if (fNeedPrepareRenderTarget ||
fContext->getRenderTarget() != fRenderTarget) {
fContext->setRenderTarget(fRenderTarget);
- SkASSERT(draw.fClipStack);
+ SkASSERT(draw.fClipStack && draw.fClipStack == fClipStack);
convert_matrixclip(fContext, *draw.fMatrix,
- *draw.fClipStack, *draw.fClip, this->getOrigin());
+ *fClipStack, *draw.fClip, this->getOrigin());
fNeedPrepareRenderTarget = false;
}
}
@@ -384,14 +402,15 @@
fNeedPrepareRenderTarget = true;
}
-void SkGpuDevice::gainFocus(SkCanvas* canvas, const SkMatrix& matrix,
- const SkRegion& clip, const SkClipStack& clipStack) {
+void SkGpuDevice::gainFocus(const SkMatrix& matrix, const SkRegion& clip) {
+
+ GrAssert(NULL != fClipStack);
fContext->setRenderTarget(fRenderTarget);
- this->INHERITED::gainFocus(canvas, matrix, clip, clipStack);
+ this->INHERITED::gainFocus(matrix, clip);
- convert_matrixclip(fContext, matrix, clipStack, clip, this->getOrigin());
+ convert_matrixclip(fContext, matrix, *fClipStack, clip, this->getOrigin());
DO_DEFERRED_CLEAR;
}
@@ -1964,7 +1983,8 @@
GrTexture* texture,
TexCache cacheEntry,
bool needClear)
- : SkDevice(make_bitmap(context, texture->asRenderTarget())) {
+ : SkDevice(make_bitmap(context, texture->asRenderTarget()))
+ , fClipStack(NULL) {
GrAssert(texture && texture->asRenderTarget());
GrAssert(NULL == cacheEntry.texture() || texture == cacheEntry.texture());
this->initFromRenderTarget(context, texture->asRenderTarget());
diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp
index d05b640..55aae8d 100644
--- a/src/pdf/SkPDFDevice.cpp
+++ b/src/pdf/SkPDFDevice.cpp
@@ -514,7 +514,8 @@
fPageSize(pageSize),
fContentSize(contentSize),
fLastContentEntry(NULL),
- fLastMarginContentEntry(NULL) {
+ fLastMarginContentEntry(NULL),
+ fClipStack(NULL) {
// Skia generally uses the top left as the origin but PDF natively has the
// origin at the bottom left. This matrix corrects for that. But that only
// needs to be done once, we don't do it when layering.
@@ -538,7 +539,8 @@
fExistingClipStack(existingClipStack),
fExistingClipRegion(existingClipRegion),
fLastContentEntry(NULL),
- fLastMarginContentEntry(NULL) {
+ fLastMarginContentEntry(NULL),
+ fClipStack(NULL) {
fInitialTransform.reset();
this->init();
}
@@ -945,6 +947,19 @@
fFontGlyphUsage->merge(pdfDevice->getFontGlyphUsage());
}
+void SkPDFDevice::onAttachToCanvas(SkCanvas* canvas) {
+ INHERITED::onAttachToCanvas(canvas);
+
+ // Canvas promises that this ptr is valid until onDetachFromCanvas is called
+ fClipStack = canvas->getClipStack();
+}
+
+void SkPDFDevice::onDetachFromCanvas() {
+ INHERITED::onDetachFromCanvas();
+
+ fClipStack = NULL;
+}
+
ContentEntry* SkPDFDevice::getLastContentEntry() {
if (fDrawingArea == kContent_DrawingArea) {
return fLastContentEntry;