Changeset 251874 in webkit
- Timestamp:
- Oct 31, 2019 1:41:56 PM (4 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r251871 r251874 1 2019-10-31 Zan Dobersek <zdobersek@igalia.com> and Chris Lord <clord@igalia.com> 2 3 Move ImageBuffer-related functionality from HTMLCanvasElement to CanvasBase 4 https://bugs.webkit.org/show_bug.cgi?id=182503 5 6 Reviewed by Ryosuke Niwa. 7 8 Move the ImageBuffer member variable, other related member variables and 9 majority of methods that operate on these from the HTMLCanvasElement 10 class up to the CanvasBase class. This will make it possible for the 11 OffscreenCanvas implementation to leverage the same code when using 2D 12 contexts for painting. 13 14 Most of the moved methods are public, while the setImageBuffer() method 15 is made protected so that it's still accessible from the inheriting 16 class. 17 18 Along with setImageBuffer(), the active pixel memory counter is moved 19 into the CanvasBase class. It's still using static storage, but is now 20 a member of the class with protected access. The storage has been made 21 atomic so as to allow its consistency to be maintained when accessed 22 from multiple threads (which may happen in the future). 23 24 The m_size member variable is also moved up into the CanvasBase class. 25 Constructor is changed so that the passed-in IntSize argument is used 26 to initialize it. Canvas implementations are still the owners of their 27 respective canvas contexts and are responsible for the destruction of 28 both the context and the ImageBuffer, in that order. 29 30 HTMLCanvasElement destructor still has to invoke 31 CanvasBase::notifyObserversCanvasDestroyed() since some CanvasObserver 32 derivatives perform virtual method calls on the CanvasBase object for 33 typecasting purposes in their canvasDestroyed() implementation. 34 Calling virtual methods on an object that's being destroyed is normally 35 discouraged and should be fixed separately, but it works as long as 36 invocations are done before the HTMLCanvasElement object is destroyed 37 completely (as has been the case so far). 38 39 CanvasRenderingContext2DBase is already changed in unwindStateStack() 40 to call CanvasBase::existingDrawingContext() and not downcast the 41 CanvasBase object to HTMLCanvasElement. This is done now due to 42 unwindStateStack() being called from the destructor, which is now 43 invoked from the CanvasBase destructor and not the HTMLCanvasElement 44 destructor, avoiding virtual method calls on the CanvasBase object as 45 it's being destroyed. 46 47 This patch doesn't address various methods using const qualifier and 48 then working around that by requiring member variables to be mutable. 49 This should be amended as much as possible in a separate patch. 50 51 No new tests -- no change in functionality, only refactoring. 52 53 * html/CanvasBase.cpp: 54 (WebCore::CanvasBase::CanvasBase): 55 (WebCore::CanvasBase::~CanvasBase): 56 (WebCore::CanvasBase::drawingContext const): 57 (WebCore::CanvasBase::existingDrawingContext const): 58 (WebCore::CanvasBase::buffer const): 59 (WebCore::CanvasBase::baseTransform const): 60 (WebCore::CanvasBase::makeRenderingResultsAvailable): 61 (WebCore::CanvasBase::memoryCost const): 62 (WebCore::CanvasBase::externalMemoryCost const): 63 (WebCore::CanvasBase::callTracingActive const): 64 (WebCore::CanvasBase::setImageBuffer const): 65 (WebCore::CanvasBase::activePixelMemory): 66 (WebCore::CanvasBase::resetGraphicsContextState const): 67 * html/CanvasBase.h: 68 (WebCore::CanvasBase::width const): 69 (WebCore::CanvasBase::height const): 70 (WebCore::CanvasBase::size const): 71 (WebCore::CanvasBase::setSize): 72 (WebCore::CanvasBase::hasCreatedImageBuffer const): 73 (WebCore::CanvasBase::createImageBuffer const): 74 * html/CustomPaintCanvas.cpp: 75 (WebCore::CustomPaintCanvas::CustomPaintCanvas): 76 (WebCore::CustomPaintCanvas::~CustomPaintCanvas): 77 * html/CustomPaintCanvas.h: 78 * html/HTMLCanvasElement.cpp: 79 (WebCore::HTMLCanvasElement::HTMLCanvasElement): 80 (WebCore::HTMLCanvasElement::~HTMLCanvasElement): 81 (WebCore::HTMLCanvasElement::setSize): 82 (WebCore::HTMLCanvasElement::createContext2d): 83 (WebCore::HTMLCanvasElement::reset): 84 (WebCore::HTMLCanvasElement::setSurfaceSize): 85 (WebCore::HTMLCanvasElement::toDataURL): 86 (WebCore::HTMLCanvasElement::toBlob): 87 (WebCore::HTMLCanvasElement::createImageBuffer const): 88 (WebCore::HTMLCanvasElement::setImageBufferAndMarkDirty): 89 * html/HTMLCanvasElement.h: 90 * html/OffscreenCanvas.cpp: 91 (WebCore::OffscreenCanvas::OffscreenCanvas): 92 (WebCore::OffscreenCanvas::~OffscreenCanvas): 93 (WebCore::OffscreenCanvas::setWidth): 94 (WebCore::OffscreenCanvas::setHeight): 95 (WebCore::OffscreenCanvas::transferToImageBitmap): 96 (WebCore::OffscreenCanvas::createImageBuffer const): 97 * html/OffscreenCanvas.h: 98 1 99 2019-10-31 Devin Rousso <drousso@apple.com> 2 100 -
trunk/Source/WebCore/html/CanvasBase.cpp
r243820 r251874 32 32 #include "FloatRect.h" 33 33 #include "InspectorInstrumentation.h" 34 #include <JavaScriptCore/JSCInlines.h> 35 #include <JavaScriptCore/JSLock.h> 36 #include <atomic> 34 37 #include <wtf/Vector.h> 35 38 39 static std::atomic<size_t> s_activePixelMemory { 0 }; 40 36 41 namespace WebCore { 37 42 38 CanvasBase::CanvasBase() 43 #if USE(CG) 44 // FIXME: It seems strange that the default quality is not the one that is literally named "default". 45 // Should fix names to make this easier to understand, or write an excellent comment here explaining why not. 46 const InterpolationQuality defaultInterpolationQuality = InterpolationLow; 47 #else 48 const InterpolationQuality defaultInterpolationQuality = InterpolationDefault; 49 #endif 50 51 CanvasBase::CanvasBase(IntSize size) 52 : m_size(size) 39 53 { 40 54 } … … 42 56 CanvasBase::~CanvasBase() 43 57 { 44 ASSERT(!m_context); // Should have been set to null by base class.45 58 ASSERT(m_didNotifyObserversCanvasDestroyed); 46 59 ASSERT(m_observers.isEmpty()); 47 } 48 49 CanvasRenderingContext* CanvasBase::renderingContext() const 50 { 51 return m_context.get(); 60 ASSERT(!m_imageBuffer); 61 } 62 63 GraphicsContext* CanvasBase::drawingContext() const 64 { 65 auto* context = renderingContext(); 66 if (context && !context->is2d()) 67 return nullptr; 68 69 return buffer() ? &m_imageBuffer->context() : nullptr; 70 } 71 72 GraphicsContext* CanvasBase::existingDrawingContext() const 73 { 74 if (!hasCreatedImageBuffer()) 75 return nullptr; 76 77 return drawingContext(); 78 } 79 80 ImageBuffer* CanvasBase::buffer() const 81 { 82 if (!hasCreatedImageBuffer()) 83 createImageBuffer(); 84 return m_imageBuffer.get(); 85 } 86 87 AffineTransform CanvasBase::baseTransform() const 88 { 89 ASSERT(hasCreatedImageBuffer()); 90 return m_imageBuffer->baseTransform(); 91 } 92 93 void CanvasBase::makeRenderingResultsAvailable() 94 { 95 if (auto* context = renderingContext()) 96 context->paintRenderingResultsToCanvas(); 97 } 98 99 size_t CanvasBase::memoryCost() const 100 { 101 // memoryCost() may be invoked concurrently from a GC thread, and we need to be careful 102 // about what data we access here and how. We need to hold a lock to prevent m_imageBuffer 103 // from being changed while we access it. 104 auto locker = holdLock(m_imageBufferAssignmentLock); 105 if (!m_imageBuffer) 106 return 0; 107 return m_imageBuffer->memoryCost(); 108 } 109 110 size_t CanvasBase::externalMemoryCost() const 111 { 112 // externalMemoryCost() may be invoked concurrently from a GC thread, and we need to be careful 113 // about what data we access here and how. We need to hold a lock to prevent m_imageBuffer 114 // from being changed while we access it. 115 auto locker = holdLock(m_imageBufferAssignmentLock); 116 if (!m_imageBuffer) 117 return 0; 118 return m_imageBuffer->externalMemoryCost(); 52 119 } 53 120 … … 112 179 bool CanvasBase::callTracingActive() const 113 180 { 114 return m_context && m_context->callTracingActive(); 115 } 116 117 } 181 auto* context = renderingContext(); 182 return context && context->callTracingActive(); 183 } 184 185 void CanvasBase::setImageBuffer(std::unique_ptr<ImageBuffer>&& buffer) const 186 { 187 { 188 auto locker = holdLock(m_imageBufferAssignmentLock); 189 m_contextStateSaver = nullptr; 190 m_imageBuffer = WTFMove(buffer); 191 } 192 193 if (m_imageBuffer && m_size != m_imageBuffer->internalSize()) 194 m_size = m_imageBuffer->internalSize(); 195 196 size_t previousMemoryCost = m_imageBufferCost; 197 m_imageBufferCost = memoryCost(); 198 s_activePixelMemory += m_imageBufferCost - previousMemoryCost; 199 200 auto* context = renderingContext(); 201 if (context && m_imageBuffer && previousMemoryCost != m_imageBufferCost) 202 InspectorInstrumentation::didChangeCanvasMemory(*context); 203 204 if (!m_imageBuffer) 205 return; 206 207 m_imageBuffer->context().setShadowsIgnoreTransforms(true); 208 m_imageBuffer->context().setImageInterpolationQuality(defaultInterpolationQuality); 209 m_imageBuffer->context().setStrokeThickness(1); 210 m_contextStateSaver = makeUnique<GraphicsContextStateSaver>(m_imageBuffer->context()); 211 212 JSC::JSLockHolder lock(scriptExecutionContext()->vm()); 213 scriptExecutionContext()->vm().heap.reportExtraMemoryAllocated(m_imageBufferCost); 214 } 215 216 size_t CanvasBase::activePixelMemory() 217 { 218 return s_activePixelMemory.load(); 219 } 220 221 void CanvasBase::resetGraphicsContextState() const 222 { 223 if (m_contextStateSaver) { 224 // Reset to the initial graphics context state. 225 m_contextStateSaver->restore(); 226 m_contextStateSaver->save(); 227 } 228 } 229 230 } -
trunk/Source/WebCore/html/CanvasBase.h
r243820 r251874 26 26 #pragma once 27 27 28 #include "IntSize.h" 28 29 #include <wtf/HashSet.h> 29 30 #include <wtf/TypeCasts.h> … … 36 37 class Element; 37 38 class GraphicsContext; 39 class GraphicsContextStateSaver; 38 40 class Image; 39 41 class ImageBuffer; 40 class IntSize;41 42 class FloatRect; 42 43 class ScriptExecutionContext; … … 65 66 virtual bool isCustomPaintCanvas() const { return false; } 66 67 67 virtual unsigned width() const = 0; 68 virtual unsigned height() const = 0; 69 virtual const IntSize& size() const = 0; 70 virtual void setSize(const IntSize&) = 0; 68 unsigned width() const { return m_size.width(); } 69 unsigned height() const { return m_size.height(); } 70 const IntSize& size() const { return m_size; } 71 72 ImageBuffer* buffer() const; 73 74 virtual AffineTransform baseTransform() const; 75 76 void makeRenderingResultsAvailable(); 77 78 size_t memoryCost() const; 79 size_t externalMemoryCost() const; 71 80 72 81 void setOriginClean() { m_originClean = true; } … … 77 86 ScriptExecutionContext* scriptExecutionContext() const { return canvasBaseScriptExecutionContext(); } 78 87 79 CanvasRenderingContext* renderingContext() const;88 virtual CanvasRenderingContext* renderingContext() const = 0; 80 89 81 90 void addObserver(CanvasObserver&); … … 87 96 HashSet<Element*> cssCanvasClients() const; 88 97 89 virtual GraphicsContext* drawingContext() const = 0;90 virtual GraphicsContext* existingDrawingContext() const = 0;98 virtual GraphicsContext* drawingContext() const; 99 virtual GraphicsContext* existingDrawingContext() const; 91 100 92 virtual void makeRenderingResultsAvailable() = 0;93 101 virtual void didDraw(const FloatRect&) = 0; 94 102 95 virtual AffineTransform baseTransform() const = 0;96 103 virtual Image* copiedImage() const = 0; 97 98 104 bool callTracingActive() const; 99 105 100 106 protected: 101 CanvasBase();107 explicit CanvasBase(IntSize); 102 108 103 109 virtual ScriptExecutionContext* canvasBaseScriptExecutionContext() const = 0; 104 110 105 std::unique_ptr<CanvasRenderingContext> m_context; 111 virtual void setSize(const IntSize& size) { m_size = size; } 112 113 void setImageBuffer(std::unique_ptr<ImageBuffer>&&) const; 114 virtual bool hasCreatedImageBuffer() const { return false; } 115 static size_t activePixelMemory(); 116 117 void resetGraphicsContextState() const; 106 118 107 119 private: 120 virtual void createImageBuffer() const { } 121 122 mutable IntSize m_size; 123 mutable Lock m_imageBufferAssignmentLock; 124 mutable std::unique_ptr<ImageBuffer> m_imageBuffer; 125 mutable size_t m_imageBufferCost { 0 }; 126 mutable std::unique_ptr<GraphicsContextStateSaver> m_contextStateSaver; 127 108 128 bool m_originClean { true }; 109 129 #ifndef NDEBUG -
trunk/Source/WebCore/html/CustomPaintCanvas.cpp
r243820 r251874 29 29 #if ENABLE(CSS_PAINTING_API) 30 30 31 #include "CanvasRenderingContext.h" 31 32 #include "ImageBitmap.h" 32 33 #include "PaintRenderingContext2D.h" … … 40 41 41 42 CustomPaintCanvas::CustomPaintCanvas(ScriptExecutionContext& context, unsigned width, unsigned height) 42 : C ontextDestructionObserver(&context)43 , m_size(width, height)43 : CanvasBase(IntSize(width, height)) 44 , ContextDestructionObserver(&context) 44 45 { 45 46 } … … 50 51 51 52 m_context = nullptr; // Ensure this goes away before the ImageBuffer. 52 } 53 54 unsigned CustomPaintCanvas::width() const 55 { 56 return m_size.width(); 57 } 58 59 void CustomPaintCanvas::setWidth(unsigned newWidth) 60 { 61 return m_size.setWidth(newWidth); 62 } 63 64 unsigned CustomPaintCanvas::height() const 65 { 66 return m_size.height(); 67 } 68 69 void CustomPaintCanvas::setHeight(unsigned newHeight) 70 { 71 return m_size.setHeight(newHeight); 72 } 73 74 const IntSize& CustomPaintCanvas::size() const 75 { 76 return m_size; 77 } 78 79 void CustomPaintCanvas::setSize(const IntSize& newSize) 80 { 81 m_size = newSize; 53 setImageBuffer(nullptr); 82 54 } 83 55 … … 145 117 } 146 118 147 void CustomPaintCanvas::makeRenderingResultsAvailable()148 {149 if (m_context)150 m_context->paintRenderingResultsToCanvas();151 }152 153 119 } 154 120 #endif -
trunk/Source/WebCore/html/CustomPaintCanvas.h
r250735 r251874 42 42 namespace WebCore { 43 43 44 class CanvasRenderingContext; 44 45 class ImageBitmap; 45 46 class PaintRenderingContext2D; … … 53 54 bool isCustomPaintCanvas() const final { return true; } 54 55 55 unsigned width() const final;56 void setWidth(unsigned);57 unsigned height() const final;58 void setHeight(unsigned);59 60 const IntSize& size() const final;61 void setSize(const IntSize&) final;62 63 56 ExceptionOr<RefPtr<PaintRenderingContext2D>> getContext(); 64 57 58 CanvasRenderingContext* renderingContext() const final { return m_context.get(); } 65 59 GraphicsContext* drawingContext() const final; 66 60 GraphicsContext* existingDrawingContext() const final; 67 61 68 void makeRenderingResultsAvailable() final;69 62 void didDraw(const FloatRect&) final { } 70 63 … … 83 76 ScriptExecutionContext* canvasBaseScriptExecutionContext() const final { return ContextDestructionObserver::scriptExecutionContext(); } 84 77 78 std::unique_ptr<CanvasRenderingContext> m_context; 85 79 mutable GraphicsContext* m_destinationGraphicsContext = nullptr; 86 mutable IntSize m_size;87 80 mutable std::unique_ptr<ImageBuffer> m_copiedBuffer; 88 81 mutable RefPtr<Image> m_copiedImage; -
trunk/Source/WebCore/html/HTMLCanvasElement.cpp
r251425 r251874 56 56 #include "StringAdaptors.h" 57 57 #include <JavaScriptCore/JSCInlines.h> 58 #include <JavaScriptCore/JSLock.h>59 58 #include <math.h> 60 59 #include <wtf/IsoMallocInlines.h> … … 105 104 #endif 106 105 107 #if USE(CG)108 // FIXME: It seems strange that the default quality is not the one that is literally named "default".109 // Should fix names to make this easier to understand, or write an excellent comment here explaining why not.110 const InterpolationQuality defaultInterpolationQuality = InterpolationLow;111 #else112 const InterpolationQuality defaultInterpolationQuality = InterpolationDefault;113 #endif114 115 static size_t activePixelMemory = 0;116 106 static size_t maxActivePixelMemoryForTesting = 0; 117 107 118 108 HTMLCanvasElement::HTMLCanvasElement(const QualifiedName& tagName, Document& document) 119 109 : HTMLElement(tagName, document) 120 , m_size(defaultWidth, defaultHeight)110 , CanvasBase(IntSize(defaultWidth, defaultHeight)) 121 111 { 122 112 ASSERT(hasTagName(canvasTag)); … … 133 123 } 134 124 135 static void removeFromActivePixelMemory(size_t pixelsReleased)136 {137 if (!pixelsReleased)138 return;139 140 if (pixelsReleased < activePixelMemory)141 activePixelMemory -= pixelsReleased;142 else143 activePixelMemory = 0;144 }145 146 125 HTMLCanvasElement::~HTMLCanvasElement() 147 126 { 127 // FIXME: This has to be called here because CSSCanvasValue::CanvasObserverProxy::canvasDestroyed() 128 // downcasts the CanvasBase object to HTMLCanvasElement. That invokes virtual methods, which should be 129 // avoided in destructors, but works as long as it's done before HTMLCanvasElement destructs completely. 148 130 notifyObserversCanvasDestroyed(); 149 131 150 132 m_context = nullptr; // Ensure this goes away before the ImageBuffer. 151 152 releaseImageBufferAndContext(); 133 setImageBuffer(nullptr); 153 134 } 154 135 … … 192 173 setAttributeWithoutSynchronization(widthAttr, AtomString::number(limitToOnlyHTMLNonNegative(value, defaultWidth))); 193 174 return { }; 175 } 176 177 void HTMLCanvasElement::setSize(const IntSize& newSize) 178 { 179 if (newSize == size()) 180 return; 181 182 m_ignoreReset = true; 183 setWidth(newSize.width()); 184 setHeight(newSize.height()); 185 m_ignoreReset = false; 186 reset(); 194 187 } 195 188 … … 342 335 // Make sure we don't use more pixel memory than the system can support. 343 336 size_t requestedPixelMemory = 4 * width() * height(); 344 if (activePixelMemory + requestedPixelMemory > maxActivePixelMemory()) {337 if (activePixelMemory() + requestedPixelMemory > maxActivePixelMemory()) { 345 338 StringBuilder stringBuilder; 346 339 stringBuilder.appendLiteral("Total canvas memory use exceeds the maximum limit ("); … … 548 541 int h = limitToOnlyHTMLNonNegative(attributeWithoutSynchronization(heightAttr), defaultHeight); 549 542 550 if (m_contextStateSaver) { 551 // Reset to the initial graphics context state. 552 m_contextStateSaver->restore(); 553 m_contextStateSaver->save(); 554 } 555 543 resetGraphicsContextState(); 556 544 if (is<CanvasRenderingContext2D>(m_context.get())) 557 545 downcast<CanvasRenderingContext2D>(*m_context).reset(); … … 641 629 } 642 630 643 void HTMLCanvasElement::makeRenderingResultsAvailable()644 {645 if (m_context)646 m_context->paintRenderingResultsToCanvas();647 }648 649 631 void HTMLCanvasElement::makePresentationCopy() 650 632 { … … 660 642 } 661 643 662 void HTMLCanvasElement::releaseImageBufferAndContext() 663 { 664 m_contextStateSaver = nullptr; 644 void HTMLCanvasElement::setSurfaceSize(const IntSize& size) 645 { 646 CanvasBase::setSize(size); 647 m_hasCreatedImageBuffer = false; 665 648 setImageBuffer(nullptr); 666 }667 668 void HTMLCanvasElement::setSurfaceSize(const IntSize& size)669 {670 m_size = size;671 m_hasCreatedImageBuffer = false;672 releaseImageBufferAndContext();673 649 clearCopiedImage(); 674 650 } … … 699 675 return Exception { SecurityError }; 700 676 701 if ( m_size.isEmpty() || !buffer())677 if (size().isEmpty() || !buffer()) 702 678 return UncachedString { "data:,"_s }; 703 679 if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled()) … … 728 704 return Exception { SecurityError }; 729 705 730 if ( m_size.isEmpty() || !buffer()) {706 if (size().isEmpty() || !buffer()) { 731 707 callback->scheduleCallback(context, nullptr); 732 708 return { }; … … 841 817 } 842 818 843 size_t HTMLCanvasElement::memoryCost() const844 {845 // memoryCost() may be invoked concurrently from a GC thread, and we need to be careful846 // about what data we access here and how. We need to hold a lock to prevent m_imageBuffer847 // from being changed while we access it.848 auto locker = holdLock(m_imageBufferAssignmentLock);849 if (!m_imageBuffer)850 return 0;851 return m_imageBuffer->memoryCost();852 }853 854 size_t HTMLCanvasElement::externalMemoryCost() const855 {856 // externalMemoryCost() may be invoked concurrently from a GC thread, and we need to be careful857 // about what data we access here and how. We need to hold a lock to prevent m_imageBuffer858 // from being changed while we access it.859 auto locker = holdLock(m_imageBufferAssignmentLock);860 if (!m_imageBuffer)861 return 0;862 return m_imageBuffer->externalMemoryCost();863 }864 865 819 void HTMLCanvasElement::setUsesDisplayListDrawing(bool usesDisplayListDrawing) 866 820 { … … 903 857 void HTMLCanvasElement::createImageBuffer() const 904 858 { 905 ASSERT(! m_imageBuffer);859 ASSERT(!hasCreatedImageBuffer()); 906 860 907 861 m_hasCreatedImageBuffer = true; … … 920 874 // Make sure we don't use more pixel memory than the system can support. 921 875 size_t requestedPixelMemory = 4 * width() * height(); 922 if (activePixelMemory + requestedPixelMemory > maxActivePixelMemory()) {876 if (activePixelMemory() + requestedPixelMemory > maxActivePixelMemory()) { 923 877 StringBuilder stringBuilder; 924 878 stringBuilder.appendLiteral("Total canvas memory use exceeds the maximum limit ("); … … 936 890 auto hostWindow = (document().view() && document().view()->root()) ? document().view()->root()->hostWindow() : nullptr; 937 891 setImageBuffer(ImageBuffer::create(size(), renderingMode, 1, ColorSpaceSRGB, hostWindow)); 938 }939 940 void HTMLCanvasElement::setImageBuffer(std::unique_ptr<ImageBuffer>&& buffer) const941 {942 size_t previousMemoryCost = memoryCost();943 removeFromActivePixelMemory(previousMemoryCost);944 945 {946 auto locker = holdLock(m_imageBufferAssignmentLock);947 m_contextStateSaver = nullptr;948 m_imageBuffer = WTFMove(buffer);949 }950 951 if (m_imageBuffer && m_size != m_imageBuffer->internalSize())952 m_size = m_imageBuffer->internalSize();953 954 size_t currentMemoryCost = memoryCost();955 activePixelMemory += currentMemoryCost;956 957 if (m_context && m_imageBuffer && previousMemoryCost != currentMemoryCost)958 InspectorInstrumentation::didChangeCanvasMemory(*m_context);959 960 if (!m_imageBuffer)961 return;962 m_imageBuffer->context().setShadowsIgnoreTransforms(true);963 m_imageBuffer->context().setImageInterpolationQuality(defaultInterpolationQuality);964 m_imageBuffer->context().setStrokeThickness(1);965 m_contextStateSaver = makeUnique<GraphicsContextStateSaver>(m_imageBuffer->context());966 967 JSC::JSLockHolder lock(HTMLElement::scriptExecutionContext()->vm());968 HTMLElement::scriptExecutionContext()->vm().heap.reportExtraMemoryAllocated(memoryCost());969 892 970 893 #if USE(IOSURFACE_CANVAS_BACKING_STORE) || ENABLE(ACCELERATED_2D_CANVAS) … … 980 903 m_hasCreatedImageBuffer = true; 981 904 setImageBuffer(WTFMove(buffer)); 982 didDraw(FloatRect(FloatPoint(), m_size)); 983 } 984 985 GraphicsContext* HTMLCanvasElement::drawingContext() const 986 { 987 if (m_context && !m_context->is2d()) 988 return nullptr; 989 990 return buffer() ? &m_imageBuffer->context() : nullptr; 991 } 992 993 GraphicsContext* HTMLCanvasElement::existingDrawingContext() const 994 { 995 if (!m_hasCreatedImageBuffer) 996 return nullptr; 997 998 return drawingContext(); 999 } 1000 1001 ImageBuffer* HTMLCanvasElement::buffer() const 1002 { 1003 if (!m_hasCreatedImageBuffer) 1004 createImageBuffer(); 1005 return m_imageBuffer.get(); 905 didDraw(FloatRect(FloatPoint(), size())); 1006 906 } 1007 907 … … 1036 936 } 1037 937 1038 AffineTransform HTMLCanvasElement::baseTransform() const 1039 { 1040 ASSERT(m_hasCreatedImageBuffer); 1041 return m_imageBuffer->baseTransform(); 1042 } 1043 1044 } 938 } -
trunk/Source/WebCore/html/HTMLCanvasElement.h
r251425 r251874 32 32 #include "HTMLElement.h" 33 33 #include "ImageBitmapRenderingContextSettings.h" 34 #include "IntSize.h"35 34 #include <memory> 36 35 #include <wtf/Forward.h> … … 43 42 44 43 class BlobCallback; 44 class CanvasRenderingContext; 45 45 class CanvasRenderingContext2D; 46 46 class GraphicsContext; 47 class GraphicsContextStateSaver;48 47 class Image; 49 48 class ImageBuffer; … … 66 65 virtual ~HTMLCanvasElement(); 67 66 68 unsigned width() const final { return size().width(); }69 unsigned height() const final { return size().height(); }70 71 67 WEBCORE_EXPORT ExceptionOr<void> setWidth(unsigned); 72 68 WEBCORE_EXPORT ExceptionOr<void> setHeight(unsigned); 73 69 74 const IntSize& size() const final { return m_size; }70 void setSize(const IntSize& newSize) override; 75 71 76 void setSize(const IntSize& newSize) override 77 { 78 if (newSize == size()) 79 return; 80 m_ignoreReset = true; 81 setWidth(newSize.width()); 82 setHeight(newSize.height()); 83 m_ignoreReset = false; 84 reset(); 85 } 86 72 CanvasRenderingContext* renderingContext() const final { return m_context.get(); } 87 73 ExceptionOr<Optional<RenderingContext>> getContext(JSC::JSGlobalObject&, const String& contextId, Vector<JSC::Strong<JSC::Unknown>>&& arguments); 88 74 … … 117 103 void paint(GraphicsContext&, const LayoutRect&); 118 104 119 GraphicsContext* drawingContext() const final;120 GraphicsContext* existingDrawingContext() const final;121 122 105 #if ENABLE(MEDIA_STREAM) 123 106 RefPtr<MediaSample> toMediaSample(); … … 125 108 #endif 126 109 127 ImageBuffer* buffer() const;128 110 Image* copiedImage() const final; 129 111 void clearCopiedImage(); … … 134 116 SecurityOrigin* securityOrigin() const final; 135 117 136 AffineTransform baseTransform() const final;137 138 void makeRenderingResultsAvailable() final;139 bool hasCreatedImageBuffer() const { return m_hasCreatedImageBuffer; }140 141 118 bool shouldAccelerate(const IntSize&) const; 142 119 … … 145 122 WEBCORE_EXPORT String displayListAsText(DisplayList::AsTextFlags) const; 146 123 WEBCORE_EXPORT String replayDisplayListAsText(DisplayList::AsTextFlags) const; 147 148 size_t memoryCost() const;149 size_t externalMemoryCost() const;150 124 151 125 // FIXME: Only some canvas rendering contexts need an ImageBuffer. … … 168 142 void reset(); 169 143 170 void createImageBuffer() const ;144 void createImageBuffer() const final; 171 145 void clearImageBuffer() const; 172 146 147 bool hasCreatedImageBuffer() const final { return m_hasCreatedImageBuffer; } 148 173 149 void setSurfaceSize(const IntSize&); 174 void setImageBuffer(std::unique_ptr<ImageBuffer>&&) const;175 void releaseImageBufferAndContext();176 150 177 151 bool paintsIntoCanvasBuffer() const; … … 185 159 186 160 FloatRect m_dirtyRect; 187 mutable IntSize m_size;188 161 189 162 bool m_ignoreReset { false }; … … 192 165 bool m_tracksDisplayListReplay { false }; 193 166 194 mutable Lock m_imageBufferAssignmentLock;195 196 // m_ createdImageBuffer means we tried to malloc the buffer.We didn't necessarily get it.167 std::unique_ptr<CanvasRenderingContext> m_context; 168 169 // m_hasCreatedImageBuffer means we tried to malloc the buffer. We didn't necessarily get it. 197 170 mutable bool m_hasCreatedImageBuffer { false }; 198 171 mutable bool m_didClearImageBuffer { false }; 199 mutable std::unique_ptr<ImageBuffer> m_imageBuffer; 200 mutable std::unique_ptr<GraphicsContextStateSaver> m_contextStateSaver; 201 172 202 173 mutable RefPtr<Image> m_presentedImage; 203 174 mutable RefPtr<Image> m_copiedImage; // FIXME: This is temporary for platforms that have to copy the image buffer to render (and for CSSCanvasValue). -
trunk/Source/WebCore/html/OffscreenCanvas.cpp
r251630 r251874 45 45 46 46 OffscreenCanvas::OffscreenCanvas(ScriptExecutionContext& context, unsigned width, unsigned height) 47 : C ontextDestructionObserver(&context)48 , m_size(width, height)47 : CanvasBase(IntSize(width, height)) 48 , ContextDestructionObserver(&context) 49 49 { 50 50 } … … 54 54 notifyObserversCanvasDestroyed(); 55 55 56 m_context = nullptr; 57 } 58 59 unsigned OffscreenCanvas::width() const 60 { 61 return m_size.width(); 56 m_context = nullptr; // Ensure this goes away before the ImageBuffer. 57 setImageBuffer(nullptr); 62 58 } 63 59 64 60 void OffscreenCanvas::setWidth(unsigned newWidth) 65 61 { 66 return m_size.setWidth(newWidth); 67 } 68 69 unsigned OffscreenCanvas::height() const 70 { 71 return m_size.height(); 62 setSize(IntSize(newWidth, height())); 72 63 } 73 64 74 65 void OffscreenCanvas::setHeight(unsigned newHeight) 75 66 { 76 return m_size.setHeight(newHeight); 77 } 78 79 const IntSize& OffscreenCanvas::size() const 80 { 81 return m_size; 82 } 83 84 void OffscreenCanvas::setSize(const IntSize& newSize) 85 { 86 m_size = newSize; 67 setSize(IntSize(width(), newHeight)); 87 68 } 88 69 … … 124 105 // create a new bitmap and paint into it. 125 106 126 auto imageBitmap = ImageBitmap::create( m_size);107 auto imageBitmap = ImageBitmap::create(size()); 127 108 if (!imageBitmap->buffer()) 128 109 return nullptr; … … 147 128 } 148 129 130 void OffscreenCanvas::createImageBuffer() const 131 { 132 } 133 149 134 } 150 135 -
trunk/Source/WebCore/html/OffscreenCanvas.h
r251630 r251874 42 42 namespace WebCore { 43 43 44 class CanvasRenderingContext; 44 45 class ImageBitmap; 45 46 class WebGLRenderingContext; … … 66 67 virtual ~OffscreenCanvas(); 67 68 68 unsigned width() const final;69 69 void setWidth(unsigned); 70 unsigned height() const final;71 70 void setHeight(unsigned); 72 71 73 const IntSize& size() const final; 74 void setSize(const IntSize&) final; 72 CanvasRenderingContext* renderingContext() const final { return m_context.get(); } 75 73 76 74 #if ENABLE(WEBGL) … … 80 78 // void convertToBlob(ImageEncodeOptions options); 81 79 82 GraphicsContext* drawingContext() const final { return nullptr; }83 GraphicsContext* existingDrawingContext() const final { return nullptr; }84 85 void makeRenderingResultsAvailable() final { }86 80 void didDraw(const FloatRect&) final { } 87 81 88 AffineTransform baseTransform() const final { return { }; }89 82 Image* copiedImage() const final { return nullptr; } 90 83 … … 108 101 void derefCanvasBase() final { deref(); } 109 102 110 IntSize m_size; 103 void createImageBuffer() const final; 104 105 std::unique_ptr<CanvasRenderingContext> m_context; 111 106 }; 112 107
Note: See TracChangeset
for help on using the changeset viewer.