зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1441308 - Correct Renderer issues with multiple documents r=gw
This corrects A) An issue encountered with our strategy for skipping the end_pass call for all but an offscreen render target. See the comment above the end_pass call for details, and B) An issue with depth clearing where we do not clear the whole rect if there are multiple non-intersecting documents. Differential Revision: https://phabricator.services.mozilla.com/D23056 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
45b7708846
Коммит
09c427ac55
|
@ -104,7 +104,7 @@ use std::cell::RefCell;
|
||||||
use texture_cache::TextureCache;
|
use texture_cache::TextureCache;
|
||||||
use thread_profiler::{register_thread_with_profiler, write_profile};
|
use thread_profiler::{register_thread_with_profiler, write_profile};
|
||||||
use tiling::{AlphaRenderTarget, ColorRenderTarget};
|
use tiling::{AlphaRenderTarget, ColorRenderTarget};
|
||||||
use tiling::{BlitJob, BlitJobSource, RenderPass, RenderPassKind, RenderTargetList};
|
use tiling::{BlitJob, BlitJobSource, RenderPassKind, RenderTargetList};
|
||||||
use tiling::{Frame, RenderTarget, RenderTargetKind, TextureCacheRenderTarget};
|
use tiling::{Frame, RenderTarget, RenderTargetKind, TextureCacheRenderTarget};
|
||||||
#[cfg(not(feature = "pathfinder"))]
|
#[cfg(not(feature = "pathfinder"))]
|
||||||
use tiling::GlyphJob;
|
use tiling::GlyphJob;
|
||||||
|
@ -2602,32 +2602,6 @@ impl Renderer {
|
||||||
(cpu_profiles, gpu_profiles)
|
(cpu_profiles, gpu_profiles)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if the active rendered documents (that need depth buffer)
|
|
||||||
/// intersect on the main framebuffer, in which case we don't clear
|
|
||||||
/// the whole depth and instead clear each document area separately.
|
|
||||||
fn are_documents_intersecting_depth(&self) -> bool {
|
|
||||||
let document_rects = self.active_documents
|
|
||||||
.iter()
|
|
||||||
.filter_map(|&(_, ref render_doc)| {
|
|
||||||
match render_doc.frame.passes.last() {
|
|
||||||
Some(&RenderPass { kind: RenderPassKind::MainFramebuffer(ref target), .. })
|
|
||||||
if target.needs_depth() => Some(render_doc.frame.framebuffer_rect),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect::<SmallVec<[_; 3]>>();
|
|
||||||
|
|
||||||
for (i, rect) in document_rects.iter().enumerate() {
|
|
||||||
for other in &document_rects[i+1 ..] {
|
|
||||||
if rect.intersects(other) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn notify_slow_frame(&mut self) {
|
pub fn notify_slow_frame(&mut self) {
|
||||||
self.slow_frame_indicator.changed();
|
self.slow_frame_indicator.changed();
|
||||||
}
|
}
|
||||||
|
@ -2717,10 +2691,6 @@ impl Renderer {
|
||||||
});
|
});
|
||||||
|
|
||||||
profile_timers.cpu_time.profile(|| {
|
profile_timers.cpu_time.profile(|| {
|
||||||
// If the documents don't intersect for depth, we can just do
|
|
||||||
// a single, global depth clear.
|
|
||||||
let clear_depth_per_doc = self.are_documents_intersecting_depth();
|
|
||||||
|
|
||||||
//Note: another borrowck dance
|
//Note: another borrowck dance
|
||||||
let mut active_documents = mem::replace(&mut self.active_documents, Vec::default());
|
let mut active_documents = mem::replace(&mut self.active_documents, Vec::default());
|
||||||
// sort by the document layer id
|
// sort by the document layer id
|
||||||
|
@ -2731,6 +2701,7 @@ impl Renderer {
|
||||||
self.owned_external_images.iter().map(|(key, value)| (*key, value.clone()))
|
self.owned_external_images.iter().map(|(key, value)| (*key, value.clone()))
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let last_document_index = active_documents.len() - 1;
|
||||||
for (doc_index, (_, RenderedDocument { ref mut frame, .. })) in active_documents.iter_mut().enumerate() {
|
for (doc_index, (_, RenderedDocument { ref mut frame, .. })) in active_documents.iter_mut().enumerate() {
|
||||||
frame.profile_counters.reset_targets();
|
frame.profile_counters.reset_targets();
|
||||||
self.prepare_gpu_cache(frame);
|
self.prepare_gpu_cache(frame);
|
||||||
|
@ -2738,41 +2709,12 @@ impl Renderer {
|
||||||
"Received frame depends on a later GPU cache epoch ({:?}) than one we received last via `UpdateGpuCache` ({:?})",
|
"Received frame depends on a later GPU cache epoch ({:?}) than one we received last via `UpdateGpuCache` ({:?})",
|
||||||
frame.gpu_cache_frame_id, self.gpu_cache_frame_id);
|
frame.gpu_cache_frame_id, self.gpu_cache_frame_id);
|
||||||
|
|
||||||
// Work out what color to clear the frame buffer for this document.
|
|
||||||
// The document's supplied clear color is used, unless:
|
|
||||||
// (a) The document has no specified clear color AND
|
|
||||||
// (b) We are rendering the first document.
|
|
||||||
// If both those conditions are true, the overall renderer
|
|
||||||
// clear color will be used, if specified.
|
|
||||||
|
|
||||||
// Get the default clear color from the renderer.
|
|
||||||
let mut fb_clear_color = if doc_index == 0 {
|
|
||||||
self.clear_color
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
// Override with document clear color if no overall clear
|
|
||||||
// color or not on the first document.
|
|
||||||
if fb_clear_color.is_none() {
|
|
||||||
fb_clear_color = frame.background_color;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only clear the depth buffer for this document if this is
|
|
||||||
// the first document, or we need to clear depth per document.
|
|
||||||
let fb_clear_depth = if clear_depth_per_doc || doc_index == 0 {
|
|
||||||
Some(1.0)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
self.draw_tile_frame(
|
self.draw_tile_frame(
|
||||||
frame,
|
frame,
|
||||||
framebuffer_size,
|
framebuffer_size,
|
||||||
cpu_frame_id,
|
cpu_frame_id,
|
||||||
&mut results.stats,
|
&mut results.stats,
|
||||||
fb_clear_color,
|
doc_index == 0,
|
||||||
fb_clear_depth,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(_) = framebuffer_size {
|
if let Some(_) = framebuffer_size {
|
||||||
|
@ -2785,6 +2727,14 @@ impl Renderer {
|
||||||
let dirty_regions =
|
let dirty_regions =
|
||||||
mem::replace(&mut frame.recorded_dirty_regions, Vec::new());
|
mem::replace(&mut frame.recorded_dirty_regions, Vec::new());
|
||||||
results.recorded_dirty_regions.extend(dirty_regions);
|
results.recorded_dirty_regions.extend(dirty_regions);
|
||||||
|
|
||||||
|
// If we're the last document, don't call end_pass here, because we'll
|
||||||
|
// be moving on to drawing the debug overlays. See the comment above
|
||||||
|
// the end_pass call in draw_tile_frame about debug draw overlays
|
||||||
|
// for a bit more context.
|
||||||
|
if doc_index != last_document_index {
|
||||||
|
self.texture_resolver.end_pass(&mut self.device, None, None);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.unlock_external_images();
|
self.unlock_external_images();
|
||||||
|
@ -4361,8 +4311,7 @@ impl Renderer {
|
||||||
framebuffer_size: Option<FramebufferIntSize>,
|
framebuffer_size: Option<FramebufferIntSize>,
|
||||||
frame_id: GpuFrameId,
|
frame_id: GpuFrameId,
|
||||||
stats: &mut RendererStats,
|
stats: &mut RendererStats,
|
||||||
fb_clear_color: Option<ColorF>,
|
clear_framebuffer: bool,
|
||||||
fb_clear_depth: Option<f32>,
|
|
||||||
) {
|
) {
|
||||||
let _gm = self.gpu_profile.start_marker("tile frame draw");
|
let _gm = self.gpu_profile.start_marker("tile frame draw");
|
||||||
|
|
||||||
|
@ -4407,15 +4356,24 @@ impl Renderer {
|
||||||
ORTHO_FAR_PLANE,
|
ORTHO_FAR_PLANE,
|
||||||
);
|
);
|
||||||
|
|
||||||
self.draw_color_target(
|
let draw_target = DrawTarget::Default {
|
||||||
DrawTarget::Default {
|
|
||||||
rect: frame.framebuffer_rect,
|
rect: frame.framebuffer_rect,
|
||||||
total_size: framebuffer_size,
|
total_size: framebuffer_size,
|
||||||
},
|
};
|
||||||
|
if clear_framebuffer {
|
||||||
|
self.device.bind_draw_target(draw_target);
|
||||||
|
self.device.enable_depth_write();
|
||||||
|
self.device.clear_target(self.clear_color.map(|color| color.to_array()),
|
||||||
|
Some(1.0),
|
||||||
|
None);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.draw_color_target(
|
||||||
|
draw_target,
|
||||||
target,
|
target,
|
||||||
frame.content_origin,
|
frame.content_origin,
|
||||||
fb_clear_color.map(|color| color.to_array()),
|
None,
|
||||||
fb_clear_depth,
|
None,
|
||||||
&frame.render_tasks,
|
&frame.render_tasks,
|
||||||
&projection,
|
&projection,
|
||||||
frame_id,
|
frame_id,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче