Bug 1663355 - Always clear and render entire picture cache tiles on Mali-Gxx. r=gw,geckoview-reviewers,agi

On Mali-Gxx there is a driver bug which causes partial updates to offscreen
render targets to fail. This was originally encountered in bug 1558374, where we
thought that the problem was just to do with scissored glClear()s, so we used a
shader to clear the target instead of glClear(). On some sites, however, even
this is not enough, and sometimes renderering to the target fails leaving some
of the previous content in place.

We appear to be able to work around this by ensuring that the entire render
target is cleared, by calling glClear() with the scissor test disabled. This
means that for picture cache tiles we must ensure the entire valid region is
rendered. This patch also reverts the first attempt at a fix from bug 1558374,
as it is no longer necessary since the entire target is being cleared.

Differential Revision: https://phabricator.services.mozilla.com/D90531
This commit is contained in:
Jamie Nicol 2020-09-17 20:37:11 +00:00
Родитель 7a8ce6c724
Коммит 25488144c9
6 изменённых файлов: 21 добавлений и 18 удалений

Просмотреть файл

@ -956,6 +956,8 @@ pub struct Capabilities {
pub supports_nonzero_pbo_offsets: bool,
/// Whether the driver supports specifying the texture usage up front.
pub supports_texture_usage: bool,
/// Whether offscreen render targets can be partially updated.
pub supports_render_target_partial_update: bool,
/// The name of the renderer, as reported by GL
pub renderer_name: String,
}
@ -1562,6 +1564,11 @@ impl Device {
// from a non-zero offset within a PBO to fail. See bug 1603783.
let supports_nonzero_pbo_offsets = !is_macos;
// On Mali-Gxx there is a driver bug when rendering partial updates to
// offscreen render targets, so we must ensure we render to the entire target.
// See bug 1663355.
let supports_render_target_partial_update = !renderer_name.starts_with("Mali-G");
Device {
gl,
base_gl: None,
@ -1581,6 +1588,7 @@ impl Device {
supports_texture_swizzle,
supports_nonzero_pbo_offsets,
supports_texture_usage,
supports_render_target_partial_update,
renderer_name,
},

Просмотреть файл

@ -66,6 +66,7 @@ pub struct FrameBuilderConfig {
pub gpu_supports_fast_clears: bool,
pub gpu_supports_advanced_blend: bool,
pub advanced_blend_is_coherent: bool,
pub gpu_supports_render_target_partial_update: bool,
pub batch_lookback_count: usize,
pub background_color: Option<ColorF>,
pub compositor_kind: CompositorKind,

Просмотреть файл

@ -1381,11 +1381,12 @@ impl Tile {
}
// Check if the selected composite mode supports dirty rect updates. For Draw composite
// mode, we can always update the content with smaller dirty rects. For native composite
// mode, we can only use dirty rects if the compositor supports partial surface updates.
// mode, we can always update the content with smaller dirty rects, unless there is a
// driver bug to workaround. For native composite mode, we can only use dirty rects if
// the compositor supports partial surface updates.
let (supports_dirty_rects, supports_simple_prims) = match state.composite_state.compositor_kind {
CompositorKind::Draw { .. } => {
(true, true)
(frame_context.config.gpu_supports_render_target_partial_update, true)
}
CompositorKind::Native { max_update_rects, .. } => {
(max_update_rects > 0, false)

Просмотреть файл

@ -2615,6 +2615,7 @@ impl Renderer {
gpu_supports_fast_clears: options.gpu_supports_fast_clears,
gpu_supports_advanced_blend: ext_blend_equation_advanced,
advanced_blend_is_coherent: ext_blend_equation_advanced_coherent,
gpu_supports_render_target_partial_update: device.get_capabilities().supports_render_target_partial_update,
batch_lookback_count: RendererOptions::BATCH_LOOKBACK_COUNT,
background_color: options.clear_color,
compositor_kind,
@ -4450,7 +4451,12 @@ impl Renderer {
self.set_blend(false, framebuffer_kind);
let clear_color = target.clear_color.map(|c| c.to_array());
match target.alpha_batch_container.task_scissor_rect {
let scissor_rect = if self.device.get_capabilities().supports_render_target_partial_update {
target.alpha_batch_container.task_scissor_rect
} else {
None
};
match scissor_rect {
// If updating only a dirty rect within a picture cache target, the
// clear must also be scissored to that dirty region.
Some(r) if self.clear_caches_with_quads => {

Просмотреть файл

@ -301,6 +301,7 @@ impl BuiltScene {
gpu_supports_fast_clears: false,
gpu_supports_advanced_blend: false,
advanced_blend_is_coherent: false,
gpu_supports_render_target_partial_update: true,
batch_lookback_count: 0,
background_color: None,
compositor_kind: CompositorKind::default(),

Просмотреть файл

@ -599,20 +599,6 @@ nsresult GfxInfo::GetFeatureStatusImpl(
}
return NS_OK;
}
if (aFeature == FEATURE_WEBRENDER_SCISSORED_CACHE_CLEARS) {
// Mali-G71 and G72 (and presumably others) are buggy when attempting
// to clear picture cache textures with a scissor rect set.
const bool isMaliGxx =
mGLStrings->Renderer().Find("Mali-G", /*ignoreCase*/ true) >= 0;
if (isMaliGxx) {
*aStatus = nsIGfxInfo::FEATURE_BLOCKED_DEVICE;
aFailureId = "FEATURE_FAILURE_BUG_1603515";
} else {
*aStatus = nsIGfxInfo::FEATURE_STATUS_OK;
}
return NS_OK;
}
}
return GfxInfoBase::GetFeatureStatusImpl(