| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved. | 2 * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved. |
| 3 * Copyright (C) 2007 Alp Toker <alp@atoker.com> | 3 * Copyright (C) 2007 Alp Toker <alp@atoker.com> |
| 4 * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. | 4 * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. |
| 5 * | 5 * |
| 6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
| 7 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions |
| 8 * are met: | 8 * are met: |
| 9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 | 120 |
| 121 DEFINE_NODE_FACTORY(HTMLCanvasElement) | 121 DEFINE_NODE_FACTORY(HTMLCanvasElement) |
| 122 | 122 |
| 123 HTMLCanvasElement::~HTMLCanvasElement() | 123 HTMLCanvasElement::~HTMLCanvasElement() |
| 124 { | 124 { |
| 125 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-m_external
lyAllocatedMemory); | 125 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-m_external
lyAllocatedMemory); |
| 126 #if !ENABLE(OILPAN) | 126 #if !ENABLE(OILPAN) |
| 127 for (CanvasObserver* canvasObserver : m_observers) | 127 for (CanvasObserver* canvasObserver : m_observers) |
| 128 canvasObserver->canvasDestroyed(this); | 128 canvasObserver->canvasDestroyed(this); |
| 129 // Ensure these go away before the ImageBuffer. | 129 // Ensure these go away before the ImageBuffer. |
| 130 m_contextStateSaver.clear(); | |
| 131 m_context.clear(); | 130 m_context.clear(); |
| 132 #endif | 131 #endif |
| 133 } | 132 } |
| 134 | 133 |
| 135 void HTMLCanvasElement::parseAttribute(const QualifiedName& name, const AtomicSt
ring& value) | 134 void HTMLCanvasElement::parseAttribute(const QualifiedName& name, const AtomicSt
ring& value) |
| 136 { | 135 { |
| 137 if (name == widthAttr || name == heightAttr) | 136 if (name == widthAttr || name == heightAttr) |
| 138 reset(); | 137 reset(); |
| 139 HTMLElement::parseAttribute(name, value); | 138 HTMLElement::parseAttribute(name, value); |
| 140 } | 139 } |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 282 { | 281 { |
| 283 if (rect.isEmpty()) | 282 if (rect.isEmpty()) |
| 284 return; | 283 return; |
| 285 m_imageBufferIsClear = false; | 284 m_imageBufferIsClear = false; |
| 286 clearCopiedImage(); | 285 clearCopiedImage(); |
| 287 if (layoutObject()) | 286 if (layoutObject()) |
| 288 layoutObject()->setMayNeedPaintInvalidation(); | 287 layoutObject()->setMayNeedPaintInvalidation(); |
| 289 m_dirtyRect.unite(rect); | 288 m_dirtyRect.unite(rect); |
| 290 if (m_context && m_context->is2d() && hasImageBuffer()) | 289 if (m_context && m_context->is2d() && hasImageBuffer()) |
| 291 buffer()->didDraw(rect); | 290 buffer()->didDraw(rect); |
| 292 notifyObserversCanvasChanged(m_dirtyRect); | 291 notifyObserversCanvasChanged(rect); |
| 293 } | 292 } |
| 294 | 293 |
| 295 void HTMLCanvasElement::didFinalizeFrame() | 294 void HTMLCanvasElement::didFinalizeFrame() |
| 296 { | 295 { |
| 297 if (m_dirtyRect.isEmpty()) | 296 if (m_dirtyRect.isEmpty()) |
| 298 return; | 297 return; |
| 299 | 298 |
| 300 // Propagate the m_dirtyRect accumulated so far to the compositor | 299 // Propagate the m_dirtyRect accumulated so far to the compositor |
| 301 // before restarting with a blank dirty rect. | 300 // before restarting with a blank dirty rect. |
| 302 FloatRect srcRect(0, 0, size().width(), size().height()); | 301 FloatRect srcRect(0, 0, size().width(), size().height()); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 363 bool hadImageBuffer = hasImageBuffer(); | 362 bool hadImageBuffer = hasImageBuffer(); |
| 364 | 363 |
| 365 int w = getAttribute(widthAttr).toInt(&ok); | 364 int w = getAttribute(widthAttr).toInt(&ok); |
| 366 if (!ok || w < 0) | 365 if (!ok || w < 0) |
| 367 w = DefaultWidth; | 366 w = DefaultWidth; |
| 368 | 367 |
| 369 int h = getAttribute(heightAttr).toInt(&ok); | 368 int h = getAttribute(heightAttr).toInt(&ok); |
| 370 if (!ok || h < 0) | 369 if (!ok || h < 0) |
| 371 h = DefaultHeight; | 370 h = DefaultHeight; |
| 372 | 371 |
| 373 if (m_contextStateSaver) { | |
| 374 // Reset to the initial graphics context state. | |
| 375 m_contextStateSaver->restore(); | |
| 376 m_contextStateSaver->save(); | |
| 377 } | |
| 378 | |
| 379 if (m_context && m_context->is2d()) | 372 if (m_context && m_context->is2d()) |
| 380 toCanvasRenderingContext2D(m_context.get())->reset(); | 373 toCanvasRenderingContext2D(m_context.get())->reset(); |
| 381 | 374 |
| 382 IntSize oldSize = size(); | 375 IntSize oldSize = size(); |
| 383 IntSize newSize(w, h); | 376 IntSize newSize(w, h); |
| 384 | 377 |
| 385 // If the size of an existing buffer matches, we can just clear it instead o
f reallocating. | 378 // If the size of an existing buffer matches, we can just clear it instead o
f reallocating. |
| 386 // This optimization is only done for 2D canvases for now. | 379 // This optimization is only done for 2D canvases for now. |
| 387 if (hadImageBuffer && oldSize == newSize && m_context && m_context->is2d() &
& !buffer()->isRecording()) { | 380 if (hadImageBuffer && oldSize == newSize && m_context && m_context->is2d() &
& !buffer()->isRecording()) { |
| 388 if (!m_imageBufferIsClear) { | 381 if (!m_imageBufferIsClear) { |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 641 void HTMLCanvasElement::createImageBuffer() | 634 void HTMLCanvasElement::createImageBuffer() |
| 642 { | 635 { |
| 643 createImageBufferInternal(nullptr); | 636 createImageBufferInternal(nullptr); |
| 644 if (m_didFailToCreateImageBuffer && m_context->is2d()) | 637 if (m_didFailToCreateImageBuffer && m_context->is2d()) |
| 645 toCanvasRenderingContext2D(m_context.get())->loseContext(CanvasRendering
Context2D::SyntheticLostContext); | 638 toCanvasRenderingContext2D(m_context.get())->loseContext(CanvasRendering
Context2D::SyntheticLostContext); |
| 646 } | 639 } |
| 647 | 640 |
| 648 void HTMLCanvasElement::createImageBufferInternal(PassOwnPtr<ImageBufferSurface>
externalSurface) | 641 void HTMLCanvasElement::createImageBufferInternal(PassOwnPtr<ImageBufferSurface>
externalSurface) |
| 649 { | 642 { |
| 650 ASSERT(!m_imageBuffer); | 643 ASSERT(!m_imageBuffer); |
| 651 ASSERT(!m_contextStateSaver); | |
| 652 | 644 |
| 653 m_didFailToCreateImageBuffer = true; | 645 m_didFailToCreateImageBuffer = true; |
| 654 m_imageBufferIsClear = true; | 646 m_imageBufferIsClear = true; |
| 655 | 647 |
| 656 if (!canCreateImageBuffer(size())) | 648 if (!canCreateImageBuffer(size())) |
| 657 return; | 649 return; |
| 658 | 650 |
| 659 int msaaSampleCount = 0; | 651 int msaaSampleCount = 0; |
| 660 OwnPtr<ImageBufferSurface> surface; | 652 OwnPtr<ImageBufferSurface> surface; |
| 661 if (externalSurface) { | 653 if (externalSurface) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 675 m_didFailToCreateImageBuffer = false; | 667 m_didFailToCreateImageBuffer = false; |
| 676 | 668 |
| 677 updateExternallyAllocatedMemory(); | 669 updateExternallyAllocatedMemory(); |
| 678 | 670 |
| 679 if (is3D()) { | 671 if (is3D()) { |
| 680 // Early out for WebGL canvases | 672 // Early out for WebGL canvases |
| 681 return; | 673 return; |
| 682 } | 674 } |
| 683 | 675 |
| 684 m_imageBuffer->setClient(this); | 676 m_imageBuffer->setClient(this); |
| 685 m_imageBuffer->context()->setShouldClampToSourceRect(false); | |
| 686 m_imageBuffer->context()->disableAntialiasingOptimizationForHairlineImages()
; | |
| 687 m_imageBuffer->context()->setImageInterpolationQuality(CanvasDefaultInterpol
ationQuality); | |
| 688 // Enabling MSAA overrides a request to disable antialiasing. This is true r
egardless of whether the | 677 // Enabling MSAA overrides a request to disable antialiasing. This is true r
egardless of whether the |
| 689 // rendering mode is accelerated or not. For consistency, we don't want to a
pply AA in accelerated | 678 // rendering mode is accelerated or not. For consistency, we don't want to a
pply AA in accelerated |
| 690 // canvases but not in unaccelerated canvases. | 679 // canvases but not in unaccelerated canvases. |
| 691 if (!msaaSampleCount && document().settings() && !document().settings()->ant
ialiased2dCanvasEnabled()) | 680 if (!msaaSampleCount && document().settings() && !document().settings()->ant
ialiased2dCanvasEnabled()) |
| 692 m_imageBuffer->context()->setShouldAntialias(false); | 681 toCanvasRenderingContext2D(m_context.get())->setShouldAntialias(false); |
| 693 #if ENABLE(ASSERT) | |
| 694 m_imageBuffer->context()->disableDestructionChecks(); // 2D canvas is allowe
d to leave context in an unfinalized state. | |
| 695 #endif | |
| 696 m_contextStateSaver = adoptPtr(new GraphicsContextStateSaver(*m_imageBuffer-
>context())); | |
| 697 | 682 |
| 698 if (m_context) | 683 if (m_context) |
| 699 setNeedsCompositingUpdate(); | 684 setNeedsCompositingUpdate(); |
| 700 } | 685 } |
| 701 | 686 |
| 702 void HTMLCanvasElement::notifySurfaceInvalid() | 687 void HTMLCanvasElement::notifySurfaceInvalid() |
| 703 { | 688 { |
| 704 if (m_context && m_context->is2d()) { | 689 if (m_context && m_context->is2d()) { |
| 705 CanvasRenderingContext2D* context2d = toCanvasRenderingContext2D(m_conte
xt.get()); | 690 CanvasRenderingContext2D* context2d = toCanvasRenderingContext2D(m_conte
xt.get()); |
| 706 context2d->loseContext(CanvasRenderingContext2D::RealLostContext); | 691 context2d->loseContext(CanvasRenderingContext2D::RealLostContext); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 742 checkedExternallyAllocatedMemory *= height(); | 727 checkedExternallyAllocatedMemory *= height(); |
| 743 intptr_t externallyAllocatedMemory; | 728 intptr_t externallyAllocatedMemory; |
| 744 if (checkedExternallyAllocatedMemory.safeGet(externallyAllocatedMemory) == C
heckedState::DidOverflow) | 729 if (checkedExternallyAllocatedMemory.safeGet(externallyAllocatedMemory) == C
heckedState::DidOverflow) |
| 745 externallyAllocatedMemory = std::numeric_limits<intptr_t>::max(); | 730 externallyAllocatedMemory = std::numeric_limits<intptr_t>::max(); |
| 746 | 731 |
| 747 // Subtracting two intptr_t that are known to be positive will never underfl
ow. | 732 // Subtracting two intptr_t that are known to be positive will never underfl
ow. |
| 748 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(externallyA
llocatedMemory - m_externallyAllocatedMemory); | 733 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(externallyA
llocatedMemory - m_externallyAllocatedMemory); |
| 749 m_externallyAllocatedMemory = externallyAllocatedMemory; | 734 m_externallyAllocatedMemory = externallyAllocatedMemory; |
| 750 } | 735 } |
| 751 | 736 |
| 752 GraphicsContext* HTMLCanvasElement::drawingContext() const | |
| 753 { | |
| 754 return buffer() ? m_imageBuffer->context() : nullptr; | |
| 755 } | |
| 756 | |
| 757 SkCanvas* HTMLCanvasElement::drawingCanvas() const | 737 SkCanvas* HTMLCanvasElement::drawingCanvas() const |
| 758 { | 738 { |
| 759 return buffer() ? m_imageBuffer->canvas() : nullptr; | 739 return buffer() ? m_imageBuffer->canvas() : nullptr; |
| 760 } | 740 } |
| 761 | 741 |
| 762 SkCanvas* HTMLCanvasElement::existingDrawingCanvas() const | 742 SkCanvas* HTMLCanvasElement::existingDrawingCanvas() const |
| 763 { | 743 { |
| 764 if (!hasImageBuffer()) | 744 if (!hasImageBuffer()) |
| 765 return nullptr; | 745 return nullptr; |
| 766 | 746 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 807 needToUpdate |= m_context->paintRenderingResultsToCanvas(sourceBuffer); | 787 needToUpdate |= m_context->paintRenderingResultsToCanvas(sourceBuffer); |
| 808 if (needToUpdate && buffer()) { | 788 if (needToUpdate && buffer()) { |
| 809 m_copiedImage = buffer()->copyImage(CopyBackingStore, Unscaled); | 789 m_copiedImage = buffer()->copyImage(CopyBackingStore, Unscaled); |
| 810 updateExternallyAllocatedMemory(); | 790 updateExternallyAllocatedMemory(); |
| 811 } | 791 } |
| 812 return m_copiedImage; | 792 return m_copiedImage; |
| 813 } | 793 } |
| 814 | 794 |
| 815 void HTMLCanvasElement::discardImageBuffer() | 795 void HTMLCanvasElement::discardImageBuffer() |
| 816 { | 796 { |
| 817 m_contextStateSaver.clear(); // uses context owned by m_imageBuffer | |
| 818 m_imageBuffer.clear(); | 797 m_imageBuffer.clear(); |
| 819 m_dirtyRect = FloatRect(); | 798 m_dirtyRect = FloatRect(); |
| 820 updateExternallyAllocatedMemory(); | 799 updateExternallyAllocatedMemory(); |
| 821 } | 800 } |
| 822 | 801 |
| 823 void HTMLCanvasElement::clearCopiedImage() | 802 void HTMLCanvasElement::clearCopiedImage() |
| 824 { | 803 { |
| 825 if (m_copiedImage) { | 804 if (m_copiedImage) { |
| 826 m_copiedImage.clear(); | 805 m_copiedImage.clear(); |
| 827 updateExternallyAllocatedMemory(); | 806 updateExternallyAllocatedMemory(); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 898 { | 877 { |
| 899 return FloatSize(width(), height()); | 878 return FloatSize(width(), height()); |
| 900 } | 879 } |
| 901 | 880 |
| 902 bool HTMLCanvasElement::isOpaque() const | 881 bool HTMLCanvasElement::isOpaque() const |
| 903 { | 882 { |
| 904 return m_context && !m_context->hasAlpha(); | 883 return m_context && !m_context->hasAlpha(); |
| 905 } | 884 } |
| 906 | 885 |
| 907 } // blink | 886 } // blink |
| OLD | NEW |