aboutsummaryrefslogtreecommitdiffhomepage
path: root/include/core
diff options
context:
space:
mode:
authorGravatar Mike Reed <reed@google.com>2017-01-10 11:58:39 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-01-10 17:31:58 +0000
commit356f7c2600ef54237fb8678cf63d5953f065b7da (patch)
tree419a3546f763b8cdbf5a37fb72905912bb987c37 /include/core
parentc0a7a0835905e02ba234ddc4bc2229e7806ba0ef (diff)
support external raster handles
draft CL for chrome: https://codereview.chromium.org/2618323005/ BUG=skia: Change-Id: I5dbcd700818776a9f62f1e10723d2efcc248dc44 Reviewed-on: https://skia-review.googlesource.com/6406 Reviewed-by: Florin Malita <fmalita@chromium.org> Commit-Queue: Mike Reed <reed@google.com>
Diffstat (limited to 'include/core')
-rw-r--r--include/core/SkBitmapDevice.h9
-rw-r--r--include/core/SkCanvas.h7
-rw-r--r--include/core/SkDevice.h8
-rw-r--r--include/core/SkRasterHandleAllocator.h86
4 files changed, 107 insertions, 3 deletions
diff --git a/include/core/SkBitmapDevice.h b/include/core/SkBitmapDevice.h
index 7ad4abec21..776b6a0dec 100644
--- a/include/core/SkBitmapDevice.h
+++ b/include/core/SkBitmapDevice.h
@@ -28,6 +28,7 @@ class SkPaint;
class SkPath;
class SkPixelRef;
class SkPixmap;
+class SkRasterHandleAllocator;
class SkRRect;
class SkSurface;
struct SkPoint;
@@ -54,12 +55,15 @@ public:
* valid for the bitmap to have no pixels associated with it. In that case,
* any drawing to this device will have no effect.
*/
- SkBitmapDevice(const SkBitmap& bitmap, const SkSurfaceProps& surfaceProps);
+ SkBitmapDevice(const SkBitmap& bitmap, const SkSurfaceProps& surfaceProps,
+ void* externalHandle = nullptr);
- static SkBitmapDevice* Create(const SkImageInfo&, const SkSurfaceProps&);
+ static SkBitmapDevice* Create(const SkImageInfo&, const SkSurfaceProps&,
+ SkRasterHandleAllocator* = nullptr);
protected:
bool onShouldDisableLCD(const SkPaint&) const override;
+ void* getRasterHandle() const override { return fRasterHandle; }
/** These are called inside the per-device-layer loop for each draw call.
When these are called, we have already applied any saveLayer operations,
@@ -172,6 +176,7 @@ private:
SkImageFilterCache* getImageFilterCache() override;
SkBitmap fBitmap;
+ void* fRasterHandle = nullptr;
void setNewSize(const SkISize&); // Used by SkCanvas for resetForNextPicture().
diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h
index 63f7f780de..704584a050 100644
--- a/include/core/SkCanvas.h
+++ b/include/core/SkCanvas.h
@@ -15,6 +15,7 @@
#include "SkDeque.h"
#include "SkImage.h"
#include "SkPaint.h"
+#include "SkRasterHandleAllocator.h"
#include "SkRefCnt.h"
#include "SkRegion.h"
#include "SkSurfaceProps.h"
@@ -217,6 +218,8 @@ public:
*/
void* accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin = NULL);
+ SkRasterHandleAllocator::Handle accessTopRasterHandle() const;
+
/**
* If the canvas has readable pixels in its base layer (and is not recording to a picture
* or other non-raster target) and has direct access to its pixels (i.e. they are in
@@ -1569,6 +1572,7 @@ private:
int fSaveCount; // value returned by getSaveCount()
SkMetaData* fMetaData;
+ std::unique_ptr<SkRasterHandleAllocator> fAllocator;
SkSurface_Base* fSurfaceBase;
SkSurface_Base* getSurfaceBase() const { return fSurfaceBase; }
@@ -1599,6 +1603,7 @@ private:
friend class SkPicturePlayback; // SaveFlagsToSaveLayerFlags
friend class SkDeferredCanvas; // For use of resetForNextPicture
friend class SkOverdrawCanvas;
+ friend class SkRasterHandleAllocator;
enum InitFlags {
kDefault_InitFlags = 0,
@@ -1606,6 +1611,8 @@ private:
};
SkCanvas(const SkIRect& bounds, InitFlags);
SkCanvas(SkBaseDevice* device, InitFlags);
+ SkCanvas(const SkBitmap&, std::unique_ptr<SkRasterHandleAllocator>,
+ SkRasterHandleAllocator::Handle);
void resetForNextPicture(const SkIRect& bounds);
diff --git a/include/core/SkDevice.h b/include/core/SkDevice.h
index b0aac41d0b..fa427c6a15 100644
--- a/include/core/SkDevice.h
+++ b/include/core/SkDevice.h
@@ -21,6 +21,7 @@ class SkImageFilterCache;
struct SkIRect;
class SkMatrix;
class SkMetaData;
+class SkRasterHandleAllocator;
class SkRegion;
class SkSpecialImage;
class GrRenderTarget;
@@ -112,6 +113,8 @@ public:
*/
const SkIPoint& getOrigin() const { return fOrigin; }
+ virtual void* getRasterHandle() const { return nullptr; }
+
protected:
enum TileUsage {
kPossible_TileUsage, //!< the created device may be drawn tiled
@@ -292,15 +295,18 @@ protected:
CreateInfo(const SkImageInfo& info,
TileUsage tileUsage,
SkPixelGeometry geo,
- bool preserveLCDText)
+ bool preserveLCDText,
+ SkRasterHandleAllocator* allocator)
: fInfo(info)
, fTileUsage(tileUsage)
, fPixelGeometry(AdjustGeometry(info, tileUsage, geo, preserveLCDText))
+ , fAllocator(allocator)
{}
const SkImageInfo fInfo;
const TileUsage fTileUsage;
const SkPixelGeometry fPixelGeometry;
+ SkRasterHandleAllocator* fAllocator = nullptr;
};
/**
diff --git a/include/core/SkRasterHandleAllocator.h b/include/core/SkRasterHandleAllocator.h
new file mode 100644
index 0000000000..62796cb62a
--- /dev/null
+++ b/include/core/SkRasterHandleAllocator.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkRasterHandleAllocator_DEFINED
+#define SkRasterHandleAllocator_DEFINED
+
+#include "SkImageInfo.h"
+
+class SkCanvas;
+class SkMatrix;
+
+/**
+ * If a client wants to control the allocation of raster layers in a canvas, it should subclass
+ * SkRasterHandleAllocator. This allocator performs two tasks:
+ * 1. controls how the memory for the pixels is allocated
+ * 2. associates a "handle" to a private object that can track the matrix/clip of the SkCanvas
+ *
+ * This example allocates a canvas, and defers to the allocator to create the base layer.
+ *
+ * std::unique_ptr<SkCanvas> canvas = SkRasterHandleAllocator::MakeCanvas(
+ * SkImageInfo::Make(...),
+ * skstd::make_unique<MySubclassRasterHandleAllocator>(...),
+ * nullptr);
+ *
+ * If you have already allocated the base layer (and its handle, release-proc etc.) then you
+ * can pass those in using the last parameter to MakeCanvas().
+ *
+ * Regardless of how the base layer is allocated, each time canvas->saveLayer() is called,
+ * your allocator's allocHandle() will be called.
+ */
+class SK_API SkRasterHandleAllocator {
+public:
+ virtual ~SkRasterHandleAllocator() {}
+
+ // The value that is returned to clients of the canvas that has this allocator installed.
+ typedef void* Handle;
+
+ struct Rec {
+ // When the allocation goes out of scope, this proc is called to free everything associated
+ // with it: the pixels, the "handle", etc. This is passed the pixel address and fReleaseCtx.
+ void (*fReleaseProc)(void* pixels, void* ctx);
+ void* fReleaseCtx; // context passed to fReleaseProc
+ void* fPixels; // pixels for this allocation
+ size_t fRowBytes; // rowbytes for these pixels
+ Handle fHandle; // public handle returned by SkCanvas::accessTopRasterHandle()
+ };
+
+ /**
+ * Given a requested info, allocate the corresponding pixels/rowbytes, and whatever handle
+ * is desired to give clients access to those pixels. The rec also contains a proc and context
+ * which will be called when this allocation goes out of scope.
+ *
+ * e.g.
+ * when canvas->saveLayer() is called, the allocator will be called to allocate the pixels
+ * for the layer. When canvas->restore() is called, the fReleaseProc will be called.
+ */
+ virtual bool allocHandle(const SkImageInfo&, Rec*) = 0;
+
+ /**
+ * Clients access the handle for a given layer by calling SkCanvas::accessTopRasterHandle().
+ * To allow the handle to reflect the current matrix/clip in the canvs, updateHandle() is
+ * is called. The subclass is responsible to update the handle as it sees fit.
+ */
+ virtual void updateHandle(Handle, const SkMatrix&, const SkIRect&) = 0;
+
+ /**
+ * This creates a canvas which will use the allocator to manage pixel allocations, including
+ * all calls to saveLayer().
+ *
+ * If rec is non-null, then it will be used as the base-layer of pixels/handle.
+ * If rec is null, then the allocator will be called for the base-layer as well.
+ */
+ static std::unique_ptr<SkCanvas> MakeCanvas(std::unique_ptr<SkRasterHandleAllocator>,
+ const SkImageInfo&, const Rec* rec = nullptr);
+
+private:
+ friend class SkBitmapDevice;
+
+ Handle allocBitmap(const SkImageInfo&, SkBitmap*);
+};
+
+#endif