SkBlitter.cpp revision 59f59bde0b05a6ac5ff28fdebc1942dbf0d43aab
10910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/* libs/graphics/sgl/SkBlitter.cpp
20910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project**
30910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** Copyright 2006, The Android Open Source Project
40910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project**
50910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");
60910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** you may not use this file except in compliance with the License.
70910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** You may obtain a copy of the License at
80910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project**
90910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project**     http://www.apache.org/licenses/LICENSE-2.0
100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project**
110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** Unless required by applicable law or agreed to in writing, software
120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS,
130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** See the License for the specific language governing permissions and
150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** limitations under the License.
160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/
170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkBlitter.h"
190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkAntiRun.h"
200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkColor.h"
210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkColorFilter.h"
220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkMask.h"
230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkMaskFilter.h"
240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkTemplatesPriv.h"
250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkUtils.h"
260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkXfermode.h"
270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2859f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike ReedSkBlitter::~SkBlitter() {}
290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectconst SkBitmap* SkBlitter::justAnOpaqueColor(uint32_t* value)
310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return NULL;
330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkBlitter::blitH(int x, int y, int width)
360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(!"unimplemented");
380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkBlitter::blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[])
410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(!"unimplemented");
430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkBlitter::blitV(int x, int y, int height, SkAlpha alpha)
460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (alpha == 255)
480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this->blitRect(x, y, 1, height);
490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int16_t runs[2];
520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        runs[0] = 1;
530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        runs[1] = 0;
540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        while (--height >= 0)
560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            this->blitAntiH(x, y++, &alpha, runs);
570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkBlitter::blitRect(int x, int y, int width, int height)
610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while (--height >= 0)
630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this->blitH(x, y++, width);
640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project//////////////////////////////////////////////////////////////////////////////
670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic inline void bits_to_runs(SkBlitter* blitter, int x, int y, const uint8_t bits[],
690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                U8CPU left_mask, int rowBytes, U8CPU right_mask)
700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int inFill = 0;
720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int pos = 0;
730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while (--rowBytes >= 0)
750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        unsigned b = *bits++ & left_mask;
770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (rowBytes == 0)
780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            b &= right_mask;
790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        for (unsigned test = 0x80; test != 0; test >>= 1)
810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (b & test)
830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            {
840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (!inFill)
850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                {
860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    pos = x;
870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    inFill = true;
880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            else
910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            {
920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (inFill)
930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                {
940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    blitter->blitH(pos, y, x - pos);
950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    inFill = false;
960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            x += 1;
990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
1000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        left_mask = 0xFF;
1010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // final cleanup
1040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (inFill)
1050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        blitter->blitH(pos, y, x - pos);
1060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkBlitter::blitMask(const SkMask& mask, const SkIRect& clip)
1090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(mask.fBounds.contains(clip));
1110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (mask.fFormat == SkMask::kBW_Format)
1130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
1140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int cx = clip.fLeft;
1150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int cy = clip.fTop;
1160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int maskLeft = mask.fBounds.fLeft;
1170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int mask_rowBytes = mask.fRowBytes;
1180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int height = clip.height();
1190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const uint8_t* bits = mask.getAddr1(cx, cy);
1210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (cx == maskLeft && clip.fRight == mask.fBounds.fRight)
1230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
1240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            while (--height >= 0)
1250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            {
1260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                bits_to_runs(this, cx, cy, bits, 0xFF, mask_rowBytes, 0xFF);
1270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                bits += mask_rowBytes;
1280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                cy += 1;
1290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
1300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
1310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        else
1320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
1330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            int left_edge = cx - maskLeft;
1340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(left_edge >= 0);
1350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            int rite_edge = clip.fRight - maskLeft;
1360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(rite_edge > left_edge);
1370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            int left_mask = 0xFF >> (left_edge & 7);
1390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            int rite_mask = 0xFF << (8 - (rite_edge & 7));
1400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            int full_runs = (rite_edge >> 3) - ((left_edge + 7) >> 3);
1410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            // check for empty right mask, so we don't read off the end (or go slower than we need to)
1430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (rite_mask == 0)
1440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            {
1450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkASSERT(full_runs >= 0);
1460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                full_runs -= 1;
1470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                rite_mask = 0xFF;
1480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
1490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (left_mask == 0xFF)
1500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                full_runs -= 1;
1510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            // back up manually so we can keep in sync with our byte-aligned src
1530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            // have cx reflect our actual starting x-coord
1540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            cx -= left_edge & 7;
1550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (full_runs < 0)
1570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            {
1580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkASSERT((left_mask & rite_mask) != 0);
1590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                while (--height >= 0)
1600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                {
1610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    bits_to_runs(this, cx, cy, bits, left_mask, 1, rite_mask);
1620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    bits += mask_rowBytes;
1630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    cy += 1;
1640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
1650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
1660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            else
1670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            {
1680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                while (--height >= 0)
1690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                {
1700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    bits_to_runs(this, cx, cy, bits, left_mask, full_runs + 2, rite_mask);
1710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    bits += mask_rowBytes;
1720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    cy += 1;
1730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
1740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
1750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
1760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
1780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
1790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int                         width = clip.width();
1800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkAutoSTMalloc<64, int16_t> runStorage(width + 1);
1810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int16_t*                    runs = runStorage.get();
1820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const uint8_t*              aa = mask.getAddr(clip.fLeft, clip.fTop);
1830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_memset16((uint16_t*)runs, 1, width);
1850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        runs[width] = 0;
1860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int height = clip.height();
1880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int y = clip.fTop;
1890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        while (--height >= 0)
1900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
1910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            this->blitAntiH(clip.fLeft, y, aa, runs);
1920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            aa += mask.fRowBytes;
1930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            y += 1;
1940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
1950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////// these guys are not virtual, just a helpers
1990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkBlitter::blitMaskRegion(const SkMask& mask, const SkRegion& clip) {
2010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (clip.quickReject(mask.fBounds)) {
2020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return;
2030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
2040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRegion::Cliperator clipper(clip, mask.fBounds);
2060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while (!clipper.done()) {
2080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const SkIRect& cr = clipper.rect();
2090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this->blitMask(mask, cr);
2100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        clipper.next();
2110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
2120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkBlitter::blitRectRegion(const SkIRect& rect, const SkRegion& clip) {
2150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRegion::Cliperator clipper(clip, rect);
2160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while (!clipper.done()) {
2180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const SkIRect& cr = clipper.rect();
2190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this->blitRect(cr.fLeft, cr.fTop, cr.width(), cr.height());
2200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        clipper.next();
2210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
2220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkBlitter::blitRegion(const SkRegion& clip) {
2250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRegion::Iterator iter(clip);
2260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while (!iter.done()) {
2280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const SkIRect& cr = iter.rect();
2290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this->blitRect(cr.fLeft, cr.fTop, cr.width(), cr.height());
2300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        iter.next();
2310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
2320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////////////
2350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////////////
2360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkNullBlitter::blitH(int x, int y, int width)
2380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkNullBlitter::blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[])
2420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkNullBlitter::blitV(int x, int y, int height, SkAlpha alpha)
2460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkNullBlitter::blitRect(int x, int y, int width, int height)
2500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkNullBlitter::blitMask(const SkMask& mask, const SkIRect& clip)
2540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectconst SkBitmap* SkNullBlitter::justAnOpaqueColor(uint32_t* value)
2580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return NULL;
2600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////////////
2630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////////////
2640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic int compute_anti_width(const int16_t runs[])
2660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int width = 0;
2680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    for (;;)
2700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
2710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int count = runs[0];
2720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(count >= 0);
2740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (count == 0)
2750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
2760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        width += count;
2770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        runs += count;
2780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(width < 20000);
2800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
2810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return width;
2820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic inline bool y_in_rect(int y, const SkIRect& rect)
2850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return (unsigned)(y - rect.fTop) < (unsigned)rect.height();
2870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic inline bool x_in_rect(int x, const SkIRect& rect)
2900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return (unsigned)(x - rect.fLeft) < (unsigned)rect.width();
2920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkRectClipBlitter::blitH(int left, int y, int width)
2950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(width > 0);
2970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (!y_in_rect(y, fClipRect))
2990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return;
3000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int right = left + width;
3020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (left < fClipRect.fLeft)
3040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        left = fClipRect.fLeft;
3050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (right > fClipRect.fRight)
3060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        right = fClipRect.fRight;
3070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    width = right - left;
3090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (width > 0)
3100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fBlitter->blitH(left, y, width);
3110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkRectClipBlitter::blitAntiH(int left, int y, const SkAlpha aa[], const int16_t runs[])
3140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
3150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (!y_in_rect(y, fClipRect) || left >= fClipRect.fRight)
3160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return;
3170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int x0 = left;
3190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int x1 = left + compute_anti_width(runs);
3200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (x1 <= fClipRect.fLeft)
3220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return;
3230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(x0 < x1);
3250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (x0 < fClipRect.fLeft)
3260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
3270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int dx = fClipRect.fLeft - x0;
3280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkAlphaRuns::BreakAt((int16_t*)runs, (uint8_t*)aa, dx);
3290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        runs += dx;
3300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        aa += dx;
3310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        x0 = fClipRect.fLeft;
3320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
3330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(x0 < x1 && runs[x1 - x0] == 0);
3350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (x1 > fClipRect.fRight)
3360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
3370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        x1 = fClipRect.fRight;
3380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkAlphaRuns::BreakAt((int16_t*)runs, (uint8_t*)aa, x1 - x0);
3390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        ((int16_t*)runs)[x1 - x0] = 0;
3400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
3410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(x0 < x1 && runs[x1 - x0] == 0);
3430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(compute_anti_width(runs) == x1 - x0);
3440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fBlitter->blitAntiH(x0, y, aa, runs);
3460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkRectClipBlitter::blitV(int x, int y, int height, SkAlpha alpha)
3490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
3500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(height > 0);
3510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (!x_in_rect(x, fClipRect))
3530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return;
3540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int y0 = y;
3560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int y1 = y + height;
3570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (y0 < fClipRect.fTop)
3590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        y0 = fClipRect.fTop;
3600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (y1 > fClipRect.fBottom)
3610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        y1 = fClipRect.fBottom;
3620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (y0 < y1)
3640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fBlitter->blitV(x, y0, y1 - y0, alpha);
3650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkRectClipBlitter::blitRect(int left, int y, int width, int height)
3680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
3690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkIRect    r;
3700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    r.set(left, y, left + width, y + height);
3720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (r.intersect(fClipRect))
3730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height());
3740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkRectClipBlitter::blitMask(const SkMask& mask, const SkIRect& clip)
3770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
3780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(mask.fBounds.contains(clip));
3790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkIRect    r = clip;
3810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (r.intersect(fClipRect))
3830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fBlitter->blitMask(mask, r);
3840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectconst SkBitmap* SkRectClipBlitter::justAnOpaqueColor(uint32_t* value)
3870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
3880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return fBlitter->justAnOpaqueColor(value);
3890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////////////
3920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////////////
3930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkRgnClipBlitter::blitH(int x, int y, int width)
3950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
3960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRegion::Spanerator span(*fRgn, y, x, x + width);
3970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int left, right;
3980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while (span.next(&left, &right))
4000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
4010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(left < right);
4020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fBlitter->blitH(left, y, right - left);
4030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
4040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkRgnClipBlitter::blitAntiH(int x, int y, const SkAlpha aa[], const int16_t runs[])
4070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
4080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int width = compute_anti_width(runs);
4090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRegion::Spanerator span(*fRgn, y, x, x + width);
4100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int left, right;
4110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkDEBUGCODE(const SkIRect& bounds = fRgn->getBounds();)
4120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int prevRite = x;
4140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while (span.next(&left, &right))
4150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
4160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(x <= left);
4170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(left < right);
4180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(left >= bounds.fLeft && right <= bounds.fRight);
4190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkAlphaRuns::Break((int16_t*)runs, (uint8_t*)aa, left - x, right - left);
4210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // now zero before left
4230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (left > prevRite)
4240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
4250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            int index = prevRite - x;
4260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            ((uint8_t*)aa)[index] = 0;   // skip runs after right
4270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            ((int16_t*)runs)[index] = SkToS16(left - prevRite);
4280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
4290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        prevRite = right;
4310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
4320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (prevRite > x)
4340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
4350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        ((int16_t*)runs)[prevRite - x] = 0;
4360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (x < 0) {
4380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            int skip = runs[0];
4390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(skip >= -x);
4400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            aa += skip;
4410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            runs += skip;
4420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            x += skip;
4430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
4440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fBlitter->blitAntiH(x, y, aa, runs);
4450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
4460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkRgnClipBlitter::blitV(int x, int y, int height, SkAlpha alpha)
4490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
4500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkIRect    bounds;
4510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bounds.set(x, y, x + 1, y + height);
4520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRegion::Cliperator    iter(*fRgn, bounds);
4540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while (!iter.done())
4560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
4570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const SkIRect& r = iter.rect();
4580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(bounds.contains(r));
4590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fBlitter->blitV(x, r.fTop, r.height(), alpha);
4610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        iter.next();
4620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
4630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkRgnClipBlitter::blitRect(int x, int y, int width, int height)
4660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
4670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkIRect    bounds;
4680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bounds.set(x, y, x + width, y + height);
4690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRegion::Cliperator    iter(*fRgn, bounds);
4710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while (!iter.done())
4730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
4740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const SkIRect& r = iter.rect();
4750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(bounds.contains(r));
4760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height());
4780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        iter.next();
4790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
4800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkRgnClipBlitter::blitMask(const SkMask& mask, const SkIRect& clip)
4830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
4840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(mask.fBounds.contains(clip));
4850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRegion::Cliperator iter(*fRgn, clip);
4870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const SkIRect&       r = iter.rect();
4880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkBlitter*           blitter = fBlitter;
4890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while (!iter.done())
4910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
4920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        blitter->blitMask(mask, r);
4930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        iter.next();
4940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
4950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectconst SkBitmap* SkRgnClipBlitter::justAnOpaqueColor(uint32_t* value)
4980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
4990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return fBlitter->justAnOpaqueColor(value);
5000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
5010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////////////
5030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////////////
5040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkBlitter* SkBlitterClipper::apply(SkBlitter* blitter, const SkRegion* clip, const SkIRect* ir)
5060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
5070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (clip)
5080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
5090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const SkIRect& clipR = clip->getBounds();
5100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (clip->isEmpty() || (ir && !SkIRect::Intersects(clipR, *ir)))
5120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            blitter = &fNullBlitter;
5130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        else if (clip->isRect())
5140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
5150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (ir == NULL || !clipR.contains(*ir))
5160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            {
5170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                fRectBlitter.init(blitter, clipR);
5180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                blitter = &fRectBlitter;
5190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
5200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
5210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        else
5220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
5230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fRgnBlitter.init(blitter, clip);
5240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            blitter = &fRgnBlitter;
5250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
5260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
5270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return blitter;
5280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
5290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////////////
5310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////////////
5320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkColorShader.h"
5340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkColorPriv.h"
5350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass Sk3DShader : public SkShader {
5370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic:
5380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    Sk3DShader(SkShader* proxy) : fProxy(proxy)
5390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
5400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        proxy->safeRef();
5410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fMask = NULL;
5420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
5430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    virtual ~Sk3DShader()
5440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
5450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fProxy->safeUnref();
5460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
5470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    void setMask(const SkMask* mask) { fMask = mask; }
5480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    virtual bool setContext(const SkBitmap& device, const SkPaint& paint, const SkMatrix& matrix)
5500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
5510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (fProxy)
5520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return fProxy->setContext(device, paint, matrix);
5530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        else
5540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
5550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fPMColor = SkPreMultiplyColor(paint.getColor());
5560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return this->INHERITED::setContext(device, paint, matrix);
5570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
5580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
5590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    virtual void shadeSpan(int x, int y, SkPMColor span[], int count)
5600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
5610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (fProxy)
5620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fProxy->shadeSpan(x, y, span, count);
5630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (fMask == NULL)
5650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
5660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (fProxy == NULL)
5670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                sk_memset32(span, fPMColor, count);
5680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return;
5690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
5700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(fMask->fBounds.contains(x, y));
5720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(fMask->fBounds.contains(x + count - 1, y));
5730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        size_t          size = fMask->computeImageSize();
5750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const uint8_t*  alpha = fMask->getAddr(x, y);
5760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const uint8_t*  mulp = alpha + size;
5770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const uint8_t*  addp = mulp + size;
5780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (fProxy)
5800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
5810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            for (int i = 0; i < count; i++)
5820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            {
5830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (alpha[i])
5840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                {
5850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    SkPMColor c = span[i];
5860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    if (c)
5870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    {
5880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        unsigned a = SkGetPackedA32(c);
5890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        unsigned r = SkGetPackedR32(c);
5900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        unsigned g = SkGetPackedG32(c);
5910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        unsigned b = SkGetPackedB32(c);
5920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        unsigned mul = SkAlpha255To256(mulp[i]);
5940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        unsigned add = addp[i];
5950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        r = SkFastMin32(SkAlphaMul(r, mul) + add, a);
5970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        g = SkFastMin32(SkAlphaMul(g, mul) + add, a);
5980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        b = SkFastMin32(SkAlphaMul(b, mul) + add, a);
5990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        span[i] = SkPackARGB32(a, r, g, b);
6010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    }
6020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
6030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                else
6040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    span[i] = 0;
6050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
6060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
6070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        else    // color
6080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
6090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            unsigned a = SkGetPackedA32(fPMColor);
6100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            unsigned r = SkGetPackedR32(fPMColor);
6110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            unsigned g = SkGetPackedG32(fPMColor);
6120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            unsigned b = SkGetPackedB32(fPMColor);
6130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            for (int i = 0; i < count; i++)
6140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            {
6150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (alpha[i])
6160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                {
6170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    unsigned mul = SkAlpha255To256(mulp[i]);
6180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    unsigned add = addp[i];
6190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    span[i] = SkPackARGB32( a,
6210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                            SkFastMin32(SkAlphaMul(r, mul) + add, a),
6220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                            SkFastMin32(SkAlphaMul(g, mul) + add, a),
6230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                            SkFastMin32(SkAlphaMul(b, mul) + add, a));
6240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
6250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                else
6260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    span[i] = 0;
6270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
6280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
6290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
6300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    virtual void beginSession()
6320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
6330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this->INHERITED::beginSession();
6340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (fProxy)
6350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fProxy->beginSession();
6360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
6370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    virtual void endSession()
6390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
6400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (fProxy)
6410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fProxy->endSession();
6420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this->INHERITED::endSession();
6430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
6440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprotected:
6460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    Sk3DShader(SkFlattenableReadBuffer& buffer) :
6470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        INHERITED(buffer)
6480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
6490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fProxy = static_cast<SkShader*>(buffer.readFlattenable());
6500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPMColor = buffer.readU32();
6510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fMask = NULL;
6520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
6530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    virtual void flatten(SkFlattenableWriteBuffer& buffer)
6550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
6560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this->INHERITED::flatten(buffer);
6570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        buffer.writeFlattenable(fProxy);
6580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        buffer.write32(fPMColor);
6590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
6600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    virtual Factory getFactory()
6620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
6630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return CreateProc;
6640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
6650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate:
6670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer)
6680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
6690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return SkNEW_ARGS(Sk3DShader, (buffer));
6700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
6710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkShader*       fProxy;
6730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPMColor       fPMColor;
6740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const SkMask*   fMask;
6750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    typedef SkShader INHERITED;
6770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
6780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass Sk3DBlitter : public SkBlitter {
6800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic:
6810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    Sk3DBlitter(SkBlitter* proxy, Sk3DShader* shader, void (*killProc)(void*))
6820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        : fProxy(proxy), f3DShader(shader), fKillProc(killProc)
6830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
6840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        shader->ref();
6850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
6860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    virtual ~Sk3DBlitter()
6870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
6880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        f3DShader->unref();
6890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fKillProc(fProxy);
6900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
6910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    virtual void blitH(int x, int y, int width)
6930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
6940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fProxy->blitH(x, y, width);
6950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
6960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    virtual void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[])
6970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
6980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fProxy->blitAntiH(x, y, antialias, runs);
6990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
7000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    virtual void blitV(int x, int y, int height, SkAlpha alpha)
7010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
7020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fProxy->blitV(x, y, height, alpha);
7030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
7040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    virtual void blitRect(int x, int y, int width, int height)
7050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
7060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fProxy->blitRect(x, y, width, height);
7070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
7080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    virtual void blitMask(const SkMask& mask, const SkIRect& clip)
7090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
7100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (mask.fFormat == SkMask::k3D_Format)
7110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
7120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            f3DShader->setMask(&mask);
7130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            ((SkMask*)&mask)->fFormat = SkMask::kA8_Format;
7150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fProxy->blitMask(mask, clip);
7160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            ((SkMask*)&mask)->fFormat = SkMask::k3D_Format;
7170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            f3DShader->setMask(NULL);
7190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
7200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        else
7210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fProxy->blitMask(mask, clip);
7220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
7230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate:
7240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkBlitter*  fProxy;
7250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    Sk3DShader* f3DShader;
7260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    void        (*fKillProc)(void*);
7270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
7280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////////////
7300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////////////
7310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkCoreBlitters.h"
7330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass SkAutoRestoreShader {
7350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic:
7360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoRestoreShader(const SkPaint& p) : fPaint((SkPaint*)&p)
7370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
7380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fShader = fPaint->getShader();
7390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fShader->safeRef();
7400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
7410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    ~SkAutoRestoreShader()
7420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
7430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPaint->setShader(fShader);
7440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fShader->safeUnref();
7450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
7460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate:
7470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPaint*    fPaint;
7480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkShader*   fShader;
7490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
7500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass SkAutoCallProc {
7520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic:
7530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    typedef void (*Proc)(void*);
7540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoCallProc(void* obj, Proc proc)
7550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        : fObj(obj), fProc(proc)
7560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
7570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
7580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    ~SkAutoCallProc()
7590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
7600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (fObj && fProc)
7610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fProc(fObj);
7620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
7630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    void* get() const { return fObj; }
7640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    void* detach()
7650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
7660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        void* obj = fObj;
7670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fObj = NULL;
7680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return obj;
7690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
7700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate:
7710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    void*   fObj;
7720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    Proc    fProc;
7730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
7740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic void destroy_blitter(void* blitter)
7760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
7770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    ((SkBlitter*)blitter)->~SkBlitter();
7780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
7790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic void delete_blitter(void* blitter)
7810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
7820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkDELETE((SkBlitter*)blitter);
7830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
7840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
785ab1af391811c7721e755a3893539d51565422eccMike Reedstatic bool just_solid_color(const SkPaint& paint) {
786ab1af391811c7721e755a3893539d51565422eccMike Reed    if (paint.getAlpha() == 0xFF && paint.getColorFilter() == NULL) {
787ab1af391811c7721e755a3893539d51565422eccMike Reed        SkShader* shader = paint.getShader();
788ab1af391811c7721e755a3893539d51565422eccMike Reed        if (NULL == shader ||
789ab1af391811c7721e755a3893539d51565422eccMike Reed            (shader->getFlags() & SkShader::kOpaqueAlpha_Flag)) {
790ab1af391811c7721e755a3893539d51565422eccMike Reed            return true;
791ab1af391811c7721e755a3893539d51565422eccMike Reed        }
792ab1af391811c7721e755a3893539d51565422eccMike Reed    }
793ab1af391811c7721e755a3893539d51565422eccMike Reed    return false;
794ab1af391811c7721e755a3893539d51565422eccMike Reed}
795ab1af391811c7721e755a3893539d51565422eccMike Reed
796ab1af391811c7721e755a3893539d51565422eccMike Reed/** By analyzing the paint (with an xfermode), we may decide we can take
797ab1af391811c7721e755a3893539d51565422eccMike Reed    special action. This enum lists our possible actions
798ab1af391811c7721e755a3893539d51565422eccMike Reed */
799ab1af391811c7721e755a3893539d51565422eccMike Reedenum XferInterp {
800ab1af391811c7721e755a3893539d51565422eccMike Reed    kNormal_XferInterp,         // no special interpretation, draw normally
801ab1af391811c7721e755a3893539d51565422eccMike Reed    kSrcOver_XferInterp,        // draw as if in srcover mode
802ab1af391811c7721e755a3893539d51565422eccMike Reed    kSkipDrawing_XferInterp     // draw nothing
803ab1af391811c7721e755a3893539d51565422eccMike Reed};
804ab1af391811c7721e755a3893539d51565422eccMike Reed
805ab1af391811c7721e755a3893539d51565422eccMike Reedstatic XferInterp interpret_xfermode(const SkPaint& paint, SkXfermode* xfer,
806ab1af391811c7721e755a3893539d51565422eccMike Reed                                     SkBitmap::Config deviceConfig) {
80759f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed    SkXfermode::Mode  mode;
808ab1af391811c7721e755a3893539d51565422eccMike Reed
80959f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed    if (SkXfermode::IsMode(xfer, &mode)) {
810ab1af391811c7721e755a3893539d51565422eccMike Reed        switch (mode) {
81159f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed            case SkXfermode::kSrc_Mode:
812ab1af391811c7721e755a3893539d51565422eccMike Reed                if (just_solid_color(paint)) {
813ab1af391811c7721e755a3893539d51565422eccMike Reed                    return kSrcOver_XferInterp;
814ab1af391811c7721e755a3893539d51565422eccMike Reed                }
815ab1af391811c7721e755a3893539d51565422eccMike Reed                break;
81659f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed            case SkXfermode::kDst_Mode:
817ab1af391811c7721e755a3893539d51565422eccMike Reed                return kSkipDrawing_XferInterp;
81859f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed            case SkXfermode::kSrcOver_Mode:
819ab1af391811c7721e755a3893539d51565422eccMike Reed                return kSrcOver_XferInterp;
82059f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed            case SkXfermode::kDstOver_Mode:
821ab1af391811c7721e755a3893539d51565422eccMike Reed                if (SkBitmap::kRGB_565_Config == deviceConfig) {
822ab1af391811c7721e755a3893539d51565422eccMike Reed                    return kSkipDrawing_XferInterp;
823ab1af391811c7721e755a3893539d51565422eccMike Reed                }
824ab1af391811c7721e755a3893539d51565422eccMike Reed                break;
82559f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed            case SkXfermode::kSrcIn_Mode:
826ab1af391811c7721e755a3893539d51565422eccMike Reed                if (SkBitmap::kRGB_565_Config == deviceConfig &&
827ab1af391811c7721e755a3893539d51565422eccMike Reed                    just_solid_color(paint)) {
828ab1af391811c7721e755a3893539d51565422eccMike Reed                    return kSrcOver_XferInterp;
829ab1af391811c7721e755a3893539d51565422eccMike Reed                }
830ab1af391811c7721e755a3893539d51565422eccMike Reed                break;
83159f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed            case SkXfermode::kDstIn_Mode:
832ab1af391811c7721e755a3893539d51565422eccMike Reed                if (just_solid_color(paint)) {
833ab1af391811c7721e755a3893539d51565422eccMike Reed                    return kSkipDrawing_XferInterp;
834ab1af391811c7721e755a3893539d51565422eccMike Reed                }
835ab1af391811c7721e755a3893539d51565422eccMike Reed                break;
836ab1af391811c7721e755a3893539d51565422eccMike Reed            default:
837ab1af391811c7721e755a3893539d51565422eccMike Reed                break;
838ab1af391811c7721e755a3893539d51565422eccMike Reed        }
839ab1af391811c7721e755a3893539d51565422eccMike Reed    }
840ab1af391811c7721e755a3893539d51565422eccMike Reed    return kNormal_XferInterp;
841ab1af391811c7721e755a3893539d51565422eccMike Reed}
842ab1af391811c7721e755a3893539d51565422eccMike Reed
8430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkBlitter* SkBlitter::Choose(const SkBitmap& device,
8440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                             const SkMatrix& matrix,
8450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                             const SkPaint& paint,
8460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                             void* storage, size_t storageSize)
8470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
8480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(storageSize == 0 || storage != NULL);
8490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkBlitter*  blitter = NULL;
8510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // which check, in case we're being called by a client with a dummy device
8530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // (e.g. they have a bounder that always aborts the draw)
8540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (SkBitmap::kNo_Config == device.getConfig())
8550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
8560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SK_PLACEMENT_NEW(blitter, SkNullBlitter, storage, storageSize);
8570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return blitter;
8580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
8590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoRestoreShader restore(paint);
8610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkShader* shader = paint.getShader();
8620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    Sk3DShader* shader3D = NULL;
8640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (paint.getMaskFilter() != NULL && paint.getMaskFilter()->getFormat() == SkMask::k3D_Format)
8650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
8660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        shader3D = SkNEW_ARGS(Sk3DShader, (shader));
8670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        ((SkPaint*)&paint)->setShader(shader3D)->unref();
8680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        shader = shader3D;
8690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
8700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkXfermode* mode = paint.getXfermode();
872ab1af391811c7721e755a3893539d51565422eccMike Reed    if (NULL != mode) {
873ab1af391811c7721e755a3893539d51565422eccMike Reed        switch (interpret_xfermode(paint, mode, device.config())) {
874ab1af391811c7721e755a3893539d51565422eccMike Reed            case kSrcOver_XferInterp:
875ab1af391811c7721e755a3893539d51565422eccMike Reed                mode = NULL;
876ab1af391811c7721e755a3893539d51565422eccMike Reed                break;
877ab1af391811c7721e755a3893539d51565422eccMike Reed            case kSkipDrawing_XferInterp:
878ab1af391811c7721e755a3893539d51565422eccMike Reed                SK_PLACEMENT_NEW(blitter, SkNullBlitter, storage, storageSize);
879ab1af391811c7721e755a3893539d51565422eccMike Reed                return blitter;
880ab1af391811c7721e755a3893539d51565422eccMike Reed            default:
881ab1af391811c7721e755a3893539d51565422eccMike Reed                break;
882ab1af391811c7721e755a3893539d51565422eccMike Reed        }
883ab1af391811c7721e755a3893539d51565422eccMike Reed    }
884ab1af391811c7721e755a3893539d51565422eccMike Reed
8850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (NULL == shader && (NULL != mode || paint.getColorFilter() != NULL))
8860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
8870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // xfermodes require shaders for our current set of blitters
8880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        shader = SkNEW(SkColorShader);
8890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        ((SkPaint*)&paint)->setShader(shader)->unref();
8900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
8910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (paint.getColorFilter() != NULL)
8930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
8940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(shader);
8950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        shader = SkNEW_ARGS(SkFilterShader, (shader, paint.getColorFilter()));
8960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        ((SkPaint*)&paint)->setShader(shader)->unref();
8970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
8980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool doDither = paint.isDither();
9000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (shader)
9020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
9030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (!shader->setContext(device, paint, matrix))
9040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return SkNEW(SkNullBlitter);
9050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // disable dither if our shader is natively 16bit (no need to upsample)
9070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (shader->getFlags() & SkShader::kIntrinsicly16_Flag)
9080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            doDither = false;
9090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
9100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    switch (device.getConfig()) {
9120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    case SkBitmap::kA1_Config:
9130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SK_PLACEMENT_NEW_ARGS(blitter, SkA1_Blitter, storage, storageSize, (device, paint));
9140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        break;
9150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    case SkBitmap::kA8_Config:
9170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (shader)
9180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SK_PLACEMENT_NEW_ARGS(blitter, SkA8_Shader_Blitter, storage, storageSize, (device, paint));
9190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        else
9200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SK_PLACEMENT_NEW_ARGS(blitter, SkA8_Blitter, storage, storageSize, (device, paint));
9210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        break;
9220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    case SkBitmap::kARGB_4444_Config:
9240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        blitter = SkBlitter_ChooseD4444(device, paint, storage, storageSize);
9250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        break;
9260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    case SkBitmap::kRGB_565_Config:
9280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (shader)
9290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
9300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (mode)
9310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Shader_Xfermode_Blitter, storage, storageSize, (device, paint));
9320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            else if (SkShader::CanCallShadeSpan16(shader->getFlags()) && !doDither)
9330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Shader16_Blitter, storage, storageSize, (device, paint));
9340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            else
9350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Shader_Blitter, storage, storageSize, (device, paint));
936f294d10d594ac335ea3bd09caec89004d41edc5cMike Reed        } else {
937f294d10d594ac335ea3bd09caec89004d41edc5cMike Reed            SkColor color = paint.getColor();
938f294d10d594ac335ea3bd09caec89004d41edc5cMike Reed            if (0 == SkColorGetA(color)) {
939f294d10d594ac335ea3bd09caec89004d41edc5cMike Reed                SK_PLACEMENT_NEW(blitter, SkNullBlitter, storage, storageSize);
940f294d10d594ac335ea3bd09caec89004d41edc5cMike Reed            } else if (SK_ColorBLACK == color) {
941f294d10d594ac335ea3bd09caec89004d41edc5cMike Reed                SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Black_Blitter, storage,
942f294d10d594ac335ea3bd09caec89004d41edc5cMike Reed                                      storageSize, (device, paint));
943f294d10d594ac335ea3bd09caec89004d41edc5cMike Reed            } else if (0xFF == SkColorGetA(color)) {
944f294d10d594ac335ea3bd09caec89004d41edc5cMike Reed                SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Opaque_Blitter, storage,
945f294d10d594ac335ea3bd09caec89004d41edc5cMike Reed                                      storageSize, (device, paint));
946f294d10d594ac335ea3bd09caec89004d41edc5cMike Reed            } else {
947f294d10d594ac335ea3bd09caec89004d41edc5cMike Reed                SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Blitter, storage,
948f294d10d594ac335ea3bd09caec89004d41edc5cMike Reed                                      storageSize, (device, paint));
949f294d10d594ac335ea3bd09caec89004d41edc5cMike Reed            }
9500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
9510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        break;
9520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    case SkBitmap::kARGB_8888_Config:
9540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (shader)
9550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SK_PLACEMENT_NEW_ARGS(blitter, SkARGB32_Shader_Blitter, storage, storageSize, (device, paint));
9560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        else if (paint.getColor() == SK_ColorBLACK)
9570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SK_PLACEMENT_NEW_ARGS(blitter, SkARGB32_Black_Blitter, storage, storageSize, (device, paint));
9580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        else if (paint.getAlpha() == 0xFF)
9590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SK_PLACEMENT_NEW_ARGS(blitter, SkARGB32_Opaque_Blitter, storage, storageSize, (device, paint));
9600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        else
9610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SK_PLACEMENT_NEW_ARGS(blitter, SkARGB32_Blitter, storage, storageSize, (device, paint));
9620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        break;
9630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    default:
9650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(!"unsupported device config");
9660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SK_PLACEMENT_NEW(blitter, SkNullBlitter, storage, storageSize);
9670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
9680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (shader3D)
9700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
9710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        void (*proc)(void*) = ((void*)storage == (void*)blitter) ? destroy_blitter : delete_blitter;
9720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkAutoCallProc  tmp(blitter, proc);
9730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        blitter = SkNEW_ARGS(Sk3DBlitter, (blitter, shader3D, proc));
9750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        (void)tmp.detach();
9760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
9770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return blitter;
9780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
9790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project//////////////////////////////////////////////////////////////////////////////////////////////////////
9810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectconst uint16_t gMask_0F0F = 0xF0F;
9830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectconst uint32_t gMask_00FF00FF = 0xFF00FF;
9840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project//////////////////////////////////////////////////////////////////////////////////////////////////////
9860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkShaderBlitter::SkShaderBlitter(const SkBitmap& device, const SkPaint& paint)
988f294d10d594ac335ea3bd09caec89004d41edc5cMike Reed        : INHERITED(device) {
9890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fShader = paint.getShader();
9900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(fShader);
9910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fShader->ref();
9930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fShader->beginSession();
994f294d10d594ac335ea3bd09caec89004d41edc5cMike Reed    fShaderFlags = fShader->getFlags();
9950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
9960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
997f294d10d594ac335ea3bd09caec89004d41edc5cMike ReedSkShaderBlitter::~SkShaderBlitter() {
9980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fShader->endSession();
9990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fShader->unref();
10000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
10010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1002