From cf85e75f83468cef6f63128bbe450aff6ad93242 Mon Sep 17 00:00:00 2001 From: Morris Tseng Date: Wed, 29 Nov 2017 15:14:24 +0800 Subject: [PATCH] Add drop-shadow support. --- webrender/res/brush_image.glsl | 7 +- webrender/res/ps_hardware_composite.glsl | 2 +- webrender/src/frame_builder.rs | 5 +- webrender/src/internal_types.rs | 7 ++ webrender/src/picture.rs | 47 +++++++- webrender/src/render_task.rs | 8 ++ webrender/src/renderer.rs | 104 ++++++++++++++---- webrender/src/scene.rs | 6 +- webrender/src/tiling.rs | 98 +++++++++++++++-- webrender_api/src/display_item.rs | 1 + .../reftests/filters/filter-drop-shadow.png | Bin 0 -> 79986 bytes .../reftests/filters/filter-drop-shadow.yaml | 9 ++ wrench/reftests/filters/reftest.list | 1 + wrench/reftests/transforms/reftest.list | 2 +- wrench/src/parse_function.rs | 20 +++- wrench/src/yaml_frame_writer.rs | 6 + wrench/src/yaml_helper.rs | 10 +- 17 files changed, 285 insertions(+), 48 deletions(-) create mode 100644 wrench/reftests/filters/filter-drop-shadow.png create mode 100644 wrench/reftests/filters/filter-drop-shadow.yaml diff --git a/webrender/res/brush_image.glsl b/webrender/res/brush_image.glsl index cd03fede96..adca94181b 100644 --- a/webrender/res/brush_image.glsl +++ b/webrender/res/brush_image.glsl @@ -14,7 +14,7 @@ flat varying vec4 vUvBounds; flat varying vec4 vUvBounds_NoClamp; flat varying vec4 vParams; -#if defined WR_FEATURE_ALPHA_TARGET +#if defined WR_FEATURE_ALPHA_TARGET || defined WR_FEATURE_COLOR_TARGET_ALPHA_MASK flat varying vec4 vColor; #endif @@ -41,6 +41,9 @@ void brush_vs( #if defined WR_FEATURE_COLOR_TARGET vec2 texture_size = vec2(textureSize(sColor0, 0).xy); +#elif defined WR_FEATURE_COLOR_TARGET_ALPHA_MASK + vec2 texture_size = vec2(textureSize(sColor0, 0).xy); + vColor = blur_task.color; #else vec2 texture_size = vec2(textureSize(sColor1, 0).xy); vColor = blur_task.color; @@ -120,6 +123,8 @@ vec4 brush_fs() { #if defined WR_FEATURE_COLOR_TARGET vec4 color = texture(sColor0, vec3(uv, vUv.z)); +#elif defined WR_FEATURE_COLOR_TARGET_ALPHA_MASK + vec4 color = vColor * texture(sColor0, vec3(uv, vUv.z)).a; #else vec4 color = vColor * texture(sColor1, vec3(uv, vUv.z)).r; #endif diff --git a/webrender/res/ps_hardware_composite.glsl b/webrender/res/ps_hardware_composite.glsl index 30f1c70121..253b9b29eb 100644 --- a/webrender/res/ps_hardware_composite.glsl +++ b/webrender/res/ps_hardware_composite.glsl @@ -34,6 +34,6 @@ void main(void) { #ifdef WR_FRAGMENT_SHADER void main(void) { vec2 uv = clamp(vUv.xy, vUvBounds.xy, vUvBounds.zw); - oFragColor = texture(sCacheRGBA8, vec3(uv, vUv.z)); + oFragColor = texture(sColor0, vec3(uv, vUv.z)); } #endif diff --git a/webrender/src/frame_builder.rs b/webrender/src/frame_builder.rs index e795c38e26..80cc7e27db 100644 --- a/webrender/src/frame_builder.rs +++ b/webrender/src/frame_builder.rs @@ -22,7 +22,7 @@ use frame::FrameId; use glyph_rasterizer::FontInstance; use gpu_cache::GpuCache; use gpu_types::ClipScrollNodeData; -use internal_types::{FastHashMap, FastHashSet}; +use internal_types::{FastHashMap, FastHashSet, RenderPassIndex}; use picture::{PictureCompositeMode, PictureKind, PicturePrimitive, RasterizationSpace}; use prim_store::{BrushAntiAliasMode, BrushKind, BrushPrimitive, TexelRect, YuvImagePrimitiveCpu}; use prim_store::{GradientPrimitiveCpu, ImagePrimitiveCpu, LinePrimitive, PrimitiveKind}; @@ -1761,7 +1761,7 @@ impl FrameBuilder { let mut deferred_resolves = vec![]; - for pass in &mut passes { + for (pass_index, pass) in passes.iter_mut().enumerate() { let ctx = RenderTargetContext { device_pixel_ratio, prim_store: &self.prim_store, @@ -1776,6 +1776,7 @@ impl FrameBuilder { &mut render_tasks, &mut deferred_resolves, &self.clip_store, + RenderPassIndex(pass_index), ); profile_counters.passes.inc(); diff --git a/webrender/src/internal_types.rs b/webrender/src/internal_types.rs index f80bde7765..1e04fb8da5 100644 --- a/webrender/src/internal_types.rs +++ b/webrender/src/internal_types.rs @@ -32,6 +32,9 @@ pub type FastHashSet = HashSet>; #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] pub struct CacheTextureId(pub usize); +#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] +pub struct RenderPassIndex(pub usize); + // Represents the source for a texture. // These are passed from throughout the // pipeline until they reach the rendering @@ -45,6 +48,10 @@ pub enum SourceTexture { External(ExternalImageData), CacheA8, CacheRGBA8, + // XXX Remove this once RenderTaskCacheA8 is used. + #[allow(dead_code)] + RenderTaskCacheA8(RenderPassIndex), + RenderTaskCacheRGBA8(RenderPassIndex), } pub const ORTHO_NEAR_PLANE: f32 = -1000000.0; diff --git a/webrender/src/picture.rs b/webrender/src/picture.rs index b707f377a8..b12d902353 100644 --- a/webrender/src/picture.rs +++ b/webrender/src/picture.rs @@ -67,7 +67,10 @@ pub enum PictureKind { // If a mix-blend-mode, contains the render task for // the readback of the framebuffer that we use to sample // from in the mix-blend-mode shader. - readback_render_task_id: Option, + // For drop-shadow filter, this will store the original + // picture task which would be rendered on screen after + // blur pass. + secondary_render_task_id: Option, /// How this picture should be composited. /// If None, don't composite - just draw directly on parent surface. composite_mode: Option, @@ -186,7 +189,7 @@ impl PicturePrimitive { runs: Vec::new(), render_task_id: None, kind: PictureKind::Image { - readback_render_task_id: None, + secondary_render_task_id: None, composite_mode, is_in_3d_context, frame_output_pipeline_id, @@ -236,6 +239,11 @@ impl PicturePrimitive { let inflate_size = blur_radius * BLUR_SAMPLE_SCALE; local_content_rect.inflate(inflate_size, inflate_size) } + Some(PictureCompositeMode::Filter(FilterOp::DropShadow(offset, blur_radius, _))) => { + let inflate_size = blur_radius * BLUR_SAMPLE_SCALE; + local_content_rect.inflate(inflate_size, inflate_size) + .translate(&offset) + } _ => { local_content_rect } @@ -304,7 +312,7 @@ impl PicturePrimitive { ) { match self.kind { PictureKind::Image { - ref mut readback_render_task_id, + ref mut secondary_render_task_id, composite_mode, .. } => { @@ -341,6 +349,37 @@ impl PicturePrimitive { let blur_render_task_id = render_tasks.add(blur_render_task); self.render_task_id = Some(blur_render_task_id); } + Some(PictureCompositeMode::Filter(FilterOp::DropShadow(offset, blur_radius, color))) => { + let picture_task = RenderTask::new_picture( + Some(prim_screen_rect.size), + prim_index, + RenderTargetKind::Color, + prim_screen_rect.origin.x as f32 - offset.x, + prim_screen_rect.origin.y as f32 - offset.y, + PremultipliedColorF::TRANSPARENT, + ClearMode::Transparent, + self.rasterization_kind, + child_tasks, + None, + ); + + let blur_std_deviation = blur_radius * prim_context.device_pixel_ratio; + let picture_task_id = render_tasks.add(picture_task); + + let blur_render_task = RenderTask::new_blur( + blur_std_deviation, + picture_task_id, + render_tasks, + RenderTargetKind::Color, + &[], + ClearMode::Transparent, + color.premultiplied(), + None, + ); + + *secondary_render_task_id = Some(picture_task_id); + self.render_task_id = Some(render_tasks.add(blur_render_task)); + } Some(PictureCompositeMode::MixBlend(..)) => { let picture_task = RenderTask::new_picture( Some(prim_screen_rect.size), @@ -357,7 +396,7 @@ impl PicturePrimitive { let readback_task_id = render_tasks.add(RenderTask::new_readback(*prim_screen_rect)); - *readback_render_task_id = Some(readback_task_id); + *secondary_render_task_id = Some(readback_task_id); parent_tasks.push(readback_task_id); self.render_task_id = Some(render_tasks.add(picture_task)); diff --git a/webrender/src/render_task.rs b/webrender/src/render_task.rs index df3d624373..e2a743bc93 100644 --- a/webrender/src/render_task.rs +++ b/webrender/src/render_task.rs @@ -9,6 +9,7 @@ use clip::{ClipSourcesWeakHandle}; use clip_scroll_tree::CoordinateSystemId; use euclid::TypedSize2D; use gpu_types::{ClipScrollNodeIndex}; +use internal_types::RenderPassIndex; use picture::RasterizationSpace; use prim_store::{PrimitiveIndex}; #[cfg(feature = "debugger")] @@ -241,6 +242,7 @@ pub struct RenderTask { pub children: Vec, pub kind: RenderTaskKind, pub clear_mode: ClearMode, + pub pass_index: Option, } impl RenderTask { @@ -276,6 +278,7 @@ impl RenderTask { rasterization_kind, }), clear_mode, + pass_index: None, } } @@ -286,6 +289,7 @@ impl RenderTask { location: RenderTaskLocation::Dynamic(None, screen_rect.size), kind: RenderTaskKind::Readback(screen_rect), clear_mode: ClearMode::Transparent, + pass_index: None, } } @@ -305,6 +309,7 @@ impl RenderTask { coordinate_system_id: prim_coordinate_system_id, }), clear_mode: ClearMode::One, + pass_index: None, } } @@ -375,6 +380,7 @@ impl RenderTask { scale_factor, }), clear_mode, + pass_index: None, }; let blur_task_v_id = render_tasks.add(blur_task_v); @@ -394,6 +400,7 @@ impl RenderTask { scale_factor, }), clear_mode, + pass_index: None, }; blur_task_h @@ -417,6 +424,7 @@ impl RenderTask { RenderTargetKind::Color => ClearMode::Transparent, RenderTargetKind::Alpha => ClearMode::One, }, + pass_index: None, } } diff --git a/webrender/src/renderer.rs b/webrender/src/renderer.rs index f438d7538c..7f292d1355 100644 --- a/webrender/src/renderer.rs +++ b/webrender/src/renderer.rs @@ -40,7 +40,7 @@ use gpu_cache::{GpuBlockData, GpuCacheUpdate, GpuCacheUpdateList}; use gpu_types::PrimitiveInstance; use internal_types::{BatchTextures, SourceTexture, ORTHO_FAR_PLANE, ORTHO_NEAR_PLANE}; use internal_types::{CacheTextureId, FastHashMap, RenderedDocument, ResultMsg, TextureUpdateOp}; -use internal_types::{DebugOutput, RenderTargetInfo, TextureUpdateList, TextureUpdateSource}; +use internal_types::{DebugOutput, RenderPassIndex, RenderTargetInfo, TextureUpdateList, TextureUpdateSource}; use profiler::{BackendProfileCounters, Profiler}; use profiler::{GpuProfileTag, RendererProfileCounters, RendererProfileTimers}; use query::{GpuProfiler, GpuTimer}; @@ -65,8 +65,8 @@ use std::thread; use texture_cache::TextureCache; use thread_profiler::{register_thread_with_profiler, write_profile}; use tiling::{AlphaRenderTarget, ColorRenderTarget}; -use tiling::{RenderPass, RenderPassKind, RenderTargetKind, RenderTargetList}; -use tiling::{BatchKey, BatchKind, BrushBatchKind, Frame, RenderTarget, ScalingInfo, TransformBatchKind}; +use tiling::{RenderPass, RenderPassKind, RenderTargetList}; +use tiling::{BatchKey, BatchKind, BrushBatchKind, BrushImageSourceKind, Frame, RenderTarget, ScalingInfo, TransformBatchKind}; use time::precise_time_ns; use util::TransformedRectKind; @@ -551,6 +551,8 @@ impl CpuProfile { } } +struct RenderTargetPoolId(usize); + struct SourceTextureResolver { /// A vector for fast resolves of texture cache IDs to /// native texture IDs. This maps to a free-list managed @@ -573,6 +575,11 @@ struct SourceTextureResolver { /// The current cache textures. cache_rgba8_texture: Option, cache_a8_texture: Option, + + pass_rgba8_textures: FastHashMap, + pass_a8_textures: FastHashMap, + + render_target_pool: Vec, } impl SourceTextureResolver { @@ -595,6 +602,9 @@ impl SourceTextureResolver { dummy_cache_texture, cache_a8_texture: None, cache_rgba8_texture: None, + pass_rgba8_textures: FastHashMap::default(), + pass_a8_textures: FastHashMap::default(), + render_target_pool: Vec::new(), } } @@ -604,27 +614,44 @@ impl SourceTextureResolver { for texture in self.cache_texture_map { device.delete_texture(texture); } + + for texture in self.render_target_pool { + device.delete_texture(texture); + } } - fn begin_frame(&self) { + fn begin_frame(&mut self) { assert!(self.cache_rgba8_texture.is_none()); assert!(self.cache_a8_texture.is_none()); + + self.pass_rgba8_textures.clear(); + self.pass_a8_textures.clear(); } - fn end_frame(&mut self, pool: &mut Vec) { + fn end_frame(&mut self, pass_index: RenderPassIndex) { // return the cached targets to the pool - self.end_pass(None, None, pool) + self.end_pass(None, None, pass_index) } fn end_pass( &mut self, a8_texture: Option, rgba8_texture: Option, - pool: &mut Vec, + pass_index: RenderPassIndex, ) { // If we have cache textures from previous pass, return them to the pool. - pool.extend(self.cache_rgba8_texture.take()); - pool.extend(self.cache_a8_texture.take()); + // Also assign the pool index of those cache textures to last pass's index because this is + // the result of last pass. + if let Some(texture) = self.cache_rgba8_texture.take() { + self.pass_rgba8_textures.insert( + RenderPassIndex(pass_index.0 - 1), RenderTargetPoolId(self.render_target_pool.len())); + self.render_target_pool.push(texture); + } + if let Some(texture) = self.cache_a8_texture.take() { + self.pass_a8_textures.insert( + RenderPassIndex(pass_index.0 - 1), RenderTargetPoolId(self.render_target_pool.len())); + self.render_target_pool.push(texture); + } // We have another pass to process, make these textures available // as inputs to the next pass. @@ -658,6 +685,18 @@ impl SourceTextureResolver { let texture = &self.cache_texture_map[index.0]; device.bind_texture(sampler, texture); } + SourceTexture::RenderTaskCacheRGBA8(pass_index) => { + let pool_index = self.pass_rgba8_textures + .get(&pass_index) + .expect("BUG: pass_index doesn't map to pool_index"); + device.bind_texture(sampler, &self.render_target_pool[pool_index.0]) + } + SourceTexture::RenderTaskCacheA8(pass_index) => { + let pool_index = self.pass_a8_textures + .get(&pass_index) + .expect("BUG: pass_index doesn't map to pool_index"); + device.bind_texture(sampler, &self.render_target_pool[pool_index.0]) + } } } @@ -681,6 +720,18 @@ impl SourceTextureResolver { panic!("BUG: External textures cannot be resolved, they can only be bound."); } SourceTexture::TextureCache(index) => Some(&self.cache_texture_map[index.0]), + SourceTexture::RenderTaskCacheRGBA8(pass_index) => { + let pool_index = self.pass_rgba8_textures + .get(&pass_index) + .expect("BUG: pass_index doesn't map to pool_index"); + Some(&self.render_target_pool[pool_index.0]) + }, + SourceTexture::RenderTaskCacheA8(pass_index) => { + let pool_index = self.pass_a8_textures + .get(&pass_index) + .expect("BUG: pass_index doesn't map to pool_index"); + Some(&self.render_target_pool[pool_index.0]) + }, } } } @@ -1349,6 +1400,7 @@ pub struct Renderer { brush_mask_corner: LazilyCompiledShader, brush_mask_rounded_rect: LazilyCompiledShader, brush_image_rgba8: BrushShader, + brush_image_rgba8_alpha_mask: BrushShader, brush_image_a8: BrushShader, brush_solid: BrushShader, @@ -1394,8 +1446,6 @@ pub struct Renderer { profiler: Profiler, last_time: u64, - render_target_pool: Vec, - gpu_profile: GpuProfiler, prim_vao: VAO, blur_vao: VAO, @@ -1574,6 +1624,13 @@ impl Renderer { options.precache_shaders) }; + let brush_image_rgba8_alpha_mask = try!{ + BrushShader::new("brush_image", + &mut device, + &["COLOR_TARGET_ALPHA_MASK"], + options.precache_shaders) + }; + let cs_blur_a8 = try!{ LazilyCompiledShader::new(ShaderKind::Cache(VertexArrayKind::Blur), "cs_blur", @@ -1998,6 +2055,7 @@ impl Renderer { brush_mask_corner, brush_mask_rounded_rect, brush_image_rgba8, + brush_image_rgba8_alpha_mask, brush_image_a8, brush_solid, cs_clip_rectangle, @@ -2027,7 +2085,6 @@ impl Renderer { clear_color: options.clear_color, enable_clear_scissor: options.enable_clear_scissor, last_time: 0, - render_target_pool: Vec::new(), gpu_profile, prim_vao, blur_vao, @@ -2778,8 +2835,9 @@ impl Renderer { } BrushBatchKind::Image(target_kind) => { let shader = match target_kind { - RenderTargetKind::Alpha => &mut self.brush_image_a8, - RenderTargetKind::Color => &mut self.brush_image_rgba8, + BrushImageSourceKind::Alpha => &mut self.brush_image_a8, + BrushImageSourceKind::Color => &mut self.brush_image_rgba8, + BrushImageSourceKind::ColorAlphaMask => &mut self.brush_image_rgba8_alpha_mask, }; shader.bind( &mut self.device, @@ -3684,7 +3742,7 @@ impl Renderer { num_layers: list.targets.len() as _, format: list.format, }; - let index = self.render_target_pool + let index = self.texture_resolver.render_target_pool .iter() .position(|texture| { selector == TargetSelector { @@ -3694,14 +3752,14 @@ impl Renderer { } }); match index { - Some(pos) => self.render_target_pool.swap_remove(pos), + Some(pos) => self.texture_resolver.render_target_pool.swap_remove(pos), None => return, } } else { if list.texture.is_some() { return } - match self.render_target_pool.pop() { + match self.texture_resolver.render_target_pool.pop() { Some(texture) => texture, None => self.device.create_texture(TextureTarget::Array), } @@ -3885,7 +3943,7 @@ impl Renderer { self.texture_resolver.end_pass( cur_alpha, cur_color, - &mut self.render_target_pool, + RenderPassIndex(pass_index), ); // After completing the first pass, make the A8 target available as an @@ -3900,7 +3958,7 @@ impl Renderer { } } - self.texture_resolver.end_frame(&mut self.render_target_pool); + self.texture_resolver.end_frame(RenderPassIndex(frame.passes.len())); self.draw_render_target_debug(framebuffer_size); self.draw_texture_cache_debug(framebuffer_size); self.draw_epoch_debug(); @@ -3967,7 +4025,7 @@ impl Renderer { let mut spacing = 16; let mut size = 512; let fb_width = framebuffer_size.width as i32; - let num_layers: i32 = self.render_target_pool + let num_layers: i32 = self.texture_resolver.render_target_pool .iter() .map(|texture| texture.get_render_target_layer_count() as i32) .sum(); @@ -3979,7 +4037,7 @@ impl Renderer { } let mut target_index = 0; - for texture in &self.render_target_pool { + for texture in &self.texture_resolver.render_target_pool { let dimensions = texture.get_dimensions(); let src_rect = DeviceIntRect::new(DeviceIntPoint::zero(), dimensions.to_i32()); @@ -4121,9 +4179,6 @@ impl Renderer { } self.node_data_texture.deinit(&mut self.device); self.render_task_texture.deinit(&mut self.device); - for texture in self.render_target_pool { - self.device.delete_texture(texture); - } self.device.delete_pbo(self.texture_cache_upload_pbo); self.texture_resolver.deinit(&mut self.device); self.device.delete_vao(self.prim_vao); @@ -4137,6 +4192,7 @@ impl Renderer { self.brush_mask_rounded_rect.deinit(&mut self.device); self.brush_mask_corner.deinit(&mut self.device); self.brush_image_rgba8.deinit(&mut self.device); + self.brush_image_rgba8_alpha_mask.deinit(&mut self.device); self.brush_image_a8.deinit(&mut self.device); self.brush_solid.deinit(&mut self.device); self.cs_clip_rectangle.deinit(&mut self.device); diff --git a/webrender/src/scene.rs b/webrender/src/scene.rs index 99bf9bb89e..fc5f665ccb 100644 --- a/webrender/src/scene.rs +++ b/webrender/src/scene.rs @@ -162,7 +162,8 @@ impl FilterOpHelpers for FilterOp { FilterOp::HueRotate(..) | FilterOp::Invert(..) | FilterOp::Saturate(..) | - FilterOp::Sepia(..) => true, + FilterOp::Sepia(..) | + FilterOp::DropShadow(..) => true, FilterOp::Opacity(_, amount) => { amount > OPACITY_EPSILON } @@ -180,6 +181,9 @@ impl FilterOpHelpers for FilterOp { FilterOp::Opacity(_, amount) => amount >= 1.0, FilterOp::Saturate(amount) => amount == 1.0, FilterOp::Sepia(amount) => amount == 0.0, + FilterOp::DropShadow(offset, blur, _) => { + offset.x == 0.0 && offset.y == 0.0 && blur == 0.0 + } } } } diff --git a/webrender/src/tiling.rs b/webrender/src/tiling.rs index 9120164dd3..b780d5e7aa 100644 --- a/webrender/src/tiling.rs +++ b/webrender/src/tiling.rs @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use api::{BorderRadiusKind, ClipId, ColorF, DeviceIntPoint, ImageKey}; -use api::{DeviceIntRect, DeviceIntSize, DeviceUintPoint, DeviceUintRect, DeviceUintSize}; +use api::{DeviceIntRect, DeviceIntSize, device_length, DeviceUintPoint, DeviceUintRect, DeviceUintSize}; use api::{DocumentLayer, ExternalImageType, FilterOp, FontRenderMode}; use api::{ImageFormat, ImageRendering}; use api::{LayerRect, MixBlendMode, PipelineId}; @@ -20,7 +20,7 @@ use gpu_types::{BlurDirection, BlurInstance, BrushInstance, BrushImageKind, Clip use gpu_types::{CompositePrimitiveInstance, PrimitiveInstance, SimplePrimitiveInstance}; use gpu_types::{ClipScrollNodeIndex, ClipScrollNodeData}; use internal_types::{FastHashMap, SourceTexture}; -use internal_types::{BatchTextures}; +use internal_types::{BatchTextures, RenderPassIndex}; use picture::{PictureCompositeMode, PictureKind, PicturePrimitive, RasterizationSpace}; use plane_split::{BspSplitter, Polygon, Splitter}; use prim_store::{PrimitiveIndex, PrimitiveKind, PrimitiveMetadata, PrimitiveStore}; @@ -148,9 +148,6 @@ pub struct ScrollbarPrimitive { #[derive(Debug, Copy, Clone)] pub struct RenderTargetIndex(pub usize); -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -pub struct RenderPassIndex(isize); - #[derive(Debug)] struct DynamicTaskInfo { task_id: RenderTaskId, @@ -627,7 +624,8 @@ fn add_to_batch( match picture.kind { PictureKind::TextShadow { .. } => { let kind = BatchKind::Brush( - BrushBatchKind::Image(picture.target_kind()), + BrushBatchKind::Image( + BrushImageSourceKind::from_render_target_kind(picture.target_kind())), ); let key = BatchKey::new(kind, blend_mode, textures); let batch = batch_list.get_suitable_batch(key, item_bounding_rect); @@ -647,7 +645,8 @@ fn add_to_batch( } PictureKind::BoxShadow { radii_kind, .. } => { let kind = BatchKind::Brush( - BrushBatchKind::Image(picture.target_kind()), + BrushBatchKind::Image( + BrushImageSourceKind::from_render_target_kind(picture.target_kind())), ); let key = BatchKey::new(kind, blend_mode, textures); let batch = batch_list.get_suitable_batch(key, item_bounding_rect); @@ -676,7 +675,7 @@ fn add_to_batch( } PictureKind::Image { composite_mode, - readback_render_task_id, + secondary_render_task_id, is_in_3d_context, reference_frame_id, real_local_rect, @@ -717,7 +716,7 @@ fn add_to_batch( let key = BatchKey::new( BatchKind::HardwareComposite, BlendMode::PremultipliedAlpha, - BatchTextures::no_texture(), + BatchTextures::render_target_cache(), ); let batch = batch_list.get_suitable_batch(key, &item_bounding_rect); let instance = CompositePrimitiveInstance::new( @@ -733,6 +732,61 @@ fn add_to_batch( batch.push(PrimitiveInstance::from(instance)); } + FilterOp::DropShadow(offset, _, _) => { + let kind = BatchKind::Brush( + BrushBatchKind::Image(BrushImageSourceKind::ColorAlphaMask), + ); + let key = BatchKey::new(kind, blend_mode, textures); + + let instance = BrushInstance { + picture_address: task_address, + prim_address: prim_cache_address, + clip_id, + scroll_id, + clip_task_address, + z, + segment_kind: 0, + user_data0: cache_task_address.0 as i32, + user_data1: BrushImageKind::Simple as i32, + }; + + { + let batch = batch_list.get_suitable_batch(key, item_bounding_rect); + batch.push(PrimitiveInstance::from(instance)); + } + + let secondary_id = secondary_render_task_id.expect("no secondary!?"); + let render_task = &render_tasks[secondary_id]; + let secondary_task_address = render_tasks.get_task_address(secondary_id); + let render_pass_index = render_task.pass_index.expect("no render_pass_index!?"); + let secondary_textures = BatchTextures { + colors: [ + SourceTexture::RenderTaskCacheRGBA8(render_pass_index), + SourceTexture::Invalid, + SourceTexture::Invalid, + ], + }; + let key = BatchKey::new( + BatchKind::HardwareComposite, + BlendMode::PremultipliedAlpha, + secondary_textures, + ); + let batch = batch_list.get_suitable_batch(key, &item_bounding_rect); + let device_offset_x = device_length(offset.x, ctx.device_pixel_ratio); + let device_offset_y = device_length(offset.y, ctx.device_pixel_ratio); + let instance = CompositePrimitiveInstance::new( + task_address, + secondary_task_address, + RenderTaskAddress(0), + item_bounding_rect.origin.x - device_offset_x.0, + item_bounding_rect.origin.y - device_offset_y.0, + z, + item_bounding_rect.size.width, + item_bounding_rect.size.height, + ); + + batch.push(PrimitiveInstance::from(instance)); + } _ => { let key = BatchKey::new( BatchKind::Blend, @@ -751,6 +805,7 @@ fn add_to_batch( FilterOp::Sepia(amount) => (6, amount), FilterOp::Brightness(amount) => (7, amount), FilterOp::Opacity(_, amount) => (8, amount), + FilterOp::DropShadow(..) => unreachable!(), }; let amount = (amount * 65535.0).round() as i32; @@ -772,7 +827,7 @@ fn add_to_batch( } } PictureCompositeMode::MixBlend(mode) => { - let backdrop_id = readback_render_task_id.expect("no backdrop!?"); + let backdrop_id = secondary_render_task_id.expect("no backdrop!?"); let key = BatchKey::new( BatchKind::Composite { @@ -805,7 +860,7 @@ fn add_to_batch( let key = BatchKey::new( BatchKind::HardwareComposite, BlendMode::PremultipliedAlpha, - BatchTextures::no_texture(), + BatchTextures::render_target_cache(), ); let batch = batch_list.get_suitable_batch(key, &item_bounding_rect); let instance = CompositePrimitiveInstance::new( @@ -1796,6 +1851,7 @@ impl RenderPass { render_tasks: &mut RenderTaskTree, deferred_resolves: &mut Vec, clip_store: &ClipStore, + pass_index: RenderPassIndex, ) { profile_scope!("RenderPass::build"); @@ -1803,6 +1859,7 @@ impl RenderPass { RenderPassKind::MainFramebuffer(ref mut target) => { for &task_id in &self.tasks { assert_eq!(render_tasks[task_id].target_kind(), RenderTargetKind::Color); + render_tasks[task_id].pass_index = Some(pass_index); target.add_task(task_id, ctx, gpu_cache, render_tasks, clip_store); } target.build(ctx, gpu_cache, render_tasks, deferred_resolves); @@ -1812,6 +1869,7 @@ impl RenderPass { for &task_id in &self.tasks { let target_kind = { let task = &mut render_tasks[task_id]; + task.pass_index = Some(pass_index); let target_kind = task.target_kind(); // Find a target to assign this task to, or create a new @@ -1880,9 +1938,25 @@ pub enum TransformBatchKind { Line, } +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] +pub enum BrushImageSourceKind { + Alpha, + Color, + ColorAlphaMask, +} + +impl BrushImageSourceKind { + pub fn from_render_target_kind(render_target_kind: RenderTargetKind) -> BrushImageSourceKind { + match render_target_kind { + RenderTargetKind::Color => BrushImageSourceKind::Color, + RenderTargetKind::Alpha => BrushImageSourceKind::Alpha, + } + } +} + #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub enum BrushBatchKind { - Image(RenderTargetKind), + Image(BrushImageSourceKind), Solid, } diff --git a/webrender_api/src/display_item.rs b/webrender_api/src/display_item.rs index cb94876a81..bd2e449490 100644 --- a/webrender_api/src/display_item.rs +++ b/webrender_api/src/display_item.rs @@ -458,6 +458,7 @@ pub enum FilterOp { Opacity(PropertyBinding, f32), Saturate(f32), Sepia(f32), + DropShadow(LayoutVector2D, f32, ColorF), } #[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)] diff --git a/wrench/reftests/filters/filter-drop-shadow.png b/wrench/reftests/filters/filter-drop-shadow.png new file mode 100644 index 0000000000000000000000000000000000000000..95c910f124077f6910d593dd0f2b648bdaad6b02 GIT binary patch literal 79986 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 literal 0 HcmV?d00001 diff --git a/wrench/reftests/filters/filter-drop-shadow.yaml b/wrench/reftests/filters/filter-drop-shadow.yaml new file mode 100644 index 0000000000..59f90b42da --- /dev/null +++ b/wrench/reftests/filters/filter-drop-shadow.yaml @@ -0,0 +1,9 @@ +--- +root: + items: + - type: stacking-context + bounds: [100, 100, 400, 400] + filters: drop-shadow([73, 73], 20, [255, 0, 0, 1]) + items: + - image: "firefox.png" + bounds: 0 0 256 256 diff --git a/wrench/reftests/filters/reftest.list b/wrench/reftests/filters/reftest.list index 48e3a3fa3d..e32cf622e6 100644 --- a/wrench/reftests/filters/reftest.list +++ b/wrench/reftests/filters/reftest.list @@ -29,3 +29,4 @@ == filter-hue-rotate-1.yaml filter-hue-rotate-1-ref.yaml == filter-hue-rotate-alpha-1.yaml filter-hue-rotate-alpha-1-ref.yaml == filter-long-chain.yaml filter-long-chain.png +== filter-drop-shadow.yaml filter-drop-shadow.png diff --git a/wrench/reftests/transforms/reftest.list b/wrench/reftests/transforms/reftest.list index a986305e49..91bfce9fa4 100644 --- a/wrench/reftests/transforms/reftest.list +++ b/wrench/reftests/transforms/reftest.list @@ -5,6 +5,6 @@ # but fails when all the tests are run fuzzy(1,2) == rotated-image.yaml rotated-image.png == singular.yaml singular-ref.yaml -fuzzy(1,41) == perspective.yaml perspective.png +fuzzy(1,82) == perspective.yaml perspective.png == prim-suite.yaml prim-suite.png == segments-bug.yaml segments-bug-ref.yaml diff --git a/wrench/src/parse_function.rs b/wrench/src/parse_function.rs index 82267064ce..2b2328b855 100644 --- a/wrench/src/parse_function.rs +++ b/wrench/src/parse_function.rs @@ -64,8 +64,22 @@ pub fn parse_function(s: &str) -> (&str, Vec<&str>, &str) { p.skip_whitespace(); let mut end = p.start; + let mut bracket_count: i32 = 0; while let Some(k) = p.o { - if !acceptable_arg_character(k.1) { + let prev_bracket_count = bracket_count; + if k.1 == '[' { + bracket_count = bracket_count + 1; + } else if k.1 == ']' { + bracket_count = bracket_count - 1; + } + + if bracket_count < 0 { + println!("Unexpected closing bracket"); + break; + } + + let not_in_bracket = bracket_count == 0 && prev_bracket_count == 0; + if !acceptable_arg_character(k.1) && not_in_bracket { break; } end = k.0 + k.1.len_utf8(); @@ -100,4 +114,8 @@ fn test() { assert_eq!(parse_function(" rotate (40)").0, "rotate"); assert_eq!(parse_function(" rotate ( 40 )").1[0], "40"); assert_eq!(parse_function("rotate(-40.0)").1[0], "-40.0"); + assert_eq!(parse_function("drop-shadow(0, [1, 2, 3, 4], 5)").1[0], "0"); + assert_eq!(parse_function("drop-shadow(0, [1, 2, 3, 4], 5)").1[1], "[1, 2, 3, 4]"); + assert_eq!(parse_function("drop-shadow(0, [1, 2, 3, 4], 5)").1[2], "5"); + assert_eq!(parse_function("drop-shadow(0, [1, 2, [3, 4]], 5)").1[1], "[1, 2, [3, 4]]"); } diff --git a/wrench/src/yaml_frame_writer.rs b/wrench/src/yaml_frame_writer.rs index 3a85b90989..95ae535eeb 100644 --- a/wrench/src/yaml_frame_writer.rs +++ b/wrench/src/yaml_frame_writer.rs @@ -210,6 +210,12 @@ fn write_sc(parent: &mut Table, sc: &StackingContext, properties: &SceneProperti } FilterOp::Saturate(x) => { filters.push(Yaml::String(format!("saturate({})", x))) } FilterOp::Sepia(x) => { filters.push(Yaml::String(format!("sepia({})", x))) } + FilterOp::DropShadow(offset, blur, color) => { + filters.push(Yaml::String(format!("drop-shadow([{},{}],{},[{}])", + offset.x, offset.y, + blur, + color_to_string(color)))) + } } } diff --git a/wrench/src/yaml_helper.rs b/wrench/src/yaml_helper.rs index de9e8b16fa..a5841f665e 100644 --- a/wrench/src/yaml_helper.rs +++ b/wrench/src/yaml_helper.rs @@ -8,7 +8,7 @@ use parse_function::parse_function; use std::f32; use std::str::FromStr; use webrender::api::*; -use yaml_rust::Yaml; +use yaml_rust::{Yaml, YamlLoader}; pub trait YamlHelper { fn as_f32(&self) -> Option; @@ -564,6 +564,14 @@ impl YamlHelper for Yaml { ("sepia", ref args, _) if args.len() == 1 => { Some(FilterOp::Sepia(args[0].parse().unwrap())) } + ("drop-shadow", ref args, _) if args.len() == 3 => { + let str = format!("---\noffset: {}\nblur-radius: {}\ncolor: {}\n", args[0], args[1], args[2]); + let mut yaml_doc = YamlLoader::load_from_str(&str).expect("Failed to parse drop-shadow"); + let yaml = yaml_doc.pop().unwrap(); + Some(FilterOp::DropShadow(yaml["offset"].as_vector().unwrap(), + yaml["blur-radius"].as_f32().unwrap(), + yaml["color"].as_colorf().unwrap())) + } (_, _, _) => None, } } else {