Title: [288690] trunk
Revision
288690
Author
[email protected]
Date
2022-01-27 11:55:22 -0800 (Thu, 27 Jan 2022)

Log Message

ImageAnalysisQueue should prioritize elements that intersect the visible viewport
https://bugs.webkit.org/show_bug.cgi?id=235664
rdar://88131827

Reviewed by Darin Adler.

Source/WebCore:

Make few adjustments to the image analysis queueing mechanism, such that we prioritize analyzing images that
are in the visible document rect over offscreen images. To do this, we turn the current image element queue into
a PriorityQueue instead, which treats images that are in the visible viewport (at enqueueing time) as higher
priority over images that are not in the visible viewport, and otherwise treats images that were queued earlier
as higher priority in the case where both images are either visible or not visible.

Test: ImageAnalysisTests.ImageAnalysisPrioritizesVisibleImages

* page/ImageAnalysisQueue.cpp:
(WebCore::ImageAnalysisQueue::enqueueIfNeeded):
(WebCore::ImageAnalysisQueue::resumeProcessingSoon):
(WebCore::ImageAnalysisQueue::resumeProcessing):
(WebCore::ImageAnalysisQueue::clear):
* page/ImageAnalysisQueue.h:

Swap out the Deque for a PriorityQueue, and introduce ImageAnalysisQueue::Task to represent an image analysis
task (which can be compared against other tasks to determine priority using `firstIsHigherPriority()` below).

(WebCore::ImageAnalysisQueue::firstIsHigherPriority):

Tools:

Add an API test to verify that batch image analysis prioritizes a visible image over another image that appears
first in DOM traversal order, but is offscreen.

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKitCocoa/ImageAnalysisTests.mm:
(TestWebKitAPI::processedRequests):
(TestWebKitAPI::processRequestWithResults):
(TestWebKitAPI::makeFakeRequest):
(TestWebKitAPI::makeImageAnalysisRequestSwizzler):
(TestWebKitAPI::processRequestWithError):

Additionally add a mechanism for swizzling out VKImageAnalyzerRequest initialization to return a mock object
(TestVKImageAnalyzerRequest) instead, which can then be used to inspect the CGImage that would've been sent for
analysis. See changes in `ImageAnalysisTestingUtilities.*` below for more information.

(TestWebKitAPI::TEST):
* TestWebKitAPI/Tests/WebKitCocoa/offscreen-image.html: Added.
* TestWebKitAPI/cocoa/ImageAnalysisTestingUtilities.h:
* TestWebKitAPI/cocoa/ImageAnalysisTestingUtilities.mm:
(-[TestVKImageAnalyzerRequest initWithCGImage:orientation:requestType:]):
(-[TestVKImageAnalyzerRequest image]):
(-[TestVKImageAnalyzerRequest imageURL]):
(-[TestVKImageAnalyzerRequest setImageURL:]):
(-[TestVKImageAnalyzerRequest pageURL]):
(-[TestVKImageAnalyzerRequest setPageURL:]):
(TestWebKitAPI::createRequest):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (288689 => 288690)


--- trunk/Source/WebCore/ChangeLog	2022-01-27 19:45:03 UTC (rev 288689)
+++ trunk/Source/WebCore/ChangeLog	2022-01-27 19:55:22 UTC (rev 288690)
@@ -1,3 +1,31 @@
+2022-01-27  Wenson Hsieh  <[email protected]>
+
+        ImageAnalysisQueue should prioritize elements that intersect the visible viewport
+        https://bugs.webkit.org/show_bug.cgi?id=235664
+        rdar://88131827
+
+        Reviewed by Darin Adler.
+
+        Make few adjustments to the image analysis queueing mechanism, such that we prioritize analyzing images that
+        are in the visible document rect over offscreen images. To do this, we turn the current image element queue into
+        a PriorityQueue instead, which treats images that are in the visible viewport (at enqueueing time) as higher
+        priority over images that are not in the visible viewport, and otherwise treats images that were queued earlier
+        as higher priority in the case where both images are either visible or not visible.
+
+        Test: ImageAnalysisTests.ImageAnalysisPrioritizesVisibleImages
+
+        * page/ImageAnalysisQueue.cpp:
+        (WebCore::ImageAnalysisQueue::enqueueIfNeeded):
+        (WebCore::ImageAnalysisQueue::resumeProcessingSoon):
+        (WebCore::ImageAnalysisQueue::resumeProcessing):
+        (WebCore::ImageAnalysisQueue::clear):
+        * page/ImageAnalysisQueue.h:
+
+        Swap out the Deque for a PriorityQueue, and introduce ImageAnalysisQueue::Task to represent an image analysis
+        task (which can be compared against other tasks to determine priority using `firstIsHigherPriority()` below).
+
+        (WebCore::ImageAnalysisQueue::firstIsHigherPriority):
+
 2022-01-27  Gavin Phillips  <[email protected]>
 
         Detect failed ThreadableLoader creation in FileReaderLoader.

