blob: fa427c6a15c16ce449f2bef0bffc4c09cf84409f [file] [log] [blame]
reed@android.com8a1c16f2008-12-17 15:59:43 +00001/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00002 * Copyright 2010 The Android Open Source Project
reed@android.com8a1c16f2008-12-17 15:59:43 +00003 *
epoger@google.comec3ed6a2011-07-28 14:26:00 +00004 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
reed@android.com8a1c16f2008-12-17 15:59:43 +00006 */
7
8#ifndef SkDevice_DEFINED
9#define SkDevice_DEFINED
10
Mike Reed986480a2017-01-13 22:43:16 +000011#include "SkRefCnt.h"
12#include "SkCanvas.h"
13#include "SkColor.h"
14#include "SkSurfaceProps.h"
15
16class SkBitmap;
17class SkClipStack;
18class SkDraw;
19class SkDrawFilter;
20class SkImageFilterCache;
21struct SkIRect;
22class SkMatrix;
23class SkMetaData;
24class SkRasterHandleAllocator;
25class SkRegion;
26class SkSpecialImage;
27class GrRenderTarget;
28
29class SK_API SkBaseDevice : public SkRefCnt {
30public:
31 /**
32 * Construct a new device.
33 */
34 explicit SkBaseDevice(const SkImageInfo&, const SkSurfaceProps&);
35 virtual ~SkBaseDevice();
36
37 SkMetaData& getMetaData();
38
39 /**
40 * Return ImageInfo for this device. If the canvas is not backed by pixels
41 * (cpu or gpu), then the info's ColorType will be kUnknown_SkColorType.
42 */
43 const SkImageInfo& imageInfo() const { return fInfo; }
44
45 /**
46 * Return SurfaceProps for this device.
47 */
48 const SkSurfaceProps& surfaceProps() const {
49 return fSurfaceProps;
50 }
51
52 /**
53 * Return the bounds of the device in the coordinate space of the root
54 * canvas. The root device will have its top-left at 0,0, but other devices
55 * such as those associated with saveLayer may have a non-zero origin.
56 */
57 void getGlobalBounds(SkIRect* bounds) const {
58 SkASSERT(bounds);
59 const SkIPoint& origin = this->getOrigin();
60 bounds->setXYWH(origin.x(), origin.y(), this->width(), this->height());
61 }
62
63 SkIRect getGlobalBounds() const {
64 SkIRect bounds;
65 this->getGlobalBounds(&bounds);
66 return bounds;
67 }
68
69 int width() const {
70 return this->imageInfo().width();
71 }
72
73 int height() const {
74 return this->imageInfo().height();
75 }
76
77 bool isOpaque() const {
78 return this->imageInfo().isOpaque();
79 }
80
81#ifdef SK_SUPPORT_LEGACY_ACCESSBITMAP
82 /** Return the bitmap associated with this device. Call this each time you need
83 to access the bitmap, as it notifies the subclass to perform any flushing
84 etc. before you examine the pixels.
85 @param changePixels set to true if the caller plans to change the pixels
86 @return the device's bitmap
87 */
88 const SkBitmap& accessBitmap(bool changePixels);
89#endif
90
91 bool writePixels(const SkImageInfo&, const void*, size_t rowBytes, int x, int y);
92
93 /**
94 * Try to get write-access to the pixels behind the device. If successful, this returns true
95 * and fills-out the pixmap parameter. On success it also bumps the genID of the underlying
96 * bitmap.
97 *
98 * On failure, returns false and ignores the pixmap parameter.
99 */
100 bool accessPixels(SkPixmap* pmap);
101
102 /**
103 * Try to get read-only-access to the pixels behind the device. If successful, this returns
104 * true and fills-out the pixmap parameter.
105 *
106 * On failure, returns false and ignores the pixmap parameter.
107 */
108 bool peekPixels(SkPixmap*);
109
110 /**
111 * Return the device's origin: its offset in device coordinates from
112 * the default origin in its canvas' matrix/clip
113 */
114 const SkIPoint& getOrigin() const { return fOrigin; }
115
116 virtual void* getRasterHandle() const { return nullptr; }
117
118protected:
119 enum TileUsage {
120 kPossible_TileUsage, //!< the created device may be drawn tiled
121 kNever_TileUsage, //!< the created device will never be drawn tiled
122 };
123
124 struct TextFlags {
125 uint32_t fFlags; // SkPaint::getFlags()
126 };
127
128 /**
129 * Returns the text-related flags, possibly modified based on the state of the
130 * device (e.g. support for LCD).
131 */
132 uint32_t filterTextFlags(const SkPaint&) const;
133
134 virtual bool onShouldDisableLCD(const SkPaint&) const { return false; }
135
136 /** These are called inside the per-device-layer loop for each draw call.
137 When these are called, we have already applied any saveLayer operations,
138 and are handling any looping from the paint, and any effects from the
139 DrawFilter.
140 */
141 virtual void drawPaint(const SkDraw&, const SkPaint& paint) = 0;
142 virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count,
143 const SkPoint[], const SkPaint& paint) = 0;
144 virtual void drawRect(const SkDraw&, const SkRect& r,
145 const SkPaint& paint) = 0;
146 virtual void drawRegion(const SkDraw&, const SkRegion& r,
147 const SkPaint& paint);
148 virtual void drawOval(const SkDraw&, const SkRect& oval,
149 const SkPaint& paint) = 0;
150 /** By the time this is called we know that abs(sweepAngle) is in the range [0, 360). */
151 virtual void drawArc(const SkDraw&, const SkRect& oval, SkScalar startAngle,
152 SkScalar sweepAngle, bool useCenter, const SkPaint& paint);
153 virtual void drawRRect(const SkDraw&, const SkRRect& rr,
154 const SkPaint& paint) = 0;
155
156 // Default impl calls drawPath()
157 virtual void drawDRRect(const SkDraw&, const SkRRect& outer,
158 const SkRRect& inner, const SkPaint&);
159
160 /**
161 * If pathIsMutable, then the implementation is allowed to cast path to a
162 * non-const pointer and modify it in place (as an optimization). Canvas
163 * may do this to implement helpers such as drawOval, by placing a temp
164 * path on the stack to hold the representation of the oval.
165 *
166 * If prePathMatrix is not null, it should logically be applied before any
167 * stroking or other effects. If there are no effects on the paint that
168 * affect the geometry/rasterization, then the pre matrix can just be
169 * pre-concated with the current matrix.
170 */
171 virtual void drawPath(const SkDraw&, const SkPath& path,
172 const SkPaint& paint,
173 const SkMatrix* prePathMatrix = NULL,
174 bool pathIsMutable = false) = 0;
175 virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
176 const SkMatrix& matrix, const SkPaint& paint) = 0;
177 virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
178 int x, int y, const SkPaint& paint) = 0;
179
180 /**
181 * The default impl. will create a bitmap-shader from the bitmap,
182 * and call drawRect with it.
183 */
184 virtual void drawBitmapRect(const SkDraw&, const SkBitmap&,
185 const SkRect* srcOrNull, const SkRect& dst,
186 const SkPaint& paint,
187 SkCanvas::SrcRectConstraint) = 0;
188 virtual void drawBitmapNine(const SkDraw&, const SkBitmap&, const SkIRect& center,
189 const SkRect& dst, const SkPaint&);
190 virtual void drawBitmapLattice(const SkDraw&, const SkBitmap&, const SkCanvas::Lattice&,
191 const SkRect& dst, const SkPaint&);
192
193 virtual void drawImage(const SkDraw&, const SkImage*, SkScalar x, SkScalar y, const SkPaint&);
194 virtual void drawImageRect(const SkDraw&, const SkImage*, const SkRect* src, const SkRect& dst,
195 const SkPaint&, SkCanvas::SrcRectConstraint);
196 virtual void drawImageNine(const SkDraw&, const SkImage*, const SkIRect& center,
197 const SkRect& dst, const SkPaint&);
198 virtual void drawImageLattice(const SkDraw&, const SkImage*, const SkCanvas::Lattice&,
199 const SkRect& dst, const SkPaint&);
200
201 /**
202 * Does not handle text decoration.
203 * Decorations (underline and stike-thru) will be handled by SkCanvas.
204 */
205 virtual void drawText(const SkDraw&, const void* text, size_t len,
206 SkScalar x, SkScalar y, const SkPaint& paint) = 0;
207 virtual void drawPosText(const SkDraw&, const void* text, size_t len,
208 const SkScalar pos[], int scalarsPerPos,
209 const SkPoint& offset, const SkPaint& paint) = 0;
210 virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount,
211 const SkPoint verts[], const SkPoint texs[],
212 const SkColor colors[], SkBlendMode,
213 const uint16_t indices[], int indexCount,
214 const SkPaint& paint) = 0;
215 // default implementation unrolls the blob runs.
216 virtual void drawTextBlob(const SkDraw&, const SkTextBlob*, SkScalar x, SkScalar y,
217 const SkPaint& paint, SkDrawFilter* drawFilter);
218 // default implementation calls drawVertices
219 virtual void drawPatch(const SkDraw&, const SkPoint cubics[12], const SkColor colors[4],
220 const SkPoint texCoords[4], SkBlendMode, const SkPaint& paint);
221
222 // default implementation calls drawPath
223 virtual void drawAtlas(const SkDraw&, const SkImage* atlas, const SkRSXform[], const SkRect[],
224 const SkColor[], int count, SkBlendMode, const SkPaint&);
225
226 virtual void drawAnnotation(const SkDraw&, const SkRect&, const char[], SkData*) {}
227
228 /** The SkDevice passed will be an SkDevice which was returned by a call to
229 onCreateDevice on this device with kNeverTile_TileExpectation.
230 */
231 virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y,
232 const SkPaint&) = 0;
233
234 virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len, const SkPath&,
235 const SkMatrix*, const SkPaint&);
236 virtual void drawTextRSXform(const SkDraw&, const void* text, size_t len, const SkRSXform[],
237 const SkPaint&);
238
239 virtual void drawSpecial(const SkDraw&, SkSpecialImage*, int x, int y, const SkPaint&);
240 virtual sk_sp<SkSpecialImage> makeSpecial(const SkBitmap&);
241 virtual sk_sp<SkSpecialImage> makeSpecial(const SkImage*);
242 virtual sk_sp<SkSpecialImage> snapSpecial();
243
244 bool readPixels(const SkImageInfo&, void* dst, size_t rowBytes, int x, int y);
245
246 ///////////////////////////////////////////////////////////////////////////
247
248#ifdef SK_SUPPORT_LEGACY_ACCESSBITMAP
249 /** Update as needed the pixel value in the bitmap, so that the caller can
250 access the pixels directly.
251 @return The device contents as a bitmap
252 */
253 virtual const SkBitmap& onAccessBitmap() {
254 SkASSERT(0);
255 return fLegacyBitmap;
256 }
257#endif
258
259 virtual GrContext* context() const { return nullptr; }
260
261 virtual sk_sp<SkSurface> makeSurface(const SkImageInfo&, const SkSurfaceProps&);
262 virtual bool onPeekPixels(SkPixmap*) { return false; }
263
264 /**
265 * The caller is responsible for "pre-clipping" the dst. The impl can assume that the dst
266 * image at the specified x,y offset will fit within the device's bounds.
267 *
268 * This is explicitly asserted in readPixels(), the public way to call this.
269 */
270 virtual bool onReadPixels(const SkImageInfo&, void*, size_t, int x, int y);
271
272 /**
273 * The caller is responsible for "pre-clipping" the src. The impl can assume that the src
274 * image at the specified x,y offset will fit within the device's bounds.
275 *
276 * This is explicitly asserted in writePixelsDirect(), the public way to call this.
277 */
278 virtual bool onWritePixels(const SkImageInfo&, const void*, size_t, int x, int y);
279
280 virtual bool onAccessPixels(SkPixmap*) { return false; }
281
282 struct CreateInfo {
283 static SkPixelGeometry AdjustGeometry(const SkImageInfo&, TileUsage, SkPixelGeometry,
284 bool preserveLCDText);
285
286 // The constructor may change the pixel geometry based on other parameters.
287 CreateInfo(const SkImageInfo& info,
288 TileUsage tileUsage,
289 SkPixelGeometry geo)
290 : fInfo(info)
291 , fTileUsage(tileUsage)
292 , fPixelGeometry(AdjustGeometry(info, tileUsage, geo, false))
293 {}
294
295 CreateInfo(const SkImageInfo& info,
296 TileUsage tileUsage,
297 SkPixelGeometry geo,
298 bool preserveLCDText,
299 SkRasterHandleAllocator* allocator)
300 : fInfo(info)
301 , fTileUsage(tileUsage)
302 , fPixelGeometry(AdjustGeometry(info, tileUsage, geo, preserveLCDText))
303 , fAllocator(allocator)
304 {}
305
306 const SkImageInfo fInfo;
307 const TileUsage fTileUsage;
308 const SkPixelGeometry fPixelGeometry;
309 SkRasterHandleAllocator* fAllocator = nullptr;
310 };
311
312 /**
313 * Create a new device based on CreateInfo. If the paint is not null, then it represents a
314 * preview of how the new device will be composed with its creator device (this).
315 *
316 * The subclass may be handed this device in drawDevice(), so it must always return
317 * a device that it knows how to draw, and that it knows how to identify if it is not of the
318 * same subclass (since drawDevice is passed a SkBaseDevice*). If the subclass cannot fulfill
319 * that contract (e.g. PDF cannot support some settings on the paint) it should return NULL,
320 * and the caller may then decide to explicitly create a bitmapdevice, knowing that later
321 * it could not call drawDevice with it (but it could call drawSprite or drawBitmap).
322 */
323 virtual SkBaseDevice* onCreateDevice(const CreateInfo&, const SkPaint*) {
324 return NULL;
325 }
326
327 // A helper function used by derived classes to log the scale factor of a bitmap or image draw.
328 static void LogDrawScaleFactor(const SkMatrix&, SkFilterQuality);
329
330private:
331 friend class SkCanvas;
332 friend struct DeviceCM; //for setMatrixClip
333 friend class SkDraw;
334 friend class SkDrawIter;
335 friend class SkDeviceFilteredPaint;
336 friend class SkNoPixelsBitmapDevice;
337 friend class SkSurface_Raster;
338 friend class DeviceTestingAccess;
339
340 // used to change the backend's pixels (and possibly config/rowbytes)
341 // but cannot change the width/height, so there should be no change to
342 // any clip information.
343 // TODO: move to SkBitmapDevice
344 virtual void replaceBitmapBackendForRasterSurface(const SkBitmap&) {}
345
346 virtual bool forceConservativeRasterClip() const { return false; }
347
348 /**
349 * Don't call this!
350 */
351 virtual GrRenderTargetContext* accessRenderTargetContext() { return nullptr; }
352
353 // just called by SkCanvas when built as a layer
354 void setOrigin(int x, int y) { fOrigin.set(x, y); }
355
356 /** Causes any deferred drawing to the device to be completed.
357 */
358 virtual void flush() {}
359
360 virtual SkImageFilterCache* getImageFilterCache() { return NULL; }
361
362 friend class SkBitmapDevice;
363 void privateResize(int w, int h) {
364 *const_cast<SkImageInfo*>(&fInfo) = fInfo.makeWH(w, h);
365 }
366
367 bool drawExternallyScaledImage(const SkDraw& draw, const SkImage* image, const SkRect* src,
368 const SkRect& dst, const SkPaint& paint,
369 SkCanvas::SrcRectConstraint constraint);
370
371 SkIPoint fOrigin;
372 SkMetaData* fMetaData;
373 const SkImageInfo fInfo;
374 const SkSurfaceProps fSurfaceProps;
375
376#ifdef SK_SUPPORT_LEGACY_ACCESSBITMAP
377 SkBitmap fLegacyBitmap;
378#endif
379
380 typedef SkRefCnt INHERITED;
381};
reed@android.com8a1c16f2008-12-17 15:59:43 +0000382
reed@android.com8a1c16f2008-12-17 15:59:43 +0000383#endif