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