Modified: trunk/Source/WebCore/page/ImageAnalysisQueue.cpp (288689 => 288690)


--- trunk/Source/WebCore/page/ImageAnalysisQueue.cpp	2022-01-27 19:45:03 UTC (rev 288689)
+++ trunk/Source/WebCore/page/ImageAnalysisQueue.cpp	2022-01-27 19:55:22 UTC (rev 288690)
@@ -30,10 +30,12 @@
 
 #include "Chrome.h"
 #include "ChromeClient.h"
+#include "FrameView.h"
 #include "HTMLCollection.h"
 #include "HTMLImageElement.h"
 #include "ImageOverlay.h"
 #include "RenderImage.h"
+#include "RenderView.h"
 #include "Timer.h"
 
 namespace WebCore {
@@ -67,10 +69,23 @@
     if (!m_queuedElements.add(element).isNewEntry)
         return;
 
-    m_queue.append({ element });
-    resumeProcessing();
+    Ref view = renderer.view().frameView();
+    m_queue.enqueue({
+        element,
+        renderer.isVisibleInDocumentRect(view->windowToContents(view->windowClipRect())) ? Priority::High : Priority::Low,
+        nextTaskNumber()
+    });
+    resumeProcessingSoon();
 }
 
+void ImageAnalysisQueue::resumeProcessingSoon()
+{
+    if (m_queue.isEmpty() || m_resumeProcessingTimer.isActive())
+        return;
+
+    m_resumeProcessingTimer.startOneShot(resumeProcessingDelay);
+}
+
 void ImageAnalysisQueue::enqueueAllImages(Document& document, const String& identifier)
 {
     if (!m_page)
@@ -91,8 +106,7 @@
         return;
 
     while (!m_queue.isEmpty() && m_pendingRequestCount < maximumPendingImageAnalysisCount) {
-        auto weakElement = m_queue.takeFirst();
-        RefPtr element = weakElement.get();
+        RefPtr element = m_queue.dequeue().element.get();
         if (!element || !element->isConnected())
             continue;
 
@@ -99,14 +113,13 @@
         m_pendingRequestCount++;
         m_page->resetTextRecognitionResult(*element);
         m_page->chrome().client().requestTextRecognition(*element, m_identifier, [this, page = m_page] (auto&&) {
-            if (!page)
+            if (!page || page->imageAnalysisQueueIfExists() != this)
                 return;
 
             if (m_pendingRequestCount)
                 m_pendingRequestCount--;
 
-            if (!m_queue.isEmpty() && !m_resumeProcessingTimer.isActive())
-                m_resumeProcessingTimer.startOneShot(resumeProcessingDelay);
+            resumeProcessingSoon();
         });
     }
 }
@@ -116,9 +129,10 @@
     // FIXME: This should cancel pending requests in addition to emptying the task queue.
     m_pendingRequestCount = 0;
     m_resumeProcessingTimer.stop();
-    m_queue.clear();
+    m_queue = { };
     m_queuedElements.clear();
     m_identifier = { };
+    m_currentTaskNumber = 0;
 }
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/page/ImageAnalysisQueue.h (288689 => 288690)


--- trunk/Source/WebCore/page/ImageAnalysisQueue.h	2022-01-27 19:45:03 UTC (rev 288689)
+++ trunk/Source/WebCore/page/ImageAnalysisQueue.h	2022-01-27 19:55:22 UTC (rev 288690)
@@ -27,8 +27,8 @@
 
 #if ENABLE(IMAGE_ANALYSIS)
 
-#include <wtf/Deque.h>
 #include <wtf/FastMalloc.h>
