diff options
author | Mike Reed <reed@google.com> | 2017-01-10 11:58:39 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-01-10 17:31:58 +0000 |
commit | 356f7c2600ef54237fb8678cf63d5953f065b7da (patch) | |
tree | 419a3546f763b8cdbf5a37fb72905912bb987c37 /include/core | |
parent | c0a7a0835905e02ba234ddc4bc2229e7806ba0ef (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.h | 9 | ||||
-rw-r--r-- | include/core/SkCanvas.h | 7 | ||||
-rw-r--r-- | include/core/SkDevice.h | 8 | ||||
-rw-r--r-- | include/core/SkRasterHandleAllocator.h | 86 |
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 |