1395eabeb0e72334c45324874c6e009b54634df21reed/* 2395eabeb0e72334c45324874c6e009b54634df21reed * Copyright 2016 Google Inc. 3395eabeb0e72334c45324874c6e009b54634df21reed * 4395eabeb0e72334c45324874c6e009b54634df21reed * Use of this source code is governed by a BSD-style license that can be 5395eabeb0e72334c45324874c6e009b54634df21reed * found in the LICENSE file. 6395eabeb0e72334c45324874c6e009b54634df21reed */ 7395eabeb0e72334c45324874c6e009b54634df21reed 8395eabeb0e72334c45324874c6e009b54634df21reed#include "SkCoreBlitters.h" 9395eabeb0e72334c45324874c6e009b54634df21reed#include "SkColorPriv.h" 10395eabeb0e72334c45324874c6e009b54634df21reed#include "SkShader.h" 11395eabeb0e72334c45324874c6e009b54634df21reed#include "SkUtils.h" 12395eabeb0e72334c45324874c6e009b54634df21reed#include "SkXfermode.h" 13395eabeb0e72334c45324874c6e009b54634df21reed#include "SkBlitMask.h" 14a34be68a7eff0ae475b194f8a29975460cf3e456reed#include "SkTemplates.h" 15dd9ffea9ce051a49dbc6544e6aa3cb68fe987f47reed#include "SkPM4f.h" 16395eabeb0e72334c45324874c6e009b54634df21reed 17a34be68a7eff0ae475b194f8a29975460cf3e456reedtemplate <typename State> class SkState_Blitter : public SkRasterBlitter { 18a34be68a7eff0ae475b194f8a29975460cf3e456reed typedef SkRasterBlitter INHERITED; 19a34be68a7eff0ae475b194f8a29975460cf3e456reed State fState; 20395eabeb0e72334c45324874c6e009b54634df21reed 21a34be68a7eff0ae475b194f8a29975460cf3e456reedpublic: 22a34be68a7eff0ae475b194f8a29975460cf3e456reed SkState_Blitter(const SkPixmap& device, const SkPaint& paint) 23a34be68a7eff0ae475b194f8a29975460cf3e456reed : INHERITED(device) 24a34be68a7eff0ae475b194f8a29975460cf3e456reed , fState(device.info(), paint, nullptr) 25a34be68a7eff0ae475b194f8a29975460cf3e456reed {} 26395eabeb0e72334c45324874c6e009b54634df21reed 27a34be68a7eff0ae475b194f8a29975460cf3e456reed void blitH(int x, int y, int width) override { 28a34be68a7eff0ae475b194f8a29975460cf3e456reed SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width()); 29a34be68a7eff0ae475b194f8a29975460cf3e456reed 308f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed fState.fProc1(fState.fXfer, State::WritableAddr(fDevice, x, y), 318f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed &fState.fPM4f, width, nullptr); 32395eabeb0e72334c45324874c6e009b54634df21reed } 33a34be68a7eff0ae475b194f8a29975460cf3e456reed 34a34be68a7eff0ae475b194f8a29975460cf3e456reed void blitV(int x, int y, int height, SkAlpha alpha) override { 35a34be68a7eff0ae475b194f8a29975460cf3e456reed SkASSERT(x >= 0 && y >= 0 && y + height <= fDevice.height()); 36a34be68a7eff0ae475b194f8a29975460cf3e456reed 37a34be68a7eff0ae475b194f8a29975460cf3e456reed typename State::DstType* device = State::WritableAddr(fDevice, x, y); 38a34be68a7eff0ae475b194f8a29975460cf3e456reed size_t deviceRB = fDevice.rowBytes(); 39a34be68a7eff0ae475b194f8a29975460cf3e456reed 40a34be68a7eff0ae475b194f8a29975460cf3e456reed for (int i = 0; i < height; ++i) { 418f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed fState.fProc1(fState.fXfer, device, &fState.fPM4f, 1, &alpha); 42a34be68a7eff0ae475b194f8a29975460cf3e456reed device = (typename State::DstType*)((char*)device + deviceRB); 43a34be68a7eff0ae475b194f8a29975460cf3e456reed } 44395eabeb0e72334c45324874c6e009b54634df21reed } 45395eabeb0e72334c45324874c6e009b54634df21reed 46a34be68a7eff0ae475b194f8a29975460cf3e456reed void blitRect(int x, int y, int width, int height) override { 47a34be68a7eff0ae475b194f8a29975460cf3e456reed SkASSERT(x >= 0 && y >= 0 && 48a34be68a7eff0ae475b194f8a29975460cf3e456reed x + width <= fDevice.width() && y + height <= fDevice.height()); 49a34be68a7eff0ae475b194f8a29975460cf3e456reed 50a34be68a7eff0ae475b194f8a29975460cf3e456reed typename State::DstType* device = State::WritableAddr(fDevice, x, y); 51a34be68a7eff0ae475b194f8a29975460cf3e456reed size_t deviceRB = fDevice.rowBytes(); 52a34be68a7eff0ae475b194f8a29975460cf3e456reed 53a34be68a7eff0ae475b194f8a29975460cf3e456reed do { 548f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed fState.fProc1(fState.fXfer, device, &fState.fPM4f, width, nullptr); 55a34be68a7eff0ae475b194f8a29975460cf3e456reed y += 1; 56a34be68a7eff0ae475b194f8a29975460cf3e456reed device = (typename State::DstType*)((char*)device + deviceRB); 57a34be68a7eff0ae475b194f8a29975460cf3e456reed } while (--height > 0); 58a34be68a7eff0ae475b194f8a29975460cf3e456reed } 59395eabeb0e72334c45324874c6e009b54634df21reed 60a34be68a7eff0ae475b194f8a29975460cf3e456reed void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]) override { 61a34be68a7eff0ae475b194f8a29975460cf3e456reed typename State::DstType* device = State::WritableAddr(fDevice, x, y); 62a34be68a7eff0ae475b194f8a29975460cf3e456reed 63a34be68a7eff0ae475b194f8a29975460cf3e456reed for (;;) { 64a34be68a7eff0ae475b194f8a29975460cf3e456reed int count = *runs; 65a34be68a7eff0ae475b194f8a29975460cf3e456reed if (count <= 0) { 66a34be68a7eff0ae475b194f8a29975460cf3e456reed break; 67a34be68a7eff0ae475b194f8a29975460cf3e456reed } 68a34be68a7eff0ae475b194f8a29975460cf3e456reed int aa = *antialias; 69a34be68a7eff0ae475b194f8a29975460cf3e456reed if (aa) { 70a34be68a7eff0ae475b194f8a29975460cf3e456reed if (aa == 255) { 718f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed fState.fProc1(fState.fXfer, device, &fState.fPM4f, count, nullptr); 72a34be68a7eff0ae475b194f8a29975460cf3e456reed } else { 73a34be68a7eff0ae475b194f8a29975460cf3e456reed for (int i = 0; i < count; ++i) { 748f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed fState.fProc1(fState.fXfer, &device[i], &fState.fPM4f, 1, antialias); 75a34be68a7eff0ae475b194f8a29975460cf3e456reed } 76a34be68a7eff0ae475b194f8a29975460cf3e456reed } 77a34be68a7eff0ae475b194f8a29975460cf3e456reed } 78a34be68a7eff0ae475b194f8a29975460cf3e456reed device += count; 79a34be68a7eff0ae475b194f8a29975460cf3e456reed runs += count; 80a34be68a7eff0ae475b194f8a29975460cf3e456reed antialias += count; 81a34be68a7eff0ae475b194f8a29975460cf3e456reed x += count; 82a34be68a7eff0ae475b194f8a29975460cf3e456reed } 83a34be68a7eff0ae475b194f8a29975460cf3e456reed } 84395eabeb0e72334c45324874c6e009b54634df21reed 854528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed void blitLCDMask(const SkMask& mask, const SkIRect& clip) { 864528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed auto proc = fState.getLCDProc(SkXfermode::kSrcIsSingle_LCDFlag); 874528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed 884528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed const int x = clip.fLeft; 894528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed const int width = clip.width(); 904528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed const int y = clip.fTop; 914528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed const int height = clip.height(); 924528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed 934528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed typename State::DstType* device = State::WritableAddr(fDevice, x, y); 944528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed const size_t dstRB = fDevice.rowBytes(); 954528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed const uint16_t* maskRow = (const uint16_t*)mask.getAddr(x, y); 964528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed const size_t maskRB = mask.fRowBytes; 974528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed 984528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed for (int i = 0; i < height; ++i) { 994528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed proc(device, &fState.fPM4f, width, maskRow); 1004528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed device = (typename State::DstType*)((char*)device + dstRB); 1014528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed maskRow = (const uint16_t*)((const char*)maskRow + maskRB); 1024528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed } 1034528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed } 1044528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed 105a34be68a7eff0ae475b194f8a29975460cf3e456reed void blitMask(const SkMask& mask, const SkIRect& clip) override { 1064528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed if (SkMask::kLCD16_Format == mask.fFormat) { 1074528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed this->blitLCDMask(mask, clip); 1084528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed return; 1094528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed } 110a34be68a7eff0ae475b194f8a29975460cf3e456reed if (SkMask::kA8_Format != mask.fFormat) { 111a34be68a7eff0ae475b194f8a29975460cf3e456reed this->INHERITED::blitMask(mask, clip); 112a34be68a7eff0ae475b194f8a29975460cf3e456reed return; 113a34be68a7eff0ae475b194f8a29975460cf3e456reed } 114a34be68a7eff0ae475b194f8a29975460cf3e456reed 115a34be68a7eff0ae475b194f8a29975460cf3e456reed SkASSERT(mask.fBounds.contains(clip)); 116a34be68a7eff0ae475b194f8a29975460cf3e456reed 117a34be68a7eff0ae475b194f8a29975460cf3e456reed const int x = clip.fLeft; 118a34be68a7eff0ae475b194f8a29975460cf3e456reed const int width = clip.width(); 119a34be68a7eff0ae475b194f8a29975460cf3e456reed const int y = clip.fTop; 120a34be68a7eff0ae475b194f8a29975460cf3e456reed const int height = clip.height(); 121a34be68a7eff0ae475b194f8a29975460cf3e456reed 122a34be68a7eff0ae475b194f8a29975460cf3e456reed typename State::DstType* device = State::WritableAddr(fDevice, x, y); 123a34be68a7eff0ae475b194f8a29975460cf3e456reed const size_t dstRB = fDevice.rowBytes(); 124a34be68a7eff0ae475b194f8a29975460cf3e456reed const uint8_t* maskRow = (const uint8_t*)mask.getAddr(x, y); 125a34be68a7eff0ae475b194f8a29975460cf3e456reed const size_t maskRB = mask.fRowBytes; 126a34be68a7eff0ae475b194f8a29975460cf3e456reed 127a34be68a7eff0ae475b194f8a29975460cf3e456reed for (int i = 0; i < height; ++i) { 1288f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed fState.fProc1(fState.fXfer, device, &fState.fPM4f, width, maskRow); 129a34be68a7eff0ae475b194f8a29975460cf3e456reed device = (typename State::DstType*)((char*)device + dstRB); 130a34be68a7eff0ae475b194f8a29975460cf3e456reed maskRow += maskRB; 131a34be68a7eff0ae475b194f8a29975460cf3e456reed } 132a34be68a7eff0ae475b194f8a29975460cf3e456reed } 133a34be68a7eff0ae475b194f8a29975460cf3e456reed}; 134395eabeb0e72334c45324874c6e009b54634df21reed 135a34be68a7eff0ae475b194f8a29975460cf3e456reed/////////////////////////////////////////////////////////////////////////////////////////////////// 136395eabeb0e72334c45324874c6e009b54634df21reed 137a34be68a7eff0ae475b194f8a29975460cf3e456reedtemplate <typename State> class SkState_Shader_Blitter : public SkShaderBlitter { 138a34be68a7eff0ae475b194f8a29975460cf3e456reedpublic: 139a34be68a7eff0ae475b194f8a29975460cf3e456reed SkState_Shader_Blitter(const SkPixmap& device, const SkPaint& paint, 140a34be68a7eff0ae475b194f8a29975460cf3e456reed SkShader::Context* shaderContext) 141a34be68a7eff0ae475b194f8a29975460cf3e456reed : INHERITED(device, paint, shaderContext) 142a34be68a7eff0ae475b194f8a29975460cf3e456reed , fState(device.info(), paint, shaderContext) 143a34be68a7eff0ae475b194f8a29975460cf3e456reed {} 144a34be68a7eff0ae475b194f8a29975460cf3e456reed 145a34be68a7eff0ae475b194f8a29975460cf3e456reed void blitH(int x, int y, int width) override { 146a34be68a7eff0ae475b194f8a29975460cf3e456reed SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width()); 147a34be68a7eff0ae475b194f8a29975460cf3e456reed 148a34be68a7eff0ae475b194f8a29975460cf3e456reed typename State::DstType* device = State::WritableAddr(fDevice, x, y); 149a34be68a7eff0ae475b194f8a29975460cf3e456reed fShaderContext->shadeSpan4f(x, y, fState.fBuffer, width); 1508f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed fState.fProcN(fState.fXfer, device, fState.fBuffer, width, nullptr); 151a34be68a7eff0ae475b194f8a29975460cf3e456reed } 152395eabeb0e72334c45324874c6e009b54634df21reed 153a34be68a7eff0ae475b194f8a29975460cf3e456reed void blitV(int x, int y, int height, SkAlpha alpha) override { 154a34be68a7eff0ae475b194f8a29975460cf3e456reed SkASSERT(x >= 0 && y >= 0 && y + height <= fDevice.height()); 155a34be68a7eff0ae475b194f8a29975460cf3e456reed 156a34be68a7eff0ae475b194f8a29975460cf3e456reed typename State::DstType* device = State::WritableAddr(fDevice, x, y); 157a34be68a7eff0ae475b194f8a29975460cf3e456reed size_t deviceRB = fDevice.rowBytes(); 158a34be68a7eff0ae475b194f8a29975460cf3e456reed const int bottom = y + height; 159a34be68a7eff0ae475b194f8a29975460cf3e456reed 160a34be68a7eff0ae475b194f8a29975460cf3e456reed if (fConstInY) { 161a34be68a7eff0ae475b194f8a29975460cf3e456reed fShaderContext->shadeSpan4f(x, y, fState.fBuffer, 1); 162a34be68a7eff0ae475b194f8a29975460cf3e456reed } 163a34be68a7eff0ae475b194f8a29975460cf3e456reed for (; y < bottom; ++y) { 164a34be68a7eff0ae475b194f8a29975460cf3e456reed if (!fConstInY) { 165a34be68a7eff0ae475b194f8a29975460cf3e456reed fShaderContext->shadeSpan4f(x, y, fState.fBuffer, 1); 166a34be68a7eff0ae475b194f8a29975460cf3e456reed } 1678f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed fState.fProcN(fState.fXfer, device, fState.fBuffer, 1, &alpha); 168a34be68a7eff0ae475b194f8a29975460cf3e456reed device = (typename State::DstType*)((char*)device + deviceRB); 169a34be68a7eff0ae475b194f8a29975460cf3e456reed } 170a34be68a7eff0ae475b194f8a29975460cf3e456reed } 171395eabeb0e72334c45324874c6e009b54634df21reed 172a34be68a7eff0ae475b194f8a29975460cf3e456reed void blitRect(int x, int y, int width, int height) override { 173a34be68a7eff0ae475b194f8a29975460cf3e456reed SkASSERT(x >= 0 && y >= 0 && 174a34be68a7eff0ae475b194f8a29975460cf3e456reed x + width <= fDevice.width() && y + height <= fDevice.height()); 175a34be68a7eff0ae475b194f8a29975460cf3e456reed 176a34be68a7eff0ae475b194f8a29975460cf3e456reed typename State::DstType* device = State::WritableAddr(fDevice, x, y); 177a34be68a7eff0ae475b194f8a29975460cf3e456reed size_t deviceRB = fDevice.rowBytes(); 178a34be68a7eff0ae475b194f8a29975460cf3e456reed const int bottom = y + height; 179a34be68a7eff0ae475b194f8a29975460cf3e456reed 180a34be68a7eff0ae475b194f8a29975460cf3e456reed if (fConstInY) { 181a34be68a7eff0ae475b194f8a29975460cf3e456reed fShaderContext->shadeSpan4f(x, y, fState.fBuffer, width); 182a34be68a7eff0ae475b194f8a29975460cf3e456reed } 183a34be68a7eff0ae475b194f8a29975460cf3e456reed for (; y < bottom; ++y) { 184a34be68a7eff0ae475b194f8a29975460cf3e456reed if (!fConstInY) { 185a34be68a7eff0ae475b194f8a29975460cf3e456reed fShaderContext->shadeSpan4f(x, y, fState.fBuffer, width); 186a34be68a7eff0ae475b194f8a29975460cf3e456reed } 1878f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed fState.fProcN(fState.fXfer, device, fState.fBuffer, width, nullptr); 188a34be68a7eff0ae475b194f8a29975460cf3e456reed device = (typename State::DstType*)((char*)device + deviceRB); 189a34be68a7eff0ae475b194f8a29975460cf3e456reed } 190395eabeb0e72334c45324874c6e009b54634df21reed } 191395eabeb0e72334c45324874c6e009b54634df21reed 192a34be68a7eff0ae475b194f8a29975460cf3e456reed void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]) override { 193a34be68a7eff0ae475b194f8a29975460cf3e456reed typename State::DstType* device = State::WritableAddr(fDevice, x, y); 194a34be68a7eff0ae475b194f8a29975460cf3e456reed 195a34be68a7eff0ae475b194f8a29975460cf3e456reed for (;;) { 196a34be68a7eff0ae475b194f8a29975460cf3e456reed int count = *runs; 197a34be68a7eff0ae475b194f8a29975460cf3e456reed if (count <= 0) { 198a34be68a7eff0ae475b194f8a29975460cf3e456reed break; 199a34be68a7eff0ae475b194f8a29975460cf3e456reed } 200a34be68a7eff0ae475b194f8a29975460cf3e456reed int aa = *antialias; 201a34be68a7eff0ae475b194f8a29975460cf3e456reed if (aa) { 202a34be68a7eff0ae475b194f8a29975460cf3e456reed fShaderContext->shadeSpan4f(x, y, fState.fBuffer, count); 203a34be68a7eff0ae475b194f8a29975460cf3e456reed if (aa == 255) { 2048f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed fState.fProcN(fState.fXfer, device, fState.fBuffer, count, nullptr); 205a34be68a7eff0ae475b194f8a29975460cf3e456reed } else { 206a34be68a7eff0ae475b194f8a29975460cf3e456reed for (int i = 0; i < count; ++i) { 2078f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed fState.fProcN(fState.fXfer, &device[i], &fState.fBuffer[i], 1, antialias); 208a34be68a7eff0ae475b194f8a29975460cf3e456reed } 209395eabeb0e72334c45324874c6e009b54634df21reed } 210395eabeb0e72334c45324874c6e009b54634df21reed } 211a34be68a7eff0ae475b194f8a29975460cf3e456reed device += count; 212a34be68a7eff0ae475b194f8a29975460cf3e456reed runs += count; 213a34be68a7eff0ae475b194f8a29975460cf3e456reed antialias += count; 214a34be68a7eff0ae475b194f8a29975460cf3e456reed x += count; 215395eabeb0e72334c45324874c6e009b54634df21reed } 216395eabeb0e72334c45324874c6e009b54634df21reed } 217395eabeb0e72334c45324874c6e009b54634df21reed 2184528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed void blitLCDMask(const SkMask& mask, const SkIRect& clip) { 2194528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed auto proc = fState.getLCDProc(0); 2204528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed 2214528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed const int x = clip.fLeft; 2224528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed const int width = clip.width(); 2234528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed int y = clip.fTop; 2244528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed 2254528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed typename State::DstType* device = State::WritableAddr(fDevice, x, y); 2264528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed const size_t deviceRB = fDevice.rowBytes(); 2274528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed const uint16_t* maskRow = (const uint16_t*)mask.getAddr(x, y); 2284528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed const size_t maskRB = mask.fRowBytes; 2294528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed 2304528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed if (fConstInY) { 2314528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed fShaderContext->shadeSpan4f(x, y, fState.fBuffer, width); 2324528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed } 2334528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed for (; y < clip.fBottom; ++y) { 2344528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed if (!fConstInY) { 2354528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed fShaderContext->shadeSpan4f(x, y, fState.fBuffer, width); 2364528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed } 2374528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed proc(device, fState.fBuffer, width, maskRow); 2384528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed device = (typename State::DstType*)((char*)device + deviceRB); 2394528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed maskRow = (const uint16_t*)((const char*)maskRow + maskRB); 2404528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed } 2414528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed } 2424528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed 243a34be68a7eff0ae475b194f8a29975460cf3e456reed void blitMask(const SkMask& mask, const SkIRect& clip) override { 2444528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed if (SkMask::kLCD16_Format == mask.fFormat) { 2454528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed this->blitLCDMask(mask, clip); 2464528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed return; 2474528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed } 248a34be68a7eff0ae475b194f8a29975460cf3e456reed if (SkMask::kA8_Format != mask.fFormat) { 249a34be68a7eff0ae475b194f8a29975460cf3e456reed this->INHERITED::blitMask(mask, clip); 250a34be68a7eff0ae475b194f8a29975460cf3e456reed return; 251a34be68a7eff0ae475b194f8a29975460cf3e456reed } 252a34be68a7eff0ae475b194f8a29975460cf3e456reed 253a34be68a7eff0ae475b194f8a29975460cf3e456reed SkASSERT(mask.fBounds.contains(clip)); 254a34be68a7eff0ae475b194f8a29975460cf3e456reed 255a34be68a7eff0ae475b194f8a29975460cf3e456reed const int x = clip.fLeft; 256a34be68a7eff0ae475b194f8a29975460cf3e456reed const int width = clip.width(); 257a34be68a7eff0ae475b194f8a29975460cf3e456reed int y = clip.fTop; 258a34be68a7eff0ae475b194f8a29975460cf3e456reed 259a34be68a7eff0ae475b194f8a29975460cf3e456reed typename State::DstType* device = State::WritableAddr(fDevice, x, y); 260a34be68a7eff0ae475b194f8a29975460cf3e456reed const size_t deviceRB = fDevice.rowBytes(); 261a34be68a7eff0ae475b194f8a29975460cf3e456reed const uint8_t* maskRow = (const uint8_t*)mask.getAddr(x, y); 262a34be68a7eff0ae475b194f8a29975460cf3e456reed const size_t maskRB = mask.fRowBytes; 263a34be68a7eff0ae475b194f8a29975460cf3e456reed 264a34be68a7eff0ae475b194f8a29975460cf3e456reed if (fConstInY) { 265a34be68a7eff0ae475b194f8a29975460cf3e456reed fShaderContext->shadeSpan4f(x, y, fState.fBuffer, width); 266a34be68a7eff0ae475b194f8a29975460cf3e456reed } 267a34be68a7eff0ae475b194f8a29975460cf3e456reed for (; y < clip.fBottom; ++y) { 268a34be68a7eff0ae475b194f8a29975460cf3e456reed if (!fConstInY) { 269a34be68a7eff0ae475b194f8a29975460cf3e456reed fShaderContext->shadeSpan4f(x, y, fState.fBuffer, width); 270a34be68a7eff0ae475b194f8a29975460cf3e456reed } 2718f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed fState.fProcN(fState.fXfer, device, fState.fBuffer, width, maskRow); 272a34be68a7eff0ae475b194f8a29975460cf3e456reed device = (typename State::DstType*)((char*)device + deviceRB); 273a34be68a7eff0ae475b194f8a29975460cf3e456reed maskRow += maskRB; 274a34be68a7eff0ae475b194f8a29975460cf3e456reed } 275395eabeb0e72334c45324874c6e009b54634df21reed } 276a34be68a7eff0ae475b194f8a29975460cf3e456reed 277a34be68a7eff0ae475b194f8a29975460cf3e456reedprivate: 278a34be68a7eff0ae475b194f8a29975460cf3e456reed State fState; 279395eabeb0e72334c45324874c6e009b54634df21reed 280a34be68a7eff0ae475b194f8a29975460cf3e456reed typedef SkShaderBlitter INHERITED; 281a34be68a7eff0ae475b194f8a29975460cf3e456reed}; 282395eabeb0e72334c45324874c6e009b54634df21reed 283a34be68a7eff0ae475b194f8a29975460cf3e456reed////////////////////////////////////////////////////////////////////////////////////// 284395eabeb0e72334c45324874c6e009b54634df21reed 285a34be68a7eff0ae475b194f8a29975460cf3e456reedstatic bool is_opaque(const SkPaint& paint, const SkShader::Context* shaderContext) { 286a34be68a7eff0ae475b194f8a29975460cf3e456reed return shaderContext ? SkToBool(shaderContext->getFlags() & SkShader::kOpaqueAlpha_Flag) 287a34be68a7eff0ae475b194f8a29975460cf3e456reed : 0xFF == paint.getAlpha(); 288395eabeb0e72334c45324874c6e009b54634df21reed} 289395eabeb0e72334c45324874c6e009b54634df21reed 2908f7b0b2d809510d4af4e6ff6f731bac78eded6c4reedstruct State4f { 2918f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed State4f(const SkImageInfo& info, const SkPaint& paint, const SkShader::Context* shaderContext) { 2928f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed fXfer = paint.getXfermode(); 2938f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed if (shaderContext) { 2948f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed fBuffer.reset(info.width()); 2958f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed } else { 2968f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed fPM4f = SkColor4f::FromColor(paint.getColor()).premul(); 2978f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed } 2988f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed fFlags = 0; 2998f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed } 3008f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed 3018f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed SkXfermode* fXfer; 302a34be68a7eff0ae475b194f8a29975460cf3e456reed SkPM4f fPM4f; 3038f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed SkAutoTMalloc<SkPM4f> fBuffer; 3048f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed uint32_t fFlags; 3058f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed}; 3068f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed 3078f7b0b2d809510d4af4e6ff6f731bac78eded6c4reedstruct State32 : State4f { 3088f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed typedef uint32_t DstType; 309a34be68a7eff0ae475b194f8a29975460cf3e456reed 3108f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed SkXfermode::D32Proc fProc1; 3118f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed SkXfermode::D32Proc fProcN; 3128f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed 3138f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed State32(const SkImageInfo& info, const SkPaint& paint, const SkShader::Context* shaderContext) 3148f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed : State4f(info, paint, shaderContext) 3158f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed { 316a34be68a7eff0ae475b194f8a29975460cf3e456reed if (is_opaque(paint, shaderContext)) { 3178f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed fFlags |= SkXfermode::kSrcIsOpaque_D32Flag; 318a34be68a7eff0ae475b194f8a29975460cf3e456reed } 319a34be68a7eff0ae475b194f8a29975460cf3e456reed if (info.isSRGB()) { 3208f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed fFlags |= SkXfermode::kDstIsSRGB_D32Flag; 321a34be68a7eff0ae475b194f8a29975460cf3e456reed } 3228f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed fProc1 = SkXfermode::GetD32Proc(fXfer, fFlags | SkXfermode::kSrcIsSingle_D32Flag); 3238f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed fProcN = SkXfermode::GetD32Proc(fXfer, fFlags); 324a34be68a7eff0ae475b194f8a29975460cf3e456reed } 325a34be68a7eff0ae475b194f8a29975460cf3e456reed 3264528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed SkXfermode::LCD32Proc getLCDProc(uint32_t oneOrManyFlag) const { 3274528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed uint32_t flags = fFlags & 1; 3288f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed if (!(fFlags & SkXfermode::kDstIsSRGB_D32Flag)) { 3294528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed flags |= SkXfermode::kDstIsLinearInt_LCDFlag; 3304528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed } 3314528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed return SkXfermode::GetLCD32Proc(flags | oneOrManyFlag); 3324528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed } 3334528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed 334a34be68a7eff0ae475b194f8a29975460cf3e456reed static DstType* WritableAddr(const SkPixmap& device, int x, int y) { 335a34be68a7eff0ae475b194f8a29975460cf3e456reed return device.writable_addr32(x, y); 336a34be68a7eff0ae475b194f8a29975460cf3e456reed } 337a34be68a7eff0ae475b194f8a29975460cf3e456reed}; 338395eabeb0e72334c45324874c6e009b54634df21reed 3398f7b0b2d809510d4af4e6ff6f731bac78eded6c4reedstruct State64 : State4f { 3408f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed typedef uint64_t DstType; 341a34be68a7eff0ae475b194f8a29975460cf3e456reed 3428f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed SkXfermode::D64Proc fProc1; 3438f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed SkXfermode::D64Proc fProcN; 344a34be68a7eff0ae475b194f8a29975460cf3e456reed 3458f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed State64(const SkImageInfo& info, const SkPaint& paint, const SkShader::Context* shaderContext) 3468f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed : State4f(info, paint, shaderContext) 3478f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed { 348a34be68a7eff0ae475b194f8a29975460cf3e456reed if (is_opaque(paint, shaderContext)) { 3498f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed fFlags |= SkXfermode::kSrcIsOpaque_D64Flag; 350a34be68a7eff0ae475b194f8a29975460cf3e456reed } 351a34be68a7eff0ae475b194f8a29975460cf3e456reed if (kRGBA_F16_SkColorType == info.colorType()) { 3528f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed fFlags |= SkXfermode::kDstIsFloat16_D64Flag; 353a34be68a7eff0ae475b194f8a29975460cf3e456reed } 3548f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed fProc1 = SkXfermode::GetD64Proc(fXfer, fFlags | SkXfermode::kSrcIsSingle_D64Flag); 3558f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed fProcN = SkXfermode::GetD64Proc(fXfer, fFlags); 356a34be68a7eff0ae475b194f8a29975460cf3e456reed } 3578f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed 3584528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed SkXfermode::LCD64Proc getLCDProc(uint32_t oneOrManyFlag) const { 3594528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed uint32_t flags = fFlags & 1; 3608f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed if (!(fFlags & SkXfermode::kDstIsFloat16_D64Flag)) { 3614528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed flags |= SkXfermode::kDstIsLinearInt_LCDFlag; 3624528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed } 3634528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed return SkXfermode::GetLCD64Proc(flags | oneOrManyFlag); 3644528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed } 3654528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed 366a34be68a7eff0ae475b194f8a29975460cf3e456reed static DstType* WritableAddr(const SkPixmap& device, int x, int y) { 367a34be68a7eff0ae475b194f8a29975460cf3e456reed return device.writable_addr64(x, y); 368a34be68a7eff0ae475b194f8a29975460cf3e456reed } 369a34be68a7eff0ae475b194f8a29975460cf3e456reed}; 370a34be68a7eff0ae475b194f8a29975460cf3e456reed 371a34be68a7eff0ae475b194f8a29975460cf3e456reedtemplate <typename State> SkBlitter* create(const SkPixmap& device, const SkPaint& paint, 372a34be68a7eff0ae475b194f8a29975460cf3e456reed SkShader::Context* shaderContext, 373a34be68a7eff0ae475b194f8a29975460cf3e456reed SkTBlitterAllocator* allocator) { 374a34be68a7eff0ae475b194f8a29975460cf3e456reed SkASSERT(allocator != nullptr); 375a34be68a7eff0ae475b194f8a29975460cf3e456reed 376a34be68a7eff0ae475b194f8a29975460cf3e456reed if (shaderContext) { 377a34be68a7eff0ae475b194f8a29975460cf3e456reed return allocator->createT<SkState_Shader_Blitter<State>>(device, paint, shaderContext); 378395eabeb0e72334c45324874c6e009b54634df21reed } else { 379a34be68a7eff0ae475b194f8a29975460cf3e456reed SkColor color = paint.getColor(); 380a34be68a7eff0ae475b194f8a29975460cf3e456reed if (0 == SkColorGetA(color)) { 381a34be68a7eff0ae475b194f8a29975460cf3e456reed return nullptr; 382a34be68a7eff0ae475b194f8a29975460cf3e456reed } 383a34be68a7eff0ae475b194f8a29975460cf3e456reed return allocator->createT<SkState_Blitter<State>>(device, paint); 384395eabeb0e72334c45324874c6e009b54634df21reed } 385395eabeb0e72334c45324874c6e009b54634df21reed} 386a34be68a7eff0ae475b194f8a29975460cf3e456reed 387a34be68a7eff0ae475b194f8a29975460cf3e456reedSkBlitter* SkBlitter_ARGB32_Create(const SkPixmap& device, const SkPaint& paint, 388a34be68a7eff0ae475b194f8a29975460cf3e456reed SkShader::Context* shaderContext, 389a34be68a7eff0ae475b194f8a29975460cf3e456reed SkTBlitterAllocator* allocator) { 390a34be68a7eff0ae475b194f8a29975460cf3e456reed return create<State32>(device, paint, shaderContext, allocator); 391a34be68a7eff0ae475b194f8a29975460cf3e456reed} 392a34be68a7eff0ae475b194f8a29975460cf3e456reed 393a34be68a7eff0ae475b194f8a29975460cf3e456reedSkBlitter* SkBlitter_ARGB64_Create(const SkPixmap& device, const SkPaint& paint, 394a34be68a7eff0ae475b194f8a29975460cf3e456reed SkShader::Context* shaderContext, 395a34be68a7eff0ae475b194f8a29975460cf3e456reed SkTBlitterAllocator* allocator) { 396a34be68a7eff0ae475b194f8a29975460cf3e456reed return create<State64>(device, paint, shaderContext, allocator); 397a34be68a7eff0ae475b194f8a29975460cf3e456reed} 398