+#include <wtf/PriorityQueue.h>
 #include <wtf/WeakHashSet.h>
 #include <wtf/WeakPtr.h>
 
@@ -51,16 +51,36 @@
     void enqueueIfNeeded(HTMLImageElement&);
 
 private:
+    void resumeProcessingSoon();
     void resumeProcessing();
 
+    enum class Priority : bool { Low, High };
+    struct Task {
+        WeakPtr<HTMLImageElement> element;
+        Priority priority { Priority::Low };
+        unsigned taskNumber { 0 };
+    };
+
+    static bool firstIsHigherPriority(const Task&, const Task&);
+    unsigned nextTaskNumber() { return ++m_currentTaskNumber; }
+
     String m_identifier;
     WeakPtr<Page> m_page;
     Timer m_resumeProcessingTimer;
     WeakHashSet<HTMLImageElement> m_queuedElements;
-    Deque<WeakPtr<HTMLImageElement>> m_queue;
+    PriorityQueue<Task, firstIsHigherPriority> m_queue;
     unsigned m_pendingRequestCount { 0 };
+    unsigned m_currentTaskNumber { 0 };
 };
 
+inline bool ImageAnalysisQueue::firstIsHigherPriority(const Task& first, const Task& second)
+{
+    if (first.priority != second.priority)
+        return first.priority == Priority::High;
+
+    return first.taskNumber < second.taskNumber;
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(IMAGE_ANALYSIS)

Modified: trunk/Tools/ChangeLog (288689 => 288690)


--- trunk/Tools/ChangeLog	2022-01-27 19:45:03 UTC (rev 288689)
+++ trunk/Tools/ChangeLog	2022-01-27 19:55:22 UTC (rev 288690)
@@ -1,3 +1,38 @@
+2022-01-27  Wenson Hsieh  <[email protected]>
+
+        ImageAnalysisQueue should prioritize elements that intersect the visible viewport
+        https://bugs.webkit.org/show_bug.cgi?id=235664
+        rdar://88131827
+
+        Reviewed by Darin Adler.
+
+        Add an API test to verify that batch image analysis prioritizes a visible image over another image that appears
+        first in DOM traversal order, but is offscreen.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebKitCocoa/ImageAnalysisTests.mm:
+        (TestWebKitAPI::processedRequests):
+        (TestWebKitAPI::processRequestWithResults):
+        (TestWebKitAPI::makeFakeRequest):
+        (TestWebKitAPI::makeImageAnalysisRequestSwizzler):
+        (TestWebKitAPI::processRequestWithError):
+
+        Additionally add a mechanism for swizzling out VKImageAnalyzerRequest initialization to return a mock object
+        (TestVKImageAnalyzerRequest) instead, which can then be used to inspect the CGImage that would've been sent for
+        analysis. See changes in `ImageAnalysisTestingUtilities.*` below for more information.
+
+        (TestWebKitAPI::TEST):
+        * TestWebKitAPI/Tests/WebKitCocoa/offscreen-image.html: Added.
+        * TestWebKitAPI/cocoa/ImageAnalysisTestingUtilities.h:
+        * TestWebKitAPI/cocoa/ImageAnalysisTestingUtilities.mm:
+        (-[TestVKImageAnalyzerRequest initWithCGImage:orientation:requestType:]):
+        (-[TestVKImageAnalyzerRequest image]):
+        (-[TestVKImageAnalyzerRequest imageURL]):
+        (-[TestVKImageAnalyzerRequest setImageURL:]):
+        (-[TestVKImageAnalyzerRequest pageURL]):
+        (-[TestVKImageAnalyzerRequest setPageURL:]):
+        (TestWebKitAPI::createRequest):
+
 2022-01-26  Jonathan Bedard  <[email protected]>
 
         [webkitbugspy] JSON encode trackers

Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (288689 => 288690)


--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2022-01-27 19:45:03 UTC (rev 288689)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2022-01-27 19:55:22 UTC (rev 288690)
@@ -1058,6 +1058,7 @@
 		F45E15732112CE2900307E82 /* KeyboardInputTestsIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = F45E15722112CE2900307E82 /* KeyboardInputTestsIOS.mm */; };
 		F45E15762112CE6200307E82 /* TestInputDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = F45E15752112CE6200307E82 /* TestInputDelegate.mm */; };
 		F45EB60427739F34003571AE /* TestModalContainerControls.mlmodelc in Copy Resources */ = {isa = PBXBuildFile; fileRef = F45EB60327739F2B003571AE /* TestModalContainerControls.mlmodelc */; };
