blob: fcc28d5b9a83e71fa0222099c0ee995e1e4cd12e [file] [log] [blame]
reed@android.com8a1c16f2008-12-17 15:59:43 +00001/*
vandebo@chromium.org8c1d88d2010-11-11 00:49:41 +00002 * Copyright (C) 2010 The Android Open Source Project
reed@android.com8a1c16f2008-12-17 15:59:43 +00003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef SkDevice_DEFINED
18#define SkDevice_DEFINED
19
20#include "SkRefCnt.h"
21#include "SkBitmap.h"
22#include "SkCanvas.h"
23#include "SkColor.h"
24
reed@google.com46799cd2011-02-22 20:56:26 +000025class SkClipStack;
vandebo@chromium.org8d84fac2010-10-13 22:13:05 +000026class SkDevice;
reed@android.com8a1c16f2008-12-17 15:59:43 +000027class SkDraw;
28struct SkIRect;
29class SkMatrix;
reed@google.coma7d94852011-03-30 21:23:07 +000030class SkMetaData;
reed@android.com8a1c16f2008-12-17 15:59:43 +000031class SkRegion;
32
vandebo@chromium.org8d84fac2010-10-13 22:13:05 +000033/** \class SkDeviceFactory
34
bsalomon@google.come97f0852011-06-17 13:10:25 +000035 DEPRECATED: Will be replaced by SkDevice::createCompatibleDevice
36
vandebo@chromium.org8d84fac2010-10-13 22:13:05 +000037 Devices that extend SkDevice should also provide a SkDeviceFactory class
38 to pass into SkCanvas. Doing so will eliminate the need to extend
39 SkCanvas as well.
40*/
mike@reedtribe.orgea4ac972011-04-26 11:48:33 +000041class SK_API SkDeviceFactory : public SkRefCnt {
vandebo@chromium.org8d84fac2010-10-13 22:13:05 +000042public:
mike@reedtribe.orgea4ac972011-04-26 11:48:33 +000043 SkDeviceFactory();
vandebo@chromium.org8c1d88d2010-11-11 00:49:41 +000044 virtual ~SkDeviceFactory();
reed@android.comf2b98d62010-12-20 18:26:13 +000045 virtual SkDevice* newDevice(SkCanvas*, SkBitmap::Config, int width,
46 int height, bool isOpaque, bool isLayer) = 0;
vandebo@chromium.org8d84fac2010-10-13 22:13:05 +000047};
48
49class SkRasterDeviceFactory : public SkDeviceFactory {
50public:
reed@android.comf2b98d62010-12-20 18:26:13 +000051 virtual SkDevice* newDevice(SkCanvas*, SkBitmap::Config, int width,
52 int height, bool isOpaque, bool isLayer);
vandebo@chromium.org8d84fac2010-10-13 22:13:05 +000053};
54
ctguil@chromium.org7ffb1b22011-03-15 21:27:08 +000055class SK_API SkDevice : public SkRefCnt {
reed@android.com8a1c16f2008-12-17 15:59:43 +000056public:
reed@google.comaf951c92011-06-16 19:10:39 +000057// SkDevice();
reed@google.com3dd42b32011-02-07 22:44:43 +000058
reed@google.comaf951c92011-06-16 19:10:39 +000059 /**
60 * Construct a new device with the specified bitmap as its backend. It is
61 * valid for the bitmap to have no pixels associated with it. In that case,
62 * any drawing to this device will have no effect.
reed@android.com8a1c16f2008-12-17 15:59:43 +000063 */
reed@google.comaf951c92011-06-16 19:10:39 +000064 SkDevice(const SkBitmap& bitmap);
65
66 /**
67 * Create a new raster device and have the pixels be automatically
68 * allocated. The rowBytes of the device will be computed automatically
69 * based on the config and the width.
70 *
71 * @param config The desired config for the pixels. If the request cannot
72 * be met, the closest matching support config will be used.
73 * @param width width (in pixels) of the device
74 * @param height height (in pixels) of the device
75 * @param isOpaque Set to true if it is known that all of the pixels will
76 * be drawn to opaquely. Used as an accelerator when drawing
77 * these pixels to another device.
78 */
79 SkDevice(SkBitmap::Config config, int width, int height, bool isOpaque = false);
80
reed@google.coma7d94852011-03-30 21:23:07 +000081 virtual ~SkDevice();
reed@android.com8a1c16f2008-12-17 15:59:43 +000082
mike@reedtribe.orgea4ac972011-04-26 11:48:33 +000083 /**
bsalomon@google.come97f0852011-06-17 13:10:25 +000084 * DEPRECATED: Will be replaced by SkDevice::createCompatibleDevice
85 *
mike@reedtribe.orgea4ac972011-04-26 11:48:33 +000086 * Return the factory that will create this subclass of SkDevice.
87 * The returned factory is cached by the device, and so its reference count
88 * is not changed by this call.
89 */
90 SkDeviceFactory* getDeviceFactory();
vandebo@chromium.org8d84fac2010-10-13 22:13:05 +000091
bsalomon@google.come97f0852011-06-17 13:10:25 +000092 /**
reed@google.com2d54d062011-06-21 12:19:28 +000093 * Creates a device that is of the same type as this device (e.g. SW-raster,
94 * GPU, or PDF). The backing store for this device is created automatically
95 * (e.g. offscreen pixels or FBO or whatever is appropriate).
bsalomon@google.come97f0852011-06-17 13:10:25 +000096 *
reed@google.com2d54d062011-06-21 12:19:28 +000097 * @param width width of the device to create
98 * @param height height of the device to create
99 * @param isOpaque performance hint, set to true if you know that you will
100 * draw into this device such that all of the pixels will
101 * be opaque.
bsalomon@google.come97f0852011-06-17 13:10:25 +0000102 */
103 SkDevice* createCompatibleDevice(SkBitmap::Config config,
104 int width, int height,
105 bool isOpaque);
106
vandebo@chromium.org35fc62b2010-10-26 19:47:30 +0000107 enum Capabilities {
108 kGL_Capability = 0x1, //!< mask indicating GL support
109 kVector_Capability = 0x2, //!< mask indicating a vector representation
110 kAll_Capabilities = 0x3
111 };
112 virtual uint32_t getDeviceCapabilities() { return 0; }
113
reed@android.com8a1c16f2008-12-17 15:59:43 +0000114 /** Return the width of the device (in pixels).
115 */
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000116 virtual int width() const { return fBitmap.width(); }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000117 /** Return the height of the device (in pixels).
118 */
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000119 virtual int height() const { return fBitmap.height(); }
reed@google.com6f8f2922011-03-04 22:27:10 +0000120
121 /**
122 * Return the device's origin: its offset in device coordinates from
123 * the default origin in its canvas' matrix/clip
124 */
125 const SkIPoint& getOrigin() const { return fOrigin; }
126
reed@android.com8a1c16f2008-12-17 15:59:43 +0000127 /** Return the bitmap config of the device's pixels
128 */
129 SkBitmap::Config config() const { return fBitmap.getConfig(); }
130 /** Returns true if the device's bitmap's config treats every pixels as
131 implicitly opaque.
132 */
133 bool isOpaque() const { return fBitmap.isOpaque(); }
reed@google.com3dd42b32011-02-07 22:44:43 +0000134
reed@android.com8a1c16f2008-12-17 15:59:43 +0000135 /** Return the bounds of the device
136 */
137 void getBounds(SkIRect* bounds) const;
reed@google.com3dd42b32011-02-07 22:44:43 +0000138
reed@android.com8a1c16f2008-12-17 15:59:43 +0000139 /** Return true if the specified rectangle intersects the bounds of the
140 device. If sect is not NULL and there is an intersection, sect returns
141 the intersection.
142 */
143 bool intersects(const SkIRect& r, SkIRect* sect = NULL) const;
144
145 /** Return the bitmap associated with this device. Call this each time you need
146 to access the bitmap, as it notifies the subclass to perform any flushing
147 etc. before you examine the pixels.
148 @param changePixels set to true if the caller plans to change the pixels
149 @return the device's bitmap
150 */
151 const SkBitmap& accessBitmap(bool changePixels);
152
bsalomon@google.com398109c2011-04-14 18:40:27 +0000153 /** Clears the entire device to the specified color (including alpha).
154 * Ignores the clip.
155 */
156 virtual void clear(SkColor color);
157
158 /**
159 * Deprecated name for clear.
160 */
161 void eraseColor(SkColor eraseColor) { this->clear(eraseColor); }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000162
163 /** Called when this device is installed into a Canvas. Balanaced by a call
164 to unlockPixels() when the device is removed from a Canvas.
165 */
166 virtual void lockPixels();
167 virtual void unlockPixels();
168
reed@android.comf2b98d62010-12-20 18:26:13 +0000169 /** Return the device's associated texture, or NULL. If returned, it may be
170 drawn into another device
171 */
172 virtual SkGpuTexture* accessTexture() { return NULL; }
173
reed@google.com46799cd2011-02-22 20:56:26 +0000174 /**
175 * Called with the correct matrix and clip before this device is drawn
176 * to using those settings. If your subclass overrides this, be sure to
177 * call through to the base class as well.
178 *
179 * The clipstack is another view of the clip. It records the actual
180 * geometry that went into building the region. It is present for devices
181 * that want to parse it, but is not required: the region is a complete
182 * picture of the current clip. (i.e. if you regionize all of the geometry
183 * in the clipstack, you will arrive at an equivalent region to the one
184 * passed in).
reed@android.com8a1c16f2008-12-17 15:59:43 +0000185 */
reed@google.com46799cd2011-02-22 20:56:26 +0000186 virtual void setMatrixClip(const SkMatrix&, const SkRegion&,
187 const SkClipStack&);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000188
189 /** Called when this device gains focus (i.e becomes the current device
190 for drawing).
191 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000192 virtual void gainFocus(SkCanvas*, const SkMatrix&, const SkRegion&,
193 const SkClipStack&) {}
reed@google.com3dd42b32011-02-07 22:44:43 +0000194
reed@android.comf2b98d62010-12-20 18:26:13 +0000195 /** Causes any deferred drawing to the device to be completed.
196 */
197 virtual void flush() {}
198
199 /**
200 * Copy the pixels from the device into bitmap. Returns true on success.
201 * If false is returned, then the bitmap parameter is left unchanged.
reed@google.com3dd42b32011-02-07 22:44:43 +0000202 * The bitmap parameter is treated as output-only, and will be completely
203 * overwritten (if the method returns true).
reed@android.comf2b98d62010-12-20 18:26:13 +0000204 */
205 virtual bool readPixels(const SkIRect& srcRect, SkBitmap* bitmap);
206
207 /**
208 * Similar to draw sprite, this method will copy the pixels in bitmap onto
209 * the device, with the top/left corner specified by (x, y). The pixel
210 * values in the device are completely replaced: there is no blending.
211 */
212 virtual void writePixels(const SkBitmap& bitmap, int x, int y);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000213
214 /** These are called inside the per-device-layer loop for each draw call.
215 When these are called, we have already applied any saveLayer operations,
216 and are handling any looping from the paint, and any effects from the
217 DrawFilter.
218 */
219 virtual void drawPaint(const SkDraw&, const SkPaint& paint);
220 virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count,
221 const SkPoint[], const SkPaint& paint);
222 virtual void drawRect(const SkDraw&, const SkRect& r,
223 const SkPaint& paint);
reed@google.com7ff8d812011-03-25 15:08:16 +0000224 /**
225 * If pathIsMutable, then the implementation is allowed to cast path to a
226 * non-const pointer and modify it in place (as an optimization). Canvas
227 * may do this to implement helpers such as drawOval, by placing a temp
228 * path on the stack to hold the representation of the oval.
229 *
230 * If prePathMatrix is not null, it should logically be applied before any
231 * stroking or other effects. If there are no effects on the paint that
232 * affect the geometry/rasterization, then the pre matrix can just be
233 * pre-concated with the current matrix.
234 */
reed@android.com8a1c16f2008-12-17 15:59:43 +0000235 virtual void drawPath(const SkDraw&, const SkPath& path,
reed@android.comf2b98d62010-12-20 18:26:13 +0000236 const SkPaint& paint,
237 const SkMatrix* prePathMatrix = NULL,
238 bool pathIsMutable = false);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000239 virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
reed@android.comf2b98d62010-12-20 18:26:13 +0000240 const SkIRect* srcRectOrNull,
reed@android.com8a1c16f2008-12-17 15:59:43 +0000241 const SkMatrix& matrix, const SkPaint& paint);
242 virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
243 int x, int y, const SkPaint& paint);
244 virtual void drawText(const SkDraw&, const void* text, size_t len,
245 SkScalar x, SkScalar y, const SkPaint& paint);
246 virtual void drawPosText(const SkDraw&, const void* text, size_t len,
247 const SkScalar pos[], SkScalar constY,
248 int scalarsPerPos, const SkPaint& paint);
249 virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
250 const SkPath& path, const SkMatrix* matrix,
251 const SkPaint& paint);
djsollen@google.comcd9d69b2011-03-14 20:30:14 +0000252#ifdef ANDROID
253 virtual void drawPosTextOnPath(const SkDraw& draw, const void* text, size_t len,
254 const SkPoint pos[], const SkPaint& paint,
255 const SkPath& path, const SkMatrix* matrix);
256#endif
reed@android.com8a1c16f2008-12-17 15:59:43 +0000257 virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount,
258 const SkPoint verts[], const SkPoint texs[],
259 const SkColor colors[], SkXfermode* xmode,
260 const uint16_t indices[], int indexCount,
261 const SkPaint& paint);
262 virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y,
263 const SkPaint&);
264
reed@google.com3636ed52011-01-25 23:50:57 +0000265 ///////////////////////////////////////////////////////////////////////////
266
reed@google.coma7d94852011-03-30 21:23:07 +0000267 SkMetaData& getMetaData();
reed@google.com3636ed52011-01-25 23:50:57 +0000268
reed@google.comf67e4cf2011-03-15 20:56:58 +0000269 struct TextFlags {
270 uint32_t fFlags; // SkPaint::getFlags()
271 SkPaint::Hinting fHinting;
272 };
273
274 /**
275 * Device may filter the text flags for drawing text here. If it wants to
276 * make a change to the specified values, it should write them into the
277 * textflags parameter (output) and return true. If the paint is fine as
278 * is, then ignore the textflags parameter and return false.
279 *
280 * The baseclass SkDevice filters based on its depth and blitters.
281 */
282 virtual bool filterTextFlags(const SkPaint& paint, TextFlags*);
283
reed@android.com8a1c16f2008-12-17 15:59:43 +0000284protected:
mike@reedtribe.orgea4ac972011-04-26 11:48:33 +0000285 /**
bsalomon@google.come97f0852011-06-17 13:10:25 +0000286 * DEPRECATED: Will be replaced by SkDevice::createCompatibleDevice
287 *
288 * subclasses can override this to return a new (or ref'd) instance of
mike@reedtribe.orgea4ac972011-04-26 11:48:33 +0000289 * a device factory that will create this subclass of device. This value
290 * is cached, so it should get called at most once for a given instance.
bsalomon@google.come97f0852011-06-17 13:10:25 +0000291 *
292 * If not overriden then createCompatibleDevice will be used by canvas.
mike@reedtribe.orgea4ac972011-04-26 11:48:33 +0000293 */
294 virtual SkDeviceFactory* onNewDeviceFactory();
295
reed@android.com8a1c16f2008-12-17 15:59:43 +0000296 /** Update as needed the pixel value in the bitmap, so that the caller can access
297 the pixels directly. Note: only the pixels field should be altered. The config/width/height/rowbytes
298 must remain unchanged.
299 */
300 virtual void onAccessBitmap(SkBitmap*);
301
bsalomon@google.come97f0852011-06-17 13:10:25 +0000302 enum Usage {
303 kGeneral_Usage,
304 kSaveLayer_Usage, // <! internal use only
305 };
306 /**
307 * subclasses should override this to implement createCompatibleDevice.
308 */
309 virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config config,
310 int width, int height,
311 bool isOpaque,
312 Usage usage);
313
reed@android.comf2b98d62010-12-20 18:26:13 +0000314 SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); }
315 // just for subclasses, to assign a custom pixelref
316 SkPixelRef* setPixelRef(SkPixelRef* pr, size_t offset) {
317 fBitmap.setPixelRef(pr, offset);
318 return pr;
319 }
320
reed@android.com8a1c16f2008-12-17 15:59:43 +0000321private:
reed@google.com6f8f2922011-03-04 22:27:10 +0000322 friend class SkCanvas;
323 // just called by SkCanvas when built as a layer
324 void setOrigin(int x, int y) { fOrigin.set(x, y); }
bsalomon@google.come97f0852011-06-17 13:10:25 +0000325 // just called by SkCanvas for saveLayer
326 SkDevice* createCompatibleDeviceForSaveLayer(SkBitmap::Config config,
327 int width, int height,
328 bool isOpaque);
reed@google.com6f8f2922011-03-04 22:27:10 +0000329
reed@google.com3636ed52011-01-25 23:50:57 +0000330 SkBitmap fBitmap;
reed@google.com6f8f2922011-03-04 22:27:10 +0000331 SkIPoint fOrigin;
reed@google.coma7d94852011-03-30 21:23:07 +0000332 SkMetaData* fMetaData;
mike@reedtribe.orgea4ac972011-04-26 11:48:33 +0000333
334 SkDeviceFactory* fCachedDeviceFactory;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000335};
336
337#endif