Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add platform screenshot provider to take screenshot (iOS) #11059

Closed
wants to merge 1 commit into from

Conversation

cyanglaz
Copy link
Contributor

Background:

For platforms use a PlatformViewLayer(e.g iOS) that composite the UI using native APIs, the screenshot by Skia won't take account of the native UI. For example, screenshot with a webview will show blank in the window that displays the webview on iOS.
We need to have a way to take screenshots with PlatformViewLayer in the scene to unblock screenshot testing for iOS platform views.

What does this PR do:

Introduced a PlatformScreenshotProvider class to handle the screenshot using APIs from the platform instead of Skia if necessary.
Also added iOS implementation for the `PlatformScreenshotProvider.

@cyanglaz cyanglaz force-pushed the screenshot_provider branch from e25673b to 2511ad1 Compare August 16, 2019 18:57
// matrix to identity.
SkMatrix root_surface_transformation;
root_surface_transformation.reset();
// Prepare an image from the surface, this image may potentially be on the
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Despite the big diff, here I only added

const auto screen_shot_provider = surface_->GetScreenShotProvider();
  if (snapshot_surface == nullptr) {	  if (screen_shot_provider != nullptr) {
    FML_LOG(ERROR) << "Screenshot: unable to create snapshot surface";	    potentially_gpu_snapshot = screen_shot_provider->TakeScreenShot();
    return nullptr;	  
}

and put everything into an "else" block.

@cyanglaz cyanglaz requested review from chinmaygarde and amirh August 16, 2019 19:02
Copy link
Member

@chinmaygarde chinmaygarde left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think I understood your approach with this interface. If you wanted to screenshot the entire view hierarchy with multiple interleaved levels of platform views and Flutter rendered views, you would have to to screenshot all the platform views as individual images and then composite them together with the Flutter overlays to form one image (the screenshot). As prototyped, the PlatformScreenShotProvider will return a single image. It isn't clear how you will manage interleaving of Flutter vs non-Flutter rendered contents.

Also, reading the iOS implementation, it seems like you will end up snapshotting the Flutter view, but that wont contain the contents rendered by Flutter using OpenGL because it doesn't have access to the GPU context.

@@ -233,6 +233,11 @@ class ExternalViewEmbedder {

}; // ExternalViewEmbedder

class PlatformScreenShotProvider {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Please put new classes and interfaces in their own files. I realize the embedded_views.h is becoming sort of a a catchall for all things embedded platform views related, but we can separate this out in a later commit.

@@ -233,6 +233,11 @@ class ExternalViewEmbedder {

}; // ExternalViewEmbedder

class PlatformScreenShotProvider {
public:
virtual sk_sp<SkImage> TakeScreenShot() = 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you document this in doxygen format please?

Also, we might need to rework this interface once overlays are not screen sized. We will need some sort of offset or ability to apply transformation. Not saying we should do this now, but just something to think about.

sk_sp<SkImage> potentially_gpu_snapshot;
const auto screen_shot_provider = surface_->GetScreenShotProvider();
if (screen_shot_provider != nullptr) {
potentially_gpu_snapshot = screen_shot_provider->TakeScreenShot();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can't be a GPU snapshot though. The overlays don't have access to a GPU context and cannot reference flutter managed resource. This has to be a raster (CPU) snapshot.

@cyanglaz
Copy link
Contributor Author

After offline discussion with @chinmaygarde, it looks like the approach of this PR will only work for simulator. Going to close this PR and rework a solution.

@cyanglaz cyanglaz closed this Aug 19, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants