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 | * std::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: |
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 | |