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

[Flutter GPU] Use vm.Vector4 for clear color instead of ui.Color. #55416

Merged
merged 2 commits into from
Sep 25, 2024
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
2 changes: 2 additions & 0 deletions lib/gpu/lib/gpu.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import 'dart:typed_data';
// ignore: uri_does_not_exist
import 'dart:ui' as ui;

import 'package:vector_math/vector_math.dart' as vm;

part 'src/buffer.dart';
part 'src/command_buffer.dart';
part 'src/context.dart';
Expand Down
36 changes: 21 additions & 15 deletions lib/gpu/lib/src/render_pass.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ base class ColorAttachment {
ColorAttachment({
this.loadAction = LoadAction.clear,
this.storeAction = StoreAction.store,
this.clearValue = const ui.Color(0x00000000),
vm.Vector4? clearValue = null,
Copy link
Contributor

Choose a reason for hiding this comment

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

Vector4 (and all vector math classes) are backed by a fixed size TypedData array that aren't const constructable.

Copy link
Member Author

Choose a reason for hiding this comment

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

Meh, oh well. :/ Thanks for taking a look.

required this.texture,
this.resolveTexture = null,
});
}) : clearValue = clearValue ?? vm.Vector4.zero();

LoadAction loadAction;
StoreAction storeAction;
ui.Color clearValue;
vm.Vector4 clearValue;

Texture texture;
Texture? resolveTexture;
Expand Down Expand Up @@ -121,15 +121,6 @@ base class RenderTarget {
final DepthStencilAttachment? depthStencilAttachment;
}

// TODO(gaaclarke): Refactor this to support wide gamut colors.
int _colorToInt(ui.Color color) {
assert(color.colorSpace == ui.ColorSpace.sRGB);
return ((color.a * 255.0).round() << 24) |
((color.r * 255.0).round() << 16) |
((color.g * 255.0).round() << 8) |
((color.b * 255.0).round() << 0);
}

base class RenderPass extends NativeFieldWrapperClass1 {
/// Creates a new RenderPass.
RenderPass._(CommandBuffer commandBuffer, RenderTarget renderTarget) {
Expand All @@ -140,7 +131,10 @@ base class RenderPass extends NativeFieldWrapperClass1 {
index,
color.loadAction.index,
color.storeAction.index,
_colorToInt(color.clearValue),
color.clearValue.r,
color.clearValue.g,
color.clearValue.b,
color.clearValue.a,
color.texture,
color.resolveTexture);
if (error != null) {
Expand Down Expand Up @@ -276,13 +270,25 @@ base class RenderPass extends NativeFieldWrapperClass1 {
external void _initialize();

@Native<
Handle Function(Pointer<Void>, Int, Int, Int, Int, Pointer<Void>,
Handle Function(
Pointer<Void>,
Int,
Int,
Int,
Float,
Float,
Float,
Float,
Pointer<Void>,
Handle)>(symbol: 'InternalFlutterGpu_RenderPass_SetColorAttachment')
external String? _setColorAttachment(
int colorAttachmentIndex,
int loadAction,
int storeAction,
int clearColor,
double clearColorR,
double clearColorG,
double clearColorB,
double clearColorA,
Texture texture,
Texture? resolveTexture);

Expand Down
5 changes: 5 additions & 0 deletions lib/gpu/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,10 @@ environment:
sdk: '>=3.2.0-0 <4.0.0'

dependencies:
# To update these, use "flutter update-packages --force-upgrade".
#
# For detailed instructions, refer to:
# https://github.com/flutter/flutter/blob/main/docs/infra/Updating-dependencies-in-Flutter.md
vector_math: ^2.1.4
sky_engine:
sdk: flutter
15 changes: 6 additions & 9 deletions lib/gpu/render_pass.cc
Original file line number Diff line number Diff line change
Expand Up @@ -190,13 +190,6 @@ bool RenderPass::Draw() {
} // namespace gpu
} // namespace flutter

static impeller::Color ToImpellerColor(uint32_t argb) {
return impeller::Color::MakeRGBA8((argb >> 16) & 0xFF, // R
(argb >> 8) & 0xFF, // G
argb & 0xFF, // B
argb >> 24); // A
}

//----------------------------------------------------------------------------
/// Exports
///
Expand All @@ -211,13 +204,17 @@ Dart_Handle InternalFlutterGpu_RenderPass_SetColorAttachment(
int color_attachment_index,
int load_action,
int store_action,
int clear_color,
float clear_color_r,
float clear_color_g,
float clear_color_b,
float clear_color_a,
flutter::gpu::Texture* texture,
Dart_Handle resolve_texture_wrapper) {
impeller::ColorAttachment desc;
desc.load_action = flutter::gpu::ToImpellerLoadAction(load_action);
desc.store_action = flutter::gpu::ToImpellerStoreAction(store_action);
desc.clear_color = ToImpellerColor(static_cast<uint32_t>(clear_color));
desc.clear_color = impeller::Color(clear_color_r, clear_color_g,
clear_color_b, clear_color_a);
desc.texture = texture->GetTexture();
if (!Dart_IsNull(resolve_texture_wrapper)) {
flutter::gpu::Texture* resolve_texture =
Expand Down
5 changes: 4 additions & 1 deletion lib/gpu/render_pass.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,10 @@ extern Dart_Handle InternalFlutterGpu_RenderPass_SetColorAttachment(
int color_attachment_index,
int load_action,
int store_action,
int clear_color,
float clear_color_r,
float clear_color_g,
float clear_color_b,
float clear_color_a,
flutter::gpu::Texture* texture,
Dart_Handle resolve_texture_wrapper);

Expand Down
15 changes: 13 additions & 2 deletions testing/dart/gpu_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import 'dart:typed_data';
import 'dart:ui' as ui;

import 'package:test/test.dart';
import 'package:vector_math/vector_math.dart';

import '../../lib/gpu/lib/gpu.dart' as gpu;

Expand Down Expand Up @@ -41,7 +42,7 @@ class RenderPassState {
}

/// Create a simple RenderPass with simple color and depth-stencil attachments.
RenderPassState createSimpleRenderPass() {
RenderPassState createSimpleRenderPass({Vector4? clearColor}) {
final gpu.Texture? renderTexture =
gpu.gpuContext.createTexture(gpu.StorageMode.devicePrivate, 100, 100);
assert(renderTexture != null);
Expand All @@ -53,7 +54,7 @@ RenderPassState createSimpleRenderPass() {
final gpu.CommandBuffer commandBuffer = gpu.gpuContext.createCommandBuffer();

final gpu.RenderTarget renderTarget = gpu.RenderTarget.singleColor(
gpu.ColorAttachment(texture: renderTexture!),
gpu.ColorAttachment(texture: renderTexture!, clearValue: clearColor),
depthStencilAttachment:
gpu.DepthStencilAttachment(texture: depthStencilTexture!));

Expand Down Expand Up @@ -313,6 +314,16 @@ void main() async {
}
}, skip: !impellerEnabled);

// Performs no draw calls. Just clears the render target to a solid green color.
test('Can render clear color', () async {
final state = createSimpleRenderPass(clearColor: Colors.lime);

state.commandBuffer.submit();

final ui.Image image = state.renderTexture.asImage();
await comparer.addGoldenImage(image, 'flutter_gpu_test_clear_color.png');
}, skip: !impellerEnabled);

// Renders a green triangle pointing downwards.
test('Can render triangle', () async {
final state = createSimpleRenderPass();
Expand Down