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

Composite multiple layers in Windows software rendering #51759

Merged
merged 20 commits into from
Apr 11, 2024

Conversation

yaakovschectman
Copy link
Contributor

Blend pixels per-alpha when presenting multiple layers from the software compositor.

Part of flutter/flutter#143375

Pre-launch Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I read and followed the Flutter Style Guide and the C++, Objective-C, Java style guides.
  • I listed at least one issue that this PR fixes in the description above.
  • I added new tests to check the change I am making or feature I am adding, or the PR is test-exempt. See testing the engine for instructions on writing and running engine tests.
  • I updated/added relevant documentation (doc comments with ///).
  • I signed the CLA.
  • All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel on Discord.

@yaakovschectman yaakovschectman marked this pull request as ready for review March 29, 2024 18:31

int width = x_max - x_min;
int height = y_max - y_min;
std::vector<uint32_t> allocation(width * height);
Copy link
Member

@loic-sharma loic-sharma Mar 29, 2024

Choose a reason for hiding this comment

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

Can we avoid this allocation if there's only 1 layer?


return view->PresentSoftwareBitmap(
backing_store.allocation, backing_store.row_bytes, backing_store.height);
int x_min = INT_MAX;
Copy link
Member

Choose a reason for hiding this comment

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

Could we split this up and have a helper for the compositing step?

// Overlay layer has pixel values:
// RED: 127 WHITE: 0
// BLUE: 127 BLACK: 255
TEST_F(CompositorSoftwareTest, PresentMultiLayers) {
Copy link
Member

Choose a reason for hiding this comment

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

Could we also have a test for layers that don't overlap fully?

@yaakovschectman
Copy link
Contributor Author

yaakovschectman commented Apr 1, 2024 via email

@yaakovschectman
Copy link
Contributor Author

yaakovschectman commented Apr 1, 2024 via email

@yaakovschectman
Copy link
Contributor Author

yaakovschectman commented Apr 1, 2024 via email

Copy link
Member

@cbracken cbracken left a comment

Choose a reason for hiding this comment

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

Overall looks good - just a few comments!

auto& offset = layer.offset;
auto& size = layer.size;

for (int y_src = 0; y_src < size.height; y_src++) {
Copy link
Member

Choose a reason for hiding this comment

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

Will take a closer look, but first thoughts:

  1. but it feels like it should be possible to update the loop conditions to avoid the two < 0, >= height checks below.
  2. this feels like there should be a way to parallelise this a bit

Copy link
Contributor Author

@yaakovschectman yaakovschectman Apr 4, 2024

Choose a reason for hiding this comment

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

I suppose the obvious way to parallelize this would be to use the GPU, but this is the software compositor, so that seems self defeating.
Also, I will test adjusting the loop statements once it rebuilds.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Feel free to check now.

Copy link
Member

@loic-sharma loic-sharma Apr 5, 2024

Choose a reason for hiding this comment

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

I suspect the right way to parallelize would be to vectorize this code if possible... I wonder if Windows has any helpers that can do efficient bitmap blending? If not, that seems like too much work for an MVP.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The only ones I'm familiar with work with HDCs instead of pixel data in memory, and so we would need to create those new DCs per layer to apply them as far as I understand

Comment on lines 67 to 84
int x_min = INT_MAX;
int x_max = INT_MIN;
int y_min = INT_MAX;
int y_max = INT_MIN;
for (const FlutterLayer** layer = layers; layer < layers + layers_count;
layer++) {
const FlutterPoint& offset = (*layer)->offset;
const FlutterSize& size = (*layer)->size;
// FlutterPoint and FlutterSize store coordinates as doubles.
// Coordinates must be truncated to integers to represent whole pixels.
x_min = std::min(x_min, static_cast<int>(offset.x));
y_min = std::min(y_min, static_cast<int>(offset.y));
x_max = std::max(x_max, static_cast<int>(offset.x + size.width));
y_max = std::max(y_max, static_cast<int>(offset.y + size.height));
}

int width = x_max - x_min;
int height = y_max - y_min;
Copy link
Member

Choose a reason for hiding this comment

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

Could we add a helper for the logic to calculate the position/size of the present?

width * 4, height);
}

void CompositorSoftware::BlendLayer(std::vector<uint32_t>& allocation,
Copy link
Member

Choose a reason for hiding this comment

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

Instead of an instance method that's declared in the header, should we make this be a top-level function in an anonymous namespace in this file?

In my mind the header file is best for public APIs or methods that need to interact with instance fields. However, this helper is self-contained logic that doesn't require any instance members.

return view->PresentSoftwareBitmap(
backing_store.allocation, backing_store.row_bytes, backing_store.height);
return view->PresentSoftwareBitmap(static_cast<void*>(allocation.data()),
width * 4, height);
Copy link
Member

Choose a reason for hiding this comment

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

For someone not familiar with the bitmap allocation, this 4 might look like a magic value. Could we add a constant for the 4 with a quick comment for clarity?

Copy link
Member

@loic-sharma loic-sharma left a comment

Choose a reason for hiding this comment

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

LGTM, excellent work!

Copy link
Member

@cbracken cbracken left a comment

Choose a reason for hiding this comment

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

LGTM stamp from a Japanese personal seal

Pass two: lgtm! Awesome stuff!

@yaakovschectman yaakovschectman merged commit fb2722c into flutter:main Apr 11, 2024
26 checks passed
@yaakovschectman yaakovschectman deleted the software_layers branch April 11, 2024 14:25
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Apr 11, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Apr 11, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Apr 11, 2024
auto-submit bot pushed a commit to flutter/flutter that referenced this pull request Apr 11, 2024
…146645)

flutter/engine@d8560d4...98a8ad1

2024-04-11 [email protected] [et] Correctly plumb usage line length limit (flutter/engine#52039)
2024-04-11 [email protected] Revert "Roll Dart SDK from 3d13dbfb3284 to 764bdb7d0344 (1 revision) (#52051)" (flutter/engine#52060)
2024-04-11 [email protected] Composite multiple layers in Windows software rendering (flutter/engine#51759)
2024-04-11 98614782+auto-submit[bot]@users.noreply.github.com Reverts "Roll Dart SDK from 764bdb7d0344 to 0219e897c6ac (1 revision) (#52053)" (flutter/engine#52058)
2024-04-11 [email protected] Roll Skia from 2a2fe4303507 to 1dc3c2c1b550 (1 revision) (flutter/engine#52055)
2024-04-11 [email protected] Roll Skia from aa30d76a345f to 2a2fe4303507 (1 revision) (flutter/engine#52054)
2024-04-11 [email protected] Roll Dart SDK from 764bdb7d0344 to 0219e897c6ac (1 revision) (flutter/engine#52053)
2024-04-11 [email protected] Roll Skia from 29f0c9d84e70 to aa30d76a345f (1 revision) (flutter/engine#52052)
2024-04-11 [email protected] Roll Dart SDK from 3d13dbfb3284 to 764bdb7d0344 (1 revision) (flutter/engine#52051)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-engine-flutter-autoroll
Please CC [email protected],[email protected],[email protected] on the revert to ensure that a human
is aware of the problem.

To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
gilnobrega pushed a commit to gilnobrega/flutter that referenced this pull request Apr 22, 2024
…lutter#146645)

flutter/engine@d8560d4...98a8ad1

2024-04-11 [email protected] [et] Correctly plumb usage line length limit (flutter/engine#52039)
2024-04-11 [email protected] Revert "Roll Dart SDK from 3d13dbfb3284 to 764bdb7d0344 (1 revision) (flutter#52051)" (flutter/engine#52060)
2024-04-11 [email protected] Composite multiple layers in Windows software rendering (flutter/engine#51759)
2024-04-11 98614782+auto-submit[bot]@users.noreply.github.com Reverts "Roll Dart SDK from 764bdb7d0344 to 0219e897c6ac (1 revision) (flutter#52053)" (flutter/engine#52058)
2024-04-11 [email protected] Roll Skia from 2a2fe4303507 to 1dc3c2c1b550 (1 revision) (flutter/engine#52055)
2024-04-11 [email protected] Roll Skia from aa30d76a345f to 2a2fe4303507 (1 revision) (flutter/engine#52054)
2024-04-11 [email protected] Roll Dart SDK from 764bdb7d0344 to 0219e897c6ac (1 revision) (flutter/engine#52053)
2024-04-11 [email protected] Roll Skia from 29f0c9d84e70 to aa30d76a345f (1 revision) (flutter/engine#52052)
2024-04-11 [email protected] Roll Dart SDK from 3d13dbfb3284 to 764bdb7d0344 (1 revision) (flutter/engine#52051)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-engine-flutter-autoroll
Please CC [email protected],[email protected],[email protected] on the revert to ensure that a human
is aware of the problem.

To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

3 participants