[CompositeAfterPaint] Repaint canvas layer when cc layer changes

Bug: 524134
Change-Id: I15b3a40112a9382e2f0e83c140738e2de2bd2891
Reviewed-on: https://chromium-review.googlesource.com/c/1380346
Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org>
Reviewed-by: Philip Rogers <pdr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#617569}
diff --git a/third_party/blink/public/platform/web_surface_layer_bridge.h b/third_party/blink/public/platform/web_surface_layer_bridge.h
index c7ce029..0f80bc2 100644
--- a/third_party/blink/public/platform/web_surface_layer_bridge.h
+++ b/third_party/blink/public/platform/web_surface_layer_bridge.h
@@ -21,8 +21,10 @@
   // Triggered by resizing or surface layer creation.
   virtual void OnWebLayerUpdated() = 0;
 
-  // Called when new a SurfaceLayer is created.
+  // Called when a new contents cc layer is created.
   virtual void RegisterContentsLayer(cc::Layer*) = 0;
+
+  // Called when a contents cc layer will be destroyed.
   virtual void UnregisterContentsLayer(cc::Layer*) = 0;
 
   // Called when a SurfaceLayer is activated.
diff --git a/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc b/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
index 826fbf7..f239a2b 100644
--- a/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
+++ b/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
@@ -254,6 +254,16 @@
 CanvasRenderingContext* HTMLCanvasElement::GetCanvasRenderingContext(
     const String& type,
     const CanvasContextCreationAttributesCore& attributes) {
+  auto* old_contents_cc_layer = ContentsCcLayer();
+  auto* result = GetCanvasRenderingContextInternal(type, attributes);
+  if (ContentsCcLayer() != old_contents_cc_layer)
+    OnContentsCcLayerChanged();
+  return result;
+}
+
+CanvasRenderingContext* HTMLCanvasElement::GetCanvasRenderingContextInternal(
+    const String& type,
+    const CanvasContextCreationAttributesCore& attributes) {
   CanvasRenderingContext::ContextType context_type =
       CanvasRenderingContext::ContextTypeFromId(type);
 
@@ -1386,10 +1396,12 @@
 
 void HTMLCanvasElement::RegisterContentsLayer(cc::Layer* layer) {
   GraphicsLayer::RegisterContentsLayer(layer);
+  OnContentsCcLayerChanged();
 }
 
 void HTMLCanvasElement::UnregisterContentsLayer(cc::Layer* layer) {
   GraphicsLayer::UnregisterContentsLayer(layer);
+  OnContentsCcLayerChanged();
 }
 
 FontSelector* HTMLCanvasElement::GetFontSelector() {
@@ -1494,4 +1506,20 @@
           type == CanvasRenderingContext::kContextXRPresent);
 }
 
+cc::Layer* HTMLCanvasElement::ContentsCcLayer() const {
+  if (surface_layer_bridge_)
+    return surface_layer_bridge_->GetCcLayer();
+  if (context_ && context_->IsComposited())
+    return context_->CcLayer();
+  return nullptr;
+}
+
+void HTMLCanvasElement::OnContentsCcLayerChanged() {
+  // We need to repaint the layer because the foreign layer display item may
+  // appear, disappear or change.
+  if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
+      GetLayoutObject() && GetLayoutObject()->HasLayer())
+    GetLayoutBoxModelObject()->Layer()->SetNeedsRepaint();
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/html/canvas/html_canvas_element.h b/third_party/blink/renderer/core/html/canvas/html_canvas_element.h
index 6fdc3ad6..9f1eaa32 100644
--- a/third_party/blink/renderer/core/html/canvas/html_canvas_element.h
+++ b/third_party/blink/renderer/core/html/canvas/html_canvas_element.h
@@ -301,6 +301,11 @@
   scoped_refptr<StaticBitmapImage> Snapshot(SourceDrawingBuffer,
                                             AccelerationHint) const;
 
+  // Returns the cc layer containing the contents. It's the cc layer of
+  // SurfaceLayerBridge() or RenderingContext(), or nullptr if the canvas is not
+  // composited.
+  cc::Layer* ContentsCcLayer() const;
+
  protected:
   void DidMoveToNewDocument(Document& old_document) override;
 
@@ -340,6 +345,12 @@
   // ImageBitmapRenderingContextBase.
   bool HasImageBitmapContext() const;
 
+  CanvasRenderingContext* GetCanvasRenderingContextInternal(
+      const String&,
+      const CanvasContextCreationAttributesCore&);
+
+  void OnContentsCcLayerChanged();
+
   HeapHashSet<WeakMember<CanvasDrawListener>> listeners_;
 
   IntSize size_;
