blob: 95b63892aefcaf016419243a893a6e866426d829 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
reed@android.com8a1c16f2008-12-17 15:59:43 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * Copyright 2010 The Android Open Source Project
reed@android.com8a1c16f2008-12-17 15:59:43 +00004 *
epoger@google.comec3ed6a2011-07-28 14:26:00 +00005 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
reed@android.com8a1c16f2008-12-17 15:59:43 +00007 */
8
epoger@google.comec3ed6a2011-07-28 14:26:00 +00009
reed@android.com8a1c16f2008-12-17 15:59:43 +000010#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
reed@google.com46799cd2011-02-22 20:56:26 +000018class SkClipStack;
reed@android.com8a1c16f2008-12-17 15:59:43 +000019class SkDraw;
20struct SkIRect;
21class SkMatrix;
reed@google.coma7d94852011-03-30 21:23:07 +000022class SkMetaData;
reed@android.com8a1c16f2008-12-17 15:59:43 +000023class SkRegion;
24
bungeman@google.com88edf1e2011-08-08 19:41:56 +000025// This is an opaque class, not interpreted by skia
bsalomon@google.comd9f826c2011-07-18 15:25:04 +000026class SkGpuRenderTarget;
27
ctguil@chromium.org7ffb1b22011-03-15 21:27:08 +000028class SK_API SkDevice : public SkRefCnt {
reed@android.com8a1c16f2008-12-17 15:59:43 +000029public:
reed@google.comaf951c92011-06-16 19:10:39 +000030 /**
31 * Construct a new device with the specified bitmap as its backend. It is
32 * valid for the bitmap to have no pixels associated with it. In that case,
33 * any drawing to this device will have no effect.
reed@android.com8a1c16f2008-12-17 15:59:43 +000034 */
reed@google.comaf951c92011-06-16 19:10:39 +000035 SkDevice(const SkBitmap& bitmap);
36
37 /**
38 * Create a new raster device and have the pixels be automatically
39 * allocated. The rowBytes of the device will be computed automatically
40 * based on the config and the width.
41 *
42 * @param config The desired config for the pixels. If the request cannot
43 * be met, the closest matching support config will be used.
44 * @param width width (in pixels) of the device
45 * @param height height (in pixels) of the device
46 * @param isOpaque Set to true if it is known that all of the pixels will
47 * be drawn to opaquely. Used as an accelerator when drawing
48 * these pixels to another device.
49 */
50 SkDevice(SkBitmap::Config config, int width, int height, bool isOpaque = false);
51
reed@google.coma7d94852011-03-30 21:23:07 +000052 virtual ~SkDevice();
reed@android.com8a1c16f2008-12-17 15:59:43 +000053
mike@reedtribe.orgea4ac972011-04-26 11:48:33 +000054 /**
reed@google.com2d54d062011-06-21 12:19:28 +000055 * Creates a device that is of the same type as this device (e.g. SW-raster,
56 * GPU, or PDF). The backing store for this device is created automatically
57 * (e.g. offscreen pixels or FBO or whatever is appropriate).
bsalomon@google.come97f0852011-06-17 13:10:25 +000058 *
reed@google.com2d54d062011-06-21 12:19:28 +000059 * @param width width of the device to create
60 * @param height height of the device to create
61 * @param isOpaque performance hint, set to true if you know that you will
62 * draw into this device such that all of the pixels will
63 * be opaque.
bsalomon@google.come97f0852011-06-17 13:10:25 +000064 */
65 SkDevice* createCompatibleDevice(SkBitmap::Config config,
66 int width, int height,
67 bool isOpaque);
68
bungeman@google.com88edf1e2011-08-08 19:41:56 +000069 SkMetaData& getMetaData();
70
vandebo@chromium.org35fc62b2010-10-26 19:47:30 +000071 enum Capabilities {
72 kGL_Capability = 0x1, //!< mask indicating GL support
73 kVector_Capability = 0x2, //!< mask indicating a vector representation
74 kAll_Capabilities = 0x3
75 };
tomhudson@google.com8a0b0292011-09-13 14:41:06 +000076 virtual uint32_t getDeviceCapabilities() { return 0; }
vandebo@chromium.org35fc62b2010-10-26 19:47:30 +000077
reed@android.com8a1c16f2008-12-17 15:59:43 +000078 /** Return the width of the device (in pixels).
79 */
tomhudson@google.com8a0b0292011-09-13 14:41:06 +000080 virtual int width() const { return fBitmap.width(); }
reed@android.com8a1c16f2008-12-17 15:59:43 +000081 /** Return the height of the device (in pixels).
82 */
tomhudson@google.com8a0b0292011-09-13 14:41:06 +000083 virtual int height() const { return fBitmap.height(); }
reed@google.com6f8f2922011-03-04 22:27:10 +000084
reed@google.comd51bfa02011-08-30 15:56:11 +000085 /**
86 * Return the bounds of the device in the coordinate space of the root
87 * canvas. The root device will have its top-left at 0,0, but other devices
88 * such as those associated with saveLayer may have a non-zero origin.
89 */
90 void getGlobalBounds(SkIRect* bounds) const;
bungeman@google.com88edf1e2011-08-08 19:41:56 +000091
reed@android.com8a1c16f2008-12-17 15:59:43 +000092 /** Returns true if the device's bitmap's config treats every pixels as
93 implicitly opaque.
94 */
95 bool isOpaque() const { return fBitmap.isOpaque(); }
reed@google.com3dd42b32011-02-07 22:44:43 +000096
bungeman@google.com88edf1e2011-08-08 19:41:56 +000097 /** Return the bitmap config of the device's pixels
reed@android.com8a1c16f2008-12-17 15:59:43 +000098 */
bungeman@google.com88edf1e2011-08-08 19:41:56 +000099 SkBitmap::Config config() const { return fBitmap.getConfig(); }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000100
101 /** Return the bitmap associated with this device. Call this each time you need
102 to access the bitmap, as it notifies the subclass to perform any flushing
103 etc. before you examine the pixels.
104 @param changePixels set to true if the caller plans to change the pixels
105 @return the device's bitmap
106 */
107 const SkBitmap& accessBitmap(bool changePixels);
108
bungeman@google.com88edf1e2011-08-08 19:41:56 +0000109 /**
110 * Copy the pixels from the device into bitmap. Returns true on success.
111 * If false is returned, then the bitmap parameter is left unchanged.
112 * The bitmap parameter is treated as output-only, and will be completely
113 * overwritten (if the method returns true).
bsalomon@google.com398109c2011-04-14 18:40:27 +0000114 */
bungeman@google.com88edf1e2011-08-08 19:41:56 +0000115 virtual bool readPixels(const SkIRect& srcRect, SkBitmap* bitmap);
bsalomon@google.com398109c2011-04-14 18:40:27 +0000116
117 /**
bungeman@google.com88edf1e2011-08-08 19:41:56 +0000118 * Similar to draw sprite, this method will copy the pixels in bitmap onto
119 * the device, with the top/left corner specified by (x, y). The pixel
120 * values in the device are completely replaced: there is no blending.
bsalomon@google.com398109c2011-04-14 18:40:27 +0000121 */
bungeman@google.com88edf1e2011-08-08 19:41:56 +0000122 virtual void writePixels(const SkBitmap& bitmap, int x, int y);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000123
bsalomon@google.comd9f826c2011-07-18 15:25:04 +0000124 /**
125 * Return the device's associated gpu render target, or NULL.
reed@android.comf2b98d62010-12-20 18:26:13 +0000126 */
bsalomon@google.comd9f826c2011-07-18 15:25:04 +0000127 virtual SkGpuRenderTarget* accessRenderTarget() { return NULL; }
reed@android.comf2b98d62010-12-20 18:26:13 +0000128
bungeman@google.com88edf1e2011-08-08 19:41:56 +0000129protected:
130 enum Usage {
131 kGeneral_Usage,
132 kSaveLayer_Usage, // <! internal use only
133 };
134
135 /**
136 * Return the device's origin: its offset in device coordinates from
137 * the default origin in its canvas' matrix/clip
138 */
139 const SkIPoint& getOrigin() const { return fOrigin; }
140
bungeman@google.com88edf1e2011-08-08 19:41:56 +0000141 struct TextFlags {
142 uint32_t fFlags; // SkPaint::getFlags()
143 SkPaint::Hinting fHinting;
144 };
145
146 /**
147 * Device may filter the text flags for drawing text here. If it wants to
148 * make a change to the specified values, it should write them into the
149 * textflags parameter (output) and return true. If the paint is fine as
150 * is, then ignore the textflags parameter and return false.
151 *
152 * The baseclass SkDevice filters based on its depth and blitters.
153 */
154 virtual bool filterTextFlags(const SkPaint& paint, TextFlags*);
155
reed@google.com46799cd2011-02-22 20:56:26 +0000156 /**
tomhudson@google.com8a0b0292011-09-13 14:41:06 +0000157 * Called with the correct matrix and clip before this device is drawn
158 * to using those settings. If your subclass overrides this, be sure to
159 * call through to the base class as well.
160 *
161 * The clipstack is another view of the clip. It records the actual
162 * geometry that went into building the region. It is present for devices
163 * that want to parse it, but is not required: the region is a complete
164 * picture of the current clip. (i.e. if you regionize all of the geometry
165 * in the clipstack, you will arrive at an equivalent region to the one
166 * passed in).
167 */
168 virtual void setMatrixClip(const SkMatrix&, const SkRegion&,
169 const SkClipStack&);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000170
171 /** Called when this device gains focus (i.e becomes the current device
172 for drawing).
173 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000174 virtual void gainFocus(SkCanvas*, const SkMatrix&, const SkRegion&,
tomhudson@google.com8a0b0292011-09-13 14:41:06 +0000175 const SkClipStack&) {}
reed@google.com3dd42b32011-02-07 22:44:43 +0000176
bungeman@google.com88edf1e2011-08-08 19:41:56 +0000177 /** Clears the entire device to the specified color (including alpha).
178 * Ignores the clip.
reed@android.comf2b98d62010-12-20 18:26:13 +0000179 */
bungeman@google.com88edf1e2011-08-08 19:41:56 +0000180 virtual void clear(SkColor color);
reed@android.comf2b98d62010-12-20 18:26:13 +0000181
182 /**
bungeman@google.com88edf1e2011-08-08 19:41:56 +0000183 * Deprecated name for clear.
reed@android.comf2b98d62010-12-20 18:26:13 +0000184 */
bungeman@google.com88edf1e2011-08-08 19:41:56 +0000185 void eraseColor(SkColor eraseColor) { this->clear(eraseColor); }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000186
187 /** These are called inside the per-device-layer loop for each draw call.
188 When these are called, we have already applied any saveLayer operations,
189 and are handling any looping from the paint, and any effects from the
190 DrawFilter.
191 */
192 virtual void drawPaint(const SkDraw&, const SkPaint& paint);
193 virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count,
194 const SkPoint[], const SkPaint& paint);
195 virtual void drawRect(const SkDraw&, const SkRect& r,
196 const SkPaint& paint);
reed@google.com7ff8d812011-03-25 15:08:16 +0000197 /**
198 * If pathIsMutable, then the implementation is allowed to cast path to a
199 * non-const pointer and modify it in place (as an optimization). Canvas
200 * may do this to implement helpers such as drawOval, by placing a temp
201 * path on the stack to hold the representation of the oval.
202 *
203 * If prePathMatrix is not null, it should logically be applied before any
204 * stroking or other effects. If there are no effects on the paint that
205 * affect the geometry/rasterization, then the pre matrix can just be
206 * pre-concated with the current matrix.
207 */
reed@android.com8a1c16f2008-12-17 15:59:43 +0000208 virtual void drawPath(const SkDraw&, const SkPath& path,
reed@android.comf2b98d62010-12-20 18:26:13 +0000209 const SkPaint& paint,
210 const SkMatrix* prePathMatrix = NULL,
211 bool pathIsMutable = false);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000212 virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
reed@android.comf2b98d62010-12-20 18:26:13 +0000213 const SkIRect* srcRectOrNull,
reed@android.com8a1c16f2008-12-17 15:59:43 +0000214 const SkMatrix& matrix, const SkPaint& paint);
215 virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
216 int x, int y, const SkPaint& paint);
bungeman@google.com52c748b2011-08-22 21:30:43 +0000217 /**
218 * Does not handle text decoration.
219 * Decorations (underline and stike-thru) will be handled by SkCanvas.
220 */
reed@android.com8a1c16f2008-12-17 15:59:43 +0000221 virtual void drawText(const SkDraw&, const void* text, size_t len,
222 SkScalar x, SkScalar y, const SkPaint& paint);
223 virtual void drawPosText(const SkDraw&, const void* text, size_t len,
224 const SkScalar pos[], SkScalar constY,
225 int scalarsPerPos, const SkPaint& paint);
226 virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
227 const SkPath& path, const SkMatrix* matrix,
228 const SkPaint& paint);
djsollen@google.comcd9d69b2011-03-14 20:30:14 +0000229#ifdef ANDROID
230 virtual void drawPosTextOnPath(const SkDraw& draw, const void* text, size_t len,
231 const SkPoint pos[], const SkPaint& paint,
232 const SkPath& path, const SkMatrix* matrix);
233#endif
reed@android.com8a1c16f2008-12-17 15:59:43 +0000234 virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount,
235 const SkPoint verts[], const SkPoint texs[],
236 const SkColor colors[], SkXfermode* xmode,
237 const uint16_t indices[], int indexCount,
238 const SkPaint& paint);
bungeman@google.com88edf1e2011-08-08 19:41:56 +0000239 /** The SkDevice passed will be an SkDevice which was returned by a call to
240 onCreateCompatibleDevice on this device with kSaveLayer_Usage.
241 */
reed@android.com8a1c16f2008-12-17 15:59:43 +0000242 virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y,
243 const SkPaint&);
244
reed@google.com3636ed52011-01-25 23:50:57 +0000245 ///////////////////////////////////////////////////////////////////////////
246
reed@android.com8a1c16f2008-12-17 15:59:43 +0000247 /** Update as needed the pixel value in the bitmap, so that the caller can access
248 the pixels directly. Note: only the pixels field should be altered. The config/width/height/rowbytes
249 must remain unchanged.
250 */
251 virtual void onAccessBitmap(SkBitmap*);
252
reed@android.comf2b98d62010-12-20 18:26:13 +0000253 SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); }
254 // just for subclasses, to assign a custom pixelref
255 SkPixelRef* setPixelRef(SkPixelRef* pr, size_t offset) {
256 fBitmap.setPixelRef(pr, offset);
257 return pr;
258 }
259
bungeman@google.com88edf1e2011-08-08 19:41:56 +0000260 /** Called when this device is installed into a Canvas. Balanaced by a call
261 to unlockPixels() when the device is removed from a Canvas.
262 */
263 virtual void lockPixels();
264 virtual void unlockPixels();
265
reed@android.com8a1c16f2008-12-17 15:59:43 +0000266private:
reed@google.com6f8f2922011-03-04 22:27:10 +0000267 friend class SkCanvas;
bungeman@google.com88edf1e2011-08-08 19:41:56 +0000268 friend struct DeviceCM; //for setMatrixClip
269 friend class SkDraw;
270 friend class SkDrawIter;
271 friend class SkDeviceFilteredPaint;
272
vandebo@chromium.org5676b4a2011-10-03 19:03:48 +0000273 // just called by SkCanvas when built as a layer
274 void setOrigin(int x, int y) { fOrigin.set(x, y); }
bsalomon@google.come97f0852011-06-17 13:10:25 +0000275 // just called by SkCanvas for saveLayer
276 SkDevice* createCompatibleDeviceForSaveLayer(SkBitmap::Config config,
277 int width, int height,
278 bool isOpaque);
reed@google.com6f8f2922011-03-04 22:27:10 +0000279
bungeman@google.com88edf1e2011-08-08 19:41:56 +0000280 /**
281 * Subclasses should override this to implement createCompatibleDevice.
282 */
283 virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config config,
284 int width, int height,
285 bool isOpaque,
286 Usage usage);
287
288 /** Causes any deferred drawing to the device to be completed.
289 */
tomhudson@google.com8a0b0292011-09-13 14:41:06 +0000290 virtual void flush() {}
bungeman@google.com88edf1e2011-08-08 19:41:56 +0000291
reed@google.com3636ed52011-01-25 23:50:57 +0000292 SkBitmap fBitmap;
reed@google.com6f8f2922011-03-04 22:27:10 +0000293 SkIPoint fOrigin;
reed@google.coma7d94852011-03-30 21:23:07 +0000294 SkMetaData* fMetaData;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000295};
296
297#endif