WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch
bug-202797-20200430155032.patch (text/plain), 37.17 KB, created by
Chris Lord
on 2020-04-30 07:50:33 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Chris Lord
Created:
2020-04-30 07:50:33 PDT
Size:
37.17 KB
patch
obsolete
>Subversion Revision: 260747 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 459a33fb70848f38d92e2e6b19dc2fe10e6a767d..49913c525a5eef8fcb6c18e22a0ba4cf7c5ac1d8 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,47 @@ >+2020-02-13 Chris Lord <clord@igalia.com> >+ >+ Implement Canvas.transferControlToOffscreen and OffscreenCanvasRenderingContext2D.commit >+ https://bugs.webkit.org/show_bug.cgi?id=202797 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Implement HTMLCanvasElement.transferControlToOffscreen and >+ OffscreenCanvasRenderingContext2D.commit. This allows for >+ (synchronous) display of asynchronously rendered OffscreenCanvas >+ content. >+ >+ No new tests. Covered by existing tests. >+ >+ * html/HTMLCanvasElement.cpp: >+ (WebCore::HTMLCanvasElement::setHeight): >+ (WebCore::HTMLCanvasElement::setWidth): >+ (WebCore::HTMLCanvasElement::reset): >+ (WebCore::HTMLCanvasElement::transferControlToOffscreen): >+ (WebCore::HTMLCanvasElement::setImageBufferAndMarkDirty): >+ (WebCore::HTMLCanvasElement::isControlledByOffscreen const): >+ * html/HTMLCanvasElement.h: >+ * html/HTMLCanvasElement.idl: >+ * html/OffscreenCanvas.cpp: >+ (WebCore::DetachedOffscreenCanvas::DetachedOffscreenCanvas): >+ (WebCore::DetachedOffscreenCanvas::takePlaceholderCanvas): >+ (WebCore::OffscreenCanvas::create): >+ (WebCore::OffscreenCanvas::getContext): >+ (WebCore::OffscreenCanvas::didDraw): >+ (WebCore::OffscreenCanvas::detach): >+ (WebCore::OffscreenCanvas::setPlaceholderCanvas): >+ (WebCore::OffscreenCanvas::pushBufferToPlaceholder): >+ (WebCore::OffscreenCanvas::commitToPlaceholderCanvas): >+ (WebCore::OffscreenCanvas::scheduleCommitToPlaceholderCanvas): >+ (WebCore::OffscreenCanvas::reset): >+ * html/OffscreenCanvas.h: >+ * html/canvas/OffscreenCanvasRenderingContext2D.cpp: >+ (WebCore::OffscreenCanvasRenderingContext2D::commit): >+ * html/canvas/OffscreenCanvasRenderingContext2D.h: >+ * html/canvas/OffscreenCanvasRenderingContext2D.idl: >+ * html/canvas/PlaceholderRenderingContext.cpp: >+ (WebCore::PlaceholderRenderingContext::canvas const): >+ * html/canvas/PlaceholderRenderingContext.h: >+ > 2020-04-27 Claudio Saavedra <csaavedra@igalia.com> > > [GTK4] GdkRGBA has float members instead of double >diff --git a/Source/WebCore/html/HTMLCanvasElement.cpp b/Source/WebCore/html/HTMLCanvasElement.cpp >index 0db5268adede0bdf1054014e4917b439b828e0f3..4dba2a72c7dbe68498ce83086a549871941100b6 100644 >--- a/Source/WebCore/html/HTMLCanvasElement.cpp >+++ b/Source/WebCore/html/HTMLCanvasElement.cpp >@@ -49,6 +49,7 @@ > #include "InspectorInstrumentation.h" > #include "JSDOMConvertDictionary.h" > #include "MIMETypeRegistry.h" >+#include "PlaceholderRenderingContext.h" > #include "RenderElement.h" > #include "RenderHTMLCanvas.h" > #include "ResourceLoadObserver.h" >@@ -171,7 +172,7 @@ bool HTMLCanvasElement::canStartSelection() const > > ExceptionOr<void> HTMLCanvasElement::setHeight(unsigned value) > { >- if (m_context && m_context->isPlaceholder()) >+ if (isControlledByOffscreen()) > return Exception { InvalidStateError }; > setAttributeWithoutSynchronization(heightAttr, AtomString::number(limitToOnlyHTMLNonNegative(value, defaultHeight))); > return { }; >@@ -179,7 +180,7 @@ ExceptionOr<void> HTMLCanvasElement::setHeight(unsigned value) > > ExceptionOr<void> HTMLCanvasElement::setWidth(unsigned value) > { >- if (m_context && m_context->isPlaceholder()) >+ if (isControlledByOffscreen()) > return Exception { InvalidStateError }; > setAttributeWithoutSynchronization(widthAttr, AtomString::number(limitToOnlyHTMLNonNegative(value, defaultWidth))); > return { }; >@@ -540,7 +541,7 @@ void HTMLCanvasElement::didDraw(const FloatRect& rect) > > void HTMLCanvasElement::reset() > { >- if (m_ignoreReset) >+ if (m_ignoreReset || isControlledByOffscreen()) > return; > > bool hadImageBuffer = hasCreatedImageBuffer(); >@@ -742,6 +743,17 @@ ExceptionOr<void> HTMLCanvasElement::toBlob(ScriptExecutionContext& context, Ref > return { }; > } > >+#if ENABLE(OFFSCREEN_CANVAS) >+ExceptionOr<Ref<OffscreenCanvas>> HTMLCanvasElement::transferControlToOffscreen(ScriptExecutionContext& context) >+{ >+ if (m_context) >+ return Exception { InvalidStateError }; >+ >+ m_context = makeUnique<PlaceholderRenderingContext>(*this); >+ return OffscreenCanvas::create(context, *this); >+} >+#endif >+ > RefPtr<ImageData> HTMLCanvasElement::getImageData() > { > #if ENABLE(WEBGL) >@@ -916,8 +928,24 @@ void HTMLCanvasElement::createImageBuffer() const > > void HTMLCanvasElement::setImageBufferAndMarkDirty(std::unique_ptr<ImageBuffer>&& buffer) > { >+ IntSize oldSize = size(); > m_hasCreatedImageBuffer = true; > setImageBuffer(WTFMove(buffer)); >+ >+ if (isControlledByOffscreen() && oldSize != size()) { >+ setAttributeWithoutSynchronization(widthAttr, AtomString::number(width())); >+ setAttributeWithoutSynchronization(heightAttr, AtomString::number(height())); >+ >+ auto renderer = this->renderer(); >+ if (is<RenderHTMLCanvas>(renderer)) { >+ auto& canvasRenderer = downcast<RenderHTMLCanvas>(*renderer); >+ canvasRenderer.canvasSizeChanged(); >+ canvasRenderer.contentChanged(CanvasChanged); >+ } >+ >+ notifyObserversCanvasResized(); >+ } >+ > didDraw(FloatRect(FloatPoint(), size())); > } > >@@ -977,4 +1005,9 @@ void HTMLCanvasElement::eventListenersDidChange() > #endif > } > >+bool HTMLCanvasElement::isControlledByOffscreen() const >+{ >+ return m_context && m_context->isPlaceholder(); >+} >+ > } >diff --git a/Source/WebCore/html/HTMLCanvasElement.h b/Source/WebCore/html/HTMLCanvasElement.h >index 50e7c2cdee10582b6a97ccd2a775674908dff38c..b601b7ea542a34ffa41106ca9ebb964e69421817 100644 >--- a/Source/WebCore/html/HTMLCanvasElement.h >+++ b/Source/WebCore/html/HTMLCanvasElement.h >@@ -50,6 +50,7 @@ class ImageBuffer; > class ImageData; > class MediaSample; > class MediaStream; >+class OffscreenCanvas; > class WebGLRenderingContextBase; > class GPUCanvasContext; > struct UncachedString; >@@ -97,6 +98,9 @@ public: > WEBCORE_EXPORT ExceptionOr<UncachedString> toDataURL(const String& mimeType, JSC::JSValue quality); > WEBCORE_EXPORT ExceptionOr<UncachedString> toDataURL(const String& mimeType); > ExceptionOr<void> toBlob(ScriptExecutionContext&, Ref<BlobCallback>&&, const String& mimeType, JSC::JSValue quality); >+#if ENABLE(OFFSCREEN_CANVAS) >+ ExceptionOr<Ref<OffscreenCanvas>> transferControlToOffscreen(ScriptExecutionContext&); >+#endif > > // Used for rendering > void didDraw(const FloatRect&) final; >@@ -129,6 +133,8 @@ public: > > WEBCORE_EXPORT static void setMaxPixelMemoryForTesting(size_t); > >+ bool isControlledByOffscreen() const; >+ > private: > HTMLCanvasElement(const QualifiedName&, Document&); > >diff --git a/Source/WebCore/html/HTMLCanvasElement.idl b/Source/WebCore/html/HTMLCanvasElement.idl >index 718a9ea7a4c9715a2e780477552c2b5f513a9a0a..ae4fcaac269f6bc3f540ebd1e47b58927db3eeed 100644 >--- a/Source/WebCore/html/HTMLCanvasElement.idl >+++ b/Source/WebCore/html/HTMLCanvasElement.idl >@@ -50,6 +50,7 @@ typedef ( > > [MayThrowException] DOMString toDataURL(optional DOMString type, optional any quality); > [CallWith=ScriptExecutionContext, MayThrowException] void toBlob(BlobCallback callback, optional DOMString type, optional any quality); >+ [Conditional=OFFSCREEN_CANVAS, CallWith=ScriptExecutionContext, MayThrowException] OffscreenCanvas transferControlToOffscreen(); > > [Conditional=MEDIA_STREAM, CallWith=Document, MayThrowException, NewObject] MediaStream captureStream(optional double frameRequestRate); > }; >diff --git a/Source/WebCore/html/OffscreenCanvas.cpp b/Source/WebCore/html/OffscreenCanvas.cpp >index 606a4d7ce158d28f599796e3a39665aff46ad07f..4badd4eeb525a2003886ca6a55d382fd44a3a682 100644 >--- a/Source/WebCore/html/OffscreenCanvas.cpp >+++ b/Source/WebCore/html/OffscreenCanvas.cpp >@@ -31,11 +31,14 @@ > #include "CSSValuePool.h" > #include "CanvasRenderingContext.h" > #include "Document.h" >+#include "HTMLCanvasElement.h" > #include "ImageBitmap.h" >+#include "ImageData.h" > #include "JSBlob.h" > #include "JSDOMPromiseDeferred.h" > #include "MIMETypeRegistry.h" > #include "OffscreenCanvasRenderingContext2D.h" >+#include "PlaceholderRenderingContext.h" > #include "WebGLRenderingContext.h" > #include "WorkerGlobalScope.h" > #include <wtf/IsoMallocInlines.h> >@@ -56,6 +59,12 @@ std::unique_ptr<ImageBuffer> DetachedOffscreenCanvas::takeImageBuffer() > return WTFMove(m_buffer); > } > >+WeakPtr<HTMLCanvasElement> DetachedOffscreenCanvas::takePlaceholderCanvas() >+{ >+ ASSERT(isMainThread()); >+ return std::exchange(m_placeholderCanvas, nullptr); >+} >+ > Ref<OffscreenCanvas> OffscreenCanvas::create(ScriptExecutionContext& context, unsigned width, unsigned height) > { > return adoptRef(*new OffscreenCanvas(context, width, height)); >@@ -68,9 +77,21 @@ Ref<OffscreenCanvas> OffscreenCanvas::create(ScriptExecutionContext& context, st > if (!detachedCanvas->originClean()) > clone->setOriginTainted(); > >+ callOnMainThread([detachedCanvas = WTFMove(detachedCanvas), offscreenCanvas = makeRef(clone.get())] () mutable { >+ offscreenCanvas->m_placeholderCanvas = detachedCanvas->takePlaceholderCanvas(); >+ offscreenCanvas->scriptExecutionContext()->postTask([releaseOffscreenCanvas = WTFMove(offscreenCanvas)] (ScriptExecutionContext&) { }); >+ }); >+ > return clone; > } > >+Ref<OffscreenCanvas> OffscreenCanvas::create(ScriptExecutionContext& context, HTMLCanvasElement& canvas) >+{ >+ auto offscreen = adoptRef(*new OffscreenCanvas(context, canvas.width(), canvas.height())); >+ offscreen->setPlaceholderCanvas(canvas); >+ return offscreen; >+} >+ > OffscreenCanvas::OffscreenCanvas(ScriptExecutionContext& context, unsigned width, unsigned height) > : CanvasBase(IntSize(width, height)) > , ContextDestructionObserver(&context) >@@ -119,7 +140,7 @@ void OffscreenCanvas::setSize(const IntSize& newSize) > reset(); > } > >-ExceptionOr<OffscreenRenderingContext> OffscreenCanvas::getContext(JSC::JSGlobalObject& state, RenderingContextType contextType, Vector<JSC::Strong<JSC::Unknown>>&& arguments) >+ExceptionOr<Optional<OffscreenRenderingContext>> OffscreenCanvas::getContext(JSC::JSGlobalObject& state, RenderingContextType contextType, Vector<JSC::Strong<JSC::Unknown>>&& arguments) > { > if (m_detached) > return Exception { InvalidStateError }; >@@ -127,22 +148,22 @@ ExceptionOr<OffscreenRenderingContext> OffscreenCanvas::getContext(JSC::JSGlobal > if (contextType == RenderingContextType::_2d) { > if (m_context) { > if (!is<OffscreenCanvasRenderingContext2D>(*m_context)) >- return Exception { InvalidStateError }; >- return { RefPtr<OffscreenCanvasRenderingContext2D> { &downcast<OffscreenCanvasRenderingContext2D>(*m_context) } }; >+ return { { WTF::nullopt } }; >+ return { { RefPtr<OffscreenCanvasRenderingContext2D> { &downcast<OffscreenCanvasRenderingContext2D>(*m_context) } } }; > } > > m_context = makeUnique<OffscreenCanvasRenderingContext2D>(*this); > if (!m_context) >- return { RefPtr<OffscreenCanvasRenderingContext2D> { nullptr } }; >+ return { { WTF::nullopt } }; > >- return { RefPtr<OffscreenCanvasRenderingContext2D> { &downcast<OffscreenCanvasRenderingContext2D>(*m_context) } }; >+ return { { RefPtr<OffscreenCanvasRenderingContext2D> { &downcast<OffscreenCanvasRenderingContext2D>(*m_context) } } }; > } > #if ENABLE(WEBGL) > if (contextType == RenderingContextType::Webgl) { > if (m_context) { >- if (!is<WebGLRenderingContext>(*m_context)) >- return Exception { InvalidStateError }; >- return { RefPtr<WebGLRenderingContext> { &downcast<WebGLRenderingContext>(*m_context) } }; >+ if (is<WebGLRenderingContext>(*m_context)) >+ return { { RefPtr<WebGLRenderingContext> { &downcast<WebGLRenderingContext>(*m_context) } } }; >+ return { { WTF::nullopt } }; > } > > auto scope = DECLARE_THROW_SCOPE(state.vm()); >@@ -151,13 +172,13 @@ ExceptionOr<OffscreenRenderingContext> OffscreenCanvas::getContext(JSC::JSGlobal > > m_context = WebGLRenderingContextBase::create(*this, attributes, "webgl"); > if (!m_context) >- return { RefPtr<WebGLRenderingContext> { nullptr } }; >+ return { { WTF::nullopt } }; > >- return { RefPtr<WebGLRenderingContext> { &downcast<WebGLRenderingContext>(*m_context) } }; >+ return { { RefPtr<WebGLRenderingContext> { &downcast<WebGLRenderingContext>(*m_context) } } }; > } > #endif > >- return Exception { NotSupportedError }; >+ return Exception { TypeError }; > } > > ExceptionOr<RefPtr<ImageBitmap>> OffscreenCanvas::transferToImageBitmap() >@@ -259,6 +280,7 @@ void OffscreenCanvas::convertToBlob(ImageEncodeOptions&& options, Ref<DeferredPr > void OffscreenCanvas::didDraw(const FloatRect& rect) > { > clearCopiedImage(); >+ scheduleCommitToPlaceholderCanvas(); > notifyObserversCanvasChanged(rect); > } > >@@ -301,7 +323,73 @@ std::unique_ptr<DetachedOffscreenCanvas> OffscreenCanvas::detach() > > m_detached = true; > >- return makeUnique<DetachedOffscreenCanvas>(takeImageBuffer(), size(), originClean()); >+ auto detached = makeUnique<DetachedOffscreenCanvas>(takeImageBuffer(), size(), originClean()); >+ detached->m_placeholderCanvas = std::exchange(m_placeholderCanvas, nullptr); >+ >+ return detached; >+} >+ >+void OffscreenCanvas::setPlaceholderCanvas(HTMLCanvasElement& canvas) >+{ >+ ASSERT(!m_context); >+ ASSERT(isMainThread()); >+ m_placeholderCanvas = makeWeakPtr(canvas); >+} >+ >+void OffscreenCanvas::pushBufferToPlaceholder() >+{ >+ callOnMainThread([protectedThis = makeRef(*this), this] () mutable { >+ auto locker = holdLock(m_commitLock); >+ >+ if (m_placeholderCanvas && m_hasPendingCommitData) { >+ std::unique_ptr<ImageBuffer> buffer = ImageBuffer::create(FloatSize(m_pendingCommitData->size()), RenderingMode::Unaccelerated); >+ buffer->putImageData(AlphaPremultiplication::Premultiplied, *m_pendingCommitData, IntRect(IntPoint(), m_pendingCommitData->size())); >+ m_placeholderCanvas->setImageBufferAndMarkDirty(WTFMove(buffer)); >+ m_hasPendingCommitData = false; >+ } >+ >+ scriptExecutionContext()->postTask([releaseThis = WTFMove(protectedThis)] (ScriptExecutionContext&) { }); >+ }); >+} >+ >+void OffscreenCanvas::commitToPlaceholderCanvas() >+{ >+ auto* imageBuffer = buffer(); >+ if (!imageBuffer) >+ return; >+ >+ // FIXME: Transfer texture over if we're using accelerated compositing >+ if (m_context && (m_context->isWebGL() || m_context->isAccelerated())) >+ m_context->paintRenderingResultsToCanvas(); >+ >+ if (isMainThread()) { >+ if (m_placeholderCanvas) { >+ if (auto bufferCopy = imageBuffer->copyRectToBuffer(FloatRect(FloatPoint(), imageBuffer->logicalSize()), ColorSpace::SRGB, imageBuffer->context())) >+ m_placeholderCanvas->setImageBufferAndMarkDirty(WTFMove(bufferCopy)); >+ } >+ return; >+ } >+ >+ auto locker = holdLock(m_commitLock); >+ >+ bool shouldPushBuffer = !m_hasPendingCommitData; >+ m_pendingCommitData = imageBuffer->getImageData(AlphaPremultiplication::Premultiplied, IntRect(IntPoint(), imageBuffer->logicalSize())); >+ m_hasPendingCommitData = true; >+ >+ if (shouldPushBuffer) >+ pushBufferToPlaceholder(); >+} >+ >+void OffscreenCanvas::scheduleCommitToPlaceholderCanvas() >+{ >+ if (!m_hasScheduledCommit) { >+ auto& scriptContext = *scriptExecutionContext(); >+ m_hasScheduledCommit = true; >+ scriptContext.postTask([protectedThis = makeRef(*this), this] (ScriptExecutionContext&) { >+ m_hasScheduledCommit = false; >+ commitToPlaceholderCanvas(); >+ }); >+ } > } > > CSSValuePool& OffscreenCanvas::cssValuePool() >@@ -351,6 +439,7 @@ void OffscreenCanvas::reset() > clearCopiedImage(); > > notifyObserversCanvasResized(); >+ scheduleCommitToPlaceholderCanvas(); > } > > } >diff --git a/Source/WebCore/html/OffscreenCanvas.h b/Source/WebCore/html/OffscreenCanvas.h >index 3e5e30a576e31a932a6f146a97ebf08de9a25f39..a3d1610e0e1d9e6c9fe3ab51e0f7dd5cf467060a 100644 >--- a/Source/WebCore/html/OffscreenCanvas.h >+++ b/Source/WebCore/html/OffscreenCanvas.h >@@ -37,6 +37,7 @@ > #include "ScriptWrappable.h" > #include <wtf/Forward.h> > #include <wtf/RefCounted.h> >+#include <wtf/WeakPtr.h> > #include <wtf/text/WTFString.h> > > namespace WebCore { >@@ -44,7 +45,9 @@ namespace WebCore { > class CanvasRenderingContext; > class CSSValuePool; > class DeferredPromise; >+class HTMLCanvasElement; > class ImageBitmap; >+class ImageData; > class OffscreenCanvasRenderingContext2D; > class WebGLRenderingContext; > >@@ -57,17 +60,21 @@ using OffscreenRenderingContext = Variant<RefPtr<OffscreenCanvasRenderingContext > class DetachedOffscreenCanvas { > WTF_MAKE_NONCOPYABLE(DetachedOffscreenCanvas); > WTF_MAKE_FAST_ALLOCATED; >+ friend class OffscreenCanvas; >+ > public: > DetachedOffscreenCanvas(std::unique_ptr<ImageBuffer>&&, const IntSize&, bool originClean); > > std::unique_ptr<ImageBuffer> takeImageBuffer(); > const IntSize& size() const { return m_size; } > bool originClean() const { return m_originClean; } >+ WeakPtr<HTMLCanvasElement> takePlaceholderCanvas(); > > private: > std::unique_ptr<ImageBuffer> m_buffer; > IntSize m_size; > bool m_originClean; >+ WeakPtr<HTMLCanvasElement> m_placeholderCanvas; > }; > > class OffscreenCanvas final : public RefCounted<OffscreenCanvas>, public CanvasBase, public EventTargetWithInlineData, private ContextDestructionObserver { >@@ -86,6 +93,7 @@ public: > > static Ref<OffscreenCanvas> create(ScriptExecutionContext&, unsigned width, unsigned height); > static Ref<OffscreenCanvas> create(ScriptExecutionContext&, std::unique_ptr<DetachedOffscreenCanvas>&&); >+ static Ref<OffscreenCanvas> create(ScriptExecutionContext&, HTMLCanvasElement&); > virtual ~OffscreenCanvas(); > > unsigned width() const final; >@@ -95,7 +103,7 @@ public: > > CanvasRenderingContext* renderingContext() const final { return m_context.get(); } > >- ExceptionOr<OffscreenRenderingContext> getContext(JSC::JSGlobalObject&, RenderingContextType, Vector<JSC::Strong<JSC::Unknown>>&& arguments); >+ ExceptionOr<Optional<OffscreenRenderingContext>> getContext(JSC::JSGlobalObject&, RenderingContextType, Vector<JSC::Strong<JSC::Unknown>>&& arguments); > ExceptionOr<RefPtr<ImageBitmap>> transferToImageBitmap(); > void convertToBlob(ImageEncodeOptions&&, Ref<DeferredPromise>&&); > >@@ -109,6 +117,8 @@ public: > bool canDetach() const; > std::unique_ptr<DetachedOffscreenCanvas> detach(); > >+ void commitToPlaceholderCanvas(); >+ > CSSValuePool& cssValuePool(); > > using RefCounted::ref; >@@ -138,6 +148,10 @@ private: > > void clearCopiedImage() const; > >+ void setPlaceholderCanvas(HTMLCanvasElement&); >+ void pushBufferToPlaceholder(); >+ void scheduleCommitToPlaceholderCanvas(); >+ > std::unique_ptr<CanvasRenderingContext> m_context; > > // m_hasCreatedImageBuffer means we tried to malloc the buffer. We didn't necessarily get it. >@@ -146,6 +160,13 @@ private: > bool m_detached { false }; > > mutable RefPtr<Image> m_copiedImage; >+ >+ bool m_hasScheduledCommit { false }; >+ WeakPtr<HTMLCanvasElement> m_placeholderCanvas; >+ >+ mutable Lock m_commitLock; >+ bool m_hasPendingCommitData { false }; >+ RefPtr<ImageData> m_pendingCommitData; > }; > > } >diff --git a/Source/WebCore/html/canvas/OffscreenCanvasRenderingContext2D.cpp b/Source/WebCore/html/canvas/OffscreenCanvasRenderingContext2D.cpp >index 86d784a351d584ce6ef3a6992e7ec206e68d9600..0b9a0441c16bc381bf68706e72230bb5463aef0f 100644 >--- a/Source/WebCore/html/canvas/OffscreenCanvasRenderingContext2D.cpp >+++ b/Source/WebCore/html/canvas/OffscreenCanvasRenderingContext2D.cpp >@@ -48,6 +48,11 @@ OffscreenCanvasRenderingContext2D::OffscreenCanvasRenderingContext2D(CanvasBase& > > OffscreenCanvasRenderingContext2D::~OffscreenCanvasRenderingContext2D() = default; > >+void OffscreenCanvasRenderingContext2D::commit() >+{ >+ downcast<OffscreenCanvas>(canvasBase()).commitToPlaceholderCanvas(); >+} >+ > } // namespace WebCore > > #endif >diff --git a/Source/WebCore/html/canvas/OffscreenCanvasRenderingContext2D.h b/Source/WebCore/html/canvas/OffscreenCanvasRenderingContext2D.h >index ccb16e92cd2bd04ca568bcf61632792e694933e0..ee929af2b29dae8263de1daf60dd16454257e9e1 100644 >--- a/Source/WebCore/html/canvas/OffscreenCanvasRenderingContext2D.h >+++ b/Source/WebCore/html/canvas/OffscreenCanvasRenderingContext2D.h >@@ -42,6 +42,8 @@ public: > bool isOffscreen2d() const override { return true; } > > OffscreenCanvas& canvas() const { return downcast<OffscreenCanvas>(canvasBase()); } >+ >+ void commit(); > }; > > } // namespace WebCore >diff --git a/Source/WebCore/html/canvas/OffscreenCanvasRenderingContext2D.idl b/Source/WebCore/html/canvas/OffscreenCanvasRenderingContext2D.idl >index 04ec6a7519b14a75a12564f5e9deb910ec8bf139..d7fec8799369044bda72de0eb5c53d637ae02709 100644 >--- a/Source/WebCore/html/canvas/OffscreenCanvasRenderingContext2D.idl >+++ b/Source/WebCore/html/canvas/OffscreenCanvasRenderingContext2D.idl >@@ -27,14 +27,13 @@ > CustomIsReachable, > EnabledAtRuntime=OffscreenCanvas, > Conditional=OFFSCREEN_CANVAS, >- Exposed=(Window), // FIXME: OffscreenCanvas - should be Window,Worker >+ Exposed=(Window,Worker), > JSGenerateToJSObject, > JSCustomMarkFunction, > // CallTracingCallback=recordCanvasAction, // FIXME: OffscreenCanvas. > ] interface OffscreenCanvasRenderingContext2D { > readonly attribute OffscreenCanvas canvas; >- // FIXME: OffscreenCanvas. >- // void commit(); >+ void commit(); > > // Inspector-only. > // FIXME: OffscreenCanvas. >diff --git a/Source/WebCore/html/canvas/PlaceholderRenderingContext.cpp b/Source/WebCore/html/canvas/PlaceholderRenderingContext.cpp >index 092c4aef60a5513f476c7d71433ebe71afa781d4..1ec7a24edf445211bbba9942e8146bb1e7f684c0 100644 >--- a/Source/WebCore/html/canvas/PlaceholderRenderingContext.cpp >+++ b/Source/WebCore/html/canvas/PlaceholderRenderingContext.cpp >@@ -26,6 +26,10 @@ > #include "config.h" > #include "PlaceholderRenderingContext.h" > >+#if ENABLE(OFFSCREEN_CANVAS) >+ >+#include "HTMLCanvasElement.h" >+#include "OffscreenCanvas.h" > #include <wtf/IsoMallocInlines.h> > > namespace WebCore { >@@ -37,4 +41,14 @@ PlaceholderRenderingContext::PlaceholderRenderingContext(CanvasBase& canvas) > { > } > >+HTMLCanvasElement* PlaceholderRenderingContext::canvas() const >+{ >+ auto& base = canvasBase(); >+ if (!is<HTMLCanvasElement>(base)) >+ return nullptr; >+ return &downcast<HTMLCanvasElement>(base); > } >+ >+} >+ >+#endif >diff --git a/Source/WebCore/html/canvas/PlaceholderRenderingContext.h b/Source/WebCore/html/canvas/PlaceholderRenderingContext.h >index c348e518952cb9d415c6bd1795f216dcb165d259..645091459dd01cc2a7977dc003b45265de5ba7d8 100644 >--- a/Source/WebCore/html/canvas/PlaceholderRenderingContext.h >+++ b/Source/WebCore/html/canvas/PlaceholderRenderingContext.h >@@ -25,15 +25,21 @@ > > #pragma once > >+#if ENABLE(OFFSCREEN_CANVAS) >+ > #include "CanvasRenderingContext.h" > > namespace WebCore { > >+class OffscreenCanvas; >+ > class PlaceholderRenderingContext final : public CanvasRenderingContext { > WTF_MAKE_ISO_ALLOCATED(PlaceholderRenderingContext); > public: > PlaceholderRenderingContext(CanvasBase&); > >+ HTMLCanvasElement* canvas() const; >+ > private: > bool isPlaceholder() const final { return true; } > }; >@@ -41,3 +47,5 @@ private: > } > > SPECIALIZE_TYPE_TRAITS_CANVASRENDERINGCONTEXT(WebCore::PlaceholderRenderingContext, isPlaceholder()) >+ >+#endif >diff --git a/LayoutTests/imported/w3c/ChangeLog b/LayoutTests/imported/w3c/ChangeLog >index 1ce56cd46d689d1d04f292c84be21c0820f5155d..7963814a83b1600505f72323625c85facb28fbf2 100644 >--- a/LayoutTests/imported/w3c/ChangeLog >+++ b/LayoutTests/imported/w3c/ChangeLog >@@ -1,3 +1,18 @@ >+2020-02-13 Chris Lord <clord@igalia.com> >+ >+ Implement Canvas.transferControlToOffscreen and OffscreenCanvasRenderingContext2D.commit >+ https://bugs.webkit.org/show_bug.cgi?id=202797 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.commit-expected.txt: >+ * web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.commit.w-expected.txt: >+ * web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.getcontext-expected.txt: >+ * web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.getcontext.worker-expected.txt: >+ * web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.resize-expected.txt: >+ * web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.transfercontrol.to.offscreen-expected.txt: >+ * web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.transfercontrol.to.offscreen.w-expected.txt: >+ > 2020-04-26 Alexey Shvayka <shvaikalesh@gmail.com> > > InternalFunction::createSubclassStructure should use newTarget's globalObject >diff --git a/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.commit-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.commit-expected.txt >index 6f1c7050e5e828c3f323f295fb1d2a4fec8c007c..b3b39a7a91fc0ac8557a9a28c2ebb624b5e47714 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.commit-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.commit-expected.txt >@@ -1,4 +1,5 @@ >+CONSOLE MESSAGE: Error: assert_equals: Green channel of the pixel at (5, 5) expected 255 but got 0 > >-FAIL Test that calling OffscreenCanvas's commit pushes its contents to its placeholder. placeholder.transferControlToOffscreen is not a function. (In 'placeholder.transferControlToOffscreen()', 'placeholder.transferControlToOffscreen' is undefined) >-FAIL Test that calling commit on an OffscreenCanvas that is not transferred from a HTMLCanvasElement is a noop. ctx.commit is not a function. (In 'ctx.commit()', 'ctx.commit' is undefined) >+PASS Test that calling OffscreenCanvas's commit pushes its contents to its placeholder. >+PASS Test that calling commit on an OffscreenCanvas that is not transferred from a HTMLCanvasElement is a noop. > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.commit.w-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.commit.w-expected.txt >index 434332ce51abfe3712d0e24958a805281a607074..c4218ecac273d0547f5e49c3d123fdaf83f3eab6 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.commit.w-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.commit.w-expected.txt >@@ -1,4 +1,4 @@ > >-FAIL Test that calling OffscreenCanvas's commit pushes its contents to its placeholder. placeholder.transferControlToOffscreen is not a function. (In 'placeholder.transferControlToOffscreen()', 'placeholder.transferControlToOffscreen' is undefined) >+PASS Test that calling OffscreenCanvas's commit pushes its contents to its placeholder. > PASS Test that calling commit on an OffscreenCanvas that is not transferred from a HTMLCanvasElement throws an exception in a worker. > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.getcontext-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.getcontext-expected.txt >index bd9aa0e1677e949480b223312238f47099ef1377..c57a293ec4a9bd68c6d91f9abc82554c4df88f6a 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.getcontext-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.getcontext-expected.txt >@@ -1,7 +1,7 @@ > > PASS Test that getContext with un-supported string throws a TypeError. > FAIL Test that getContext with supported string returns correct results Argument 1 ('contextType') to OffscreenCanvas.getContext must be one of: "2d", "webgl" >-FAIL Test that getContext twice with different context type returns null the second time The object is in an invalid state. >+PASS Test that getContext twice with different context type returns null the second time > PASS Test that 2dcontext.canvas should return the original OffscreenCanvas > PASS Test that webglcontext.canvas should return the original OffscreenCanvas > FAIL Test that OffscreenCanvasRenderingContext2D with alpha disabled makes the OffscreenCanvas opaque assert_approx_equals: Green channel of the pixel at (5, 5) expected 127 +/- 2 but got 255 >diff --git a/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.getcontext.worker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.getcontext.worker-expected.txt >index f224ce74eea878cf76a1333bcae1baa10fd4f667..39fc2cf9aadde7f2db1b3e2e33689ed707178ca1 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.getcontext.worker-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.getcontext.worker-expected.txt >@@ -1,7 +1,7 @@ > > PASS Test that getContext with un-supported string throws a TypeError. >-FAIL Test that getContext with supported string returns correct results Can't find variable: OffscreenCanvasRenderingContext2D >-FAIL Test that getContext twice with different context type returns null the second time The object is in an invalid state. >+FAIL Test that getContext with supported string returns correct results Can't find variable: WebGLRenderingContext >+PASS Test that getContext twice with different context type returns null the second time > PASS Test that 2dcontext.canvas should return the original OffscreenCanvas > PASS Test that webglcontext.canvas should return the original OffscreenCanvas > FAIL Test that OffscreenCanvasRenderingContext2D with alpha disabled makes the OffscreenCanvas opaque assert_approx_equals: Green channel of the pixel at (5, 5) expected 127 +/- 2 but got 255 >diff --git a/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.resize-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.resize-expected.txt >index f45507172b76baf06ab0e44ed15ce3306ad4818a..6c11c8df4b65a7900addc746aa9a0ee77941861e 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.resize-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.resize-expected.txt >@@ -2,11 +2,11 @@ > PASS Verify that writing to the width and height attributes of an OffscreenCanvas works when there is no context attached. > PASS Verify that writing to the width and height attributes of an OffscreenCanvas works when there is a 2d context attached. > PASS Verify that writing to the width and height attributes of an OffscreenCanvas works when there is a webgl context attached. >-FAIL Verify that writing to the width or height attribute of a placeholder canvas throws an exception placeholder.transferControlToOffscreen is not a function. (In 'placeholder.transferControlToOffscreen()', 'placeholder.transferControlToOffscreen' is undefined) >-FAIL Verify that writing to the width or height attribute of a placeholder canvas throws an exception even when not changing the value of the attribute. placeholder.transferControlToOffscreen is not a function. (In 'placeholder.transferControlToOffscreen()', 'placeholder.transferControlToOffscreen' is undefined) >+PASS Verify that writing to the width or height attribute of a placeholder canvas throws an exception >+PASS Verify that writing to the width or height attribute of a placeholder canvas throws an exception even when not changing the value of the attribute. > PASS Verify that resizing a 2d context resets its state. > PASS Verify that setting the size of a 2d context to the same size it already had resets its state. >-FAIL Verify that resizing an OffscreenCanvas with a 2d context propagates the new size to its placeholder canvas asynchronously. placeholder.transferControlToOffscreen is not a function. (In 'placeholder.transferControlToOffscreen()', 'placeholder.transferControlToOffscreen' is undefined) >-FAIL Verify that resizing an OffscreenCanvas with a webgl context propagates the new size to its placeholder canvas asynchronously. placeholder.transferControlToOffscreen is not a function. (In 'placeholder.transferControlToOffscreen()', 'placeholder.transferControlToOffscreen' is undefined) >-FAIL Verify that drawImage uses the size of the frame as the intinsic size of a placeholder canvas. placeholder.transferControlToOffscreen is not a function. (In 'placeholder.transferControlToOffscreen()', 'placeholder.transferControlToOffscreen' is undefined) >+PASS Verify that resizing an OffscreenCanvas with a 2d context propagates the new size to its placeholder canvas asynchronously. >+PASS Verify that resizing an OffscreenCanvas with a webgl context propagates the new size to its placeholder canvas asynchronously. >+PASS Verify that drawImage uses the size of the frame as the intinsic size of a placeholder canvas. > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.transfercontrol.to.offscreen-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.transfercontrol.to.offscreen-expected.txt >index 4f42e507428280a2ea19f763cf8c9619ae5bb305..2960485b7b6ad6f7062def9fe7b79e5cb74b83be 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.transfercontrol.to.offscreen-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.transfercontrol.to.offscreen-expected.txt >@@ -1,5 +1,5 @@ > >-FAIL Test that an OffscreenCanvas generated by transferControlToOffscreen gets correct width and height placeholder.transferControlToOffscreen is not a function. (In 'placeholder.transferControlToOffscreen()', 'placeholder.transferControlToOffscreen' is undefined) >-FAIL Test that calling getContext on a placeholder canvas that has already transferred its control throws an exception placeholder.transferControlToOffscreen is not a function. (In 'placeholder.transferControlToOffscreen()', 'placeholder.transferControlToOffscreen' is undefined) >-FAIL Test that calling transferControlToOffscreen twice throws an exception placeholder.transferControlToOffscreen is not a function. (In 'placeholder.transferControlToOffscreen()', 'placeholder.transferControlToOffscreen' is undefined) >+PASS Test that an OffscreenCanvas generated by transferControlToOffscreen gets correct width and height >+PASS Test that calling getContext on a placeholder canvas that has already transferred its control throws an exception >+PASS Test that calling transferControlToOffscreen twice throws an exception > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.transfercontrol.to.offscreen.w-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.transfercontrol.to.offscreen.w-expected.txt >index 2cd3db4b276dc1c11d1ecdb048b3b79093eee0da..33b8532cb2e00414a6d54a6da79ae76eaf46563f 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.transfercontrol.to.offscreen.w-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.transfercontrol.to.offscreen.w-expected.txt >@@ -1,5 +1,5 @@ > >-FAIL Test that an OffscreenCanvas generated by transferControlToOffscreen gets correct width and height when it is transferred to a worker placeholder.transferControlToOffscreen is not a function. (In 'placeholder.transferControlToOffscreen()', 'placeholder.transferControlToOffscreen' is undefined) >-FAIL Test that calling getContext on a placeholder canvas that is transferred its control to an OffscreenCanvas throws an exception, when the OffscreenCanvas is transferred to a worker placeholder.transferControlToOffscreen is not a function. (In 'placeholder.transferControlToOffscreen()', 'placeholder.transferControlToOffscreen' is undefined) >-FAIL Test that calling transferControlToOffscreen twice throws an exception, when its associated OffscreenCanvas is transferred to a worker placeholder.transferControlToOffscreen is not a function. (In 'placeholder.transferControlToOffscreen()', 'placeholder.transferControlToOffscreen' is undefined) >+PASS Test that an OffscreenCanvas generated by transferControlToOffscreen gets correct width and height when it is transferred to a worker >+PASS Test that calling getContext on a placeholder canvas that is transferred its control to an OffscreenCanvas throws an exception, when the OffscreenCanvas is transferred to a worker >+PASS Test that calling transferControlToOffscreen twice throws an exception, when its associated OffscreenCanvas is transferred to a worker >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 202797
:
380645
|
390644
|
395065
|
395157
|
395666
|
397666
|
397669
|
397677
|
397691
|
397702
|
397814
|
398046
|
398054
|
406369
|
406451