viz: Set RPDQ blend to kSrcOver for empty backdrop rects

When the backdrop rect for a render pass is empty, gl_renderer currently
sets use_shaders_for_blending to false, disregarding if the render
pass blend mode is supported by the underlying graphics API.
If it's not supported, a DCHECK is later hit when setting up alpha
blending.

This patch sets the blend function to kSrcOver in those cases where the
backdrop rect is empty.
The backdrop rect should be empty only in cases where the render pass
draw quad is completely clipped.
In the test case found by cluster fuzz the element has a
clip-path: polygon(3px 0px, 35px 1px) that limits the render pass
output rect. When computing the backdrop rect we intersect it with
the render pass output rect resulting in an empty rect.

Bug: 946464
Test: https://clusterfuzz.com/testcase?key=5140838366707712
Change-Id: Ie8a487a4f85c3a69ab4f809fc1ade1a71bdaaeda
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1576233
Reviewed-by: Antoine Labour <piman@chromium.org>
Commit-Queue: Daniele Castagna <dcastagna@chromium.org>
Cr-Commit-Position: refs/heads/master@{#653371}
diff --git a/components/viz/service/display/gl_renderer.cc b/components/viz/service/display/gl_renderer.cc
index 336484b..19ce877 100644
--- a/components/viz/service/display/gl_renderer.cc
+++ b/components/viz/service/display/gl_renderer.cc
@@ -230,8 +230,11 @@
   float edge[24];
   SkScalar color_matrix[20];
 
-  // Blending refers to modifications to the backdrop.
+  // Blending in the fragment shaders is used for modifications to the backdrop
+  // and for supporting advanced blending equation when not available by the
+  // underlying graphics API.
   bool use_shaders_for_blending = false;
+  SkBlendMode blend_mode = SkBlendMode::kSrcOver;
 
   bool use_aa = false;
 
@@ -1122,9 +1125,9 @@
 void GLRenderer::UpdateRPDQShadersForBlending(
     DrawRenderPassDrawQuadParams* params) {
   const RenderPassDrawQuad* quad = params->quad;
-  SkBlendMode blend_mode = quad->shared_quad_state->blend_mode;
+  params->blend_mode = quad->shared_quad_state->blend_mode;
   params->use_shaders_for_blending =
-      !CanApplyBlendModeUsingBlendFunc(blend_mode) ||
+      !CanApplyBlendModeUsingBlendFunc(params->blend_mode) ||
       ShouldApplyBackdropFilters(params->backdrop_filters) ||
       settings_->force_blending_with_shaders;
 
@@ -1170,7 +1173,7 @@
           gl_->DeleteTextures(1, &params->background_texture);
           params->background_texture = 0;
         }
-      } else if (CanApplyBlendModeUsingBlendFunc(blend_mode) &&
+      } else if (CanApplyBlendModeUsingBlendFunc(params->blend_mode) &&
                  ShouldApplyBackdropFilters(params->backdrop_filters)) {
         // Something went wrong with applying backdrop filters to the
         // backdrop.
@@ -1181,6 +1184,7 @@
     } else {  // params->background_rect.IsEmpty()
       DCHECK(!params->background_image_id);
       params->use_shaders_for_blending = false;
+      params->blend_mode = SkBlendMode::kSrcOver;
     }
   }
 
@@ -1330,7 +1334,7 @@
 }
 
 void GLRenderer::UpdateRPDQBlendMode(DrawRenderPassDrawQuadParams* params) {
-  SkBlendMode blend_mode = params->quad->shared_quad_state->blend_mode;
+  SkBlendMode blend_mode = params->blend_mode;
   SetBlendEnabled((!params->use_shaders_for_blending &&
                    (params->quad->ShouldDrawWithBlending() ||
                     !IsDefaultBlendMode(blend_mode))) ||
@@ -1351,7 +1355,7 @@
 
   BlendMode shader_blend_mode =
       params->use_shaders_for_blending
-          ? BlendModeFromSkXfermode(params->quad->shared_quad_state->blend_mode)
+          ? BlendModeFromSkXfermode(params->blend_mode)
           : BLEND_MODE_NONE;
 
   SamplerType sampler_type = SAMPLER_TYPE_2D;
@@ -1522,7 +1526,7 @@
     gl_->Flush();
 
   if (!params.use_shaders_for_blending)
-    RestoreBlendFuncToDefault(params.quad->shared_quad_state->blend_mode);
+    RestoreBlendFuncToDefault(params.blend_mode);
 }
 
 namespace {