Conversation
fddfbcf to
7311b14
Compare
StarArawn
left a comment
There was a problem hiding this comment.
Looks pretty good over all. Can we add an example showcasing this? Right now it's a little hard to test and verify the work.
| for closed_window in closed.iter() { | ||
| extracted_windows.remove(&closed_window.id); | ||
| } | ||
| for (window, screenshot_func) in screenshot_manager.callbacks.lock().drain() { |
There was a problem hiding this comment.
Probably should use try_lock here to avoid a deadlock if a screenshot is being taken at the same time? Although I guess the bevy scheduler prevents that from happening here..
There was a problem hiding this comment.
Yep, this can't really happen because callbacks is pub(crate) and this is the singular callsite where it's called. Even if somehow a user ended up with two of these systems, one would simply take the lock and they'd run in series. Only one lock isn't enough to cause a deadlock.
There was a problem hiding this comment.
Nile, your comment here would make a great comment for this line of code.
| self.data, | ||
| ) | ||
| .map(DynamicImage::ImageRgba8), | ||
| TextureFormat::Bgra8UnormSrgb => ImageBuffer::from_raw( |
There was a problem hiding this comment.
Why do we introduce the TextureFormat::Bgra8UnormSrgb here? Is there a reason bgra might be preferred over rgba?
There was a problem hiding this comment.
Seconding the confusion about why this is part of this PR. I don't mind it, just a bit confused.
There was a problem hiding this comment.
wgpu apparently quite likes this format for swapchain textures - this was necessary to get the save to disk functionality working on my machine.
There was a problem hiding this comment.
Interesting. Can you please leave a comment here to that effect then?
alice-i-cecile
left a comment
There was a problem hiding this comment.
Useful functionality, generally looks solid. I'd like to see a top-level example before this gets merged.
Code quality and docs otherwise LGTM. I'll defer to rendering experts on the implementation strategy.
|
crashes for me on macOS: |
|
Changed the code to ensure a panic like the one @mockersf encountered is no longer possible, but it's a lot more code now. |
| &render_queue.0, | ||
| world, | ||
| |encoder| { | ||
| crate::view::screenshot::submit_screenshot_commands(world, encoder); |
There was a problem hiding this comment.
Is there a reason why you didn't just import the screenshot module?
There was a problem hiding this comment.
Not really, other than not wanting to pollute the namespace i guess.
There was a problem hiding this comment.
Fair, I don't mind either way. I'd prefer having the screenshot module in scope just to not have crate::view, but really it's up to you, really not a big deal.
Works for me now! Thanks |
|
Crashes in WASM too: |
This seems to be a result of the brightness values being stored in the alpha channel - the two images are once again identical when alpha is disabled. |
|
the PR also needs to be updated for #7681 I think |
|
What's the current status of this PR? |
|
Does this snippet work without the WinitPlugin ? |
|
@TheRawMeatball I think there has been an issue with your merge |
2b5edfa to
1da0a8a
Compare
|
What's the purpose of the render pass? Is it to avoid putting |
IceSentry
left a comment
There was a problem hiding this comment.
I feel like there should probably be a bit more docs in screenshot.rs, but in general the code works and I haven't seen anything obviously wrong.
I don't fully like the idea of passing a finalizer callback to the graph runner, but I'm not sure how to avoid that.
cart
left a comment
There was a problem hiding this comment.
I think this is a reasonable solution to the specific problem of taking screenshots of a window. But I don't love how "hacked in" it is. I think this impl points to a fundamental "render output feedback" problem that should (ultimately) be solved generically. The screenshot api is pretty opinionated and isn't a full solve to the problem. People should be able to build similar abstractions on their own.
I see a number of paths forward:
- Continue down the
finalizerpath, but just modularize it (ex let people add arbitrary functions to the process via some new abstraction) - Build this into our graph abstraction ... this would mean screenshotting would not be a global feature, but rather one that exists in specific graphs ... this seems ok to me. We could build common "feedback" nodes (including a screenshot node). It seems to me like this PR could have already been expressed that way, rather than adding the
finalizer. Functionallysubmit_screenshot_commandsis really equivalent to a "render graph node that exists in every graph and always runs last". This doesn't solve the "window / swap chain / image management stuff" though, which is definitely the bigger challenge. It feels like a chunk of this could/should be expressed as some generic graph node that says "at this point in the graph, write this COPY_SRC texture view to a buffer of appropriate size and (maybe optionally) create an image from it". That leaves the problem of "writing the swap chain to a COPY_SRC texture" to be solved on its own in whatever way we deem "best" / "most modular"/ whatever we choose to optimize for. - Give up on reading swap chain outputs and instead read
ViewTarget::maint_target_texturesoutputs in render graph nodes. Seems like we could make those COPY_SRC (maybe in an opt-in fashion when screenshots are enabled). This does ignore the upscaling step though (which does seem like a problem).
That being said, creating a generic abstraction is not a blocker (and I understand there is a fair amount of implementation nuance here when it comes to swapchain access). This is totally fine for now.
# Objective - Enable taking a screenshot in wasm - Followup on #7163 ## Solution - Create a blob from the image data, generate a url to that blob, add an `a` element to the document linking to that url, click on that element, then revoke the url - This will automatically trigger a download of the screenshot file in the browser
|
Still could this work without a window? It seems some questions in the comments are unanswered. |


Fixes #1207
Objective
Right now, it's impossible to capture a screenshot of the entire window without forking bevy. This is because
Solution
Changelog
ScreenshotManagerresource with two functions,take_screenshotandsave_screenshot_to_disk