xref: /aosp_15_r20/external/skia/include/core/SkRasterHandleAllocator.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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