tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

yuv.rs (7027B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 extern crate gleam;
      6 extern crate glutin;
      7 extern crate webrender;
      8 extern crate winit;
      9 
     10 #[path = "common/boilerplate.rs"]
     11 mod boilerplate;
     12 
     13 use crate::boilerplate::Example;
     14 use gleam::gl;
     15 use webrender::api::*;
     16 use webrender::render_api::*;
     17 use webrender::api::units::*;
     18 
     19 
     20 fn init_gl_texture(
     21    id: gl::GLuint,
     22    internal: gl::GLenum,
     23    external: gl::GLenum,
     24    bytes: &[u8],
     25    gl: &dyn gl::Gl,
     26 ) {
     27    gl.bind_texture(gl::TEXTURE_2D, id);
     28    gl.tex_parameter_i(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::LINEAR as gl::GLint);
     29    gl.tex_parameter_i(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::LINEAR as gl::GLint);
     30    gl.tex_parameter_i(gl::TEXTURE_2D, gl::TEXTURE_WRAP_S, gl::CLAMP_TO_EDGE as gl::GLint);
     31    gl.tex_parameter_i(gl::TEXTURE_2D, gl::TEXTURE_WRAP_T, gl::CLAMP_TO_EDGE as gl::GLint);
     32    gl.tex_image_2d(
     33        gl::TEXTURE_2D,
     34        0,
     35        internal as gl::GLint,
     36        100,
     37        100,
     38        0,
     39        external,
     40        gl::UNSIGNED_BYTE,
     41        Some(bytes),
     42    );
     43    gl.bind_texture(gl::TEXTURE_2D, 0);
     44 }
     45 
     46 struct YuvImageProvider {
     47    texture_ids: Vec<gl::GLuint>,
     48 }
     49 
     50 impl YuvImageProvider {
     51    fn new(gl: &dyn gl::Gl) -> Self {
     52        let texture_ids = gl.gen_textures(4);
     53 
     54        init_gl_texture(texture_ids[0], gl::RED, gl::RED, &[127; 100 * 100], gl);
     55        init_gl_texture(texture_ids[1], gl::RG8, gl::RG, &[0; 100 * 100 * 2], gl);
     56        init_gl_texture(texture_ids[2], gl::RED, gl::RED, &[127; 100 * 100], gl);
     57        init_gl_texture(texture_ids[3], gl::RED, gl::RED, &[127; 100 * 100], gl);
     58 
     59        YuvImageProvider {
     60            texture_ids
     61        }
     62    }
     63 }
     64 
     65 impl ExternalImageHandler for YuvImageProvider {
     66    fn lock(
     67        &mut self,
     68        key: ExternalImageId,
     69        _channel_index: u8,
     70        _is_composited: bool,
     71    ) -> ExternalImage<'_> {
     72        let id = self.texture_ids[key.0 as usize];
     73        ExternalImage {
     74            uv: TexelRect::new(0.0, 0.0, 1.0, 1.0),
     75            source: ExternalImageSource::NativeTexture(id),
     76        }
     77    }
     78    fn unlock(&mut self, _key: ExternalImageId, _channel_index: u8) {
     79    }
     80 }
     81 
     82 struct App {
     83    texture_id: gl::GLuint,
     84    current_value: u8,
     85 }
     86 
     87 impl Example for App {
     88    fn render(
     89        &mut self,
     90        api: &mut RenderApi,
     91        builder: &mut DisplayListBuilder,
     92        txn: &mut Transaction,
     93        _device_size: DeviceIntSize,
     94        pipeline_id: PipelineId,
     95        _document_id: DocumentId,
     96    ) {
     97        let bounds = LayoutRect::from_size(LayoutSize::new(500.0, 500.0));
     98        let space_and_clip = SpaceAndClipInfo::root_scroll(pipeline_id);
     99 
    100        builder.push_simple_stacking_context(
    101            bounds.min,
    102            space_and_clip.spatial_id,
    103            PrimitiveFlags::IS_BACKFACE_VISIBLE,
    104        );
    105 
    106        let yuv_chanel1 = api.generate_image_key();
    107        let yuv_chanel2 = api.generate_image_key();
    108        let yuv_chanel2_1 = api.generate_image_key();
    109        let yuv_chanel3 = api.generate_image_key();
    110        txn.add_image(
    111            yuv_chanel1,
    112            ImageDescriptor::new(100, 100, ImageFormat::R8, ImageDescriptorFlags::IS_OPAQUE),
    113            ImageData::External(ExternalImageData {
    114                id: ExternalImageId(0),
    115                channel_index: 0,
    116                image_type: ExternalImageType::TextureHandle(
    117                    ImageBufferKind::Texture2D,
    118                ),
    119                normalized_uvs: false,
    120            }),
    121            None,
    122        );
    123        txn.add_image(
    124            yuv_chanel2,
    125            ImageDescriptor::new(100, 100, ImageFormat::RG8, ImageDescriptorFlags::IS_OPAQUE),
    126            ImageData::External(ExternalImageData {
    127                id: ExternalImageId(1),
    128                channel_index: 0,
    129                image_type: ExternalImageType::TextureHandle(
    130                    ImageBufferKind::Texture2D,
    131                ),
    132                normalized_uvs: false,
    133            }),
    134            None,
    135        );
    136        txn.add_image(
    137            yuv_chanel2_1,
    138            ImageDescriptor::new(100, 100, ImageFormat::R8, ImageDescriptorFlags::IS_OPAQUE),
    139            ImageData::External(ExternalImageData {
    140                id: ExternalImageId(2),
    141                channel_index: 0,
    142                image_type: ExternalImageType::TextureHandle(
    143                    ImageBufferKind::Texture2D,
    144                ),
    145                normalized_uvs: false,
    146            }),
    147            None,
    148        );
    149        txn.add_image(
    150            yuv_chanel3,
    151            ImageDescriptor::new(100, 100, ImageFormat::R8, ImageDescriptorFlags::IS_OPAQUE),
    152            ImageData::External(ExternalImageData {
    153                id: ExternalImageId(3),
    154                channel_index: 0,
    155                image_type: ExternalImageType::TextureHandle(
    156                    ImageBufferKind::Texture2D,
    157                ),
    158                normalized_uvs: false,
    159            }),
    160            None,
    161        );
    162 
    163        let info = CommonItemProperties::new(
    164            LayoutRect::from_origin_and_size(LayoutPoint::new(100.0, 0.0), LayoutSize::new(100.0, 100.0)),
    165            space_and_clip,
    166        );
    167        builder.push_yuv_image(
    168            &info,
    169            bounds,
    170            YuvData::NV12(yuv_chanel1, yuv_chanel2),
    171            ColorDepth::Color8,
    172            YuvColorSpace::Rec601,
    173            ColorRange::Limited,
    174            ImageRendering::Auto,
    175        );
    176 
    177        let info = CommonItemProperties::new(
    178            LayoutRect::from_origin_and_size(LayoutPoint::new(300.0, 0.0), LayoutSize::new(100.0, 100.0)),
    179            space_and_clip,
    180        );
    181        builder.push_yuv_image(
    182            &info,
    183            bounds,
    184            YuvData::PlanarYCbCr(yuv_chanel1, yuv_chanel2_1, yuv_chanel3),
    185            ColorDepth::Color8,
    186            YuvColorSpace::Rec601,
    187            ColorRange::Limited,
    188            ImageRendering::Auto,
    189        );
    190 
    191        builder.pop_stacking_context();
    192    }
    193 
    194    fn on_event(
    195        &mut self,
    196        _event: winit::event::WindowEvent,
    197        _window: &winit::window::Window,
    198        _api: &mut RenderApi,
    199        _document_id: DocumentId,
    200    ) -> bool {
    201        false
    202    }
    203 
    204    fn get_image_handler(
    205        &mut self,
    206        gl: &dyn gl::Gl,
    207    ) -> Option<Box<dyn ExternalImageHandler>> {
    208        let provider = YuvImageProvider::new(gl);
    209        self.texture_id = provider.texture_ids[0];
    210        Some(Box::new(provider))
    211    }
    212 
    213    fn draw_custom(&mut self, gl: &dyn gl::Gl) {
    214        init_gl_texture(self.texture_id, gl::RED, gl::RED, &[self.current_value; 100 * 100], gl);
    215        self.current_value = self.current_value.wrapping_add(1);
    216    }
    217 }
    218 
    219 fn main() {
    220    let mut app = App {
    221        texture_id: 0,
    222        current_value: 0,
    223    };
    224 
    225    let opts = webrender::WebRenderOptions {
    226        ..Default::default()
    227    };
    228 
    229    boilerplate::main_wrapper(&mut app, Some(opts));
    230 }