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