SkBlitter_ARGB32.cpp revision 8a1c16ff38322f0210116fa7293eb8817c7e477e
18a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* libs/graphics/sgl/SkBlitter_ARGB32.cpp
28a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com**
38a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com** Copyright 2006, The Android Open Source Project
48a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com**
58a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com** Licensed under the Apache License, Version 2.0 (the "License");
68a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com** you may not use this file except in compliance with the License.
78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com** You may obtain a copy of the License at
88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com**
98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com**     http://www.apache.org/licenses/LICENSE-2.0
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com**
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com** Unless required by applicable law or agreed to in writing, software
128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com** distributed under the License is distributed on an "AS IS" BASIS,
138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com** See the License for the specific language governing permissions and
158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com** limitations under the License.
168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/
178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCoreBlitters.h"
198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorPriv.h"
208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkShader.h"
218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkUtils.h"
228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkXfermode.h"
238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkARGB32_Blitter::SkARGB32_Blitter(const SkBitmap& device, const SkPaint& paint)
258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        : INHERITED(device) {
268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint32_t color = paint.getColor();
278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fSrcA = SkColorGetA(color);
298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    unsigned scale = SkAlpha255To256(fSrcA);
308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fSrcR = SkAlphaMul(SkColorGetR(color), scale);
318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fSrcG = SkAlphaMul(SkColorGetG(color), scale);
328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fSrcB = SkAlphaMul(SkColorGetB(color), scale);
338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fPMColor = SkPackARGB32(fSrcA, fSrcR, fSrcG, fSrcB);
358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkBitmap* SkARGB32_Blitter::justAnOpaqueColor(uint32_t* value) {
388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (255 == fSrcA) {
398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        *value = fPMColor;
408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return &fDevice;
418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return NULL;
438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#if defined _WIN32 && _MSC_VER >= 1300  // disable warning : local variable used without having been initialized
468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#pragma warning ( push )
478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#pragma warning ( disable : 4701 )
488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkARGB32_Blitter::blitH(int x, int y, int width) {
518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width());
528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fSrcA == 0) {
548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return;
558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint32_t* device = fDevice.getAddr32(x, y);
588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fSrcA == 255) {
608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        sk_memset32(device, fPMColor, width);
618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    } else {
628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        uint32_t color = fPMColor;
638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned dst_scale = SkAlpha255To256(255 - fSrcA);
648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        uint32_t prevDst = ~device[0];  // so we always fail the test the first time
658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        uint32_t result SK_INIT_TO_AVOID_WARNING;
668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        for (int i = 0; i < width; i++) {
688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            uint32_t currDst = device[i];
698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if (currDst != prevDst) {
708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                result = color + SkAlphaMulQ(currDst, dst_scale);
718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                prevDst = currDst;
728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            device[i] = result;
748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkARGB32_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                 const int16_t runs[]) {
808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fSrcA == 0) {
818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return;
828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint32_t    color = fPMColor;
858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint32_t*   device = fDevice.getAddr32(x, y);
868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    unsigned    opaqueMask = fSrcA; // if fSrcA is 0xFF, then we will catch the fast opaque case
878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (;;) {
898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        int count = runs[0];
908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT(count >= 0);
918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (count <= 0) {
928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return;
938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned aa = antialias[0];
958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (aa) {
968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if ((opaqueMask & aa) == 255) {
978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                sk_memset32(device, color, count);
988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            } else {
998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                uint32_t sc = SkAlphaMulQ(color, aa);
1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                unsigned dst_scale = 255 - SkGetPackedA32(sc);
1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                int n = count;
1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                do {
1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    --n;
1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    device[n] = sc + SkAlphaMulQ(device[n], dst_scale);
1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                } while (n > 0);
1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        runs += count;
1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        antialias += count;
1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        device += count;
1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////////////////////
1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define solid_8_pixels(mask, dst, color)    \
1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    do {                                    \
1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (mask & 0x80) dst[0] = color;    \
1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (mask & 0x40) dst[1] = color;    \
1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (mask & 0x20) dst[2] = color;    \
1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (mask & 0x10) dst[3] = color;    \
1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (mask & 0x08) dst[4] = color;    \
1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (mask & 0x04) dst[5] = color;    \
1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (mask & 0x02) dst[6] = color;    \
1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (mask & 0x01) dst[7] = color;    \
1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    } while (0)
1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_NAME                  SkARGB32_BlitBW
1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_ARGS                  , SkPMColor color
1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_BLIT8(mask, dst)      solid_8_pixels(mask, dst, color)
1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_GETADDR               getAddr32
1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_DEVTYPE               uint32_t
1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkBlitBWMaskTemplate.h"
1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define blend_8_pixels(mask, dst, sc, dst_scale)                            \
1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    do {                                                                    \
1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (mask & 0x80) { dst[0] = sc + SkAlphaMulQ(dst[0], dst_scale); }  \
1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (mask & 0x40) { dst[1] = sc + SkAlphaMulQ(dst[1], dst_scale); }  \
1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (mask & 0x20) { dst[2] = sc + SkAlphaMulQ(dst[2], dst_scale); }  \
1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (mask & 0x10) { dst[3] = sc + SkAlphaMulQ(dst[3], dst_scale); }  \
1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (mask & 0x08) { dst[4] = sc + SkAlphaMulQ(dst[4], dst_scale); }  \
1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (mask & 0x04) { dst[5] = sc + SkAlphaMulQ(dst[5], dst_scale); }  \
1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (mask & 0x02) { dst[6] = sc + SkAlphaMulQ(dst[6], dst_scale); }  \
1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (mask & 0x01) { dst[7] = sc + SkAlphaMulQ(dst[7], dst_scale); }  \
1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    } while (0)
1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_NAME                  SkARGB32_BlendBW
1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_ARGS                  , uint32_t sc, unsigned dst_scale
1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_BLIT8(mask, dst)      blend_8_pixels(mask, dst, sc, dst_scale)
1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_GETADDR               getAddr32
1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_DEVTYPE               uint32_t
1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkBlitBWMaskTemplate.h"
1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkARGB32_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) {
1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(mask.fBounds.contains(clip));
1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(fSrcA != 0xFF);
1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fSrcA == 0) {
1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return;
1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (mask.fFormat == SkMask::kBW_Format) {
1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkARGB32_BlendBW(fDevice, mask, clip, fPMColor, SkAlpha255To256(255 - fSrcA));
1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return;
1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int x = clip.fLeft;
1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int y = clip.fTop;
1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int width = clip.width();
1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int height = clip.height();
1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint32_t*       device = fDevice.getAddr32(x, y);
1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const uint8_t*  alpha = mask.getAddr(x, y);
1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint32_t        srcColor = fPMColor;
1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    unsigned        devRB = fDevice.rowBytes() - (width << 2);
1768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    unsigned        maskRB = mask.fRowBytes - width;
1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    do {
1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        int w = width;
1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        do {
1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            unsigned aa = *alpha++;
1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            *device = SkBlendARGB32(srcColor, *device, aa);
1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            device += 1;
1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        } while (--w != 0);
1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        device = (uint32_t*)((char*)device + devRB);
1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        alpha += maskRB;
1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    } while (--height != 0);
1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkARGB32_Opaque_Blitter::blitMask(const SkMask& mask,
1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                       const SkIRect& clip) {
1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(mask.fBounds.contains(clip));
1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (mask.fFormat == SkMask::kBW_Format) {
1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkARGB32_BlitBW(fDevice, mask, clip, fPMColor);
1968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return;
1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int x = clip.fLeft;
2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int y = clip.fTop;
2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int width = clip.width();
2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int height = clip.height();
2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint32_t*       device = fDevice.getAddr32(x, y);
2058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const uint8_t*  alpha = mask.getAddr(x, y);
2068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint32_t        srcColor = fPMColor;
2078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    unsigned        devRB = fDevice.rowBytes() - (width << 2);
2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    unsigned        maskRB = mask.fRowBytes - width;
2098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    do {
2118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        int w = width;
2128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        do {
2138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            unsigned aa = *alpha++;
2148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            *device = SkAlphaMulQ(srcColor, SkAlpha255To256(aa)) + SkAlphaMulQ(*device, SkAlpha255To256(255 - aa));
2158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            device += 1;
2168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        } while (--w != 0);
2178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        device = (uint32_t*)((char*)device + devRB);
2188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        alpha += maskRB;
2198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    } while (--height != 0);
2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////////////////////
2238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkARGB32_Blitter::blitV(int x, int y, int height, SkAlpha alpha) {
2258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (alpha == 0 || fSrcA == 0) {
2268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return;
2278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint32_t* device = fDevice.getAddr32(x, y);
2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint32_t  color = fPMColor;
2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (alpha != 255) {
2338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        color = SkAlphaMulQ(color, SkAlpha255To256(alpha));
2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    unsigned dst_scale = 255 - SkGetPackedA32(color);
2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint32_t prevDst = ~device[0];
2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint32_t result  SK_INIT_TO_AVOID_WARNING;
2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint32_t rowBytes = fDevice.rowBytes();
2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    while (--height >= 0) {
2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        uint32_t dst = device[0];
2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (dst != prevDst) {
2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            result = color + SkAlphaMulQ(dst, dst_scale);
2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            prevDst = dst;
2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        device[0] = result;
2488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        device = (uint32_t*)((char*)device + rowBytes);
2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkARGB32_Blitter::blitRect(int x, int y, int width, int height) {
2538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width() && y + height <= fDevice.height());
2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fSrcA == 0) {
2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return;
2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint32_t*   device = fDevice.getAddr32(x, y);
2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint32_t    color = fPMColor;
2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fSrcA == 255) {
2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        while (--height >= 0) {
2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            sk_memset32(device, color, width);
2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            device = (uint32_t*)((char*)device + fDevice.rowBytes());
2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    } else {
2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned dst_scale = SkAlpha255To256(255 - fSrcA);
2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        while (--height >= 0) {
2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            uint32_t prevDst = ~device[0];
2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            uint32_t result SK_INIT_TO_AVOID_WARNING;
2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            for (int i = 0; i < width; i++) {
2758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                uint32_t dst = device[i];
2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                if (dst != prevDst) {
2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    result = color + SkAlphaMulQ(dst, dst_scale);
2788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    prevDst = dst;
2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                }
2808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                device[i] = result;
2818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            device = (uint32_t*)((char*)device + fDevice.rowBytes());
2838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
2848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#if defined _WIN32 && _MSC_VER >= 1300
2888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#pragma warning ( pop )
2898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
2908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////
2928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkARGB32_Black_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) {
2948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(mask.fBounds.contains(clip));
2958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (mask.fFormat == SkMask::kBW_Format) {
2978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkPMColor black = (SkPMColor)(SK_A32_MASK << SK_A32_SHIFT);
2988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkARGB32_BlitBW(fDevice, mask, clip, black);
3008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    } else {
3018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        uint32_t*       device = fDevice.getAddr32(clip.fLeft, clip.fTop);
3028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        const uint8_t*  alpha = mask.getAddr(clip.fLeft, clip.fTop);
3038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned        width = clip.width();
3048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned        height = clip.height();
3058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned        deviceRB = fDevice.rowBytes() - (width << 2);
3068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned        maskRB = mask.fRowBytes - width;
3078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT((int)height > 0);
3098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT((int)width > 0);
3108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT((int)deviceRB >= 0);
3118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT((int)maskRB >= 0);
3128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        do {
3148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            unsigned w = width;
3158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            do {
3168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                unsigned aa = *alpha++;
3178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                *device = (aa << SK_A32_SHIFT) + SkAlphaMulQ(*device, SkAlpha255To256(255 - aa));
3188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                device += 1;
3198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            } while (--w != 0);
3208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            device = (uint32_t*)((char*)device + deviceRB);
3218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            alpha += maskRB;
3228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        } while (--height != 0);
3238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
3248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkARGB32_Black_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
3278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                       const int16_t runs[]) {
3288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint32_t*   device = fDevice.getAddr32(x, y);
3298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPMColor   black = (SkPMColor)(SK_A32_MASK << SK_A32_SHIFT);
3308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (;;) {
3328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        int count = runs[0];
3338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT(count >= 0);
3348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (count <= 0) {
3358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return;
3368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
3378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned aa = antialias[0];
3388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (aa) {
3398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if (aa == 255) {
3408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                sk_memset32(device, black, count);
3418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            } else {
3428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                SkPMColor src = aa << SK_A32_SHIFT;
3438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                unsigned dst_scale = 256 - aa;
3448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                int n = count;
3458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                do {
3468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    --n;
3478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    device[n] = src + SkAlphaMulQ(device[n], dst_scale);
3488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                } while (n > 0);
3498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
3508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
3518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        runs += count;
3528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        antialias += count;
3538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        device += count;
3548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
3558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////////////////////////
3588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkARGB32_Shader_Blitter::SkARGB32_Shader_Blitter(const SkBitmap& device,
3608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                                 const SkPaint& paint)
3618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        : INHERITED(device, paint) {
3628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fBuffer = (SkPMColor*)sk_malloc_throw(device.width() * (sizeof(SkPMColor)));
3638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    (fXfermode = paint.getXfermode())->safeRef();
3658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkARGB32_Shader_Blitter::~SkARGB32_Shader_Blitter() {
3688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fXfermode->safeUnref();
3698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    sk_free(fBuffer);
3708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkARGB32_Shader_Blitter::blitH(int x, int y, int width) {
3738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width());
3748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint32_t*   device = fDevice.getAddr32(x, y);
3768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fXfermode == NULL && (fShader->getFlags() & SkShader::kOpaqueAlpha_Flag)) {
3788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fShader->shadeSpan(x, y, device, width);
3798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    } else {
3808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkPMColor*  span = fBuffer;
3818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fShader->shadeSpan(x, y, span, width);
3828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (fXfermode) {
3838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            fXfermode->xfer32(device, span, width, NULL);
3848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        } else {
3858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            for (int i = 0; i < width; i++) {
3868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                uint32_t src = span[i];
3878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                if (src) {
3888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    unsigned srcA = SkGetPackedA32(src);
3898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    if (srcA != 0xFF) {
3908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                        src += SkAlphaMulQ(device[i], SkAlpha255To256(255 - srcA));
3918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    }
3928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    device[i] = src;
3938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                }
3948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
3958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
3968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
3978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////////////////////
4008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkARGB32_Shader_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
4028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                        const int16_t runs[]) {
4038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPMColor*  span = fBuffer;
4048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint32_t*   device = fDevice.getAddr32(x, y);
4058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkShader*   shader = fShader;
4068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fXfermode) {
4088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        for (;;) {
4098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            SkXfermode* xfer = fXfermode;
4108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            int count = *runs;
4128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if (count <= 0)
4138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                break;
4148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            int aa = *antialias;
4158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if (aa) {
4168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                shader->shadeSpan(x, y, span, count);
4178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                if (aa == 255) {
4188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    xfer->xfer32(device, span, count, NULL);
4198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                } else {
4208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    // count is almost always 1
4218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    for (int i = count - 1; i >= 0; --i) {
4228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                        xfer->xfer32(&device[i], &span[i], 1, antialias);
4238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    }
4248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                }
4258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
4268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            device += count;
4278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            runs += count;
4288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            antialias += count;
4298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            x += count;
4308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
4318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    } else if (fShader->getFlags() & SkShader::kOpaqueAlpha_Flag) {
4328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        for (;;) {
4338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            int count = *runs;
4348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if (count <= 0) {
4358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                break;
4368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
4378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            int aa = *antialias;
4388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if (aa) {
4398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                if (aa == 255) {  // cool, have the shader draw right into the device
4408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    shader->shadeSpan(x, y, device, count);
4418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                } else {
4428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    shader->shadeSpan(x, y, span, count);
4438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    for (int i = count - 1; i >= 0; --i) {
4448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                        if (span[i]) {
4458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                            device[i] = SkBlendARGB32(span[i], device[i], aa);
4468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                        }
4478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    }
4488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                }
4498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
4508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            device += count;
4518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            runs += count;
4528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            antialias += count;
4538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            x += count;
4548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
4558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    } else {    // no xfermode but we are not opaque
4568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        for (;;) {
4578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            int count = *runs;
4588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if (count <= 0) {
4598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                break;
4608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
4618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            int aa = *antialias;
4628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if (aa) {
4638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                fShader->shadeSpan(x, y, span, count);
4648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                if (aa == 255) {
4658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    for (int i = count - 1; i >= 0; --i) {
4668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                        if (span[i]) {
4678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                            device[i] = SkPMSrcOver(span[i], device[i]);
4688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                        }
4698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    }
4708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                } else {
4718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    for (int i = count - 1; i >= 0; --i) {
4728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                        if (span[i]) {
4738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                            device[i] = SkBlendARGB32(span[i], device[i], aa);
4748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                        }
4758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    }
4768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                }
4778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
4788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            device += count;
4798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            runs += count;
4808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            antialias += count;
4818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            x += count;
4828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
4838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
4848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
4858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
486