| 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 virtual SkShader::Context* createContext( | 2357 bool setup(const SkPoint pts[], const SkColor colors[], int, int, int); |
| 2358 const SkBitmap&, const SkPaint&, const SkMatrix&, void*) const SK_OV
ERRIDE; | |
| 2359 virtual size_t contextSize() const SK_OVERRIDE; | |
| 2360 | 2358 |
| 2361 class TriColorShaderContext : public SkShader::Context { | 2359 virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count) SK_OVERRID
E; |
| 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 }; | |
| 2377 | 2360 |
| 2378 SK_TO_STRING_OVERRIDE() | 2361 SK_TO_STRING_OVERRIDE() |
| 2379 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkTriColorShader) | 2362 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkTriColorShader) |
| 2380 | 2363 |
| 2381 protected: | 2364 protected: |
| 2382 SkTriColorShader(SkReadBuffer& buffer) : SkShader(buffer) {} | 2365 SkTriColorShader(SkReadBuffer& buffer) : SkShader(buffer) {} |
| 2383 | 2366 |
| 2384 private: | 2367 private: |
| 2368 SkMatrix fDstToUnit; |
| 2369 SkPMColor fColors[3]; |
| 2370 |
| 2385 typedef SkShader INHERITED; | 2371 typedef SkShader INHERITED; |
| 2386 }; | 2372 }; |
| 2387 | 2373 |
| 2388 SkShader::Context* SkTriColorShader::createContext(const SkBitmap& device, const
SkPaint& paint, | 2374 bool SkTriColorShader::setup(const SkPoint pts[], const SkColor colors[], |
| 2389 const SkMatrix& matrix, void*
storage) const { | 2375 int index0, int index1, int index2) { |
| 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) { | |
| 2399 | 2376 |
| 2400 fColors[0] = SkPreMultiplyColor(colors[index0]); | 2377 fColors[0] = SkPreMultiplyColor(colors[index0]); |
| 2401 fColors[1] = SkPreMultiplyColor(colors[index1]); | 2378 fColors[1] = SkPreMultiplyColor(colors[index1]); |
| 2402 fColors[2] = SkPreMultiplyColor(colors[index2]); | 2379 fColors[2] = SkPreMultiplyColor(colors[index2]); |
| 2403 | 2380 |
| 2404 SkMatrix m, im; | 2381 SkMatrix m, im; |
| 2405 m.reset(); | 2382 m.reset(); |
| 2406 m.set(0, pts[index1].fX - pts[index0].fX); | 2383 m.set(0, pts[index1].fX - pts[index0].fX); |
| 2407 m.set(1, pts[index2].fX - pts[index0].fX); | 2384 m.set(1, pts[index2].fX - pts[index0].fX); |
| 2408 m.set(2, pts[index0].fX); | 2385 m.set(2, pts[index0].fX); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 2423 int scale = SkScalarToFixed(v) >> 8; | 2400 int scale = SkScalarToFixed(v) >> 8; |
| 2424 if (scale < 0) { | 2401 if (scale < 0) { |
| 2425 scale = 0; | 2402 scale = 0; |
| 2426 } | 2403 } |
| 2427 if (scale > 255) { | 2404 if (scale > 255) { |
| 2428 scale = 255; | 2405 scale = 255; |
| 2429 } | 2406 } |
| 2430 return SkAlpha255To256(scale); | 2407 return SkAlpha255To256(scale); |
| 2431 } | 2408 } |
| 2432 | 2409 |
| 2433 | 2410 void SkTriColorShader::shadeSpan(int x, int y, SkPMColor dstC[], int count) { |
| 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) { | |
| 2445 SkPoint src; | 2411 SkPoint src; |
| 2446 | 2412 |
| 2447 for (int i = 0; i < count; i++) { | 2413 for (int i = 0; i < count; i++) { |
| 2448 fDstToUnit.mapXY(SkIntToScalar(x), SkIntToScalar(y), &src); | 2414 fDstToUnit.mapXY(SkIntToScalar(x), SkIntToScalar(y), &src); |
| 2449 x += 1; | 2415 x += 1; |
| 2450 | 2416 |
| 2451 int scale1 = ScalarTo256(src.fX); | 2417 int scale1 = ScalarTo256(src.fX); |
| 2452 int scale2 = ScalarTo256(src.fY); | 2418 int scale2 = ScalarTo256(src.fY); |
| 2453 int scale0 = 256 - scale1 - scale2; | 2419 int scale0 = 256 - scale1 - scale2; |
| 2454 if (scale0 < 0) { | 2420 if (scale0 < 0) { |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2519 if (NULL == shader) { | 2485 if (NULL == shader) { |
| 2520 // if we have no shader, we ignore the texture coordinates | 2486 // if we have no shader, we ignore the texture coordinates |
| 2521 textures = NULL; | 2487 textures = NULL; |
| 2522 } else if (NULL == textures) { | 2488 } else if (NULL == textures) { |
| 2523 // if we don't have texture coordinates, ignore the shader | 2489 // if we don't have texture coordinates, ignore the shader |
| 2524 p.setShader(NULL); | 2490 p.setShader(NULL); |
| 2525 shader = NULL; | 2491 shader = NULL; |
| 2526 } | 2492 } |
| 2527 | 2493 |
| 2528 // setup the custom shader (if needed) | 2494 // setup the custom shader (if needed) |
| 2529 SkAutoTUnref<SkComposeShader> composeShader; | |
| 2530 if (NULL != colors) { | 2495 if (NULL != colors) { |
| 2531 if (NULL == textures) { | 2496 if (NULL == textures) { |
| 2532 // just colors (no texture) | 2497 // just colors (no texture) |
| 2533 shader = p.setShader(&triShader); | 2498 shader = p.setShader(&triShader); |
| 2534 } else { | 2499 } else { |
| 2535 // colors * texture | 2500 // colors * texture |
| 2536 SkASSERT(shader); | 2501 SkASSERT(shader); |
| 2537 bool releaseMode = false; | 2502 bool releaseMode = false; |
| 2538 if (NULL == xmode) { | 2503 if (NULL == xmode) { |
| 2539 xmode = SkXfermode::Create(SkXfermode::kModulate_Mode); | 2504 xmode = SkXfermode::Create(SkXfermode::kModulate_Mode); |
| 2540 releaseMode = true; | 2505 releaseMode = true; |
| 2541 } | 2506 } |
| 2542 composeShader.reset(SkNEW_ARGS(SkComposeShader, (&triShader, shader,
xmode))); | 2507 SkShader* compose = SkNEW_ARGS(SkComposeShader, |
| 2543 p.setShader(composeShader); | 2508 (&triShader, shader, xmode)); |
| 2509 p.setShader(compose)->unref(); |
| 2544 if (releaseMode) { | 2510 if (releaseMode) { |
| 2545 xmode->unref(); | 2511 xmode->unref(); |
| 2546 } | 2512 } |
| 2547 } | 2513 } |
| 2548 } | 2514 } |
| 2549 | 2515 |
| 2550 SkAutoBlitterChoose blitter(*fBitmap, *fMatrix, p); | 2516 SkAutoBlitterChoose blitter(*fBitmap, *fMatrix, p); |
| 2551 // Abort early if we failed to create a shader context. | 2517 // important that we abort early, as below we may manipulate the shader |
| 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. |
| 2552 if (blitter->isNullBlitter()) { | 2520 if (blitter->isNullBlitter()) { |
| 2553 return; | 2521 return; |
| 2554 } | 2522 } |
| 2555 | 2523 |
| 2556 // setup our state and function pointer for iterating triangles | 2524 // setup our state and function pointer for iterating triangles |
| 2557 VertState state(count, indices, indexCount); | 2525 VertState state(count, indices, indexCount); |
| 2558 VertState::Proc vertProc = state.chooseProc(vmode); | 2526 VertState::Proc vertProc = state.chooseProc(vmode); |
| 2559 | 2527 |
| 2560 if (NULL != textures || NULL != colors) { | 2528 if (NULL != textures || NULL != colors) { |
| 2561 SkMatrix tempM; | 2529 SkMatrix tempM; |
| 2562 SkMatrix savedLocalM; | 2530 SkMatrix savedLocalM; |
| 2563 if (shader) { | 2531 if (shader) { |
| 2564 savedLocalM = shader->getLocalMatrix(); | 2532 savedLocalM = shader->getLocalMatrix(); |
| 2565 } | 2533 } |
| 2566 | 2534 |
| 2535 // setContext has already been called and verified to return true |
| 2536 // by the constructor of SkAutoBlitterChoose |
| 2537 bool prevContextSuccess = true; |
| 2567 while (vertProc(&state)) { | 2538 while (vertProc(&state)) { |
| 2568 if (NULL != textures) { | 2539 if (NULL != textures) { |
| 2569 if (texture_to_matrix(state, vertices, textures, &tempM)) { | 2540 if (texture_to_matrix(state, vertices, textures, &tempM)) { |
| 2570 tempM.postConcat(savedLocalM); | 2541 tempM.postConcat(savedLocalM); |
| 2571 shader->setLocalMatrix(tempM); | 2542 shader->setLocalMatrix(tempM); |
| 2572 if (!blitter->resetShaderContext(*fBitmap, p, *fMatrix)) { | 2543 // Need to recall setContext since we changed the local matr
ix. |
| 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) { |
| 2573 continue; | 2552 continue; |
| 2574 } | 2553 } |
| 2575 } | 2554 } |
| 2576 } | 2555 } |
| 2577 if (NULL != colors) { | 2556 if (NULL != colors) { |
| 2578 // Find the context for triShader. | 2557 if (!triShader.setup(vertices, colors, |
| 2579 SkTriColorShader::TriColorShaderContext* triColorShaderContext; | 2558 state.f0, state.f1, state.f2)) { |
| 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))
{ | |
| 2599 continue; | 2559 continue; |
| 2600 } | 2560 } |
| 2601 } | 2561 } |
| 2602 | 2562 |
| 2603 SkPoint tmp[] = { | 2563 SkPoint tmp[] = { |
| 2604 devVerts[state.f0], devVerts[state.f1], devVerts[state.f2] | 2564 devVerts[state.f0], devVerts[state.f1], devVerts[state.f2] |
| 2605 }; | 2565 }; |
| 2606 SkScan::FillTriangle(tmp, *fRC, blitter.get()); | 2566 SkScan::FillTriangle(tmp, *fRC, blitter.get()); |
| 2607 } | 2567 } |
| 2608 | 2568 |
| 2609 // now restore the shader's original local matrix | 2569 // now restore the shader's original local matrix |
| 2610 if (NULL != shader) { | 2570 if (NULL != shader) { |
| 2611 shader->setLocalMatrix(savedLocalM); | 2571 shader->setLocalMatrix(savedLocalM); |
| 2612 } | 2572 } |
| 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 } |
| 2613 } else { | 2580 } else { |
| 2614 // no colors[] and no texture | 2581 // no colors[] and no texture |
| 2615 HairProc hairProc = ChooseHairProc(paint.isAntiAlias()); | 2582 HairProc hairProc = ChooseHairProc(paint.isAntiAlias()); |
| 2616 const SkRasterClip& clip = *fRC; | 2583 const SkRasterClip& clip = *fRC; |
| 2617 while (vertProc(&state)) { | 2584 while (vertProc(&state)) { |
| 2618 hairProc(devVerts[state.f0], devVerts[state.f1], clip, blitter.get()
); | 2585 hairProc(devVerts[state.f0], devVerts[state.f1], clip, blitter.get()
); |
| 2619 hairProc(devVerts[state.f1], devVerts[state.f2], clip, blitter.get()
); | 2586 hairProc(devVerts[state.f1], devVerts[state.f2], clip, blitter.get()
); |
| 2620 hairProc(devVerts[state.f2], devVerts[state.f0], clip, blitter.get()
); | 2587 hairProc(devVerts[state.f2], devVerts[state.f0], clip, blitter.get()
); |
| 2621 } | 2588 } |
| 2622 } | 2589 } |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2834 mask->fImage = SkMask::AllocImage(size); | 2801 mask->fImage = SkMask::AllocImage(size); |
| 2835 memset(mask->fImage, 0, mask->computeImageSize()); | 2802 memset(mask->fImage, 0, mask->computeImageSize()); |
| 2836 } | 2803 } |
| 2837 | 2804 |
| 2838 if (SkMask::kJustComputeBounds_CreateMode != mode) { | 2805 if (SkMask::kJustComputeBounds_CreateMode != mode) { |
| 2839 draw_into_mask(*mask, devPath, style); | 2806 draw_into_mask(*mask, devPath, style); |
| 2840 } | 2807 } |
| 2841 | 2808 |
| 2842 return true; | 2809 return true; |
| 2843 } | 2810 } |
| OLD | NEW |