18a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2010 The Android Open Source Project
38a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
68a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */
78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifndef SkDevice_DEFINED
98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkDevice_DEFINED
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkRefCnt.h"
128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkBitmap.h"
138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCanvas.h"
148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColor.h"
15532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com#include "SkDeviceProperties.h"
164cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org#include "SkImageFilter.h"
178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1846799cd9f0bded51a189d77731b25af159ab4609reed@google.comclass SkClipStack;
198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkDraw;
208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstruct SkIRect;
218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkMatrix;
22a7d948523dce6044fc02db90726e5f971a93628breed@google.comclass SkMetaData;
238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkRegion;
248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
25b8d00db075b5ea09e353508a26ef5ced50722a6ccommit-bot@chromium.orgclass GrRenderTarget;
26d9f826c0dbc38f3608797a02948adf9bc99d5d50bsalomon@google.com
271f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comclass SK_API SkBaseDevice : public SkRefCnt {
288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
291f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com    SK_DECLARE_INST_COUNT(SkBaseDevice)
3015e9d3e66e161ce23df30bc13f8a0c87d196b463robertphillips@google.com
31af951c9bc4cbb6e60b430194fe5127ebe99c53fbreed@google.com    /**
321f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com     *  Construct a new device.
338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
341f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com    SkBaseDevice();
35af951c9bc4cbb6e60b430194fe5127ebe99c53fbreed@google.com
36af951c9bc4cbb6e60b430194fe5127ebe99c53fbreed@google.com    /**
371f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com     *  Construct a new device.
38532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com    */
391f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com    SkBaseDevice(const SkDeviceProperties& deviceProperties);
409b051a375ba6d6b61cea98f35834cd032aaa5347robertphillips@google.com
411f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com    virtual ~SkBaseDevice();
428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4315a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    SkBaseDevice* createCompatibleDevice(const SkImageInfo&);
44e97f0856a8044866b12527819d14cdfbcdfd96f2bsalomon@google.com
4588edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com    SkMetaData& getMetaData();
4688edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com
47532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com    /** Return the image properties of the device. */
48532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com    virtual const SkDeviceProperties& getDeviceProperties() const {
49532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com        //Currently, all the properties are leaky.
50532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com        return fLeakyProperties;
51532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com    }
52532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com
53d51bfa0583c82c7b731b993e56159fbf815dd2e0reed@google.com    /**
54c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org     *  Return ImageInfo for this device. If the canvas is not backed by pixels
55c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org     *  (cpu or gpu), then the info's ColorType will be kUnknown_SkColorType.
56c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org     */
57c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org    virtual SkImageInfo imageInfo() const;
58c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org
59c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org    /**
60d51bfa0583c82c7b731b993e56159fbf815dd2e0reed@google.com     *  Return the bounds of the device in the coordinate space of the root
61d51bfa0583c82c7b731b993e56159fbf815dd2e0reed@google.com     *  canvas. The root device will have its top-left at 0,0, but other devices
62d51bfa0583c82c7b731b993e56159fbf815dd2e0reed@google.com     *  such as those associated with saveLayer may have a non-zero origin.
63d51bfa0583c82c7b731b993e56159fbf815dd2e0reed@google.com     */
64ec3ca87d331c4b7058a0fff376a05e84ae0619careed@google.com    void getGlobalBounds(SkIRect* bounds) const {
65ec3ca87d331c4b7058a0fff376a05e84ae0619careed@google.com        SkASSERT(bounds);
66ec3ca87d331c4b7058a0fff376a05e84ae0619careed@google.com        const SkIPoint& origin = this->getOrigin();
67ec3ca87d331c4b7058a0fff376a05e84ae0619careed@google.com        bounds->setXYWH(origin.x(), origin.y(), this->width(), this->height());
68ec3ca87d331c4b7058a0fff376a05e84ae0619careed@google.com    }
6973a5d53d96cb7a0b4214e273ed147d401e31ea16skia.committer@gmail.com
70f252f64f17efddf7235682a96d155d7c86c898e3reed#ifdef SK_SUPPORT_LEGACY_DEVICE_VIRTUAL_ISOPAQUE
71f252f64f17efddf7235682a96d155d7c86c898e3reed    virtual int width() const {
72f252f64f17efddf7235682a96d155d7c86c898e3reed        return this->imageInfo().width();
73f252f64f17efddf7235682a96d155d7c86c898e3reed    }
74f252f64f17efddf7235682a96d155d7c86c898e3reed    virtual int height() const {
75f252f64f17efddf7235682a96d155d7c86c898e3reed        return this->imageInfo().height();
76f252f64f17efddf7235682a96d155d7c86c898e3reed    }
77f252f64f17efddf7235682a96d155d7c86c898e3reed    virtual bool isOpaque() const {
78f252f64f17efddf7235682a96d155d7c86c898e3reed        return this->imageInfo().isOpaque();
79f252f64f17efddf7235682a96d155d7c86c898e3reed    }
80f252f64f17efddf7235682a96d155d7c86c898e3reed#else
81f252f64f17efddf7235682a96d155d7c86c898e3reed    int width() const {
82f252f64f17efddf7235682a96d155d7c86c898e3reed        return this->imageInfo().width();
83f252f64f17efddf7235682a96d155d7c86c898e3reed    }
84f252f64f17efddf7235682a96d155d7c86c898e3reed    int height() const {
85f252f64f17efddf7235682a96d155d7c86c898e3reed        return this->imageInfo().height();
86f252f64f17efddf7235682a96d155d7c86c898e3reed    }
87f252f64f17efddf7235682a96d155d7c86c898e3reed    bool isOpaque() const {
88f252f64f17efddf7235682a96d155d7c86c898e3reed        return this->imageInfo().isOpaque();
89f252f64f17efddf7235682a96d155d7c86c898e3reed    }
90f252f64f17efddf7235682a96d155d7c86c898e3reed#endif
91772c4e6d09f5e0971a584d2035ee789483d6f47askia.committer@gmail.com
928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Return the bitmap associated with this device. Call this each time you need
938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        to access the bitmap, as it notifies the subclass to perform any flushing
948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        etc. before you examine the pixels.
958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param changePixels set to true if the caller plans to change the pixels
968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @return the device's bitmap
978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const SkBitmap& accessBitmap(bool changePixels);
998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1004ef54f8d72420a521d4aae04ff5cd438810eca7fcommit-bot@chromium.org    bool writePixels(const SkImageInfo&, const void*, size_t rowBytes, int x, int y);
1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1029c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com    void* accessPixels(SkImageInfo* info, size_t* rowBytes);
1039c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com
104d9f826c0dbc38f3608797a02948adf9bc99d5d50bsalomon@google.com    /**
105d9f826c0dbc38f3608797a02948adf9bc99d5d50bsalomon@google.com     * Return the device's associated gpu render target, or NULL.
106f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com     */
1071f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com    virtual GrRenderTarget* accessRenderTarget() = 0;
108f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
10988edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com
11088edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com    /**
11188edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com     *  Return the device's origin: its offset in device coordinates from
11288edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com     *  the default origin in its canvas' matrix/clip
11388edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com     */
11488edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com    const SkIPoint& getOrigin() const { return fOrigin; }
11588edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com
116fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com    /**
11740a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com     * onAttachToCanvas is invoked whenever a device is installed in a canvas
11840a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com     * (i.e., setDevice, saveLayer (for the new device created by the save),
1191f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com     * and SkCanvas' SkBaseDevice & SkBitmap -taking ctors). It allows the
12040a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com     * devices to prepare for drawing (e.g., locking their pixels, etc.)
12140a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com     */
122e0e385c1d4171e065348ba17c546b3463a0bd651sugoi@google.com    virtual void onAttachToCanvas(SkCanvas*) {
123405d0f43d8fa03874aee23669e5fdb38f21cc3e7bsalomon@google.com        SkASSERT(!fAttachedToCanvas);
12440a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com        this->lockPixels();
12540a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com#ifdef SK_DEBUG
12640a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com        fAttachedToCanvas = true;
12740a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com#endif
12840a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com    };
12940a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com
13040a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com    /**
13140a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com     * onDetachFromCanvas notifies a device that it will no longer be drawn to.
13240a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com     * It gives the device a chance to clean up (e.g., unlock its pixels). It
133fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com     * is invoked from setDevice (for the displaced device), restore and
13440a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com     * possibly from SkCanvas' dtor.
13540a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com     */
13640a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com    virtual void onDetachFromCanvas() {
137405d0f43d8fa03874aee23669e5fdb38f21cc3e7bsalomon@google.com        SkASSERT(fAttachedToCanvas);
13840a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com        this->unlockPixels();
13940a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com#ifdef SK_DEBUG
14040a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com        fAttachedToCanvas = false;
14140a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com#endif
14240a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com    };
14340a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com
144d53f7c28bf8aecd5b7f0ee2189ac97e309a1b06dcaryclark@google.comprotected:
145d53f7c28bf8aecd5b7f0ee2189ac97e309a1b06dcaryclark@google.com    enum Usage {
146d53f7c28bf8aecd5b7f0ee2189ac97e309a1b06dcaryclark@google.com       kGeneral_Usage,
1471f90287df3129cb267422e482c52ebeca6a8990ftomhudson@google.com       kSaveLayer_Usage  // <! internal use only
148d53f7c28bf8aecd5b7f0ee2189ac97e309a1b06dcaryclark@google.com    };
149d53f7c28bf8aecd5b7f0ee2189ac97e309a1b06dcaryclark@google.com
15088edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com    struct TextFlags {
15188edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com        uint32_t            fFlags;     // SkPaint::getFlags()
15288edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com        SkPaint::Hinting    fHinting;
15388edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com    };
15488edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com
15588edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com    /**
15688edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com     *  Device may filter the text flags for drawing text here. If it wants to
15788edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com     *  make a change to the specified values, it should write them into the
15888edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com     *  textflags parameter (output) and return true. If the paint is fine as
15988edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com     *  is, then ignore the textflags parameter and return false.
16088edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com     *
1611f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com     *  The baseclass SkBaseDevice filters based on its depth and blitters.
16288edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com     */
1631f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com    virtual bool filterTextFlags(const SkPaint& paint, TextFlags*) = 0;
16488edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com
1653fffb2ee9fa01ae61efb2395973eb7575eda4c96robertphillips@google.com    /**
166a6926b1f0352916c31cda66f2239a25d52f09315bsalomon@google.com     *
167a6926b1f0352916c31cda66f2239a25d52f09315bsalomon@google.com     *  DEPRECATED: This will be removed in a future change. Device subclasses
168a6926b1f0352916c31cda66f2239a25d52f09315bsalomon@google.com     *  should use the matrix and clip from the SkDraw passed to draw functions.
169a6926b1f0352916c31cda66f2239a25d52f09315bsalomon@google.com     *
1703fffb2ee9fa01ae61efb2395973eb7575eda4c96robertphillips@google.com     *  Called with the correct matrix and clip before this device is drawn
1713fffb2ee9fa01ae61efb2395973eb7575eda4c96robertphillips@google.com     *  to using those settings. If your subclass overrides this, be sure to
1723fffb2ee9fa01ae61efb2395973eb7575eda4c96robertphillips@google.com     *  call through to the base class as well.
1733fffb2ee9fa01ae61efb2395973eb7575eda4c96robertphillips@google.com     *
1743fffb2ee9fa01ae61efb2395973eb7575eda4c96robertphillips@google.com     *  The clipstack is another view of the clip. It records the actual
1753fffb2ee9fa01ae61efb2395973eb7575eda4c96robertphillips@google.com     *  geometry that went into building the region. It is present for devices
1763fffb2ee9fa01ae61efb2395973eb7575eda4c96robertphillips@google.com     *  that want to parse it, but is not required: the region is a complete
1773fffb2ee9fa01ae61efb2395973eb7575eda4c96robertphillips@google.com     *  picture of the current clip. (i.e. if you regionize all of the geometry
1783fffb2ee9fa01ae61efb2395973eb7575eda4c96robertphillips@google.com     *  in the clipstack, you will arrive at an equivalent region to the one
1793fffb2ee9fa01ae61efb2395973eb7575eda4c96robertphillips@google.com     *  passed in).
180a6926b1f0352916c31cda66f2239a25d52f09315bsalomon@google.com     */
181a6926b1f0352916c31cda66f2239a25d52f09315bsalomon@google.com     virtual void setMatrixClip(const SkMatrix&, const SkRegion&,
1821f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com                                const SkClipStack&) {};
1833fffb2ee9fa01ae61efb2395973eb7575eda4c96robertphillips@google.com
18488edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com    /** Clears the entire device to the specified color (including alpha).
18588edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com     *  Ignores the clip.
186f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com     */
1871f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com    virtual void clear(SkColor color) = 0;
188f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
18962f1048ada9312f48fc62f8de4f91a0a8f8f6047tfarina@chromium.org    SK_ATTR_DEPRECATED("use clear() instead")
19088edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com    void eraseColor(SkColor eraseColor) { this->clear(eraseColor); }
1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** These are called inside the per-device-layer loop for each draw call.
1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     When these are called, we have already applied any saveLayer operations,
1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     and are handling any looping from the paint, and any effects from the
1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     DrawFilter.
1968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     */
1971f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com    virtual void drawPaint(const SkDraw&, const SkPaint& paint) = 0;
1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count,
1991f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com                            const SkPoint[], const SkPaint& paint) = 0;
2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual void drawRect(const SkDraw&, const SkRect& r,
2011f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com                          const SkPaint& paint) = 0;
20246d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com    virtual void drawOval(const SkDraw&, const SkRect& oval,
2031f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com                          const SkPaint& paint) = 0;
204f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org    virtual void drawRRect(const SkDraw&, const SkRRect& rr,
2051f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com                           const SkPaint& paint) = 0;
206f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org
207ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org    // Default impl calls drawPath()
208ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org    virtual void drawDRRect(const SkDraw&, const SkRRect& outer,
209ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org                            const SkRRect& inner, const SkPaint&);
210ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org
2117ff8d81290c3d9d461f2e304f4fd7846275f956dreed@google.com    /**
2127ff8d81290c3d9d461f2e304f4fd7846275f956dreed@google.com     *  If pathIsMutable, then the implementation is allowed to cast path to a
2137ff8d81290c3d9d461f2e304f4fd7846275f956dreed@google.com     *  non-const pointer and modify it in place (as an optimization). Canvas
2147ff8d81290c3d9d461f2e304f4fd7846275f956dreed@google.com     *  may do this to implement helpers such as drawOval, by placing a temp
2157ff8d81290c3d9d461f2e304f4fd7846275f956dreed@google.com     *  path on the stack to hold the representation of the oval.
2167ff8d81290c3d9d461f2e304f4fd7846275f956dreed@google.com     *
2177ff8d81290c3d9d461f2e304f4fd7846275f956dreed@google.com     *  If prePathMatrix is not null, it should logically be applied before any
2187ff8d81290c3d9d461f2e304f4fd7846275f956dreed@google.com     *  stroking or other effects. If there are no effects on the paint that
2197ff8d81290c3d9d461f2e304f4fd7846275f956dreed@google.com     *  affect the geometry/rasterization, then the pre matrix can just be
2207ff8d81290c3d9d461f2e304f4fd7846275f956dreed@google.com     *  pre-concated with the current matrix.
2217ff8d81290c3d9d461f2e304f4fd7846275f956dreed@google.com     */
2228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual void drawPath(const SkDraw&, const SkPath& path,
223f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com                          const SkPaint& paint,
224f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com                          const SkMatrix* prePathMatrix = NULL,
2251f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com                          bool pathIsMutable = false) = 0;
2268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
2271f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com                            const SkMatrix& matrix, const SkPaint& paint) = 0;
2288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
2291f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com                            int x, int y, const SkPaint& paint) = 0;
23033535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com
23133535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com    /**
23233535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com     *  The default impl. will create a bitmap-shader from the bitmap,
23333535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com     *  and call drawRect with it.
23433535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com     */
23533535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com    virtual void drawBitmapRect(const SkDraw&, const SkBitmap&,
23633535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com                                const SkRect* srcOrNull, const SkRect& dst,
237eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org                                const SkPaint& paint,
2381f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com                                SkCanvas::DrawBitmapRectFlags flags) = 0;
23933535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com
24052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com    /**
24152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com     *  Does not handle text decoration.
24252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com     *  Decorations (underline and stike-thru) will be handled by SkCanvas.
24352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com     */
2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual void drawText(const SkDraw&, const void* text, size_t len,
2451f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com                          SkScalar x, SkScalar y, const SkPaint& paint) = 0;
2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual void drawPosText(const SkDraw&, const void* text, size_t len,
2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                             const SkScalar pos[], SkScalar constY,
2481f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com                             int scalarsPerPos, const SkPaint& paint) = 0;
2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                const SkPath& path, const SkMatrix* matrix,
2511f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com                                const SkPaint& paint) = 0;
2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount,
2538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                              const SkPoint verts[], const SkPoint texs[],
2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                              const SkColor colors[], SkXfermode* xmode,
2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                              const uint16_t indices[], int indexCount,
2561f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com                              const SkPaint& paint) = 0;
2579b051a375ba6d6b61cea98f35834cd032aaa5347robertphillips@google.com    /** The SkDevice passed will be an SkDevice which was returned by a call to
25815a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        onCreateDevice on this device with kSaveLayer_Usage.
25988edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com     */
2601f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com    virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y,
2611f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com                            const SkPaint&) = 0;
2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
263a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org    bool readPixels(const SkImageInfo&, void* dst, size_t rowBytes, int x, int y);
2646850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com
2653636ed558fb2af5a48a9634efec55fd8a87c88d7reed@google.com    ///////////////////////////////////////////////////////////////////////////
2663636ed558fb2af5a48a9634efec55fd8a87c88d7reed@google.com
2671f9767c03bad1ef85e5388d84e23e4b5dff4bc1ajunov@chromium.org    /** Update as needed the pixel value in the bitmap, so that the caller can
268772c4e6d09f5e0971a584d2035ee789483d6f47askia.committer@gmail.com        access the pixels directly.
2691f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com        @return The device contents as a bitmap
2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
2711f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com    virtual const SkBitmap& onAccessBitmap() = 0;
27274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org
27307f81a57ba5720fd65563077114bd9e5ba840151robertphillips@google.com    /** Called when this device is installed into a Canvas. Balanced by a call
27488edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com        to unlockPixels() when the device is removed from a Canvas.
27588edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com    */
2761f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com    virtual void lockPixels() = 0;
2771f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com    virtual void unlockPixels() = 0;
27888edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com
27976dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com    /**
280b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com     *  Returns true if the device allows processing of this imagefilter. If
281b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com     *  false is returned, then the filter is ignored. This may happen for
282b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com     *  some subclasses that do not support pixel manipulations after drawing
283b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com     *  has occurred (e.g. printing). The default implementation returns true.
284b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com     */
285ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org    virtual bool allowImageFilter(const SkImageFilter*) = 0;
286b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com
287b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com    /**
2888926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com     *  Override and return true for filters that the device can handle
2898926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com     *  intrinsically. Doing so means that SkCanvas will pass-through this
2908926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com     *  filter to drawSprite and drawDevice (and potentially filterImage).
2918926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com     *  Returning false means the SkCanvas will have apply the filter itself,
2928926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com     *  and just pass the resulting image to the device.
29376dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com     */
294ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org    virtual bool canHandleImageFilter(const SkImageFilter*) = 0;
2958926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com
2968926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com    /**
2978926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com     *  Related (but not required) to canHandleImageFilter, this method returns
2988926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com     *  true if the device could apply the filter to the src bitmap and return
2998926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com     *  the result (and updates offset as needed).
3008926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com     *  If the device does not recognize or support this filter,
3018926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com     *  it just returns false and leaves result and offset unchanged.
3028926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com     */
3034cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org    virtual bool filterImage(const SkImageFilter*, const SkBitmap&,
3044cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org                             const SkImageFilter::Context& ctx,
3051f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com                             SkBitmap* result, SkIPoint* offset) = 0;
30676dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com
3078128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.orgprotected:
30876f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com    // default impl returns NULL
30976f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com    virtual SkSurface* newSurface(const SkImageInfo&);
31002d6f546161e2c98d69066373cec3f54f3c46252skia.committer@gmail.com
311c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org    // default impl returns NULL
312c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org    virtual const void* peekPixels(SkImageInfo*, size_t* rowBytes);
31302d6f546161e2c98d69066373cec3f54f3c46252skia.committer@gmail.com
3148128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org    /**
315a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org     *  The caller is responsible for "pre-clipping" the dst. The impl can assume that the dst
316a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org     *  image at the specified x,y offset will fit within the device's bounds.
317a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org     *
318a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org     *  This is explicitly asserted in readPixels(), the public way to call this.
319a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org     */
320a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org    virtual bool onReadPixels(const SkImageInfo&, void*, size_t, int x, int y);
3212cccf833265a607be62f1d77ee51662b49d9e813commit-bot@chromium.org
3222cccf833265a607be62f1d77ee51662b49d9e813commit-bot@chromium.org    /**
3234cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org     *  The caller is responsible for "pre-clipping" the src. The impl can assume that the src
3244cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org     *  image at the specified x,y offset will fit within the device's bounds.
3254cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org     *
3264cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org     *  This is explicitly asserted in writePixelsDirect(), the public way to call this.
3274cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org     */
3284cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org    virtual bool onWritePixels(const SkImageInfo&, const void*, size_t, int x, int y);
3294cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org
3304cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org    /**
3319c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com     *  Default impl returns NULL.
3329c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com     */
3339c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com    virtual void* onAccessPixels(SkImageInfo* info, size_t* rowBytes);
3349c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com
3359c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com    /**
3368128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org     *  Leaky properties are those which the device should be applying but it isn't.
3378128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org     *  These properties will be applied by the draw, when and as it can.
3388128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org     *  If the device does handle a property, that property should be set to the identity value
3398128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org     *  for that property, effectively making it non-leaky.
3408128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org     */
3418128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org    SkDeviceProperties fLeakyProperties;
3428128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org
343145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org    /**
344145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org     *  PRIVATE / EXPERIMENTAL -- do not call
345145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org     *  Construct an acceleration object and attach it to 'picture'
346145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org     */
3479b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips    virtual void EXPERIMENTAL_optimize(const SkPicture* picture);
348145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org
349145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org    /**
350145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org     *  PRIVATE / EXPERIMENTAL -- do not call
351c873329ae9ff00b0c45f7294172ad2e9b1ec44c8commit-bot@chromium.org     *  Purge all discardable optimization information for 'picture'. If
352c873329ae9ff00b0c45f7294172ad2e9b1ec44c8commit-bot@chromium.org     *  picture is NULL then purge discardable information for all pictures.
353c873329ae9ff00b0c45f7294172ad2e9b1ec44c8commit-bot@chromium.org     */
3549b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips    virtual void EXPERIMENTAL_purge(const SkPicture* picture);
355c873329ae9ff00b0c45f7294172ad2e9b1ec44c8commit-bot@chromium.org
356c873329ae9ff00b0c45f7294172ad2e9b1ec44c8commit-bot@chromium.org    /**
357c873329ae9ff00b0c45f7294172ad2e9b1ec44c8commit-bot@chromium.org     *  PRIVATE / EXPERIMENTAL -- do not call
358145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org     *  This entry point gives the backend an opportunity to take over the rendering
359145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org     *  of 'picture'. If optimization data is available (due to an earlier
360145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org     *  'optimize' call) this entry point should make use of it and return true
361145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org     *  if all rendering has been done. If false is returned, SkCanvas will
362eb849e5fd10cbe00cbc31307ba97fd9efca0b41bskia.committer@gmail.com     *  perform its own rendering pass. It is acceptable for the backend
363145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org     *  to perform some device-specific warm up tasks and then let SkCanvas
364145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org     *  perform the main rendering loop (by return false from here).
365145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org     */
3669b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips    virtual bool EXPERIMENTAL_drawPicture(SkCanvas* canvas, const SkPicture* picture);
367145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org
3688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate:
3696f8f292aa768869a9e85c314b124875f57504f2creed@google.com    friend class SkCanvas;
3703fffb2ee9fa01ae61efb2395973eb7575eda4c96robertphillips@google.com    friend struct DeviceCM; //for setMatrixClip
37188edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com    friend class SkDraw;
37288edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com    friend class SkDrawIter;
37388edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com    friend class SkDeviceFilteredPaint;
3749c39744a00573b7133fc765b0a9d50a0ceace7b8senorblanco@chromium.org    friend class SkDeviceImageFilterProxy;
3759c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com    friend class SkDeferredDevice;    // for newSurface
37688edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com
37797af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com    friend class SkSurface_Raster;
3781f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com
37997af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com    // used to change the backend's pixels (and possibly config/rowbytes)
38097af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com    // but cannot change the width/height, so there should be no change to
38197af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com    // any clip information.
382ec3ca87d331c4b7058a0fff376a05e84ae0619careed@google.com    // TODO: move to SkBitmapDevice
3831f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com    virtual void replaceBitmapBackendForRasterSurface(const SkBitmap&) = 0;
38497af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com
3855676b4a23a190b9a0e2f4d803fe17dbfa47caf7evandebo@chromium.org    // just called by SkCanvas when built as a layer
3865676b4a23a190b9a0e2f4d803fe17dbfa47caf7evandebo@chromium.org    void setOrigin(int x, int y) { fOrigin.set(x, y); }
387e97f0856a8044866b12527819d14cdfbcdfd96f2bsalomon@google.com    // just called by SkCanvas for saveLayer
38815a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    SkBaseDevice* createCompatibleDeviceForSaveLayer(const SkImageInfo&);
3896f8f292aa768869a9e85c314b124875f57504f2creed@google.com
39015a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    virtual SkBaseDevice* onCreateDevice(const SkImageInfo&, Usage) {
39115a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        return NULL;
39215a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    }
39388edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com
39488edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com    /** Causes any deferred drawing to the device to be completed.
39588edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com     */
3961f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com    virtual void flush() = 0;
39788edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com
3986f8f292aa768869a9e85c314b124875f57504f2creed@google.com    SkIPoint    fOrigin;
399a7d948523dce6044fc02db90726e5f971a93628breed@google.com    SkMetaData* fMetaData;
40015e9d3e66e161ce23df30bc13f8a0c87d196b463robertphillips@google.com
40140a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com#ifdef SK_DEBUG
40240a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com    bool        fAttachedToCanvas;
40340a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com#endif
40440a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com
40515e9d3e66e161ce23df30bc13f8a0c87d196b463robertphillips@google.com    typedef SkRefCnt INHERITED;
4068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
4078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
409