Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 | 9 |
| 10 #include "SkPDFShader.h" | 10 #include "SkPDFShader.h" |
| (...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 437 SkTDArray<SkPDFObject*> fResources; | 437 SkTDArray<SkPDFObject*> fResources; |
| 438 SkAutoTDelete<const SkPDFShader::State> fState; | 438 SkAutoTDelete<const SkPDFShader::State> fState; |
| 439 | 439 |
| 440 SkPDFStream* makePSFunction(const SkString& psCode, SkPDFArray* domain); | 440 SkPDFStream* makePSFunction(const SkString& psCode, SkPDFArray* domain); |
| 441 }; | 441 }; |
| 442 | 442 |
| 443 class SkPDFImageShader : public SkPDFStream, public SkPDFShader { | 443 class SkPDFImageShader : public SkPDFStream, public SkPDFShader { |
| 444 public: | 444 public: |
| 445 explicit SkPDFImageShader(SkPDFShader::State* state); | 445 explicit SkPDFImageShader(SkPDFShader::State* state); |
| 446 virtual ~SkPDFImageShader() { | 446 virtual ~SkPDFImageShader() { |
| 447 RemoveShader(this); | 447 if (!fFailedConstructor) { |
| 448 fResources.unrefAll(); | 448 RemoveShader(this); |
| 449 fResources.unrefAll(); | |
| 450 } | |
| 449 } | 451 } |
| 450 | 452 |
| 451 virtual bool isValid() { return size() > 0; } | 453 virtual bool isValid() { return !fFailedConstructor && size() > 0; } |
| 452 | 454 |
| 453 void getResources(const SkTSet<SkPDFObject*>& knownResourceObjects, | 455 void getResources(const SkTSet<SkPDFObject*>& knownResourceObjects, |
| 454 SkTSet<SkPDFObject*>* newResourceObjects) { | 456 SkTSet<SkPDFObject*>* newResourceObjects) { |
| 455 GetResourcesHelper(&fResources.toArray(), | 457 GetResourcesHelper(&fResources.toArray(), |
| 456 knownResourceObjects, | 458 knownResourceObjects, |
| 457 newResourceObjects); | 459 newResourceObjects); |
| 458 } | 460 } |
| 459 | 461 |
| 460 private: | 462 private: |
| 461 SkTSet<SkPDFObject*> fResources; | 463 SkTSet<SkPDFObject*> fResources; |
| 462 SkAutoTDelete<const SkPDFShader::State> fState; | 464 SkAutoTDelete<const SkPDFShader::State> fState; |
| 465 bool fFailedConstructor; | |
|
vandebo (ex-Chrome)
2013/07/23 15:09:50
I don't think you need this field. Just adding th
edisonn
2013/07/23 15:34:18
Done.
| |
| 463 }; | 466 }; |
| 464 | 467 |
| 465 SkPDFShader::SkPDFShader() {} | 468 SkPDFShader::SkPDFShader() {} |
| 466 | 469 |
| 467 // static | 470 // static |
| 468 void SkPDFShader::RemoveShader(SkPDFObject* shader) { | 471 void SkPDFShader::RemoveShader(SkPDFObject* shader) { |
| 469 SkAutoMutexAcquire lock(CanonicalShadersMutex()); | 472 SkAutoMutexAcquire lock(CanonicalShadersMutex()); |
|
vandebo (ex-Chrome)
2013/07/23 15:09:50
Instead of dropping the lock in the factory method
edisonn
2013/07/23 15:34:18
I personally don't think so. We already have an as
vandebo (ex-Chrome)
2013/07/23 15:41:27
I didn't notice that - that's even a better reason
| |
| 470 ShaderCanonicalEntry entry(shader, NULL); | 473 ShaderCanonicalEntry entry(shader, NULL); |
| 471 int index = CanonicalShaders().find(entry); | 474 int index = CanonicalShaders().find(entry); |
| 472 SkASSERT(index >= 0); | 475 SkASSERT(index >= 0); |
| 473 CanonicalShaders().removeShuffle(index); | 476 CanonicalShaders().removeShuffle(index); |
| 474 } | 477 } |
| 475 | 478 |
| 476 // static | 479 // static |
| 477 SkPDFObject* SkPDFShader::GetPDFShader(const SkShader& shader, | 480 SkPDFObject* SkPDFShader::GetPDFShader(const SkShader& shader, |
| 478 const SkMatrix& matrix, | 481 const SkMatrix& matrix, |
| 479 const SkIRect& surfaceBBox) { | 482 const SkIRect& surfaceBBox) { |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 504 new SkPDFImageShader(shaderState.detach()); | 507 new SkPDFImageShader(shaderState.detach()); |
| 505 valid = imageShader->isValid(); | 508 valid = imageShader->isValid(); |
| 506 result = imageShader; | 509 result = imageShader; |
| 507 } else { | 510 } else { |
| 508 SkPDFFunctionShader* functionShader = | 511 SkPDFFunctionShader* functionShader = |
| 509 new SkPDFFunctionShader(shaderState.detach()); | 512 new SkPDFFunctionShader(shaderState.detach()); |
| 510 valid = functionShader->isValid(); | 513 valid = functionShader->isValid(); |
| 511 result = functionShader; | 514 result = functionShader; |
| 512 } | 515 } |
| 513 if (!valid) { | 516 if (!valid) { |
| 517 // Release the lock, otherwise we end up calling RemoveShader that locks again, | |
|
vandebo (ex-Chrome)
2013/07/23 15:09:50
nit: please wrap at 80 cols; the rest of the file
edisonn
2013/07/23 15:34:18
Done.
| |
| 518 // and we end up with a freeze. | |
| 519 lock.release(); | |
| 514 delete result; | 520 delete result; |
| 515 return NULL; | 521 return NULL; |
| 516 } | 522 } |
| 517 entry.fPDFShader = result; | 523 entry.fPDFShader = result; |
| 518 CanonicalShaders().push(entry); | 524 CanonicalShaders().push(entry); |
| 519 return result; // return the reference that came from new. | 525 return result; // return the reference that came from new. |
| 520 } | 526 } |
| 521 | 527 |
| 522 // static | 528 // static |
| 523 SkTDArray<SkPDFShader::ShaderCanonicalEntry>& SkPDFShader::CanonicalShaders() { | 529 SkTDArray<SkPDFShader::ShaderCanonicalEntry>& SkPDFShader::CanonicalShaders() { |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 652 | 658 |
| 653 SkPDFStream* function = makePSFunction(functionCode, domain.get()); | 659 SkPDFStream* function = makePSFunction(functionCode, domain.get()); |
| 654 pdfShader->insert("Function", new SkPDFObjRef(function))->unref(); | 660 pdfShader->insert("Function", new SkPDFObjRef(function))->unref(); |
| 655 fResources.push(function); // Pass ownership to resource list. | 661 fResources.push(function); // Pass ownership to resource list. |
| 656 | 662 |
| 657 insertInt("PatternType", 2); | 663 insertInt("PatternType", 2); |
| 658 insert("Matrix", SkPDFUtils::MatrixToArray(finalMatrix))->unref(); | 664 insert("Matrix", SkPDFUtils::MatrixToArray(finalMatrix))->unref(); |
| 659 insert("Shading", pdfShader.get()); | 665 insert("Shading", pdfShader.get()); |
| 660 } | 666 } |
| 661 | 667 |
| 662 SkPDFImageShader::SkPDFImageShader(SkPDFShader::State* state) : fState(state) { | 668 SkPDFImageShader::SkPDFImageShader(SkPDFShader::State* state) : fState(state) |
| 669 , fFailedConstruct or(false) { | |
| 663 fState.get()->fImage.lockPixels(); | 670 fState.get()->fImage.lockPixels(); |
| 664 | 671 |
| 665 SkMatrix finalMatrix = fState.get()->fCanvasTransform; | 672 SkMatrix finalMatrix = fState.get()->fCanvasTransform; |
| 666 finalMatrix.preConcat(fState.get()->fShaderTransform); | 673 finalMatrix.preConcat(fState.get()->fShaderTransform); |
| 667 SkRect surfaceBBox; | 674 SkRect surfaceBBox; |
| 668 surfaceBBox.set(fState.get()->fBBox); | 675 surfaceBBox.set(fState.get()->fBBox); |
| 669 if (!transformBBox(finalMatrix, &surfaceBBox)) { | 676 if (!transformBBox(finalMatrix, &surfaceBBox)) { |
| 677 fFailedConstructor = true; | |
| 670 return; | 678 return; |
| 671 } | 679 } |
| 672 | 680 |
| 673 SkMatrix unflip; | 681 SkMatrix unflip; |
| 674 unflip.setTranslate(0, SkScalarRoundToScalar(surfaceBBox.height())); | 682 unflip.setTranslate(0, SkScalarRoundToScalar(surfaceBBox.height())); |
| 675 unflip.preScale(SK_Scalar1, -SK_Scalar1); | 683 unflip.preScale(SK_Scalar1, -SK_Scalar1); |
| 676 SkISize size = SkISize::Make(SkScalarRound(surfaceBBox.width()), | 684 SkISize size = SkISize::Make(SkScalarRound(surfaceBBox.width()), |
| 677 SkScalarRound(surfaceBBox.height())); | 685 SkScalarRound(surfaceBBox.height())); |
| 678 SkPDFDevice pattern(size, size, unflip); | 686 SkPDFDevice pattern(size, size, unflip); |
| 679 SkCanvas canvas(&pattern); | 687 SkCanvas canvas(&pattern); |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 955 fPixelGeneration = fImage.getGenerationID(); | 963 fPixelGeneration = fImage.getGenerationID(); |
| 956 } else { | 964 } else { |
| 957 fColorData.set(sk_malloc_throw( | 965 fColorData.set(sk_malloc_throw( |
| 958 fInfo.fColorCount * (sizeof(SkColor) + sizeof(SkScalar)))); | 966 fInfo.fColorCount * (sizeof(SkColor) + sizeof(SkScalar)))); |
| 959 fInfo.fColors = reinterpret_cast<SkColor*>(fColorData.get()); | 967 fInfo.fColors = reinterpret_cast<SkColor*>(fColorData.get()); |
| 960 fInfo.fColorOffsets = | 968 fInfo.fColorOffsets = |
| 961 reinterpret_cast<SkScalar*>(fInfo.fColors + fInfo.fColorCount); | 969 reinterpret_cast<SkScalar*>(fInfo.fColors + fInfo.fColorCount); |
| 962 shader.asAGradient(&fInfo); | 970 shader.asAGradient(&fInfo); |
| 963 } | 971 } |
| 964 } | 972 } |
| OLD | NEW |