-
Notifications
You must be signed in to change notification settings - Fork 6k
Use a Pbuffer surface when the onscreen surface is not available for snapshotting on Android #27141
Conversation
Something's wrong here - in the midst of refacotring/cleaning up I broke the test I have. |
stderr=subprocess.STDOUT, | ||
universal_newlines=True, | ||
) | ||
return process |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes here are to run multiple firebase testlab tests in parallel. Now that we're running two this makes a difference. The new test executes pretty quickly but still requires setup/upload/results processing time.
This patch is ready for review. |
Sorry for the size, a substantial number of files are testing support related files :\ |
if (!surface_) { | ||
pbuffer_surface = delegate_.CreateSnapshotSurface(); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can the redundancy of surface_
versus pbuffer_surface
be reduced?
e.g. with something like
Surface* snapshot_surface = nullptr;
if (surface_ && surface_->GetContext()) {
snapshot_surface = surface_.get();
} else {
pbuffer_surface = delegate_.CreateSnapshotSurface();
if (pbuffer_surface && pbuffer_surface->GetContext())
snapshot_surface = pbuffer_surface.get();
}
The rest of the method can then only use snapshot_surface
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd ahve to manually delete the surface if it came from CreateSnapshotSurface then though. like pbuffer_surface.release()
and then a delete
at the end if it's not nullptr and not the surface_.get()
. Is there some way I'm missing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pbuffer_surface
would be a unique_ptr
declared at the same scope as snapshot_surface
. If pbuffer_surface
is assigned then it will be deleted when the function exits.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh I get it now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
shell/common/platform_view.h
Outdated
/// | ||
/// This is the only public method of this interface called on the | ||
/// raster task runner. | ||
virtual std::unique_ptr<Surface> CreateRasterSnapshotSurface(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a way to avoid having a method on PlatformView
which is a special case that is not called on the platform thread?
One potential option would be creating another interface similar to ExternalViewEmbedder
that is instantiated by the PlatformView
and then given to the Rasterizer
by the Shell
.
Like AndroidExternalViewEmbedder
, this object could hold a reference to the AndroidContext
and use that to create the pbuffer surface.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this idea. I'll try to do this - I think it'll get rid of some of the funky threading concerns around accessing the platform view.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, latest commit has these changes. This gets rid of the threading concern/note that I had in platform view before. @chinmaygarde FYI
Build failure is because the |
If the intention is to build with Gradle, then there are two options, but really just one (see 2).
|
@blasten - looks like gradlew is unhappy with buildtools?
|
Checking if it's a flake... |
AFAICT gradle is trying to download buildtools 30.0.2 and CI doesn't like it. I don't have permissions to update the CIPD packages to add 30.0.2 and roll us to that. @blasten @godofredoc |
std::unique_ptr<Surface> CreateSnapshotSurface() override; | ||
|
||
private: | ||
std::shared_ptr<AndroidSurface> android_surface_; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should hold a reference to the AndroidSurface
instead of converting AndroidSurface
into a shared pointer.
(similar to the AndroidContext&
held by the AndroidExternalViewEmbedder
)
I don't think it's safe to delete the last AndroidSurface
pointer on a thread other than the platform thread.
Normally this would not happen because the Shell
would delete the Rasterizer
before the PlatformView
, which would ensure that the PlatformView
's pointer to the AndroidSurface
would be the last to go. But if the PlatformView
must be responsible for deleting the AndroidSurface
, then I'd prefer to formalize that by having the PlatformView
hold a unique_ptr
.
Alternatively, CreateSnapshotSurface
could be moved out of AndroidSurface
and into AndroidContext
. The AndroidSurfaceGL::CreatePbufferSurface
implementation is delegating to AndroidContextGL
and does not use any of AndroidSurfaceGL
's state.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We do need an AndroidSurfaceGL to create a GPUSurfaceGL which is what the rasterizer expects to interact with. I'll ook at using the ref.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using a ref is less than ideal because it access a bunch of non-const methods.
I'm using a weak_ptr which I think should be safe w.r.t. your concerns.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok - weak_ptr doesn't actually solve this problem, because we'd still potentially release the shared_ptr on the wrong thread. changed to a non-const reference.
…ble for snapshotting on Android (flutter/engine#27141)
…ble for snapshotting on Android (flutter/engine#27141)
…ble for snapshotting on Android (flutter/engine#27141)
…ble for snapshotting on Android (flutter#27141)" (flutter#27607)" This reverts commit 0c121d3.
…snapshotting on Android (flutter#27141)
…ble for snapshotting on Android (flutter#27141)" (flutter#27607) This reverts commit a1180b1.
* Reland "Use a Pbuffer surface when the onscreen surface is not available for snapshotting on Android (flutter#27141)" (flutter#27607)" This reverts commit 0c121d3. * Do not let gradle download SDK deps
When rasterizing a Picture or Scene, we normally try to use the on screen surface. If it's not available, we go down a raster based path. However, this won't work if the image contains images that were uploaded via the resource context - Skia won't draw the pixels into the resulting picture.
We can't use the resource context from the raster thread either, and rasterizing the image on the IO thread has been attempted but does not work.
This patch adds a 1x1 pbuffer for use if the on screen surface is not available, and rasterizes using that. It only applies to Android since it is GL and background specific - on the iOS GL backend it would be illegal to use the GPU from the background anyway.
Fixes flutter/flutter#73675
Fixes flutter/flutter#86680
Need to figure out the right way to add this test case: flutter/flutter#73675 (comment)