From 7f0892aaebdd936e06515e6602ebf57dfaba006c Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Thu, 7 Nov 2024 08:59:21 -0800 Subject: [PATCH] [Impeller] disable overdraw prevention for source draws. (flutter/engine#56403) Overdraw prevention prevents overlapping triangles in the stroke tessellator from being visible with partially opaque draws. For fully opaque draws (or usage of src blend mode) I do not believe this will be an issue - so we can disable this to speed things up a tiny bit. This code runs after we covert opaque draws to src blend mode, so checking for src blend mode should be sufficient. --- .../impeller/entity/contents/color_source_contents.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/engine/src/flutter/impeller/entity/contents/color_source_contents.h b/engine/src/flutter/impeller/entity/contents/color_source_contents.h index 2dc1ec37f4..76a49ffe4a 100644 --- a/engine/src/flutter/impeller/entity/contents/color_source_contents.h +++ b/engine/src/flutter/impeller/entity/contents/color_source_contents.h @@ -232,8 +232,10 @@ class ColorSourceContents : public Contents { // If overdraw prevention is enabled (like when drawing stroke paths), we // increment the stencil buffer as we draw, preventing overlapping fragments // from drawing. Afterwards, we need to append another draw call to clean up - // the stencil buffer (happens below in this method). - if (geometry_result.mode == GeometryResult::Mode::kPreventOverdraw) { + // the stencil buffer (happens below in this method). This can be skipped + // for draws that are fully opaque or use src blend mode. + if (geometry_result.mode == GeometryResult::Mode::kPreventOverdraw && + options.blend_mode != BlendMode::kSource) { options.stencil_mode = ContentContextOptions::StencilMode::kOverdrawPreventionIncrement; } @@ -259,7 +261,8 @@ class ColorSourceContents : public Contents { // If we performed overdraw prevention, a subsection of the clip heightmap // was incremented by 1 in order to self-clip. So simply append a clip // restore to clean it up. - if (geometry_result.mode == GeometryResult::Mode::kPreventOverdraw) { + if (geometry_result.mode == GeometryResult::Mode::kPreventOverdraw && + options.blend_mode != BlendMode::kSource) { return RenderClipRestore(renderer, pass, entity.GetClipDepth(), GetCoverage(entity)); }