diff --git a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc
index d8582d74..88c74009 100644
--- a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc
+++ b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc
@@ -867,19 +867,11 @@
     graphics_layer_->SetContentsToCcLayer(
         media_element->CcLayer(),
         /*prevent_contents_opaque_changes=*/true);
-  } else if (IsSurfaceLayerCanvas(layout_object)) {
-    HTMLCanvasElement* canvas = ToHTMLCanvasElement(layout_object.GetNode());
+  } else if (layout_object.IsCanvas()) {
     graphics_layer_->SetContentsToCcLayer(
-        canvas->SurfaceLayerBridge()->GetCcLayer(),
+        ToHTMLCanvasElement(layout_object.GetNode())->ContentsCcLayer(),
         /*prevent_contents_opaque_changes=*/false);
     layer_config_changed = true;
-  } else if (IsTextureLayerCanvas(layout_object)) {
-    HTMLCanvasElement* canvas = ToHTMLCanvasElement(layout_object.GetNode());
-    if (CanvasRenderingContext* context = canvas->RenderingContext()) {
-      graphics_layer_->SetContentsToCcLayer(
-          context->CcLayer(), /*prevent_contents_opaque_changes=*/false);
-    }
-    layer_config_changed = true;
   }
   if (layout_object.IsLayoutEmbeddedContent()) {
     if (PaintLayerCompositor::AttachFrameContentLayersToIframeLayer(
diff --git a/third_party/blink/renderer/core/paint/html_canvas_painter.cc b/third_party/blink/renderer/core/paint/html_canvas_painter.cc
index e7154cb..d0f90bc 100644
--- a/third_party/blink/renderer/core/paint/html_canvas_painter.cc
+++ b/third_party/blink/renderer/core/paint/html_canvas_painter.cc
@@ -39,10 +39,8 @@
   HTMLCanvasElement* canvas =
       ToHTMLCanvasElement(layout_html_canvas_.GetNode());
 
-  if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
-      canvas->RenderingContext() &&
-      canvas->RenderingContext()->IsComposited()) {
-    if (cc::Layer* layer = canvas->RenderingContext()->CcLayer()) {
+  if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+    if (auto* layer = canvas->ContentsCcLayer()) {
       IntRect pixel_snapped_rect = PixelSnappedIntRect(paint_rect);
       layer->SetOffsetToTransformParent(
           gfx::Vector2dF(pixel_snapped_rect.X(), pixel_snapped_rect.Y()));
diff --git a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=CompositeAfterPaint b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=CompositeAfterPaint
index 3ef89fb..be4de0e0 100644
--- a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=CompositeAfterPaint
+++ b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=CompositeAfterPaint
@@ -174,20 +174,6 @@
 Bug(none) compositing/visibility/visibility-image-layers-dynamic.html [ Crash Failure ]
 Bug(none) compositing/webgl/webgl-reflection.html [ Failure Pass ]
 Bug(none) compositing/webgl/webgl-with-accelerated-background-color.html [ Failure Pass ]
-Bug(none) fast/canvas/OffscreenCanvas-2d-drawImage-in-worker.html [ Failure ]
-Bug(none) fast/canvas/OffscreenCanvas-2d-drawImage.html [ Failure ]
-Bug(none) fast/canvas/OffscreenCanvas-2d-gradients-in-worker.html [ Failure ]
-Bug(none) fast/canvas/OffscreenCanvas-2d-imageSmoothing-in-worker.html [ Failure ]
-Bug(none) fast/canvas/OffscreenCanvas-2d-pattern-in-worker.html [ Failure ]
-Bug(none) fast/canvas/OffscreenCanvas-2d-pattern.html [ Failure ]
-Bug(none) fast/canvas/OffscreenCanvas-clearRect-in-worker.html [ Failure ]
-Bug(none) fast/canvas/OffscreenCanvas-fillRect-in-worker.html [ Failure ]
-Bug(none) fast/canvas/OffscreenCanvas-filter-in-worker.html [ Failure ]
-Bug(none) fast/canvas/OffscreenCanvas-paths-in-worker.html [ Failure ]
-Bug(none) fast/canvas/OffscreenCanvas-strokeRect-in-worker.html [ Failure ]
-Bug(none) fast/canvas/OffscreenCanvas-text-FontFace-in-worker.html [ Failure ]
-Bug(none) fast/canvas/OffscreenCanvas-text-rendering-in-worker.html [ Failure ]
-Bug(none) fast/canvas/OffscreenCanvas-transform-shadow-in-worker.html [ Failure ]
 Bug(none) fast/css/outline-offset-large.html [ Failure ]
 Bug(none) fast/events/keyboard-scroll-by-page.html [ Failure ]
 Bug(none) fast/events/platform-wheelevent-paging-x-in-scrolling-page.html [ Failure ]