Skip to content

Commit 1fe3ae6

Browse files
authored
[Flutter GPU] Add Textures. (flutter#48118)
1 parent 90c3ada commit 1fe3ae6

File tree

19 files changed

+637
-19
lines changed

19 files changed

+637
-19
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3613,8 +3613,11 @@ ORIGIN: ../../../flutter/lib/gpu/lib/src/buffer.dart + ../../../flutter/LICENSE
36133613
ORIGIN: ../../../flutter/lib/gpu/lib/src/context.dart + ../../../flutter/LICENSE
36143614
ORIGIN: ../../../flutter/lib/gpu/lib/src/formats.dart + ../../../flutter/LICENSE
36153615
ORIGIN: ../../../flutter/lib/gpu/lib/src/smoketest.dart + ../../../flutter/LICENSE
3616+
ORIGIN: ../../../flutter/lib/gpu/lib/src/texture.dart + ../../../flutter/LICENSE
36163617
ORIGIN: ../../../flutter/lib/gpu/smoketest.cc + ../../../flutter/LICENSE
36173618
ORIGIN: ../../../flutter/lib/gpu/smoketest.h + ../../../flutter/LICENSE
3619+
ORIGIN: ../../../flutter/lib/gpu/texture.cc + ../../../flutter/LICENSE
3620+
ORIGIN: ../../../flutter/lib/gpu/texture.h + ../../../flutter/LICENSE
36183621
ORIGIN: ../../../flutter/lib/io/dart_io.cc + ../../../flutter/LICENSE
36193622
ORIGIN: ../../../flutter/lib/io/dart_io.h + ../../../flutter/LICENSE
36203623
ORIGIN: ../../../flutter/lib/snapshot/snapshot.h + ../../../flutter/LICENSE
@@ -6389,8 +6392,11 @@ FILE: ../../../flutter/lib/gpu/lib/src/buffer.dart
63896392
FILE: ../../../flutter/lib/gpu/lib/src/context.dart
63906393
FILE: ../../../flutter/lib/gpu/lib/src/formats.dart
63916394
FILE: ../../../flutter/lib/gpu/lib/src/smoketest.dart
6395+
FILE: ../../../flutter/lib/gpu/lib/src/texture.dart
63926396
FILE: ../../../flutter/lib/gpu/smoketest.cc
63936397
FILE: ../../../flutter/lib/gpu/smoketest.h
6398+
FILE: ../../../flutter/lib/gpu/texture.cc
6399+
FILE: ../../../flutter/lib/gpu/texture.h
63946400
FILE: ../../../flutter/lib/io/dart_io.cc
63956401
FILE: ../../../flutter/lib/io/dart_io.h
63966402
FILE: ../../../flutter/lib/snapshot/libraries_experimental.json

impeller/fixtures/dart_tests.dart

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,84 @@ void deviceBufferOverwriteThrowsForNegativeDestinationOffset() {
7878
}
7979
assert(exception!.contains('destinationOffsetInBytes must be positive'));
8080
}
81+
82+
@pragma('vm:entry-point')
83+
void canCreateTexture() {
84+
final gpu.Texture? texture =
85+
gpu.gpuContext.createTexture(gpu.StorageMode.hostVisible, 100, 100);
86+
assert(texture != null);
87+
88+
// Check the defaults.
89+
assert(
90+
texture!.coordinateSystem == gpu.TextureCoordinateSystem.renderToTexture);
91+
assert(texture!.width == 100);
92+
assert(texture!.height == 100);
93+
assert(texture!.storageMode == gpu.StorageMode.hostVisible);
94+
assert(texture!.sampleCount == 1);
95+
assert(texture!.format == gpu.PixelFormat.r8g8b8a8UNormInt);
96+
assert(texture!.enableRenderTargetUsage == true);
97+
assert(texture!.enableShaderReadUsage == true);
98+
assert(texture!.enableShaderWriteUsage == false);
99+
assert(texture!.bytesPerTexel == 4);
100+
assert(texture!.GetBaseMipLevelSizeInBytes() == 40000);
101+
}
102+
103+
@pragma('vm:entry-point')
104+
void canOverwriteTexture() {
105+
final gpu.Texture? texture =
106+
gpu.gpuContext.createTexture(gpu.StorageMode.hostVisible, 2, 2);
107+
assert(texture != null);
108+
final ui.Color red = ui.Color.fromARGB(0xFF, 0xFF, 0, 0);
109+
final ui.Color green = ui.Color.fromARGB(0xFF, 0, 0xFF, 0);
110+
final bool success = texture!.overwrite(
111+
Int32List.fromList(<int>[red.value, green.value, green.value, red.value])
112+
.buffer
113+
.asByteData());
114+
assert(success);
115+
}
116+
117+
@pragma('vm:entry-point')
118+
void textureOverwriteThrowsForWrongBufferSize() {
119+
final gpu.Texture? texture =
120+
gpu.gpuContext.createTexture(gpu.StorageMode.hostVisible, 100, 100);
121+
assert(texture != null);
122+
final ui.Color red = ui.Color.fromARGB(0xFF, 0xFF, 0, 0);
123+
String? exception;
124+
try {
125+
texture!.overwrite(
126+
Int32List.fromList(<int>[red.value, red.value, red.value, red.value])
127+
.buffer
128+
.asByteData());
129+
} catch (e) {
130+
exception = e.toString();
131+
}
132+
assert(exception!.contains(
133+
'The length of sourceBytes (bytes: 16) must exactly match the size of the base mip level (bytes: 40000)'));
134+
}
135+
136+
@pragma('vm:entry-point')
137+
void textureAsImageReturnsAValidUIImageHandle() {
138+
final gpu.Texture? texture =
139+
gpu.gpuContext.createTexture(gpu.StorageMode.hostVisible, 100, 100);
140+
assert(texture != null);
141+
142+
final ui.Image image = texture!.asImage();
143+
assert(image.width == 100);
144+
assert(image.height == 100);
145+
}
146+
147+
@pragma('vm:entry-point')
148+
void textureAsImageThrowsWhenNotShaderReadable() {
149+
final gpu.Texture? texture = gpu.gpuContext.createTexture(
150+
gpu.StorageMode.hostVisible, 100, 100,
151+
enableShaderReadUsage: false);
152+
assert(texture != null);
153+
String? exception;
154+
try {
155+
texture!.asImage();
156+
} catch (e) {
157+
exception = e.toString();
158+
}
159+
assert(exception!.contains(
160+
'Only shader readable Flutter GPU textures can be used as UI Images'));
161+
}

