aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/core/SkPreConfig.h16
-rw-r--r--src/core/SkBitmapProcState_matrixProcs.cpp24
-rw-r--r--src/core/SkUtilsArm.h36
3 files changed, 53 insertions, 23 deletions
diff --git a/include/core/SkPreConfig.h b/include/core/SkPreConfig.h
index bbf0124117..55b1abf3bc 100644
--- a/include/core/SkPreConfig.h
+++ b/include/core/SkPreConfig.h
@@ -173,5 +173,21 @@
#define SK_API
#endif
+//////////////////////////////////////////////////////////////////////
+
+/**
+ * Use SK_PURE_FUNC as an attribute to indicate that a function's
+ * return value only depends on the value of its parameters. This
+ * can help the compiler optimize out successive calls.
+ *
+ * Usage:
+ * void function(int params) SK_PURE_FUNC;
+ */
+#if defined(__GNUC__)
+# define SK_PURE_FUNC __attribute__((pure))
+#else
+# define SK_PURE_FUNC /* nothing */
+#endif
+
#endif
diff --git a/src/core/SkBitmapProcState_matrixProcs.cpp b/src/core/SkBitmapProcState_matrixProcs.cpp
index 77c6200d03..64755be19e 100644
--- a/src/core/SkBitmapProcState_matrixProcs.cpp
+++ b/src/core/SkBitmapProcState_matrixProcs.cpp
@@ -496,17 +496,7 @@ SkBitmapProcState::chooseMatrixProc(bool trivial_matrix) {
// clamp gets special version of filterOne
fFilterOneX = SK_Fixed1;
fFilterOneY = SK_Fixed1;
-#if SK_ARM_NEON_IS_NONE
- return ClampX_ClampY_Procs[index];
-#elif SK_ARM_NEON_IS_ALWAYS
- return ClampX_ClampY_Procs_neon[index];
-#else // SK_ARM_NEON_IS_DYNAMIC
- if (sk_cpu_arm_has_neon()) {
- return ClampX_ClampY_Procs_neon[index];
- } else {
- return ClampX_ClampY_Procs[index];
- }
-#endif
+ return SK_ARM_NEON_WRAP(ClampX_ClampY_Procs)[index];
}
// all remaining procs use this form for filterOne
@@ -516,17 +506,7 @@ SkBitmapProcState::chooseMatrixProc(bool trivial_matrix) {
if (SkShader::kRepeat_TileMode == fTileModeX &&
SkShader::kRepeat_TileMode == fTileModeY)
{
-#if SK_ARM_NEON_IS_NONE
- return RepeatX_RepeatY_Procs[index];
-#elif SK_ARM_NEON_IS_ALWAYS
- return RepeatX_RepeatY_Procs_neon[index];
-#else // SK_ARM_NEON_IS_DYNAMIC
- if (sk_cpu_arm_has_neon()) {
- return RepeatX_RepeatY_Procs_neon[index];
- } else {
- return RepeatX_RepeatY_Procs[index];
- }
-#endif
+ return SK_ARM_NEON_WRAP(RepeatX_RepeatY_Procs)[index];
}
fTileProcX = choose_tile_proc(fTileModeX);
diff --git a/src/core/SkUtilsArm.h b/src/core/SkUtilsArm.h
index 4562b01923..6a5aab8067 100644
--- a/src/core/SkUtilsArm.h
+++ b/src/core/SkUtilsArm.h
@@ -47,7 +47,41 @@ static bool sk_cpu_arm_has_neon(void) {
return true;
}
#else // SK_ARM_NEON_IS_DYNAMIC
-extern bool sk_cpu_arm_has_neon(void);
+
+extern bool sk_cpu_arm_has_neon(void) SK_PURE_FUNC;
+#endif
+
+// Use SK_ARM_NEON_WRAP(symbol) to map 'symbol' to a NEON-specific symbol
+// when applicable. This will transform 'symbol' differently depending on
+// the current NEON configuration, i.e.:
+//
+// NONE -> 'symbol'
+// ALWAYS -> 'symbol_neon'
+// DYNAMIC -> 'symbol' or 'symbol_neon' depending on runtime check.
+//
+// The goal is to simplify user code, for example:
+//
+// return SK_ARM_NEON_WRAP(do_something)(params);
+//
+// Replaces the equivalent:
+//
+// #if SK_ARM_NEON_IS_NONE
+// return do_something(params);
+// #elif SK_ARM_NEON_IS_ALWAYS
+// return do_something_neon(params);
+// #elif SK_ARM_NEON_IS_DYNAMIC
+// if (sk_cpu_arm_has_neon())
+// return do_something_neon(params);
+// else
+// return do_something(params);
+// #endif
+//
+#if SK_ARM_NEON_IS_NONE
+# define SK_ARM_NEON_WRAP(x) (x)
+#elif SK_ARM_NEON_IS_ALWAYS
+# define SK_ARM_NEON_WRAP(x) (x ## _neon)
+#elif SK_ARM_NEON_IS_DYNAMIC
+# define SK_ARM_NEON_WRAP(x) (sk_cpu_arm_has_neon() ? x ## _neon : x)
#endif
#endif // SkUtilsArm_DEFINED