diff --git a/webrender/src/batch.rs b/webrender/src/batch.rs index 048be35515..596283120f 100644 --- a/webrender/src/batch.rs +++ b/webrender/src/batch.rs @@ -18,7 +18,7 @@ use gpu_types::{CompositePrimitiveInstance, PrimitiveInstance, SimplePrimitiveIn use internal_types::{FastHashMap, SavedTargetIndex, SourceTexture}; use picture::{ContentOrigin, PictureCompositeMode, PictureKind, PicturePrimitive, PictureSurface}; use plane_split::{BspSplitter, Polygon, Splitter}; -use prim_store::{ImageSource, PrimitiveIndex, PrimitiveKind, PrimitiveMetadata, PrimitiveStore}; +use prim_store::{CachedGradient, ImageSource, PrimitiveIndex, PrimitiveKind, PrimitiveMetadata, PrimitiveStore}; use prim_store::{BrushPrimitive, BrushKind, DeferredResolve, EdgeAaSegmentMask, PrimitiveRun}; use render_task::{RenderTaskAddress, RenderTaskId, RenderTaskKind, RenderTaskTree}; use renderer::{BlendMode, ImageBufferKind}; @@ -681,6 +681,7 @@ impl AlphaBatchBuilder { ctx.resource_cache, gpu_cache, deferred_resolves, + &ctx.cached_gradients, ) { self.add_brush_to_batch( brush, @@ -1312,6 +1313,7 @@ impl BrushPrimitive { resource_cache: &ResourceCache, gpu_cache: &mut GpuCache, deferred_resolves: &mut Vec, + cached_gradients: &[CachedGradient], ) -> Option<(BrushBatchKind, BatchTextures, [i32; 3])> { match self.kind { BrushKind::Line { .. } => { @@ -1358,7 +1360,8 @@ impl BrushPrimitive { [0; 3], )) } - BrushKind::RadialGradient { ref stops_handle, .. } => { + BrushKind::RadialGradient { gradient_index, .. } => { + let stops_handle = &cached_gradients[gradient_index.0].handle; Some(( BrushBatchKind::RadialGradient, BatchTextures::no_texture(), @@ -1369,7 +1372,8 @@ impl BrushPrimitive { ], )) } - BrushKind::LinearGradient { ref stops_handle, .. } => { + BrushKind::LinearGradient { gradient_index, .. } => { + let stops_handle = &cached_gradients[gradient_index.0].handle; Some(( BrushBatchKind::LinearGradient, BatchTextures::no_texture(), diff --git a/webrender/src/frame_builder.rs b/webrender/src/frame_builder.rs index f3023300bd..8aecebb038 100644 --- a/webrender/src/frame_builder.rs +++ b/webrender/src/frame_builder.rs @@ -18,12 +18,12 @@ use clip_scroll_tree::{ClipScrollTree, ClipChainIndex}; use euclid::{SideOffsets2D, vec2}; use frame::{FrameId, ClipIdToIndexMapper}; use glyph_rasterizer::FontInstance; -use gpu_cache::{GpuCache, GpuCacheHandle}; +use gpu_cache::GpuCache; use gpu_types::{ClipChainRectIndex, ClipScrollNodeData, PictureType}; use hit_test::{HitTester, HitTestingItem, HitTestingRun}; use internal_types::{FastHashMap, FastHashSet}; use picture::{ContentOrigin, PictureCompositeMode, PictureKind, PicturePrimitive, PictureSurface}; -use prim_store::{BrushKind, BrushPrimitive, BrushSegmentDescriptor}; +use prim_store::{BrushKind, BrushPrimitive, BrushSegmentDescriptor, CachedGradient, CachedGradientIndex}; use prim_store::{ImageCacheKey, ImagePrimitiveCpu, ImageSource, PrimitiveContainer}; use prim_store::{PrimitiveIndex, PrimitiveKind, PrimitiveRun, PrimitiveStore}; use prim_store::{ScrollNodeAndClipChain, TextRunPrimitiveCpu}; @@ -85,6 +85,7 @@ pub struct FrameBuilder { pub clip_store: ClipStore, hit_testing_runs: Vec, pub config: FrameBuilderConfig, + pub cached_gradients: Vec, // A stack of the current shadow primitives. // The sub-Vec stores a buffer of fast-path primitives to be appended on pop. @@ -123,6 +124,7 @@ pub struct FrameState<'a> { pub local_clip_rects: &'a mut Vec, pub resource_cache: &'a mut ResourceCache, pub gpu_cache: &'a mut GpuCache, + pub cached_gradients: &'a mut [CachedGradient], } pub struct PictureContext<'a> { @@ -172,6 +174,7 @@ impl FrameBuilder { FrameBuilder { hit_testing_runs: Vec::new(), shadow_prim_stack: Vec::new(), + cached_gradients: Vec::new(), pending_shadow_contents: Vec::new(), scrollbar_prims: Vec::new(), reference_frame_stack: Vec::new(), @@ -200,6 +203,7 @@ impl FrameBuilder { FrameBuilder { hit_testing_runs: recycle_vec(self.hit_testing_runs), shadow_prim_stack: recycle_vec(self.shadow_prim_stack), + cached_gradients: recycle_vec(self.cached_gradients), pending_shadow_contents: recycle_vec(self.pending_shadow_contents), scrollbar_prims: recycle_vec(self.scrollbar_prims), reference_frame_stack: recycle_vec(self.reference_frame_stack), @@ -1232,7 +1236,7 @@ impl FrameBuilder { } } - pub fn add_gradient_impl( + fn add_gradient_impl( &mut self, clip_and_scroll: ScrollNodeAndClipChain, info: &LayerPrimitiveInfo, @@ -1241,6 +1245,7 @@ impl FrameBuilder { stops: ItemRange, stops_count: usize, extend_mode: ExtendMode, + gradient_index: CachedGradientIndex, ) { // Try to ensure that if the gradient is specified in reverse, then so long as the stops // are also supplied in reverse that the rendered result will be equivalent. To do this, @@ -1262,13 +1267,13 @@ impl FrameBuilder { let prim = BrushPrimitive::new( BrushKind::LinearGradient { - stops_handle: GpuCacheHandle::new(), stops_range: stops, stops_count, extend_mode, reverse_stops, start_point: sp, end_point: ep, + gradient_index, }, None, ); @@ -1290,6 +1295,9 @@ impl FrameBuilder { tile_size: LayerSize, tile_spacing: LayerSize, ) { + let gradient_index = CachedGradientIndex(self.cached_gradients.len()); + self.cached_gradients.push(CachedGradient::new()); + let prim_infos = info.decompose( tile_size, tile_spacing, @@ -1305,6 +1313,7 @@ impl FrameBuilder { stops, stops_count, extend_mode, + gradient_index, ); } else { for prim_info in prim_infos { @@ -1316,6 +1325,7 @@ impl FrameBuilder { stops, stops_count, extend_mode, + gradient_index, ); } } @@ -1332,17 +1342,18 @@ impl FrameBuilder { ratio_xy: f32, stops: ItemRange, extend_mode: ExtendMode, + gradient_index: CachedGradientIndex, ) { let prim = BrushPrimitive::new( BrushKind::RadialGradient { stops_range: stops, extend_mode, - stops_handle: GpuCacheHandle::new(), start_center, end_center, start_radius, end_radius, ratio_xy, + gradient_index, }, None, ); @@ -1369,6 +1380,9 @@ impl FrameBuilder { tile_size: LayerSize, tile_spacing: LayerSize, ) { + let gradient_index = CachedGradientIndex(self.cached_gradients.len()); + self.cached_gradients.push(CachedGradient::new()); + let prim_infos = info.decompose( tile_size, tile_spacing, @@ -1386,6 +1400,7 @@ impl FrameBuilder { ratio_xy, stops, extend_mode, + gradient_index, ); } else { for prim_info in prim_infos { @@ -1399,6 +1414,7 @@ impl FrameBuilder { ratio_xy, stops, extend_mode, + gradient_index, ); } } @@ -1718,6 +1734,7 @@ impl FrameBuilder { local_clip_rects, resource_cache, gpu_cache, + cached_gradients: &mut self.cached_gradients, }; let pic_context = PictureContext { @@ -1886,6 +1903,7 @@ impl FrameBuilder { clip_scroll_tree, use_dual_source_blending, node_data: &node_data, + cached_gradients: &self.cached_gradients, }; pass.build( diff --git a/webrender/src/prim_store.rs b/webrender/src/prim_store.rs index e6ab6538a1..29a5695e3c 100644 --- a/webrender/src/prim_store.rs +++ b/webrender/src/prim_store.rs @@ -71,6 +71,21 @@ impl PrimitiveOpacity { } } +#[derive(Debug, Copy, Clone)] +pub struct CachedGradientIndex(pub usize); + +pub struct CachedGradient { + pub handle: GpuCacheHandle, +} + +impl CachedGradient { + pub fn new() -> CachedGradient { + CachedGradient { + handle: GpuCacheHandle::new(), + } + } +} + // Represents the local space rect of a list of // primitive runs. For most primitive runs, the // primitive runs are attached to the parent they @@ -205,9 +220,9 @@ pub enum BrushKind { image_rendering: ImageRendering, }, RadialGradient { + gradient_index: CachedGradientIndex, stops_range: ItemRange, extend_mode: ExtendMode, - stops_handle: GpuCacheHandle, start_center: LayerPoint, end_center: LayerPoint, start_radius: f32, @@ -215,9 +230,9 @@ pub enum BrushKind { ratio_xy: f32, }, LinearGradient { + gradient_index: CachedGradientIndex, stops_range: ItemRange, stops_count: usize, - stops_handle: GpuCacheHandle, extend_mode: ExtendMode, reverse_stops: bool, start_point: LayerPoint, @@ -1255,7 +1270,8 @@ impl PrimitiveStore { ); } } - BrushKind::RadialGradient { ref mut stops_handle, stops_range, .. } => { + BrushKind::RadialGradient { gradient_index, stops_range, .. } => { + let stops_handle = &mut frame_state.cached_gradients[gradient_index.0].handle; if let Some(mut request) = frame_state.gpu_cache.request(stops_handle) { let gradient_builder = GradientGpuBlockBuilder::new( stops_range, @@ -1267,7 +1283,8 @@ impl PrimitiveStore { ); } } - BrushKind::LinearGradient { ref mut stops_handle, stops_range, reverse_stops, .. } => { + BrushKind::LinearGradient { gradient_index, stops_range, reverse_stops, .. } => { + let stops_handle = &mut frame_state.cached_gradients[gradient_index.0].handle; if let Some(mut request) = frame_state.gpu_cache.request(stops_handle) { let gradient_builder = GradientGpuBlockBuilder::new( stops_range, diff --git a/webrender/src/tiling.rs b/webrender/src/tiling.rs index ba18a150f4..90e1d34271 100644 --- a/webrender/src/tiling.rs +++ b/webrender/src/tiling.rs @@ -16,7 +16,7 @@ use gpu_types::{ClipScrollNodeData, ClipScrollNodeIndex}; use gpu_types::{PrimitiveInstance}; use internal_types::{FastHashMap, SavedTargetIndex, SourceTexture}; use picture::{PictureKind}; -use prim_store::{PrimitiveIndex, PrimitiveKind, PrimitiveStore}; +use prim_store::{CachedGradient, PrimitiveIndex, PrimitiveKind, PrimitiveStore}; use prim_store::{BrushMaskKind, BrushKind, DeferredResolve, EdgeAaSegmentMask}; use profiler::FrameProfileCounters; use render_task::{BlitSource, RenderTaskAddress, RenderTaskId, RenderTaskKind}; @@ -46,6 +46,7 @@ pub struct RenderTargetContext<'a> { pub clip_scroll_tree: &'a ClipScrollTree, pub use_dual_source_blending: bool, pub node_data: &'a [ClipScrollNodeData], + pub cached_gradients: &'a [CachedGradient], } #[cfg_attr(feature = "capture", derive(Serialize))]