1/*
2    Copyright 2010 Google Inc.
3
4    Licensed under the Apache License, Version 2.0 (the "License");
5    you may not use this file except in compliance with the License.
6    You may obtain a copy of the License at
7
8         http://www.apache.org/licenses/LICENSE-2.0
9
10    Unless required by applicable law or agreed to in writing, software
11    distributed under the License is distributed on an "AS IS" BASIS,
12    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13    See the License for the specific language governing permissions and
14    limitations under the License.
15 */
16
17
18#ifndef GrConfig_DEFINED
19#define GrConfig_DEFINED
20
21///////////////////////////////////////////////////////////////////////////////
22// preconfig section:
23//
24// All the work before including GrUserConfig.h should center around guessing
25// what platform we're on, and defining low-level symbols based on that.
26//
27// A build environment may have already defined symbols, so we first check
28// for that
29//
30
31// hack to ensure we know what sort of Apple platform we're on
32#if defined(__APPLE_CPP__) || defined(__APPLE_CC__)
33    #include <TargetConditionals.h>
34#endif
35
36/**
37 *  Gr defines are set to 0 or 1, rather than being undefined or defined
38 */
39
40#if !defined(GR_ANDROID_BUILD)
41    #define GR_ANDROID_BUILD    0
42#endif
43#if !defined(GR_IOS_BUILD)
44    #define GR_IOS_BUILD        0
45#endif
46#if !defined(GR_LINUX_BUILD)
47    #define GR_LINUX_BUILD      0
48#endif
49#if !defined(GR_MAC_BUILD)
50    #define GR_MAC_BUILD        0
51#endif
52#if !defined(GR_WIN32_BUILD)
53    #define GR_WIN32_BUILD      0
54#endif
55#if !defined(GR_QNX_BUILD)
56    #define GR_QNX_BUILD        0
57#endif
58
59/**
60 *  If no build target has been defined, attempt to infer.
61 */
62#if !GR_ANDROID_BUILD && !GR_IOS_BUILD && !GR_LINUX_BUILD && !GR_MAC_BUILD && !GR_WIN32_BUILD && !GR_QNX_BUILD
63    #if defined(_WIN32)
64        #undef GR_WIN32_BUILD
65        #define GR_WIN32_BUILD      1
66//      #error "WIN"
67    #elif TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
68        #undef GR_IOS_BUILD
69        #define GR_IOS_BUILD        1
70//      #error "IOS"
71    #elif (defined(ANDROID_NDK) && ANDROID_NDK) || defined(ANDROID)
72        #undef GR_ANDROID_BUILD
73        #define GR_ANDROID_BUILD    1
74//      #error "ANDROID"
75    #elif TARGET_OS_MAC
76        #undef GR_MAC_BUILD
77        #define GR_MAC_BUILD        1
78//      #error "MAC"
79    #elif TARGET_OS_QNX || defined(__QNXNTO__)
80        #undef GR_QNX_BUILD
81        #define GR_QNX_BUILD        1
82//      #error "QNX"
83    #else
84        #undef GR_LINUX_BUILD
85        #define GR_LINUX_BUILD      1
86//      #error "LINUX"
87    #endif
88#endif
89
90// we need both GR_DEBUG and GR_RELEASE to be defined as 0 or 1
91//
92#ifndef GR_DEBUG
93    #ifdef GR_RELEASE
94        #define GR_DEBUG !GR_RELEASE
95    #else
96        #ifdef NDEBUG
97            #define GR_DEBUG    0
98        #else
99            #define GR_DEBUG    1
100        #endif
101    #endif
102#endif
103
104#ifndef GR_RELEASE
105    #define GR_RELEASE  !GR_DEBUG
106#endif
107
108#if GR_DEBUG == GR_RELEASE
109    #error "GR_DEBUG and GR_RELEASE must not be the same"
110#endif
111
112///////////////////////////////////////////////////////////////////////////////
113///////////////////////////////////////////////////////////////////////////////
114
115#if GR_WIN32_BUILD
116// VC8 doesn't support stdint.h, so we define those types here.
117typedef signed char int8_t;
118typedef unsigned char uint8_t;
119typedef short int16_t;
120typedef unsigned short uint16_t;
121typedef int int32_t;
122typedef unsigned uint32_t;
123typedef __int64 int64_t;
124typedef unsigned __int64 uint64_t;
125#else
126/*
127 *  Include stdint.h with defines that trigger declaration of C99 limit/const
128 *  macros here before anyone else has a chance to include stdint.h without
129 *  these.
130 */
131#define __STDC_LIMIT_MACROS
132#define __STDC_CONSTANT_MACROS
133#include <stdint.h>
134#endif
135
136/*
137 *  The "user config" file can be empty, and everything should work. It is
138 *  meant to store a given platform/client's overrides of our guess-work.
139 *
140 *  A alternate user config file can be specified by defining
141 *  GR_USER_CONFIG_FILE. It should be defined relative to GrConfig.h
142 *
143 *  e.g. it can specify GR_DEBUG/GR_RELEASE as it please, change the BUILD
144 *  target, or supply its own defines for anything else (e.g. GR_SCALAR)
145 */
146#if !defined(GR_USER_CONFIG_FILE)
147    #include "GrUserConfig.h"
148#else
149    #include GR_USER_CONFIG_FILE
150#endif
151
152
153///////////////////////////////////////////////////////////////////////////////
154///////////////////////////////////////////////////////////////////////////////
155// postconfig section:
156//
157
158// GR_IMPLEMENTATION should be define to 1 when building Gr and 0 when including
159// it in another dependent build. The Gr makefile/ide-project should define this
160// to 1.
161#if !defined(GR_IMPLEMENTATION)
162    #define GR_IMPLEMENTATION 0
163#endif
164
165// If Gr is built as a shared library then GR_DLL should be defined to 1 (both
166// when building Gr and when including its headers in dependent builds). Only
167// currently supported minimally for Chrome's Win32 Multi-DLL build (TODO:
168// correctly exort all of the public API correctly and support shared lib on
169// other platforms).
170#if !defined(GR_DLL)
171    #define GR_DLL 0
172#endif
173
174#if GR_DLL
175    #if GR_WIN32_BUILD
176        #if GR_IMPLEMENTATION
177            #define GR_API __declspec(dllexport)
178        #else
179            #define GR_API __declspec(dllimport)
180        #endif
181    #else
182        #define GR_API __attribute__((visibility("default")))
183    #endif
184#else
185    #define GR_API
186#endif
187
188// By now we must have a GR_..._BUILD symbol set to 1, and a decision about
189// debug -vs- release
190//
191
192extern GR_API void GrPrintf(const char format[], ...);
193
194/**
195 *  GR_STRING makes a string of X where X is expanded before conversion to a string
196 *  if X itself contains macros.
197 */
198#define GR_STRING(X) GR_STRING_IMPL(X)
199#define GR_STRING_IMPL(X) #X
200
201/**
202 *  GR_CONCAT concatenates X and Y  where each is expanded before
203 *  contanenation if either contains macros.
204 */
205#define GR_CONCAT(X,Y) GR_CONCAT_IMPL(X,Y)
206#define GR_CONCAT_IMPL(X,Y) X##Y
207
208/**
209 *  Creates a string of the form "<filename>(<linenumber>) : "
210 */
211#define GR_FILE_AND_LINE_STR __FILE__ "(" GR_STRING(__LINE__) ") : "
212
213/**
214 *  Compilers have different ways of issuing warnings. This macro
215 *  attempts to abstract them, but may need to be specialized for your
216 *  particular compiler.
217 *  To insert compiler warnings use "#pragma message GR_WARN(<string>)"
218 */
219#if defined(_MSC_VER) && _MSC_VER
220    #define GR_WARN(MSG) (GR_FILE_AND_LINE_STR "WARNING: " MSG)
221#else//__GNUC__ - may need other defines for different compilers
222    #define GR_WARN(MSG) ("WARNING: " MSG)
223#endif
224
225/**
226 *  GR_ALWAYSBREAK is an unconditional break in all builds.
227 */
228#if !defined(GR_ALWAYSBREAK)
229    #if     GR_WIN32_BUILD
230        #define GR_ALWAYSBREAK __debugbreak()
231    #else
232        // TODO: do other platforms really not have continuable breakpoints?
233        // sign extend for 64bit architectures to be sure this is
234        // in the high address range
235        #define GR_ALWAYSBREAK *((int*)(int64_t)(int32_t)0xbeefcafe) = 0;
236    #endif
237#endif
238
239/**
240 *  GR_DEBUGBREAK is an unconditional break in debug builds.
241 */
242#if !defined(GR_DEBUGBREAK)
243    #if GR_DEBUG
244        #define GR_DEBUGBREAK GR_ALWAYSBREAK
245    #else
246        #define GR_DEBUGBREAK
247    #endif
248#endif
249
250/**
251 *  GR_ALWAYSASSERT is an assertion in all builds.
252 */
253#if !defined(GR_ALWAYSASSERT)
254    #define GR_ALWAYSASSERT(COND)                                        \
255        do {                                                             \
256            if (!(COND)) {                                               \
257                GrPrintf("%s %s failed\n", GR_FILE_AND_LINE_STR, #COND); \
258                GR_ALWAYSBREAK;                                          \
259            }                                                            \
260        } while (false)
261#endif
262
263/**
264 *  GR_DEBUGASSERT is an assertion in debug builds only.
265 */
266#if !defined(GR_DEBUGASSERT)
267    #if GR_DEBUG
268        #define GR_DEBUGASSERT(COND) GR_ALWAYSASSERT(COND)
269    #else
270        #define GR_DEBUGASSERT(COND)
271    #endif
272#endif
273
274/**
275 *  Prettier forms of the above macros.
276 */
277#define GrAssert(COND) GR_DEBUGASSERT(COND)
278#define GrAlwaysAssert(COND) GR_ALWAYSASSERT(COND)
279
280/**
281 * Crash from unrecoverable condition, optionally with a message.
282 */
283inline void GrCrash() { GrAlwaysAssert(false); }
284inline void GrCrash(const char* msg) { GrPrintf(msg); GrAlwaysAssert(false); }
285
286/**
287 *  GR_DEBUGCODE compiles the code X in debug builds only
288 */
289#if !defined(GR_DEBUGCODE)
290    #if GR_DEBUG
291        #define GR_DEBUGCODE(X) X
292    #else
293        #define GR_DEBUGCODE(X)
294    #endif
295#endif
296
297/**
298 *  GR_STATIC_ASSERT is a compile time assertion. Depending on the platform
299 *  it may print the message in the compiler log. Obviously, the condition must
300 *  be evaluatable at compile time.
301 */
302// VS 2010 and GCC compiled with c++0x or gnu++0x support the new
303// static_assert.
304#if !defined(GR_STATIC_ASSERT)
305    #if (defined(_MSC_VER) && _MSC_VER >= 1600) || (defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__)
306        #define GR_STATIC_ASSERT(CONDITION) static_assert(CONDITION, "bug")
307    #else
308        template <bool> class GR_STATIC_ASSERT_FAILURE;
309        template <> class GR_STATIC_ASSERT_FAILURE<true> {};
310        #define GR_STATIC_ASSERT(CONDITION) \
311            enum {GR_CONCAT(X,__LINE__) = \
312            sizeof(GR_STATIC_ASSERT_FAILURE<CONDITION>)}
313    #endif
314#endif
315
316#if !defined(GR_SCALAR_IS_FLOAT)
317    #define GR_SCALAR_IS_FLOAT   0
318#endif
319#if !defined(GR_SCALAR_IS_FIXED)
320    #define GR_SCALAR_IS_FIXED   0
321#endif
322
323#if !defined(GR_TEXT_SCALAR_TYPE_IS_USHORT)
324    #define GR_TEXT_SCALAR_TYPE_IS_USHORT  0
325#endif
326#if !defined(GR_TEXT_SCALAR_TYPE_IS_FLOAT)
327    #define GR_TEXT_SCALAR_TYPE_IS_FLOAT   0
328#endif
329#if !defined(GR_TEXT_SCALAR_TYPE_IS_FIXED)
330    #define GR_TEXT_SCALAR_TYPE_IS_FIXED   0
331#endif
332
333#ifndef GR_DUMP_TEXTURE_UPLOAD
334    #define GR_DUMP_TEXTURE_UPLOAD  0
335#endif
336
337/**
338 *  GR_COLLECT_STATS controls whether the GrGpu class collects stats.
339 *  If not already defined then collect in debug build but not release.
340 */
341#if !defined(GR_COLLECT_STATS)
342    #define GR_COLLECT_STATS GR_DEBUG
343#endif
344
345/**
346 *  GR_STATIC_RECT_VB controls whether rects are drawn by issuing a vertex
347 *  for each corner or using a static vb that is positioned by modifying the
348 *  view / texture matrix.
349 */
350#if !defined(GR_STATIC_RECT_VB)
351    #define GR_STATIC_RECT_VB 0
352#endif
353
354/**
355 *  GR_AGGRESSIVE_SHADER_OPTS controls how aggressively shaders are optimized
356 *  for special cases. On systems where program changes are expensive this
357 *  may not be advantageous. Consecutive draws may no longer use the same
358 *  program.
359 */
360#if !defined(GR_AGGRESSIVE_SHADER_OPTS)
361    #define GR_AGGRESSIVE_SHADER_OPTS 0
362#endif
363
364/**
365 * GR_GEOM_BUFFER_LOCK_THRESHOLD gives a threshold (in bytes) for when Gr should
366 * lock a GrGeometryBuffer to update its contents. It will use Lock() if the
367 * size of the udpated region is greater than the threshold. Otherwise it will
368 * use updateData() or updateSubData().
369 */
370#if !defined(GR_GEOM_BUFFER_LOCK_THRESHOLD)
371    #define GR_GEOM_BUFFER_LOCK_THRESHOLD (1 << 15)
372#endif
373
374///////////////////////////////////////////////////////////////////////////////
375// tail section:
376//
377// Now we just assert if we are missing some required define, or if we detect
378// and inconsistent combination of defines
379//
380
381
382/**
383 *  Only one build target macro should be 1 and the rest should be 0.
384 */
385#define GR_BUILD_SUM    (GR_WIN32_BUILD + GR_MAC_BUILD + GR_IOS_BUILD + GR_ANDROID_BUILD + GR_LINUX_BUILD + GR_QNX_BUILD)
386#if 0 == GR_BUILD_SUM
387    #error "Missing a GR_BUILD define"
388#elif 1 != GR_BUILD_SUM
389    #error "More than one GR_BUILD defined"
390#endif
391
392
393#if !GR_SCALAR_IS_FLOAT && !GR_SCALAR_IS_FIXED
394    #undef  GR_SCALAR_IS_FLOAT
395    #define GR_SCALAR_IS_FLOAT              1
396    #pragma message GR_WARN("Scalar type not defined, defaulting to float")
397#endif
398
399#if !GR_TEXT_SCALAR_IS_FLOAT && \
400    !GR_TEXT_SCALAR_IS_FIXED && \
401    !GR_TEXT_SCALAR_IS_USHORT
402    #undef  GR_TEXT_SCALAR_IS_FLOAT
403    #define GR_TEXT_SCALAR_IS_FLOAT         1
404    #pragma message GR_WARN("Text scalar type not defined, defaulting to float")
405#endif
406
407#if 0
408#if GR_WIN32_BUILD
409//    #pragma message GR_WARN("GR_WIN32_BUILD")
410#endif
411#if GR_MAC_BUILD
412//    #pragma message GR_WARN("GR_MAC_BUILD")
413#endif
414#if GR_IOS_BUILD
415//    #pragma message GR_WARN("GR_IOS_BUILD")
416#endif
417#if GR_ANDROID_BUILD
418//    #pragma message GR_WARN("GR_ANDROID_BUILD")
419#endif
420#if GR_LINUX_BUILD
421//    #pragma message GR_WARN("GR_LINUX_BUILD")
422#endif
423#if GR_QNX_BUILD
424//    #pragma message GR_WARN("GR_QNX_BUILD")
425#endif
426#endif
427
428#endif
429
430