Bug 210974 - Use CocoaImage platform abstraction for NSImage/UIImage
Summary: Use CocoaImage platform abstraction for NSImage/UIImage
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebKit2 (show other bugs)
Version: Other
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: David Kilzer (:ddkilzer)
URL:
Keywords: InRadar
Depends on: 210814
Blocks:
  Show dependency treegraph
 
Reported: 2020-04-24 09:36 PDT by David Kilzer (:ddkilzer)
Modified: 2020-04-24 14:03 PDT (History)
4 users (show)

See Also:


Attachments
Patch v1 (17.35 KB, patch)
2020-04-24 10:46 PDT, David Kilzer (:ddkilzer)
no flags Details | Formatted Diff | Diff
Patch v2 (land safely after EWS) (17.06 KB, patch)
2020-04-24 12:04 PDT, David Kilzer (:ddkilzer)
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description David Kilzer (:ddkilzer) 2020-04-24 09:36:25 PDT
Use CocoaImage platform abstraction for NSImage/UIImage.

Following on from comments in Bug 210814, move CocoaImage into its own header for reuse in other classes.

There aren't as many opportunities for this as you might think, though:

$ grep -l NSImage `grep -l -r UIImage Source | grep -v ChangeLog | grep -v .order` 
Source/WebKitLegacy/mac/WebView/WebView.mm
Source/WebKitLegacy/mac/WebView/WebViewData.h
Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm
Source/WebKit/UIProcess/API/Cocoa/_WKActivatedElementInfo.mm
Source/WebKit/UIProcess/API/Cocoa/WKWebView.h
Source/WebKit/UIProcess/API/Cocoa/_WKActivatedElementInfo.h
Source/WebKit/UIProcess/QuickLookThumbnailLoader.h
Source/WebKit/UIProcess/QuickLookThumbnailLoader.mm
Source/WebKit/WebProcess/InjectedBundle/API/Cocoa/WKWebProcessPlugInNodeHandle.h
Source/WebKit/WebProcess/InjectedBundle/API/Cocoa/WKWebProcessPlugInNodeHandle.mm
Source/WebCore/editing/cocoa/HTMLConverter.mm

The uses in WebCore and WebKitLegacy aren't really cross-platform, so all of the interesting use cases are in WebKit.

However, the initial version of the patch doesn't use CocoaImage in public headers as I wasn't sure if we were okay with doing things like this in Source/WebKit/UIProcess/API/Cocoa/WKWebView.h:

-#if TARGET_OS_IPHONE
-- (void)takeSnapshotWithConfiguration:(nullable WKSnapshotConfiguration *)snapshotConfiguration completionHandler:(void (^)(UIImage * _Nulla
ble snapshotImage, NSError * _Nullable error))completionHandler WK_API_AVAILABLE(ios(11.0));
-#else
-- (void)takeSnapshotWithConfiguration:(nullable WKSnapshotConfiguration *)snapshotConfiguration completionHandler:(void (^)(NSImage * _Nullable snapshotImage, NSError * _Nullable error))completionHandler WK_API_AVAILABLE(macos(10.13));
-#endif

