SkPostConfig.h revision b1560445c66a751fc2ea7b85b94430a985940f3e
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
8ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com#ifndef SkPostConfig_DEFINED
98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkPostConfig_DEFINED
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
118b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#if defined(SK_BUILD_FOR_WIN32) || defined(SK_BUILD_FOR_WINCE)
128b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#  define SK_BUILD_FOR_WIN
138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
146db9375b4f695c68a4e56e38bcd70f983440c2d5reed@google.com
158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#if defined(SK_DEBUG) && defined(SK_RELEASE)
1616edff2b1cbd80e36456138f8631711a585205bareed@google.com#  error "cannot define both SK_DEBUG and SK_RELEASE"
1790bf427001fd4f6d9fcee88911deb015aeb4ab7cmike@reedtribe.org#elif !defined(SK_DEBUG) && !defined(SK_RELEASE)
188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#  error "must define either SK_DEBUG or SK_RELEASE"
198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
20548a1f321011292359ef163f78c8a1d4871b3b7freed@google.com
214bbdeac58cc928dc66296bde3bd06e78070d96b7reed@google.com#if defined(SK_SUPPORT_UNITTEST) && !defined(SK_DEBUG)
2290bf427001fd4f6d9fcee88911deb015aeb4ab7cmike@reedtribe.org#  error "can't have unittests without debug"
2390bf427001fd4f6d9fcee88911deb015aeb4ab7cmike@reedtribe.org#endif
2490bf427001fd4f6d9fcee88911deb015aeb4ab7cmike@reedtribe.org
2590bf427001fd4f6d9fcee88911deb015aeb4ab7cmike@reedtribe.org/**
266db9375b4f695c68a4e56e38bcd70f983440c2d5reed@google.com * Matrix calculations may be float or double.
276db9375b4f695c68a4e56e38bcd70f983440c2d5reed@google.com * The default is double, as that is faster given our impl uses doubles
288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * for intermediate calculations.
298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */
30d252db03d9650013b545ef9781fe993c07f8f314reed@android.com#if defined(SK_MSCALAR_IS_DOUBLE) && defined(SK_MSCALAR_IS_FLOAT)
318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#  error "cannot define both SK_MSCALAR_IS_DOUBLE and SK_MSCALAR_IS_FLOAT"
328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#elif !defined(SK_MSCALAR_IS_DOUBLE) && !defined(SK_MSCALAR_IS_FLOAT)
336db9375b4f695c68a4e56e38bcd70f983440c2d5reed@google.com#  define SK_MSCALAR_IS_DOUBLE
346db9375b4f695c68a4e56e38bcd70f983440c2d5reed@google.com#endif
356db9375b4f695c68a4e56e38bcd70f983440c2d5reed@google.com
366db9375b4f695c68a4e56e38bcd70f983440c2d5reed@google.com#if defined(SK_CPU_LENDIAN) && defined(SK_CPU_BENDIAN)
376db9375b4f695c68a4e56e38bcd70f983440c2d5reed@google.com#  error "cannot define both SK_CPU_LENDIAN and SK_CPU_BENDIAN"
386db9375b4f695c68a4e56e38bcd70f983440c2d5reed@google.com#elif !defined(SK_CPU_LENDIAN) && !defined(SK_CPU_BENDIAN)
396db9375b4f695c68a4e56e38bcd70f983440c2d5reed@google.com#  error "must define either SK_CPU_LENDIAN or SK_CPU_BENDIAN"
406db9375b4f695c68a4e56e38bcd70f983440c2d5reed@google.com#endif
416db9375b4f695c68a4e56e38bcd70f983440c2d5reed@google.com
426db9375b4f695c68a4e56e38bcd70f983440c2d5reed@google.com/**
436db9375b4f695c68a4e56e38bcd70f983440c2d5reed@google.com * Ensure the port has defined all of SK_X32_SHIFT, or none of them.
448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */
458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_A32_SHIFT
468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#  if !defined(SK_R32_SHIFT) || !defined(SK_G32_SHIFT) || !defined(SK_B32_SHIFT)
478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#    error "all or none of the 32bit SHIFT amounts must be defined"
488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#  endif
49548a1f321011292359ef163f78c8a1d4871b3b7freed@google.com#else
5090bf427001fd4f6d9fcee88911deb015aeb4ab7cmike@reedtribe.org#  if defined(SK_R32_SHIFT) || defined(SK_G32_SHIFT) || defined(SK_B32_SHIFT)
5190bf427001fd4f6d9fcee88911deb015aeb4ab7cmike@reedtribe.org#    error "all or none of the 32bit SHIFT amounts must be defined"
5290bf427001fd4f6d9fcee88911deb015aeb4ab7cmike@reedtribe.org#  endif
5390bf427001fd4f6d9fcee88911deb015aeb4ab7cmike@reedtribe.org#endif
548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#if !defined(SK_HAS_COMPILER_FEATURE)
568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#  if defined(__has_feature)
578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#    define SK_HAS_COMPILER_FEATURE(x) __has_feature(x)
588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#  else
598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#    define SK_HAS_COMPILER_FEATURE(x) 0
608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#  endif
618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#if !defined(SK_ATTRIBUTE)
648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#  if defined(__clang__) || defined(__GNUC__)
65548a1f321011292359ef163f78c8a1d4871b3b7freed@google.com#    define SK_ATTRIBUTE(attr) __attribute__((attr))
66548a1f321011292359ef163f78c8a1d4871b3b7freed@google.com#  else
67548a1f321011292359ef163f78c8a1d4871b3b7freed@google.com#    define SK_ATTRIBUTE(attr)
688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#  endif
6916edff2b1cbd80e36456138f8631711a585205bareed@google.com#endif
708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
718b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#if !defined(SK_SUPPORT_GPU)
7254924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.com#  define SK_SUPPORT_GPU 1
73d2700eec7eb2e26beb206b88a0f0b6f3c5f49118djsollen@google.com#endif
748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/**
768b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org * The clang static analyzer likes to know that when the program is not
77d2700eec7eb2e26beb206b88a0f0b6f3c5f49118djsollen@google.com * expected to continue (crash, assertion failure, etc). It will notice that
7890bf427001fd4f6d9fcee88911deb015aeb4ab7cmike@reedtribe.org * some combination of parameters lead to a function call that does not return.
798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * It can then make appropriate assumptions about the parameters in code
808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * executed only if the non-returning function was *not* called.
81e28b917669fc4677b2f1c0a08c4711b651cbf1a1reed@google.com */
82d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com#if !defined(SkNO_RETURN_HINT)
83548a1f321011292359ef163f78c8a1d4871b3b7freed@google.com#  if SK_HAS_COMPILER_FEATURE(attribute_analyzer_noreturn)
844bbdeac58cc928dc66296bde3bd06e78070d96b7reed@google.com     static inline void SkNO_RETURN_HINT() __attribute__((analyzer_noreturn));
854bbdeac58cc928dc66296bde3bd06e78070d96b7reed@google.com     static inline void SkNO_RETURN_HINT() {}
86d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com#  else
87d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com#    define SkNO_RETURN_HINT() do {} while (false)
88d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com#  endif
89d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com#endif
90d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com
91d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com#if defined(SK_ZLIB_INCLUDE) && defined(SK_SYSTEM_ZLIB)
92548a1f321011292359ef163f78c8a1d4871b3b7freed@google.com#  error "cannot define both SK_ZLIB_INCLUDE and SK_SYSTEM_ZLIB"
93d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com#elif defined(SK_ZLIB_INCLUDE) || defined(SK_SYSTEM_ZLIB)
94d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com#  define SK_HAS_ZLIB
95d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com#endif
96d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com
97d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com///////////////////////////////////////////////////////////////////////////////
98d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com
99d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com#ifndef SkNEW
100d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com#  define SkNEW(type_name)                           (new type_name)
101d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com#  define SkNEW_ARGS(type_name, args)                (new type_name args)
102d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com#  define SkNEW_ARRAY(type_name, count)              (new type_name[(count)])
103d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com#  define SkNEW_PLACEMENT(buf, type_name)            (new (buf) type_name)
104d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com#  define SkNEW_PLACEMENT_ARGS(buf, type_name, args) (new (buf) type_name args)
1058b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#  define SkDELETE(obj)                              (delete (obj))
106d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com#  define SkDELETE_ARRAY(array)                      (delete[] (array))
107d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com#endif
108d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com
1098b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#ifndef SK_CRASH
110d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com#  if 1   // set to 0 for infinite loop, which can help connecting gdb
111d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com#    define SK_CRASH() do { SkNO_RETURN_HINT(); *(int *)(uintptr_t)0xbbadbeef = 0; } while (false)
112d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com#  else
113d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com#    define SK_CRASH() do { SkNO_RETURN_HINT(); } while (true)
11418dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com#  endif
11518dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com#endif
11618dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com
11718dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com///////////////////////////////////////////////////////////////////////////////
11818dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com
11918dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com/**
1208b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org * SK_ENABLE_INST_COUNT controlls printing how many reference counted objects
12118dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com * are still held on exit.
1222b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com * Defaults to 1 in DEBUG and 0 in RELEASE.
12318dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com * FIXME: currently always 0, since it fails if multiple threads run at once
12418dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com * (see skbug.com/1219 ).
1258b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org */
12618dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com#ifndef SK_ENABLE_INST_COUNT
1272b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com#  ifdef SK_DEBUG
12818dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com#    define SK_ENABLE_INST_COUNT 0
12918dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com#  else
130548a1f321011292359ef163f78c8a1d4871b3b7freed@google.com#    define SK_ENABLE_INST_COUNT 0
131548a1f321011292359ef163f78c8a1d4871b3b7freed@google.com#  endif
13218dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com#endif
13318dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com
134///////////////////////////////////////////////////////////////////////////////
135
136#ifdef SK_BUILD_FOR_WIN
137#  ifndef WIN32_LEAN_AND_MEAN
138#    define WIN32_LEAN_AND_MEAN
139#    define WIN32_IS_MEAN_WAS_LOCALLY_DEFINED
140#  endif
141#  ifndef NOMINMAX
142#    define NOMINMAX
143#    define NOMINMAX_WAS_LOCALLY_DEFINED
144#  endif
145#
146#  include <windows.h>
147#
148#  ifdef WIN32_IS_MEAN_WAS_LOCALLY_DEFINED
149#    undef WIN32_IS_MEAN_WAS_LOCALLY_DEFINED
150#    undef WIN32_LEAN_AND_MEAN
151#  endif
152#  ifdef NOMINMAX_WAS_LOCALLY_DEFINED
153#    undef NOMINMAX_WAS_LOCALLY_DEFINED
154#    undef NOMINMAX
155#  endif
156#
157#  ifndef SK_DEBUGBREAK
158#    define SK_DEBUGBREAK(p) do { if (!(p)) { SkNO_RETURN_HINT(); __debugbreak(); }} while (false)
159#  endif
160#
161#  ifndef SK_A32_SHIFT
162#    define SK_A32_SHIFT 24
163#    define SK_R32_SHIFT 16
164#    define SK_G32_SHIFT 8
165#    define SK_B32_SHIFT 0
166#  endif
167#
168#else
169#  ifdef SK_DEBUG
170#    include <stdio.h>
171#    ifndef SK_DEBUGBREAK
172#      define SK_DEBUGBREAK(cond) do { if (cond) break; \
173                SkDebugf("%s:%d: failed assertion \"%s\"\n", \
174                __FILE__, __LINE__, #cond); SK_CRASH(); } while (false)
175#    endif
176#  endif
177#endif
178
179/**
180 *  We check to see if the SHIFT value has already been defined.
181 *  if not, we define it ourself to some default values. We default to OpenGL
182 *  order (in memory: r,g,b,a)
183 */
184#ifndef SK_A32_SHIFT
185#  ifdef SK_CPU_BENDIAN
186#    define SK_R32_SHIFT    24
187#    define SK_G32_SHIFT    16
188#    define SK_B32_SHIFT    8
189#    define SK_A32_SHIFT    0
190#  else
191#    define SK_R32_SHIFT    0
192#    define SK_G32_SHIFT    8
193#    define SK_B32_SHIFT    16
194#    define SK_A32_SHIFT    24
195#  endif
196#endif
197
198/**
199 * SkColor has well defined shift values, but SkPMColor is configurable. This
200 * macro is a convenience that returns true if the shift values are equal while
201 * ignoring the machine's endianness.
202 */
203#define SK_COLOR_MATCHES_PMCOLOR_BYTE_ORDER \
204    (SK_A32_SHIFT == 24 && SK_R32_SHIFT == 16 && SK_G32_SHIFT == 8 && SK_B32_SHIFT == 0)
205
206/**
207 * SK_PMCOLOR_BYTE_ORDER can be used to query the byte order of SkPMColor at compile time. The
208 * relationship between the byte order and shift values depends on machine endianness. If the shift
209 * order is R=0, G=8, B=16, A=24 then ((char*)&pmcolor)[0] will produce the R channel on a little
210 * endian machine and the A channel on a big endian machine. Thus, given those shifts values,
211 * SK_PMCOLOR_BYTE_ORDER(R,G,B,A) will be true on a little endian machine and
212 * SK_PMCOLOR_BYTE_ORDER(A,B,G,R) will be true on a big endian machine.
213 */
214#ifdef SK_CPU_BENDIAN
215#  define SK_PMCOLOR_BYTE_ORDER(C0, C1, C2, C3)     \
216        (SK_ ## C3 ## 32_SHIFT == 0  &&             \
217         SK_ ## C2 ## 32_SHIFT == 8  &&             \
218         SK_ ## C1 ## 32_SHIFT == 16 &&             \
219         SK_ ## C0 ## 32_SHIFT == 24)
220#else
221#  define SK_PMCOLOR_BYTE_ORDER(C0, C1, C2, C3)     \
222        (SK_ ## C0 ## 32_SHIFT == 0  &&             \
223         SK_ ## C1 ## 32_SHIFT == 8  &&             \
224         SK_ ## C2 ## 32_SHIFT == 16 &&             \
225         SK_ ## C3 ## 32_SHIFT == 24)
226#endif
227
228//////////////////////////////////////////////////////////////////////
229
230#if defined(SK_BUILD_FOR_WIN32) || defined(SK_BUILD_FOR_MAC)
231#  ifndef SkLONGLONG
232#    ifdef SK_BUILD_FOR_WIN32
233#      define SkLONGLONG __int64
234#    else
235#      define SkLONGLONG long long
236#    endif
237#  endif
238#endif
239
240//////////////////////////////////////////////////////////////////////////////////////////////
241#ifndef SK_BUILD_FOR_WINCE
242#  include <string.h>
243#  include <stdlib.h>
244#else
245#  define _CMNINTRIN_DECLARE_ONLY
246#  include "cmnintrin.h"
247#endif
248
249#if defined SK_DEBUG && defined SK_BUILD_FOR_WIN32
250#  ifdef free
251#    undef free
252#  endif
253#  include <crtdbg.h>
254#  undef free
255#
256#  ifdef SK_DEBUGx
257#    if defined(SK_SIMULATE_FAILED_MALLOC) && defined(__cplusplus)
258       void * operator new(
259           size_t cb,
260           int nBlockUse,
261           const char * szFileName,
262           int nLine,
263           int foo
264           );
265       void * operator new[](
266           size_t cb,
267           int nBlockUse,
268           const char * szFileName,
269           int nLine,
270           int foo
271           );
272       void operator delete(
273           void *pUserData,
274           int, const char*, int, int
275           );
276       void operator delete(
277           void *pUserData
278           );
279       void operator delete[]( void * p );
280#      define DEBUG_CLIENTBLOCK   new( _CLIENT_BLOCK, __FILE__, __LINE__, 0)
281#    else
282#      define DEBUG_CLIENTBLOCK   new( _CLIENT_BLOCK, __FILE__, __LINE__)
283#    endif
284#    define new DEBUG_CLIENTBLOCK
285#  else
286#    define DEBUG_CLIENTBLOCK
287#  endif
288#endif
289
290//////////////////////////////////////////////////////////////////////
291
292#ifndef SK_OVERRIDE
293#  if defined(_MSC_VER)
294#    define SK_OVERRIDE override
295#  elif defined(__clang__)
296     // Using __attribute__((override)) on clang does not appear to always work.
297     // Clang defaults to C++03 and warns about using override. Squelch that. Intentionally no
298     // push/pop here so all users of SK_OVERRIDE ignore the warning too. This is like passing
299     // -Wno-c++11-extensions, except that GCC won't die (because it won't see this pragma).
300#    pragma clang diagnostic ignored "-Wc++11-extensions"
301#
302#    if __has_feature(cxx_override_control)
303#      define SK_OVERRIDE override
304#    elif defined(__has_extension) && __has_extension(cxx_override_control)
305#      define SK_OVERRIDE override
306#    endif
307#  endif
308#  ifndef SK_OVERRIDE
309#    define SK_OVERRIDE
310#  endif
311#endif
312
313//////////////////////////////////////////////////////////////////////
314
315#if !defined(SK_UNUSED)
316#  define SK_UNUSED SK_ATTRIBUTE(unused)
317#endif
318
319#if !defined(SK_ATTR_DEPRECATED)
320   // FIXME: we ignore msg for now...
321#  define SK_ATTR_DEPRECATED(msg) SK_ATTRIBUTE(deprecated)
322#endif
323
324/**
325 * If your judgment is better than the compiler's (i.e. you've profiled it),
326 * you can use SK_ALWAYS_INLINE to force inlining. E.g.
327 *     inline void someMethod() { ... }             // may not be inlined
328 *     SK_ALWAYS_INLINE void someMethod() { ... }   // should always be inlined
329 */
330#if !defined(SK_ALWAYS_INLINE)
331#  if defined(SK_BUILD_FOR_WIN)
332#    define SK_ALWAYS_INLINE __forceinline
333#  else
334#    define SK_ALWAYS_INLINE SK_ATTRIBUTE(always_inline) inline
335#  endif
336#endif
337
338//////////////////////////////////////////////////////////////////////
339
340#if defined(__clang__) || defined(__GNUC__)
341#  define SK_PREFETCH(ptr) __builtin_prefetch(ptr)
342#  define SK_WRITE_PREFETCH(ptr) __builtin_prefetch(ptr, 1)
343#else
344#  define SK_PREFETCH(ptr)
345#  define SK_WRITE_PREFETCH(ptr)
346#endif
347
348//////////////////////////////////////////////////////////////////////
349
350#ifndef SK_PRINTF_LIKE
351#  if defined(__clang__) || defined(__GNUC__)
352#    define SK_PRINTF_LIKE(A, B) __attribute__((format(printf, (A), (B))))
353#  else
354#    define SK_PRINTF_LIKE(A, B)
355#  endif
356#endif
357
358//////////////////////////////////////////////////////////////////////
359
360#ifndef SK_SIZE_T_SPECIFIER
361#  if defined(_MSC_VER)
362#    define SK_SIZE_T_SPECIFIER "%Iu"
363#  else
364#    define SK_SIZE_T_SPECIFIER "%zu"
365#  endif
366#endif
367
368//////////////////////////////////////////////////////////////////////
369
370#ifndef SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
371#  define SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 1
372#endif
373
374//////////////////////////////////////////////////////////////////////
375
376#ifndef SK_ATOMICS_PLATFORM_H
377#  if defined(SK_BUILD_FOR_WIN)
378#    define SK_ATOMICS_PLATFORM_H "../../src/ports/SkAtomics_win.h"
379#  elif defined(SK_BUILD_FOR_ANDROID_FRAMEWORK)
380#    define SK_ATOMICS_PLATFORM_H "../../src/ports/SkAtomics_android.h"
381#  else
382#    define SK_ATOMICS_PLATFORM_H "../../src/ports/SkAtomics_sync.h"
383#  endif
384#endif
385
386#ifndef SK_MUTEX_PLATFORM_H
387#  if defined(SK_BUILD_FOR_WIN)
388#    define SK_MUTEX_PLATFORM_H "../../src/ports/SkMutex_win.h"
389#  else
390#    define SK_MUTEX_PLATFORM_H "../../src/ports/SkMutex_pthread.h"
391#  endif
392#endif
393
394#endif // SkPostConfig_DEFINED
395