1685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com/* 2685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * Copyright 2006 The Android Open Source Project 3685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * 4685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * found in the LICENSE file. 6685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com */ 7685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com 8bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "SkCoreBlitters.h" 9bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "SkColorPriv.h" 10bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "SkShader.h" 11bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "SkUtils.h" 12bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "SkXfermode.h" 139fccaf03218080b80f8da85f5b422aca469f2b1breed@google.com#include "SkBlitMask.h" 14bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 15c8ee9920ac53db56da7e53e591057f359f03693dreed@google.com/////////////////////////////////////////////////////////////////////////////// 16c8ee9920ac53db56da7e53e591057f359f03693dreed@google.com 17e216b62841acd5db9d91b63960805568259a2e0ereed@android.comstatic void SkARGB32_Blit32(const SkBitmap& device, const SkMask& mask, 18935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com const SkIRect& clip, SkPMColor srcColor) { 19935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com U8CPU alpha = SkGetPackedA32(srcColor); 20935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com unsigned flags = SkBlitRow::kSrcPixelAlpha_Flag32; 21935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com if (alpha != 255) { 22935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com flags |= SkBlitRow::kGlobalAlpha_Flag32; 23935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com } 24935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com SkBlitRow::Proc32 proc = SkBlitRow::Factory32(flags); 25e216b62841acd5db9d91b63960805568259a2e0ereed@android.com 26e216b62841acd5db9d91b63960805568259a2e0ereed@android.com int x = clip.fLeft; 27e216b62841acd5db9d91b63960805568259a2e0ereed@android.com int y = clip.fTop; 28e216b62841acd5db9d91b63960805568259a2e0ereed@android.com int width = clip.width(); 29e216b62841acd5db9d91b63960805568259a2e0ereed@android.com int height = clip.height(); 30919114813d58933c9d9433b141e0222c34b700b1reed@google.com 31935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com SkPMColor* dstRow = device.getAddr32(x, y); 32e2961f787751b880e535e893ca068af71218ba32reed@google.com const SkPMColor* srcRow = reinterpret_cast<const SkPMColor*>(mask.getAddr8(x, y)); 33e216b62841acd5db9d91b63960805568259a2e0ereed@android.com 34e216b62841acd5db9d91b63960805568259a2e0ereed@android.com do { 35935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com proc(dstRow, srcRow, width, alpha); 36e216b62841acd5db9d91b63960805568259a2e0ereed@android.com dstRow = (SkPMColor*)((char*)dstRow + device.rowBytes()); 37e216b62841acd5db9d91b63960805568259a2e0ereed@android.com srcRow = (const SkPMColor*)((const char*)srcRow + mask.fRowBytes); 38e216b62841acd5db9d91b63960805568259a2e0ereed@android.com } while (--height != 0); 39e216b62841acd5db9d91b63960805568259a2e0ereed@android.com} 40e216b62841acd5db9d91b63960805568259a2e0ereed@android.com 41e216b62841acd5db9d91b63960805568259a2e0ereed@android.com////////////////////////////////////////////////////////////////////////////////////// 42e216b62841acd5db9d91b63960805568259a2e0ereed@android.com 43bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comSkARGB32_Blitter::SkARGB32_Blitter(const SkBitmap& device, const SkPaint& paint) 44bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com : INHERITED(device) { 45def3e927ac43495ad443f186a1717cdfd15d1630reed@google.com SkColor color = paint.getColor(); 46def3e927ac43495ad443f186a1717cdfd15d1630reed@google.com fColor = color; 47bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 48bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fSrcA = SkColorGetA(color); 49bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com unsigned scale = SkAlpha255To256(fSrcA); 50bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fSrcR = SkAlphaMul(SkColorGetR(color), scale); 51bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fSrcG = SkAlphaMul(SkColorGetG(color), scale); 52bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fSrcB = SkAlphaMul(SkColorGetB(color), scale); 53bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 54bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fPMColor = SkPackARGB32(fSrcA, fSrcR, fSrcG, fSrcB); 553c376b1cb0de6fe8e496a756742d117562c3f26dsenorblanco@chromium.org fColor32Proc = SkBlitRow::ColorProcFactory(); 56c0a3e317e6385742b150a2164adeda99c176b6ddtomhudson@google.com fColorRect32Proc = SkBlitRow::ColorRectProcFactory(); 57bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 58bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 59bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comconst SkBitmap* SkARGB32_Blitter::justAnOpaqueColor(uint32_t* value) { 60bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (255 == fSrcA) { 61bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com *value = fPMColor; 62bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return &fDevice; 63bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 64bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return NULL; 65bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 66bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 67bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#if defined _WIN32 && _MSC_VER >= 1300 // disable warning : local variable used without having been initialized 68bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#pragma warning ( push ) 69bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#pragma warning ( disable : 4701 ) 70bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#endif 71bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 72bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkARGB32_Blitter::blitH(int x, int y, int width) { 73bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width()); 74bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 753c376b1cb0de6fe8e496a756742d117562c3f26dsenorblanco@chromium.org uint32_t* device = fDevice.getAddr32(x, y); 763c376b1cb0de6fe8e496a756742d117562c3f26dsenorblanco@chromium.org fColor32Proc(device, device, width, fPMColor); 77bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 78bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 79bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkARGB32_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[], 80bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com const int16_t runs[]) { 81bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (fSrcA == 0) { 82bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return; 83bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 84bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 85bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com uint32_t color = fPMColor; 86bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com uint32_t* device = fDevice.getAddr32(x, y); 87bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com unsigned opaqueMask = fSrcA; // if fSrcA is 0xFF, then we will catch the fast opaque case 88bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 89bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com for (;;) { 90bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int count = runs[0]; 91bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(count >= 0); 92bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (count <= 0) { 93bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return; 94bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 95bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com unsigned aa = antialias[0]; 96bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (aa) { 97bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if ((opaqueMask & aa) == 255) { 98bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com sk_memset32(device, color, count); 99bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } else { 100cdbc582d7a596ad26571dc8c7e857f74d3a8ae7creed@android.com uint32_t sc = SkAlphaMulQ(color, SkAlpha255To256(aa)); 1013c376b1cb0de6fe8e496a756742d117562c3f26dsenorblanco@chromium.org fColor32Proc(device, device, count, sc); 102bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 103bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 104bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com runs += count; 105bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com antialias += count; 106bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com device += count; 107bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 108bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 109bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 110bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com////////////////////////////////////////////////////////////////////////////////////// 111bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 112bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#define solid_8_pixels(mask, dst, color) \ 113bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com do { \ 114bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (mask & 0x80) dst[0] = color; \ 115bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (mask & 0x40) dst[1] = color; \ 116bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (mask & 0x20) dst[2] = color; \ 117bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (mask & 0x10) dst[3] = color; \ 118bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (mask & 0x08) dst[4] = color; \ 119bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (mask & 0x04) dst[5] = color; \ 120bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (mask & 0x02) dst[6] = color; \ 121bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (mask & 0x01) dst[7] = color; \ 122bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } while (0) 123bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 124bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#define SK_BLITBWMASK_NAME SkARGB32_BlitBW 125bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#define SK_BLITBWMASK_ARGS , SkPMColor color 126bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#define SK_BLITBWMASK_BLIT8(mask, dst) solid_8_pixels(mask, dst, color) 127bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#define SK_BLITBWMASK_GETADDR getAddr32 128bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#define SK_BLITBWMASK_DEVTYPE uint32_t 129bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "SkBlitBWMaskTemplate.h" 130bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 131bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#define blend_8_pixels(mask, dst, sc, dst_scale) \ 132bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com do { \ 133bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (mask & 0x80) { dst[0] = sc + SkAlphaMulQ(dst[0], dst_scale); } \ 134bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (mask & 0x40) { dst[1] = sc + SkAlphaMulQ(dst[1], dst_scale); } \ 135bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (mask & 0x20) { dst[2] = sc + SkAlphaMulQ(dst[2], dst_scale); } \ 136bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (mask & 0x10) { dst[3] = sc + SkAlphaMulQ(dst[3], dst_scale); } \ 137bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (mask & 0x08) { dst[4] = sc + SkAlphaMulQ(dst[4], dst_scale); } \ 138bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (mask & 0x04) { dst[5] = sc + SkAlphaMulQ(dst[5], dst_scale); } \ 139bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (mask & 0x02) { dst[6] = sc + SkAlphaMulQ(dst[6], dst_scale); } \ 140bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (mask & 0x01) { dst[7] = sc + SkAlphaMulQ(dst[7], dst_scale); } \ 141bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } while (0) 142bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 143bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#define SK_BLITBWMASK_NAME SkARGB32_BlendBW 144bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#define SK_BLITBWMASK_ARGS , uint32_t sc, unsigned dst_scale 145bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#define SK_BLITBWMASK_BLIT8(mask, dst) blend_8_pixels(mask, dst, sc, dst_scale) 146bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#define SK_BLITBWMASK_GETADDR getAddr32 147bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#define SK_BLITBWMASK_DEVTYPE uint32_t 148bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "SkBlitBWMaskTemplate.h" 149bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 150bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkARGB32_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) { 151bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(mask.fBounds.contains(clip)); 152bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(fSrcA != 0xFF); 153bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 154bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (fSrcA == 0) { 155bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return; 156bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 157bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1589bed9d7780715fe1c6aae1df1ceee692a8c365a2reed@google.com if (SkBlitMask::BlitColor(fDevice, mask, clip, fColor)) { 1599bed9d7780715fe1c6aae1df1ceee692a8c365a2reed@google.com return; 1609bed9d7780715fe1c6aae1df1ceee692a8c365a2reed@google.com } 1619bed9d7780715fe1c6aae1df1ceee692a8c365a2reed@google.com 162bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (mask.fFormat == SkMask::kBW_Format) { 163bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkARGB32_BlendBW(fDevice, mask, clip, fPMColor, SkAlpha255To256(255 - fSrcA)); 164e216b62841acd5db9d91b63960805568259a2e0ereed@android.com } else if (SkMask::kARGB32_Format == mask.fFormat) { 165935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com SkARGB32_Blit32(fDevice, mask, clip, fPMColor); 166bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 167bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 168bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 169bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkARGB32_Opaque_Blitter::blitMask(const SkMask& mask, 170bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com const SkIRect& clip) { 171bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(mask.fBounds.contains(clip)); 172bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1739bed9d7780715fe1c6aae1df1ceee692a8c365a2reed@google.com if (SkBlitMask::BlitColor(fDevice, mask, clip, fColor)) { 1749bed9d7780715fe1c6aae1df1ceee692a8c365a2reed@google.com return; 1759bed9d7780715fe1c6aae1df1ceee692a8c365a2reed@google.com } 176935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com 177bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (mask.fFormat == SkMask::kBW_Format) { 178bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkARGB32_BlitBW(fDevice, mask, clip, fPMColor); 179e216b62841acd5db9d91b63960805568259a2e0ereed@android.com } else if (SkMask::kARGB32_Format == mask.fFormat) { 180935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com SkARGB32_Blit32(fDevice, mask, clip, fPMColor); 181935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com } 182bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 183bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1845048d4852ca019b359ebdaffaec0e28fc8dcd689reed@google.com/////////////////////////////////////////////////////////////////////////////// 185bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 186bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkARGB32_Blitter::blitV(int x, int y, int height, SkAlpha alpha) { 187bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (alpha == 0 || fSrcA == 0) { 188bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return; 189bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 190bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 191bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com uint32_t* device = fDevice.getAddr32(x, y); 192bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com uint32_t color = fPMColor; 193bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 194bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (alpha != 255) { 195bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com color = SkAlphaMulQ(color, SkAlpha255To256(alpha)); 196bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 197bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 198bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com unsigned dst_scale = 255 - SkGetPackedA32(color); 1992dcc8513452824388c1f2bb47cb4095cfd7abbfescroggo@google.com size_t rowBytes = fDevice.rowBytes(); 200bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com while (--height >= 0) { 2015048d4852ca019b359ebdaffaec0e28fc8dcd689reed@google.com device[0] = color + SkAlphaMulQ(device[0], dst_scale); 202bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com device = (uint32_t*)((char*)device + rowBytes); 203bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 204bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 205bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 206bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkARGB32_Blitter::blitRect(int x, int y, int width, int height) { 207bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width() && y + height <= fDevice.height()); 208bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 209bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (fSrcA == 0) { 210bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return; 211bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 212bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 213bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com uint32_t* device = fDevice.getAddr32(x, y); 214bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com uint32_t color = fPMColor; 215cdbc582d7a596ad26571dc8c7e857f74d3a8ae7creed@android.com size_t rowBytes = fDevice.rowBytes(); 216bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 21754547aa4eb530859a7dd934aef008012dea19228tomhudson@google.com if (255 == SkGetPackedA32(color)) { 218c0a3e317e6385742b150a2164adeda99c176b6ddtomhudson@google.com fColorRect32Proc(device, width, height, rowBytes, color); 21954547aa4eb530859a7dd934aef008012dea19228tomhudson@google.com } else { 22054547aa4eb530859a7dd934aef008012dea19228tomhudson@google.com while (--height >= 0) { 22154547aa4eb530859a7dd934aef008012dea19228tomhudson@google.com fColor32Proc(device, device, width, color); 22254547aa4eb530859a7dd934aef008012dea19228tomhudson@google.com device = (uint32_t*)((char*)device + rowBytes); 22354547aa4eb530859a7dd934aef008012dea19228tomhudson@google.com } 22454547aa4eb530859a7dd934aef008012dea19228tomhudson@google.com } 225bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 226bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 227bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#if defined _WIN32 && _MSC_VER >= 1300 228bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#pragma warning ( pop ) 229bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#endif 230bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 231bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com/////////////////////////////////////////////////////////////////////// 232bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 233bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkARGB32_Black_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[], 234bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com const int16_t runs[]) { 235bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com uint32_t* device = fDevice.getAddr32(x, y); 236bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkPMColor black = (SkPMColor)(SK_A32_MASK << SK_A32_SHIFT); 237bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 238bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com for (;;) { 239bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int count = runs[0]; 240bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(count >= 0); 241bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (count <= 0) { 242bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return; 243bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 244bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com unsigned aa = antialias[0]; 245bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (aa) { 246bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (aa == 255) { 247bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com sk_memset32(device, black, count); 248bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } else { 249bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkPMColor src = aa << SK_A32_SHIFT; 250bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com unsigned dst_scale = 256 - aa; 251bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int n = count; 252bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com do { 253bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com --n; 254bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com device[n] = src + SkAlphaMulQ(device[n], dst_scale); 255bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } while (n > 0); 256bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 257bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 258bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com runs += count; 259bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com antialias += count; 260bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com device += count; 261bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 262bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 263bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 26426cb94b362c50333cde0ed993dae6aa747b307dareed@google.com/////////////////////////////////////////////////////////////////////////////// 265bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 266e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com// Special version of SkBlitRow::Factory32 that knows we're in kSrc_Mode, 267e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com// instead of kSrcOver_Mode 268e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.comstatic void blend_srcmode(SkPMColor* SK_RESTRICT device, 269e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com const SkPMColor* SK_RESTRICT span, 270e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com int count, U8CPU aa) { 271e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com int aa256 = SkAlpha255To256(aa); 272e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com for (int i = 0; i < count; ++i) { 273e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com device[i] = SkFourByteInterp256(span[i], device[i], aa256); 274e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com } 275e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com} 276e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com 277bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comSkARGB32_Shader_Blitter::SkARGB32_Shader_Blitter(const SkBitmap& device, 278cdbc582d7a596ad26571dc8c7e857f74d3a8ae7creed@android.com const SkPaint& paint) : INHERITED(device, paint) { 279bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fBuffer = (SkPMColor*)sk_malloc_throw(device.width() * (sizeof(SkPMColor))); 280bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 281cdbc582d7a596ad26571dc8c7e857f74d3a8ae7creed@android.com fXfermode = paint.getXfermode(); 282cdbc582d7a596ad26571dc8c7e857f74d3a8ae7creed@android.com SkSafeRef(fXfermode); 283cdbc582d7a596ad26571dc8c7e857f74d3a8ae7creed@android.com 284cdbc582d7a596ad26571dc8c7e857f74d3a8ae7creed@android.com int flags = 0; 285cdbc582d7a596ad26571dc8c7e857f74d3a8ae7creed@android.com if (!(fShader->getFlags() & SkShader::kOpaqueAlpha_Flag)) { 286cdbc582d7a596ad26571dc8c7e857f74d3a8ae7creed@android.com flags |= SkBlitRow::kSrcPixelAlpha_Flag32; 287cdbc582d7a596ad26571dc8c7e857f74d3a8ae7creed@android.com } 288cdbc582d7a596ad26571dc8c7e857f74d3a8ae7creed@android.com // we call this on the output from the shader 289cdbc582d7a596ad26571dc8c7e857f74d3a8ae7creed@android.com fProc32 = SkBlitRow::Factory32(flags); 290cdbc582d7a596ad26571dc8c7e857f74d3a8ae7creed@android.com // we call this on the output from the shader + alpha from the aa buffer 291cdbc582d7a596ad26571dc8c7e857f74d3a8ae7creed@android.com fProc32Blend = SkBlitRow::Factory32(flags | SkBlitRow::kGlobalAlpha_Flag32); 292e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com 293e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com fShadeDirectlyIntoDevice = false; 294e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com if (fXfermode == NULL) { 295e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com if (fShader->getFlags() & SkShader::kOpaqueAlpha_Flag) { 296e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com fShadeDirectlyIntoDevice = true; 297e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com } 298e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com } else { 299e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com SkXfermode::Mode mode; 300e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com if (fXfermode->asMode(&mode)) { 301e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com if (SkXfermode::kSrc_Mode == mode) { 302e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com fShadeDirectlyIntoDevice = true; 303e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com fProc32Blend = blend_srcmode; 304e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com } 305e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com } 306e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com } 307e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com 308e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com fConstInY = SkToBool(fShader->getFlags() & SkShader::kConstInY32_Flag); 309bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 310bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 311bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comSkARGB32_Shader_Blitter::~SkARGB32_Shader_Blitter() { 312919114813d58933c9d9433b141e0222c34b700b1reed@google.com SkSafeUnref(fXfermode); 313bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com sk_free(fBuffer); 314bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 315bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 316bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkARGB32_Shader_Blitter::blitH(int x, int y, int width) { 317bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width()); 318bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 319bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com uint32_t* device = fDevice.getAddr32(x, y); 320bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 321e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com if (fShadeDirectlyIntoDevice) { 322bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fShader->shadeSpan(x, y, device, width); 323bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } else { 324bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkPMColor* span = fBuffer; 325bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fShader->shadeSpan(x, y, span, width); 326bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (fXfermode) { 327bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fXfermode->xfer32(device, span, width, NULL); 328bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } else { 329cdbc582d7a596ad26571dc8c7e857f74d3a8ae7creed@android.com fProc32(device, span, width, 255); 330bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 331bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 332bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 333bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 334f1bbd533e266687c5c2b6b406e06ae28bc500920reed@google.comvoid SkARGB32_Shader_Blitter::blitRect(int x, int y, int width, int height) { 335f1bbd533e266687c5c2b6b406e06ae28bc500920reed@google.com SkASSERT(x >= 0 && y >= 0 && 336f1bbd533e266687c5c2b6b406e06ae28bc500920reed@google.com x + width <= fDevice.width() && y + height <= fDevice.height()); 337d16b9898e212b0b141b8849ce89e08dc23dadd39skia.committer@gmail.com 338f1bbd533e266687c5c2b6b406e06ae28bc500920reed@google.com uint32_t* device = fDevice.getAddr32(x, y); 339f1bbd533e266687c5c2b6b406e06ae28bc500920reed@google.com size_t deviceRB = fDevice.rowBytes(); 340f1bbd533e266687c5c2b6b406e06ae28bc500920reed@google.com SkShader* shader = fShader; 341e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com SkPMColor* span = fBuffer; 342e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com 343e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com if (fConstInY) { 344e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com if (fShadeDirectlyIntoDevice) { 345e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com // shade the first row directly into the device 346e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com fShader->shadeSpan(x, y, device, width); 347e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com span = device; 348e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com while (--height > 0) { 349e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com device = (uint32_t*)((char*)device + deviceRB); 350e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com memcpy(device, span, width << 2); 351e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com } 352e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com } else { 353e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com fShader->shadeSpan(x, y, span, width); 354e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com SkXfermode* xfer = fXfermode; 355e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com if (xfer) { 356e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com do { 357e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com xfer->xfer32(device, span, width, NULL); 358e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com y += 1; 359e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com device = (uint32_t*)((char*)device + deviceRB); 360e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com } while (--height > 0); 361e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com } else { 362e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com SkBlitRow::Proc32 proc = fProc32; 363e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com do { 364e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com proc(device, span, width, 255); 365e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com y += 1; 366e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com device = (uint32_t*)((char*)device + deviceRB); 367e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com } while (--height > 0); 368e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com } 369e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com } 370e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com return; 371e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com } 372f1bbd533e266687c5c2b6b406e06ae28bc500920reed@google.com 373e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com if (fShadeDirectlyIntoDevice) { 374f1bbd533e266687c5c2b6b406e06ae28bc500920reed@google.com void* ctx; 375f1bbd533e266687c5c2b6b406e06ae28bc500920reed@google.com SkShader::ShadeProc shadeProc = fShader->asAShadeProc(&ctx); 376f1bbd533e266687c5c2b6b406e06ae28bc500920reed@google.com if (shadeProc) { 377f1bbd533e266687c5c2b6b406e06ae28bc500920reed@google.com do { 378f1bbd533e266687c5c2b6b406e06ae28bc500920reed@google.com shadeProc(ctx, x, y, device, width); 379f1bbd533e266687c5c2b6b406e06ae28bc500920reed@google.com y += 1; 380f1bbd533e266687c5c2b6b406e06ae28bc500920reed@google.com device = (uint32_t*)((char*)device + deviceRB); 381f1bbd533e266687c5c2b6b406e06ae28bc500920reed@google.com } while (--height > 0); 382f1bbd533e266687c5c2b6b406e06ae28bc500920reed@google.com } else { 383f1bbd533e266687c5c2b6b406e06ae28bc500920reed@google.com do { 384f1bbd533e266687c5c2b6b406e06ae28bc500920reed@google.com shader->shadeSpan(x, y, device, width); 385f1bbd533e266687c5c2b6b406e06ae28bc500920reed@google.com y += 1; 386f1bbd533e266687c5c2b6b406e06ae28bc500920reed@google.com device = (uint32_t*)((char*)device + deviceRB); 387f1bbd533e266687c5c2b6b406e06ae28bc500920reed@google.com } while (--height > 0); 388f1bbd533e266687c5c2b6b406e06ae28bc500920reed@google.com } 389f1bbd533e266687c5c2b6b406e06ae28bc500920reed@google.com } else { 390f1bbd533e266687c5c2b6b406e06ae28bc500920reed@google.com SkXfermode* xfer = fXfermode; 391f1bbd533e266687c5c2b6b406e06ae28bc500920reed@google.com if (xfer) { 392f1bbd533e266687c5c2b6b406e06ae28bc500920reed@google.com do { 393f1bbd533e266687c5c2b6b406e06ae28bc500920reed@google.com shader->shadeSpan(x, y, span, width); 394f1bbd533e266687c5c2b6b406e06ae28bc500920reed@google.com xfer->xfer32(device, span, width, NULL); 395f1bbd533e266687c5c2b6b406e06ae28bc500920reed@google.com y += 1; 396f1bbd533e266687c5c2b6b406e06ae28bc500920reed@google.com device = (uint32_t*)((char*)device + deviceRB); 397f1bbd533e266687c5c2b6b406e06ae28bc500920reed@google.com } while (--height > 0); 398f1bbd533e266687c5c2b6b406e06ae28bc500920reed@google.com } else { 399f1bbd533e266687c5c2b6b406e06ae28bc500920reed@google.com SkBlitRow::Proc32 proc = fProc32; 400f1bbd533e266687c5c2b6b406e06ae28bc500920reed@google.com do { 401f1bbd533e266687c5c2b6b406e06ae28bc500920reed@google.com shader->shadeSpan(x, y, span, width); 402f1bbd533e266687c5c2b6b406e06ae28bc500920reed@google.com proc(device, span, width, 255); 403f1bbd533e266687c5c2b6b406e06ae28bc500920reed@google.com y += 1; 404f1bbd533e266687c5c2b6b406e06ae28bc500920reed@google.com device = (uint32_t*)((char*)device + deviceRB); 405f1bbd533e266687c5c2b6b406e06ae28bc500920reed@google.com } while (--height > 0); 406f1bbd533e266687c5c2b6b406e06ae28bc500920reed@google.com } 407f1bbd533e266687c5c2b6b406e06ae28bc500920reed@google.com } 408f1bbd533e266687c5c2b6b406e06ae28bc500920reed@google.com} 409f1bbd533e266687c5c2b6b406e06ae28bc500920reed@google.com 410bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkARGB32_Shader_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[], 411bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com const int16_t runs[]) { 412bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkPMColor* span = fBuffer; 413bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com uint32_t* device = fDevice.getAddr32(x, y); 414bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkShader* shader = fShader; 415bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 416e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com if (fXfermode && !fShadeDirectlyIntoDevice) { 417bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com for (;;) { 418bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkXfermode* xfer = fXfermode; 419bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 420bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int count = *runs; 421bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (count <= 0) 422bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com break; 423bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int aa = *antialias; 424bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (aa) { 425bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com shader->shadeSpan(x, y, span, count); 426bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (aa == 255) { 427bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com xfer->xfer32(device, span, count, NULL); 428bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } else { 429bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com // count is almost always 1 430bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com for (int i = count - 1; i >= 0; --i) { 431bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com xfer->xfer32(&device[i], &span[i], 1, antialias); 432bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 433bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 434bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 435bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com device += count; 436bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com runs += count; 437bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com antialias += count; 438bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com x += count; 439919114813d58933c9d9433b141e0222c34b700b1reed@google.com } 440e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com } else if (fShadeDirectlyIntoDevice || 441e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com (fShader->getFlags() & SkShader::kOpaqueAlpha_Flag)) { 442bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com for (;;) { 443bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int count = *runs; 444bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (count <= 0) { 445bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com break; 446bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 447bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int aa = *antialias; 448bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (aa) { 449cdbc582d7a596ad26571dc8c7e857f74d3a8ae7creed@android.com if (aa == 255) { 450cdbc582d7a596ad26571dc8c7e857f74d3a8ae7creed@android.com // cool, have the shader draw right into the device 451bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com shader->shadeSpan(x, y, device, count); 452bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } else { 453bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com shader->shadeSpan(x, y, span, count); 454cdbc582d7a596ad26571dc8c7e857f74d3a8ae7creed@android.com fProc32Blend(device, span, count, aa); 455bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 456bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 457bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com device += count; 458bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com runs += count; 459bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com antialias += count; 460bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com x += count; 461919114813d58933c9d9433b141e0222c34b700b1reed@google.com } 462e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com } else { 463bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com for (;;) { 464bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int count = *runs; 465bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (count <= 0) { 466bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com break; 467bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 468bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int aa = *antialias; 469bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (aa) { 470bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fShader->shadeSpan(x, y, span, count); 471bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (aa == 255) { 472cdbc582d7a596ad26571dc8c7e857f74d3a8ae7creed@android.com fProc32(device, span, count, 255); 473bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } else { 474cdbc582d7a596ad26571dc8c7e857f74d3a8ae7creed@android.com fProc32Blend(device, span, count, aa); 475bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 476bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 477bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com device += count; 478bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com runs += count; 479bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com antialias += count; 480bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com x += count; 481919114813d58933c9d9433b141e0222c34b700b1reed@google.com } 482bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 483bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 48426cb94b362c50333cde0ed993dae6aa747b307dareed@google.com 48526cb94b362c50333cde0ed993dae6aa747b307dareed@google.comvoid SkARGB32_Shader_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) { 48626cb94b362c50333cde0ed993dae6aa747b307dareed@google.com // we only handle kA8 with an xfermode 48726cb94b362c50333cde0ed993dae6aa747b307dareed@google.com if (fXfermode && (SkMask::kA8_Format != mask.fFormat)) { 48826cb94b362c50333cde0ed993dae6aa747b307dareed@google.com this->INHERITED::blitMask(mask, clip); 48926cb94b362c50333cde0ed993dae6aa747b307dareed@google.com return; 49026cb94b362c50333cde0ed993dae6aa747b307dareed@google.com } 49126cb94b362c50333cde0ed993dae6aa747b307dareed@google.com 49226cb94b362c50333cde0ed993dae6aa747b307dareed@google.com SkASSERT(mask.fBounds.contains(clip)); 49326cb94b362c50333cde0ed993dae6aa747b307dareed@google.com 49426cb94b362c50333cde0ed993dae6aa747b307dareed@google.com SkBlitMask::RowProc proc = NULL; 49526cb94b362c50333cde0ed993dae6aa747b307dareed@google.com if (!fXfermode) { 49626cb94b362c50333cde0ed993dae6aa747b307dareed@google.com unsigned flags = 0; 49726cb94b362c50333cde0ed993dae6aa747b307dareed@google.com if (fShader->getFlags() & SkShader::kOpaqueAlpha_Flag) { 49826cb94b362c50333cde0ed993dae6aa747b307dareed@google.com flags |= SkBlitMask::kSrcIsOpaque_RowFlag; 49926cb94b362c50333cde0ed993dae6aa747b307dareed@google.com } 50026cb94b362c50333cde0ed993dae6aa747b307dareed@google.com proc = SkBlitMask::RowFactory(SkBitmap::kARGB_8888_Config, mask.fFormat, 50126cb94b362c50333cde0ed993dae6aa747b307dareed@google.com (SkBlitMask::RowFlags)flags); 50226cb94b362c50333cde0ed993dae6aa747b307dareed@google.com if (NULL == proc) { 50326cb94b362c50333cde0ed993dae6aa747b307dareed@google.com this->INHERITED::blitMask(mask, clip); 50426cb94b362c50333cde0ed993dae6aa747b307dareed@google.com return; 50526cb94b362c50333cde0ed993dae6aa747b307dareed@google.com } 50626cb94b362c50333cde0ed993dae6aa747b307dareed@google.com } 50726cb94b362c50333cde0ed993dae6aa747b307dareed@google.com 50826cb94b362c50333cde0ed993dae6aa747b307dareed@google.com const int x = clip.fLeft; 50926cb94b362c50333cde0ed993dae6aa747b307dareed@google.com const int width = clip.width(); 51026cb94b362c50333cde0ed993dae6aa747b307dareed@google.com int y = clip.fTop; 51126cb94b362c50333cde0ed993dae6aa747b307dareed@google.com int height = clip.height(); 51226cb94b362c50333cde0ed993dae6aa747b307dareed@google.com 51326cb94b362c50333cde0ed993dae6aa747b307dareed@google.com char* dstRow = (char*)fDevice.getAddr32(x, y); 51426cb94b362c50333cde0ed993dae6aa747b307dareed@google.com const size_t dstRB = fDevice.rowBytes(); 51526cb94b362c50333cde0ed993dae6aa747b307dareed@google.com const uint8_t* maskRow = (const uint8_t*)mask.getAddr(x, y); 51626cb94b362c50333cde0ed993dae6aa747b307dareed@google.com const size_t maskRB = mask.fRowBytes; 51726cb94b362c50333cde0ed993dae6aa747b307dareed@google.com 51826cb94b362c50333cde0ed993dae6aa747b307dareed@google.com SkShader* shader = fShader; 51926cb94b362c50333cde0ed993dae6aa747b307dareed@google.com SkPMColor* span = fBuffer; 52026cb94b362c50333cde0ed993dae6aa747b307dareed@google.com 52126cb94b362c50333cde0ed993dae6aa747b307dareed@google.com if (fXfermode) { 52226cb94b362c50333cde0ed993dae6aa747b307dareed@google.com SkASSERT(SkMask::kA8_Format == mask.fFormat); 52326cb94b362c50333cde0ed993dae6aa747b307dareed@google.com SkXfermode* xfer = fXfermode; 52426cb94b362c50333cde0ed993dae6aa747b307dareed@google.com do { 52526cb94b362c50333cde0ed993dae6aa747b307dareed@google.com shader->shadeSpan(x, y, span, width); 52626cb94b362c50333cde0ed993dae6aa747b307dareed@google.com xfer->xfer32((SkPMColor*)dstRow, span, width, maskRow); 52726cb94b362c50333cde0ed993dae6aa747b307dareed@google.com dstRow += dstRB; 52826cb94b362c50333cde0ed993dae6aa747b307dareed@google.com maskRow += maskRB; 52926cb94b362c50333cde0ed993dae6aa747b307dareed@google.com y += 1; 53026cb94b362c50333cde0ed993dae6aa747b307dareed@google.com } while (--height > 0); 53126cb94b362c50333cde0ed993dae6aa747b307dareed@google.com } else { 53226cb94b362c50333cde0ed993dae6aa747b307dareed@google.com do { 53326cb94b362c50333cde0ed993dae6aa747b307dareed@google.com shader->shadeSpan(x, y, span, width); 53426cb94b362c50333cde0ed993dae6aa747b307dareed@google.com proc(dstRow, maskRow, span, width); 53526cb94b362c50333cde0ed993dae6aa747b307dareed@google.com dstRow += dstRB; 53626cb94b362c50333cde0ed993dae6aa747b307dareed@google.com maskRow += maskRB; 53726cb94b362c50333cde0ed993dae6aa747b307dareed@google.com y += 1; 53826cb94b362c50333cde0ed993dae6aa747b307dareed@google.com } while (--height > 0); 53926cb94b362c50333cde0ed993dae6aa747b307dareed@google.com } 54026cb94b362c50333cde0ed993dae6aa747b307dareed@google.com} 54126cb94b362c50333cde0ed993dae6aa747b307dareed@google.com 542e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.comvoid SkARGB32_Shader_Blitter::blitV(int x, int y, int height, SkAlpha alpha) { 543e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com SkASSERT(x >= 0 && y >= 0 && y + height <= fDevice.height()); 544713a335d7ed43207cb059d437c4dde44cc0f86a4skia.committer@gmail.com 545e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com uint32_t* device = fDevice.getAddr32(x, y); 546e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com size_t deviceRB = fDevice.rowBytes(); 547e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com SkShader* shader = fShader; 548713a335d7ed43207cb059d437c4dde44cc0f86a4skia.committer@gmail.com 549e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com if (fConstInY) { 550e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com SkPMColor c; 551e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com fShader->shadeSpan(x, y, &c, 1); 552e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com 553e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com if (fShadeDirectlyIntoDevice) { 554e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com if (255 == alpha) { 555e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com do { 556e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com *device = c; 557e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com device = (uint32_t*)((char*)device + deviceRB); 558e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com } while (--height > 0); 559e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com } else { 560e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com do { 561e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com *device = SkFourByteInterp(c, *device, alpha); 562e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com device = (uint32_t*)((char*)device + deviceRB); 563e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com } while (--height > 0); 564e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com } 565e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com } else { 566e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com SkXfermode* xfer = fXfermode; 567e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com if (xfer) { 568e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com do { 569e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com xfer->xfer32(device, &c, 1, &alpha); 570e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com device = (uint32_t*)((char*)device + deviceRB); 571e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com } while (--height > 0); 572e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com } else { 5737a154279d801eb51ccec5f1f8bffec73c7998ae9reed@google.com SkBlitRow::Proc32 proc = (255 == alpha) ? fProc32 : fProc32Blend; 574e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com do { 575e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com proc(device, &c, 1, alpha); 576e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com device = (uint32_t*)((char*)device + deviceRB); 577e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com } while (--height > 0); 578e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com } 579e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com } 580e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com return; 581e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com } 582e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com 583e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com if (fShadeDirectlyIntoDevice) { 584e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com void* ctx; 585e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com SkShader::ShadeProc shadeProc = fShader->asAShadeProc(&ctx); 586e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com if (255 == alpha) { 587e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com if (shadeProc) { 588e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com do { 589e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com shadeProc(ctx, x, y, device, 1); 590e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com y += 1; 591e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com device = (uint32_t*)((char*)device + deviceRB); 592e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com } while (--height > 0); 593e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com } else { 594e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com do { 595e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com shader->shadeSpan(x, y, device, 1); 596e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com y += 1; 597e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com device = (uint32_t*)((char*)device + deviceRB); 598e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com } while (--height > 0); 599e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com } 600e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com } else { // alpha < 255 601e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com SkPMColor c; 602e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com if (shadeProc) { 603e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com do { 604e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com shadeProc(ctx, x, y, &c, 1); 605e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com *device = SkFourByteInterp(c, *device, alpha); 606e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com y += 1; 607e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com device = (uint32_t*)((char*)device + deviceRB); 608e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com } while (--height > 0); 609e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com } else { 610e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com do { 611e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com shader->shadeSpan(x, y, &c, 1); 612e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com *device = SkFourByteInterp(c, *device, alpha); 613e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com y += 1; 614e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com device = (uint32_t*)((char*)device + deviceRB); 615e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com } while (--height > 0); 616e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com } 617e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com } 618e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com } else { 619e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com SkPMColor* span = fBuffer; 620e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com SkXfermode* xfer = fXfermode; 621e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com if (xfer) { 622e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com do { 623e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com shader->shadeSpan(x, y, span, 1); 624e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com xfer->xfer32(device, span, 1, &alpha); 625e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com y += 1; 626e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com device = (uint32_t*)((char*)device + deviceRB); 627e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com } while (--height > 0); 628e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com } else { 6296f8396a6040707a706b87658817c225d373ee859reed@google.com SkBlitRow::Proc32 proc = (255 == alpha) ? fProc32 : fProc32Blend; 630e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com do { 631e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com shader->shadeSpan(x, y, span, 1); 6326f8396a6040707a706b87658817c225d373ee859reed@google.com proc(device, span, 1, alpha); 633e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com y += 1; 634e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com device = (uint32_t*)((char*)device + deviceRB); 635e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com } while (--height > 0); 636e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com } 637e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com } 638e86b0de924a4d5c053aae451f4b41fb42aa9a921reed@google.com} 639