Commit 79fb9f2d authored by Siddhartha's avatar Siddhartha Committed by Commit Bot

Add a delay to clear GL context when app is backgrounded

A common behavior on Android is for the user to press home or recents
button accidently and get back to the app. This behavior would cause
Chrome to clear the contexts and recreate which is a waste of time. So,
add a 5 second delay before clearing the context.
As a side effect, this delay also considerably lowers the risk of the
renderers initializing the GPU command buffer after clearing since they
usually receive the "not-visible" message within 5 seconds.

BUG=725303

Change-Id: I7d2655c75b66cf073b82c270baa3f1f3b27b3a8a
Reviewed-on: https://chromium-review.googlesource.com/571294
Commit-Queue: Siddhartha S <ssid@chromium.org>
Reviewed-by: default avatarMaria Khomenko <mariakhomenko@chromium.org>
Reviewed-by: default avatarEric Karl <ericrk@chromium.org>
Reviewed-by: default avatarKenneth Russell <kbr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#487539}
parent 583026b8
...@@ -78,6 +78,7 @@ GpuChannelManager::GpuChannelManager( ...@@ -78,6 +78,7 @@ GpuChannelManager::GpuChannelManager(
base::Bind(&GpuChannelManager::OnApplicationStateChange, base::Bind(&GpuChannelManager::OnApplicationStateChange,
base::Unretained(this))), base::Unretained(this))),
is_running_on_low_end_mode_(base::SysInfo::IsLowEndDevice()), is_running_on_low_end_mode_(base::SysInfo::IsLowEndDevice()),
is_backgrounded_for_testing_(false),
#endif #endif
exiting_for_lost_context_(false), exiting_for_lost_context_(false),
activity_flags_(std::move(activity_flags)), activity_flags_(std::move(activity_flags)),
...@@ -258,13 +259,31 @@ void GpuChannelManager::OnApplicationStateChange( ...@@ -258,13 +259,31 @@ void GpuChannelManager::OnApplicationStateChange(
return; return;
} }
if (!task_runner_->BelongsToCurrentThread()) { // Clear the GL context on low-end devices after a 5 second delay, so that we
task_runner_->PostTask( // don't clear in case the user pressed the home or recents button by mistake
FROM_HERE, base::Bind(&GpuChannelManager::OnApplicationStateChange, // and got back to Chrome quickly.
weak_factory_.GetWeakPtr(), state)); const int64_t kDelayToClearContextMs = 5000;
task_runner_->PostDelayedTask(
FROM_HERE,
base::Bind(&GpuChannelManager::OnApplicationBackgrounded,
weak_factory_.GetWeakPtr()),
base::TimeDelta::FromMilliseconds(kDelayToClearContextMs));
return;
}
void GpuChannelManager::OnApplicationBackgrounded() {
// Check if the app is still in background after the delay.
auto state = base::android::ApplicationStatusListener::GetState();
if (state != base::android::APPLICATION_STATE_HAS_STOPPED_ACTIVITIES &&
state != base::android::APPLICATION_STATE_HAS_DESTROYED_ACTIVITIES &&
!is_backgrounded_for_testing_) {
return; return;
} }
if (!is_running_on_low_end_mode_)
return;
// Delete all the GL contexts when the channel does not use WebGL and Chrome // Delete all the GL contexts when the channel does not use WebGL and Chrome
// goes to background on low-end devices. // goes to background on low-end devices.
std::vector<int> channels_to_clear; std::vector<int> channels_to_clear;
......
...@@ -145,12 +145,16 @@ class GPU_EXPORT GpuChannelManager { ...@@ -145,12 +145,16 @@ class GPU_EXPORT GpuChannelManager {
SyncPointManager* sync_point_manager() const { return sync_point_manager_; } SyncPointManager* sync_point_manager() const { return sync_point_manager_; }
private: private:
friend class GpuChannelManagerTest;
void InternalDestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id, int client_id); void InternalDestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id, int client_id);
void InternalDestroyGpuMemoryBufferOnIO(gfx::GpuMemoryBufferId id, void InternalDestroyGpuMemoryBufferOnIO(gfx::GpuMemoryBufferId id,
int client_id); int client_id);
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
void ScheduleWakeUpGpu(); void ScheduleWakeUpGpu();
void DoWakeUpGpu(); void DoWakeUpGpu();
void OnApplicationBackgrounded();
#endif #endif
void HandleMemoryPressure( void HandleMemoryPressure(
...@@ -195,6 +199,7 @@ class GPU_EXPORT GpuChannelManager { ...@@ -195,6 +199,7 @@ class GPU_EXPORT GpuChannelManager {
base::android::ApplicationStatusListener application_status_listener_; base::android::ApplicationStatusListener application_status_listener_;
bool is_running_on_low_end_mode_; bool is_running_on_low_end_mode_;
bool is_backgrounded_for_testing_;
#endif #endif
// Set during intentional GPU process shutdown. // Set during intentional GPU process shutdown.
......
...@@ -47,8 +47,8 @@ class GpuChannelManagerTest : public GpuChannelTestCommon { ...@@ -47,8 +47,8 @@ class GpuChannelManagerTest : public GpuChannelTestCommon {
GpuCommandBufferStub* stub = channel->LookupCommandBuffer(kRouteId); GpuCommandBufferStub* stub = channel->LookupCommandBuffer(kRouteId);
EXPECT_TRUE(stub); EXPECT_TRUE(stub);
channel_manager()->OnApplicationStateChange( channel_manager()->is_backgrounded_for_testing_ = true;
base::android::APPLICATION_STATE_HAS_STOPPED_ACTIVITIES); channel_manager()->OnApplicationBackgrounded();
stub = channel->LookupCommandBuffer(kRouteId); stub = channel->LookupCommandBuffer(kRouteId);
if (should_clear_stub) { if (should_clear_stub) {
EXPECT_FALSE(stub); EXPECT_FALSE(stub);
......
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