summaryrefslogtreecommitdiff
path: root/chromium/content/browser/renderer_host/compositor_impl_android_browsertest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/content/browser/renderer_host/compositor_impl_android_browsertest.cc')
-rw-r--r--chromium/content/browser/renderer_host/compositor_impl_android_browsertest.cc170
1 files changed, 170 insertions, 0 deletions
diff --git a/chromium/content/browser/renderer_host/compositor_impl_android_browsertest.cc b/chromium/content/browser/renderer_host/compositor_impl_android_browsertest.cc
new file mode 100644
index 00000000000..bfaadc54359
--- /dev/null
+++ b/chromium/content/browser/renderer_host/compositor_impl_android_browsertest.cc
@@ -0,0 +1,170 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/base_switches.h"
+#include "content/browser/browser_main_loop.h"
+#include "content/browser/gpu/gpu_process_host.h"
+#include "content/browser/renderer_host/compositor_impl_android.h"
+#include "content/browser/renderer_host/render_widget_host_view_android.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/common/gpu_stream_constants.h"
+#include "content/public/common/content_switches.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/content_browser_test.h"
+#include "content/public/test/content_browser_test_utils.h"
+#include "content/shell/browser/shell.h"
+#include "content/test/content_browser_test_utils_internal.h"
+#include "content/test/gpu_browsertest_helpers.h"
+#include "gpu/command_buffer/client/gles2_interface.h"
+#include "gpu/ipc/client/gpu_channel_host.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "ui/android/window_android.h"
+#include "url/gurl.h"
+
+namespace content {
+
+namespace {
+
+class CompositorImplLowEndBrowserTest : public ContentBrowserTest {
+ public:
+ CompositorImplLowEndBrowserTest() {}
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ command_line->AppendSwitch(switches::kEnableLowEndDeviceMode);
+ command_line->AppendSwitch(switches::kInProcessGPU);
+ content::ContentBrowserTest::SetUpCommandLine(command_line);
+ }
+
+ protected:
+ void SetUpOnMainThread() override {
+ ASSERT_TRUE(embedded_test_server()->Start());
+ net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
+ https_server.ServeFilesFromSourceDirectory("content/test/data");
+ ASSERT_TRUE(https_server.Start());
+ GURL http_url(embedded_test_server()->GetURL("/title1.html"));
+ ASSERT_TRUE(NavigateToURL(shell(), http_url));
+ }
+
+ ui::WindowAndroid* window() const {
+ return web_contents()->GetTopLevelNativeWindow();
+ }
+
+ CompositorImpl* compositor_impl() const {
+ return static_cast<CompositorImpl*>(window()->GetCompositor());
+ }
+
+ WebContentsImpl* web_contents() const {
+ return static_cast<WebContentsImpl*>(shell()->web_contents());
+ }
+
+ RenderWidgetHostViewAndroid* render_widget_host_view_android() const {
+ return static_cast<RenderWidgetHostViewAndroid*>(
+ web_contents()->GetRenderWidgetHostView());
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(CompositorImplLowEndBrowserTest);
+};
+
+// RunLoop implementation that calls glFlush() every second until it observes
+// OnContextLost().
+class ContextLostRunLoop : public viz::ContextLostObserver {
+ public:
+ ContextLostRunLoop(viz::ContextProvider* context_provider)
+ : context_provider_(context_provider) {
+ context_provider_->AddObserver(this);
+ }
+ ~ContextLostRunLoop() override { context_provider_->RemoveObserver(this); }
+
+ void RunUntilContextLost() {
+ CheckForContextLoss();
+ run_loop_.Run();
+ }
+
+ void CheckForContextLoss() {
+ if (did_lose_context_) {
+ run_loop_.Quit();
+ return;
+ }
+ context_provider_->ContextGL()->Flush();
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE,
+ base::BindOnce(&ContextLostRunLoop::CheckForContextLoss,
+ base::Unretained(this)),
+ base::TimeDelta::FromSeconds(1));
+ }
+
+ private:
+ // viz::LostContextProvider:
+ void OnContextLost() override { did_lose_context_ = true; }
+
+ viz::ContextProvider* const context_provider_;
+ bool did_lose_context_ = false;
+ base::RunLoop run_loop_;
+
+ DISALLOW_COPY_AND_ASSIGN(ContextLostRunLoop);
+};
+
+// RunLoop implementation that runs until it observes a compositor frame.
+class CompositorFrameRunLoop : public ui::WindowAndroidObserver {
+ public:
+ CompositorFrameRunLoop(ui::WindowAndroid* window) : window_(window) {
+ window_->AddObserver(this);
+ }
+ ~CompositorFrameRunLoop() override { window_->RemoveObserver(this); }
+
+ void RunUntilFrame() { run_loop_.Run(); }
+
+ private:
+ // ui::WindowAndroidObserver:
+ void OnCompositingDidCommit() override { run_loop_.Quit(); }
+ void OnRootWindowVisibilityChanged(bool visible) override {}
+ void OnAttachCompositor() override {}
+ void OnDetachCompositor() override {}
+ void OnActivityStopped() override {}
+ void OnActivityStarted() override {}
+
+ ui::WindowAndroid* const window_;
+ base::RunLoop run_loop_;
+
+ DISALLOW_COPY_AND_ASSIGN(CompositorFrameRunLoop);
+};
+
+IN_PROC_BROWSER_TEST_F(CompositorImplLowEndBrowserTest,
+ CompositorImplDropsResourcesOnBackground) {
+ auto* rwhva = render_widget_host_view_android();
+ auto* compositor = compositor_impl();
+ auto context = GpuBrowsertestCreateContext(
+ GpuBrowsertestEstablishGpuChannelSyncRunLoop());
+ context->BindToCurrentThread();
+
+ CompositorFrameRunLoop(window()).RunUntilFrame();
+ EXPECT_TRUE(rwhva->HasValidFrame());
+
+ ContextLostRunLoop run_loop(context.get());
+ compositor->SetVisibleForTesting(false);
+ rwhva->OnRootWindowVisibilityChanged(false);
+ rwhva->Hide();
+
+ // Ensure that context is eventually dropped and at that point we do not have
+ // a valid frame.
+ run_loop.RunUntilContextLost();
+ EXPECT_FALSE(rwhva->HasValidFrame());
+
+ // Become visible again:
+ compositor->SetVisibleForTesting(true);
+ rwhva->Show();
+ rwhva->OnRootWindowVisibilityChanged(true);
+
+ // We should have taken the compositor lock on resume.
+ EXPECT_TRUE(compositor->IsLockedForTesting());
+ EXPECT_FALSE(rwhva->HasValidFrame());
+
+ // The compositor should eventually be unlocked and produce a frame.
+ CompositorFrameRunLoop(window()).RunUntilFrame();
+ EXPECT_FALSE(compositor->IsLockedForTesting());
+ EXPECT_TRUE(rwhva->HasValidFrame());
+}
+
+} // namespace
+} // namespace content