[Webkit-unassigned] [Bug 172061] New: Synchronize the call to ImageDecoder::createFrameImageAtIndex() in ImageFrameCache

bugzilla-daemon at webkit.org bugzilla-daemon at webkit.org
Fri May 12 16:46:03 PDT 2017


https://bugs.webkit.org/show_bug.cgi?id=172061

            Bug ID: 172061
           Summary: Synchronize the call to
                    ImageDecoder::createFrameImageAtIndex() in
                    ImageFrameCache
           Product: WebKit
           Version: WebKit Nightly Build
          Hardware: Unspecified
                OS: Unspecified
            Status: NEW
          Severity: Normal
          Priority: P2
         Component: Images
          Assignee: webkit-unassigned at lists.webkit.org
          Reporter: sabouhallawa at apple.com

For BitmapImage, ImageFrameCache is the only caller to ImageDecoder::createFrameImageAtIndex(). One call is made by the decoding thread in ImageFrameCache::startAsyncDecodingQueue(). The other call is made by ImageFrameCache::frameAtIndexCacheIfNeeded() which is called on the main thread.

First, all the image decoders WebKit uses, are not thread-safe. Second, there was not a problem before enabling the async image decoding for large images. An animated image can either be decoded synchronously or asynchronously. There was not conflict between the main thread and the decoding thread trying to decode the same frame or different frame from the same image at the same time. After enabling the asynchronous decoding for large images, we realize that for some cases the image has to be decoded synchronously, e.g drawing on a canvas. That means, if an image is set to be the background of an element but at the same time it's drawn on a canvas. The same image frame may be decoded from the main thread and from the decoding thread. This situation leads to crash in the image decoder when it tries to write to one of its members in two thread. For example, one thread realloc a vector memory and the other thread tries to read it.

Consider the following timeline:

1) BitmapImage::draw(DecodingMode::Asynchronous): 
       1.1) Calls ImageFrameCache::requestFrameAsyncDecodingAtIndex() which appends the requested from to m_frameCommitQueue.
2) DecodingThread in ImageFrameCache::startAsyncDecodingQueue(): 
       2.1) Calls ImageDecoder::createFrameImageAtIndex()
3) ImageSource::clear(): 
       3.1) Calls ImageFrameCache::setDecoder()
           3.1.1) Calls ImageFrameCache::stopAsyncDecodingQueue() which clears m_frameCommitQueue.
4) BitmapImage::draw(DecodingMode::Synchronous):
       4.1) Calls frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex()
           4.1.1) Calls ImageFrameCache::frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex() which returns false because m_frameCommitQueue is empty.
       4.2) Calls frameImageAtIndexCacheIfNeeded()
           4.2.1) Calls ImageFrameCache::frameAtIndexCacheIfNeeded()
               4.2.1.1) Calls ImageDecoder::createFrameImageAtIndex()

If the call 2.1 did not finish before 4.2.1.1 starts the crash will happen.

-- 
You are receiving this mail because:
You are the assignee for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.webkit.org/pipermail/webkit-unassigned/attachments/20170512/0663e84c/attachment.html>


More information about the webkit-unassigned mailing list