Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -756,6 +756,11 @@ public void setCallback(Callback callback) {
this.callback = callback;
}

@Override
public boolean handlesCropAndRotation() {
return false;
}

@Override
public long id() {
return id;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ public void setCallback(Callback callback) {
// Intentionally blank: SurfaceTextures don't get platform notifications or cleanup.
}

@Override
public boolean handlesCropAndRotation() {
return true;
}

@Override
@NonNull
public SurfaceTexture getSurfaceTexture() {
Expand Down
22 changes: 22 additions & 0 deletions shell/platform/android/io/flutter/view/TextureRegistry.java
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,28 @@ interface Callback {

/** This method is not officially part of the public API surface and will be deprecated. */
void scheduleFrame();

/**
* Returns whether the current rendering path handles crop and rotation metadata.
Copy link
Contributor

Choose a reason for hiding this comment

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

I would probably add this is generally 29+ in the details.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done!

*
* <p>On most newer Android devices (API 29+), a {@link android.media.ImageReader} backend is
* used, which has more features, works in new graphic backends directly (such as Impeller's
* Vulkan backend), and is the Android recommended solution. However, crop and rotation metadata
* are <strong>not</strong> handled automatically, and require plugin authors to make
* appropriate changes ({@see https://github.com/flutter/flutter/issues/144407}).
*
* <pre>{@code
* void example(SurfaceProducer producer) {
* bool supported = producer.handlesCropAndRotation();
* if (!supported) {
* // Manually rotate/crop, either in the Android plugin or in the Dart framework layer.
* }
* }
* }</pre>
*
* @return {@code true} if crop and rotation is handled automatically, {@code false} otherwise.
*/
boolean handlesCropAndRotation();
}

/** A registry entry for a managed SurfaceTexture. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
import static android.content.ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.anyInt;
Expand Down Expand Up @@ -735,6 +737,27 @@ public void SurfaceTextureSurfaceProducerCreatesAConnectedTexture() {
}
}

@Test
public void SurfaceTextureSurfaceProducerDoesNotCropOrRotate() {
try {
FlutterRenderer.debugForceSurfaceProducerGlTextures = true;
FlutterRenderer flutterRenderer = engineRule.getFlutterEngine().getRenderer();
TextureRegistry.SurfaceProducer producer = flutterRenderer.createSurfaceProducer();

assertTrue(producer.handlesCropAndRotation());
} finally {
FlutterRenderer.debugForceSurfaceProducerGlTextures = false;
}
}

@Test
public void ImageReaderSurfaceProducerDoesNotCropOrRotate() {
FlutterRenderer flutterRenderer = engineRule.getFlutterEngine().getRenderer();
TextureRegistry.SurfaceProducer producer = flutterRenderer.createSurfaceProducer();

assertFalse(producer.handlesCropAndRotation());
}

@Test
public void ImageReaderSurfaceProducerIsDestroyedOnTrimMemory() {
FlutterRenderer flutterRenderer = engineRule.getFlutterEngine().getRenderer();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1651,6 +1651,11 @@ public Surface getSurface() {
return null;
}

@Override
public boolean handlesCropAndRotation() {
return false;
}

public void scheduleFrame() {}
};
}
Expand Down