| /* |
| * 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 |