• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 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 
width()67     int width() const { return fWidth; }
height()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      *  Call this if the contents have changed. This will (lazily) force a new
83      *  value to be returned from generationID() when it is called next.
84      */
85     void notifyContentChanged();
86 
87     /**
88      *  Return a canvas that will draw into this surface. This will always
89      *  return the same canvas for a given surface, and is manged/owned by the
90      *  surface. It should not be used when its parent surface has gone out of
91      *  scope.
92      */
93     SkCanvas* getCanvas();
94 
95     /**
96      *  Return a new surface that is "compatible" with this one, in that it will
97      *  efficiently be able to be drawn into this surface. Typical calling
98      *  pattern:
99      *
100      *  SkSurface* A = SkSurface::New...();
101      *  SkCanvas* canvasA = surfaceA->newCanvas();
102      *  ...
103      *  SkSurface* surfaceB = surfaceA->newSurface(...);
104      *  SkCanvas* canvasB = surfaceB->newCanvas();
105      *  ... // draw using canvasB
106      *  canvasA->drawSurface(surfaceB); // <--- this will always be optimal!
107      */
108     SkSurface* newSurface(const SkImage::Info&);
109 
110     /**
111      *  Returns an image of the current state of the surface pixels up to this
112      *  point. Subsequent changes to the surface (by drawing into its canvas)
113      *  will not be reflected in this image.
114      */
115     SkImage* newImageShapshot();
116 
117     /**
118      *  Thought the caller could get a snapshot image explicitly, and draw that,
119      *  it seems that directly drawing a surface into another canvas might be
120      *  a common pattern, and that we could possibly be more efficient, since
121      *  we'd know that the "snapshot" need only live until we've handed it off
122      *  to the canvas.
123      */
124     void draw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*);
125 
126 protected:
127     SkSurface(int width, int height);
128 
129     // called by subclass if their contents have changed
dirtyGenerationID()130     void dirtyGenerationID() {
131         fGenerationID = 0;
132     }
133 
134 private:
135     const int   fWidth;
136     const int   fHeight;
137     uint32_t    fGenerationID;
138 
139     typedef SkRefCnt INHERITED;
140 };
141 
142 #endif
143