OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkCoreBlitters.h" | 8 #include "SkCoreBlitters.h" |
9 #include "SkColorPriv.h" | 9 #include "SkColorPriv.h" |
10 #include "SkShader.h" | 10 #include "SkShader.h" |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
127 for (int i = 0; i < height; ++i) { | 127 for (int i = 0; i < height; ++i) { |
128 fState.fProc1(fState.fXfer, device, &fState.fPM4f, width, maskRow); | 128 fState.fProc1(fState.fXfer, device, &fState.fPM4f, width, maskRow); |
129 device = (typename State::DstType*)((char*)device + dstRB); | 129 device = (typename State::DstType*)((char*)device + dstRB); |
130 maskRow += maskRB; | 130 maskRow += maskRB; |
131 } | 131 } |
132 } | 132 } |
133 }; | 133 }; |
134 | 134 |
135 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 135 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
136 | 136 |
137 template <typename State> class SkState_Shader_Blitter : public SkShaderBlitter
{ | 137 template <typename State, bool UseBProc> class SkState_Shader_Blitter : public S
kShaderBlitter { |
138 public: | 138 public: |
139 SkState_Shader_Blitter(const SkPixmap& device, const SkPaint& paint, | 139 SkState_Shader_Blitter(const SkPixmap& device, const SkPaint& paint, |
140 SkShader::Context* shaderContext) | 140 const SkShader::Context::BlitState& bstate, |
141 : INHERITED(device, paint, shaderContext) | 141 SkShader::Context::BlitProc bproc) |
142 , fState(device.info(), paint, shaderContext) | 142 : INHERITED(device, paint, bstate.fCtx) |
| 143 , fState(device.info(), paint, bstate.fCtx) |
| 144 , fBState(bstate) |
| 145 , fBProc(bproc) |
143 {} | 146 {} |
144 | 147 |
145 void blitH(int x, int y, int width) override { | 148 void blitH(int x, int y, int width) override { |
146 SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width()); | 149 SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width()); |
147 | 150 |
| 151 if (UseBProc) { |
| 152 fBProc(&fBState, x, y, fDevice, width, nullptr); |
| 153 return; |
| 154 } |
| 155 |
148 typename State::DstType* device = State::WritableAddr(fDevice, x, y); | 156 typename State::DstType* device = State::WritableAddr(fDevice, x, y); |
149 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, width); | 157 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, width); |
150 fState.fProcN(fState.fXfer, device, fState.fBuffer, width, nullptr); | 158 fState.fProcN(fState.fXfer, device, fState.fBuffer, width, nullptr); |
151 } | 159 } |
152 | 160 |
153 void blitV(int x, int y, int height, SkAlpha alpha) override { | 161 void blitV(int x, int y, int height, SkAlpha alpha) override { |
154 SkASSERT(x >= 0 && y >= 0 && y + height <= fDevice.height()); | 162 SkASSERT(x >= 0 && y >= 0 && y + height <= fDevice.height()); |
155 | 163 |
| 164 if (UseBProc) { |
| 165 for (const int bottom = y + height; y < bottom; ++y) { |
| 166 fBProc(&fBState, x, y, fDevice, 1, &alpha); |
| 167 } |
| 168 return; |
| 169 } |
| 170 |
156 typename State::DstType* device = State::WritableAddr(fDevice, x, y); | 171 typename State::DstType* device = State::WritableAddr(fDevice, x, y); |
157 size_t deviceRB = fDevice.rowBytes(); | 172 size_t deviceRB = fDevice.rowBytes(); |
158 const int bottom = y + height; | |
159 | 173 |
160 if (fConstInY) { | 174 if (fConstInY) { |
161 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, 1); | 175 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, 1); |
162 } | 176 } |
163 for (; y < bottom; ++y) { | 177 for (const int bottom = y + height; y < bottom; ++y) { |
164 if (!fConstInY) { | 178 if (!fConstInY) { |
165 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, 1); | 179 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, 1); |
166 } | 180 } |
167 fState.fProcN(fState.fXfer, device, fState.fBuffer, 1, &alpha); | 181 fState.fProcN(fState.fXfer, device, fState.fBuffer, 1, &alpha); |
168 device = (typename State::DstType*)((char*)device + deviceRB); | 182 device = (typename State::DstType*)((char*)device + deviceRB); |
169 } | 183 } |
170 } | 184 } |
171 | 185 |
172 void blitRect(int x, int y, int width, int height) override { | 186 void blitRect(int x, int y, int width, int height) override { |
173 SkASSERT(x >= 0 && y >= 0 && | 187 SkASSERT(x >= 0 && y >= 0 && |
174 x + width <= fDevice.width() && y + height <= fDevice.height())
; | 188 x + width <= fDevice.width() && y + height <= fDevice.height())
; |
175 | 189 |
| 190 if (UseBProc) { |
| 191 for (const int bottom = y + height; y < bottom; ++y) { |
| 192 fBProc(&fBState, x, y, fDevice, width, nullptr); |
| 193 } |
| 194 return; |
| 195 } |
| 196 |
176 typename State::DstType* device = State::WritableAddr(fDevice, x, y); | 197 typename State::DstType* device = State::WritableAddr(fDevice, x, y); |
177 size_t deviceRB = fDevice.rowBytes(); | 198 size_t deviceRB = fDevice.rowBytes(); |
178 const int bottom = y + height; | |
179 | 199 |
180 if (fConstInY) { | 200 if (fConstInY) { |
181 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, width); | 201 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, width); |
182 } | 202 } |
183 for (; y < bottom; ++y) { | 203 for (const int bottom = y + height; y < bottom; ++y) { |
184 if (!fConstInY) { | 204 if (!fConstInY) { |
185 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, width); | 205 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, width); |
186 } | 206 } |
187 fState.fProcN(fState.fXfer, device, fState.fBuffer, width, nullptr); | 207 fState.fProcN(fState.fXfer, device, fState.fBuffer, width, nullptr); |
188 device = (typename State::DstType*)((char*)device + deviceRB); | 208 device = (typename State::DstType*)((char*)device + deviceRB); |
189 } | 209 } |
190 } | 210 } |
191 | 211 |
192 void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]
) override { | 212 void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]
) override { |
193 typename State::DstType* device = State::WritableAddr(fDevice, x, y); | 213 typename State::DstType* device = State::WritableAddr(fDevice, x, y); |
194 | 214 |
195 for (;;) { | 215 for (;;) { |
196 int count = *runs; | 216 int count = *runs; |
197 if (count <= 0) { | 217 if (count <= 0) { |
198 break; | 218 break; |
199 } | 219 } |
200 int aa = *antialias; | 220 int aa = *antialias; |
201 if (aa) { | 221 if (aa) { |
202 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, count); | 222 if (UseBProc && (aa == 255)) { |
203 if (aa == 255) { | 223 fBProc(&fBState, x, y, fDevice, count, nullptr); |
204 fState.fProcN(fState.fXfer, device, fState.fBuffer, count, n
ullptr); | |
205 } else { | 224 } else { |
206 for (int i = 0; i < count; ++i) { | 225 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, count); |
207 fState.fProcN(fState.fXfer, &device[i], &fState.fBuffer[
i], 1, antialias); | 226 if (aa == 255) { |
| 227 fState.fProcN(fState.fXfer, device, fState.fBuffer, coun
t, nullptr); |
| 228 } else { |
| 229 for (int i = 0; i < count; ++i) { |
| 230 fState.fProcN(fState.fXfer, &device[i], &fState.fBuf
fer[i], 1, antialias); |
| 231 } |
208 } | 232 } |
209 } | 233 } |
210 } | 234 } |
211 device += count; | 235 device += count; |
212 runs += count; | 236 runs += count; |
213 antialias += count; | 237 antialias += count; |
214 x += count; | 238 x += count; |
215 } | 239 } |
216 } | 240 } |
217 | 241 |
(...skipping 24 matching lines...) Expand all Loading... |
242 | 266 |
243 void blitMask(const SkMask& mask, const SkIRect& clip) override { | 267 void blitMask(const SkMask& mask, const SkIRect& clip) override { |
244 if (SkMask::kLCD16_Format == mask.fFormat) { | 268 if (SkMask::kLCD16_Format == mask.fFormat) { |
245 this->blitLCDMask(mask, clip); | 269 this->blitLCDMask(mask, clip); |
246 return; | 270 return; |
247 } | 271 } |
248 if (SkMask::kA8_Format != mask.fFormat) { | 272 if (SkMask::kA8_Format != mask.fFormat) { |
249 this->INHERITED::blitMask(mask, clip); | 273 this->INHERITED::blitMask(mask, clip); |
250 return; | 274 return; |
251 } | 275 } |
252 | 276 |
253 SkASSERT(mask.fBounds.contains(clip)); | 277 SkASSERT(mask.fBounds.contains(clip)); |
254 | 278 |
255 const int x = clip.fLeft; | 279 const int x = clip.fLeft; |
256 const int width = clip.width(); | 280 const int width = clip.width(); |
257 int y = clip.fTop; | 281 int y = clip.fTop; |
258 | 282 const uint8_t* maskRow = (const uint8_t*)mask.getAddr(x, y); |
| 283 const size_t maskRB = mask.fRowBytes; |
| 284 |
| 285 if (UseBProc) { |
| 286 for (; y < clip.fBottom; ++y) { |
| 287 fBProc(&fBState, x, y, fDevice, width, maskRow); |
| 288 maskRow += maskRB; |
| 289 } |
| 290 return; |
| 291 } |
| 292 |
259 typename State::DstType* device = State::WritableAddr(fDevice, x, y); | 293 typename State::DstType* device = State::WritableAddr(fDevice, x, y); |
260 const size_t deviceRB = fDevice.rowBytes(); | 294 const size_t deviceRB = fDevice.rowBytes(); |
261 const uint8_t* maskRow = (const uint8_t*)mask.getAddr(x, y); | |
262 const size_t maskRB = mask.fRowBytes; | |
263 | 295 |
264 if (fConstInY) { | 296 if (fConstInY) { |
265 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, width); | 297 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, width); |
266 } | 298 } |
267 for (; y < clip.fBottom; ++y) { | 299 for (; y < clip.fBottom; ++y) { |
268 if (!fConstInY) { | 300 if (!fConstInY) { |
269 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, width); | 301 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, width); |
270 } | 302 } |
271 fState.fProcN(fState.fXfer, device, fState.fBuffer, width, maskRow); | 303 fState.fProcN(fState.fXfer, device, fState.fBuffer, width, maskRow); |
272 device = (typename State::DstType*)((char*)device + deviceRB); | 304 device = (typename State::DstType*)((char*)device + deviceRB); |
273 maskRow += maskRB; | 305 maskRow += maskRB; |
274 } | 306 } |
275 } | 307 } |
276 | 308 |
277 private: | 309 protected: |
278 State fState; | 310 State fState; |
| 311 SkShader::Context::BlitState fBState; |
| 312 SkShader::Context::BlitProc fBProc; |
279 | 313 |
280 typedef SkShaderBlitter INHERITED; | 314 typedef SkShaderBlitter INHERITED; |
281 }; | 315 }; |
282 | 316 |
283 ////////////////////////////////////////////////////////////////////////////////
////// | 317 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
| 318 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
284 | 319 |
285 static bool is_opaque(const SkPaint& paint, const SkShader::Context* shaderConte
xt) { | 320 static bool is_opaque(const SkPaint& paint, const SkShader::Context* shaderConte
xt) { |
286 return shaderContext ? SkToBool(shaderContext->getFlags() & SkShader::kOpaqu
eAlpha_Flag) | 321 return shaderContext ? SkToBool(shaderContext->getFlags() & SkShader::kOpaqu
eAlpha_Flag) |
287 : 0xFF == paint.getAlpha(); | 322 : 0xFF == paint.getAlpha(); |
288 } | 323 } |
289 | 324 |
290 struct State4f { | 325 struct State4f { |
291 State4f(const SkImageInfo& info, const SkPaint& paint, const SkShader::Conte
xt* shaderContext) { | 326 State4f(const SkImageInfo& info, const SkPaint& paint, const SkShader::Conte
xt* shaderContext) { |
292 fXfer = paint.getXfermode(); | 327 fXfer = paint.getXfermode(); |
293 if (shaderContext) { | 328 if (shaderContext) { |
294 fBuffer.reset(info.width()); | 329 fBuffer.reset(info.width()); |
295 } else { | 330 } else { |
296 fPM4f = SkColor4f::FromColor(paint.getColor()).premul(); | 331 fPM4f = SkColor4f::FromColor(paint.getColor()).premul(); |
297 } | 332 } |
298 fFlags = 0; | 333 fFlags = 0; |
299 } | 334 } |
300 | 335 |
301 SkXfermode* fXfer; | 336 SkXfermode* fXfer; |
302 SkPM4f fPM4f; | 337 SkPM4f fPM4f; |
303 SkAutoTMalloc<SkPM4f> fBuffer; | 338 SkAutoTMalloc<SkPM4f> fBuffer; |
304 uint32_t fFlags; | 339 uint32_t fFlags; |
| 340 |
| 341 SkShader::Context::BlitState fBState; |
| 342 SkShader::Context::BlitProc fBProc; |
305 }; | 343 }; |
306 | 344 |
307 struct State32 : State4f { | 345 struct State32 : State4f { |
308 typedef uint32_t DstType; | 346 typedef uint32_t DstType; |
309 | 347 |
310 SkXfermode::D32Proc fProc1; | 348 SkXfermode::D32Proc fProc1; |
311 SkXfermode::D32Proc fProcN; | 349 SkXfermode::D32Proc fProcN; |
312 | 350 |
313 State32(const SkImageInfo& info, const SkPaint& paint, const SkShader::Conte
xt* shaderContext) | 351 State32(const SkImageInfo& info, const SkPaint& paint, const SkShader::Conte
xt* shaderContext) |
314 : State4f(info, paint, shaderContext) | 352 : State4f(info, paint, shaderContext) |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
365 | 403 |
366 static DstType* WritableAddr(const SkPixmap& device, int x, int y) { | 404 static DstType* WritableAddr(const SkPixmap& device, int x, int y) { |
367 return device.writable_addr64(x, y); | 405 return device.writable_addr64(x, y); |
368 } | 406 } |
369 }; | 407 }; |
370 | 408 |
371 template <typename State> SkBlitter* create(const SkPixmap& device, const SkPain
t& paint, | 409 template <typename State> SkBlitter* create(const SkPixmap& device, const SkPain
t& paint, |
372 SkShader::Context* shaderContext, | 410 SkShader::Context* shaderContext, |
373 SkTBlitterAllocator* allocator) { | 411 SkTBlitterAllocator* allocator) { |
374 SkASSERT(allocator != nullptr); | 412 SkASSERT(allocator != nullptr); |
375 | 413 |
376 if (shaderContext) { | 414 if (shaderContext) { |
377 return allocator->createT<SkState_Shader_Blitter<State>>(device, paint,
shaderContext); | 415 SkShader::Context::BlitState bstate; |
| 416 bstate.fCtx = shaderContext; |
| 417 bstate.fXfer = paint.getXfermode(); |
| 418 |
| 419 auto bproc = shaderContext->chooseBlitProc(device.info(), &bstate); |
| 420 if (bproc) { |
| 421 return allocator->createT<SkState_Shader_Blitter<State, true>>(devic
e, paint, bstate, |
| 422 bproc
); |
| 423 } else { |
| 424 return allocator->createT<SkState_Shader_Blitter<State, false>>(devi
ce, paint, bstate, |
| 425 bpro
c); |
| 426 } |
378 } else { | 427 } else { |
379 SkColor color = paint.getColor(); | 428 SkColor color = paint.getColor(); |
380 if (0 == SkColorGetA(color)) { | 429 if (0 == SkColorGetA(color)) { |
381 return nullptr; | 430 return nullptr; |
382 } | 431 } |
383 return allocator->createT<SkState_Blitter<State>>(device, paint); | 432 return allocator->createT<SkState_Blitter<State>>(device, paint); |
384 } | 433 } |
385 } | 434 } |
386 | 435 |
387 SkBlitter* SkBlitter_ARGB32_Create(const SkPixmap& device, const SkPaint& paint, | 436 SkBlitter* SkBlitter_ARGB32_Create(const SkPixmap& device, const SkPaint& paint, |
388 SkShader::Context* shaderContext, | 437 SkShader::Context* shaderContext, |
389 SkTBlitterAllocator* allocator) { | 438 SkTBlitterAllocator* allocator) { |
390 return create<State32>(device, paint, shaderContext, allocator); | 439 return create<State32>(device, paint, shaderContext, allocator); |
391 } | 440 } |
392 | 441 |
393 SkBlitter* SkBlitter_ARGB64_Create(const SkPixmap& device, const SkPaint& paint, | 442 SkBlitter* SkBlitter_ARGB64_Create(const SkPixmap& device, const SkPaint& paint, |
394 SkShader::Context* shaderContext, | 443 SkShader::Context* shaderContext, |
395 SkTBlitterAllocator* allocator) { | 444 SkTBlitterAllocator* allocator) { |
396 return create<State64>(device, paint, shaderContext, allocator); | 445 return create<State64>(device, paint, shaderContext, allocator); |
397 } | 446 } |
OLD | NEW |