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

Conversation

@bdero
Copy link
Member

@bdero bdero commented Jun 7, 2022

Been meaning to add this for a while to speed up some our of fancier tests (like color wheel). Just noticed flutter/flutter#104718 as I was making this PR. I don't know what the context of that issue is or how it might interface with the dispatcher, but perhaps this is in the right direction anyhow?

Screen.Recording.2022-06-06.at.7.20.22.PM.mov

return nullptr;
}

return std::make_shared<Image>(target.GetRenderTargetTexture());
Copy link
Contributor

Choose a reason for hiding this comment

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

This is a GPU resident texture right?

The API exposed via toImage expects a CPU resident image.

Copy link
Member Author

Choose a reason for hiding this comment

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

We can mark the new texture as host visible and have Image handle the shared buffer transfer internally. Would prefer to punt that down the road to when we add in stuff like ReadPixels (if/when we need it).

Copy link
Contributor

Choose a reason for hiding this comment

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

This isn't exposed up through the Dart API AFAICT, right?

If so, let's just document the behavior in a comment here.

Copy link
Member Author

Choose a reason for hiding this comment

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

Nah this is only Impeller internal right now. Added a comment about the visibility.

struct Picture {
std::unique_ptr<EntityPass> pass;

std::shared_ptr<Image> RenderToImage(AiksContext& renderer);
Copy link
Member

Choose a reason for hiding this comment

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

Nit: AiksContext& context?

Copy link
Member

Choose a reason for hiding this comment

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

Another idea could be to flip it and ask the AiksContext to snapshot the picture as an image.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done.


//
std::shared_ptr<Image> Picture::RenderToImage(AiksContext& renderer) {
auto coverage = pass->GetElementsCoverage();
Copy link
Member

Choose a reason for hiding this comment

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

Since this is a utility method, add validity checks. Some stuff that comes to mind:

  • Null checks for pass.
  • Check for empty coverage. You won't be able to create a zero sized offscreen texture anyway.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done. Added check for render target + coverage. Gotta be more careful about these coverage optionals -- I've forgotten to check them before.

*renderer.context_, ISize(coverage->GetRight(), coverage->GetBottom()));

if (!renderer.Render(*this, target)) {
return nullptr;
Copy link
Member

Choose a reason for hiding this comment

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

VALIDATION_LOG here?

Copy link
Member Author

Choose a reason for hiding this comment

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

Done.

std::shared_ptr<Image> Picture::RenderToImage(AiksContext& renderer) {
auto coverage = pass->GetElementsCoverage();
auto target = RenderTarget::CreateOffscreen(
*renderer.context_, ISize(coverage->GetRight(), coverage->GetBottom()));
Copy link
Member

Choose a reason for hiding this comment

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

This will create an unnecessarily large texture if the coverage has an offset element. In that case, pass entities would need to be copied and offset applied (I believe we already do this in the entity pass).

Copy link
Member Author

Choose a reason for hiding this comment

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

This is the behavior of the picture.toImage. I found it a tad less confusing to reason about as opposed to returning the position as part of the result or otherwise forcing the caller to fetch coverage from the picture separately. Up to you though -- I don't really have a strong opinion.

A good middle ground might be to add a convenience method for walking the picture and absorbing the top left coverage margin as you mention.

Copy link
Member

Choose a reason for hiding this comment

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

In that case, I think we should return an impeller::Snapshot in //impeller/entity/contents. Returning the position as part of image is then taken care of. Introducing a potentially large allocation overhead to make the API easier to reason makes me nervous. Especially when we have followed the right pattern elsewhere and have utilities for this purpose already.

If you do decide to use the snapshot, perhaps just call the method Picture::Snapshot as well and also move //impeller/entity/contents/snapshot to someplace more easily discoverable. Perhaps //impeller/renderer/snapshot? I think it's a good way of thinking about snapshotting and you have already thought through the various ways in which snapshotting can be used.

Copy link
Member Author

Choose a reason for hiding this comment

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

SGTM, done.

return nullptr;
}

return std::make_shared<Image>(target.GetRenderTargetTexture());
Copy link
Member

Choose a reason for hiding this comment

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

Check that the texture is not null. Add a validation log if it is and return nullptr.

Copy link
Member

Choose a reason for hiding this comment

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

IMO, we should, by convention, not return invalid resources out of factories that return resources via a pointer. Instead, favoring returning null. This makes the caller not have to do a null and IsValid invocation pair.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done.

std::unique_ptr<ContentContext> content_context_;
bool is_valid_ = false;

friend Picture;
Copy link
Member

Choose a reason for hiding this comment

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

If the caller needs the impeller::Context from the AiksContext, you could just add a getter (completely reasonable IMO) instead of adding a friend.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done.

@bdero bdero force-pushed the bdero/picture-to-image branch from 4a01f85 to c0a7891 Compare June 8, 2022 03:06
@chinmaygarde
Copy link
Member

Left a comment about snapshotting. Not sure if this is a bit of a yak-shave though.

@chinmaygarde
Copy link
Member

cc @bdero Ping on the open question on the usage of an impeller::Snapshot. If you'd rather handle it in a later patch, LGTM here. I don't want to block other work that perhaps builds on top of this.

@bdero
Copy link
Member Author

bdero commented Jun 13, 2022

Sorry for the delay, just got around to fixing this up.

@bdero bdero force-pushed the bdero/picture-to-image branch from c932ced to 6bb5b25 Compare June 14, 2022 06:16
@bdero bdero 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 Jun 14, 2022
@fluttergithubbot
Copy link
Contributor

This pull request is not suitable for automatic merging in its current state.

  • The status or check suite Linux Unopt has failed. Please fix the issues identified (or deflake) before re-applying this label.

@fluttergithubbot fluttergithubbot removed the waiting for tree to go green This PR is approved and tested, but waiting for the tree to be green to land. label Jun 14, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

No open projects
Archived in project

Development

Successfully merging this pull request may close these issues.

4 participants