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

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

Issue 207683004: Extract most of the mutable state of SkShader into a separate Context object. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: clean up Created 6 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
OLDNEW
1 /* 1 /*
2 * Copyright 2006 The Android Open Source Project 2 * Copyright 2006 The Android Open Source Project
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 "SkDraw.h" 8 #include "SkDraw.h"
9 #include "SkBlitter.h" 9 #include "SkBlitter.h"
10 #include "SkBounder.h" 10 #include "SkBounder.h"
(...skipping 2337 matching lines...) Expand 10 before | Expand all | Expand 10 after
2348 2348
2349 src[0] = texs[state.f0]; 2349 src[0] = texs[state.f0];
2350 src[1] = texs[state.f1]; 2350 src[1] = texs[state.f1];
2351 src[2] = texs[state.f2]; 2351 src[2] = texs[state.f2];
2352 dst[0] = verts[state.f0]; 2352 dst[0] = verts[state.f0];
2353 dst[1] = verts[state.f1]; 2353 dst[1] = verts[state.f1];
2354 dst[2] = verts[state.f2]; 2354 dst[2] = verts[state.f2];
2355 return matrix->setPolyToPoly(src, dst, 3); 2355 return matrix->setPolyToPoly(src, dst, 3);
2356 } 2356 }
2357 2357
2358 /**
2359 * This class is NOT immutable due to the setup() method being called repeatedl y after
2360 * the shader has been associated with a paint. This is okay because we only ev er
2361 * associate this shader with temporary paints.
2362 */
2358 class SkTriColorShader : public SkShader { 2363 class SkTriColorShader : public SkShader {
2359 public: 2364 public:
2360 SkTriColorShader() {} 2365 SkTriColorShader() {}
2361 2366
2362 bool setup(const SkPoint pts[], const SkColor colors[], int, int, int); 2367 // TODO(dominikg): Feels like this should be part of the context, but we don 't have
2368 // access to it where we need it.
2369 bool setup(const SkPoint pts[], const SkColor colors[], int, int, int, const SkMatrix&);
2363 2370
2364 virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count) SK_OVERRID E; 2371 virtual SkShader::Context* createContext(
2372 const SkBitmap&, const SkPaint&, const SkMatrix&, void*) const SK_OV ERRIDE;
2373 virtual size_t contextSize() const SK_OVERRIDE;
2374
2375 class TriColorShaderContext : public SkShader::Context {
2376 public:
2377 TriColorShaderContext(const SkTriColorShader& shader, const SkBitmap& de vice,
2378 const SkPaint& paint, const SkMatrix& matrix);
2379 virtual ~TriColorShaderContext();
2380
2381 virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count) SK_OVE RRIDE;
2382 private:
2383 const SkTriColorShader& fTriColorShader;
scroggo 2014/03/24 21:24:46 Any reason SkTriColorShader does not simply static
Dominik Grewe 2014/03/26 17:22:22 Done.
2384
2385 typedef SkShader::Context INHERITED;
2386 };
2365 2387
2366 SK_DEVELOPER_TO_STRING() 2388 SK_DEVELOPER_TO_STRING()
2367 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkTriColorShader) 2389 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkTriColorShader)
2368 2390
2369 protected: 2391 protected:
2370 SkTriColorShader(SkReadBuffer& buffer) : SkShader(buffer) {} 2392 SkTriColorShader(SkReadBuffer& buffer) : SkShader(buffer) {}
2371 2393
2372 private: 2394 private:
2373 SkMatrix fDstToUnit; 2395 SkMatrix fDstToUnit;
2374 SkPMColor fColors[3]; 2396 SkPMColor fColors[3];
2375 2397
2376 typedef SkShader INHERITED; 2398 typedef SkShader INHERITED;
2377 }; 2399 };
2378 2400
2401 SkShader::Context* SkTriColorShader::createContext(const SkBitmap& device, const SkPaint& paint,
2402 const SkMatrix& matrix, void* storage) const {
2403 if (!this->validContext(device, paint, matrix)) {
2404 return NULL;
2405 }
2406
2407 return SkNEW_PLACEMENT_ARGS(storage, TriColorShaderContext, (*this, device, paint, matrix));
2408 }
2409
2379 bool SkTriColorShader::setup(const SkPoint pts[], const SkColor colors[], 2410 bool SkTriColorShader::setup(const SkPoint pts[], const SkColor colors[],
2380 int index0, int index1, int index2) { 2411 int index0, int index1, int index2, const SkMatrix& matrix) {
scroggo 2014/03/24 21:24:46 Maybe rename this parameter to make it clear what
Dominik Grewe 2014/03/26 17:22:22 It's not the totalInverse though, is it? We use it
scroggo 2014/03/26 23:13:09 Oh, I misread the code below...
2381 2412
2382 fColors[0] = SkPreMultiplyColor(colors[index0]); 2413 fColors[0] = SkPreMultiplyColor(colors[index0]);
2383 fColors[1] = SkPreMultiplyColor(colors[index1]); 2414 fColors[1] = SkPreMultiplyColor(colors[index1]);
2384 fColors[2] = SkPreMultiplyColor(colors[index2]); 2415 fColors[2] = SkPreMultiplyColor(colors[index2]);
2385 2416
2386 SkMatrix m, im; 2417 SkMatrix m, im;
2387 m.reset(); 2418 m.reset();
2388 m.set(0, pts[index1].fX - pts[index0].fX); 2419 m.set(0, pts[index1].fX - pts[index0].fX);
2389 m.set(1, pts[index2].fX - pts[index0].fX); 2420 m.set(1, pts[index2].fX - pts[index0].fX);
2390 m.set(2, pts[index0].fX); 2421 m.set(2, pts[index0].fX);
2391 m.set(3, pts[index1].fY - pts[index0].fY); 2422 m.set(3, pts[index1].fY - pts[index0].fY);
2392 m.set(4, pts[index2].fY - pts[index0].fY); 2423 m.set(4, pts[index2].fY - pts[index0].fY);
2393 m.set(5, pts[index0].fY); 2424 m.set(5, pts[index0].fY);
2394 if (!m.invert(&im)) { 2425 if (!m.invert(&im)) {
2395 return false; 2426 return false;
2396 } 2427 }
2397 return fDstToUnit.setConcat(im, this->getTotalInverse()); 2428 SkMatrix inverse;
2429 SkASSERT(matrix.invert(&inverse));
scroggo 2014/03/26 23:13:09 I seemed to have overlooked this part. I take it t
Dominik Grewe 2014/03/27 14:27:20 Actually, if we add a SkBlitter::getShaderContext(
scroggo 2014/03/27 18:05:33 That seems even better to me.
2430 return fDstToUnit.setConcat(im, inverse);
2398 } 2431 }
2399 2432
2400 #include "SkColorPriv.h" 2433 #include "SkColorPriv.h"
2401 #include "SkComposeShader.h" 2434 #include "SkComposeShader.h"
2402 2435
2403 static int ScalarTo256(SkScalar v) { 2436 static int ScalarTo256(SkScalar v) {
2404 int scale = SkScalarToFixed(v) >> 8; 2437 int scale = SkScalarToFixed(v) >> 8;
2405 if (scale < 0) { 2438 if (scale < 0) {
2406 scale = 0; 2439 scale = 0;
2407 } 2440 }
2408 if (scale > 255) { 2441 if (scale > 255) {
2409 scale = 255; 2442 scale = 255;
2410 } 2443 }
2411 return SkAlpha255To256(scale); 2444 return SkAlpha255To256(scale);
2412 } 2445 }
2413 2446
2414 void SkTriColorShader::shadeSpan(int x, int y, SkPMColor dstC[], int count) { 2447
2448 SkTriColorShader::TriColorShaderContext::TriColorShaderContext(
2449 const SkTriColorShader& shader, const SkBitmap& device,
scroggo 2014/03/24 21:24:46 nit: Parameters that fit on the same line should g
Dominik Grewe 2014/03/26 17:22:22 If I move the first one to the same line and line
2450 const SkPaint& paint, const SkMatrix& matrix)
2451 : INHERITED(shader, device, paint, matrix)
2452 , fTriColorShader(shader) {}
2453
2454 SkTriColorShader::TriColorShaderContext::~TriColorShaderContext() {}
2455
2456 size_t SkTriColorShader::contextSize() const {
2457 return sizeof(TriColorShaderContext);
2458 }
2459 void SkTriColorShader::TriColorShaderContext::shadeSpan(int x, int y, SkPMColor dstC[], int count) {
2415 SkPoint src; 2460 SkPoint src;
2416 2461
2417 for (int i = 0; i < count; i++) { 2462 for (int i = 0; i < count; i++) {
2418 fDstToUnit.mapXY(SkIntToScalar(x), SkIntToScalar(y), &src); 2463 fTriColorShader.fDstToUnit.mapXY(SkIntToScalar(x), SkIntToScalar(y), &sr c);
2419 x += 1; 2464 x += 1;
2420 2465
2421 int scale1 = ScalarTo256(src.fX); 2466 int scale1 = ScalarTo256(src.fX);
2422 int scale2 = ScalarTo256(src.fY); 2467 int scale2 = ScalarTo256(src.fY);
2423 int scale0 = 256 - scale1 - scale2; 2468 int scale0 = 256 - scale1 - scale2;
2424 if (scale0 < 0) { 2469 if (scale0 < 0) {
2425 if (scale1 > scale2) { 2470 if (scale1 > scale2) {
2426 scale2 = 256 - scale1; 2471 scale2 = 256 - scale1;
2427 } else { 2472 } else {
2428 scale1 = 256 - scale2; 2473 scale1 = 256 - scale2;
2429 } 2474 }
2430 scale0 = 0; 2475 scale0 = 0;
2431 } 2476 }
2432 2477
2433 dstC[i] = SkAlphaMulQ(fColors[0], scale0) + 2478 dstC[i] = SkAlphaMulQ(fTriColorShader.fColors[0], scale0) +
2434 SkAlphaMulQ(fColors[1], scale1) + 2479 SkAlphaMulQ(fTriColorShader.fColors[1], scale1) +
2435 SkAlphaMulQ(fColors[2], scale2); 2480 SkAlphaMulQ(fTriColorShader.fColors[2], scale2);
2436 } 2481 }
2437 } 2482 }
2438 2483
2439 #ifdef SK_DEVELOPER 2484 #ifdef SK_DEVELOPER
2440 void SkTriColorShader::toString(SkString* str) const { 2485 void SkTriColorShader::toString(SkString* str) const {
2441 str->append("SkTriColorShader: ("); 2486 str->append("SkTriColorShader: (");
2442 2487
2443 this->INHERITED::toString(str); 2488 this->INHERITED::toString(str);
2444 2489
2445 str->append(")"); 2490 str->append(")");
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
2511 SkShader* compose = SkNEW_ARGS(SkComposeShader, 2556 SkShader* compose = SkNEW_ARGS(SkComposeShader,
2512 (&triShader, shader, xmode)); 2557 (&triShader, shader, xmode));
2513 p.setShader(compose)->unref(); 2558 p.setShader(compose)->unref();
2514 if (releaseMode) { 2559 if (releaseMode) {
2515 xmode->unref(); 2560 xmode->unref();
2516 } 2561 }
2517 } 2562 }
2518 } 2563 }
2519 2564
2520 SkAutoBlitterChoose blitter(*fBitmap, *fMatrix, p); 2565 SkAutoBlitterChoose blitter(*fBitmap, *fMatrix, p);
2521 // important that we abort early, as below we may manipulate the shader 2566 // Important that we abort early, as below we may manipulate the shader cont ext
2522 // and that is only valid if the shader returned true from setContext. 2567 // and that is only valid if a context was successfully created from the sha der.
2523 // If it returned false, then our blitter will be the NullBlitter. 2568 // If it returned false, then our blitter will be the NullBlitter.
2524 if (blitter->isNullBlitter()) { 2569 if (blitter->isNullBlitter()) {
2525 return; 2570 return;
2526 } 2571 }
2527 2572
2528 // setup our state and function pointer for iterating triangles 2573 // setup our state and function pointer for iterating triangles
2529 VertState state(count, indices, indexCount); 2574 VertState state(count, indices, indexCount);
2530 VertState::Proc vertProc = state.chooseProc(vmode); 2575 VertState::Proc vertProc = state.chooseProc(vmode);
2531 2576
2532 if (NULL != textures || NULL != colors) { 2577 if (NULL != textures || NULL != colors) {
2533 SkMatrix tempM; 2578 SkMatrix tempM;
2534 SkMatrix savedLocalM; 2579 SkMatrix savedLocalM;
2535 if (shader) { 2580 if (shader) {
2536 savedLocalM = shader->getLocalMatrix(); 2581 savedLocalM = shader->getLocalMatrix();
2537 } 2582 }
2538 2583
2539 // setContext has already been called and verified to return true
2540 // by the constructor of SkAutoBlitterChoose
2541 bool prevContextSuccess = true;
2542 while (vertProc(&state)) { 2584 while (vertProc(&state)) {
2543 if (NULL != textures) { 2585 if (NULL != textures) {
2544 if (texture_to_matrix(state, vertices, textures, &tempM)) { 2586 if (texture_to_matrix(state, vertices, textures, &tempM)) {
2545 tempM.postConcat(savedLocalM); 2587 tempM.postConcat(savedLocalM);
2546 shader->setLocalMatrix(tempM); 2588 shader->setLocalMatrix(tempM);
2547 // Need to recall setContext since we changed the local matr ix. 2589 if (!blitter->resetShaderContext(*fBitmap, p, *fMatrix)) {
Dominik Grewe 2014/03/21 12:52:50 Afaict, we want to create a new shader context her
scroggo 2014/03/24 21:24:46 This seems like a fine way to do it to me.
2548 // However, we also need to balance the calls this with a
2549 // call to endContext which requires tracking the result of
2550 // the previous call to setContext.
2551 if (prevContextSuccess) {
2552 shader->endContext();
2553 }
2554 prevContextSuccess = shader->setContext(*fBitmap, p, *fMatri x);
2555 if (!prevContextSuccess) {
2556 continue; 2590 continue;
2557 } 2591 }
2558 } 2592 }
2559 } 2593 }
2560 if (NULL != colors) { 2594 if (NULL != colors) {
2561 if (!triShader.setup(vertices, colors, 2595 if (!triShader.setup(vertices, colors,
2562 state.f0, state.f1, state.f2)) { 2596 state.f0, state.f1, state.f2, *fMatrix)) {
2563 continue; 2597 continue;
2564 } 2598 }
2565 } 2599 }
2566 2600
2567 SkPoint tmp[] = { 2601 SkPoint tmp[] = {
2568 devVerts[state.f0], devVerts[state.f1], devVerts[state.f2] 2602 devVerts[state.f0], devVerts[state.f1], devVerts[state.f2]
2569 }; 2603 };
2570 SkScan::FillTriangle(tmp, *fRC, blitter.get()); 2604 SkScan::FillTriangle(tmp, *fRC, blitter.get());
2571 } 2605 }
2572 2606
2573 // now restore the shader's original local matrix 2607 // now restore the shader's original local matrix
2574 if (NULL != shader) { 2608 if (NULL != shader) {
2575 shader->setLocalMatrix(savedLocalM); 2609 shader->setLocalMatrix(savedLocalM);
2576 } 2610 }
2577
2578 // If the final call to setContext fails we must make it suceed so that the
2579 // call to endContext in the destructor for SkAutoBlitterChoose is balan ced.
2580 if (!prevContextSuccess) {
2581 prevContextSuccess = shader->setContext(*fBitmap, paint, SkMatrix::I ());
2582 SkASSERT(prevContextSuccess);
2583 }
2584 } else { 2611 } else {
2585 // no colors[] and no texture 2612 // no colors[] and no texture
2586 HairProc hairProc = ChooseHairProc(paint.isAntiAlias()); 2613 HairProc hairProc = ChooseHairProc(paint.isAntiAlias());
2587 const SkRasterClip& clip = *fRC; 2614 const SkRasterClip& clip = *fRC;
2588 while (vertProc(&state)) { 2615 while (vertProc(&state)) {
2589 hairProc(devVerts[state.f0], devVerts[state.f1], clip, blitter.get() ); 2616 hairProc(devVerts[state.f0], devVerts[state.f1], clip, blitter.get() );
2590 hairProc(devVerts[state.f1], devVerts[state.f2], clip, blitter.get() ); 2617 hairProc(devVerts[state.f1], devVerts[state.f2], clip, blitter.get() );
2591 hairProc(devVerts[state.f2], devVerts[state.f0], clip, blitter.get() ); 2618 hairProc(devVerts[state.f2], devVerts[state.f0], clip, blitter.get() );
2592 } 2619 }
2593 } 2620 }
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
2805 mask->fImage = SkMask::AllocImage(size); 2832 mask->fImage = SkMask::AllocImage(size);
2806 memset(mask->fImage, 0, mask->computeImageSize()); 2833 memset(mask->fImage, 0, mask->computeImageSize());
2807 } 2834 }
2808 2835
2809 if (SkMask::kJustComputeBounds_CreateMode != mode) { 2836 if (SkMask::kJustComputeBounds_CreateMode != mode) {
2810 draw_into_mask(*mask, devPath, style); 2837 draw_into_mask(*mask, devPath, style);
2811 } 2838 }
2812 2839
2813 return true; 2840 return true;
2814 } 2841 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698