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 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCoreBlitters.h" 9a4083c97d48e8a4f88e2797d7363f141e3d42553Cary Clark#include "SkColorData.h" 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkShader.h" 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkUtils.h" 12d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed#include "SkXfermodePriv.h" 1358af9a64701540c7f8083bc22a42d0bae3a5583creed@google.com#include "SkBlitMask.h" 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 15f88d6765a594cf9fb0825b74779f74394a7ccc7areed@google.com/////////////////////////////////////////////////////////////////////////////// 16f88d6765a594cf9fb0825b74779f74394a7ccc7areed@google.com 1741e010cb901c0da9066c4df562030808c9ccd7f8reedstatic void SkARGB32_Blit32(const SkPixmap& device, const SkMask& mask, 18fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com const SkIRect& clip, SkPMColor srcColor) { 19fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com U8CPU alpha = SkGetPackedA32(srcColor); 20fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com unsigned flags = SkBlitRow::kSrcPixelAlpha_Flag32; 21fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com if (alpha != 255) { 22fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com flags |= SkBlitRow::kGlobalAlpha_Flag32; 23fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 24fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com SkBlitRow::Proc32 proc = SkBlitRow::Factory32(flags); 25f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 26f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com int x = clip.fLeft; 27f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com int y = clip.fTop; 28f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com int width = clip.width(); 29f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com int height = clip.height(); 3082065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 3141e010cb901c0da9066c4df562030808c9ccd7f8reed SkPMColor* dstRow = device.writable_addr32(x, y); 327989186dab6bc2f1c1927daf91bddd32b7fd8d0creed@google.com const SkPMColor* srcRow = reinterpret_cast<const SkPMColor*>(mask.getAddr8(x, y)); 33f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 34f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com do { 35fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com proc(dstRow, srcRow, width, alpha); 36f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com dstRow = (SkPMColor*)((char*)dstRow + device.rowBytes()); 37f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com srcRow = (const SkPMColor*)((const char*)srcRow + mask.fRowBytes); 38f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } while (--height != 0); 39f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com} 40f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 41f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com////////////////////////////////////////////////////////////////////////////////////// 42f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 4341e010cb901c0da9066c4df562030808c9ccd7f8reedSkARGB32_Blitter::SkARGB32_Blitter(const SkPixmap& device, const SkPaint& paint) 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com : INHERITED(device) { 45ee467ee79d449ebe6ae7f7946e613cc70a479c69reed@google.com SkColor color = paint.getColor(); 46ee467ee79d449ebe6ae7f7946e613cc70a479c69reed@google.com fColor = color; 478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fSrcA = SkColorGetA(color); 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned scale = SkAlpha255To256(fSrcA); 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fSrcR = SkAlphaMul(SkColorGetR(color), scale); 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fSrcG = SkAlphaMul(SkColorGetG(color), scale); 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fSrcB = SkAlphaMul(SkColorGetB(color), scale); 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPMColor = SkPackARGB32(fSrcA, fSrcR, fSrcG, fSrcB); 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5741e010cb901c0da9066c4df562030808c9ccd7f8reedconst SkPixmap* SkARGB32_Blitter::justAnOpaqueColor(uint32_t* value) { 588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (255 == fSrcA) { 598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *value = fPMColor; 608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return &fDevice; 618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 6296fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 65d7dc76f7e99309cbd09a5420c22e55b951067debbungeman#if defined _WIN32 // disable warning : local variable used without having been initialized 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#pragma warning ( push ) 678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#pragma warning ( disable : 4701 ) 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkARGB32_Blitter::blitH(int x, int y, int width) { 718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width()); 728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7341e010cb901c0da9066c4df562030808c9ccd7f8reed uint32_t* device = fDevice.writable_addr32(x, y); 7495cc012ccaea20f372893ae277ea0a8a6339d094mtklein SkBlitRow::Color32(device, device, width, fPMColor); 758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkARGB32_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[], 788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const int16_t runs[]) { 798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fSrcA == 0) { 808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint32_t color = fPMColor; 8441e010cb901c0da9066c4df562030808c9ccd7f8reed uint32_t* device = fDevice.writable_addr32(x, y); 858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned opaqueMask = fSrcA; // if fSrcA is 0xFF, then we will catch the fast opaque case 868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (;;) { 888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int count = runs[0]; 898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count >= 0); 908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (count <= 0) { 918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned aa = antialias[0]; 948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (aa) { 958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if ((opaqueMask & aa) == 255) { 968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_memset32(device, color, count); 978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 98c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com uint32_t sc = SkAlphaMulQ(color, SkAlpha255To256(aa)); 9995cc012ccaea20f372893ae277ea0a8a6339d094mtklein SkBlitRow::Color32(device, device, count, sc); 1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com runs += count; 1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com antialias += count; 1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device += count; 1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1086983f66d8b3a489133b751e2cef03e72a03bfeaereedvoid SkARGB32_Blitter::blitAntiH2(int x, int y, U8CPU a0, U8CPU a1) { 10941e010cb901c0da9066c4df562030808c9ccd7f8reed uint32_t* device = fDevice.writable_addr32(x, y); 11041e010cb901c0da9066c4df562030808c9ccd7f8reed SkDEBUGCODE((void)fDevice.writable_addr32(x + 1, y);) 11195cc012ccaea20f372893ae277ea0a8a6339d094mtklein 1126983f66d8b3a489133b751e2cef03e72a03bfeaereed device[0] = SkBlendARGB32(fPMColor, device[0], a0); 1136983f66d8b3a489133b751e2cef03e72a03bfeaereed device[1] = SkBlendARGB32(fPMColor, device[1], a1); 1146983f66d8b3a489133b751e2cef03e72a03bfeaereed} 1156983f66d8b3a489133b751e2cef03e72a03bfeaereed 1166983f66d8b3a489133b751e2cef03e72a03bfeaereedvoid SkARGB32_Blitter::blitAntiV2(int x, int y, U8CPU a0, U8CPU a1) { 11741e010cb901c0da9066c4df562030808c9ccd7f8reed uint32_t* device = fDevice.writable_addr32(x, y); 11841e010cb901c0da9066c4df562030808c9ccd7f8reed SkDEBUGCODE((void)fDevice.writable_addr32(x, y + 1);) 11995cc012ccaea20f372893ae277ea0a8a6339d094mtklein 1206983f66d8b3a489133b751e2cef03e72a03bfeaereed device[0] = SkBlendARGB32(fPMColor, device[0], a0); 1216983f66d8b3a489133b751e2cef03e72a03bfeaereed device = (uint32_t*)((char*)device + fDevice.rowBytes()); 1226983f66d8b3a489133b751e2cef03e72a03bfeaereed device[0] = SkBlendARGB32(fPMColor, device[0], a1); 1236983f66d8b3a489133b751e2cef03e72a03bfeaereed} 1246983f66d8b3a489133b751e2cef03e72a03bfeaereed 1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////////////// 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define solid_8_pixels(mask, dst, color) \ 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { \ 1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x80) dst[0] = color; \ 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x40) dst[1] = color; \ 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x20) dst[2] = color; \ 1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x10) dst[3] = color; \ 1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x08) dst[4] = color; \ 1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x04) dst[5] = color; \ 1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x02) dst[6] = color; \ 1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x01) dst[7] = color; \ 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (0) 1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_NAME SkARGB32_BlitBW 1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_ARGS , SkPMColor color 1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_BLIT8(mask, dst) solid_8_pixels(mask, dst, color) 14241e010cb901c0da9066c4df562030808c9ccd7f8reed#define SK_BLITBWMASK_GETADDR writable_addr32 1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_DEVTYPE uint32_t 1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkBlitBWMaskTemplate.h" 1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define blend_8_pixels(mask, dst, sc, dst_scale) \ 1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { \ 1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x80) { dst[0] = sc + SkAlphaMulQ(dst[0], dst_scale); } \ 1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x40) { dst[1] = sc + SkAlphaMulQ(dst[1], dst_scale); } \ 1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x20) { dst[2] = sc + SkAlphaMulQ(dst[2], dst_scale); } \ 1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x10) { dst[3] = sc + SkAlphaMulQ(dst[3], dst_scale); } \ 1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x08) { dst[4] = sc + SkAlphaMulQ(dst[4], dst_scale); } \ 1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x04) { dst[5] = sc + SkAlphaMulQ(dst[5], dst_scale); } \ 1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x02) { dst[6] = sc + SkAlphaMulQ(dst[6], dst_scale); } \ 1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mask & 0x01) { dst[7] = sc + SkAlphaMulQ(dst[7], dst_scale); } \ 1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (0) 1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_NAME SkARGB32_BlendBW 1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_ARGS , uint32_t sc, unsigned dst_scale 1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_BLIT8(mask, dst) blend_8_pixels(mask, dst, sc, dst_scale) 16141e010cb901c0da9066c4df562030808c9ccd7f8reed#define SK_BLITBWMASK_GETADDR writable_addr32 1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_DEVTYPE uint32_t 1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkBlitBWMaskTemplate.h" 1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkARGB32_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) { 1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(mask.fBounds.contains(clip)); 1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(fSrcA != 0xFF); 1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fSrcA == 0) { 1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 173edb606cb999887d54629f361bcbf57c5fede1bb0reed@google.com if (SkBlitMask::BlitColor(fDevice, mask, clip, fColor)) { 174edb606cb999887d54629f361bcbf57c5fede1bb0reed@google.com return; 175edb606cb999887d54629f361bcbf57c5fede1bb0reed@google.com } 176edb606cb999887d54629f361bcbf57c5fede1bb0reed@google.com 1773be72b0413ebc7cb1133e704169e3d543830d8e7herb switch (mask.fFormat) { 1783be72b0413ebc7cb1133e704169e3d543830d8e7herb case SkMask::kBW_Format: 1793be72b0413ebc7cb1133e704169e3d543830d8e7herb SkARGB32_BlendBW(fDevice, mask, clip, fPMColor, SkAlpha255To256(255 - fSrcA)); 1803be72b0413ebc7cb1133e704169e3d543830d8e7herb break; 1813be72b0413ebc7cb1133e704169e3d543830d8e7herb case SkMask::kARGB32_Format: 1823be72b0413ebc7cb1133e704169e3d543830d8e7herb SkARGB32_Blit32(fDevice, mask, clip, fPMColor); 1833be72b0413ebc7cb1133e704169e3d543830d8e7herb break; 1843be72b0413ebc7cb1133e704169e3d543830d8e7herb default: 185b4aab9ae6d27c446af8302b79d15b832c816c633Ben Wagner SK_ABORT("Mask format not handled."); 1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkARGB32_Opaque_Blitter::blitMask(const SkMask& mask, 1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkIRect& clip) { 1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(mask.fBounds.contains(clip)); 1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 193edb606cb999887d54629f361bcbf57c5fede1bb0reed@google.com if (SkBlitMask::BlitColor(fDevice, mask, clip, fColor)) { 194edb606cb999887d54629f361bcbf57c5fede1bb0reed@google.com return; 195edb606cb999887d54629f361bcbf57c5fede1bb0reed@google.com } 196fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1973be72b0413ebc7cb1133e704169e3d543830d8e7herb switch (mask.fFormat) { 1983be72b0413ebc7cb1133e704169e3d543830d8e7herb case SkMask::kBW_Format: 1993be72b0413ebc7cb1133e704169e3d543830d8e7herb SkARGB32_BlitBW(fDevice, mask, clip, fPMColor); 2003be72b0413ebc7cb1133e704169e3d543830d8e7herb break; 2013be72b0413ebc7cb1133e704169e3d543830d8e7herb case SkMask::kARGB32_Format: 2023be72b0413ebc7cb1133e704169e3d543830d8e7herb SkARGB32_Blit32(fDevice, mask, clip, fPMColor); 2033be72b0413ebc7cb1133e704169e3d543830d8e7herb break; 2043be72b0413ebc7cb1133e704169e3d543830d8e7herb default: 205b4aab9ae6d27c446af8302b79d15b832c816c633Ben Wagner SK_ABORT("Mask format not handled."); 206fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 2078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2096983f66d8b3a489133b751e2cef03e72a03bfeaereedvoid SkARGB32_Opaque_Blitter::blitAntiH2(int x, int y, U8CPU a0, U8CPU a1) { 21041e010cb901c0da9066c4df562030808c9ccd7f8reed uint32_t* device = fDevice.writable_addr32(x, y); 21141e010cb901c0da9066c4df562030808c9ccd7f8reed SkDEBUGCODE((void)fDevice.writable_addr32(x + 1, y);) 2126983f66d8b3a489133b751e2cef03e72a03bfeaereed 2136983f66d8b3a489133b751e2cef03e72a03bfeaereed device[0] = SkFastFourByteInterp(fPMColor, device[0], a0); 2146983f66d8b3a489133b751e2cef03e72a03bfeaereed device[1] = SkFastFourByteInterp(fPMColor, device[1], a1); 2156983f66d8b3a489133b751e2cef03e72a03bfeaereed} 2166983f66d8b3a489133b751e2cef03e72a03bfeaereed 2176983f66d8b3a489133b751e2cef03e72a03bfeaereedvoid SkARGB32_Opaque_Blitter::blitAntiV2(int x, int y, U8CPU a0, U8CPU a1) { 21841e010cb901c0da9066c4df562030808c9ccd7f8reed uint32_t* device = fDevice.writable_addr32(x, y); 21941e010cb901c0da9066c4df562030808c9ccd7f8reed SkDEBUGCODE((void)fDevice.writable_addr32(x, y + 1);) 2206983f66d8b3a489133b751e2cef03e72a03bfeaereed 2216983f66d8b3a489133b751e2cef03e72a03bfeaereed device[0] = SkFastFourByteInterp(fPMColor, device[0], a0); 2226983f66d8b3a489133b751e2cef03e72a03bfeaereed device = (uint32_t*)((char*)device + fDevice.rowBytes()); 2236983f66d8b3a489133b751e2cef03e72a03bfeaereed device[0] = SkFastFourByteInterp(fPMColor, device[0], a1); 2246983f66d8b3a489133b751e2cef03e72a03bfeaereed} 2256983f66d8b3a489133b751e2cef03e72a03bfeaereed 22667cdbf5c63cfd77523d2a3070a44a200fabf0739reed@google.com/////////////////////////////////////////////////////////////////////////////// 2278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkARGB32_Blitter::blitV(int x, int y, int height, SkAlpha alpha) { 2298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (alpha == 0 || fSrcA == 0) { 2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23341e010cb901c0da9066c4df562030808c9ccd7f8reed uint32_t* device = fDevice.writable_addr32(x, y); 2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint32_t color = fPMColor; 2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (alpha != 255) { 2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com color = SkAlphaMulQ(color, SkAlpha255To256(alpha)); 2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24040254c2c2dc28a34f96294d5a1ad94a99b0be8a6lsalzman unsigned dst_scale = SkAlpha255To256(255 - SkGetPackedA32(color)); 241e5f48243bdbed2662be7a31be0888abc273b09e8scroggo@google.com size_t rowBytes = fDevice.rowBytes(); 2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (--height >= 0) { 24367cdbf5c63cfd77523d2a3070a44a200fabf0739reed@google.com device[0] = color + SkAlphaMulQ(device[0], dst_scale); 2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device = (uint32_t*)((char*)device + rowBytes); 2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkARGB32_Blitter::blitRect(int x, int y, int width, int height) { 2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width() && y + height <= fDevice.height()); 2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fSrcA == 0) { 2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 2538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25541e010cb901c0da9066c4df562030808c9ccd7f8reed uint32_t* device = fDevice.writable_addr32(x, y); 2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint32_t color = fPMColor; 257c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com size_t rowBytes = fDevice.rowBytes(); 2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 259edeccc58606e0421a1ae275e391ee4347c6f52f6mtklein while (--height >= 0) { 26095cc012ccaea20f372893ae277ea0a8a6339d094mtklein SkBlitRow::Color32(device, device, width, color); 261edeccc58606e0421a1ae275e391ee4347c6f52f6mtklein device = (uint32_t*)((char*)device + rowBytes); 26257e080c1eb34253a3fc3829c2b03bb3ee63e006ftomhudson@google.com } 2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 265d7dc76f7e99309cbd09a5420c22e55b951067debbungeman#if defined _WIN32 2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#pragma warning ( pop ) 2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////// 2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkARGB32_Black_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[], 2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const int16_t runs[]) { 27341e010cb901c0da9066c4df562030808c9ccd7f8reed uint32_t* device = fDevice.writable_addr32(x, y); 2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPMColor black = (SkPMColor)(SK_A32_MASK << SK_A32_SHIFT); 2758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (;;) { 2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int count = runs[0]; 2788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count >= 0); 2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (count <= 0) { 2808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 2818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned aa = antialias[0]; 2838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (aa) { 2848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (aa == 255) { 2858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_memset32(device, black, count); 2868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 2878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPMColor src = aa << SK_A32_SHIFT; 2888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned dst_scale = 256 - aa; 2898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int n = count; 2908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 2918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com --n; 2928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device[n] = src + SkAlphaMulQ(device[n], dst_scale); 2938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (n > 0); 2948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com runs += count; 2978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com antialias += count; 2988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device += count; 2998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3026983f66d8b3a489133b751e2cef03e72a03bfeaereedvoid SkARGB32_Black_Blitter::blitAntiH2(int x, int y, U8CPU a0, U8CPU a1) { 30341e010cb901c0da9066c4df562030808c9ccd7f8reed uint32_t* device = fDevice.writable_addr32(x, y); 30441e010cb901c0da9066c4df562030808c9ccd7f8reed SkDEBUGCODE((void)fDevice.writable_addr32(x + 1, y);) 3056983f66d8b3a489133b751e2cef03e72a03bfeaereed 3066983f66d8b3a489133b751e2cef03e72a03bfeaereed device[0] = (a0 << SK_A32_SHIFT) + SkAlphaMulQ(device[0], 256 - a0); 3076983f66d8b3a489133b751e2cef03e72a03bfeaereed device[1] = (a1 << SK_A32_SHIFT) + SkAlphaMulQ(device[1], 256 - a1); 3086983f66d8b3a489133b751e2cef03e72a03bfeaereed} 3096983f66d8b3a489133b751e2cef03e72a03bfeaereed 3106983f66d8b3a489133b751e2cef03e72a03bfeaereedvoid SkARGB32_Black_Blitter::blitAntiV2(int x, int y, U8CPU a0, U8CPU a1) { 31141e010cb901c0da9066c4df562030808c9ccd7f8reed uint32_t* device = fDevice.writable_addr32(x, y); 31241e010cb901c0da9066c4df562030808c9ccd7f8reed SkDEBUGCODE((void)fDevice.writable_addr32(x, y + 1);) 31395cc012ccaea20f372893ae277ea0a8a6339d094mtklein 3146983f66d8b3a489133b751e2cef03e72a03bfeaereed device[0] = (a0 << SK_A32_SHIFT) + SkAlphaMulQ(device[0], 256 - a0); 3156983f66d8b3a489133b751e2cef03e72a03bfeaereed device = (uint32_t*)((char*)device + fDevice.rowBytes()); 3166983f66d8b3a489133b751e2cef03e72a03bfeaereed device[0] = (a1 << SK_A32_SHIFT) + SkAlphaMulQ(device[0], 256 - a1); 3176983f66d8b3a489133b751e2cef03e72a03bfeaereed} 3186983f66d8b3a489133b751e2cef03e72a03bfeaereed 3191750bf17635e788198200f971d9cb66f67399363reed@google.com/////////////////////////////////////////////////////////////////////////////// 3208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 32113201e74f43b9c5fa173339eb36de515370e6973reed@google.com// Special version of SkBlitRow::Factory32 that knows we're in kSrc_Mode, 32213201e74f43b9c5fa173339eb36de515370e6973reed@google.com// instead of kSrcOver_Mode 32313201e74f43b9c5fa173339eb36de515370e6973reed@google.comstatic void blend_srcmode(SkPMColor* SK_RESTRICT device, 32413201e74f43b9c5fa173339eb36de515370e6973reed@google.com const SkPMColor* SK_RESTRICT span, 32513201e74f43b9c5fa173339eb36de515370e6973reed@google.com int count, U8CPU aa) { 32613201e74f43b9c5fa173339eb36de515370e6973reed@google.com int aa256 = SkAlpha255To256(aa); 32713201e74f43b9c5fa173339eb36de515370e6973reed@google.com for (int i = 0; i < count; ++i) { 32813201e74f43b9c5fa173339eb36de515370e6973reed@google.com device[i] = SkFourByteInterp256(span[i], device[i], aa256); 32913201e74f43b9c5fa173339eb36de515370e6973reed@google.com } 33013201e74f43b9c5fa173339eb36de515370e6973reed@google.com} 33113201e74f43b9c5fa173339eb36de515370e6973reed@google.com 33241e010cb901c0da9066c4df562030808c9ccd7f8reedSkARGB32_Shader_Blitter::SkARGB32_Shader_Blitter(const SkPixmap& device, 3334aed13889bd9085337e0d4c20df28686687b833bFlorin Malita const SkPaint& paint, SkShaderBase::Context* shaderContext) 33487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org : INHERITED(device, paint, shaderContext) 33587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org{ 3368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBuffer = (SkPMColor*)sk_malloc_throw(device.width() * (sizeof(SkPMColor))); 3378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 338374772bd61951f01bf84fe17bf53d8867681c9aereed fXfermode = SkXfermode::Peek(paint.getBlendMode()); 339c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com 340c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com int flags = 0; 3414aed13889bd9085337e0d4c20df28686687b833bFlorin Malita if (!(shaderContext->getFlags() & SkShaderBase::kOpaqueAlpha_Flag)) { 342c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com flags |= SkBlitRow::kSrcPixelAlpha_Flag32; 343c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com } 344c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com // we call this on the output from the shader 345c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com fProc32 = SkBlitRow::Factory32(flags); 346c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com // we call this on the output from the shader + alpha from the aa buffer 347c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com fProc32Blend = SkBlitRow::Factory32(flags | SkBlitRow::kGlobalAlpha_Flag32); 34813201e74f43b9c5fa173339eb36de515370e6973reed@google.com 34913201e74f43b9c5fa173339eb36de515370e6973reed@google.com fShadeDirectlyIntoDevice = false; 35096fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (fXfermode == nullptr) { 3514aed13889bd9085337e0d4c20df28686687b833bFlorin Malita if (shaderContext->getFlags() & SkShaderBase::kOpaqueAlpha_Flag) { 35213201e74f43b9c5fa173339eb36de515370e6973reed@google.com fShadeDirectlyIntoDevice = true; 35313201e74f43b9c5fa173339eb36de515370e6973reed@google.com } 35413201e74f43b9c5fa173339eb36de515370e6973reed@google.com } else { 355cde9031a5a347a762a3946d216f96542d9cfcef4Mike Reed if (SkBlendMode::kSrc == paint.getBlendMode()) { 356cde9031a5a347a762a3946d216f96542d9cfcef4Mike Reed fShadeDirectlyIntoDevice = true; 357cde9031a5a347a762a3946d216f96542d9cfcef4Mike Reed fProc32Blend = blend_srcmode; 35813201e74f43b9c5fa173339eb36de515370e6973reed@google.com } 35913201e74f43b9c5fa173339eb36de515370e6973reed@google.com } 36013201e74f43b9c5fa173339eb36de515370e6973reed@google.com 3614aed13889bd9085337e0d4c20df28686687b833bFlorin Malita fConstInY = SkToBool(shaderContext->getFlags() & SkShaderBase::kConstInY32_Flag); 3628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkARGB32_Shader_Blitter::~SkARGB32_Shader_Blitter() { 3658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_free(fBuffer); 3668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkARGB32_Shader_Blitter::blitH(int x, int y, int width) { 3698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width()); 3708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 37141e010cb901c0da9066c4df562030808c9ccd7f8reed uint32_t* device = fDevice.writable_addr32(x, y); 3728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 37313201e74f43b9c5fa173339eb36de515370e6973reed@google.com if (fShadeDirectlyIntoDevice) { 37487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org fShaderContext->shadeSpan(x, y, device, width); 3758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 3768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPMColor* span = fBuffer; 37787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org fShaderContext->shadeSpan(x, y, span, width); 3788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fXfermode) { 37996fcdcc219d2a0d3579719b84b28bede76efba64halcanary fXfermode->xfer32(device, span, width, nullptr); 3808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 381c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com fProc32(device, span, width, 255); 3828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3863bafe74a29c37761082980ed4ee9b831256bd27ereed@google.comvoid SkARGB32_Shader_Blitter::blitRect(int x, int y, int width, int height) { 3873bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com SkASSERT(x >= 0 && y >= 0 && 3883bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com x + width <= fDevice.width() && y + height <= fDevice.height()); 389f57c01bdcfdf1c923b9a473974bfe6f8c66eca3eskia.committer@gmail.com 3904aed13889bd9085337e0d4c20df28686687b833bFlorin Malita uint32_t* device = fDevice.writable_addr32(x, y); 3914aed13889bd9085337e0d4c20df28686687b833bFlorin Malita size_t deviceRB = fDevice.rowBytes(); 3924aed13889bd9085337e0d4c20df28686687b833bFlorin Malita auto* shaderContext = fShaderContext; 3934aed13889bd9085337e0d4c20df28686687b833bFlorin Malita SkPMColor* span = fBuffer; 39413201e74f43b9c5fa173339eb36de515370e6973reed@google.com 39513201e74f43b9c5fa173339eb36de515370e6973reed@google.com if (fConstInY) { 39613201e74f43b9c5fa173339eb36de515370e6973reed@google.com if (fShadeDirectlyIntoDevice) { 39713201e74f43b9c5fa173339eb36de515370e6973reed@google.com // shade the first row directly into the device 39887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org shaderContext->shadeSpan(x, y, device, width); 39913201e74f43b9c5fa173339eb36de515370e6973reed@google.com span = device; 40013201e74f43b9c5fa173339eb36de515370e6973reed@google.com while (--height > 0) { 40113201e74f43b9c5fa173339eb36de515370e6973reed@google.com device = (uint32_t*)((char*)device + deviceRB); 40213201e74f43b9c5fa173339eb36de515370e6973reed@google.com memcpy(device, span, width << 2); 40313201e74f43b9c5fa173339eb36de515370e6973reed@google.com } 40413201e74f43b9c5fa173339eb36de515370e6973reed@google.com } else { 40587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org shaderContext->shadeSpan(x, y, span, width); 40613201e74f43b9c5fa173339eb36de515370e6973reed@google.com SkXfermode* xfer = fXfermode; 40713201e74f43b9c5fa173339eb36de515370e6973reed@google.com if (xfer) { 40813201e74f43b9c5fa173339eb36de515370e6973reed@google.com do { 40996fcdcc219d2a0d3579719b84b28bede76efba64halcanary xfer->xfer32(device, span, width, nullptr); 41013201e74f43b9c5fa173339eb36de515370e6973reed@google.com y += 1; 41113201e74f43b9c5fa173339eb36de515370e6973reed@google.com device = (uint32_t*)((char*)device + deviceRB); 41213201e74f43b9c5fa173339eb36de515370e6973reed@google.com } while (--height > 0); 41313201e74f43b9c5fa173339eb36de515370e6973reed@google.com } else { 41413201e74f43b9c5fa173339eb36de515370e6973reed@google.com SkBlitRow::Proc32 proc = fProc32; 41513201e74f43b9c5fa173339eb36de515370e6973reed@google.com do { 41613201e74f43b9c5fa173339eb36de515370e6973reed@google.com proc(device, span, width, 255); 41713201e74f43b9c5fa173339eb36de515370e6973reed@google.com y += 1; 41813201e74f43b9c5fa173339eb36de515370e6973reed@google.com device = (uint32_t*)((char*)device + deviceRB); 41913201e74f43b9c5fa173339eb36de515370e6973reed@google.com } while (--height > 0); 42013201e74f43b9c5fa173339eb36de515370e6973reed@google.com } 42113201e74f43b9c5fa173339eb36de515370e6973reed@google.com } 42213201e74f43b9c5fa173339eb36de515370e6973reed@google.com return; 42313201e74f43b9c5fa173339eb36de515370e6973reed@google.com } 4243bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com 42513201e74f43b9c5fa173339eb36de515370e6973reed@google.com if (fShadeDirectlyIntoDevice) { 4268aeec29bec673e7a3585625dc48e00e51897d474Mike Reed do { 4278aeec29bec673e7a3585625dc48e00e51897d474Mike Reed shaderContext->shadeSpan(x, y, device, width); 4288aeec29bec673e7a3585625dc48e00e51897d474Mike Reed y += 1; 4298aeec29bec673e7a3585625dc48e00e51897d474Mike Reed device = (uint32_t*)((char*)device + deviceRB); 4308aeec29bec673e7a3585625dc48e00e51897d474Mike Reed } while (--height > 0); 4313bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com } else { 4323bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com SkXfermode* xfer = fXfermode; 4333bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com if (xfer) { 4343bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com do { 43587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org shaderContext->shadeSpan(x, y, span, width); 43696fcdcc219d2a0d3579719b84b28bede76efba64halcanary xfer->xfer32(device, span, width, nullptr); 4373bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com y += 1; 4383bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com device = (uint32_t*)((char*)device + deviceRB); 4393bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com } while (--height > 0); 4403bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com } else { 4413bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com SkBlitRow::Proc32 proc = fProc32; 4423bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com do { 44387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org shaderContext->shadeSpan(x, y, span, width); 4443bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com proc(device, span, width, 255); 4453bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com y += 1; 4463bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com device = (uint32_t*)((char*)device + deviceRB); 4473bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com } while (--height > 0); 4483bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com } 4493bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com } 4503bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com} 4513bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com 4528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkARGB32_Shader_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[], 4538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const int16_t runs[]) { 4544aed13889bd9085337e0d4c20df28686687b833bFlorin Malita SkPMColor* span = fBuffer; 4554aed13889bd9085337e0d4c20df28686687b833bFlorin Malita uint32_t* device = fDevice.writable_addr32(x, y); 4564aed13889bd9085337e0d4c20df28686687b833bFlorin Malita auto* shaderContext = fShaderContext; 4578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 45813201e74f43b9c5fa173339eb36de515370e6973reed@google.com if (fXfermode && !fShadeDirectlyIntoDevice) { 4598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (;;) { 4608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkXfermode* xfer = fXfermode; 4618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int count = *runs; 4638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (count <= 0) 4648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 4658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int aa = *antialias; 4668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (aa) { 46787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org shaderContext->shadeSpan(x, y, span, count); 4688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (aa == 255) { 46996fcdcc219d2a0d3579719b84b28bede76efba64halcanary xfer->xfer32(device, span, count, nullptr); 4708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 4718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // count is almost always 1 4728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int i = count - 1; i >= 0; --i) { 4738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com xfer->xfer32(&device[i], &span[i], 1, antialias); 4748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device += count; 4788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com runs += count; 4798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com antialias += count; 4808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x += count; 48182065d667f64e232bcde2ad849756a6096fcbe6freed@google.com } 48213201e74f43b9c5fa173339eb36de515370e6973reed@google.com } else if (fShadeDirectlyIntoDevice || 4834aed13889bd9085337e0d4c20df28686687b833bFlorin Malita (shaderContext->getFlags() & SkShaderBase::kOpaqueAlpha_Flag)) { 4848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (;;) { 4858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int count = *runs; 4868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (count <= 0) { 4878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 4888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int aa = *antialias; 4908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (aa) { 491c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com if (aa == 255) { 492c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com // cool, have the shader draw right into the device 49387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org shaderContext->shadeSpan(x, y, device, count); 4948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 49587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org shaderContext->shadeSpan(x, y, span, count); 496c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com fProc32Blend(device, span, count, aa); 4978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device += count; 5008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com runs += count; 5018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com antialias += count; 5028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x += count; 50382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com } 50413201e74f43b9c5fa173339eb36de515370e6973reed@google.com } else { 5058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (;;) { 5068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int count = *runs; 5078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (count <= 0) { 5088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 5098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int aa = *antialias; 5118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (aa) { 51287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org shaderContext->shadeSpan(x, y, span, count); 5138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (aa == 255) { 514c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com fProc32(device, span, count, 255); 5158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 516c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com fProc32Blend(device, span, count, aa); 5178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device += count; 5208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com runs += count; 5218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com antialias += count; 5228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x += count; 52382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com } 5248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5261750bf17635e788198200f971d9cb66f67399363reed@google.com 5271750bf17635e788198200f971d9cb66f67399363reed@google.comvoid SkARGB32_Shader_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) { 5281750bf17635e788198200f971d9cb66f67399363reed@google.com // we only handle kA8 with an xfermode 5291750bf17635e788198200f971d9cb66f67399363reed@google.com if (fXfermode && (SkMask::kA8_Format != mask.fFormat)) { 5301750bf17635e788198200f971d9cb66f67399363reed@google.com this->INHERITED::blitMask(mask, clip); 5311750bf17635e788198200f971d9cb66f67399363reed@google.com return; 5321750bf17635e788198200f971d9cb66f67399363reed@google.com } 5331750bf17635e788198200f971d9cb66f67399363reed@google.com 5341750bf17635e788198200f971d9cb66f67399363reed@google.com SkASSERT(mask.fBounds.contains(clip)); 5351750bf17635e788198200f971d9cb66f67399363reed@google.com 5364aed13889bd9085337e0d4c20df28686687b833bFlorin Malita auto* shaderContext = fShaderContext; 53796fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkBlitMask::RowProc proc = nullptr; 5381750bf17635e788198200f971d9cb66f67399363reed@google.com if (!fXfermode) { 5391750bf17635e788198200f971d9cb66f67399363reed@google.com unsigned flags = 0; 5404aed13889bd9085337e0d4c20df28686687b833bFlorin Malita if (shaderContext->getFlags() & SkShaderBase::kOpaqueAlpha_Flag) { 5411750bf17635e788198200f971d9cb66f67399363reed@google.com flags |= SkBlitMask::kSrcIsOpaque_RowFlag; 5421750bf17635e788198200f971d9cb66f67399363reed@google.com } 543cba73780bbd12fd254229517aec04fcbf0b64b52commit-bot@chromium.org proc = SkBlitMask::RowFactory(kN32_SkColorType, mask.fFormat, 5441750bf17635e788198200f971d9cb66f67399363reed@google.com (SkBlitMask::RowFlags)flags); 54596fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == proc) { 5461750bf17635e788198200f971d9cb66f67399363reed@google.com this->INHERITED::blitMask(mask, clip); 5471750bf17635e788198200f971d9cb66f67399363reed@google.com return; 5481750bf17635e788198200f971d9cb66f67399363reed@google.com } 5491750bf17635e788198200f971d9cb66f67399363reed@google.com } 5501750bf17635e788198200f971d9cb66f67399363reed@google.com 5511750bf17635e788198200f971d9cb66f67399363reed@google.com const int x = clip.fLeft; 5521750bf17635e788198200f971d9cb66f67399363reed@google.com const int width = clip.width(); 5531750bf17635e788198200f971d9cb66f67399363reed@google.com int y = clip.fTop; 5541750bf17635e788198200f971d9cb66f67399363reed@google.com int height = clip.height(); 5551750bf17635e788198200f971d9cb66f67399363reed@google.com 55641e010cb901c0da9066c4df562030808c9ccd7f8reed char* dstRow = (char*)fDevice.writable_addr32(x, y); 5571750bf17635e788198200f971d9cb66f67399363reed@google.com const size_t dstRB = fDevice.rowBytes(); 5581750bf17635e788198200f971d9cb66f67399363reed@google.com const uint8_t* maskRow = (const uint8_t*)mask.getAddr(x, y); 5591750bf17635e788198200f971d9cb66f67399363reed@google.com const size_t maskRB = mask.fRowBytes; 5601750bf17635e788198200f971d9cb66f67399363reed@google.com 5611750bf17635e788198200f971d9cb66f67399363reed@google.com SkPMColor* span = fBuffer; 5621750bf17635e788198200f971d9cb66f67399363reed@google.com 5631750bf17635e788198200f971d9cb66f67399363reed@google.com if (fXfermode) { 5641750bf17635e788198200f971d9cb66f67399363reed@google.com SkASSERT(SkMask::kA8_Format == mask.fFormat); 5651750bf17635e788198200f971d9cb66f67399363reed@google.com SkXfermode* xfer = fXfermode; 5661750bf17635e788198200f971d9cb66f67399363reed@google.com do { 56787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org shaderContext->shadeSpan(x, y, span, width); 568c7a784cc8cb1c1dfcd39a32b2170ffe547904e9fherb xfer->xfer32(reinterpret_cast<SkPMColor*>(dstRow), span, width, maskRow); 5691750bf17635e788198200f971d9cb66f67399363reed@google.com dstRow += dstRB; 5701750bf17635e788198200f971d9cb66f67399363reed@google.com maskRow += maskRB; 5711750bf17635e788198200f971d9cb66f67399363reed@google.com y += 1; 5721750bf17635e788198200f971d9cb66f67399363reed@google.com } while (--height > 0); 5731750bf17635e788198200f971d9cb66f67399363reed@google.com } else { 5741750bf17635e788198200f971d9cb66f67399363reed@google.com do { 57587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org shaderContext->shadeSpan(x, y, span, width); 576c7a784cc8cb1c1dfcd39a32b2170ffe547904e9fherb proc(reinterpret_cast<SkPMColor*>(dstRow), maskRow, span, width); 5771750bf17635e788198200f971d9cb66f67399363reed@google.com dstRow += dstRB; 5781750bf17635e788198200f971d9cb66f67399363reed@google.com maskRow += maskRB; 5791750bf17635e788198200f971d9cb66f67399363reed@google.com y += 1; 5801750bf17635e788198200f971d9cb66f67399363reed@google.com } while (--height > 0); 5811750bf17635e788198200f971d9cb66f67399363reed@google.com } 5821750bf17635e788198200f971d9cb66f67399363reed@google.com} 5831750bf17635e788198200f971d9cb66f67399363reed@google.com 58413201e74f43b9c5fa173339eb36de515370e6973reed@google.comvoid SkARGB32_Shader_Blitter::blitV(int x, int y, int height, SkAlpha alpha) { 58513201e74f43b9c5fa173339eb36de515370e6973reed@google.com SkASSERT(x >= 0 && y >= 0 && y + height <= fDevice.height()); 586886b25f14ce6a6974521f096eb5feac0b4327236skia.committer@gmail.com 5874aed13889bd9085337e0d4c20df28686687b833bFlorin Malita uint32_t* device = fDevice.writable_addr32(x, y); 5884aed13889bd9085337e0d4c20df28686687b833bFlorin Malita size_t deviceRB = fDevice.rowBytes(); 5894aed13889bd9085337e0d4c20df28686687b833bFlorin Malita auto* shaderContext = fShaderContext; 590886b25f14ce6a6974521f096eb5feac0b4327236skia.committer@gmail.com 59113201e74f43b9c5fa173339eb36de515370e6973reed@google.com if (fConstInY) { 59213201e74f43b9c5fa173339eb36de515370e6973reed@google.com SkPMColor c; 59387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org shaderContext->shadeSpan(x, y, &c, 1); 59413201e74f43b9c5fa173339eb36de515370e6973reed@google.com 59513201e74f43b9c5fa173339eb36de515370e6973reed@google.com if (fShadeDirectlyIntoDevice) { 59613201e74f43b9c5fa173339eb36de515370e6973reed@google.com if (255 == alpha) { 59713201e74f43b9c5fa173339eb36de515370e6973reed@google.com do { 59813201e74f43b9c5fa173339eb36de515370e6973reed@google.com *device = c; 59913201e74f43b9c5fa173339eb36de515370e6973reed@google.com device = (uint32_t*)((char*)device + deviceRB); 60013201e74f43b9c5fa173339eb36de515370e6973reed@google.com } while (--height > 0); 60113201e74f43b9c5fa173339eb36de515370e6973reed@google.com } else { 60213201e74f43b9c5fa173339eb36de515370e6973reed@google.com do { 60313201e74f43b9c5fa173339eb36de515370e6973reed@google.com *device = SkFourByteInterp(c, *device, alpha); 60413201e74f43b9c5fa173339eb36de515370e6973reed@google.com device = (uint32_t*)((char*)device + deviceRB); 60513201e74f43b9c5fa173339eb36de515370e6973reed@google.com } while (--height > 0); 60613201e74f43b9c5fa173339eb36de515370e6973reed@google.com } 60713201e74f43b9c5fa173339eb36de515370e6973reed@google.com } else { 60813201e74f43b9c5fa173339eb36de515370e6973reed@google.com SkXfermode* xfer = fXfermode; 60913201e74f43b9c5fa173339eb36de515370e6973reed@google.com if (xfer) { 61013201e74f43b9c5fa173339eb36de515370e6973reed@google.com do { 61113201e74f43b9c5fa173339eb36de515370e6973reed@google.com xfer->xfer32(device, &c, 1, &alpha); 61213201e74f43b9c5fa173339eb36de515370e6973reed@google.com device = (uint32_t*)((char*)device + deviceRB); 61313201e74f43b9c5fa173339eb36de515370e6973reed@google.com } while (--height > 0); 61413201e74f43b9c5fa173339eb36de515370e6973reed@google.com } else { 61553007a2b1724c15c170340658daac012f9d909bereed@google.com SkBlitRow::Proc32 proc = (255 == alpha) ? fProc32 : fProc32Blend; 61613201e74f43b9c5fa173339eb36de515370e6973reed@google.com do { 61713201e74f43b9c5fa173339eb36de515370e6973reed@google.com proc(device, &c, 1, alpha); 61813201e74f43b9c5fa173339eb36de515370e6973reed@google.com device = (uint32_t*)((char*)device + deviceRB); 61913201e74f43b9c5fa173339eb36de515370e6973reed@google.com } while (--height > 0); 62013201e74f43b9c5fa173339eb36de515370e6973reed@google.com } 62113201e74f43b9c5fa173339eb36de515370e6973reed@google.com } 62213201e74f43b9c5fa173339eb36de515370e6973reed@google.com return; 62313201e74f43b9c5fa173339eb36de515370e6973reed@google.com } 62413201e74f43b9c5fa173339eb36de515370e6973reed@google.com 62513201e74f43b9c5fa173339eb36de515370e6973reed@google.com if (fShadeDirectlyIntoDevice) { 62613201e74f43b9c5fa173339eb36de515370e6973reed@google.com if (255 == alpha) { 6278aeec29bec673e7a3585625dc48e00e51897d474Mike Reed do { 6288aeec29bec673e7a3585625dc48e00e51897d474Mike Reed shaderContext->shadeSpan(x, y, device, 1); 6298aeec29bec673e7a3585625dc48e00e51897d474Mike Reed y += 1; 6308aeec29bec673e7a3585625dc48e00e51897d474Mike Reed device = (uint32_t*)((char*)device + deviceRB); 6318aeec29bec673e7a3585625dc48e00e51897d474Mike Reed } while (--height > 0); 6328aeec29bec673e7a3585625dc48e00e51897d474Mike Reed } else { 6338aeec29bec673e7a3585625dc48e00e51897d474Mike Reed do { 6348aeec29bec673e7a3585625dc48e00e51897d474Mike Reed SkPMColor c; 6358aeec29bec673e7a3585625dc48e00e51897d474Mike Reed shaderContext->shadeSpan(x, y, &c, 1); 6368aeec29bec673e7a3585625dc48e00e51897d474Mike Reed *device = SkFourByteInterp(c, *device, alpha); 6378aeec29bec673e7a3585625dc48e00e51897d474Mike Reed y += 1; 6388aeec29bec673e7a3585625dc48e00e51897d474Mike Reed device = (uint32_t*)((char*)device + deviceRB); 6398aeec29bec673e7a3585625dc48e00e51897d474Mike Reed } while (--height > 0); 64013201e74f43b9c5fa173339eb36de515370e6973reed@google.com } 64113201e74f43b9c5fa173339eb36de515370e6973reed@google.com } else { 64213201e74f43b9c5fa173339eb36de515370e6973reed@google.com SkPMColor* span = fBuffer; 64313201e74f43b9c5fa173339eb36de515370e6973reed@google.com SkXfermode* xfer = fXfermode; 64413201e74f43b9c5fa173339eb36de515370e6973reed@google.com if (xfer) { 64513201e74f43b9c5fa173339eb36de515370e6973reed@google.com do { 64687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org shaderContext->shadeSpan(x, y, span, 1); 64713201e74f43b9c5fa173339eb36de515370e6973reed@google.com xfer->xfer32(device, span, 1, &alpha); 64813201e74f43b9c5fa173339eb36de515370e6973reed@google.com y += 1; 64913201e74f43b9c5fa173339eb36de515370e6973reed@google.com device = (uint32_t*)((char*)device + deviceRB); 65013201e74f43b9c5fa173339eb36de515370e6973reed@google.com } while (--height > 0); 65113201e74f43b9c5fa173339eb36de515370e6973reed@google.com } else { 65259d968fb29b39cc1f4eb0ac687007c74618c6c1creed@google.com SkBlitRow::Proc32 proc = (255 == alpha) ? fProc32 : fProc32Blend; 65313201e74f43b9c5fa173339eb36de515370e6973reed@google.com do { 65487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org shaderContext->shadeSpan(x, y, span, 1); 65559d968fb29b39cc1f4eb0ac687007c74618c6c1creed@google.com proc(device, span, 1, alpha); 65613201e74f43b9c5fa173339eb36de515370e6973reed@google.com y += 1; 65713201e74f43b9c5fa173339eb36de515370e6973reed@google.com device = (uint32_t*)((char*)device + deviceRB); 65813201e74f43b9c5fa173339eb36de515370e6973reed@google.com } while (--height > 0); 65913201e74f43b9c5fa173339eb36de515370e6973reed@google.com } 66013201e74f43b9c5fa173339eb36de515370e6973reed@google.com } 66113201e74f43b9c5fa173339eb36de515370e6973reed@google.com} 662