/* 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/. */
extern crate gleam;
extern crate glutin;
extern crate webrender;
extern crate winit;
#[ path =
"common/boilerplate.rs" ]
mod boilerplate;
use crate ::boilerplate::Example;
use gleam::gl;
use webrender::api::*;
use webrender::render_api::*;
use webrender::api::units::*;
fn init_gl_texture(
id: gl::GLuint,
internal: gl::GLenum,
external: gl::GLenum,
bytes: &[u8],
gl: &
dyn gl::Gl,
) {
gl.bind_texture(gl::TEXTURE_2D, 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::GLin
t);
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 ,
internal as gl::GLint,
100 ,
100 ,
0 ,
external,
gl::UNSIGNED_BYTE,
Some(bytes),
);
gl.bind_texture(gl::TEXTURE_2D, 0 );
}
struct YuvImageProvider {
texture_ids: Vec<gl::GLuint>,
}
impl YuvImageProvider {
fn new(gl: &dyn gl::Gl) -> Self {
let texture_ids = gl.gen_textures(4 );
init_gl_texture(texture_ids[0 ], gl::RED, gl::RED, &[127 ; 100 * 100 ], gl);
init_gl_texture(texture_ids[1 ], gl::RG8, gl::RG, &[0 ; 100 * 100 * 2 ], gl);
init_gl_texture(texture_ids[2 ], gl::RED, gl::RED, &[127 ; 100 * 100 ], gl);
init_gl_texture(texture_ids[3 ], gl::RED, gl::RED, &[127 ; 100 * 100 ], gl);
YuvImageProvider {
texture_ids
}
}
}
impl ExternalImageHandler for YuvImageProvider {
fn lock(
&mut self ,
key: ExternalImageId,
_channel_index: u8,
_is_composited: bool,
) -> ExternalImage<'_> {
let id = self .texture_ids[key.0 as usize];
ExternalImage {
uv: TexelRect::new(0 .0 , 0 .0 , 1 .0 , 1 .0 ),
source: ExternalImageSource::NativeTexture(id),
}
}
fn unlock(&mut self , _key: ExternalImageId, _channel_index: u8) {
}
}
struct App {
texture_id: gl::GLuint,
current_value: u8,
}
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,
) {
let bounds = LayoutRect::from_size(LayoutSize::new(500 .0 , 500 .0 ));
let space_and_clip = SpaceAndClipInfo::root_scroll(pipeline_id);
builder.push_simple_stacking_context(
space_and_clip.spatial_id,
PrimitiveFlags::IS_BACKFACE_VISIBLE,
);
let yuv_chanel1 = api.generate_image_key();
let yuv_chanel2 = api.generate_image_key();
let yuv_chanel2_1 = api.generate_image_key();
let yuv_chanel3 = api.generate_image_key();
txn.add_image(
yuv_chanel1,
ImageDescriptor::new(100 , 100 , ImageFormat::R8, ImageDescriptorFlags::IS_OPAQUE),
ImageData::External(ExternalImageData {
id: ExternalImageId(0 ),
channel_index: 0 ,
image_type: ExternalImageType::TextureHandle(
ImageBufferKind::Texture2D,
),
normalized_uvs: false ,
}),
None,
);
txn.add_image(
yuv_chanel2,
ImageDescriptor::new(100 , 100 , ImageFormat::RG8, ImageDescriptorFlags::IS_OPAQUE),
ImageData::External(ExternalImageData {
id: ExternalImageId(1 ),
channel_index: 0 ,
image_type: ExternalImageType::TextureHandle(
ImageBufferKind::Texture2D,
),
normalized_uvs: false ,
}),
None,
);
txn.add_image(
yuv_chanel2_1,
ImageDescriptor::new(100 , 100 , ImageFormat::R8, ImageDescriptorFlags::IS_OPAQUE),
ImageData::External(ExternalImageData {
id: ExternalImageId(2 ),
channel_index: 0 ,
image_type: ExternalImageType::TextureHandle(
ImageBufferKind::Texture2D,
),
normalized_uvs: false ,
}),
None,
);
txn.add_image(
yuv_chanel3,
ImageDescriptor::new(100 , 100 , ImageFormat::R8, ImageDescriptorFlags::IS_OPAQUE),
ImageData::External(ExternalImageData {
id: ExternalImageId(3 ),
channel_index: 0 ,
image_type: ExternalImageType::TextureHandle(
ImageBufferKind::Texture2D,
),
normalized_uvs: false ,
}),
None,
);
let info = CommonItemProperties::new(
LayoutRect::from_origin_and_size(LayoutPoint::new(100 .0 , 0 .0 ), LayoutSize::new(100 .0 , 100 .0 )),
space_and_clip,
);
builder.push_yuv_image(
&info,
bounds,
YuvData::NV12(yuv_chanel1, yuv_chanel2),
ColorDepth::Color8,
YuvColorSpace::Rec601,
ColorRange::Limited,
ImageRendering::Auto,
);
let info = CommonItemProperties::new(
LayoutRect::from_origin_and_size(LayoutPoint::new(300 .0 , 0 .0 ), LayoutSize::new(100 .0 , 100 .0 )),
space_and_clip,
);
builder.push_yuv_image(
&info,
bounds,
YuvData::PlanarYCbCr(yuv_chanel1, yuv_chanel2_1, yuv_chanel3),
ColorDepth::Color8,
YuvColorSpace::Rec601,
ColorRange::Limited,
ImageRendering::Auto,
);
builder.pop_stacking_context();
}
fn on_event(
&mut self ,
_event: winit::event::WindowEvent,
_window: &winit::window::Window,
_api: &mut RenderApi,
_document_id: DocumentId,
) -> bool {
false
}
fn get_image_handler(
&mut self ,
gl: &dyn gl::Gl,
) -> Option<Box <dyn ExternalImageHandler>> {
let provider = YuvImageProvider::new(gl);
self .texture_id = provider.texture_ids[0 ];
Some(Box ::new(provider))
}
fn draw_custom(&mut self , gl: &dyn gl::Gl) {
init_gl_texture(self .texture_id, gl::RED, gl::RED, &[self .current_value; 100 * 100 ], gl);
self .current_value = self .current_value.wrapping_add(1 );
}
}
fn main() {
let mut app = App {
texture_id: 0 ,
current_value: 0 ,
};
let opts = webrender::WebRenderOptions {
..Default::default()
};
boilerplate::main_wrapper(&mut app, Some(opts));
}
Messung V0.5 in Prozent C=92 H=91 G=91
¤ Dauer der Verarbeitung: 0.4 Sekunden
¤
*© Formatika GbR, Deutschland