Index: Source/web/tests/WebViewTest.cpp |
diff --git a/Source/web/tests/WebViewTest.cpp b/Source/web/tests/WebViewTest.cpp |
index 1831bbe43c06effba0934b0b0e87fa47c335c3e9..7048e22e0dedcd4e866142e2fefb264aff1aa685 100644 |
--- a/Source/web/tests/WebViewTest.cpp |
+++ b/Source/web/tests/WebViewTest.cpp |
@@ -45,11 +45,15 @@ |
#include "core/html/HTMLInputElement.h" |
#include "core/html/HTMLTextAreaElement.h" |
#include "core/layout/LayoutView.h" |
+#include "core/loader/DocumentLoader.h" |
#include "core/loader/FrameLoadRequest.h" |
#include "core/page/Chrome.h" |
#include "core/page/Page.h" |
#include "core/paint/DeprecatedPaintLayer.h" |
#include "core/paint/DeprecatedPaintLayerPainter.h" |
+#include "core/timing/DOMWindowPerformance.h" |
+#include "core/timing/Performance.h" |
+#include "core/timing/PerformanceCompositeTiming.h" |
#include "platform/KeyboardCodes.h" |
#include "platform/UserGestureIndicator.h" |
#include "platform/geometry/IntSize.h" |
@@ -91,6 +95,7 @@ |
using namespace blink; |
using blink::FrameTestHelpers::loadFrame; |
using blink::URLTestHelpers::toKURL; |
+using blink::URLTestHelpers::registerMockedURLLoad; |
using blink::testing::runPendingTasks; |
namespace { |
@@ -2750,4 +2755,241 @@ TEST_F(WebViewTest, ShowUnhandledTapUIIfNeededWithPreventDefault) |
m_webViewHelper.reset(); // Remove dependency on locally scoped client. |
} |
+// Test 3 frames, all on the same layer (i.e. [1 2 3]) |
+TEST_F(WebViewTest, TestPushFrameTimingRequestRectsToGraphicsLayer1) |
+{ |
+ std::string url = m_baseURL + "frame_timing_inner.html?100px:100px"; |
+ registerMockedURLLoad(toKURL(url), "frame_timing_inner.html"); |
+ url = m_baseURL + "frame_timing_inner.html?200px:200px"; |
+ registerMockedURLLoad(toKURL(url), "frame_timing_inner.html"); |
+ url = m_baseURL + "frame_timing_inner.html?300px:300px"; |
+ registerMockedURLLoad(toKURL(url), "frame_timing_inner.html"); |
+ url = m_baseURL + "frame_timing_1.html"; |
+ registerMockedURLLoad(toKURL(url), "frame_timing_1.html"); |
+ |
+ WebView* webView = m_webViewHelper.initialize(true); |
+ loadFrame(webView->mainFrame(), url); |
+ |
+ webView->resize(WebSize(800, 600)); |
+ webView->layout(); |
+ |
+ WebViewImpl* webViewImpl = toWebViewImpl(webView); |
+ |
+ Frame* frame = webViewImpl->page()->mainFrame(); |
+ int64_t id = frame->frameID(); |
+ |
+ EXPECT_EQ(3u, frame->tree().childCount()); |
+ |
+ WebVector<std::pair<int64_t, WebRect>> frameTimingRequests = |
+ toLocalFrame(frame)->document() |
+ ->layoutView()->enclosingLayer() |
+ ->enclosingLayerForPaintInvalidationCrossingFrameBoundaries() |
+ ->graphicsLayerBacking()->platformLayer()->frameTimingRequests(); |
+ |
+ EXPECT_EQ(4u, frameTimingRequests.size()); |
+ EXPECT_EQ(id + 0, frameTimingRequests[0].first); |
+ EXPECT_EQ(WebRect(0, 0, 800, 600), frameTimingRequests[0].second); |
+ EXPECT_EQ(id + 1, frameTimingRequests[1].first); |
+ EXPECT_EQ(WebRect(2, 2, 100, 100), frameTimingRequests[1].second); |
+ EXPECT_EQ(id + 2, frameTimingRequests[2].first); |
+ EXPECT_EQ(WebRect(106, 2, 200, 200), frameTimingRequests[2].second); |
+ EXPECT_EQ(id + 3, frameTimingRequests[3].first); |
+ EXPECT_EQ(WebRect(310, 2, 300, 300), frameTimingRequests[3].second); |
+} |
+ |
+// Test 3 frames, where frame 2 is on a different GraphicsLayer (i.e. [1 2' 3]) |
+TEST_F(WebViewTest, TestPushFrameTimingRequestRectsToGraphicsLayer2) |
+{ |
+ std::string url = m_baseURL + "frame_timing_inner.html?100px:100px"; |
+ registerMockedURLLoad(toKURL(url), "frame_timing_inner.html"); |
+ url = m_baseURL + "frame_timing_inner.html?200px:200px"; |
+ registerMockedURLLoad(toKURL(url), "frame_timing_inner.html"); |
+ url = m_baseURL + "frame_timing_inner.html?300px:300px"; |
+ registerMockedURLLoad(toKURL(url), "frame_timing_inner.html"); |
+ url = m_baseURL + "frame_timing_2.html"; |
+ registerMockedURLLoad(toKURL(url), "frame_timing_2.html"); |
+ |
+ WebView* webView = m_webViewHelper.initialize(true); |
+ loadFrame(webView->mainFrame(), url); |
+ |
+ webView->resize(WebSize(800, 600)); |
+ webView->layout(); |
+ |
+ WebViewImpl* webViewImpl = toWebViewImpl(webView); |
+ |
+ Frame* frame = webViewImpl->page()->mainFrame(); |
+ int64_t id = frame->frameID(); |
+ |
+ EXPECT_EQ(3u, frame->tree().childCount()); |
+ |
+ const WebLayer* graphicsLayer1 = |
+ toLocalFrame(webViewImpl->page()->mainFrame())->document() |
+ ->layoutView()->enclosingLayer() |
+ ->enclosingLayerForPaintInvalidationCrossingFrameBoundaries() |
+ ->graphicsLayerBacking()->platformLayer(); |
+ WebVector<std::pair<int64_t, WebRect>> frameTimingRequests1 = |
+ graphicsLayer1->frameTimingRequests(); |
+ |
+ EXPECT_EQ(3u, frameTimingRequests1.size()); |
+ EXPECT_EQ(id + 0, frameTimingRequests1[0].first); |
+ EXPECT_EQ(WebRect(0, 0, 800, 600), frameTimingRequests1[0].second); |
+ EXPECT_EQ(id + 1, frameTimingRequests1[1].first); |
+ EXPECT_EQ(WebRect(2, 2, 100, 100), frameTimingRequests1[1].second); |
+ EXPECT_EQ(id + 3, frameTimingRequests1[2].first); |
+ EXPECT_EQ(WebRect(310, 2, 300, 300), frameTimingRequests1[2].second); |
+ |
+ const WebLayer* graphicsLayer2 = nullptr; |
+ for (Frame* frame = webViewImpl->page()->mainFrame(); frame; |
+ frame = frame->tree().traverseNext()) { |
+ graphicsLayer2 = toLocalFrame(frame)->document()->layoutView() |
+ ->enclosingLayer() |
+ ->enclosingLayerForPaintInvalidationCrossingFrameBoundaries() |
+ ->graphicsLayerBacking()->platformLayer(); |
+ if (graphicsLayer2 != graphicsLayer1) |
+ break; |
+ } |
+ WebVector<std::pair<int64_t, WebRect>> frameTimingRequests2 = |
+ graphicsLayer2->frameTimingRequests(); |
+ EXPECT_EQ(1u, frameTimingRequests2.size()); |
+ EXPECT_EQ(id + 2, frameTimingRequests2[0].first); |
+ EXPECT_EQ(WebRect(2, 2, 200, 200), frameTimingRequests2[0].second); |
+} |
+ |
+ |
+// Test nested frames (i.e. [1 2'[4 5'] 3]) |
+TEST_F(WebViewTest, TestPushFrameTimingRequestRectsToGraphicsLayer3) |
+{ |
+ std::string url = m_baseURL + "frame_timing_inner.html?100px:100px"; |
+ registerMockedURLLoad(toKURL(url), "frame_timing_inner.html"); |
+ url = m_baseURL + "frame_timing_inner.html?200px:200px"; |
+ registerMockedURLLoad(toKURL(url), "frame_timing_inner.html"); |
+ url = m_baseURL + "frame_timing_inner.html?300px:300px"; |
+ registerMockedURLLoad(toKURL(url), "frame_timing_inner.html"); |
+ url = m_baseURL + "frame_timing_b.html"; |
+ registerMockedURLLoad(toKURL(url), "frame_timing_b.html"); |
+ url = m_baseURL + "frame_timing_3.html"; |
+ registerMockedURLLoad(toKURL(url), "frame_timing_3.html"); |
+ |
+ WebView* webView = m_webViewHelper.initialize(true); |
+ loadFrame(webView->mainFrame(), url); |
+ |
+ webView->resize(WebSize(800, 600)); |
+ webView->layout(); |
+ |
+ WebViewImpl* webViewImpl = toWebViewImpl(webView); |
+ |
+ Frame* frame = webViewImpl->page()->mainFrame(); |
+ int64_t id = frame->frameID(); |
+ |
+ EXPECT_EQ(3u, frame->tree().childCount()); |
+ |
+ const WebLayer* graphicsLayer1 = |
+ toLocalFrame(webViewImpl->page()->mainFrame())->document() |
+ ->layoutView()->enclosingLayer() |
+ ->enclosingLayerForPaintInvalidationCrossingFrameBoundaries() |
+ ->graphicsLayerBacking()->platformLayer(); |
+ WebVector<std::pair<int64_t, WebRect>> frameTimingRequests1 = |
+ graphicsLayer1->frameTimingRequests(); |
+ |
+ EXPECT_EQ(3u, frameTimingRequests1.size()); |
+ EXPECT_EQ(id + 0, frameTimingRequests1[0].first); |
+ EXPECT_EQ(WebRect(0, 0, 800, 600), frameTimingRequests1[0].second); |
+ EXPECT_EQ(WebRect(2, 2, 100, 100), frameTimingRequests1[1].second); |
+ EXPECT_EQ(WebRect(410, 2, 200, 200), frameTimingRequests1[2].second); |
+ |
+ const WebLayer* graphicsLayer2 = nullptr; |
+ for (Frame* frame = webViewImpl->page()->mainFrame(); frame; |
+ frame = frame->tree().traverseNext()) { |
+ graphicsLayer2 = toLocalFrame(frame)->document()->layoutView() |
+ ->enclosingLayer() |
+ ->enclosingLayerForPaintInvalidationCrossingFrameBoundaries() |
+ ->graphicsLayerBacking()->platformLayer(); |
+ if (graphicsLayer2 != graphicsLayer1) |
+ break; |
+ } |
+ WebVector<std::pair<int64_t, WebRect>> frameTimingRequests2 = |
+ graphicsLayer2->frameTimingRequests(); |
+ EXPECT_EQ(2u, frameTimingRequests2.size()); |
+ EXPECT_EQ(WebRect(0, 0, 300, 300), frameTimingRequests2[0].second); |
+ EXPECT_EQ(WebRect(2, 2, 100, 100), frameTimingRequests2[1].second); |
+ |
+ const WebLayer* graphicsLayer3 = nullptr; |
+ for (Frame* frame = webViewImpl->page()->mainFrame(); frame; |
+ frame = frame->tree().traverseNext()) { |
+ graphicsLayer3 = toLocalFrame(frame)->document()->layoutView() |
+ ->enclosingLayer() |
+ ->enclosingLayerForPaintInvalidationCrossingFrameBoundaries() |
+ ->graphicsLayerBacking()->platformLayer(); |
+ if (graphicsLayer3 != graphicsLayer1 && graphicsLayer3 != graphicsLayer2) |
+ break; |
+ } |
+ WebVector<std::pair<int64_t, WebRect>> frameTimingRequests3 = |
+ graphicsLayer3->frameTimingRequests(); |
+ EXPECT_EQ(1u, frameTimingRequests3.size()); |
+ EXPECT_EQ(WebRect(2, 2, 100, 100), frameTimingRequests3[0].second); |
+} |
+ |
+// Test 3 frames, all on the same layer (i.e. [1 2 3]) |
+TEST_F(WebViewTest, TestRecordFrameTimingEvents) |
+{ |
+ std::string url = m_baseURL + "frame_timing_inner.html?100px:100px"; |
+ registerMockedURLLoad(toKURL(url), "frame_timing_inner.html"); |
+ url = m_baseURL + "frame_timing_inner.html?200px:200px"; |
+ registerMockedURLLoad(toKURL(url), "frame_timing_inner.html"); |
+ url = m_baseURL + "frame_timing_inner.html?300px:300px"; |
+ registerMockedURLLoad(toKURL(url), "frame_timing_inner.html"); |
+ url = m_baseURL + "frame_timing_1.html"; |
+ registerMockedURLLoad(toKURL(url), "frame_timing_1.html"); |
+ |
+ WebView* webView = m_webViewHelper.initialize(true); |
+ loadFrame(webView->mainFrame(), url); |
+ |
+ webView->resize(WebSize(800, 600)); |
+ webView->layout(); |
+ |
+ WebViewImpl* webViewImpl = toWebViewImpl(webView); |
+ |
+ Frame* frame = webViewImpl->page()->mainFrame(); |
+ int64_t id = frame->frameID(); |
+ |
+ std::vector<WebFrameTimingEvent> compositePairs(3); |
+ compositePairs[0] = WebFrameTimingEvent(1, 2.0); |
+ compositePairs[1] = WebFrameTimingEvent(2, 3.0); |
+ compositePairs[2] = WebFrameTimingEvent(3, 4.0); |
+ WebVector<WebFrameTimingEvent> compositeEvents(compositePairs); |
+ webViewImpl->recordFrameTimingEvent(WebView::CompositeEvent, id, compositeEvents); |
+ PerformanceEntryVector composites = DOMWindowPerformance::performance(*frame->domWindow())->getEntriesByType("composite"); |
+ PerformanceEntryVector renders = DOMWindowPerformance::performance(*frame->domWindow())->getEntriesByType("render"); |
+ ASSERT_EQ(3ul, composites.size()); |
+ ASSERT_EQ(0ul, renders.size()); |
+ for (size_t i = 0; i < composites.size(); ++i) { |
+ double docTime = frame->domWindow()->document()->loader()->timing().monotonicTimeToZeroBasedDocumentTime(compositePairs[i].startTime) * 1000.0; |
+ ASSERT_EQ(docTime, composites[i]->startTime()); |
+ } |
+ |
+ // Skip ahead to subframe 2. |
+ frame = frame->tree().traverseNext(); |
+ frame = frame->tree().traverseNext(); |
+ id += 2; |
+ |
+ std::vector<WebFrameTimingEvent> renderPairs(4); |
+ renderPairs[0] = WebFrameTimingEvent(4, 5.0, 6.0); |
+ renderPairs[1] =WebFrameTimingEvent(5, 6.0, 7.0); |
+ renderPairs[2] =WebFrameTimingEvent(6, 7.0, 8.0); |
+ renderPairs[3] =WebFrameTimingEvent(7, 8.0, 9.0); |
+ WebVector<WebFrameTimingEvent> renderEvents(renderPairs); |
+ webViewImpl->recordFrameTimingEvent(WebView::RenderEvent, id, renderEvents); |
+ composites = DOMWindowPerformance::performance(*frame->domWindow())->getEntriesByType("composite"); |
+ renders = DOMWindowPerformance::performance(*frame->domWindow())->getEntriesByType("render"); |
+ ASSERT_EQ(0ul, composites.size()); |
+ ASSERT_EQ(4ul, renders.size()); |
+ for (size_t i = 0; i < renders.size(); ++i) { |
+ double docStartTime = frame->domWindow()->document()->loader()->timing().monotonicTimeToZeroBasedDocumentTime(renderPairs[i].startTime) * 1000.0; |
+ ASSERT_DOUBLE_EQ(docStartTime, renders[i]->startTime()); |
+ double docFinishTime = frame->domWindow()->document()->loader()->timing().monotonicTimeToZeroBasedDocumentTime(renderPairs[i].finishTime) * 1000.0; |
+ double docDuration = docFinishTime - docStartTime; |
+ ASSERT_DOUBLE_EQ(docDuration, renders[i]->duration()); |
+ } |
+} |
+ |
} // namespace |