--- a/gfx/webrender/src/batch.rs
+++ b/gfx/webrender/src/batch.rs
@@ -4,24 +4,24 @@
use api::{AlphaType, ClipMode, DeviceIntRect, DeviceIntSize, LineStyle};
use api::{DeviceUintRect, DeviceUintPoint, ExternalImageType, FilterOp, ImageRendering};
use api::{YuvColorSpace, YuvFormat, WorldRect, ColorDepth};
use clip::{ClipDataStore, ClipNodeFlags, ClipNodeRange, ClipItem, ClipStore};
use clip_scroll_tree::{ClipScrollTree, ROOT_SPATIAL_NODE_INDEX, SpatialNodeIndex};
use glyph_rasterizer::GlyphFormat;
use gpu_cache::{GpuCache, GpuCacheHandle, GpuCacheAddress};
-use gpu_types::{BrushFlags, BrushInstance, PrimitiveHeaders};
+use gpu_types::{BrushFlags, BrushInstance, PrimitiveHeaders, ZBufferId, ZBufferIdGenerator};
use gpu_types::{ClipMaskInstance, SplitCompositeInstance};
use gpu_types::{PrimitiveInstanceData, RasterizationSpace, GlyphInstance};
use gpu_types::{PrimitiveHeader, PrimitiveHeaderIndex, TransformPaletteId, TransformPalette};
use internal_types::{FastHashMap, SavedTargetIndex, TextureSource};
use picture::{Picture3DContext, PictureCompositeMode, PicturePrimitive, PictureSurface};
use prim_store::{BrushKind, BrushPrimitive, BrushSegmentTaskId, DeferredResolve};
-use prim_store::{EdgeAaSegmentMask, ImageSource, PrimitiveIndex};
+use prim_store::{EdgeAaSegmentMask, ImageSource};
use prim_store::{VisibleGradientTile, PrimitiveInstance};
use prim_store::{BrushSegment, BorderSource, Primitive, PrimitiveDetails};
use render_task::{RenderTaskAddress, RenderTaskId, RenderTaskTree};
use renderer::{BlendMode, ImageBufferKind, ShaderColorMode};
use renderer::BLOCKS_PER_UV_RECT;
use resource_cache::{CacheItem, GlyphFetchResult, ImageRequest, ResourceCache, ImageProperties};
use scene::FilterOpHelpers;
use smallvec::SmallVec;
@@ -122,36 +122,36 @@ impl BatchKey {
fn textures_compatible(t1: TextureSource, t2: TextureSource) -> bool {
t1 == TextureSource::Invalid || t2 == TextureSource::Invalid || t1 == t2
}
pub struct AlphaBatchList {
pub batches: Vec<PrimitiveBatch>,
pub item_rects: Vec<Vec<WorldRect>>,
current_batch_index: usize,
- current_prim_index: PrimitiveIndex,
+ current_z_id: ZBufferId,
}
impl AlphaBatchList {
fn new() -> Self {
AlphaBatchList {
batches: Vec::new(),
item_rects: Vec::new(),
- current_prim_index: PrimitiveIndex(usize::MAX),
+ current_z_id: ZBufferId::invalid(),
current_batch_index: usize::MAX,
}
}
pub fn set_params_and_get_batch(
&mut self,
key: BatchKey,
bounding_rect: &WorldRect,
- prim_index: PrimitiveIndex,
+ z_id: ZBufferId,
) -> &mut Vec<PrimitiveInstanceData> {
- if prim_index != self.current_prim_index ||
+ if z_id != self.current_z_id ||
self.current_batch_index == usize::MAX ||
!self.batches[self.current_batch_index].key.is_compatible_with(&key) {
let mut selected_batch_index = None;
match key.blend_mode {
BlendMode::SubpixelWithBgColor => {
'outer_multipass: for (batch_index, batch) in self.batches.iter().enumerate().rev().take(10) {
// Some subpixel batches are drawn in two passes. Because of this, we need
@@ -194,17 +194,17 @@ impl AlphaBatchList {
let new_batch = PrimitiveBatch::new(key);
selected_batch_index = Some(self.batches.len());
self.batches.push(new_batch);
self.item_rects.push(Vec::new());
}
self.current_batch_index = selected_batch_index.unwrap();
self.item_rects[self.current_batch_index].push(*bounding_rect);
- self.current_prim_index = prim_index;
+ self.current_z_id = z_id;
}
&mut self.batches[self.current_batch_index].instances
}
}
pub struct OpaqueBatchList {
pub pixel_area_threshold_for_new_batch: f32,
@@ -292,57 +292,57 @@ impl BatchList {
opaque_batch_list: OpaqueBatchList::new(batch_area_threshold),
}
}
pub fn push_single_instance(
&mut self,
key: BatchKey,
bounding_rect: &WorldRect,
- prim_index: PrimitiveIndex,
+ z_id: ZBufferId,
instance: PrimitiveInstanceData,
) {
match key.blend_mode {
BlendMode::None => {
self.opaque_batch_list
.set_params_and_get_batch(key, bounding_rect)
.push(instance);
}
BlendMode::Alpha |
BlendMode::PremultipliedAlpha |
BlendMode::PremultipliedDestOut |
BlendMode::SubpixelConstantTextColor(..) |
BlendMode::SubpixelWithBgColor |
BlendMode::SubpixelDualSource => {
self.alpha_batch_list
- .set_params_and_get_batch(key, bounding_rect, prim_index)
+ .set_params_and_get_batch(key, bounding_rect, z_id)
.push(instance);
}
}
}
pub fn set_params_and_get_batch(
&mut self,
key: BatchKey,
bounding_rect: &WorldRect,
- prim_index: PrimitiveIndex,
+ z_id: ZBufferId,
) -> &mut Vec<PrimitiveInstanceData> {
match key.blend_mode {
BlendMode::None => {
self.opaque_batch_list
.set_params_and_get_batch(key, bounding_rect)
}
BlendMode::Alpha |
BlendMode::PremultipliedAlpha |
BlendMode::PremultipliedDestOut |
BlendMode::SubpixelConstantTextColor(..) |
BlendMode::SubpixelWithBgColor |
BlendMode::SubpixelDualSource => {
self.alpha_batch_list
- .set_params_and_get_batch(key, bounding_rect, prim_index)
+ .set_params_and_get_batch(key, bounding_rect, z_id)
}
}
}
fn finalize(&mut self) {
self.opaque_batch_list.finalize()
}
}
@@ -470,32 +470,34 @@ impl AlphaBatchBuilder {
task_id: RenderTaskId,
ctx: &RenderTargetContext,
gpu_cache: &mut GpuCache,
render_tasks: &RenderTaskTree,
deferred_resolves: &mut Vec<DeferredResolve>,
prim_headers: &mut PrimitiveHeaders,
transforms: &mut TransformPalette,
root_spatial_node_index: SpatialNodeIndex,
+ z_generator: &mut ZBufferIdGenerator,
) {
let task_address = render_tasks.get_task_address(task_id);
// Add each run in this picture to the batch.
for prim_instance in &pic.prim_instances {
self.add_prim_to_batch(
prim_instance,
ctx,
gpu_cache,
render_tasks,
task_id,
task_address,
deferred_resolves,
prim_headers,
transforms,
root_spatial_node_index,
+ z_generator,
);
}
}
// Adds a primitive to a batch.
// It can recursively call itself in some situations, for
// example if it encounters a picture where the items
// in that picture are being drawn into the same target.
@@ -506,16 +508,17 @@ impl AlphaBatchBuilder {
gpu_cache: &mut GpuCache,
render_tasks: &RenderTaskTree,
task_id: RenderTaskId,
task_address: RenderTaskAddress,
deferred_resolves: &mut Vec<DeferredResolve>,
prim_headers: &mut PrimitiveHeaders,
transforms: &mut TransformPalette,
root_spatial_node_index: SpatialNodeIndex,
+ z_generator: &mut ZBufferIdGenerator,
) {
let prim = &ctx.prim_store.primitives[prim_instance.prim_index.0];
if prim_instance.clipped_world_rect.is_none() {
return;
}
#[cfg(debug_assertions)] //TODO: why is this needed?
@@ -530,16 +533,17 @@ impl AlphaBatchBuilder {
// TODO(gw): Calculating this for every primitive is a bit
// wasteful. We should probably cache this in
// the scroll node...
let transform_kind = transform_id.transform_kind();
let bounding_rect = prim_instance.clipped_world_rect
.as_ref()
.expect("bug");
+ let z_id = z_generator.next();
// If the primitive is internally decomposed into multiple sub-primitives we may not
// use some of the per-primitive data and get it from each sub-primitive instead.
let is_multiple_primitives = match prim.details {
PrimitiveDetails::Brush(ref brush) => {
match brush.kind {
BrushKind::Image { ref visible_tiles, .. } => !visible_tiles.is_empty(),
BrushKind::LinearGradient { ref visible_tiles, .. } => !visible_tiles.is_empty(),
@@ -588,17 +592,16 @@ impl AlphaBatchBuilder {
match prim.details {
PrimitiveDetails::Brush(ref brush) => {
match brush.kind {
BrushKind::Picture { pic_index } => {
let picture = &ctx.prim_store.pictures[pic_index.0];
match picture.context_3d {
// Convert all children of the 3D hierarchy root into batches.
Picture3DContext::In { root_data: Some(ref list), .. } => {
- let z = prim_headers.z_generator.next();
for child in list {
let prim_instance = &picture.prim_instances[child.anchor];
let pic_primitive = &ctx.prim_store.primitives[prim_instance.prim_index.0];
let clip_task_address = prim_instance
.clip_task_id
.map_or(OPAQUE_TASK_ADDRESS, |id| render_tasks.get_task_address(id));
@@ -632,38 +635,38 @@ impl AlphaBatchBuilder {
.as_ref()
.expect("BUG: no surface")
.resolve(
render_tasks,
ctx.resource_cache,
gpu_cache,
);
- let prim_header_index = prim_headers.push(&prim_header, [
+ let prim_header_index = prim_headers.push(&prim_header, z_id, [
uv_rect_address.as_int(),
0,
0,
]);
let key = BatchKey::new(
BatchKind::SplitComposite,
BlendMode::PremultipliedAlpha,
BatchTextures::no_texture(),
);
let instance = SplitCompositeInstance::new(
prim_header_index,
child.gpu_address,
- z,
+ z_id,
);
self.batch_list.push_single_instance(
key,
&prim_instance.clipped_world_rect.as_ref().expect("bug"),
- prim_instance.prim_index,
+ z_id,
PrimitiveInstanceData::from(instance),
);
}
}
// Ignore the 3D pictures that are not in the root of preserve-3D
// hierarchy, since we process them with the root.
Picture3DContext::In { root_data: None, .. } => return,
// Proceed for non-3D pictures.
@@ -689,17 +692,17 @@ impl AlphaBatchBuilder {
ctx.resource_cache,
gpu_cache,
);
let key = BatchKey::new(
kind,
non_segmented_blend_mode,
textures,
);
- let prim_header_index = prim_headers.push(&prim_header, [
+ let prim_header_index = prim_headers.push(&prim_header, z_id, [
ShaderColorMode::Image as i32,
RasterizationSpace::Screen as i32,
0,
]);
let instance = BrushInstance {
prim_header_index,
segment_index: 0,
@@ -707,17 +710,17 @@ impl AlphaBatchBuilder {
brush_flags: BrushFlags::empty(),
clip_task_address,
user_data: uv_rect_address.as_int(),
};
self.batch_list.push_single_instance(
key,
bounding_rect,
- prim_instance.prim_index,
+ z_id,
PrimitiveInstanceData::from(instance),
);
}
FilterOp::DropShadow(offset, ..) => {
// Draw an instance of the shadow first, following by the content.
// Both the shadow and the content get drawn as a brush image.
let kind = BatchKind::Brush(
@@ -751,33 +754,36 @@ impl AlphaBatchBuilder {
.as_int();
let content_uv_rect_address = render_tasks[secondary_id]
.get_texture_address(gpu_cache)
.as_int();
// Get the GPU cache address of the extra data handle.
let shadow_prim_address = gpu_cache.get_address(&picture.extra_gpu_data_handle);
- let content_prim_header_index = prim_headers.push(&prim_header, [
+ let z_id_shadow = z_id;
+ let z_id_content = z_generator.next();
+
+ let content_prim_header_index = prim_headers.push(&prim_header, z_id_content, [
ShaderColorMode::Image as i32,
RasterizationSpace::Screen as i32,
0,
]);
let shadow_rect = prim.local_rect.translate(&offset);
let shadow_clip_rect = prim.local_clip_rect.translate(&offset);
let shadow_prim_header = PrimitiveHeader {
local_rect: shadow_rect,
local_clip_rect: shadow_clip_rect,
specific_prim_address: shadow_prim_address,
..prim_header
};
- let shadow_prim_header_index = prim_headers.push(&shadow_prim_header, [
+ let shadow_prim_header_index = prim_headers.push(&shadow_prim_header, z_id_shadow, [
ShaderColorMode::Alpha as i32,
RasterizationSpace::Screen as i32,
0,
]);
let shadow_instance = BrushInstance {
prim_header_index: shadow_prim_header_index,
clip_task_address,
@@ -794,24 +800,24 @@ impl AlphaBatchBuilder {
edge_flags: EdgeAaSegmentMask::empty(),
brush_flags: BrushFlags::empty(),
user_data: content_uv_rect_address,
};
self.batch_list.push_single_instance(
shadow_key,
bounding_rect,
- prim_instance.prim_index,
+ z_id_shadow,
PrimitiveInstanceData::from(shadow_instance),
);
self.batch_list.push_single_instance(
content_key,
bounding_rect,
- prim_instance.prim_index,
+ z_id_content,
PrimitiveInstanceData::from(content_instance),
);
}
_ => {
let filter_mode = match filter {
FilterOp::Identity => 1, // matches `Contrast(1)`
FilterOp::Blur(..) => 0,
FilterOp::Contrast(..) => 1,
@@ -861,17 +867,17 @@ impl AlphaBatchBuilder {
);
let key = BatchKey::new(
BatchKind::Brush(BrushBatchKind::Blend),
BlendMode::PremultipliedAlpha,
textures,
);
- let prim_header_index = prim_headers.push(&prim_header, [
+ let prim_header_index = prim_headers.push(&prim_header, z_id, [
uv_rect_address.as_int(),
filter_mode,
user_data,
]);
let instance = BrushInstance {
prim_header_index,
clip_task_address,
@@ -879,17 +885,17 @@ impl AlphaBatchBuilder {
edge_flags: EdgeAaSegmentMask::empty(),
brush_flags: BrushFlags::empty(),
user_data: 0,
};
self.batch_list.push_single_instance(
key,
bounding_rect,
- prim_instance.prim_index,
+ z_id,
PrimitiveInstanceData::from(instance),
);
}
}
}
PictureCompositeMode::MixBlend(mode) => {
let cache_task_id = surface.resolve_render_task_id();
let backdrop_id = picture.secondary_render_task_id.expect("no backdrop!?");
@@ -902,17 +908,17 @@ impl AlphaBatchBuilder {
backdrop_id,
},
),
BlendMode::PremultipliedAlpha,
BatchTextures::no_texture(),
);
let backdrop_task_address = render_tasks.get_task_address(backdrop_id);
let source_task_address = render_tasks.get_task_address(cache_task_id);
- let prim_header_index = prim_headers.push(&prim_header, [
+ let prim_header_index = prim_headers.push(&prim_header, z_id, [
mode as u32 as i32,
backdrop_task_address.0 as i32,
source_task_address.0 as i32,
]);
let instance = BrushInstance {
prim_header_index,
clip_task_address,
@@ -920,17 +926,17 @@ impl AlphaBatchBuilder {
edge_flags: EdgeAaSegmentMask::empty(),
brush_flags: BrushFlags::empty(),
user_data: 0,
};
self.batch_list.push_single_instance(
key,
bounding_rect,
- prim_instance.prim_index,
+ z_id,
PrimitiveInstanceData::from(instance),
);
}
PictureCompositeMode::Blit => {
let cache_task_id = surface.resolve_render_task_id();
let kind = BatchKind::Brush(
BrushBatchKind::Image(ImageBufferKind::Texture2DArray)
);
@@ -938,17 +944,17 @@ impl AlphaBatchBuilder {
kind,
non_segmented_blend_mode,
BatchTextures::render_target_cache(),
);
let uv_rect_address = render_tasks[cache_task_id]
.get_texture_address(gpu_cache)
.as_int();
- let prim_header_index = prim_headers.push(&prim_header, [
+ let prim_header_index = prim_headers.push(&prim_header, z_id, [
ShaderColorMode::Image as i32,
RasterizationSpace::Screen as i32,
0,
]);
let instance = BrushInstance {
prim_header_index,
clip_task_address,
@@ -956,17 +962,17 @@ impl AlphaBatchBuilder {
edge_flags: EdgeAaSegmentMask::empty(),
brush_flags: BrushFlags::empty(),
user_data: uv_rect_address,
};
self.batch_list.push_single_instance(
key,
bounding_rect,
- prim_instance.prim_index,
+ z_id,
PrimitiveInstanceData::from(instance),
);
}
}
}
None => {
// If this picture is being drawn into an existing target (i.e. with
// no composition operation), recurse and add to the current batch list.
@@ -975,16 +981,17 @@ impl AlphaBatchBuilder {
task_id,
ctx,
gpu_cache,
render_tasks,
deferred_resolves,
prim_headers,
transforms,
root_spatial_node_index,
+ z_generator,
);
}
}
}
BrushKind::Image { request, ref visible_tiles, .. } if !visible_tiles.is_empty() => {
for tile in visible_tiles {
if let Some((batch_kind, textures, user_data, uv_rect_address)) = get_image_tile_params(
ctx.resource_cache,
@@ -994,86 +1001,87 @@ impl AlphaBatchBuilder {
) {
let prim_cache_address = gpu_cache.get_address(&tile.handle);
let prim_header = PrimitiveHeader {
specific_prim_address: prim_cache_address,
local_rect: tile.local_rect,
local_clip_rect: tile.local_clip_rect,
..prim_header
};
- let prim_header_index = prim_headers.push(&prim_header, user_data);
+ let prim_header_index = prim_headers.push(&prim_header, z_id, user_data);
self.add_image_tile_to_batch(
- prim_instance,
batch_kind,
specified_blend_mode,
textures,
prim_header_index,
clip_task_address,
bounding_rect,
tile.edge_flags,
uv_rect_address,
+ z_id,
);
}
}
}
BrushKind::LinearGradient { ref stops_handle, ref visible_tiles, .. } if !visible_tiles.is_empty() => {
add_gradient_tiles(
- prim_instance,
visible_tiles,
stops_handle,
BrushBatchKind::LinearGradient,
specified_blend_mode,
bounding_rect,
clip_task_address,
gpu_cache,
&mut self.batch_list,
&prim_header,
prim_headers,
+ z_id,
);
}
BrushKind::RadialGradient { ref stops_handle, ref visible_tiles, .. } if !visible_tiles.is_empty() => {
add_gradient_tiles(
- prim_instance,
visible_tiles,
stops_handle,
BrushBatchKind::RadialGradient,
specified_blend_mode,
bounding_rect,
clip_task_address,
gpu_cache,
&mut self.batch_list,
&prim_header,
prim_headers,
+ z_id,
);
}
_ => {
if let Some(params) = brush.get_batch_params(
ctx.resource_cache,
gpu_cache,
deferred_resolves,
ctx.prim_store.chase_id == Some(prim_instance.prim_index),
) {
- let prim_header_index = prim_headers.push(&prim_header, params.prim_user_data);
+ let prim_header_index = prim_headers.push(&prim_header, z_id, params.prim_user_data);
if cfg!(debug_assertions) && ctx.prim_store.chase_id == Some(prim_instance.prim_index) {
println!("\t{:?} {:?}, task relative bounds {:?}",
params.batch_kind, prim_header_index, bounding_rect);
}
self.add_brush_to_batch(
brush,
¶ms,
prim_instance,
specified_blend_mode,
non_segmented_blend_mode,
prim_header_index,
clip_task_address,
bounding_rect,
transform_kind,
render_tasks,
+ z_id,
);
}
}
}
}
PrimitiveDetails::TextRun(ref text_cpu) => {
let subpx_dir = text_cpu.used_font.get_subpx_dir();
@@ -1141,25 +1149,25 @@ impl AlphaBatchBuilder {
GlyphFormat::ColorBitmap => {
(
BlendMode::PremultipliedAlpha,
ShaderColorMode::ColorBitmap,
)
}
};
- let prim_header_index = prim_headers.push(&prim_header, [0; 3]);
+ let prim_header_index = prim_headers.push(&prim_header, z_id, [0; 3]);
let key = BatchKey::new(kind, blend_mode, textures);
let base_instance = GlyphInstance::new(
prim_header_index,
);
let batch = alpha_batch_list.set_params_and_get_batch(
key,
bounding_rect,
- prim_instance.prim_index,
+ z_id,
);
for glyph in glyphs {
batch.push(base_instance.build(
glyph.index_in_text_run,
glyph.uv_rect_address.as_int(),
(subpx_dir as u32 as i32) << 16 |
(color_mode as u32 as i32),
@@ -1168,25 +1176,25 @@ impl AlphaBatchBuilder {
},
);
}
}
}
fn add_image_tile_to_batch(
&mut self,
- prim_instance: &PrimitiveInstance,
batch_kind: BrushBatchKind,
blend_mode: BlendMode,
textures: BatchTextures,
prim_header_index: PrimitiveHeaderIndex,
clip_task_address: RenderTaskAddress,
bounding_rect: &WorldRect,
edge_flags: EdgeAaSegmentMask,
uv_rect_address: GpuCacheAddress,
+ z_id: ZBufferId,
) {
let base_instance = BrushInstance {
prim_header_index,
clip_task_address,
segment_index: 0,
edge_flags,
brush_flags: BrushFlags::PERSPECTIVE_INTERPOLATION,
user_data: uv_rect_address.as_int(),
@@ -1195,17 +1203,17 @@ impl AlphaBatchBuilder {
let batch_key = BatchKey {
blend_mode,
kind: BatchKind::Brush(batch_kind),
textures,
};
self.batch_list.push_single_instance(
batch_key,
bounding_rect,
- prim_instance.prim_index,
+ z_id,
PrimitiveInstanceData::from(base_instance),
);
}
/// Add a single segment instance to a batch.
fn add_segment_to_batch(
&mut self,
segment: &BrushSegment,
@@ -1213,16 +1221,17 @@ impl AlphaBatchBuilder {
segment_index: i32,
batch_kind: BrushBatchKind,
prim_instance: &PrimitiveInstance,
prim_header_index: PrimitiveHeaderIndex,
alpha_blend_mode: BlendMode,
bounding_rect: &WorldRect,
transform_kind: TransformedRectKind,
render_tasks: &RenderTaskTree,
+ z_id: ZBufferId,
) {
let clip_task_address = match segment.clip_task_id {
BrushSegmentTaskId::RenderTaskId(id) =>
render_tasks.get_task_address(id),
BrushSegmentTaskId::Opaque => OPAQUE_TASK_ADDRESS,
BrushSegmentTaskId::Empty => return,
};
@@ -1252,17 +1261,17 @@ impl AlphaBatchBuilder {
blend_mode: if needs_blending { alpha_blend_mode } else { BlendMode::None },
kind: BatchKind::Brush(batch_kind),
textures: segment_data.textures,
};
self.batch_list.push_single_instance(
batch_key,
bounding_rect,
- prim_instance.prim_index,
+ z_id,
instance,
);
}
/// Add any segment(s) from a brush to batches.
fn add_brush_to_batch(
&mut self,
brush: &BrushPrimitive,
@@ -1270,16 +1279,17 @@ impl AlphaBatchBuilder {
prim_instance: &PrimitiveInstance,
alpha_blend_mode: BlendMode,
non_segmented_blend_mode: BlendMode,
prim_header_index: PrimitiveHeaderIndex,
clip_task_address: RenderTaskAddress,
bounding_rect: &WorldRect,
transform_kind: TransformedRectKind,
render_tasks: &RenderTaskTree,
+ z_id: ZBufferId,
) {
match (&brush.segment_desc, ¶ms.segment_data) {
(Some(ref segment_desc), SegmentDataKind::Instanced(ref segment_data)) => {
// In this case, we have both a list of segments, and a list of
// per-segment instance data. Zip them together to build batches.
debug_assert_eq!(segment_desc.segments.len(), segment_data.len());
for (segment_index, (segment, segment_data)) in segment_desc.segments
.iter()
@@ -1291,16 +1301,17 @@ impl AlphaBatchBuilder {
segment_index as i32,
params.batch_kind,
prim_instance,
prim_header_index,
alpha_blend_mode,
bounding_rect,
transform_kind,
render_tasks,
+ z_id,
);
}
}
(Some(ref segment_desc), SegmentDataKind::Shared(ref segment_data)) => {
// A list of segments, but the per-segment data is common
// between all segments.
for (segment_index, segment) in segment_desc.segments
.iter()
@@ -1311,16 +1322,17 @@ impl AlphaBatchBuilder {
segment_index as i32,
params.batch_kind,
prim_instance,
prim_header_index,
alpha_blend_mode,
bounding_rect,
transform_kind,
render_tasks,
+ z_id,
);
}
}
(None, SegmentDataKind::Shared(ref segment_data)) => {
// No segments, and thus no per-segment instance data.
let batch_key = BatchKey {
blend_mode: non_segmented_blend_mode,
kind: BatchKind::Brush(params.batch_kind),
@@ -1332,62 +1344,62 @@ impl AlphaBatchBuilder {
clip_task_address,
brush_flags: BrushFlags::PERSPECTIVE_INTERPOLATION,
prim_header_index,
user_data: segment_data.user_data,
});
self.batch_list.push_single_instance(
batch_key,
bounding_rect,
- prim_instance.prim_index,
+ z_id,
PrimitiveInstanceData::from(instance),
);
}
(None, SegmentDataKind::Instanced(..)) => {
// We should never hit the case where there are no segments,
// but a list of segment instance data.
unreachable!();
}
}
}
}
fn add_gradient_tiles(
- prim_instance: &PrimitiveInstance,
visible_tiles: &[VisibleGradientTile],
stops_handle: &GpuCacheHandle,
kind: BrushBatchKind,
blend_mode: BlendMode,
bounding_rect: &WorldRect,
clip_task_address: RenderTaskAddress,
gpu_cache: &GpuCache,
batch_list: &mut BatchList,
base_prim_header: &PrimitiveHeader,
prim_headers: &mut PrimitiveHeaders,
+ z_id: ZBufferId,
) {
let batch = batch_list.set_params_and_get_batch(
BatchKey {
blend_mode: blend_mode,
kind: BatchKind::Brush(kind),
textures: BatchTextures::no_texture(),
},
bounding_rect,
- prim_instance.prim_index,
+ z_id,
);
let user_data = [stops_handle.as_int(gpu_cache), 0, 0];
for tile in visible_tiles {
let prim_header = PrimitiveHeader {
specific_prim_address: gpu_cache.get_address(&tile.handle),
local_rect: tile.local_rect,
local_clip_rect: tile.local_clip_rect,
..*base_prim_header
};
- let prim_header_index = prim_headers.push(&prim_header, user_data);
+ let prim_header_index = prim_headers.push(&prim_header, z_id, user_data);
batch.push(PrimitiveInstanceData::from(
BrushInstance {
prim_header_index,
clip_task_address,
segment_index: 0,
edge_flags: EdgeAaSegmentMask::all(),
brush_flags: BrushFlags::PERSPECTIVE_INTERPOLATION,
--- a/gfx/webrender/src/tiling.rs
+++ b/gfx/webrender/src/tiling.rs
@@ -8,17 +8,17 @@ use api::{MixBlendMode, PipelineId, Devi
use batch::{AlphaBatchBuilder, AlphaBatchContainer, ClipBatcher, resolve_image};
use clip::ClipStore;
use clip_scroll_tree::{ClipScrollTree};
use device::{FrameId, Texture};
#[cfg(feature = "pathfinder")]
use euclid::{TypedPoint2D, TypedVector2D};
use gpu_cache::{GpuCache};
use gpu_types::{BorderInstance, BlurDirection, BlurInstance, PrimitiveHeaders, ScalingInstance};
-use gpu_types::{TransformData, TransformPalette};
+use gpu_types::{TransformData, TransformPalette, ZBufferIdGenerator};
use internal_types::{CacheTextureId, FastHashMap, SavedTargetIndex, TextureSource};
#[cfg(feature = "pathfinder")]
use pathfinder_partitioner::mesh::Mesh;
use prim_store::{PrimitiveStore, DeferredResolve};
use profiler::FrameProfileCounters;
use render_backend::FrameResources;
use render_task::{BlitSource, RenderTaskAddress, RenderTaskId, RenderTaskKind};
use render_task::{BlurTask, ClearMode, GlyphTask, RenderTaskLocation, RenderTaskTree, ScalingTask};
@@ -119,16 +119,17 @@ pub trait RenderTarget {
fn build(
&mut self,
_ctx: &mut RenderTargetContext,
_gpu_cache: &mut GpuCache,
_render_tasks: &mut RenderTaskTree,
_deferred_resolves: &mut Vec<DeferredResolve>,
_prim_headers: &mut PrimitiveHeaders,
_transforms: &mut TransformPalette,
+ _z_generator: &mut ZBufferIdGenerator,
) {
}
/// Associates a `RenderTask` with this target. That task must be assigned
/// to a region returned by invoking `allocate()` on this target.
///
/// TODO(gw): It's a bit odd that we need the deferred resolves and mutable
/// GPU cache here. They are typically used by the build step above. They
@@ -212,28 +213,30 @@ impl<T: RenderTarget> RenderTargetList<T
&mut self,
ctx: &mut RenderTargetContext,
gpu_cache: &mut GpuCache,
render_tasks: &mut RenderTaskTree,
deferred_resolves: &mut Vec<DeferredResolve>,
saved_index: Option<SavedTargetIndex>,
prim_headers: &mut PrimitiveHeaders,
transforms: &mut TransformPalette,
+ z_generator: &mut ZBufferIdGenerator,
) {
debug_assert_eq!(None, self.saved_index);
self.saved_index = saved_index;
for target in &mut self.targets {
target.build(
ctx,
gpu_cache,
render_tasks,
deferred_resolves,
prim_headers,
transforms,
+ z_generator,
);
}
}
fn add_task(
&mut self,
task_id: RenderTaskId,
ctx: &RenderTargetContext,
@@ -394,16 +397,17 @@ impl RenderTarget for ColorRenderTarget
fn build(
&mut self,
ctx: &mut RenderTargetContext,
gpu_cache: &mut GpuCache,
render_tasks: &mut RenderTaskTree,
deferred_resolves: &mut Vec<DeferredResolve>,
prim_headers: &mut PrimitiveHeaders,
transforms: &mut TransformPalette,
+ z_generator: &mut ZBufferIdGenerator,
) {
let mut merged_batches = AlphaBatchContainer::new(None);
for task_id in &self.alpha_tasks {
let task = &render_tasks[*task_id];
match task.kind {
RenderTaskKind::Picture(ref pic_task) => {
@@ -422,16 +426,17 @@ impl RenderTarget for ColorRenderTarget
*task_id,
ctx,
gpu_cache,
render_tasks,
deferred_resolves,
prim_headers,
transforms,
pic_task.root_spatial_node_index,
+ z_generator,
);
if let Some(batch_container) = batch_builder.build(&mut merged_batches) {
self.alpha_batch_containers.push(batch_container);
}
}
_ => {
unreachable!();
@@ -890,16 +895,17 @@ impl RenderPass {
&mut self,
ctx: &mut RenderTargetContext,
gpu_cache: &mut GpuCache,
render_tasks: &mut RenderTaskTree,
deferred_resolves: &mut Vec<DeferredResolve>,
clip_store: &ClipStore,
transforms: &mut TransformPalette,
prim_headers: &mut PrimitiveHeaders,
+ z_generator: &mut ZBufferIdGenerator,
) {
profile_scope!("RenderPass::build");
match self.kind {
RenderPassKind::MainFramebuffer(ref mut target) => {
for &task_id in &self.tasks {
assert_eq!(render_tasks[task_id].target_kind(), RenderTargetKind::Color);
target.add_task(
@@ -914,16 +920,17 @@ impl RenderPass {
}
target.build(
ctx,
gpu_cache,
render_tasks,
deferred_resolves,
prim_headers,
transforms,
+ z_generator,
);
}
RenderPassKind::OffScreen { ref mut color, ref mut alpha, ref mut texture_cache } => {
let saved_color = if self.tasks.iter().any(|&task_id| {
let t = &render_tasks[task_id];
t.target_kind() == RenderTargetKind::Color && t.saved_index.is_some()
}) {
Some(render_tasks.save_target())
@@ -1018,25 +1025,27 @@ impl RenderPass {
color.build(
ctx,
gpu_cache,
render_tasks,
deferred_resolves,
saved_color,
prim_headers,
transforms,
+ z_generator,
);
alpha.build(
ctx,
gpu_cache,
render_tasks,
deferred_resolves,
saved_alpha,
prim_headers,
transforms,
+ z_generator,
);
}
}
}
}
#[derive(Debug, Clone, Default)]
pub struct CompositeOps {