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 
     14 class SkCanvas;
     15 class SkPaint;
     16 class GrContext;
     17 class GrRenderTarget;
     18 
     19 /**
     20  *  SkSurface represents the backend/results of drawing to a canvas. For raster
     21  *  drawing, the surface will be pixels, but (for example) when drawing into
     22  *  a PDF or Picture canvas, the surface stores the recorded commands.
     23  *
     24  *  To draw into a canvas, first create the appropriate type of Surface, and
     25  *  then request the canvas from the surface.
     26  */
     27 class SK_API SkSurface : public SkRefCnt {
     28 public:
     29     SK_DECLARE_INST_COUNT(SkSurface)
     30 
     31     /**
     32      *  Create a new surface, using the specified pixels/rowbytes as its
     33      *  backend.
     34      *
     35      *  If the requested surface cannot be created, or the request is not a
     36      *  supported configuration, NULL will be returned.
     37      */
     38     static SkSurface* NewRasterDirect(const SkImage::Info&, void* pixels, size_t rowBytes);
     39 
     40     /**
     41      *  Return a new surface, with the memory for the pixels automatically
     42      *  allocated.
     43      *
     44      *  If the requested surface cannot be created, or the request is not a
     45      *  supported configuration, NULL will be returned.
     46      */
     47     static SkSurface* NewRaster(const SkImage::Info&);
     48 
     49     /**
     50      *  Return a new surface whose contents will be recorded into a picture.
     51      *  When this surface is drawn into another canvas, its contents will be
     52      *  "replayed" into that canvas.
     53      */
     54     static SkSurface* NewPicture(int width, int height);
     55 
     56     /**
     57      *  Return a new surface using the specified render target.
     58      */
     59     static SkSurface* NewRenderTargetDirect(GrContext*, GrRenderTarget*);
     60 
     61     /**
     62      *  Return a new surface whose contents will be drawn to an offscreen
     63      *  render target, allocated by the surface.
     64      */
     65     static SkSurface* NewRenderTarget(GrContext*, const SkImage::Info&, int sampleCount = 0);
     66 
     67     int width() const { return fWidth; }
     68     int height() const { return fHeight; }
     69 
     70     /**
     71      *  Returns a unique non-zero, unique value identifying the content of this
     72      *  surface. Each time the content is changed changed, either by drawing
     73      *  into this surface, or explicitly calling notifyContentChanged()) this
     74      *  method will return a new value.
     75      *
     76      *  If this surface is empty (i.e. has a zero-dimention), this will return
     77      *  0.
     78      */
     79     uint32_t generationID();
     80 
     81     /**
     82      *  Modes that can be passed to notifyContentWillChange
     83      */
     84     enum ContentChangeMode {
     85         /**
     86          *  Use this mode if it is known that the upcoming content changes will
     87          *  clear or overwrite prior contents, thus making them discardable.
     88          */
     89         kDiscard_ContentChangeMode,
     90         /**
     91          *  Use this mode if prior surface contents need to be preserved or
     92          *  if in doubt.
     93          */
     94         kRetain_ContentChangeMode,
     95     };
     96 
     97     /**
     98      *  Call this if the contents are about to change. This will (lazily) force a new
     99      *  value to be returned from generationID() when it is called next.
    100      */
    101     void notifyContentWillChange(ContentChangeMode mode);
    102 
    103     /**
    104      *  Return a canvas that will draw into this surface. This will always
    105      *  return the same canvas for a given surface, and is manged/owned by the
    106      *  surface. It should not be used when its parent surface has gone out of
    107      *  scope.
    108      */
    109     SkCanvas* getCanvas();
    110 
    111     /**
    112      *  Return a new surface that is "compatible" with this one, in that it will
    113      *  efficiently be able to be drawn into this surface. Typical calling
    114      *  pattern:
    115      *
    116      *  SkSurface* A = SkSurface::New...();
    117      *  SkCanvas* canvasA = surfaceA->newCanvas();
    118      *  ...
    119      *  SkSurface* surfaceB = surfaceA->newSurface(...);
    120      *  SkCanvas* canvasB = surfaceB->newCanvas();
    121      *  ... // draw using canvasB
    122      *  canvasA->drawSurface(surfaceB); // <--- this will always be optimal!
    123      */
    124     SkSurface* newSurface(const SkImage::Info&);
    125 
    126     /**
    127      *  Returns an image of the current state of the surface pixels up to this
    128      *  point. Subsequent changes to the surface (by drawing into its canvas)
    129      *  will not be reflected in this image.
    130      */
    131     SkImage* newImageSnapshot();
    132 
    133     /**
    134      *  Thought the caller could get a snapshot image explicitly, and draw that,
    135      *  it seems that directly drawing a surface into another canvas might be
    136      *  a common pattern, and that we could possibly be more efficient, since
    137      *  we'd know that the "snapshot" need only live until we've handed it off
    138      *  to the canvas.
    139      */
    140     void draw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*);
    141 
    142 protected:
    143     SkSurface(int width, int height);
    144 
    145     // called by subclass if their contents have changed
    146     void dirtyGenerationID() {
    147         fGenerationID = 0;
    148     }
    149 
    150 private:
    151     const int   fWidth;
    152     const int   fHeight;
    153     uint32_t    fGenerationID;
    154 
    155     typedef SkRefCnt INHERITED;
    156 };
    157 
    158 #endif
    159