1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCoreBlitters.h"
98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorPriv.h"
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkShader.h"
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkUtils.h"
128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkXfermode.h"
1358af9a64701540c7f8083bc22a42d0bae3a5583creed@google.com#include "SkBlitMask.h"
148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
15f88d6765a594cf9fb0825b74779f74394a7ccc7areed@google.com///////////////////////////////////////////////////////////////////////////////
16f88d6765a594cf9fb0825b74779f74394a7ccc7areed@google.com
17f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comstatic void SkARGB32_Blit32(const SkBitmap& device, const SkMask& mask,
18fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com                            const SkIRect& clip, SkPMColor srcColor) {
19fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com    U8CPU alpha = SkGetPackedA32(srcColor);
20fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com    unsigned flags = SkBlitRow::kSrcPixelAlpha_Flag32;
21fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com    if (alpha != 255) {
22fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com        flags |= SkBlitRow::kGlobalAlpha_Flag32;
23fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com    }
24fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com    SkBlitRow::Proc32 proc = SkBlitRow::Factory32(flags);
25f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
26f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    int x = clip.fLeft;
27f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    int y = clip.fTop;
28f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    int width = clip.width();
29f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    int height = clip.height();
3082065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
31fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com    SkPMColor*         dstRow = device.getAddr32(x, y);
327989186dab6bc2f1c1927daf91bddd32b7fd8d0creed@google.com    const SkPMColor* srcRow = reinterpret_cast<const SkPMColor*>(mask.getAddr8(x, y));
33f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
34f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    do {
35fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com        proc(dstRow, srcRow, width, alpha);
36f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        dstRow = (SkPMColor*)((char*)dstRow + device.rowBytes());
37f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        srcRow = (const SkPMColor*)((const char*)srcRow + mask.fRowBytes);
38f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    } while (--height != 0);
39f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com}
40f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
41f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com//////////////////////////////////////////////////////////////////////////////////////
42f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkARGB32_Blitter::SkARGB32_Blitter(const SkBitmap& device, const SkPaint& paint)
448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        : INHERITED(device) {
45ee467ee79d449ebe6ae7f7946e613cc70a479c69reed@google.com    SkColor color = paint.getColor();
46ee467ee79d449ebe6ae7f7946e613cc70a479c69reed@google.com    fColor = color;
478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fSrcA = SkColorGetA(color);
498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    unsigned scale = SkAlpha255To256(fSrcA);
508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fSrcR = SkAlphaMul(SkColorGetR(color), scale);
518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fSrcG = SkAlphaMul(SkColorGetG(color), scale);
528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fSrcB = SkAlphaMul(SkColorGetB(color), scale);
538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fPMColor = SkPackARGB32(fSrcA, fSrcR, fSrcG, fSrcB);
558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkBitmap* SkARGB32_Blitter::justAnOpaqueColor(uint32_t* value) {
588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (255 == fSrcA) {
598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        *value = fPMColor;
608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return &fDevice;
618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return NULL;
638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#if defined _WIN32 && _MSC_VER >= 1300  // disable warning : local variable used without having been initialized
668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#pragma warning ( push )
678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#pragma warning ( disable : 4701 )
688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkARGB32_Blitter::blitH(int x, int y, int width) {
718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width());
728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
7329e5054dd07c97c2195c5f64bf67aaa6b5afa204senorblanco@chromium.org    uint32_t*   device = fDevice.getAddr32(x, y);
7495cc012ccaea20f372893ae277ea0a8a6339d094mtklein    SkBlitRow::Color32(device, device, width, fPMColor);
758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkARGB32_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                 const int16_t runs[]) {
798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fSrcA == 0) {
808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return;
818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint32_t    color = fPMColor;
848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint32_t*   device = fDevice.getAddr32(x, y);
858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    unsigned    opaqueMask = fSrcA; // if fSrcA is 0xFF, then we will catch the fast opaque case
868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (;;) {
888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        int count = runs[0];
898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT(count >= 0);
908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (count <= 0) {
918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return;
928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned aa = antialias[0];
948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (aa) {
958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if ((opaqueMask & aa) == 255) {
968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                sk_memset32(device, color, count);
978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            } else {
98c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com                uint32_t sc = SkAlphaMulQ(color, SkAlpha255To256(aa));
9995cc012ccaea20f372893ae277ea0a8a6339d094mtklein                SkBlitRow::Color32(device, device, count, sc);
1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        runs += count;
1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        antialias += count;
1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        device += count;
1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1086983f66d8b3a489133b751e2cef03e72a03bfeaereedvoid SkARGB32_Blitter::blitAntiH2(int x, int y, U8CPU a0, U8CPU a1) {
1096983f66d8b3a489133b751e2cef03e72a03bfeaereed    uint32_t* device = fDevice.getAddr32(x, y);
1106983f66d8b3a489133b751e2cef03e72a03bfeaereed    SkDEBUGCODE((void)fDevice.getAddr32(x + 1, y);)
11195cc012ccaea20f372893ae277ea0a8a6339d094mtklein
1126983f66d8b3a489133b751e2cef03e72a03bfeaereed    device[0] = SkBlendARGB32(fPMColor, device[0], a0);
1136983f66d8b3a489133b751e2cef03e72a03bfeaereed    device[1] = SkBlendARGB32(fPMColor, device[1], a1);
1146983f66d8b3a489133b751e2cef03e72a03bfeaereed}
1156983f66d8b3a489133b751e2cef03e72a03bfeaereed
1166983f66d8b3a489133b751e2cef03e72a03bfeaereedvoid SkARGB32_Blitter::blitAntiV2(int x, int y, U8CPU a0, U8CPU a1) {
1176983f66d8b3a489133b751e2cef03e72a03bfeaereed    uint32_t* device = fDevice.getAddr32(x, y);
1186983f66d8b3a489133b751e2cef03e72a03bfeaereed    SkDEBUGCODE((void)fDevice.getAddr32(x, y + 1);)
11995cc012ccaea20f372893ae277ea0a8a6339d094mtklein
1206983f66d8b3a489133b751e2cef03e72a03bfeaereed    device[0] = SkBlendARGB32(fPMColor, device[0], a0);
1216983f66d8b3a489133b751e2cef03e72a03bfeaereed    device = (uint32_t*)((char*)device + fDevice.rowBytes());
1226983f66d8b3a489133b751e2cef03e72a03bfeaereed    device[0] = SkBlendARGB32(fPMColor, device[0], a1);
1236983f66d8b3a489133b751e2cef03e72a03bfeaereed}
1246983f66d8b3a489133b751e2cef03e72a03bfeaereed
1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////////////////////
1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define solid_8_pixels(mask, dst, color)    \
1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    do {                                    \
1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (mask & 0x80) dst[0] = color;    \
1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (mask & 0x40) dst[1] = color;    \
1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (mask & 0x20) dst[2] = color;    \
1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (mask & 0x10) dst[3] = color;    \
1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (mask & 0x08) dst[4] = color;    \
1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (mask & 0x04) dst[5] = color;    \
1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (mask & 0x02) dst[6] = color;    \
1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (mask & 0x01) dst[7] = color;    \
1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    } while (0)
1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_NAME                  SkARGB32_BlitBW
1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_ARGS                  , SkPMColor color
1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_BLIT8(mask, dst)      solid_8_pixels(mask, dst, color)
1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_GETADDR               getAddr32
1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_DEVTYPE               uint32_t
1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkBlitBWMaskTemplate.h"
1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define blend_8_pixels(mask, dst, sc, dst_scale)                            \
1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    do {                                                                    \
1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (mask & 0x80) { dst[0] = sc + SkAlphaMulQ(dst[0], dst_scale); }  \
1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (mask & 0x40) { dst[1] = sc + SkAlphaMulQ(dst[1], dst_scale); }  \
1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (mask & 0x20) { dst[2] = sc + SkAlphaMulQ(dst[2], dst_scale); }  \
1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (mask & 0x10) { dst[3] = sc + SkAlphaMulQ(dst[3], dst_scale); }  \
1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (mask & 0x08) { dst[4] = sc + SkAlphaMulQ(dst[4], dst_scale); }  \
1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (mask & 0x04) { dst[5] = sc + SkAlphaMulQ(dst[5], dst_scale); }  \
1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (mask & 0x02) { dst[6] = sc + SkAlphaMulQ(dst[6], dst_scale); }  \
1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (mask & 0x01) { dst[7] = sc + SkAlphaMulQ(dst[7], dst_scale); }  \
1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    } while (0)
1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_NAME                  SkARGB32_BlendBW
1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_ARGS                  , uint32_t sc, unsigned dst_scale
1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_BLIT8(mask, dst)      blend_8_pixels(mask, dst, sc, dst_scale)
1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_GETADDR               getAddr32
1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_DEVTYPE               uint32_t
1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkBlitBWMaskTemplate.h"
1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkARGB32_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) {
1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(mask.fBounds.contains(clip));
1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(fSrcA != 0xFF);
1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fSrcA == 0) {
1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return;
1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
173edb606cb999887d54629f361bcbf57c5fede1bb0reed@google.com    if (SkBlitMask::BlitColor(fDevice, mask, clip, fColor)) {
174edb606cb999887d54629f361bcbf57c5fede1bb0reed@google.com        return;
175edb606cb999887d54629f361bcbf57c5fede1bb0reed@google.com    }
176edb606cb999887d54629f361bcbf57c5fede1bb0reed@google.com
1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (mask.fFormat == SkMask::kBW_Format) {
1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkARGB32_BlendBW(fDevice, mask, clip, fPMColor, SkAlpha255To256(255 - fSrcA));
179f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    } else if (SkMask::kARGB32_Format == mask.fFormat) {
180fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com        SkARGB32_Blit32(fDevice, mask, clip, fPMColor);
1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkARGB32_Opaque_Blitter::blitMask(const SkMask& mask,
1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                       const SkIRect& clip) {
1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(mask.fBounds.contains(clip));
1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
188edb606cb999887d54629f361bcbf57c5fede1bb0reed@google.com    if (SkBlitMask::BlitColor(fDevice, mask, clip, fColor)) {
189edb606cb999887d54629f361bcbf57c5fede1bb0reed@google.com        return;
190edb606cb999887d54629f361bcbf57c5fede1bb0reed@google.com    }
191fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (mask.fFormat == SkMask::kBW_Format) {
1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkARGB32_BlitBW(fDevice, mask, clip, fPMColor);
194f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    } else if (SkMask::kARGB32_Format == mask.fFormat) {
195fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com        SkARGB32_Blit32(fDevice, mask, clip, fPMColor);
196fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com    }
1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1996983f66d8b3a489133b751e2cef03e72a03bfeaereedvoid SkARGB32_Opaque_Blitter::blitAntiH2(int x, int y, U8CPU a0, U8CPU a1) {
2006983f66d8b3a489133b751e2cef03e72a03bfeaereed    uint32_t* device = fDevice.getAddr32(x, y);
2016983f66d8b3a489133b751e2cef03e72a03bfeaereed    SkDEBUGCODE((void)fDevice.getAddr32(x + 1, y);)
2026983f66d8b3a489133b751e2cef03e72a03bfeaereed
2036983f66d8b3a489133b751e2cef03e72a03bfeaereed    device[0] = SkFastFourByteInterp(fPMColor, device[0], a0);
2046983f66d8b3a489133b751e2cef03e72a03bfeaereed    device[1] = SkFastFourByteInterp(fPMColor, device[1], a1);
2056983f66d8b3a489133b751e2cef03e72a03bfeaereed}
2066983f66d8b3a489133b751e2cef03e72a03bfeaereed
2076983f66d8b3a489133b751e2cef03e72a03bfeaereedvoid SkARGB32_Opaque_Blitter::blitAntiV2(int x, int y, U8CPU a0, U8CPU a1) {
2086983f66d8b3a489133b751e2cef03e72a03bfeaereed    uint32_t* device = fDevice.getAddr32(x, y);
2096983f66d8b3a489133b751e2cef03e72a03bfeaereed    SkDEBUGCODE((void)fDevice.getAddr32(x, y + 1);)
2106983f66d8b3a489133b751e2cef03e72a03bfeaereed
2116983f66d8b3a489133b751e2cef03e72a03bfeaereed    device[0] = SkFastFourByteInterp(fPMColor, device[0], a0);
2126983f66d8b3a489133b751e2cef03e72a03bfeaereed    device = (uint32_t*)((char*)device + fDevice.rowBytes());
2136983f66d8b3a489133b751e2cef03e72a03bfeaereed    device[0] = SkFastFourByteInterp(fPMColor, device[0], a1);
2146983f66d8b3a489133b751e2cef03e72a03bfeaereed}
2156983f66d8b3a489133b751e2cef03e72a03bfeaereed
21667cdbf5c63cfd77523d2a3070a44a200fabf0739reed@google.com///////////////////////////////////////////////////////////////////////////////
2178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkARGB32_Blitter::blitV(int x, int y, int height, SkAlpha alpha) {
2198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (alpha == 0 || fSrcA == 0) {
2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return;
2218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint32_t* device = fDevice.getAddr32(x, y);
2248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint32_t  color = fPMColor;
2258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (alpha != 255) {
2278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        color = SkAlphaMulQ(color, SkAlpha255To256(alpha));
2288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    unsigned dst_scale = 255 - SkGetPackedA32(color);
231e5f48243bdbed2662be7a31be0888abc273b09e8scroggo@google.com    size_t rowBytes = fDevice.rowBytes();
2328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    while (--height >= 0) {
23367cdbf5c63cfd77523d2a3070a44a200fabf0739reed@google.com        device[0] = color + SkAlphaMulQ(device[0], dst_scale);
2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        device = (uint32_t*)((char*)device + rowBytes);
2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkARGB32_Blitter::blitRect(int x, int y, int width, int height) {
2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width() && y + height <= fDevice.height());
2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fSrcA == 0) {
2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return;
2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint32_t*   device = fDevice.getAddr32(x, y);
2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint32_t    color = fPMColor;
247c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com    size_t      rowBytes = fDevice.rowBytes();
2488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
249edeccc58606e0421a1ae275e391ee4347c6f52f6mtklein    while (--height >= 0) {
25095cc012ccaea20f372893ae277ea0a8a6339d094mtklein        SkBlitRow::Color32(device, device, width, color);
251edeccc58606e0421a1ae275e391ee4347c6f52f6mtklein        device = (uint32_t*)((char*)device + rowBytes);
25257e080c1eb34253a3fc3829c2b03bb3ee63e006ftomhudson@google.com    }
2538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#if defined _WIN32 && _MSC_VER >= 1300
2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#pragma warning ( pop )
2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////
2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkARGB32_Black_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                       const int16_t runs[]) {
2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint32_t*   device = fDevice.getAddr32(x, y);
2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPMColor   black = (SkPMColor)(SK_A32_MASK << SK_A32_SHIFT);
2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (;;) {
2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        int count = runs[0];
2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT(count >= 0);
2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (count <= 0) {
2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return;
2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned aa = antialias[0];
2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (aa) {
2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if (aa == 255) {
2758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                sk_memset32(device, black, count);
2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            } else {
2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                SkPMColor src = aa << SK_A32_SHIFT;
2788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                unsigned dst_scale = 256 - aa;
2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                int n = count;
2808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                do {
2818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    --n;
2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    device[n] = src + SkAlphaMulQ(device[n], dst_scale);
2838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                } while (n > 0);
2848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
2858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
2868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        runs += count;
2878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        antialias += count;
2888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        device += count;
2898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2926983f66d8b3a489133b751e2cef03e72a03bfeaereedvoid SkARGB32_Black_Blitter::blitAntiH2(int x, int y, U8CPU a0, U8CPU a1) {
2936983f66d8b3a489133b751e2cef03e72a03bfeaereed    uint32_t* device = fDevice.getAddr32(x, y);
2946983f66d8b3a489133b751e2cef03e72a03bfeaereed    SkDEBUGCODE((void)fDevice.getAddr32(x + 1, y);)
2956983f66d8b3a489133b751e2cef03e72a03bfeaereed
2966983f66d8b3a489133b751e2cef03e72a03bfeaereed    device[0] = (a0 << SK_A32_SHIFT) + SkAlphaMulQ(device[0], 256 - a0);
2976983f66d8b3a489133b751e2cef03e72a03bfeaereed    device[1] = (a1 << SK_A32_SHIFT) + SkAlphaMulQ(device[1], 256 - a1);
2986983f66d8b3a489133b751e2cef03e72a03bfeaereed}
2996983f66d8b3a489133b751e2cef03e72a03bfeaereed
3006983f66d8b3a489133b751e2cef03e72a03bfeaereedvoid SkARGB32_Black_Blitter::blitAntiV2(int x, int y, U8CPU a0, U8CPU a1) {
3016983f66d8b3a489133b751e2cef03e72a03bfeaereed    uint32_t* device = fDevice.getAddr32(x, y);
3026983f66d8b3a489133b751e2cef03e72a03bfeaereed    SkDEBUGCODE((void)fDevice.getAddr32(x, y + 1);)
30395cc012ccaea20f372893ae277ea0a8a6339d094mtklein
3046983f66d8b3a489133b751e2cef03e72a03bfeaereed    device[0] = (a0 << SK_A32_SHIFT) + SkAlphaMulQ(device[0], 256 - a0);
3056983f66d8b3a489133b751e2cef03e72a03bfeaereed    device = (uint32_t*)((char*)device + fDevice.rowBytes());
3066983f66d8b3a489133b751e2cef03e72a03bfeaereed    device[0] = (a1 << SK_A32_SHIFT) + SkAlphaMulQ(device[0], 256 - a1);
3076983f66d8b3a489133b751e2cef03e72a03bfeaereed}
3086983f66d8b3a489133b751e2cef03e72a03bfeaereed
3091750bf17635e788198200f971d9cb66f67399363reed@google.com///////////////////////////////////////////////////////////////////////////////
3108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
31113201e74f43b9c5fa173339eb36de515370e6973reed@google.com// Special version of SkBlitRow::Factory32 that knows we're in kSrc_Mode,
31213201e74f43b9c5fa173339eb36de515370e6973reed@google.com// instead of kSrcOver_Mode
31313201e74f43b9c5fa173339eb36de515370e6973reed@google.comstatic void blend_srcmode(SkPMColor* SK_RESTRICT device,
31413201e74f43b9c5fa173339eb36de515370e6973reed@google.com                          const SkPMColor* SK_RESTRICT span,
31513201e74f43b9c5fa173339eb36de515370e6973reed@google.com                          int count, U8CPU aa) {
31613201e74f43b9c5fa173339eb36de515370e6973reed@google.com    int aa256 = SkAlpha255To256(aa);
31713201e74f43b9c5fa173339eb36de515370e6973reed@google.com    for (int i = 0; i < count; ++i) {
31813201e74f43b9c5fa173339eb36de515370e6973reed@google.com        device[i] = SkFourByteInterp256(span[i], device[i], aa256);
31913201e74f43b9c5fa173339eb36de515370e6973reed@google.com    }
32013201e74f43b9c5fa173339eb36de515370e6973reed@google.com}
32113201e74f43b9c5fa173339eb36de515370e6973reed@google.com
3228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkARGB32_Shader_Blitter::SkARGB32_Shader_Blitter(const SkBitmap& device,
32387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        const SkPaint& paint, SkShader::Context* shaderContext)
32487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    : INHERITED(device, paint, shaderContext)
32587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org{
3268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fBuffer = (SkPMColor*)sk_malloc_throw(device.width() * (sizeof(SkPMColor)));
3278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
328c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com    fXfermode = paint.getXfermode();
329c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com    SkSafeRef(fXfermode);
330c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com
331c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com    int flags = 0;
33287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    if (!(shaderContext->getFlags() & SkShader::kOpaqueAlpha_Flag)) {
333c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com        flags |= SkBlitRow::kSrcPixelAlpha_Flag32;
334c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com    }
335c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com    // we call this on the output from the shader
336c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com    fProc32 = SkBlitRow::Factory32(flags);
337c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com    // we call this on the output from the shader + alpha from the aa buffer
338c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com    fProc32Blend = SkBlitRow::Factory32(flags | SkBlitRow::kGlobalAlpha_Flag32);
33913201e74f43b9c5fa173339eb36de515370e6973reed@google.com
34013201e74f43b9c5fa173339eb36de515370e6973reed@google.com    fShadeDirectlyIntoDevice = false;
34113201e74f43b9c5fa173339eb36de515370e6973reed@google.com    if (fXfermode == NULL) {
34287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        if (shaderContext->getFlags() & SkShader::kOpaqueAlpha_Flag) {
34313201e74f43b9c5fa173339eb36de515370e6973reed@google.com            fShadeDirectlyIntoDevice = true;
34413201e74f43b9c5fa173339eb36de515370e6973reed@google.com        }
34513201e74f43b9c5fa173339eb36de515370e6973reed@google.com    } else {
34613201e74f43b9c5fa173339eb36de515370e6973reed@google.com        SkXfermode::Mode mode;
34713201e74f43b9c5fa173339eb36de515370e6973reed@google.com        if (fXfermode->asMode(&mode)) {
34813201e74f43b9c5fa173339eb36de515370e6973reed@google.com            if (SkXfermode::kSrc_Mode == mode) {
34913201e74f43b9c5fa173339eb36de515370e6973reed@google.com                fShadeDirectlyIntoDevice = true;
35013201e74f43b9c5fa173339eb36de515370e6973reed@google.com                fProc32Blend = blend_srcmode;
35113201e74f43b9c5fa173339eb36de515370e6973reed@google.com            }
35213201e74f43b9c5fa173339eb36de515370e6973reed@google.com        }
35313201e74f43b9c5fa173339eb36de515370e6973reed@google.com    }
35413201e74f43b9c5fa173339eb36de515370e6973reed@google.com
35587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    fConstInY = SkToBool(shaderContext->getFlags() & SkShader::kConstInY32_Flag);
3568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkARGB32_Shader_Blitter::~SkARGB32_Shader_Blitter() {
35982065d667f64e232bcde2ad849756a6096fcbe6freed@google.com    SkSafeUnref(fXfermode);
3608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    sk_free(fBuffer);
3618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkARGB32_Shader_Blitter::blitH(int x, int y, int width) {
3648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width());
3658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint32_t*   device = fDevice.getAddr32(x, y);
3678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
36813201e74f43b9c5fa173339eb36de515370e6973reed@google.com    if (fShadeDirectlyIntoDevice) {
36987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        fShaderContext->shadeSpan(x, y, device, width);
3708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    } else {
3718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkPMColor*  span = fBuffer;
37287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        fShaderContext->shadeSpan(x, y, span, width);
3738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (fXfermode) {
3748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            fXfermode->xfer32(device, span, width, NULL);
3758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        } else {
376c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com            fProc32(device, span, width, 255);
3778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
3788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
3798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3813bafe74a29c37761082980ed4ee9b831256bd27ereed@google.comvoid SkARGB32_Shader_Blitter::blitRect(int x, int y, int width, int height) {
3823bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com    SkASSERT(x >= 0 && y >= 0 &&
3833bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com             x + width <= fDevice.width() && y + height <= fDevice.height());
384f57c01bdcfdf1c923b9a473974bfe6f8c66eca3eskia.committer@gmail.com
38587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    uint32_t*          device = fDevice.getAddr32(x, y);
38687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    size_t             deviceRB = fDevice.rowBytes();
38787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    SkShader::Context* shaderContext = fShaderContext;
38887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    SkPMColor*         span = fBuffer;
38913201e74f43b9c5fa173339eb36de515370e6973reed@google.com
39013201e74f43b9c5fa173339eb36de515370e6973reed@google.com    if (fConstInY) {
39113201e74f43b9c5fa173339eb36de515370e6973reed@google.com        if (fShadeDirectlyIntoDevice) {
39213201e74f43b9c5fa173339eb36de515370e6973reed@google.com            // shade the first row directly into the device
39387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org            shaderContext->shadeSpan(x, y, device, width);
39413201e74f43b9c5fa173339eb36de515370e6973reed@google.com            span = device;
39513201e74f43b9c5fa173339eb36de515370e6973reed@google.com            while (--height > 0) {
39613201e74f43b9c5fa173339eb36de515370e6973reed@google.com                device = (uint32_t*)((char*)device + deviceRB);
39713201e74f43b9c5fa173339eb36de515370e6973reed@google.com                memcpy(device, span, width << 2);
39813201e74f43b9c5fa173339eb36de515370e6973reed@google.com            }
39913201e74f43b9c5fa173339eb36de515370e6973reed@google.com        } else {
40087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org            shaderContext->shadeSpan(x, y, span, width);
40113201e74f43b9c5fa173339eb36de515370e6973reed@google.com            SkXfermode* xfer = fXfermode;
40213201e74f43b9c5fa173339eb36de515370e6973reed@google.com            if (xfer) {
40313201e74f43b9c5fa173339eb36de515370e6973reed@google.com                do {
40413201e74f43b9c5fa173339eb36de515370e6973reed@google.com                    xfer->xfer32(device, span, width, NULL);
40513201e74f43b9c5fa173339eb36de515370e6973reed@google.com                    y += 1;
40613201e74f43b9c5fa173339eb36de515370e6973reed@google.com                    device = (uint32_t*)((char*)device + deviceRB);
40713201e74f43b9c5fa173339eb36de515370e6973reed@google.com                } while (--height > 0);
40813201e74f43b9c5fa173339eb36de515370e6973reed@google.com            } else {
40913201e74f43b9c5fa173339eb36de515370e6973reed@google.com                SkBlitRow::Proc32 proc = fProc32;
41013201e74f43b9c5fa173339eb36de515370e6973reed@google.com                do {
41113201e74f43b9c5fa173339eb36de515370e6973reed@google.com                    proc(device, span, width, 255);
41213201e74f43b9c5fa173339eb36de515370e6973reed@google.com                    y += 1;
41313201e74f43b9c5fa173339eb36de515370e6973reed@google.com                    device = (uint32_t*)((char*)device + deviceRB);
41413201e74f43b9c5fa173339eb36de515370e6973reed@google.com                } while (--height > 0);
41513201e74f43b9c5fa173339eb36de515370e6973reed@google.com            }
41613201e74f43b9c5fa173339eb36de515370e6973reed@google.com        }
41713201e74f43b9c5fa173339eb36de515370e6973reed@google.com        return;
41813201e74f43b9c5fa173339eb36de515370e6973reed@google.com    }
4193bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com
42013201e74f43b9c5fa173339eb36de515370e6973reed@google.com    if (fShadeDirectlyIntoDevice) {
4213bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com        void* ctx;
42287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        SkShader::Context::ShadeProc shadeProc = shaderContext->asAShadeProc(&ctx);
4233bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com        if (shadeProc) {
4243bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com            do {
4253bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com                shadeProc(ctx, x, y, device, width);
4263bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com                y += 1;
4273bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com                device = (uint32_t*)((char*)device + deviceRB);
4283bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com            } while (--height > 0);
4293bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com        } else {
4303bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com            do {
43187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org                shaderContext->shadeSpan(x, y, device, width);
4323bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com                y += 1;
4333bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com                device = (uint32_t*)((char*)device + deviceRB);
4343bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com            } while (--height > 0);
4353bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com        }
4363bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com    } else {
4373bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com        SkXfermode* xfer = fXfermode;
4383bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com        if (xfer) {
4393bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com            do {
44087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org                shaderContext->shadeSpan(x, y, span, width);
4413bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com                xfer->xfer32(device, span, width, NULL);
4423bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com                y += 1;
4433bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com                device = (uint32_t*)((char*)device + deviceRB);
4443bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com            } while (--height > 0);
4453bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com        } else {
4463bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com            SkBlitRow::Proc32 proc = fProc32;
4473bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com            do {
44887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org                shaderContext->shadeSpan(x, y, span, width);
4493bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com                proc(device, span, width, 255);
4503bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com                y += 1;
4513bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com                device = (uint32_t*)((char*)device + deviceRB);
4523bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com            } while (--height > 0);
4533bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com        }
4543bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com    }
4553bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com}
4563bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com
4578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkARGB32_Shader_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
4588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                        const int16_t runs[]) {
45987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    SkPMColor*         span = fBuffer;
46087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    uint32_t*          device = fDevice.getAddr32(x, y);
46187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    SkShader::Context* shaderContext = fShaderContext;
4628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
46313201e74f43b9c5fa173339eb36de515370e6973reed@google.com    if (fXfermode && !fShadeDirectlyIntoDevice) {
4648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        for (;;) {
4658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            SkXfermode* xfer = fXfermode;
4668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            int count = *runs;
4688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if (count <= 0)
4698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                break;
4708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            int aa = *antialias;
4718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if (aa) {
47287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org                shaderContext->shadeSpan(x, y, span, count);
4738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                if (aa == 255) {
4748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    xfer->xfer32(device, span, count, NULL);
4758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                } else {
4768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    // count is almost always 1
4778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    for (int i = count - 1; i >= 0; --i) {
4788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                        xfer->xfer32(&device[i], &span[i], 1, antialias);
4798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    }
4808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                }
4818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
4828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            device += count;
4838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            runs += count;
4848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            antialias += count;
4858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            x += count;
48682065d667f64e232bcde2ad849756a6096fcbe6freed@google.com        }
48713201e74f43b9c5fa173339eb36de515370e6973reed@google.com    } else if (fShadeDirectlyIntoDevice ||
48887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org               (shaderContext->getFlags() & SkShader::kOpaqueAlpha_Flag)) {
4898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        for (;;) {
4908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            int count = *runs;
4918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if (count <= 0) {
4928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                break;
4938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
4948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            int aa = *antialias;
4958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if (aa) {
496c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com                if (aa == 255) {
497c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com                    // cool, have the shader draw right into the device
49887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org                    shaderContext->shadeSpan(x, y, device, count);
4998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                } else {
50087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org                    shaderContext->shadeSpan(x, y, span, count);
501c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com                    fProc32Blend(device, span, count, aa);
5028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                }
5038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
5048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            device += count;
5058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            runs += count;
5068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            antialias += count;
5078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            x += count;
50882065d667f64e232bcde2ad849756a6096fcbe6freed@google.com        }
50913201e74f43b9c5fa173339eb36de515370e6973reed@google.com    } else {
5108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        for (;;) {
5118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            int count = *runs;
5128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if (count <= 0) {
5138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                break;
5148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
5158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            int aa = *antialias;
5168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if (aa) {
51787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org                shaderContext->shadeSpan(x, y, span, count);
5188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                if (aa == 255) {
519c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com                    fProc32(device, span, count, 255);
5208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                } else {
521c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com                    fProc32Blend(device, span, count, aa);
5228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                }
5238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
5248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            device += count;
5258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            runs += count;
5268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            antialias += count;
5278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            x += count;
52882065d667f64e232bcde2ad849756a6096fcbe6freed@google.com        }
5298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
5308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
5311750bf17635e788198200f971d9cb66f67399363reed@google.com
5321750bf17635e788198200f971d9cb66f67399363reed@google.comvoid SkARGB32_Shader_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) {
5331750bf17635e788198200f971d9cb66f67399363reed@google.com    // we only handle kA8 with an xfermode
5341750bf17635e788198200f971d9cb66f67399363reed@google.com    if (fXfermode && (SkMask::kA8_Format != mask.fFormat)) {
5351750bf17635e788198200f971d9cb66f67399363reed@google.com        this->INHERITED::blitMask(mask, clip);
5361750bf17635e788198200f971d9cb66f67399363reed@google.com        return;
5371750bf17635e788198200f971d9cb66f67399363reed@google.com    }
5381750bf17635e788198200f971d9cb66f67399363reed@google.com
5391750bf17635e788198200f971d9cb66f67399363reed@google.com    SkASSERT(mask.fBounds.contains(clip));
5401750bf17635e788198200f971d9cb66f67399363reed@google.com
54187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    SkShader::Context*  shaderContext = fShaderContext;
5421750bf17635e788198200f971d9cb66f67399363reed@google.com    SkBlitMask::RowProc proc = NULL;
5431750bf17635e788198200f971d9cb66f67399363reed@google.com    if (!fXfermode) {
5441750bf17635e788198200f971d9cb66f67399363reed@google.com        unsigned flags = 0;
54587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        if (shaderContext->getFlags() & SkShader::kOpaqueAlpha_Flag) {
5461750bf17635e788198200f971d9cb66f67399363reed@google.com            flags |= SkBlitMask::kSrcIsOpaque_RowFlag;
5471750bf17635e788198200f971d9cb66f67399363reed@google.com        }
548cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org        proc = SkBlitMask::RowFactory(kN32_SkColorType, mask.fFormat,
5491750bf17635e788198200f971d9cb66f67399363reed@google.com                                      (SkBlitMask::RowFlags)flags);
5501750bf17635e788198200f971d9cb66f67399363reed@google.com        if (NULL == proc) {
5511750bf17635e788198200f971d9cb66f67399363reed@google.com            this->INHERITED::blitMask(mask, clip);
5521750bf17635e788198200f971d9cb66f67399363reed@google.com            return;
5531750bf17635e788198200f971d9cb66f67399363reed@google.com        }
5541750bf17635e788198200f971d9cb66f67399363reed@google.com    }
5551750bf17635e788198200f971d9cb66f67399363reed@google.com
5561750bf17635e788198200f971d9cb66f67399363reed@google.com    const int x = clip.fLeft;
5571750bf17635e788198200f971d9cb66f67399363reed@google.com    const int width = clip.width();
5581750bf17635e788198200f971d9cb66f67399363reed@google.com    int y = clip.fTop;
5591750bf17635e788198200f971d9cb66f67399363reed@google.com    int height = clip.height();
5601750bf17635e788198200f971d9cb66f67399363reed@google.com
5611750bf17635e788198200f971d9cb66f67399363reed@google.com    char* dstRow = (char*)fDevice.getAddr32(x, y);
5621750bf17635e788198200f971d9cb66f67399363reed@google.com    const size_t dstRB = fDevice.rowBytes();
5631750bf17635e788198200f971d9cb66f67399363reed@google.com    const uint8_t* maskRow = (const uint8_t*)mask.getAddr(x, y);
5641750bf17635e788198200f971d9cb66f67399363reed@google.com    const size_t maskRB = mask.fRowBytes;
5651750bf17635e788198200f971d9cb66f67399363reed@google.com
5661750bf17635e788198200f971d9cb66f67399363reed@google.com    SkPMColor* span = fBuffer;
5671750bf17635e788198200f971d9cb66f67399363reed@google.com
5681750bf17635e788198200f971d9cb66f67399363reed@google.com    if (fXfermode) {
5691750bf17635e788198200f971d9cb66f67399363reed@google.com        SkASSERT(SkMask::kA8_Format == mask.fFormat);
5701750bf17635e788198200f971d9cb66f67399363reed@google.com        SkXfermode* xfer = fXfermode;
5711750bf17635e788198200f971d9cb66f67399363reed@google.com        do {
57287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org            shaderContext->shadeSpan(x, y, span, width);
5731750bf17635e788198200f971d9cb66f67399363reed@google.com            xfer->xfer32((SkPMColor*)dstRow, span, width, maskRow);
5741750bf17635e788198200f971d9cb66f67399363reed@google.com            dstRow += dstRB;
5751750bf17635e788198200f971d9cb66f67399363reed@google.com            maskRow += maskRB;
5761750bf17635e788198200f971d9cb66f67399363reed@google.com            y += 1;
5771750bf17635e788198200f971d9cb66f67399363reed@google.com        } while (--height > 0);
5781750bf17635e788198200f971d9cb66f67399363reed@google.com    } else {
5791750bf17635e788198200f971d9cb66f67399363reed@google.com        do {
58087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org            shaderContext->shadeSpan(x, y, span, width);
5811750bf17635e788198200f971d9cb66f67399363reed@google.com            proc(dstRow, maskRow, span, width);
5821750bf17635e788198200f971d9cb66f67399363reed@google.com            dstRow += dstRB;
5831750bf17635e788198200f971d9cb66f67399363reed@google.com            maskRow += maskRB;
5841750bf17635e788198200f971d9cb66f67399363reed@google.com            y += 1;
5851750bf17635e788198200f971d9cb66f67399363reed@google.com        } while (--height > 0);
5861750bf17635e788198200f971d9cb66f67399363reed@google.com    }
5871750bf17635e788198200f971d9cb66f67399363reed@google.com}
5881750bf17635e788198200f971d9cb66f67399363reed@google.com
58913201e74f43b9c5fa173339eb36de515370e6973reed@google.comvoid SkARGB32_Shader_Blitter::blitV(int x, int y, int height, SkAlpha alpha) {
59013201e74f43b9c5fa173339eb36de515370e6973reed@google.com    SkASSERT(x >= 0 && y >= 0 && y + height <= fDevice.height());
591886b25f14ce6a6974521f096eb5feac0b4327236skia.committer@gmail.com
59287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    uint32_t*          device = fDevice.getAddr32(x, y);
59387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    size_t             deviceRB = fDevice.rowBytes();
59487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    SkShader::Context* shaderContext = fShaderContext;
595886b25f14ce6a6974521f096eb5feac0b4327236skia.committer@gmail.com
59613201e74f43b9c5fa173339eb36de515370e6973reed@google.com    if (fConstInY) {
59713201e74f43b9c5fa173339eb36de515370e6973reed@google.com        SkPMColor c;
59887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        shaderContext->shadeSpan(x, y, &c, 1);
59913201e74f43b9c5fa173339eb36de515370e6973reed@google.com
60013201e74f43b9c5fa173339eb36de515370e6973reed@google.com        if (fShadeDirectlyIntoDevice) {
60113201e74f43b9c5fa173339eb36de515370e6973reed@google.com            if (255 == alpha) {
60213201e74f43b9c5fa173339eb36de515370e6973reed@google.com                do {
60313201e74f43b9c5fa173339eb36de515370e6973reed@google.com                    *device = c;
60413201e74f43b9c5fa173339eb36de515370e6973reed@google.com                    device = (uint32_t*)((char*)device + deviceRB);
60513201e74f43b9c5fa173339eb36de515370e6973reed@google.com                } while (--height > 0);
60613201e74f43b9c5fa173339eb36de515370e6973reed@google.com            } else {
60713201e74f43b9c5fa173339eb36de515370e6973reed@google.com                do {
60813201e74f43b9c5fa173339eb36de515370e6973reed@google.com                    *device = SkFourByteInterp(c, *device, alpha);
60913201e74f43b9c5fa173339eb36de515370e6973reed@google.com                    device = (uint32_t*)((char*)device + deviceRB);
61013201e74f43b9c5fa173339eb36de515370e6973reed@google.com                } while (--height > 0);
61113201e74f43b9c5fa173339eb36de515370e6973reed@google.com            }
61213201e74f43b9c5fa173339eb36de515370e6973reed@google.com        } else {
61313201e74f43b9c5fa173339eb36de515370e6973reed@google.com            SkXfermode* xfer = fXfermode;
61413201e74f43b9c5fa173339eb36de515370e6973reed@google.com            if (xfer) {
61513201e74f43b9c5fa173339eb36de515370e6973reed@google.com                do {
61613201e74f43b9c5fa173339eb36de515370e6973reed@google.com                    xfer->xfer32(device, &c, 1, &alpha);
61713201e74f43b9c5fa173339eb36de515370e6973reed@google.com                    device = (uint32_t*)((char*)device + deviceRB);
61813201e74f43b9c5fa173339eb36de515370e6973reed@google.com                } while (--height > 0);
61913201e74f43b9c5fa173339eb36de515370e6973reed@google.com            } else {
62053007a2b1724c15c170340658daac012f9d909bereed@google.com                SkBlitRow::Proc32 proc = (255 == alpha) ? fProc32 : fProc32Blend;
62113201e74f43b9c5fa173339eb36de515370e6973reed@google.com                do {
62213201e74f43b9c5fa173339eb36de515370e6973reed@google.com                    proc(device, &c, 1, alpha);
62313201e74f43b9c5fa173339eb36de515370e6973reed@google.com                    device = (uint32_t*)((char*)device + deviceRB);
62413201e74f43b9c5fa173339eb36de515370e6973reed@google.com                } while (--height > 0);
62513201e74f43b9c5fa173339eb36de515370e6973reed@google.com            }
62613201e74f43b9c5fa173339eb36de515370e6973reed@google.com        }
62713201e74f43b9c5fa173339eb36de515370e6973reed@google.com        return;
62813201e74f43b9c5fa173339eb36de515370e6973reed@google.com    }
62913201e74f43b9c5fa173339eb36de515370e6973reed@google.com
63013201e74f43b9c5fa173339eb36de515370e6973reed@google.com    if (fShadeDirectlyIntoDevice) {
63113201e74f43b9c5fa173339eb36de515370e6973reed@google.com        void* ctx;
63287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        SkShader::Context::ShadeProc shadeProc = shaderContext->asAShadeProc(&ctx);
63313201e74f43b9c5fa173339eb36de515370e6973reed@google.com        if (255 == alpha) {
63413201e74f43b9c5fa173339eb36de515370e6973reed@google.com            if (shadeProc) {
63513201e74f43b9c5fa173339eb36de515370e6973reed@google.com                do {
63613201e74f43b9c5fa173339eb36de515370e6973reed@google.com                    shadeProc(ctx, x, y, device, 1);
63713201e74f43b9c5fa173339eb36de515370e6973reed@google.com                    y += 1;
63813201e74f43b9c5fa173339eb36de515370e6973reed@google.com                    device = (uint32_t*)((char*)device + deviceRB);
63913201e74f43b9c5fa173339eb36de515370e6973reed@google.com                } while (--height > 0);
64013201e74f43b9c5fa173339eb36de515370e6973reed@google.com            } else {
64113201e74f43b9c5fa173339eb36de515370e6973reed@google.com                do {
64287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org                    shaderContext->shadeSpan(x, y, device, 1);
64313201e74f43b9c5fa173339eb36de515370e6973reed@google.com                    y += 1;
64413201e74f43b9c5fa173339eb36de515370e6973reed@google.com                    device = (uint32_t*)((char*)device + deviceRB);
64513201e74f43b9c5fa173339eb36de515370e6973reed@google.com                } while (--height > 0);
64613201e74f43b9c5fa173339eb36de515370e6973reed@google.com            }
64713201e74f43b9c5fa173339eb36de515370e6973reed@google.com        } else {    // alpha < 255
64813201e74f43b9c5fa173339eb36de515370e6973reed@google.com            SkPMColor c;
64913201e74f43b9c5fa173339eb36de515370e6973reed@google.com            if (shadeProc) {
65013201e74f43b9c5fa173339eb36de515370e6973reed@google.com                do {
65113201e74f43b9c5fa173339eb36de515370e6973reed@google.com                    shadeProc(ctx, x, y, &c, 1);
65213201e74f43b9c5fa173339eb36de515370e6973reed@google.com                    *device = SkFourByteInterp(c, *device, alpha);
65313201e74f43b9c5fa173339eb36de515370e6973reed@google.com                    y += 1;
65413201e74f43b9c5fa173339eb36de515370e6973reed@google.com                    device = (uint32_t*)((char*)device + deviceRB);
65513201e74f43b9c5fa173339eb36de515370e6973reed@google.com                } while (--height > 0);
65613201e74f43b9c5fa173339eb36de515370e6973reed@google.com            } else {
65713201e74f43b9c5fa173339eb36de515370e6973reed@google.com                do {
65887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org                    shaderContext->shadeSpan(x, y, &c, 1);
65913201e74f43b9c5fa173339eb36de515370e6973reed@google.com                    *device = SkFourByteInterp(c, *device, alpha);
66013201e74f43b9c5fa173339eb36de515370e6973reed@google.com                    y += 1;
66113201e74f43b9c5fa173339eb36de515370e6973reed@google.com                    device = (uint32_t*)((char*)device + deviceRB);
66213201e74f43b9c5fa173339eb36de515370e6973reed@google.com                } while (--height > 0);
66313201e74f43b9c5fa173339eb36de515370e6973reed@google.com            }
66413201e74f43b9c5fa173339eb36de515370e6973reed@google.com        }
66513201e74f43b9c5fa173339eb36de515370e6973reed@google.com    } else {
66613201e74f43b9c5fa173339eb36de515370e6973reed@google.com        SkPMColor* span = fBuffer;
66713201e74f43b9c5fa173339eb36de515370e6973reed@google.com        SkXfermode* xfer = fXfermode;
66813201e74f43b9c5fa173339eb36de515370e6973reed@google.com        if (xfer) {
66913201e74f43b9c5fa173339eb36de515370e6973reed@google.com            do {
67087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org                shaderContext->shadeSpan(x, y, span, 1);
67113201e74f43b9c5fa173339eb36de515370e6973reed@google.com                xfer->xfer32(device, span, 1, &alpha);
67213201e74f43b9c5fa173339eb36de515370e6973reed@google.com                y += 1;
67313201e74f43b9c5fa173339eb36de515370e6973reed@google.com                device = (uint32_t*)((char*)device + deviceRB);
67413201e74f43b9c5fa173339eb36de515370e6973reed@google.com            } while (--height > 0);
67513201e74f43b9c5fa173339eb36de515370e6973reed@google.com        } else {
67659d968fb29b39cc1f4eb0ac687007c74618c6c1creed@google.com            SkBlitRow::Proc32 proc = (255 == alpha) ? fProc32 : fProc32Blend;
67713201e74f43b9c5fa173339eb36de515370e6973reed@google.com            do {
67887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org                shaderContext->shadeSpan(x, y, span, 1);
67959d968fb29b39cc1f4eb0ac687007c74618c6c1creed@google.com                proc(device, span, 1, alpha);
68013201e74f43b9c5fa173339eb36de515370e6973reed@google.com                y += 1;
68113201e74f43b9c5fa173339eb36de515370e6973reed@google.com                device = (uint32_t*)((char*)device + deviceRB);
68213201e74f43b9c5fa173339eb36de515370e6973reed@google.com            } while (--height > 0);
68313201e74f43b9c5fa173339eb36de515370e6973reed@google.com        }
68413201e74f43b9c5fa173339eb36de515370e6973reed@google.com    }
68513201e74f43b9c5fa173339eb36de515370e6973reed@google.com}
686