Bug 1958109 - Support rounded clip rects during (draw / non-native) compositing r=gfx-reviewers,nical
Support for this with native compositing will be added by follow up patches. Differential Revision: https://phabricator.services.mozilla.com/D244264
This commit is contained in:
@@ -15,6 +15,13 @@
|
||||
#include yuv
|
||||
#endif
|
||||
|
||||
#ifndef WR_FEATURE_FAST_PATH
|
||||
// Parameters for compositor clip
|
||||
varying highp vec2 vNormalizedWorldPos;
|
||||
flat varying highp vec2 vRoundedClipParams;
|
||||
flat varying highp vec4 vRoundedClipRadii;
|
||||
#endif
|
||||
|
||||
#ifdef WR_FEATURE_YUV
|
||||
flat varying YUV_PRECISION vec3 vYcbcrBias;
|
||||
flat varying YUV_PRECISION mat3 vRgbFromDebiasedYcbcr;
|
||||
@@ -51,6 +58,11 @@ PER_INSTANCE attribute vec4 aColor;
|
||||
PER_INSTANCE attribute vec4 aParams;
|
||||
PER_INSTANCE attribute vec2 aFlip;
|
||||
|
||||
#ifndef WR_FEATURE_FAST_PATH
|
||||
PER_INSTANCE attribute vec4 aDeviceRoundedClipRect;
|
||||
PER_INSTANCE attribute vec4 aDeviceRoundedClipRadii;
|
||||
#endif
|
||||
|
||||
#ifdef WR_FEATURE_YUV
|
||||
// YUV treats these as a UV clip rect (clamp)
|
||||
PER_INSTANCE attribute vec4 aUvRect0;
|
||||
@@ -80,6 +92,13 @@ void main(void) {
|
||||
// Clip the position to the world space clip rect
|
||||
vec2 clipped_world_pos = clamp(world_pos, aDeviceClipRect.xy, aDeviceClipRect.zw);
|
||||
|
||||
#ifndef WR_FEATURE_FAST_PATH
|
||||
vec2 half_clip_box_size = 0.5 * (aDeviceRoundedClipRect.zw - aDeviceRoundedClipRect.xy);
|
||||
vNormalizedWorldPos = aDeviceRoundedClipRect.xy + half_clip_box_size - clipped_world_pos;
|
||||
vRoundedClipParams = half_clip_box_size;
|
||||
vRoundedClipRadii = aDeviceRoundedClipRadii;
|
||||
#endif
|
||||
|
||||
// Derive the normalized UV from the clipped vertex position
|
||||
vec2 uv = (clipped_world_pos - device_rect.xy) / (device_rect.zw - device_rect.xy);
|
||||
|
||||
@@ -160,6 +179,20 @@ void main(void) {
|
||||
#endif
|
||||
|
||||
#ifdef WR_FRAGMENT_SHADER
|
||||
|
||||
#ifndef WR_FEATURE_FAST_PATH
|
||||
// See https://www.shadertoy.com/view/4llXD7
|
||||
// Notes:
|
||||
// * pos is centered in the origin (so 0,0 is the center of the box).
|
||||
// * The border radii must not be larger than half_box_size.
|
||||
float sd_round_box(in vec2 pos, in vec2 half_box_size, in vec4 radii) {
|
||||
radii.xy = (pos.x > 0.0) ? radii.xy : radii.zw;
|
||||
radii.x = (pos.y > 0.0) ? radii.x : radii.y;
|
||||
vec2 q = abs(pos) - half_box_size + radii.x;
|
||||
return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - radii.x;
|
||||
}
|
||||
#endif
|
||||
|
||||
void main(void) {
|
||||
#ifdef WR_FEATURE_YUV
|
||||
vec4 color = sample_yuv(
|
||||
@@ -188,6 +221,27 @@ void main(void) {
|
||||
vec4 color = vColor * texel;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// TODO(gw): Do we need to support this on ESSL1?
|
||||
#ifndef WR_FEATURE_TEXTURE_EXTERNAL_ESSL1
|
||||
#ifndef WR_FEATURE_FAST_PATH
|
||||
// Apply compositor clip
|
||||
float aa_range = compute_aa_range(vNormalizedWorldPos);
|
||||
|
||||
float dist = sd_round_box(
|
||||
vNormalizedWorldPos,
|
||||
vRoundedClipParams,
|
||||
vRoundedClipRadii
|
||||
);
|
||||
|
||||
// Compute AA for the given dist and range.
|
||||
float clip_alpha = distance_aa(aa_range, dist);
|
||||
|
||||
// Apply clip alpha
|
||||
color *= clip_alpha;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
write_output(color);
|
||||
}
|
||||
|
||||
@@ -225,6 +279,27 @@ void swgl_drawSpanRGBA8() {
|
||||
vec4 color = vColor;
|
||||
vec4 uvBounds = vUVBounds;
|
||||
#endif
|
||||
|
||||
// TODO(gw): Do we need to support this on ESSL1?
|
||||
#ifndef WR_FEATURE_TEXTURE_EXTERNAL_ESSL1
|
||||
#ifndef WR_FEATURE_FAST_PATH
|
||||
// Apply compositor clip
|
||||
float aa_range = compute_aa_range(vNormalizedWorldPos);
|
||||
|
||||
float dist = sd_round_box(
|
||||
vNormalizedWorldPos,
|
||||
vRoundedClipParams,
|
||||
vRoundedClipRadii
|
||||
);
|
||||
|
||||
// Compute AA for the given dist and range.
|
||||
float clip_alpha = distance_aa(aa_range, dist);
|
||||
|
||||
// Apply clip alpha
|
||||
color *= clip_alpha;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (color != vec4(1.0)) {
|
||||
swgl_commitTextureColorRGBA8(sColor0, vUv, uvBounds, color);
|
||||
} else {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use api::{ColorF, ExternalImageId, ImageBufferKind, ImageKey, ImageRendering, YuvFormat, YuvRangedColorSpace};
|
||||
use api::{BorderRadius, ColorF, ExternalImageId, ImageBufferKind, ImageKey, ImageRendering, YuvFormat, YuvRangedColorSpace};
|
||||
use api::units::*;
|
||||
use api::ColorDepth;
|
||||
use crate::image_source::resolve_image;
|
||||
@@ -13,11 +13,12 @@ use crate::internal_types::{FrameAllocator, FrameMemory, FrameVec, TextureSource
|
||||
use crate::picture::{ImageDependency, ResolvedSurfaceTexture, TileCacheInstance, TileId, TileSurface};
|
||||
use crate::prim_store::DeferredResolve;
|
||||
use crate::resource_cache::{ImageRequest, ResourceCache};
|
||||
use crate::util::{Preallocator, ScaleOffset};
|
||||
use crate::util::{extract_inner_rect_safe, Preallocator, ScaleOffset};
|
||||
use crate::tile_cache::PictureCacheDebugInfo;
|
||||
use crate::device::Device;
|
||||
use crate::space::SpaceMapper;
|
||||
use std::{ops, u64, os::raw::c_void};
|
||||
use std::num::NonZeroUsize;
|
||||
|
||||
/*
|
||||
Types and definitions related to compositing picture cache tiles
|
||||
@@ -115,6 +116,8 @@ bitflags! {
|
||||
const NO_UV_CLAMP = 1 << 0;
|
||||
// The texture sample should not be modulated by a specified color.
|
||||
const NO_COLOR_MODULATION = 1 << 1;
|
||||
// Can skip applying clip mask.
|
||||
const NO_CLIP_MASK = 1 << 2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,6 +140,12 @@ impl CompositorTransformIndex {
|
||||
pub const INVALID: CompositorTransformIndex = CompositorTransformIndex(!0);
|
||||
}
|
||||
|
||||
// Index in to the compositor clips stored in `CompositeState`
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct CompositorClipIndex(NonZeroUsize);
|
||||
|
||||
/// Describes the geometry and surface of a tile to be composited
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
@@ -150,6 +159,7 @@ pub struct CompositeTile {
|
||||
pub z_id: ZBufferId,
|
||||
pub kind: TileKind,
|
||||
pub transform_index: CompositorTransformIndex,
|
||||
pub clip_index: Option<CompositorClipIndex>,
|
||||
}
|
||||
|
||||
pub fn tile_kind(surface: &CompositeTileSurface, is_opaque: bool) -> TileKind {
|
||||
@@ -595,6 +605,13 @@ pub struct CompositorTransform {
|
||||
local_to_device: ScaleOffset,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
pub struct CompositorClip {
|
||||
pub rect: DeviceRect,
|
||||
pub radius: BorderRadius,
|
||||
}
|
||||
|
||||
/// The list of tiles to be drawn this frame
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
@@ -629,6 +646,8 @@ pub struct CompositeState {
|
||||
pub transforms: FrameVec<CompositorTransform>,
|
||||
/// Whether we have low quality pinch zoom enabled
|
||||
low_quality_pinch_zoom: bool,
|
||||
/// List of registered clips used by picture cache and/or external surfaces
|
||||
pub clips: FrameVec<CompositorClip>,
|
||||
}
|
||||
|
||||
impl CompositeState {
|
||||
@@ -641,6 +660,14 @@ impl CompositeState {
|
||||
low_quality_pinch_zoom: bool,
|
||||
memory: &FrameMemory,
|
||||
) -> Self {
|
||||
// Since CompositorClipIndex is NonZeroUSize, we need to
|
||||
// push a dummy entry in to this array.
|
||||
let mut clips = memory.new_vec();
|
||||
clips.push(CompositorClip {
|
||||
rect: DeviceRect::zero(),
|
||||
radius: BorderRadius::zero(),
|
||||
});
|
||||
|
||||
CompositeState {
|
||||
tiles: memory.new_vec(),
|
||||
z_generator: ZBufferIdGenerator::new(max_depth_ids),
|
||||
@@ -652,6 +679,7 @@ impl CompositeState {
|
||||
picture_cache_debug: PictureCacheDebugInfo::new(),
|
||||
transforms: memory.new_vec(),
|
||||
low_quality_pinch_zoom,
|
||||
clips,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -674,6 +702,22 @@ impl CompositeState {
|
||||
index
|
||||
}
|
||||
|
||||
/// Register use of a clip for a picture cache tile and/or external surface
|
||||
pub fn register_clip(
|
||||
&mut self,
|
||||
rect: DeviceRect,
|
||||
radius: BorderRadius,
|
||||
) -> CompositorClipIndex {
|
||||
let index = CompositorClipIndex(NonZeroUsize::new(self.clips.len()).expect("bug"));
|
||||
|
||||
self.clips.push(CompositorClip {
|
||||
rect,
|
||||
radius,
|
||||
});
|
||||
|
||||
index
|
||||
}
|
||||
|
||||
/// Calculate the device-space rect of a local compositor surface rect
|
||||
pub fn get_device_rect(
|
||||
&self,
|
||||
@@ -723,13 +767,44 @@ impl CompositeState {
|
||||
transform.raster_to_device
|
||||
}
|
||||
|
||||
/// Get the compositor clip
|
||||
pub fn get_compositor_clip(
|
||||
&self,
|
||||
clip_index: CompositorClipIndex,
|
||||
) -> &CompositorClip {
|
||||
&self.clips[clip_index.0.get()]
|
||||
}
|
||||
|
||||
/// Register an occluder during picture cache updates that can be
|
||||
/// used during frame building to occlude tiles.
|
||||
pub fn register_occluder(
|
||||
&mut self,
|
||||
z_id: ZBufferId,
|
||||
rect: WorldRect,
|
||||
compositor_clip: Option<CompositorClipIndex>,
|
||||
) {
|
||||
let rect = match compositor_clip {
|
||||
Some(clip_index) => {
|
||||
let clip = self.get_compositor_clip(clip_index);
|
||||
|
||||
let inner_rect = match extract_inner_rect_safe(
|
||||
&clip.rect,
|
||||
&clip.radius,
|
||||
) {
|
||||
Some(rect) => rect,
|
||||
None => return,
|
||||
};
|
||||
|
||||
match inner_rect.cast_unit().intersection(&rect) {
|
||||
Some(rect) => rect,
|
||||
None => return,
|
||||
}
|
||||
}
|
||||
None => {
|
||||
rect
|
||||
}
|
||||
};
|
||||
|
||||
let world_rect = rect.round().to_i32();
|
||||
|
||||
self.occluders.push(world_rect, z_id);
|
||||
@@ -744,6 +819,7 @@ impl CompositeState {
|
||||
resource_cache: &ResourceCache,
|
||||
gpu_cache: &mut GpuCache,
|
||||
deferred_resolves: &mut FrameVec<DeferredResolve>,
|
||||
clip_index: Option<CompositorClipIndex>,
|
||||
) {
|
||||
let clip_rect = external_surface
|
||||
.clip_rect
|
||||
@@ -815,6 +891,7 @@ impl CompositeState {
|
||||
device_clip_rect: clip_rect,
|
||||
z_id: external_surface.z_id,
|
||||
transform_index: external_surface.transform_index,
|
||||
clip_index,
|
||||
};
|
||||
|
||||
// Add a surface descriptor for each compositor surface. For the Draw
|
||||
@@ -879,6 +956,7 @@ impl CompositeState {
|
||||
resource_cache,
|
||||
gpu_cache,
|
||||
deferred_resolves,
|
||||
tile_cache.compositor_clip,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -955,6 +1033,7 @@ impl CompositeState {
|
||||
resource_cache,
|
||||
gpu_cache,
|
||||
deferred_resolves,
|
||||
tile_cache.compositor_clip,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
use api::{AlphaType, PremultipliedColorF, YuvFormat, YuvRangedColorSpace};
|
||||
use api::units::*;
|
||||
use crate::composite::CompositeFeatures;
|
||||
use crate::composite::{CompositeFeatures, CompositorClip};
|
||||
use crate::segment::EdgeAaSegmentMask;
|
||||
use crate::spatial_tree::{SpatialTree, SpatialNodeIndex};
|
||||
use crate::gpu_cache::{GpuCacheAddress, GpuDataRequest};
|
||||
@@ -14,7 +14,7 @@ use crate::render_task::RenderTaskAddress;
|
||||
use crate::render_task_graph::RenderTaskId;
|
||||
use crate::renderer::{ShaderColorMode, GpuBufferAddress};
|
||||
use std::i32;
|
||||
use crate::util::{TransformedRectKind, MatrixHelpers};
|
||||
use crate::util::{MatrixHelpers, TransformedRectKind};
|
||||
use glyph_rasterizer::SubpixelDirection;
|
||||
use crate::util::{ScaleOffset, pack_as_float};
|
||||
|
||||
@@ -307,6 +307,10 @@ pub struct CompositeInstance {
|
||||
|
||||
// Whether to flip the x and y axis respectively, where 0.0 is no-flip and 1.0 is flip.
|
||||
flip: (f32, f32),
|
||||
|
||||
// Optional rounded rect clip to apply during compositing
|
||||
rounded_clip_rect: DeviceRect,
|
||||
rounded_clip_radii: [f32; 4],
|
||||
}
|
||||
|
||||
impl CompositeInstance {
|
||||
@@ -315,8 +319,12 @@ impl CompositeInstance {
|
||||
clip_rect: DeviceRect,
|
||||
color: PremultipliedColorF,
|
||||
flip: (bool, bool),
|
||||
clip: Option<&CompositorClip>,
|
||||
) -> Self {
|
||||
let uv = TexelRect::new(0.0, 0.0, 1.0, 1.0);
|
||||
|
||||
let (rounded_clip_rect, rounded_clip_radii) = Self::vertex_clip_params(clip, rect);
|
||||
|
||||
CompositeInstance {
|
||||
rect,
|
||||
clip_rect,
|
||||
@@ -327,6 +335,8 @@ impl CompositeInstance {
|
||||
yuv_channel_bit_depth: 0.0,
|
||||
uv_rects: [uv, uv, uv],
|
||||
flip: (flip.0.into(), flip.1.into()),
|
||||
rounded_clip_rect,
|
||||
rounded_clip_radii,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -337,7 +347,10 @@ impl CompositeInstance {
|
||||
uv_rect: TexelRect,
|
||||
normalized_uvs: bool,
|
||||
flip: (bool, bool),
|
||||
clip: Option<&CompositorClip>,
|
||||
) -> Self {
|
||||
let (rounded_clip_rect, rounded_clip_radii) = Self::vertex_clip_params(clip, rect);
|
||||
|
||||
let uv_type = match normalized_uvs {
|
||||
true => UV_TYPE_NORMALIZED,
|
||||
false => UV_TYPE_UNNORMALIZED,
|
||||
@@ -352,6 +365,8 @@ impl CompositeInstance {
|
||||
yuv_channel_bit_depth: 0.0,
|
||||
uv_rects: [uv_rect, uv_rect, uv_rect],
|
||||
flip: (flip.0.into(), flip.1.into()),
|
||||
rounded_clip_rect,
|
||||
rounded_clip_radii,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -363,7 +378,11 @@ impl CompositeInstance {
|
||||
yuv_channel_bit_depth: u32,
|
||||
uv_rects: [TexelRect; 3],
|
||||
flip: (bool, bool),
|
||||
clip: Option<&CompositorClip>,
|
||||
) -> Self {
|
||||
|
||||
let (rounded_clip_rect, rounded_clip_radii) = Self::vertex_clip_params(clip, rect);
|
||||
|
||||
CompositeInstance {
|
||||
rect,
|
||||
clip_rect,
|
||||
@@ -374,6 +393,8 @@ impl CompositeInstance {
|
||||
yuv_channel_bit_depth: pack_as_float(yuv_channel_bit_depth),
|
||||
uv_rects,
|
||||
flip: (flip.0.into(), flip.1.into()),
|
||||
rounded_clip_rect,
|
||||
rounded_clip_radii,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -394,8 +415,48 @@ impl CompositeInstance {
|
||||
features |= CompositeFeatures::NO_COLOR_MODULATION
|
||||
}
|
||||
|
||||
// If all the clip radii are <= 0.0, then we don't need clip masking
|
||||
if self.rounded_clip_radii.iter().all(|r| *r <= 0.0) {
|
||||
features |= CompositeFeatures::NO_CLIP_MASK
|
||||
}
|
||||
|
||||
features
|
||||
}
|
||||
|
||||
// Returns the CompositeFeatures that can be used to composite
|
||||
// this YUV instance.
|
||||
pub fn get_yuv_features(&self) -> CompositeFeatures {
|
||||
let mut features = CompositeFeatures::empty();
|
||||
|
||||
// If all the clip radii are <= 0.0, then we don't need clip masking
|
||||
if self.rounded_clip_radii.iter().all(|r| *r <= 0.0) {
|
||||
features |= CompositeFeatures::NO_CLIP_MASK
|
||||
}
|
||||
|
||||
features
|
||||
}
|
||||
|
||||
fn vertex_clip_params(
|
||||
clip: Option<&CompositorClip>,
|
||||
default_rect: DeviceRect,
|
||||
) -> (DeviceRect, [f32; 4]) {
|
||||
match clip {
|
||||
Some(clip) => {
|
||||
(
|
||||
clip.rect.cast_unit(),
|
||||
[
|
||||
clip.radius.top_left.width,
|
||||
clip.radius.bottom_left.width,
|
||||
clip.radius.top_right.width,
|
||||
clip.radius.bottom_right.width,
|
||||
],
|
||||
)
|
||||
}
|
||||
None => {
|
||||
(default_rect, [0.0; 4])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Vertex format for issuing colored quads.
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
//! blend the overlay tile (this is not always optimal right now, but will be
|
||||
//! improved as a follow up).
|
||||
|
||||
use api::{FilterPrimitiveKind, MixBlendMode, PremultipliedColorF, SVGFE_GRAPH_MAX};
|
||||
use api::{BorderRadius, ClipMode, FilterPrimitiveKind, MixBlendMode, PremultipliedColorF, SVGFE_GRAPH_MAX};
|
||||
use api::{PropertyBinding, PropertyBindingId, FilterPrimitive, FilterOpGraphPictureBufferId, RasterSpace};
|
||||
use api::{DebugFlags, ImageKey, ColorF, ColorU, PrimitiveFlags, SnapshotInfo};
|
||||
use api::{ImageRendering, ColorDepth, YuvRangedColorSpace, YuvFormat, AlphaType};
|
||||
@@ -102,10 +102,10 @@ use api::units::*;
|
||||
use crate::prim_store::image::AdjustedImageSource;
|
||||
use crate::{command_buffer::PrimitiveCommand, render_task_graph::RenderTaskGraphBuilder, renderer::GpuBufferBuilderF};
|
||||
use crate::box_shadow::BLUR_SAMPLE_SCALE;
|
||||
use crate::clip::{ClipStore, ClipChainInstance, ClipLeafId, ClipNodeId, ClipTreeBuilder};
|
||||
use crate::clip::{ClipChainInstance, ClipItemKind, ClipLeafId, ClipNodeId, ClipSpaceConversion, ClipStore, ClipTreeBuilder};
|
||||
use crate::profiler::{self, TransactionProfile};
|
||||
use crate::spatial_tree::{SpatialTree, CoordinateSpaceMapping, SpatialNodeIndex, VisibleFace};
|
||||
use crate::composite::{CompositorKind, CompositeState, NativeSurfaceId, NativeTileId, CompositeTileSurface, tile_kind};
|
||||
use crate::composite::{tile_kind, CompositeState, CompositeTileSurface, CompositorClipIndex, CompositorKind, NativeSurfaceId, NativeTileId};
|
||||
use crate::composite::{ExternalSurfaceDescriptor, ExternalSurfaceDependency, CompositeTileDescriptor, CompositeTile};
|
||||
use crate::composite::{CompositorTransformIndex, CompositorSurfaceKind};
|
||||
use crate::debug_colors;
|
||||
@@ -1824,6 +1824,8 @@ pub struct TileCacheInstance {
|
||||
pub local_rect: PictureRect,
|
||||
/// The local clip rect, from the shared clips of this picture.
|
||||
pub local_clip_rect: PictureRect,
|
||||
/// Registered clip in CompositeState for this picture cache
|
||||
pub compositor_clip: Option<CompositorClipIndex>,
|
||||
/// The screen rect, transformed to local picture space.
|
||||
pub screen_rect_in_pic_space: PictureRect,
|
||||
/// The surface index that this tile cache will be drawn into.
|
||||
@@ -1960,6 +1962,7 @@ impl TileCacheInstance {
|
||||
tile_bounds_p1: TileOffset::zero(),
|
||||
local_rect: PictureRect::zero(),
|
||||
local_clip_rect: PictureRect::zero(),
|
||||
compositor_clip: None,
|
||||
screen_rect_in_pic_space: PictureRect::zero(),
|
||||
surface_index: SurfaceIndex(0),
|
||||
background_color: params.background_color,
|
||||
@@ -2206,9 +2209,72 @@ impl TileCacheInstance {
|
||||
// Ensure that if the entire picture cache is clipped out, the local
|
||||
// clip rect is zero. This makes sure we don't register any occluders
|
||||
// that are actually off-screen.
|
||||
self.local_clip_rect = clip_chain_instance.map_or(PictureRect::zero(), |clip_chain_instance| {
|
||||
clip_chain_instance.pic_coverage_rect
|
||||
});
|
||||
self.local_clip_rect = PictureRect::zero();
|
||||
self.compositor_clip = None;
|
||||
|
||||
if let Some(clip_chain) = clip_chain_instance {
|
||||
self.local_clip_rect = clip_chain.pic_coverage_rect;
|
||||
|
||||
self.compositor_clip = if clip_chain.needs_mask {
|
||||
let clip_instance = frame_state
|
||||
.clip_store
|
||||
.get_instance_from_range(&clip_chain.clips_range, 0);
|
||||
let clip_node = &frame_state.data_stores.clip[clip_instance.handle];
|
||||
|
||||
let index = match clip_node.item.kind {
|
||||
ClipItemKind::RoundedRectangle { rect, radius, mode } => {
|
||||
assert_eq!(mode, ClipMode::Clip);
|
||||
|
||||
// Map the clip in to device space. We know from the shared
|
||||
// clip creation logic it's in root coord system, so only a
|
||||
// 2d axis-aligned transform can apply. For example, in the
|
||||
// case of a pinch-zoom effect.
|
||||
let map = ClipSpaceConversion::new(
|
||||
frame_context.root_spatial_node_index,
|
||||
clip_node.item.spatial_node_index,
|
||||
frame_context.root_spatial_node_index,
|
||||
frame_context.spatial_tree,
|
||||
);
|
||||
|
||||
let (rect, radius) = match map {
|
||||
ClipSpaceConversion::Local => {
|
||||
(rect.cast_unit(), radius)
|
||||
}
|
||||
ClipSpaceConversion::ScaleOffset(scale_offset) => {
|
||||
(
|
||||
scale_offset.map_rect(&rect),
|
||||
BorderRadius {
|
||||
top_left: scale_offset.map_size(&radius.top_left),
|
||||
top_right: scale_offset.map_size(&radius.top_right),
|
||||
bottom_left: scale_offset.map_size(&radius.bottom_left),
|
||||
bottom_right: scale_offset.map_size(&radius.bottom_right),
|
||||
},
|
||||
)
|
||||
}
|
||||
ClipSpaceConversion::Transform(..) => {
|
||||
unreachable!();
|
||||
}
|
||||
};
|
||||
|
||||
frame_state.composite_state.register_clip(
|
||||
rect,
|
||||
radius,
|
||||
)
|
||||
}
|
||||
_ => {
|
||||
// The logic to check for shared clips excludes other mask
|
||||
// clip types (box-shadow, image-mask) and ensures that the
|
||||
// clip is in the root coord system (so rect clips can't
|
||||
// produce a mask).
|
||||
unreachable!();
|
||||
}
|
||||
};
|
||||
|
||||
Some(index)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Advance the current frame ID counter for this picture cache (must be done
|
||||
@@ -3950,6 +4016,7 @@ impl TileCacheInstance {
|
||||
composite_state.register_occluder(
|
||||
underlay.z_id,
|
||||
world_surface_rect,
|
||||
self.compositor_clip,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -3964,6 +4031,7 @@ impl TileCacheInstance {
|
||||
composite_state.register_occluder(
|
||||
compositor_surface.descriptor.z_id,
|
||||
world_surface_rect,
|
||||
self.compositor_clip,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -3991,6 +4059,7 @@ impl TileCacheInstance {
|
||||
composite_state.register_occluder(
|
||||
z_id_backdrop,
|
||||
world_backdrop_rect,
|
||||
self.compositor_clip,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -5752,6 +5821,7 @@ impl PicturePrimitive {
|
||||
device_clip_rect,
|
||||
z_id: tile.z_id,
|
||||
transform_index: tile_cache.transform_index,
|
||||
clip_index: tile_cache.compositor_clip,
|
||||
};
|
||||
|
||||
sub_slice.composite_tiles.push(composite_tile);
|
||||
|
||||
@@ -1119,8 +1119,8 @@ pub enum QuadTileKind {
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct QuadTileInfo {
|
||||
rect: LayoutRect,
|
||||
kind: QuadTileKind,
|
||||
pub rect: LayoutRect,
|
||||
pub kind: QuadTileKind,
|
||||
}
|
||||
|
||||
impl Default for QuadTileInfo {
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
//! up the scissor, are accepting already transformed coordinates, which we can get by
|
||||
//! calling `DrawTarget::to_framebuffer_rect`
|
||||
|
||||
use api::{ColorF, ColorU, MixBlendMode};
|
||||
use api::{ClipMode, ColorF, ColorU, MixBlendMode};
|
||||
use api::{DocumentId, Epoch, ExternalImageHandler, RenderReasons};
|
||||
#[cfg(feature = "replay")]
|
||||
use api::ExternalImageId;
|
||||
@@ -58,6 +58,7 @@ use crate::composite::{CompositeState, CompositeTileSurface, CompositorInputLaye
|
||||
use crate::composite::{CompositorKind, Compositor, NativeTileId, CompositeFeatures, CompositeSurfaceFormat, ResolvedExternalSurfaceColorData};
|
||||
use crate::composite::{CompositorConfig, NativeSurfaceOperationDetails, NativeSurfaceId, NativeSurfaceOperation};
|
||||
use crate::composite::TileKind;
|
||||
use crate::segment::SegmentBuilder;
|
||||
use crate::{debug_colors, CompositorInputConfig, CompositorSurfaceUsage};
|
||||
use crate::device::{DepthFunction, Device, DrawTarget, ExternalTexture, GpuFrameId, UploadPBOPool};
|
||||
use crate::device::{ReadTarget, ShaderError, Texture, TextureFilter, TextureFlags, TextureSlot, Texel};
|
||||
@@ -265,11 +266,21 @@ const GPU_TAG_COMPOSITE: GpuProfileTag = GpuProfileTag {
|
||||
color: debug_colors::TOMATO,
|
||||
};
|
||||
|
||||
// Key used when adding compositing tiles to the occlusion tracker.
|
||||
// Since an entire tile may have a mask, but we may segment that in
|
||||
// to masked and non-masked regions, we need to track which of the
|
||||
// occlusion tracker outputs need a mask
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
struct OcclusionItemKey {
|
||||
tile_index: usize,
|
||||
needs_mask: bool,
|
||||
}
|
||||
|
||||
// Defines the content that we will draw to a given swapchain / layer, calculated
|
||||
// after occlusion culling.
|
||||
struct SwapChainLayer {
|
||||
occlusion: occlusion::FrontToBackBuilder<usize>,
|
||||
clear_tiles: Vec<occlusion::Item<usize>>,
|
||||
occlusion: occlusion::FrontToBackBuilder<OcclusionItemKey>,
|
||||
clear_tiles: Vec<occlusion::Item<OcclusionItemKey>>,
|
||||
}
|
||||
|
||||
/// The clear color used for the texture cache when the debug display is enabled.
|
||||
@@ -3068,21 +3079,6 @@ impl Renderer {
|
||||
ResolvedExternalSurfaceColorData::Yuv{
|
||||
ref planes, color_space, format, channel_bit_depth, .. } => {
|
||||
|
||||
// Bind an appropriate YUV shader for the texture format kind
|
||||
self.shaders
|
||||
.borrow_mut()
|
||||
.get_composite_shader(
|
||||
CompositeSurfaceFormat::Yuv,
|
||||
surface.image_buffer_kind,
|
||||
CompositeFeatures::empty(),
|
||||
).bind(
|
||||
&mut self.device,
|
||||
&projection,
|
||||
None,
|
||||
&mut self.renderer_errors,
|
||||
&mut self.profile,
|
||||
);
|
||||
|
||||
let textures = BatchTextures::composite_yuv(
|
||||
planes[0].texture,
|
||||
planes[1].texture,
|
||||
@@ -3110,17 +3106,16 @@ impl Renderer {
|
||||
channel_bit_depth,
|
||||
uv_rects,
|
||||
(false, false),
|
||||
None,
|
||||
);
|
||||
|
||||
( textures, instance )
|
||||
},
|
||||
ResolvedExternalSurfaceColorData::Rgb{ ref plane, .. } => {
|
||||
// Bind an appropriate YUV shader for the texture format kind
|
||||
self.shaders
|
||||
.borrow_mut()
|
||||
.get_composite_shader(
|
||||
CompositeSurfaceFormat::Rgba,
|
||||
CompositeSurfaceFormat::Yuv,
|
||||
surface.image_buffer_kind,
|
||||
CompositeFeatures::empty(),
|
||||
instance.get_yuv_features(),
|
||||
).bind(
|
||||
&mut self.device,
|
||||
&projection,
|
||||
@@ -3128,7 +3123,10 @@ impl Renderer {
|
||||
&mut self.renderer_errors,
|
||||
&mut self.profile,
|
||||
);
|
||||
|
||||
|
||||
( textures, instance )
|
||||
},
|
||||
ResolvedExternalSurfaceColorData::Rgb{ ref plane, .. } => {
|
||||
let textures = BatchTextures::composite_rgb(plane.texture);
|
||||
let uv_rect = self.texture_resolver.get_uv_rect(&textures.input.colors[0], plane.uv_rect);
|
||||
let instance = CompositeInstance::new_rgb(
|
||||
@@ -3138,7 +3136,23 @@ impl Renderer {
|
||||
uv_rect,
|
||||
plane.texture.uses_normalized_uvs(),
|
||||
(false, false),
|
||||
None,
|
||||
);
|
||||
let features = instance.get_rgb_features();
|
||||
|
||||
self.shaders
|
||||
.borrow_mut()
|
||||
.get_composite_shader(
|
||||
CompositeSurfaceFormat::Rgba,
|
||||
surface.image_buffer_kind,
|
||||
features,
|
||||
).bind(
|
||||
&mut self.device,
|
||||
&projection,
|
||||
None,
|
||||
&mut self.renderer_errors,
|
||||
&mut self.profile,
|
||||
);
|
||||
|
||||
( textures, instance )
|
||||
},
|
||||
@@ -3161,7 +3175,7 @@ impl Renderer {
|
||||
}
|
||||
|
||||
/// Draw a list of tiles to the framebuffer
|
||||
fn draw_tile_list<'a, I: Iterator<Item = &'a occlusion::Item<usize>>>(
|
||||
fn draw_tile_list<'a, I: Iterator<Item = &'a occlusion::Item<OcclusionItemKey>>>(
|
||||
&mut self,
|
||||
tiles_iter: I,
|
||||
composite_state: &CompositeState,
|
||||
@@ -3193,13 +3207,21 @@ impl Renderer {
|
||||
);
|
||||
|
||||
for item in tiles_iter {
|
||||
let tile = &composite_state.tiles[item.key];
|
||||
let tile = &composite_state.tiles[item.key.tile_index];
|
||||
|
||||
let clip_rect = item.rectangle;
|
||||
let tile_rect = composite_state.get_device_rect(&tile.local_rect, tile.transform_index);
|
||||
let transform = composite_state.get_device_transform(tile.transform_index);
|
||||
let flip = (transform.scale.x < 0.0, transform.scale.y < 0.0);
|
||||
|
||||
let clip = if item.key.needs_mask {
|
||||
tile.clip_index.map(|index| {
|
||||
composite_state.get_compositor_clip(index)
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
// Work out the draw params based on the tile surface
|
||||
let (instance, textures, shader_params) = match tile.surface {
|
||||
CompositeTileSurface::Color { color } => {
|
||||
@@ -3210,6 +3232,7 @@ impl Renderer {
|
||||
clip_rect,
|
||||
color.premultiplied(),
|
||||
flip,
|
||||
clip,
|
||||
);
|
||||
let features = instance.get_rgb_features();
|
||||
(
|
||||
@@ -3224,6 +3247,7 @@ impl Renderer {
|
||||
clip_rect,
|
||||
PremultipliedColorF::WHITE,
|
||||
flip,
|
||||
clip,
|
||||
);
|
||||
let features = instance.get_rgb_features();
|
||||
(
|
||||
@@ -3259,21 +3283,25 @@ impl Renderer {
|
||||
self.texture_resolver.get_uv_rect(&textures.input.colors[2], planes[2].uv_rect),
|
||||
];
|
||||
|
||||
let instance = CompositeInstance::new_yuv(
|
||||
tile_rect,
|
||||
clip_rect,
|
||||
color_space,
|
||||
format,
|
||||
channel_bit_depth,
|
||||
uv_rects,
|
||||
flip,
|
||||
clip,
|
||||
);
|
||||
let features = instance.get_yuv_features();
|
||||
|
||||
(
|
||||
CompositeInstance::new_yuv(
|
||||
tile_rect,
|
||||
clip_rect,
|
||||
color_space,
|
||||
format,
|
||||
channel_bit_depth,
|
||||
uv_rects,
|
||||
flip,
|
||||
),
|
||||
instance,
|
||||
textures,
|
||||
(
|
||||
CompositeSurfaceFormat::Yuv,
|
||||
surface.image_buffer_kind,
|
||||
CompositeFeatures::empty(),
|
||||
features,
|
||||
None
|
||||
),
|
||||
)
|
||||
@@ -3287,6 +3315,7 @@ impl Renderer {
|
||||
uv_rect,
|
||||
plane.texture.uses_normalized_uvs(),
|
||||
flip,
|
||||
clip,
|
||||
);
|
||||
let features = instance.get_rgb_features();
|
||||
(
|
||||
@@ -3310,6 +3339,7 @@ impl Renderer {
|
||||
clip_rect,
|
||||
PremultipliedColorF::BLACK,
|
||||
flip,
|
||||
clip,
|
||||
);
|
||||
let features = instance.get_rgb_features();
|
||||
(
|
||||
@@ -3503,6 +3533,7 @@ impl Renderer {
|
||||
let mut input_layers: Vec<CompositorInputLayer> = Vec::new();
|
||||
let mut swapchain_layers = Vec::new();
|
||||
let cap = composite_state.tiles.len();
|
||||
let mut segment_builder = SegmentBuilder::new();
|
||||
|
||||
// NOTE: Tiles here are being iterated in front-to-back order by
|
||||
// z-id, due to the sort in composite_state.end_frame()
|
||||
@@ -3646,20 +3677,48 @@ impl Renderer {
|
||||
|
||||
// Clear tiles overwrite whatever is under them, so they are treated as opaque.
|
||||
match tile.kind {
|
||||
TileKind::Opaque => {
|
||||
// Store (index of tile, index of layer) so we can segment them below
|
||||
layer.occlusion.add(&rect, true, idx);
|
||||
}
|
||||
TileKind::Alpha => {
|
||||
// Store (index of tile, index of layer) so we can segment them below
|
||||
layer.occlusion.add(&rect, false, idx);
|
||||
TileKind::Opaque | TileKind::Alpha => {
|
||||
let is_opaque = tile.kind != TileKind::Alpha;
|
||||
|
||||
match tile.clip_index {
|
||||
Some(clip_index) => {
|
||||
let clip = composite_state.get_compositor_clip(clip_index);
|
||||
|
||||
// TODO(gw): Make segment builder generic on unit to avoid casts below.
|
||||
segment_builder.initialize(
|
||||
rect.cast_unit(),
|
||||
None,
|
||||
rect.cast_unit(),
|
||||
);
|
||||
segment_builder.push_clip_rect(
|
||||
clip.rect.cast_unit(),
|
||||
Some(clip.radius),
|
||||
ClipMode::Clip,
|
||||
);
|
||||
segment_builder.build(|segment| {
|
||||
let key = OcclusionItemKey { tile_index: idx, needs_mask: segment.has_mask };
|
||||
|
||||
layer. occlusion.add(
|
||||
&segment.rect.cast_unit(),
|
||||
is_opaque && !segment.has_mask,
|
||||
key,
|
||||
);
|
||||
});
|
||||
}
|
||||
None => {
|
||||
layer.occlusion.add(&rect, is_opaque, OcclusionItemKey {
|
||||
tile_index: idx,
|
||||
needs_mask: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
TileKind::Clear => {
|
||||
// Clear tiles are specific to how we render the window buttons on
|
||||
// Windows 8. They clobber what's under them so they can be treated as opaque,
|
||||
// but require a different blend state so they will be rendered after the opaque
|
||||
// tiles and before transparent ones.
|
||||
layer.clear_tiles.push(occlusion::Item { rectangle: rect, key: idx });
|
||||
layer.clear_tiles.push(occlusion::Item { rectangle: rect, key: OcclusionItemKey { tile_index: idx, needs_mask: false } });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1382,7 +1382,8 @@ pub struct CompositorShaders {
|
||||
// or color modulation.
|
||||
rgba_fast_path: Vec<Option<LazilyCompiledShader>>,
|
||||
// The same set of composite shaders but with WR_FEATURE_YUV added.
|
||||
yuv: Vec<Option<LazilyCompiledShader>>,
|
||||
yuv_clip: Vec<Option<LazilyCompiledShader>>,
|
||||
yuv_fast: Vec<Option<LazilyCompiledShader>>,
|
||||
}
|
||||
|
||||
impl CompositorShaders {
|
||||
@@ -1395,12 +1396,14 @@ impl CompositorShaders {
|
||||
// so use a dummy one.
|
||||
let mut profile = TransactionProfile::new();
|
||||
|
||||
let mut yuv_features = Vec::new();
|
||||
let mut yuv_clip_features = Vec::new();
|
||||
let mut yuv_fast_features = Vec::new();
|
||||
let mut rgba_features = Vec::new();
|
||||
let mut fast_path_features = Vec::new();
|
||||
let mut rgba = Vec::new();
|
||||
let mut rgba_fast_path = Vec::new();
|
||||
let mut yuv = Vec::new();
|
||||
let mut yuv_clip = Vec::new();
|
||||
let mut yuv_fast = Vec::new();
|
||||
|
||||
let texture_external_version = if device.get_capabilities().supports_image_external_essl3 {
|
||||
TextureExternalVersion::ESSL3
|
||||
@@ -1412,7 +1415,8 @@ impl CompositorShaders {
|
||||
let shader_list = get_shader_features(feature_flags);
|
||||
|
||||
for _ in 0..IMAGE_BUFFER_KINDS.len() {
|
||||
yuv.push(None);
|
||||
yuv_clip.push(None);
|
||||
yuv_fast.push(None);
|
||||
rgba.push(None);
|
||||
rgba_fast_path.push(None);
|
||||
}
|
||||
@@ -1422,7 +1426,9 @@ impl CompositorShaders {
|
||||
continue;
|
||||
}
|
||||
|
||||
yuv_features.push("YUV");
|
||||
yuv_clip_features.push("YUV");
|
||||
yuv_fast_features.push("YUV");
|
||||
yuv_fast_features.push("FAST_PATH");
|
||||
fast_path_features.push("FAST_PATH");
|
||||
|
||||
let index = Self::get_shader_index(*image_buffer_kind);
|
||||
@@ -1432,7 +1438,8 @@ impl CompositorShaders {
|
||||
texture_external_version,
|
||||
);
|
||||
if feature_string != "" {
|
||||
yuv_features.push(feature_string);
|
||||
yuv_clip_features.push(feature_string);
|
||||
yuv_fast_features.push(feature_string);
|
||||
rgba_features.push(feature_string);
|
||||
fast_path_features.push(feature_string);
|
||||
}
|
||||
@@ -1441,10 +1448,20 @@ impl CompositorShaders {
|
||||
if *image_buffer_kind != ImageBufferKind::TextureExternal ||
|
||||
texture_external_version == TextureExternalVersion::ESSL3 {
|
||||
|
||||
yuv[index] = Some(LazilyCompiledShader::new(
|
||||
yuv_clip[index] = Some(LazilyCompiledShader::new(
|
||||
ShaderKind::Composite,
|
||||
"composite",
|
||||
&yuv_features,
|
||||
&yuv_clip_features,
|
||||
device,
|
||||
precache_flags,
|
||||
&shader_list,
|
||||
&mut profile,
|
||||
)?);
|
||||
|
||||
yuv_fast[index] = Some(LazilyCompiledShader::new(
|
||||
ShaderKind::Composite,
|
||||
"composite",
|
||||
&yuv_fast_features,
|
||||
device,
|
||||
precache_flags,
|
||||
&shader_list,
|
||||
@@ -1472,7 +1489,8 @@ impl CompositorShaders {
|
||||
&mut profile,
|
||||
)?);
|
||||
|
||||
yuv_features.clear();
|
||||
yuv_fast_features.clear();
|
||||
yuv_clip_features.clear();
|
||||
rgba_features.clear();
|
||||
fast_path_features.clear();
|
||||
}
|
||||
@@ -1480,7 +1498,8 @@ impl CompositorShaders {
|
||||
Ok(CompositorShaders {
|
||||
rgba,
|
||||
rgba_fast_path,
|
||||
yuv,
|
||||
yuv_clip,
|
||||
yuv_fast,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1494,6 +1513,7 @@ impl CompositorShaders {
|
||||
CompositeSurfaceFormat::Rgba => {
|
||||
if features.contains(CompositeFeatures::NO_UV_CLAMP)
|
||||
&& features.contains(CompositeFeatures::NO_COLOR_MODULATION)
|
||||
&& features.contains(CompositeFeatures::NO_CLIP_MASK)
|
||||
{
|
||||
let shader_index = Self::get_shader_index(buffer_kind);
|
||||
self.rgba_fast_path[shader_index]
|
||||
@@ -1508,9 +1528,15 @@ impl CompositorShaders {
|
||||
}
|
||||
CompositeSurfaceFormat::Yuv => {
|
||||
let shader_index = Self::get_shader_index(buffer_kind);
|
||||
self.yuv[shader_index]
|
||||
.as_mut()
|
||||
.expect("bug: unsupported yuv shader requested")
|
||||
if features.contains(CompositeFeatures::NO_CLIP_MASK) {
|
||||
self.yuv_fast[shader_index]
|
||||
.as_mut()
|
||||
.expect("bug: unsupported yuv shader requested")
|
||||
} else {
|
||||
self.yuv_clip[shader_index]
|
||||
.as_mut()
|
||||
.expect("bug: unsupported yuv shader requested")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1530,7 +1556,12 @@ impl CompositorShaders {
|
||||
shader.deinit(device);
|
||||
}
|
||||
}
|
||||
for shader in self.yuv.drain(..) {
|
||||
for shader in self.yuv_clip.drain(..) {
|
||||
if let Some(shader) = shader {
|
||||
shader.deinit(device);
|
||||
}
|
||||
}
|
||||
for shader in self.yuv_fast.drain(..) {
|
||||
if let Some(shader) = shader {
|
||||
shader.deinit(device);
|
||||
}
|
||||
|
||||
@@ -776,6 +776,16 @@ pub mod desc {
|
||||
count: 2,
|
||||
kind: VertexAttributeKind::F32,
|
||||
},
|
||||
VertexAttribute {
|
||||
name: "aDeviceRoundedClipRect",
|
||||
count: 4,
|
||||
kind: VertexAttributeKind::F32,
|
||||
},
|
||||
VertexAttribute {
|
||||
name: "aDeviceRoundedClipRadii",
|
||||
count: 4,
|
||||
kind: VertexAttributeKind::F32,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use api::{ColorF, DebugFlags, PrimitiveFlags, QualitySettings, RasterSpace, ClipId};
|
||||
use api::{BorderRadius, ClipId, ClipMode, ColorF, DebugFlags, PrimitiveFlags, QualitySettings, RasterSpace};
|
||||
use api::units::*;
|
||||
use crate::clip::{ClipItemKeyKind, ClipNodeId, ClipTreeBuilder};
|
||||
use crate::frame_builder::FrameBuilderConfig;
|
||||
@@ -561,19 +561,26 @@ fn create_tile_cache(
|
||||
|
||||
let node_valid = if is_rcs {
|
||||
match clip_node_data.key.kind {
|
||||
ClipItemKeyKind::BoxShadow(..) | ClipItemKeyKind::ImageMask(..) => {
|
||||
ClipItemKeyKind::BoxShadow(..) |
|
||||
ClipItemKeyKind::ImageMask(..) |
|
||||
ClipItemKeyKind::Rectangle(_, ClipMode::ClipOut) |
|
||||
ClipItemKeyKind::RoundedRectangle(_, _, ClipMode::ClipOut) => {
|
||||
// Has a box-shadow / image-mask, we can't handle this as a shared clip
|
||||
false
|
||||
}
|
||||
ClipItemKeyKind::RoundedRectangle(..) => {
|
||||
rounded_rect_count += 1;
|
||||
ClipItemKeyKind::RoundedRectangle(rect, radius, ClipMode::Clip) => {
|
||||
// The shader and CoreAnimation rely on certain constraints such
|
||||
// as uniform radii to be able to apply the clip during compositing.
|
||||
if BorderRadius::from(radius).can_use_fast_path_in(&rect.into()) {
|
||||
rounded_rect_count += 1;
|
||||
|
||||
// TODO(gw): This initial patch retains existing behavior by not
|
||||
// allowing a rounded-rect clip to be part of the shared
|
||||
// clip. Follow up patch in this series will relax this.
|
||||
false
|
||||
// TODO(gw): Enable this once also supported by native and swgl compositors
|
||||
false
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
ClipItemKeyKind::Rectangle(..) => {
|
||||
ClipItemKeyKind::Rectangle(_, ClipMode::Clip) => {
|
||||
// We can apply multiple (via combining) axis-aligned rectangle
|
||||
// clips to the shared compositing clip.
|
||||
true
|
||||
|
||||
@@ -209,6 +209,14 @@ pub fn get_shader_features(flags: ShaderFeatureFlags) -> ShaderFeatures {
|
||||
}
|
||||
list.add("FAST_PATH");
|
||||
composite_features.push(list.finish());
|
||||
|
||||
// YUV shaders are not compatible with ESSL1
|
||||
if *texture_type == "TEXTURE_EXTERNAL_ESSL1" {
|
||||
continue;
|
||||
}
|
||||
|
||||
list.add("YUV");
|
||||
composite_features.push(list.finish());
|
||||
}
|
||||
shaders.insert("composite", composite_features);
|
||||
|
||||
|
||||
BIN
gfx/wr/wrench/reftests/compositor/barn-u.png
Normal file
BIN
gfx/wr/wrench/reftests/compositor/barn-u.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
BIN
gfx/wr/wrench/reftests/compositor/barn-v.png
Normal file
BIN
gfx/wr/wrench/reftests/compositor/barn-v.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
BIN
gfx/wr/wrench/reftests/compositor/barn-y.png
Normal file
BIN
gfx/wr/wrench/reftests/compositor/barn-y.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 91 KiB |
7
gfx/wr/wrench/reftests/compositor/reftest.list
Normal file
7
gfx/wr/wrench/reftests/compositor/reftest.list
Normal file
@@ -0,0 +1,7 @@
|
||||
color_targets(3) == rounded-corners-1.yaml rounded-corners-1-ref.yaml
|
||||
# color_targets(2) == rounded-corners-2.yaml rounded-corners-2-ref.yaml
|
||||
== rounded-corners-3.yaml rounded-corners-3-ref.yaml
|
||||
== rounded-corners-4.yaml rounded-corners-4-ref.yaml
|
||||
# fuzzy(2,106) == rounded-yuv-surface.yaml rounded-yuv-surface-ref.yaml
|
||||
== rounded-rgb-surface.yaml rounded-rgb-surface-ref.yaml
|
||||
== tile-occlusion.yaml tile-occlusion-ref.yaml
|
||||
13
gfx/wr/wrench/reftests/compositor/rounded-corners-1-ref.yaml
Normal file
13
gfx/wr/wrench/reftests/compositor/rounded-corners-1-ref.yaml
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
root:
|
||||
items:
|
||||
- type: clip
|
||||
id: 2
|
||||
complex:
|
||||
- rect: [50, 50, 200, 200]
|
||||
radius: 32
|
||||
|
||||
- type: rect
|
||||
bounds: 50 50 200 200
|
||||
color: red
|
||||
clip-chain: [2]
|
||||
25
gfx/wr/wrench/reftests/compositor/rounded-corners-1.yaml
Normal file
25
gfx/wr/wrench/reftests/compositor/rounded-corners-1.yaml
Normal file
@@ -0,0 +1,25 @@
|
||||
# Since there is no clip-chain shared between the two prims, the rounded
|
||||
# clip will be applied to the primitive, causing allocation of a mask surface.
|
||||
# The second prim is clipped out to make it match the reference.
|
||||
---
|
||||
root:
|
||||
items:
|
||||
- type: clip
|
||||
id: 2
|
||||
complex:
|
||||
- rect: [50, 50, 200, 200]
|
||||
radius: 32
|
||||
|
||||
- type: clip
|
||||
id: 3
|
||||
bounds: [300, 50, 0, 0]
|
||||
|
||||
- type: rect
|
||||
bounds: 50 50 200 200
|
||||
color: red
|
||||
clip-chain: [2]
|
||||
|
||||
- type: rect
|
||||
bounds: 300 50 200 200
|
||||
color: red
|
||||
clip-chain: [3]
|
||||
13
gfx/wr/wrench/reftests/compositor/rounded-corners-2-ref.yaml
Normal file
13
gfx/wr/wrench/reftests/compositor/rounded-corners-2-ref.yaml
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
root:
|
||||
items:
|
||||
- type: clip
|
||||
id: 2
|
||||
complex:
|
||||
- rect: [50, 50, 200, 200]
|
||||
radius: 32
|
||||
|
||||
- type: rect
|
||||
bounds: 50 50 200 200
|
||||
color: red
|
||||
clip-chain: [2]
|
||||
21
gfx/wr/wrench/reftests/compositor/rounded-corners-2.yaml
Normal file
21
gfx/wr/wrench/reftests/compositor/rounded-corners-2.yaml
Normal file
@@ -0,0 +1,21 @@
|
||||
# Since the clip-chain is shared between the two prims, the rounded
|
||||
# clip will be applied to the tile cache, so no mask surface will be allocated.
|
||||
# The second prim is clipped out to make it match the reference.
|
||||
---
|
||||
root:
|
||||
items:
|
||||
- type: clip
|
||||
id: 2
|
||||
complex:
|
||||
- rect: [50, 50, 200, 200]
|
||||
radius: 32
|
||||
|
||||
- type: rect
|
||||
bounds: 50 50 200 200
|
||||
color: red
|
||||
clip-chain: [2]
|
||||
|
||||
- type: rect
|
||||
bounds: 300 50 200 200
|
||||
color: red
|
||||
clip-chain: [2]
|
||||
22
gfx/wr/wrench/reftests/compositor/rounded-corners-3-ref.yaml
Normal file
22
gfx/wr/wrench/reftests/compositor/rounded-corners-3-ref.yaml
Normal file
@@ -0,0 +1,22 @@
|
||||
---
|
||||
root:
|
||||
items:
|
||||
- type: clip
|
||||
id: 2
|
||||
complex:
|
||||
- rect: [50, 50, 200, 200]
|
||||
radius: [25, 50, 100, 75]
|
||||
|
||||
- type: clip
|
||||
id: 3
|
||||
bounds: [300, 50, 0, 0]
|
||||
|
||||
- type: rect
|
||||
bounds: 50 50 200 200
|
||||
color: red
|
||||
clip-chain: [2]
|
||||
|
||||
- type: rect
|
||||
bounds: 300 50 200 200
|
||||
color: red
|
||||
clip-chain: [3]
|
||||
24
gfx/wr/wrench/reftests/compositor/rounded-corners-3.yaml
Normal file
24
gfx/wr/wrench/reftests/compositor/rounded-corners-3.yaml
Normal file
@@ -0,0 +1,24 @@
|
||||
# When the clip chains are shared and handled when compositing the picture cache
|
||||
# slice, ensure that the border radii are passed in the correct order to the shader.
|
||||
---
|
||||
root:
|
||||
items:
|
||||
- type: clip
|
||||
id: 2
|
||||
complex:
|
||||
- rect: [50, 50, 200, 200]
|
||||
radius: [25, 50, 100, 75]
|
||||
|
||||
- type: clip
|
||||
id: 3
|
||||
bounds: [300, 50, 0, 0]
|
||||
|
||||
- type: rect
|
||||
bounds: 50 50 200 200
|
||||
color: red
|
||||
clip-chain: [2]
|
||||
|
||||
- type: rect
|
||||
bounds: 300 50 200 200
|
||||
color: red
|
||||
clip-chain: [2]
|
||||
25
gfx/wr/wrench/reftests/compositor/rounded-corners-4-ref.yaml
Normal file
25
gfx/wr/wrench/reftests/compositor/rounded-corners-4-ref.yaml
Normal file
@@ -0,0 +1,25 @@
|
||||
---
|
||||
root:
|
||||
items:
|
||||
- type: stacking-context
|
||||
transform: scale(0.5)
|
||||
items:
|
||||
- type: clip
|
||||
id: 2
|
||||
complex:
|
||||
- rect: [50, 50, 200, 200]
|
||||
radius: 100
|
||||
|
||||
- type: clip
|
||||
id: 3
|
||||
bounds: [300, 50, 0, 0]
|
||||
|
||||
- type: rect
|
||||
bounds: 50 50 200 200
|
||||
color: red
|
||||
clip-chain: [2]
|
||||
|
||||
- type: rect
|
||||
bounds: 300 50 200 200
|
||||
color: red
|
||||
clip-chain: [3]
|
||||
27
gfx/wr/wrench/reftests/compositor/rounded-corners-4.yaml
Normal file
27
gfx/wr/wrench/reftests/compositor/rounded-corners-4.yaml
Normal file
@@ -0,0 +1,27 @@
|
||||
# Ensure that shared (compositor applied) clip correctly handles transform from
|
||||
# (axis-aligned) local coordinate system to device coordinate system
|
||||
---
|
||||
root:
|
||||
items:
|
||||
- type: stacking-context
|
||||
transform: scale(0.5)
|
||||
items:
|
||||
- type: clip
|
||||
id: 2
|
||||
complex:
|
||||
- rect: [50, 50, 200, 200]
|
||||
radius: 100
|
||||
|
||||
- type: clip
|
||||
id: 3
|
||||
bounds: [300, 50, 0, 0]
|
||||
|
||||
- type: rect
|
||||
bounds: 50 50 200 200
|
||||
color: red
|
||||
clip-chain: [2]
|
||||
|
||||
- type: rect
|
||||
bounds: 300 50 200 200
|
||||
color: red
|
||||
clip-chain: [2]
|
||||
@@ -0,0 +1,12 @@
|
||||
---
|
||||
root:
|
||||
items:
|
||||
- type: clip
|
||||
id: 2
|
||||
complex:
|
||||
- rect: [100, 100, 200, 200]
|
||||
radius: 32
|
||||
|
||||
- bounds: [100, 100, 200, 200]
|
||||
image: checkerboard(4, 16, 12)
|
||||
clip-chain: [2]
|
||||
15
gfx/wr/wrench/reftests/compositor/rounded-rgb-surface.yaml
Normal file
15
gfx/wr/wrench/reftests/compositor/rounded-rgb-surface.yaml
Normal file
@@ -0,0 +1,15 @@
|
||||
# Ensure that a RGB compositor surface is correctly clipped when
|
||||
# compositing with a shared rounded clip on the tile cache.
|
||||
---
|
||||
root:
|
||||
items:
|
||||
- type: clip
|
||||
id: 2
|
||||
complex:
|
||||
- rect: [100, 100, 200, 200]
|
||||
radius: 32
|
||||
|
||||
- bounds: [100, 100, 200, 200]
|
||||
image: checkerboard(4, 16, 12)
|
||||
clip-chain: [2]
|
||||
prefer-compositor-surface: true
|
||||
@@ -0,0 +1,16 @@
|
||||
---
|
||||
root:
|
||||
items:
|
||||
- type: clip
|
||||
id: 2
|
||||
complex:
|
||||
- rect: [100, 100, 299, 299]
|
||||
radius: 32
|
||||
|
||||
- type: yuv-image
|
||||
format: planar
|
||||
src-y: barn-y.png
|
||||
src-u: barn-u.png
|
||||
src-v: barn-v.png
|
||||
bounds: [100, 100, 299, 299]
|
||||
clip-chain: [2]
|
||||
19
gfx/wr/wrench/reftests/compositor/rounded-yuv-surface.yaml
Normal file
19
gfx/wr/wrench/reftests/compositor/rounded-yuv-surface.yaml
Normal file
@@ -0,0 +1,19 @@
|
||||
# Ensure that a YUV compositor surface is correctly clipped when
|
||||
# compositing with a shared rounded clip on the tile cache.
|
||||
---
|
||||
root:
|
||||
items:
|
||||
- type: clip
|
||||
id: 2
|
||||
complex:
|
||||
- rect: [100, 100, 299, 299]
|
||||
radius: 32
|
||||
|
||||
- type: yuv-image
|
||||
format: planar
|
||||
src-y: barn-y.png
|
||||
src-u: barn-u.png
|
||||
src-v: barn-v.png
|
||||
bounds: [100, 100, 299, 299]
|
||||
clip-chain: [2]
|
||||
prefer-compositor-surface: true
|
||||
17
gfx/wr/wrench/reftests/compositor/tile-occlusion-ref.yaml
Normal file
17
gfx/wr/wrench/reftests/compositor/tile-occlusion-ref.yaml
Normal file
@@ -0,0 +1,17 @@
|
||||
---
|
||||
root:
|
||||
items:
|
||||
- type: clip
|
||||
id: 2
|
||||
complex:
|
||||
- rect: [100, 100, 200, 200]
|
||||
radius: 64
|
||||
|
||||
- type: rect
|
||||
bounds: [100, 100, 200, 200]
|
||||
color: green
|
||||
|
||||
- type: rect
|
||||
bounds: [100, 100, 200, 200]
|
||||
color: red
|
||||
clip-chain: [2]
|
||||
25
gfx/wr/wrench/reftests/compositor/tile-occlusion.yaml
Normal file
25
gfx/wr/wrench/reftests/compositor/tile-occlusion.yaml
Normal file
@@ -0,0 +1,25 @@
|
||||
# Ensure that a compositor surface with a rounded clip applied
|
||||
# doesn't incorrectly occlude tile(s) behind it.
|
||||
---
|
||||
root:
|
||||
items:
|
||||
- type: clip
|
||||
id: 2
|
||||
complex:
|
||||
- rect: [100, 100, 200, 200]
|
||||
radius: 64
|
||||
|
||||
- type: rect
|
||||
bounds: [100, 100, 200, 200]
|
||||
color: green
|
||||
|
||||
-
|
||||
type: "scroll-frame"
|
||||
id: 3
|
||||
bounds: [0, 0, 300, 300]
|
||||
|
||||
- type: rect
|
||||
spatial-id: 3
|
||||
bounds: [100, 100, 200, 200]
|
||||
color: red
|
||||
clip-chain: [2]
|
||||
@@ -4,6 +4,7 @@ include blend/reftest.list
|
||||
include border/reftest.list
|
||||
include boxshadow/reftest.list
|
||||
include clip/reftest.list
|
||||
include compositor/reftest.list
|
||||
include compositor-surface/reftest.list
|
||||
include crash/reftest.list
|
||||
include filters/reftest.list
|
||||
|
||||
Reference in New Issue
Block a user