OLD | NEW |
---|---|
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 Loading... | |
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 | |
scroggo
2014/04/02 20:16:53
Now that setup is on the context, isn't this comme
Dominik Grewe
2014/04/03 12:12:59
You're right. Thanks for spotting.
| |
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 virtual SkShader::Context* createContext( |
2368 const SkBitmap&, const SkPaint&, const SkMatrix&, void*) const SK_OV ERRIDE; | |
2369 virtual size_t contextSize() const SK_OVERRIDE; | |
2363 | 2370 |
2364 virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count) SK_OVERRID E; | 2371 class TriColorShaderContext : public SkShader::Context { |
2372 public: | |
2373 TriColorShaderContext(const SkTriColorShader& shader, const SkBitmap& de vice, | |
2374 const SkPaint& paint, const SkMatrix& matrix); | |
2375 virtual ~TriColorShaderContext(); | |
2376 | |
2377 bool setup(const SkPoint pts[], const SkColor colors[], int, int, int); | |
2378 | |
2379 virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count) SK_OVE RRIDE; | |
2380 | |
2381 private: | |
2382 SkMatrix fDstToUnit; | |
2383 SkPMColor fColors[3]; | |
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: | |
2373 SkMatrix fDstToUnit; | |
2374 SkPMColor fColors[3]; | |
2375 | |
2376 typedef SkShader INHERITED; | 2394 typedef SkShader INHERITED; |
2377 }; | 2395 }; |
2378 | 2396 |
2379 bool SkTriColorShader::setup(const SkPoint pts[], const SkColor colors[], | 2397 SkShader::Context* SkTriColorShader::createContext(const SkBitmap& device, const SkPaint& paint, |
2380 int index0, int index1, int index2) { | 2398 const SkMatrix& matrix, void* storage) const { |
2399 if (!this->validContext(device, paint, matrix)) { | |
2400 return NULL; | |
2401 } | |
2402 | |
2403 return SkNEW_PLACEMENT_ARGS(storage, TriColorShaderContext, (*this, device, paint, matrix)); | |
2404 } | |
2405 | |
2406 bool SkTriColorShader::TriColorShaderContext::setup(const SkPoint pts[], const S kColor colors[], | |
2407 int index0, int index1, int index2) { | |
2381 | 2408 |
2382 fColors[0] = SkPreMultiplyColor(colors[index0]); | 2409 fColors[0] = SkPreMultiplyColor(colors[index0]); |
2383 fColors[1] = SkPreMultiplyColor(colors[index1]); | 2410 fColors[1] = SkPreMultiplyColor(colors[index1]); |
2384 fColors[2] = SkPreMultiplyColor(colors[index2]); | 2411 fColors[2] = SkPreMultiplyColor(colors[index2]); |
2385 | 2412 |
2386 SkMatrix m, im; | 2413 SkMatrix m, im; |
2387 m.reset(); | 2414 m.reset(); |
2388 m.set(0, pts[index1].fX - pts[index0].fX); | 2415 m.set(0, pts[index1].fX - pts[index0].fX); |
2389 m.set(1, pts[index2].fX - pts[index0].fX); | 2416 m.set(1, pts[index2].fX - pts[index0].fX); |
2390 m.set(2, pts[index0].fX); | 2417 m.set(2, pts[index0].fX); |
(...skipping 13 matching lines...) Expand all Loading... | |
2404 int scale = SkScalarToFixed(v) >> 8; | 2431 int scale = SkScalarToFixed(v) >> 8; |
2405 if (scale < 0) { | 2432 if (scale < 0) { |
2406 scale = 0; | 2433 scale = 0; |
2407 } | 2434 } |
2408 if (scale > 255) { | 2435 if (scale > 255) { |
2409 scale = 255; | 2436 scale = 255; |
2410 } | 2437 } |
2411 return SkAlpha255To256(scale); | 2438 return SkAlpha255To256(scale); |
2412 } | 2439 } |
2413 | 2440 |
2414 void SkTriColorShader::shadeSpan(int x, int y, SkPMColor dstC[], int count) { | 2441 |
2442 SkTriColorShader::TriColorShaderContext::TriColorShaderContext( | |
2443 const SkTriColorShader& shader, const SkBitmap& device, | |
2444 const SkPaint& paint, const SkMatrix& matrix) | |
2445 : INHERITED(shader, device, paint, matrix) {} | |
2446 | |
2447 SkTriColorShader::TriColorShaderContext::~TriColorShaderContext() {} | |
2448 | |
2449 size_t SkTriColorShader::contextSize() const { | |
2450 return sizeof(TriColorShaderContext); | |
2451 } | |
2452 void SkTriColorShader::TriColorShaderContext::shadeSpan(int x, int y, SkPMColor dstC[], int count) { | |
2415 SkPoint src; | 2453 SkPoint src; |
2416 | 2454 |
2417 for (int i = 0; i < count; i++) { | 2455 for (int i = 0; i < count; i++) { |
2418 fDstToUnit.mapXY(SkIntToScalar(x), SkIntToScalar(y), &src); | 2456 fDstToUnit.mapXY(SkIntToScalar(x), SkIntToScalar(y), &src); |
2419 x += 1; | 2457 x += 1; |
2420 | 2458 |
2421 int scale1 = ScalarTo256(src.fX); | 2459 int scale1 = ScalarTo256(src.fX); |
2422 int scale2 = ScalarTo256(src.fY); | 2460 int scale2 = ScalarTo256(src.fY); |
2423 int scale0 = 256 - scale1 - scale2; | 2461 int scale0 = 256 - scale1 - scale2; |
2424 if (scale0 < 0) { | 2462 if (scale0 < 0) { |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2511 SkShader* compose = SkNEW_ARGS(SkComposeShader, | 2549 SkShader* compose = SkNEW_ARGS(SkComposeShader, |
2512 (&triShader, shader, xmode)); | 2550 (&triShader, shader, xmode)); |
2513 p.setShader(compose)->unref(); | 2551 p.setShader(compose)->unref(); |
2514 if (releaseMode) { | 2552 if (releaseMode) { |
2515 xmode->unref(); | 2553 xmode->unref(); |
2516 } | 2554 } |
2517 } | 2555 } |
2518 } | 2556 } |
2519 | 2557 |
2520 SkAutoBlitterChoose blitter(*fBitmap, *fMatrix, p); | 2558 SkAutoBlitterChoose blitter(*fBitmap, *fMatrix, p); |
2521 // important that we abort early, as below we may manipulate the shader | 2559 // Abort early if we failed to create a shader context. |
2522 // and that is only valid if the shader returned true from setContext. | |
2523 // If it returned false, then our blitter will be the NullBlitter. | |
2524 if (blitter->isNullBlitter()) { | 2560 if (blitter->isNullBlitter()) { |
2525 return; | 2561 return; |
2526 } | 2562 } |
2527 | 2563 |
2528 // setup our state and function pointer for iterating triangles | 2564 // setup our state and function pointer for iterating triangles |
2529 VertState state(count, indices, indexCount); | 2565 VertState state(count, indices, indexCount); |
2530 VertState::Proc vertProc = state.chooseProc(vmode); | 2566 VertState::Proc vertProc = state.chooseProc(vmode); |
2531 | 2567 |
2532 if (NULL != textures || NULL != colors) { | 2568 if (NULL != textures || NULL != colors) { |
2533 SkMatrix tempM; | 2569 SkMatrix tempM; |
2534 SkMatrix savedLocalM; | 2570 SkMatrix savedLocalM; |
2535 if (shader) { | 2571 if (shader) { |
2536 savedLocalM = shader->getLocalMatrix(); | 2572 savedLocalM = shader->getLocalMatrix(); |
2537 } | 2573 } |
2538 | 2574 |
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)) { | 2575 while (vertProc(&state)) { |
2543 if (NULL != textures) { | 2576 if (NULL != textures) { |
2544 if (texture_to_matrix(state, vertices, textures, &tempM)) { | 2577 if (texture_to_matrix(state, vertices, textures, &tempM)) { |
2545 tempM.postConcat(savedLocalM); | 2578 tempM.postConcat(savedLocalM); |
2546 shader->setLocalMatrix(tempM); | 2579 shader->setLocalMatrix(tempM); |
2547 // Need to recall setContext since we changed the local matr ix. | 2580 if (!blitter->resetShaderContext(*fBitmap, p, *fMatrix)) { |
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; | 2581 continue; |
2557 } | 2582 } |
2558 } | 2583 } |
2559 } | 2584 } |
2560 if (NULL != colors) { | 2585 if (NULL != colors) { |
2561 if (!triShader.setup(vertices, colors, | 2586 // Find the context for triShader. |
2562 state.f0, state.f1, state.f2)) { | 2587 SkTriColorShader::TriColorShaderContext* triColorShaderContext; |
2588 | |
2589 SkShader::Context* shaderContext = blitter->getShaderContext(); | |
2590 SkASSERT(shaderContext); | |
2591 if (p.getShader() == &triShader) { | |
2592 triColorShaderContext = | |
2593 static_cast<SkTriColorShader::TriColorShaderContext* >(shaderContext); | |
2594 } else { | |
2595 // The shader is a compose shader and triShader is its first shader. | |
2596 SkComposeShader::ComposeShaderContext* composeShaderContext = | |
2597 static_cast<SkComposeShader::ComposeShaderContext*>( shaderContext); | |
scroggo
2014/04/02 20:16:53
This code makes a lot of assumptions about the cod
Dominik Grewe
2014/04/03 12:12:59
Good point. I've added the asserts.
| |
2598 SkShader::Context* shaderContextA = composeShaderContext->ge tShaderContextA(); | |
2599 triColorShaderContext = | |
2600 static_cast<SkTriColorShader::TriColorShaderContext* >(shaderContextA); | |
2601 } | |
2602 | |
2603 if (!triColorShaderContext->setup(vertices, colors, | |
2604 state.f0, state.f1, state.f2)) { | |
2563 continue; | 2605 continue; |
2564 } | 2606 } |
2565 } | 2607 } |
2566 | 2608 |
2567 SkPoint tmp[] = { | 2609 SkPoint tmp[] = { |
2568 devVerts[state.f0], devVerts[state.f1], devVerts[state.f2] | 2610 devVerts[state.f0], devVerts[state.f1], devVerts[state.f2] |
2569 }; | 2611 }; |
2570 SkScan::FillTriangle(tmp, *fRC, blitter.get()); | 2612 SkScan::FillTriangle(tmp, *fRC, blitter.get()); |
2571 } | 2613 } |
2572 | 2614 |
2573 // now restore the shader's original local matrix | 2615 // now restore the shader's original local matrix |
2574 if (NULL != shader) { | 2616 if (NULL != shader) { |
2575 shader->setLocalMatrix(savedLocalM); | 2617 shader->setLocalMatrix(savedLocalM); |
2576 } | 2618 } |
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 { | 2619 } else { |
2585 // no colors[] and no texture | 2620 // no colors[] and no texture |
2586 HairProc hairProc = ChooseHairProc(paint.isAntiAlias()); | 2621 HairProc hairProc = ChooseHairProc(paint.isAntiAlias()); |
2587 const SkRasterClip& clip = *fRC; | 2622 const SkRasterClip& clip = *fRC; |
2588 while (vertProc(&state)) { | 2623 while (vertProc(&state)) { |
2589 hairProc(devVerts[state.f0], devVerts[state.f1], clip, blitter.get() ); | 2624 hairProc(devVerts[state.f0], devVerts[state.f1], clip, blitter.get() ); |
2590 hairProc(devVerts[state.f1], devVerts[state.f2], clip, blitter.get() ); | 2625 hairProc(devVerts[state.f1], devVerts[state.f2], clip, blitter.get() ); |
2591 hairProc(devVerts[state.f2], devVerts[state.f0], clip, blitter.get() ); | 2626 hairProc(devVerts[state.f2], devVerts[state.f0], clip, blitter.get() ); |
2592 } | 2627 } |
2593 } | 2628 } |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2805 mask->fImage = SkMask::AllocImage(size); | 2840 mask->fImage = SkMask::AllocImage(size); |
2806 memset(mask->fImage, 0, mask->computeImageSize()); | 2841 memset(mask->fImage, 0, mask->computeImageSize()); |
2807 } | 2842 } |
2808 | 2843 |
2809 if (SkMask::kJustComputeBounds_CreateMode != mode) { | 2844 if (SkMask::kJustComputeBounds_CreateMode != mode) { |
2810 draw_into_mask(*mask, devPath, style); | 2845 draw_into_mask(*mask, devPath, style); |
2811 } | 2846 } |
2812 | 2847 |
2813 return true; | 2848 return true; |
2814 } | 2849 } |
OLD | NEW |