impeller/renderer/renderer_dart_unittests.cc

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class RendererDartTest : public PlaygroundTest,
5050
flutter::testing::AutoIsolateShutdown* GetIsolate() {
5151
// Sneak the context into the Flutter GPU API.
5252
assert(GetContext() != nullptr);
53-
flutter::Context::SetOverrideContext(GetContext());
53+
flutter::gpu::Context::SetOverrideContext(GetContext());
5454

5555
return isolate_.get();
5656
}
@@ -128,11 +128,17 @@ TEST_P(RendererDartTest, CanInstantiateFlutterGPUContext) {
128128
/// `flutter/impeller/fixtures/dart_tests.dart`
129129

130130
DART_TEST_CASE(canEmplaceHostBuffer);
131-
DART_TEST_CASE(canCreateDeviceBuffer);
132131

132+
DART_TEST_CASE(canCreateDeviceBuffer);
133133
DART_TEST_CASE(canOverwriteDeviceBuffer);
134134
DART_TEST_CASE(deviceBufferOverwriteFailsWhenOutOfBounds);
135135
DART_TEST_CASE(deviceBufferOverwriteThrowsForNegativeDestinationOffset);
136136

137+
DART_TEST_CASE(canCreateTexture);
138+
DART_TEST_CASE(canOverwriteTexture);
139+
DART_TEST_CASE(textureOverwriteThrowsForWrongBufferSize);
140+
DART_TEST_CASE(textureAsImageReturnsAValidUIImageHandle);
141+
DART_TEST_CASE(textureAsImageThrowsWhenNotShaderReadable);
142+
137143
} // namespace testing
138144
} // namespace impeller

