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 SkASSERT(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 ///////////////////////////////////////////////////////////////////////////////
129
130 /**
131 * Return true if n is a power of 2
132 */
GrIsPow2(unsigned n)133 static inline bool GrIsPow2(unsigned n) {
134 return n && 0 == (n & (n - 1));
135 }
136
137 /**
138 * Return the next power of 2 >= n.
139 */
GrNextPow2(uint32_t n)140 static inline uint32_t GrNextPow2(uint32_t n) {
141 return n ? (1 << (32 - SkCLZ(n - 1))) : 1;
142 }
143
GrNextPow2(int n)144 static inline int GrNextPow2(int n) {
145 SkASSERT(n >= 0); // this impl only works for non-neg.
146 return n ? (1 << (32 - SkCLZ(n - 1))) : 1;
147 }
148
149 ///////////////////////////////////////////////////////////////////////////////
150
151 /**
152 * 16.16 fixed point type
153 */
154 typedef int32_t GrFixed;
155
156 #ifdef SK_DEBUG
157
GrToS16(intptr_t x)158 static inline int16_t GrToS16(intptr_t x) {
159 SkASSERT((int16_t)x == x);
160 return (int16_t)x;
161 }
162
163 #else
164
165 #define GrToS16(x) x
166
167 #endif
168
169
170 ///////////////////////////////////////////////////////////////////////////////
171
172 /**
173 * Possible 3D APIs that may be used by Ganesh.
174 */
175 enum GrBackend {
176 kOpenGL_GrBackend,
177 };
178
179 /**
180 * Backend-specific 3D context handle
181 * GrGLInterface* for OpenGL. If NULL will use the default GL interface.
182 */
183 typedef intptr_t GrBackendContext;
184
185 ///////////////////////////////////////////////////////////////////////////////
186
187 /**
188 * Geometric primitives used for drawing.
189 */
190 enum GrPrimitiveType {
191 kTriangles_GrPrimitiveType,
192 kTriangleStrip_GrPrimitiveType,
193 kTriangleFan_GrPrimitiveType,
194 kPoints_GrPrimitiveType,
195 kLines_GrPrimitiveType, // 1 pix wide only
196 kLineStrip_GrPrimitiveType // 1 pix wide only
197 };
198
GrIsPrimTypeLines(GrPrimitiveType type)199 static inline bool GrIsPrimTypeLines(GrPrimitiveType type) {
200 return kLines_GrPrimitiveType == type || kLineStrip_GrPrimitiveType == type;
201 }
202
GrIsPrimTypeTris(GrPrimitiveType type)203 static inline bool GrIsPrimTypeTris(GrPrimitiveType type) {
204 return kTriangles_GrPrimitiveType == type ||
205 kTriangleStrip_GrPrimitiveType == type ||
206 kTriangleFan_GrPrimitiveType == type;
207 }
208
209 /**
210 * Coeffecients for alpha-blending.
211 */
212 enum GrBlendCoeff {
213 kInvalid_GrBlendCoeff = -1,
214
215 kZero_GrBlendCoeff, //<! 0
216 kOne_GrBlendCoeff, //<! 1
217 kSC_GrBlendCoeff, //<! src color
218 kISC_GrBlendCoeff, //<! one minus src color
219 kDC_GrBlendCoeff, //<! dst color
220 kIDC_GrBlendCoeff, //<! one minus dst color
221 kSA_GrBlendCoeff, //<! src alpha
222 kISA_GrBlendCoeff, //<! one minus src alpha
223 kDA_GrBlendCoeff, //<! dst alpha
224 kIDA_GrBlendCoeff, //<! one minus dst alpha
225 kConstC_GrBlendCoeff, //<! constant color
226 kIConstC_GrBlendCoeff, //<! one minus constant color
227 kConstA_GrBlendCoeff, //<! constant color alpha
228 kIConstA_GrBlendCoeff, //<! one minus constant color alpha
229
230 kPublicGrBlendCoeffCount
231 };
232
233 /**
234 * Formats for masks, used by the font cache.
235 * Important that these are 0-based.
236 */
237 enum GrMaskFormat {
238 kA8_GrMaskFormat, //!< 1-byte per pixel
239 kA565_GrMaskFormat, //!< 2-bytes per pixel
240 kA888_GrMaskFormat, //!< 4-bytes per pixel
241 kARGB_GrMaskFormat, //!< 4-bytes per pixel, color format
242
243 kLast_GrMaskFormat = kARGB_GrMaskFormat
244 };
245 static const int kMaskFormatCount = kLast_GrMaskFormat + 1;
246
247 /**
248 * Return the number of bytes-per-pixel for the specified mask format.
249 */
GrMaskFormatBytesPerPixel(GrMaskFormat format)250 static inline int GrMaskFormatBytesPerPixel(GrMaskFormat format) {
251 SkASSERT((unsigned)format <= 3);
252 // kA8 (0) -> 1
253 // kA565 (1) -> 2
254 // kA888 (2) -> 4
255 // kARGB (3) -> 4
256 static const int sBytesPerPixel[] = { 1, 2, 4, 4 };
257 SK_COMPILE_ASSERT(SK_ARRAY_COUNT(sBytesPerPixel) == kMaskFormatCount, array_size_mismatch);
258
259 return sBytesPerPixel[(int) format];
260 }
261
262 /**
263 * Pixel configurations.
264 */
265 enum GrPixelConfig {
266 kUnknown_GrPixelConfig,
267 kAlpha_8_GrPixelConfig,
268 kIndex_8_GrPixelConfig,
269 kRGB_565_GrPixelConfig,
270 /**
271 * Premultiplied
272 */
273 kRGBA_4444_GrPixelConfig,
274 /**
275 * Premultiplied. Byte order is r,g,b,a.
276 */
277 kRGBA_8888_GrPixelConfig,
278 /**
279 * Premultiplied. Byte order is b,g,r,a.
280 */
281 kBGRA_8888_GrPixelConfig,
282
283 kLast_GrPixelConfig = kBGRA_8888_GrPixelConfig
284 };
285 static const int kGrPixelConfigCnt = kLast_GrPixelConfig + 1;
286
287 // Aliases for pixel configs that match skia's byte order.
288 #ifndef SK_CPU_LENDIAN
289 #error "Skia gpu currently assumes little endian"
290 #endif
291 #if SK_PMCOLOR_BYTE_ORDER(B,G,R,A)
292 static const GrPixelConfig kSkia8888_GrPixelConfig = kBGRA_8888_GrPixelConfig;
293 #elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A)
294 static const GrPixelConfig kSkia8888_GrPixelConfig = kRGBA_8888_GrPixelConfig;
295 #else
296 #error "SK_*32_SHIFT values must correspond to GL_BGRA or GL_RGBA format."
297 #endif
298
299 // Returns true if the pixel config is 32 bits per pixel
GrPixelConfigIs8888(GrPixelConfig config)300 static inline bool GrPixelConfigIs8888(GrPixelConfig config) {
301 switch (config) {
302 case kRGBA_8888_GrPixelConfig:
303 case kBGRA_8888_GrPixelConfig:
304 return true;
305 default:
306 return false;
307 }
308 }
309
310 // Takes a config and returns the equivalent config with the R and B order
311 // swapped if such a config exists. Otherwise, kUnknown_GrPixelConfig
GrPixelConfigSwapRAndB(GrPixelConfig config)312 static inline GrPixelConfig GrPixelConfigSwapRAndB(GrPixelConfig config) {
313 switch (config) {
314 case kBGRA_8888_GrPixelConfig:
315 return kRGBA_8888_GrPixelConfig;
316 case kRGBA_8888_GrPixelConfig:
317 return kBGRA_8888_GrPixelConfig;
318 default:
319 return kUnknown_GrPixelConfig;
320 }
321 }
322
GrBytesPerPixel(GrPixelConfig config)323 static inline size_t GrBytesPerPixel(GrPixelConfig config) {
324 switch (config) {
325 case kAlpha_8_GrPixelConfig:
326 case kIndex_8_GrPixelConfig:
327 return 1;
328 case kRGB_565_GrPixelConfig:
329 case kRGBA_4444_GrPixelConfig:
330 return 2;
331 case kRGBA_8888_GrPixelConfig:
332 case kBGRA_8888_GrPixelConfig:
333 return 4;
334 default:
335 return 0;
336 }
337 }
338
GrPixelConfigIsOpaque(GrPixelConfig config)339 static inline bool GrPixelConfigIsOpaque(GrPixelConfig config) {
340 switch (config) {
341 case kRGB_565_GrPixelConfig:
342 return true;
343 default:
344 return false;
345 }
346 }
347
GrPixelConfigIsAlphaOnly(GrPixelConfig config)348 static inline bool GrPixelConfigIsAlphaOnly(GrPixelConfig config) {
349 switch (config) {
350 case kAlpha_8_GrPixelConfig:
351 return true;
352 default:
353 return false;
354 }
355 }
356
357 /**
358 * Optional bitfield flags that can be passed to createTexture.
359 */
360 enum GrTextureFlags {
361 kNone_GrTextureFlags = 0x0,
362 /**
363 * Creates a texture that can be rendered to as a GrRenderTarget. Use
364 * GrTexture::asRenderTarget() to access.
365 */
366 kRenderTarget_GrTextureFlagBit = 0x1,
367 /**
368 * By default all render targets have an associated stencil buffer that
369 * may be required for path filling. This flag overrides stencil buffer
370 * creation.
371 * MAKE THIS PRIVATE?
372 */
373 kNoStencil_GrTextureFlagBit = 0x2,
374 /**
375 * Hint that the CPU may modify this texture after creation.
376 */
377 kDynamicUpdate_GrTextureFlagBit = 0x4,
378 /**
379 * Indicates that all allocations (color buffer, FBO completeness, etc)
380 * should be verified.
381 */
382 kCheckAllocation_GrTextureFlagBit = 0x8,
383
384 kDummy_GrTextureFlagBit,
385 kLastPublic_GrTextureFlagBit = kDummy_GrTextureFlagBit-1,
386 };
387
388 GR_MAKE_BITFIELD_OPS(GrTextureFlags)
389
390 enum {
391 /**
392 * For Index8 pixel config, the colortable must be 256 entries
393 */
394 kGrColorTableSize = 256 * 4 //sizeof(GrColor)
395 };
396
397 /**
398 * Some textures will be stored such that the upper and left edges of the content meet at the
399 * the origin (in texture coord space) and for other textures the lower and left edges meet at
400 * the origin. kDefault_GrSurfaceOrigin sets textures to TopLeft, and render targets
401 * to BottomLeft.
402 */
403
404 enum GrSurfaceOrigin {
405 kDefault_GrSurfaceOrigin, // DEPRECATED; to be removed
406 kTopLeft_GrSurfaceOrigin,
407 kBottomLeft_GrSurfaceOrigin,
408 };
409
410 /**
411 * Describes a texture to be created.
412 */
413 struct GrTextureDesc {
GrTextureDescGrTextureDesc414 GrTextureDesc()
415 : fFlags(kNone_GrTextureFlags)
416 , fOrigin(kDefault_GrSurfaceOrigin)
417 , fWidth(0)
418 , fHeight(0)
419 , fConfig(kUnknown_GrPixelConfig)
420 , fSampleCnt(0) {
421 }
422
423 GrTextureFlags fFlags; //!< bitfield of TextureFlags
424 GrSurfaceOrigin fOrigin; //!< origin of the texture
425 int fWidth; //!< Width of the texture
426 int fHeight; //!< Height of the texture
427
428 /**
429 * Format of source data of the texture. Not guaranteed to be the same as
430 * internal format used by 3D API.
431 */
432 GrPixelConfig fConfig;
433
434 /**
435 * The number of samples per pixel or 0 to disable full scene AA. This only
436 * applies if the kRenderTarget_GrTextureFlagBit is set. The actual number
437 * of samples may not exactly match the request. The request will be rounded
438 * up to the next supported sample count, or down if it is larger than the
439 * max supported count.
440 */
441 int fSampleCnt;
442 };
443
444 /**
445 * GrCacheID is used create and find cached GrResources (e.g. GrTextures). The ID has two parts:
446 * the domain and the key. Domains simply allow multiple clients to use 0-based indices as their
447 * cache key without colliding. The key uniquely identifies a GrResource within the domain.
448 * Users of the cache must obtain a domain via GenerateDomain().
449 */
450 struct GrCacheID {
451 public:
452 typedef uint8_t Domain;
453
454 struct Key {
455 union {
456 uint8_t fData8[16];
457 uint32_t fData32[4];
458 uint64_t fData64[2];
459 };
460 };
461
462 /**
463 * A default cache ID is invalid; a set method must be called before the object is used.
464 */
GrCacheIDGrCacheID465 GrCacheID() { fDomain = kInvalid_Domain; }
466
467 /**
468 * Initialize the cache ID to a domain and key.
469 */
GrCacheIDGrCacheID470 GrCacheID(Domain domain, const Key& key) {
471 SkASSERT(kInvalid_Domain != domain);
472 this->reset(domain, key);
473 }
474
resetGrCacheID475 void reset(Domain domain, const Key& key) {
476 fDomain = domain;
477 memcpy(&fKey, &key, sizeof(Key));
478 }
479
480 /** Has this been initialized to a valid domain */
isValidGrCacheID481 bool isValid() const { return kInvalid_Domain != fDomain; }
482
getKeyGrCacheID483 const Key& getKey() const { SkASSERT(this->isValid()); return fKey; }
getDomainGrCacheID484 Domain getDomain() const { SkASSERT(this->isValid()); return fDomain; }
485
486 /** Creates a new unique ID domain. */
487 static Domain GenerateDomain();
488
489 private:
490 Key fKey;
491 Domain fDomain;
492
493 static const Domain kInvalid_Domain = 0;
494 };
495
496 /**
497 * Clips are composed from these objects.
498 */
499 enum GrClipType {
500 kRect_ClipType,
501 kPath_ClipType
502 };
503
504 ///////////////////////////////////////////////////////////////////////////////
505
506 // opaque type for 3D API object handles
507 typedef intptr_t GrBackendObject;
508
509 /**
510 * Gr can wrap an existing texture created by the client with a GrTexture
511 * object. The client is responsible for ensuring that the texture lives at
512 * least as long as the GrTexture object wrapping it. We require the client to
513 * explicitly provide information about the texture, such as width, height,
514 * and pixel config, rather than querying the 3D APIfor these values. We expect
515 * these to be immutable even if the 3D API doesn't require this (OpenGL).
516 *
517 * Textures that are also render targets are supported as well. Gr will manage
518 * any ancillary 3D API (stencil buffer, FBO id, etc) objects necessary for
519 * Gr to draw into the render target. To access the render target object
520 * call GrTexture::asRenderTarget().
521 *
522 * If in addition to the render target flag, the caller also specifies a sample
523 * count Gr will create an MSAA buffer that resolves into the texture. Gr auto-
524 * resolves when it reads from the texture. The client can explictly resolve
525 * using the GrRenderTarget interface.
526 *
527 * Note: These flags currently form a subset of GrTexture's flags.
528 */
529
530 enum GrBackendTextureFlags {
531 /**
532 * No flags enabled
533 */
534 kNone_GrBackendTextureFlag = kNone_GrTextureFlags,
535 /**
536 * Indicates that the texture is also a render target, and thus should have
537 * a GrRenderTarget object.
538 *
539 * D3D (future): client must have created the texture with flags that allow
540 * it to be used as a render target.
541 */
542 kRenderTarget_GrBackendTextureFlag = kRenderTarget_GrTextureFlagBit,
543 };
544 GR_MAKE_BITFIELD_OPS(GrBackendTextureFlags)
545
546 struct GrBackendTextureDesc {
GrBackendTextureDescGrBackendTextureDesc547 GrBackendTextureDesc() { memset(this, 0, sizeof(*this)); }
548 GrBackendTextureFlags fFlags;
549 GrSurfaceOrigin fOrigin;
550 int fWidth; //<! width in pixels
551 int fHeight; //<! height in pixels
552 GrPixelConfig fConfig; //<! color format
553 /**
554 * If the render target flag is set and sample count is greater than 0
555 * then Gr will create an MSAA buffer that resolves to the texture.
556 */
557 int fSampleCnt;
558 /**
559 * Handle to the 3D API object.
560 * OpenGL: Texture ID.
561 */
562 GrBackendObject fTextureHandle;
563 };
564
565 ///////////////////////////////////////////////////////////////////////////////
566
567 /**
568 * Gr can wrap an existing render target created by the client in the 3D API
569 * with a GrRenderTarget object. The client is responsible for ensuring that the
570 * underlying 3D API object lives at least as long as the GrRenderTarget object
571 * wrapping it. We require the client to explicitly provide information about
572 * the target, such as width, height, and pixel config rather than querying the
573 * 3D API for these values. We expect these properties to be immutable even if
574 * the 3D API doesn't require this (OpenGL).
575 */
576
577 struct GrBackendRenderTargetDesc {
GrBackendRenderTargetDescGrBackendRenderTargetDesc578 GrBackendRenderTargetDesc() { memset(this, 0, sizeof(*this)); }
579 int fWidth; //<! width in pixels
580 int fHeight; //<! height in pixels
581 GrPixelConfig fConfig; //<! color format
582 GrSurfaceOrigin fOrigin; //<! pixel origin
583 /**
584 * The number of samples per pixel. Gr uses this to influence decisions
585 * about applying other forms of anti-aliasing.
586 */
587 int fSampleCnt;
588 /**
589 * Number of bits of stencil per-pixel.
590 */
591 int fStencilBits;
592 /**
593 * Handle to the 3D API object.
594 * OpenGL: FBO ID
595 */
596 GrBackendObject fRenderTargetHandle;
597 };
598
599 /**
600 * The GrContext's cache of backend context state can be partially invalidated.
601 * These enums are specific to the GL backend and we'd add a new set for an alternative backend.
602 */
603 enum GrGLBackendState {
604 kRenderTarget_GrGLBackendState = 1 << 0,
605 kTextureBinding_GrGLBackendState = 1 << 1,
606 // View state stands for scissor and viewport
607 kView_GrGLBackendState = 1 << 2,
608 kBlend_GrGLBackendState = 1 << 3,
609 kAA_GrGLBackendState = 1 << 4,
610 kVertex_GrGLBackendState = 1 << 5,
611 kStencil_GrGLBackendState = 1 << 6,
612 kPixelStore_GrGLBackendState = 1 << 7,
613 kProgram_GrGLBackendState = 1 << 8,
614 kFixedFunction_GrGLBackendState = 1 << 9,
615 kMisc_GrGLBackendState = 1 << 10,
616 kPathRendering_GrGLBackendState = 1 << 11,
617 kALL_GrGLBackendState = 0xffff
618 };
619
620 /**
621 * This value translates to reseting all the context state for any backend.
622 */
623 static const uint32_t kAll_GrBackendState = 0xffffffff;
624
625 ///////////////////////////////////////////////////////////////////////////////
626
627 #endif
628