Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright 2012 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 SkSurface_DEFINED
      9 #define SkSurface_DEFINED
     10 
     11 #include "SkRefCnt.h"
     12 #include "SkImage.h"
     13 #include "SkSurfaceProps.h"
     14 
     15 class SkCanvas;
     16 class SkPaint;
     17 class GrContext;
     18 class GrRenderTarget;
     19 
     20 /**
     21  *  SkSurface represents the backend/results of drawing to a canvas. For raster
     22  *  drawing, the surface will be pixels, but (for example) when drawing into
     23  *  a PDF or Picture canvas, the surface stores the recorded commands.
     24  *
     25  *  To draw into a canvas, first create the appropriate type of Surface, and
     26  *  then request the canvas from the surface.
     27  */
     28 class SK_API SkSurface : public SkRefCnt {
     29 public:
     30     SK_DECLARE_INST_COUNT(SkSurface)
     31 
     32     /**
     33      *  Create a new surface, using the specified pixels/rowbytes as its
     34      *  backend.
     35      *
     36      *  If the requested surface cannot be created, or the request is not a
     37      *  supported configuration, NULL will be returned.
     38      */
     39     static SkSurface* NewRasterDirect(const SkImageInfo&, void* pixels, size_t rowBytes,
     40                                       const SkSurfaceProps* = NULL);
     41 
     42     /**
     43      *  The same as NewRasterDirect, but also accepts a call-back routine, which is invoked
     44      *  when the surface is deleted, and is passed the pixel memory and the specified context.
     45      */
     46     static SkSurface* NewRasterDirectReleaseProc(const SkImageInfo&, void* pixels, size_t rowBytes,
     47                                                  void (*releaseProc)(void* pixels, void* context),
     48                                                  void* context, const SkSurfaceProps* = NULL);
     49 
     50     /**
     51      *  Return a new surface, with the memory for the pixels automatically
     52      *  allocated.
     53      *
     54      *  If the requested surface cannot be created, or the request is not a
     55      *  supported configuration, NULL will be returned.
     56      */
     57     static SkSurface* NewRaster(const SkImageInfo&, const SkSurfaceProps* = NULL);
     58 
     59     /**
     60      *  Helper version of NewRaster. It creates a SkImageInfo with the
     61      *  specified width and height, and populates the rest of info to match
     62      *  pixels in SkPMColor format.
     63      */
     64     static SkSurface* NewRasterPMColor(int width, int height, const SkSurfaceProps* props = NULL) {
     65         return NewRaster(SkImageInfo::MakeN32Premul(width, height), props);
     66     }
     67 
     68     /**
     69      *  Return a new surface using the specified render target.
     70      */
     71     static SkSurface* NewRenderTargetDirect(GrRenderTarget*, const SkSurfaceProps*);
     72 
     73     static SkSurface* NewRenderTargetDirect(GrRenderTarget* target) {
     74         return NewRenderTargetDirect(target, NULL);
     75     }
     76 
     77     /**
     78      *  Return a new surface whose contents will be drawn to an offscreen
     79      *  render target, allocated by the surface.
     80      */
     81     static SkSurface* NewRenderTarget(GrContext*, const SkImageInfo&, int sampleCount,
     82                                       const SkSurfaceProps* = NULL);
     83 
     84     static SkSurface* NewRenderTarget(GrContext* gr, const SkImageInfo& info) {
     85         return NewRenderTarget(gr, info, 0, NULL);
     86     }
     87 
     88     /**
     89      *  Return a new surface whose contents will be drawn to an offscreen
     90      *  render target, allocated by the surface from the scratch texture pool
     91      *  managed by the GrContext. The scratch texture pool serves the purpose
     92      *  of retaining textures after they are no longer in use in order to
     93      *  re-use them later without having to re-allocate.  Scratch textures
     94      *  should be used in cases where high turnover is expected. This allows,
     95      *  for example, the copy on write to recycle a texture from a recently
     96      *  released SkImage snapshot of the surface.
     97      *  Note: Scratch textures count against the GrContext's cached resource
     98      *  budget.
     99      */
    100     static SkSurface* NewScratchRenderTarget(GrContext*, const SkImageInfo&, int sampleCount,
    101                                              const SkSurfaceProps* = NULL);
    102 
    103     static SkSurface* NewScratchRenderTarget(GrContext* gr, const SkImageInfo& info) {
    104         return NewScratchRenderTarget(gr, info, 0, NULL);
    105     }
    106 
    107 #ifdef SK_SUPPORT_LEGACY_TEXTRENDERMODE
    108     /**
    109      *  Text rendering modes that can be passed to NewRenderTarget*
    110      */
    111     enum TextRenderMode {
    112         /**
    113          *  This will use the standard text rendering method
    114          */
    115         kStandard_TextRenderMode,
    116         /**
    117          *  This will use signed distance fields for text rendering when possible
    118          */
    119         kDistanceField_TextRenderMode,
    120     };
    121     static SkSurface* NewRenderTargetDirect(GrRenderTarget*, TextRenderMode);
    122     static SkSurface* NewRenderTarget(GrContext*, const SkImageInfo&, int sampleCount,
    123                                       TextRenderMode);
    124     static SkSurface* NewScratchRenderTarget(GrContext*, const SkImageInfo&, int sampleCount,
    125                                              TextRenderMode);
    126 #endif
    127 
    128     int width() const { return fWidth; }
    129     int height() const { return fHeight; }
    130 
    131     /**
    132      *  Returns a unique non-zero, unique value identifying the content of this
    133      *  surface. Each time the content is changed changed, either by drawing
    134      *  into this surface, or explicitly calling notifyContentChanged()) this
    135      *  method will return a new value.
    136      *
    137      *  If this surface is empty (i.e. has a zero-dimention), this will return
    138      *  0.
    139      */
    140     uint32_t generationID();
    141 
    142     /**
    143      *  Modes that can be passed to notifyContentWillChange
    144      */
    145     enum ContentChangeMode {
    146         /**
    147          *  Use this mode if it is known that the upcoming content changes will
    148          *  clear or overwrite prior contents, thus making them discardable.
    149          */
    150         kDiscard_ContentChangeMode,
    151         /**
    152          *  Use this mode if prior surface contents need to be preserved or
    153          *  if in doubt.
    154          */
    155         kRetain_ContentChangeMode,
    156     };
    157 
    158     /**
    159      *  Call this if the contents are about to change. This will (lazily) force a new
    160      *  value to be returned from generationID() when it is called next.
    161      */
    162     void notifyContentWillChange(ContentChangeMode mode);
    163 
    164     /**
    165      *  Return a canvas that will draw into this surface. This will always
    166      *  return the same canvas for a given surface, and is manged/owned by the
    167      *  surface. It should not be used when its parent surface has gone out of
    168      *  scope.
    169      */
    170     SkCanvas* getCanvas();
    171 
    172     /**
    173      *  Return a new surface that is "compatible" with this one, in that it will
    174      *  efficiently be able to be drawn into this surface. Typical calling
    175      *  pattern:
    176      *
    177      *  SkSurface* A = SkSurface::New...();
    178      *  SkCanvas* canvasA = surfaceA->newCanvas();
    179      *  ...
    180      *  SkSurface* surfaceB = surfaceA->newSurface(...);
    181      *  SkCanvas* canvasB = surfaceB->newCanvas();
    182      *  ... // draw using canvasB
    183      *  canvasA->drawSurface(surfaceB); // <--- this will always be optimal!
    184      */
    185     SkSurface* newSurface(const SkImageInfo&);
    186 
    187     /**
    188      *  Returns an image of the current state of the surface pixels up to this
    189      *  point. Subsequent changes to the surface (by drawing into its canvas)
    190      *  will not be reflected in this image.
    191      */
    192     SkImage* newImageSnapshot();
    193 
    194     /**
    195      *  Thought the caller could get a snapshot image explicitly, and draw that,
    196      *  it seems that directly drawing a surface into another canvas might be
    197      *  a common pattern, and that we could possibly be more efficient, since
    198      *  we'd know that the "snapshot" need only live until we've handed it off
    199      *  to the canvas.
    200      */
    201     void draw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*);
    202 
    203     /**
    204      *  If the surface has direct access to its pixels (i.e. they are in local
    205      *  RAM) return the const-address of those pixels, and if not null, return
    206      *  the ImageInfo and rowBytes. The returned address is only valid while
    207      *  the surface object is in scope, and no API call is made on the surface
    208      *  or its canvas.
    209      *
    210      *  On failure, returns NULL and the info and rowBytes parameters are
    211      *  ignored.
    212      */
    213     const void* peekPixels(SkImageInfo* info, size_t* rowBytes);
    214 
    215     const SkSurfaceProps& props() const { return fProps; }
    216 
    217 protected:
    218     SkSurface(int width, int height, const SkSurfaceProps*);
    219     SkSurface(const SkImageInfo&, const SkSurfaceProps*);
    220 
    221     // called by subclass if their contents have changed
    222     void dirtyGenerationID() {
    223         fGenerationID = 0;
    224     }
    225 
    226 private:
    227     const SkSurfaceProps fProps;
    228     const int            fWidth;
    229     const int            fHeight;
    230     uint32_t             fGenerationID;
    231 
    232     typedef SkRefCnt INHERITED;
    233 };
    234 
    235 #endif
    236