+		F460BEEA27A1F416007B87D9 /* offscreen-image.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F460BEE727A1F2D6007B87D9 /* offscreen-image.html */; };
 		F460F657261116EA0064F2B6 /* InjectedBundleHitTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = F460F656261116EA0064F2B6 /* InjectedBundleHitTest.mm */; };
 		F460F65B261119580064F2B6 /* InjectedBundleHitTestPlugIn.mm in Sources */ = {isa = PBXBuildFile; fileRef = F460F659261117E70064F2B6 /* InjectedBundleHitTestPlugIn.mm */; };
 		F460F669261263370064F2B6 /* simple-responsive-page.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F460F668261262C70064F2B6 /* simple-responsive-page.html */; };
@@ -1499,6 +1500,7 @@
 				466C3843210637DE006A88DE /* notify-resourceLoadObserver.html in Copy Resources */,
 				CDB5DFFF213610FA00D3E189 /* now-playing.html in Copy Resources */,
 				93E2D2761ED7D53200FA76F6 /* offscreen-iframe-of-media-document.html in Copy Resources */,
+				F460BEEA27A1F416007B87D9 /* offscreen-image.html in Copy Resources */,
 				074994421EA5034B000DA44F /* ondevicechange.html in Copy Resources */,
 				1DAA52CC243BE805001A3159 /* one-video.html in Copy Resources */,
 				CEA6CF2819CCF69D0064F5A7 /* open-and-close-window.html in Copy Resources */,
@@ -3035,6 +3037,7 @@
 		F45E15752112CE6200307E82 /* TestInputDelegate.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = TestInputDelegate.mm; sourceTree = "<group>"; };
 		F45EB60327739F2B003571AE /* TestModalContainerControls.mlmodelc */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = TestModalContainerControls.mlmodelc; sourceTree = "<group>"; };
 		F45EB6062773C371003571AE /* ModalContainerObservation.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ModalContainerObservation.mm; sourceTree = "<group>"; };
+		F460BEE727A1F2D6007B87D9 /* offscreen-image.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "offscreen-image.html"; sourceTree = "<group>"; };
 		F460F656261116EA0064F2B6 /* InjectedBundleHitTest.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = InjectedBundleHitTest.mm; sourceTree = "<group>"; };
 		F460F659261117E70064F2B6 /* InjectedBundleHitTestPlugIn.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = InjectedBundleHitTestPlugIn.mm; sourceTree = "<group>"; };
 		F460F65A2611183F0064F2B6 /* InjectedBundleHitTestProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InjectedBundleHitTestProtocol.h; sourceTree = "<group>"; };
@@ -4186,6 +4189,7 @@
 				466C3842210637CE006A88DE /* notify-resourceLoadObserver.html */,
 				CDB5DFFE21360ED800D3E189 /* now-playing.html */,
 				93E2D2751ED7D51700FA76F6 /* offscreen-iframe-of-media-document.html */,
+				F460BEE727A1F2D6007B87D9 /* offscreen-image.html */,
 				7CCB99221D3B44E7003922F6 /* open-multiple-external-url.html */,
 				931C281B22BC5583001D98C4 /* opendatabase-always-exists.html */,
 				F49992C5248DABE400034167 /* overflow-hidden.html */,

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ImageAnalysisTests.mm (288689 => 288690)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ImageAnalysisTests.mm	2022-01-27 19:45:03 UTC (rev 288689)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ImageAnalysisTests.mm	2022-01-27 19:55:22 UTC (rev 288690)
@@ -53,6 +53,10 @@
 
 #endif // PLATFORM(IOS_FAMILY)
 
+@interface VKImageAnalyzerRequest (TestSupport)
+@property (nonatomic, readonly) CGImageRef image;
+@end
+
 @interface TestWKWebView (ImageAnalysisTests)
 - (void)waitForImageAnalysisRequests:(unsigned)numberOfRequests;
 #if PLATFORM(IOS_FAMILY)
