1 /* 2 * Copyright 2016 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef SkRasterHandleAllocator_DEFINED 9 #define SkRasterHandleAllocator_DEFINED 10 11 #include "include/core/SkImageInfo.h" 12 13 class SkBitmap; 14 class SkCanvas; 15 class SkMatrix; 16 class SkSurfaceProps; 17 18 /** 19 * If a client wants to control the allocation of raster layers in a canvas, it should subclass 20 * SkRasterHandleAllocator. This allocator performs two tasks: 21 * 1. controls how the memory for the pixels is allocated 22 * 2. associates a "handle" to a private object that can track the matrix/clip of the SkCanvas 23 * 24 * This example allocates a canvas, and defers to the allocator to create the base layer. 25 * 26 * std::unique_ptr<SkCanvas> canvas = SkRasterHandleAllocator::MakeCanvas( 27 * SkImageInfo::Make(...), 28 * std::make_unique<MySubclassRasterHandleAllocator>(...), 29 * nullptr); 30 * 31 * If you have already allocated the base layer (and its handle, release-proc etc.) then you 32 * can pass those in using the last parameter to MakeCanvas(). 33 * 34 * Regardless of how the base layer is allocated, each time canvas->saveLayer() is called, 35 * your allocator's allocHandle() will be called. 36 */ 37 class SK_API SkRasterHandleAllocator { 38 public: 39 virtual ~SkRasterHandleAllocator() = default; 40 41 // The value that is returned to clients of the canvas that has this allocator installed. 42 typedef void* Handle; 43 44 struct Rec { 45 // When the allocation goes out of scope, this proc is called to free everything associated 46 // with it: the pixels, the "handle", etc. This is passed the pixel address and fReleaseCtx. 47 void (*fReleaseProc)(void* pixels, void* ctx); 48 void* fReleaseCtx; // context passed to fReleaseProc 49 void* fPixels; // pixels for this allocation 50 size_t fRowBytes; // rowbytes for these pixels 51 Handle fHandle; // public handle returned by SkCanvas::accessTopRasterHandle() 52 }; 53 54 /** 55 * Given a requested info, allocate the corresponding pixels/rowbytes, and whatever handle 56 * is desired to give clients access to those pixels. The rec also contains a proc and context 57 * which will be called when this allocation goes out of scope. 58 * 59 * e.g. 60 * when canvas->saveLayer() is called, the allocator will be called to allocate the pixels 61 * for the layer. When canvas->restore() is called, the fReleaseProc will be called. 62 */ 63 virtual bool allocHandle(const SkImageInfo&, Rec*) = 0; 64 65 /** 66 * Clients access the handle for a given layer by calling SkCanvas::accessTopRasterHandle(). 67 * To allow the handle to reflect the current matrix/clip in the canvs, updateHandle() is 68 * is called. The subclass is responsible to update the handle as it sees fit. 69 */ 70 virtual void updateHandle(Handle, const SkMatrix&, const SkIRect&) = 0; 71 72 /** 73 * This creates a canvas which will use the allocator to manage pixel allocations, including 74 * all calls to saveLayer(). 75 * 76 * If rec is non-null, then it will be used as the base-layer of pixels/handle. 77 * If rec is null, then the allocator will be called for the base-layer as well. 78 */ 79 static std::unique_ptr<SkCanvas> MakeCanvas(std::unique_ptr<SkRasterHandleAllocator>, 80 const SkImageInfo&, const Rec* rec = nullptr, 81 const SkSurfaceProps* props = nullptr); 82 83 protected: 84 SkRasterHandleAllocator() = default; 85 SkRasterHandleAllocator(const SkRasterHandleAllocator&) = delete; 86 SkRasterHandleAllocator& operator=(const SkRasterHandleAllocator&) = delete; 87 88 private: 89 friend class SkBitmapDevice; 90 91 Handle allocBitmap(const SkImageInfo&, SkBitmap*); 92 }; 93 94 #endif 95