+- (void)takeSnapshotWithConfiguration:(nullable WKSnapshotConfiguration *)snapshotConfiguration completionHandler:(void (^)(CocoaImage * _Nullable snapshotImage, NSError * _Nullable error))completionHandler WK_API_AVAILABLE(macos(10.13), ios(11.0));
Comment 1 Darin Adler 2020-04-24 09:39:43 PDT
(In reply to David Kilzer (:ddkilzer) from comment #0)
> However, the initial version of the patch doesn't use CocoaImage in public
> headers

Yes, I don’t think it is good to use it in public headers.
Comment 2 David Kilzer (:ddkilzer) 2020-04-24 10:46:25 PDT
Created attachment 397471 [details]
Patch v1
Comment 3 David Kilzer (:ddkilzer) 2020-04-24 10:47:51 PDT
Comment on attachment 397471 [details]
Patch v1

View in context: https://bugs.webkit.org/attachment.cgi?id=397471&action=review

> Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm:983
> -#if PLATFORM(MAC)
> -- (void)takeSnapshotWithConfiguration:(WKSnapshotConfiguration *)snapshotConfiguration completionHandler:(void(^)(NSImage *, NSError *))completionHandler
> +- (void)takeSnapshotWithConfiguration:(WKSnapshotConfiguration *)snapshotConfiguration completionHandler:(void(^)(CocoaImage *, NSError *))completionHandler

This is the least-satisfying improvement.  Maybe I need to extract the platform-specific code into static methods?
Comment 4 Darin Adler 2020-04-24 10:59:48 PDT
Comment on attachment 397471 [details]
Patch v1

View in context: https://bugs.webkit.org/attachment.cgi?id=397471&action=review

Nice improvement.

> Source/WebKit/Platform/cocoa/CocoaImage.h:26
> +#import <wtf/PlatformUse.h>

This should not be necessary. The prefix header takes care of this.

> Source/WebKit/Platform/cocoa/CocoaImage.h:35
> +#ifdef __cplusplus
> +using CocoaImage = NSImage;
> +#else
> +#define CocoaImage NSImage
> +#endif

If we need something that works with Objective-C (not C++) then I suggest we use typedef, not #define, and not using. But, can this just be an Objective-C++ header? Then it would use using unconditionally.

> Source/WebKit/Platform/cocoa/CocoaImage.h:44
> +#ifdef __cplusplus
> +using CocoaImage = UIImage;
> +#else
> +#define CocoaImage UIImage
> +#endif

Ditto.

>> Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm:983
>> +- (void)takeSnapshotWithConfiguration:(WKSnapshotConfiguration *)snapshotConfiguration completionHandler:(void(^)(CocoaImage *, NSError *))completionHandler
> 
> This is the least-satisfying improvement.  Maybe I need to extract the platform-specific code into static methods?

Can chip away at it more later.

> Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm:1017
> -        RetainPtr<NSImage> nsImage = adoptNS([[NSImage alloc] initWithCGImage:cgImage.get() size:NSMakeSize(snapshotWidth, imageHeight)]);
> -        handler(nsImage.get(), nil);
> +        auto image = adoptNS([[CocoaImage alloc] initWithCGImage:cgImage.get() size:NSMakeSize(snapshotWidth, imageHeight)]);
> +        handler(image.get(), nil);

I don’t think this change is needed. Nice to use auto, but no need to use CocoaImage here.

> Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm:1032
> -            RetainPtr<UIImage> uiImage;
> +            RetainPtr<CocoaImage> image;
>              
>              if (!snapshotImage)
>                  error = createNSError(WKErrorUnknown);
>              else
> -                uiImage = adoptNS([[UIImage alloc] initWithCGImage:snapshotImage scale:deviceScale orientation:UIImageOrientationUp]);
> +                image = adoptNS([[CocoaImage alloc] initWithCGImage:snapshotImage scale:deviceScale orientation:UIImageOrientationUp]);
>              
> -            handler(uiImage.get(), error.get());
> +            handler(image.get(), error.get());

I don’t think this change is needed. Nicer local variable name, but no need to use CocoaImage here.

> Source/WebKit/UIProcess/API/Cocoa/_WKActivatedElementInfo.mm:154
> +        return [[_cocoaImage copy] autorelease];

Surprised that we need copy/autorelease.

> Source/WebKit/UIProcess/API/Cocoa/_WKActivatedElementInfo.mm:163
> +#if USE(APPKIT)
> +    _cocoaImage = adoptNS([[CocoaImage alloc] initWithCGImage:_image->makeCGImageCopy().get() size:NSSizeFromCGSize(_boundingRect.size)]);
> +#else
> +    _cocoaImage = adoptNS([[CocoaImage alloc] initWithCGImage:_image->makeCGImageCopy().get()]);
> +#endif

I would have used the class names NSImage and UIImage here, not CocoaImage, but it’s OK either way I suppose.

> Source/WebKit/WebProcess/InjectedBundle/API/Cocoa/WKWebProcessPlugInNodeHandle.mm:77
> +#if USE(APPKIT)
> +    return [[[CocoaImage alloc] initWithCGImage:image->bitmap().makeCGImage().get() size:NSZeroSize] autorelease];
> +#else
> +    return [[[CocoaImage alloc] initWithCGImage:image->bitmap().makeCGImage().get()] autorelease];
>  #endif

Here too.
Comment 5 Darin Adler 2020-04-24 11:02:59 PDT
Comment on attachment 397471 [details]
Patch v1

View in context: https://bugs.webkit.org/attachment.cgi?id=397471&action=review

>> Source/WebKit/UIProcess/API/Cocoa/_WKActivatedElementInfo.mm:154
>> +        return [[_cocoaImage copy] autorelease];
> 
> Surprised that we need copy/autorelease.

Oops, not sure why I left that comment in. Please don’t change this! I am surprised but we should take no risk on this at this time, just based on that surprise!
Comment 6 David Kilzer (:ddkilzer) 2020-04-24 11:28:23 PDT
Comment on attachment 397471 [details]
Patch v1

View in context: https://bugs.webkit.org/attachment.cgi?id=397471&action=review

>> Source/WebKit/Platform/cocoa/CocoaImage.h:26
>> +#import <wtf/PlatformUse.h>
> 
> This should not be necessary. The prefix header takes care of this.

Will remove.

>> Source/WebKit/Platform/cocoa/CocoaImage.h:35
>> +#endif
> 
> If we need something that works with Objective-C (not C++) then I suggest we use typedef, not #define, and not using. But, can this just be an Objective-C++ header? Then it would use using unconditionally.

Only used in Objective-C++ for now, so will just keep using statement.

>> Source/WebKit/Platform/cocoa/CocoaImage.h:44
>> +#endif
> 
> Ditto.

Only used in Objective-C++ for now, so will just keep using statement.

>> Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm:1017
>> +        handler(image.get(), nil);
> 
> I don’t think this change is needed. Nice to use auto, but no need to use CocoaImage here.

Will keep the variable name change and auto and revert the class name change.

>> Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm:1032
>> +            handler(image.get(), error.get());
> 
> I don’t think this change is needed. Nicer local variable name, but no need to use CocoaImage here.

Will keep the variable name change and revert the class name change.

>>> Source/WebKit/UIProcess/API/Cocoa/_WKActivatedElementInfo.mm:154
>>> +        return [[_cocoaImage copy] autorelease];
>> 
>> Surprised that we need copy/autorelease.
> 
> Oops, not sure why I left that comment in. Please don’t change this! I am surprised but we should take no risk on this at this time, just based on that surprise!

Okay.

>> Source/WebKit/UIProcess/API/Cocoa/_WKActivatedElementInfo.mm:163
>> +#endif
> 
> I would have used the class names NSImage and UIImage here, not CocoaImage, but it’s OK either way I suppose.

Will revert the class name change.

>> Source/WebKit/WebProcess/InjectedBundle/API/Cocoa/WKWebProcessPlugInNodeHandle.mm:77
>>  #endif
> 
> Here too.

Will revert the class name change.
Comment 7 David Kilzer (:ddkilzer) 2020-04-24 12:04:50 PDT
Created attachment 397480 [details]
Patch v2 (land safely after EWS)
Comment 8 EWS 2020-04-24 14:02:52 PDT
Committed r260667: <https://trac.webkit.org/changeset/260667>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 397480 [details].
Comment 9 Radar WebKit Bug Importer 2020-04-24 14:03:23 PDT
<rdar://problem/62337926>