skia.committer@gmail.com | 3e50e99 | 2013-05-21 07:01:40 +0000 | [diff] [blame] | 1 | |
bsalomon@google.com | dfe75bc | 2011-03-25 12:31:16 +0000 | [diff] [blame] | 2 | /* |
epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame] | 3 | * Copyright 2011 Google Inc. |
| 4 | * |
| 5 | * Use of this source code is governed by a BSD-style license that can be |
| 6 | * found in the LICENSE file. |
bsalomon@google.com | dfe75bc | 2011-03-25 12:31:16 +0000 | [diff] [blame] | 7 | */ |
| 8 | |
| 9 | #ifndef GrPathRenderer_DEFINED |
| 10 | #define GrPathRenderer_DEFINED |
| 11 | |
| 12 | #include "GrDrawTarget.h" |
bsalomon@google.com | 45a15f5 | 2012-12-10 19:10:17 +0000 | [diff] [blame] | 13 | #include "GrStencil.h" |
kkinnunen | 1899651 | 2015-04-26 23:18:49 -0700 | [diff] [blame] | 14 | #include "GrStrokeInfo.h" |
bsalomon@google.com | dfe75bc | 2011-03-25 12:31:16 +0000 | [diff] [blame] | 15 | |
commit-bot@chromium.org | e0a868c | 2013-11-22 07:02:11 +0000 | [diff] [blame] | 16 | #include "SkDrawProcs.h" |
bsalomon@google.com | 49313f6 | 2011-09-14 13:54:05 +0000 | [diff] [blame] | 17 | #include "SkTArray.h" |
| 18 | |
reed@google.com | 07f3ee1 | 2011-05-16 17:21:57 +0000 | [diff] [blame] | 19 | class SkPath; |
bsalomon@google.com | 3008519 | 2011-08-19 15:42:31 +0000 | [diff] [blame] | 20 | |
bsalomon@google.com | dfe75bc | 2011-03-25 12:31:16 +0000 | [diff] [blame] | 21 | struct GrPoint; |
| 22 | |
| 23 | /** |
| 24 | * Base class for drawing paths into a GrDrawTarget. |
robertphillips@google.com | bf5cad4 | 2012-05-10 12:40:40 +0000 | [diff] [blame] | 25 | * |
egdaniel | 8dd688b | 2015-01-22 10:16:09 -0800 | [diff] [blame] | 26 | * Derived classes can use stages GrPaint::kTotalStages through GrPipelineBuilder::kNumStages-1. |
| 27 | * The stages before GrPaint::kTotalStages are reserved for setting up the draw (i.e., textures and |
bsalomon@google.com | 45a15f5 | 2012-12-10 19:10:17 +0000 | [diff] [blame] | 28 | * filter masks). |
bsalomon@google.com | dfe75bc | 2011-03-25 12:31:16 +0000 | [diff] [blame] | 29 | */ |
commit-bot@chromium.org | a4de8c2 | 2013-09-09 13:38:37 +0000 | [diff] [blame] | 30 | class SK_API GrPathRenderer : public SkRefCnt { |
bsalomon@google.com | dfe75bc | 2011-03-25 12:31:16 +0000 | [diff] [blame] | 31 | public: |
bsalomon@google.com | c2099d2 | 2012-03-02 21:26:50 +0000 | [diff] [blame] | 32 | GrPathRenderer(); |
bsalomon@google.com | dfe75bc | 2011-03-25 12:31:16 +0000 | [diff] [blame] | 33 | |
| 34 | /** |
bsalomon@google.com | 45a15f5 | 2012-12-10 19:10:17 +0000 | [diff] [blame] | 35 | * A caller may wish to use a path renderer to draw a path into the stencil buffer. However, |
| 36 | * the path renderer itself may require use of the stencil buffer. Also a path renderer may |
joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 37 | * use a GrProcessor coverage stage that sets coverage to zero to eliminate pixels that are |
| 38 | * covered by bounding geometry but outside the path. These exterior pixels would still be |
| 39 | * rendered into the stencil. |
bsalomon@google.com | 45a15f5 | 2012-12-10 19:10:17 +0000 | [diff] [blame] | 40 | * |
| 41 | * A GrPathRenderer can provide three levels of support for stenciling paths: |
egdaniel | 8dd688b | 2015-01-22 10:16:09 -0800 | [diff] [blame] | 42 | * 1) kNoRestriction: This is the most general. The caller sets up the GrPipelineBuilder on the target |
bsalomon@google.com | 45a15f5 | 2012-12-10 19:10:17 +0000 | [diff] [blame] | 43 | * and calls drawPath(). The path is rendered exactly as the draw state |
| 44 | * indicates including support for simultaneous color and stenciling with |
| 45 | * arbitrary stenciling rules. Pixels partially covered by AA paths are |
| 46 | * affected by the stencil settings. |
| 47 | * 2) kStencilOnly: The path renderer cannot apply arbitrary stencil rules nor shade and stencil |
| 48 | * simultaneously. The path renderer does support the stencilPath() function |
| 49 | * which performs no color writes and writes a non-zero stencil value to pixels |
| 50 | * covered by the path. |
| 51 | * 3) kNoSupport: This path renderer cannot be used to stencil the path. |
| 52 | */ |
robertphillips | 6873782 | 2015-10-29 12:12:21 -0700 | [diff] [blame] | 53 | enum StencilSupport { |
| 54 | kNoSupport_StencilSupport, |
| 55 | kStencilOnly_StencilSupport, |
| 56 | kNoRestriction_StencilSupport, |
| 57 | }; |
bsalomon@google.com | 45a15f5 | 2012-12-10 19:10:17 +0000 | [diff] [blame] | 58 | |
| 59 | /** |
robertphillips@google.com | e79f320 | 2014-02-11 16:30:21 +0000 | [diff] [blame] | 60 | * This function is to get the stencil support for a particular path. The path's fill must |
bsalomon@google.com | 45a15f5 | 2012-12-10 19:10:17 +0000 | [diff] [blame] | 61 | * not be an inverse type. |
bsalomon@google.com | dfe75bc | 2011-03-25 12:31:16 +0000 | [diff] [blame] | 62 | * |
robertphillips@google.com | e79f320 | 2014-02-11 16:30:21 +0000 | [diff] [blame] | 63 | * @param path the path that will be drawn |
| 64 | * @param stroke the stroke information (width, join, cap). |
bsalomon@google.com | dfe75bc | 2011-03-25 12:31:16 +0000 | [diff] [blame] | 65 | */ |
robertphillips | e7d4b2f | 2015-08-13 07:57:10 -0700 | [diff] [blame] | 66 | StencilSupport getStencilSupport(const SkPath& path, const GrStrokeInfo& stroke) const { |
robertphillips@google.com | e79f320 | 2014-02-11 16:30:21 +0000 | [diff] [blame] | 67 | SkASSERT(!path.isInverseFillType()); |
robertphillips | e7d4b2f | 2015-08-13 07:57:10 -0700 | [diff] [blame] | 68 | return this->onGetStencilSupport(path, stroke); |
bsalomon@google.com | c2099d2 | 2012-03-02 21:26:50 +0000 | [diff] [blame] | 69 | } |
bsalomon@google.com | dfe75bc | 2011-03-25 12:31:16 +0000 | [diff] [blame] | 70 | |
bsalomon | 0aff2fa | 2015-07-31 06:48:27 -0700 | [diff] [blame] | 71 | /** Args to canDrawPath() |
| 72 | * |
robertphillips | e7d4b2f | 2015-08-13 07:57:10 -0700 | [diff] [blame] | 73 | * fShaderCaps The shader caps |
bsalomon | 0aff2fa | 2015-07-31 06:48:27 -0700 | [diff] [blame] | 74 | * fPipelineBuilder The pipelineBuilder |
| 75 | * fViewMatrix The viewMatrix |
| 76 | * fPath The path to draw |
| 77 | * fStroke The stroke information (width, join, cap) |
| 78 | * fAntiAlias True if anti-aliasing is required. |
| 79 | */ |
| 80 | struct CanDrawPathArgs { |
robertphillips | e7d4b2f | 2015-08-13 07:57:10 -0700 | [diff] [blame] | 81 | const GrShaderCaps* fShaderCaps; |
bsalomon | 0aff2fa | 2015-07-31 06:48:27 -0700 | [diff] [blame] | 82 | const SkMatrix* fViewMatrix; |
| 83 | const SkPath* fPath; |
| 84 | const GrStrokeInfo* fStroke; |
| 85 | bool fAntiAlias; |
robertphillips | e7d4b2f | 2015-08-13 07:57:10 -0700 | [diff] [blame] | 86 | |
robertphillips | 6873782 | 2015-10-29 12:12:21 -0700 | [diff] [blame] | 87 | // These next two are only used by GrStencilAndCoverPathRenderer |
| 88 | bool fIsStencilDisabled; |
| 89 | bool fIsStencilBufferMSAA; |
| 90 | |
robertphillips | e7d4b2f | 2015-08-13 07:57:10 -0700 | [diff] [blame] | 91 | void validate() const { |
| 92 | SkASSERT(fShaderCaps); |
robertphillips | e7d4b2f | 2015-08-13 07:57:10 -0700 | [diff] [blame] | 93 | SkASSERT(fViewMatrix); |
| 94 | SkASSERT(fPath); |
| 95 | SkASSERT(fStroke); |
| 96 | SkASSERT(!fPath->isEmpty()); |
| 97 | } |
bsalomon | 0aff2fa | 2015-07-31 06:48:27 -0700 | [diff] [blame] | 98 | }; |
| 99 | |
bsalomon@google.com | 208236d | 2012-03-12 13:15:33 +0000 | [diff] [blame] | 100 | /** |
robertphillips@google.com | e79f320 | 2014-02-11 16:30:21 +0000 | [diff] [blame] | 101 | * Returns true if this path renderer is able to render the path. Returning false allows the |
| 102 | * caller to fallback to another path renderer This function is called when searching for a path |
| 103 | * renderer capable of rendering a path. |
bsalomon@google.com | 208236d | 2012-03-12 13:15:33 +0000 | [diff] [blame] | 104 | * |
bsalomon@google.com | 208236d | 2012-03-12 13:15:33 +0000 | [diff] [blame] | 105 | * @return true if the path can be drawn by this object, false otherwise. |
| 106 | */ |
bsalomon | 0aff2fa | 2015-07-31 06:48:27 -0700 | [diff] [blame] | 107 | bool canDrawPath(const CanDrawPathArgs& args) const { |
robertphillips | e7d4b2f | 2015-08-13 07:57:10 -0700 | [diff] [blame] | 108 | SkDEBUGCODE(args.validate();) |
bsalomon | 0aff2fa | 2015-07-31 06:48:27 -0700 | [diff] [blame] | 109 | return this->onCanDrawPath(args); |
| 110 | } |
| 111 | |
| 112 | /** |
| 113 | * Args to drawPath() |
| 114 | * |
| 115 | * fTarget The target that the path will be rendered to |
| 116 | * fResourceProvider The resource provider for creating gpu resources to render the path |
| 117 | * fPipelineBuilder The pipelineBuilder |
jvanverth | 512e437 | 2015-11-23 11:50:02 -0800 | [diff] [blame] | 118 | * fColor Color to render with |
bsalomon | 0aff2fa | 2015-07-31 06:48:27 -0700 | [diff] [blame] | 119 | * fViewMatrix The viewMatrix |
| 120 | * fPath the path to draw. |
| 121 | * fStroke the stroke information (width, join, cap) |
| 122 | * fAntiAlias true if anti-aliasing is required. |
| 123 | */ |
| 124 | struct DrawPathArgs { |
| 125 | GrDrawTarget* fTarget; |
| 126 | GrResourceProvider* fResourceProvider; |
| 127 | GrPipelineBuilder* fPipelineBuilder; |
| 128 | GrColor fColor; |
| 129 | const SkMatrix* fViewMatrix; |
| 130 | const SkPath* fPath; |
| 131 | const GrStrokeInfo* fStroke; |
| 132 | bool fAntiAlias; |
robertphillips | e7d4b2f | 2015-08-13 07:57:10 -0700 | [diff] [blame] | 133 | |
| 134 | void validate() const { |
| 135 | SkASSERT(fTarget); |
| 136 | SkASSERT(fResourceProvider); |
| 137 | SkASSERT(fPipelineBuilder); |
| 138 | SkASSERT(fViewMatrix); |
| 139 | SkASSERT(fPath); |
| 140 | SkASSERT(fStroke); |
| 141 | SkASSERT(!fPath->isEmpty()); |
| 142 | } |
bsalomon | 0aff2fa | 2015-07-31 06:48:27 -0700 | [diff] [blame] | 143 | }; |
| 144 | |
bsalomon@google.com | ee43512 | 2011-07-01 14:57:55 +0000 | [diff] [blame] | 145 | /** |
robertphillips@google.com | e79f320 | 2014-02-11 16:30:21 +0000 | [diff] [blame] | 146 | * Draws the path into the draw target. If getStencilSupport() would return kNoRestriction then |
bsalomon | 0aff2fa | 2015-07-31 06:48:27 -0700 | [diff] [blame] | 147 | * the subclass must respect the stencil settings of the GrPipelineBuilder. |
bsalomon@google.com | ee43512 | 2011-07-01 14:57:55 +0000 | [diff] [blame] | 148 | */ |
bsalomon | 0aff2fa | 2015-07-31 06:48:27 -0700 | [diff] [blame] | 149 | bool drawPath(const DrawPathArgs& args) { |
robertphillips | e7d4b2f | 2015-08-13 07:57:10 -0700 | [diff] [blame] | 150 | SkDEBUGCODE(args.validate();) |
bsalomon | 0aff2fa | 2015-07-31 06:48:27 -0700 | [diff] [blame] | 151 | #ifdef SK_DEBUG |
| 152 | CanDrawPathArgs canArgs; |
robertphillips | e7d4b2f | 2015-08-13 07:57:10 -0700 | [diff] [blame] | 153 | canArgs.fShaderCaps = args.fTarget->caps()->shaderCaps(); |
bsalomon | 0aff2fa | 2015-07-31 06:48:27 -0700 | [diff] [blame] | 154 | canArgs.fViewMatrix = args.fViewMatrix; |
| 155 | canArgs.fPath = args.fPath; |
| 156 | canArgs.fStroke = args.fStroke; |
| 157 | canArgs.fAntiAlias = args.fAntiAlias; |
robertphillips | 6873782 | 2015-10-29 12:12:21 -0700 | [diff] [blame] | 158 | |
| 159 | canArgs.fIsStencilDisabled = args.fPipelineBuilder->getStencil().isDisabled(); |
| 160 | canArgs.fIsStencilBufferMSAA = |
| 161 | args.fPipelineBuilder->getRenderTarget()->isStencilBufferMultisampled(); |
bsalomon | 0aff2fa | 2015-07-31 06:48:27 -0700 | [diff] [blame] | 162 | SkASSERT(this->canDrawPath(canArgs)); |
| 163 | SkASSERT(args.fPipelineBuilder->getStencil().isDisabled() || |
robertphillips | e7d4b2f | 2015-08-13 07:57:10 -0700 | [diff] [blame] | 164 | kNoRestriction_StencilSupport == this->getStencilSupport(*args.fPath, |
bsalomon | 0aff2fa | 2015-07-31 06:48:27 -0700 | [diff] [blame] | 165 | *args.fStroke)); |
| 166 | #endif |
| 167 | return this->onDrawPath(args); |
bsalomon@google.com | c2099d2 | 2012-03-02 21:26:50 +0000 | [diff] [blame] | 168 | } |
bsalomon@google.com | ee43512 | 2011-07-01 14:57:55 +0000 | [diff] [blame] | 169 | |
bsalomon | 0aff2fa | 2015-07-31 06:48:27 -0700 | [diff] [blame] | 170 | /* Args to stencilPath(). |
| 171 | * |
| 172 | * fTarget The target that the path will be rendered to. |
robertphillips | e7d4b2f | 2015-08-13 07:57:10 -0700 | [diff] [blame] | 173 | * fResourceProvider The resource provider for creating gpu resources to render the path |
bsalomon | 0aff2fa | 2015-07-31 06:48:27 -0700 | [diff] [blame] | 174 | * fPipelineBuilder The pipeline builder. |
| 175 | * fViewMatrix Matrix applied to the path. |
| 176 | * fPath The path to draw. |
| 177 | * fStroke The stroke information (width, join, cap) |
| 178 | */ |
| 179 | struct StencilPathArgs { |
| 180 | GrDrawTarget* fTarget; |
bsalomon | 0aff2fa | 2015-07-31 06:48:27 -0700 | [diff] [blame] | 181 | GrResourceProvider* fResourceProvider; |
robertphillips | e7d4b2f | 2015-08-13 07:57:10 -0700 | [diff] [blame] | 182 | GrPipelineBuilder* fPipelineBuilder; |
bsalomon | 0aff2fa | 2015-07-31 06:48:27 -0700 | [diff] [blame] | 183 | const SkMatrix* fViewMatrix; |
| 184 | const SkPath* fPath; |
| 185 | const GrStrokeInfo* fStroke; |
robertphillips | e7d4b2f | 2015-08-13 07:57:10 -0700 | [diff] [blame] | 186 | |
| 187 | void validate() const { |
| 188 | SkASSERT(fTarget); |
| 189 | SkASSERT(fResourceProvider); |
| 190 | SkASSERT(fPipelineBuilder); |
| 191 | SkASSERT(fViewMatrix); |
| 192 | SkASSERT(fPath); |
| 193 | SkASSERT(fStroke); |
| 194 | SkASSERT(!fPath->isEmpty()); |
| 195 | } |
bsalomon | 0aff2fa | 2015-07-31 06:48:27 -0700 | [diff] [blame] | 196 | }; |
| 197 | |
bsalomon@google.com | ee43512 | 2011-07-01 14:57:55 +0000 | [diff] [blame] | 198 | /** |
robertphillips@google.com | e79f320 | 2014-02-11 16:30:21 +0000 | [diff] [blame] | 199 | * Draws the path to the stencil buffer. Assume the writable stencil bits are already |
| 200 | * initialized to zero. The pixels inside the path will have non-zero stencil values afterwards. |
bsalomon@google.com | 208236d | 2012-03-12 13:15:33 +0000 | [diff] [blame] | 201 | * |
bsalomon@google.com | 45a15f5 | 2012-12-10 19:10:17 +0000 | [diff] [blame] | 202 | */ |
bsalomon | 0aff2fa | 2015-07-31 06:48:27 -0700 | [diff] [blame] | 203 | void stencilPath(const StencilPathArgs& args) { |
robertphillips | e7d4b2f | 2015-08-13 07:57:10 -0700 | [diff] [blame] | 204 | SkDEBUGCODE(args.validate();) |
| 205 | SkASSERT(kNoSupport_StencilSupport != this->getStencilSupport(*args.fPath, *args.fStroke)); |
| 206 | |
bsalomon | 0aff2fa | 2015-07-31 06:48:27 -0700 | [diff] [blame] | 207 | this->onStencilPath(args); |
bsalomon@google.com | 45a15f5 | 2012-12-10 19:10:17 +0000 | [diff] [blame] | 208 | } |
| 209 | |
commit-bot@chromium.org | e0a868c | 2013-11-22 07:02:11 +0000 | [diff] [blame] | 210 | // Helper for determining if we can treat a thin stroke as a hairline w/ coverage. |
| 211 | // If we can, we draw lots faster (raster device does this same test). |
kkinnunen | 1899651 | 2015-04-26 23:18:49 -0700 | [diff] [blame] | 212 | static bool IsStrokeHairlineOrEquivalent(const GrStrokeInfo& stroke, const SkMatrix& matrix, |
commit-bot@chromium.org | e0a868c | 2013-11-22 07:02:11 +0000 | [diff] [blame] | 213 | SkScalar* outCoverage) { |
kkinnunen | 1899651 | 2015-04-26 23:18:49 -0700 | [diff] [blame] | 214 | if (stroke.isDashed()) { |
| 215 | return false; |
| 216 | } |
kkinnunen | d156d36 | 2015-05-18 22:23:54 -0700 | [diff] [blame] | 217 | if (stroke.isHairlineStyle()) { |
bsalomon | 49f085d | 2014-09-05 13:34:00 -0700 | [diff] [blame] | 218 | if (outCoverage) { |
commit-bot@chromium.org | e0a868c | 2013-11-22 07:02:11 +0000 | [diff] [blame] | 219 | *outCoverage = SK_Scalar1; |
| 220 | } |
| 221 | return true; |
| 222 | } |
kkinnunen | d156d36 | 2015-05-18 22:23:54 -0700 | [diff] [blame] | 223 | return stroke.getStyle() == SkStrokeRec::kStroke_Style && |
| 224 | SkDrawTreatAAStrokeAsHairline(stroke.getWidth(), matrix, outCoverage); |
commit-bot@chromium.org | e0a868c | 2013-11-22 07:02:11 +0000 | [diff] [blame] | 225 | } |
| 226 | |
bsalomon@google.com | 45a15f5 | 2012-12-10 19:10:17 +0000 | [diff] [blame] | 227 | protected: |
bsalomon@google.com | 1dd9baa | 2013-05-20 16:49:06 +0000 | [diff] [blame] | 228 | // Helper for getting the device bounds of a path. Inverse filled paths will have bounds set |
| 229 | // by devSize. Non-inverse path bounds will not necessarily be clipped to devSize. |
| 230 | static void GetPathDevBounds(const SkPath& path, |
| 231 | int devW, |
| 232 | int devH, |
| 233 | const SkMatrix& matrix, |
| 234 | SkRect* bounds); |
| 235 | |
| 236 | // Helper version that gets the dev width and height from a GrSurface. |
| 237 | static void GetPathDevBounds(const SkPath& path, |
| 238 | const GrSurface* device, |
| 239 | const SkMatrix& matrix, |
| 240 | SkRect* bounds) { |
| 241 | GetPathDevBounds(path, device->width(), device->height(), matrix, bounds); |
| 242 | } |
| 243 | |
bsalomon@google.com | dfe75bc | 2011-03-25 12:31:16 +0000 | [diff] [blame] | 244 | private: |
bsalomon | 0aff2fa | 2015-07-31 06:48:27 -0700 | [diff] [blame] | 245 | /** |
| 246 | * Subclass overrides if it has any limitations of stenciling support. |
| 247 | */ |
robertphillips | e7d4b2f | 2015-08-13 07:57:10 -0700 | [diff] [blame] | 248 | virtual StencilSupport onGetStencilSupport(const SkPath&, const GrStrokeInfo&) const { |
bsalomon | 0aff2fa | 2015-07-31 06:48:27 -0700 | [diff] [blame] | 249 | return kNoRestriction_StencilSupport; |
| 250 | } |
| 251 | |
| 252 | /** |
| 253 | * Subclass implementation of drawPath() |
| 254 | */ |
| 255 | virtual bool onDrawPath(const DrawPathArgs& args) = 0; |
| 256 | |
| 257 | /** |
| 258 | * Subclass implementation of canDrawPath() |
| 259 | */ |
| 260 | virtual bool onCanDrawPath(const CanDrawPathArgs& args) const = 0; |
| 261 | |
| 262 | /** |
| 263 | * Subclass implementation of stencilPath(). Subclass must override iff it ever returns |
| 264 | * kStencilOnly in onGetStencilSupport(). |
| 265 | */ |
| 266 | virtual void onStencilPath(const StencilPathArgs& args) { |
| 267 | GR_STATIC_CONST_SAME_STENCIL(kIncrementStencil, |
| 268 | kReplace_StencilOp, |
| 269 | kReplace_StencilOp, |
| 270 | kAlways_StencilFunc, |
| 271 | 0xffff, |
| 272 | 0xffff, |
| 273 | 0xffff); |
| 274 | args.fPipelineBuilder->setStencil(kIncrementStencil); |
| 275 | args.fPipelineBuilder->setDisableColorXPFactory(); |
| 276 | DrawPathArgs drawArgs; |
| 277 | drawArgs.fTarget = args.fTarget; |
| 278 | drawArgs.fResourceProvider = args.fResourceProvider; |
| 279 | drawArgs.fPipelineBuilder = args.fPipelineBuilder; |
| 280 | drawArgs.fColor = 0xFFFFFFFF; |
| 281 | drawArgs.fViewMatrix = args.fViewMatrix; |
| 282 | drawArgs.fPath = args.fPath; |
| 283 | drawArgs.fStroke = args.fStroke; |
| 284 | drawArgs.fAntiAlias = false; |
| 285 | this->drawPath(drawArgs); |
| 286 | } |
| 287 | |
bsalomon@google.com | dfe75bc | 2011-03-25 12:31:16 +0000 | [diff] [blame] | 288 | |
commit-bot@chromium.org | a4de8c2 | 2013-09-09 13:38:37 +0000 | [diff] [blame] | 289 | typedef SkRefCnt INHERITED; |
bsalomon@google.com | dfe75bc | 2011-03-25 12:31:16 +0000 | [diff] [blame] | 290 | }; |
| 291 | |
bsalomon@google.com | dfe75bc | 2011-03-25 12:31:16 +0000 | [diff] [blame] | 292 | #endif |