Changeset 269046 in webkit
- Timestamp:
- Oct 27, 2020, 10:08:50 AM (6 years ago)
- Location:
- trunk
- Files:
-
- 4 edited
-
LayoutTests/platform/glib/TestExpectations (modified) (1 diff)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/html/OffscreenCanvas.cpp (modified) (5 diffs)
-
Source/WebCore/html/OffscreenCanvas.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/platform/glib/TestExpectations
r269043 r269046 392 392 393 393 webkit.org/b/215462 imported/w3c/web-platform-tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.commit.html [ Failure Pass ] 394 395 # Flaky crash on pushBufferToPlaceholder().396 webkit.org/b/217986 imported/w3c/web-platform-tests/html/canvas/offscreen/line-styles/2d.line.width.transformed.html [ Crash Pass ]397 webkit.org/b/217986 imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.arc.selfintersect.1.worker.html [ Crash Pass ]398 webkit.org/b/217986 imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.arc.selfintersect.1.html [ Crash Pass ]399 394 400 395 #//////////////////////////////////////////////////////////////////////////////////////// -
trunk/Source/WebCore/ChangeLog
r269041 r269046 1 2020-10-27 Chris Lord <clord@igalia.com> 2 3 [GLIB] imported/w3c/web-platform-tests/html/canvas/offscreen/line-styles/2d.line.width.transformed.html is a flaky crash 4 https://bugs.webkit.org/show_bug.cgi?id=217986 5 6 Reviewed by Simon Fraser. 7 8 Fix race condition caused by use of OffscreenCanvas::scriptExecutionContext() on main thread. 9 Instead of passing a reference to the OffscreenCanvas object when dealing with the placeholder 10 canvas on the main thread, encapsulate the necessary data in a separate, ThreadSafeRefCounted 11 object and pass that instead, negating the need to call back to the Worker thread to release 12 the reference. 13 14 Covered by existing tests. 15 16 * html/OffscreenCanvas.cpp: 17 (WebCore::OffscreenCanvas::create): 18 (WebCore::OffscreenCanvas::OffscreenCanvas): 19 (WebCore::OffscreenCanvas::detach): 20 (WebCore::OffscreenCanvas::setPlaceholderCanvas): 21 (WebCore::OffscreenCanvas::pushBufferToPlaceholder): 22 (WebCore::OffscreenCanvas::commitToPlaceholderCanvas): 23 * html/OffscreenCanvas.h: 24 1 25 2020-10-27 Antti Koivisto <antti@apple.com> 2 26 -
trunk/Source/WebCore/html/OffscreenCanvas.cpp
r267735 r269046 86 86 clone->setOriginTainted(); 87 87 88 callOnMainThread([detachedCanvas = WTFMove(detachedCanvas), offscreenCanvas = makeRef(clone.get())] () mutable {89 offscreenCanvas->m_placeholderCanvas = detachedCanvas->takePlaceholderCanvas();90 if ( offscreenCanvas->m_placeholderCanvas) {91 auto& placeholderContext = downcast<PlaceholderRenderingContext>(* offscreenCanvas->m_placeholderCanvas->renderingContext());88 callOnMainThread([detachedCanvas = WTFMove(detachedCanvas), placeholderData = makeRef(*clone->m_placeholderData)] () mutable { 89 placeholderData->canvas = detachedCanvas->takePlaceholderCanvas(); 90 if (placeholderData->canvas) { 91 auto& placeholderContext = downcast<PlaceholderRenderingContext>(*placeholderData->canvas->renderingContext()); 92 92 auto& imageBufferPipe = placeholderContext.imageBufferPipe(); 93 93 if (imageBufferPipe) 94 offscreenCanvas->m_bufferPipeSource = imageBufferPipe->source();94 placeholderData->bufferPipeSource = imageBufferPipe->source(); 95 95 } 96 offscreenCanvas->scriptExecutionContext()->postTask({ ScriptExecutionContext::Task::CleanupTask,97 [releaseOffscreenCanvas = WTFMove(offscreenCanvas)] (ScriptExecutionContext&) { } });98 96 }); 99 97 … … 111 109 : CanvasBase(IntSize(width, height)) 112 110 , ContextDestructionObserver(&context) 111 , m_placeholderData(PlaceholderData::create()) 113 112 { 114 113 } … … 390 389 391 390 auto detached = makeUnique<DetachedOffscreenCanvas>(takeImageBuffer(), size(), originClean()); 392 detached->m_placeholderCanvas = std::exchange(m_placeholder Canvas, nullptr);391 detached->m_placeholderCanvas = std::exchange(m_placeholderData->canvas, nullptr); 393 392 394 393 return detached; … … 399 398 ASSERT(!m_context); 400 399 ASSERT(isMainThread()); 401 m_placeholder Canvas = makeWeakPtr(canvas);400 m_placeholderData->canvas = makeWeakPtr(canvas); 402 401 auto& placeholderContext = downcast<PlaceholderRenderingContext>(*canvas.renderingContext()); 403 402 auto& imageBufferPipe = placeholderContext.imageBufferPipe(); 404 403 if (imageBufferPipe) 405 m_ bufferPipeSource = imageBufferPipe->source();404 m_placeholderData->bufferPipeSource = imageBufferPipe->source(); 406 405 } 407 406 408 407 void OffscreenCanvas::pushBufferToPlaceholder() 409 408 { 410 callOnMainThread([protectedThis = makeRef(*this), this] () mutable { 411 { 412 auto locker = holdLock(m_commitLock); 413 if (m_placeholderCanvas && m_pendingCommitBuffer) 414 m_placeholderCanvas->setImageBufferAndMarkDirty(WTFMove(m_pendingCommitBuffer)); 415 m_pendingCommitBuffer = nullptr; 416 } 417 418 scriptExecutionContext()->postTask({ ScriptExecutionContext::Task::CleanupTask, 419 [releaseThis = WTFMove(protectedThis)] (ScriptExecutionContext&) { } }); 409 callOnMainThread([placeholderData = makeRef(*m_placeholderData)] () mutable { 410 auto locker = holdLock(placeholderData->bufferLock); 411 if (placeholderData->canvas && placeholderData->pendingCommitBuffer) 412 placeholderData->canvas->setImageBufferAndMarkDirty(WTFMove(placeholderData->pendingCommitBuffer)); 413 placeholderData->pendingCommitBuffer = nullptr; 420 414 }); 421 415 } … … 431 425 m_context->paintRenderingResultsToCanvas(); 432 426 433 if (m_ bufferPipeSource) {427 if (m_placeholderData->bufferPipeSource) { 434 428 auto bufferCopy = imageBuffer->copyRectToBuffer(FloatRect(FloatPoint(), imageBuffer->logicalSize()), ColorSpace::SRGB, imageBuffer->context()); 435 429 if (bufferCopy) 436 m_ bufferPipeSource->handle(WTFMove(bufferCopy));437 } 438 439 auto locker = holdLock(m_ commitLock);440 bool shouldPushBuffer = !m_p endingCommitBuffer;441 m_p endingCommitBuffer = imageBuffer->copyRectToBuffer(FloatRect(FloatPoint(), imageBuffer->logicalSize()), ColorSpace::SRGB, imageBuffer->context());442 if (m_p endingCommitBuffer && shouldPushBuffer)430 m_placeholderData->bufferPipeSource->handle(WTFMove(bufferCopy)); 431 } 432 433 auto locker = holdLock(m_placeholderData->bufferLock); 434 bool shouldPushBuffer = !m_placeholderData->pendingCommitBuffer; 435 m_placeholderData->pendingCommitBuffer = imageBuffer->copyRectToBuffer(FloatRect(FloatPoint(), imageBuffer->logicalSize()), ColorSpace::SRGB, imageBuffer->context()); 436 if (m_placeholderData->pendingCommitBuffer && shouldPushBuffer) 443 437 pushBufferToPlaceholder(); 444 438 } -
trunk/Source/WebCore/html/OffscreenCanvas.h
r267735 r269046 40 40 #include <wtf/Forward.h> 41 41 #include <wtf/RefCounted.h> 42 #include <wtf/ThreadSafeRefCounted.h> 42 43 #include <wtf/WeakPtr.h> 43 44 #include <wtf/text/WTFString.h> … … 188 189 189 190 bool m_hasScheduledCommit { false }; 190 WeakPtr<HTMLCanvasElement> m_placeholderCanvas; 191 RefPtr<ImageBufferPipe::Source> m_bufferPipeSource; 192 193 mutable Lock m_commitLock; 194 std::unique_ptr<ImageBuffer> m_pendingCommitBuffer; 191 192 class PlaceholderData : public ThreadSafeRefCounted<PlaceholderData> { 193 public: 194 static Ref<PlaceholderData> create() 195 { 196 return adoptRef(*new PlaceholderData); 197 } 198 199 WeakPtr<HTMLCanvasElement> canvas; 200 RefPtr<ImageBufferPipe::Source> bufferPipeSource; 201 std::unique_ptr<ImageBuffer> pendingCommitBuffer; 202 mutable Lock bufferLock; 203 }; 204 205 RefPtr<PlaceholderData> m_placeholderData; 195 206 }; 196 207
Note:
See TracChangeset
for help on using the changeset viewer.