Correct blitmask procs to recognize that we pass them an SkColor, and if they
authorreed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Wed, 9 Mar 2011 13:23:57 +0000 (13:23 +0000)
committerreed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Wed, 9 Mar 2011 13:23:57 +0000 (13:23 +0000)
want a SkPMColor, they need to call SkPreMultiplyColor()

Add Opaque and Black optimizations for blitmask_d32

git-svn-id: http://skia.googlecode.com/svn/trunk@911 2bbb7eff-a529-9590-31e7-b0007b416f81

src/core/SkBlitRow_D32.cpp
src/core/SkBlitter_ARGB32.cpp
src/core/SkCoreBlitters.h
src/opts/SkBlitRow_opts_SSE2.cpp

index 7b9aabc1df0ac6cd72e5aab4d5697dd4cdfbca64..642fe7f8e08ba655f10ead3fb685c4fe2a6da323 100644 (file)
@@ -170,11 +170,10 @@ void SkBlitRow::Color32(SkPMColor dst[], const SkPMColor src[],
 
 ///////////////////////////////////////////////////////////////////////////////
 
-static void SkARGB32_BlitMask_portable(void* dst, size_t dstRB,
-                                       SkBitmap::Config dstConfig,
-                                       const uint8_t* mask,
-                                       size_t maskRB, SkColor color,
-                                       int width, int height) {
+static void D32_Mask_Color(void* dst, size_t dstRB, SkBitmap::Config,
+                           const uint8_t* mask, size_t maskRB, SkColor color,
+                           int width, int height) {
+    SkPMColor pmc = SkPreMultiplyColor(color);
     size_t dstOffset = dstRB - (width << 2);
     size_t maskOffset = maskRB - width;
     SkPMColor *device = (SkPMColor *)dst;
@@ -182,7 +181,7 @@ static void SkARGB32_BlitMask_portable(void* dst, size_t dstRB,
         int w = width;
         do {
             unsigned aa = *mask++;
-            *device = SkBlendARGB32(color, *device, aa);
+            *device = SkBlendARGB32(pmc, *device, aa);
             device += 1;
         } while (--w != 0);
         device = (uint32_t*)((char*)device + dstOffset);
@@ -190,15 +189,57 @@ static void SkARGB32_BlitMask_portable(void* dst, size_t dstRB,
     } while (--height != 0);
 }
 
+static void D32_Mask_Opaque(void* dst, size_t dstRB, SkBitmap::Config,
+                            const uint8_t* mask, size_t maskRB, SkColor color,
+                            int width, int height) {
+    SkPMColor pmc = SkPreMultiplyColor(color);
+    uint32_t* device = (uint32_t*)dst;
+
+    maskRB -= width;
+    dstRB -= (width << 2);
+    do {
+        int w = width;
+        do {
+            unsigned aa = *mask++;
+            *device = SkAlphaMulQ(pmc, SkAlpha255To256(aa)) + SkAlphaMulQ(*device, SkAlpha255To256(255 - aa));
+            device += 1;
+        } while (--w != 0);
+        device = (uint32_t*)((char*)device + dstRB);
+        mask += maskRB;
+    } while (--height != 0);
+}
+
+static void D32_Mask_Black(void* dst, size_t dstRB, SkBitmap::Config,
+                           const uint8_t* mask, size_t maskRB, SkColor,
+                           int width, int height) {
+    uint32_t* device = (uint32_t*)dst;
+
+    maskRB -= width;
+    dstRB -= (width << 2);
+    do {
+        int w = width;
+        do {
+            unsigned aa = *mask++;
+            *device = (aa << SK_A32_SHIFT) + SkAlphaMulQ(*device, SkAlpha255To256(255 - aa));
+            device += 1;
+        } while (--w != 0);
+        device = (uint32_t*)((char*)device + dstRB);
+        mask += maskRB;
+    } while (--height != 0);
+}
+
 SkBlitMask::Proc SkBlitMask::Factory(SkBitmap::Config config, SkColor color) {
     SkBlitMask::Proc proc = PlatformProcs(config, color);
+    proc = NULL;
     if (NULL == proc) {
         switch (config) {
             case SkBitmap::kARGB_8888_Config:
-                if ( SK_ColorBLACK != color && 0xFF != SkColorGetA(color) ) {
-                    //TODO: blitmask for black;
-                    //TODO: blitmask for opaque;
-                    proc = SkARGB32_BlitMask_portable;
+                if (SK_ColorBLACK == color) {
+                    proc = D32_Mask_Black;
+                } else if (0xFF == SkColorGetA(color)) {
+                    proc = D32_Mask_Opaque;
+                } else {
+                    proc = D32_Mask_Color;
                 }
                 break;
             default:
index 3cb69a14888c915634ffa5b210a0cf3789579d30..09cbe13710eae5e64111464a47e5caec0d067e0e 100644 (file)
@@ -68,7 +68,8 @@ static void SkARGB32_Blit32(const SkBitmap& device, const SkMask& mask,
 
 SkARGB32_Blitter::SkARGB32_Blitter(const SkBitmap& device, const SkPaint& paint)
         : INHERITED(device) {
-    uint32_t color = paint.getColor();
+    SkColor color = paint.getColor();
+    fColor = color;
 
     fSrcA = SkColorGetA(color);
     unsigned scale = SkAlpha255To256(fSrcA);
@@ -192,14 +193,11 @@ void SkARGB32_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) {
 
     int x = clip.fLeft;
     int y = clip.fTop;
-    int width = clip.width();
-    int height = clip.height();
 
-    uint32_t*       device = fDevice.getAddr32(x, y);
-    const uint8_t*  alpha = mask.getAddr(x, y);
-    uint32_t        srcColor = fPMColor;
-    fBlitMaskProc(device, fDevice.rowBytes(), SkBitmap::kARGB_8888_Config,
-                  alpha, mask.fRowBytes, srcColor, width, height);
+    fBlitMaskProc(fDevice.getAddr32(x, y), fDevice.rowBytes(),
+                  SkBitmap::kARGB_8888_Config,
+                  mask.getAddr(x, y), mask.fRowBytes,
+                  fColor, clip.width(), clip.height());
 }
 
 void SkARGB32_Opaque_Blitter::blitMask(const SkMask& mask,
@@ -225,7 +223,7 @@ void SkARGB32_Opaque_Blitter::blitMask(const SkMask& mask,
 #endif
 
     // In LCD mode the masks have either an extra couple of rows or columns on the edges.
-    uint32_t        srcColor = fPMColor;
+    SkPMColor srcColor = fPMColor;
 
 #if defined(SK_SUPPORT_LCDTEXT)
     if (lcdMode || verticalLCDMode) {
@@ -254,20 +252,9 @@ void SkARGB32_Opaque_Blitter::blitMask(const SkMask& mask,
     }
 #endif
 
-    uint32_t*      device = fDevice.getAddr32(x, y);
-    const uint8_t* alpha = mask.getAddr(x, y);
-    unsigned       maskRB = mask.fRowBytes - width;
-    unsigned       devRB = fDevice.rowBytes() - (width << 2);
-    do {
-        int w = width;
-        do {
-            unsigned aa = *alpha++;
-            *device = SkAlphaMulQ(srcColor, SkAlpha255To256(aa)) + SkAlphaMulQ(*device, SkAlpha255To256(255 - aa));
-            device += 1;
-        } while (--w != 0);
-        device = (uint32_t*)((char*)device + devRB);
-        alpha += maskRB;
-    } while (--height != 0);
+    fBlitMaskProc(fDevice.getAddr32(x, y), fDevice.rowBytes(),
+                  SkBitmap::kARGB_8888_Config,
+                  mask.getAddr(x, y), mask.fRowBytes, fColor, width, height);
 }
 
 //////////////////////////////////////////////////////////////////////////////////////
index 5a407d6023192054f4a36ff0940992d6c627d6d8..b8724c281aa8fee9b8a753984e227fffddb4cc8b 100644 (file)
@@ -101,7 +101,8 @@ public:
     virtual const SkBitmap* justAnOpaqueColor(uint32_t*);
 
 protected:
-    SkColor                fPMColor;
+    SkColor                fColor;
+    SkPMColor              fPMColor;
     SkBlitRow::ColorProc   fColor32Proc;
     SkBlitMask::Proc       fBlitMaskProc;
 
index b5757fc919aab74114622f32f62575be754ec9ba..4f69fdd60d5574c992d6580fd47c6f399df1910f 100644 (file)
@@ -393,9 +393,10 @@ void Color32_SSE2(SkPMColor dst[], const SkPMColor src[], int count,
 
 void SkARGB32_BlitMask_SSE2(void* device, size_t dstRB,
                             SkBitmap::Config dstConfig, const uint8_t* mask,
-                            size_t maskRB, SkColor color,
+                            size_t maskRB, SkColor origColor,
                             int width, int height)
 {
+    SkPMColor color = SkPreMultiplyColor(origColor);
     size_t dstOffset = dstRB - (width << 2);
     size_t maskOffset = maskRB - width;
     SkPMColor* dst = (SkPMColor *)device;