Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[dart:ui] Adds a reusable FragmentShader #35253

Merged
merged 1 commit into from
Aug 31, 2022

Conversation

zanderso
Copy link
Member

@zanderso zanderso commented Aug 9, 2022

This PR adds a new FragmentShader subclass of Shader that does not require allocating new uniform and sampler arrays on every frame. Instead the float and sampler uniforms are backed by native allocations, whose entries can be updated between uses.

Like an ImageShader, the FragmentShader should be disposed. Instead of copy-pasting that code from ImageShader, this PR also moves the dispose() and debugDisposed methods to the Shader class.

After use of this API propagates to the framework, I'll remove the old API.

@zanderso zanderso added the Work in progress (WIP) Not ready (yet) for review! label Aug 9, 2022
@zanderso zanderso marked this pull request as draft August 9, 2022 03:50
@zanderso
Copy link
Member Author

zanderso commented Aug 9, 2022

@jonahwilliams wdyt?

@zanderso zanderso force-pushed the fragment-shader-builder branch from 30da86c to 4c98a67 Compare August 9, 2022 14:51
@jonahwilliams
Copy link
Member

From offline discussion: really like that we can dramatically cut down on typed data copying, and love the additional documentation. My only potential concern is that multiple shaders created from the same builder will have the same backing data, which may or may not be surprising. What if the Shader was more like a paint object and had mutable uniforms? Might be more obvious how that behaves - but this is an educated guess since the shader APIs aren't widely used.

@zanderso zanderso force-pushed the fragment-shader-builder branch from 4c98a67 to 8873298 Compare August 10, 2022 04:40
@zanderso zanderso force-pushed the fragment-shader-builder branch from 8873298 to ca6d566 Compare August 27, 2022 04:42
@zanderso zanderso changed the title [dart:ui] Adds FragmentShaderBuilder [dart:ui] Adds a reusable FragmentShader Aug 27, 2022
@zanderso zanderso force-pushed the fragment-shader-builder branch 7 times, most recently from 5255a87 to 4b18c16 Compare August 28, 2022 22:52
@flutter-dashboard flutter-dashboard bot added the platform-web Code specifically for the web engine label Aug 29, 2022
@zanderso zanderso marked this pull request as ready for review August 29, 2022 18:17
@zanderso
Copy link
Member Author

The InkSparkle in the framework will look roughly like this flutter/flutter#110552.

@jonahwilliams
Copy link
Member

I will take an indepth pass on this tomorrow, but so far I really like this API

Comment on lines +68 to +73
auto* fragment_program =
tonic::DartConverter<FragmentProgram*>::FromDart(program);
uint64_t float_count =
tonic::DartConverter<uint64_t>::FromDart(float_count_handle);
uint64_t sampler_count =
tonic::DartConverter<uint64_t>::FromDart(sampler_count_handle);
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: if you type these in the declaration tonic will just do this for you.

Copy link
Member Author

Choose a reason for hiding this comment

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

That's how I had it at first, but the integer parameters were getting the value of the Dart_Handle rather than the value wrapped by the Dart_Handle. I'm going to leave these as is, and try to make a repro of the issue I was seeing.

Copy link
Contributor

@dnfield dnfield left a comment

Choose a reason for hiding this comment

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

Just nits

lib/ui/painting.dart Outdated Show resolved Hide resolved
lib/ui/painting.dart Outdated Show resolved Hide resolved
lib/ui/painting.dart Outdated Show resolved Hide resolved
lib/ui/painting.dart Outdated Show resolved Hide resolved
lib/ui/painting.dart Outdated Show resolved Hide resolved
lib/ui/painting.dart Outdated Show resolved Hide resolved
@zanderso zanderso force-pushed the fragment-shader-builder branch from 4b18c16 to 5c810cf Compare August 30, 2022 22:11
/// only `shader.setFloat(0, newValue)` needs to be called. The other uniforms
/// will retain their values. The sampler uniforms will also persist in the same
/// way.
class FragmentShader extends Shader {
Copy link
Member

Choose a reason for hiding this comment

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

Another approach, if the ergonomics of setFloat aren't to your liking. Just create a view of the original object:

class Float32Uniforms {
  FragmentShader? _instance;
  
  operator[]=(int index, double value) {
     assert(disposedStuff);
     _instance._setFloat(index, value);
   }
}

class FragmentShader {
  Float32Uniforms _floatUniforms;
  Float32Uniforms get floatUniforms => _floatUniforms;
  
