| /* | |
| * 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 "include/core/SkImageInfo.h" | |
| class SkBitmap; | |
| class SkCanvas; | |
| class SkMatrix; | |
| class SkSurfaceProps; | |
| /** | |
| * 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(...), | |
| * std::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() = default; | |
| // 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, | |
| const SkSurfaceProps* props = nullptr); | |
| protected: | |
| SkRasterHandleAllocator() = default; | |
| SkRasterHandleAllocator(const SkRasterHandleAllocator&) = delete; | |
| SkRasterHandleAllocator& operator=(const SkRasterHandleAllocator&) = delete; | |
| private: | |
| friend class SkBitmapDevice; | |
| Handle allocBitmap(const SkImageInfo&, SkBitmap*); | |
| }; | |
| #endif |