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 2336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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: | |
2368 SkMatrix fDstToUnit; | |
2369 SkPMColor fColors[3]; | |
2370 | |
2371 typedef SkShader INHERITED; | 2384 typedef SkShader INHERITED; |
2372 }; | 2385 }; |
2373 | 2386 |
2374 bool SkTriColorShader::setup(const SkPoint pts[], const SkColor colors[], | 2387 SkShader::Context* SkTriColorShader::createContext(const SkBitmap& device, const SkPaint& paint, |
2375 int index0, int index1, int index2) { | 2388 const SkMatrix& matrix, void* storage) const { |
2389 if (!this->validContext(device, paint, matrix)) { | |
2390 return NULL; | |
2391 } | |
2392 | |
2393 return SkNEW_PLACEMENT_ARGS(storage, TriColorShaderContext, (*this, device, paint, matrix)); | |
2394 } | |
2395 | |
2396 bool SkTriColorShader::TriColorShaderContext::setup(const SkPoint pts[], const S kColor colors[], | |
2397 int index0, int index1, int index2) { | |
2376 | 2398 |
2377 fColors[0] = SkPreMultiplyColor(colors[index0]); | 2399 fColors[0] = SkPreMultiplyColor(colors[index0]); |
2378 fColors[1] = SkPreMultiplyColor(colors[index1]); | 2400 fColors[1] = SkPreMultiplyColor(colors[index1]); |
2379 fColors[2] = SkPreMultiplyColor(colors[index2]); | 2401 fColors[2] = SkPreMultiplyColor(colors[index2]); |
2380 | 2402 |
2381 SkMatrix m, im; | 2403 SkMatrix m, im; |
2382 m.reset(); | 2404 m.reset(); |
2383 m.set(0, pts[index1].fX - pts[index0].fX); | 2405 m.set(0, pts[index1].fX - pts[index0].fX); |
2384 m.set(1, pts[index2].fX - pts[index0].fX); | 2406 m.set(1, pts[index2].fX - pts[index0].fX); |
2385 m.set(2, pts[index0].fX); | 2407 m.set(2, pts[index0].fX); |
(...skipping 14 matching lines...) Expand all Loading... | |
2400 int scale = SkScalarToFixed(v) >> 8; | 2422 int scale = SkScalarToFixed(v) >> 8; |
2401 if (scale < 0) { | 2423 if (scale < 0) { |
2402 scale = 0; | 2424 scale = 0; |
2403 } | 2425 } |
2404 if (scale > 255) { | 2426 if (scale > 255) { |
2405 scale = 255; | 2427 scale = 255; |
2406 } | 2428 } |
2407 return SkAlpha255To256(scale); | 2429 return SkAlpha255To256(scale); |
2408 } | 2430 } |
2409 | 2431 |
2410 void SkTriColorShader::shadeSpan(int x, int y, SkPMColor dstC[], int count) { | 2432 |
2433 SkTriColorShader::TriColorShaderContext::TriColorShaderContext( | |
2434 const SkTriColorShader& shader, const SkBitmap& device, | |
2435 const SkPaint& paint, const SkMatrix& matrix) | |
2436 : INHERITED(shader, device, paint, matrix) {} | |
2437 | |
2438 SkTriColorShader::TriColorShaderContext::~TriColorShaderContext() {} | |
2439 | |
2440 size_t SkTriColorShader::contextSize() const { | |
2441 return sizeof(TriColorShaderContext); | |
2442 } | |
2443 void SkTriColorShader::TriColorShaderContext::shadeSpan(int x, int y, SkPMColor dstC[], int count) { | |
2411 SkPoint src; | 2444 SkPoint src; |
2412 | 2445 |
2413 for (int i = 0; i < count; i++) { | 2446 for (int i = 0; i < count; i++) { |
2414 fDstToUnit.mapXY(SkIntToScalar(x), SkIntToScalar(y), &src); | 2447 fDstToUnit.mapXY(SkIntToScalar(x), SkIntToScalar(y), &src); |
2415 x += 1; | 2448 x += 1; |
2416 | 2449 |
2417 int scale1 = ScalarTo256(src.fX); | 2450 int scale1 = ScalarTo256(src.fX); |
2418 int scale2 = ScalarTo256(src.fY); | 2451 int scale2 = ScalarTo256(src.fY); |
2419 int scale0 = 256 - scale1 - scale2; | 2452 int scale0 = 256 - scale1 - scale2; |
2420 if (scale0 < 0) { | 2453 if (scale0 < 0) { |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2485 if (NULL == shader) { | 2518 if (NULL == shader) { |
2486 // if we have no shader, we ignore the texture coordinates | 2519 // if we have no shader, we ignore the texture coordinates |
2487 textures = NULL; | 2520 textures = NULL; |
2488 } else if (NULL == textures) { | 2521 } else if (NULL == textures) { |
2489 // if we don't have texture coordinates, ignore the shader | 2522 // if we don't have texture coordinates, ignore the shader |
2490 p.setShader(NULL); | 2523 p.setShader(NULL); |
2491 shader = NULL; | 2524 shader = NULL; |
2492 } | 2525 } |
2493 | 2526 |
2494 // setup the custom shader (if needed) | 2527 // setup the custom shader (if needed) |
2528 SkAutoTUnref<SkComposeShader> composeShader; | |
scroggo
2014/04/03 15:35:54
This should be in SkDEBUGCODE, since we only need
Dominik Grewe
2014/04/04 10:59:41
I also use it below though (outside of the assert)
| |
2495 if (NULL != colors) { | 2529 if (NULL != colors) { |
2496 if (NULL == textures) { | 2530 if (NULL == textures) { |
2497 // just colors (no texture) | 2531 // just colors (no texture) |
2498 shader = p.setShader(&triShader); | 2532 shader = p.setShader(&triShader); |
2499 } else { | 2533 } else { |
2500 // colors * texture | 2534 // colors * texture |
2501 SkASSERT(shader); | 2535 SkASSERT(shader); |
2502 bool releaseMode = false; | 2536 bool releaseMode = false; |
2503 if (NULL == xmode) { | 2537 if (NULL == xmode) { |
2504 xmode = SkXfermode::Create(SkXfermode::kModulate_Mode); | 2538 xmode = SkXfermode::Create(SkXfermode::kModulate_Mode); |
2505 releaseMode = true; | 2539 releaseMode = true; |
2506 } | 2540 } |
2507 SkShader* compose = SkNEW_ARGS(SkComposeShader, | 2541 composeShader.reset(SkNEW_ARGS(SkComposeShader, (&triShader, shader, xmode))); |
2508 (&triShader, shader, xmode)); | 2542 p.setShader(composeShader); |
2509 p.setShader(compose)->unref(); | |
2510 if (releaseMode) { | 2543 if (releaseMode) { |
2511 xmode->unref(); | 2544 xmode->unref(); |
2512 } | 2545 } |
2513 } | 2546 } |
2514 } | 2547 } |
2515 | 2548 |
2516 SkAutoBlitterChoose blitter(*fBitmap, *fMatrix, p); | 2549 SkAutoBlitterChoose blitter(*fBitmap, *fMatrix, p); |
2517 // important that we abort early, as below we may manipulate the shader | 2550 // 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()) { | 2551 if (blitter->isNullBlitter()) { |
2521 return; | 2552 return; |
2522 } | 2553 } |
2523 | 2554 |
2524 // setup our state and function pointer for iterating triangles | 2555 // setup our state and function pointer for iterating triangles |
2525 VertState state(count, indices, indexCount); | 2556 VertState state(count, indices, indexCount); |
2526 VertState::Proc vertProc = state.chooseProc(vmode); | 2557 VertState::Proc vertProc = state.chooseProc(vmode); |
2527 | 2558 |
2528 if (NULL != textures || NULL != colors) { | 2559 if (NULL != textures || NULL != colors) { |
2529 SkMatrix tempM; | 2560 SkMatrix tempM; |
2530 SkMatrix savedLocalM; | 2561 SkMatrix savedLocalM; |
2531 if (shader) { | 2562 if (shader) { |
2532 savedLocalM = shader->getLocalMatrix(); | 2563 savedLocalM = shader->getLocalMatrix(); |
2533 } | 2564 } |
2534 | 2565 |
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)) { | 2566 while (vertProc(&state)) { |
2539 if (NULL != textures) { | 2567 if (NULL != textures) { |
2540 if (texture_to_matrix(state, vertices, textures, &tempM)) { | 2568 if (texture_to_matrix(state, vertices, textures, &tempM)) { |
2541 tempM.postConcat(savedLocalM); | 2569 tempM.postConcat(savedLocalM); |
2542 shader->setLocalMatrix(tempM); | 2570 shader->setLocalMatrix(tempM); |
2543 // Need to recall setContext since we changed the local matr ix. | 2571 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; | 2572 continue; |
2553 } | 2573 } |
2554 } | 2574 } |
2555 } | 2575 } |
2556 if (NULL != colors) { | 2576 if (NULL != colors) { |
2557 if (!triShader.setup(vertices, colors, | 2577 // Find the context for triShader. |
2558 state.f0, state.f1, state.f2)) { | 2578 SkTriColorShader::TriColorShaderContext* triColorShaderContext; |
2579 | |
2580 SkShader::Context* shaderContext = blitter->getShaderContext(); | |
2581 SkASSERT(shaderContext); | |
2582 if (p.getShader() == &triShader) { | |
2583 triColorShaderContext = | |
2584 static_cast<SkTriColorShader::TriColorShaderContext* >(shaderContext); | |
2585 } else { | |
2586 // The shader is a compose shader and triShader is its first shader. | |
2587 SkASSERT(p.getShader() == composeShader); | |
2588 SkASSERT(composeShader->getShaderA() == &triShader); | |
2589 SkComposeShader::ComposeShaderContext* composeShaderContext = | |
2590 static_cast<SkComposeShader::ComposeShaderContext*>( shaderContext); | |
2591 SkShader::Context* shaderContextA = composeShaderContext->ge tShaderContextA(); | |
2592 triColorShaderContext = | |
2593 static_cast<SkTriColorShader::TriColorShaderContext* >(shaderContextA); | |
2594 } | |
2595 | |
2596 if (!triColorShaderContext->setup(vertices, colors, | |
2597 state.f0, state.f1, state.f2)) { | |
2559 continue; | 2598 continue; |
2560 } | 2599 } |
2561 } | 2600 } |
2562 | 2601 |
2563 SkPoint tmp[] = { | 2602 SkPoint tmp[] = { |
2564 devVerts[state.f0], devVerts[state.f1], devVerts[state.f2] | 2603 devVerts[state.f0], devVerts[state.f1], devVerts[state.f2] |
2565 }; | 2604 }; |
2566 SkScan::FillTriangle(tmp, *fRC, blitter.get()); | 2605 SkScan::FillTriangle(tmp, *fRC, blitter.get()); |
2567 } | 2606 } |
2568 | 2607 |
2569 // now restore the shader's original local matrix | 2608 // now restore the shader's original local matrix |
2570 if (NULL != shader) { | 2609 if (NULL != shader) { |
2571 shader->setLocalMatrix(savedLocalM); | 2610 shader->setLocalMatrix(savedLocalM); |
2572 } | 2611 } |
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 { | 2612 } else { |
2581 // no colors[] and no texture | 2613 // no colors[] and no texture |
2582 HairProc hairProc = ChooseHairProc(paint.isAntiAlias()); | 2614 HairProc hairProc = ChooseHairProc(paint.isAntiAlias()); |
2583 const SkRasterClip& clip = *fRC; | 2615 const SkRasterClip& clip = *fRC; |
2584 while (vertProc(&state)) { | 2616 while (vertProc(&state)) { |
2585 hairProc(devVerts[state.f0], devVerts[state.f1], clip, blitter.get() ); | 2617 hairProc(devVerts[state.f0], devVerts[state.f1], clip, blitter.get() ); |
2586 hairProc(devVerts[state.f1], devVerts[state.f2], clip, blitter.get() ); | 2618 hairProc(devVerts[state.f1], devVerts[state.f2], clip, blitter.get() ); |
2587 hairProc(devVerts[state.f2], devVerts[state.f0], clip, blitter.get() ); | 2619 hairProc(devVerts[state.f2], devVerts[state.f0], clip, blitter.get() ); |
2588 } | 2620 } |
2589 } | 2621 } |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2801 mask->fImage = SkMask::AllocImage(size); | 2833 mask->fImage = SkMask::AllocImage(size); |
2802 memset(mask->fImage, 0, mask->computeImageSize()); | 2834 memset(mask->fImage, 0, mask->computeImageSize()); |
2803 } | 2835 } |
2804 | 2836 |
2805 if (SkMask::kJustComputeBounds_CreateMode != mode) { | 2837 if (SkMask::kJustComputeBounds_CreateMode != mode) { |
2806 draw_into_mask(*mask, devPath, style); | 2838 draw_into_mask(*mask, devPath, style); |
2807 } | 2839 } |
2808 | 2840 |
2809 return true; | 2841 return true; |
2810 } | 2842 } |
OLD | NEW |