3 * Copyright 2010 The Android Open Source Project
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
10 #ifndef SkDevice_DEFINED
11 #define SkDevice_DEFINED
17 #include "SkDeviceProperties.h"
18 #include "SkImageFilter.h"
29 class SK_API SkBaseDevice : public SkRefCnt {
31 SK_DECLARE_INST_COUNT(SkBaseDevice)
34 * Construct a new device.
39 * Construct a new device.
41 SkBaseDevice(const SkDeviceProperties& deviceProperties);
43 virtual ~SkBaseDevice();
45 SkBaseDevice* createCompatibleDevice(const SkImageInfo&);
47 SkMetaData& getMetaData();
49 /** Return the width of the device (in pixels).
51 virtual int width() const = 0;
52 /** Return the height of the device (in pixels).
54 virtual int height() const = 0;
56 /** Return the image properties of the device. */
57 virtual const SkDeviceProperties& getDeviceProperties() const {
58 //Currently, all the properties are leaky.
59 return fLeakyProperties;
63 * Return ImageInfo for this device. If the canvas is not backed by pixels
64 * (cpu or gpu), then the info's ColorType will be kUnknown_SkColorType.
66 virtual SkImageInfo imageInfo() const;
69 * Return the bounds of the device in the coordinate space of the root
70 * canvas. The root device will have its top-left at 0,0, but other devices
71 * such as those associated with saveLayer may have a non-zero origin.
73 void getGlobalBounds(SkIRect* bounds) const {
75 const SkIPoint& origin = this->getOrigin();
76 bounds->setXYWH(origin.x(), origin.y(), this->width(), this->height());
80 /** Returns true if the device's bitmap's config treats every pixel as
83 virtual bool isOpaque() const = 0;
85 /** Return the bitmap config of the device's pixels
87 virtual SkBitmap::Config config() const = 0;
89 /** Return the bitmap associated with this device. Call this each time you need
90 to access the bitmap, as it notifies the subclass to perform any flushing
91 etc. before you examine the pixels.
92 @param changePixels set to true if the caller plans to change the pixels
93 @return the device's bitmap
95 const SkBitmap& accessBitmap(bool changePixels);
97 bool writePixels(const SkImageInfo&, const void*, size_t rowBytes, int x, int y);
99 void* accessPixels(SkImageInfo* info, size_t* rowBytes);
102 * Return the device's associated gpu render target, or NULL.
104 virtual GrRenderTarget* accessRenderTarget() = 0;
108 * Return the device's origin: its offset in device coordinates from
109 * the default origin in its canvas' matrix/clip
111 const SkIPoint& getOrigin() const { return fOrigin; }
114 * onAttachToCanvas is invoked whenever a device is installed in a canvas
115 * (i.e., setDevice, saveLayer (for the new device created by the save),
116 * and SkCanvas' SkBaseDevice & SkBitmap -taking ctors). It allows the
117 * devices to prepare for drawing (e.g., locking their pixels, etc.)
119 virtual void onAttachToCanvas(SkCanvas*) {
120 SkASSERT(!fAttachedToCanvas);
123 fAttachedToCanvas = true;
128 * onDetachFromCanvas notifies a device that it will no longer be drawn to.
129 * It gives the device a chance to clean up (e.g., unlock its pixels). It
130 * is invoked from setDevice (for the displaced device), restore and
131 * possibly from SkCanvas' dtor.
133 virtual void onDetachFromCanvas() {
134 SkASSERT(fAttachedToCanvas);
135 this->unlockPixels();
137 fAttachedToCanvas = false;
144 kSaveLayer_Usage // <! internal use only
148 uint32_t fFlags; // SkPaint::getFlags()
149 SkPaint::Hinting fHinting;
153 * Device may filter the text flags for drawing text here. If it wants to
154 * make a change to the specified values, it should write them into the
155 * textflags parameter (output) and return true. If the paint is fine as
156 * is, then ignore the textflags parameter and return false.
158 * The baseclass SkBaseDevice filters based on its depth and blitters.
160 virtual bool filterTextFlags(const SkPaint& paint, TextFlags*) = 0;
164 * DEPRECATED: This will be removed in a future change. Device subclasses
165 * should use the matrix and clip from the SkDraw passed to draw functions.
167 * Called with the correct matrix and clip before this device is drawn
168 * to using those settings. If your subclass overrides this, be sure to
169 * call through to the base class as well.
171 * The clipstack is another view of the clip. It records the actual
172 * geometry that went into building the region. It is present for devices
173 * that want to parse it, but is not required: the region is a complete
174 * picture of the current clip. (i.e. if you regionize all of the geometry
175 * in the clipstack, you will arrive at an equivalent region to the one
178 virtual void setMatrixClip(const SkMatrix&, const SkRegion&,
179 const SkClipStack&) {};
181 /** Clears the entire device to the specified color (including alpha).
184 virtual void clear(SkColor color) = 0;
186 SK_ATTR_DEPRECATED("use clear() instead")
187 void eraseColor(SkColor eraseColor) { this->clear(eraseColor); }
189 /** These are called inside the per-device-layer loop for each draw call.
190 When these are called, we have already applied any saveLayer operations,
191 and are handling any looping from the paint, and any effects from the
194 virtual void drawPaint(const SkDraw&, const SkPaint& paint) = 0;
195 virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count,
196 const SkPoint[], const SkPaint& paint) = 0;
197 virtual void drawRect(const SkDraw&, const SkRect& r,
198 const SkPaint& paint) = 0;
199 virtual void drawOval(const SkDraw&, const SkRect& oval,
200 const SkPaint& paint) = 0;
201 virtual void drawRRect(const SkDraw&, const SkRRect& rr,
202 const SkPaint& paint) = 0;
204 // Default impl calls drawPath()
205 virtual void drawDRRect(const SkDraw&, const SkRRect& outer,
206 const SkRRect& inner, const SkPaint&);
209 * If pathIsMutable, then the implementation is allowed to cast path to a
210 * non-const pointer and modify it in place (as an optimization). Canvas
211 * may do this to implement helpers such as drawOval, by placing a temp
212 * path on the stack to hold the representation of the oval.
214 * If prePathMatrix is not null, it should logically be applied before any
215 * stroking or other effects. If there are no effects on the paint that
216 * affect the geometry/rasterization, then the pre matrix can just be
217 * pre-concated with the current matrix.
219 virtual void drawPath(const SkDraw&, const SkPath& path,
220 const SkPaint& paint,
221 const SkMatrix* prePathMatrix = NULL,
222 bool pathIsMutable = false) = 0;
223 virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
224 const SkMatrix& matrix, const SkPaint& paint) = 0;
225 virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
226 int x, int y, const SkPaint& paint) = 0;
229 * The default impl. will create a bitmap-shader from the bitmap,
230 * and call drawRect with it.
232 virtual void drawBitmapRect(const SkDraw&, const SkBitmap&,
233 const SkRect* srcOrNull, const SkRect& dst,
234 const SkPaint& paint,
235 SkCanvas::DrawBitmapRectFlags flags) = 0;
238 * Does not handle text decoration.
239 * Decorations (underline and stike-thru) will be handled by SkCanvas.
241 virtual void drawText(const SkDraw&, const void* text, size_t len,
242 SkScalar x, SkScalar y, const SkPaint& paint) = 0;
243 virtual void drawPosText(const SkDraw&, const void* text, size_t len,
244 const SkScalar pos[], SkScalar constY,
245 int scalarsPerPos, const SkPaint& paint) = 0;
246 virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
247 const SkPath& path, const SkMatrix* matrix,
248 const SkPaint& paint) = 0;
249 virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount,
250 const SkPoint verts[], const SkPoint texs[],
251 const SkColor colors[], SkXfermode* xmode,
252 const uint16_t indices[], int indexCount,
253 const SkPaint& paint) = 0;
254 /** The SkDevice passed will be an SkDevice which was returned by a call to
255 onCreateDevice on this device with kSaveLayer_Usage.
257 virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y,
260 bool readPixels(const SkImageInfo&, void* dst, size_t rowBytes, int x, int y);
262 ///////////////////////////////////////////////////////////////////////////
264 /** Update as needed the pixel value in the bitmap, so that the caller can
265 access the pixels directly.
266 @return The device contents as a bitmap
268 virtual const SkBitmap& onAccessBitmap() = 0;
270 /** Called when this device is installed into a Canvas. Balanced by a call
271 to unlockPixels() when the device is removed from a Canvas.
273 virtual void lockPixels() = 0;
274 virtual void unlockPixels() = 0;
277 * Returns true if the device allows processing of this imagefilter. If
278 * false is returned, then the filter is ignored. This may happen for
279 * some subclasses that do not support pixel manipulations after drawing
280 * has occurred (e.g. printing). The default implementation returns true.
282 virtual bool allowImageFilter(const SkImageFilter*) = 0;
285 * Override and return true for filters that the device can handle
286 * intrinsically. Doing so means that SkCanvas will pass-through this
287 * filter to drawSprite and drawDevice (and potentially filterImage).
288 * Returning false means the SkCanvas will have apply the filter itself,
289 * and just pass the resulting image to the device.
291 virtual bool canHandleImageFilter(const SkImageFilter*) = 0;
294 * Related (but not required) to canHandleImageFilter, this method returns
295 * true if the device could apply the filter to the src bitmap and return
296 * the result (and updates offset as needed).
297 * If the device does not recognize or support this filter,
298 * it just returns false and leaves result and offset unchanged.
300 virtual bool filterImage(const SkImageFilter*, const SkBitmap&,
301 const SkImageFilter::Context& ctx,
302 SkBitmap* result, SkIPoint* offset) = 0;
305 // default impl returns NULL
306 virtual SkSurface* newSurface(const SkImageInfo&);
308 // default impl returns NULL
309 virtual const void* peekPixels(SkImageInfo*, size_t* rowBytes);
312 * The caller is responsible for "pre-clipping" the dst. The impl can assume that the dst
313 * image at the specified x,y offset will fit within the device's bounds.
315 * This is explicitly asserted in readPixels(), the public way to call this.
317 virtual bool onReadPixels(const SkImageInfo&, void*, size_t, int x, int y);
320 * The caller is responsible for "pre-clipping" the src. The impl can assume that the src
321 * image at the specified x,y offset will fit within the device's bounds.
323 * This is explicitly asserted in writePixelsDirect(), the public way to call this.
325 virtual bool onWritePixels(const SkImageInfo&, const void*, size_t, int x, int y);
328 * Default impl returns NULL.
330 virtual void* onAccessPixels(SkImageInfo* info, size_t* rowBytes);
333 * Leaky properties are those which the device should be applying but it isn't.
334 * These properties will be applied by the draw, when and as it can.
335 * If the device does handle a property, that property should be set to the identity value
336 * for that property, effectively making it non-leaky.
338 SkDeviceProperties fLeakyProperties;
341 * PRIVATE / EXPERIMENTAL -- do not call
342 * Construct an acceleration object and attach it to 'picture'
344 virtual void EXPERIMENTAL_optimize(SkPicture* picture);
347 * PRIVATE / EXPERIMENTAL -- do not call
348 * Purge all discardable optimization information for 'picture'. If
349 * picture is NULL then purge discardable information for all pictures.
351 virtual void EXPERIMENTAL_purge(SkPicture* picture);
354 * PRIVATE / EXPERIMENTAL -- do not call
355 * This entry point gives the backend an opportunity to take over the rendering
356 * of 'picture'. If optimization data is available (due to an earlier
357 * 'optimize' call) this entry point should make use of it and return true
358 * if all rendering has been done. If false is returned, SkCanvas will
359 * perform its own rendering pass. It is acceptable for the backend
360 * to perform some device-specific warm up tasks and then let SkCanvas
361 * perform the main rendering loop (by return false from here).
363 virtual bool EXPERIMENTAL_drawPicture(SkCanvas* canvas, SkPicture* picture);
366 friend class SkCanvas;
367 friend struct DeviceCM; //for setMatrixClip
369 friend class SkDrawIter;
370 friend class SkDeviceFilteredPaint;
371 friend class SkDeviceImageFilterProxy;
372 friend class SkDeferredDevice; // for newSurface
374 friend class SkSurface_Raster;
376 // used to change the backend's pixels (and possibly config/rowbytes)
377 // but cannot change the width/height, so there should be no change to
378 // any clip information.
379 // TODO: move to SkBitmapDevice
380 virtual void replaceBitmapBackendForRasterSurface(const SkBitmap&) = 0;
382 // just called by SkCanvas when built as a layer
383 void setOrigin(int x, int y) { fOrigin.set(x, y); }
384 // just called by SkCanvas for saveLayer
385 SkBaseDevice* createCompatibleDeviceForSaveLayer(const SkImageInfo&);
387 virtual SkBaseDevice* onCreateDevice(const SkImageInfo&, Usage) {
391 /** Causes any deferred drawing to the device to be completed.
393 virtual void flush() = 0;
396 SkMetaData* fMetaData;
399 bool fAttachedToCanvas;
402 typedef SkRefCnt INHERITED;