Skip to content
Closed
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
10 changes: 10 additions & 0 deletions .github/workflows/run-flutter-builds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,16 @@ jobs:
flutter pub get
flutter test

# The checked-in example overrides are relative monorepo paths. Real
# consumers of a Git or hosted package receive absolute file:/// root
# URIs in package_config.json, so exercise that resolution path too.
- name: Exercise absolute package URIs (Linux)
if: matrix.name == 'Linux'
shell: bash
run: |
sed -i "s|path: ../../../thermion_dart|path: ${GITHUB_WORKSPACE}/thermion_dart|" quickstart/pubspec.yaml
sed -i "s|path: ../../../thermion_dart|path: ${GITHUB_WORKSPACE}/thermion_dart|" picking/pubspec.yaml

- name: Build quickstart (Linux)
if: matrix.name == 'Linux'
run: cd quickstart && flutter pub get && flutter build linux
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class MethodChannelPlatformTextureDescriptor extends PlatformTextureDescriptor {
required super.windowHandle,
required super.width,
required super.height,
super.flipVertically,
bool deferred = false,
}) : _deferred = deferred;

Expand All @@ -38,6 +39,7 @@ class MethodChannelPlatformTextureDescriptor extends PlatformTextureDescriptor {
int width,
int height, {
bool deferred = false,
bool flipVertically = false,
}) async {
final allocation = await allocateMethodChannelTexture(
channel,
Expand All @@ -52,6 +54,7 @@ class MethodChannelPlatformTextureDescriptor extends PlatformTextureDescriptor {
width: width,
height: height,
deferred: deferred,
flipVertically: flipVertically,
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ class NativeTextureSurfaceManager {
resumeRenderingIfReady: lifecycle.resumeRenderingIfReady,
runTextureMutation: lifecycle.duringTextureMutation,
androidTextureSource: () => options().androidTextureSource,
flipLinuxTextureVertically: () => options().backend != Backend.VULKAN,
);

static final _logger = Logger('NativeTextureSurfaceManager');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ abstract class PlatformTextureDescriptor {

int height;

/// Whether Flutter must invert this texture vertically when presenting it.
///
/// OpenGL render targets use a bottom-left origin, while Flutter's widget
/// coordinate system uses a top-left origin.
final bool flipVertically;

View? _boundView;

/// The (possibly null) view this descriptor is bound to
Expand All @@ -28,6 +34,7 @@ abstract class PlatformTextureDescriptor {
required this.width,
required this.height,
this.windowHandle,
this.flipVertically = false,
});

/// Descriptors are identified by their Flutter texture id. This is stable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,17 @@ class NativePlatformTextureDescriptorRegistry
required void Function() resumeRenderingIfReady,
required TextureMutationRunner runTextureMutation,
required AndroidTextureSource Function() androidTextureSource,
required bool Function() flipLinuxTextureVertically,
}) : _pauseRendering = pauseRendering,
_resumeRenderingIfReady = resumeRenderingIfReady,
_runTextureMutation = runTextureMutation,
super(
allocator: (width, height) =>
_allocate(width, height, androidTextureSource()),
allocator: (width, height) => _allocate(
width,
height,
androidTextureSource(),
flipLinuxTextureVertically(),
),
) {
if (Platform.isAndroid) {
channel.setMethodCallHandler(_handlePlatformMethodCall);
Expand All @@ -62,6 +67,7 @@ class NativePlatformTextureDescriptorRegistry
int width,
int height,
AndroidTextureSource androidTextureSource,
bool flipLinuxTextureVertically,
) {
if (Platform.isMacOS || Platform.isIOS) {
return Future.value(
Expand Down Expand Up @@ -89,6 +95,7 @@ class NativePlatformTextureDescriptorRegistry
width,
height,
deferred: true,
flipVertically: flipLinuxTextureVertically,
);
}
throw UnsupportedError('Platform textures are not supported on $Platform');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,17 @@ Widget surfaceWidgetBuilder(PlatformTextureDescriptor? descriptor, View view) {
if (descriptor == null) {
return const SizedBox.shrink();
}
return Texture(
return buildTextureWidget(descriptor);
}

@visibleForTesting
Widget buildTextureWidget(PlatformTextureDescriptor descriptor) {
final texture = Texture(
key: ObjectKey("flutter_texture_${descriptor.flutterTextureId}"),
textureId: descriptor.flutterTextureId,
filterQuality: FilterQuality.none,
freeze: false,
);
if (!descriptor.flipVertically) return texture;
return Transform.flip(flipY: true, child: texture);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import 'package:flutter/material.dart';
import 'package:logging/logging.dart';
import 'package:thermion_flutter/thermion_flutter.dart' hide Texture;

import 'texture_bootstrap.dart';

enum ManipulatorType { NONE, ORBIT, FREE_FLIGHT }

class ViewerWidget extends StatefulWidget {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ library;

export 'src/thermion_widget.dart';
export 'src/viewer_widget.dart';
export 'src/texture_bootstrap.dart';
export 'src/thermion_listener_widget.dart';
export 'src/camera/camera_selector_widget.dart';
export 'src/camera/camera_orientation_widget.dart';
Expand Down
9 changes: 4 additions & 5 deletions thermion_flutter/thermion_flutter/linux/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,10 @@ if(_PKG_CONFIG)
endforeach()

if(_td_rootUri)
# rootUri may be a file:/// URI (e.g. file:///D:/path on Windows,
# file:///home on Linux) or a relative path like "../../thermion_dart".
# Strip file:/// (3 slashes) first, then file:// (2 slashes) as fallback.
string(REGEX REPLACE "^file:///" "" _td_root "${_td_rootUri}")
string(REGEX REPLACE "^file://" "" _td_root "${_td_root}")
# rootUri may be an absolute file:/// URI or a relative path such as
# "../../thermion_dart". Strip only the file:// scheme prefix: the
# remaining slash is the root of an absolute Linux path.
string(REGEX REPLACE "^file://" "" _td_root "${_td_rootUri}")
if(NOT IS_ABSOLUTE "${_td_root}")
get_filename_component(_pkg_dir "${_PKG_CONFIG}" DIRECTORY)
get_filename_component(_td_root "${_pkg_dir}/${_td_root}" ABSOLUTE)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:thermion_flutter/src/platform/src/platform_texture_descriptor.dart';
import 'package:thermion_flutter/src/widgets/src/thermion_widget.dart';
import 'package:thermion_flutter/src/widgets/src/thermion_widget_internal/texture_widget_builder.dart';

void main() {
testWidgets('staged replacement is mounted below the last valid frame', (
Expand Down Expand Up @@ -48,4 +50,45 @@ void main() {
expect(find.byKey(currentKey), findsOneWidget);
expect(find.byType(Stack), findsNothing);
});

testWidgets('flagged platform texture is vertically flipped', (tester) async {
await tester.pumpWidget(
MaterialApp(
home: buildTextureWidget(_TextureDescriptor(flipVertically: true)),
),
);

final transform = tester.widget<Transform>(find.byType(Transform));
expect(transform.transform.entry(0, 0), 1);
expect(transform.transform.entry(1, 1), -1);
expect(find.byType(Texture), findsOneWidget);
});

testWidgets('unflagged platform texture is not transformed', (tester) async {
await tester.pumpWidget(
MaterialApp(
home: buildTextureWidget(_TextureDescriptor(flipVertically: false)),
),
);

expect(find.byType(Transform), findsNothing);
expect(find.byType(Texture), findsOneWidget);
});
}

class _TextureDescriptor extends PlatformTextureDescriptor {
_TextureDescriptor({required bool flipVertically})
: super(
flutterTextureId: 1,
hardwareId: 2,
width: 3,
height: 4,
flipVertically: flipVertically,
);

@override
Future<void> destroy() async {}

@override
Future<void> markTextureFrameAvailable() async {}
}