| 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 |  | 
|---|