Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(97)

Unified Diff: src/core/SkCanvas.cpp

Issue 1763143002: WIP RasterCanvasLayerAllocator (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: test and some further work Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/core/SkCanvas.cpp
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 4150a9a55b663584879600346610b2d042259824..90b1562ac56afe6382a4e4ff0c1a8934293bd722 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -25,6 +25,7 @@
#include "SkPaintPriv.h"
#include "SkPatchUtils.h"
#include "SkPicture.h"
+#include "SkRasterCanvasLayerAllocator.h"
#include "SkRasterClip.h"
#include "SkReadPixelsRec.h"
#include "SkRRect.h"
@@ -196,6 +197,8 @@ struct DeviceCM {
SkRasterClip fClip;
SkPaint* fPaint; // may be null (in the future)
const SkMatrix* fMatrix;
+ SkRasterCanvasLayerAllocator* fAllocator;
+ void* fNativeContext;
SkMatrix fMatrixStorage;
SkMatrix fStashedMatrix; // original CTM; used by imagefilter in saveLayer
const bool fDeviceIsBitmapDevice;
@@ -204,6 +207,8 @@ struct DeviceCM {
bool conservativeRasterClip, bool deviceIsBitmapDevice, const SkMatrix& stashed)
: fNext(nullptr)
, fClip(conservativeRasterClip)
+ , fAllocator(nullptr)
+ , fNativeContext(nullptr)
, fStashedMatrix(stashed)
, fDeviceIsBitmapDevice(deviceIsBitmapDevice)
{
@@ -217,6 +222,10 @@ struct DeviceCM {
~DeviceCM() {
if (fDevice) {
+ if (fAllocator) {
+ fAllocator->free(fDevice->accessBitmap(false).getPixels(),
+ fNativeContext);
+ }
fDevice->onDetachFromCanvas();
fDevice->unref();
}
@@ -643,7 +652,8 @@ void SkCanvas::resetForNextPicture(const SkIRect& bounds) {
static_cast<SkBitmapDevice*>(fMCRec->fLayer->fDevice)->setNewSize(bounds.size());
}
-SkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) {
+SkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags,
+ sk_sp<SkRasterCanvasLayerAllocator> allocator) {
if (device && device->forceConservativeRasterClip()) {
flags = InitFlags(flags | kConservativeRasterClip_InitFlag);
}
@@ -672,6 +682,8 @@ SkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) {
fMCRec->fTopLayer = fMCRec->fLayer;
fSurfaceBase = nullptr;
+ fAllocator = allocator;
+ fMCRec->fLayer->fAllocator = allocator.get();
if (device) {
// The root device and the canvas should always have the same pixel geometry
@@ -690,7 +702,7 @@ SkCanvas::SkCanvas()
{
inc_canvas();
- this->init(nullptr, kDefault_InitFlags);
+ this->init(nullptr, kDefault_InitFlags, nullptr);
}
static SkBitmap make_nopixels(int width, int height) {
@@ -720,7 +732,7 @@ SkCanvas::SkCanvas(int width, int height, const SkSurfaceProps* props)
inc_canvas();
this->init(new SkNoPixelsBitmapDevice(SkIRect::MakeWH(width, height), fProps),
- kDefault_InitFlags)->unref();
+ kDefault_InitFlags, nullptr)->unref();
}
SkCanvas::SkCanvas(const SkIRect& bounds, InitFlags flags)
@@ -730,7 +742,8 @@ SkCanvas::SkCanvas(const SkIRect& bounds, InitFlags flags)
{
inc_canvas();
- this->init(new SkNoPixelsBitmapDevice(bounds, fProps), flags)->unref();
+ this->init(new SkNoPixelsBitmapDevice(bounds, fProps), flags,
+ nullptr)->unref();
}
SkCanvas::SkCanvas(SkBaseDevice* device)
@@ -740,7 +753,7 @@ SkCanvas::SkCanvas(SkBaseDevice* device)
{
inc_canvas();
- this->init(device, kDefault_InitFlags);
+ this->init(device, kDefault_InitFlags, nullptr);
}
SkCanvas::SkCanvas(SkBaseDevice* device, InitFlags flags)
@@ -750,7 +763,7 @@ SkCanvas::SkCanvas(SkBaseDevice* device, InitFlags flags)
{
inc_canvas();
- this->init(device, flags);
+ this->init(device, flags, nullptr);
}
SkCanvas::SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props)
@@ -761,7 +774,7 @@ SkCanvas::SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props)
inc_canvas();
SkAutoTUnref<SkBaseDevice> device(new SkBitmapDevice(bitmap, fProps));
- this->init(device, kDefault_InitFlags);
+ this->init(device, kDefault_InitFlags, nullptr);
}
SkCanvas::SkCanvas(const SkBitmap& bitmap)
@@ -772,7 +785,22 @@ SkCanvas::SkCanvas(const SkBitmap& bitmap)
inc_canvas();
SkAutoTUnref<SkBaseDevice> device(new SkBitmapDevice(bitmap, fProps));
- this->init(device, kDefault_InitFlags);
+ this->init(device, kDefault_InitFlags, nullptr);
+}
+
+SkCanvas::SkCanvas(const SkBitmap& bitmap,
+ sk_sp<SkRasterCanvasLayerAllocator> allocator)
+ : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
+ , fProps(SkSurfaceProps::kLegacyFontHost_InitType)
+ , fConservativeRasterClip(false)
+{
+ inc_canvas();
+
+ SkAutoTUnref<SkBaseDevice> device(new SkBitmapDevice(bitmap, fProps));
+ this->init(device, kDefault_InitFlags, allocator);
+ // TODO(tomhudson): this is circuitous, wasteful, and ugly to boot
+ this->fMCRec->fLayer->fNativeContext =
+ allocator->getNativeContext(this->accessTopLayerPixels(nullptr, nullptr));
}
SkCanvas::~SkCanvas() {
@@ -1275,7 +1303,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.get());
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);
@@ -1300,6 +1328,10 @@ void SkCanvas::internalSaveLayer(const SaveLayerRec& rec, SaveLayerStrategy stra
device->unref();
layer->fNext = fMCRec->fTopLayer;
+ layer->fAllocator = fAllocator.get();
+ layer->fNativeContext = fAllocator
+ ? fAllocator->getNativeContext(device->accessBitmap(false).getPixels())
+ : nullptr;
fMCRec->fLayer = layer;
fMCRec->fTopLayer = layer; // this field is NOT an owner of layer
}
@@ -1324,6 +1356,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;
@@ -1337,6 +1370,7 @@ void SkCanvas::internalRestore() {
recorder will have already recorded the restore).
*/
if (layer) {
+ SkASSERT(layer->fAllocator == fAllocator.get());
if (layer->fNext) {
const SkIPoint& origin = layer->fDevice->getOrigin();
this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(),
@@ -1767,6 +1801,11 @@ void SkCanvas::replayClips(ClipVisitor* visitor) const {
}
}
+void* SkCanvas::getTopLayerNative() const {
+ return fMCRec->fLayer->fNativeContext;
+}
+
+
///////////////////////////////////////////////////////////////////////////////
bool SkCanvas::isClipEmpty() const {

Powered by Google App Engine
This is Rietveld 408576698