• 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 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      */
NewRasterPMColor(int width,int height)54     static SkSurface* NewRasterPMColor(int width, int height) {
55         SkImageInfo info = {
56             width, height, kPMColor_SkColorType, kPremul_SkAlphaType
57         };
58         return NewRaster(info);
59     }
60 
61     /**
62      *  Return a new surface whose contents will be recorded into a picture.
63      *  When this surface is drawn into another canvas, its contents will be
64      *  "replayed" into that canvas.
65      */
66     static SkSurface* NewPicture(int width, int height);
67 
68     /**
69      *  Return a new surface using the specified render target.
70      */
71     static SkSurface* NewRenderTargetDirect(GrContext*, GrRenderTarget*);
72 
73     /**
74      *  Return a new surface whose contents will be drawn to an offscreen
75      *  render target, allocated by the surface.
76      */
77     static SkSurface* NewRenderTarget(GrContext*, const SkImageInfo&, int sampleCount = 0);
78 
width()79     int width() const { return fWidth; }
height()80     int height() const { return fHeight; }
81 
82     /**
83      *  Returns a unique non-zero, unique value identifying the content of this
84      *  surface. Each time the content is changed changed, either by drawing
85      *  into this surface, or explicitly calling notifyContentChanged()) this
86      *  method will return a new value.
87      *
88      *  If this surface is empty (i.e. has a zero-dimention), this will return
89      *  0.
90      */
91     uint32_t generationID();
92 
93     /**
94      *  Modes that can be passed to notifyContentWillChange
95      */
96     enum ContentChangeMode {
97         /**
98          *  Use this mode if it is known that the upcoming content changes will
99          *  clear or overwrite prior contents, thus making them discardable.
100          */
101         kDiscard_ContentChangeMode,
102         /**
103          *  Use this mode if prior surface contents need to be preserved or
104          *  if in doubt.
105          */
106         kRetain_ContentChangeMode,
107     };
108 
109     /**
110      *  Call this if the contents are about to change. This will (lazily) force a new
111      *  value to be returned from generationID() when it is called next.
112      */
113     void notifyContentWillChange(ContentChangeMode mode);
114 
115     /**
116      *  Return a canvas that will draw into this surface. This will always
117      *  return the same canvas for a given surface, and is manged/owned by the
118      *  surface. It should not be used when its parent surface has gone out of
119      *  scope.
120      */
121     SkCanvas* getCanvas();
122 
123     /**
124      *  Return a new surface that is "compatible" with this one, in that it will
125      *  efficiently be able to be drawn into this surface. Typical calling
126      *  pattern:
127      *
128      *  SkSurface* A = SkSurface::New...();
129      *  SkCanvas* canvasA = surfaceA->newCanvas();
130      *  ...
131      *  SkSurface* surfaceB = surfaceA->newSurface(...);
132      *  SkCanvas* canvasB = surfaceB->newCanvas();
133      *  ... // draw using canvasB
134      *  canvasA->drawSurface(surfaceB); // <--- this will always be optimal!
135      */
136     SkSurface* newSurface(const SkImageInfo&);
137 
138     /**
139      *  Returns an image of the current state of the surface pixels up to this
140      *  point. Subsequent changes to the surface (by drawing into its canvas)
141      *  will not be reflected in this image.
142      */
143     SkImage* newImageSnapshot();
144 
145     /**
146      *  Thought the caller could get a snapshot image explicitly, and draw that,
147      *  it seems that directly drawing a surface into another canvas might be
148      *  a common pattern, and that we could possibly be more efficient, since
149      *  we'd know that the "snapshot" need only live until we've handed it off
150      *  to the canvas.
151      */
152     void draw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*);
153 
154 protected:
155     SkSurface(int width, int height);
156 
157     // called by subclass if their contents have changed
dirtyGenerationID()158     void dirtyGenerationID() {
159         fGenerationID = 0;
160     }
161 
162 private:
163     const int   fWidth;
164     const int   fHeight;
165     uint32_t    fGenerationID;
166 
167     typedef SkRefCnt INHERITED;
168 };
169 
170 #endif
171