gfx/skia/trunk/src/core/SkBlitter_ARGB32.cpp

Thu, 15 Jan 2015 21:03:48 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 21:03:48 +0100
branch
TOR_BUG_9701
changeset 11
deefc01c0e14
permissions
-rw-r--r--

Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)

     1 /*
     2  * Copyright 2006 The Android Open Source Project
     3  *
     4  * Use of this source code is governed by a BSD-style license that can be
     5  * found in the LICENSE file.
     6  */
     8 #include "SkCoreBlitters.h"
     9 #include "SkColorPriv.h"
    10 #include "SkShader.h"
    11 #include "SkUtils.h"
    12 #include "SkXfermode.h"
    13 #include "SkBlitMask.h"
    15 ///////////////////////////////////////////////////////////////////////////////
    17 static void SkARGB32_Blit32(const SkBitmap& device, const SkMask& mask,
    18                             const SkIRect& clip, SkPMColor srcColor) {
    19     U8CPU alpha = SkGetPackedA32(srcColor);
    20     unsigned flags = SkBlitRow::kSrcPixelAlpha_Flag32;
    21     if (alpha != 255) {
    22         flags |= SkBlitRow::kGlobalAlpha_Flag32;
    23     }
    24     SkBlitRow::Proc32 proc = SkBlitRow::Factory32(flags);
    26     int x = clip.fLeft;
    27     int y = clip.fTop;
    28     int width = clip.width();
    29     int height = clip.height();
    31     SkPMColor*         dstRow = device.getAddr32(x, y);
    32     const SkPMColor* srcRow = reinterpret_cast<const SkPMColor*>(mask.getAddr8(x, y));
    34     do {
    35         proc(dstRow, srcRow, width, alpha);
    36         dstRow = (SkPMColor*)((char*)dstRow + device.rowBytes());
    37         srcRow = (const SkPMColor*)((const char*)srcRow + mask.fRowBytes);
    38     } while (--height != 0);
    39 }
    41 //////////////////////////////////////////////////////////////////////////////////////
    43 SkARGB32_Blitter::SkARGB32_Blitter(const SkBitmap& device, const SkPaint& paint)
    44         : INHERITED(device) {
    45     SkColor color = paint.getColor();
    46     fColor = color;
    48     fSrcA = SkColorGetA(color);
    49     unsigned scale = SkAlpha255To256(fSrcA);
    50     fSrcR = SkAlphaMul(SkColorGetR(color), scale);
    51     fSrcG = SkAlphaMul(SkColorGetG(color), scale);
    52     fSrcB = SkAlphaMul(SkColorGetB(color), scale);
    54     fPMColor = SkPackARGB32(fSrcA, fSrcR, fSrcG, fSrcB);
    55     fColor32Proc = SkBlitRow::ColorProcFactory();
    56     fColorRect32Proc = SkBlitRow::ColorRectProcFactory();
    57 }
    59 const SkBitmap* SkARGB32_Blitter::justAnOpaqueColor(uint32_t* value) {
    60     if (255 == fSrcA) {
    61         *value = fPMColor;
    62         return &fDevice;
    63     }
    64     return NULL;
    65 }
    67 #if defined _WIN32 && _MSC_VER >= 1300  // disable warning : local variable used without having been initialized
    68 #pragma warning ( push )
    69 #pragma warning ( disable : 4701 )
    70 #endif
    72 void SkARGB32_Blitter::blitH(int x, int y, int width) {
    73     SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width());
    75     uint32_t*   device = fDevice.getAddr32(x, y);
    76     fColor32Proc(device, device, width, fPMColor);
    77 }
    79 void SkARGB32_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
    80                                  const int16_t runs[]) {
    81     if (fSrcA == 0) {
    82         return;
    83     }
    85     uint32_t    color = fPMColor;
    86     uint32_t*   device = fDevice.getAddr32(x, y);
    87     unsigned    opaqueMask = fSrcA; // if fSrcA is 0xFF, then we will catch the fast opaque case
    89     for (;;) {
    90         int count = runs[0];
    91         SkASSERT(count >= 0);
    92         if (count <= 0) {
    93             return;
    94         }
    95         unsigned aa = antialias[0];
    96         if (aa) {
    97             if ((opaqueMask & aa) == 255) {
    98                 sk_memset32(device, color, count);
    99             } else {
   100                 uint32_t sc = SkAlphaMulQ(color, SkAlpha255To256(aa));
   101                 fColor32Proc(device, device, count, sc);
   102             }
   103         }
   104         runs += count;
   105         antialias += count;
   106         device += count;
   107     }
   108 }
   110 //////////////////////////////////////////////////////////////////////////////////////
   112 #define solid_8_pixels(mask, dst, color)    \
   113     do {                                    \
   114         if (mask & 0x80) dst[0] = color;    \
   115         if (mask & 0x40) dst[1] = color;    \
   116         if (mask & 0x20) dst[2] = color;    \
   117         if (mask & 0x10) dst[3] = color;    \
   118         if (mask & 0x08) dst[4] = color;    \
   119         if (mask & 0x04) dst[5] = color;    \
   120         if (mask & 0x02) dst[6] = color;    \
   121         if (mask & 0x01) dst[7] = color;    \
   122     } while (0)
   124 #define SK_BLITBWMASK_NAME                  SkARGB32_BlitBW
   125 #define SK_BLITBWMASK_ARGS                  , SkPMColor color
   126 #define SK_BLITBWMASK_BLIT8(mask, dst)      solid_8_pixels(mask, dst, color)
   127 #define SK_BLITBWMASK_GETADDR               getAddr32
   128 #define SK_BLITBWMASK_DEVTYPE               uint32_t
   129 #include "SkBlitBWMaskTemplate.h"
   131 #define blend_8_pixels(mask, dst, sc, dst_scale)                            \
   132     do {                                                                    \
   133         if (mask & 0x80) { dst[0] = sc + SkAlphaMulQ(dst[0], dst_scale); }  \
   134         if (mask & 0x40) { dst[1] = sc + SkAlphaMulQ(dst[1], dst_scale); }  \
   135         if (mask & 0x20) { dst[2] = sc + SkAlphaMulQ(dst[2], dst_scale); }  \
   136         if (mask & 0x10) { dst[3] = sc + SkAlphaMulQ(dst[3], dst_scale); }  \
   137         if (mask & 0x08) { dst[4] = sc + SkAlphaMulQ(dst[4], dst_scale); }  \
   138         if (mask & 0x04) { dst[5] = sc + SkAlphaMulQ(dst[5], dst_scale); }  \
   139         if (mask & 0x02) { dst[6] = sc + SkAlphaMulQ(dst[6], dst_scale); }  \
   140         if (mask & 0x01) { dst[7] = sc + SkAlphaMulQ(dst[7], dst_scale); }  \
   141     } while (0)
   143 #define SK_BLITBWMASK_NAME                  SkARGB32_BlendBW
   144 #define SK_BLITBWMASK_ARGS                  , uint32_t sc, unsigned dst_scale
   145 #define SK_BLITBWMASK_BLIT8(mask, dst)      blend_8_pixels(mask, dst, sc, dst_scale)
   146 #define SK_BLITBWMASK_GETADDR               getAddr32
   147 #define SK_BLITBWMASK_DEVTYPE               uint32_t
   148 #include "SkBlitBWMaskTemplate.h"
   150 void SkARGB32_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) {
   151     SkASSERT(mask.fBounds.contains(clip));
   152     SkASSERT(fSrcA != 0xFF);
   154     if (fSrcA == 0) {
   155         return;
   156     }
   158     if (SkBlitMask::BlitColor(fDevice, mask, clip, fColor)) {
   159         return;
   160     }
   162     if (mask.fFormat == SkMask::kBW_Format) {
   163         SkARGB32_BlendBW(fDevice, mask, clip, fPMColor, SkAlpha255To256(255 - fSrcA));
   164     } else if (SkMask::kARGB32_Format == mask.fFormat) {
   165         SkARGB32_Blit32(fDevice, mask, clip, fPMColor);
   166     }
   167 }
   169 void SkARGB32_Opaque_Blitter::blitMask(const SkMask& mask,
   170                                        const SkIRect& clip) {
   171     SkASSERT(mask.fBounds.contains(clip));
   173     if (SkBlitMask::BlitColor(fDevice, mask, clip, fColor)) {
   174         return;
   175     }
   177     if (mask.fFormat == SkMask::kBW_Format) {
   178         SkARGB32_BlitBW(fDevice, mask, clip, fPMColor);
   179     } else if (SkMask::kARGB32_Format == mask.fFormat) {
   180         SkARGB32_Blit32(fDevice, mask, clip, fPMColor);
   181     }
   182 }
   184 ///////////////////////////////////////////////////////////////////////////////
   186 void SkARGB32_Blitter::blitV(int x, int y, int height, SkAlpha alpha) {
   187     if (alpha == 0 || fSrcA == 0) {
   188         return;
   189     }
   191     uint32_t* device = fDevice.getAddr32(x, y);
   192     uint32_t  color = fPMColor;
   194     if (alpha != 255) {
   195         color = SkAlphaMulQ(color, SkAlpha255To256(alpha));
   196     }
   198     unsigned dst_scale = 255 - SkGetPackedA32(color);
   199     size_t rowBytes = fDevice.rowBytes();
   200     while (--height >= 0) {
   201         device[0] = color + SkAlphaMulQ(device[0], dst_scale);
   202         device = (uint32_t*)((char*)device + rowBytes);
   203     }
   204 }
   206 void SkARGB32_Blitter::blitRect(int x, int y, int width, int height) {
   207     SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width() && y + height <= fDevice.height());
   209     if (fSrcA == 0) {
   210         return;
   211     }
   213     uint32_t*   device = fDevice.getAddr32(x, y);
   214     uint32_t    color = fPMColor;
   215     size_t      rowBytes = fDevice.rowBytes();
   217     if (255 == SkGetPackedA32(color)) {
   218         fColorRect32Proc(device, width, height, rowBytes, color);
   219     } else {
   220         while (--height >= 0) {
   221             fColor32Proc(device, device, width, color);
   222             device = (uint32_t*)((char*)device + rowBytes);
   223         }
   224     }
   225 }
   227 #if defined _WIN32 && _MSC_VER >= 1300
   228 #pragma warning ( pop )
   229 #endif
   231 ///////////////////////////////////////////////////////////////////////
   233 void SkARGB32_Black_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
   234                                        const int16_t runs[]) {
   235     uint32_t*   device = fDevice.getAddr32(x, y);
   236     SkPMColor   black = (SkPMColor)(SK_A32_MASK << SK_A32_SHIFT);
   238     for (;;) {
   239         int count = runs[0];
   240         SkASSERT(count >= 0);
   241         if (count <= 0) {
   242             return;
   243         }
   244         unsigned aa = antialias[0];
   245         if (aa) {
   246             if (aa == 255) {
   247                 sk_memset32(device, black, count);
   248             } else {
   249                 SkPMColor src = aa << SK_A32_SHIFT;
   250                 unsigned dst_scale = 256 - aa;
   251                 int n = count;
   252                 do {
   253                     --n;
   254                     device[n] = src + SkAlphaMulQ(device[n], dst_scale);
   255                 } while (n > 0);
   256             }
   257         }
   258         runs += count;
   259         antialias += count;
   260         device += count;
   261     }
   262 }
   264 ///////////////////////////////////////////////////////////////////////////////
   266 // Special version of SkBlitRow::Factory32 that knows we're in kSrc_Mode,
   267 // instead of kSrcOver_Mode
   268 static void blend_srcmode(SkPMColor* SK_RESTRICT device,
   269                           const SkPMColor* SK_RESTRICT span,
   270                           int count, U8CPU aa) {
   271     int aa256 = SkAlpha255To256(aa);
   272     for (int i = 0; i < count; ++i) {
   273         device[i] = SkFourByteInterp256(span[i], device[i], aa256);
   274     }
   275 }
   277 SkARGB32_Shader_Blitter::SkARGB32_Shader_Blitter(const SkBitmap& device,
   278                             const SkPaint& paint) : INHERITED(device, paint) {
   279     fBuffer = (SkPMColor*)sk_malloc_throw(device.width() * (sizeof(SkPMColor)));
   281     fXfermode = paint.getXfermode();
   282     SkSafeRef(fXfermode);
   284     int flags = 0;
   285     if (!(fShader->getFlags() & SkShader::kOpaqueAlpha_Flag)) {
   286         flags |= SkBlitRow::kSrcPixelAlpha_Flag32;
   287     }
   288     // we call this on the output from the shader
   289     fProc32 = SkBlitRow::Factory32(flags);
   290     // we call this on the output from the shader + alpha from the aa buffer
   291     fProc32Blend = SkBlitRow::Factory32(flags | SkBlitRow::kGlobalAlpha_Flag32);
   293     fShadeDirectlyIntoDevice = false;
   294     if (fXfermode == NULL) {
   295         if (fShader->getFlags() & SkShader::kOpaqueAlpha_Flag) {
   296             fShadeDirectlyIntoDevice = true;
   297         }
   298     } else {
   299         SkXfermode::Mode mode;
   300         if (fXfermode->asMode(&mode)) {
   301             if (SkXfermode::kSrc_Mode == mode) {
   302                 fShadeDirectlyIntoDevice = true;
   303                 fProc32Blend = blend_srcmode;
   304             }
   305         }
   306     }
   308     fConstInY = SkToBool(fShader->getFlags() & SkShader::kConstInY32_Flag);
   309 }
   311 SkARGB32_Shader_Blitter::~SkARGB32_Shader_Blitter() {
   312     SkSafeUnref(fXfermode);
   313     sk_free(fBuffer);
   314 }
   316 void SkARGB32_Shader_Blitter::blitH(int x, int y, int width) {
   317     SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width());
   319     uint32_t*   device = fDevice.getAddr32(x, y);
   321     if (fShadeDirectlyIntoDevice) {
   322         fShader->shadeSpan(x, y, device, width);
   323     } else {
   324         SkPMColor*  span = fBuffer;
   325         fShader->shadeSpan(x, y, span, width);
   326         if (fXfermode) {
   327             fXfermode->xfer32(device, span, width, NULL);
   328         } else {
   329             fProc32(device, span, width, 255);
   330         }
   331     }
   332 }
   334 void SkARGB32_Shader_Blitter::blitRect(int x, int y, int width, int height) {
   335     SkASSERT(x >= 0 && y >= 0 &&
   336              x + width <= fDevice.width() && y + height <= fDevice.height());
   338     uint32_t*   device = fDevice.getAddr32(x, y);
   339     size_t      deviceRB = fDevice.rowBytes();
   340     SkShader*   shader = fShader;
   341     SkPMColor*  span = fBuffer;
   343     if (fConstInY) {
   344         if (fShadeDirectlyIntoDevice) {
   345             // shade the first row directly into the device
   346             fShader->shadeSpan(x, y, device, width);
   347             span = device;
   348             while (--height > 0) {
   349                 device = (uint32_t*)((char*)device + deviceRB);
   350                 memcpy(device, span, width << 2);
   351             }
   352         } else {
   353             fShader->shadeSpan(x, y, span, width);
   354             SkXfermode* xfer = fXfermode;
   355             if (xfer) {
   356                 do {
   357                     xfer->xfer32(device, span, width, NULL);
   358                     y += 1;
   359                     device = (uint32_t*)((char*)device + deviceRB);
   360                 } while (--height > 0);
   361             } else {
   362                 SkBlitRow::Proc32 proc = fProc32;
   363                 do {
   364                     proc(device, span, width, 255);
   365                     y += 1;
   366                     device = (uint32_t*)((char*)device + deviceRB);
   367                 } while (--height > 0);
   368             }
   369         }
   370         return;
   371     }
   373     if (fShadeDirectlyIntoDevice) {
   374         void* ctx;
   375         SkShader::ShadeProc shadeProc = fShader->asAShadeProc(&ctx);
   376         if (shadeProc) {
   377             do {
   378                 shadeProc(ctx, x, y, device, width);
   379                 y += 1;
   380                 device = (uint32_t*)((char*)device + deviceRB);
   381             } while (--height > 0);
   382         } else {
   383             do {
   384                 shader->shadeSpan(x, y, device, width);
   385                 y += 1;
   386                 device = (uint32_t*)((char*)device + deviceRB);
   387             } while (--height > 0);
   388         }
   389     } else {
   390         SkXfermode* xfer = fXfermode;
   391         if (xfer) {
   392             do {
   393                 shader->shadeSpan(x, y, span, width);
   394                 xfer->xfer32(device, span, width, NULL);
   395                 y += 1;
   396                 device = (uint32_t*)((char*)device + deviceRB);
   397             } while (--height > 0);
   398         } else {
   399             SkBlitRow::Proc32 proc = fProc32;
   400             do {
   401                 shader->shadeSpan(x, y, span, width);
   402                 proc(device, span, width, 255);
   403                 y += 1;
   404                 device = (uint32_t*)((char*)device + deviceRB);
   405             } while (--height > 0);
   406         }
   407     }
   408 }
   410 void SkARGB32_Shader_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
   411                                         const int16_t runs[]) {
   412     SkPMColor*  span = fBuffer;
   413     uint32_t*   device = fDevice.getAddr32(x, y);
   414     SkShader*   shader = fShader;
   416     if (fXfermode && !fShadeDirectlyIntoDevice) {
   417         for (;;) {
   418             SkXfermode* xfer = fXfermode;
   420             int count = *runs;
   421             if (count <= 0)
   422                 break;
   423             int aa = *antialias;
   424             if (aa) {
   425                 shader->shadeSpan(x, y, span, count);
   426                 if (aa == 255) {
   427                     xfer->xfer32(device, span, count, NULL);
   428                 } else {
   429                     // count is almost always 1
   430                     for (int i = count - 1; i >= 0; --i) {
   431                         xfer->xfer32(&device[i], &span[i], 1, antialias);
   432                     }
   433                 }
   434             }
   435             device += count;
   436             runs += count;
   437             antialias += count;
   438             x += count;
   439         }
   440     } else if (fShadeDirectlyIntoDevice ||
   441                (fShader->getFlags() & SkShader::kOpaqueAlpha_Flag)) {
   442         for (;;) {
   443             int count = *runs;
   444             if (count <= 0) {
   445                 break;
   446             }
   447             int aa = *antialias;
   448             if (aa) {
   449                 if (aa == 255) {
   450                     // cool, have the shader draw right into the device
   451                     shader->shadeSpan(x, y, device, count);
   452                 } else {
   453                     shader->shadeSpan(x, y, span, count);
   454                     fProc32Blend(device, span, count, aa);
   455                 }
   456             }
   457             device += count;
   458             runs += count;
   459             antialias += count;
   460             x += count;
   461         }
   462     } else {
   463         for (;;) {
   464             int count = *runs;
   465             if (count <= 0) {
   466                 break;
   467             }
   468             int aa = *antialias;
   469             if (aa) {
   470                 fShader->shadeSpan(x, y, span, count);
   471                 if (aa == 255) {
   472                     fProc32(device, span, count, 255);
   473                 } else {
   474                     fProc32Blend(device, span, count, aa);
   475                 }
   476             }
   477             device += count;
   478             runs += count;
   479             antialias += count;
   480             x += count;
   481         }
   482     }
   483 }
   485 void SkARGB32_Shader_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) {
   486     // we only handle kA8 with an xfermode
   487     if (fXfermode && (SkMask::kA8_Format != mask.fFormat)) {
   488         this->INHERITED::blitMask(mask, clip);
   489         return;
   490     }
   492     SkASSERT(mask.fBounds.contains(clip));
   494     SkBlitMask::RowProc proc = NULL;
   495     if (!fXfermode) {
   496         unsigned flags = 0;
   497         if (fShader->getFlags() & SkShader::kOpaqueAlpha_Flag) {
   498             flags |= SkBlitMask::kSrcIsOpaque_RowFlag;
   499         }
   500         proc = SkBlitMask::RowFactory(SkBitmap::kARGB_8888_Config, mask.fFormat,
   501                                       (SkBlitMask::RowFlags)flags);
   502         if (NULL == proc) {
   503             this->INHERITED::blitMask(mask, clip);
   504             return;
   505         }
   506     }
   508     const int x = clip.fLeft;
   509     const int width = clip.width();
   510     int y = clip.fTop;
   511     int height = clip.height();
   513     char* dstRow = (char*)fDevice.getAddr32(x, y);
   514     const size_t dstRB = fDevice.rowBytes();
   515     const uint8_t* maskRow = (const uint8_t*)mask.getAddr(x, y);
   516     const size_t maskRB = mask.fRowBytes;
   518     SkShader* shader = fShader;
   519     SkPMColor* span = fBuffer;
   521     if (fXfermode) {
   522         SkASSERT(SkMask::kA8_Format == mask.fFormat);
   523         SkXfermode* xfer = fXfermode;
   524         do {
   525             shader->shadeSpan(x, y, span, width);
   526             xfer->xfer32((SkPMColor*)dstRow, span, width, maskRow);
   527             dstRow += dstRB;
   528             maskRow += maskRB;
   529             y += 1;
   530         } while (--height > 0);
   531     } else {
   532         do {
   533             shader->shadeSpan(x, y, span, width);
   534             proc(dstRow, maskRow, span, width);
   535             dstRow += dstRB;
   536             maskRow += maskRB;
   537             y += 1;
   538         } while (--height > 0);
   539     }
   540 }
   542 void SkARGB32_Shader_Blitter::blitV(int x, int y, int height, SkAlpha alpha) {
   543     SkASSERT(x >= 0 && y >= 0 && y + height <= fDevice.height());
   545     uint32_t*   device = fDevice.getAddr32(x, y);
   546     size_t      deviceRB = fDevice.rowBytes();
   547     SkShader*   shader = fShader;
   549     if (fConstInY) {
   550         SkPMColor c;
   551         fShader->shadeSpan(x, y, &c, 1);
   553         if (fShadeDirectlyIntoDevice) {
   554             if (255 == alpha) {
   555                 do {
   556                     *device = c;
   557                     device = (uint32_t*)((char*)device + deviceRB);
   558                 } while (--height > 0);
   559             } else {
   560                 do {
   561                     *device = SkFourByteInterp(c, *device, alpha);
   562                     device = (uint32_t*)((char*)device + deviceRB);
   563                 } while (--height > 0);
   564             }
   565         } else {
   566             SkXfermode* xfer = fXfermode;
   567             if (xfer) {
   568                 do {
   569                     xfer->xfer32(device, &c, 1, &alpha);
   570                     device = (uint32_t*)((char*)device + deviceRB);
   571                 } while (--height > 0);
   572             } else {
   573                 SkBlitRow::Proc32 proc = (255 == alpha) ? fProc32 : fProc32Blend;
   574                 do {
   575                     proc(device, &c, 1, alpha);
   576                     device = (uint32_t*)((char*)device + deviceRB);
   577                 } while (--height > 0);
   578             }
   579         }
   580         return;
   581     }
   583     if (fShadeDirectlyIntoDevice) {
   584         void* ctx;
   585         SkShader::ShadeProc shadeProc = fShader->asAShadeProc(&ctx);
   586         if (255 == alpha) {
   587             if (shadeProc) {
   588                 do {
   589                     shadeProc(ctx, x, y, device, 1);
   590                     y += 1;
   591                     device = (uint32_t*)((char*)device + deviceRB);
   592                 } while (--height > 0);
   593             } else {
   594                 do {
   595                     shader->shadeSpan(x, y, device, 1);
   596                     y += 1;
   597                     device = (uint32_t*)((char*)device + deviceRB);
   598                 } while (--height > 0);
   599             }
   600         } else {    // alpha < 255
   601             SkPMColor c;
   602             if (shadeProc) {
   603                 do {
   604                     shadeProc(ctx, x, y, &c, 1);
   605                     *device = SkFourByteInterp(c, *device, alpha);
   606                     y += 1;
   607                     device = (uint32_t*)((char*)device + deviceRB);
   608                 } while (--height > 0);
   609             } else {
   610                 do {
   611                     shader->shadeSpan(x, y, &c, 1);
   612                     *device = SkFourByteInterp(c, *device, alpha);
   613                     y += 1;
   614                     device = (uint32_t*)((char*)device + deviceRB);
   615                 } while (--height > 0);
   616             }
   617         }
   618     } else {
   619         SkPMColor* span = fBuffer;
   620         SkXfermode* xfer = fXfermode;
   621         if (xfer) {
   622             do {
   623                 shader->shadeSpan(x, y, span, 1);
   624                 xfer->xfer32(device, span, 1, &alpha);
   625                 y += 1;
   626                 device = (uint32_t*)((char*)device + deviceRB);
   627             } while (--height > 0);
   628         } else {
   629             SkBlitRow::Proc32 proc = (255 == alpha) ? fProc32 : fProc32Blend;
   630             do {
   631                 shader->shadeSpan(x, y, span, 1);
   632                 proc(device, span, 1, alpha);
   633                 y += 1;
   634                 device = (uint32_t*)((char*)device + deviceRB);
   635             } while (--height > 0);
   636         }
   637     }
   638 }

mercurial