RESOLVED FIXED Bug 201727
ImageDecoders: use a thread safe data buffer for Cairo backing store
https://bugs.webkit.org/show_bug.cgi?id=201727
Summary ImageDecoders: use a thread safe data buffer for Cairo backing store
Charlie Turner
Reported 2019-09-12 11:01:30 PDT
ImageDecoders: use a thread safe data buffer for Cairo backing store
Attachments
Patch (6.87 KB, patch)
2019-09-12 11:10 PDT, Charlie Turner
no flags
Patch for landing (9.19 KB, patch)
2019-10-28 02:16 PDT, Charlie Turner
no flags
Patch for landing (9.19 KB, patch)
2019-10-28 02:16 PDT, Charlie Turner
no flags
Patch for landing (7.08 KB, patch)
2019-10-28 02:17 PDT, Charlie Turner
no flags
Patch (3.32 KB, patch)
2019-10-29 03:38 PDT, Carlos Garcia Campos
Hironori.Fujii: review+
Charlie Turner
Comment 1 2019-09-12 11:10:17 PDT
Charlie Turner
Comment 2 2019-09-16 09:52:05 PDT
This is sometimes crashing in release builds only, i'm starting to suspect the compiler, but in the meantime it's not ready for landing it seems.
Carlos Alberto Lopez Perez
Comment 3 2019-10-23 11:09:27 PDT
This has been here ignored because there isn't any reviewer CC'ed. Next time try to CC any reviewer. You can pass the flag "--suggest-reviewers" to the webkit-patch tool and it will automatically suggest them
Miguel Gomez
Comment 4 2019-10-23 23:51:38 PDT
This totally makes sense. The introduction of async image decoding is what caused buffers to be accessed from different threads (before that everything happened on the main thread). The patch looks good IMO.
Carlos Garcia Campos
Comment 5 2019-10-24 00:10:06 PDT
Comment on attachment 378659 [details] Patch Do we only need the refcounting to be thread safe? or also the data can be accessed from multiple threads? because in that case we would need a lock to protect the pixels, no?
Miguel Gomez
Comment 6 2019-10-24 00:41:54 PDT
(In reply to Carlos Garcia Campos from comment #5) > Comment on attachment 378659 [details] > Patch > > Do we only need the refcounting to be thread safe? or also the data can be > accessed from multiple threads? because in that case we would need a lock to > protect the pixels, no? The buffer is going to be created on the decoding thread and filled there. Once the decoding is finished a repaint is requested and at that point it's when the main thread will start accessing the buffer contents, and the decoding thread shouldn't be accessing it anymore. So I don't think the data can be accessed from both threads at the same time.
Carlos Garcia Campos
Comment 7 2019-10-24 00:53:46 PDT
(In reply to Miguel Gomez from comment #6) > (In reply to Carlos Garcia Campos from comment #5) > > Comment on attachment 378659 [details] > > Patch > > > > Do we only need the refcounting to be thread safe? or also the data can be > > accessed from multiple threads? because in that case we would need a lock to > > protect the pixels, no? > > The buffer is going to be created on the decoding thread and filled there. > Once the decoding is finished a repaint is requested and at that point it's > when the main thread will start accessing the buffer contents, and the > decoding thread shouldn't be accessing it anymore. So I don't think the data > can be accessed from both threads at the same time. Ok, it doesn't matter much because it's a private helper class, but I think I would rename it as RGBAPixelBufferThreadSafeRefCounted to make it clearer.
Carlos Garcia Campos
Comment 8 2019-10-24 00:54:59 PDT
Comment on attachment 378659 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=378659&action=review > Source/WebCore/platform/graphics/ImageBackingStore.h:188 > + class ThreadSafeRGBAPixelBuffer : public ThreadSafeRefCounted<ThreadSafeRGBAPixelBuffer> { As I suggested in the comments I would rename this, because this name is confusing.
Zan Dobersek
Comment 9 2019-10-24 23:29:30 PDT
Comment on attachment 378659 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=378659&action=review > Source/WebCore/platform/graphics/ImageBackingStore.h:199 > + m_isValid = m_pixels.tryReserveCapacity(initialSize.area().unsafeGet()); This operation on Vector, as name suggests, only reserve-expands the capacity -- it doesn't change the size of it. But the zero-fill in zeroPixelData() does fill the Vector's data based on the size, i.e. it zeroes out nothing. An additional Vector<>::resize() call here (if reservation was successful) would avoid that.
Charlie Turner
Comment 10 2019-10-28 02:16:01 PDT
Created attachment 382052 [details] Patch for landing
Charlie Turner
Comment 11 2019-10-28 02:16:43 PDT
Created attachment 382053 [details] Patch for landing
Charlie Turner
Comment 12 2019-10-28 02:17:35 PDT
Created attachment 382054 [details] Patch for landing
WebKit Commit Bot
Comment 13 2019-10-28 03:11:58 PDT
The commit-queue encountered the following flaky tests while processing attachment 382054 [details]: imported/w3c/web-platform-tests/css/css-position/position-absolute-container-dynamic-002.html bug 203473 (author: simon.fraser@apple.com) imported/w3c/web-platform-tests/css/css-position/position-absolute-crash-chrome-005.html bug 203474 (author: simon.fraser@apple.com) imported/w3c/web-platform-tests/html/semantics/scripting-1/the-script-element/module/integrity.html bug 203394 (author: ysuzuki@apple.com) The commit-queue is continuing to process your patch.
WebKit Commit Bot
Comment 14 2019-10-28 03:12:50 PDT
Comment on attachment 382054 [details] Patch for landing Clearing flags on attachment: 382054 Committed r251651: <https://trac.webkit.org/changeset/251651>
WebKit Commit Bot
Comment 15 2019-10-28 03:12:52 PDT
All reviewed patches have been landed. Closing bug.
Radar WebKit Bug Importer
Comment 16 2019-10-28 03:13:17 PDT
Carlos Garcia Campos
Comment 17 2019-10-28 07:58:01 PDT
I had to revert this locally because it's causing crashes here with my riot ephjy web app (I don't know why it doesn't happen with normal ephy). It's crashing when creating the favicon, see: Thread 1 (Thread 0x7fffeaf03cc0 (LWP 2247)): #0 0x00007ffff53b91f0 in WebCore::ImageBackingStore::image() const () from /home/cgarcia/gnome/lib/libwebkit2gtk-4.0.so.37 #1 0x00007ffff53a87b1 in WebCore::ScalableImageDecoder::createFrameImageAtIndex(unsigned long, WebCore::SubsamplingLevel, WebCore::DecodingOptions const&) () from /home/cgarcia/gnome/lib/li--Type <RET> for more, q to quit, c to continue without paging-- bwebkit2gtk-4.0.so.37 #2 0x00007ffff4ce65f3 in WebCore::ImageSource::frameAtIndexCacheIfNeeded(unsigned long, WebCore::ImageFrame::Caching, WTF::Optional<WebCore::SubsamplingLevel> const&) () from /home/cgarcia/gnome/lib/libwebkit2gtk-4.0.so.37 #3 0x00007ffff4ce6830 in WebCore::ImageSource::frameImageAtIndexCacheIfNeeded(unsigned long, WebCore::SubsamplingLevel) () from /home/cgarcia/gnome/lib/libwebkit2gtk-4.0.so.37 #4 0x00007ffff4c87297 in WebCore::BitmapImage::frameImageAtIndexCacheIfNeeded(unsigned long, WebCore::SubsamplingLevel, WebCore::GraphicsContext const*) () from /home/cgarcia/gnome/lib/libwebkit2gtk-4.0.so.37 #5 0x00007ffff4c872f3 in WebCore::BitmapImage::nativeImageForCurrentFrame(WebCore::GraphicsContext const*) () from /home/cgarcia/gnome/lib/libwebkit2gtk-4.0.so.37 #6 0x00007ffff3827d2e in WTF::Detail::CallableWrapper<WebKit::IconDatabase::loadIconForPageURL(WTF::String const&, WebKit::IconDatabase::AllowDatabaseWrite, WTF::CompletionHandler<void (WTF::RefPtr<_cairo_surface, WTF::DumbPtrTraits<_cairo_surface> >&&)>&&)::{lambda()#1}::operator()()::{lambda()#1}, void>::call() () from /home/cgarcia/gnome/lib/libwebkit2gtk-4.0.so.37 #7 0x00007ffff1697f85 in WTF::RunLoop::performWork() () from /home/cgarcia/gnome/lib/libjavascriptcoregtk-4.0.so.18 #8 0x00007ffff16f4a29 in WTF::RunLoop::RunLoop()::{lambda(void*)#1}::_FUN(void*) () from /home/cgarcia/gnome/lib/libjavascriptcoregtk-4.0.so.18 #9 0x00007ffff74a6a1e in g_main_dispatch (context=0x55555567f120) at ../glib/gmain.c:3179 #10 g_main_context_dispatch (context=context@entry=0x55555567f120) at ../glib/gmain.c:3844 #11 0x00007ffff74a6da0 in g_main_context_iterate (context=context@entry=0x55555567f120, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at ../glib/gmain.c:3917 #12 0x00007ffff74a6e2f in g_main_context_iteration (context=context@entry=0x55555567f120, may_block=may_block@entry=1) at ../glib/gmain.c:3978 #13 0x00007ffff76a9a4d in g_application_run (application=0x55555595c2e0, argc=<optimized out>, argv=<optimized out>) at ../gio/gapplication.c:2559 #14 0x0000555555559bf9 in main (argc=1, argv=0x7fffffffd928) at ../src/ephy-main.c:427
Carlos Garcia Campos
Comment 18 2019-10-28 08:01:36 PDT
Bots are also exiting early after r251651 due to crashes, so I'll roll this out.
WebKit Commit Bot
Comment 19 2019-10-28 08:02:31 PDT
Re-opened since this is blocked by bug 203488
Fujii Hironori
Comment 20 2019-10-28 19:27:17 PDT
*** Bug 203546 has been marked as a duplicate of this bug. ***
Carlos Garcia Campos
Comment 21 2019-10-29 03:36:12 PDT
Comment on attachment 382054 [details] Patch for landing View in context: https://bugs.webkit.org/attachment.cgi?id=382054&action=review This patch can be simplified simply using SharedBuffer::DataSegment which is already thread safe ref counted. > Source/WebCore/platform/graphics/ImageBackingStore.h:-205 > - m_pixels = SharedBuffer::create(other.m_pixels->data(), other.m_pixels->size()); > - m_pixelsPtr = reinterpret_cast<RGBA32*>(const_cast<char*>(m_pixels->data())); I think this is the problem, we actually need to copy the data here.
Carlos Garcia Campos
Comment 22 2019-10-29 03:38:02 PDT
Charlie Turner
Comment 23 2019-10-29 08:11:52 PDT
Comment on attachment 382173 [details] Patch It LGTM, I come to same conclusion about the copy ctor and was about to upload :-), but the DataSegment is much nicer, thanks for taking a look!
Carlos Garcia Campos
Comment 24 2019-10-30 00:59:10 PDT
Note You need to log in before you can comment on or make changes to this bug.