Chromium Code Reviews| 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 { |