@@ -92,6 +96,12 @@
 
 namespace TestWebKitAPI {
 
+static Vector<RetainPtr<VKImageAnalyzerRequest>>& processedRequests()
+{
+    static NeverDestroyed requests = Vector<RetainPtr<VKImageAnalyzerRequest>> { };
+    return requests.get();
+}
+
 static RetainPtr<TestWKWebView> createWebViewWithTextRecognitionEnhancements()
 {
     RetainPtr configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals" configureJSCForTesting:YES];
@@ -104,23 +114,33 @@
     return adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 300, 300) configuration:configuration.get()]);
 }
 
-static void processRequestWithResults(id, SEL, VKImageAnalyzerRequest *, void (^)(double progress), void (^completion)(VKImageAnalysis *, NSError *))
+static void processRequestWithResults(id, SEL, VKImageAnalyzerRequest *request, void (^)(double progress), void (^completion)(VKImageAnalysis *, NSError *))
 {
     gDidProcessRequestCount++;
+    processedRequests().append({ request });
     completion(createImageAnalysisWithSimpleFixedResults().get(), nil);
 }
 
+static VKImageAnalyzerRequest *makeFakeRequest(id, SEL, CGImageRef image, VKImageOrientation orientation, VKAnalysisTypes requestTypes)
+{
+    return createRequest(image, orientation, requestTypes).leakRef();
+}
+
 template <typename FunctionType>
-InstanceMethodSwizzler makeImageAnalysisRequestSwizzler(FunctionType function)
+std::pair<std::unique_ptr<InstanceMethodSwizzler>, std::unique_ptr<InstanceMethodSwizzler>> makeImageAnalysisRequestSwizzler(FunctionType function)
 {
-    return InstanceMethodSwizzler { PAL::getVKImageAnalyzerClass(), @selector(processRequest:progressHandler:completionHandler:), reinterpret_cast<IMP>(function) };
+    return std::pair {
+        makeUnique<InstanceMethodSwizzler>(PAL::getVKImageAnalyzerClass(), @selector(processRequest:progressHandler:completionHandler:), reinterpret_cast<IMP>(function)),
+        makeUnique<InstanceMethodSwizzler>(PAL::getVKImageAnalyzerRequestClass(), @selector(initWithCGImage:orientation:requestType:), reinterpret_cast<IMP>(makeFakeRequest))
+    };
 }
 
 #if PLATFORM(IOS_FAMILY)
 
-static void processRequestWithError(id, SEL, VKImageAnalyzerRequest *, void (^)(double progress), void (^completion)(VKImageAnalysis *analysis, NSError *error))
+static void processRequestWithError(id, SEL, VKImageAnalyzerRequest *request, void (^)(double progress), void (^completion)(VKImageAnalysis *analysis, NSError *error))
 {
     gDidProcessRequestCount++;
+    processedRequests().append({ request });
     completion(nil, [NSError errorWithDomain:NSCocoaErrorDomain code:1 userInfo:nil]);
 }
 
@@ -224,6 +244,22 @@
     EXPECT_EQ(gDidProcessRequestCount, 5U);
 }
 
+TEST(ImageAnalysisTests, ImageAnalysisPrioritizesVisibleImages)
+{
+    auto requestSwizzler = makeImageAnalysisRequestSwizzler(processRequestWithResults);
+    auto webView = createWebViewWithTextRecognitionEnhancements();
+    [webView synchronouslyLoadTestPageNamed:@"offscreen-image"];
+    [webView _startImageAnalysis:nil];
+    [webView waitForImageAnalysisRequests:2];
+
+    auto firstRequestedImage = [processedRequests().first() image];
+    auto lastRequestedImage = [processedRequests().last() image];
+    EXPECT_EQ(200U, CGImageGetWidth(firstRequestedImage));
+    EXPECT_EQ(150U, CGImageGetHeight(firstRequestedImage));
+    EXPECT_EQ(600U, CGImageGetWidth(lastRequestedImage));
+    EXPECT_EQ(450U, CGImageGetHeight(lastRequestedImage));
+}
+
 } // namespace TestWebKitAPI
 
 #endif // ENABLE(IMAGE_ANALYSIS)

Added: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/offscreen-image.html (0 => 288690)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/offscreen-image.html	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/offscreen-image.html	2022-01-27 19:55:22 UTC (rev 288690)
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta name="viewport" content="initial-scale=1">
+<style>
+img {
+    position: absolute;
+}
+</style>
+</head>
+<body>
+<img style="top: 9000px;" src=""
+<img src=""
+</body>
+</html>

