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, bool UseBProc> class SkState_Shader_Blitter : public S
kShaderBlitter { | 137 template <typename State> class SkState_Shader_Blitter : public SkShaderBlitter
{ |
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 const SkShader::Context::BlitState& bstate, | 140 const SkShader::Context::BlitState& bstate) |
141 SkShader::Context::BlitProc bproc) | |
142 : INHERITED(device, paint, bstate.fCtx) | 141 : INHERITED(device, paint, bstate.fCtx) |
143 , fState(device.info(), paint, bstate.fCtx) | 142 , fState(device.info(), paint, bstate.fCtx) |
144 , fBState(bstate) | 143 , fBState(bstate) |
145 , fBProc(bproc) | 144 , fBlitBW(bstate.fBlitBW) |
| 145 , fBlitAA(bstate.fBlitAA) |
146 {} | 146 {} |
147 | 147 |
148 void blitH(int x, int y, int width) override { | 148 void blitH(int x, int y, int width) override { |
149 SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width()); | 149 SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width()); |
150 | 150 |
151 if (UseBProc) { | 151 if (fBlitBW) { |
152 fBProc(&fBState, x, y, fDevice, width, nullptr); | 152 fBlitBW(&fBState, x, y, fDevice, width); |
153 return; | 153 return; |
154 } | 154 } |
155 | 155 |
156 typename State::DstType* device = State::WritableAddr(fDevice, x, y); | 156 typename State::DstType* device = State::WritableAddr(fDevice, x, y); |
157 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, width); | 157 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, width); |
158 fState.fProcN(fState.fXfer, device, fState.fBuffer, width, nullptr); | 158 fState.fProcN(fState.fXfer, device, fState.fBuffer, width, nullptr); |
159 } | 159 } |
160 | 160 |
161 void blitV(int x, int y, int height, SkAlpha alpha) override { | 161 void blitV(int x, int y, int height, SkAlpha alpha) override { |
162 SkASSERT(x >= 0 && y >= 0 && y + height <= fDevice.height()); | 162 SkASSERT(x >= 0 && y >= 0 && y + height <= fDevice.height()); |
163 | 163 |
164 if (UseBProc) { | 164 if (fBlitAA) { |
165 for (const int bottom = y + height; y < bottom; ++y) { | 165 for (const int bottom = y + height; y < bottom; ++y) { |
166 fBProc(&fBState, x, y, fDevice, 1, &alpha); | 166 fBlitAA(&fBState, x, y, fDevice, 1, &alpha); |
167 } | 167 } |
168 return; | 168 return; |
169 } | 169 } |
170 | 170 |
171 typename State::DstType* device = State::WritableAddr(fDevice, x, y); | 171 typename State::DstType* device = State::WritableAddr(fDevice, x, y); |
172 size_t deviceRB = fDevice.rowBytes(); | 172 size_t deviceRB = fDevice.rowBytes(); |
173 | 173 |
174 if (fConstInY) { | 174 if (fConstInY) { |
175 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, 1); | 175 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, 1); |
176 } | 176 } |
177 for (const int bottom = y + height; y < bottom; ++y) { | 177 for (const int bottom = y + height; y < bottom; ++y) { |
178 if (!fConstInY) { | 178 if (!fConstInY) { |
179 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, 1); | 179 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, 1); |
180 } | 180 } |
181 fState.fProcN(fState.fXfer, device, fState.fBuffer, 1, &alpha); | 181 fState.fProcN(fState.fXfer, device, fState.fBuffer, 1, &alpha); |
182 device = (typename State::DstType*)((char*)device + deviceRB); | 182 device = (typename State::DstType*)((char*)device + deviceRB); |
183 } | 183 } |
184 } | 184 } |
185 | 185 |
186 void blitRect(int x, int y, int width, int height) override { | 186 void blitRect(int x, int y, int width, int height) override { |
187 SkASSERT(x >= 0 && y >= 0 && | 187 SkASSERT(x >= 0 && y >= 0 && |
188 x + width <= fDevice.width() && y + height <= fDevice.height())
; | 188 x + width <= fDevice.width() && y + height <= fDevice.height())
; |
189 | 189 |
190 if (UseBProc) { | 190 if (fBlitBW) { |
191 for (const int bottom = y + height; y < bottom; ++y) { | 191 for (const int bottom = y + height; y < bottom; ++y) { |
192 fBProc(&fBState, x, y, fDevice, width, nullptr); | 192 fBlitBW(&fBState, x, y, fDevice, width); |
193 } | 193 } |
194 return; | 194 return; |
195 } | 195 } |
196 | 196 |
197 typename State::DstType* device = State::WritableAddr(fDevice, x, y); | 197 typename State::DstType* device = State::WritableAddr(fDevice, x, y); |
198 size_t deviceRB = fDevice.rowBytes(); | 198 size_t deviceRB = fDevice.rowBytes(); |
199 | 199 |
200 if (fConstInY) { | 200 if (fConstInY) { |
201 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, width); | 201 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, width); |
202 } | 202 } |
203 for (const int bottom = y + height; y < bottom; ++y) { | 203 for (const int bottom = y + height; y < bottom; ++y) { |
204 if (!fConstInY) { | 204 if (!fConstInY) { |
205 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, width); | 205 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, width); |
206 } | 206 } |
207 fState.fProcN(fState.fXfer, device, fState.fBuffer, width, nullptr); | 207 fState.fProcN(fState.fXfer, device, fState.fBuffer, width, nullptr); |
208 device = (typename State::DstType*)((char*)device + deviceRB); | 208 device = (typename State::DstType*)((char*)device + deviceRB); |
209 } | 209 } |
210 } | 210 } |
211 | 211 |
212 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 { |
213 typename State::DstType* device = State::WritableAddr(fDevice, x, y); | 213 typename State::DstType* device = State::WritableAddr(fDevice, x, y); |
214 | 214 |
215 for (;;) { | 215 for (;;) { |
216 int count = *runs; | 216 int count = *runs; |
217 if (count <= 0) { | 217 if (count <= 0) { |
218 break; | 218 break; |
219 } | 219 } |
220 int aa = *antialias; | 220 int aa = *antialias; |
221 if (aa) { | 221 if (aa) { |
222 if (UseBProc && (aa == 255)) { | 222 if (fBlitBW && (aa == 255)) { |
223 fBProc(&fBState, x, y, fDevice, count, nullptr); | 223 fBlitBW(&fBState, x, y, fDevice, count); |
224 } else { | 224 } else { |
225 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, count); | 225 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, count); |
226 if (aa == 255) { | 226 if (aa == 255) { |
227 fState.fProcN(fState.fXfer, device, fState.fBuffer, coun
t, nullptr); | 227 fState.fProcN(fState.fXfer, device, fState.fBuffer, coun
t, nullptr); |
228 } else { | 228 } else { |
229 for (int i = 0; i < count; ++i) { | 229 for (int i = 0; i < count; ++i) { |
230 fState.fProcN(fState.fXfer, &device[i], &fState.fBuf
fer[i], 1, antialias); | 230 fState.fProcN(fState.fXfer, &device[i], &fState.fBuf
fer[i], 1, antialias); |
231 } | 231 } |
232 } | 232 } |
233 } | 233 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 } | 275 } |
276 | 276 |
277 SkASSERT(mask.fBounds.contains(clip)); | 277 SkASSERT(mask.fBounds.contains(clip)); |
278 | 278 |
279 const int x = clip.fLeft; | 279 const int x = clip.fLeft; |
280 const int width = clip.width(); | 280 const int width = clip.width(); |
281 int y = clip.fTop; | 281 int y = clip.fTop; |
282 const uint8_t* maskRow = (const uint8_t*)mask.getAddr(x, y); | 282 const uint8_t* maskRow = (const uint8_t*)mask.getAddr(x, y); |
283 const size_t maskRB = mask.fRowBytes; | 283 const size_t maskRB = mask.fRowBytes; |
284 | 284 |
285 if (UseBProc) { | 285 if (fBlitAA) { |
286 for (; y < clip.fBottom; ++y) { | 286 for (; y < clip.fBottom; ++y) { |
287 fBProc(&fBState, x, y, fDevice, width, maskRow); | 287 fBlitAA(&fBState, x, y, fDevice, width, maskRow); |
288 maskRow += maskRB; | 288 maskRow += maskRB; |
289 } | 289 } |
290 return; | 290 return; |
291 } | 291 } |
292 | 292 |
293 typename State::DstType* device = State::WritableAddr(fDevice, x, y); | 293 typename State::DstType* device = State::WritableAddr(fDevice, x, y); |
294 const size_t deviceRB = fDevice.rowBytes(); | 294 const size_t deviceRB = fDevice.rowBytes(); |
295 | 295 |
296 if (fConstInY) { | 296 if (fConstInY) { |
297 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, width); | 297 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, width); |
298 } | 298 } |
299 for (; y < clip.fBottom; ++y) { | 299 for (; y < clip.fBottom; ++y) { |
300 if (!fConstInY) { | 300 if (!fConstInY) { |
301 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, width); | 301 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, width); |
302 } | 302 } |
303 fState.fProcN(fState.fXfer, device, fState.fBuffer, width, maskRow); | 303 fState.fProcN(fState.fXfer, device, fState.fBuffer, width, maskRow); |
304 device = (typename State::DstType*)((char*)device + deviceRB); | 304 device = (typename State::DstType*)((char*)device + deviceRB); |
305 maskRow += maskRB; | 305 maskRow += maskRB; |
306 } | 306 } |
307 } | 307 } |
308 | 308 |
309 protected: | 309 protected: |
310 State fState; | 310 State fState; |
311 SkShader::Context::BlitState fBState; | 311 SkShader::Context::BlitState fBState; |
312 SkShader::Context::BlitProc fBProc; | 312 SkShader::Context::BlitBW fBlitBW; |
| 313 SkShader::Context::BlitAA fBlitAA; |
313 | 314 |
314 typedef SkShaderBlitter INHERITED; | 315 typedef SkShaderBlitter INHERITED; |
315 }; | 316 }; |
316 | 317 |
317 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 318 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
318 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 319 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
319 | 320 |
320 static bool is_opaque(const SkPaint& paint, const SkShader::Context* shaderConte
xt) { | 321 static bool is_opaque(const SkPaint& paint, const SkShader::Context* shaderConte
xt) { |
321 return shaderContext ? SkToBool(shaderContext->getFlags() & SkShader::kOpaqu
eAlpha_Flag) | 322 return shaderContext ? SkToBool(shaderContext->getFlags() & SkShader::kOpaqu
eAlpha_Flag) |
322 : 0xFF == paint.getAlpha(); | 323 : 0xFF == paint.getAlpha(); |
323 } | 324 } |
324 | 325 |
325 struct State4f { | 326 struct State4f { |
326 State4f(const SkImageInfo& info, const SkPaint& paint, const SkShader::Conte
xt* shaderContext) { | 327 State4f(const SkImageInfo& info, const SkPaint& paint, const SkShader::Conte
xt* shaderContext) { |
327 fXfer = paint.getXfermode(); | 328 fXfer = paint.getXfermode(); |
328 if (shaderContext) { | 329 if (shaderContext) { |
329 fBuffer.reset(info.width()); | 330 fBuffer.reset(info.width()); |
330 } else { | 331 } else { |
331 fPM4f = SkColor4f::FromColor(paint.getColor()).premul(); | 332 fPM4f = SkColor4f::FromColor(paint.getColor()).premul(); |
332 } | 333 } |
333 fFlags = 0; | 334 fFlags = 0; |
334 } | 335 } |
335 | 336 |
336 SkXfermode* fXfer; | 337 SkXfermode* fXfer; |
337 SkPM4f fPM4f; | 338 SkPM4f fPM4f; |
338 SkAutoTMalloc<SkPM4f> fBuffer; | 339 SkAutoTMalloc<SkPM4f> fBuffer; |
339 uint32_t fFlags; | 340 uint32_t fFlags; |
340 | 341 |
341 SkShader::Context::BlitState fBState; | 342 SkShader::Context::BlitState fBState; |
342 SkShader::Context::BlitProc fBProc; | |
343 }; | 343 }; |
344 | 344 |
345 struct State32 : State4f { | 345 struct State32 : State4f { |
346 typedef uint32_t DstType; | 346 typedef uint32_t DstType; |
347 | 347 |
348 SkXfermode::D32Proc fProc1; | 348 SkXfermode::D32Proc fProc1; |
349 SkXfermode::D32Proc fProcN; | 349 SkXfermode::D32Proc fProcN; |
350 | 350 |
351 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) |
352 : State4f(info, paint, shaderContext) | 352 : State4f(info, paint, shaderContext) |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
406 } | 406 } |
407 }; | 407 }; |
408 | 408 |
409 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, |
410 SkShader::Context* shaderContext, | 410 SkShader::Context* shaderContext, |
411 SkTBlitterAllocator* allocator) { | 411 SkTBlitterAllocator* allocator) { |
412 SkASSERT(allocator != nullptr); | 412 SkASSERT(allocator != nullptr); |
413 | 413 |
414 if (shaderContext) { | 414 if (shaderContext) { |
415 SkShader::Context::BlitState bstate; | 415 SkShader::Context::BlitState bstate; |
| 416 sk_bzero(&bstate, sizeof(bstate)); |
416 bstate.fCtx = shaderContext; | 417 bstate.fCtx = shaderContext; |
417 bstate.fXfer = paint.getXfermode(); | 418 bstate.fXfer = paint.getXfermode(); |
418 | 419 |
419 auto bproc = shaderContext->chooseBlitProc(device.info(), &bstate); | 420 (void)shaderContext->chooseBlitProcs(device.info(), &bstate); |
420 if (bproc) { | 421 return allocator->createT<SkState_Shader_Blitter<State>>(device, paint,
bstate); |
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 } | |
427 } else { | 422 } else { |
428 SkColor color = paint.getColor(); | 423 SkColor color = paint.getColor(); |
429 if (0 == SkColorGetA(color)) { | 424 if (0 == SkColorGetA(color)) { |
430 return nullptr; | 425 return nullptr; |
431 } | 426 } |
432 return allocator->createT<SkState_Blitter<State>>(device, paint); | 427 return allocator->createT<SkState_Blitter<State>>(device, paint); |
433 } | 428 } |
434 } | 429 } |
435 | 430 |
436 SkBlitter* SkBlitter_ARGB32_Create(const SkPixmap& device, const SkPaint& paint, | 431 SkBlitter* SkBlitter_ARGB32_Create(const SkPixmap& device, const SkPaint& paint, |
437 SkShader::Context* shaderContext, | 432 SkShader::Context* shaderContext, |
438 SkTBlitterAllocator* allocator) { | 433 SkTBlitterAllocator* allocator) { |
439 return create<State32>(device, paint, shaderContext, allocator); | 434 return create<State32>(device, paint, shaderContext, allocator); |
440 } | 435 } |
441 | 436 |
442 SkBlitter* SkBlitter_ARGB64_Create(const SkPixmap& device, const SkPaint& paint, | 437 SkBlitter* SkBlitter_ARGB64_Create(const SkPixmap& device, const SkPaint& paint, |
443 SkShader::Context* shaderContext, | 438 SkShader::Context* shaderContext, |
444 SkTBlitterAllocator* allocator) { | 439 SkTBlitterAllocator* allocator) { |
445 return create<State64>(device, paint, shaderContext, allocator); | 440 return create<State64>(device, paint, shaderContext, allocator); |
446 } | 441 } |
OLD | NEW |