Home | History | Annotate | Download | only in core
      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 "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:
     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