Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decompose gradients during scene building. #2752

Merged
merged 2 commits into from May 11, 2018
Merged
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Next

Decompose gradients during scene building.

  • Loading branch information
nical committed May 11, 2018
commit 7689c54eacbcfec02a512a0769bff10828c03c8d
@@ -21,7 +21,8 @@ use picture::{PictureCompositeMode, PicturePrimitive, PictureSurface};
use plane_split::{BspSplitter, Polygon, Splitter};
use prim_store::{BrushKind, BrushPrimitive, BrushSegmentTaskId, CachedGradient, DeferredResolve};
use prim_store::{EdgeAaSegmentMask, ImageSource, PictureIndex, PrimitiveIndex, PrimitiveKind};
use prim_store::{PrimitiveMetadata, PrimitiveRun, PrimitiveStore};
use prim_store::{PrimitiveMetadata, PrimitiveRun, PrimitiveStore, VisibleGradientTile};
use prim_store::CachedGradientIndex;
use render_task::{RenderTaskAddress, RenderTaskId, RenderTaskKind, RenderTaskTree};
use renderer::{BlendMode, ImageBufferKind};
use renderer::{BLOCKS_PER_UV_RECT, ShaderColorMode};
@@ -615,6 +616,8 @@ impl AlphaBatchBuilder {
let brush = &ctx.prim_store.cpu_brushes[prim_metadata.cpu_prim_index.0];
match brush.kind {
BrushKind::Image { ref visible_tiles, .. } => !visible_tiles.is_empty(),
BrushKind::LinearGradient { ref visible_tiles, .. } => !visible_tiles.is_empty(),
BrushKind::RadialGradient { ref visible_tiles, .. } => !visible_tiles.is_empty(),
_ => false,
}
}
@@ -1018,6 +1021,40 @@ impl AlphaBatchBuilder {
}
}
}
BrushKind::LinearGradient { gradient_index, ref visible_tiles, .. } if !visible_tiles.is_empty() => {
add_gradient_tiles(
visible_tiles,
gradient_index,
BrushBatchKind::LinearGradient,
specified_blend_mode,
&task_relative_bounding_rect,
clip_chain_rect_index,
scroll_id,
task_address,
clip_task_address,
z,
ctx,
gpu_cache,
&mut self.batch_list,
);
}
BrushKind::RadialGradient { gradient_index, ref visible_tiles, .. } if !visible_tiles.is_empty() => {
add_gradient_tiles(
visible_tiles,
gradient_index,
BrushBatchKind::RadialGradient,
specified_blend_mode,
&task_relative_bounding_rect,
clip_chain_rect_index,
scroll_id,
task_address,
clip_task_address,
z,
ctx,
gpu_cache,
&mut self.batch_list,
);
}
_ => {
if let Some((batch_kind, textures, user_data)) = brush.get_batch_params(
ctx.resource_cache,
@@ -1348,6 +1385,57 @@ impl AlphaBatchBuilder {
}
}

fn add_gradient_tiles(
visible_tiles: &[VisibleGradientTile],
gradient_index: CachedGradientIndex,
kind: BrushBatchKind,
blend_mode: BlendMode,
task_relative_bounding_rect: &DeviceIntRect,
clip_chain_rect_index: ClipChainRectIndex,
scroll_id: ClipScrollNodeIndex,
task_address: RenderTaskAddress,
clip_task_address: RenderTaskAddress,
z: ZBufferId,
ctx: &RenderTargetContext,
gpu_cache: &GpuCache,
batch_list: &mut BatchList,
) {
batch_list.add_bounding_rect(task_relative_bounding_rect);
let batch = batch_list.get_suitable_batch(
BatchKey {
blend_mode: blend_mode,
kind: BatchKind::Brush(kind),
textures: BatchTextures::no_texture(),
},
task_relative_bounding_rect
);

let stops_handle = &ctx.cached_gradients[gradient_index.0].handle;
let user_data = [stops_handle.as_int(gpu_cache), 0, 0];

let base_instance = BrushInstance {
picture_address: task_address,
prim_address: GpuCacheAddress::invalid(),
clip_chain_rect_index,
scroll_id,
clip_task_address,
z,
segment_index: 0,
edge_flags: EdgeAaSegmentMask::all(),
brush_flags: BrushFlags::PERSPECTIVE_INTERPOLATION,
user_data,
};

for tile in visible_tiles {
batch.push(PrimitiveInstance::from(
BrushInstance {
prim_address: gpu_cache.get_address(&tile.handle),
..base_instance
}
));
}
}

fn get_image_tile_params(
resource_cache: &ResourceCache,
gpu_cache: &mut GpuCache,
@@ -1800,7 +1800,7 @@ impl<'a> DisplayListFlattener<'a> {
}
}

fn add_gradient_impl(
pub fn add_gradient(
&mut self,
clip_and_scroll: ScrollNodeAndClipChain,
info: &LayoutPrimitiveInfo,
@@ -1809,9 +1809,19 @@ impl<'a> DisplayListFlattener<'a> {
stops: ItemRange<GradientStop>,
stops_count: usize,
extend_mode: ExtendMode,
gradient_index: CachedGradientIndex,
stretch_size: LayoutSize,
mut tile_spacing: LayoutSize,
) {
let gradient_index = CachedGradientIndex(self.cached_gradients.len());
self.cached_gradients.push(CachedGradient::new());

let mut prim_rect = info.rect;
simplify_repeated_primitive(&stretch_size, &mut tile_spacing, &mut prim_rect);
let info = LayoutPrimitiveInfo {
rect: prim_rect,
.. *info
};

// 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,
// a reference orientation for the gradient line must be chosen, somewhat arbitrarily, so
@@ -1840,23 +1850,26 @@ impl<'a> DisplayListFlattener<'a> {
end_point: ep,
gradient_index,
stretch_size,
tile_spacing,
visible_tiles: Vec::new(),
},
None,
);

let prim = PrimitiveContainer::Brush(prim);

self.add_primitive(clip_and_scroll, info, Vec::new(), prim);
self.add_primitive(clip_and_scroll, &info, Vec::new(), prim);
}

pub fn add_gradient(
pub fn add_radial_gradient(
&mut self,
clip_and_scroll: ScrollNodeAndClipChain,
info: &LayoutPrimitiveInfo,
start_point: LayoutPoint,
end_point: LayoutPoint,
center: LayoutPoint,
start_radius: f32,
end_radius: f32,
ratio_xy: f32,
stops: ItemRange<GradientStop>,
stops_count: usize,
extend_mode: ExtendMode,
stretch_size: LayoutSize,
mut tile_spacing: LayoutSize,
@@ -1871,58 +1884,6 @@ impl<'a> DisplayListFlattener<'a> {
.. *info
};

if tile_spacing != LayoutSize::zero() {
let prim_infos = info.decompose(
stretch_size,
tile_spacing,
64 * 64,
);

if !prim_infos.is_empty() {
for prim_info in prim_infos {
self.add_gradient_impl(
clip_and_scroll,
&prim_info,
start_point,
end_point,
stops,
stops_count,
extend_mode,
gradient_index,
prim_info.rect.size,
);
}

return;
}
}

self.add_gradient_impl(
clip_and_scroll,
&info,
start_point,
end_point,
stops,
stops_count,
extend_mode,
gradient_index,
stretch_size,
);
}

fn add_radial_gradient_impl(
&mut self,
clip_and_scroll: ScrollNodeAndClipChain,
info: &LayoutPrimitiveInfo,
center: LayoutPoint,
start_radius: f32,
end_radius: f32,
ratio_xy: f32,
stops: ItemRange<GradientStop>,
extend_mode: ExtendMode,
gradient_index: CachedGradientIndex,
stretch_size: LayoutSize,
) {
let prim = BrushPrimitive::new(
BrushKind::RadialGradient {
stops_range: stops,
@@ -1933,82 +1894,20 @@ impl<'a> DisplayListFlattener<'a> {
ratio_xy,
gradient_index,
stretch_size,
tile_spacing,
visible_tiles: Vec::new(),
},
None,
);

self.add_primitive(
clip_and_scroll,
info,
&info,
Vec::new(),
PrimitiveContainer::Brush(prim),
);
}

pub fn add_radial_gradient(
&mut self,
clip_and_scroll: ScrollNodeAndClipChain,
info: &LayoutPrimitiveInfo,
center: LayoutPoint,
start_radius: f32,
end_radius: f32,
ratio_xy: f32,
stops: ItemRange<GradientStop>,
extend_mode: ExtendMode,
stretch_size: LayoutSize,
mut tile_spacing: LayoutSize,
) {
let gradient_index = CachedGradientIndex(self.cached_gradients.len());
self.cached_gradients.push(CachedGradient::new());

let mut prim_rect = info.rect;
simplify_repeated_primitive(&stretch_size, &mut tile_spacing, &mut prim_rect);
let info = LayoutPrimitiveInfo {
rect: prim_rect,
.. *info
};

if tile_spacing != LayoutSize::zero() {
let prim_infos = info.decompose(
stretch_size,
tile_spacing,
64 * 64,
);

if !prim_infos.is_empty() {
for prim_info in prim_infos {
self.add_radial_gradient_impl(
clip_and_scroll,
&prim_info,
center,
start_radius,
end_radius,
ratio_xy,
stops,
extend_mode,
gradient_index,
stretch_size,
);
}

return;
}
}

self.add_radial_gradient_impl(
clip_and_scroll,
&info,
center,
start_radius,
end_radius,
ratio_xy,
stops,
extend_mode,
gradient_index,
stretch_size,
);
}

pub fn add_text(
&mut self,
clip_and_scroll: ScrollNodeAndClipChain,
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.