Index: src/core/SkCanvas.cpp |
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp |
index f7f870210d0844b6347030575ec159d210f15ea9..989903406adf4a11a832da84eeca436f64b0fc0f 100644 |
--- a/src/core/SkCanvas.cpp |
+++ b/src/core/SkCanvas.cpp |
@@ -24,6 +24,7 @@ |
#include "SkPaintPriv.h" |
#include "SkPatchUtils.h" |
#include "SkPicture.h" |
+#include "SkRasterCanvasLayerAllocator.h" |
#include "SkRasterClip.h" |
#include "SkReadPixelsRec.h" |
#include "SkRRect.h" |
@@ -195,6 +196,8 @@ struct DeviceCM { |
SkRasterClip fClip; |
SkPaint* fPaint; // may be null (in the future) |
const SkMatrix* fMatrix; |
+ SkRasterCanvasLayerAllocator* fAllocator; |
+ void* fNativeContext; |
SkMatrix fMatrixStorage; |
const bool fDeviceIsBitmapDevice; |
@@ -202,6 +205,8 @@ struct DeviceCM { |
bool conservativeRasterClip, bool deviceIsBitmapDevice) |
: fNext(nullptr) |
, fClip(conservativeRasterClip) |
+ , fAllocator(nullptr) |
+ , fNativeContext(nullptr) |
, fDeviceIsBitmapDevice(deviceIsBitmapDevice) |
{ |
if (nullptr != device) { |
@@ -214,6 +219,10 @@ struct DeviceCM { |
~DeviceCM() { |
if (fDevice) { |
+ if (fAllocator) { |
+ fAllocator->free(fDevice->accessBitmap(false).getPixels(), |
reed1
2016/05/11 18:58:24
Do we need to pass the actual pixel addr to the fr
tomhudson
2016/05/26 16:36:17
I'd assumed that allocators would have to map from
|
+ fNativeContext); |
+ } |
fDevice->onDetachFromCanvas(); |
fDevice->unref(); |
} |
@@ -669,6 +678,7 @@ SkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) { |
fMCRec->fTopLayer = fMCRec->fLayer; |
fSurfaceBase = nullptr; |
+ fAllocator = nullptr; |
if (device) { |
// The root device and the canvas should always have the same pixel geometry |
@@ -1237,7 +1247,7 @@ void SkCanvas::internalSaveLayer(const SaveLayerRec& rec, SaveLayerStrategy stra |
const SkBaseDevice::TileUsage usage = SkBaseDevice::kNever_TileUsage; |
const SkBaseDevice::CreateInfo createInfo = SkBaseDevice::CreateInfo(info, usage, geo, |
preserveLCDText, false); |
- SkBaseDevice* newDev = device->onCreateDevice(createInfo, paint); |
+ SkBaseDevice* newDev = device->onCreateDevice(createInfo, paint, fAllocator); |
if (nullptr == newDev) { |
// If onCreateDevice didn't succeed, try raster (e.g. PDF couldn't handle the paint) |
const SkSurfaceProps surfaceProps(fProps.flags(), createInfo.fPixelGeometry); |
@@ -1262,6 +1272,10 @@ void SkCanvas::internalSaveLayer(const SaveLayerRec& rec, SaveLayerStrategy stra |
device->unref(); |
layer->fNext = fMCRec->fTopLayer; |
+ layer->fAllocator = fAllocator; |
+ layer->fNativeContext = fAllocator |
+ ? fAllocator->getNativeContext(device->accessBitmap(false).getPixels()) |
+ : nullptr; |
fMCRec->fLayer = layer; |
fMCRec->fTopLayer = layer; // this field is NOT an owner of layer |
} |
@@ -1286,6 +1300,7 @@ void SkCanvas::internalRestore() { |
// reserve our layer (if any) |
DeviceCM* layer = fMCRec->fLayer; // may be null |
+ |
// now detach it from fMCRec so we can pop(). Gets freed after its drawn |
fMCRec->fLayer = nullptr; |
@@ -1299,6 +1314,7 @@ void SkCanvas::internalRestore() { |
recorder will have already recorded the restore). |
*/ |
if (layer) { |
+ SkASSERT(layer->fAllocator == fAllocator); |
if (layer->fNext) { |
const SkIPoint& origin = layer->fDevice->getOrigin(); |
this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(), |
@@ -1737,6 +1753,11 @@ void SkCanvas::replayClips(ClipVisitor* visitor) const { |
} |
} |
+void* SkCanvas::getTopLayerNative() const { |
+ return fMCRec->fLayer->fNativeContext; |
+} |
+ |
+ |
/////////////////////////////////////////////////////////////////////////////// |
bool SkCanvas::isClipEmpty() const { |