Title: [294179] trunk
Revision
294179
Author
wenson_hs...@apple.com
Date
2022-05-13 15:20:39 -0700 (Fri, 13 May 2022)

Log Message

ImageAnalysisQueue should reanalyze image elements whose image sources have changed
https://bugs.webkit.org/show_bug.cgi?id=240371
rdar://93175651

Reviewed by Tim Horton.

Currently, ImageAnalysisQueue maintains the set of all image elements that have been queued for analysis, and
avoids re-queueing such image elements. However, on some websites, this leads to stale analysis results being
shown in certain image elements that have changed image sources (and subsequently finished loaded the new image).
To address this, we introduce a mechanism to remember the latest image URL for image elements that have been
analyzed using the analysis queue; we only avoid reanalyzing these same image elements if the source URL is the
same as the source URL when we last analyzed it.

This allows us (for instance) to handle the scenario where a single image element periodically cycles between
different `src` attribute values.

Test: ImageAnalysisTests.AnalyzeImageAfterChangingSource

* page/ImageAnalysisQueue.cpp:
(WebCore::ImageAnalysisQueue::enqueueIfNeeded):

Also avoid trying to prematurely analyze images whose cached images only contain the null image. This caused
empty results to sometimes be incorrectly cached for some image elements, if analysis is triggered too early.

(WebCore::ImageAnalysisQueue::resumeProcessing):
* page/ImageAnalysisQueue.h:

To aid with debugging similar issues in the future, plumb the image URL through to
`requestImageAnalysisWithIdentifier`, which (if an engineering default is specified) will additionally reveal
the URL in system logs.

* Platform/cocoa/ImageAnalysisUtilities.h:
* UIProcess/Cocoa/WebViewImpl.mm:
(WebKit::WebViewImpl::requestTextRecognition):
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView requestTextRecognition:imageData:identifier:completionHandler:]):

Add an API test to exercise the scenario by verifying that the same image element is reanalyzed after setting
the `src` to a different image URL.

* TestWebKitAPI/Tests/WebKitCocoa/ImageAnalysisTests.mm:
(TestWebKitAPI::TEST):

Canonical link: https://commits.webkit.org/250546@main

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (294178 => 294179)


--- trunk/Source/WebCore/ChangeLog	2022-05-13 22:11:26 UTC (rev 294178)
+++ trunk/Source/WebCore/ChangeLog	2022-05-13 22:20:39 UTC (rev 294179)
@@ -1,3 +1,32 @@
+2022-05-13  Wenson Hsieh  <wenson_hs...@apple.com>
+
+        ImageAnalysisQueue should reanalyze image elements whose image sources have changed
+        https://bugs.webkit.org/show_bug.cgi?id=240371
+        rdar://93175651
+
+        Reviewed by Tim Horton.
+
+        Currently, ImageAnalysisQueue maintains the set of all image elements that have been queued for analysis, and
+        avoids re-queueing such image elements. However, on some websites, this leads to stale analysis results being
+        shown in certain image elements that have changed image sources (and subsequently finished loaded the new image).
+        To address this, we introduce a mechanism to remember the latest image URL for image elements that have been
+        analyzed using the analysis queue; we only avoid reanalyzing these same image elements if the source URL is the
+        same as the source URL when we last analyzed it.
+
+        This allows us (for instance) to handle the scenario where a single image element periodically cycles between
+        different `src` attribute values.
+
+        Test: ImageAnalysisTests.AnalyzeImageAfterChangingSource
+
+        * page/ImageAnalysisQueue.cpp:
+        (WebCore::ImageAnalysisQueue::enqueueIfNeeded):
+
+        Also avoid trying to prematurely analyze images whose cached images only contain the null image. This caused
+        empty results to sometimes be incorrectly cached for some image elements, if analysis is triggered too early.
+
+        (WebCore::ImageAnalysisQueue::resumeProcessing):
+        * page/ImageAnalysisQueue.h:
+
 2022-05-13  Adrian Perez de Castro  <ape...@igalia.com>
 
         Non-unified build broken in debug mode

Modified: trunk/Source/WebCore/page/ImageAnalysisQueue.cpp (294178 => 294179)


--- trunk/Source/WebCore/page/ImageAnalysisQueue.cpp	2022-05-13 22:11:26 UTC (rev 294178)
+++ trunk/Source/WebCore/page/ImageAnalysisQueue.cpp	2022-05-13 22:20:39 UTC (rev 294179)
@@ -64,10 +64,35 @@
     if (!cachedImage || cachedImage->errorOccurred())
         return;
 
