SkBlitter.cpp revision 35e2e62b55598210f6999fc2ea26ff8f41446ffe
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**
540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger** Licensed under the Apache License, Version 2.0 (the "License");
640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger** you may not use this file except in compliance with the License.
740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger** You may obtain a copy of the License at
80910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project**
940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger**     http://www.apache.org/licenses/LICENSE-2.0
100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project**
1140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger** Unless required by applicable law or agreed to in writing, software
1240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger** distributed under the License is distributed on an "AS IS" BASIS,
1340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger** 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
3040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerconst SkBitmap* SkBlitter::justAnOpaqueColor(uint32_t* value) {
310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return NULL;
320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkBlitter::blitH(int x, int y, int width) {
350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(!"unimplemented");
360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkBlitter::blitAntiH(int x, int y, const SkAlpha antialias[],
3940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                          const int16_t runs[]) {
400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(!"unimplemented");
410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkBlitter::blitV(int x, int y, int height, SkAlpha alpha) {
4440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (alpha == 255) {
450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this->blitRect(x, y, 1, height);
4640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    } else {
470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int16_t runs[2];
480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        runs[0] = 1;
490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        runs[1] = 0;
500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        while (--height >= 0) {
520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            this->blitAntiH(x, y++, &alpha, runs);
5340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        }
540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkBlitter::blitRect(int x, int y, int width, int height) {
5840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    while (--height >= 0) {
590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this->blitH(x, y++, width);
6040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project//////////////////////////////////////////////////////////////////////////////
640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic inline void bits_to_runs(SkBlitter* blitter, int x, int y,
6640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                const uint8_t bits[],
6740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                U8CPU left_mask, int rowBytes,
6840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                U8CPU right_mask) {
690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int inFill = 0;
700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int pos = 0;
710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    while (--rowBytes >= 0) {
730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        unsigned b = *bits++ & left_mask;
7440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (rowBytes == 0) {
750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            b &= right_mask;
7640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        }
770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        for (unsigned test = 0x80; test != 0; test >>= 1) {
7940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            if (b & test) {
8040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                if (!inFill) {
810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    pos = x;
820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    inFill = true;
830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
8440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            } else {
8540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                if (inFill) {
860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    blitter->blitH(pos, y, x - pos);
870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    inFill = false;
880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            x += 1;
910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        left_mask = 0xFF;
930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // final cleanup
9640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (inFill) {
970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        blitter->blitH(pos, y, x - pos);
9840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {
1020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(mask.fBounds.contains(clip));
1030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (mask.fFormat == SkMask::kBW_Format) {
1050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int cx = clip.fLeft;
1060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int cy = clip.fTop;
1070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int maskLeft = mask.fBounds.fLeft;
1080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int mask_rowBytes = mask.fRowBytes;
1090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int height = clip.height();
1100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const uint8_t* bits = mask.getAddr1(cx, cy);
1120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (cx == maskLeft && clip.fRight == mask.fBounds.fRight) {
11440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            while (--height >= 0) {
1150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                bits_to_runs(this, cx, cy, bits, 0xFF, mask_rowBytes, 0xFF);
1160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                bits += mask_rowBytes;
1170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                cy += 1;
1180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
11940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        } else {
1200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            int left_edge = cx - maskLeft;
1210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(left_edge >= 0);
1220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            int rite_edge = clip.fRight - maskLeft;
1230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(rite_edge > left_edge);
1240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            int left_mask = 0xFF >> (left_edge & 7);
1260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            int rite_mask = 0xFF << (8 - (rite_edge & 7));
1270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            int full_runs = (rite_edge >> 3) - ((left_edge + 7) >> 3);
1280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            // check for empty right mask, so we don't read off the end (or go slower than we need to)
13040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            if (rite_mask == 0) {
1310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkASSERT(full_runs >= 0);
1320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                full_runs -= 1;
1330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                rite_mask = 0xFF;
1340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
13540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            if (left_mask == 0xFF) {
1360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                full_runs -= 1;
13740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            }
1380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            // back up manually so we can keep in sync with our byte-aligned src
1400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            // have cx reflect our actual starting x-coord
1410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            cx -= left_edge & 7;
1420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            if (full_runs < 0) {
1440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkASSERT((left_mask & rite_mask) != 0);
14540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                while (--height >= 0) {
1460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    bits_to_runs(this, cx, cy, bits, left_mask, 1, rite_mask);
1470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    bits += mask_rowBytes;
1480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    cy += 1;
1490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
15040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            } else {
15140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                while (--height >= 0) {
1520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    bits_to_runs(this, cx, cy, bits, left_mask, full_runs + 2, rite_mask);
1530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    bits += mask_rowBytes;
1540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    cy += 1;
1550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
1560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
1570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
15840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    } else {
1590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int                         width = clip.width();
1600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkAutoSTMalloc<64, int16_t> runStorage(width + 1);
1610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int16_t*                    runs = runStorage.get();
1620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const uint8_t*              aa = mask.getAddr(clip.fLeft, clip.fTop);
1630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_memset16((uint16_t*)runs, 1, width);
1650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        runs[width] = 0;
1660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int height = clip.height();
1680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int y = clip.fTop;
16940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        while (--height >= 0) {
1700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            this->blitAntiH(clip.fLeft, y, aa, runs);
1710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            aa += mask.fRowBytes;
1720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            y += 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/////////////////////// these guys are not virtual, just a helpers
1780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkBlitter::blitMaskRegion(const SkMask& mask, const SkRegion& clip) {
1800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (clip.quickReject(mask.fBounds)) {
1810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return;
1820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
18340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
1840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRegion::Cliperator clipper(clip, mask.fBounds);
18540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
1860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while (!clipper.done()) {
1870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const SkIRect& cr = clipper.rect();
1880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this->blitMask(mask, cr);
1890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        clipper.next();
1900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkBlitter::blitRectRegion(const SkIRect& rect, const SkRegion& clip) {
1940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRegion::Cliperator clipper(clip, rect);
19540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
1960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while (!clipper.done()) {
1970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const SkIRect& cr = clipper.rect();
1980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this->blitRect(cr.fLeft, cr.fTop, cr.width(), cr.height());
1990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        clipper.next();
2000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
2010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkBlitter::blitRegion(const SkRegion& clip) {
2040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRegion::Iterator iter(clip);
20540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
2060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while (!iter.done()) {
2070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const SkIRect& cr = iter.rect();
2080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this->blitRect(cr.fLeft, cr.fTop, cr.width(), cr.height());
2090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        iter.next();
2100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
2110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
21340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
2140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
21540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkNullBlitter::blitH(int x, int y, int width) {}
2160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
21740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkNullBlitter::blitAntiH(int x, int y, const SkAlpha antialias[],
21840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                              const int16_t runs[]) {}
2190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
22040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkNullBlitter::blitV(int x, int y, int height, SkAlpha alpha) {}
2210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
22240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkNullBlitter::blitRect(int x, int y, int width, int height) {}
2230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
22440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkNullBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {}
2250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
22640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerconst SkBitmap* SkNullBlitter::justAnOpaqueColor(uint32_t* value) {
2270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return NULL;
2280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
23040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
2310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
23240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic int compute_anti_width(const int16_t runs[]) {
2330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int width = 0;
23440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
23540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    for (;;) {
2360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int count = runs[0];
23740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
2380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(count >= 0);
23940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (count == 0) {
2400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
24140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        }
2420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        width += count;
2430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        runs += count;
24440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
2450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(width < 20000);
2460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
2470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return width;
2480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
25040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic inline bool y_in_rect(int y, const SkIRect& rect) {
2510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return (unsigned)(y - rect.fTop) < (unsigned)rect.height();
2520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
25440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic inline bool x_in_rect(int x, const SkIRect& rect) {
2550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return (unsigned)(x - rect.fLeft) < (unsigned)rect.width();
2560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
25840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkRectClipBlitter::blitH(int left, int y, int width) {
2590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(width > 0);
2600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
26140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (!y_in_rect(y, fClipRect)) {
2620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return;
26340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
2640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int right = left + width;
2660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
26740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (left < fClipRect.fLeft) {
2680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        left = fClipRect.fLeft;
26940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
27040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (right > fClipRect.fRight) {
2710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        right = fClipRect.fRight;
27240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
2730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    width = right - left;
27540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (width > 0) {
2760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fBlitter->blitH(left, y, width);
27740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
2780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
28040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkRectClipBlitter::blitAntiH(int left, int y, const SkAlpha aa[],
28140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                  const int16_t runs[]) {
28240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (!y_in_rect(y, fClipRect) || left >= fClipRect.fRight) {
2830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return;
28440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
2850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int x0 = left;
2870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int x1 = left + compute_anti_width(runs);
2880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
28940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (x1 <= fClipRect.fLeft) {
2900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return;
29140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
2920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(x0 < x1);
29440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (x0 < fClipRect.fLeft) {
2950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int dx = fClipRect.fLeft - x0;
2960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkAlphaRuns::BreakAt((int16_t*)runs, (uint8_t*)aa, dx);
2970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        runs += dx;
2980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        aa += dx;
2990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        x0 = fClipRect.fLeft;
3000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
3010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(x0 < x1 && runs[x1 - x0] == 0);
30340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (x1 > fClipRect.fRight) {
3040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        x1 = fClipRect.fRight;
3050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkAlphaRuns::BreakAt((int16_t*)runs, (uint8_t*)aa, x1 - x0);
3060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        ((int16_t*)runs)[x1 - x0] = 0;
3070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
3080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(x0 < x1 && runs[x1 - x0] == 0);
3100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(compute_anti_width(runs) == x1 - x0);
3110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fBlitter->blitAntiH(x0, y, aa, runs);
3130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
31540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkRectClipBlitter::blitV(int x, int y, int height, SkAlpha alpha) {
3160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(height > 0);
3170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
31840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (!x_in_rect(x, fClipRect)) {
3190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return;
32040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
3210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int y0 = y;
3230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int y1 = y + height;
3240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
32540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (y0 < fClipRect.fTop) {
3260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        y0 = fClipRect.fTop;
32740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
32840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (y1 > fClipRect.fBottom) {
3290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        y1 = fClipRect.fBottom;
33040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
3310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
33240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (y0 < y1) {
3330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fBlitter->blitV(x, y0, y1 - y0, alpha);
33440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
3350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
33740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkRectClipBlitter::blitRect(int left, int y, int width, int height) {
3380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkIRect    r;
3390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    r.set(left, y, left + width, y + height);
34140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (r.intersect(fClipRect)) {
3420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height());
34340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
3440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
34640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkRectClipBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {
3470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(mask.fBounds.contains(clip));
3480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkIRect    r = clip;
3500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
35140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (r.intersect(fClipRect)) {
3520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fBlitter->blitMask(mask, r);
35340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
3540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
35640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerconst SkBitmap* SkRectClipBlitter::justAnOpaqueColor(uint32_t* value) {
3570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return fBlitter->justAnOpaqueColor(value);
3580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
36040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
3610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
36240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkRgnClipBlitter::blitH(int x, int y, int width) {
3630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRegion::Spanerator span(*fRgn, y, x, x + width);
3640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int left, right;
3650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
36640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    while (span.next(&left, &right)) {
3670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(left < right);
3680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fBlitter->blitH(left, y, right - left);
3690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
3700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
37240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkRgnClipBlitter::blitAntiH(int x, int y, const SkAlpha aa[],
37340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                 const int16_t runs[]) {
3740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int width = compute_anti_width(runs);
3750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRegion::Spanerator span(*fRgn, y, x, x + width);
3760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int left, right;
3770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkDEBUGCODE(const SkIRect& bounds = fRgn->getBounds();)
37840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
3790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int prevRite = x;
38040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    while (span.next(&left, &right)) {
3810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(x <= left);
3820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(left < right);
3830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(left >= bounds.fLeft && right <= bounds.fRight);
38440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
3850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkAlphaRuns::Break((int16_t*)runs, (uint8_t*)aa, left - x, right - left);
3860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // now zero before left
38840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (left > prevRite) {
3890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            int index = prevRite - x;
3900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            ((uint8_t*)aa)[index] = 0;   // skip runs after right
3910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            ((int16_t*)runs)[index] = SkToS16(left - prevRite);
3920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
39340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
3940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        prevRite = right;
3950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
39640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
39740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (prevRite > x) {
3980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        ((int16_t*)runs)[prevRite - x] = 0;
39940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
4000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (x < 0) {
4010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            int skip = runs[0];
4020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(skip >= -x);
4030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            aa += skip;
4040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            runs += skip;
4050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            x += skip;
4060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
4070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fBlitter->blitAntiH(x, y, aa, runs);
4080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
4090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
41140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkRgnClipBlitter::blitV(int x, int y, int height, SkAlpha alpha) {
4120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkIRect    bounds;
4130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bounds.set(x, y, x + 1, y + height);
4140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRegion::Cliperator    iter(*fRgn, bounds);
4160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
41740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    while (!iter.done()) {
4180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const SkIRect& r = iter.rect();
4190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(bounds.contains(r));
4200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fBlitter->blitV(x, r.fTop, r.height(), alpha);
4220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        iter.next();
4230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
4240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
42640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkRgnClipBlitter::blitRect(int x, int y, int width, int height) {
4270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkIRect    bounds;
4280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bounds.set(x, y, x + width, y + height);
4290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRegion::Cliperator    iter(*fRgn, bounds);
4310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
43240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    while (!iter.done()) {
4330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const SkIRect& r = iter.rect();
4340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(bounds.contains(r));
4350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height());
4370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        iter.next();
4380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
4390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
44140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkRgnClipBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {
4420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(mask.fBounds.contains(clip));
4430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRegion::Cliperator iter(*fRgn, clip);
4450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const SkIRect&       r = iter.rect();
4460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkBlitter*           blitter = fBlitter;
4470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
44840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    while (!iter.done()) {
4490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        blitter->blitMask(mask, r);
4500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        iter.next();
4510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
4520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
45440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerconst SkBitmap* SkRgnClipBlitter::justAnOpaqueColor(uint32_t* value) {
4550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return fBlitter->justAnOpaqueColor(value);
4560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
45840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
4590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
46040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkBlitter* SkBlitterClipper::apply(SkBlitter* blitter, const SkRegion* clip,
46140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                   const SkIRect* ir) {
46240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (clip) {
4630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const SkIRect& clipR = clip->getBounds();
4640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
46540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (clip->isEmpty() || (ir && !SkIRect::Intersects(clipR, *ir))) {
4660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            blitter = &fNullBlitter;
46740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        } else if (clip->isRect()) {
46840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            if (ir == NULL || !clipR.contains(*ir)) {
4690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                fRectBlitter.init(blitter, clipR);
4700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                blitter = &fRectBlitter;
4710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
47240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        } else {
4730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fRgnBlitter.init(blitter, clip);
4740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            blitter = &fRgnBlitter;
4750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
4760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
4770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return blitter;
4780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
48040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
4810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkColorShader.h"
4830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkColorPriv.h"
4840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass Sk3DShader : public SkShader {
4860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic:
48740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    Sk3DShader(SkShader* proxy) : fProxy(proxy) {
48840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        SkSafeRef(proxy);
4890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fMask = NULL;
4900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
49140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
49240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    virtual ~Sk3DShader() {
49340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        SkSafeUnref(fProxy);
4940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
49540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
4960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    void setMask(const SkMask* mask) { fMask = mask; }
4970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
49840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    virtual bool setContext(const SkBitmap& device, const SkPaint& paint,
49940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                            const SkMatrix& matrix) {
50040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (fProxy) {
5010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return fProxy->setContext(device, paint, matrix);
50240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        } else {
5030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fPMColor = SkPreMultiplyColor(paint.getColor());
5040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return this->INHERITED::setContext(device, paint, matrix);
5050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
5060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
50740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
50840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    virtual void shadeSpan(int x, int y, SkPMColor span[], int count) {
50940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (fProxy) {
5100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fProxy->shadeSpan(x, y, span, count);
51140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        }
5120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
51340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (fMask == NULL) {
51440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            if (fProxy == NULL) {
5150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                sk_memset32(span, fPMColor, count);
51640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            }
5170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return;
5180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
5190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(fMask->fBounds.contains(x, y));
5210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(fMask->fBounds.contains(x + count - 1, y));
5220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        size_t          size = fMask->computeImageSize();
5240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const uint8_t*  alpha = fMask->getAddr(x, y);
5250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const uint8_t*  mulp = alpha + size;
5260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const uint8_t*  addp = mulp + size;
5270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
52840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (fProxy) {
52940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            for (int i = 0; i < count; i++) {
53040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                if (alpha[i]) {
5310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    SkPMColor c = span[i];
53240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                    if (c) {
5330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        unsigned a = SkGetPackedA32(c);
5340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        unsigned r = SkGetPackedR32(c);
5350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        unsigned g = SkGetPackedG32(c);
5360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        unsigned b = SkGetPackedB32(c);
5370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        unsigned mul = SkAlpha255To256(mulp[i]);
5390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        unsigned add = addp[i];
5400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        r = SkFastMin32(SkAlphaMul(r, mul) + add, a);
5420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        g = SkFastMin32(SkAlphaMul(g, mul) + add, a);
5430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        b = SkFastMin32(SkAlphaMul(b, mul) + add, a);
5440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        span[i] = SkPackARGB32(a, r, g, b);
5460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    }
54740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                } else {
5480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    span[i] = 0;
54940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                }
5500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
55140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        } else {    // color
5520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            unsigned a = SkGetPackedA32(fPMColor);
5530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            unsigned r = SkGetPackedR32(fPMColor);
5540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            unsigned g = SkGetPackedG32(fPMColor);
5550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            unsigned b = SkGetPackedB32(fPMColor);
55640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            for (int i = 0; i < count; i++) {
55740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                if (alpha[i]) {
5580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    unsigned mul = SkAlpha255To256(mulp[i]);
5590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    unsigned add = addp[i];
5600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    span[i] = SkPackARGB32( a,
56240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                    SkFastMin32(SkAlphaMul(r, mul) + add, a),
56340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                    SkFastMin32(SkAlphaMul(g, mul) + add, a),
56440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                    SkFastMin32(SkAlphaMul(b, mul) + add, a));
56540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                } else {
5660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    span[i] = 0;
56740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                }
5680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
5690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
5700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
57140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
57240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    virtual void beginSession() {
5730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this->INHERITED::beginSession();
57440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (fProxy) {
5750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fProxy->beginSession();
57640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        }
5770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
57840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
57940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    virtual void endSession() {
58040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (fProxy) {
5810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fProxy->endSession();
58240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        }
5830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this->INHERITED::endSession();
5840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
5850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprotected:
5870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    Sk3DShader(SkFlattenableReadBuffer& buffer) :
58840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            INHERITED(buffer) {
5890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fProxy = static_cast<SkShader*>(buffer.readFlattenable());
5900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPMColor = buffer.readU32();
5910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fMask = NULL;
5920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
59340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
59440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    virtual void flatten(SkFlattenableWriteBuffer& buffer) {
5950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this->INHERITED::flatten(buffer);
5960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        buffer.writeFlattenable(fProxy);
5970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        buffer.write32(fPMColor);
5980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
59940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
60040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    virtual Factory getFactory() {
6010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return CreateProc;
6020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
6030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate:
60540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
6060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return SkNEW_ARGS(Sk3DShader, (buffer));
6070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
6080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkShader*       fProxy;
6100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPMColor       fPMColor;
6110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const SkMask*   fMask;
6120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    typedef SkShader INHERITED;
6140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
6150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass Sk3DBlitter : public SkBlitter {
6170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic:
6180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    Sk3DBlitter(SkBlitter* proxy, Sk3DShader* shader, void (*killProc)(void*))
61940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            : fProxy(proxy), f3DShader(shader), fKillProc(killProc) {
6200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        shader->ref();
6210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
62240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
62340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    virtual ~Sk3DBlitter() {
6240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        f3DShader->unref();
6250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fKillProc(fProxy);
6260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
6270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
62840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    virtual void blitH(int x, int y, int width) {
6290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fProxy->blitH(x, y, width);
6300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
63140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
63240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    virtual void blitAntiH(int x, int y, const SkAlpha antialias[],
63340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                           const int16_t runs[]) {
6340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fProxy->blitAntiH(x, y, antialias, runs);
6350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
63640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
63740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    virtual void blitV(int x, int y, int height, SkAlpha alpha) {
6380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fProxy->blitV(x, y, height, alpha);
6390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
64040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
64140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    virtual void blitRect(int x, int y, int width, int height) {
6420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fProxy->blitRect(x, y, width, height);
6430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
64440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
64540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    virtual void blitMask(const SkMask& mask, const SkIRect& clip) {
64640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (mask.fFormat == SkMask::k3D_Format) {
6470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            f3DShader->setMask(&mask);
6480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            ((SkMask*)&mask)->fFormat = SkMask::kA8_Format;
6500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fProxy->blitMask(mask, clip);
6510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            ((SkMask*)&mask)->fFormat = SkMask::k3D_Format;
6520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            f3DShader->setMask(NULL);
65440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        } else {
6550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fProxy->blitMask(mask, clip);
65640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        }
6570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
65840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
6590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate:
6600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkBlitter*  fProxy;
6610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    Sk3DShader* f3DShader;
6620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    void        (*fKillProc)(void*);
6630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
6640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
66540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
6660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkCoreBlitters.h"
6680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass SkAutoCallProc {
6700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic:
6710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    typedef void (*Proc)(void*);
67240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
6730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoCallProc(void* obj, Proc proc)
67440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    : fObj(obj), fProc(proc) {}
67540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
67640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    ~SkAutoCallProc() {
67740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (fObj && fProc) {
6780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fProc(fObj);
67940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        }
6800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
68140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
6820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    void* get() const { return fObj; }
68340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
68440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    void* detach() {
6850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        void* obj = fObj;
6860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fObj = NULL;
6870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return obj;
6880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
68940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
6900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate:
6910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    void*   fObj;
6920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    Proc    fProc;
6930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
6940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
69540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic void destroy_blitter(void* blitter) {
6960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    ((SkBlitter*)blitter)->~SkBlitter();
6970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
6980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
69940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic void delete_blitter(void* blitter) {
7000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkDELETE((SkBlitter*)blitter);
7010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
7020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
703ab1af391811c7721e755a3893539d51565422eccMike Reedstatic bool just_solid_color(const SkPaint& paint) {
704ab1af391811c7721e755a3893539d51565422eccMike Reed    if (paint.getAlpha() == 0xFF && paint.getColorFilter() == NULL) {
705ab1af391811c7721e755a3893539d51565422eccMike Reed        SkShader* shader = paint.getShader();
706ab1af391811c7721e755a3893539d51565422eccMike Reed        if (NULL == shader ||
707ab1af391811c7721e755a3893539d51565422eccMike Reed            (shader->getFlags() & SkShader::kOpaqueAlpha_Flag)) {
708ab1af391811c7721e755a3893539d51565422eccMike Reed            return true;
709ab1af391811c7721e755a3893539d51565422eccMike Reed        }
710ab1af391811c7721e755a3893539d51565422eccMike Reed    }
711ab1af391811c7721e755a3893539d51565422eccMike Reed    return false;
712ab1af391811c7721e755a3893539d51565422eccMike Reed}
71340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
714ab1af391811c7721e755a3893539d51565422eccMike Reed/** By analyzing the paint (with an xfermode), we may decide we can take
715ab1af391811c7721e755a3893539d51565422eccMike Reed    special action. This enum lists our possible actions
716ab1af391811c7721e755a3893539d51565422eccMike Reed */
717ab1af391811c7721e755a3893539d51565422eccMike Reedenum XferInterp {
718ab1af391811c7721e755a3893539d51565422eccMike Reed    kNormal_XferInterp,         // no special interpretation, draw normally
719ab1af391811c7721e755a3893539d51565422eccMike Reed    kSrcOver_XferInterp,        // draw as if in srcover mode
720ab1af391811c7721e755a3893539d51565422eccMike Reed    kSkipDrawing_XferInterp     // draw nothing
721ab1af391811c7721e755a3893539d51565422eccMike Reed};
722ab1af391811c7721e755a3893539d51565422eccMike Reed
723ab1af391811c7721e755a3893539d51565422eccMike Reedstatic XferInterp interpret_xfermode(const SkPaint& paint, SkXfermode* xfer,
724ab1af391811c7721e755a3893539d51565422eccMike Reed                                     SkBitmap::Config deviceConfig) {
72559f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed    SkXfermode::Mode  mode;
72640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
72759f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed    if (SkXfermode::IsMode(xfer, &mode)) {
728ab1af391811c7721e755a3893539d51565422eccMike Reed        switch (mode) {
72959f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed            case SkXfermode::kSrc_Mode:
730ab1af391811c7721e755a3893539d51565422eccMike Reed                if (just_solid_color(paint)) {
731ab1af391811c7721e755a3893539d51565422eccMike Reed                    return kSrcOver_XferInterp;
732ab1af391811c7721e755a3893539d51565422eccMike Reed                }
733ab1af391811c7721e755a3893539d51565422eccMike Reed                break;
73459f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed            case SkXfermode::kDst_Mode:
735ab1af391811c7721e755a3893539d51565422eccMike Reed                return kSkipDrawing_XferInterp;
73659f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed            case SkXfermode::kSrcOver_Mode:
737ab1af391811c7721e755a3893539d51565422eccMike Reed                return kSrcOver_XferInterp;
73859f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed            case SkXfermode::kDstOver_Mode:
739ab1af391811c7721e755a3893539d51565422eccMike Reed                if (SkBitmap::kRGB_565_Config == deviceConfig) {
740ab1af391811c7721e755a3893539d51565422eccMike Reed                    return kSkipDrawing_XferInterp;
741ab1af391811c7721e755a3893539d51565422eccMike Reed                }
742ab1af391811c7721e755a3893539d51565422eccMike Reed                break;
74359f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed            case SkXfermode::kSrcIn_Mode:
744ab1af391811c7721e755a3893539d51565422eccMike Reed                if (SkBitmap::kRGB_565_Config == deviceConfig &&
745ab1af391811c7721e755a3893539d51565422eccMike Reed                    just_solid_color(paint)) {
746ab1af391811c7721e755a3893539d51565422eccMike Reed                    return kSrcOver_XferInterp;
747ab1af391811c7721e755a3893539d51565422eccMike Reed                }
748ab1af391811c7721e755a3893539d51565422eccMike Reed                break;
74959f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed            case SkXfermode::kDstIn_Mode:
750ab1af391811c7721e755a3893539d51565422eccMike Reed                if (just_solid_color(paint)) {
751ab1af391811c7721e755a3893539d51565422eccMike Reed                    return kSkipDrawing_XferInterp;
752ab1af391811c7721e755a3893539d51565422eccMike Reed                }
753ab1af391811c7721e755a3893539d51565422eccMike Reed                break;
754ab1af391811c7721e755a3893539d51565422eccMike Reed            default:
755ab1af391811c7721e755a3893539d51565422eccMike Reed                break;
756ab1af391811c7721e755a3893539d51565422eccMike Reed        }
757ab1af391811c7721e755a3893539d51565422eccMike Reed    }
758ab1af391811c7721e755a3893539d51565422eccMike Reed    return kNormal_XferInterp;
759ab1af391811c7721e755a3893539d51565422eccMike Reed}
760ab1af391811c7721e755a3893539d51565422eccMike Reed
7610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkBlitter* SkBlitter::Choose(const SkBitmap& device,
7620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                             const SkMatrix& matrix,
76335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger                             const SkPaint& origPaint,
76440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                             void* storage, size_t storageSize) {
7650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(storageSize == 0 || storage != NULL);
7660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkBlitter*  blitter = NULL;
7680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // which check, in case we're being called by a client with a dummy device
7700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // (e.g. they have a bounder that always aborts the draw)
77140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (SkBitmap::kNo_Config == device.getConfig()) {
7720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SK_PLACEMENT_NEW(blitter, SkNullBlitter, storage, storageSize);
7730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return blitter;
7740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
7750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
77635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    SkPaint paint(origPaint);
7770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkShader* shader = paint.getShader();
77835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    SkColorFilter* cf = paint.getColorFilter();
77935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    SkXfermode* mode = paint.getXfermode();
7800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    Sk3DShader* shader3D = NULL;
78240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (paint.getMaskFilter() != NULL &&
78340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            paint.getMaskFilter()->getFormat() == SkMask::k3D_Format) {
7840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        shader3D = SkNEW_ARGS(Sk3DShader, (shader));
78535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        paint.setShader(shader3D)->unref();
7860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        shader = shader3D;
7870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
7880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
789ab1af391811c7721e755a3893539d51565422eccMike Reed    if (NULL != mode) {
790ab1af391811c7721e755a3893539d51565422eccMike Reed        switch (interpret_xfermode(paint, mode, device.config())) {
791ab1af391811c7721e755a3893539d51565422eccMike Reed            case kSrcOver_XferInterp:
792ab1af391811c7721e755a3893539d51565422eccMike Reed                mode = NULL;
79335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger                paint.setXfermode(NULL);
794ab1af391811c7721e755a3893539d51565422eccMike Reed                break;
795ab1af391811c7721e755a3893539d51565422eccMike Reed            case kSkipDrawing_XferInterp:
796ab1af391811c7721e755a3893539d51565422eccMike Reed                SK_PLACEMENT_NEW(blitter, SkNullBlitter, storage, storageSize);
797ab1af391811c7721e755a3893539d51565422eccMike Reed                return blitter;
798ab1af391811c7721e755a3893539d51565422eccMike Reed            default:
799ab1af391811c7721e755a3893539d51565422eccMike Reed                break;
800ab1af391811c7721e755a3893539d51565422eccMike Reed        }
801ab1af391811c7721e755a3893539d51565422eccMike Reed    }
802ab1af391811c7721e755a3893539d51565422eccMike Reed
80335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    if (NULL == shader) {
80435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#ifdef SK_IGNORE_CF_OPTIMIZATION
80535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        if (mode || cf) {
80635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#else
80735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        if (mode) {
80835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#endif
80935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger            // xfermodes (and filters) require shaders for our current blitters
81035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger            shader = SkNEW(SkColorShader);
81135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger            paint.setShader(shader)->unref();
81235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        } else if (cf) {
81335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger            // if no shader && no xfermode, we just apply the colorfilter to
81435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger            // our color and move on.
81535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger            paint.setColor(cf->filterColor(paint.getColor()));
81635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger            paint.setColorFilter(NULL);
81735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger            cf = NULL;
81835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        }
8190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
82040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
82135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    if (cf) {
8220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(shader);
82335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        shader = SkNEW_ARGS(SkFilterShader, (shader, cf));
82435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        paint.setShader(shader)->unref();
8254663d79a396bd4d45a9140626921c9fbad77fbf8Mike Reed        // blitters should ignore the presence/absence of a filter, since
8264663d79a396bd4d45a9140626921c9fbad77fbf8Mike Reed        // if there is one, the shader will take care of it.
8270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
82840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
8293026a9ec59b285412941d278a570e382088f8adaMike Reed    if (shader && !shader->setContext(device, paint, matrix)) {
8303026a9ec59b285412941d278a570e382088f8adaMike Reed        return SkNEW(SkNullBlitter);
8310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
8320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    switch (device.getConfig()) {
83440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        case SkBitmap::kA1_Config:
83540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            SK_PLACEMENT_NEW_ARGS(blitter, SkA1_Blitter,
83640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                  storage, storageSize, (device, paint));
83740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            break;
83840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
83940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        case SkBitmap::kA8_Config:
84040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            if (shader) {
84140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                SK_PLACEMENT_NEW_ARGS(blitter, SkA8_Shader_Blitter,
84240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                      storage, storageSize, (device, paint));
84340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            } else {
84440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                SK_PLACEMENT_NEW_ARGS(blitter, SkA8_Blitter,
84540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                      storage, storageSize, (device, paint));
84640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            }
84740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            break;
84840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
84940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        case SkBitmap::kARGB_4444_Config:
85040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            blitter = SkBlitter_ChooseD4444(device, paint, storage, storageSize);
85140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            break;
85240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
85340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        case SkBitmap::kRGB_565_Config:
85440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            blitter = SkBlitter_ChooseD565(device, paint, storage, storageSize);
85540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            break;
85640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
85740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        case SkBitmap::kARGB_8888_Config:
85840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            if (shader) {
85940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                SK_PLACEMENT_NEW_ARGS(blitter, SkARGB32_Shader_Blitter,
86040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                      storage, storageSize, (device, paint));
86140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            } else if (paint.getColor() == SK_ColorBLACK) {
86240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                SK_PLACEMENT_NEW_ARGS(blitter, SkARGB32_Black_Blitter,
86340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                      storage, storageSize, (device, paint));
86440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            } else if (paint.getAlpha() == 0xFF) {
86540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                SK_PLACEMENT_NEW_ARGS(blitter, SkARGB32_Opaque_Blitter,
86640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                      storage, storageSize, (device, paint));
86740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            } else {
86840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                SK_PLACEMENT_NEW_ARGS(blitter, SkARGB32_Blitter,
86940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                      storage, storageSize, (device, paint));
87040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            }
87140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            break;
87240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
87340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        default:
87440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            SkASSERT(!"unsupported device config");
87540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            SK_PLACEMENT_NEW(blitter, SkNullBlitter, storage, storageSize);
87640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            break;
8770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
8780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
87940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (shader3D) {
8800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        void (*proc)(void*) = ((void*)storage == (void*)blitter) ? destroy_blitter : delete_blitter;
8810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkAutoCallProc  tmp(blitter, proc);
8820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        blitter = SkNEW_ARGS(Sk3DBlitter, (blitter, shader3D, proc));
8840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        (void)tmp.detach();
8850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
8860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return blitter;
8870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
8880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
88940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
8900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectconst uint16_t gMask_0F0F = 0xF0F;
8920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectconst uint32_t gMask_00FF00FF = 0xFF00FF;
8930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
89440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
8950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkShaderBlitter::SkShaderBlitter(const SkBitmap& device, const SkPaint& paint)
897f294d10d594ac335ea3bd09caec89004d41edc5cMike Reed        : INHERITED(device) {
8980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fShader = paint.getShader();
8990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(fShader);
9000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fShader->ref();
9020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fShader->beginSession();
903f294d10d594ac335ea3bd09caec89004d41edc5cMike Reed    fShaderFlags = fShader->getFlags();
9040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
9050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
906f294d10d594ac335ea3bd09caec89004d41edc5cMike ReedSkShaderBlitter::~SkShaderBlitter() {
9070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fShader->endSession();
9080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fShader->unref();
9090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
9100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
911