reed@google.com | ac10a2d | 2010-12-22 21:39:39 +0000 | [diff] [blame] | 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" |
reed@google.com | c921843 | 2011-01-25 19:05:12 +0000 | [diff] [blame] | 71 | #elif (defined(ANDROID_NDK) && ANDROID_NDK) || defined(ANDROID) |
reed@google.com | ac10a2d | 2010-12-22 21:39:39 +0000 | [diff] [blame] | 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 | |
reed@google.com | c921843 | 2011-01-25 19:05:12 +0000 | [diff] [blame] | 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 |
reed@google.com | ac10a2d | 2010-12-22 21:39:39 +0000 | [diff] [blame] | 95 | #else |
reed@google.com | c921843 | 2011-01-25 19:05:12 +0000 | [diff] [blame] | 96 | #ifdef NDEBUG |
| 97 | #define GR_DEBUG 0 |
| 98 | #else |
| 99 | #define GR_DEBUG 1 |
| 100 | #endif |
reed@google.com | ac10a2d | 2010-12-22 21:39:39 +0000 | [diff] [blame] | 101 | #endif |
reed@google.com | c921843 | 2011-01-25 19:05:12 +0000 | [diff] [blame] | 102 | #endif |
| 103 | |
| 104 | #ifndef GR_RELEASE |
reed@google.com | ac10a2d | 2010-12-22 21:39:39 +0000 | [diff] [blame] | 105 | #define GR_RELEASE !GR_DEBUG |
| 106 | #endif |
| 107 | |
reed@google.com | c921843 | 2011-01-25 19:05:12 +0000 | [diff] [blame] | 108 | #if GR_DEBUG == GR_RELEASE |
reed@google.com | 8752ad7 | 2011-01-26 04:55:57 +0000 | [diff] [blame] | 109 | #error "GR_DEBUG and GR_RELEASE must not be the same" |
reed@google.com | c921843 | 2011-01-25 19:05:12 +0000 | [diff] [blame] | 110 | #endif |
| 111 | |
reed@google.com | ac10a2d | 2010-12-22 21:39:39 +0000 | [diff] [blame] | 112 | /////////////////////////////////////////////////////////////////////////////// |
| 113 | /////////////////////////////////////////////////////////////////////////////// |
| 114 | |
| 115 | /* |
| 116 | * Pull stdint.h in before user-config, to be sure our __STDC... macros are |
| 117 | * defined before anyone else might try to include stdint.h |
| 118 | */ |
| 119 | #define __STDC_LIMIT_MACROS |
| 120 | #define __STDC_CONSTANT_MACROS |
| 121 | #include <stdint.h> |
| 122 | |
| 123 | /* |
| 124 | * The "user config" file can be empty, and everything should work. It is |
| 125 | * meant to store a given platform/client's overrides of our guess-work. |
| 126 | * |
| 127 | * A alternate user config file can be specified by defining |
| 128 | * GR_USER_CONFIG_FILE. It should be defined relative to GrConfig.h |
| 129 | * |
| 130 | * e.g. it can specify GR_DEBUG/GR_RELEASE as it please, change the BUILD |
| 131 | * target, or supply its own defines for anything else (e.g. GR_SCALAR) |
| 132 | */ |
| 133 | #if !defined(GR_USER_CONFIG_FILE) |
| 134 | #include "GrUserConfig.h" |
| 135 | #else |
| 136 | #include GR_USER_CONFIG_FILE |
| 137 | #endif |
| 138 | |
| 139 | |
| 140 | /////////////////////////////////////////////////////////////////////////////// |
| 141 | /////////////////////////////////////////////////////////////////////////////// |
| 142 | // postconfig section: |
| 143 | // |
| 144 | // By now we must have a GR_..._BUILD symbol set to 1, and a decision about |
| 145 | // debug -vs- release |
| 146 | // |
| 147 | |
| 148 | extern void GrPrintf(const char format[], ...); |
| 149 | |
| 150 | /** |
| 151 | * GR_STRING makes a string of X where X is expanded before conversion to a string |
| 152 | * if X itself contains macros. |
| 153 | */ |
| 154 | #define GR_STRING(X) GR_STRING_IMPL(X) |
| 155 | #define GR_STRING_IMPL(X) #X |
| 156 | |
| 157 | /** |
| 158 | * GR_CONCAT concatenates X and Y where each is expanded before |
| 159 | * contanenation if either contains macros. |
| 160 | */ |
| 161 | #define GR_CONCAT(X,Y) GR_CONCAT_IMPL(X,Y) |
| 162 | #define GR_CONCAT_IMPL(X,Y) X##Y |
| 163 | |
| 164 | /** |
| 165 | * Creates a string of the form "<filename>(<linenumber>) : " |
| 166 | */ |
| 167 | #define GR_FILE_AND_LINE_STR __FILE__ "(" GR_STRING(__LINE__) ") : " |
| 168 | |
| 169 | /** |
| 170 | * Compilers have different ways of issuing warnings. This macro |
| 171 | * attempts to abstract them, but may need to be specialized for your |
| 172 | * particular compiler. |
| 173 | * To insert compiler warnings use "#pragma message GR_WARN(<string>)" |
| 174 | */ |
reed@google.com | c921843 | 2011-01-25 19:05:12 +0000 | [diff] [blame] | 175 | #if defined(_MSC_VER) && _MSC_VER |
reed@google.com | ac10a2d | 2010-12-22 21:39:39 +0000 | [diff] [blame] | 176 | #define GR_WARN(MSG) (GR_FILE_AND_LINE_STR "WARNING: " MSG) |
| 177 | #else//__GNUC__ - may need other defines for different compilers |
| 178 | #define GR_WARN(MSG) ("WARNING: " MSG) |
| 179 | #endif |
| 180 | |
| 181 | /** |
| 182 | * GR_ALWAYSBREAK is an unconditional break in all builds. |
| 183 | */ |
| 184 | #if !defined(GR_ALWAYSBREAK) |
| 185 | #if GR_WIN32_BUILD |
| 186 | #define GR_ALWAYSBREAK __debugbreak() |
| 187 | #else |
| 188 | // TODO: do other platforms really not have continuable breakpoints? |
| 189 | // sign extend for 64bit architectures to be sure this is |
| 190 | // in the high address range |
| 191 | #define GR_ALWAYSBREAK *((int*)(int64_t)(int32_t)0xbeefcafe) = 0; |
| 192 | #endif |
| 193 | #endif |
| 194 | |
| 195 | /** |
| 196 | * GR_DEBUGBREAK is an unconditional break in debug builds. |
| 197 | */ |
| 198 | #if !defined(GR_DEBUGBREAK) |
| 199 | #if GR_DEBUG |
| 200 | #define GR_DEBUGBREAK GR_ALWAYSBREAK |
| 201 | #else |
| 202 | #define GR_DEBUGBREAK |
| 203 | #endif |
| 204 | #endif |
| 205 | |
| 206 | /** |
| 207 | * GR_ALWAYSASSERT is an assertion in all builds. |
| 208 | */ |
| 209 | #if !defined(GR_ALWAYSASSERT) |
| 210 | #define GR_ALWAYSASSERT(COND) \ |
| 211 | do { \ |
| 212 | if (!(COND)) { \ |
| 213 | GrPrintf("%s %s failed\n", GR_FILE_AND_LINE_STR, #COND); \ |
| 214 | GR_ALWAYSBREAK; \ |
| 215 | } \ |
| 216 | } while (false) |
| 217 | #endif |
| 218 | |
| 219 | /** |
| 220 | * GR_DEBUGASSERT is an assertion in debug builds only. |
| 221 | */ |
| 222 | #if !defined(GR_DEBUGASSERT) |
| 223 | #if GR_DEBUG |
| 224 | #define GR_DEBUGASSERT(COND) GR_ALWAYSASSERT(COND) |
| 225 | #else |
| 226 | #define GR_DEBUGASSERT(COND) |
| 227 | #endif |
| 228 | #endif |
| 229 | |
| 230 | /** |
| 231 | * Prettier forms of the above macros. |
| 232 | */ |
| 233 | #define GrAssert(COND) GR_DEBUGASSERT(COND) |
| 234 | #define GrAlwaysAssert(COND) GR_ALWAYSASSERT(COND) |
| 235 | |
| 236 | /** |
bsalomon@google.com | 6f7fbc9 | 2011-02-01 19:12:40 +0000 | [diff] [blame^] | 237 | * Crash from unrecoverable condition, optionally with a message. |
| 238 | */ |
| 239 | inline void GrCrash() { GrAlwaysAssert(false); } |
| 240 | inline void GrCrash(const char* msg) { GrPrintf(msg); GrAlwaysAssert(false); } |
| 241 | |
| 242 | /** |
reed@google.com | ac10a2d | 2010-12-22 21:39:39 +0000 | [diff] [blame] | 243 | * GR_DEBUGCODE compiles the code X in debug builds only |
| 244 | */ |
| 245 | #if !defined(GR_DEBUGCODE) |
| 246 | #if GR_DEBUG |
| 247 | #define GR_DEBUGCODE(X) X |
| 248 | #else |
| 249 | #define GR_DEBUGCODE(X) |
| 250 | #endif |
| 251 | #endif |
| 252 | |
| 253 | /** |
| 254 | * GR_STATIC_ASSERT is a compile time assertion. Depending on the platform |
| 255 | * it may print the message in the compiler log. Obviously, the condition must |
| 256 | * be evaluatable at compile time. |
| 257 | */ |
| 258 | // VS 2010 and GCC compiled with c++0x or gnu++0x support the new |
| 259 | // static_assert. |
| 260 | #if !defined(GR_STATIC_ASSERT) |
reed@google.com | c921843 | 2011-01-25 19:05:12 +0000 | [diff] [blame] | 261 | #if (defined(_MSC_VER) && _MSC_VER >= 1600) || (defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__) |
reed@google.com | ac10a2d | 2010-12-22 21:39:39 +0000 | [diff] [blame] | 262 | #define GR_STATIC_ASSERT(CONDITION) static_assert(CONDITION, "bug") |
| 263 | #else |
| 264 | template <bool> class GR_STATIC_ASSERT_FAILURE; |
| 265 | template <> class GR_STATIC_ASSERT_FAILURE<true> {}; |
| 266 | #define GR_STATIC_ASSERT(CONDITION) \ |
| 267 | enum {GR_CONCAT(X,__LINE__) = \ |
| 268 | sizeof(GR_STATIC_ASSERT_FAILURE<CONDITION>)} |
| 269 | #endif |
| 270 | #endif |
| 271 | |
| 272 | #if !defined(GR_SCALAR_IS_FLOAT) |
| 273 | #define GR_SCALAR_IS_FLOAT 0 |
| 274 | #endif |
| 275 | #if !defined(GR_SCALAR_IS_FIXED) |
| 276 | #define GR_SCALAR_IS_FIXED 0 |
| 277 | #endif |
| 278 | |
| 279 | #if !defined(GR_TEXT_SCALAR_TYPE_IS_USHORT) |
| 280 | #define GR_TEXT_SCALAR_TYPE_IS_USHORT 0 |
| 281 | #endif |
| 282 | #if !defined(GR_TEXT_SCALAR_TYPE_IS_FLOAT) |
| 283 | #define GR_TEXT_SCALAR_TYPE_IS_FLOAT 0 |
| 284 | #endif |
| 285 | #if !defined(GR_TEXT_SCALAR_TYPE_IS_FIXED) |
| 286 | #define GR_TEXT_SCALAR_TYPE_IS_FIXED 0 |
| 287 | #endif |
| 288 | |
| 289 | #ifndef GR_DUMP_TEXTURE_UPLOAD |
| 290 | #define GR_DUMP_TEXTURE_UPLOAD 0 |
| 291 | #endif |
| 292 | |
| 293 | /** |
| 294 | * GR_COLLECT_STATS controls whether the GrGpu class collects stats. |
| 295 | * If not already defined then collect in debug build but not release. |
| 296 | */ |
| 297 | #if !defined(GR_COLLECT_STATS) |
| 298 | #define GR_COLLECT_STATS GR_DEBUG |
| 299 | #endif |
| 300 | |
| 301 | /** |
| 302 | * GR_GL_LOG_CALLS controls whether each GL call is logged. |
| 303 | */ |
| 304 | #if !defined(GR_GL_LOG_CALLS) |
| 305 | #define GR_GL_LOG_CALLS 0 |
| 306 | #endif |
| 307 | |
| 308 | /////////////////////////////////////////////////////////////////////////////// |
| 309 | // tail section: |
| 310 | // |
| 311 | // Now we just assert if we are missing some required define, or if we detect |
| 312 | // and inconsistent combination of defines |
| 313 | // |
| 314 | |
| 315 | |
| 316 | /** |
| 317 | * Only one build target macro should be 1 and the rest should be 0. |
| 318 | */ |
| 319 | #define GR_BUILD_SUM (GR_WIN32_BUILD + GR_MAC_BUILD + GR_IOS_BUILD + GR_ANDROID_BUILD + GR_LINUX_BUILD + GR_QNX_BUILD) |
| 320 | #if 0 == GR_BUILD_SUM |
| 321 | #error "Missing a GR_BUILD define" |
| 322 | #elif 1 != GR_BUILD_SUM |
| 323 | #error "More than one GR_BUILD defined" |
| 324 | #endif |
| 325 | |
| 326 | |
| 327 | #if !GR_SCALAR_IS_FLOAT && !GR_SCALAR_IS_FIXED |
| 328 | #undef GR_SCALAR_IS_FLOAT |
| 329 | #define GR_SCALAR_IS_FLOAT 1 |
| 330 | #pragma message GR_WARN("Scalar type not defined, defaulting to float") |
| 331 | #endif |
| 332 | |
| 333 | #if !GR_TEXT_SCALAR_IS_FLOAT && \ |
| 334 | !GR_TEXT_SCALAR_IS_FIXED && \ |
| 335 | !GR_TEXT_SCALAR_IS_USHORT |
| 336 | #undef GR_TEXT_SCALAR_IS_FLOAT |
| 337 | #define GR_TEXT_SCALAR_IS_FLOAT 1 |
| 338 | #pragma message GR_WARN("Text scalar type not defined, defaulting to float") |
| 339 | #endif |
| 340 | |
| 341 | #if 0 |
| 342 | #if GR_WIN32_BUILD |
| 343 | // #pragma message GR_WARN("GR_WIN32_BUILD") |
| 344 | #endif |
| 345 | #if GR_MAC_BUILD |
| 346 | // #pragma message GR_WARN("GR_MAC_BUILD") |
| 347 | #endif |
| 348 | #if GR_IOS_BUILD |
| 349 | // #pragma message GR_WARN("GR_IOS_BUILD") |
| 350 | #endif |
| 351 | #if GR_ANDROID_BUILD |
| 352 | // #pragma message GR_WARN("GR_ANDROID_BUILD") |
| 353 | #endif |
| 354 | #if GR_LINUX_BUILD |
| 355 | // #pragma message GR_WARN("GR_LINUX_BUILD") |
| 356 | #endif |
| 357 | #if GR_QNX_BUILD |
| 358 | // #pragma message GR_WARN("GR_QNX_BUILD") |
| 359 | #endif |
| 360 | #endif |
| 361 | |
| 362 | #endif |
| 363 | |