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

Conversation

@dnfield
Copy link
Contributor

@dnfield dnfield commented Mar 14, 2023

Fixes flutter/flutter#122566

The cause of that bug is that multiple dependent toImageSync calls are made such that each successive image depends on the previous one.

In the current implementation, a std::map is causing the OnGrContextCreated calls to happen in sort-order based on pointer values. This patch adds another map to track the insertion order and a test to make sure that the callbacks respect insertion order.

@dnfield dnfield requested a review from jason-simmons March 14, 2023 06:04
uintptr_t id,
std::weak_ptr<ContextListener> image) {
images_[id] = std::move(image);
size_t next_id = image_counter_.fetch_add(1);
Copy link
Member

Choose a reason for hiding this comment

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

C++ operator overloading of ++ does this for you already. IMO that is more readable that fetch_add.

Copy link
Member

Choose a reason for hiding this comment

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

Besides, does this need to be an atomic? I thought all texture registry operations were raster thread only.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I guess it doesn't need to be atomic. I was being overly cautious :)

} else {
images_.erase(id);
image_indices_.erase(index_id);
ordered_images_.erase(id);
Copy link
Member

Choose a reason for hiding this comment

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

Here and elsewhere, mutation while enumeration makes me nervous. Are iterators on ordered_images_ invalidated when the erase happens here?

Copy link
Member

Choose a reason for hiding this comment

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

Used to doing this safely by using iterators explicitly and assigning the iterator to the return call of erase. I am not sure I have ever done it this way. So want to double check this is safe.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I'll change this. It seems to work but it'd be safer to use the iterator.

I had another issue with mutation during iteration that I fixed by copying the map into a vector, but that would be overkill here.

// This map makes sure that iteration of images happens in insertion order
// (managed by image_counter_) so that images which depend on other images get
// re-created in the right order.
std::map<size_t, std::pair<uintptr_t, std::weak_ptr<ContextListener>>>
Copy link
Member

Choose a reason for hiding this comment

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

I guess this makes sense but is a bit rough to read. How about we take advantage of the fact that the map is ordered already and store the existing key and the order as a key type. Then you can have a custom std::less on the key type and typedef the whole thing for more readibility. Iterating over the map elements will be order then. I suppose you will need a separate map for the removal (a unintptr to order association).

Just a suggestion.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I considered that but it comes down to either storing extra data in the key or extra data in the value.

This makes the key easier to hash and avoids the need for a custom comparer that ignores part of the data. I'll use the typedef though.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

(if I didn't need to worry about updating the order when someone re-registers I could just use a std::vector)

@dnfield dnfield added the autosubmit Merge PR when tree becomes green via auto submit App label Mar 14, 2023
@auto-submit auto-submit bot merged commit db79f01 into flutter:main Mar 14, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Mar 14, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Mar 14, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Mar 14, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Mar 15, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Mar 15, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Mar 15, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Mar 15, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Mar 15, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Mar 15, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Mar 15, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Mar 15, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

autosubmit Merge PR when tree becomes green via auto submit App

Projects

None yet

Development

Successfully merging this pull request may close these issues.

toImageSync throws away *part of* the oldest content, both violating its API semantics and seems to violate rasterization

2 participants