  void dispose() {
    _floatUniforms._instance = null;
  }
}

Copy link
Member Author

Choose a reason for hiding this comment

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

I trust the VM's ability to inline the simple wrapper that's currently in the PR. Adding more indirection would make me start to worry...

Copy link
Member

Choose a reason for hiding this comment

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

no prob. might be possible to do "for free" someday with views when/if they come out:

view Float32Uniforms on FragmentShader {
  void operator[]=(int index, double value) => this.setFloat(index, value);
}

class FragmentShader {
  Float32Uniforms get floatUniforms => this as Float32Uniforms;
}

/// twice will also result in an exception being thrown.
@override
void dispose() {
super.dispose();
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: call super.dispose last, since it might rip something out from under you

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, hm, probably should call _dispose last since it deletes the native peer though...

Copy link
Member Author

Choose a reason for hiding this comment

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

Right.

@zanderso zanderso force-pushed the fragment-shader-builder branch from 5c810cf to 1fa30da Compare August 31, 2022 01:40
Copy link
Member

@jonahwilliams jonahwilliams left a comment

Choose a reason for hiding this comment

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

Lgtm

@zanderso zanderso merged commit e114573 into flutter:main Aug 31, 2022
@zanderso zanderso deleted the fragment-shader-builder branch August 31, 2022 03:22
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Aug 31, 2022
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Aug 31, 2022
zanderso added a commit that referenced this pull request Aug 31, 2022
zanderso added a commit that referenced this pull request Aug 31, 2022
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Aug 31, 2022
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Aug 31, 2022
zanderso pushed a commit to flutter/flutter that referenced this pull request Aug 31, 2022
…110697)

* d782c3303 [web] roll CanvasKit to 0.36.1 (flutter/engine#35747)

* 300592bc8 allows mallocmapping copies of size zero (flutter/engine#35803)

* 61e4c0715 Generate mac os framework with a global generator. (flutter/engine#35673)

* 7a03a54a8 Roll Skia from 545e45ab4d5d to 27a2eeacd330 (11 revisions) (flutter/engine#35805)

* 89909d966 Fix DartPerformanceMode enum mismatch (flutter/engine#35806)

* ead134880 Queue all semantic nodes & actions before completing batch (flutter/engine#35792)

* adec6edb0 Run clang-tidy and Mac Unopt on Xcode beta (flutter/engine#35793)

* eb6e2e08c Roll Skia from 27a2eeacd330 to 18b36bd2e2a3 (1 revision) (flutter/engine#35807)

* e74352c7f Remove extract_far.dart (flutter/engine#35801)

* 5ee7b3816 Test cover 'toImage'. (flutter/engine#35791)

* 8ed1e6ca7 Roll Skia from 18b36bd2e2a3 to 7c67a21eec59 (3 revisions) (flutter/engine#35810)

* cc2a32332 Roll Dart SDK from 9faec45da06c to 7e5a69f6b25f (1 revision) (flutter/engine#35811)

* c2a2a5679 Roll Fuchsia Linux SDK from NwG1XTWHxB9R3XcU5... to usGLIrlCJW1C1yaF1... (flutter/engine#35812)

* 8ab3b8f5a Migrate testing/symbols to null safety (flutter/engine#35809)

* 7e27b923b Roll Skia from 7c67a21eec59 to 3abad1ab16cc (1 revision) (flutter/engine#35816)

* 4cb5be089 [web] remove references to IE11 and old Edge; treat Samsung browser as Blink (flutter/engine#35205)

* 5154b8ac0 Roll Fuchsia Mac SDK from 4GZkuoQmvVanO84uA... to V_dBCcwGfOqJkrG9b... (flutter/engine#35817)

* b5a5a0dc7 Roll Dart SDK from 7e5a69f6b25f to 5a2737b71877 (1 revision) (flutter/engine#35818)

* e11457362 [dart:ui] Adds a reusable FragmentShader (flutter/engine#35253)

* 26d6bcfd6 Roll Skia from 3abad1ab16cc to a7829f6da292 (1 revision) (flutter/engine#35819)

* 6c9f6f5b8 Roll Skia from a7829f6da292 to 83b5d7ae4bca (2 revisions) (flutter/engine#35821)

* 169181f8d Make shader mask layer code builder aware (flutter/engine#35622)

* 06925ed06 Roll Fuchsia Linux SDK from usGLIrlCJW1C1yaF1... to 5YEIlndU4ncjOl9I_... (flutter/engine#35824)

* 7a40a0a26 Roll Skia from 83b5d7ae4bca to e4a2061eb1fc (1 revision) (flutter/engine#35826)

* 43ee40e31 Engine startup event timed after VM initializes (flutter/engine#35713)

* 9eb524bad Roll Fuchsia Mac SDK from V_dBCcwGfOqJkrG9b... to sgXD5SyRPOxGjWV4q... (flutter/engine#35829)

* cfdc83ad6 Roll Skia from e4a2061eb1fc to 34df0f94c849 (1 revision) (flutter/engine#35828)

* 90d65fa5f fix null access for CkParagraph.dispose (flutter/engine#35815)

* ef039c197 Update the API check script for the latest Dart analyzer APIs (flutter/engine#35831)

* c3c872776 Revert "[web] roll CanvasKit to 0.36.1 (#35747)" (flutter/engine#35837)

* db97b55d0 Roll Skia from 34df0f94c849 to e0b87738eca7 (5 revisions) (flutter/engine#35832)

* f69e0ccc3 add enterkeyhint property to web textfields (flutter/engine#35411)

* 54a1b59c9 Add a comment in the scenario app to meet the latest analyzer requirements (flutter/engine#35838)

* d993e0d55 Revert "[dart:ui] Adds a reusable FragmentShader (#35253)" (flutter/engine#35843)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
platform-web Code specifically for the web engine Work in progress (WIP) Not ready (yet) for review!
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants