Backed out 2 changesets (bug 1898621) as requested by tnikkel for causing bug 1901370. CLOSED TREE

Backed out changeset c7f221a9e1db (bug 1898621)
Backed out changeset 032081e46073 (bug 1898621)
This commit is contained in:
Tamas Szentpeteri 2024-06-09 02:42:42 +03:00
parent 910eb17c6e
commit 51f395e7d2
8 changed files with 166 additions and 256 deletions

View file

@ -574,8 +574,6 @@ static void WebRenderDebugPrefChangeCallback(const char* aPrefName, void*) {
GFX_WEBRENDER_DEBUG(".window-visibility", GFX_WEBRENDER_DEBUG(".window-visibility",
wr::DebugFlags::WINDOW_VISIBILITY_DBG) wr::DebugFlags::WINDOW_VISIBILITY_DBG)
GFX_WEBRENDER_DEBUG(".restrict-blob-size", wr::DebugFlags::RESTRICT_BLOB_SIZE) GFX_WEBRENDER_DEBUG(".restrict-blob-size", wr::DebugFlags::RESTRICT_BLOB_SIZE)
GFX_WEBRENDER_DEBUG(".surface-promotion-logging",
wr::DebugFlags::SURFACE_PROMOTION_LOGGING)
#undef GFX_WEBRENDER_DEBUG #undef GFX_WEBRENDER_DEBUG
gfx::gfxVars::SetWebRenderDebugFlags(flags._0); gfx::gfxVars::SetWebRenderDebugFlags(flags._0);
} }

View file

