Commit a7888b8e authored by Khushal's avatar Khushal Committed by Commit Bot

gpu: Detect consecutive surface initialization failures on Android.

If we fail to initialize the GLSurface associated with an ANativeWindow
the error is propagated to the browser so we can retry with a new
window. Add tracking to detect consecutive failures with this retry
to avoid a perpetual retry loop.

R=boliu@chromium.org, ericrk@chromium.org

Bug: 972667
Change-Id: Ieaf0a7c7454f12ffbfa068e7c17c452857776ffd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1654233
Commit-Queue: Khushal <khushalsagar@chromium.org>
Auto-Submit: Khushal <khushalsagar@chromium.org>
Reviewed-by: default avatarBo <boliu@chromium.org>
Reviewed-by: default avatarEric Karl <ericrk@chromium.org>
Reviewed-by: default avatarTom Sepez <tsepez@chromium.org>
Cr-Commit-Position: refs/heads/master@{#668479}
parent 59dfa811
...@@ -167,17 +167,18 @@ std::unique_ptr<OutputSurface> OutputSurfaceProviderImpl::CreateOutputSurface( ...@@ -167,17 +167,18 @@ std::unique_ptr<OutputSurface> OutputSurfaceProviderImpl::CreateOutputSurface(
image_factory_, gpu_channel_manager_delegate_, renderer_settings); image_factory_, gpu_channel_manager_delegate_, renderer_settings);
context_result = context_provider->BindToCurrentThread(); context_result = context_provider->BindToCurrentThread();
if (IsFatalOrSurfaceFailure(context_result)) {
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
display_client->OnFatalOrSurfaceContextCreationFailure(context_result); display_client->OnContextCreationResult(context_result);
#elif defined(OS_CHROMEOS) || defined(IS_CHROMECAST) #endif
if (IsFatalOrSurfaceFailure(context_result)) {
#if defined(OS_CHROMEOS) || defined(IS_CHROMECAST)
// TODO(kylechar): Chrome OS can't disable GPU compositing. This needs // TODO(kylechar): Chrome OS can't disable GPU compositing. This needs
// to be handled similar to Android. // to be handled similar to Android.
CHECK(false); CHECK(false);
#else #elif !defined(OS_ANDROID)
gpu_service_impl_->DisableGpuCompositing(); gpu_service_impl_->DisableGpuCompositing();
#endif #endif
return nullptr; return nullptr;
} }
} }
......
...@@ -30,8 +30,7 @@ class MockDisplayClient : public mojom::DisplayClient { ...@@ -30,8 +30,7 @@ class MockDisplayClient : public mojom::DisplayClient {
#endif #endif
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
MOCK_METHOD1(DidCompleteSwapWithSize, void(const gfx::Size&)); MOCK_METHOD1(DidCompleteSwapWithSize, void(const gfx::Size&));
MOCK_METHOD1(OnFatalOrSurfaceContextCreationFailure, MOCK_METHOD1(OnContextCreationResult, void(gpu::ContextResult));
void(gpu::ContextResult));
MOCK_METHOD1(SetPreferredRefreshRate, void(float refresh_rate)); MOCK_METHOD1(SetPreferredRefreshRate, void(float refresh_rate));
#endif #endif
#if defined(USE_X11) #if defined(USE_X11)
......
...@@ -93,6 +93,11 @@ namespace { ...@@ -93,6 +93,11 @@ namespace {
static const char* kBrowser = "Browser"; static const char* kBrowser = "Browser";
// NOINLINE to make sure crashes use this for magic signature.
NOINLINE void FatalSurfaceFailure() {
LOG(FATAL) << "Fatal surface initialization failure";
}
gfx::OverlayTransform RotationToDisplayTransform( gfx::OverlayTransform RotationToDisplayTransform(
display::Display::Rotation rotation) { display::Display::Rotation rotation) {
// Note that the angle provided by |rotation| here is the opposite direction // Note that the angle provided by |rotation| here is the opposite direction
...@@ -352,9 +357,8 @@ class CompositorImpl::AndroidHostDisplayClient : public viz::HostDisplayClient { ...@@ -352,9 +357,8 @@ class CompositorImpl::AndroidHostDisplayClient : public viz::HostDisplayClient {
void DidCompleteSwapWithSize(const gfx::Size& pixel_size) override { void DidCompleteSwapWithSize(const gfx::Size& pixel_size) override {
compositor_->DidSwapBuffers(pixel_size); compositor_->DidSwapBuffers(pixel_size);
} }
void OnFatalOrSurfaceContextCreationFailure( void OnContextCreationResult(gpu::ContextResult context_result) override {
gpu::ContextResult context_result) override { compositor_->OnContextCreationResult(context_result);
compositor_->OnFatalOrSurfaceContextCreationFailure(context_result);
} }
void SetPreferredRefreshRate(float refresh_rate) override { void SetPreferredRefreshRate(float refresh_rate) override {
if (compositor_->root_window_) if (compositor_->root_window_)
...@@ -791,9 +795,17 @@ void CompositorImpl::OnGpuChannelEstablished( ...@@ -791,9 +795,17 @@ void CompositorImpl::OnGpuChannelEstablished(
requires_alpha_channel_), requires_alpha_channel_),
viz::command_buffer_metrics::ContextType::BROWSER_COMPOSITOR); viz::command_buffer_metrics::ContextType::BROWSER_COMPOSITOR);
auto result = context_provider->BindToCurrentThread(); auto result = context_provider->BindToCurrentThread();
if (surface_handle != gpu::kNullSurfaceHandle) {
// Only use OnContextCreationResult for onscreen contexts, where recovering
// from a surface initialization failure is possible by re-creating the
// native window.
OnContextCreationResult(result);
} else if (result == gpu::ContextResult::kFatalFailure) {
LOG(FATAL) << "Fatal failure in creating offscreen context";
}
if (result != gpu::ContextResult::kSuccess) { if (result != gpu::ContextResult::kSuccess) {
if (gpu::IsFatalOrSurfaceFailure(result))
OnFatalOrSurfaceContextCreationFailure(result);
HandlePendingLayerTreeFrameSinkRequest(); HandlePendingLayerTreeFrameSinkRequest();
return; return;
} }
...@@ -1100,12 +1112,26 @@ viz::LocalSurfaceIdAllocation CompositorImpl::GenerateLocalSurfaceId() { ...@@ -1100,12 +1112,26 @@ viz::LocalSurfaceIdAllocation CompositorImpl::GenerateLocalSurfaceId() {
return viz::LocalSurfaceIdAllocation(); return viz::LocalSurfaceIdAllocation();
} }
void CompositorImpl::OnContextCreationResult(
gpu::ContextResult context_result) {
if (!gpu::IsFatalOrSurfaceFailure(context_result)) {
num_of_consecutive_surface_failures_ = 0u;
return;
}
OnFatalOrSurfaceContextCreationFailure(context_result);
}
void CompositorImpl::OnFatalOrSurfaceContextCreationFailure( void CompositorImpl::OnFatalOrSurfaceContextCreationFailure(
gpu::ContextResult context_result) { gpu::ContextResult context_result) {
DCHECK(gpu::IsFatalOrSurfaceFailure(context_result)); DCHECK(gpu::IsFatalOrSurfaceFailure(context_result));
LOG_IF(FATAL, context_result == gpu::ContextResult::kFatalFailure) LOG_IF(FATAL, context_result == gpu::ContextResult::kFatalFailure)
<< "Fatal error making Gpu context"; << "Fatal error making Gpu context";
constexpr size_t kMaxConsecutiveSurfaceFailures = 10u;
if (++num_of_consecutive_surface_failures_ > kMaxConsecutiveSurfaceFailures)
FatalSurfaceFailure();
if (context_result == gpu::ContextResult::kSurfaceFailure) { if (context_result == gpu::ContextResult::kSurfaceFailure) {
SetSurface(nullptr, false); SetSurface(nullptr, false);
client_->RecreateSurface(); client_->RecreateSurface();
......
...@@ -202,7 +202,8 @@ class CONTENT_EXPORT CompositorImpl ...@@ -202,7 +202,8 @@ class CONTENT_EXPORT CompositorImpl
// Registers the root frame sink ID. // Registers the root frame sink ID.
void RegisterRootFrameSink(); void RegisterRootFrameSink();
// Called when we fail to create the context for the root frame sink. // Called with the result of context creation for the root frame sink.
void OnContextCreationResult(gpu::ContextResult context_result);
void OnFatalOrSurfaceContextCreationFailure( void OnFatalOrSurfaceContextCreationFailure(
gpu::ContextResult context_result); gpu::ContextResult context_result);
...@@ -275,6 +276,8 @@ class CONTENT_EXPORT CompositorImpl ...@@ -275,6 +276,8 @@ class CONTENT_EXPORT CompositorImpl
base::RepeatingCallback<void(const gfx::Size&)> base::RepeatingCallback<void(const gfx::Size&)>
swap_completed_with_size_for_testing_; swap_completed_with_size_for_testing_;
size_t num_of_consecutive_surface_failures_ = 0u;
base::WeakPtrFactory<CompositorImpl> weak_factory_; base::WeakPtrFactory<CompositorImpl> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(CompositorImpl); DISALLOW_COPY_AND_ASSIGN(CompositorImpl);
......
...@@ -94,10 +94,10 @@ interface DisplayClient { ...@@ -94,10 +94,10 @@ interface DisplayClient {
[EnableIf=use_x11] [EnableIf=use_x11]
DidCompleteSwapWithNewSize(gfx.mojom.Size size); DidCompleteSwapWithNewSize(gfx.mojom.Size size);
// Notifies that context creation failed. On Android we can't fall back to // Notifies the client of the result of context creation attempt. On Android we can't
// SW in these cases, so we need to handle this specifically. // fall back to SW in failure cases, so we need to handle this specifically.
[EnableIf=is_android] [EnableIf=is_android]
OnFatalOrSurfaceContextCreationFailure(gpu.mojom.ContextResult result); OnContextCreationResult(gpu.mojom.ContextResult result);
[EnableIf=is_android] [EnableIf=is_android]
SetPreferredRefreshRate(float refresh_rate); SetPreferredRefreshRate(float refresh_rate);
......
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