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 #ifndef GrTypes_DEFINED
10 #define GrTypes_DEFINED
11
12 #include "SkTypes.h"
13 #include "GrConfig.h"
14 #include "SkMath.h"
15
16 ////////////////////////////////////////////////////////////////////////////////
17
18 /**
19 * Defines overloaded bitwise operators to make it easier to use an enum as a
20 * bitfield.
21 */
22 #define GR_MAKE_BITFIELD_OPS(X) \
23 inline X operator | (X a, X b) { \
24 return (X) (+a | +b); \
25 } \
26 inline X& operator |= (X& a, X b) { \
27 return (a = a | b); \
28 } \
29 \
30 inline X operator & (X a, X b) { \
31 return (X) (+a & +b); \
32 } \
33 template <typename T> \
34 inline X operator & (T a, X b) { \
35 return (X) (+a & +b); \
36 } \
37 template <typename T> \
38 inline X operator & (X a, T b) { \
39 return (X) (+a & +b); \
40 } \
41
42 #define GR_DECL_BITFIELD_OPS_FRIENDS(X) \
43 friend X operator | (X a, X b); \
44 friend X& operator |= (X& a, X b); \
45 \
46 friend X operator & (X a, X b); \
47 \
48 template <typename T> \
49 friend X operator & (T a, X b); \
50 \
51 template <typename T> \
52 friend X operator & (X a, T b); \
53 ////////////////////////////////////////////////////////////////////////////////
54
55 // compile time versions of min/max
56 #define GR_CT_MAX(a, b) (((b) < (a)) ? (a) : (b))
57 #define GR_CT_MIN(a, b) (((b) < (a)) ? (b) : (a))
58
59 /**
60 * divide, rounding up
61 */
GrIDivRoundUp(int x,int y)62 static inline int32_t GrIDivRoundUp(int x, int y) {
63 SkASSERT(y > 0);
64 return (x + (y-1)) / y;
65 }
GrUIDivRoundUp(uint32_t x,uint32_t y)66 static inline uint32_t GrUIDivRoundUp(uint32_t x, uint32_t y) {
67 return (x + (y-1)) / y;
68 }
GrSizeDivRoundUp(size_t x,size_t y)69 static inline size_t GrSizeDivRoundUp(size_t x, size_t y) {
70 return (x + (y-1)) / y;
71 }
72
73 // compile time, evaluates Y multiple times
74 #define GR_CT_DIV_ROUND_UP(X, Y) (((X) + ((Y)-1)) / (Y))
75
76 /**
77 * align up
78 */
GrUIAlignUp(uint32_t x,uint32_t alignment)79 static inline uint32_t GrUIAlignUp(uint32_t x, uint32_t alignment) {
80 return GrUIDivRoundUp(x, alignment) * alignment;
81 }
GrSizeAlignUp(size_t x,size_t alignment)82 static inline size_t GrSizeAlignUp(size_t x, size_t alignment) {
83 return GrSizeDivRoundUp(x, alignment) * alignment;
84 }
85
86 // compile time, evaluates A multiple times
87 #define GR_CT_ALIGN_UP(X, A) (GR_CT_DIV_ROUND_UP((X),(A)) * (A))
88
89 /**
90 * amount of pad needed to align up
91 */
GrUIAlignUpPad(uint32_t x,uint32_t alignment)92 static inline uint32_t GrUIAlignUpPad(uint32_t x, uint32_t alignment) {
93 return (alignment - x % alignment) % alignment;
94 }
GrSizeAlignUpPad(size_t x,size_t alignment)95 static inline size_t GrSizeAlignUpPad(size_t x, size_t alignment) {
96 return (alignment - x % alignment) % alignment;
97 }
98
99 /**
100 * align down
101 */
GrUIAlignDown(uint32_t x,uint32_t alignment)102 static inline uint32_t GrUIAlignDown(uint32_t x, uint32_t alignment) {
103 return (x / alignment) * alignment;
104 }
GrSizeAlignDown(size_t x,uint32_t alignment)105 static inline size_t GrSizeAlignDown(size_t x, uint32_t alignment) {
106 return (x / alignment) * alignment;
107 }
108
109 ///////////////////////////////////////////////////////////////////////////////
110
111 /**
112 * Return the next power of 2 >= n.
113 */
GrNextPow2(uint32_t n)114 static inline uint32_t GrNextPow2(uint32_t n) {
115 return n ? (1 << (32 - SkCLZ(n - 1))) : 1;
116 }
117
GrNextPow2(int n)118 static inline int GrNextPow2(int n) {
119 SkASSERT(n >= 0); // this impl only works for non-neg.
120 return n ? (1 << (32 - SkCLZ(n - 1))) : 1;
121 }
122
123 ///////////////////////////////////////////////////////////////////////////////
124
125 /**
126 * Possible 3D APIs that may be used by Ganesh.
127 */
128 enum GrBackend {
129 kOpenGL_GrBackend,
130 };
131
132 /**
133 * Backend-specific 3D context handle
134 * GrGLInterface* for OpenGL. If NULL will use the default GL interface.
135 */
136 typedef intptr_t GrBackendContext;
137
138 ///////////////////////////////////////////////////////////////////////////////
139
140 /**
141 * Geometric primitives used for drawing.
142 */
143 enum GrPrimitiveType {
144 kTriangles_GrPrimitiveType,
145 kTriangleStrip_GrPrimitiveType,
146 kTriangleFan_GrPrimitiveType,
147 kPoints_GrPrimitiveType,
148 kLines_GrPrimitiveType, // 1 pix wide only
149 kLineStrip_GrPrimitiveType, // 1 pix wide only
150 kLast_GrPrimitiveType = kLineStrip_GrPrimitiveType
151 };
152
GrIsPrimTypeLines(GrPrimitiveType type)153 static inline bool GrIsPrimTypeLines(GrPrimitiveType type) {
154 return kLines_GrPrimitiveType == type || kLineStrip_GrPrimitiveType == type;
155 }
156
GrIsPrimTypeTris(GrPrimitiveType type)157 static inline bool GrIsPrimTypeTris(GrPrimitiveType type) {
158 return kTriangles_GrPrimitiveType == type ||
159 kTriangleStrip_GrPrimitiveType == type ||
160 kTriangleFan_GrPrimitiveType == type;
161 }
162
163 /**
164 * Formats for masks, used by the font cache.
165 * Important that these are 0-based.
166 */
167 enum GrMaskFormat {
168 kA8_GrMaskFormat, //!< 1-byte per pixel
169 kA565_GrMaskFormat, //!< 2-bytes per pixel, RGB represent 3-channel LCD coverage
170 kARGB_GrMaskFormat, //!< 4-bytes per pixel, color format
171
172 kLast_GrMaskFormat = kARGB_GrMaskFormat
173 };
174 static const int kMaskFormatCount = kLast_GrMaskFormat + 1;
175
176 /**
177 * Return the number of bytes-per-pixel for the specified mask format.
178 */
GrMaskFormatBytesPerPixel(GrMaskFormat format)179 static inline int GrMaskFormatBytesPerPixel(GrMaskFormat format) {
180 SkASSERT((unsigned)format < kMaskFormatCount);
181 // kA8 (0) -> 1
182 // kA565 (1) -> 2
183 // kARGB (2) -> 4
184 static const int sBytesPerPixel[] = { 1, 2, 4 };
185 SK_COMPILE_ASSERT(SK_ARRAY_COUNT(sBytesPerPixel) == kMaskFormatCount, array_size_mismatch);
186 SK_COMPILE_ASSERT(kA8_GrMaskFormat == 0, enum_order_dependency);
187 SK_COMPILE_ASSERT(kA565_GrMaskFormat == 1, enum_order_dependency);
188 SK_COMPILE_ASSERT(kARGB_GrMaskFormat == 2, enum_order_dependency);
189
190 return sBytesPerPixel[(int) format];
191 }
192
193 /**
194 * Pixel configurations.
195 */
196 enum GrPixelConfig {
197 kUnknown_GrPixelConfig,
198 kAlpha_8_GrPixelConfig,
199 kIndex_8_GrPixelConfig,
200 kRGB_565_GrPixelConfig,
201 /**
202 * Premultiplied
203 */
204 kRGBA_4444_GrPixelConfig,
205 /**
206 * Premultiplied. Byte order is r,g,b,a.
207 */
208 kRGBA_8888_GrPixelConfig,
209 /**
210 * Premultiplied. Byte order is b,g,r,a.
211 */
212 kBGRA_8888_GrPixelConfig,
213 /**
214 * Premultiplied and sRGB. Byte order is r,g,b,a.
215 */
216 kSRGBA_8888_GrPixelConfig,
217 /**
218 * ETC1 Compressed Data
219 */
220 kETC1_GrPixelConfig,
221 /**
222 * LATC/RGTC/3Dc/BC4 Compressed Data
223 */
224 kLATC_GrPixelConfig,
225 /**
226 * R11 EAC Compressed Data
227 * (Corresponds to section C.3.5 of the OpenGL 4.4 core profile spec)
228 */
229 kR11_EAC_GrPixelConfig,
230
231 /**
232 * 12x12 ASTC Compressed Data
233 * ASTC stands for Adaptive Scalable Texture Compression. It is a technique
234 * that allows for a lot of customization in the compressed representataion
235 * of a block. The only thing fixed in the representation is the block size,
236 * which means that a texture that contains ASTC data must be treated as
237 * having RGBA values. However, there are single-channel encodings which set
238 * the alpha to opaque and all three RGB channels equal effectively making the
239 * compression format a single channel such as R11 EAC and LATC.
240 */
241 kASTC_12x12_GrPixelConfig,
242
243 /**
244 * Byte order is r, g, b, a. This color format is 32 bits per channel
245 */
246 kRGBA_float_GrPixelConfig,
247
248 /**
249 * This color format is a single 16 bit float channel
250 */
251 kAlpha_half_GrPixelConfig,
252
253 kLast_GrPixelConfig = kAlpha_half_GrPixelConfig
254 };
255 static const int kGrPixelConfigCnt = kLast_GrPixelConfig + 1;
256
257 // Aliases for pixel configs that match skia's byte order.
258 #ifndef SK_CPU_LENDIAN
259 #error "Skia gpu currently assumes little endian"
260 #endif
261 #if SK_PMCOLOR_BYTE_ORDER(B,G,R,A)
262 static const GrPixelConfig kSkia8888_GrPixelConfig = kBGRA_8888_GrPixelConfig;
263 #elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A)
264 static const GrPixelConfig kSkia8888_GrPixelConfig = kRGBA_8888_GrPixelConfig;
265 #else
266 #error "SK_*32_SHIFT values must correspond to GL_BGRA or GL_RGBA format."
267 #endif
268
269 // Returns true if the pixel config is a GPU-specific compressed format
270 // representation.
GrPixelConfigIsCompressed(GrPixelConfig config)271 static inline bool GrPixelConfigIsCompressed(GrPixelConfig config) {
272 switch (config) {
273 case kIndex_8_GrPixelConfig:
274 case kETC1_GrPixelConfig:
275 case kLATC_GrPixelConfig:
276 case kR11_EAC_GrPixelConfig:
277 case kASTC_12x12_GrPixelConfig:
278 return true;
279 default:
280 return false;
281 }
282 }
283
284 /** If the pixel config is compressed, return an equivalent uncompressed format. */
GrMakePixelConfigUncompressed(GrPixelConfig config)285 static inline GrPixelConfig GrMakePixelConfigUncompressed(GrPixelConfig config) {
286 switch (config) {
287 case kIndex_8_GrPixelConfig:
288 case kETC1_GrPixelConfig:
289 case kASTC_12x12_GrPixelConfig:
290 return kRGBA_8888_GrPixelConfig;
291 case kLATC_GrPixelConfig:
292 case kR11_EAC_GrPixelConfig:
293 return kAlpha_8_GrPixelConfig;
294 default:
295 SkASSERT(!GrPixelConfigIsCompressed(config));
296 return config;
297 }
298 }
299
300 // Returns true if the pixel config is 32 bits per pixel
GrPixelConfigIs8888(GrPixelConfig config)301 static inline bool GrPixelConfigIs8888(GrPixelConfig config) {
302 switch (config) {
303 case kRGBA_8888_GrPixelConfig:
304 case kBGRA_8888_GrPixelConfig:
305 case kSRGBA_8888_GrPixelConfig:
306 return true;
307 default:
308 return false;
309 }
310 }
311
312 // Takes a config and returns the equivalent config with the R and B order
313 // swapped if such a config exists. Otherwise, kUnknown_GrPixelConfig
GrPixelConfigSwapRAndB(GrPixelConfig config)314 static inline GrPixelConfig GrPixelConfigSwapRAndB(GrPixelConfig config) {
315 switch (config) {
316 case kBGRA_8888_GrPixelConfig:
317 return kRGBA_8888_GrPixelConfig;
318 case kRGBA_8888_GrPixelConfig:
319 return kBGRA_8888_GrPixelConfig;
320 default:
321 return kUnknown_GrPixelConfig;
322 }
323 }
324
GrBytesPerPixel(GrPixelConfig config)325 static inline size_t GrBytesPerPixel(GrPixelConfig config) {
326 SkASSERT(!GrPixelConfigIsCompressed(config));
327 switch (config) {
328 case kAlpha_8_GrPixelConfig:
329 return 1;
330 case kRGB_565_GrPixelConfig:
331 case kRGBA_4444_GrPixelConfig:
332 case kAlpha_half_GrPixelConfig:
333 return 2;
334 case kRGBA_8888_GrPixelConfig:
335 case kBGRA_8888_GrPixelConfig:
336 case kSRGBA_8888_GrPixelConfig:
337 return 4;
338 case kRGBA_float_GrPixelConfig:
339 return 16;
340 default:
341 return 0;
342 }
343 }
344
GrUnpackAlignment(GrPixelConfig config)345 static inline size_t GrUnpackAlignment(GrPixelConfig config) {
346 SkASSERT(!GrPixelConfigIsCompressed(config));
347 switch (config) {
348 case kAlpha_8_GrPixelConfig:
349 return 1;
350 case kRGB_565_GrPixelConfig:
351 case kRGBA_4444_GrPixelConfig:
352 case kAlpha_half_GrPixelConfig:
353 return 2;
354 case kRGBA_8888_GrPixelConfig:
355 case kBGRA_8888_GrPixelConfig:
356 case kSRGBA_8888_GrPixelConfig:
357 case kRGBA_float_GrPixelConfig:
358 return 4;
359 default:
360 return 0;
361 }
362 }
363
GrPixelConfigIsOpaque(GrPixelConfig config)364 static inline bool GrPixelConfigIsOpaque(GrPixelConfig config) {
365 switch (config) {
366 case kETC1_GrPixelConfig:
367 case kRGB_565_GrPixelConfig:
368 return true;
369 default:
370 return false;
371 }
372 }
373
GrPixelConfigIsAlphaOnly(GrPixelConfig config)374 static inline bool GrPixelConfigIsAlphaOnly(GrPixelConfig config) {
375 switch (config) {
376 case kR11_EAC_GrPixelConfig:
377 case kLATC_GrPixelConfig:
378 case kASTC_12x12_GrPixelConfig:
379 case kAlpha_8_GrPixelConfig:
380 case kAlpha_half_GrPixelConfig:
381 return true;
382 default:
383 return false;
384 }
385 }
386
387 /**
388 * Optional bitfield flags that can be set on GrSurfaceDesc (below).
389 */
390 enum GrSurfaceFlags {
391 kNone_GrSurfaceFlags = 0x0,
392 /**
393 * Creates a texture that can be rendered to as a GrRenderTarget. Use
394 * GrTexture::asRenderTarget() to access.
395 */
396 kRenderTarget_GrSurfaceFlag = 0x1,
397 /**
398 * Indicates that all allocations (color buffer, FBO completeness, etc)
399 * should be verified.
400 */
401 kCheckAllocation_GrSurfaceFlag = 0x4,
402 };
403
404 GR_MAKE_BITFIELD_OPS(GrSurfaceFlags)
405
406 /**
407 * Some textures will be stored such that the upper and left edges of the content meet at the
408 * the origin (in texture coord space) and for other textures the lower and left edges meet at
409 * the origin. kDefault_GrSurfaceOrigin sets textures to TopLeft, and render targets
410 * to BottomLeft.
411 */
412
413 enum GrSurfaceOrigin {
414 kDefault_GrSurfaceOrigin, // DEPRECATED; to be removed
415 kTopLeft_GrSurfaceOrigin,
416 kBottomLeft_GrSurfaceOrigin,
417 };
418
419 /**
420 * Describes a surface to be created.
421 */
422 struct GrSurfaceDesc {
GrSurfaceDescGrSurfaceDesc423 GrSurfaceDesc()
424 : fFlags(kNone_GrSurfaceFlags)
425 , fOrigin(kDefault_GrSurfaceOrigin)
426 , fWidth(0)
427 , fHeight(0)
428 , fConfig(kUnknown_GrPixelConfig)
429 , fSampleCnt(0) {
430 }
431
432 GrSurfaceFlags fFlags; //!< bitfield of TextureFlags
433 GrSurfaceOrigin fOrigin; //!< origin of the texture
434 int fWidth; //!< Width of the texture
435 int fHeight; //!< Height of the texture
436
437 /**
438 * Format of source data of the texture. Not guaranteed to be the same as
439 * internal format used by 3D API.
440 */
441 GrPixelConfig fConfig;
442
443 /**
444 * The number of samples per pixel or 0 to disable full scene AA. This only
445 * applies if the kRenderTarget_GrSurfaceFlag is set. The actual number
446 * of samples may not exactly match the request. The request will be rounded
447 * up to the next supported sample count, or down if it is larger than the
448 * max supported count.
449 */
450 int fSampleCnt;
451 };
452
453 // Legacy alias
454 typedef GrSurfaceDesc GrTextureDesc;
455
456 /**
457 * Clips are composed from these objects.
458 */
459 enum GrClipType {
460 kRect_ClipType,
461 kPath_ClipType
462 };
463
464 ///////////////////////////////////////////////////////////////////////////////
465
466 // opaque type for 3D API object handles
467 typedef intptr_t GrBackendObject;
468
469 /**
470 * Gr can wrap an existing texture created by the client with a GrTexture
471 * object. The client is responsible for ensuring that the texture lives at
472 * least as long as the GrTexture object wrapping it. We require the client to
473 * explicitly provide information about the texture, such as width, height,
474 * and pixel config, rather than querying the 3D APIfor these values. We expect
475 * these to be immutable even if the 3D API doesn't require this (OpenGL).
476 *
477 * Textures that are also render targets are supported as well. Gr will manage
478 * any ancillary 3D API (stencil buffer, FBO id, etc) objects necessary for
479 * Gr to draw into the render target. To access the render target object
480 * call GrTexture::asRenderTarget().
481 *
482 * If in addition to the render target flag, the caller also specifies a sample
483 * count Gr will create an MSAA buffer that resolves into the texture. Gr auto-
484 * resolves when it reads from the texture. The client can explictly resolve
485 * using the GrRenderTarget interface.
486 *
487 * Note: These flags currently form a subset of GrTexture's flags.
488 */
489
490 enum GrBackendTextureFlags {
491 /**
492 * No flags enabled
493 */
494 kNone_GrBackendTextureFlag = 0,
495 /**
496 * Indicates that the texture is also a render target, and thus should have
497 * a GrRenderTarget object.
498 */
499 kRenderTarget_GrBackendTextureFlag = kRenderTarget_GrSurfaceFlag,
500 };
501 GR_MAKE_BITFIELD_OPS(GrBackendTextureFlags)
502
503 struct GrBackendTextureDesc {
GrBackendTextureDescGrBackendTextureDesc504 GrBackendTextureDesc() { memset(this, 0, sizeof(*this)); }
505 GrBackendTextureFlags fFlags;
506 GrSurfaceOrigin fOrigin;
507 int fWidth; //<! width in pixels
508 int fHeight; //<! height in pixels
509 GrPixelConfig fConfig; //<! color format
510 /**
511 * If the render target flag is set and sample count is greater than 0
512 * then Gr will create an MSAA buffer that resolves to the texture.
513 */
514 int fSampleCnt;
515 /**
516 * Handle to the 3D API object.
517 * OpenGL: Texture ID.
518 */
519 GrBackendObject fTextureHandle;
520 };
521
522 ///////////////////////////////////////////////////////////////////////////////
523
524 /**
525 * Gr can wrap an existing render target created by the client in the 3D API
526 * with a GrRenderTarget object. The client is responsible for ensuring that the
527 * underlying 3D API object lives at least as long as the GrRenderTarget object
528 * wrapping it. We require the client to explicitly provide information about
529 * the target, such as width, height, and pixel config rather than querying the
530 * 3D API for these values. We expect these properties to be immutable even if
531 * the 3D API doesn't require this (OpenGL).
532 */
533
534 struct GrBackendRenderTargetDesc {
GrBackendRenderTargetDescGrBackendRenderTargetDesc535 GrBackendRenderTargetDesc() { memset(this, 0, sizeof(*this)); }
536 int fWidth; //<! width in pixels
537 int fHeight; //<! height in pixels
538 GrPixelConfig fConfig; //<! color format
539 GrSurfaceOrigin fOrigin; //<! pixel origin
540 /**
541 * The number of samples per pixel. Gr uses this to influence decisions
542 * about applying other forms of anti-aliasing.
543 */
544 int fSampleCnt;
545 /**
546 * Number of bits of stencil per-pixel.
547 */
548 int fStencilBits;
549 /**
550 * Handle to the 3D API object.
551 * OpenGL: FBO ID
552 */
553 GrBackendObject fRenderTargetHandle;
554 };
555
556 /**
557 * The GrContext's cache of backend context state can be partially invalidated.
558 * These enums are specific to the GL backend and we'd add a new set for an alternative backend.
559 */
560 enum GrGLBackendState {
561 kRenderTarget_GrGLBackendState = 1 << 0,
562 kTextureBinding_GrGLBackendState = 1 << 1,
563 // View state stands for scissor and viewport
564 kView_GrGLBackendState = 1 << 2,
565 kBlend_GrGLBackendState = 1 << 3,
566 kMSAAEnable_GrGLBackendState = 1 << 4,
567 kVertex_GrGLBackendState = 1 << 5,
568 kStencil_GrGLBackendState = 1 << 6,
569 kPixelStore_GrGLBackendState = 1 << 7,
570 kProgram_GrGLBackendState = 1 << 8,
571 kFixedFunction_GrGLBackendState = 1 << 9,
572 kMisc_GrGLBackendState = 1 << 10,
573 kPathRendering_GrGLBackendState = 1 << 11,
574 kALL_GrGLBackendState = 0xffff
575 };
576
577 /**
578 * Returns the data size for the given compressed pixel config
579 */
GrCompressedFormatDataSize(GrPixelConfig config,int width,int height)580 static inline size_t GrCompressedFormatDataSize(GrPixelConfig config,
581 int width, int height) {
582 SkASSERT(GrPixelConfigIsCompressed(config));
583 static const int kGrIndex8TableSize = 256 * 4; // 4 == sizeof(GrColor)
584
585 switch (config) {
586 case kIndex_8_GrPixelConfig:
587 return width * height + kGrIndex8TableSize;
588 case kR11_EAC_GrPixelConfig:
589 case kLATC_GrPixelConfig:
590 case kETC1_GrPixelConfig:
591 SkASSERT((width & 3) == 0);
592 SkASSERT((height & 3) == 0);
593 return (width >> 2) * (height >> 2) * 8;
594
595 case kASTC_12x12_GrPixelConfig:
596 SkASSERT((width % 12) == 0);
597 SkASSERT((height % 12) == 0);
598 return (width / 12) * (height / 12) * 16;
599
600 default:
601 SkFAIL("Unknown compressed pixel config");
602 return 4 * width * height;
603 }
604 }
605
606 /**
607 * This value translates to reseting all the context state for any backend.
608 */
609 static const uint32_t kAll_GrBackendState = 0xffffffff;
610
611 ///////////////////////////////////////////////////////////////////////////////
612
613 #if GR_ALWAYS_ALLOCATE_ON_HEAP
614 #define GrAutoMallocBaseType SkAutoMalloc
615 #else
616 #define GrAutoMallocBaseType SkAutoSMalloc<S>
617 #endif
618
619 template <size_t S> class GrAutoMalloc : public GrAutoMallocBaseType {
620 public:
GrAutoMalloc()621 GrAutoMalloc() : INHERITED() {}
GrAutoMalloc(size_t size)622 explicit GrAutoMalloc(size_t size) : INHERITED(size) {}
~GrAutoMalloc()623 virtual ~GrAutoMalloc() {}
624 private:
625 typedef GrAutoMallocBaseType INHERITED;
626 };
627
628 #undef GrAutoMallocBaseType
629 #endif
630