1356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed/* 2356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed * Copyright 2016 Google Inc. 3356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed * 4356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed * Use of this source code is governed by a BSD-style license that can be 5356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed * found in the LICENSE file. 6356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed */ 7356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 8356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed#ifndef SkRasterHandleAllocator_DEFINED 9356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed#define SkRasterHandleAllocator_DEFINED 10356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 11356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed#include "SkImageInfo.h" 12356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 136b20a559968e1ed0d3aa4ecbd6ddda9e681b4f86Hal Canaryclass SkBitmap; 14356f7c2600ef54237fb8678cf63d5953f065b7daMike Reedclass SkCanvas; 15356f7c2600ef54237fb8678cf63d5953f065b7daMike Reedclass SkMatrix; 16356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 17356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed/** 18356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed * If a client wants to control the allocation of raster layers in a canvas, it should subclass 19356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed * SkRasterHandleAllocator. This allocator performs two tasks: 20356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed * 1. controls how the memory for the pixels is allocated 21356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed * 2. associates a "handle" to a private object that can track the matrix/clip of the SkCanvas 22356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed * 23356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed * This example allocates a canvas, and defers to the allocator to create the base layer. 24356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed * 25356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed * std::unique_ptr<SkCanvas> canvas = SkRasterHandleAllocator::MakeCanvas( 26356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed * SkImageInfo::Make(...), 27356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed * skstd::make_unique<MySubclassRasterHandleAllocator>(...), 28356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed * nullptr); 29356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed * 30356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed * If you have already allocated the base layer (and its handle, release-proc etc.) then you 31356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed * can pass those in using the last parameter to MakeCanvas(). 32356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed * 33356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed * Regardless of how the base layer is allocated, each time canvas->saveLayer() is called, 34356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed * your allocator's allocHandle() will be called. 35356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed */ 36356f7c2600ef54237fb8678cf63d5953f065b7daMike Reedclass SK_API SkRasterHandleAllocator { 37356f7c2600ef54237fb8678cf63d5953f065b7daMike Reedpublic: 38356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed virtual ~SkRasterHandleAllocator() {} 39356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 40356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed // The value that is returned to clients of the canvas that has this allocator installed. 41356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed typedef void* Handle; 42356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 43356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed struct Rec { 44356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed // When the allocation goes out of scope, this proc is called to free everything associated 45356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed // with it: the pixels, the "handle", etc. This is passed the pixel address and fReleaseCtx. 46356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed void (*fReleaseProc)(void* pixels, void* ctx); 47356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed void* fReleaseCtx; // context passed to fReleaseProc 48356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed void* fPixels; // pixels for this allocation 49356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed size_t fRowBytes; // rowbytes for these pixels 50356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed Handle fHandle; // public handle returned by SkCanvas::accessTopRasterHandle() 51356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed }; 52356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 53356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed /** 54356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed * Given a requested info, allocate the corresponding pixels/rowbytes, and whatever handle 55356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed * is desired to give clients access to those pixels. The rec also contains a proc and context 56356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed * which will be called when this allocation goes out of scope. 57356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed * 58356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed * e.g. 59356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed * when canvas->saveLayer() is called, the allocator will be called to allocate the pixels 60356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed * for the layer. When canvas->restore() is called, the fReleaseProc will be called. 61356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed */ 62356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed virtual bool allocHandle(const SkImageInfo&, Rec*) = 0; 63356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 64356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed /** 65356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed * Clients access the handle for a given layer by calling SkCanvas::accessTopRasterHandle(). 66356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed * To allow the handle to reflect the current matrix/clip in the canvs, updateHandle() is 67356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed * is called. The subclass is responsible to update the handle as it sees fit. 68356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed */ 69356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed virtual void updateHandle(Handle, const SkMatrix&, const SkIRect&) = 0; 70356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 71356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed /** 72356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed * This creates a canvas which will use the allocator to manage pixel allocations, including 73356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed * all calls to saveLayer(). 74356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed * 75356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed * If rec is non-null, then it will be used as the base-layer of pixels/handle. 76356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed * If rec is null, then the allocator will be called for the base-layer as well. 77356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed */ 78356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed static std::unique_ptr<SkCanvas> MakeCanvas(std::unique_ptr<SkRasterHandleAllocator>, 79356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed const SkImageInfo&, const Rec* rec = nullptr); 80356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 81356f7c2600ef54237fb8678cf63d5953f065b7daMike Reedprivate: 82356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed friend class SkBitmapDevice; 83356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 84356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed Handle allocBitmap(const SkImageInfo&, SkBitmap*); 85356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed}; 86356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 87356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed#endif 88