1
2 /*
3 * Copyright 2010 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.
7 */
8
9
10
11 #ifndef GrTypes_DEFINED
12 #define GrTypes_DEFINED
13
14 #include "SkTypes.h"
15 #include "GrConfig.h"
16 #include "SkMath.h"
17
18 ////////////////////////////////////////////////////////////////////////////////
19
20 /**
21 * Defines overloaded bitwise operators to make it easier to use an enum as a
22 * bitfield.
23 */
24 #define GR_MAKE_BITFIELD_OPS(X) \
25 inline X operator | (X a, X b) { \
26 return (X) (+a | +b); \
27 } \
28 \
29 inline X operator & (X a, X b) { \
30 return (X) (+a & +b); \
31 } \
32 template <typename T> \
33 inline X operator & (T a, X b) { \
34 return (X) (+a & +b); \
35 } \
36 template <typename T> \
37 inline X operator & (X a, T b) { \
38 return (X) (+a & +b); \
39 } \
40
41 #define GR_DECL_BITFIELD_OPS_FRIENDS(X) \
42 friend X operator | (X a, X b); \
43 \
44 friend X operator & (X a, X b); \
45 \
46 template <typename T> \
47 friend X operator & (T a, X b); \
48 \
49 template <typename T> \
50 friend X operator & (X a, T b); \
51 ////////////////////////////////////////////////////////////////////////////////
52
53
54 /**
55 * Macro to round n up to the next multiple of 4, or return it unchanged if
56 * n is already a multiple of 4
57 */
58 #define GrALIGN4(n) SkAlign4(n)
59 #define GrIsALIGN4(n) SkIsAlign4(n)
60
GrMin(const T & a,const T & b)61 template <typename T> const T& GrMin(const T& a, const T& b) {
62 return (a < b) ? a : b;
63 }
64
GrMax(const T & a,const T & b)65 template <typename T> const T& GrMax(const T& a, const T& b) {
66 return (b < a) ? a : b;
67 }
68
69 // compile time versions of min/max
70 #define GR_CT_MAX(a, b) (((b) < (a)) ? (a) : (b))
71 #define GR_CT_MIN(a, b) (((b) < (a)) ? (b) : (a))
72
73 /**
74 * divide, rounding up
75 */
GrIDivRoundUp(int x,int y)76 static inline int32_t GrIDivRoundUp(int x, int y) {
77 GrAssert(y > 0);
78 return (x + (y-1)) / y;
79 }
GrUIDivRoundUp(uint32_t x,uint32_t y)80 static inline uint32_t GrUIDivRoundUp(uint32_t x, uint32_t y) {
81 return (x + (y-1)) / y;
82 }
GrSizeDivRoundUp(size_t x,size_t y)83 static inline size_t GrSizeDivRoundUp(size_t x, size_t y) {
84 return (x + (y-1)) / y;
85 }
86
87 // compile time, evaluates Y multiple times
88 #define GR_CT_DIV_ROUND_UP(X, Y) (((X) + ((Y)-1)) / (Y))
89
90 /**
91 * align up
92 */
GrUIAlignUp(uint32_t x,uint32_t alignment)93 static inline uint32_t GrUIAlignUp(uint32_t x, uint32_t alignment) {
94 return GrUIDivRoundUp(x, alignment) * alignment;
95 }
GrSizeAlignUp(size_t x,size_t alignment)96 static inline size_t GrSizeAlignUp(size_t x, size_t alignment) {
97 return GrSizeDivRoundUp(x, alignment) * alignment;
98 }
99
100 // compile time, evaluates A multiple times
101 #define GR_CT_ALIGN_UP(X, A) (GR_CT_DIV_ROUND_UP((X),(A)) * (A))
102
103 /**
104 * amount of pad needed to align up
105 */
GrUIAlignUpPad(uint32_t x,uint32_t alignment)106 static inline uint32_t GrUIAlignUpPad(uint32_t x, uint32_t alignment) {
107 return (alignment - x % alignment) % alignment;
108 }
GrSizeAlignUpPad(size_t x,size_t alignment)109 static inline size_t GrSizeAlignUpPad(size_t x, size_t alignment) {
110 return (alignment - x % alignment) % alignment;
111 }
112
113 /**
114 * align down
115 */
GrUIAlignDown(uint32_t x,uint32_t alignment)116 static inline uint32_t GrUIAlignDown(uint32_t x, uint32_t alignment) {
117 return (x / alignment) * alignment;
118 }
GrSizeAlignDown(size_t x,uint32_t alignment)119 static inline size_t GrSizeAlignDown(size_t x, uint32_t alignment) {
120 return (x / alignment) * alignment;
121 }
122
123 /**
124 * Count elements in an array
125 */
126 #define GR_ARRAY_COUNT(array) SK_ARRAY_COUNT(array)
127
128 //!< allocate a block of memory, will never return NULL
129 extern void* GrMalloc(size_t bytes);
130
131 //!< free block allocated by GrMalloc. ptr may be NULL
132 extern void GrFree(void* ptr);
133
Gr_bzero(void * dst,size_t size)134 static inline void Gr_bzero(void* dst, size_t size) {
135 memset(dst, 0, size);
136 }
137
138 ///////////////////////////////////////////////////////////////////////////////
139
140 /**
141 * Return true if n is a power of 2
142 */
GrIsPow2(unsigned n)143 static inline bool GrIsPow2(unsigned n) {
144 return n && 0 == (n & (n - 1));
145 }
146
147 /**
148 * Return the next power of 2 >= n.
149 */
GrNextPow2(uint32_t n)150 static inline uint32_t GrNextPow2(uint32_t n) {
151 return n ? (1 << (32 - SkCLZ(n - 1))) : 1;
152 }
153
GrNextPow2(int n)154 static inline int GrNextPow2(int n) {
155 GrAssert(n >= 0); // this impl only works for non-neg.
156 return n ? (1 << (32 - SkCLZ(n - 1))) : 1;
157 }
158
159 ///////////////////////////////////////////////////////////////////////////////
160
161 /**
162 * 16.16 fixed point type
163 */
164 typedef int32_t GrFixed;
165
166 #if GR_DEBUG
167
GrToS16(intptr_t x)168 static inline int16_t GrToS16(intptr_t x) {
169 GrAssert((int16_t)x == x);
170 return (int16_t)x;
171 }
172
173 #else
174
175 #define GrToS16(x) x
176
177 #endif
178
179
180 ///////////////////////////////////////////////////////////////////////////////
181
182 /**
183 * Possible 3D APIs that may be used by Ganesh.
184 */
185 enum GrBackend {
186 kOpenGL_GrBackend,
187 };
188
189 /**
190 * Backend-specific 3D context handle
191 * GrGLInterface* for OpenGL. If NULL will use the default GL interface.
192 */
193 typedef intptr_t GrBackendContext;
194
195 ///////////////////////////////////////////////////////////////////////////////
196
197 /**
198 * Type used to describe format of vertices in arrays
199 * Values are defined in GrDrawTarget
200 */
201 typedef int GrVertexLayout;
202
203 /**
204 * Geometric primitives used for drawing.
205 */
206 enum GrPrimitiveType {
207 kTriangles_GrPrimitiveType,
208 kTriangleStrip_GrPrimitiveType,
209 kTriangleFan_GrPrimitiveType,
210 kPoints_GrPrimitiveType,
211 kLines_GrPrimitiveType, // 1 pix wide only
212 kLineStrip_GrPrimitiveType // 1 pix wide only
213 };
214
GrIsPrimTypeLines(GrPrimitiveType type)215 static inline bool GrIsPrimTypeLines(GrPrimitiveType type) {
216 return kLines_GrPrimitiveType == type || kLineStrip_GrPrimitiveType == type;
217 }
218
GrIsPrimTypeTris(GrPrimitiveType type)219 static inline bool GrIsPrimTypeTris(GrPrimitiveType type) {
220 return kTriangles_GrPrimitiveType == type ||
221 kTriangleStrip_GrPrimitiveType == type ||
222 kTriangleFan_GrPrimitiveType == type;
223 }
224
225 /**
226 * Coeffecients for alpha-blending.
227 */
228 enum GrBlendCoeff {
229 kInvalid_GrBlendCoeff = -1,
230
231 kZero_GrBlendCoeff, //<! 0
232 kOne_GrBlendCoeff, //<! 1
233 kSC_GrBlendCoeff, //<! src color
234 kISC_GrBlendCoeff, //<! one minus src color
235 kDC_GrBlendCoeff, //<! dst color
236 kIDC_GrBlendCoeff, //<! one minus dst color
237 kSA_GrBlendCoeff, //<! src alpha
238 kISA_GrBlendCoeff, //<! one minus src alpha
239 kDA_GrBlendCoeff, //<! dst alpha
240 kIDA_GrBlendCoeff, //<! one minus dst alpha
241 kConstC_GrBlendCoeff, //<! constant color
242 kIConstC_GrBlendCoeff, //<! one minus constant color
243 kConstA_GrBlendCoeff, //<! constant color alpha
244 kIConstA_GrBlendCoeff, //<! one minus constant color alpha
245
246 kPublicGrBlendCoeffCount
247 };
248
249 /**
250 * Formats for masks, used by the font cache.
251 * Important that these are 0-based.
252 */
253 enum GrMaskFormat {
254 kA8_GrMaskFormat, //!< 1-byte per pixel
255 kA565_GrMaskFormat, //!< 2-bytes per pixel
256 kA888_GrMaskFormat, //!< 4-bytes per pixel
257
258 kCount_GrMaskFormats //!< used to allocate arrays sized for mask formats
259 };
260
261 /**
262 * Return the number of bytes-per-pixel for the specified mask format.
263 */
GrMaskFormatBytesPerPixel(GrMaskFormat format)264 static inline int GrMaskFormatBytesPerPixel(GrMaskFormat format) {
265 GrAssert((unsigned)format <= 2);
266 // kA8 (0) -> 1
267 // kA565 (1) -> 2
268 // kA888 (2) -> 4
269 return 1 << (int)format;
270 }
271
272 /**
273 * Pixel configurations.
274 */
275 enum GrPixelConfig {
276 kUnknown_GrPixelConfig,
277 kAlpha_8_GrPixelConfig,
278 kIndex_8_GrPixelConfig,
279 kRGB_565_GrPixelConfig,
280 /**
281 * Premultiplied
282 */
283 kRGBA_4444_GrPixelConfig,
284 /**
285 * Premultiplied. Byte order is r,g,b,a.
286 */
287 kRGBA_8888_GrPixelConfig,
288 /**
289 * Premultiplied. Byte order is b,g,r,a.
290 */
291 kBGRA_8888_GrPixelConfig,
292
293 kGrPixelConfigCount
294 };
295
296 // Aliases for pixel configs that match skia's byte order.
297 #ifndef SK_CPU_LENDIAN
298 #error "Skia gpu currently assumes little endian"
299 #endif
300 #if 24 == SK_A32_SHIFT && 16 == SK_R32_SHIFT && \
301 8 == SK_G32_SHIFT && 0 == SK_B32_SHIFT
302 static const GrPixelConfig kSkia8888_GrPixelConfig = kBGRA_8888_GrPixelConfig;
303 #elif 24 == SK_A32_SHIFT && 16 == SK_B32_SHIFT && \
304 8 == SK_G32_SHIFT && 0 == SK_R32_SHIFT
305 static const GrPixelConfig kSkia8888_GrPixelConfig = kRGBA_8888_GrPixelConfig;
306 #else
307 #error "SK_*32_SHIFT values must correspond to GL_BGRA or GL_RGBA format."
308 #endif
309
310 // This alias is deprecated and will be removed.
311 static const GrPixelConfig kSkia8888_PM_GrPixelConfig = kSkia8888_GrPixelConfig;
312
313 // Returns true if the pixel config has 8bit r,g,b,a components in that byte
314 // order
GrPixelConfigIsRGBA8888(GrPixelConfig config)315 static inline bool GrPixelConfigIsRGBA8888(GrPixelConfig config) {
316 switch (config) {
317 case kRGBA_8888_GrPixelConfig:
318 return true;
319 default:
320 return false;
321 }
322 }
323
324 // Returns true if the pixel config has 8bit b,g,r,a components in that byte
325 // order
GrPixelConfigIsBGRA8888(GrPixelConfig config)326 static inline bool GrPixelConfigIsBGRA8888(GrPixelConfig config) {
327 switch (config) {
328 case kBGRA_8888_GrPixelConfig:
329 return true;
330 default:
331 return false;
332 }
333 }
334
335 // Returns true if the pixel config is 32 bits per pixel
GrPixelConfigIs32Bit(GrPixelConfig config)336 static inline bool GrPixelConfigIs32Bit(GrPixelConfig config) {
337 switch (config) {
338 case kRGBA_8888_GrPixelConfig:
339 case kBGRA_8888_GrPixelConfig:
340 return true;
341 default:
342 return false;
343 }
344 }
345
346 // Takes a config and returns the equivalent config with the R and B order
347 // swapped if such a config exists. Otherwise, kUnknown_GrPixelConfig
GrPixelConfigSwapRAndB(GrPixelConfig config)348 static inline GrPixelConfig GrPixelConfigSwapRAndB(GrPixelConfig config) {
349 switch (config) {
350 case kBGRA_8888_GrPixelConfig:
351 return kRGBA_8888_GrPixelConfig;
352 case kRGBA_8888_GrPixelConfig:
353 return kBGRA_8888_GrPixelConfig;
354 default:
355 return kUnknown_GrPixelConfig;
356 }
357 }
358
GrBytesPerPixel(GrPixelConfig config)359 static inline size_t GrBytesPerPixel(GrPixelConfig config) {
360 switch (config) {
361 case kAlpha_8_GrPixelConfig:
362 case kIndex_8_GrPixelConfig:
363 return 1;
364 case kRGB_565_GrPixelConfig:
365 case kRGBA_4444_GrPixelConfig:
366 return 2;
367 case kRGBA_8888_GrPixelConfig:
368 case kBGRA_8888_GrPixelConfig:
369 return 4;
370 default:
371 return 0;
372 }
373 }
374
GrPixelConfigIsOpaque(GrPixelConfig config)375 static inline bool GrPixelConfigIsOpaque(GrPixelConfig config) {
376 switch (config) {
377 case kRGB_565_GrPixelConfig:
378 return true;
379 default:
380 return false;
381 }
382 }
383
GrPixelConfigIsAlphaOnly(GrPixelConfig config)384 static inline bool GrPixelConfigIsAlphaOnly(GrPixelConfig config) {
385 switch (config) {
386 case kAlpha_8_GrPixelConfig:
387 return true;
388 default:
389 return false;
390 }
391 }
392
393 /**
394 * Optional bitfield flags that can be passed to createTexture.
395 */
396 enum GrTextureFlags {
397 kNone_GrTextureFlags = 0x0,
398 /**
399 * Creates a texture that can be rendered to as a GrRenderTarget. Use
400 * GrTexture::asRenderTarget() to access.
401 */
402 kRenderTarget_GrTextureFlagBit = 0x1,
403 /**
404 * By default all render targets have an associated stencil buffer that
405 * may be required for path filling. This flag overrides stencil buffer
406 * creation.
407 * MAKE THIS PRIVATE?
408 */
409 kNoStencil_GrTextureFlagBit = 0x2,
410 /**
411 * Hint that the CPU may modify this texture after creation.
412 */
413 kDynamicUpdate_GrTextureFlagBit = 0x4,
414
415 kDummy_GrTextureFlagBit,
416 kLastPublic_GrTextureFlagBit = kDummy_GrTextureFlagBit-1,
417 };
418
419 GR_MAKE_BITFIELD_OPS(GrTextureFlags)
420
421 enum {
422 /**
423 * For Index8 pixel config, the colortable must be 256 entries
424 */
425 kGrColorTableSize = 256 * 4 //sizeof(GrColor)
426 };
427
428 /**
429 * Some textures will be stored such that the upper and left edges of the content meet at the
430 * the origin (in texture coord space) and for other textures the lower and left edges meet at
431 * the origin. Render-targets are always consistent with the convention of the underlying
432 * backend API to make it easier to mix native backend rendering with Skia rendering.
433 */
434
435 enum GrSurfaceOrigin {
436 kBottomLeft_GrSurfaceOrigin,
437 kTopLeft_GrSurfaceOrigin,
438 };
439
440 /**
441 * Describes a texture to be created.
442 */
443 struct GrTextureDesc {
GrTextureDescGrTextureDesc444 GrTextureDesc()
445 : fFlags(kNone_GrTextureFlags)
446 , fWidth(0)
447 , fHeight(0)
448 , fConfig(kUnknown_GrPixelConfig)
449 , fSampleCnt(0) {
450 }
451
452 GrTextureFlags fFlags; //!< bitfield of TextureFlags
453 int fWidth; //!< Width of the texture
454 int fHeight; //!< Height of the texture
455
456 /**
457 * Format of source data of the texture. Not guaranteed to be the same as
458 * internal format used by 3D API.
459 */
460 GrPixelConfig fConfig;
461
462 /**
463 * The number of samples per pixel or 0 to disable full scene AA. This only
464 * applies if the kRenderTarget_GrTextureFlagBit is set. The actual number
465 * of samples may not exactly match the request. The request will be rounded
466 * up to the next supported sample count, or down if it is larger than the
467 * max supported count.
468 */
469 int fSampleCnt;
470 };
471
472 /**
473 * GrCacheID is used create and find cached GrResources (e.g. GrTextures). The ID has two parts:
474 * the domain and the key. Domains simply allow multiple clients to use 0-based indices as their
475 * cache key without colliding. The key uniquely identifies a GrResource within the domain.
476 * Users of the cache must obtain a domain via GenerateDomain().
477 */
478 struct GrCacheID {
479 public:
480 typedef uint8_t Domain;
481
482 struct Key {
483 union {
484 uint8_t fData8[16];
485 uint32_t fData32[4];
486 uint64_t fData64[2];
487 };
488 };
489
490 /**
491 * A default cache ID is invalid; a set method must be called before the object is used.
492 */
GrCacheIDGrCacheID493 GrCacheID() { fDomain = kInvalid_Domain; }
494
495 /**
496 * Initialize the cache ID to a domain and key.
497 */
GrCacheIDGrCacheID498 GrCacheID(Domain domain, const Key& key) {
499 GrAssert(kInvalid_Domain != domain);
500 this->reset(domain, key);
501 }
502
resetGrCacheID503 void reset(Domain domain, const Key& key) {
504 fDomain = domain;
505 memcpy(&fKey, &key, sizeof(Key));
506 }
507
508 /** Has this been initialized to a valid domain */
isValidGrCacheID509 bool isValid() const { return kInvalid_Domain != fDomain; }
510
getKeyGrCacheID511 const Key& getKey() const { GrAssert(this->isValid()); return fKey; }
getDomainGrCacheID512 Domain getDomain() const { GrAssert(this->isValid()); return fDomain; }
513
514 /** Creates a new unique ID domain. */
515 static Domain GenerateDomain();
516
517 private:
518 Key fKey;
519 Domain fDomain;
520
521 static const Domain kInvalid_Domain = 0;
522 };
523
524 /**
525 * Clips are composed from these objects.
526 */
527 enum GrClipType {
528 kRect_ClipType,
529 kPath_ClipType
530 };
531
532 /**
533 * Commands used to describe a path. Each command
534 * is accompanied by some number of points.
535 */
536 enum GrPathCmd {
537 kMove_PathCmd, //!< Starts a new subpath at
538 // at the returned point
539 // 1 point
540 kLine_PathCmd, //!< Adds a line segment
541 // 2 points
542 kQuadratic_PathCmd, //!< Adds a quadratic segment
543 // 3 points
544 kCubic_PathCmd, //!< Adds a cubic segment
545 // 4 points
546 kClose_PathCmd, //!< Closes the current subpath
547 // by connecting a line to the
548 // starting point.
549 // 0 points
550 kEnd_PathCmd //!< Indicates the end of the last subpath
551 // when iterating
552 // 0 points.
553 };
554
555 /**
556 * Gets the number of points associated with a path command.
557 */
NumPathCmdPoints(GrPathCmd cmd)558 static int inline NumPathCmdPoints(GrPathCmd cmd) {
559 static const int gNumPoints[] = {
560 1, 2, 3, 4, 0, 0
561 };
562 return gNumPoints[cmd];
563 }
564
565 ///////////////////////////////////////////////////////////////////////////////
566
567 // opaque type for 3D API object handles
568 typedef intptr_t GrBackendObject;
569
570 /**
571 * Gr can wrap an existing texture created by the client with a GrTexture
572 * object. The client is responsible for ensuring that the texture lives at
573 * least as long as the GrTexture object wrapping it. We require the client to
574 * explicitly provide information about the texture, such as width, height,
575 * and pixel config, rather than querying the 3D APIfor these values. We expect
576 * these to be immutable even if the 3D API doesn't require this (OpenGL).
577 *
578 * Textures that are also render targets are supported as well. Gr will manage
579 * any ancillary 3D API (stencil buffer, FBO id, etc) objects necessary for
580 * Gr to draw into the render target. To access the render target object
581 * call GrTexture::asRenderTarget().
582 *
583 * If in addition to the render target flag, the caller also specifies a sample
584 * count Gr will create an MSAA buffer that resolves into the texture. Gr auto-
585 * resolves when it reads from the texture. The client can explictly resolve
586 * using the GrRenderTarget interface.
587 *
588 * Note: These flags currently form a subset of GrTexture's flags.
589 */
590
591 enum GrBackendTextureFlags {
592 /**
593 * No flags enabled
594 */
595 kNone_GrBackendTextureFlag = kNone_GrTextureFlags,
596 /**
597 * Indicates that the texture is also a render target, and thus should have
598 * a GrRenderTarget object.
599 *
600 * D3D (future): client must have created the texture with flags that allow
601 * it to be used as a render target.
602 */
603 kRenderTarget_GrBackendTextureFlag = kRenderTarget_GrTextureFlagBit,
604 };
605 GR_MAKE_BITFIELD_OPS(GrBackendTextureFlags)
606
607 struct GrBackendTextureDesc {
GrBackendTextureDescGrBackendTextureDesc608 GrBackendTextureDesc() { memset(this, 0, sizeof(*this)); }
609 GrBackendTextureFlags fFlags;
610 GrSurfaceOrigin fOrigin;
611 int fWidth; //<! width in pixels
612 int fHeight; //<! height in pixels
613 GrPixelConfig fConfig; //<! color format
614 /**
615 * If the render target flag is set and sample count is greater than 0
616 * then Gr will create an MSAA buffer that resolves to the texture.
617 */
618 int fSampleCnt;
619 /**
620 * Handle to the 3D API object.
621 * OpenGL: Texture ID.
622 */
623 GrBackendObject fTextureHandle;
624 };
625
626 ///////////////////////////////////////////////////////////////////////////////
627
628 /**
629 * Gr can wrap an existing render target created by the client in the 3D API
630 * with a GrRenderTarget object. The client is responsible for ensuring that the
631 * underlying 3D API object lives at least as long as the GrRenderTarget object
632 * wrapping it. We require the client to explicitly provide information about
633 * the target, such as width, height, and pixel config rather than querying the
634 * 3D API for these values. We expect these properties to be immutable even if
635 * the 3D API doesn't require this (OpenGL).
636 */
637
638 struct GrBackendRenderTargetDesc {
GrBackendRenderTargetDescGrBackendRenderTargetDesc639 GrBackendRenderTargetDesc() { memset(this, 0, sizeof(*this)); }
640 int fWidth; //<! width in pixels
641 int fHeight; //<! height in pixels
642 GrPixelConfig fConfig; //<! color format
643 /**
644 * The number of samples per pixel. Gr uses this to influence decisions
645 * about applying other forms of anti-aliasing.
646 */
647 int fSampleCnt;
648 /**
649 * Number of bits of stencil per-pixel.
650 */
651 int fStencilBits;
652 /**
653 * Handle to the 3D API object.
654 * OpenGL: FBO ID
655 */
656 GrBackendObject fRenderTargetHandle;
657 };
658
659 ///////////////////////////////////////////////////////////////////////////////
660 // Legacy names that will be kept until WebKit can be updated.
661
662 typedef GrBackend GrEngine;
663 static const GrBackend kOpenGL_Shaders_GrEngine = kOpenGL_GrBackend;
664
665 typedef GrBackendContext GrPlatform3DContext;
666
667 typedef GrBackendObject GrPlatform3DObject;
668
669 typedef GrBackendTextureFlags GrPlatformTextureFlags;
670 static const GrBackendTextureFlags kNone_GrPlatformTextureFlag = kNone_GrBackendTextureFlag;
671 static const GrBackendTextureFlags kRenderTarget_GrPlatformTextureFlag = kRenderTarget_GrBackendTextureFlag;
672
673 typedef GrBackendTextureDesc GrPlatformTextureDesc;
674
675 typedef GrBackendRenderTargetDesc GrPlatformRenderTargetDesc;
676
677 ///////////////////////////////////////////////////////////////////////////////
678
679 #endif
680