Bug 1721437 - Render clear tiles before alpha tiles. r=gfx-reviewers,bradwerth

Before this patch the clear tiles were drawn last which meant they would always be drawn on top of all transparent content. It was finde under the assumption that nothing is ever rendered on top of clear tiles, however it turns out to be an issue with the proton window modal darkining which renders some semi-transparent black on top of the whole window (including window controls on windows 8 which use clear tiles). Since the occlusion culling treats clear tiles as opaque they will cut through anything under them regardless of the drawing order, so we can render them before transaprent tiles to get the correct result which is to overwrite what's under the clear tile while still being able to render semi-transparent content on top.

Differential Revision: https://phabricator.services.mozilla.com/D120844
This commit is contained in:
Nicolas Silva 2021-07-28 12:44:08 +00:00
Родитель 084e0e97ff
Коммит 7315cd8716
1 изменённых файлов: 10 добавлений и 10 удалений

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

@ -3350,9 +3350,9 @@ impl Renderer {
if tile.kind == TileKind::Clear {
// Clear tiles are specific to how we render the window buttons on
// Windows 8. We can get away with drawing them at the end on top
// of everything else, which we do to avoid having to juggle with
// the blend state.
// 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.
clear_tiles.push(occlusion::Item { rectangle: rect, key: idx });
continue;
}
@ -3404,13 +3404,12 @@ impl Renderer {
self.gpu_profiler.finish_sampler(opaque_sampler);
}
// Draw alpha tiles
if !occlusion.alpha_items().is_empty() {
if !clear_tiles.is_empty() {
let transparent_sampler = self.gpu_profiler.start_sampler(GPU_SAMPLER_TAG_TRANSPARENT);
self.set_blend(true, FramebufferKind::Main);
self.set_blend_mode_premultiplied_alpha(FramebufferKind::Main);
self.device.set_blend_mode_premultiplied_dest_out();
self.draw_tile_list(
occlusion.alpha_items().iter().rev(),
clear_tiles.iter(),
&composite_state,
&composite_state.external_surfaces,
projection,
@ -3419,12 +3418,13 @@ impl Renderer {
self.gpu_profiler.finish_sampler(transparent_sampler);
}
if !clear_tiles.is_empty() {
// Draw alpha tiles
if !occlusion.alpha_items().is_empty() {
let transparent_sampler = self.gpu_profiler.start_sampler(GPU_SAMPLER_TAG_TRANSPARENT);
self.set_blend(true, FramebufferKind::Main);
self.device.set_blend_mode_premultiplied_dest_out();
self.set_blend_mode_premultiplied_alpha(FramebufferKind::Main);
self.draw_tile_list(
clear_tiles.iter(),
occlusion.alpha_items().iter().rev(),
&composite_state,
&composite_state.external_surfaces,
projection,