OSDN Git Service

brushlib: refactor (get_color)
authorMartin Renold <martinxyz@gmx.ch>
Sat, 4 Jun 2011 12:52:02 +0000 (14:52 +0200)
committerMartin Renold <martinxyz@gmx.ch>
Sun, 12 Jun 2011 11:45:43 +0000 (13:45 +0200)
Move performance critical code into own function.

lib/brushmodes.hpp
lib/tiledsurface.hpp

index bcdc424..5cc69de 100644 (file)
@@ -112,3 +112,51 @@ void draw_dab_pixels_BlendMode_LockAlpha (uint16_t * mask,
   }
 };
 
+
+// Sum up the color/alpha components inside the masked region.
+// Called by get_color().
+//
+void get_color_pixels_accumulate (uint16_t * mask,
+                                  uint16_t * rgba,
+                                  float * sum_weight,
+                                  float * sum_r,
+                                  float * sum_g,
+                                  float * sum_b,
+                                  float * sum_a
+                                  ) {
+
+
+  // The sum of a 64x64 tile fits into a 32 bit integer, but the sum
+  // of an arbitrary number of tiles may not fit. We assume that we
+  // are processing a single tile at a time, so we can use integers.
+  // But for the result we need floats.
+
+  uint32_t weight = 0;
+  uint32_t r = 0;
+  uint32_t g = 0;
+  uint32_t b = 0;
+  uint32_t a = 0;
+
+  while (1) {
+    for (; mask[0]; mask++, rgba+=4) {
+      uint32_t opa = mask[0];
+      weight += opa;
+      r      += opa*rgba[0]/(1<<15);
+      g      += opa*rgba[1]/(1<<15);
+      b      += opa*rgba[2]/(1<<15);
+      a      += opa*rgba[3]/(1<<15);
+
+    }
+    if (!mask[1]) break;
+    rgba += mask[1];
+    mask += 2;
+  }
+
+  // convert integer to float outside the performance critical loop
+  *sum_weight += weight;
+  *sum_r += r;
+  *sum_g += g;
+  *sum_b += b;
+  *sum_a += a;
+};
+
index afbb4de..675cbdf 100644 (file)
@@ -296,8 +296,8 @@ public:
     const float aspect_ratio = 1.0;
     const float angle = 0.0;
 
-    float sum_r, sum_g, sum_b, sum_a, sum_weight;
-    sum_r = sum_g = sum_b = sum_a = sum_weight = 0.0;
+    float sum_weight, sum_r, sum_g, sum_b, sum_a;
+    sum_weight = sum_r = sum_g = sum_b = sum_a = 0.0;
 
     // in case we return with an error
     *color_r = 0.0;
@@ -332,38 +332,9 @@ public:
                         aspect_ratio, angle
                         );
 
-        // accumulate
-
-        // the sum of a 64x64 tile fits into a 32 bit integer
-        // (but not the sum of an arbitrary number of tiles)
-        uint32_t sum_weight_tmp = 0;
-        uint32_t sum_a_tmp = 0;
-        uint32_t sum_r_tmp = 0;
-        uint32_t sum_g_tmp = 0;
-        uint32_t sum_b_tmp = 0;
-
-        uint16_t * mask_p = mask;
-        while (1) {
-          for (; mask_p[0]; mask_p++, rgba_p+=4) {
-            uint32_t opa = mask_p[0];
-            sum_weight_tmp += opa;
-            sum_r_tmp      += opa*rgba_p[0]/(1<<15);
-            sum_g_tmp      += opa*rgba_p[1]/(1<<15);
-            sum_b_tmp      += opa*rgba_p[2]/(1<<15);
-            sum_a_tmp      += opa*rgba_p[3]/(1<<15);
-            
-          }
-          if (!mask_p[1]) break;
-          rgba_p += mask_p[1];
-          mask_p += 2;
-        }
+        get_color_pixels_accumulate (mask, rgba_p,
+                                     &sum_weight, &sum_r, &sum_g, &sum_b, &sum_a);
 
-        // conver to float outside the critical loop
-        sum_weight += sum_weight_tmp;
-        sum_r += sum_r_tmp;
-        sum_g += sum_g_tmp;
-        sum_b += sum_b_tmp;
-        sum_a += sum_a_tmp;
       }
     }