@ -134,7 +134,6 @@ use crate::spatial_tree::CoordinateSystemId;
use crate::surface::{SurfaceDescriptor, SurfaceTileDescriptor}; use crate::surface::{SurfaceDescriptor, SurfaceTileDescriptor};
use smallvec::SmallVec; use smallvec::SmallVec;
use std::{mem, u8, marker, u32}; use std::{mem, u8, marker, u32};
use std::fmt::{Display, Error, Formatter};
use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::atomic::{AtomicUsize, Ordering};
use std::collections::hash_map::Entry; use std::collections::hash_map::Entry;
use std::ops::Range; use std::ops::Range;
@ -1620,8 +1619,6 @@ impl SliceId {
/// Information that is required to reuse or create a new tile cache. Created /// Information that is required to reuse or create a new tile cache. Created
/// during scene building and passed to the render backend / frame builder. /// during scene building and passed to the render backend / frame builder.
pub struct TileCacheParams { pub struct TileCacheParams {
// The current debug flags for the system.
pub debug_flags: DebugFlags,
// Index of the slice (also effectively the key of the tile cache, though we use SliceId where that matters) // Index of the slice (also effectively the key of the tile cache, though we use SliceId where that matters)
pub slice: usize, pub slice: usize,
// Flags describing content of this cache (e.g. scrollbars) // Flags describing content of this cache (e.g. scrollbars)
@ -1758,8 +1755,6 @@ pub struct BackdropSurface {
/// Represents a cache of tiles that make up a picture primitives. /// Represents a cache of tiles that make up a picture primitives.
pub struct TileCacheInstance { pub struct TileCacheInstance {
// The current debug flags for the system.
pub debug_flags: DebugFlags,
/// Index of the tile cache / slice for this frame builder. It's determined /// Index of the tile cache / slice for this frame builder. It's determined
/// by the setup_picture_caching method during flattening, which splits the /// by the setup_picture_caching method during flattening, which splits the
/// picture tree into multiple slices. It's used as a simple input to the tile /// picture tree into multiple slices. It's used as a simple input to the tile
@ -1868,41 +1863,9 @@ pub struct TileCacheInstance {
pub yuv_images_remaining: usize, pub yuv_images_remaining: usize,
} }
#[derive(Clone, Copy)] enum SurfacePromotionResult {
enum SurfacePromotionFailure { Failed,
ImageWaitingOnYuvImage, Success,
NotPremultipliedAlpha,
OverlaySurfaceLimit,
OverlayNeedsMask,
UnderlayAlphaBackdrop,
UnderlaySurfaceLimit,
UnderlayIntersectsOverlay,
NotRootTileCache,
ComplexTransform,
SliceAtomic,
SizeTooLarge,
}
impl Display for SurfacePromotionFailure {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
write!(
f,
"{}",
match *self {
SurfacePromotionFailure::ImageWaitingOnYuvImage => "Image prim waiting for all YuvImage prims to be considered for promotion",
SurfacePromotionFailure::NotPremultipliedAlpha => "does not use premultiplied alpha",
SurfacePromotionFailure::OverlaySurfaceLimit => "hit the overlay surface limit",
SurfacePromotionFailure::OverlayNeedsMask => "overlay not allowed for prim with mask",
SurfacePromotionFailure::UnderlayAlphaBackdrop => "underlay requires an opaque backdrop",
SurfacePromotionFailure::UnderlaySurfaceLimit => "hit the underlay surface limit",
SurfacePromotionFailure::UnderlayIntersectsOverlay => "underlay intersects already-promoted overlay",
SurfacePromotionFailure::NotRootTileCache => "is not on a root tile cache",
SurfacePromotionFailure::ComplexTransform => "has a complex transform",
SurfacePromotionFailure::SliceAtomic => "slice is atomic",
SurfacePromotionFailure::SizeTooLarge => "surface is too large for compositor",
}.to_owned()
)
}
} }
impl TileCacheInstance { impl TileCacheInstance {
@ -1917,7 +1880,6 @@ impl TileCacheInstance {
} }
TileCacheInstance { TileCacheInstance {
debug_flags: params.debug_flags,
slice: params.slice, slice: params.slice,
slice_flags: params.slice_flags, slice_flags: params.slice_flags,
spatial_node_index: params.spatial_node_index, spatial_node_index: params.spatial_node_index,
@ -2511,6 +2473,7 @@ impl TileCacheInstance {
fn can_promote_to_surface( fn can_promote_to_surface(
&mut self, &mut self,
flags: PrimitiveFlags,
prim_clip_chain: &ClipChainInstance, prim_clip_chain: &ClipChainInstance,
prim_spatial_node_index: SpatialNodeIndex, prim_spatial_node_index: SpatialNodeIndex,
is_root_tile_cache: bool, is_root_tile_cache: bool,
@ -2518,8 +2481,11 @@ impl TileCacheInstance {
surface_kind: CompositorSurfaceKind, surface_kind: CompositorSurfaceKind,
pic_coverage_rect: PictureRect, pic_coverage_rect: PictureRect,
frame_context: &FrameVisibilityContext, frame_context: &FrameVisibilityContext,
) -> Result<CompositorSurfaceKind, SurfacePromotionFailure> { ) -> SurfacePromotionResult {
use crate::picture::SurfacePromotionFailure::*; // Check if this primitive _wants_ to be promoted to a compositor surface.
if !flags.contains(PrimitiveFlags::PREFER_COMPOSITOR_SURFACE) {
return SurfacePromotionResult::Failed;
}
// Each strategy has different restrictions on whether we can promote // Each strategy has different restrictions on whether we can promote
match surface_kind { match surface_kind {
@ -2528,33 +2494,26 @@ impl TileCacheInstance {
// Non-opaque compositor surfaces require sub-slices, as they are drawn // Non-opaque compositor surfaces require sub-slices, as they are drawn
// as overlays. // as overlays.
if sub_slice_index == self.sub_slices.len() - 1 { if sub_slice_index == self.sub_slices.len() - 1 {
return Err(OverlaySurfaceLimit); return SurfacePromotionResult::Failed;
} }
// If a complex clip is being applied to this primitive, it can't be // If a complex clip is being applied to this primitive, it can't be
// promoted directly to a compositor surface. // promoted directly to a compositor surface.
if prim_clip_chain.needs_mask { if prim_clip_chain.needs_mask {
return Err(OverlayNeedsMask); return SurfacePromotionResult::Failed;
} }
} }
CompositorSurfaceKind::Underlay => { CompositorSurfaceKind::Underlay => {
// If a mask is needed, there are some restrictions. // Underlay strategy relies on the slice being opaque if a mask is needed,
if prim_clip_chain.needs_mask { // and only one underlay can rely on a mask.
// Need an opaque backdrop. if prim_clip_chain.needs_mask && (self.backdrop.kind.is_none() || !self.underlays.is_empty()) {
if self.backdrop.kind.is_none() { return SurfacePromotionResult::Failed;
return Err(UnderlayAlphaBackdrop);
}
// Only one masked underlay allowed.
if !self.underlays.is_empty() {
return Err(UnderlaySurfaceLimit);
}
} }
// Underlays can't appear on top of overlays, because they can't punch // Underlays can't appear on top of overlays, because they can't punch
// through the existing overlay. // through the existing overlay.
if self.overlay_region.intersects(&pic_coverage_rect) { if self.overlay_region.intersects(&pic_coverage_rect) {
return Err(UnderlayIntersectsOverlay); return SurfacePromotionResult::Failed;
} }
} }
CompositorSurfaceKind::Blit => unreachable!(), CompositorSurfaceKind::Blit => unreachable!(),
@ -2563,7 +2522,7 @@ impl TileCacheInstance {
// If not on the root picture cache, it has some kind of // If not on the root picture cache, it has some kind of
// complex effect (such as a filter, mix-blend-mode or 3d transform). // complex effect (such as a filter, mix-blend-mode or 3d transform).
if !is_root_tile_cache { if !is_root_tile_cache {
return Err(NotRootTileCache); return SurfacePromotionResult::Failed;
} }
let mapper : SpaceMapper<PicturePixel, WorldPixel> = SpaceMapper::new_with_target( let mapper : SpaceMapper<PicturePixel, WorldPixel> = SpaceMapper::new_with_target(
@ -2573,14 +2532,14 @@ impl TileCacheInstance {
&frame_context.spatial_tree); &frame_context.spatial_tree);
let transform = mapper.get_transform(); let transform = mapper.get_transform();
if !transform.is_2d_scale_translation() { if !transform.is_2d_scale_translation() {
return Err(ComplexTransform); return SurfacePromotionResult::Failed;
} }
if self.slice_flags.contains(SliceFlags::IS_ATOMIC) { if self.slice_flags.contains(SliceFlags::IS_ATOMIC) {
return Err(SliceAtomic); return SurfacePromotionResult::Failed;
} }
Ok(surface_kind) SurfacePromotionResult::Success
} }
fn setup_compositor_surfaces_yuv( fn setup_compositor_surfaces_yuv(
@ -2602,7 +2561,7 @@ impl TileCacheInstance {
color_space: YuvRangedColorSpace, color_space: YuvRangedColorSpace,
format: YuvFormat, format: YuvFormat,
surface_kind: CompositorSurfaceKind, surface_kind: CompositorSurfaceKind,
) -> Result<CompositorSurfaceKind, SurfacePromotionFailure> { ) -> bool {
for &key in api_keys { for &key in api_keys {
if key != ImageKey::DUMMY { if key != ImageKey::DUMMY {
// TODO: See comment in setup_compositor_surfaces_rgb. // TODO: See comment in setup_compositor_surfaces_rgb.
@ -2656,7 +2615,7 @@ impl TileCacheInstance {
image_rendering: ImageRendering, image_rendering: ImageRendering,
is_opaque: bool, is_opaque: bool,
surface_kind: CompositorSurfaceKind, surface_kind: CompositorSurfaceKind,
) -> Result<CompositorSurfaceKind, SurfacePromotionFailure> { ) -> bool {
let mut api_keys = [ImageKey::DUMMY; 3]; let mut api_keys = [ImageKey::DUMMY; 3];
api_keys[0] = api_key; api_keys[0] = api_key;
@ -2712,9 +2671,7 @@ impl TileCacheInstance {
image_rendering: ImageRendering, image_rendering: ImageRendering,
is_opaque: bool, is_opaque: bool,
surface_kind: CompositorSurfaceKind, surface_kind: CompositorSurfaceKind,
) -> Result<CompositorSurfaceKind, SurfacePromotionFailure> { ) -> bool {
use crate::picture::SurfacePromotionFailure::*;
let map_local_to_picture = SpaceMapper::new_with_target( let map_local_to_picture = SpaceMapper::new_with_target(
self.spatial_node_index, self.spatial_node_index,
prim_spatial_node_index, prim_spatial_node_index,
@ -2725,12 +2682,12 @@ impl TileCacheInstance {
// Map the primitive local rect into picture space. // Map the primitive local rect into picture space.
let prim_rect = match map_local_to_picture.map(&local_prim_rect) { let prim_rect = match map_local_to_picture.map(&local_prim_rect) {
Some(rect) => rect, Some(rect) => rect,
None => return Ok(surface_kind), None => return true,
}; };
// If the rect is invalid, no need to create dependencies. // If the rect is invalid, no need to create dependencies.
if prim_rect.is_empty() { if prim_rect.is_empty() {
return Ok(surface_kind); return true;
} }
let pic_to_world_mapper = SpaceMapper::new_with_target( let pic_to_world_mapper = SpaceMapper::new_with_target(
@ -2746,7 +2703,7 @@ impl TileCacheInstance {
let is_visible = world_clip_rect.intersects(&frame_context.global_screen_world_rect); let is_visible = world_clip_rect.intersects(&frame_context.global_screen_world_rect);
if !is_visible { if !is_visible {
return Ok(surface_kind); return true;
} }
let prim_offset = ScaleOffset::from_offset(local_prim_rect.min.to_vector().cast_unit()); let prim_offset = ScaleOffset::from_offset(local_prim_rect.min.to_vector().cast_unit());
@ -2798,7 +2755,7 @@ impl TileCacheInstance {
if surface_size.width >= MAX_COMPOSITOR_SURFACES_SIZE || if surface_size.width >= MAX_COMPOSITOR_SURFACES_SIZE ||
surface_size.height >= MAX_COMPOSITOR_SURFACES_SIZE { surface_size.height >= MAX_COMPOSITOR_SURFACES_SIZE {
return Err(SizeTooLarge); return false;
} }
// When using native compositing, we need to find an existing native surface // When using native compositing, we need to find an existing native surface
@ -2936,7 +2893,7 @@ impl TileCacheInstance {
CompositorSurfaceKind::Blit => unreachable!(), CompositorSurfaceKind::Blit => unreachable!(),
} }
Ok(surface_kind) true
} }
/// Push an estimated rect for an off-screen surface during dependency updates. This is /// Push an estimated rect for an off-screen surface during dependency updates. This is
@ -2988,20 +2945,6 @@ impl TileCacheInstance {
self.current_surface_traversal_depth -= 1; self.current_surface_traversal_depth -= 1;
} }
fn maybe_report_promotion_failure(&self,
result: Result<CompositorSurfaceKind, SurfacePromotionFailure>,
rect: PictureRect,
reported: &mut bool) {
if !self.debug_flags.contains(DebugFlags::SURFACE_PROMOTION_LOGGING) || result.is_ok() || *reported {
return;
}
// Report this as a warning.
// TODO: Find a way to expose this to web authors.
warn!("Surface promotion of prim at {:?} failed with: {}.", rect, result.unwrap_err());
*reported = true;
}
/// Update the dependencies for each tile for a given primitive instance. /// Update the dependencies for each tile for a given primitive instance.
pub fn update_prim_dependencies( pub fn update_prim_dependencies(
&mut self, &mut self,
@ -3021,8 +2964,6 @@ impl TileCacheInstance {
is_root_tile_cache: bool, is_root_tile_cache: bool,
surfaces: &mut [SurfaceInfo], surfaces: &mut [SurfaceInfo],
) { ) {
use crate::picture::SurfacePromotionFailure::*;
// This primitive exists on the last element on the current surface stack. // This primitive exists on the last element on the current surface stack.
profile_scope!("update_prim_dependencies"); profile_scope!("update_prim_dependencies");
let prim_surface_index = surface_stack.last().unwrap().1; let prim_surface_index = surface_stack.last().unwrap().1;
@ -3162,8 +3103,6 @@ impl TileCacheInstance {
// rect eventually means it doesn't affect that tile). // rect eventually means it doesn't affect that tile).
// TODO(gw): Get picture clips earlier (during the initial picture traversal // TODO(gw): Get picture clips earlier (during the initial picture traversal
// pass) so that we can calculate these correctly. // pass) so that we can calculate these correctly.
let mut promotion_result: Result<CompositorSurfaceKind, SurfacePromotionFailure> = Ok(CompositorSurfaceKind::Blit);
let mut promotion_failure_reported = false;
match prim_instance.kind { match prim_instance.kind {
PrimitiveInstanceKind::Picture { pic_index,.. } => { PrimitiveInstanceKind::Picture { pic_index,.. } => {
// Pictures can depend on animated opacity bindings. // Pictures can depend on animated opacity bindings.
@ -3226,60 +3165,62 @@ impl TileCacheInstance {
is_opaque = image_properties.descriptor.is_opaque(); is_opaque = image_properties.descriptor.is_opaque();
} }
if image_key.common.flags.contains(PrimitiveFlags::PREFER_COMPOSITOR_SURFACE) { let mut promote_to_surface = false;
// Only consider promoting Images if all of our YuvImages have been
// processed (whether they were promoted or not). // Only consider promoting Images if all of our YuvImages have been
if self.yuv_images_remaining > 0 { // processed (whether they were promoted or not).
promotion_result = Err(ImageWaitingOnYuvImage); if self.yuv_images_remaining == 0 {
} else { match self.can_promote_to_surface(image_key.common.flags,
promotion_result = self.can_promote_to_surface(prim_clip_chain, prim_clip_chain,
prim_spatial_node_index, prim_spatial_node_index,
is_root_tile_cache, is_root_tile_cache,
sub_slice_index, sub_slice_index,
CompositorSurfaceKind::Overlay, CompositorSurfaceKind::Overlay,
pic_coverage_rect, pic_coverage_rect,
frame_context); frame_context) {
} SurfacePromotionResult::Failed => {
}
// Native OS compositors (DC and CA, at least) support premultiplied alpha SurfacePromotionResult::Success => {
// only. If we have an image that's not pre-multiplied alpha, we can't promote it. promote_to_surface = true;
if image_data.alpha_type == AlphaType::Alpha { }
promotion_result = Err(NotPremultipliedAlpha);
}
if let Ok(kind) = promotion_result {
promotion_result = self.setup_compositor_surfaces_rgb(
sub_slice_index,
&mut prim_info,
image_key.common.flags,
local_prim_rect,
prim_spatial_node_index,
pic_coverage_rect,
frame_context,
ImageDependency {
key: image_data.key,
generation: resource_cache.get_image_generation(image_data.key),
},
image_data.key,
resource_cache,
composite_state,
gpu_cache,
image_data.image_rendering,
is_opaque,
kind,
);
} }
} }
if let Ok(kind) = promotion_result { // Native OS compositors (DC and CA, at least) support premultiplied alpha
*compositor_surface_kind = kind; // only. If we have an image that's not pre-multiplied alpha, we can't promote it.
if image_data.alpha_type == AlphaType::Alpha {
promote_to_surface = false;
}
if kind == CompositorSurfaceKind::Overlay { if promote_to_surface {
prim_instance.vis.state = VisibilityState::Culled; promote_to_surface = self.setup_compositor_surfaces_rgb(
return; sub_slice_index,
} &mut prim_info,
image_key.common.flags,
local_prim_rect,
prim_spatial_node_index,
pic_coverage_rect,
frame_context,
ImageDependency {
key: image_data.key,
generation: resource_cache.get_image_generation(image_data.key),
},
image_data.key,
resource_cache,
composite_state,
gpu_cache,
image_data.image_rendering,
is_opaque,
CompositorSurfaceKind::Overlay,
);
}
assert!(kind == CompositorSurfaceKind::Blit, "Image prims should either be overlays or blits."); if promote_to_surface {
*compositor_surface_kind = CompositorSurfaceKind::Overlay;
prim_instance.vis.state = VisibilityState::Culled;
return;
} else {
*compositor_surface_kind = CompositorSurfaceKind::Blit;
prim_info.images.push(ImageDependency { prim_info.images.push(ImageDependency {
key: image_data.key, key: image_data.key,
@ -3290,103 +3231,106 @@ impl TileCacheInstance {
PrimitiveInstanceKind::YuvImage { data_handle, ref mut compositor_surface_kind, .. } => { PrimitiveInstanceKind::YuvImage { data_handle, ref mut compositor_surface_kind, .. } => {
let prim_data = &data_stores.yuv_image[data_handle]; let prim_data = &data_stores.yuv_image[data_handle];
if prim_data.common.flags.contains(PrimitiveFlags::PREFER_COMPOSITOR_SURFACE) { // Note if this is one of the YuvImages we were considering for
// Note if this is one of the YuvImages we were considering for // surface promotion. We only care for primitives that were added
// surface promotion. We only care for primitives that were added // to us, indicated by is_root_tile_cache. Those are the only ones
// to us, indicated by is_root_tile_cache. Those are the only ones // that were added to the TileCacheParams that configured the
// that were added to the TileCacheParams that configured the // current scene.
// current scene. if is_root_tile_cache && prim_data.common.flags.contains(PrimitiveFlags::PREFER_COMPOSITOR_SURFACE) {
if is_root_tile_cache { self.yuv_images_remaining -= 1;
self.yuv_images_remaining -= 1; }
}
let clip_on_top = prim_clip_chain.needs_mask; let clip_on_top = prim_clip_chain.needs_mask;
let prefer_underlay = clip_on_top || !cfg!(target_os = "macos"); let prefer_underlay = clip_on_top || !cfg!(target_os = "macos");
let promotion_attempts = if prefer_underlay { let promotion_attempts = if prefer_underlay {
[CompositorSurfaceKind::Underlay, CompositorSurfaceKind::Overlay] [CompositorSurfaceKind::Underlay, CompositorSurfaceKind::Overlay]
} else { } else {
[CompositorSurfaceKind::Overlay, CompositorSurfaceKind::Underlay] [CompositorSurfaceKind::Overlay, CompositorSurfaceKind::Underlay]
};
let mut promotion_kind = None;
for kind in promotion_attempts {
let success = match self.can_promote_to_surface(
prim_data.common.flags,
prim_clip_chain,
prim_spatial_node_index,
is_root_tile_cache,
sub_slice_index,
kind,
pic_coverage_rect,
frame_context) {
SurfacePromotionResult::Failed => false,
SurfacePromotionResult::Success => true,
}; };
if success {
promotion_kind = Some(kind);
break;
}
}
// TODO(gw): When we support RGBA images for external surfaces, we also
// need to check if opaque (YUV images are implicitly opaque).
for kind in promotion_attempts { // If this primitive is being promoted to a surface, construct an external
// Since this might be an attempt after an earlier error, clear the flag // surface descriptor for use later during batching and compositing. We only
// so that we are allowed to report another error. // add the image keys for this primitive as a dependency if this is _not_
promotion_failure_reported = false; // a promoted surface, since we don't want the tiles to invalidate when the
promotion_result = self.can_promote_to_surface( // video content changes, if it's a compositor surface!
prim_clip_chain, if let Some(kind) = promotion_kind {
prim_spatial_node_index, // Build dependency for each YUV plane, with current image generation for
is_root_tile_cache, // later detection of when the composited surface has changed.
sub_slice_index, let mut image_dependencies = [ImageDependency::INVALID; 3];
kind, for (key, dep) in prim_data.kind.yuv_key.iter().cloned().zip(image_dependencies.iter_mut()) {
pic_coverage_rect, *dep = ImageDependency {
frame_context); key,
if promotion_result.is_ok() { generation: resource_cache.get_image_generation(key),
break;
} }
self.maybe_report_promotion_failure(promotion_result, pic_coverage_rect, &mut promotion_failure_reported);
} }
// TODO(gw): When we support RGBA images for external surfaces, we also let success = self.setup_compositor_surfaces_yuv(
// need to check if opaque (YUV images are implicitly opaque). sub_slice_index,
&mut prim_info,
// If this primitive is being promoted to a surface, construct an external prim_data.common.flags,
// surface descriptor for use later during batching and compositing. We only local_prim_rect,
// add the image keys for this primitive as a dependency if this is _not_ prim_spatial_node_index,
// a promoted surface, since we don't want the tiles to invalidate when the pic_coverage_rect,
// video content changes, if it's a compositor surface! frame_context,
if let Ok(kind) = promotion_result { &image_dependencies,
// Build dependency for each YUV plane, with current image generation for &prim_data.kind.yuv_key,
// later detection of when the composited surface has changed. resource_cache,
let mut image_dependencies = [ImageDependency::INVALID; 3]; composite_state,
for (key, dep) in prim_data.kind.yuv_key.iter().cloned().zip(image_dependencies.iter_mut()) { gpu_cache,
*dep = ImageDependency { prim_data.kind.image_rendering,
key, prim_data.kind.color_depth,
generation: resource_cache.get_image_generation(key), prim_data.kind.color_space.with_range(prim_data.kind.color_range),
} prim_data.kind.format,
} kind,
);
promotion_result = self.setup_compositor_surfaces_yuv( if !success {
sub_slice_index, promotion_kind = None;
&mut prim_info,
prim_data.common.flags,
local_prim_rect,
prim_spatial_node_index,
pic_coverage_rect,
frame_context,
&image_dependencies,
&prim_data.kind.yuv_key,
resource_cache,
composite_state,
gpu_cache,
prim_data.kind.image_rendering,
prim_data.kind.color_depth,
prim_data.kind.color_space.with_range(prim_data.kind.color_range),
prim_data.kind.format,
kind,
);
} }
} }
// Store on the YUV primitive instance whether this is a promoted surface. // Store on the YUV primitive instance whether this is a promoted surface.
// This is used by the batching code to determine whether to draw the // This is used by the batching code to determine whether to draw the
// image to the content tiles, or just a transparent z-write. // image to the content tiles, or just a transparent z-write.
if let Ok(kind) = promotion_result { if let Some(kind) = promotion_kind {
*compositor_surface_kind = kind; *compositor_surface_kind = kind;
if kind == CompositorSurfaceKind::Overlay { if kind == CompositorSurfaceKind::Overlay {
prim_instance.vis.state = VisibilityState::Culled; prim_instance.vis.state = VisibilityState::Culled;
return; return;
} }
if kind == CompositorSurfaceKind::Blit { } else {
prim_info.images.extend( *compositor_surface_kind = CompositorSurfaceKind::Blit;
prim_data.kind.yuv_key.iter().map(|key| {
ImageDependency { prim_info.images.extend(
key: *key, prim_data.kind.yuv_key.iter().map(|key| {
generation: resource_cache.get_image_generation(*key), ImageDependency {
} key: *key,
}) generation: resource_cache.get_image_generation(*key),
); }
} })
);
} }
} }
PrimitiveInstanceKind::ImageBorder { data_handle, .. } => { PrimitiveInstanceKind::ImageBorder { data_handle, .. } => {
@ -3487,9 +3431,7 @@ impl TileCacheInstance {
PrimitiveInstanceKind::TextRun { .. } => { PrimitiveInstanceKind::TextRun { .. } => {
// These don't contribute dependencies // These don't contribute dependencies
} }
}; };
self.maybe_report_promotion_failure(promotion_result, pic_coverage_rect, &mut promotion_failure_reported);
// Calculate the screen rect in local space. When we calculate backdrops, we // Calculate the screen rect in local space. When we calculate backdrops, we
// care only that they cover the visible rect (based off the local clip), and // care only that they cover the visible rect (based off the local clip), and

View file

@ -1168,8 +1168,6 @@ impl RenderApi {
self.resources.set_debug_flags(flags); self.resources.set_debug_flags(flags);
let cmd = DebugCommand::SetFlags(flags); let cmd = DebugCommand::SetFlags(flags);
self.api_sender.send(ApiMsg::DebugCommand(cmd)).unwrap(); self.api_sender.send(ApiMsg::DebugCommand(cmd)).unwrap();
self.scene_sender.send(SceneBuilderRequest ::SetFlags(flags)).unwrap();
self.low_priority_scene_sender.send(SceneBuilderRequest ::SetFlags(flags)).unwrap();
} }
/// Stop RenderBackend's task until shut down /// Stop RenderBackend's task until shut down

View file

@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use api::{AsyncBlobImageRasterizer, BlobImageResult, DebugFlags, Parameter}; use api::{AsyncBlobImageRasterizer, BlobImageResult, Parameter};
use api::{DocumentId, PipelineId, ExternalEvent, BlobImageRequest}; use api::{DocumentId, PipelineId, ExternalEvent, BlobImageRequest};
use api::{NotificationRequest, Checkpoint, IdNamespace, QualitySettings}; use api::{NotificationRequest, Checkpoint, IdNamespace, QualitySettings};
use api::{PrimitiveKeyKind, GlyphDimensionRequest, GlyphIndexRequest}; use api::{PrimitiveKeyKind, GlyphDimensionRequest, GlyphIndexRequest};
@ -99,7 +99,6 @@ pub enum SceneBuilderRequest {
StopRenderBackend, StopRenderBackend,
ShutDown(Option<Sender<()>>), ShutDown(Option<Sender<()>>),
Flush(Sender<()>), Flush(Sender<()>),
SetFlags(DebugFlags),
SetFrameBuilderConfig(FrameBuilderConfig), SetFrameBuilderConfig(FrameBuilderConfig),
SetParameter(Parameter), SetParameter(Parameter),
ReportMemory(Box<MemoryReport>, Sender<Box<MemoryReport>>), ReportMemory(Box<MemoryReport>, Sender<Box<MemoryReport>>),
@ -241,7 +240,6 @@ pub struct SceneBuilderThread {
removed_pipelines: FastHashSet<PipelineId>, removed_pipelines: FastHashSet<PipelineId>,
#[cfg(feature = "capture")] #[cfg(feature = "capture")]
capture_config: Option<CaptureConfig>, capture_config: Option<CaptureConfig>,
debug_flags: DebugFlags,
} }
pub struct SceneBuilderThreadChannels { pub struct SceneBuilderThreadChannels {
@ -286,7 +284,6 @@ impl SceneBuilderThread {
removed_pipelines: FastHashSet::default(), removed_pipelines: FastHashSet::default(),
#[cfg(feature = "capture")] #[cfg(feature = "capture")]
capture_config: None, capture_config: None,
debug_flags: DebugFlags::default(),
} }
} }
@ -312,9 +309,6 @@ impl SceneBuilderThread {
Ok(SceneBuilderRequest::Flush(tx)) => { Ok(SceneBuilderRequest::Flush(tx)) => {
self.send(SceneBuilderResult::FlushComplete(tx)); self.send(SceneBuilderResult::FlushComplete(tx));
} }
Ok(SceneBuilderRequest::SetFlags(debug_flags)) => {
self.debug_flags = debug_flags;
}
Ok(SceneBuilderRequest::Transactions(txns)) => { Ok(SceneBuilderRequest::Transactions(txns)) => {
let built_txns : Vec<Box<BuiltTransaction>> = txns.into_iter() let built_txns : Vec<Box<BuiltTransaction>> = txns.into_iter()
.map(|txn| self.process_transaction(*txn)) .map(|txn| self.process_transaction(*txn))
@ -440,7 +434,6 @@ impl SceneBuilderThread {
&mut item.interners, &mut item.interners,
&mut item.spatial_tree, &mut item.spatial_tree,
&SceneStats::empty(), &SceneStats::empty(),
self.debug_flags,
)); ));
interner_updates = Some( interner_updates = Some(
@ -605,7 +598,6 @@ impl SceneBuilderThread {
&mut doc.interners, &mut doc.interners,
&mut doc.spatial_tree, &mut doc.spatial_tree,
&doc.stats, &doc.stats,
self.debug_flags,
); );
// Update the allocation stats for next scene // Update the allocation stats for next scene

View file

@ -37,7 +37,7 @@
use api::{AlphaType, BorderDetails, BorderDisplayItem, BuiltDisplayListIter, BuiltDisplayList, PrimitiveFlags}; use api::{AlphaType, BorderDetails, BorderDisplayItem, BuiltDisplayListIter, BuiltDisplayList, PrimitiveFlags};
use api::{ClipId, ColorF, CommonItemProperties, ComplexClipRegion, ComponentTransferFuncType, RasterSpace}; use api::{ClipId, ColorF, CommonItemProperties, ComplexClipRegion, ComponentTransferFuncType, RasterSpace};
use api::{DebugFlags, DisplayItem, DisplayItemRef, ExtendMode, ExternalScrollId, FilterData}; use api::{DisplayItem, DisplayItemRef, ExtendMode, ExternalScrollId, FilterData};
use api::{FilterOp, FilterPrimitive, FontInstanceKey, FontSize, GlyphInstance, GlyphOptions, GradientStop}; use api::{FilterOp, FilterPrimitive, FontInstanceKey, FontSize, GlyphInstance, GlyphOptions, GradientStop};
use api::{IframeDisplayItem, ImageKey, ImageRendering, ItemRange, ColorDepth, QualitySettings}; use api::{IframeDisplayItem, ImageKey, ImageRendering, ItemRange, ColorDepth, QualitySettings};
use api::{LineOrientation, LineStyle, NinePatchBorderSource, PipelineId, MixBlendMode, StackingContextFlags}; use api::{LineOrientation, LineStyle, NinePatchBorderSource, PipelineId, MixBlendMode, StackingContextFlags};
@ -540,7 +540,6 @@ impl<'a> SceneBuilder<'a> {
interners: &mut Interners, interners: &mut Interners,
spatial_tree: &mut SceneSpatialTree, spatial_tree: &mut SceneSpatialTree,
stats: &SceneStats, stats: &SceneStats,
debug_flags: DebugFlags,
) -> BuiltScene { ) -> BuiltScene {
profile_scope!("build_scene"); profile_scope!("build_scene");
@ -576,7 +575,6 @@ impl<'a> SceneBuilder<'a> {
tile_cache_builder: TileCacheBuilder::new( tile_cache_builder: TileCacheBuilder::new(
root_reference_frame_index, root_reference_frame_index,
frame_builder_config.background_color, frame_builder_config.background_color,
debug_flags,
), ),
snap_to_device, snap_to_device,
picture_graph: PictureGraph::new(), picture_graph: PictureGraph::new(),

View file

@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use api::{ColorF, DebugFlags, PrimitiveFlags, QualitySettings, RasterSpace, ClipId}; use api::{ColorF, PrimitiveFlags, QualitySettings, RasterSpace, ClipId};
use api::units::*; use api::units::*;
use crate::clip::{ClipNodeKind, ClipLeafId, ClipNodeId, ClipTreeBuilder}; use crate::clip::{ClipNodeKind, ClipLeafId, ClipNodeId, ClipTreeBuilder};
use crate::frame_builder::FrameBuilderConfig; use crate::frame_builder::FrameBuilderConfig;
@ -119,8 +119,6 @@ pub struct TileCacheBuilder {
prev_scroll_root_cache: (SpatialNodeIndex, SpatialNodeIndex), prev_scroll_root_cache: (SpatialNodeIndex, SpatialNodeIndex),
/// Handle to the root reference frame /// Handle to the root reference frame
root_spatial_node_index: SpatialNodeIndex, root_spatial_node_index: SpatialNodeIndex,
/// Debug flags to provide to our TileCacheInstances.
debug_flags: DebugFlags,
} }
/// The output of a tile cache builder, containing all details needed to construct the /// The output of a tile cache builder, containing all details needed to construct the
@ -147,13 +145,11 @@ impl TileCacheBuilder {
pub fn new( pub fn new(
root_spatial_node_index: SpatialNodeIndex, root_spatial_node_index: SpatialNodeIndex,
background_color: Option<ColorF>, background_color: Option<ColorF>,
debug_flags: DebugFlags,
) -> Self { ) -> Self {
TileCacheBuilder { TileCacheBuilder {
primary_slices: vec![PrimarySlice::new(SliceFlags::empty(), None, background_color)], primary_slices: vec![PrimarySlice::new(SliceFlags::empty(), None, background_color)],
prev_scroll_root_cache: (SpatialNodeIndex::INVALID, SpatialNodeIndex::INVALID), prev_scroll_root_cache: (SpatialNodeIndex::INVALID, SpatialNodeIndex::INVALID),
root_spatial_node_index, root_spatial_node_index,
debug_flags,
} }
} }
@ -475,7 +471,6 @@ impl TileCacheBuilder {
clip_tree_builder, clip_tree_builder,
) { ) {
create_tile_cache( create_tile_cache(
self.debug_flags,
primary_slice.slice_flags, primary_slice.slice_flags,
descriptor.scroll_root, descriptor.scroll_root,
primary_slice.iframe_clip, primary_slice.iframe_clip,
@ -493,7 +488,6 @@ impl TileCacheBuilder {
SliceKind::Default { secondary_slices } => { SliceKind::Default { secondary_slices } => {
for descriptor in secondary_slices { for descriptor in secondary_slices {
create_tile_cache( create_tile_cache(
self.debug_flags,
primary_slice.slice_flags, primary_slice.slice_flags,
descriptor.scroll_root, descriptor.scroll_root,
primary_slice.iframe_clip, primary_slice.iframe_clip,
@ -572,7 +566,6 @@ fn find_shared_clip_root(
/// Given a PrimitiveList and scroll root, construct a tile cache primitive instance /// Given a PrimitiveList and scroll root, construct a tile cache primitive instance
/// that wraps the primitive list. /// that wraps the primitive list.
fn create_tile_cache( fn create_tile_cache(
debug_flags: DebugFlags,
slice_flags: SliceFlags, slice_flags: SliceFlags,
scroll_root: SpatialNodeIndex, scroll_root: SpatialNodeIndex,
iframe_clip: Option<ClipId>, iframe_clip: Option<ClipId>,
@ -618,7 +611,6 @@ fn create_tile_cache(
// Store some information about the picture cache slice. This is used when we swap the // Store some information about the picture cache slice. This is used when we swap the
// new scene into the frame builder to either reuse existing slices, or create new ones. // new scene into the frame builder to either reuse existing slices, or create new ones.
tile_caches.insert(slice_id, TileCacheParams { tile_caches.insert(slice_id, TileCacheParams {
debug_flags,
slice, slice,
slice_flags, slice_flags,
spatial_node_index: scroll_root, spatial_node_index: scroll_root,

View file

@ -720,8 +720,6 @@ bitflags! {
/// Render large blobs with at a smaller size (incorrectly). This is a temporary workaround for /// Render large blobs with at a smaller size (incorrectly). This is a temporary workaround for
/// fuzzing. /// fuzzing.
const RESTRICT_BLOB_SIZE = 1 << 28; const RESTRICT_BLOB_SIZE = 1 << 28;
/// Enable surface promotion logging.
const SURFACE_PROMOTION_LOGGING = 1 << 29;
} }
} }

View file

@ -6545,14 +6545,6 @@
value: false value: false
mirror: always mirror: always
# When true, we output warning messages when rejecting surface promotion
# when it has been requested. This is important for color correctness of
# wide color videos, as well as for GPU performance for all videos.
- name: gfx.webrender.debug.surface-promotion-logging
type: RelaxedAtomicBool
value: false
mirror: always
#ifdef MOZ_WIDGET_GTK #ifdef MOZ_WIDGET_GTK
- name: gfx.webrender.reject-software-driver - name: gfx.webrender.reject-software-driver
type: bool type: bool