lib/gpu/BUILD.gn

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ source_set("gpu") {
4242
"host_buffer.h",
4343
"smoketest.cc",
4444
"smoketest.h",
45+
"texture.cc",
46+
"texture.h",
4547
]
4648
}
4749
deps = [

lib/gpu/context.cc

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "tonic/converter/dart_converter.h"
1313

1414
namespace flutter {
15+
namespace gpu {
1516

1617
IMPLEMENT_WRAPPERTYPEINFO(gpu, Context);
1718

@@ -34,6 +35,7 @@ std::shared_ptr<impeller::Context> Context::GetContext() {
3435
return context_;
3536
}
3637

38+
} // namespace gpu
3739
} // namespace flutter
3840

3941
//----------------------------------------------------------------------------
@@ -44,7 +46,7 @@ Dart_Handle InternalFlutterGpu_Context_InitializeDefault(Dart_Handle wrapper) {
4446
auto dart_state = flutter::UIDartState::Current();
4547

4648
std::shared_ptr<impeller::Context> impeller_context =
47-
flutter::Context::GetDefaultContext();
49+
flutter::gpu::Context::GetDefaultContext();
4850

4951
if (!impeller_context) {
5052
if (!dart_state->IsImpellerEnabled()) {
@@ -68,8 +70,27 @@ Dart_Handle InternalFlutterGpu_Context_InitializeDefault(Dart_Handle wrapper) {
6870
if (!impeller_context) {
6971
return tonic::ToDart("Unable to retrieve the Impeller context.");
7072
}
71-
auto res = fml::MakeRefCounted<flutter::Context>(impeller_context);
73+
auto res = fml::MakeRefCounted<flutter::gpu::Context>(impeller_context);
7274
res->AssociateWithDartWrapper(wrapper);
7375

7476
return Dart_Null();
7577
}
78+
79+
///
80+
extern int InternalFlutterGpu_Context_GetDefaultColorFormat(
81+
flutter::gpu::Context* wrapper) {
82+
return static_cast<int>(
83+
wrapper->GetContext()->GetCapabilities()->GetDefaultColorFormat());
84+
}
85+
86+
extern int InternalFlutterGpu_Context_GetDefaultStencilFormat(
87+
flutter::gpu::Context* wrapper) {
88+
return static_cast<int>(
89+
wrapper->GetContext()->GetCapabilities()->GetDefaultStencilFormat());
90+
}
91+
92+
extern int InternalFlutterGpu_Context_GetDefaultDepthStencilFormat(
93+
flutter::gpu::Context* wrapper) {
94+
return static_cast<int>(
95+
wrapper->GetContext()->GetCapabilities()->GetDefaultDepthStencilFormat());
96+
}

lib/gpu/context.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "impeller/renderer/context.h"
1111

1212
namespace flutter {
13+
namespace gpu {
1314

1415
class Context : public RefCountedDartWrappable<Context> {
1516
DEFINE_WRAPPERTYPEINFO();
@@ -36,6 +37,7 @@ class Context : public RefCountedDartWrappable<Context> {
3637
FML_DISALLOW_COPY_AND_ASSIGN(Context);
3738
};
3839

40+
} // namespace gpu
3941
} // namespace flutter
4042

4143
//----------------------------------------------------------------------------
@@ -48,4 +50,20 @@ FLUTTER_GPU_EXPORT
4850
extern Dart_Handle InternalFlutterGpu_Context_InitializeDefault(
4951
Dart_Handle wrapper);
5052

53+
FLUTTER_GPU_EXPORT
54+
extern int InternalFlutterGpu_Context_GetBackendType(
55+
flutter::gpu::Context* wrapper);
56+
57+
FLUTTER_GPU_EXPORT
58+
extern int InternalFlutterGpu_Context_GetDefaultColorFormat(
59+
flutter::gpu::Context* wrapper);
60+
61+
FLUTTER_GPU_EXPORT
62+
extern int InternalFlutterGpu_Context_GetDefaultStencilFormat(
63+
flutter::gpu::Context* wrapper);
64+
65+
FLUTTER_GPU_EXPORT
66+
extern int InternalFlutterGpu_Context_GetDefaultDepthStencilFormat(
67+
flutter::gpu::Context* wrapper);
68+
5169
} // extern "C"

lib/gpu/device_buffer.cc

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "tonic/converter/dart_converter.h"
1616

1717
namespace flutter {
18+
namespace gpu {
1819

1920
IMPLEMENT_WRAPPERTYPEINFO(gpu, DeviceBuffer);
2021

@@ -35,16 +36,18 @@ bool DeviceBuffer::Overwrite(const tonic::DartByteData& source_bytes,
3536
return true;
3637
}
3738

39+
} // namespace gpu
3840
} // namespace flutter
3941

4042
//----------------------------------------------------------------------------
4143
/// Exports
4244
///
4345

44-
bool InternalFlutterGpu_DeviceBuffer_Initialize(Dart_Handle wrapper,
45-
flutter::Context* gpu_context,
46-
int storage_mode,
47-
int size_in_bytes) {
46+
bool InternalFlutterGpu_DeviceBuffer_Initialize(
47+
Dart_Handle wrapper,
48+
flutter::gpu::Context* gpu_context,
49+
int storage_mode,
50+
int size_in_bytes) {
4851
impeller::DeviceBufferDescriptor desc;
4952
desc.storage_mode = static_cast<impeller::StorageMode>(storage_mode);
5053
desc.size = size_in_bytes;
@@ -56,15 +59,15 @@ bool InternalFlutterGpu_DeviceBuffer_Initialize(Dart_Handle wrapper,
5659
}
5760

5861
auto res =
59-
fml::MakeRefCounted<flutter::DeviceBuffer>(std::move(device_buffer));
62+
fml::MakeRefCounted<flutter::gpu::DeviceBuffer>(std::move(device_buffer));
6063
res->AssociateWithDartWrapper(wrapper);
6164

6265
return true;
6366
}
6467

6568
bool InternalFlutterGpu_DeviceBuffer_InitializeWithHostData(
6669
Dart_Handle wrapper,
67-
flutter::Context* gpu_context,
70+
flutter::gpu::Context* gpu_context,
6871
Dart_Handle byte_data) {
6972
auto data = tonic::DartByteData(byte_data);
7073
auto mapping = fml::NonOwnedMapping(reinterpret_cast<uint8_t*>(data.data()),
@@ -78,14 +81,14 @@ bool InternalFlutterGpu_DeviceBuffer_InitializeWithHostData(
7881
}
7982

8083
auto res =
81-
fml::MakeRefCounted<flutter::DeviceBuffer>(std::move(device_buffer));
84+
fml::MakeRefCounted<flutter::gpu::DeviceBuffer>(std::move(device_buffer));
8285
res->AssociateWithDartWrapper(wrapper);
8386

8487
return true;
8588
}
8689

8790
bool InternalFlutterGpu_DeviceBuffer_Overwrite(
88-
flutter::DeviceBuffer* device_buffer,
91+
flutter::gpu::DeviceBuffer* device_buffer,
8992
Dart_Handle source_byte_data,
9093
int destination_offset_in_bytes) {
9194
return device_buffer->Overwrite(tonic::DartByteData(source_byte_data),

lib/gpu/device_buffer.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "third_party/tonic/typed_data/dart_byte_data.h"
1212

1313
namespace flutter {
14+
namespace gpu {
1415

1516
class DeviceBuffer : public RefCountedDartWrappable<DeviceBuffer> {
1617
DEFINE_WRAPPERTYPEINFO();
@@ -30,6 +31,7 @@ class DeviceBuffer : public RefCountedDartWrappable<DeviceBuffer> {
3031
FML_DISALLOW_COPY_AND_ASSIGN(DeviceBuffer);
3132
};
3233

34+
} // namespace gpu
3335
} // namespace flutter
3436

3537
//----------------------------------------------------------------------------
@@ -41,19 +43,19 @@ extern "C" {
4143
FLUTTER_GPU_EXPORT
4244
extern bool InternalFlutterGpu_DeviceBuffer_Initialize(
4345
Dart_Handle wrapper,
44-
flutter::Context* gpu_context,
46+
flutter::gpu::Context* gpu_context,
4547
int storage_mode,
4648
int size_in_bytes);
4749

4850
FLUTTER_GPU_EXPORT
4951
extern bool InternalFlutterGpu_DeviceBuffer_InitializeWithHostData(
5052
Dart_Handle wrapper,
51-
flutter::Context* gpu_context,
53+
flutter::gpu::Context* gpu_context,
5254
Dart_Handle byte_data);
5355

5456
FLUTTER_GPU_EXPORT
5557
extern bool InternalFlutterGpu_DeviceBuffer_Overwrite(
56-
flutter::DeviceBuffer* wrapper,
58+
flutter::gpu::DeviceBuffer* wrapper,
5759
Dart_Handle source_byte_data,
5860
int destination_offset_in_bytes);
5961

lib/gpu/host_buffer.cc

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "third_party/tonic/typed_data/dart_byte_data.h"
1010

1111
namespace flutter {
12+
namespace gpu {
1213

1314
IMPLEMENT_WRAPPERTYPEINFO(gpu, HostBuffer);
1415

@@ -23,18 +24,20 @@ size_t HostBuffer::EmplaceBytes(const tonic::DartByteData& byte_data) {
2324
return view.range.offset;
2425
}
2526

27+
} // namespace gpu
2628
} // namespace flutter
2729

2830
//----------------------------------------------------------------------------
2931
/// Exports
3032
///
3133

3234
void InternalFlutterGpu_HostBuffer_Initialize(Dart_Handle wrapper) {
33-
auto res = fml::MakeRefCounted<flutter::HostBuffer>();
35+
auto res = fml::MakeRefCounted<flutter::gpu::HostBuffer>();
3436
res->AssociateWithDartWrapper(wrapper);
3537
}
3638

37-
size_t InternalFlutterGpu_HostBuffer_EmplaceBytes(flutter::HostBuffer* wrapper,
38-
Dart_Handle byte_data) {
39+
size_t InternalFlutterGpu_HostBuffer_EmplaceBytes(
40+
flutter::gpu::HostBuffer* wrapper,
41+
Dart_Handle byte_data) {
3942
return wrapper->EmplaceBytes(tonic::DartByteData(byte_data));
4043
}

lib/gpu/host_buffer.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "third_party/tonic/typed_data/dart_byte_data.h"
1111

1212
namespace flutter {
13+
namespace gpu {
1314

1415
class HostBuffer : public RefCountedDartWrappable<HostBuffer> {
1516
DEFINE_WRAPPERTYPEINFO();
@@ -28,6 +29,7 @@ class HostBuffer : public RefCountedDartWrappable<HostBuffer> {
2829
FML_DISALLOW_COPY_AND_ASSIGN(HostBuffer);
2930
};
3031

32+
} // namespace gpu
3133
} // namespace flutter
3234

3335
//----------------------------------------------------------------------------
@@ -41,7 +43,7 @@ extern void InternalFlutterGpu_HostBuffer_Initialize(Dart_Handle wrapper);
4143

4244
FLUTTER_GPU_EXPORT
4345
extern size_t InternalFlutterGpu_HostBuffer_EmplaceBytes(
44-
flutter::HostBuffer* wrapper,
46+
flutter::gpu::HostBuffer* wrapper,
4547
Dart_Handle byte_data);
4648

4749
} // extern "C"

0 commit comments

Comments
 (0)