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 {
new() -> Self28 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
generate_image(&mut self, size: i32)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
take(&mut self) -> Vec<u8>61 fn take(&mut self) -> Vec<u8> {
62 mem::replace(&mut self.current_image, Vec::new())
63 }
64 }
65
66 impl ExternalImageHandler for ImageGenerator {
lock( &mut self, _key: ExternalImageId, channel_index: u8, _rendering: ImageRendering ) -> ExternalImage67 fn lock(
68 &mut self,
69 _key: ExternalImageId,
70 channel_index: u8,
71 _rendering: ImageRendering
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 }
unlock(&mut self, _key: ExternalImageId, _channel_index: u8)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 {
render( &mut self, api: &mut RenderApi, builder: &mut DisplayListBuilder, txn: &mut Transaction, _device_size: DeviceIntSize, pipeline_id: PipelineId, _document_id: DocumentId, )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
on_event( &mut self, event: winit::WindowEvent, api: &mut RenderApi, document_id: DocumentId, ) -> bool193 fn on_event(
194 &mut self,
195 event: winit::WindowEvent,
196 api: &mut RenderApi,
197 document_id: DocumentId,
198 ) -> bool {
199 match event {
200 winit::WindowEvent::KeyboardInput {
201 input: winit::KeyboardInput {
202 state: winit::ElementState::Pressed,
203 virtual_keycode: Some(key),
204 ..
205 },
206 ..
207 } => {
208 let mut txn = Transaction::new();
209
210 match key {
211 winit::VirtualKeyCode::S => {
212 self.stress_keys.clear();
213
214 for _ in 0 .. 16 {
215 for _ in 0 .. 16 {
216 let size = 4;
217
218 let image_key = api.generate_image_key();
219
220 self.image_generator.generate_image(size);
221
222 txn.add_image(
223 image_key,
224 ImageDescriptor::new(
225 size,
226 size,
227 ImageFormat::BGRA8,
228 ImageDescriptorFlags::IS_OPAQUE,
229 ),
230 ImageData::new(self.image_generator.take()),
231 None,
232 );
233
234 self.stress_keys.push(image_key);
235 }
236 }
237 }
238 winit::VirtualKeyCode::D => if let Some(image_key) = self.image_key.take() {
239 txn.delete_image(image_key);
240 },
241 winit::VirtualKeyCode::U => if let Some(image_key) = self.image_key {
242 let size = 128;
243 self.image_generator.generate_image(size);
244
245 txn.update_image(
246 image_key,
247 ImageDescriptor::new(size, size, ImageFormat::BGRA8, ImageDescriptorFlags::IS_OPAQUE),
248 ImageData::new(self.image_generator.take()),
249 &DirtyRect::All,
250 );
251 },
252 winit::VirtualKeyCode::E => {
253 if let Some(image_key) = self.image_key.take() {
254 txn.delete_image(image_key);
255 }
256
257 let size = 32;
258 let image_key = api.generate_image_key();
259
260 let image_data = ExternalImageData {
261 id: ExternalImageId(0),
262 channel_index: size as u8,
263 image_type: ExternalImageType::Buffer,
264 };
265
266 txn.add_image(
267 image_key,
268 ImageDescriptor::new(size, size, ImageFormat::BGRA8, ImageDescriptorFlags::IS_OPAQUE),
269 ImageData::External(image_data),
270 None,
271 );
272
273 self.image_key = Some(image_key);
274 }
275 winit::VirtualKeyCode::R => {
276 if let Some(image_key) = self.image_key.take() {
277 txn.delete_image(image_key);
278 }
279
280 let image_key = api.generate_image_key();
281 let size = 32;
282 self.image_generator.generate_image(size);
283
284 txn.add_image(
285 image_key,
286 ImageDescriptor::new(size, size, ImageFormat::BGRA8, ImageDescriptorFlags::IS_OPAQUE),
287 ImageData::new(self.image_generator.take()),
288 None,
289 );
290
291 self.image_key = Some(image_key);
292 }
293 _ => {}
294 }
295
296 api.send_transaction(document_id, txn);
297 return true;
298 }
299 _ => {}
300 }
301
302 false
303 }
304
get_image_handler( &mut self, _gl: &dyn gl::Gl, ) -> Option<Box<dyn ExternalImageHandler>>305 fn get_image_handler(
306 &mut self,
307 _gl: &dyn gl::Gl,
308 ) -> Option<Box<dyn ExternalImageHandler>> {
309 Some(Box::new(ImageGenerator::new()))
310 }
311 }
312
main()313 fn main() {
314 let mut app = App {
315 image_key: None,
316 stress_keys: Vec::new(),
317 image_generator: ImageGenerator::new(),
318 swap_keys: Vec::new(),
319 swap_index: 0,
320 };
321 boilerplate::main_wrapper(&mut app, None);
322 }
323