Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 0570c24

Browse files
author
Emmanuel Garcia
committed
Fix surface resize bugs
1 parent 9b60a35 commit 0570c24

File tree

4 files changed

+54
-19
lines changed

4 files changed

+54
-19
lines changed

shell/common/rasterizer.cc

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -377,12 +377,6 @@ RasterStatus Rasterizer::DrawToSurface(flutter::LayerTree& layer_tree) {
377377
TRACE_EVENT0("flutter", "Rasterizer::DrawToSurface");
378378
FML_DCHECK(surface_);
379379

380-
auto frame = surface_->AcquireFrame(layer_tree.frame_size());
381-
382-
if (frame == nullptr) {
383-
return RasterStatus::kFailed;
384-
}
385-
386380
// There is no way for the compositor to know how long the layer tree
387381
// construction took. Fortunately, the layer tree does. Grab that time
388382
// for instrumentation.
@@ -398,6 +392,12 @@ RasterStatus Rasterizer::DrawToSurface(flutter::LayerTree& layer_tree) {
398392
embedder_root_canvas = external_view_embedder->GetRootCanvas();
399393
}
400394

395+
auto frame = surface_->AcquireFrame(layer_tree.frame_size());
396+
397+
if (frame == nullptr) {
398+
return RasterStatus::kFailed;
399+
}
400+
401401
// If the external view embedder has specified an optional root surface, the
402402
// root surface transformation is set by the embedder instead of
403403
// having to apply it here.

shell/platform/android/external_view_embedder/external_view_embedder.cc

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -142,12 +142,15 @@ bool AndroidExternalViewEmbedder::SubmitFrame(
142142
background_canvas->drawPicture(pictures.at(view_id));
143143
}
144144
// Submit the background canvas frame before switching the GL context to
145-
// the surfaces above.
145+
// the overlay surfaces.
146+
//
147+
// Skip a frame if the embedding is switching surfaces.
146148
auto should_submit_current_frame =
147149
previous_frame_view_count_ > 0 || current_frame_view_count == 0;
148150
if (should_submit_current_frame) {
149151
frame->Submit();
150152
}
153+
151154
for (int64_t view_id : composition_order_) {
152155
SkRect view_rect = GetViewRect(view_id);
153156
// Display the platform view. If it's already displayed, then it's
@@ -159,12 +162,14 @@ bool AndroidExternalViewEmbedder::SubmitFrame(
159162
view_rect.height() //
160163
);
161164
for (const SkRect& overlay_rect : overlay_layers.at(view_id)) {
162-
CreateSurfaceIfNeeded(context, //
163-
view_id, //
164-
pictures.at(view_id), //
165-
overlay_rect //
166-
)
167-
->Submit();
165+
auto frame = CreateSurfaceIfNeeded(context, //
166+
view_id, //
167+
pictures.at(view_id), //
168+
overlay_rect //
169+
);
170+
if (should_submit_current_frame) {
171+
frame->Submit();
172+
}
168173
}
169174
}
170175
return true;
@@ -244,6 +249,9 @@ void AndroidExternalViewEmbedder::BeginFrame(
244249
double device_pixel_ratio,
245250
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) {
246251
Reset();
252+
253+
// The surface size changed. Therefore, destroy existing surfaces as
254+
// the existing surfaces in the pool can't be recycled.
247255
if (frame_size_ != frame_size) {
248256
surface_pool_->DestroyLayers(jni_facade_);
249257
}

shell/platform/android/io/flutter/embedding/android/FlutterImageView.java

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -194,14 +194,25 @@ public boolean acquireLatestImage() {
194194

195195
/** Creates a new image reader with the provided size. */
196196
public void resizeIfNeeded(int width, int height) {
197+
if (flutterRenderer == null) {
198+
return;
199+
}
197200
if (width == imageReader.getWidth() && height == imageReader.getHeight()) {
198201
return;
199202
}
200-
if (kind == SurfaceKind.background && flutterRenderer != null) {
201-
imageReader.close();
202-
imageReader = createImageReader(width, height);
203-
flutterRenderer.swapSurface(imageReader.getSurface());
203+
// Close resources.
204+
if (nextImage != null) {
205+
nextImage.close();
206+
nextImage = null;
204207
}
208+
if (currentImage != null) {
209+
currentImage.close();
210+
currentImage = null;
211+
}
212+
imageReader.close();
213+
// Image readers cannot be resized once created.
214+
imageReader = createImageReader(width, height);
215+
pendingImages = 0;
205216
}
206217

207218
@Override
@@ -251,6 +262,16 @@ private void updateCurrentBitmap() {
251262

252263
@Override
253264
protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) {
254-
resizeIfNeeded(width, height);
265+
// `SurfaceKind.overlay` isn't resized. Instead, the `FlutterImageView` instance
266+
// is destroyed. As a result, an instance with the new size is created by the surface
267+
// pool in the native side.
268+
if (kind == SurfaceKind.background && isAttachedToFlutterRenderer) {
269+
if (width != imageReader.getWidth() || height != imageReader.getHeight()) {
270+
resizeIfNeeded(width, height);
271+
// Bind native window to the new surface, and create a new onscreen surface
272+
// with the new size in the native side.
273+
flutterRenderer.swapSurface(imageReader.getSurface());
274+
}
275+
}
255276
}
256277
}

shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -710,9 +710,9 @@ public void onEndFrame() {
710710
FlutterImageView overlayView = overlayLayerViews.valueAt(i);
711711

712712
if (currentFrameUsedOverlayLayerIds.contains(overlayId)) {
713+
((FlutterView) flutterView).attachOverlaySurfaceToRender(overlayView);
713714
boolean didAcquireOverlaySurfaceImage = overlayView.acquireLatestImage();
714715
isFrameRenderedUsingImageReaders &= didAcquireOverlaySurfaceImage;
715-
((FlutterView) flutterView).attachOverlaySurfaceToRender(overlayView);
716716
} else {
717717
// If the background surface isn't rendered by the image view, then the
718718
// overlay surfaces can be detached from the rendered.
@@ -763,6 +763,12 @@ public FlutterOverlaySurface createOverlaySurface() {
763763
}
764764

765765
public void destroyOverlaySurfaces() {
766+
for (int i = 0; i < overlayLayerViews.size(); i++) {
767+
int overlayId = overlayLayerViews.keyAt(i);
768+
FlutterImageView overlayView = overlayLayerViews.valueAt(i);
769+
overlayView.detachFromRenderer();
770+
((FlutterView) flutterView).removeView(overlayView);
771+
}
766772
overlayLayerViews.clear();
767773
}
768774
}

0 commit comments

Comments
 (0)