• 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         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 
width()100     int width() const { return fWidth; }
height()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
dirtyGenerationID()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