diff options
author | Mukilan Thiyagarajan <mukilan@igalia.com> | 2023-09-14 15:00:42 +0530 |
---|---|---|
committer | Mukilan Thiyagarajan <mukilan@igalia.com> | 2023-09-14 15:00:42 +0530 |
commit | c385b3c9737c17d59cb02e520c3b68b232cb6497 (patch) | |
tree | ad598ffbbdfbcecd6a4cf458abe2afc702d92c27 /third_party/webrender/examples/frame_output.rs | |
parent | 988e05a68b48c9e744bf49459faf41a1bd9b81d7 (diff) | |
download | servo-revert-webrender.tar.gz servo-revert-webrender.zip |
Revert "Upgrade WebRender to e491e1ae637b2eed1e7195855d88357e5eb3ddf9 (#30323)"revert-webrender
This reverts commit a9d37cb85ac2c55fc630fccffe1ba60ff00f555b.
Diffstat (limited to 'third_party/webrender/examples/frame_output.rs')
-rw-r--r-- | third_party/webrender/examples/frame_output.rs | 238 |
1 files changed, 238 insertions, 0 deletions
diff --git a/third_party/webrender/examples/frame_output.rs b/third_party/webrender/examples/frame_output.rs new file mode 100644 index 00000000000..2cd612c9b4c --- /dev/null +++ b/third_party/webrender/examples/frame_output.rs @@ -0,0 +1,238 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use euclid; +use gleam; +use glutin; +use webrender; +use winit; + +#[path = "common/boilerplate.rs"] +mod boilerplate; + +use crate::boilerplate::{Example, HandyDandyRectBuilder}; +use euclid::Scale; +use gleam::gl; +use webrender::api::*; +use webrender::api::units::*; + + +// This example demonstrates using the frame output feature to copy +// the output of a WR framebuffer to a custom texture. + +#[derive(Debug)] +struct Document { + id: DocumentId, + pipeline_id: PipelineId, + content_rect: LayoutRect, + color: ColorF, +} + + +struct App { + external_image_key: Option<ImageKey>, + output_document: Option<Document> +} + +struct OutputHandler { + texture_id: gl::GLuint +} + +struct ExternalHandler { + texture_id: gl::GLuint +} + +impl OutputImageHandler for OutputHandler { + fn lock(&mut self, _id: PipelineId) -> Option<(u32, FramebufferIntSize)> { + Some((self.texture_id, FramebufferIntSize::new(500, 500))) + } + + fn unlock(&mut self, _id: PipelineId) {} +} + +impl ExternalImageHandler for ExternalHandler { + fn lock( + &mut self, + _key: ExternalImageId, + _channel_index: u8, + _rendering: ImageRendering + ) -> ExternalImage { + ExternalImage { + uv: TexelRect::new(0.0, 0.0, 1.0, 1.0), + source: ExternalImageSource::NativeTexture(self.texture_id), + } + } + fn unlock(&mut self, _key: ExternalImageId, _channel_index: u8) {} +} + +impl App { + fn init_output_document( + &mut self, + api: &mut RenderApi, + device_size: DeviceIntSize, + device_pixel_ratio: f32, + ) { + // Generate the external image key that will be used to render the output document to the root document. + self.external_image_key = Some(api.generate_image_key()); + + let pipeline_id = PipelineId(1, 0); + let layer = 1; + let color = ColorF::new(1., 1., 0., 1.); + let document_id = api.add_document(device_size, layer); + api.enable_frame_output(document_id, pipeline_id, true); + api.set_document_view( + document_id, + device_size.into(), + device_pixel_ratio, + ); + + let document = Document { + id: document_id, + pipeline_id, + content_rect: LayoutRect::new( + LayoutPoint::zero(), + device_size.to_f32() / Scale::new(device_pixel_ratio), + ), + color, + }; + + let mut txn = Transaction::new(); + + txn.add_image( + self.external_image_key.unwrap(), + ImageDescriptor::new(100, 100, ImageFormat::BGRA8, ImageDescriptorFlags::IS_OPAQUE), + ImageData::External(ExternalImageData { + id: ExternalImageId(0), + channel_index: 0, + image_type: ExternalImageType::TextureHandle(TextureTarget::Default), + }), + None, + ); + + let space_and_clip = SpaceAndClipInfo::root_scroll(pipeline_id); + let mut builder = DisplayListBuilder::new( + document.pipeline_id, + document.content_rect.size, + ); + + builder.push_simple_stacking_context( + document.content_rect.origin, + space_and_clip.spatial_id, + PrimitiveFlags::IS_BACKFACE_VISIBLE, + ); + + builder.push_rect( + &CommonItemProperties::new(document.content_rect, space_and_clip), + document.content_rect, + ColorF::new(1.0, 1.0, 0.0, 1.0) + ); + builder.pop_stacking_context(); + + txn.set_root_pipeline(pipeline_id); + txn.set_display_list( + Epoch(0), + Some(document.color), + document.content_rect.size, + builder.finalize(), + true, + ); + txn.generate_frame(); + api.send_transaction(document.id, txn); + self.output_document = Some(document); + } +} + +impl Example for App { + fn render( + &mut self, + api: &mut RenderApi, + builder: &mut DisplayListBuilder, + _txn: &mut Transaction, + device_size: DeviceIntSize, + pipeline_id: PipelineId, + _document_id: DocumentId, + ) { + if self.output_document.is_none() { + let device_pixel_ratio = device_size.width as f32 / + builder.content_size().width; + self.init_output_document(api, DeviceIntSize::new(200, 200), device_pixel_ratio); + } + + let bounds = (100, 100).to(200, 200); + let space_and_clip = SpaceAndClipInfo::root_scroll(pipeline_id); + + builder.push_simple_stacking_context( + bounds.origin, + space_and_clip.spatial_id, + PrimitiveFlags::IS_BACKFACE_VISIBLE, + ); + + builder.push_image( + &CommonItemProperties::new(bounds, space_and_clip), + bounds, + ImageRendering::Auto, + AlphaType::PremultipliedAlpha, + self.external_image_key.unwrap(), + ColorF::WHITE, + ); + + builder.pop_stacking_context(); + } + + fn get_image_handlers( + &mut self, + gl: &dyn gl::Gl, + ) -> (Option<Box<dyn ExternalImageHandler>>, + Option<Box<dyn OutputImageHandler>>) { + let texture_id = gl.gen_textures(1)[0]; + + gl.bind_texture(gl::TEXTURE_2D, texture_id); + gl.tex_parameter_i( + gl::TEXTURE_2D, + gl::TEXTURE_MAG_FILTER, + gl::LINEAR as gl::GLint, + ); + gl.tex_parameter_i( + gl::TEXTURE_2D, + gl::TEXTURE_MIN_FILTER, + gl::LINEAR as gl::GLint, + ); + gl.tex_parameter_i( + gl::TEXTURE_2D, + gl::TEXTURE_WRAP_S, + gl::CLAMP_TO_EDGE as gl::GLint, + ); + gl.tex_parameter_i( + gl::TEXTURE_2D, + gl::TEXTURE_WRAP_T, + gl::CLAMP_TO_EDGE as gl::GLint, + ); + gl.tex_image_2d( + gl::TEXTURE_2D, + 0, + gl::RGBA as gl::GLint, + 100, + 100, + 0, + gl::BGRA, + gl::UNSIGNED_BYTE, + None, + ); + gl.bind_texture(gl::TEXTURE_2D, 0); + + ( + Some(Box::new(ExternalHandler { texture_id })), + Some(Box::new(OutputHandler { texture_id })) + ) + } +} + +fn main() { + let mut app = App { + external_image_key: None, + output_document: None + }; + + boilerplate::main_wrapper(&mut app, None); +} |