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

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: rebase Created 6 years, 8 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 | « src/core/SkCoreBlitters.h ('k') | src/core/SkFilterShader.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 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 2336 matching lines...) Expand 10 before | Expand all | Expand 10 after
2347 dst[0] = verts[state.f0]; 2347 dst[0] = verts[state.f0];
2348 dst[1] = verts[state.f1]; 2348 dst[1] = verts[state.f1];
2349 dst[2] = verts[state.f2]; 2349 dst[2] = verts[state.f2];
2350 return matrix->setPolyToPoly(src, dst, 3); 2350 return matrix->setPolyToPoly(src, dst, 3);
2351 } 2351 }
2352 2352
2353 class SkTriColorShader : public SkShader { 2353 class SkTriColorShader : public SkShader {
2354 public: 2354 public:
2355 SkTriColorShader() {} 2355 SkTriColorShader() {}
2356 2356
2357 bool setup(const SkPoint pts[], const SkColor colors[], int, int, int); 2357 virtual SkShader::Context* createContext(
2358 const SkBitmap&, const SkPaint&, const SkMatrix&, void*) const SK_OV ERRIDE;
2359 virtual size_t contextSize() const SK_OVERRIDE;
2358 2360
2359 virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count) SK_OVERRID E; 2361 class TriColorShaderContext : public SkShader::Context {
2362 public:
2363 TriColorShaderContext(const SkTriColorShader& shader, const SkBitmap& de vice,
2364 const SkPaint& paint, const SkMatrix& matrix);
2365 virtual ~TriColorShaderContext();
2366
2367 bool setup(const SkPoint pts[], const SkColor colors[], int, int, int);
2368
2369 virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count) SK_OVE RRIDE;
2370
2371 private:
2372 SkMatrix fDstToUnit;
2373 SkPMColor fColors[3];
2374
2375 typedef SkShader::Context INHERITED;
2376 };
2360 2377
2361 SK_TO_STRING_OVERRIDE() 2378 SK_TO_STRING_OVERRIDE()
2362 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkTriColorShader) 2379 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkTriColorShader)
2363 2380
2364 protected: 2381 protected:
2365 SkTriColorShader(SkReadBuffer& buffer) : SkShader(buffer) {} 2382 SkTriColorShader(SkReadBuffer& buffer) : SkShader(buffer) {}
2366 2383
2367 private: 2384 private:
2368 SkMatrix fDstToUnit;
2369 SkPMColor fColors[3];
2370
2371 typedef SkShader INHERITED; 2385 typedef SkShader INHERITED;
2372 }; 2386 };
2373 2387
2374 bool SkTriColorShader::setup(const SkPoint pts[], const SkColor colors[], 2388 SkShader::Context* SkTriColorShader::createContext(const SkBitmap& device, const SkPaint& paint,
2375 int index0, int index1, int index2) { 2389 const SkMatrix& matrix, void* storage) const {
2390 if (!this->validContext(device, paint, matrix)) {
2391 return NULL;
2392 }
2393
2394 return SkNEW_PLACEMENT_ARGS(storage, TriColorShaderContext, (*this, device, paint, matrix));
2395 }
2396
2397 bool SkTriColorShader::TriColorShaderContext::setup(const SkPoint pts[], const S kColor colors[],
2398 int index0, int index1, int index2) {
2376 2399
2377 fColors[0] = SkPreMultiplyColor(colors[index0]); 2400 fColors[0] = SkPreMultiplyColor(colors[index0]);
2378 fColors[1] = SkPreMultiplyColor(colors[index1]); 2401 fColors[1] = SkPreMultiplyColor(colors[index1]);
2379 fColors[2] = SkPreMultiplyColor(colors[index2]); 2402 fColors[2] = SkPreMultiplyColor(colors[index2]);
2380 2403
2381 SkMatrix m, im; 2404 SkMatrix m, im;
2382 m.reset(); 2405 m.reset();
2383 m.set(0, pts[index1].fX - pts[index0].fX); 2406 m.set(0, pts[index1].fX - pts[index0].fX);
2384 m.set(1, pts[index2].fX - pts[index0].fX); 2407 m.set(1, pts[index2].fX - pts[index0].fX);
2385 m.set(2, pts[index0].fX); 2408 m.set(2, pts[index0].fX);
(...skipping 14 matching lines...) Expand all
2400 int scale = SkScalarToFixed(v) >> 8; 2423 int scale = SkScalarToFixed(v) >> 8;
2401 if (scale < 0) { 2424 if (scale < 0) {
2402 scale = 0; 2425 scale = 0;
2403 } 2426 }
2404 if (scale > 255) { 2427 if (scale > 255) {
2405 scale = 255; 2428 scale = 255;
2406 } 2429 }
2407 return SkAlpha255To256(scale); 2430 return SkAlpha255To256(scale);
2408 } 2431 }
2409 2432
2410 void SkTriColorShader::shadeSpan(int x, int y, SkPMColor dstC[], int count) { 2433
2434 SkTriColorShader::TriColorShaderContext::TriColorShaderContext(
2435 const SkTriColorShader& shader, const SkBitmap& device,
2436 const SkPaint& paint, const SkMatrix& matrix)
2437 : INHERITED(shader, device, paint, matrix) {}
2438
2439 SkTriColorShader::TriColorShaderContext::~TriColorShaderContext() {}
2440
2441 size_t SkTriColorShader::contextSize() const {
2442 return sizeof(TriColorShaderContext);
2443 }
2444 void SkTriColorShader::TriColorShaderContext::shadeSpan(int x, int y, SkPMColor dstC[], int count) {
2411 SkPoint src; 2445 SkPoint src;
2412 2446
2413 for (int i = 0; i < count; i++) { 2447 for (int i = 0; i < count; i++) {
2414 fDstToUnit.mapXY(SkIntToScalar(x), SkIntToScalar(y), &src); 2448 fDstToUnit.mapXY(SkIntToScalar(x), SkIntToScalar(y), &src);
2415 x += 1; 2449 x += 1;
2416 2450
2417 int scale1 = ScalarTo256(src.fX); 2451 int scale1 = ScalarTo256(src.fX);
2418 int scale2 = ScalarTo256(src.fY); 2452 int scale2 = ScalarTo256(src.fY);
2419 int scale0 = 256 - scale1 - scale2; 2453 int scale0 = 256 - scale1 - scale2;
2420 if (scale0 < 0) { 2454 if (scale0 < 0) {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
2485 if (NULL == shader) { 2519 if (NULL == shader) {
2486 // if we have no shader, we ignore the texture coordinates 2520 // if we have no shader, we ignore the texture coordinates
2487 textures = NULL; 2521 textures = NULL;
2488 } else if (NULL == textures) { 2522 } else if (NULL == textures) {
2489 // if we don't have texture coordinates, ignore the shader 2523 // if we don't have texture coordinates, ignore the shader
2490 p.setShader(NULL); 2524 p.setShader(NULL);
2491 shader = NULL; 2525 shader = NULL;
2492 } 2526 }
2493 2527
2494 // setup the custom shader (if needed) 2528 // setup the custom shader (if needed)
2529 SkAutoTUnref<SkComposeShader> composeShader;
2495 if (NULL != colors) { 2530 if (NULL != colors) {
2496 if (NULL == textures) { 2531 if (NULL == textures) {
2497 // just colors (no texture) 2532 // just colors (no texture)
2498 shader = p.setShader(&triShader); 2533 shader = p.setShader(&triShader);
2499 } else { 2534 } else {
2500 // colors * texture 2535 // colors * texture
2501 SkASSERT(shader); 2536 SkASSERT(shader);
2502 bool releaseMode = false; 2537 bool releaseMode = false;
2503 if (NULL == xmode) { 2538 if (NULL == xmode) {
2504 xmode = SkXfermode::Create(SkXfermode::kModulate_Mode); 2539 xmode = SkXfermode::Create(SkXfermode::kModulate_Mode);
2505 releaseMode = true; 2540 releaseMode = true;
2506 } 2541 }
2507 SkShader* compose = SkNEW_ARGS(SkComposeShader, 2542 composeShader.reset(SkNEW_ARGS(SkComposeShader, (&triShader, shader, xmode)));
2508 (&triShader, shader, xmode)); 2543 p.setShader(composeShader);
2509 p.setShader(compose)->unref();
2510 if (releaseMode) { 2544 if (releaseMode) {
2511 xmode->unref(); 2545 xmode->unref();
2512 } 2546 }
2513 } 2547 }
2514 } 2548 }
2515 2549
2516 SkAutoBlitterChoose blitter(*fBitmap, *fMatrix, p); 2550 SkAutoBlitterChoose blitter(*fBitmap, *fMatrix, p);
2517 // important that we abort early, as below we may manipulate the shader 2551 // Abort early if we failed to create a shader context.
2518 // and that is only valid if the shader returned true from setContext.
2519 // If it returned false, then our blitter will be the NullBlitter.
2520 if (blitter->isNullBlitter()) { 2552 if (blitter->isNullBlitter()) {
2521 return; 2553 return;
2522 } 2554 }
2523 2555
2524 // setup our state and function pointer for iterating triangles 2556 // setup our state and function pointer for iterating triangles
2525 VertState state(count, indices, indexCount); 2557 VertState state(count, indices, indexCount);
2526 VertState::Proc vertProc = state.chooseProc(vmode); 2558 VertState::Proc vertProc = state.chooseProc(vmode);
2527 2559
2528 if (NULL != textures || NULL != colors) { 2560 if (NULL != textures || NULL != colors) {
2529 SkMatrix tempM; 2561 SkMatrix tempM;
2530 SkMatrix savedLocalM; 2562 SkMatrix savedLocalM;
2531 if (shader) { 2563 if (shader) {
2532 savedLocalM = shader->getLocalMatrix(); 2564 savedLocalM = shader->getLocalMatrix();
2533 } 2565 }
2534 2566
2535 // setContext has already been called and verified to return true
2536 // by the constructor of SkAutoBlitterChoose
2537 bool prevContextSuccess = true;
2538 while (vertProc(&state)) { 2567 while (vertProc(&state)) {
2539 if (NULL != textures) { 2568 if (NULL != textures) {
2540 if (texture_to_matrix(state, vertices, textures, &tempM)) { 2569 if (texture_to_matrix(state, vertices, textures, &tempM)) {
2541 tempM.postConcat(savedLocalM); 2570 tempM.postConcat(savedLocalM);
2542 shader->setLocalMatrix(tempM); 2571 shader->setLocalMatrix(tempM);
2543 // Need to recall setContext since we changed the local matr ix. 2572 if (!blitter->resetShaderContext(*fBitmap, p, *fMatrix)) {
2544 // However, we also need to balance the calls this with a
2545 // call to endContext which requires tracking the result of
2546 // the previous call to setContext.
2547 if (prevContextSuccess) {
2548 shader->endContext();
2549 }
2550 prevContextSuccess = shader->setContext(*fBitmap, p, *fMatri x);
2551 if (!prevContextSuccess) {
2552 continue; 2573 continue;
2553 } 2574 }
2554 } 2575 }
2555 } 2576 }
2556 if (NULL != colors) { 2577 if (NULL != colors) {
2557 if (!triShader.setup(vertices, colors, 2578 // Find the context for triShader.
2558 state.f0, state.f1, state.f2)) { 2579 SkTriColorShader::TriColorShaderContext* triColorShaderContext;
2580
2581 SkShader::Context* shaderContext = blitter->getShaderContext();
2582 SkASSERT(shaderContext);
2583 if (p.getShader() == &triShader) {
2584 triColorShaderContext =
2585 static_cast<SkTriColorShader::TriColorShaderContext* >(shaderContext);
2586 } else {
2587 // The shader is a compose shader and triShader is its first shader.
2588 SkASSERT(p.getShader() == composeShader);
2589 SkASSERT(composeShader->getShaderA() == &triShader);
2590 SkComposeShader::ComposeShaderContext* composeShaderContext =
2591 static_cast<SkComposeShader::ComposeShaderContext*>( shaderContext);
2592 SkShader::Context* shaderContextA = composeShaderContext->ge tShaderContextA();
2593 triColorShaderContext =
2594 static_cast<SkTriColorShader::TriColorShaderContext* >(shaderContextA);
2595 }
2596
2597 if (!triColorShaderContext->setup(vertices, colors,
2598 state.f0, state.f1, state.f2)) {
2559 continue; 2599 continue;
2560 } 2600 }
2561 } 2601 }
2562 2602
2563 SkPoint tmp[] = { 2603 SkPoint tmp[] = {
2564 devVerts[state.f0], devVerts[state.f1], devVerts[state.f2] 2604 devVerts[state.f0], devVerts[state.f1], devVerts[state.f2]
2565 }; 2605 };
2566 SkScan::FillTriangle(tmp, *fRC, blitter.get()); 2606 SkScan::FillTriangle(tmp, *fRC, blitter.get());
2567 } 2607 }
2568 2608
2569 // now restore the shader's original local matrix 2609 // now restore the shader's original local matrix
2570 if (NULL != shader) { 2610 if (NULL != shader) {
2571 shader->setLocalMatrix(savedLocalM); 2611 shader->setLocalMatrix(savedLocalM);
2572 } 2612 }
2573
2574 // If the final call to setContext fails we must make it suceed so that the
2575 // call to endContext in the destructor for SkAutoBlitterChoose is balan ced.
2576 if (!prevContextSuccess) {
2577 prevContextSuccess = shader->setContext(*fBitmap, paint, SkMatrix::I ());
2578 SkASSERT(prevContextSuccess);
2579 }
2580 } else { 2613 } else {
2581 // no colors[] and no texture 2614 // no colors[] and no texture
2582 HairProc hairProc = ChooseHairProc(paint.isAntiAlias()); 2615 HairProc hairProc = ChooseHairProc(paint.isAntiAlias());
2583 const SkRasterClip& clip = *fRC; 2616 const SkRasterClip& clip = *fRC;
2584 while (vertProc(&state)) { 2617 while (vertProc(&state)) {
2585 hairProc(devVerts[state.f0], devVerts[state.f1], clip, blitter.get() ); 2618 hairProc(devVerts[state.f0], devVerts[state.f1], clip, blitter.get() );
2586 hairProc(devVerts[state.f1], devVerts[state.f2], clip, blitter.get() ); 2619 hairProc(devVerts[state.f1], devVerts[state.f2], clip, blitter.get() );
2587 hairProc(devVerts[state.f2], devVerts[state.f0], clip, blitter.get() ); 2620 hairProc(devVerts[state.f2], devVerts[state.f0], clip, blitter.get() );
2588 } 2621 }
2589 } 2622 }
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
2801 mask->fImage = SkMask::AllocImage(size); 2834 mask->fImage = SkMask::AllocImage(size);
2802 memset(mask->fImage, 0, mask->computeImageSize()); 2835 memset(mask->fImage, 0, mask->computeImageSize());
2803 } 2836 }
2804 2837
2805 if (SkMask::kJustComputeBounds_CreateMode != mode) { 2838 if (SkMask::kJustComputeBounds_CreateMode != mode) {
2806 draw_into_mask(*mask, devPath, style); 2839 draw_into_mask(*mask, devPath, style);
2807 } 2840 }
2808 2841
2809 return true; 2842 return true;
2810 } 2843 }
OLDNEW
« no previous file with comments | « src/core/SkCoreBlitters.h ('k') | src/core/SkFilterShader.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698