WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
NEW
178039
HTMLImageElement.decode() should optimize the decoding for the image explicit size
https://bugs.webkit.org/show_bug.cgi?id=178039
Summary
HTMLImageElement.decode() should optimize the decoding for the image explicit...
Said Abou-Hallawa
Reported
2017-10-06 18:05:01 PDT
If the HTMLImageElement has an intrinsic size, the decode() method should use it instead of decoding the image for the native size. The intrinsic size of an HTMLImageElement can be set to the width and the height attributes of the <img> element. Example is: <img width="200" height="100> Or it can be set from the javascript. Example is: var image = new Image(200, 100); If the intrinsic size is used, decoding the image and drawing it will be much faster than using the native size. This is because a large image will not be scaled down when it is drawn into a smaller rectangle.
Attachments
Patch
(15.51 KB, patch)
2017-10-06 18:16 PDT
,
Said Abou-Hallawa
no flags
Details
Formatted Diff
Diff
Archive of layout-test-results from ews101 for mac-elcapitan
(1.30 MB, application/zip)
2017-10-06 19:56 PDT
,
Build Bot
no flags
Details
Archive of layout-test-results from ews124 for ios-simulator-wk2
(7.06 MB, application/zip)
2017-10-06 19:59 PDT
,
Build Bot
no flags
Details
Archive of layout-test-results from ews107 for mac-elcapitan-wk2
(1.19 MB, application/zip)
2017-10-06 20:22 PDT
,
Build Bot
no flags
Details
Archive of layout-test-results from ews115 for mac-elcapitan
(1.93 MB, application/zip)
2017-10-07 05:41 PDT
,
Build Bot
no flags
Details
Patch
(17.47 KB, patch)
2017-10-08 22:05 PDT
,
Said Abou-Hallawa
no flags
Details
Formatted Diff
Diff
Patch
(19.26 KB, patch)
2017-10-09 11:37 PDT
,
Said Abou-Hallawa
no flags
Details
Formatted Diff
Diff
Patch
(21.57 KB, patch)
2017-10-24 16:55 PDT
,
Said Abou-Hallawa
no flags
Details
Formatted Diff
Diff
Patch
(22.60 KB, patch)
2017-10-25 19:43 PDT
,
Said Abou-Hallawa
no flags
Details
Formatted Diff
Diff
Patch
(22.60 KB, patch)
2017-10-25 19:56 PDT
,
Said Abou-Hallawa
no flags
Details
Formatted Diff
Diff
Patch
(22.60 KB, patch)
2017-10-26 10:43 PDT
,
Said Abou-Hallawa
no flags
Details
Formatted Diff
Diff
Archive of layout-test-results from ews105 for mac-elcapitan-wk2
(1.46 MB, application/zip)
2017-10-26 12:50 PDT
,
Build Bot
no flags
Details
Patch
(26.41 KB, patch)
2017-10-26 15:44 PDT
,
Said Abou-Hallawa
no flags
Details
Formatted Diff
Diff
Patch
(26.43 KB, patch)
2017-10-26 15:59 PDT
,
Said Abou-Hallawa
no flags
Details
Formatted Diff
Diff
Patch
(26.34 KB, patch)
2017-10-26 18:39 PDT
,
Said Abou-Hallawa
no flags
Details
Formatted Diff
Diff
Patch
(26.35 KB, patch)
2017-10-27 10:05 PDT
,
Said Abou-Hallawa
no flags
Details
Formatted Diff
Diff
Patch
(26.67 KB, patch)
2017-11-01 15:23 PDT
,
Said Abou-Hallawa
mjs
: review-
Details
Formatted Diff
Diff
Show Obsolete
(16)
View All
Add attachment
proposed patch, testcase, etc.
Said Abou-Hallawa
Comment 1
2017-10-06 18:16:09 PDT
Created
attachment 323074
[details]
Patch
Build Bot
Comment 2
2017-10-06 19:56:35 PDT
Comment on
attachment 323074
[details]
Patch
Attachment 323074
[details]
did not pass mac-ews (mac): Output:
http://webkit-queues.webkit.org/results/4787123
New failing tests: fast/images/decode-animated-image.html fast/images/decode-render-animated-image.html
Build Bot
Comment 3
2017-10-06 19:56:36 PDT
Created
attachment 323078
[details]
Archive of layout-test-results from ews101 for mac-elcapitan The attached test failures were seen while running run-webkit-tests on the mac-ews. Bot: ews101 Port: mac-elcapitan Platform: Mac OS X 10.11.6
Build Bot
Comment 4
2017-10-06 19:59:29 PDT
Comment on
attachment 323074
[details]
Patch
Attachment 323074
[details]
did not pass ios-sim-ews (ios-simulator-wk2): Output:
http://webkit-queues.webkit.org/results/4787039
New failing tests: fast/images/decode-animated-image.html fast/images/decode-render-animated-image.html
Build Bot
Comment 5
2017-10-06 19:59:31 PDT
Created
attachment 323079
[details]
Archive of layout-test-results from ews124 for ios-simulator-wk2 The attached test failures were seen while running run-webkit-tests on the ios-sim-ews. Bot: ews124 Port: ios-simulator-wk2 Platform: Mac OS X 10.12.6
Build Bot
Comment 6
2017-10-06 20:22:00 PDT
Comment on
attachment 323074
[details]
Patch
Attachment 323074
[details]
did not pass mac-wk2-ews (mac-wk2): Output:
http://webkit-queues.webkit.org/results/4787204
New failing tests: fast/images/decode-animated-image.html fast/images/decode-render-animated-image.html
Build Bot
Comment 7
2017-10-06 20:22:02 PDT
Created
attachment 323081
[details]
Archive of layout-test-results from ews107 for mac-elcapitan-wk2 The attached test failures were seen while running run-webkit-tests on the mac-wk2-ews. Bot: ews107 Port: mac-elcapitan-wk2 Platform: Mac OS X 10.11.6
Build Bot
Comment 8
2017-10-07 05:41:38 PDT
Comment on
attachment 323074
[details]
Patch
Attachment 323074
[details]
did not pass mac-debug-ews (mac): Output:
http://webkit-queues.webkit.org/results/4788850
New failing tests: fast/images/decode-animated-image.html fast/images/decode-render-animated-image.html
Build Bot
Comment 9
2017-10-07 05:41:39 PDT
Created
attachment 323096
[details]
Archive of layout-test-results from ews115 for mac-elcapitan The attached test failures were seen while running run-webkit-tests on the mac-debug-ews. Bot: ews115 Port: mac-elcapitan Platform: Mac OS X 10.11.6
Said Abou-Hallawa
Comment 10
2017-10-08 22:05:46 PDT
Created
attachment 323158
[details]
Patch
Said Abou-Hallawa
Comment 11
2017-10-09 11:37:20 PDT
Created
attachment 323192
[details]
Patch
Said Abou-Hallawa
Comment 12
2017-10-24 16:55:47 PDT
Created
attachment 324757
[details]
Patch
Simon Fraser (smfr)
Comment 13
2017-10-25 14:59:16 PDT
Comment on
attachment 324757
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=324757&action=review
> Source/WebCore/html/HTMLImageElement.cpp:440 > + return std::nullopt;
I think this can be 'return { }'
> Source/WebCore/html/HTMLImageElement.cpp:447 > + return std::nullopt;
Ditto.
> Source/WebCore/html/HTMLImageElement.h:53 > + std::optional<unsigned> intrinsicWidth() const; > + std::optional<unsigned> intrinsicHeight() const;
I'm not super keen on the names of these functions because "intrinsic size" has a specific meaning in CSS, and this isn't the same; all it does is read the attribute if present. Maybe this is more like "explicitWidth" or "widthFromAttribute"?
> Source/WebCore/platform/graphics/BitmapImage.cpp:516 > + // Animated images should be decoded with the native size always.
Comment should say why.
> Source/WebCore/platform/graphics/BitmapImage.cpp:543 > + Vector<size_t> itemsToBeDeleted;
This is a vector of indexes, not of items (or requests).
> Source/WebCore/platform/graphics/BitmapImage.cpp:544 > + for (auto it = m_decodingRequests->begin(); it != m_decodingRequests->end(); ++it) {
Use a modern C++ loop: for (auto request : *m_decodingRequests) ?
> Source/WebCore/platform/graphics/BitmapImage.cpp:549 > + it->callback();
What if the callback modifies m_decodingRequests? I think you should copy m_decodingRequests before iterating it.
> Source/WebCore/platform/graphics/BitmapImage.cpp:562 > + m_decodingRequests->remove(itemsToBeDeleted.takeLast());
Is this removing by index or by item? Confused.
Said Abou-Hallawa
Comment 14
2017-10-25 19:43:46 PDT
Created
attachment 324945
[details]
Patch
Tim Horton
Comment 15
2017-10-25 19:54:01 PDT
Isn’t the wording here wrong? You’re now deciding at the target resolution, explicitly NOT the intrinsic size of the image.
Said Abou-Hallawa
Comment 16
2017-10-25 19:54:12 PDT
Comment on
attachment 324757
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=324757&action=review
>> Source/WebCore/html/HTMLImageElement.cpp:440 >> + return std::nullopt; > > I think this can be 'return { }'
Done.
>> Source/WebCore/html/HTMLImageElement.cpp:447 >> + return std::nullopt; > > Ditto.
Done.
>> Source/WebCore/html/HTMLImageElement.h:53 >> + std::optional<unsigned> intrinsicHeight() const; > > I'm not super keen on the names of these functions because "intrinsic size" has a specific meaning in CSS, and this isn't the same; all it does is read the attribute if present. Maybe this is more like "explicitWidth" or "widthFromAttribute"?
Names were changed to explicitWidth() and explicitHeight().
>> Source/WebCore/platform/graphics/BitmapImage.cpp:516 >> + // Animated images should be decoded with the native size always. > > Comment should say why.
The comment was changed.
>> Source/WebCore/platform/graphics/BitmapImage.cpp:543 >> + Vector<size_t> itemsToBeDeleted; > > This is a vector of indexes, not of items (or requests).
The name of vector was renamed to indicesOfItemsToBeDeleted.
>> Source/WebCore/platform/graphics/BitmapImage.cpp:544 >> + for (auto it = m_decodingRequests->begin(); it != m_decodingRequests->end(); ++it) { > > Use a modern C++ loop: for (auto request : *m_decodingRequests) ?
Done. I used the classic for-loop because I wanted to calculate the index of the element = it - m_decodingRequests->begin(). I now calculate the index of the element = &request - &m_decodingRequests->first().
>> Source/WebCore/platform/graphics/BitmapImage.cpp:549 >> + it->callback(); > > What if the callback modifies m_decodingRequests? I think you should copy m_decodingRequests before iterating it.
There is only caller for the decode() method which is ImageLoader::decode(). The ImageLoader passes a callback which resolves a promise. Resolving the promise can't result in reentering BitmapImage::decode(). Drain asked this question before and I answered it in
https://bugs.webkit.org/show_bug.cgi?id=176732#c5
.
>> Source/WebCore/platform/graphics/BitmapImage.cpp:562 >> + m_decodingRequests->remove(itemsToBeDeleted.takeLast()); > > Is this removing by index or by item? Confused.
Name of the vector was changed to indicesOfItemsToBeDeleted.
Tim Horton
Comment 17
2017-10-25 19:55:21 PDT
(In reply to Tim Horton from
comment #15
)
> Isn’t the wording here wrong? You’re now deciding at the target resolution, > explicitly NOT the intrinsic size of the image.
Deciding=decoding, and I see smfr raised the same complaint. Bug title is still wrong, though.
Said Abou-Hallawa
Comment 18
2017-10-25 19:56:56 PDT
Created
attachment 324946
[details]
Patch
Said Abou-Hallawa
Comment 19
2017-10-26 10:43:31 PDT
Created
attachment 325028
[details]
Patch
Simon Fraser (smfr)
Comment 20
2017-10-26 10:45:38 PDT
Comment on
attachment 324946
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=324946&action=review
Can we test this change?
> Source/WebCore/platform/graphics/BitmapImage.cpp:554 > + for (const auto& request : *m_decodingRequests) { > + if (!frameHasDecodedNativeImageCompatibleWithOptionsAtIndex(m_currentFrame, m_currentSubsamplingLevel, request.sizeForDrawing)) > + continue; > + > + // Call the request callback and mark this request for deletion. > + request.callback(); > + indicesOfItemsToBeDeleted.append(&request - &m_decodingRequests->first());
Since you're getting the index here, the loop would be much cleaner as just for (size_t i = 0; i < m_decodingRequests.size(); ++i) You say that calling the callback while traversing m_decodingRequests is safe because promise resolution isn't synchronous. However, this doesn't protect us against our own coding mistakes in C++ where we later change our code to modify m_decodingRequests inside the callback. I think you should copy the vector.
> Source/WebCore/platform/graphics/BitmapImage.cpp:566 > + while (!indicesOfItemsToBeDeleted.isEmpty()) > + m_decodingRequests->remove(indicesOfItemsToBeDeleted.takeLast());
Why bother to mutate (indicesOfItemsToBeDeleted? Just run through the list.
> Source/WebCore/platform/graphics/BitmapImage.h:175 > + bool hasStartedAnimating() const { return bool(m_desiredFrameStartTime); }
I would find m_desiredFrameStartTime != 0 more readable.
Build Bot
Comment 21
2017-10-26 12:50:48 PDT
Comment on
attachment 325028
[details]
Patch
Attachment 325028
[details]
did not pass mac-wk2-ews (mac-wk2): Output:
http://webkit-queues.webkit.org/results/5001405
New failing tests: fast/xsl/xslt-enc.xml
Build Bot
Comment 22
2017-10-26 12:50:50 PDT
Created
attachment 325043
[details]
Archive of layout-test-results from ews105 for mac-elcapitan-wk2 The attached test failures were seen while running run-webkit-tests on the mac-wk2-ews. Bot: ews105 Port: mac-elcapitan-wk2 Platform: Mac OS X 10.11.6
Said Abou-Hallawa
Comment 23
2017-10-26 15:44:00 PDT
Created
attachment 325065
[details]
Patch
Said Abou-Hallawa
Comment 24
2017-10-26 15:58:12 PDT
Comment on
attachment 324946
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=324946&action=review
>> Source/WebCore/platform/graphics/BitmapImage.cpp:554 >> + indicesOfItemsToBeDeleted.append(&request - &m_decodingRequests->first()); > > Since you're getting the index here, the loop would be much cleaner as just for (size_t i = 0; i < m_decodingRequests.size(); ++i) > > You say that calling the callback while traversing m_decodingRequests is safe because promise resolution isn't synchronous. However, this doesn't protect us against our own coding mistakes in C++ where we later change our code to modify m_decodingRequests inside the callback. I think you should copy the vector.
I changed the for loop as suggested. But I could not copy the Vector m_decodingRequests because the WTF::Function is not copyable. I tried to think of all the cases that can wrong with m_decodingRequests and I realized even using a vector of indices is wrong. If callDecodingCallbacks() is reentrant from callDecodingCallbacks() this will mess up all the indices. I tried to come up with a solution which can stand up against all the bugs which may introduce because of mistakes in our C++ code. Then I felt it's too much complicated for bug that we know for sure it does not exist. Instead I can add assertion that callDecodingCallbacks() is not reentrant from callDecodingCallbacks() decode() is not reentrant from either decode() or callDecodingCallbacks()
>> Source/WebCore/platform/graphics/BitmapImage.cpp:566 >> + m_decodingRequests->remove(indicesOfItemsToBeDeleted.takeLast()); > > Why bother to mutate (indicesOfItemsToBeDeleted? Just run through the list.
Done.
>> Source/WebCore/platform/graphics/BitmapImage.h:175 >> + bool hasStartedAnimating() const { return bool(m_desiredFrameStartTime); } > > I would find m_desiredFrameStartTime != 0 more readable.
Done.
Said Abou-Hallawa
Comment 25
2017-10-26 15:59:37 PDT
Created
attachment 325071
[details]
Patch
Build Bot
Comment 26
2017-10-26 16:02:23 PDT
Attachment 325071
[details]
did not pass style-queue: ERROR: Source/WebCore/platform/graphics/BitmapImage.h:175: Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons. [readability/comparison_to_zero] [5] Total errors found: 1 in 12 files If any of these errors are false positives, please file a bug against check-webkit-style.
Said Abou-Hallawa
Comment 27
2017-10-26 18:39:22 PDT
Created
attachment 325094
[details]
Patch
Said Abou-Hallawa
Comment 28
2017-10-27 10:05:30 PDT
Created
attachment 325171
[details]
Patch
Said Abou-Hallawa
Comment 29
2017-10-27 10:09:10 PDT
Comment on
attachment 324946
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=324946&action=review
>>> Source/WebCore/platform/graphics/BitmapImage.h:175 >>> + bool hasStartedAnimating() const { return bool(m_desiredFrameStartTime); } >> >> I would find m_desiredFrameStartTime != 0 more readable. > > Done.
It has to be m_desiredFrameStartTime != MonotonicTime() because the conversion constructor MonotonicTime(double rawValue) is private.
Said Abou-Hallawa
Comment 30
2017-11-01 15:23:31 PDT
Created
attachment 325640
[details]
Patch
Said Abou-Hallawa
Comment 31
2017-11-01 15:27:56 PDT
(In reply to Said Abou-Hallawa from
comment #30
)
> Created
attachment 325640
[details]
> Patch
Tim suggested a solution for protecting m_decodingRequests while calling the decoding callbacks. We can move m_decodingRequests to a local protectedDecodingRequests. See which ones are compatible with the decoded frame. Call their callbacks. Delete these compatible requests from the local protectedDecodingRequests. Move the rest back to m_decodingRequests once we finish. I implemented this solution in this patch.
Maciej Stachowiak
Comment 32
2020-05-30 19:51:26 PDT
Comment on
attachment 325640
[details]
Patch Unfortunately, this old patch no longer applies.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug