Commit d7fb6a61 authored by Xianzhu Wang's avatar Xianzhu Wang Committed by Commit Bot

[CompositeAfterPaint] Fix full screen overlay

In pre-CAP, when there is a full screen overlay layer, during paint, we
start from the overlay layer and ignore all other layers.

This CL let CAP do the equivalent thing: during paint, if there is
full screen overlay element, starts painting from the element instead of
from the top level frame.

Bug: 1031922
Change-Id: I7b0a25926e75bb12a475ecdb891f33d2634b8812
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2248487Reviewed-by: default avatarPhilip Rogers <pdr@chromium.org>
Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#779500}
parent 6d02a596
...@@ -77,6 +77,7 @@ ...@@ -77,6 +77,7 @@
#include "third_party/blink/renderer/core/html/forms/text_control_element.h" #include "third_party/blink/renderer/core/html/forms/text_control_element.h"
#include "third_party/blink/renderer/core/html/html_frame_element.h" #include "third_party/blink/renderer/core/html/html_frame_element.h"
#include "third_party/blink/renderer/core/html/html_plugin_element.h" #include "third_party/blink/renderer/core/html/html_plugin_element.h"
#include "third_party/blink/renderer/core/html/media/html_video_element.h"
#include "third_party/blink/renderer/core/html/parser/text_resource_decoder.h" #include "third_party/blink/renderer/core/html/parser/text_resource_decoder.h"
#include "third_party/blink/renderer/core/html/portal/document_portals.h" #include "third_party/blink/renderer/core/html/portal/document_portals.h"
#include "third_party/blink/renderer/core/html/portal/html_portal_element.h" #include "third_party/blink/renderer/core/html/portal/html_portal_element.h"
...@@ -122,6 +123,7 @@ ...@@ -122,6 +123,7 @@
#include "third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h" #include "third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h"
#include "third_party/blink/renderer/core/paint/frame_painter.h" #include "third_party/blink/renderer/core/paint/frame_painter.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/paint/paint_layer.h"
#include "third_party/blink/renderer/core/paint/paint_layer_painter.h"
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
#include "third_party/blink/renderer/core/paint/paint_timing.h" #include "third_party/blink/renderer/core/paint/paint_timing.h"
#include "third_party/blink/renderer/core/paint/paint_timing_detector.h" #include "third_party/blink/renderer/core/paint/paint_timing_detector.h"
...@@ -2839,29 +2841,44 @@ void LocalFrameView::PaintTree() { ...@@ -2839,29 +2841,44 @@ void LocalFrameView::PaintTree() {
BuildDarkModeSettings(*settings, *GetLayoutView())); BuildDarkModeSettings(*settings, *GetLayoutView()));
} }
PaintInternal(graphics_context, kGlobalPaintNormalPhase, bool painted_full_screen_overlay = false;
CullRect::Infinite()); if (frame_->IsMainFrame()) {
PaintLayer* full_screen_layer = GetFullScreenOverlayLayer();
if (full_screen_layer) {
PaintLayerPainter(*full_screen_layer)
.Paint(graphics_context, CullRect::Infinite(),
kGlobalPaintNormalPhase, 0);
painted_full_screen_overlay = true;
visual_viewport_needs_repaint_ = false;
}
}
GetPage()->GetLinkHighlight().Paint(graphics_context); if (!painted_full_screen_overlay) {
PaintInternal(graphics_context, kGlobalPaintNormalPhase,
CullRect::Infinite());
GetPage()->GetValidationMessageClient().PaintOverlay(graphics_context); GetPage()->GetValidationMessageClient().PaintOverlay(graphics_context);
ForAllNonThrottledLocalFrameViews( ForAllNonThrottledLocalFrameViews(
[&graphics_context](LocalFrameView& view) { [&graphics_context](LocalFrameView& view) {
view.frame_->PaintFrameColorOverlay(graphics_context); view.frame_->PaintFrameColorOverlay(graphics_context);
}); });
// Devtools overlays query the inspected page's paint data so this update // Devtools overlays query the inspected page's paint data so this
// needs to be after other paintings. // update needs to be after other paintings.
if (has_dev_tools_overlays) if (has_dev_tools_overlays)
web_local_frame_impl->PaintDevToolsOverlays(graphics_context); web_local_frame_impl->PaintDevToolsOverlays(graphics_context);
if (frame_->IsMainFrame()) { if (frame_->IsMainFrame()) {
frame_->GetPage()->GetVisualViewport().Paint(graphics_context); frame_->GetPage()->GetVisualViewport().Paint(graphics_context);
visual_viewport_needs_repaint_ = false; visual_viewport_needs_repaint_ = false;
} else { }
DCHECK(!visual_viewport_needs_repaint_);
} }
// Link highlights paint after all other paintings.
GetPage()->GetLinkHighlight().Paint(graphics_context);
DCHECK(!visual_viewport_needs_repaint_);
paint_controller_->CommitNewDisplayItems(); paint_controller_->CommitNewDisplayItems();
} }
} else { } else {
...@@ -4599,4 +4616,52 @@ StickyAdDetector& LocalFrameView::EnsureStickyAdDetector() { ...@@ -4599,4 +4616,52 @@ StickyAdDetector& LocalFrameView::EnsureStickyAdDetector() {
return *sticky_ad_detector_.get(); return *sticky_ad_detector_.get();
} }
static PaintLayer* GetFullScreenOverlayVideoLayer(Document& document) {
// Recursively find the document that is in fullscreen.
Document* content_document = &document;
Element* fullscreen_element =
Fullscreen::FullscreenElementFrom(*content_document);
while (auto* frame_owner =
DynamicTo<HTMLFrameOwnerElement>(fullscreen_element)) {
content_document = frame_owner->contentDocument();
if (!content_document)
return nullptr;
fullscreen_element = Fullscreen::FullscreenElementFrom(*content_document);
}
auto* video_element = DynamicTo<HTMLVideoElement>(fullscreen_element);
if (!video_element || !video_element->UsesOverlayFullscreenVideo())
return nullptr;
return video_element->GetLayoutBoxModelObject()->Layer();
}
static PaintLayer* GetXrOverlayLayer(Document& document) {
// immersive-ar DOM overlay mode is very similar to fullscreen video, using
// the AR camera image instead of a video element as a background that's
// separately composited in the browser. The fullscreened DOM content is shown
// on top of that, same as HTML video controls.
if (!document.IsXrOverlay())
return nullptr;
Element* fullscreen_element = Fullscreen::FullscreenElementFrom(document);
if (!fullscreen_element)
return nullptr;
const auto* object = fullscreen_element->GetLayoutBoxModelObject();
if (!object) {
// Currently, only HTML fullscreen elements are supported for this mode,
// not others such as SVG or MathML.
DVLOG(1) << "no LayoutBoxModelObject for element " << fullscreen_element;
return nullptr;
}
return object->Layer();
}
PaintLayer* LocalFrameView::GetFullScreenOverlayLayer() const {
DCHECK(frame_->IsMainFrame());
if (auto* layer = GetXrOverlayLayer(*frame_->GetDocument()))
return layer;
return GetFullScreenOverlayVideoLayer(*frame_->GetDocument());
}
} // namespace blink } // namespace blink
...@@ -702,6 +702,8 @@ class CORE_EXPORT LocalFrameView final ...@@ -702,6 +702,8 @@ class CORE_EXPORT LocalFrameView final
bool HasDominantVideoElement() const; bool HasDominantVideoElement() const;
PaintLayer* GetFullScreenOverlayLayer() const;
protected: protected:
void FrameRectsChanged(const IntRect&) override; void FrameRectsChanged(const IntRect&) override;
void SelfVisibleChanged() override; void SelfVisibleChanged() override;
......
...@@ -38,9 +38,7 @@ ...@@ -38,9 +38,7 @@
#include "third_party/blink/renderer/core/frame/settings.h" #include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/fullscreen/fullscreen.h" #include "third_party/blink/renderer/core/fullscreen/fullscreen.h"
#include "third_party/blink/renderer/core/html/html_iframe_element.h" #include "third_party/blink/renderer/core/html/html_iframe_element.h"
#include "third_party/blink/renderer/core/html/media/html_video_element.h"
#include "third_party/blink/renderer/core/layout/layout_embedded_content.h" #include "third_party/blink/renderer/core/layout/layout_embedded_content.h"
#include "third_party/blink/renderer/core/layout/layout_video.h"
#include "third_party/blink/renderer/core/layout/layout_view.h" #include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/page/chrome_client.h" #include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/core/page/page.h"
...@@ -99,23 +97,6 @@ void PaintLayerCompositor::UpdateAcceleratedCompositingSettings() { ...@@ -99,23 +97,6 @@ void PaintLayerCompositor::UpdateAcceleratedCompositingSettings() {
root_layer->SetNeedsCompositingInputsUpdate(); root_layer->SetNeedsCompositingInputsUpdate();
} }
static LayoutVideo* FindFullscreenVideoLayoutObject(Document& document) {
// Recursively find the document that is in fullscreen.
Element* fullscreen_element = Fullscreen::FullscreenElementFrom(document);
Document* content_document = &document;
while (auto* frame_owner =
DynamicTo<HTMLFrameOwnerElement>(fullscreen_element)) {
content_document = frame_owner->contentDocument();
if (!content_document)
return nullptr;
fullscreen_element = Fullscreen::FullscreenElementFrom(*content_document);
}
if (!IsA<HTMLVideoElement>(fullscreen_element))
return nullptr;
LayoutObject* layout_object = fullscreen_element->GetLayoutObject();
return To<LayoutVideo>(layout_object);
}
void PaintLayerCompositor::UpdateIfNeededRecursive( void PaintLayerCompositor::UpdateIfNeededRecursive(
DocumentLifecycle::LifecycleState target_state) { DocumentLifecycle::LifecycleState target_state) {
CompositingReasonsStats compositing_reasons_stats; CompositingReasonsStats compositing_reasons_stats;
...@@ -231,18 +212,6 @@ void PaintLayerCompositor::SetNeedsCompositingUpdate( ...@@ -231,18 +212,6 @@ void PaintLayerCompositor::SetNeedsCompositingUpdate(
Lifecycle().EnsureStateAtMost(DocumentLifecycle::kLayoutClean); Lifecycle().EnsureStateAtMost(DocumentLifecycle::kLayoutClean);
} }
GraphicsLayer* PaintLayerCompositor::OverlayFullscreenVideoGraphicsLayer()
const {
LayoutVideo* video =
FindFullscreenVideoLayoutObject(layout_view_.GetDocument());
if (!video || !video->Layer()->HasCompositedLayerMapping() ||
!video->VideoElement()->UsesOverlayFullscreenVideo()) {
return nullptr;
}
return video->Layer()->GetCompositedLayerMapping()->MainGraphicsLayer();
}
void PaintLayerCompositor::UpdateWithoutAcceleratedCompositing( void PaintLayerCompositor::UpdateWithoutAcceleratedCompositing(
CompositingUpdateType update_type) { CompositingUpdateType update_type) {
DCHECK(!layout_view_.GetDocument() DCHECK(!layout_view_.GetDocument()
...@@ -548,36 +517,6 @@ GraphicsLayer* PaintLayerCompositor::RootGraphicsLayer() const { ...@@ -548,36 +517,6 @@ GraphicsLayer* PaintLayerCompositor::RootGraphicsLayer() const {
return nullptr; return nullptr;
} }
GraphicsLayer* PaintLayerCompositor::GetXrOverlayLayer() const {
// immersive-ar DOM overlay mode is very similar to fullscreen video, using
// the AR camera image instead of a video element as a background that's
// separately composited in the browser. The fullscreened DOM content is shown
// on top of that, same as HTML video controls.
DCHECK(IsMainFrame());
if (!layout_view_.GetDocument().IsXrOverlay())
return nullptr;
Element* fullscreen_element =
Fullscreen::FullscreenElementFrom(layout_view_.GetDocument());
if (!fullscreen_element)
return nullptr;
LayoutBoxModelObject* box = fullscreen_element->GetLayoutBoxModelObject();
if (!box) {
// Currently, only HTML fullscreen elements are supported for this mode,
// not others such as SVG or MathML.
DVLOG(1) << "no LayoutBoxModelObject for element " << fullscreen_element;
return nullptr;
}
// The fullscreen element will be in its own layer due to
// CompositingReasonFinder treating this scenario as a direct_reason.
PaintLayer* layer = box->Layer();
DCHECK(layer);
GraphicsLayer* full_screen_layer = layer->GraphicsLayerBacking(box);
return full_screen_layer;
}
GraphicsLayer* PaintLayerCompositor::PaintRootGraphicsLayer() const { GraphicsLayer* PaintLayerCompositor::PaintRootGraphicsLayer() const {
if (layout_view_.GetDocument().GetPage()->GetChromeClient().IsPopup() || if (layout_view_.GetDocument().GetPage()->GetChromeClient().IsPopup() ||
!IsMainFrame()) !IsMainFrame())
...@@ -585,10 +524,11 @@ GraphicsLayer* PaintLayerCompositor::PaintRootGraphicsLayer() const { ...@@ -585,10 +524,11 @@ GraphicsLayer* PaintLayerCompositor::PaintRootGraphicsLayer() const {
// Start from the full screen overlay layer if exists. Other layers will be // Start from the full screen overlay layer if exists. Other layers will be
// skipped during painting. // skipped during painting.
if (auto* layer = GetXrOverlayLayer()) if (PaintLayer* layer =
return layer; layout_view_.GetFrameView()->GetFullScreenOverlayLayer()) {
if (auto* layer = OverlayFullscreenVideoGraphicsLayer()) if (layer->HasCompositedLayerMapping())
return layer; return layer->GetCompositedLayerMapping()->MainGraphicsLayer();
}
return RootGraphicsLayer(); return RootGraphicsLayer();
} }
......
...@@ -173,8 +173,6 @@ class CORE_EXPORT PaintLayerCompositor { ...@@ -173,8 +173,6 @@ class CORE_EXPORT PaintLayerCompositor {
ScrollingCoordinator* GetScrollingCoordinator() const; ScrollingCoordinator* GetScrollingCoordinator() const;
GraphicsLayer* OverlayFullscreenVideoGraphicsLayer() const;
// Checks the given graphics layer against the compositor's horizontal and // Checks the given graphics layer against the compositor's horizontal and
// vertical scrollbar graphics layers, returning the associated Scrollbar // vertical scrollbar graphics layers, returning the associated Scrollbar
// instance if any, else nullptr. // instance if any, else nullptr.
...@@ -182,8 +180,6 @@ class CORE_EXPORT PaintLayerCompositor { ...@@ -182,8 +180,6 @@ class CORE_EXPORT PaintLayerCompositor {
bool IsMainFrame() const; bool IsMainFrame() const;
GraphicsLayer* GetXrOverlayLayer() const;
LayoutView& layout_view_; LayoutView& layout_view_;
bool compositing_ = false; bool compositing_ = false;
......
...@@ -46,11 +46,8 @@ paint/invalidation/compositing/subpixel-offset-scaled-transform-composited.html ...@@ -46,11 +46,8 @@ paint/invalidation/compositing/subpixel-offset-scaled-transform-composited.html
crbug.com/957674 external/wpt/largest-contentful-paint/invisible-images-composited-2.html [ Pass ] crbug.com/957674 external/wpt/largest-contentful-paint/invisible-images-composited-2.html [ Pass ]
crbug.com/957674 virtual/scalefactor200/external/wpt/largest-contentful-paint/invisible-images-composited-2.html [ Pass ] crbug.com/957674 virtual/scalefactor200/external/wpt/largest-contentful-paint/invisible-images-composited-2.html [ Pass ]
virtual/android/fullscreen/video-overlay-scroll.html [ Failure ]
external/wpt/css/css-transforms/transform3d-backface-visibility-006.html [ Failure ] external/wpt/css/css-transforms/transform3d-backface-visibility-006.html [ Failure ]
external/wpt/css/filter-effects/effect-reference-feimage-002.html [ Failure ] external/wpt/css/filter-effects/effect-reference-feimage-002.html [ Failure ]
fullscreen/compositor-touch-hit-rects-fullscreen-video-controls.html [ Failure ]
printing/fixed-positioned-headers-and-footers-absolute-covering-some-pages.html [ Failure ] printing/fixed-positioned-headers-and-footers-absolute-covering-some-pages.html [ Failure ]
printing/fixed-positioned-headers-and-footers-larger-than-page.html [ Failure ] printing/fixed-positioned-headers-and-footers-larger-than-page.html [ Failure ]
...@@ -66,9 +63,6 @@ paint/invalidation/raster-under-invalidation-checking.html [ Failure ] ...@@ -66,9 +63,6 @@ paint/invalidation/raster-under-invalidation-checking.html [ Failure ]
# No composited scrolling for overflow:hidden (on marquee). # No composited scrolling for overflow:hidden (on marquee).
compositing/overflow/do-not-repaint-if-scrolling-composited-layers.html [ Failure ] compositing/overflow/do-not-repaint-if-scrolling-composited-layers.html [ Failure ]
# Subpixel or invisible color differences that look benign, but we can't rebaseline ref tests.
fullscreen/rendering/backdrop-object.html [ Failure ]
# Passes on bot, timeouts locally. # Passes on bot, timeouts locally.
virtual/threaded/fast/events/pinch/scroll-visual-viewport-send-boundary-events.html [ Pass Timeout ] virtual/threaded/fast/events/pinch/scroll-visual-viewport-send-boundary-events.html [ Pass Timeout ]
...@@ -80,8 +74,5 @@ http/tests/devtools/layers/layer-scroll-rects-get.js [ Failure ] ...@@ -80,8 +74,5 @@ http/tests/devtools/layers/layer-scroll-rects-get.js [ Failure ]
# Outline paints incorrectly with columns. # Outline paints incorrectly with columns.
crbug.com/1047358 paint/pagination/composited-paginated-outlined-box.html [ Failure ] crbug.com/1047358 paint/pagination/composited-paginated-outlined-box.html [ Failure ]
# Ad frame highlight size is incorrect
crbug.com/1047359 http/tests/subresource_filter/ad-highlight-frame-resized.html [ Failure ]
compositing/gestures/gesture-tapHighlight-composited-img.html [ Pass Failure ] compositing/gestures/gesture-tapHighlight-composited-img.html [ Pass Failure ]
http/tests/images/image-decode-in-frame.html [ Pass Failure ] http/tests/images/image-decode-in-frame.html [ Pass Failure ]
This test makes sure that touch hit rects are reported for fullscreen HTML5 video control elements even when there is a document handler.
Should have single rect on document before fullscreen
handler: layer(800x600) has hit test rect (0,0 800x600)
handler: layer(800x600) has hit test rect (0,0 800x600)
EVENT(webkitfullscreenchange)
Should keep rect on document
handler: layer(800x600) has hit test rect (0,0 800x600)
handler: layer(800x600) has hit test rect (0,0 800x600)
handler: layer(800x600) has hit test rect (0,0 800x600)
END OF TEST
{
"layers": [
{
"name": "LayoutNGFlexibleBox (relative positioned) DIV class='phase-pre-ready state-no-source sizing-small use-default-poster'",
"bounds": [800, 600],
"contentsOpaque": true,
"backgroundColor": "#333333"
}
]
}
<!DOCTYPE html> <!DOCTYPE html>
<style> <style>
body { body {
background: green; background: blue;
margin: 0; margin: 0;
} }
object { div {
position: fixed; position: fixed;
width: 100%; width: 100px;
height: 100%; height: 100px;
background: green;
} }
</style> </style>
<object width="200" type="image/svg+xml" data="../../svg/as-image/resources/circle.svg"></object> <div></div>
...@@ -3,10 +3,10 @@ ...@@ -3,10 +3,10 @@
<script src="../trusted-click.js"></script> <script src="../trusted-click.js"></script>
<style> <style>
object::backdrop { object::backdrop {
background: green; background: blue;
} }
</style> </style>
<object width="200" type="image/svg+xml" data="../../svg/as-image/resources/circle.svg"></object> <object width="200" type="image/svg+xml" data="../../svg/as-image/resources/100px-green-rect.svg"></object>
<script> <script>
var object = document.querySelector("object"); var object = document.querySelector("object");
Promise.all([ Promise.all([
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment