Add initial support for offscreen rendering (#30767)

* Offscreen rendering

* shared memory case never actually rendered to backbuffer

* fix compile errors (in theory) when gl crate feature disabled

* update doc comments

* remove dark CentralPanel border covering edges of viewport

* clear to transparent, to avoid pink artifacts

* fix mouse input for browser being consumed by egui

* avoid destroying OpenGL resources unless resizing window

* clean up compositing::gl

* fix flickering around edges after resizing window

* unset invalidate_last_render_target after invalidating

* fix incorrect DRAW_FRAMEBUFFER name when blitting

* bind the widget surface fbo before painting egui

* make composite_specific_target take CompositeTarget, not Option

* compositing: remove cargo feature “gl”

* capitalise FBO in bind log message

Co-authored-by: Martin Robinson <mrobinson@igalia.com>

* capitalise FBO in drop log message

Co-authored-by: Martin Robinson <mrobinson@igalia.com>

* rename RenderTargetInfo fields and use OnceCell for next field

* rename RenderTargetInfo.read to read_back_from_gpu

* document servo_framebuffer_id in Minibrowser::update

* rename needs_fbo to use_offscreen_framebuffer

* capitalise FBO in unbind log message

* clarify the purpose of Minibrowser::on_event

* fix unused_must_use warning

* reduce nesting in Minibrowser::update

* use implicit format argument in panic

* store Minibrowser.widget_surface_fbo as glow type

* explain why servo_framebuffer_id is None in first call site

* rename output_framebuffer_id to offscreen_framebuffer_id

---------

Co-authored-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
Delan Azabani 2023-12-13 10:49:25 +08:00 committed by GitHub
parent 97e6c72f57
commit 17f3c45d4f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 498 additions and 273 deletions

View file

@ -37,7 +37,7 @@ bluetooth = { path = "../bluetooth" }
bluetooth_traits = { workspace = true }
canvas = { path = "../canvas", default-features = false }
canvas_traits = { workspace = true }
compositing = { path = "../compositing", features = ["gl"] }
compositing = { path = "../compositing" }
compositing_traits = { workspace = true }
constellation = { path = "../constellation" }
crossbeam-channel = { workspace = true }

View file

@ -30,7 +30,7 @@ use canvas::canvas_paint_thread::{self, CanvasPaintThread};
use canvas::WebGLComm;
use canvas_traits::webgl::WebGLThreads;
use compositing::windowing::{EmbedderEvent, EmbedderMethods, WindowMethods};
use compositing::{IOCompositor, InitialCompositorState, ShutdownState};
use compositing::{CompositeTarget, IOCompositor, InitialCompositorState, ShutdownState};
use compositing_traits::{
CanvasToCompositorMsg, CompositingReason, CompositorMsg, CompositorProxy, CompositorReceiver,
ConstellationMsg, FontToCompositorMsg, ForwardedToCompositorMsg,
@ -224,6 +224,7 @@ where
mut embedder: Box<dyn EmbedderMethods>,
window: Rc<Window>,
user_agent: Option<String>,
composite_target: CompositeTarget,
) -> InitializedServo<Window> {
// Global configuration options, parsed from the command line.
let opts = opts::get();
@ -447,6 +448,12 @@ where
}
}
let composite_target = if let Some(path) = opts.output_file.clone() {
CompositeTarget::PngFile(path.into())
} else {
composite_target
};
// The compositor coordinates with the client window to create the final
// rendered page and display it somewhere.
let compositor = IOCompositor::create(
@ -464,7 +471,7 @@ where
webrender_gl,
webxr_main_thread,
},
opts.output_file.clone(),
composite_target,
opts.is_running_problem_test,
opts.exit_after_load,
opts.debug.convert_mouse_to_touch,
@ -769,6 +776,12 @@ where
pub fn recomposite(&mut self) {
self.compositor.composite();
}
/// Return the OpenGL framebuffer name of the most-recently-completed frame when compositing to
/// [`CompositeTarget::Fbo`], or None otherwise.
pub fn offscreen_framebuffer_id(&self) -> Option<u32> {
self.compositor.offscreen_framebuffer_id()
}
}
fn create_embedder_channel(