rm: Introduce SK_ARM_NEON_WRAP handy wrapper macro.
    
It is used to simplify arm/neon dispatch logic code.
Review URL: https://codereview.appspot.com/6458060

git-svn-id: http://skia.googlecode.com/svn/trunk@4958 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/core/SkPreConfig.h b/include/core/SkPreConfig.h
index bbf0124..55b1abf 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 77c6200..64755be 100644
--- a/src/core/SkBitmapProcState_matrixProcs.cpp
+++ b/src/core/SkBitmapProcState_matrixProcs.cpp
@@ -496,17 +496,7 @@
         // 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 @@
     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 4562b01..6a5aab8 100644
--- a/src/core/SkUtilsArm.h
+++ b/src/core/SkUtilsArm.h
@@ -47,7 +47,41 @@
     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