Modified: trunk/Tools/TestWebKitAPI/cocoa/ImageAnalysisTestingUtilities.h (288689 => 288690)


--- trunk/Tools/TestWebKitAPI/cocoa/ImageAnalysisTestingUtilities.h	2022-01-27 19:45:03 UTC (rev 288689)
+++ trunk/Tools/TestWebKitAPI/cocoa/ImageAnalysisTestingUtilities.h	2022-01-27 19:55:22 UTC (rev 288690)
@@ -25,6 +25,7 @@
 
 #pragma once
 
+#import <pal/spi/cocoa/VisionKitCoreSPI.h>
 #import <wtf/RetainPtr.h>
 
 #if HAVE(VK_IMAGE_ANALYSIS)
@@ -42,6 +43,7 @@
 RetainPtr<VKWKTextInfo> createTextInfo(NSString *text, VKQuad *);
 RetainPtr<VKWKLineInfo> createLineInfo(NSString *text, VKQuad *, NSArray<VKWKTextInfo *> *);
 RetainPtr<VKImageAnalysis> createImageAnalysis(NSArray<VKWKLineInfo *> *);
+RetainPtr<VKImageAnalyzerRequest> createRequest(CGImageRef, VKImageOrientation, VKAnalysisTypes);
 
 } // namespace TestWebKitAPI
 

Modified: trunk/Tools/TestWebKitAPI/cocoa/ImageAnalysisTestingUtilities.mm (288689 => 288690)


--- trunk/Tools/TestWebKitAPI/cocoa/ImageAnalysisTestingUtilities.mm	2022-01-27 19:45:03 UTC (rev 288689)
+++ trunk/Tools/TestWebKitAPI/cocoa/ImageAnalysisTestingUtilities.mm	2022-01-27 19:55:22 UTC (rev 288690)
@@ -142,6 +142,60 @@
 
 @end
 
+@interface TestVKImageAnalyzerRequest : NSObject
+@property (nonatomic, readonly) CGImageRef image;
+@property (nonatomic, readonly) VKImageOrientation orientation;
+@property (nonatomic, readonly) VKAnalysisTypes requestType;
+@property (nonatomic, copy) NSURL *imageURL;
+@property (nonatomic, copy) NSURL *pageURL;
+@end
+
+@implementation TestVKImageAnalyzerRequest {
+    RetainPtr<CGImageRef> _image;
+    VKImageOrientation _orientation;
+    VKAnalysisTypes _requestType;
+    RetainPtr<NSURL> _imageURL;
+    RetainPtr<NSURL> _pageURL;
+}
+
+- (instancetype)initWithCGImage:(CGImageRef)image orientation:(VKImageOrientation)orientation requestType:(VKAnalysisTypes)requestType
+{
+    if (!(self = [super init]))
+        return nil;
+
+    _image = image;
+    _orientation = orientation;
+    _requestType = requestType;
+    return self;
+}
+
+- (CGImageRef)image
+{
+    return _image.get();
+}
+
+- (NSURL *)imageURL
+{
+    return _imageURL.get();
+}
+
+- (void)setImageURL:(NSURL *)url
+{
+    _imageURL = adoptNS(url.copy);
+}
+
+- (NSURL *)pageURL
+{
+    return _pageURL.get();
+}
+
+- (void)setPageURL:(NSURL *)url
+{
+    _pageURL = adoptNS(url.copy);
+}
+
+@end
+
 namespace TestWebKitAPI {
 
 RetainPtr<VKQuad> createQuad(CGPoint topLeft, CGPoint topRight, CGPoint bottomLeft, CGPoint bottomRight)
@@ -172,6 +226,11 @@
     return createImageAnalysis(@[ line.get() ]);
 }
 
+RetainPtr<VKImageAnalyzerRequest> createRequest(CGImageRef image, VKImageOrientation orientation, VKAnalysisTypes types)
+{
+    return adoptNS(static_cast<VKImageAnalyzerRequest *>([[TestVKImageAnalyzerRequest alloc] initWithCGImage:image orientation:orientation requestType:types]));
+}
+
 } // namespace TestWebKitAPI
 
 #endif // HAVE(VK_IMAGE_ANALYSIS)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to