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 tiled images during frame building (v4) #2742

Merged
merged 3 commits into from May 10, 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 tiled images during frame building.

  • Loading branch information
jrmuizel committed May 10, 2018
commit 066eeb35200033d5fe5e503cbd7e2c1ed5ee8a1e
@@ -608,7 +608,26 @@ impl AlphaBatchBuilder {
screen_rect.unclipped.size,
);

let prim_cache_address = gpu_cache.get_address(&prim_metadata.gpu_location);
// If the primitive is internally decomposed into multiple sub-primitives we may not
// use some of the per-primitive data typically stored in PrimitiveMetadata and get
// it from each sub-primitive instead.
let is_multiple_primitives = match prim_metadata.prim_kind {
PrimitiveKind::Brush => {
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(),
_ => false,
}
}
_ => false,
};

let prim_cache_address = if is_multiple_primitives {
GpuCacheAddress::invalid()
} else {
gpu_cache.get_address(&prim_metadata.gpu_location)
};

let no_textures = BatchTextures::no_texture();
let clip_task_address = prim_metadata
.clip_task_id
@@ -974,6 +993,32 @@ impl AlphaBatchBuilder {
);
}
}
BrushKind::Image { request, ref visible_tiles, .. } if !visible_tiles.is_empty() => {
for tile in visible_tiles {
if let Some((batch_kind, textures, user_data)) = get_image_tile_params(
ctx.resource_cache,
gpu_cache,
deferred_resolves,
request.with_tile(tile.tile_offset),
) {
let prim_cache_address = gpu_cache.get_address(&tile.handle);
self.add_image_tile_to_batch(
batch_kind,
specified_blend_mode,
textures,
clip_chain_rect_index,
clip_task_address,
&task_relative_bounding_rect,
prim_cache_address,
scroll_id,
task_address,
z,
user_data,
tile.edge_flags
);
}
}
}
_ => {
if let Some((batch_kind, textures, user_data)) = brush.get_batch_params(
ctx.resource_cache,
@@ -1210,6 +1255,45 @@ impl AlphaBatchBuilder {
}
}

fn add_image_tile_to_batch(
&mut self,
batch_kind: BrushBatchKind,
blend_mode: BlendMode,
textures: BatchTextures,
clip_chain_rect_index: ClipChainRectIndex,
clip_task_address: RenderTaskAddress,
task_relative_bounding_rect: &DeviceIntRect,
prim_cache_address: GpuCacheAddress,
scroll_id: ClipScrollNodeIndex,
task_address: RenderTaskAddress,
z: ZBufferId,
user_data: [i32; 3],
edge_flags: EdgeAaSegmentMask,
) {
let base_instance = BrushInstance {
picture_address: task_address,
prim_address: prim_cache_address,
clip_chain_rect_index,
scroll_id,
clip_task_address,
z,
segment_index: 0,
edge_flags,
brush_flags: BrushFlags::PERSPECTIVE_INTERPOLATION,
user_data,
};

self.batch_list.add_bounding_rect(task_relative_bounding_rect);

let batch_key = BatchKey {
blend_mode,
kind: BatchKind::Brush(batch_kind),
textures,
};
let batch = self.batch_list.get_suitable_batch(batch_key, task_relative_bounding_rect);
batch.push(PrimitiveInstance::from(base_instance));
}

fn add_brush_to_batch(
&mut self,
brush: &BrushPrimitive,
@@ -1309,6 +1393,37 @@ impl AlphaBatchBuilder {
}
}

fn get_image_tile_params(
resource_cache: &ResourceCache,
gpu_cache: &mut GpuCache,
deferred_resolves: &mut Vec<DeferredResolve>,
request: ImageRequest,
) -> Option<(BrushBatchKind, BatchTextures, [i32; 3])> {

let cache_item = resolve_image(
request,
resource_cache,
gpu_cache,
deferred_resolves,
);

if cache_item.texture_id == SourceTexture::Invalid {
None
} else {
let textures = BatchTextures::color(cache_item.texture_id);
Some((
BrushBatchKind::Image(get_buffer_kind(cache_item.texture_id)),
textures,
[
cache_item.uv_rect_handle.as_int(gpu_cache),
(ShaderColorMode::ColorBitmap as i32) << 16 |
RasterizationSpace::Local as i32,
0,
],
))
}
}

impl BrushPrimitive {
pub fn get_picture_index(&self) -> PictureIndex {
match self.kind {
@@ -8,10 +8,10 @@ use api::{ClipId, ColorF, ComplexClipRegion, DeviceIntPoint, DeviceIntRect, Devi
use api::{DevicePixelScale, DeviceUintRect, DisplayItemRef, Epoch, ExtendMode, ExternalScrollId};
use api::{FilterOp, FontInstanceKey, GlyphInstance, GlyphOptions, GlyphRasterSpace, GradientStop};
use api::{IframeDisplayItem, ImageKey, ImageRendering, ItemRange, LayoutPoint};
use api::{LayoutPrimitiveInfo, LayoutRect, LayoutSize, LayoutTransform, LayoutVector2D};
use api::{LayoutPrimitiveInfo, LayoutRect, LayoutVector2D, LayoutSize, LayoutTransform};
use api::{LineOrientation, LineStyle, LocalClip, NinePatchBorderSource, PipelineId};
use api::{PropertyBinding, RepeatMode, ScrollFrameDisplayItem, ScrollSensitivity, Shadow};
use api::{SpecificDisplayItem, StackingContext, StickyFrameDisplayItem, TexelRect, TileOffset};
use api::{SpecificDisplayItem, StackingContext, StickyFrameDisplayItem, TexelRect};
use api::{TransformStyle, YuvColorSpace, YuvData};
use app_units::Au;
use clip::{ClipRegion, ClipSource, ClipSources, ClipStore};
@@ -22,11 +22,11 @@ use frame_builder::{FrameBuilder, FrameBuilderConfig};
use glyph_rasterizer::FontInstance;
use gpu_types::BrushFlags;
use hit_test::{HitTestingItem, HitTestingRun};
use image::{decompose_image, TiledImageInfo, simplify_repeated_primitive};
use image::simplify_repeated_primitive;
use internal_types::{FastHashMap, FastHashSet};
use picture::PictureCompositeMode;
use prim_store::{BrushClipMaskKind, BrushKind, BrushPrimitive, BrushSegmentDescriptor, CachedGradient};
use prim_store::{CachedGradientIndex, EdgeAaSegmentMask, ImageCacheKey, ImagePrimitiveCpu, ImageSource};
use prim_store::{CachedGradientIndex, EdgeAaSegmentMask, ImageSource};
use prim_store::{BrushSegment, PictureIndex, PrimitiveContainer, PrimitiveIndex, PrimitiveStore};
use prim_store::{OpacityBinding, ScrollNodeAndClipChain, TextRunPrimitiveCpu};
use render_backend::{DocumentView};
@@ -623,49 +623,16 @@ impl<'a> DisplayListFlattener<'a> {
let prim_info = item.get_layout_primitive_info(&reference_frame_relative_offset);
match *item.item() {
SpecificDisplayItem::Image(ref info) => {
match self.tiled_image_map.get(&info.image_key).cloned() {
Some(tiling) => {
// The image resource is tiled. We have to generate an image primitive
// for each tile.
decompose_image(
&TiledImageInfo {
rect: prim_info.rect,
tile_spacing: info.tile_spacing,
stretch_size: info.stretch_size,
device_image_size: tiling.image_size,
device_tile_size: tiling.tile_size as u32,
},
&mut|tile| {
let mut prim_info = prim_info.clone();
prim_info.rect = tile.rect;
self.add_image(
clip_and_scroll,
&prim_info,
tile.stretch_size,
info.tile_spacing,
None,
info.image_key,
info.image_rendering,
info.alpha_type,
Some(tile.tile_offset),
);
}
);
}
None => {
self.add_image(
clip_and_scroll,
&prim_info,
info.stretch_size,
info.tile_spacing,
None,
info.image_key,
info.image_rendering,
info.alpha_type,
None,
);
}
}
self.add_image(
clip_and_scroll,
&prim_info,
info.stretch_size,
info.tile_spacing,
None,
info.image_key,
info.image_rendering,
info.alpha_type,
);
}
SpecificDisplayItem::YuvImage(ref info) => {
self.add_yuv_image(
@@ -1773,7 +1740,6 @@ impl<'a> DisplayListFlattener<'a> {
RepeatMode::Stretch,
border.repeat_vertical,
);

let descriptor = BrushSegmentDescriptor {
segments,
clip_mask_kind: BrushClipMaskKind::Unknown,
@@ -2141,7 +2107,6 @@ impl<'a> DisplayListFlattener<'a> {
image_key: ImageKey,
image_rendering: ImageRendering,
alpha_type: AlphaType,
tile_offset: Option<TileOffset>,
) {
let mut prim_rect = info.rect;
simplify_repeated_primitive(&stretch_size, &mut tile_spacing, &mut prim_rect);
@@ -2150,12 +2115,6 @@ impl<'a> DisplayListFlattener<'a> {
.. *info
};

let request = ImageRequest {
key: image_key,
rendering: image_rendering,
tile: tile_offset,
};

let sub_rect = sub_rect.map(|texel_rect| {
DeviceIntRect::new(
DeviceIntPoint::new(
@@ -2169,49 +2128,31 @@ impl<'a> DisplayListFlattener<'a> {
)
});

// See if conditions are met to run through the new
// image brush shader, which supports segments.
if tile_offset.is_none() {
let prim = BrushPrimitive::new(
BrushKind::Image {
request,
current_epoch: Epoch::invalid(),
alpha_type,
stretch_size,
tile_spacing,
source: ImageSource::Default,
sub_rect,
opacity_binding: OpacityBinding::new(),
let prim = BrushPrimitive::new(
BrushKind::Image {
request: ImageRequest {
key: image_key,
rendering: image_rendering,
tile: None,
},
None,
);

self.add_primitive(
clip_and_scroll,
&info,
Vec::new(),
PrimitiveContainer::Brush(prim),
);
} else {
let prim_cpu = ImagePrimitiveCpu {
tile_spacing,
current_epoch: Epoch::invalid(),
alpha_type,
stretch_size,
current_epoch: Epoch::invalid(),
tile_spacing,
source: ImageSource::Default,
key: ImageCacheKey {
request,
texel_rect: sub_rect,
},
};
sub_rect,
visible_tiles: Vec::new(),
opacity_binding: OpacityBinding::new(),
},
None,
);

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

pub fn add_yuv_image(
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.