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

Sync changes from mozilla-central gfx/wr #3843

Merged
merged 3 commits into from Jan 24, 2020
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

Bug 1602643 - Disable WebRender compositor dinamically for async scre…

  • Loading branch information
sotaro authored and moz-gfx committed Jan 24, 2020
commit e6b007e1bd1a3b875be71200b6364a52e0eba513
@@ -26,6 +26,7 @@ static CSS_NO_TEXTURE: &str = "fill:#c04040;fill-opacity:0.1;";
static CSS_NO_SURFACE: &str = "fill:#40c040;fill-opacity:0.1;";
static CSS_PRIM_COUNT: &str = "fill:#40f0f0;fill-opacity:0.1;";
static CSS_CONTENT: &str = "fill:#f04040;fill-opacity:0.1;";
static CSS_COMPOSITOR_KIND_CHANGED: &str = "fill:#f0c070;fill-opacity:0.1;";

fn tile_node_to_svg(node: &TileNode, x: f32, y: f32) -> String
{
@@ -62,6 +63,7 @@ fn tile_to_svg(key: TileOffset,
Some(InvalidationReason::NoTexture) => CSS_NO_TEXTURE.to_string(),
Some(InvalidationReason::NoSurface) => CSS_NO_SURFACE.to_string(),
Some(InvalidationReason::PrimCount) => CSS_PRIM_COUNT.to_string(),
Some(InvalidationReason::CompositorKindChanged) => CSS_COMPOSITOR_KIND_CHANGED.to_string(),
Some(InvalidationReason::Content { prim_compare_result } ) => {
let _foo = prim_compare_result;
CSS_CONTENT.to_string() //TODO do something with the compare result
@@ -94,6 +94,19 @@ pub enum CompositorConfig {
}
}

impl CompositorConfig {
pub fn compositor(&mut self) -> Option<&mut Box<dyn Compositor>> {
match self {
CompositorConfig::Native { ref mut compositor, .. } => {
Some(compositor)
}
CompositorConfig::Draw { .. } => {
None
}
}
}
}

impl Default for CompositorConfig {
/// Default compositor config is full present without partial present.
fn default() -> Self {
@@ -506,6 +519,9 @@ pub trait Compositor {
/// this once when all surface and visual updates are complete, to signal
/// that the OS composite transaction should be applied.
fn end_frame(&mut self);

/// Enable/disable native compositor usage
fn enable_native_compositor(&mut self, enable: bool);
}

/// Return the total area covered by a set of occluders, accounting for
@@ -608,6 +608,8 @@ pub enum InvalidationReason {
/// What changed in the primitive that was different
prim_compare_result: PrimitiveCompareResult,
},
// The compositor type changed
CompositorKindChanged,
}

/// A minimal subset of Tile for debug capturing
@@ -2100,6 +2102,36 @@ impl TileCacheInstance {
frame_state.resource_cache,
);

// If compositor mode is changed, need to drop all incompatible tiles.
match (frame_context.config.compositor_kind, self.native_surface_id) {
(CompositorKind::Draw { .. }, Some(_)) => {
frame_state.composite_state.destroy_native_tiles(
self.tiles.values_mut(),
frame_state.resource_cache,
);
for tile in self.tiles.values_mut() {
tile.surface = None;
// Invalidate the entire tile to force a redraw.
tile.invalidate(None, InvalidationReason::CompositorKindChanged);
}
if let Some(native_surface_id) = self.native_surface_id.take() {
frame_state.resource_cache.destroy_compositor_surface(native_surface_id);
}
}
(CompositorKind::Native { .. }, None) => {
// This could hit even when compositor mode is not changed,
// then we need to check if there are incompatible tiles.
for tile in self.tiles.values_mut() {
if let Some(TileSurface::Texture { descriptor: SurfaceTextureDescriptor::TextureCache { .. }, .. }) = tile.surface {
tile.surface = None;
// Invalidate the entire tile to force a redraw.
tile.invalidate(None, InvalidationReason::CompositorKindChanged);
}
}
}
(_, _) => {}
}

world_culling_rect
}

@@ -711,6 +711,7 @@ pub struct RenderBackend {
resource_cache: ResourceCache,

frame_config: FrameBuilderConfig,
default_compositor_kind: CompositorKind,
documents: FastHashMap<DocumentId, Document>,

notifier: Box<dyn RenderNotifier>,
@@ -755,6 +756,7 @@ impl RenderBackend {
resource_cache,
gpu_cache: GpuCache::new(),
frame_config,
default_compositor_kind : frame_config.compositor_kind,
documents: FastHashMap::default(),
notifier,
recorder,
@@ -1225,6 +1227,33 @@ impl RenderBackend {
self.resource_cache.clear(mask);
return RenderBackendStatus::Continue;
}
DebugCommand::EnableNativeCompositor(enable) => {
// Default CompositorKind should be Native
if let CompositorKind::Draw { .. } = self.default_compositor_kind {
unreachable!();
}

let compositor_kind = if enable {
self.default_compositor_kind
} else {
CompositorKind::default()
};

for (_, doc) in &mut self.documents {
doc.scene.config.compositor_kind = compositor_kind;
doc.frame_is_valid = false;
}

self.frame_config.compositor_kind = compositor_kind;

// Update config in SceneBuilder
self.low_priority_scene_tx.send(SceneBuilderRequest::SetFrameBuilderConfig(
self.frame_config.clone()
)).unwrap();

// We don't want to forward this message to the renderer.
return RenderBackendStatus::Continue;
}
DebugCommand::SimulateLongSceneBuild(time_ms) => {
self.scene_tx.send(SceneBuilderRequest::SimulateLongSceneBuild(time_ms)).unwrap();
return RenderBackendStatus::Continue;
@@ -1514,7 +1543,7 @@ impl RenderBackend {
// external image with NativeTexture or when platform requested to composite frame.
if invalidate_rendered_frame {
doc.rendered_frame_is_valid = false;
if let CompositorKind::Draw { max_partial_present_rects } = self.frame_config.compositor_kind {
if let CompositorKind::Draw { max_partial_present_rects } = doc.scene.config.compositor_kind {
// When partial present is enabled, we need to force redraw.
if max_partial_present_rects > 0 {
let msg = ResultMsg::ForceRedraw;
@@ -1896,6 +1896,8 @@ pub struct Renderer {
/// The compositing config, affecting how WR composites into the final scene.
compositor_config: CompositorConfig,

current_compositor_kind: CompositorKind,

/// Maintains a set of allocated native composite surfaces. This allows any
/// currently allocated surfaces to be cleaned up as soon as deinit() is
/// called (the normal bookkeeping for native surfaces exists in the
@@ -2423,6 +2425,7 @@ impl Renderer {
documents_seen: FastHashSet::default(),
force_redraw: true,
compositor_config: options.compositor_config,
current_compositor_kind: compositor_kind,
allocated_native_surfaces: FastHashSet::default(),
debug_overlay_state: DebugOverlayState::new(),
};
@@ -2870,7 +2873,8 @@ impl Renderer {
}
DebugCommand::ClearCaches(_)
| DebugCommand::SimulateLongSceneBuild(_)
| DebugCommand::SimulateLongLowPrioritySceneBuild(_) => {}
| DebugCommand::SimulateLongLowPrioritySceneBuild(_)
| DebugCommand::EnableNativeCompositor(_) => {}
DebugCommand::InvalidateGpuCache => {
match self.gpu_cache_texture.bus {
GpuCacheBus::PixelBuffer { ref mut rows, .. } => {
@@ -2961,7 +2965,9 @@ impl Renderer {
);

// Update the debug overlay surface, if we are running in native compositor mode.
if let CompositorConfig::Native { ref mut compositor, .. } = self.compositor_config {
if let CompositorKind::Native { .. } = self.current_compositor_kind {
let compositor = self.compositor_config.compositor().unwrap();

// If there is a current surface, destroy it if we don't need it for this frame, or if
// the size has changed.
if let Some(current_size) = self.debug_overlay_state.current_size {
@@ -2990,7 +2996,8 @@ impl Renderer {
fn bind_debug_overlay(&mut self) {
// Debug overlay setup are only required in native compositing mode
if self.debug_overlay_state.is_enabled {
if let CompositorConfig::Native { ref mut compositor, .. } = self.compositor_config {
if let CompositorKind::Native { .. } = self.current_compositor_kind {
let compositor = self.compositor_config.compositor().unwrap();
let surface_size = self.debug_overlay_state.current_size.unwrap();

// Bind the native surface
@@ -3024,7 +3031,8 @@ impl Renderer {
fn unbind_debug_overlay(&mut self) {
// Debug overlay setup are only required in native compositing mode
if self.debug_overlay_state.is_enabled {
if let CompositorConfig::Native { ref mut compositor, .. } = self.compositor_config {
if let CompositorKind::Native { .. } = self.current_compositor_kind {
let compositor = self.compositor_config.compositor().unwrap();
// Unbind the draw target and add it to the visual tree to be composited
compositor.unbind();

@@ -3055,6 +3063,35 @@ impl Renderer {
return Ok(results);
}

let compositor_kind = self.active_documents[0].1.frame.composite_state.compositor_kind;
// CompositorKind is updated
if self.current_compositor_kind != compositor_kind {
let enable = match (self.current_compositor_kind, compositor_kind) {
(CompositorKind::Native { .. }, CompositorKind::Draw { .. }) => {
if self.debug_overlay_state.current_size.is_some() {
self.compositor_config
.compositor()
.unwrap()
.destroy_surface(NativeSurfaceId::DEBUG_OVERLAY);
self.debug_overlay_state.current_size = None;
}
false
}
(CompositorKind::Draw { .. }, CompositorKind::Native { .. }) => {
true
}
(_, _) => {
unreachable!();
}
};

self.compositor_config
.compositor()
.unwrap()
.enable_native_compositor(enable);
self.current_compositor_kind = compositor_kind;
}

let mut frame_profiles = Vec::new();
let mut profile_timers = RendererProfileTimers::new();

@@ -3103,7 +3140,8 @@ impl Renderer {
// Inform the client that we are starting a composition transaction if native
// compositing is enabled. This needs to be done early in the frame, so that
// we can create debug overlays after drawing the main surfaces.
if let CompositorConfig::Native { ref mut compositor, .. } = self.compositor_config {
if let CompositorKind::Native { .. } = self.current_compositor_kind {
let compositor = self.compositor_config.compositor().unwrap();
compositor.begin_frame();
}

@@ -3120,6 +3158,8 @@ impl Renderer {

let last_document_index = active_documents.len() - 1;
for (doc_index, (document_id, RenderedDocument { ref mut frame, .. })) in active_documents.iter_mut().enumerate() {
assert!(self.current_compositor_kind == frame.composite_state.compositor_kind);

if self.shared_texture_cache_cleared {
assert!(self.documents_seen.contains(&document_id),
"Cleared texture cache without sending new document frame.");
@@ -3280,9 +3320,9 @@ impl Renderer {
let scale = if small_screen { 1.6 } else { 1.0 };
// TODO(gw): Tidy this up so that compositor config integrates better
// with the (non-compositor) surface y-flip options.
let surface_origin_is_top_left = match self.compositor_config {
CompositorConfig::Native { .. } => true,
CompositorConfig::Draw { .. } => self.device.surface_origin_is_top_left(),
let surface_origin_is_top_left = match self.current_compositor_kind {
CompositorKind::Native { .. } => true,
CompositorKind::Draw { .. } => self.device.surface_origin_is_top_left(),
};
debug_renderer.render(
&mut self.device,
@@ -3311,7 +3351,8 @@ impl Renderer {
// Inform the client that we are finished this composition transaction if native
// compositing is enabled. This must be called after any debug / profiling compositor
// surfaces have been drawn and added to the visual tree.
if let CompositorConfig::Native { ref mut compositor, .. } = self.compositor_config {
if let CompositorKind::Native { .. } = self.current_compositor_kind {
let compositor = self.compositor_config.compositor().unwrap();
compositor.end_frame();
}

@@ -5214,11 +5255,12 @@ impl Renderer {
if frame.composite_state.picture_caching_is_enabled {
// If we have a native OS compositor, then make use of that interface
// to specify how to composite each of the picture cache surfaces.
match self.compositor_config {
CompositorConfig::Native { ref mut compositor, .. } => {
match self.current_compositor_kind {
CompositorKind::Native { .. } => {
let compositor = self.compositor_config.compositor().unwrap();
frame.composite_state.composite_native(&mut **compositor);
}
CompositorConfig::Draw { max_partial_present_rects, .. } => {
CompositorKind::Draw { max_partial_present_rects, .. } => {
self.composite_simple(
&frame.composite_state,
clear_framebuffer,
@@ -5297,11 +5339,12 @@ impl Renderer {
)
}
ResolvedSurfaceTexture::Native { id, size } => {
let surface_info = match self.compositor_config {
CompositorConfig::Native { ref mut compositor, .. } => {
let surface_info = match self.current_compositor_kind {
CompositorKind::Native { .. } => {
let compositor = self.compositor_config.compositor().unwrap();
compositor.bind(id, picture_target.dirty_rect)
}
CompositorConfig::Draw { .. } => {
CompositorKind::Draw { .. } => {
unreachable!();
}
};
@@ -5334,11 +5377,12 @@ impl Renderer {

// Native OS surfaces must be unbound at the end of drawing to them
if let ResolvedSurfaceTexture::Native { .. } = picture_target.surface {
match self.compositor_config {
CompositorConfig::Native { ref mut compositor, .. } => {
match self.current_compositor_kind {
CompositorKind::Native { .. } => {
let compositor = self.compositor_config.compositor().unwrap();
compositor.unbind();
}
CompositorConfig::Draw { .. } => {
CompositorKind::Draw { .. } => {
unreachable!();
}
}
@@ -967,6 +967,8 @@ pub enum DebugCommand {
LoadCapture(PathBuf, MsgSender<CapturedDocument>),
/// Clear cached resources, forcing them to be re-uploaded from templates.
ClearCaches(ClearCache),
/// Enable/disable native compositor usage
EnableNativeCompositor(bool),
/// Invalidate GPU cache, forcing the update from the CPU mirror.
InvalidateGpuCache,
/// Causes the scene builder to pause for a given amount of milliseconds each time it
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.