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

Windows: FlutterDesktopPixelBuffer: Add optional release callback #28298

Merged

Conversation

jnschulze
Copy link
Member

@jnschulze jnschulze commented Aug 25, 2021

This PR adds an optional callback to FlutterDesktopPixelBuffer that gets invoked when it's safe to release the backing buffer (or unlock a mutex protecting that buffer etc.).

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 Hixie said 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.

@flutter-dashboard
Copy link

It looks like this pull request may not have tests. Please make sure to add tests before merging. If you need an exemption to this rule, contact Hixie on the #hackers channel in Chat.

If you are not sure if you need tests, consider this rule of thumb: the purpose of a test is to make sure someone doesn't accidentally revert the fix. Ask yourself, is there anything in your PR that you feel it is important we not accidentally revert back to how it was before your fix?

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing.

@jnschulze
Copy link
Member Author

@chinmaygarde

@chinmaygarde
Copy link
Member

I think this is a fine addition. But can we a test for this? I don't see an existing test for this so I am unable to provide any guidance here. Perhaps @cbracken might know.

@chinmaygarde chinmaygarde self-requested a review September 2, 2021 20:27
@cbracken
Copy link
Member

cbracken commented Sep 2, 2021

Will take a quick look -- I'm pretty sure I added a test for something similar a couple months back.

@cbracken cbracken self-requested a review September 2, 2021 20:28
@chinmaygarde
Copy link
Member

Chris may be busy with other things. To test this, I think we can just add a latch that is signalled in the unregistration callback and wait for it after calling FlutterEngineUnregisterExternalTexture. If the test times out, the watchdog should terminate the harness anyway. Since the test seems easy-ish to wire up, let's attempt to write one before landing this.

@jnschulze jnschulze force-pushed the pixelbuffer-add-release-callback branch from 074e2b2 to 61fb7ae Compare September 10, 2021 10:56
@jnschulze jnschulze force-pushed the pixelbuffer-add-release-callback branch from 61fb7ae to 4ada4b9 Compare September 10, 2021 11:24
@jnschulze
Copy link
Member Author

@chinmaygarde
I've mocked all gl* functions used by ExternalTextureGL and added a test for ExternalTextureGL::PopulateTexture (which invokes the newly introduced callback after the pixel buffer has been copied).
So we not only test the new callback but also the texture population itself.

@chinmaygarde chinmaygarde added the waiting for tree to go green This PR is approved and tested, but waiting for the tree to be green to land. label Sep 16, 2021
@chinmaygarde
Copy link
Member

Thanks!

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! Thanks!

// An optional callback that gets invoked when the |buffer| can be released.
void (*release_callback)(void* release_context);
// Opaque data passed to |release_callback|.
void* release_context;
Copy link
Contributor

Choose a reason for hiding this comment

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

Adding these caused undefined behavior for existing code (unless the code was specifically written to defend against the possibility of new values by zero-initializing the entire memory block).

If we edit this again we should add a struct size to do safe reads, as we do with embedder.h.

@MindStudioOfficial
Copy link

I have set up the Following buffer update function:

void Frame::Update(uint8_t *buffer, int32_t width, int32_t height)
{
    const std::lock_guard<std::mutex> lock(mutex_);
    flutter_pixel_buffer_.buffer = buffer;
    flutter_pixel_buffer_.width = width;
    flutter_pixel_buffer_.height = height;
    flutter_pixel_buffer_.release_context = &buffer;
    flutter_pixel_buffer_.release_callback = [](void *user_data)
    {
        uint8_t *old_buffer = reinterpret_cast<uint8_t *>(user_data);
        if (old_buffer != nullptr)
            free(old_buffer);
    };
    texture_registrar_->MarkTextureFrameAvailable(texture_id_);
}

This gets invoked by dart throught the method channel

However when I try to free(old_buffer)

I get the following error:

Debug Assertion Failed!
...
Expression: _CrtlsValidHeapPointer(block)
...

The original buffer is a uint8_t * from dart ffi.

How and where am I supposed to free the buffer?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
cla: yes needs tests platform-windows waiting for tree to go green This PR is approved and tested, but waiting for the tree to be green to land.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants