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 Jul 27, 2022

Relies on currently unimplemented Skia API.

See flutter/flutter#108389


private:
std::map<int64_t, std::shared_ptr<Texture>> mapping_;
std::map<uint32_t, ContextDestroyedListener*> images_;
Copy link
Member

Choose a reason for hiding this comment

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

Hold the reference to the image via a smart pointer here.

The raw pointer makes it unclear how the listener object's lifetime is managed and creates the potential for leaks.

For example, TextureRegistry::UnregisterContextDestroyedListener is not dropping the reference added by Picture::RasterizeToImageSync.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

DlDeferredImageGPU::~DlDeferredImageGPU() {
fml::TaskRunner::RunNowOrPostTask(
raster_task_runner_,
[image = std::move(image_), unref_queue = std::move(unref_queue_),
Copy link
Member

Choose a reason for hiding this comment

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

image_ is an sk_sp member that is supposed to be accessed only from the raster thread. But here the std::move will be reading and writing it on the UI thread without synchronization. This is potentially a race.

The image should be accessed via something wrapped in a std::atomic.

This is a preexisting issue in the current DlDeferredImageGPU implementation and can be addressed in a separate PR. However, it may make sense to handle it here.
Given the issues related to the TextureRegistry/DlDeferredImageGPU circular reference, one option would be to hold the SkImage here via a std::atomic<shared_ptr> to a wrapper object. The TextureRegistry could then hold a weak_ptr to the wrapper.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done - because the shard_ptr specialization is C++20 only I'm using the std::atomic_load/store directly, which only requires C++11.

texture_registry = std::move(texture_registry_)]() {
if (image) {
if (texture_registry) {
texture_registry->UnregisterContextDestroyedListener(
Copy link
Member

Choose a reason for hiding this comment

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

The TextureRegistry needs to hold a reference to each DlDeferredImageGPU in order to ensure that the entries in images_ have not been deleted. But holding that reference will prevent the DlDeferredImageGPU from being destructed (at least until OnGrContextDestroyed is called and the TextureRegistry drops its reference).

The TextureRegistry may need to hold the images via some kind of weak pointer.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

fml::RefPtr<fml::TaskRunner> raster_task_runner_;
fml::RefPtr<SkiaUnrefQueue> unref_queue_;
sk_sp<SkImage> image_;
TextureRegistry* texture_registry_ = nullptr;
Copy link
Member

Choose a reason for hiding this comment

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

This raw pointer must be cleared before the TextureRegistry is destroyed during rasterizer teardown.

Is OnGrContextDestroyed guaranteed to run before that happens? Possibly that can clear this pointer.

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 changed this to a std::shared_ptr here and everywhere else.

@dnfield
Copy link
Contributor Author

dnfield commented Jul 28, 2022

I'm meeting with some Skia folks on Monday to discuss this further - @jason-simmons added you to that meeting as well. Need some more input from them about whether the linked Skia patch is safe enough or we need something else.

@dnfield
Copy link
Contributor Author

dnfield commented Aug 1, 2022

I'm going to abandon this in favor of a new patch that doesn't require any new Skia API and also incorporates the feedback from Jason.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants