1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */ 7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 883e939bcb79790f5ae3b28c398fbcf034675a6e5Herb Derby#include "SkArenaAlloc.h" 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkBlitter.h" 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkAntiRun.h" 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColor.h" 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorFilter.h" 138b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkReadBuffer.h" 148b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkWriteBuffer.h" 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkMask.h" 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkMaskFilter.h" 17a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org#include "SkString.h" 18458849004892c05fa1dcbcf6d355dfcce028d77areed@google.com#include "SkTLazy.h" 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkUtils.h" 20a681433d42323d6d48e1aa3cb2ef97fb9d958d93halcanary#include "SkXfermodeInterpretation.h" 218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22395eabeb0e72334c45324874c6e009b54634df21reed// define this for testing srgb blits 23a34be68a7eff0ae475b194f8a29975460cf3e456reed//#define SK_FORCE_PM4f_FOR_L32_BLITS 24395eabeb0e72334c45324874c6e009b54634df21reed 25845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.comSkBlitter::~SkBlitter() {} 268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27ea033606a06d05d2d42aa7118409fee798e53167reed@google.combool SkBlitter::isNullBlitter() const { return false; } 28ea033606a06d05d2d42aa7118409fee798e53167reed@google.com 2941e010cb901c0da9066c4df562030808c9ccd7f8reedconst SkPixmap* SkBlitter::justAnOpaqueColor(uint32_t* value) { 3096fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 337df9e4a87d84415391c167ea54cd389d4b423c2dherb/* 3482065d667f64e232bcde2ad849756a6096fcbe6freed@google.comvoid SkBlitter::blitH(int x, int y, int width) { 350c00f21fee3f5cfa3aa7e5d46ff94cb8cf340451tomhudson@google.com SkDEBUGFAIL("unimplemented"); 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 387df9e4a87d84415391c167ea54cd389d4b423c2dherb 3982065d667f64e232bcde2ad849756a6096fcbe6freed@google.comvoid SkBlitter::blitAntiH(int x, int y, const SkAlpha antialias[], 4082065d667f64e232bcde2ad849756a6096fcbe6freed@google.com const int16_t runs[]) { 410c00f21fee3f5cfa3aa7e5d46ff94cb8cf340451tomhudson@google.com SkDEBUGFAIL("unimplemented"); 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 437df9e4a87d84415391c167ea54cd389d4b423c2dherb */ 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4582065d667f64e232bcde2ad849756a6096fcbe6freed@google.comvoid SkBlitter::blitV(int x, int y, int height, SkAlpha alpha) { 4682065d667f64e232bcde2ad849756a6096fcbe6freed@google.com if (alpha == 255) { 478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->blitRect(x, y, 1, height); 4882065d667f64e232bcde2ad849756a6096fcbe6freed@google.com } else { 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int16_t runs[2]; 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com runs[0] = 1; 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com runs[1] = 0; 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com while (--height >= 0) { 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->blitAntiH(x, y++, &alpha, runs); 5582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com } 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5982065d667f64e232bcde2ad849756a6096fcbe6freed@google.comvoid SkBlitter::blitRect(int x, int y, int width, int height) { 60a31ac73b8e261f02c4bd6ae1d622c4bd00226b80tomhudson@google.com SkASSERT(width > 0); 6182065d667f64e232bcde2ad849756a6096fcbe6freed@google.com while (--height >= 0) { 628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->blitH(x, y++, width); 6382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com } 648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6638911a7cb53474575e1cd1cb545902b50ee00889liyuqian/// Default implementation doesn't check for easy optimizations 6738911a7cb53474575e1cd1cb545902b50ee00889liyuqian/// such as alpha == 255; also uses blitV(), which some subclasses 6849eac192faa35159752525b23345563252721c64tomhudson@google.com/// may not support. 6949eac192faa35159752525b23345563252721c64tomhudson@google.comvoid SkBlitter::blitAntiRect(int x, int y, int width, int height, 7049eac192faa35159752525b23345563252721c64tomhudson@google.com SkAlpha leftAlpha, SkAlpha rightAlpha) { 7138911a7cb53474575e1cd1cb545902b50ee00889liyuqian if (leftAlpha > 0) { // we may send in x = -1 with leftAlpha = 0 7238911a7cb53474575e1cd1cb545902b50ee00889liyuqian this->blitV(x, y, height, leftAlpha); 7338911a7cb53474575e1cd1cb545902b50ee00889liyuqian } 7438911a7cb53474575e1cd1cb545902b50ee00889liyuqian x++; 75a31ac73b8e261f02c4bd6ae1d622c4bd00226b80tomhudson@google.com if (width > 0) { 764714359ec091b34a4f88eb9708868a58a22177d3tomhudson@google.com this->blitRect(x, y, width, height); 774714359ec091b34a4f88eb9708868a58a22177d3tomhudson@google.com x += width; 784714359ec091b34a4f88eb9708868a58a22177d3tomhudson@google.com } 7938911a7cb53474575e1cd1cb545902b50ee00889liyuqian if (rightAlpha > 0) { 8038911a7cb53474575e1cd1cb545902b50ee00889liyuqian this->blitV(x, y, height, rightAlpha); 8138911a7cb53474575e1cd1cb545902b50ee00889liyuqian } 8249eac192faa35159752525b23345563252721c64tomhudson@google.com} 8349eac192faa35159752525b23345563252721c64tomhudson@google.com 848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8682065d667f64e232bcde2ad849756a6096fcbe6freed@google.comstatic inline void bits_to_runs(SkBlitter* blitter, int x, int y, 8782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com const uint8_t bits[], 885520dede2968372e79c572e37b7f325524ee0739herb uint8_t left_mask, ptrdiff_t rowBytes, 895520dede2968372e79c572e37b7f325524ee0739herb uint8_t right_mask) { 908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int inFill = 0; 918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int pos = 0; 928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com while (--rowBytes >= 0) { 945520dede2968372e79c572e37b7f325524ee0739herb uint8_t b = *bits++ & left_mask; 9582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com if (rowBytes == 0) { 968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com b &= right_mask; 9782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com } 988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 995520dede2968372e79c572e37b7f325524ee0739herb for (uint8_t test = 0x80U; test != 0; test >>= 1) { 10082065d667f64e232bcde2ad849756a6096fcbe6freed@google.com if (b & test) { 10182065d667f64e232bcde2ad849756a6096fcbe6freed@google.com if (!inFill) { 1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pos = x; 1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inFill = true; 1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com } else { 10682065d667f64e232bcde2ad849756a6096fcbe6freed@google.com if (inFill) { 1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com blitter->blitH(pos, y, x - pos); 1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inFill = false; 1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x += 1; 1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1135520dede2968372e79c572e37b7f325524ee0739herb left_mask = 0xFFU; 1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // final cleanup 11782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com if (inFill) { 1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com blitter->blitH(pos, y, x - pos); 11982065d667f64e232bcde2ad849756a6096fcbe6freed@google.com } 1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1225520dede2968372e79c572e37b7f325524ee0739herb// maskBitCount is the number of 1's to place in the mask. It must be in the range between 1 and 8. 1235520dede2968372e79c572e37b7f325524ee0739herbstatic uint8_t generate_right_mask(int maskBitCount) { 1245520dede2968372e79c572e37b7f325524ee0739herb return static_cast<uint8_t>(0xFF00U >> maskBitCount); 1255520dede2968372e79c572e37b7f325524ee0739herb} 1265520dede2968372e79c572e37b7f325524ee0739herb 12782065d667f64e232bcde2ad849756a6096fcbe6freed@google.comvoid SkBlitter::blitMask(const SkMask& mask, const SkIRect& clip) { 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(mask.fBounds.contains(clip)); 1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 130d96e7e503fd24825a6717d58e90a97f95e8ebbc6reed if (mask.fFormat == SkMask::kLCD16_Format) { 131d96e7e503fd24825a6717d58e90a97f95e8ebbc6reed return; // needs to be handled by subclass 132d96e7e503fd24825a6717d58e90a97f95e8ebbc6reed } 133d96e7e503fd24825a6717d58e90a97f95e8ebbc6reed 13482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com if (mask.fFormat == SkMask::kBW_Format) { 1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int cx = clip.fLeft; 1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int cy = clip.fTop; 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int maskLeft = mask.fBounds.fLeft; 1385520dede2968372e79c572e37b7f325524ee0739herb int maskRowBytes = mask.fRowBytes; 1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int height = clip.height(); 1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint8_t* bits = mask.getAddr1(cx, cy); 1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1435520dede2968372e79c572e37b7f325524ee0739herb SkDEBUGCODE(const uint8_t* endOfImage = 1445520dede2968372e79c572e37b7f325524ee0739herb mask.fImage + (mask.fBounds.height() - 1) * maskRowBytes 1455520dede2968372e79c572e37b7f325524ee0739herb + ((mask.fBounds.width() + 7) >> 3)); 1465520dede2968372e79c572e37b7f325524ee0739herb 14782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com if (cx == maskLeft && clip.fRight == mask.fBounds.fRight) { 14882065d667f64e232bcde2ad849756a6096fcbe6freed@google.com while (--height >= 0) { 1495520dede2968372e79c572e37b7f325524ee0739herb int affectedRightBit = mask.fBounds.width() - 1; 1505520dede2968372e79c572e37b7f325524ee0739herb ptrdiff_t rowBytes = (affectedRightBit >> 3) + 1; 1515520dede2968372e79c572e37b7f325524ee0739herb SkASSERT(bits + rowBytes <= endOfImage); 1525520dede2968372e79c572e37b7f325524ee0739herb U8CPU rightMask = generate_right_mask((affectedRightBit & 7) + 1); 1535520dede2968372e79c572e37b7f325524ee0739herb bits_to_runs(this, cx, cy, bits, 0xFF, rowBytes, rightMask); 1545520dede2968372e79c572e37b7f325524ee0739herb bits += maskRowBytes; 1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com cy += 1; 1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 15782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com } else { 1583be72b0413ebc7cb1133e704169e3d543830d8e7herb // Bits is calculated as the offset into the mask at the point {cx, cy} therefore, all 1595520dede2968372e79c572e37b7f325524ee0739herb // addressing into the bit mask is relative to that point. Since this is an address 1605520dede2968372e79c572e37b7f325524ee0739herb // calculated from a arbitrary bit in that byte, calculate the left most bit. 1615520dede2968372e79c572e37b7f325524ee0739herb int bitsLeft = cx - ((cx - maskLeft) & 7); 1625520dede2968372e79c572e37b7f325524ee0739herb 1635520dede2968372e79c572e37b7f325524ee0739herb // Everything is relative to the bitsLeft. 1645520dede2968372e79c572e37b7f325524ee0739herb int leftEdge = cx - bitsLeft; 1655520dede2968372e79c572e37b7f325524ee0739herb SkASSERT(leftEdge >= 0); 1665520dede2968372e79c572e37b7f325524ee0739herb int rightEdge = clip.fRight - bitsLeft; 1675520dede2968372e79c572e37b7f325524ee0739herb SkASSERT(rightEdge > leftEdge); 1685520dede2968372e79c572e37b7f325524ee0739herb 1695520dede2968372e79c572e37b7f325524ee0739herb // Calculate left byte and mask 1705520dede2968372e79c572e37b7f325524ee0739herb const uint8_t* leftByte = bits; 1715520dede2968372e79c572e37b7f325524ee0739herb U8CPU leftMask = 0xFFU >> (leftEdge & 7); 1725520dede2968372e79c572e37b7f325524ee0739herb 1735520dede2968372e79c572e37b7f325524ee0739herb // Calculate right byte and mask 1745520dede2968372e79c572e37b7f325524ee0739herb int affectedRightBit = rightEdge - 1; 1755520dede2968372e79c572e37b7f325524ee0739herb const uint8_t* rightByte = bits + (affectedRightBit >> 3); 1765520dede2968372e79c572e37b7f325524ee0739herb U8CPU rightMask = generate_right_mask((affectedRightBit & 7) + 1); 1775520dede2968372e79c572e37b7f325524ee0739herb 1785520dede2968372e79c572e37b7f325524ee0739herb // leftByte and rightByte are byte locations therefore, to get a count of bytes the 1795520dede2968372e79c572e37b7f325524ee0739herb // code must add one. 1805520dede2968372e79c572e37b7f325524ee0739herb ptrdiff_t rowBytes = rightByte - leftByte + 1; 1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1825520dede2968372e79c572e37b7f325524ee0739herb while (--height >= 0) { 1835520dede2968372e79c572e37b7f325524ee0739herb SkASSERT(bits + rowBytes <= endOfImage); 1845520dede2968372e79c572e37b7f325524ee0739herb bits_to_runs(this, bitsLeft, cy, bits, leftMask, rowBytes, rightMask); 1855520dede2968372e79c572e37b7f325524ee0739herb bits += maskRowBytes; 1865520dede2968372e79c572e37b7f325524ee0739herb cy += 1; 1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18982065d667f64e232bcde2ad849756a6096fcbe6freed@google.com } else { 1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int width = clip.width(); 1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAutoSTMalloc<64, int16_t> runStorage(width + 1); 1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int16_t* runs = runStorage.get(); 1937989186dab6bc2f1c1927daf91bddd32b7fd8d0creed@google.com const uint8_t* aa = mask.getAddr8(clip.fLeft, clip.fTop); 1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_memset16((uint16_t*)runs, 1, width); 1968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com runs[width] = 0; 1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int height = clip.height(); 1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int y = clip.fTop; 20082065d667f64e232bcde2ad849756a6096fcbe6freed@google.com while (--height >= 0) { 2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->blitAntiH(clip.fLeft, y, aa, runs); 2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com aa += mask.fRowBytes; 2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com y += 1; 2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////// these guys are not virtual, just a helpers 2098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkBlitter::blitMaskRegion(const SkMask& mask, const SkRegion& clip) { 2118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (clip.quickReject(mask.fBounds)) { 2128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 2138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 21482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 2158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRegion::Cliperator clipper(clip, mask.fBounds); 21682065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 2178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (!clipper.done()) { 2188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkIRect& cr = clipper.rect(); 2198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->blitMask(mask, cr); 2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com clipper.next(); 2218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkBlitter::blitRectRegion(const SkIRect& rect, const SkRegion& clip) { 2258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRegion::Cliperator clipper(clip, rect); 22682065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 2278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (!clipper.done()) { 2288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkIRect& cr = clipper.rect(); 2298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->blitRect(cr.fLeft, cr.fTop, cr.width(), cr.height()); 2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com clipper.next(); 2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkBlitter::blitRegion(const SkRegion& clip) { 2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRegion::Iterator iter(clip); 23682065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (!iter.done()) { 2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkIRect& cr = iter.rect(); 2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->blitRect(cr.fLeft, cr.fTop, cr.width(), cr.height()); 2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.next(); 2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com/////////////////////////////////////////////////////////////////////////////// 2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24682065d667f64e232bcde2ad849756a6096fcbe6freed@google.comvoid SkNullBlitter::blitH(int x, int y, int width) {} 2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24882065d667f64e232bcde2ad849756a6096fcbe6freed@google.comvoid SkNullBlitter::blitAntiH(int x, int y, const SkAlpha antialias[], 24982065d667f64e232bcde2ad849756a6096fcbe6freed@google.com const int16_t runs[]) {} 2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25182065d667f64e232bcde2ad849756a6096fcbe6freed@google.comvoid SkNullBlitter::blitV(int x, int y, int height, SkAlpha alpha) {} 2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25382065d667f64e232bcde2ad849756a6096fcbe6freed@google.comvoid SkNullBlitter::blitRect(int x, int y, int width, int height) {} 2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25582065d667f64e232bcde2ad849756a6096fcbe6freed@google.comvoid SkNullBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {} 2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25741e010cb901c0da9066c4df562030808c9ccd7f8reedconst SkPixmap* SkNullBlitter::justAnOpaqueColor(uint32_t* value) { 25896fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 261ea033606a06d05d2d42aa7118409fee798e53167reed@google.combool SkNullBlitter::isNullBlitter() const { return true; } 262ea033606a06d05d2d42aa7118409fee798e53167reed@google.com 26382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com/////////////////////////////////////////////////////////////////////////////// 2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 26582065d667f64e232bcde2ad849756a6096fcbe6freed@google.comstatic int compute_anti_width(const int16_t runs[]) { 2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int width = 0; 26782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 26882065d667f64e232bcde2ad849756a6096fcbe6freed@google.com for (;;) { 2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int count = runs[0]; 27082065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count >= 0); 27282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com if (count == 0) { 2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 27482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com } 2758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com width += count; 2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com runs += count; 2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return width; 2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28182065d667f64e232bcde2ad849756a6096fcbe6freed@google.comstatic inline bool y_in_rect(int y, const SkIRect& rect) { 2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (unsigned)(y - rect.fTop) < (unsigned)rect.height(); 2838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28582065d667f64e232bcde2ad849756a6096fcbe6freed@google.comstatic inline bool x_in_rect(int x, const SkIRect& rect) { 2868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (unsigned)(x - rect.fLeft) < (unsigned)rect.width(); 2878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28982065d667f64e232bcde2ad849756a6096fcbe6freed@google.comvoid SkRectClipBlitter::blitH(int left, int y, int width) { 2908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(width > 0); 2918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com if (!y_in_rect(y, fClipRect)) { 2938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 29482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com } 2958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int right = left + width; 2978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29882065d667f64e232bcde2ad849756a6096fcbe6freed@google.com if (left < fClipRect.fLeft) { 2998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com left = fClipRect.fLeft; 30082065d667f64e232bcde2ad849756a6096fcbe6freed@google.com } 30182065d667f64e232bcde2ad849756a6096fcbe6freed@google.com if (right > fClipRect.fRight) { 3028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com right = fClipRect.fRight; 30382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com } 3048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com width = right - left; 30682065d667f64e232bcde2ad849756a6096fcbe6freed@google.com if (width > 0) { 3078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBlitter->blitH(left, y, width); 30882065d667f64e232bcde2ad849756a6096fcbe6freed@google.com } 3098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 31182065d667f64e232bcde2ad849756a6096fcbe6freed@google.comvoid SkRectClipBlitter::blitAntiH(int left, int y, const SkAlpha aa[], 31282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com const int16_t runs[]) { 31382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com if (!y_in_rect(y, fClipRect) || left >= fClipRect.fRight) { 3148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 31582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com } 3168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int x0 = left; 3188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int x1 = left + compute_anti_width(runs); 3198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 32082065d667f64e232bcde2ad849756a6096fcbe6freed@google.com if (x1 <= fClipRect.fLeft) { 3218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 32282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com } 3238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(x0 < x1); 32582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com if (x0 < fClipRect.fLeft) { 3268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int dx = fClipRect.fLeft - x0; 3278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAlphaRuns::BreakAt((int16_t*)runs, (uint8_t*)aa, dx); 3288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com runs += dx; 3298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com aa += dx; 3308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x0 = fClipRect.fLeft; 3318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(x0 < x1 && runs[x1 - x0] == 0); 33482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com if (x1 > fClipRect.fRight) { 3358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x1 = fClipRect.fRight; 3368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAlphaRuns::BreakAt((int16_t*)runs, (uint8_t*)aa, x1 - x0); 3378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ((int16_t*)runs)[x1 - x0] = 0; 3388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(x0 < x1 && runs[x1 - x0] == 0); 3418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(compute_anti_width(runs) == x1 - x0); 3428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBlitter->blitAntiH(x0, y, aa, runs); 3448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 34682065d667f64e232bcde2ad849756a6096fcbe6freed@google.comvoid SkRectClipBlitter::blitV(int x, int y, int height, SkAlpha alpha) { 3478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(height > 0); 3488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 34982065d667f64e232bcde2ad849756a6096fcbe6freed@google.com if (!x_in_rect(x, fClipRect)) { 3508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 35182065d667f64e232bcde2ad849756a6096fcbe6freed@google.com } 3528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int y0 = y; 3548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int y1 = y + height; 3558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 35682065d667f64e232bcde2ad849756a6096fcbe6freed@google.com if (y0 < fClipRect.fTop) { 3578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com y0 = fClipRect.fTop; 35882065d667f64e232bcde2ad849756a6096fcbe6freed@google.com } 35982065d667f64e232bcde2ad849756a6096fcbe6freed@google.com if (y1 > fClipRect.fBottom) { 3608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com y1 = fClipRect.fBottom; 36182065d667f64e232bcde2ad849756a6096fcbe6freed@google.com } 3628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 36382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com if (y0 < y1) { 3648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBlitter->blitV(x, y0, y1 - y0, alpha); 36582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com } 3668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 36882065d667f64e232bcde2ad849756a6096fcbe6freed@google.comvoid SkRectClipBlitter::blitRect(int left, int y, int width, int height) { 3698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIRect r; 3708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.set(left, y, left + width, y + height); 37282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com if (r.intersect(fClipRect)) { 3738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height()); 37482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com } 3758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 37749eac192faa35159752525b23345563252721c64tomhudson@google.comvoid SkRectClipBlitter::blitAntiRect(int left, int y, int width, int height, 37849eac192faa35159752525b23345563252721c64tomhudson@google.com SkAlpha leftAlpha, SkAlpha rightAlpha) { 37949eac192faa35159752525b23345563252721c64tomhudson@google.com SkIRect r; 38049eac192faa35159752525b23345563252721c64tomhudson@google.com 38149eac192faa35159752525b23345563252721c64tomhudson@google.com // The *true* width of the rectangle blitted is width+2: 38249eac192faa35159752525b23345563252721c64tomhudson@google.com r.set(left, y, left + width + 2, y + height); 38349eac192faa35159752525b23345563252721c64tomhudson@google.com if (r.intersect(fClipRect)) { 38449eac192faa35159752525b23345563252721c64tomhudson@google.com if (r.fLeft != left) { 38549eac192faa35159752525b23345563252721c64tomhudson@google.com SkASSERT(r.fLeft > left); 38649eac192faa35159752525b23345563252721c64tomhudson@google.com leftAlpha = 255; 38749eac192faa35159752525b23345563252721c64tomhudson@google.com } 38849eac192faa35159752525b23345563252721c64tomhudson@google.com if (r.fRight != left + width + 2) { 38949eac192faa35159752525b23345563252721c64tomhudson@google.com SkASSERT(r.fRight < left + width + 2); 39049eac192faa35159752525b23345563252721c64tomhudson@google.com rightAlpha = 255; 39149eac192faa35159752525b23345563252721c64tomhudson@google.com } 39249eac192faa35159752525b23345563252721c64tomhudson@google.com if (255 == leftAlpha && 255 == rightAlpha) { 39349eac192faa35159752525b23345563252721c64tomhudson@google.com fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height()); 39449eac192faa35159752525b23345563252721c64tomhudson@google.com } else if (1 == r.width()) { 39549eac192faa35159752525b23345563252721c64tomhudson@google.com if (r.fLeft == left) { 39649eac192faa35159752525b23345563252721c64tomhudson@google.com fBlitter->blitV(r.fLeft, r.fTop, r.height(), leftAlpha); 39749eac192faa35159752525b23345563252721c64tomhudson@google.com } else { 39849eac192faa35159752525b23345563252721c64tomhudson@google.com SkASSERT(r.fLeft == left + width + 1); 39949eac192faa35159752525b23345563252721c64tomhudson@google.com fBlitter->blitV(r.fLeft, r.fTop, r.height(), rightAlpha); 40049eac192faa35159752525b23345563252721c64tomhudson@google.com } 40149eac192faa35159752525b23345563252721c64tomhudson@google.com } else { 40249eac192faa35159752525b23345563252721c64tomhudson@google.com fBlitter->blitAntiRect(r.fLeft, r.fTop, r.width() - 2, r.height(), 40349eac192faa35159752525b23345563252721c64tomhudson@google.com leftAlpha, rightAlpha); 40449eac192faa35159752525b23345563252721c64tomhudson@google.com } 40549eac192faa35159752525b23345563252721c64tomhudson@google.com } 40649eac192faa35159752525b23345563252721c64tomhudson@google.com} 40749eac192faa35159752525b23345563252721c64tomhudson@google.com 40882065d667f64e232bcde2ad849756a6096fcbe6freed@google.comvoid SkRectClipBlitter::blitMask(const SkMask& mask, const SkIRect& clip) { 4098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(mask.fBounds.contains(clip)); 4108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIRect r = clip; 4128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 41382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com if (r.intersect(fClipRect)) { 4148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBlitter->blitMask(mask, r); 41582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com } 4168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 41841e010cb901c0da9066c4df562030808c9ccd7f8reedconst SkPixmap* SkRectClipBlitter::justAnOpaqueColor(uint32_t* value) { 4198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fBlitter->justAnOpaqueColor(value); 4208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 42282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com/////////////////////////////////////////////////////////////////////////////// 4238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 42482065d667f64e232bcde2ad849756a6096fcbe6freed@google.comvoid SkRgnClipBlitter::blitH(int x, int y, int width) { 4258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRegion::Spanerator span(*fRgn, y, x, x + width); 4268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int left, right; 4278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 42882065d667f64e232bcde2ad849756a6096fcbe6freed@google.com while (span.next(&left, &right)) { 4298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(left < right); 4308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBlitter->blitH(left, y, right - left); 4318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 43482065d667f64e232bcde2ad849756a6096fcbe6freed@google.comvoid SkRgnClipBlitter::blitAntiH(int x, int y, const SkAlpha aa[], 43582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com const int16_t runs[]) { 4368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int width = compute_anti_width(runs); 4378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRegion::Spanerator span(*fRgn, y, x, x + width); 4388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int left, right; 4398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(const SkIRect& bounds = fRgn->getBounds();) 44082065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 4418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int prevRite = x; 44282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com while (span.next(&left, &right)) { 4438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(x <= left); 4448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(left < right); 4458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(left >= bounds.fLeft && right <= bounds.fRight); 44682065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 4478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAlphaRuns::Break((int16_t*)runs, (uint8_t*)aa, left - x, right - left); 4488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now zero before left 45082065d667f64e232bcde2ad849756a6096fcbe6freed@google.com if (left > prevRite) { 4518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int index = prevRite - x; 4528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ((uint8_t*)aa)[index] = 0; // skip runs after right 4538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ((int16_t*)runs)[index] = SkToS16(left - prevRite); 4548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 45582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 4568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com prevRite = right; 4578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 45882065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 45982065d667f64e232bcde2ad849756a6096fcbe6freed@google.com if (prevRite > x) { 4608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ((int16_t*)runs)[prevRite - x] = 0; 46182065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 4628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (x < 0) { 4638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int skip = runs[0]; 4648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(skip >= -x); 4658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com aa += skip; 4668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com runs += skip; 4678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x += skip; 4688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBlitter->blitAntiH(x, y, aa, runs); 4708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 47382065d667f64e232bcde2ad849756a6096fcbe6freed@google.comvoid SkRgnClipBlitter::blitV(int x, int y, int height, SkAlpha alpha) { 4748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIRect bounds; 4758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bounds.set(x, y, x + 1, y + height); 4768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRegion::Cliperator iter(*fRgn, bounds); 4788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 47982065d667f64e232bcde2ad849756a6096fcbe6freed@google.com while (!iter.done()) { 4808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkIRect& r = iter.rect(); 4818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(bounds.contains(r)); 4828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBlitter->blitV(x, r.fTop, r.height(), alpha); 4848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.next(); 4858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 48882065d667f64e232bcde2ad849756a6096fcbe6freed@google.comvoid SkRgnClipBlitter::blitRect(int x, int y, int width, int height) { 4898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIRect bounds; 4908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bounds.set(x, y, x + width, y + height); 4918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRegion::Cliperator iter(*fRgn, bounds); 4938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 49482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com while (!iter.done()) { 4958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkIRect& r = iter.rect(); 4968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(bounds.contains(r)); 4978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height()); 4998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.next(); 5008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 50349eac192faa35159752525b23345563252721c64tomhudson@google.comvoid SkRgnClipBlitter::blitAntiRect(int x, int y, int width, int height, 50449eac192faa35159752525b23345563252721c64tomhudson@google.com SkAlpha leftAlpha, SkAlpha rightAlpha) { 50549eac192faa35159752525b23345563252721c64tomhudson@google.com // The *true* width of the rectangle to blit is width + 2 50649eac192faa35159752525b23345563252721c64tomhudson@google.com SkIRect bounds; 50749eac192faa35159752525b23345563252721c64tomhudson@google.com bounds.set(x, y, x + width + 2, y + height); 50849eac192faa35159752525b23345563252721c64tomhudson@google.com 50949eac192faa35159752525b23345563252721c64tomhudson@google.com SkRegion::Cliperator iter(*fRgn, bounds); 51049eac192faa35159752525b23345563252721c64tomhudson@google.com 51149eac192faa35159752525b23345563252721c64tomhudson@google.com while (!iter.done()) { 51249eac192faa35159752525b23345563252721c64tomhudson@google.com const SkIRect& r = iter.rect(); 51349eac192faa35159752525b23345563252721c64tomhudson@google.com SkASSERT(bounds.contains(r)); 51449eac192faa35159752525b23345563252721c64tomhudson@google.com SkASSERT(r.fLeft >= x); 51531bab3934c773c2bd4c1e5e9ba8eb87c1c623b09tomhudson@google.com SkASSERT(r.fRight <= x + width + 2); 51649eac192faa35159752525b23345563252721c64tomhudson@google.com 51749eac192faa35159752525b23345563252721c64tomhudson@google.com SkAlpha effectiveLeftAlpha = (r.fLeft == x) ? leftAlpha : 255; 51849eac192faa35159752525b23345563252721c64tomhudson@google.com SkAlpha effectiveRightAlpha = (r.fRight == x + width + 2) ? 51949eac192faa35159752525b23345563252721c64tomhudson@google.com rightAlpha : 255; 52049eac192faa35159752525b23345563252721c64tomhudson@google.com 52149eac192faa35159752525b23345563252721c64tomhudson@google.com if (255 == effectiveLeftAlpha && 255 == effectiveRightAlpha) { 52249eac192faa35159752525b23345563252721c64tomhudson@google.com fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height()); 52349eac192faa35159752525b23345563252721c64tomhudson@google.com } else if (1 == r.width()) { 52449eac192faa35159752525b23345563252721c64tomhudson@google.com if (r.fLeft == x) { 525fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com fBlitter->blitV(r.fLeft, r.fTop, r.height(), 52649eac192faa35159752525b23345563252721c64tomhudson@google.com effectiveLeftAlpha); 52749eac192faa35159752525b23345563252721c64tomhudson@google.com } else { 52849eac192faa35159752525b23345563252721c64tomhudson@google.com SkASSERT(r.fLeft == x + width + 1); 52949eac192faa35159752525b23345563252721c64tomhudson@google.com fBlitter->blitV(r.fLeft, r.fTop, r.height(), 53049eac192faa35159752525b23345563252721c64tomhudson@google.com effectiveRightAlpha); 53149eac192faa35159752525b23345563252721c64tomhudson@google.com } 53249eac192faa35159752525b23345563252721c64tomhudson@google.com } else { 53349eac192faa35159752525b23345563252721c64tomhudson@google.com fBlitter->blitAntiRect(r.fLeft, r.fTop, r.width() - 2, r.height(), 53449eac192faa35159752525b23345563252721c64tomhudson@google.com effectiveLeftAlpha, effectiveRightAlpha); 53549eac192faa35159752525b23345563252721c64tomhudson@google.com } 53649eac192faa35159752525b23345563252721c64tomhudson@google.com iter.next(); 53749eac192faa35159752525b23345563252721c64tomhudson@google.com } 53849eac192faa35159752525b23345563252721c64tomhudson@google.com} 53949eac192faa35159752525b23345563252721c64tomhudson@google.com 54049eac192faa35159752525b23345563252721c64tomhudson@google.com 54182065d667f64e232bcde2ad849756a6096fcbe6freed@google.comvoid SkRgnClipBlitter::blitMask(const SkMask& mask, const SkIRect& clip) { 5428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(mask.fBounds.contains(clip)); 5438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRegion::Cliperator iter(*fRgn, clip); 5458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkIRect& r = iter.rect(); 5468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkBlitter* blitter = fBlitter; 5478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 54882065d667f64e232bcde2ad849756a6096fcbe6freed@google.com while (!iter.done()) { 5498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com blitter->blitMask(mask, r); 5508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.next(); 5518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 55441e010cb901c0da9066c4df562030808c9ccd7f8reedconst SkPixmap* SkRgnClipBlitter::justAnOpaqueColor(uint32_t* value) { 5558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fBlitter->justAnOpaqueColor(value); 5568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 55882065d667f64e232bcde2ad849756a6096fcbe6freed@google.com/////////////////////////////////////////////////////////////////////////////// 5598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 56082065d667f64e232bcde2ad849756a6096fcbe6freed@google.comSkBlitter* SkBlitterClipper::apply(SkBlitter* blitter, const SkRegion* clip, 56182065d667f64e232bcde2ad849756a6096fcbe6freed@google.com const SkIRect* ir) { 56282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com if (clip) { 5638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkIRect& clipR = clip->getBounds(); 5648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 56582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com if (clip->isEmpty() || (ir && !SkIRect::Intersects(clipR, *ir))) { 5668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com blitter = &fNullBlitter; 56782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com } else if (clip->isRect()) { 56896fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (ir == nullptr || !clipR.contains(*ir)) { 5698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRectBlitter.init(blitter, clipR); 5708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com blitter = &fRectBlitter; 5718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 57282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com } else { 5738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRgnBlitter.init(blitter, clip); 5748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com blitter = &fRgnBlitter; 5758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return blitter; 5788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 58082065d667f64e232bcde2ad849756a6096fcbe6freed@google.com/////////////////////////////////////////////////////////////////////////////// 5818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorShader.h" 5838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorPriv.h" 5848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass Sk3DShader : public SkShader { 5868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 5878a21c9fe7f5fef9e87115defef27bd7218419f28reed Sk3DShader(sk_sp<SkShader> proxy) : fProxy(std::move(proxy)) {} 58882065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 58983e939bcb79790f5ae3b28c398fbcf034675a6e5Herb Derby Context* onMakeContext(const ContextRec& rec, SkArenaAlloc* alloc) const override { 59096fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkShader::Context* proxyContext = nullptr; 591a641f3f18e5319773989812a888f3fad49e4f2adreed@google.com if (fProxy) { 59283e939bcb79790f5ae3b28c398fbcf034675a6e5Herb Derby proxyContext = fProxy->makeContext(rec, alloc); 593ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.org if (!proxyContext) { 59496fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 595ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.org } 596a641f3f18e5319773989812a888f3fad49e4f2adreed@google.com } 59783e939bcb79790f5ae3b28c398fbcf034675a6e5Herb Derby return alloc->make<Sk3DShaderContext>(*this, rec, proxyContext); 5988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 59982065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 60087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org class Sk3DShaderContext : public SkShader::Context { 60187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org public: 60287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org // Calls proxyContext's destructor but will NOT free its memory. 603e901b6de3ef8dea842008a08fc81e92fb1478d61commit-bot@chromium.org Sk3DShaderContext(const Sk3DShader& shader, const ContextRec& rec, 604e901b6de3ef8dea842008a08fc81e92fb1478d61commit-bot@chromium.org SkShader::Context* proxyContext) 605e901b6de3ef8dea842008a08fc81e92fb1478d61commit-bot@chromium.org : INHERITED(shader, rec) 60696fcdcc219d2a0d3579719b84b28bede76efba64halcanary , fMask(nullptr) 60787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org , fProxyContext(proxyContext) 60887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org { 60987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org if (!fProxyContext) { 610e901b6de3ef8dea842008a08fc81e92fb1478d61commit-bot@chromium.org fPMColor = SkPreMultiplyColor(rec.fPaint->getColor()); 61187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org } 61282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com } 6138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 614d3b65972aad96453ff4510caa3e25a2b847c6d1eBrian Salomon ~Sk3DShaderContext() override { 61587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org if (fProxyContext) { 61687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org fProxyContext->~Context(); 61782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com } 6188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 6198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 62036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void set3DMask(const SkMask* mask) override { fMask = mask; } 6218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 62236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void shadeSpan(int x, int y, SkPMColor span[], int count) override { 62387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org if (fProxyContext) { 62487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org fProxyContext->shadeSpan(x, y, span, count); 62587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org } 6268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 62796fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (fMask == nullptr) { 62896fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (fProxyContext == nullptr) { 62987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org sk_memset32(span, fPMColor, count); 63087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org } 63187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org return; 63287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org } 6338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 63487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkASSERT(fMask->fBounds.contains(x, y)); 63587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkASSERT(fMask->fBounds.contains(x + count - 1, y)); 63687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 63787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org size_t size = fMask->computeImageSize(); 63887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org const uint8_t* alpha = fMask->getAddr8(x, y); 63987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org const uint8_t* mulp = alpha + size; 64087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org const uint8_t* addp = mulp + size; 64187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 64287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org if (fProxyContext) { 64387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org for (int i = 0; i < count; i++) { 64487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org if (alpha[i]) { 64587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkPMColor c = span[i]; 64687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org if (c) { 64787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org unsigned a = SkGetPackedA32(c); 64887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org unsigned r = SkGetPackedR32(c); 64987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org unsigned g = SkGetPackedG32(c); 65087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org unsigned b = SkGetPackedB32(c); 65187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 65287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org unsigned mul = SkAlpha255To256(mulp[i]); 65387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org unsigned add = addp[i]; 65487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 65587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org r = SkFastMin32(SkAlphaMul(r, mul) + add, a); 65687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org g = SkFastMin32(SkAlphaMul(g, mul) + add, a); 65787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org b = SkFastMin32(SkAlphaMul(b, mul) + add, a); 65887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 65987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org span[i] = SkPackARGB32(a, r, g, b); 66087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org } 66187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org } else { 66287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org span[i] = 0; 66387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org } 66487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org } 66587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org } else { // color 66687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org unsigned a = SkGetPackedA32(fPMColor); 66787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org unsigned r = SkGetPackedR32(fPMColor); 66887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org unsigned g = SkGetPackedG32(fPMColor); 66987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org unsigned b = SkGetPackedB32(fPMColor); 67087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org for (int i = 0; i < count; i++) { 67187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org if (alpha[i]) { 6728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned mul = SkAlpha255To256(mulp[i]); 6738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned add = addp[i]; 6748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 67587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org span[i] = SkPackARGB32( a, 67687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkFastMin32(SkAlphaMul(r, mul) + add, a), 67787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkFastMin32(SkAlphaMul(g, mul) + add, a), 67887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkFastMin32(SkAlphaMul(b, mul) + add, a)); 67987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org } else { 68087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org span[i] = 0; 6818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 68282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com } 6838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 6848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 68587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 68687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org private: 68787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org // Unowned. 68887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org const SkMask* fMask; 68987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org // Memory is unowned, but we need to call the destructor. 69087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkShader::Context* fProxyContext; 69187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkPMColor fPMColor; 69287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 69387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org typedef SkShader::Context INHERITED; 69487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org }; 69582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 6960f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org#ifndef SK_IGNORE_TO_STRING 69736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void toString(SkString* str) const override { 69876f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com str->append("Sk3DShader: ("); 69976f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com 70049f085dddff10473b6ebf832a974288300224e60bsalomon if (fProxy) { 70176f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com str->append("Proxy: "); 70276f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com fProxy->toString(str); 70376f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com } 70476f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com 70576f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com this->INHERITED::toString(str); 70676f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com 70776f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com str->append(")"); 70876f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com } 70976f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com#endif 71076f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com 711ba28d03e94dc221d6a803bf2a84a420b9159255cdjsollen@google.com SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Sk3DShader) 712ba28d03e94dc221d6a803bf2a84a420b9159255cdjsollen@google.com 7138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprotected: 71436352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void flatten(SkWriteBuffer& buffer) const override { 7158a21c9fe7f5fef9e87115defef27bd7218419f28reed buffer.writeFlattenable(fProxy.get()); 7168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 71782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 7188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 7198a21c9fe7f5fef9e87115defef27bd7218419f28reed sk_sp<SkShader> fProxy; 7208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com typedef SkShader INHERITED; 7228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 7238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 72460c9b58b3214b0154c931656e91e39b230e987d8reedsk_sp<SkFlattenable> Sk3DShader::CreateProc(SkReadBuffer& buffer) { 72560c9b58b3214b0154c931656e91e39b230e987d8reed return sk_make_sp<Sk3DShader>(buffer.readShader()); 7269fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed} 7279fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed 7288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass Sk3DBlitter : public SkBlitter { 7298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 730cc0e3110bde60201882a2c512a5cdd73c838f351reed Sk3DBlitter(SkBlitter* proxy, SkShader::Context* shaderContext) 731a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org : fProxy(proxy) 732cc0e3110bde60201882a2c512a5cdd73c838f351reed , fShaderContext(shaderContext) 733a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org {} 7348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 73536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void blitH(int x, int y, int width) override { 7368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fProxy->blitH(x, y, width); 7378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 73882065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 73960c9b58b3214b0154c931656e91e39b230e987d8reed void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]) override { 7408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fProxy->blitAntiH(x, y, antialias, runs); 7418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 74282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 74336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void blitV(int x, int y, int height, SkAlpha alpha) override { 7448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fProxy->blitV(x, y, height, alpha); 7458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 74682065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 74736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void blitRect(int x, int y, int width, int height) override { 7488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fProxy->blitRect(x, y, width, height); 7498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 75082065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 75136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void blitMask(const SkMask& mask, const SkIRect& clip) override { 75282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com if (mask.fFormat == SkMask::k3D_Format) { 753cc0e3110bde60201882a2c512a5cdd73c838f351reed fShaderContext->set3DMask(&mask); 7548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ((SkMask*)&mask)->fFormat = SkMask::kA8_Format; 7568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fProxy->blitMask(mask, clip); 7578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ((SkMask*)&mask)->fFormat = SkMask::k3D_Format; 7588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 75996fcdcc219d2a0d3579719b84b28bede76efba64halcanary fShaderContext->set3DMask(nullptr); 76082065d667f64e232bcde2ad849756a6096fcbe6freed@google.com } else { 7618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fProxy->blitMask(mask, clip); 76282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com } 7638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 76482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 7658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 76687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org // Both pointers are unowned. They will be deleted by SkSmallAllocator. 767cc0e3110bde60201882a2c512a5cdd73c838f351reed SkBlitter* fProxy; 768cc0e3110bde60201882a2c512a5cdd73c838f351reed SkShader::Context* fShaderContext; 7698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 7708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 77182065d667f64e232bcde2ad849756a6096fcbe6freed@google.com/////////////////////////////////////////////////////////////////////////////// 7728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCoreBlitters.h" 7748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 775d0c4e092d54d281991ecfdc2e4ddd5217e45b42afmalitaSkShader::ContextRec::DstType SkBlitter::PreferredShaderDest(const SkImageInfo& dstInfo) { 776d0c4e092d54d281991ecfdc2e4ddd5217e45b42afmalita#ifdef SK_FORCE_PM4f_FOR_L32_BLITS 777d0c4e092d54d281991ecfdc2e4ddd5217e45b42afmalita return SkShader::ContextRec::kPM4f_DstType; 778d0c4e092d54d281991ecfdc2e4ddd5217e45b42afmalita#else 779960b2d69bbae19dc814f06d841b94ef71e291b48reed return (dstInfo.gammaCloseToSRGB() || dstInfo.colorType() == kRGBA_F16_SkColorType) 780d0c4e092d54d281991ecfdc2e4ddd5217e45b42afmalita ? SkShader::ContextRec::kPM4f_DstType 781d0c4e092d54d281991ecfdc2e4ddd5217e45b42afmalita : SkShader::ContextRec::kPMColor_DstType; 782d0c4e092d54d281991ecfdc2e4ddd5217e45b42afmalita#endif 783d0c4e092d54d281991ecfdc2e4ddd5217e45b42afmalita} 784d0c4e092d54d281991ecfdc2e4ddd5217e45b42afmalita 78541e010cb901c0da9066c4df562030808c9ccd7f8reedSkBlitter* SkBlitter::Choose(const SkPixmap& device, 7868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& matrix, 7876b7aee387d3b4b2df5894b51fa1c0baf649c6540reed@google.com const SkPaint& origPaint, 78883e939bcb79790f5ae3b28c398fbcf034675a6e5Herb Derby SkArenaAlloc* alloc, 789126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com bool drawCoverage) { 79083e939bcb79790f5ae3b28c398fbcf034675a6e5Herb Derby SkASSERT(alloc != nullptr); 7918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // which check, in case we're being called by a client with a dummy device 7938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // (e.g. they have a bounder that always aborts the draw) 794900ecf2f1579d42c9d2959831787af0346320f86reed@google.com if (kUnknown_SkColorType == device.colorType() || 795900ecf2f1579d42c9d2959831787af0346320f86reed@google.com (drawCoverage && (kAlpha_8_SkColorType != device.colorType()))) { 79683e939bcb79790f5ae3b28c398fbcf034675a6e5Herb Derby return alloc->make<SkNullBlitter>(); 7978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 799458849004892c05fa1dcbcf6d355dfcce028d77areed@google.com SkShader* shader = origPaint.getShader(); 800458849004892c05fa1dcbcf6d355dfcce028d77areed@google.com SkColorFilter* cf = origPaint.getColorFilter(); 801374772bd61951f01bf84fe17bf53d8867681c9aereed SkBlendMode mode = origPaint.getBlendMode(); 802fe63045f075165b1be5d3e7fc5c710021d85f53breed sk_sp<Sk3DShader> shader3D; 803458849004892c05fa1dcbcf6d355dfcce028d77areed@google.com 8045dc26b97366934ba0f896cea02a3fec027d5d5c1bsalomon@google.com SkTCopyOnFirstWrite<SkPaint> paint(origPaint); 805fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 80696fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (origPaint.getMaskFilter() != nullptr && 807458849004892c05fa1dcbcf6d355dfcce028d77areed@google.com origPaint.getMaskFilter()->getFormat() == SkMask::k3D_Format) { 808fe63045f075165b1be5d3e7fc5c710021d85f53breed shader3D = sk_make_sp<Sk3DShader>(sk_ref_sp(shader)); 809458849004892c05fa1dcbcf6d355dfcce028d77areed@google.com // we know we haven't initialized lazyPaint yet, so just do it 810fe63045f075165b1be5d3e7fc5c710021d85f53breed paint.writable()->setShader(shader3D); 811fe63045f075165b1be5d3e7fc5c710021d85f53breed shader = shader3D.get(); 8128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 814374772bd61951f01bf84fe17bf53d8867681c9aereed if (mode != SkBlendMode::kSrcOver) { 815a681433d42323d6d48e1aa3cb2ef97fb9d958d93halcanary bool deviceIsOpaque = kRGB_565_SkColorType == device.colorType(); 816a681433d42323d6d48e1aa3cb2ef97fb9d958d93halcanary switch (SkInterpretXfermode(*paint, deviceIsOpaque)) { 817a681433d42323d6d48e1aa3cb2ef97fb9d958d93halcanary case kSrcOver_SkXfermodeInterpretation: 818374772bd61951f01bf84fe17bf53d8867681c9aereed mode = SkBlendMode::kSrcOver; 819374772bd61951f01bf84fe17bf53d8867681c9aereed paint.writable()->setBlendMode(mode); 820d252db03d9650013b545ef9781fe993c07f8f314reed@android.com break; 821a681433d42323d6d48e1aa3cb2ef97fb9d958d93halcanary case kSkipDrawing_SkXfermodeInterpretation:{ 82283e939bcb79790f5ae3b28c398fbcf034675a6e5Herb Derby return alloc->make<SkNullBlitter>(); 823a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org } 824d252db03d9650013b545ef9781fe993c07f8f314reed@android.com default: 825d252db03d9650013b545ef9781fe993c07f8f314reed@android.com break; 826d252db03d9650013b545ef9781fe993c07f8f314reed@android.com } 827d252db03d9650013b545ef9781fe993c07f8f314reed@android.com } 828d252db03d9650013b545ef9781fe993c07f8f314reed@android.com 82913201e74f43b9c5fa173339eb36de515370e6973reed@google.com /* 83013201e74f43b9c5fa173339eb36de515370e6973reed@google.com * If the xfermode is CLEAR, then we can completely ignore the installed 83113201e74f43b9c5fa173339eb36de515370e6973reed@google.com * color/shader/colorfilter, and just pretend we're SRC + color==0. This 83213201e74f43b9c5fa173339eb36de515370e6973reed@google.com * will fall into our optimizations for SRC mode. 83313201e74f43b9c5fa173339eb36de515370e6973reed@google.com */ 834374772bd61951f01bf84fe17bf53d8867681c9aereed if (mode == SkBlendMode::kClear) { 83513201e74f43b9c5fa173339eb36de515370e6973reed@google.com SkPaint* p = paint.writable(); 836fe63045f075165b1be5d3e7fc5c710021d85f53breed p->setShader(nullptr); 837fe63045f075165b1be5d3e7fc5c710021d85f53breed shader = nullptr; 838d053ce9c54d4e5937a142278359e5a4cde18095ereed p->setColorFilter(nullptr); 839d053ce9c54d4e5937a142278359e5a4cde18095ereed cf = nullptr; 840374772bd61951f01bf84fe17bf53d8867681c9aereed p->setBlendMode(mode = SkBlendMode::kSrc); 84113201e74f43b9c5fa173339eb36de515370e6973reed@google.com p->setColor(0); 84213201e74f43b9c5fa173339eb36de515370e6973reed@google.com } 84313201e74f43b9c5fa173339eb36de515370e6973reed@google.com 844e71b167dbd4d8da76495ca85db83d1a3b49aaabdMike Klein if (kAlpha_8_SkColorType == device.colorType() && drawCoverage) { 845e71b167dbd4d8da76495ca85db83d1a3b49aaabdMike Klein SkASSERT(nullptr == shader); 846e71b167dbd4d8da76495ca85db83d1a3b49aaabdMike Klein SkASSERT(paint->isSrcOver()); 84783e939bcb79790f5ae3b28c398fbcf034675a6e5Herb Derby return alloc->make<SkA8_Coverage_Blitter>(device, *paint); 848e71b167dbd4d8da76495ca85db83d1a3b49aaabdMike Klein } 849e71b167dbd4d8da76495ca85db83d1a3b49aaabdMike Klein 85025834ffc5a4f6c45830dded7d5d135df157870e6Matt Sarett if (SkBlitter* blitter = SkCreateRasterPipelineBlitter(device, *paint, matrix, alloc)) { 8519a5c47f4effba3b48a9a8c7c144b72b532d06efemtklein return blitter; 8529a5c47f4effba3b48a9a8c7c144b72b532d06efemtklein } 8539a5c47f4effba3b48a9a8c7c144b72b532d06efemtklein 85496fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == shader) { 855374772bd61951f01bf84fe17bf53d8867681c9aereed if (mode != SkBlendMode::kSrcOver) { 8566b7aee387d3b4b2df5894b51fa1c0baf649c6540reed@google.com // xfermodes (and filters) require shaders for our current blitters 857fe63045f075165b1be5d3e7fc5c710021d85f53breed paint.writable()->setShader(SkShader::MakeColorShader(paint->getColor())); 85876a3b2abd02841c4ae786ac4cf59c3a51c545f73commit-bot@chromium.org paint.writable()->setAlpha(0xFF); 859fe63045f075165b1be5d3e7fc5c710021d85f53breed shader = paint->getShader(); 8606b7aee387d3b4b2df5894b51fa1c0baf649c6540reed@google.com } else if (cf) { 8616b7aee387d3b4b2df5894b51fa1c0baf649c6540reed@google.com // if no shader && no xfermode, we just apply the colorfilter to 8626b7aee387d3b4b2df5894b51fa1c0baf649c6540reed@google.com // our color and move on. 8635dc26b97366934ba0f896cea02a3fec027d5d5c1bsalomon@google.com SkPaint* writablePaint = paint.writable(); 8645dc26b97366934ba0f896cea02a3fec027d5d5c1bsalomon@google.com writablePaint->setColor(cf->filterColor(paint->getColor())); 86596fcdcc219d2a0d3579719b84b28bede76efba64halcanary writablePaint->setColorFilter(nullptr); 86696fcdcc219d2a0d3579719b84b28bede76efba64halcanary cf = nullptr; 8676b7aee387d3b4b2df5894b51fa1c0baf649c6540reed@google.com } 8688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 86982065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 8706b7aee387d3b4b2df5894b51fa1c0baf649c6540reed@google.com if (cf) { 8718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(shader); 872d053ce9c54d4e5937a142278359e5a4cde18095ereed paint.writable()->setShader(shader->makeWithColorFilter(sk_ref_sp(cf))); 873150835e779ceb24e2b540f58958cbff2a0ab9942reed shader = paint->getShader(); 8741fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com // blitters should ignore the presence/absence of a filter, since 8751fc4c605def61d9e10489f9cd63dc378baa6ade3reed@android.com // if there is one, the shader will take care of it. 8768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 87782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 878a641f3f18e5319773989812a888f3fad49e4f2adreed@google.com /* 87987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org * We create a SkShader::Context object, and store it on the blitter. 880a641f3f18e5319773989812a888f3fad49e4f2adreed@google.com */ 88196fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkShader::Context* shaderContext = nullptr; 88287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org if (shader) { 883d0c4e092d54d281991ecfdc2e4ddd5217e45b42afmalita const SkShader::ContextRec rec(*paint, matrix, nullptr, 88411970e56c10b49ad06adbe9e835d32c00a63dd7dBrian Osman PreferredShaderDest(device.info()), 88511970e56c10b49ad06adbe9e835d32c00a63dd7dBrian Osman device.colorSpace()); 88683e939bcb79790f5ae3b28c398fbcf034675a6e5Herb Derby // Try to create the ShaderContext 88783e939bcb79790f5ae3b28c398fbcf034675a6e5Herb Derby shaderContext = shader->makeContext(rec, alloc); 88883e939bcb79790f5ae3b28c398fbcf034675a6e5Herb Derby if (!shaderContext) { 88983e939bcb79790f5ae3b28c398fbcf034675a6e5Herb Derby return alloc->make<SkNullBlitter>(); 89087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org } 89183e939bcb79790f5ae3b28c398fbcf034675a6e5Herb Derby SkASSERT(shaderContext); 8928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 89496fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkBlitter* blitter = nullptr; 895900ecf2f1579d42c9d2959831787af0346320f86reed@google.com switch (device.colorType()) { 896900ecf2f1579d42c9d2959831787af0346320f86reed@google.com case kAlpha_8_SkColorType: 897e71b167dbd4d8da76495ca85db83d1a3b49aaabdMike Klein SkASSERT(!drawCoverage); // Handled above. 898e71b167dbd4d8da76495ca85db83d1a3b49aaabdMike Klein if (shader) { 89983e939bcb79790f5ae3b28c398fbcf034675a6e5Herb Derby blitter = alloc->make<SkA8_Shader_Blitter>(device, *paint, shaderContext); 90082065d667f64e232bcde2ad849756a6096fcbe6freed@google.com } else { 90183e939bcb79790f5ae3b28c398fbcf034675a6e5Herb Derby blitter = alloc->make<SkA8_Blitter>(device, *paint); 90282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com } 90382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com break; 90482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 905900ecf2f1579d42c9d2959831787af0346320f86reed@google.com case kRGB_565_SkColorType: 90683e939bcb79790f5ae3b28c398fbcf034675a6e5Herb Derby blitter = SkBlitter_ChooseD565(device, *paint, shaderContext, alloc); 90782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com break; 90882065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 90928fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org case kN32_SkColorType: 910a34be68a7eff0ae475b194f8a29975460cf3e456reed#ifdef SK_FORCE_PM4f_FOR_L32_BLITS 911a34be68a7eff0ae475b194f8a29975460cf3e456reed if (true) 912a34be68a7eff0ae475b194f8a29975460cf3e456reed#else 913960b2d69bbae19dc814f06d841b94ef71e291b48reed if (device.info().gammaCloseToSRGB()) 914a34be68a7eff0ae475b194f8a29975460cf3e456reed#endif 915a34be68a7eff0ae475b194f8a29975460cf3e456reed { 91683e939bcb79790f5ae3b28c398fbcf034675a6e5Herb Derby blitter = SkBlitter_ARGB32_Create(device, *paint, shaderContext, alloc); 917a34be68a7eff0ae475b194f8a29975460cf3e456reed } else { 918a34be68a7eff0ae475b194f8a29975460cf3e456reed if (shader) { 91983e939bcb79790f5ae3b28c398fbcf034675a6e5Herb Derby blitter = alloc->make<SkARGB32_Shader_Blitter>( 920a34be68a7eff0ae475b194f8a29975460cf3e456reed device, *paint, shaderContext); 921a34be68a7eff0ae475b194f8a29975460cf3e456reed } else if (paint->getColor() == SK_ColorBLACK) { 92283e939bcb79790f5ae3b28c398fbcf034675a6e5Herb Derby blitter = alloc->make<SkARGB32_Black_Blitter>(device, *paint); 923a34be68a7eff0ae475b194f8a29975460cf3e456reed } else if (paint->getAlpha() == 0xFF) { 92483e939bcb79790f5ae3b28c398fbcf034675a6e5Herb Derby blitter = alloc->make<SkARGB32_Opaque_Blitter>(device, *paint); 925395eabeb0e72334c45324874c6e009b54634df21reed } else { 92683e939bcb79790f5ae3b28c398fbcf034675a6e5Herb Derby blitter = alloc->make<SkARGB32_Blitter>(device, *paint); 927395eabeb0e72334c45324874c6e009b54634df21reed } 92882065d667f64e232bcde2ad849756a6096fcbe6freed@google.com } 92982065d667f64e232bcde2ad849756a6096fcbe6freed@google.com break; 93082065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 931a34be68a7eff0ae475b194f8a29975460cf3e456reed case kRGBA_F16_SkColorType: 93283e939bcb79790f5ae3b28c398fbcf034675a6e5Herb Derby blitter = SkBlitter_F16_Create(device, *paint, shaderContext, alloc); 933a34be68a7eff0ae475b194f8a29975460cf3e456reed break; 934a34be68a7eff0ae475b194f8a29975460cf3e456reed 93582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com default: 93682065d667f64e232bcde2ad849756a6096fcbe6freed@google.com break; 9378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 939129ed1cd6d792f3f6cf563aefa9756fc6308289dreed if (!blitter) { 94083e939bcb79790f5ae3b28c398fbcf034675a6e5Herb Derby blitter = alloc->make<SkNullBlitter>(); 941129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } 942129ed1cd6d792f3f6cf563aefa9756fc6308289dreed 94382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com if (shader3D) { 944a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org SkBlitter* innerBlitter = blitter; 94583e939bcb79790f5ae3b28c398fbcf034675a6e5Herb Derby // FIXME - comment about allocator 946a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org // innerBlitter was allocated by allocator, which will delete it. 947cc0e3110bde60201882a2c512a5cdd73c838f351reed // We know shaderContext or its proxies is of type Sk3DShaderContext, so we need to 948cc0e3110bde60201882a2c512a5cdd73c838f351reed // wrapper the blitter to notify it when we see an emboss mask. 94983e939bcb79790f5ae3b28c398fbcf034675a6e5Herb Derby blitter = alloc->make<Sk3DBlitter>(innerBlitter, shaderContext); 9508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return blitter; 9528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 95482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com/////////////////////////////////////////////////////////////////////////////// 9558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 95656263c78d86cb536d463b8d46f00ac44cad3defbreedclass SkZeroShaderContext : public SkShader::Context { 957ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.orgpublic: 95856263c78d86cb536d463b8d46f00ac44cad3defbreed SkZeroShaderContext(const SkShader& shader, const SkShader::ContextRec& rec) 959ca76c55d60dfe041e30e210d41fa0feb7fb54a1fscroggo // Override rec with the identity matrix, so it is guaranteed to be invertible. 960d0c4e092d54d281991ecfdc2e4ddd5217e45b42afmalita : INHERITED(shader, SkShader::ContextRec(*rec.fPaint, SkMatrix::I(), nullptr, 96111970e56c10b49ad06adbe9e835d32c00a63dd7dBrian Osman rec.fPreferredDstType, rec.fDstColorSpace)) {} 962ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.org 96336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void shadeSpan(int x, int y, SkPMColor colors[], int count) override { 964ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.org sk_bzero(colors, count * sizeof(SkPMColor)); 965ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.org } 966ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.org 967ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.orgprivate: 968ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.org typedef SkShader::Context INHERITED; 969ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.org}; 970ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.org 97141e010cb901c0da9066c4df562030808c9ccd7f8reedSkShaderBlitter::SkShaderBlitter(const SkPixmap& device, const SkPaint& paint, 97287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkShader::Context* shaderContext) 97387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org : INHERITED(device) 97487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org , fShader(paint.getShader()) 97587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org , fShaderContext(shaderContext) { 9768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(fShader); 97787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkASSERT(fShaderContext); 9788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fShader->ref(); 98087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org fShaderFlags = fShaderContext->getFlags(); 981a34be68a7eff0ae475b194f8a29975460cf3e456reed fConstInY = SkToBool(fShaderFlags & SkShader::kConstInY32_Flag); 9828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9845119bdb952025a30f115b9c6a187173956e55097reed@android.comSkShaderBlitter::~SkShaderBlitter() { 9858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fShader->unref(); 9868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 98787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 98828930b46487fc94fde206d1283623204c595b0f1Mike Reed/////////////////////////////////////////////////////////////////////////////////////////////////// 98928930b46487fc94fde206d1283623204c595b0f1Mike Reed 99028930b46487fc94fde206d1283623204c595b0f1Mike Reed#ifdef SK_DEBUG 99128930b46487fc94fde206d1283623204c595b0f1Mike Reed 99228930b46487fc94fde206d1283623204c595b0f1Mike Reedvoid SkRectClipCheckBlitter::blitH(int x, int y, int width) { 99328930b46487fc94fde206d1283623204c595b0f1Mike Reed SkASSERT(fClipRect.contains(SkIRect::MakeXYWH(x, y, width, 1))); 99428930b46487fc94fde206d1283623204c595b0f1Mike Reed fBlitter->blitH(x, y, width); 99528930b46487fc94fde206d1283623204c595b0f1Mike Reed} 99628930b46487fc94fde206d1283623204c595b0f1Mike Reed 99728930b46487fc94fde206d1283623204c595b0f1Mike Reedvoid SkRectClipCheckBlitter::blitAntiH(int x, int y, const SkAlpha aa[], const int16_t runs[]) { 99828930b46487fc94fde206d1283623204c595b0f1Mike Reed const int16_t* iter = runs; 99928930b46487fc94fde206d1283623204c595b0f1Mike Reed for (; *iter; iter += *iter) 100028930b46487fc94fde206d1283623204c595b0f1Mike Reed ; 100128930b46487fc94fde206d1283623204c595b0f1Mike Reed int width = iter - runs; 100228930b46487fc94fde206d1283623204c595b0f1Mike Reed SkASSERT(fClipRect.contains(SkIRect::MakeXYWH(x, y, width, 1))); 100328930b46487fc94fde206d1283623204c595b0f1Mike Reed fBlitter->blitAntiH(x, y, aa, runs); 100428930b46487fc94fde206d1283623204c595b0f1Mike Reed} 100528930b46487fc94fde206d1283623204c595b0f1Mike Reed 100628930b46487fc94fde206d1283623204c595b0f1Mike Reedvoid SkRectClipCheckBlitter::blitV(int x, int y, int height, SkAlpha alpha) { 100728930b46487fc94fde206d1283623204c595b0f1Mike Reed SkASSERT(fClipRect.contains(SkIRect::MakeXYWH(x, y, 1, height))); 100828930b46487fc94fde206d1283623204c595b0f1Mike Reed fBlitter->blitV(x, y, height, alpha); 100928930b46487fc94fde206d1283623204c595b0f1Mike Reed} 101028930b46487fc94fde206d1283623204c595b0f1Mike Reed 101128930b46487fc94fde206d1283623204c595b0f1Mike Reedvoid SkRectClipCheckBlitter::blitRect(int x, int y, int width, int height) { 101228930b46487fc94fde206d1283623204c595b0f1Mike Reed SkASSERT(fClipRect.contains(SkIRect::MakeXYWH(x, y, width, height))); 101328930b46487fc94fde206d1283623204c595b0f1Mike Reed fBlitter->blitRect(x, y, width, height); 101428930b46487fc94fde206d1283623204c595b0f1Mike Reed} 101528930b46487fc94fde206d1283623204c595b0f1Mike Reed 101628930b46487fc94fde206d1283623204c595b0f1Mike Reedvoid SkRectClipCheckBlitter::blitAntiRect(int x, int y, int width, int height, 101728930b46487fc94fde206d1283623204c595b0f1Mike Reed SkAlpha leftAlpha, SkAlpha rightAlpha) { 10188b9a725823fb195f24a85b5004b988e42fa82ef8Yuqian Li bool skipLeft = !leftAlpha; 10198b9a725823fb195f24a85b5004b988e42fa82ef8Yuqian Li bool skipRight = !rightAlpha; 10208b9a725823fb195f24a85b5004b988e42fa82ef8Yuqian Li SkASSERT(fClipRect.contains(SkIRect::MakeXYWH(x + skipLeft, y, 10218b9a725823fb195f24a85b5004b988e42fa82ef8Yuqian Li width + 2 - skipRight - skipLeft, height))); 102228930b46487fc94fde206d1283623204c595b0f1Mike Reed fBlitter->blitAntiRect(x, y, width, height, leftAlpha, rightAlpha); 102328930b46487fc94fde206d1283623204c595b0f1Mike Reed} 102428930b46487fc94fde206d1283623204c595b0f1Mike Reed 102528930b46487fc94fde206d1283623204c595b0f1Mike Reedvoid SkRectClipCheckBlitter::blitMask(const SkMask& mask, const SkIRect& clip) { 102628930b46487fc94fde206d1283623204c595b0f1Mike Reed SkASSERT(mask.fBounds.contains(clip)); 102728930b46487fc94fde206d1283623204c595b0f1Mike Reed SkASSERT(fClipRect.contains(clip)); 102828930b46487fc94fde206d1283623204c595b0f1Mike Reed fBlitter->blitMask(mask, clip); 102928930b46487fc94fde206d1283623204c595b0f1Mike Reed} 103028930b46487fc94fde206d1283623204c595b0f1Mike Reed 103128930b46487fc94fde206d1283623204c595b0f1Mike Reedconst SkPixmap* SkRectClipCheckBlitter::justAnOpaqueColor(uint32_t* value) { 103228930b46487fc94fde206d1283623204c595b0f1Mike Reed return fBlitter->justAnOpaqueColor(value); 103328930b46487fc94fde206d1283623204c595b0f1Mike Reed} 103428930b46487fc94fde206d1283623204c595b0f1Mike Reed 103599bba9ea829323a7941d4f3a9c98da7a76432d1bYuqian Livoid SkRectClipCheckBlitter::blitAntiH2(int x, int y, U8CPU a0, U8CPU a1) { 103699bba9ea829323a7941d4f3a9c98da7a76432d1bYuqian Li SkASSERT(fClipRect.contains(SkIRect::MakeXYWH(x, y, 2, 1))); 103799bba9ea829323a7941d4f3a9c98da7a76432d1bYuqian Li fBlitter->blitAntiH2(x, y, a0, a1); 103899bba9ea829323a7941d4f3a9c98da7a76432d1bYuqian Li} 103999bba9ea829323a7941d4f3a9c98da7a76432d1bYuqian Li 104099bba9ea829323a7941d4f3a9c98da7a76432d1bYuqian Livoid SkRectClipCheckBlitter::blitAntiV2(int x, int y, U8CPU a0, U8CPU a1) { 104199bba9ea829323a7941d4f3a9c98da7a76432d1bYuqian Li SkASSERT(fClipRect.contains(SkIRect::MakeXYWH(x, y, 1, 2))); 104299bba9ea829323a7941d4f3a9c98da7a76432d1bYuqian Li fBlitter->blitAntiV2(x, y, a0, a1); 104399bba9ea829323a7941d4f3a9c98da7a76432d1bYuqian Li} 104499bba9ea829323a7941d4f3a9c98da7a76432d1bYuqian Li 104528930b46487fc94fde206d1283623204c595b0f1Mike Reed#endif 1046