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