diff --git a/webrender/src/device.rs b/webrender/src/device.rs index a7aa52b31b..bb7c67e08f 100644 --- a/webrender/src/device.rs +++ b/webrender/src/device.rs @@ -47,6 +47,10 @@ pub const MAX_INSTANCE_COUNT: usize = 1024; pub type TextureId = u32; +pub const INVALID_TEXTURE_ID: TextureId = 0; +pub const DEFAULT_READ_FBO: FBOId = FBOId(0); +pub const DEFAULT_DRAW_FBO: FBOId = FBOId(1); + const COLOR_RANGE: hal::image::SubresourceRange = hal::image::SubresourceRange { aspects: hal::format::AspectFlags::COLOR, levels: 0 .. 1, @@ -235,6 +239,7 @@ impl ExternalTexture { } } +#[derive(Debug)] pub struct Texture { id: TextureId, layer_count: i32, @@ -1178,7 +1183,7 @@ impl Program { let locals_buffer_stride = mem::size_of::(); let locals_data = vec![ Locals { - uTransform: projection.post_scale(1.0, -1.0, 1.0).to_row_arrays(), + uTransform: projection.to_row_arrays(), uDevicePixelRatio: 1.0, uMode: u_mode, }, @@ -1195,30 +1200,41 @@ impl Program { &mut self, device: &Device, ) { - use std::ops::Range; - if device.bound_textures[0] != 0 { - device.device.update_descriptor_sets::>(&[ - hal::pso::DescriptorSetWrite { - set: &self.descriptor_sets[0], - binding: self.bindings_map["tColor0"], - array_offset: 0, - write: hal::pso::DescriptorWrite::SampledImage(vec![ - ( - &device.images.get(&device.bound_textures[0]).unwrap().image_view, - hal::image::ImageLayout::Undefined, - ), - ]) - }, - hal::pso::DescriptorSetWrite { - set: &self.descriptor_sets[0], - binding: self.bindings_map["sColor0"], - array_offset: 0, - write: hal::pso::DescriptorWrite::Sampler(vec![&device.sampler_nearest]), - }, - ]); + const samplers: [(usize, &'static str); 6] = [(0, "Color0"), (1, "Color1"), (2, "Color2"), (3, "CacheA8"), (4, "CacheRGBA8"), (9, "SharedCacheA8")]; + for &(index, sampler) in samplers.iter() { + if device.bound_textures[index] != 0 { + self.bind_texture(device, &device.bound_textures[index], &device.bound_sampler[index], sampler); + } } } + fn bind_texture(&mut self, device: &Device, id: &TextureId, sampler: &TextureFilter, binding: &'static str) { + use std::ops::Range; + let sampler = match sampler { + &TextureFilter::Linear => &device.sampler_linear, + &TextureFilter::Nearest=> &device.sampler_nearest, + }; + device.device.update_descriptor_sets::>(&[ + hal::pso::DescriptorSetWrite { + set: &self.descriptor_sets[0], + binding: self.bindings_map[&("t".to_owned() + binding)], + array_offset: 0, + write: hal::pso::DescriptorWrite::SampledImage(vec![ + ( + &device.images[id].image_view, + hal::image::ImageLayout::Undefined, + ), + ]) + }, + hal::pso::DescriptorSetWrite { + set: &self.descriptor_sets[0], + binding: self.bindings_map[&("s".to_owned() + binding)], + array_offset: 0, + write: hal::pso::DescriptorWrite::Sampler(vec![sampler]), + }, + ]); + } + pub fn bind( &mut self, device: &Device, @@ -1375,6 +1391,55 @@ impl Program { } } +pub struct Framebuffer { + pub texture: TextureId, + pub layer_index: u16, + pub image_view: B::ImageView, + pub fbo: B::Framebuffer, +} + +impl Framebuffer { + pub fn new(device: &B::Device, texture: &Texture, image: &Image, layer_index: u16, render_pass: &B::RenderPass) -> Self { + let extent = hal::device::Extent { + width: texture.width as _, + height: texture.height as _, + depth: 1, + }; + let format = match texture.format { + ImageFormat::R8 => hal::format::Format::R8Unorm, + ImageFormat::RG8 => hal::format::Format::Rg8Unorm, + ImageFormat::BGRA8 => hal::format::Format::Bgra8Unorm, + _ => unimplemented!("TODO image format missing"), + }; + let image_view = device + .create_image_view( + &image.image, + format, + Swizzle::NO, + hal::image::SubresourceRange { + aspects: hal::format::AspectFlags::COLOR, + levels: 0 .. 1, + layers: layer_index .. layer_index+1, + }, + ) + .unwrap(); + let fbo = device + .create_framebuffer(render_pass, &[&image_view], extent) + .unwrap(); + Framebuffer { + texture: texture.id, + layer_index, + image_view, + fbo, + } + } + + pub fn deinit(mut self, device: &B::Device) { + device.destroy_framebuffer(self.fbo); + device.destroy_image_view(self.image_view); + } +} + pub struct Device { pub device: B::Device, pub memory_types: Vec, @@ -1402,13 +1467,14 @@ pub struct Device { blend_color: ColorF, // device state images: FastHashMap>, + fbos: FastHashMap>, + rbos: FastHashMap, bound_textures: [u32; 16], + bound_sampler: [TextureFilter; 16], bound_program: u32, //bound_vao: u32, bound_read_fbo: FBOId, bound_draw_fbo: FBOId, - default_read_fbo: u32, - default_draw_fbo: u32, device_pixel_ratio: f32, upload_method: UploadMethod, @@ -1669,13 +1735,14 @@ impl Device { }, images: FastHashMap::default(), + fbos: FastHashMap::default(), + rbos: FastHashMap::default(), bound_textures: [0; 16], + bound_sampler: [TextureFilter::Linear; 16], bound_program: 0, //bound_vao: 0, - bound_read_fbo: FBOId(0), - bound_draw_fbo: FBOId(0), - default_read_fbo: 0, - default_draw_fbo: 0, + bound_read_fbo: DEFAULT_READ_FBO, + bound_draw_fbo: DEFAULT_DRAW_FBO, max_texture_size, renderer_name, @@ -1878,11 +1945,16 @@ impl Device { //blend_mode: &BlendMode, //enable_depth_write: bool ) { + let ref fb = if self.bound_draw_fbo != DEFAULT_DRAW_FBO { + &self.fbos[&self.bound_draw_fbo].fbo + } else { + &self.framebuffers[self.current_frame_id] + }; let submit = program.submit( &mut self.command_pool, self.viewport.clone(), &self.render_pass, - &self.framebuffers[self.current_frame_id], + &fb, &vec![], &self.current_blend_state, self.blend_color @@ -1917,9 +1989,10 @@ impl Device { pub fn reset_state(&mut self) { self.bound_textures = [0; 16]; + self.bound_sampler = [TextureFilter::Linear; 16]; //self.bound_vao = 0; - self.bound_read_fbo = FBOId(0); - self.bound_draw_fbo = FBOId(0); + self.bound_read_fbo = DEFAULT_READ_FBO; + self.bound_draw_fbo = DEFAULT_DRAW_FBO; self.reset_image_buffer_offsets(); } @@ -1933,15 +2006,10 @@ impl Device { debug_assert!(!self.inside_frame); self.inside_frame = true; - // Retrive the currently set FBO. - let default_read_fbo = 0;//self.gl.get_integer_v(gl::READ_FRAMEBUFFER_BINDING); - self.default_read_fbo = default_read_fbo as u32; - let default_draw_fbo = 1;//self.gl.get_integer_v(gl::DRAW_FRAMEBUFFER_BINDING); - self.default_draw_fbo = default_draw_fbo as u32; - // Texture state for i in 0 .. self.bound_textures.len() { self.bound_textures[i] = 0; + self.bound_sampler[i] = TextureFilter::Linear; //self.gl.active_texture(gl::TEXTURE0 + i as u32); //self.gl.bind_texture(gl::TEXTURE_2D, 0); } @@ -1955,8 +2023,8 @@ impl Device { //self.gl.bind_vertex_array(0); // FBO state - self.bound_read_fbo = FBOId(self.default_read_fbo); - self.bound_draw_fbo = FBOId(self.default_draw_fbo); + self.bound_read_fbo = DEFAULT_READ_FBO; + self.bound_draw_fbo = DEFAULT_DRAW_FBO; // Pixel op state //self.gl.pixel_store_i(gl::UNPACK_ALIGNMENT, 1); @@ -1968,11 +2036,12 @@ impl Device { self.frame_id } - fn bind_texture_impl(&mut self, slot: TextureSlot, id: u32) { + fn bind_texture_impl(&mut self, slot: TextureSlot, id: u32, sampler: TextureFilter) { debug_assert!(self.inside_frame); if self.bound_textures[slot.0] != id { self.bound_textures[slot.0] = id; + self.bound_sampler[slot.0] = sampler; //self.gl.active_texture(gl::TEXTURE0 + slot.0 as u32); //self.gl.bind_texture(target, id); //self.gl.active_texture(gl::TEXTURE0); @@ -1983,14 +2052,14 @@ impl Device { where S: Into, { - self.bind_texture_impl(sampler.into(), texture.id); + self.bind_texture_impl(sampler.into(), texture.id, texture.filter); } pub fn bind_external_texture(&mut self, sampler: S, external_texture: &ExternalTexture) where S: Into, { - self.bind_texture_impl(sampler.into(), external_texture.id); + self.bind_texture_impl(sampler.into(), external_texture.id, TextureFilter::Linear); } pub fn bind_read_target_impl(&mut self, fbo_id: FBOId) { @@ -1998,16 +2067,15 @@ impl Device { if self.bound_read_fbo != fbo_id { self.bound_read_fbo = fbo_id; - //fbo_id.bind(FBOTarget::Read); } } pub fn bind_read_target(&mut self, texture_and_layer: Option<(&Texture, i32)>) { - /*let fbo_id = texture_and_layer.map_or(FBOId(self.default_read_fbo), |texture_and_layer| { + let fbo_id = texture_and_layer.map_or(DEFAULT_READ_FBO, |texture_and_layer| { texture_and_layer.0.fbo_ids[texture_and_layer.1 as usize] }); - self.bind_read_target_impl(fbo_id)*/ + self.bind_read_target_impl(fbo_id) } fn bind_draw_target_impl(&mut self, fbo_id: FBOId) { @@ -2015,7 +2083,6 @@ impl Device { if self.bound_draw_fbo != fbo_id { self.bound_draw_fbo = fbo_id; - //fbo_id.bind(FBOTarget::Draw); } } @@ -2024,20 +2091,26 @@ impl Device { texture_and_layer: Option<(&Texture, i32)>, dimensions: Option, ) { - /*let fbo_id = texture_and_layer.map_or(FBOId(self.default_draw_fbo), |texture_and_layer| { + let fbo_id = texture_and_layer.map_or(DEFAULT_DRAW_FBO, |texture_and_layer| { texture_and_layer.0.fbo_ids[texture_and_layer.1 as usize] }); self.bind_draw_target_impl(fbo_id); if let Some(dimensions) = dimensions { + self.viewport.rect = hal::command::Rect { + x: 0, + y: 0, + w: dimensions.width as _, + h: dimensions.height as _, + }; /*self.gl.viewport( 0, 0, dimensions.width as _, dimensions.height as _, );*/ - }*/ + } } pub fn create_fbo_for_external_texture(&mut self, texture_id: u32) -> FBOId { @@ -2078,24 +2151,44 @@ impl Device { }*/ fn generate_texture_id(&mut self) -> TextureId { let mut rng = rand::thread_rng(); - let mut texture_id = 1; // 0 is used for invalid + let mut texture_id = INVALID_TEXTURE_ID + 1; while self.images.contains_key(&texture_id) { - texture_id = rng.gen_range::(1, u32::max_value()); + texture_id = rng.gen_range::(INVALID_TEXTURE_ID + 1, u32::max_value()); } texture_id } + fn generate_fbo_ids(&mut self, count: i32) -> Vec { + let mut rng = rand::thread_rng(); + let mut fboids = vec!(); + let mut fbo_id = FBOId(DEFAULT_DRAW_FBO.0 + 1); + for _ in 0..count { + while self.fbos.contains_key(&fbo_id) || fboids.contains(&fbo_id) { + fbo_id = FBOId(rng.gen_range::(DEFAULT_DRAW_FBO.0 + 1, u32::max_value())); + } + fboids.push(fbo_id); + } + fboids + } + + fn generate_rbo_id(&mut self) -> RBOId { + let mut rng = rand::thread_rng(); + let mut rbo_id = RBOId(1); // 0 is used for invalid + while self.rbos.contains_key(&rbo_id) { + rbo_id = RBOId(rng.gen_range::(1, u32::max_value())); + } + rbo_id + } + fn update_image( &mut self, texture: &mut Texture, - pixels: Option<&[u8]>, ) { if texture.id == 0 { let id = self.generate_texture_id(); texture.id = id; } else { - let old_image = self.images.remove(&texture.id).expect("Texture not found."); - old_image.deinit(&self.device); + self.free_image(texture); } assert_eq!(self.images.contains_key(&texture.id), false); let img = Image::new( @@ -2106,28 +2199,18 @@ impl Device { texture.height, texture.layer_count ); - self.images.insert(texture.id, img); - if let Some(data) = pixels { - self.upload_queue - .push( - self.images - .get_mut(&texture.id) - .expect("Texture not found.") - .update( - &mut self.device, - &mut self.command_pool, - DeviceUintRect::new( - DeviceUintPoint::new(0, 0), - DeviceUintSize::new(texture.width, texture.height), - ), - 0, - data, - ) - ); + assert_eq!(texture.fbo_ids.len(), 0); + let new_fbos = self.generate_fbo_ids(texture.layer_count); + + for i in 0..texture.layer_count as u16 { + let fbo = Framebuffer::new(&self.device, &texture, &img, i, &self.render_pass); + self.fbos.insert(new_fbos[i as usize],fbo); + texture.fbo_ids.push(new_fbos[i as usize]); } - } + self.images.insert(texture.id, img); + } pub fn create_texture( &mut self, format: ImageFormat, @@ -2140,7 +2223,7 @@ impl Device { format, filter: TextureFilter::Nearest, render_target: None, - fbo_ids: vec![FBOId(0)], + fbo_ids: vec![], depth_rb: None, } } @@ -2183,7 +2266,7 @@ impl Device { self.bind_texture(DEFAULT_TEXTURE, texture); self.set_texture_parameters(/*texture.target,*/ texture.filter); - self.update_target_storage(texture, &rt_info, true, None); + self.update_target_storage(texture, &rt_info, true); let rect = DeviceIntRect::new(DeviceIntPoint::zero(), old_size.to_i32()); for (read_fbo, &draw_fbo) in old_fbos.into_iter().zip(&texture.fbo_ids) { @@ -2221,12 +2304,31 @@ impl Device { match render_target { Some(info) => { - self.update_target_storage(texture, &info, is_resized, pixels); + self.update_target_storage(texture, &info, is_resized); } None => { - self.update_image(texture, pixels); + self.update_image(texture); } } + + if let Some(data) = pixels { + self.upload_queue + .push( + self.images + .get_mut(&texture.id) + .expect("Texture not found.") + .update( + &mut self.device, + &mut self.command_pool, + DeviceUintRect::new( + DeviceUintPoint::new(0, 0), + DeviceUintSize::new(texture.width, texture.height), + ), + 0, + data, + ) + ); + } } /// Updates the render target storage for the texture, creating FBOs as required. @@ -2235,32 +2337,19 @@ impl Device { texture: &mut Texture, rt_info: &RenderTargetInfo, is_resized: bool, - pixels: Option<&[u8]>, ) { - println!("TODO update_target_storage"); assert!(texture.layer_count > 0 || texture.width + texture.height == 0); - let needed_layer_count = texture.layer_count - texture.fbo_ids.len() as i32; - let allocate_color = needed_layer_count != 0 || is_resized || pixels.is_some(); + let allocate_color = texture.layer_count != texture.fbo_ids.len() as i32 || is_resized; if allocate_color { - self.update_image(texture, pixels); + self.update_image(texture); } - /*if needed_layer_count > 0 { - // Create more framebuffers to fill the gap - let new_fbos = self.gl.gen_framebuffers(needed_layer_count); - texture - .fbo_ids - .extend(new_fbos.into_iter().map(FBOId)); - } else if needed_layer_count < 0 { - // Remove extra framebuffers - for old in texture.fbo_ids.drain(texture.layer_count as usize ..) { - self.gl.delete_framebuffers(&[old.0]); - } + if rt_info.has_depth { + println!("TODO update_target_storage depth"); } - - let (mut depth_rb, allocate_depth) = match texture.depth_rb { + /*let (mut depth_rb, allocate_depth) = match texture.depth_rb { Some(rbo) => (rbo.0, is_resized || !rt_info.has_depth), None if rt_info.has_depth => { let renderbuffer_ids = self.gl.gen_renderbuffers(1); @@ -2285,9 +2374,9 @@ impl Device { depth_rb = 0; texture.depth_rb = None; } - } + }*/ - if allocate_color || allocate_depth { + /*if allocate_color || allocate_depth { let original_bound_fbo = self.bound_draw_fbo; for (fbo_index, &fbo_id) in texture.fbo_ids.iter().enumerate() { self.bind_external_draw_target(fbo_id); @@ -2298,6 +2387,7 @@ impl Device { 0, fbo_index as _, ); + self.gl.framebuffer_renderbuffer( gl::DRAW_FRAMEBUFFER, gl::DEPTH_ATTACHMENT, @@ -2311,7 +2401,57 @@ impl Device { pub fn blit_render_target(&mut self, src_rect: DeviceIntRect, dest_rect: DeviceIntRect) { debug_assert!(self.inside_frame); + let (src_img, src_layer) = if self.bound_read_fbo != DEFAULT_READ_FBO { + let fbo = &self.fbos[&self.bound_read_fbo]; + let img = &self.images[&fbo.texture]; + let layer = fbo.layer_index; + (&img.image, layer) + } else { + (&self.frame_images[self.current_frame_id].0, 0) + }; + + let (dest_img, dest_layer) = if self.bound_draw_fbo != DEFAULT_DRAW_FBO { + let fbo = &self.fbos[&self.bound_draw_fbo]; + let img = &self.images[&fbo.texture]; + let layer = fbo.layer_index; + (&img.image, layer) + } else { + (&self.frame_images[self.current_frame_id].0, 0) + }; + let mut cmd_buffer = self.command_pool.acquire_command_buffer(false); + use std::ops::Range; + cmd_buffer.copy_image( + src_img, + hal::image::ImageLayout::ColorAttachmentOptimal, + dest_img, + hal::image::ImageLayout::ColorAttachmentOptimal, + &[ + hal::command::ImageCopy { + aspect_mask: hal::format::AspectFlags::COLOR, + src_subresource: (0, 0), + src_offset: hal::command::Offset { + x: src_rect.origin.x as i32, + y: src_rect.origin.y as i32, + z: src_layer as i32, + }, + dst_subresource: (0, 0), + dst_offset: hal::command::Offset { + x: dest_rect.origin.x as i32, + y: dest_rect.origin.y as i32, + z: dest_layer as i32, + }, + extent: hal::device::Extent { + width: src_rect.size.width as u32, + height: src_rect.size.height as u32, + depth: 1, + }, + num_layers: 1, + } + ], + ); + + self.upload_queue.push(cmd_buffer.finish()); /*self.gl.blit_framebuffer( src_rect.origin.x, src_rect.origin.y, @@ -2326,72 +2466,38 @@ impl Device { );*/ } - /*fn free_texture_storage_impl(&mut self, target: gl::GLenum, desc: FormatDesc) { - match target { - gl::TEXTURE_2D_ARRAY => { - self.gl.tex_image_3d( - gl::TEXTURE_2D_ARRAY, - 0, - desc.internal, - 0, - 0, - 0, - 0, - desc.external, - desc.pixel_type, - None, - ); - } - _ => { - self.gl.tex_image_2d( - target, - 0, - desc.internal, - 0, - 0, - 0, - desc.external, - desc.pixel_type, - None, - ); - } - } - }*/ - pub fn free_texture_storage(&mut self, texture: &mut Texture) { - /*debug_assert!(self.inside_frame); - + debug_assert!(self.inside_frame); if texture.width + texture.height == 0 { return; } - self.bind_texture(DEFAULT_TEXTURE, texture); - let desc = gl_describe_format(self.gl(), texture.format); + self.free_image(texture); - self.free_texture_storage_impl(texture.target, desc); + texture.width = 0; + texture.height = 0; + texture.layer_count = 0; + texture.id = 0; + } - if let Some(RBOId(depth_rb)) = texture.depth_rb.take() { + pub fn free_image(&mut self, texture: &mut Texture) { + /*if let Some(RBOId(depth_rb)) = texture.depth_rb.take() { self.gl.delete_renderbuffers(&[depth_rb]); - } + }*/ if !texture.fbo_ids.is_empty() { - let fbo_ids: Vec<_> = texture - .fbo_ids - .drain(..) - .map(|FBOId(fbo_id)| fbo_id) - .collect(); - self.gl.delete_framebuffers(&fbo_ids[..]); + for old in texture.fbo_ids.drain(..) { + let old_fbo = self.fbos.remove(&old).unwrap(); + old_fbo.deinit(&self.device); + } } - texture.width = 0; - texture.height = 0; - texture.layer_count = 0;*/ + let image = self.images.remove(&texture.id).expect("Texture not found."); + image.deinit(&self.device); } pub fn delete_texture(&mut self, mut texture: Texture) { self.free_texture_storage(&mut texture); - //self.gl.delete_textures(&[texture.id]); - texture.id = 0; } #[cfg(feature = "capture")] @@ -2712,14 +2818,23 @@ impl Device { ]); } + let (img, layer) = if self.bound_draw_fbo != DEFAULT_DRAW_FBO { + let fbo = &self.fbos[&self.bound_draw_fbo]; + let img = &self.images[&fbo.texture]; + let layer = fbo.layer_index; + (&img.image, layer) + } else { + (&self.frame_images[self.current_frame_id].0, 0) + }; + if let Some(color) = color { cmd_buffer.clear_color_image( - &self.frame_images[self.current_frame_id].0, + img, hal::image::ImageLayout::ColorAttachmentOptimal, hal::image::SubresourceRange { aspects: hal::format::AspectFlags::COLOR, levels: 0 .. 1, - layers: 0 .. 1, + layers: layer .. layer+1, }, hal::command::ClearColor::Float([color[0], color[1], color[2], color[3]]), ); diff --git a/webrender/src/renderer.rs b/webrender/src/renderer.rs index f573e29713..3be9c17b20 100644 --- a/webrender/src/renderer.rs +++ b/webrender/src/renderer.rs @@ -2854,9 +2854,9 @@ impl Renderer { textures: &BatchTextures, stats: &mut RendererStats, ) { - for i in 0 .. textures.colors.len() { + for (i, texture) in textures.colors.iter().enumerate() { self.texture_resolver.bind( - &textures.colors[i], + &texture, TextureSampler::color(i), &mut self.device, ); @@ -2960,6 +2960,7 @@ impl Renderer { // Handle special case readback for composites. if let BatchKind::Composite { task_id, source_id, backdrop_id } = key.kind { + println!("TODO Composite"); // composites can't be grouped together because // they may overlap and affect each other. debug_assert_eq!(instances.len(), 1); @@ -3020,9 +3021,9 @@ impl Renderer { self.device.bind_draw_target(render_target, None); } - for i in 0 .. key.textures.colors.len() { + for (i, texture) in key.textures.colors.iter().enumerate() { self.texture_resolver.bind( - &key.textures.colors[i], + &texture, TextureSampler::color(i), &mut self.device, ); @@ -3096,6 +3097,11 @@ impl Renderer { let (source_rect, source_layer) = source.get_target_rect(); let (dest_rect, _) = dest.get_target_rect(); + if source_rect.size != dest_rect.size { + println!("TODO handle_scaling"); + continue; + } + let cache_draw_target = (cache_texture, source_layer.0 as i32); self.device .bind_read_target(Some(cache_draw_target)); @@ -3223,12 +3229,18 @@ impl Renderer { let mut program = self.cs_text_run.get(&mut self.device).unwrap(); program.bind_locals(&self.device.device, projection, 0); - for (_texture_id, instances) in &target.alpha_batcher.text_run_cache_prims { - // TODO: bind_texture: BatchTextures::color(*texture_id) - program.bind_instances( - &self.device.device, - &instances.iter().map(|pi| pi.into()).collect::>(), + for (texture_id, instances) in &target.alpha_batcher.text_run_cache_prims { + for (i, texture) in BatchTextures::color(*texture_id).colors.iter().enumerate() { + self.texture_resolver.bind( + &texture, + TextureSampler::color(i), + &mut self.device, ); + } + program.bind_instances( + &self.device.device, + &instances.iter().map(|pi| pi.into()).collect::>(), + ); self.device.draw(program); } } @@ -3310,7 +3322,13 @@ impl Renderer { BlendMode::PremultipliedAlpha => { self.device.set_blend_mode_premultiplied_alpha(); let mut program = self.ps_text_run.get(glyph_format, transform_kind, &mut self.device).unwrap(); - // TODO: bind textures: batch.key.textures + for (i, texture) in batch.key.textures.colors.iter().enumerate() { + self.texture_resolver.bind( + &texture, + TextureSampler::color(i), + &mut self.device, + ); + } program.bind( &self.device, projection, @@ -3322,7 +3340,13 @@ impl Renderer { BlendMode::SubpixelDualSource => { self.device.set_blend_mode_subpixel_dual_source(); let mut program = self.ps_text_run_dual_source.get(glyph_format, transform_kind, &mut self.device).unwrap(); - // TODO: bind textures: batch.key.textures + for (i, texture) in batch.key.textures.colors.iter().enumerate() { + self.texture_resolver.bind( + &texture, + TextureSampler::color(i), + &mut self.device, + ); + } program.bind( &self.device, projection, @@ -3334,7 +3358,13 @@ impl Renderer { BlendMode::SubpixelConstantTextColor(color) => { self.device.set_blend_mode_subpixel_constant_text_color(color); let mut program = self.ps_text_run.get(glyph_format, transform_kind, &mut self.device).unwrap(); - // TODO: bind textures: batch.key.textures + for (i, texture) in batch.key.textures.colors.iter().enumerate() { + self.texture_resolver.bind( + &texture, + TextureSampler::color(i), + &mut self.device, + ); + } program.bind( &self.device, projection, @@ -3350,7 +3380,13 @@ impl Renderer { // self.device.set_blend_mode_subpixel_pass0(); let mut program = self.ps_text_run.get(glyph_format, transform_kind, &mut self.device).unwrap(); - // TODO: bind textures: batch.key.textures + for (i, texture) in batch.key.textures.colors.iter().enumerate() { + self.texture_resolver.bind( + &texture, + TextureSampler::color(i), + &mut self.device, + ); + } program.bind( &self.device, projection, @@ -3382,7 +3418,13 @@ impl Renderer { // self.device.set_blend_mode_subpixel_with_bg_color_pass0(); let mut program = self.ps_text_run.get(glyph_format, transform_kind, &mut self.device).unwrap(); - // TODO: bind textures: batch.key.textures + for (i, texture) in batch.key.textures.colors.iter().enumerate() { + self.texture_resolver.bind( + &texture, + TextureSampler::color(i), + &mut self.device, + ); + } program.bind( &self.device, projection, @@ -3672,12 +3714,25 @@ impl Renderer { // draw image masks let mut program = self.cs_clip_image.get(&mut self.device).unwrap(); program.bind_locals(&self.device.device, projection, 0); - for (_mask_texture_id, items) in &target.clip_batcher.images { - // TODO: bind textures: textures - program.bind_instances( - &self.device.device, - &items.iter().map(|ci| ci.into()).collect::>(), + for (mask_texture_id, items) in &target.clip_batcher.images { + let textures = BatchTextures { + colors: [ + mask_texture_id.clone(), + SourceTexture::Invalid, + SourceTexture::Invalid, + ], + }; + for (i, texture) in textures.colors.iter().enumerate() { + self.texture_resolver.bind( + &texture, + TextureSampler::color(i), + &mut self.device, ); + } + program.bind_instances( + &self.device.device, + &items.iter().map(|ci| ci.into()).collect::>(), + ); self.device.draw(&mut program); } } @@ -4015,8 +4070,8 @@ impl Renderer { let projection = Transform3D::ortho( 0.0, framebuffer_size.width as f32, - framebuffer_size.height as f32, 0.0, + framebuffer_size.height as f32, ORTHO_NEAR_PLANE, ORTHO_FAR_PLANE, ); @@ -4084,8 +4139,8 @@ impl Renderer { let projection = Transform3D::ortho( 0.0, color.max_size.width as f32, - 0.0, color.max_size.height as f32, + 0.0, ORTHO_NEAR_PLANE, ORTHO_FAR_PLANE, ); diff --git a/webrender/src/tiling.rs b/webrender/src/tiling.rs index c5be24cab5..79dbb12d10 100644 --- a/webrender/src/tiling.rs +++ b/webrender/src/tiling.rs @@ -211,20 +211,20 @@ impl RenderTargetList { } pub fn check_ready(&self) { - //TODO use this - /*match self.texture { + match self.texture { Some(ref t) => { assert_eq!(t.get_dimensions(), self.max_size); assert_eq!(t.get_format(), self.format); assert_eq!(t.get_render_target_layer_count(), self.targets.len()); assert_eq!(t.get_layer_count() as usize, self.targets.len()); - assert_eq!(t.has_depth(), t.get_rt_info().unwrap().has_depth); - assert_eq!(t.has_depth(), self.needs_depth()); + //TODO use this + //assert_eq!(t.has_depth(), t.get_rt_info().unwrap().has_depth); + //assert_eq!(t.has_depth(), self.needs_depth()); } None => { assert!(self.targets.is_empty()) } - }*/ + } } }