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 }