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 SkImageInfo&, 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 SkImageInfo&);
     48 
     49     /**
     50      *  Helper version of NewRaster. It creates a SkImageInfo with the
     51      *  specified width and height, and populates the rest of info to match
     52      *  pixels in SkPMColor format.
     53      */
     54     static SkSurface* NewRasterPMColor(int width, int height) {
     55         return NewRaster(SkImageInfo::MakeN32Premul(width, height));
     56     }
     57 
     58     /**
     59      *  Text rendering modes that can be passed to NewRenderTarget*
     60      */
     61     enum TextRenderMode {
     62         /**
     63          *  This will use the standard text rendering method
     64          */
     65         kStandard_TextRenderMode,
     66         /**
     67          *  This will use signed distance fields for text rendering when possible
     68          */
     69         kDistanceField_TextRenderMode,
     70     };
     71 
     72     /**
     73      *  Return a new surface using the specified render target.
     74      */
     75     static SkSurface* NewRenderTargetDirect(GrRenderTarget*,
     76                                             TextRenderMode trm = kStandard_TextRenderMode);
     77 
     78     /**
     79      *  Return a new surface whose contents will be drawn to an offscreen
     80      *  render target, allocated by the surface.
     81      */
     82     static SkSurface* NewRenderTarget(GrContext*, const SkImageInfo&, int sampleCount = 0,
     83                                       TextRenderMode trm = kStandard_TextRenderMode);
     84 
     85     /**
     86      *  Return a new surface whose contents will be drawn to an offscreen
     87      *  render target, allocated by the surface from the scratch texture pool
     88      *  managed by the GrContext. The scratch texture pool serves the purpose
     89      *  of retaining textures after they are no longer in use in order to
     90      *  re-use them later without having to re-allocate.  Scratch textures
     91      *  should be used in cases where high turnover is expected. This allows,
     92      *  for example, the copy on write to recycle a texture from a recently
     93      *  released SkImage snapshot of the surface.
     94      *  Note: Scratch textures count against the GrContext's cached resource
     95      *  budget.
     96      */
     97     static SkSurface* NewScratchRenderTarget(GrContext*, const SkImageInfo&, int sampleCount = 0,
     98                                              TextRenderMode trm = kStandard_TextRenderMode);
     99 
    100     int width() const { return fWidth; }
    101     int height() const { return fHeight; }
    102 
    103     /**
    104      *  Returns a unique non-zero, unique value identifying the content of this
    105      *  surface. Each time the content is changed changed, either by drawing
    106      *  into this surface, or explicitly calling notifyContentChanged()) this
    107      *  method will return a new value.
    108      *
    109      *  If this surface is empty (i.e. has a zero-dimention), this will return
    110      *  0.
    111      */
    112     uint32_t generationID();
    113 
    114     /**
    115      *  Modes that can be passed to notifyContentWillChange
    116      */
    117     enum ContentChangeMode {
    118         /**
    119          *  Use this mode if it is known that the upcoming content changes will
    120          *  clear or overwrite prior contents, thus making them discardable.
    121          */
    122         kDiscard_ContentChangeMode,
    123         /**
    124          *  Use this mode if prior surface contents need to be preserved or
    125          *  if in doubt.
    126          */
    127         kRetain_ContentChangeMode,
    128     };
    129 
    130     /**
    131      *  Call this if the contents are about to change. This will (lazily) force a new
    132      *  value to be returned from generationID() when it is called next.
    133      */
    134     void notifyContentWillChange(ContentChangeMode mode);
    135 
    136     /**
    137      *  Return a canvas that will draw into this surface. This will always
    138      *  return the same canvas for a given surface, and is manged/owned by the
    139      *  surface. It should not be used when its parent surface has gone out of
    140      *  scope.
    141      */
    142     SkCanvas* getCanvas();
    143 
    144     /**
    145      *  Return a new surface that is "compatible" with this one, in that it will
    146      *  efficiently be able to be drawn into this surface. Typical calling
    147      *  pattern:
    148      *
    149      *  SkSurface* A = SkSurface::New...();
    150      *  SkCanvas* canvasA = surfaceA->newCanvas();
    151      *  ...
    152      *  SkSurface* surfaceB = surfaceA->newSurface(...);
    153      *  SkCanvas* canvasB = surfaceB->newCanvas();
    154      *  ... // draw using canvasB
    155      *  canvasA->drawSurface(surfaceB); // <--- this will always be optimal!
    156      */
    157     SkSurface* newSurface(const SkImageInfo&);
    158 
    159     /**
    160      *  Returns an image of the current state of the surface pixels up to this
    161      *  point. Subsequent changes to the surface (by drawing into its canvas)
    162      *  will not be reflected in this image.
    163      */
    164     SkImage* newImageSnapshot();
    165 
    166     /**
    167      *  Thought the caller could get a snapshot image explicitly, and draw that,
    168      *  it seems that directly drawing a surface into another canvas might be
    169      *  a common pattern, and that we could possibly be more efficient, since
    170      *  we'd know that the "snapshot" need only live until we've handed it off
    171      *  to the canvas.
    172      */
    173     void draw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*);
    174 
    175     /**
    176      *  If the surface has direct access to its pixels (i.e. they are in local
    177      *  RAM) return the const-address of those pixels, and if not null, return
    178      *  the ImageInfo and rowBytes. The returned address is only valid while
    179      *  the surface object is in scope, and no API call is made on the surface
    180      *  or its canvas.
    181      *
    182      *  On failure, returns NULL and the info and rowBytes parameters are
    183      *  ignored.
    184      */
    185     const void* peekPixels(SkImageInfo* info, size_t* rowBytes);
    186 
    187 protected:
    188     SkSurface(int width, int height);
    189     SkSurface(const SkImageInfo&);
    190 
    191     // called by subclass if their contents have changed
    192     void dirtyGenerationID() {
    193         fGenerationID = 0;
    194     }
    195 
    196 private:
    197     const int   fWidth;
    198     const int   fHeight;
    199     uint32_t    fGenerationID;
    200 
    201     typedef SkRefCnt INHERITED;
    202 };
    203 
    204 #endif
    205