|
1 |
|
2 /* |
|
3 * Copyright 2010 The Android Open Source Project |
|
4 * |
|
5 * Use of this source code is governed by a BSD-style license that can be |
|
6 * found in the LICENSE file. |
|
7 */ |
|
8 |
|
9 |
|
10 #ifndef SkDevice_DEFINED |
|
11 #define SkDevice_DEFINED |
|
12 |
|
13 #include "SkRefCnt.h" |
|
14 #include "SkBitmap.h" |
|
15 #include "SkCanvas.h" |
|
16 #include "SkColor.h" |
|
17 #include "SkDeviceProperties.h" |
|
18 #include "SkImageFilter.h" |
|
19 |
|
20 // getDeviceCapabilities() is not called by skia, but this flag keeps it around |
|
21 // for clients that have "override" annotations on their subclass. These overrides |
|
22 // should be deleted. |
|
23 //#define SK_SUPPORT_LEGACY_GETDEVICECAPABILITIES |
|
24 |
|
25 //#define SK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG |
|
26 |
|
27 class SkClipStack; |
|
28 class SkDraw; |
|
29 struct SkIRect; |
|
30 class SkMatrix; |
|
31 class SkMetaData; |
|
32 class SkRegion; |
|
33 |
|
34 class GrRenderTarget; |
|
35 |
|
36 class SK_API SkBaseDevice : public SkRefCnt { |
|
37 public: |
|
38 SK_DECLARE_INST_COUNT(SkBaseDevice) |
|
39 |
|
40 /** |
|
41 * Construct a new device. |
|
42 */ |
|
43 SkBaseDevice(); |
|
44 |
|
45 /** |
|
46 * Construct a new device. |
|
47 */ |
|
48 SkBaseDevice(const SkDeviceProperties& deviceProperties); |
|
49 |
|
50 virtual ~SkBaseDevice(); |
|
51 |
|
52 #ifdef SK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG |
|
53 /** |
|
54 * Creates a device that is of the same type as this device (e.g. SW-raster, |
|
55 * GPU, or PDF). The backing store for this device is created automatically |
|
56 * (e.g. offscreen pixels or FBO or whatever is appropriate). |
|
57 * |
|
58 * @param width width of the device to create |
|
59 * @param height height of the device to create |
|
60 * @param isOpaque performance hint, set to true if you know that you will |
|
61 * draw into this device such that all of the pixels will |
|
62 * be opaque. |
|
63 */ |
|
64 SkBaseDevice* createCompatibleDevice(SkBitmap::Config config, |
|
65 int width, int height, |
|
66 bool isOpaque); |
|
67 #endif |
|
68 SkBaseDevice* createCompatibleDevice(const SkImageInfo&); |
|
69 |
|
70 SkMetaData& getMetaData(); |
|
71 |
|
72 #ifdef SK_SUPPORT_LEGACY_GETDEVICECAPABILITIES |
|
73 enum Capabilities { |
|
74 kVector_Capability = 0x1, |
|
75 }; |
|
76 virtual uint32_t getDeviceCapabilities() { return 0; } |
|
77 #endif |
|
78 |
|
79 /** Return the width of the device (in pixels). |
|
80 */ |
|
81 virtual int width() const = 0; |
|
82 /** Return the height of the device (in pixels). |
|
83 */ |
|
84 virtual int height() const = 0; |
|
85 |
|
86 /** Return the image properties of the device. */ |
|
87 virtual const SkDeviceProperties& getDeviceProperties() const { |
|
88 //Currently, all the properties are leaky. |
|
89 return fLeakyProperties; |
|
90 } |
|
91 |
|
92 /** |
|
93 * Return ImageInfo for this device. If the canvas is not backed by pixels |
|
94 * (cpu or gpu), then the info's ColorType will be kUnknown_SkColorType. |
|
95 */ |
|
96 virtual SkImageInfo imageInfo() const; |
|
97 |
|
98 /** |
|
99 * Return the bounds of the device in the coordinate space of the root |
|
100 * canvas. The root device will have its top-left at 0,0, but other devices |
|
101 * such as those associated with saveLayer may have a non-zero origin. |
|
102 */ |
|
103 void getGlobalBounds(SkIRect* bounds) const { |
|
104 SkASSERT(bounds); |
|
105 const SkIPoint& origin = this->getOrigin(); |
|
106 bounds->setXYWH(origin.x(), origin.y(), this->width(), this->height()); |
|
107 } |
|
108 |
|
109 |
|
110 /** Returns true if the device's bitmap's config treats every pixel as |
|
111 implicitly opaque. |
|
112 */ |
|
113 virtual bool isOpaque() const = 0; |
|
114 |
|
115 /** Return the bitmap config of the device's pixels |
|
116 */ |
|
117 virtual SkBitmap::Config config() const = 0; |
|
118 |
|
119 /** Return the bitmap associated with this device. Call this each time you need |
|
120 to access the bitmap, as it notifies the subclass to perform any flushing |
|
121 etc. before you examine the pixels. |
|
122 @param changePixels set to true if the caller plans to change the pixels |
|
123 @return the device's bitmap |
|
124 */ |
|
125 const SkBitmap& accessBitmap(bool changePixels); |
|
126 |
|
127 #ifdef SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG |
|
128 /** |
|
129 * DEPRECATED: This will be made protected once WebKit stops using it. |
|
130 * Instead use Canvas' writePixels method. |
|
131 * |
|
132 * Similar to draw sprite, this method will copy the pixels in bitmap onto |
|
133 * the device, with the top/left corner specified by (x, y). The pixel |
|
134 * values in the device are completely replaced: there is no blending. |
|
135 * |
|
136 * Currently if bitmap is backed by a texture this is a no-op. This may be |
|
137 * relaxed in the future. |
|
138 * |
|
139 * If the bitmap has config kARGB_8888_Config then the config8888 param |
|
140 * will determines how the pixel valuess are intepreted. If the bitmap is |
|
141 * not kARGB_8888_Config then this parameter is ignored. |
|
142 */ |
|
143 virtual void writePixels(const SkBitmap& bitmap, int x, int y, |
|
144 SkCanvas::Config8888 config8888 = SkCanvas::kNative_Premul_Config8888); |
|
145 #endif |
|
146 |
|
147 bool writePixelsDirect(const SkImageInfo&, const void*, size_t rowBytes, int x, int y); |
|
148 |
|
149 void* accessPixels(SkImageInfo* info, size_t* rowBytes); |
|
150 |
|
151 /** |
|
152 * Return the device's associated gpu render target, or NULL. |
|
153 */ |
|
154 virtual GrRenderTarget* accessRenderTarget() = 0; |
|
155 |
|
156 |
|
157 /** |
|
158 * Return the device's origin: its offset in device coordinates from |
|
159 * the default origin in its canvas' matrix/clip |
|
160 */ |
|
161 const SkIPoint& getOrigin() const { return fOrigin; } |
|
162 |
|
163 /** |
|
164 * onAttachToCanvas is invoked whenever a device is installed in a canvas |
|
165 * (i.e., setDevice, saveLayer (for the new device created by the save), |
|
166 * and SkCanvas' SkBaseDevice & SkBitmap -taking ctors). It allows the |
|
167 * devices to prepare for drawing (e.g., locking their pixels, etc.) |
|
168 */ |
|
169 virtual void onAttachToCanvas(SkCanvas*) { |
|
170 SkASSERT(!fAttachedToCanvas); |
|
171 this->lockPixels(); |
|
172 #ifdef SK_DEBUG |
|
173 fAttachedToCanvas = true; |
|
174 #endif |
|
175 }; |
|
176 |
|
177 /** |
|
178 * onDetachFromCanvas notifies a device that it will no longer be drawn to. |
|
179 * It gives the device a chance to clean up (e.g., unlock its pixels). It |
|
180 * is invoked from setDevice (for the displaced device), restore and |
|
181 * possibly from SkCanvas' dtor. |
|
182 */ |
|
183 virtual void onDetachFromCanvas() { |
|
184 SkASSERT(fAttachedToCanvas); |
|
185 this->unlockPixels(); |
|
186 #ifdef SK_DEBUG |
|
187 fAttachedToCanvas = false; |
|
188 #endif |
|
189 }; |
|
190 |
|
191 protected: |
|
192 enum Usage { |
|
193 kGeneral_Usage, |
|
194 kSaveLayer_Usage // <! internal use only |
|
195 }; |
|
196 |
|
197 struct TextFlags { |
|
198 uint32_t fFlags; // SkPaint::getFlags() |
|
199 SkPaint::Hinting fHinting; |
|
200 }; |
|
201 |
|
202 /** |
|
203 * Device may filter the text flags for drawing text here. If it wants to |
|
204 * make a change to the specified values, it should write them into the |
|
205 * textflags parameter (output) and return true. If the paint is fine as |
|
206 * is, then ignore the textflags parameter and return false. |
|
207 * |
|
208 * The baseclass SkBaseDevice filters based on its depth and blitters. |
|
209 */ |
|
210 virtual bool filterTextFlags(const SkPaint& paint, TextFlags*) = 0; |
|
211 |
|
212 /** |
|
213 * |
|
214 * DEPRECATED: This will be removed in a future change. Device subclasses |
|
215 * should use the matrix and clip from the SkDraw passed to draw functions. |
|
216 * |
|
217 * Called with the correct matrix and clip before this device is drawn |
|
218 * to using those settings. If your subclass overrides this, be sure to |
|
219 * call through to the base class as well. |
|
220 * |
|
221 * The clipstack is another view of the clip. It records the actual |
|
222 * geometry that went into building the region. It is present for devices |
|
223 * that want to parse it, but is not required: the region is a complete |
|
224 * picture of the current clip. (i.e. if you regionize all of the geometry |
|
225 * in the clipstack, you will arrive at an equivalent region to the one |
|
226 * passed in). |
|
227 */ |
|
228 virtual void setMatrixClip(const SkMatrix&, const SkRegion&, |
|
229 const SkClipStack&) {}; |
|
230 |
|
231 /** Clears the entire device to the specified color (including alpha). |
|
232 * Ignores the clip. |
|
233 */ |
|
234 virtual void clear(SkColor color) = 0; |
|
235 |
|
236 SK_ATTR_DEPRECATED("use clear() instead") |
|
237 void eraseColor(SkColor eraseColor) { this->clear(eraseColor); } |
|
238 |
|
239 /** These are called inside the per-device-layer loop for each draw call. |
|
240 When these are called, we have already applied any saveLayer operations, |
|
241 and are handling any looping from the paint, and any effects from the |
|
242 DrawFilter. |
|
243 */ |
|
244 virtual void drawPaint(const SkDraw&, const SkPaint& paint) = 0; |
|
245 virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count, |
|
246 const SkPoint[], const SkPaint& paint) = 0; |
|
247 virtual void drawRect(const SkDraw&, const SkRect& r, |
|
248 const SkPaint& paint) = 0; |
|
249 virtual void drawOval(const SkDraw&, const SkRect& oval, |
|
250 const SkPaint& paint) = 0; |
|
251 virtual void drawRRect(const SkDraw&, const SkRRect& rr, |
|
252 const SkPaint& paint) = 0; |
|
253 |
|
254 // Default impl calls drawPath() |
|
255 virtual void drawDRRect(const SkDraw&, const SkRRect& outer, |
|
256 const SkRRect& inner, const SkPaint&); |
|
257 |
|
258 /** |
|
259 * If pathIsMutable, then the implementation is allowed to cast path to a |
|
260 * non-const pointer and modify it in place (as an optimization). Canvas |
|
261 * may do this to implement helpers such as drawOval, by placing a temp |
|
262 * path on the stack to hold the representation of the oval. |
|
263 * |
|
264 * If prePathMatrix is not null, it should logically be applied before any |
|
265 * stroking or other effects. If there are no effects on the paint that |
|
266 * affect the geometry/rasterization, then the pre matrix can just be |
|
267 * pre-concated with the current matrix. |
|
268 */ |
|
269 virtual void drawPath(const SkDraw&, const SkPath& path, |
|
270 const SkPaint& paint, |
|
271 const SkMatrix* prePathMatrix = NULL, |
|
272 bool pathIsMutable = false) = 0; |
|
273 virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap, |
|
274 const SkMatrix& matrix, const SkPaint& paint) = 0; |
|
275 virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap, |
|
276 int x, int y, const SkPaint& paint) = 0; |
|
277 |
|
278 /** |
|
279 * The default impl. will create a bitmap-shader from the bitmap, |
|
280 * and call drawRect with it. |
|
281 */ |
|
282 virtual void drawBitmapRect(const SkDraw&, const SkBitmap&, |
|
283 const SkRect* srcOrNull, const SkRect& dst, |
|
284 const SkPaint& paint, |
|
285 SkCanvas::DrawBitmapRectFlags flags) = 0; |
|
286 |
|
287 /** |
|
288 * Does not handle text decoration. |
|
289 * Decorations (underline and stike-thru) will be handled by SkCanvas. |
|
290 */ |
|
291 virtual void drawText(const SkDraw&, const void* text, size_t len, |
|
292 SkScalar x, SkScalar y, const SkPaint& paint) = 0; |
|
293 virtual void drawPosText(const SkDraw&, const void* text, size_t len, |
|
294 const SkScalar pos[], SkScalar constY, |
|
295 int scalarsPerPos, const SkPaint& paint) = 0; |
|
296 virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len, |
|
297 const SkPath& path, const SkMatrix* matrix, |
|
298 const SkPaint& paint) = 0; |
|
299 virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount, |
|
300 const SkPoint verts[], const SkPoint texs[], |
|
301 const SkColor colors[], SkXfermode* xmode, |
|
302 const uint16_t indices[], int indexCount, |
|
303 const SkPaint& paint) = 0; |
|
304 /** The SkDevice passed will be an SkDevice which was returned by a call to |
|
305 onCreateDevice on this device with kSaveLayer_Usage. |
|
306 */ |
|
307 virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y, |
|
308 const SkPaint&) = 0; |
|
309 |
|
310 /** |
|
311 * On success (returns true), copy the device pixels into the bitmap. |
|
312 * On failure, the bitmap parameter is left unchanged and false is |
|
313 * returned. |
|
314 * |
|
315 * The device's pixels are converted to the bitmap's config. The only |
|
316 * supported config is kARGB_8888_Config, though this is likely to be |
|
317 * relaxed in the future. The meaning of config kARGB_8888_Config is |
|
318 * modified by the enum param config8888. The default value interprets |
|
319 * kARGB_8888_Config as SkPMColor |
|
320 * |
|
321 * If the bitmap has pixels already allocated, the device pixels will be |
|
322 * written there. If not, bitmap->allocPixels() will be called |
|
323 * automatically. If the bitmap is backed by a texture readPixels will |
|
324 * fail. |
|
325 * |
|
326 * The actual pixels written is the intersection of the device's bounds, |
|
327 * and the rectangle formed by the bitmap's width,height and the specified |
|
328 * x,y. If bitmap pixels extend outside of that intersection, they will not |
|
329 * be modified. |
|
330 * |
|
331 * Other failure conditions: |
|
332 * * If the device is not a raster device (e.g. PDF) then readPixels will |
|
333 * fail. |
|
334 * * If bitmap is texture-backed then readPixels will fail. (This may be |
|
335 * relaxed in the future.) |
|
336 */ |
|
337 bool readPixels(SkBitmap* bitmap, |
|
338 int x, int y, |
|
339 SkCanvas::Config8888 config8888); |
|
340 |
|
341 /////////////////////////////////////////////////////////////////////////// |
|
342 |
|
343 /** Update as needed the pixel value in the bitmap, so that the caller can |
|
344 access the pixels directly. |
|
345 @return The device contents as a bitmap |
|
346 */ |
|
347 virtual const SkBitmap& onAccessBitmap() = 0; |
|
348 |
|
349 /** Called when this device is installed into a Canvas. Balanced by a call |
|
350 to unlockPixels() when the device is removed from a Canvas. |
|
351 */ |
|
352 virtual void lockPixels() = 0; |
|
353 virtual void unlockPixels() = 0; |
|
354 |
|
355 /** |
|
356 * Returns true if the device allows processing of this imagefilter. If |
|
357 * false is returned, then the filter is ignored. This may happen for |
|
358 * some subclasses that do not support pixel manipulations after drawing |
|
359 * has occurred (e.g. printing). The default implementation returns true. |
|
360 */ |
|
361 virtual bool allowImageFilter(const SkImageFilter*) = 0; |
|
362 |
|
363 /** |
|
364 * Override and return true for filters that the device can handle |
|
365 * intrinsically. Doing so means that SkCanvas will pass-through this |
|
366 * filter to drawSprite and drawDevice (and potentially filterImage). |
|
367 * Returning false means the SkCanvas will have apply the filter itself, |
|
368 * and just pass the resulting image to the device. |
|
369 */ |
|
370 virtual bool canHandleImageFilter(const SkImageFilter*) = 0; |
|
371 |
|
372 /** |
|
373 * Related (but not required) to canHandleImageFilter, this method returns |
|
374 * true if the device could apply the filter to the src bitmap and return |
|
375 * the result (and updates offset as needed). |
|
376 * If the device does not recognize or support this filter, |
|
377 * it just returns false and leaves result and offset unchanged. |
|
378 */ |
|
379 virtual bool filterImage(const SkImageFilter*, const SkBitmap&, |
|
380 const SkImageFilter::Context& ctx, |
|
381 SkBitmap* result, SkIPoint* offset) = 0; |
|
382 |
|
383 // This is equal kBGRA_Premul_Config8888 or kRGBA_Premul_Config8888 if |
|
384 // either is identical to kNative_Premul_Config8888. Otherwise, -1. |
|
385 static const SkCanvas::Config8888 kPMColorAlias; |
|
386 |
|
387 protected: |
|
388 // default impl returns NULL |
|
389 virtual SkSurface* newSurface(const SkImageInfo&); |
|
390 |
|
391 // default impl returns NULL |
|
392 virtual const void* peekPixels(SkImageInfo*, size_t* rowBytes); |
|
393 |
|
394 /** |
|
395 * Implements readPixels API. The caller will ensure that: |
|
396 * 1. bitmap has pixel config kARGB_8888_Config. |
|
397 * 2. bitmap has pixels. |
|
398 * 3. The rectangle (x, y, x + bitmap->width(), y + bitmap->height()) is |
|
399 * contained in the device bounds. |
|
400 */ |
|
401 virtual bool onReadPixels(const SkBitmap& bitmap, |
|
402 int x, int y, |
|
403 SkCanvas::Config8888 config8888); |
|
404 |
|
405 /** |
|
406 * The caller is responsible for "pre-clipping" the src. The impl can assume that the src |
|
407 * image at the specified x,y offset will fit within the device's bounds. |
|
408 * |
|
409 * This is explicitly asserted in writePixelsDirect(), the public way to call this. |
|
410 */ |
|
411 virtual bool onWritePixels(const SkImageInfo&, const void*, size_t, int x, int y); |
|
412 |
|
413 /** |
|
414 * Default impl returns NULL. |
|
415 */ |
|
416 virtual void* onAccessPixels(SkImageInfo* info, size_t* rowBytes); |
|
417 |
|
418 /** |
|
419 * Leaky properties are those which the device should be applying but it isn't. |
|
420 * These properties will be applied by the draw, when and as it can. |
|
421 * If the device does handle a property, that property should be set to the identity value |
|
422 * for that property, effectively making it non-leaky. |
|
423 */ |
|
424 SkDeviceProperties fLeakyProperties; |
|
425 |
|
426 /** |
|
427 * PRIVATE / EXPERIMENTAL -- do not call |
|
428 * Construct an acceleration object and attach it to 'picture' |
|
429 */ |
|
430 virtual void EXPERIMENTAL_optimize(SkPicture* picture); |
|
431 |
|
432 /** |
|
433 * PRIVATE / EXPERIMENTAL -- do not call |
|
434 * This entry point gives the backend an opportunity to take over the rendering |
|
435 * of 'picture'. If optimization data is available (due to an earlier |
|
436 * 'optimize' call) this entry point should make use of it and return true |
|
437 * if all rendering has been done. If false is returned, SkCanvas will |
|
438 * perform its own rendering pass. It is acceptable for the backend |
|
439 * to perform some device-specific warm up tasks and then let SkCanvas |
|
440 * perform the main rendering loop (by return false from here). |
|
441 */ |
|
442 virtual bool EXPERIMENTAL_drawPicture(const SkPicture& picture); |
|
443 |
|
444 private: |
|
445 friend class SkCanvas; |
|
446 friend struct DeviceCM; //for setMatrixClip |
|
447 friend class SkDraw; |
|
448 friend class SkDrawIter; |
|
449 friend class SkDeviceFilteredPaint; |
|
450 friend class SkDeviceImageFilterProxy; |
|
451 friend class SkDeferredDevice; // for newSurface |
|
452 |
|
453 friend class SkSurface_Raster; |
|
454 |
|
455 // used to change the backend's pixels (and possibly config/rowbytes) |
|
456 // but cannot change the width/height, so there should be no change to |
|
457 // any clip information. |
|
458 // TODO: move to SkBitmapDevice |
|
459 virtual void replaceBitmapBackendForRasterSurface(const SkBitmap&) = 0; |
|
460 |
|
461 // just called by SkCanvas when built as a layer |
|
462 void setOrigin(int x, int y) { fOrigin.set(x, y); } |
|
463 // just called by SkCanvas for saveLayer |
|
464 SkBaseDevice* createCompatibleDeviceForSaveLayer(const SkImageInfo&); |
|
465 |
|
466 #ifdef SK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG |
|
467 /** |
|
468 * Justs exists during the period where clients still "override" this |
|
469 * signature. They are supported by our base-impl calling this old |
|
470 * signature from the new one (using ImageInfo). |
|
471 */ |
|
472 virtual SkBaseDevice* onCreateCompatibleDevice(SkBitmap::Config config, |
|
473 int width, int height, |
|
474 bool isOpaque, Usage) { |
|
475 return NULL; |
|
476 } |
|
477 #endif |
|
478 virtual SkBaseDevice* onCreateDevice(const SkImageInfo&, Usage) { |
|
479 return NULL; |
|
480 } |
|
481 |
|
482 /** Causes any deferred drawing to the device to be completed. |
|
483 */ |
|
484 virtual void flush() = 0; |
|
485 |
|
486 SkIPoint fOrigin; |
|
487 SkMetaData* fMetaData; |
|
488 |
|
489 #ifdef SK_DEBUG |
|
490 bool fAttachedToCanvas; |
|
491 #endif |
|
492 |
|
493 typedef SkRefCnt INHERITED; |
|
494 }; |
|
495 |
|
496 #endif |