tor-browser

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

texture_cache_stress.rs (10548B)


      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, HandyDandyRectBuilder};
     14 use gleam::gl;
     15 use std::mem;
     16 use webrender::api::*;
     17 use webrender::render_api::*;
     18 use webrender::api::units::*;
     19 
     20 
     21 struct ImageGenerator {
     22    patterns: [[u8; 3]; 6],
     23    next_pattern: usize,
     24    current_image: Vec<u8>,
     25 }
     26 
     27 impl ImageGenerator {
     28    fn new() -> Self {
     29        ImageGenerator {
     30            next_pattern: 0,
     31            patterns: [
     32                [1, 0, 0],
     33                [0, 1, 0],
     34                [0, 0, 1],
     35                [1, 1, 0],
     36                [0, 1, 1],
     37                [1, 0, 1],
     38            ],
     39            current_image: Vec::new(),
     40        }
     41    }
     42 
     43    fn generate_image(&mut self, size: i32) {
     44        let pattern = &self.patterns[self.next_pattern];
     45        self.current_image.clear();
     46        for y in 0 .. size {
     47            for x in 0 .. size {
     48                let lum = 255 * (1 - (((x & 8) == 0) ^ ((y & 8) == 0)) as u8);
     49                self.current_image.extend_from_slice(&[
     50                    lum * pattern[0],
     51                    lum * pattern[1],
     52                    lum * pattern[2],
     53                    0xff,
     54                ]);
     55            }
     56        }
     57 
     58        self.next_pattern = (self.next_pattern + 1) % self.patterns.len();
     59    }
     60 
     61    fn take(&mut self) -> Vec<u8> {
     62        mem::replace(&mut self.current_image, Vec::new())
     63    }
     64 }
     65 
     66 impl ExternalImageHandler for ImageGenerator {
     67    fn lock(
     68        &mut self,
     69        _key: ExternalImageId,
     70        channel_index: u8,
     71        _is_composited: bool,
     72    ) -> ExternalImage<'_> {
     73        self.generate_image(channel_index as i32);
     74        ExternalImage {
     75            uv: TexelRect::new(0.0, 0.0, 1.0, 1.0),
     76            source: ExternalImageSource::RawData(&self.current_image),
     77        }
     78    }
     79    fn unlock(&mut self, _key: ExternalImageId, _channel_index: u8) {}
     80 }
     81 
     82 struct App {
     83    stress_keys: Vec<ImageKey>,
     84    image_key: Option<ImageKey>,
     85    image_generator: ImageGenerator,
     86    swap_keys: Vec<ImageKey>,
     87    swap_index: usize,
     88 }
     89 
     90 impl Example for App {
     91    fn render(
     92        &mut self,
     93        api: &mut RenderApi,
     94        builder: &mut DisplayListBuilder,
     95        txn: &mut Transaction,
     96        _device_size: DeviceIntSize,
     97        pipeline_id: PipelineId,
     98        _document_id: DocumentId,
     99    ) {
    100        let bounds = (0, 0).to(512, 512);
    101        let space_and_clip = SpaceAndClipInfo::root_scroll(pipeline_id);
    102 
    103        builder.push_simple_stacking_context(
    104            bounds.min,
    105            space_and_clip.spatial_id,
    106            PrimitiveFlags::IS_BACKFACE_VISIBLE,
    107        );
    108 
    109        let x0 = 50.0;
    110        let y0 = 50.0;
    111        let image_size = LayoutSize::new(4.0, 4.0);
    112 
    113        if self.swap_keys.is_empty() {
    114            let key0 = api.generate_image_key();
    115            let key1 = api.generate_image_key();
    116 
    117            self.image_generator.generate_image(128);
    118            txn.add_image(
    119                key0,
    120                ImageDescriptor::new(128, 128, ImageFormat::BGRA8, ImageDescriptorFlags::IS_OPAQUE),
    121                ImageData::new(self.image_generator.take()),
    122                None,
    123            );
    124 
    125            self.image_generator.generate_image(128);
    126            txn.add_image(
    127                key1,
    128                ImageDescriptor::new(128, 128, ImageFormat::BGRA8, ImageDescriptorFlags::IS_OPAQUE),
    129                ImageData::new(self.image_generator.take()),
    130                None,
    131            );
    132 
    133            self.swap_keys.push(key0);
    134            self.swap_keys.push(key1);
    135        }
    136 
    137        for (i, key) in self.stress_keys.iter().enumerate() {
    138            let x = (i % 128) as f32;
    139            let y = (i / 128) as f32;
    140            let info = CommonItemProperties::new(
    141                LayoutRect::from_origin_and_size(
    142                    LayoutPoint::new(x0 + image_size.width * x, y0 + image_size.height * y),
    143                    image_size,
    144                ),
    145                space_and_clip,
    146            );
    147 
    148            builder.push_image(
    149                &info,
    150                bounds,
    151                ImageRendering::Auto,
    152                AlphaType::PremultipliedAlpha,
    153                *key,
    154                ColorF::WHITE,
    155            );
    156        }
    157 
    158        if let Some(image_key) = self.image_key {
    159            let image_size = LayoutSize::new(100.0, 100.0);
    160            let info = CommonItemProperties::new(
    161                LayoutRect::from_origin_and_size(LayoutPoint::new(100.0, 100.0), image_size),
    162                space_and_clip,
    163            );
    164            builder.push_image(
    165                &info,
    166                bounds,
    167                ImageRendering::Auto,
    168                AlphaType::PremultipliedAlpha,
    169                image_key,
    170                ColorF::WHITE,
    171            );
    172        }
    173 
    174        let swap_key = self.swap_keys[self.swap_index];
    175        let image_size = LayoutSize::new(64.0, 64.0);
    176        let info = CommonItemProperties::new(
    177            LayoutRect::from_origin_and_size(LayoutPoint::new(100.0, 400.0), image_size),
    178            space_and_clip,
    179        );
    180        builder.push_image(
    181            &info,
    182            bounds,
    183            ImageRendering::Auto,
    184            AlphaType::PremultipliedAlpha,
    185            swap_key,
    186            ColorF::WHITE,
    187        );
    188        self.swap_index = 1 - self.swap_index;
    189 
    190        builder.pop_stacking_context();
    191    }
    192 
    193    fn on_event(
    194        &mut self,
    195        event: winit::event::WindowEvent,
    196        _window: &winit::window::Window,
    197        api: &mut RenderApi,
    198        document_id: DocumentId,
    199    ) -> bool {
    200        match event {
    201            winit::event::WindowEvent::KeyboardInput {
    202                input: winit::event::KeyboardInput {
    203                    state: winit::event::ElementState::Pressed,
    204                    virtual_keycode: Some(key),
    205                    ..
    206                },
    207                ..
    208            } => {
    209                let mut txn = Transaction::new();
    210 
    211                match key {
    212                    winit::event::VirtualKeyCode::S => {
    213                        self.stress_keys.clear();
    214 
    215                        for _ in 0 .. 16 {
    216                            for _ in 0 .. 16 {
    217                                let size = 4;
    218 
    219                                let image_key = api.generate_image_key();
    220 
    221                                self.image_generator.generate_image(size);
    222 
    223                                txn.add_image(
    224                                    image_key,
    225                                    ImageDescriptor::new(
    226                                        size,
    227                                        size,
    228                                        ImageFormat::BGRA8,
    229                                        ImageDescriptorFlags::IS_OPAQUE,
    230                                    ),
    231                                    ImageData::new(self.image_generator.take()),
    232                                    None,
    233                                );
    234 
    235                                self.stress_keys.push(image_key);
    236                            }
    237                        }
    238                    }
    239                    winit::event::VirtualKeyCode::D => if let Some(image_key) = self.image_key.take() {
    240                        txn.delete_image(image_key);
    241                    },
    242                    winit::event::VirtualKeyCode::U => if let Some(image_key) = self.image_key {
    243                        let size = 128;
    244                        self.image_generator.generate_image(size);
    245 
    246                        txn.update_image(
    247                            image_key,
    248                            ImageDescriptor::new(size, size, ImageFormat::BGRA8, ImageDescriptorFlags::IS_OPAQUE),
    249                            ImageData::new(self.image_generator.take()),
    250                            &DirtyRect::All,
    251                        );
    252                    },
    253                    winit::event::VirtualKeyCode::E => {
    254                        if let Some(image_key) = self.image_key.take() {
    255                            txn.delete_image(image_key);
    256                        }
    257 
    258                        let size = 32;
    259                        let image_key = api.generate_image_key();
    260 
    261                        let image_data = ExternalImageData {
    262                            id: ExternalImageId(0),
    263                            channel_index: size as u8,
    264                            image_type: ExternalImageType::Buffer,
    265                            normalized_uvs: false,
    266                        };
    267 
    268                        txn.add_image(
    269                            image_key,
    270                            ImageDescriptor::new(size, size, ImageFormat::BGRA8, ImageDescriptorFlags::IS_OPAQUE),
    271                            ImageData::External(image_data),
    272                            None,
    273                        );
    274 
    275                        self.image_key = Some(image_key);
    276                    }
    277                    winit::event::VirtualKeyCode::R => {
    278                        if let Some(image_key) = self.image_key.take() {
    279                            txn.delete_image(image_key);
    280                        }
    281 
    282                        let image_key = api.generate_image_key();
    283                        let size = 32;
    284                        self.image_generator.generate_image(size);
    285 
    286                        txn.add_image(
    287                            image_key,
    288                            ImageDescriptor::new(size, size, ImageFormat::BGRA8, ImageDescriptorFlags::IS_OPAQUE),
    289                            ImageData::new(self.image_generator.take()),
    290                            None,
    291                        );
    292 
    293                        self.image_key = Some(image_key);
    294                    }
    295                    _ => {}
    296                }
    297 
    298                api.send_transaction(document_id, txn);
    299                return true;
    300            }
    301            _ => {}
    302        }
    303 
    304        false
    305    }
    306 
    307    fn get_image_handler(
    308        &mut self,
    309        _gl: &dyn gl::Gl,
    310    ) -> Option<Box<dyn ExternalImageHandler>> {
    311        Some(Box::new(ImageGenerator::new()))
    312    }
    313 }
    314 
    315 fn main() {
    316    let mut app = App {
    317        image_key: None,
    318        stress_keys: Vec::new(),
    319        image_generator: ImageGenerator::new(),
    320        swap_keys: Vec::new(),
    321        swap_index: 0,
    322    };
    323    boilerplate::main_wrapper(&mut app, None);
    324 }