+    auto* image = cachedImage->image();
+    if (!image || image->isNull())
+        return;
+
     if (renderer.size().width() < minimumWidthForAnalysis || renderer.size().height() < minimumHeightForAnalysis)
         return;
 
-    if (!m_queuedElements.add(element).isNewEntry)
+    bool shouldAddToQueue = [&] {
+        auto url = ""
+        auto iterator = m_queuedElements.find(element);
+        if (iterator == m_queuedElements.end()) {
+            m_queuedElements.add(element, url);
+            return true;
+        }
+
+        if (iterator->value == url)
+            return false;
+
+        iterator->value = url;
+
+        for (auto& entry : m_queue) {
+            if (entry.element == &element)
+                return false;
+        }
+
+        return true;
+    }();
+
+    if (!shouldAddToQueue)
         return;
 
     Ref view = renderer.view().frameView();
@@ -123,6 +148,10 @@
 
         m_pendingRequestCount++;
         m_page->resetTextRecognitionResult(*element);
+
+        if (auto* image = element->cachedImage(); image && !image->errorOccurred())
+            m_queuedElements.set(*element, image->url());
+
         auto allowSnapshots = m_identifier.isEmpty() ? TextRecognitionOptions::AllowSnapshots::Yes : TextRecognitionOptions::AllowSnapshots::No;
         m_page->chrome().client().requestTextRecognition(*element, { m_identifier, allowSnapshots }, [this, page = m_page] (auto&&) {
             if (!page || page->imageAnalysisQueueIfExists() != this)

Modified: trunk/Source/WebCore/page/ImageAnalysisQueue.h (294178 => 294179)


--- trunk/Source/WebCore/page/ImageAnalysisQueue.h	2022-05-13 22:11:26 UTC (rev 294178)
+++ trunk/Source/WebCore/page/ImageAnalysisQueue.h	2022-05-13 22:20:39 UTC (rev 294179)
@@ -29,7 +29,8 @@
 
 #include <wtf/FastMalloc.h>
 #include <wtf/PriorityQueue.h>
-#include <wtf/WeakHashSet.h>
+#include <wtf/URL.h>
+#include <wtf/WeakHashMap.h>
 #include <wtf/WeakPtr.h>
 
 namespace WebCore {
@@ -69,7 +70,7 @@
     String m_identifier;
     WeakPtr<Page> m_page;
     Timer m_resumeProcessingTimer;
-    WeakHashSet<HTMLImageElement> m_queuedElements;
+    WeakHashMap<HTMLImageElement, URL> m_queuedElements;
     PriorityQueue<Task, firstIsHigherPriority> m_queue;
     unsigned m_pendingRequestCount { 0 };
     unsigned m_currentTaskNumber { 0 };

Modified: trunk/Source/WebKit/ChangeLog (294178 => 294179)


--- trunk/Source/WebKit/ChangeLog	2022-05-13 22:11:26 UTC (rev 294178)
+++ trunk/Source/WebKit/ChangeLog	2022-05-13 22:20:39 UTC (rev 294179)
@@ -1,3 +1,21 @@
+2022-05-13  Wenson Hsieh  <wenson_hs...@apple.com>
+
+        ImageAnalysisQueue should reanalyze image elements whose image sources have changed
+        https://bugs.webkit.org/show_bug.cgi?id=240371
+        rdar://93175651
+
+        Reviewed by Tim Horton.
+
+        To aid with debugging similar issues in the future, plumb the image URL through to
+        `requestImageAnalysisWithIdentifier`, which (if an engineering default is specified) will additionally reveal
+        the URL in system logs.
+
+        * Platform/cocoa/ImageAnalysisUtilities.h:
+        * UIProcess/Cocoa/WebViewImpl.mm:
+        (WebKit::WebViewImpl::requestTextRecognition):
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView requestTextRecognition:imageData:identifier:completionHandler:]):
+
 2022-05-13  Aditya Keerthi  <akeer...@apple.com>
 
         [iOS] Multiple visible find highlights when searching for text after beginning a "find from selection"

Modified: trunk/Source/WebKit/Platform/cocoa/ImageAnalysisUtilities.h (294178 => 294179)


--- trunk/Source/WebKit/Platform/cocoa/ImageAnalysisUtilities.h	2022-05-13 22:11:26 UTC (rev 294178)
+++ trunk/Source/WebKit/Platform/cocoa/ImageAnalysisUtilities.h	2022-05-13 22:20:39 UTC (rev 294179)
@@ -60,7 +60,7 @@
 RetainPtr<CocoaImageAnalyzerRequest> createImageAnalyzerRequest(CGImageRef, VKAnalysisTypes);
 
 #if ENABLE(IMAGE_ANALYSIS_ENHANCEMENTS)
-void requestImageAnalysisWithIdentifier(CocoaImageAnalyzer *, const String& identifier, CGImageRef, CompletionHandler<void(WebCore::TextRecognitionResult&&)>&&);
+void requestImageAnalysisWithIdentifier(CocoaImageAnalyzer *, NSURL *, const String& identifier, CGImageRef, CompletionHandler<void(WebCore::TextRecognitionResult&&)>&&);
 void requestImageAnalysisMarkup(CGImageRef, CompletionHandler<void(CGImageRef, CGRect)>&&);
 
 std::pair<RetainPtr<NSData>, RetainPtr<CFStringRef>> imageDataForCroppedImageResult(CGImageRef, const String& sourceMIMEType);

Modified: trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm (294178 => 294179)


--- trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm	2022-05-13 22:11:26 UTC (rev 294178)
+++ trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm	2022-05-13 22:20:39 UTC (rev 294179)
@@ -266,7 +266,7 @@
 
 #if ENABLE(IMAGE_ANALYSIS_ENHANCEMENTS)
     if (!identifier.isEmpty())
-        return requestImageAnalysisWithIdentifier(ensureImageAnalyzer(), identifier, cgImage.get(), WTFMove(completion));
+        return requestImageAnalysisWithIdentifier(ensureImageAnalyzer(), imageURL, identifier, cgImage.get(), WTFMove(completion));
 #else
     UNUSED_PARAM(identifier);
 #endif

Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (294178 => 294179)


--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2022-05-13 22:11:26 UTC (rev 294178)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2022-05-13 22:20:39 UTC (rev 294179)
@@ -10825,7 +10825,7 @@
 
 #if ENABLE(IMAGE_ANALYSIS_ENHANCEMENTS)
     if (identifier.length)
-        return WebKit::requestImageAnalysisWithIdentifier(self.imageAnalyzer, identifier, cgImage.get(), WTFMove(completion));
+        return WebKit::requestImageAnalysisWithIdentifier(self.imageAnalyzer, imageURL, identifier, cgImage.get(), WTFMove(completion));
 #else
     UNUSED_PARAM(identifier);
 #endif

Modified: trunk/Tools/ChangeLog (294178 => 294179)


--- trunk/Tools/ChangeLog	2022-05-13 22:11:26 UTC (rev 294178)
+++ trunk/Tools/ChangeLog	2022-05-13 22:20:39 UTC (rev 294179)
@@ -1,3 +1,17 @@
+2022-05-13  Wenson Hsieh  <wenson_hs...@apple.com>
+
+        ImageAnalysisQueue should reanalyze image elements whose image sources have changed
+        https://bugs.webkit.org/show_bug.cgi?id=240371
+        rdar://93175651
+
+        Reviewed by Tim Horton.
+
+        Add an API test to exercise the scenario by verifying that the same image element is reanalyzed after setting
+        the `src` to a different image URL.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/ImageAnalysisTests.mm:
+        (TestWebKitAPI::TEST):
+
 2022-05-13  Alex Christensen  <achristen...@webkit.org>
 
         Disable MediaLoading.CaptivePortalHLS API test

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ImageAnalysisTests.mm (294178 => 294179)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ImageAnalysisTests.mm	2022-05-13 22:11:26 UTC (rev 294178)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ImageAnalysisTests.mm	2022-05-13 22:20:39 UTC (rev 294179)
@@ -272,6 +272,19 @@
     [webView waitForImageAnalysisRequests:10];
 }
 
+TEST(ImageAnalysisTests, AnalyzeImageAfterChangingSource)
+{
+    auto requestSwizzler = makeImageAnalysisRequestSwizzler(processRequestWithResults);
+
+    auto webView = createWebViewWithTextRecognitionEnhancements();
+    [webView synchronouslyLoadTestPageNamed:@"image"];
+    [webView _startImageAnalysis:nil];
+    [webView waitForImageAnalysisRequests:1];
+
+    [webView objectByEvaluatingJavaScript:@"document.querySelector('img').src = ''"];
+    [webView waitForImageAnalysisRequests:2];
+}
+
 TEST(ImageAnalysisTests, AnalyzeDynamicallyLoadedImages)
 {
     auto requestSwizzler = makeImageAnalysisRequestSwizzler(processRequestWithResults);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to