Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(597)

Side by Side Diff: src/core/SkBlitter_PM4f.cpp

Issue 1793883002: add blitprocs to shaders (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « include/core/SkShader.h ('k') | src/core/SkColorShader.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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 }
OLDNEW
« no previous file with comments | « include/core/SkShader.h ('k') | src/core/SkColorShader.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698