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