SkBlitter.cpp revision 1cab2921ab279367f8206cdadc9259d12e603548
11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/* 31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2006 The Android Open Source Project 41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * 51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file. 71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 81cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 90910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkBlitter.h" 110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkAntiRun.h" 120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkColor.h" 130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkColorFilter.h" 140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkMask.h" 150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkMaskFilter.h" 160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkTemplatesPriv.h" 170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkUtils.h" 180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkXfermode.h" 190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2059f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike ReedSkBlitter::~SkBlitter() {} 210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerconst SkBitmap* SkBlitter::justAnOpaqueColor(uint32_t* value) { 230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return NULL; 240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkBlitter::blitH(int x, int y, int width) { 271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDEBUGFAIL("unimplemented"); 280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkBlitter::blitAntiH(int x, int y, const SkAlpha antialias[], 3140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const int16_t runs[]) { 321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDEBUGFAIL("unimplemented"); 330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkBlitter::blitV(int x, int y, int height, SkAlpha alpha) { 3640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (alpha == 255) { 370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project this->blitRect(x, y, 1, height); 3840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int16_t runs[2]; 400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project runs[0] = 1; 410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project runs[1] = 0; 420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger while (--height >= 0) { 440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project this->blitAntiH(x, y++, &alpha, runs); 4540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkBlitter::blitRect(int x, int y, int width, int height) { 501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(width > 0); 5140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger while (--height >= 0) { 520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project this->blitH(x, y++, width); 5340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/// Default implementation doesn't check for any easy optimizations 571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/// such as alpha == 0 or 255; also uses blitV(), which some subclasses 581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/// may not support. 591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkBlitter::blitAntiRect(int x, int y, int width, int height, 601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkAlpha leftAlpha, SkAlpha rightAlpha) { 611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->blitV(x++, y, height, leftAlpha); 621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (width > 0) { 631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->blitRect(x, y, width, height); 641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger x += width; 651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->blitV(x, y, height, rightAlpha); 671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project////////////////////////////////////////////////////////////////////////////// 700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic inline void bits_to_runs(SkBlitter* blitter, int x, int y, 7240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const uint8_t bits[], 7340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger U8CPU left_mask, int rowBytes, 7440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger U8CPU right_mask) { 750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int inFill = 0; 760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int pos = 0; 770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger while (--rowBytes >= 0) { 790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned b = *bits++ & left_mask; 8040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (rowBytes == 0) { 810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project b &= right_mask; 8240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 8440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger for (unsigned test = 0x80; test != 0; test >>= 1) { 8540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (b & test) { 8640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (!inFill) { 870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project pos = x; 880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project inFill = true; 890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 9040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 9140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (inFill) { 920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project blitter->blitH(pos, y, x - pos); 930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project inFill = false; 940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project x += 1; 970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project left_mask = 0xFF; 990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // final cleanup 10240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (inFill) { 1030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project blitter->blitH(pos, y, x - pos); 10440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 1050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkBlitter::blitMask(const SkMask& mask, const SkIRect& clip) { 1080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(mask.fBounds.contains(clip)); 1090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (mask.fFormat == SkMask::kBW_Format) { 1110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int cx = clip.fLeft; 1120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int cy = clip.fTop; 1130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int maskLeft = mask.fBounds.fLeft; 1140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int mask_rowBytes = mask.fRowBytes; 1150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int height = clip.height(); 1160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const uint8_t* bits = mask.getAddr1(cx, cy); 1180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (cx == maskLeft && clip.fRight == mask.fBounds.fRight) { 12040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger while (--height >= 0) { 1210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bits_to_runs(this, cx, cy, bits, 0xFF, mask_rowBytes, 0xFF); 1220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bits += mask_rowBytes; 1230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project cy += 1; 1240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 1260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int left_edge = cx - maskLeft; 1270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(left_edge >= 0); 1280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int rite_edge = clip.fRight - maskLeft; 1290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(rite_edge > left_edge); 1300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int left_mask = 0xFF >> (left_edge & 7); 1320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int rite_mask = 0xFF << (8 - (rite_edge & 7)); 1330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int full_runs = (rite_edge >> 3) - ((left_edge + 7) >> 3); 1340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // check for empty right mask, so we don't read off the end (or go slower than we need to) 13640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (rite_mask == 0) { 1370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(full_runs >= 0); 1380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project full_runs -= 1; 1390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rite_mask = 0xFF; 1400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 14140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (left_mask == 0xFF) { 1420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project full_runs -= 1; 14340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 1440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // back up manually so we can keep in sync with our byte-aligned src 1460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // have cx reflect our actual starting x-coord 1470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project cx -= left_edge & 7; 1480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 14940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (full_runs < 0) { 1500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT((left_mask & rite_mask) != 0); 15140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger while (--height >= 0) { 1520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bits_to_runs(this, cx, cy, bits, left_mask, 1, rite_mask); 1530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bits += mask_rowBytes; 1540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project cy += 1; 1550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 15640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 15740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger while (--height >= 0) { 1580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bits_to_runs(this, cx, cy, bits, left_mask, full_runs + 2, rite_mask); 1590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bits += mask_rowBytes; 1600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project cy += 1; 1610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 16440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 1650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int width = clip.width(); 1660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoSTMalloc<64, int16_t> runStorage(width + 1); 1670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int16_t* runs = runStorage.get(); 1681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const uint8_t* aa = mask.getAddr8(clip.fLeft, clip.fTop); 1690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_memset16((uint16_t*)runs, 1, width); 1710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project runs[width] = 0; 1720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int height = clip.height(); 1740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int y = clip.fTop; 17540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger while (--height >= 0) { 1760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project this->blitAntiH(clip.fLeft, y, aa, runs); 1770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project aa += mask.fRowBytes; 1780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project y += 1; 1790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////// these guys are not virtual, just a helpers 1840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkBlitter::blitMaskRegion(const SkMask& mask, const SkRegion& clip) { 1860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (clip.quickReject(mask.fBounds)) { 1870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return; 1880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 18940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 1900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRegion::Cliperator clipper(clip, mask.fBounds); 19140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 1920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project while (!clipper.done()) { 1930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkIRect& cr = clipper.rect(); 1940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project this->blitMask(mask, cr); 1950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project clipper.next(); 1960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkBlitter::blitRectRegion(const SkIRect& rect, const SkRegion& clip) { 2000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRegion::Cliperator clipper(clip, rect); 20140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 2020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project while (!clipper.done()) { 2030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkIRect& cr = clipper.rect(); 2040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project this->blitRect(cr.fLeft, cr.fTop, cr.width(), cr.height()); 2050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project clipper.next(); 2060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 2070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkBlitter::blitRegion(const SkRegion& clip) { 2100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRegion::Iterator iter(clip); 21140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 2120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project while (!iter.done()) { 2130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkIRect& cr = iter.rect(); 2140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project this->blitRect(cr.fLeft, cr.fTop, cr.width(), cr.height()); 2150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project iter.next(); 2160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 2170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 21940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 2200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 22140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkNullBlitter::blitH(int x, int y, int width) {} 2220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 22340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkNullBlitter::blitAntiH(int x, int y, const SkAlpha antialias[], 22440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const int16_t runs[]) {} 2250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 22640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkNullBlitter::blitV(int x, int y, int height, SkAlpha alpha) {} 2270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 22840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkNullBlitter::blitRect(int x, int y, int width, int height) {} 2290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 23040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkNullBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {} 2310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 23240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerconst SkBitmap* SkNullBlitter::justAnOpaqueColor(uint32_t* value) { 2330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return NULL; 2340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 23640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 2370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 23840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic int compute_anti_width(const int16_t runs[]) { 2390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int width = 0; 24040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 24140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger for (;;) { 2420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int count = runs[0]; 24340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 2440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(count >= 0); 24540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (count == 0) { 2460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project break; 24740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 2480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project width += count; 2490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project runs += count; 25040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 2510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(width < 20000); 2520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 2530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return width; 2540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 25640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic inline bool y_in_rect(int y, const SkIRect& rect) { 2570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return (unsigned)(y - rect.fTop) < (unsigned)rect.height(); 2580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 26040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic inline bool x_in_rect(int x, const SkIRect& rect) { 2610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return (unsigned)(x - rect.fLeft) < (unsigned)rect.width(); 2620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 26440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkRectClipBlitter::blitH(int left, int y, int width) { 2650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(width > 0); 2660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 26740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (!y_in_rect(y, fClipRect)) { 2680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return; 26940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 2700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int right = left + width; 2720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 27340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (left < fClipRect.fLeft) { 2740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project left = fClipRect.fLeft; 27540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 27640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (right > fClipRect.fRight) { 2770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project right = fClipRect.fRight; 27840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 2790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project width = right - left; 28140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (width > 0) { 2820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fBlitter->blitH(left, y, width); 28340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 2840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 28640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkRectClipBlitter::blitAntiH(int left, int y, const SkAlpha aa[], 28740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const int16_t runs[]) { 28840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (!y_in_rect(y, fClipRect) || left >= fClipRect.fRight) { 2890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return; 29040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 2910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int x0 = left; 2930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int x1 = left + compute_anti_width(runs); 2940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 29540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (x1 <= fClipRect.fLeft) { 2960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return; 29740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 2980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(x0 < x1); 30040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (x0 < fClipRect.fLeft) { 3010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int dx = fClipRect.fLeft - x0; 3020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAlphaRuns::BreakAt((int16_t*)runs, (uint8_t*)aa, dx); 3030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project runs += dx; 3040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project aa += dx; 3050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project x0 = fClipRect.fLeft; 3060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 3070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(x0 < x1 && runs[x1 - x0] == 0); 30940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (x1 > fClipRect.fRight) { 3100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project x1 = fClipRect.fRight; 3110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAlphaRuns::BreakAt((int16_t*)runs, (uint8_t*)aa, x1 - x0); 3120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ((int16_t*)runs)[x1 - x0] = 0; 3130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 3140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(x0 < x1 && runs[x1 - x0] == 0); 3160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(compute_anti_width(runs) == x1 - x0); 3170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fBlitter->blitAntiH(x0, y, aa, runs); 3190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 32140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkRectClipBlitter::blitV(int x, int y, int height, SkAlpha alpha) { 3220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(height > 0); 3230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 32440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (!x_in_rect(x, fClipRect)) { 3250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return; 32640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 3270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int y0 = y; 3290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int y1 = y + height; 3300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 33140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (y0 < fClipRect.fTop) { 3320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project y0 = fClipRect.fTop; 33340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 33440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (y1 > fClipRect.fBottom) { 3350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project y1 = fClipRect.fBottom; 33640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 3370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 33840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (y0 < y1) { 3390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fBlitter->blitV(x, y0, y1 - y0, alpha); 34040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 3410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 34340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkRectClipBlitter::blitRect(int left, int y, int width, int height) { 3440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkIRect r; 3450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project r.set(left, y, left + width, y + height); 34740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (r.intersect(fClipRect)) { 3480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height()); 34940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 3500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkRectClipBlitter::blitAntiRect(int left, int y, int width, int height, 3531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkAlpha leftAlpha, SkAlpha rightAlpha) { 3541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkIRect r; 3551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // The *true* width of the rectangle blitted is width+2: 3571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger r.set(left, y, left + width + 2, y + height); 3581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (r.intersect(fClipRect)) { 3591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (r.fLeft != left) { 3601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(r.fLeft > left); 3611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger leftAlpha = 255; 3621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 3631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (r.fRight != left + width + 2) { 3641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(r.fRight < left + width + 2); 3651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger rightAlpha = 255; 3661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 3671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (255 == leftAlpha && 255 == rightAlpha) { 3681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height()); 3691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else if (1 == r.width()) { 3701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (r.fLeft == left) { 3711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fBlitter->blitV(r.fLeft, r.fTop, r.height(), leftAlpha); 3721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 3731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(r.fLeft == left + width + 1); 3741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fBlitter->blitV(r.fLeft, r.fTop, r.height(), rightAlpha); 3751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 3761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 3771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fBlitter->blitAntiRect(r.fLeft, r.fTop, r.width() - 2, r.height(), 3781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger leftAlpha, rightAlpha); 3791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 3801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 3811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 3821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 38340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkRectClipBlitter::blitMask(const SkMask& mask, const SkIRect& clip) { 3840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(mask.fBounds.contains(clip)); 3850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkIRect r = clip; 3870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 38840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (r.intersect(fClipRect)) { 3890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fBlitter->blitMask(mask, r); 39040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 3910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 39340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerconst SkBitmap* SkRectClipBlitter::justAnOpaqueColor(uint32_t* value) { 3940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return fBlitter->justAnOpaqueColor(value); 3950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 39740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 3980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 39940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkRgnClipBlitter::blitH(int x, int y, int width) { 4000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRegion::Spanerator span(*fRgn, y, x, x + width); 4010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int left, right; 4020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 40340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger while (span.next(&left, &right)) { 4040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(left < right); 4050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fBlitter->blitH(left, y, right - left); 4060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 4070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 4080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 40940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkRgnClipBlitter::blitAntiH(int x, int y, const SkAlpha aa[], 41040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const int16_t runs[]) { 4110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int width = compute_anti_width(runs); 4120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRegion::Spanerator span(*fRgn, y, x, x + width); 4130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int left, right; 4140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDEBUGCODE(const SkIRect& bounds = fRgn->getBounds();) 41540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 4160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int prevRite = x; 41740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger while (span.next(&left, &right)) { 4180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(x <= left); 4190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(left < right); 4200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(left >= bounds.fLeft && right <= bounds.fRight); 42140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 4220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAlphaRuns::Break((int16_t*)runs, (uint8_t*)aa, left - x, right - left); 4230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // now zero before left 42540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (left > prevRite) { 4260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int index = prevRite - x; 4270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ((uint8_t*)aa)[index] = 0; // skip runs after right 4280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ((int16_t*)runs)[index] = SkToS16(left - prevRite); 4290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 43040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 4310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project prevRite = right; 4320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 43340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 43440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (prevRite > x) { 4350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ((int16_t*)runs)[prevRite - x] = 0; 43640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 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 44840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkRgnClipBlitter::blitV(int x, int y, int height, SkAlpha alpha) { 4490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkIRect bounds; 4500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bounds.set(x, y, x + 1, y + height); 4510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRegion::Cliperator iter(*fRgn, bounds); 4530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 45440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger while (!iter.done()) { 4550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkIRect& r = iter.rect(); 4560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(bounds.contains(r)); 4570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fBlitter->blitV(x, r.fTop, r.height(), alpha); 4590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project iter.next(); 4600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 4610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 4620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 46340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkRgnClipBlitter::blitRect(int x, int y, int width, int height) { 4640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkIRect bounds; 4650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bounds.set(x, y, x + width, y + height); 4660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRegion::Cliperator iter(*fRgn, bounds); 4680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 46940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger while (!iter.done()) { 4700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkIRect& r = iter.rect(); 4710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(bounds.contains(r)); 4720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height()); 4740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project iter.next(); 4750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 4760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 4770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkRgnClipBlitter::blitAntiRect(int x, int y, int width, int height, 4791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkAlpha leftAlpha, SkAlpha rightAlpha) { 4801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // The *true* width of the rectangle to blit is width + 2 4811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkIRect bounds; 4821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bounds.set(x, y, x + width + 2, y + height); 4831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkRegion::Cliperator iter(*fRgn, bounds); 4851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger while (!iter.done()) { 4871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkIRect& r = iter.rect(); 4881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(bounds.contains(r)); 4891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(r.fLeft >= x); 4901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(r.fRight <= x + width + 2); 4911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkAlpha effectiveLeftAlpha = (r.fLeft == x) ? leftAlpha : 255; 4931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkAlpha effectiveRightAlpha = (r.fRight == x + width + 2) ? 4941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger rightAlpha : 255; 4951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (255 == effectiveLeftAlpha && 255 == effectiveRightAlpha) { 4971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height()); 4981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else if (1 == r.width()) { 4991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (r.fLeft == x) { 5001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fBlitter->blitV(r.fLeft, r.fTop, r.height(), 5011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger effectiveLeftAlpha); 5021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 5031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(r.fLeft == x + width + 1); 5041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fBlitter->blitV(r.fLeft, r.fTop, r.height(), 5051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger effectiveRightAlpha); 5061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 5071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 5081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fBlitter->blitAntiRect(r.fLeft, r.fTop, r.width() - 2, r.height(), 5091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger effectiveLeftAlpha, effectiveRightAlpha); 5101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 5111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger iter.next(); 5121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 5131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 5141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 51640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkRgnClipBlitter::blitMask(const SkMask& mask, const SkIRect& clip) { 5170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(mask.fBounds.contains(clip)); 5180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 5190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRegion::Cliperator iter(*fRgn, clip); 5200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkIRect& r = iter.rect(); 5210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkBlitter* blitter = fBlitter; 5220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 52340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger while (!iter.done()) { 5240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project blitter->blitMask(mask, r); 5250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project iter.next(); 5260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 5270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 5280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 52940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerconst SkBitmap* SkRgnClipBlitter::justAnOpaqueColor(uint32_t* value) { 5300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return fBlitter->justAnOpaqueColor(value); 5310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 5320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 53340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 5340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 53540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkBlitter* SkBlitterClipper::apply(SkBlitter* blitter, const SkRegion* clip, 53640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const SkIRect* ir) { 53740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (clip) { 5380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkIRect& clipR = clip->getBounds(); 5390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 54040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (clip->isEmpty() || (ir && !SkIRect::Intersects(clipR, *ir))) { 5410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project blitter = &fNullBlitter; 54240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else if (clip->isRect()) { 54340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (ir == NULL || !clipR.contains(*ir)) { 5440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fRectBlitter.init(blitter, clipR); 5450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project blitter = &fRectBlitter; 5460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 54740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 5480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fRgnBlitter.init(blitter, clip); 5490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project blitter = &fRgnBlitter; 5500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 5510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 5520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return blitter; 5530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 5540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 55540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 5560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 5570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkColorShader.h" 5580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkColorPriv.h" 5590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 5600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass Sk3DShader : public SkShader { 5610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic: 56240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger Sk3DShader(SkShader* proxy) : fProxy(proxy) { 56340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(proxy); 5640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fMask = NULL; 5650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 56640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 56740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger virtual ~Sk3DShader() { 56840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fProxy); 5690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 57040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 5710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project void setMask(const SkMask* mask) { fMask = mask; } 5720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 57340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger virtual bool setContext(const SkBitmap& device, const SkPaint& paint, 57440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const SkMatrix& matrix) { 57540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (fProxy) { 5760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return fProxy->setContext(device, paint, matrix); 57740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 5780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPMColor = SkPreMultiplyColor(paint.getColor()); 5790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return this->INHERITED::setContext(device, paint, matrix); 5800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 5810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 58240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 58340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger virtual void shadeSpan(int x, int y, SkPMColor span[], int count) { 58440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (fProxy) { 5850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fProxy->shadeSpan(x, y, span, count); 58640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 5870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 58840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (fMask == NULL) { 58940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (fProxy == NULL) { 5900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_memset32(span, fPMColor, count); 59140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 5920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return; 5930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 5940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 5950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(fMask->fBounds.contains(x, y)); 5960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(fMask->fBounds.contains(x + count - 1, y)); 5970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 5980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project size_t size = fMask->computeImageSize(); 5991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const uint8_t* alpha = fMask->getAddr8(x, y); 6000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const uint8_t* mulp = alpha + size; 6010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const uint8_t* addp = mulp + size; 6020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 60340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (fProxy) { 60440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger for (int i = 0; i < count; i++) { 60540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (alpha[i]) { 6060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkPMColor c = span[i]; 60740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (c) { 6080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned a = SkGetPackedA32(c); 6090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned r = SkGetPackedR32(c); 6100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned g = SkGetPackedG32(c); 6110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned b = SkGetPackedB32(c); 6120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 6130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned mul = SkAlpha255To256(mulp[i]); 6140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned add = addp[i]; 6150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 6160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project r = SkFastMin32(SkAlphaMul(r, mul) + add, a); 6170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project g = SkFastMin32(SkAlphaMul(g, mul) + add, a); 6180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project b = SkFastMin32(SkAlphaMul(b, mul) + add, a); 6190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 6200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project span[i] = SkPackARGB32(a, r, g, b); 6210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 62240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 6230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project span[i] = 0; 62440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 6250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 62640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { // color 6270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned a = SkGetPackedA32(fPMColor); 6280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned r = SkGetPackedR32(fPMColor); 6290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned g = SkGetPackedG32(fPMColor); 6300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned b = SkGetPackedB32(fPMColor); 63140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger for (int i = 0; i < count; i++) { 63240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (alpha[i]) { 6330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned mul = SkAlpha255To256(mulp[i]); 6340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned add = addp[i]; 6350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 6360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project span[i] = SkPackARGB32( a, 63740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkFastMin32(SkAlphaMul(r, mul) + add, a), 63840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkFastMin32(SkAlphaMul(g, mul) + add, a), 63940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkFastMin32(SkAlphaMul(b, mul) + add, a)); 64040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 6410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project span[i] = 0; 64240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 6430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 6440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 6450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 64640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 64740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger virtual void beginSession() { 6480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project this->INHERITED::beginSession(); 64940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (fProxy) { 6500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fProxy->beginSession(); 65140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 6520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 65340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 65440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger virtual void endSession() { 65540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (fProxy) { 6560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fProxy->endSession(); 65740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 6580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project this->INHERITED::endSession(); 6590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 6600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 6610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprotected: 6620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project Sk3DShader(SkFlattenableReadBuffer& buffer) : 66340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger INHERITED(buffer) { 6640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fProxy = static_cast<SkShader*>(buffer.readFlattenable()); 6650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPMColor = buffer.readU32(); 6660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fMask = NULL; 6670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 66840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 66940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger virtual void flatten(SkFlattenableWriteBuffer& buffer) { 6700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project this->INHERITED::flatten(buffer); 6710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project buffer.writeFlattenable(fProxy); 6720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project buffer.write32(fPMColor); 6730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 67440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 67540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger virtual Factory getFactory() { 6760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return CreateProc; 6770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 6780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 6790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate: 68040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { 6810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return SkNEW_ARGS(Sk3DShader, (buffer)); 6820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 6830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 6840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkShader* fProxy; 6850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkPMColor fPMColor; 6860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkMask* fMask; 6870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 6880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project typedef SkShader INHERITED; 6890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}; 6900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 6910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass Sk3DBlitter : public SkBlitter { 6920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic: 6930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project Sk3DBlitter(SkBlitter* proxy, Sk3DShader* shader, void (*killProc)(void*)) 69440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger : fProxy(proxy), f3DShader(shader), fKillProc(killProc) { 6950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project shader->ref(); 6960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 69740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 69840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger virtual ~Sk3DBlitter() { 6990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project f3DShader->unref(); 7000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fKillProc(fProxy); 7010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 7020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 70340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger virtual void blitH(int x, int y, int width) { 7040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fProxy->blitH(x, y, width); 7050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 70640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 70740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger virtual void blitAntiH(int x, int y, const SkAlpha antialias[], 70840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const int16_t runs[]) { 7090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fProxy->blitAntiH(x, y, antialias, runs); 7100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 71140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 71240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger virtual void blitV(int x, int y, int height, SkAlpha alpha) { 7130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fProxy->blitV(x, y, height, alpha); 7140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 71540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 71640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger virtual void blitRect(int x, int y, int width, int height) { 7170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fProxy->blitRect(x, y, width, height); 7180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 71940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 72040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger virtual void blitMask(const SkMask& mask, const SkIRect& clip) { 72140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (mask.fFormat == SkMask::k3D_Format) { 7220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project f3DShader->setMask(&mask); 7230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ((SkMask*)&mask)->fFormat = SkMask::kA8_Format; 7250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fProxy->blitMask(mask, clip); 7260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ((SkMask*)&mask)->fFormat = SkMask::k3D_Format; 7270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project f3DShader->setMask(NULL); 72940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 7300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fProxy->blitMask(mask, clip); 73140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 7320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 73340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 7340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate: 7350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkBlitter* fProxy; 7360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project Sk3DShader* f3DShader; 7370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project void (*fKillProc)(void*); 7380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}; 7390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 74040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 7410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkCoreBlitters.h" 7430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass SkAutoCallProc { 7450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic: 7460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project typedef void (*Proc)(void*); 74740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 7480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoCallProc(void* obj, Proc proc) 74940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger : fObj(obj), fProc(proc) {} 75040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 75140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger ~SkAutoCallProc() { 75240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (fObj && fProc) { 7530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fProc(fObj); 75440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 7550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 75640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 7570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project void* get() const { return fObj; } 75840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 75940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger void* detach() { 7600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project void* obj = fObj; 7610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fObj = NULL; 7620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return obj; 7630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 76440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 7650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate: 7660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project void* fObj; 7670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project Proc fProc; 7680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}; 7690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 77040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic void destroy_blitter(void* blitter) { 7710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ((SkBlitter*)blitter)->~SkBlitter(); 7720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 7730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 77440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic void delete_blitter(void* blitter) { 7750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDELETE((SkBlitter*)blitter); 7760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 7770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 778ab1af391811c7721e755a3893539d51565422eccMike Reedstatic bool just_solid_color(const SkPaint& paint) { 779ab1af391811c7721e755a3893539d51565422eccMike Reed if (paint.getAlpha() == 0xFF && paint.getColorFilter() == NULL) { 780ab1af391811c7721e755a3893539d51565422eccMike Reed SkShader* shader = paint.getShader(); 781ab1af391811c7721e755a3893539d51565422eccMike Reed if (NULL == shader || 782ab1af391811c7721e755a3893539d51565422eccMike Reed (shader->getFlags() & SkShader::kOpaqueAlpha_Flag)) { 783ab1af391811c7721e755a3893539d51565422eccMike Reed return true; 784ab1af391811c7721e755a3893539d51565422eccMike Reed } 785ab1af391811c7721e755a3893539d51565422eccMike Reed } 786ab1af391811c7721e755a3893539d51565422eccMike Reed return false; 787ab1af391811c7721e755a3893539d51565422eccMike Reed} 78840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 789ab1af391811c7721e755a3893539d51565422eccMike Reed/** By analyzing the paint (with an xfermode), we may decide we can take 790ab1af391811c7721e755a3893539d51565422eccMike Reed special action. This enum lists our possible actions 791ab1af391811c7721e755a3893539d51565422eccMike Reed */ 792ab1af391811c7721e755a3893539d51565422eccMike Reedenum XferInterp { 793ab1af391811c7721e755a3893539d51565422eccMike Reed kNormal_XferInterp, // no special interpretation, draw normally 794ab1af391811c7721e755a3893539d51565422eccMike Reed kSrcOver_XferInterp, // draw as if in srcover mode 795ab1af391811c7721e755a3893539d51565422eccMike Reed kSkipDrawing_XferInterp // draw nothing 796ab1af391811c7721e755a3893539d51565422eccMike Reed}; 797ab1af391811c7721e755a3893539d51565422eccMike Reed 798ab1af391811c7721e755a3893539d51565422eccMike Reedstatic XferInterp interpret_xfermode(const SkPaint& paint, SkXfermode* xfer, 799ab1af391811c7721e755a3893539d51565422eccMike Reed SkBitmap::Config deviceConfig) { 80059f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed SkXfermode::Mode mode; 80140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 8021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (SkXfermode::AsMode(xfer, &mode)) { 803ab1af391811c7721e755a3893539d51565422eccMike Reed switch (mode) { 80459f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed case SkXfermode::kSrc_Mode: 805ab1af391811c7721e755a3893539d51565422eccMike Reed if (just_solid_color(paint)) { 806ab1af391811c7721e755a3893539d51565422eccMike Reed return kSrcOver_XferInterp; 807ab1af391811c7721e755a3893539d51565422eccMike Reed } 808ab1af391811c7721e755a3893539d51565422eccMike Reed break; 80959f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed case SkXfermode::kDst_Mode: 810ab1af391811c7721e755a3893539d51565422eccMike Reed return kSkipDrawing_XferInterp; 81159f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed case SkXfermode::kSrcOver_Mode: 812ab1af391811c7721e755a3893539d51565422eccMike Reed return kSrcOver_XferInterp; 81359f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed case SkXfermode::kDstOver_Mode: 814ab1af391811c7721e755a3893539d51565422eccMike Reed if (SkBitmap::kRGB_565_Config == deviceConfig) { 815ab1af391811c7721e755a3893539d51565422eccMike Reed return kSkipDrawing_XferInterp; 816ab1af391811c7721e755a3893539d51565422eccMike Reed } 817ab1af391811c7721e755a3893539d51565422eccMike Reed break; 81859f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed case SkXfermode::kSrcIn_Mode: 819ab1af391811c7721e755a3893539d51565422eccMike Reed if (SkBitmap::kRGB_565_Config == deviceConfig && 820ab1af391811c7721e755a3893539d51565422eccMike Reed just_solid_color(paint)) { 821ab1af391811c7721e755a3893539d51565422eccMike Reed return kSrcOver_XferInterp; 822ab1af391811c7721e755a3893539d51565422eccMike Reed } 823ab1af391811c7721e755a3893539d51565422eccMike Reed break; 82459f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed case SkXfermode::kDstIn_Mode: 825ab1af391811c7721e755a3893539d51565422eccMike Reed if (just_solid_color(paint)) { 826ab1af391811c7721e755a3893539d51565422eccMike Reed return kSkipDrawing_XferInterp; 827ab1af391811c7721e755a3893539d51565422eccMike Reed } 828ab1af391811c7721e755a3893539d51565422eccMike Reed break; 829ab1af391811c7721e755a3893539d51565422eccMike Reed default: 830ab1af391811c7721e755a3893539d51565422eccMike Reed break; 831ab1af391811c7721e755a3893539d51565422eccMike Reed } 832ab1af391811c7721e755a3893539d51565422eccMike Reed } 833ab1af391811c7721e755a3893539d51565422eccMike Reed return kNormal_XferInterp; 834ab1af391811c7721e755a3893539d51565422eccMike Reed} 835ab1af391811c7721e755a3893539d51565422eccMike Reed 8360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkBlitter* SkBlitter::Choose(const SkBitmap& device, 8370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkMatrix& matrix, 83835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger const SkPaint& origPaint, 83940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger void* storage, size_t storageSize) { 8400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(storageSize == 0 || storage != NULL); 8410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 8420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkBlitter* blitter = NULL; 8430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 8440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // which check, in case we're being called by a client with a dummy device 8450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // (e.g. they have a bounder that always aborts the draw) 84640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (SkBitmap::kNo_Config == device.getConfig()) { 8470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SK_PLACEMENT_NEW(blitter, SkNullBlitter, storage, storageSize); 8480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return blitter; 8490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 8500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 85135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkPaint paint(origPaint); 8520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkShader* shader = paint.getShader(); 85335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkColorFilter* cf = paint.getColorFilter(); 85435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkXfermode* mode = paint.getXfermode(); 8550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 8560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project Sk3DShader* shader3D = NULL; 85740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (paint.getMaskFilter() != NULL && 85840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger paint.getMaskFilter()->getFormat() == SkMask::k3D_Format) { 8590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project shader3D = SkNEW_ARGS(Sk3DShader, (shader)); 86035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger paint.setShader(shader3D)->unref(); 8610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project shader = shader3D; 8620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 8630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 864ab1af391811c7721e755a3893539d51565422eccMike Reed if (NULL != mode) { 865ab1af391811c7721e755a3893539d51565422eccMike Reed switch (interpret_xfermode(paint, mode, device.config())) { 866ab1af391811c7721e755a3893539d51565422eccMike Reed case kSrcOver_XferInterp: 867ab1af391811c7721e755a3893539d51565422eccMike Reed mode = NULL; 86835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger paint.setXfermode(NULL); 869ab1af391811c7721e755a3893539d51565422eccMike Reed break; 870ab1af391811c7721e755a3893539d51565422eccMike Reed case kSkipDrawing_XferInterp: 871ab1af391811c7721e755a3893539d51565422eccMike Reed SK_PLACEMENT_NEW(blitter, SkNullBlitter, storage, storageSize); 872ab1af391811c7721e755a3893539d51565422eccMike Reed return blitter; 873ab1af391811c7721e755a3893539d51565422eccMike Reed default: 874ab1af391811c7721e755a3893539d51565422eccMike Reed break; 875ab1af391811c7721e755a3893539d51565422eccMike Reed } 876ab1af391811c7721e755a3893539d51565422eccMike Reed } 877ab1af391811c7721e755a3893539d51565422eccMike Reed 87835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (NULL == shader) { 87935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#ifdef SK_IGNORE_CF_OPTIMIZATION 88035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (mode || cf) { 88135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#else 88235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (mode) { 88335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#endif 88435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger // xfermodes (and filters) require shaders for our current blitters 88535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger shader = SkNEW(SkColorShader); 88635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger paint.setShader(shader)->unref(); 88735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } else if (cf) { 88835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger // if no shader && no xfermode, we just apply the colorfilter to 88935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger // our color and move on. 89035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger paint.setColor(cf->filterColor(paint.getColor())); 89135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger paint.setColorFilter(NULL); 89235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger cf = NULL; 89335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 8940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 89540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 89635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (cf) { 8970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(shader); 89835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger shader = SkNEW_ARGS(SkFilterShader, (shader, cf)); 89935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger paint.setShader(shader)->unref(); 9004663d79a396bd4d45a9140626921c9fbad77fbf8Mike Reed // blitters should ignore the presence/absence of a filter, since 9014663d79a396bd4d45a9140626921c9fbad77fbf8Mike Reed // if there is one, the shader will take care of it. 9020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 90340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 9043026a9ec59b285412941d278a570e382088f8adaMike Reed if (shader && !shader->setContext(device, paint, matrix)) { 9053026a9ec59b285412941d278a570e382088f8adaMike Reed return SkNEW(SkNullBlitter); 9060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 9070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project switch (device.getConfig()) { 90940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger case SkBitmap::kA1_Config: 91040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SK_PLACEMENT_NEW_ARGS(blitter, SkA1_Blitter, 91140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger storage, storageSize, (device, paint)); 91240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger break; 91340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 91440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger case SkBitmap::kA8_Config: 91540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (shader) { 91640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SK_PLACEMENT_NEW_ARGS(blitter, SkA8_Shader_Blitter, 91740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger storage, storageSize, (device, paint)); 91840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 91940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SK_PLACEMENT_NEW_ARGS(blitter, SkA8_Blitter, 92040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger storage, storageSize, (device, paint)); 92140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 92240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger break; 92340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 92440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger case SkBitmap::kARGB_4444_Config: 92540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger blitter = SkBlitter_ChooseD4444(device, paint, storage, storageSize); 92640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger break; 92740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 92840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger case SkBitmap::kRGB_565_Config: 92940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger blitter = SkBlitter_ChooseD565(device, paint, storage, storageSize); 93040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger break; 93140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 93240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger case SkBitmap::kARGB_8888_Config: 93340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (shader) { 93440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SK_PLACEMENT_NEW_ARGS(blitter, SkARGB32_Shader_Blitter, 93540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger storage, storageSize, (device, paint)); 93640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else if (paint.getColor() == SK_ColorBLACK) { 93740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SK_PLACEMENT_NEW_ARGS(blitter, SkARGB32_Black_Blitter, 93840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger storage, storageSize, (device, paint)); 93940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else if (paint.getAlpha() == 0xFF) { 94040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SK_PLACEMENT_NEW_ARGS(blitter, SkARGB32_Opaque_Blitter, 94140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger storage, storageSize, (device, paint)); 94240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 94340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SK_PLACEMENT_NEW_ARGS(blitter, SkARGB32_Blitter, 94440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger storage, storageSize, (device, paint)); 94540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 94640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger break; 94740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 94840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger default: 9491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDEBUGFAIL("unsupported device config"); 95040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SK_PLACEMENT_NEW(blitter, SkNullBlitter, storage, storageSize); 95140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger break; 9520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 9530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 95440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (shader3D) { 9550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project void (*proc)(void*) = ((void*)storage == (void*)blitter) ? destroy_blitter : delete_blitter; 9560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoCallProc tmp(blitter, proc); 9570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project blitter = SkNEW_ARGS(Sk3DBlitter, (blitter, shader3D, proc)); 9590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project (void)tmp.detach(); 9600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 9610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return blitter; 9620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 9630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 96440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 9650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectconst uint16_t gMask_0F0F = 0xF0F; 9670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectconst uint32_t gMask_00FF00FF = 0xFF00FF; 9680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 96940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 9700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkShaderBlitter::SkShaderBlitter(const SkBitmap& device, const SkPaint& paint) 972f294d10d594ac335ea3bd09caec89004d41edc5cMike Reed : INHERITED(device) { 9730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fShader = paint.getShader(); 9740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(fShader); 9750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fShader->ref(); 9770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fShader->beginSession(); 978f294d10d594ac335ea3bd09caec89004d41edc5cMike Reed fShaderFlags = fShader->getFlags(); 9790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 9800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 981f294d10d594ac335ea3bd09caec89004d41edc5cMike ReedSkShaderBlitter::~SkShaderBlitter() { 9820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fShader->endSession(); 9830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fShader->unref(); 9840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 9850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 986