Commit 0fdf3421 authored by Vasiliy Telezhnikov's avatar Vasiliy Telezhnikov Committed by Commit Bot

SkiaRenderer: Report ContextLost uma stats

This CL adds reporting for GPU.ContextLost.DisplayCompositor uma for
SkiaRenderer.

It also fixes offline flag for reporting DidContextLost to browser.

Bug: 927460
Change-Id: Iea14170b7e98f001376ae0602df1f870b1de5871
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2110216
Commit-Queue: Vasiliy Telezhnikov <vasilyt@chromium.org>
Reviewed-by: default avatarJonathan Backer <backer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#752073}
parent fab0d10e
...@@ -128,7 +128,6 @@ void SkiaOutputSurfaceDependencyWebView::UnregisterDisplayContext( ...@@ -128,7 +128,6 @@ void SkiaOutputSurfaceDependencyWebView::UnregisterDisplayContext(
} }
void SkiaOutputSurfaceDependencyWebView::DidLoseContext( void SkiaOutputSurfaceDependencyWebView::DidLoseContext(
bool offscreen,
gpu::error::ContextLostReason reason, gpu::error::ContextLostReason reason,
const GURL& active_url) { const GURL& active_url) {
// No GpuChannelManagerDelegate here, so leave it no-op for now. // No GpuChannelManagerDelegate here, so leave it no-op for now.
......
...@@ -48,8 +48,7 @@ class SkiaOutputSurfaceDependencyWebView ...@@ -48,8 +48,7 @@ class SkiaOutputSurfaceDependencyWebView
base::ScopedClosureRunner CacheGLSurface(gl::GLSurface* surface) override; base::ScopedClosureRunner CacheGLSurface(gl::GLSurface* surface) override;
void RegisterDisplayContext(gpu::DisplayContext* display_context) override; void RegisterDisplayContext(gpu::DisplayContext* display_context) override;
void UnregisterDisplayContext(gpu::DisplayContext* display_context) override; void UnregisterDisplayContext(gpu::DisplayContext* display_context) override;
void DidLoseContext(bool offscreen, void DidLoseContext(gpu::error::ContextLostReason reason,
gpu::error::ContextLostReason reason,
const GURL& active_url) override; const GURL& active_url) override;
base::TimeDelta GetGpuBlockedTimeSinceLastSwap() override; base::TimeDelta GetGpuBlockedTimeSinceLastSwap() override;
......
...@@ -26,9 +26,12 @@ enum ContextLostReason { ...@@ -26,9 +26,12 @@ enum ContextLostReason {
CONTEXT_LOST_OUT_OF_MEMORY = 10, CONTEXT_LOST_OUT_OF_MEMORY = 10,
CONTEXT_LOST_MAKECURRENT_FAILED = 11, CONTEXT_LOST_MAKECURRENT_FAILED = 11,
CONTEXT_LOST_INVALID_GPU_MESSAGE = 12, CONTEXT_LOST_INVALID_GPU_MESSAGE = 12,
// SkiaRenderer marked context as lost because of failed Reshape call
CONTEXT_LOST_RESHAPE_FAILED = 13,
// Update kMaxValue and //tools/metrics/histograms/histograms.xml when adding // Update kMaxValue and //tools/metrics/histograms/histograms.xml when adding
// new values. // new values.
kMaxValue = CONTEXT_LOST_INVALID_GPU_MESSAGE kMaxValue = CONTEXT_LOST_RESHAPE_FAILED
}; };
VIZ_COMMON_EXPORT ContextLostReason VIZ_COMMON_EXPORT ContextLostReason
......
...@@ -103,8 +103,7 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurfaceDependency { ...@@ -103,8 +103,7 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurfaceDependency {
virtual void RegisterDisplayContext(gpu::DisplayContext* display_context) = 0; virtual void RegisterDisplayContext(gpu::DisplayContext* display_context) = 0;
virtual void UnregisterDisplayContext( virtual void UnregisterDisplayContext(
gpu::DisplayContext* display_context) = 0; gpu::DisplayContext* display_context) = 0;
virtual void DidLoseContext(bool offscreen, virtual void DidLoseContext(gpu::error::ContextLostReason reason,
gpu::error::ContextLostReason reason,
const GURL& active_url) = 0; const GURL& active_url) = 0;
virtual base::TimeDelta GetGpuBlockedTimeSinceLastSwap() = 0; virtual base::TimeDelta GetGpuBlockedTimeSinceLastSwap() = 0;
......
...@@ -153,10 +153,11 @@ void SkiaOutputSurfaceDependencyImpl::UnregisterDisplayContext( ...@@ -153,10 +153,11 @@ void SkiaOutputSurfaceDependencyImpl::UnregisterDisplayContext(
} }
void SkiaOutputSurfaceDependencyImpl::DidLoseContext( void SkiaOutputSurfaceDependencyImpl::DidLoseContext(
bool offscreen,
gpu::error::ContextLostReason reason, gpu::error::ContextLostReason reason,
const GURL& active_url) { const GURL& active_url) {
gpu_service_impl_->DidLoseContext(offscreen, reason, active_url); // |offscreen| is used to determine if it's compositing context or not to
// decide if we need to disable webgl and canvas.
gpu_service_impl_->DidLoseContext(/*offscreen=*/false, reason, active_url);
} }
base::TimeDelta base::TimeDelta
......
...@@ -54,8 +54,7 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurfaceDependencyImpl ...@@ -54,8 +54,7 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurfaceDependencyImpl
void RegisterDisplayContext(gpu::DisplayContext* display_context) override; void RegisterDisplayContext(gpu::DisplayContext* display_context) override;
void UnregisterDisplayContext(gpu::DisplayContext* display_context) override; void UnregisterDisplayContext(gpu::DisplayContext* display_context) override;
void DidLoseContext(bool offscreen, void DidLoseContext(gpu::error::ContextLostReason reason,
gpu::error::ContextLostReason reason,
const GURL& active_url) override; const GURL& active_url) override;
base::TimeDelta GetGpuBlockedTimeSinceLastSwap() override; base::TimeDelta GetGpuBlockedTimeSinceLastSwap() override;
......
...@@ -734,6 +734,28 @@ SkiaOutputSurfaceImplOnGpu::ReleaseCurrent::~ReleaseCurrent() { ...@@ -734,6 +734,28 @@ SkiaOutputSurfaceImplOnGpu::ReleaseCurrent::~ReleaseCurrent() {
context_state_->ReleaseCurrent(gl_surface_.get()); context_state_->ReleaseCurrent(gl_surface_.get());
} }
class SkiaOutputSurfaceImplOnGpu::DisplayContext : public gpu::DisplayContext {
public:
DisplayContext(SkiaOutputSurfaceDependency* deps,
SkiaOutputSurfaceImplOnGpu* owner)
: dependency_(deps), owner_(owner) {
dependency_->RegisterDisplayContext(this);
}
~DisplayContext() override { dependency_->UnregisterDisplayContext(this); }
DisplayContext(const DisplayContext&) = delete;
DisplayContext& operator=(const DisplayContext&) = delete;
// gpu::DisplayContext implementation
void MarkContextLost() override {
owner_->MarkContextLost(CONTEXT_LOST_UNKNOWN);
}
private:
SkiaOutputSurfaceDependency* const dependency_;
SkiaOutputSurfaceImplOnGpu* const owner_;
};
// static // static
std::unique_ptr<SkiaOutputSurfaceImplOnGpu> SkiaOutputSurfaceImplOnGpu::Create( std::unique_ptr<SkiaOutputSurfaceImplOnGpu> SkiaOutputSurfaceImplOnGpu::Create(
SkiaOutputSurfaceDependency* deps, SkiaOutputSurfaceDependency* deps,
...@@ -790,6 +812,7 @@ SkiaOutputSurfaceImplOnGpu::SkiaOutputSurfaceImplOnGpu( ...@@ -790,6 +812,7 @@ SkiaOutputSurfaceImplOnGpu::SkiaOutputSurfaceImplOnGpu(
context_lost_callback_(std::move(context_lost_callback)), context_lost_callback_(std::move(context_lost_callback)),
gpu_vsync_callback_(std::move(gpu_vsync_callback)), gpu_vsync_callback_(std::move(gpu_vsync_callback)),
gpu_preferences_(dependency_->GetGpuPreferences()), gpu_preferences_(dependency_->GetGpuPreferences()),
display_context_(std::make_unique<DisplayContext>(deps, this)),
copier_active_url_(GURL("chrome://gpu/SkiaRendererGLRendererCopier")) { copier_active_url_(GURL("chrome://gpu/SkiaRendererGLRendererCopier")) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
...@@ -798,15 +821,11 @@ SkiaOutputSurfaceImplOnGpu::SkiaOutputSurfaceImplOnGpu( ...@@ -798,15 +821,11 @@ SkiaOutputSurfaceImplOnGpu::SkiaOutputSurfaceImplOnGpu(
weak_ptr_, std::move(did_swap_buffer_complete_callback)); weak_ptr_, std::move(did_swap_buffer_complete_callback));
buffer_presented_callback_ = CreateSafeRepeatingCallback( buffer_presented_callback_ = CreateSafeRepeatingCallback(
weak_ptr_, std::move(buffer_presented_callback)); weak_ptr_, std::move(buffer_presented_callback));
dependency_->RegisterDisplayContext(this);
} }
SkiaOutputSurfaceImplOnGpu::~SkiaOutputSurfaceImplOnGpu() { SkiaOutputSurfaceImplOnGpu::~SkiaOutputSurfaceImplOnGpu() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
dependency_->UnregisterDisplayContext(this);
// |context_provider_| and clients want either the context to be lost or made // |context_provider_| and clients want either the context to be lost or made
// current on destruction. // current on destruction.
if (context_state_ && MakeCurrent(false /* need_fbo0 */)) { if (context_state_ && MakeCurrent(false /* need_fbo0 */)) {
...@@ -847,7 +866,7 @@ void SkiaOutputSurfaceImplOnGpu::Reshape(const gfx::Size& size, ...@@ -847,7 +866,7 @@ void SkiaOutputSurfaceImplOnGpu::Reshape(const gfx::Size& size,
color_space_ = color_space; color_space_ = color_space;
if (!output_device_->Reshape(size_, device_scale_factor, color_space, format, if (!output_device_->Reshape(size_, device_scale_factor, color_space, format,
transform)) { transform)) {
MarkContextLost(); MarkContextLost(CONTEXT_LOST_RESHAPE_FAILED);
return; return;
} }
} }
...@@ -1597,9 +1616,9 @@ bool SkiaOutputSurfaceImplOnGpu::MakeCurrent(bool need_fbo0) { ...@@ -1597,9 +1616,9 @@ bool SkiaOutputSurfaceImplOnGpu::MakeCurrent(bool need_fbo0) {
if (!context_state_->MakeCurrent(need_fbo0 ? gl_surface_.get() : nullptr)) { if (!context_state_->MakeCurrent(need_fbo0 ? gl_surface_.get() : nullptr)) {
LOG(ERROR) << "Failed to make current."; LOG(ERROR) << "Failed to make current.";
dependency_->DidLoseContext( dependency_->DidLoseContext(
!need_fbo0 /* offscreen */, gpu::error::kMakeCurrentFailed, gpu::error::kMakeCurrentFailed,
GURL("chrome://gpu/SkiaOutputSurfaceImplOnGpu::MakeCurrent")); GURL("chrome://gpu/SkiaOutputSurfaceImplOnGpu::MakeCurrent"));
MarkContextLost(); MarkContextLost(CONTEXT_LOST_MAKECURRENT_FAILED);
return false; return false;
} }
context_state_->set_need_context_state_reset(true); context_state_->set_need_context_state_reset(true);
...@@ -1681,7 +1700,15 @@ void SkiaOutputSurfaceImplOnGpu::BufferPresented( ...@@ -1681,7 +1700,15 @@ void SkiaOutputSurfaceImplOnGpu::BufferPresented(
// Handled by SkiaOutputDevice already. // Handled by SkiaOutputDevice already.
} }
void SkiaOutputSurfaceImplOnGpu::MarkContextLost() { void SkiaOutputSurfaceImplOnGpu::MarkContextLost(ContextLostReason reason) {
// This function potentially can be re-entered during from
// SharedContextState::MarkContextLost(). This guards against it.
if (context_is_lost_)
return;
context_is_lost_ = true;
UMA_HISTOGRAM_ENUMERATION("GPU.ContextLost.DisplayCompositor", reason);
context_state_->MarkContextLost(); context_state_->MarkContextLost();
if (context_lost_callback_) { if (context_lost_callback_) {
PostTaskToClientThread(std::move(context_lost_callback_)); PostTaskToClientThread(std::move(context_lost_callback_));
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "base/util/type_safety/pass_key.h" #include "base/util/type_safety/pass_key.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "components/viz/common/display/renderer_settings.h" #include "components/viz/common/display/renderer_settings.h"
#include "components/viz/common/gpu/context_lost_reason.h"
#include "components/viz/common/quads/render_pass.h" #include "components/viz/common/quads/render_pass.h"
#include "components/viz/service/display/external_use_client.h" #include "components/viz/service/display/external_use_client.h"
#include "components/viz/service/display/output_surface.h" #include "components/viz/service/display/output_surface.h"
...@@ -71,8 +72,7 @@ struct RenderPassGeometry; ...@@ -71,8 +72,7 @@ struct RenderPassGeometry;
// The SkiaOutputSurface implementation running on the GPU thread. This class // The SkiaOutputSurface implementation running on the GPU thread. This class
// should be created, used and destroyed on the GPU thread. // should be created, used and destroyed on the GPU thread.
class SkiaOutputSurfaceImplOnGpu : public gpu::ImageTransportSurfaceDelegate, class SkiaOutputSurfaceImplOnGpu : public gpu::ImageTransportSurfaceDelegate {
public gpu::DisplayContext {
public: public:
class ScopedUseContextProvider; class ScopedUseContextProvider;
...@@ -197,9 +197,6 @@ class SkiaOutputSurfaceImplOnGpu : public gpu::ImageTransportSurfaceDelegate, ...@@ -197,9 +197,6 @@ class SkiaOutputSurfaceImplOnGpu : public gpu::ImageTransportSurfaceDelegate,
GpuVSyncCallback GetGpuVSyncCallback() override; GpuVSyncCallback GetGpuVSyncCallback() override;
base::TimeDelta GetGpuBlockedTimeSinceLastSwap() override; base::TimeDelta GetGpuBlockedTimeSinceLastSwap() override;
// gpu::DisplayContext implementation:
void MarkContextLost() override;
void PostTaskToClientThread(base::OnceClosure closure) { void PostTaskToClientThread(base::OnceClosure closure) {
dependency_->PostTaskToClientThread(std::move(closure)); dependency_->PostTaskToClientThread(std::move(closure));
} }
...@@ -214,6 +211,7 @@ class SkiaOutputSurfaceImplOnGpu : public gpu::ImageTransportSurfaceDelegate, ...@@ -214,6 +211,7 @@ class SkiaOutputSurfaceImplOnGpu : public gpu::ImageTransportSurfaceDelegate,
private: private:
class ScopedPromiseImageAccess; class ScopedPromiseImageAccess;
class OffscreenSurface; class OffscreenSurface;
class DisplayContext;
bool Initialize(); bool Initialize();
bool InitializeForGL(); bool InitializeForGL();
...@@ -223,6 +221,7 @@ class SkiaOutputSurfaceImplOnGpu : public gpu::ImageTransportSurfaceDelegate, ...@@ -223,6 +221,7 @@ class SkiaOutputSurfaceImplOnGpu : public gpu::ImageTransportSurfaceDelegate,
// Make context current for GL, and return false if the context is lost. // Make context current for GL, and return false if the context is lost.
// It will do nothing when Vulkan is used. // It will do nothing when Vulkan is used.
bool MakeCurrent(bool need_fbo0); bool MakeCurrent(bool need_fbo0);
void MarkContextLost(ContextLostReason reason);
void PullTextureUpdates(std::vector<gpu::SyncToken> sync_token); void PullTextureUpdates(std::vector<gpu::SyncToken> sync_token);
...@@ -304,6 +303,9 @@ class SkiaOutputSurfaceImplOnGpu : public gpu::ImageTransportSurfaceDelegate, ...@@ -304,6 +303,9 @@ class SkiaOutputSurfaceImplOnGpu : public gpu::ImageTransportSurfaceDelegate,
const gl::GLVersionInfo* gl_version_info_ = nullptr; const gl::GLVersionInfo* gl_version_info_ = nullptr;
size_t max_resource_cache_bytes_ = 0u; size_t max_resource_cache_bytes_ = 0u;
std::unique_ptr<DisplayContext> display_context_;
bool context_is_lost_ = false;
std::unique_ptr<SkiaOutputDevice> output_device_; std::unique_ptr<SkiaOutputDevice> output_device_;
base::Optional<SkiaOutputDevice::ScopedPaint> scoped_output_device_paint_; base::Optional<SkiaOutputDevice::ScopedPaint> scoped_output_device_paint_;
......
...@@ -719,8 +719,9 @@ void InProcessCommandBuffer::OnParseError() { ...@@ -719,8 +719,9 @@ void InProcessCommandBuffer::OnParseError() {
if (gpu_channel_manager_delegate_) { if (gpu_channel_manager_delegate_) {
// Tell the browser about this context loss so it can determine whether // Tell the browser about this context loss so it can determine whether
// client APIs like WebGL need to be blocked from automatically running. // client APIs like WebGL need to be blocked from automatically running.
// |offscreen| is used to determine if it's compositing context or not.
gpu_channel_manager_delegate_->DidLoseContext( gpu_channel_manager_delegate_->DidLoseContext(
is_offscreen_, state.context_lost_reason, active_url_.url()); /*offscreen=*/false, state.context_lost_reason, active_url_.url());
// Check the error reason and robustness extension to get a better idea if // Check the error reason and robustness extension to get a better idea if
// the GL context was lost. We might try restarting the GPU process to // the GL context was lost. We might try restarting the GPU process to
......
...@@ -10892,6 +10892,7 @@ Called by update_net_error_codes.py.--> ...@@ -10892,6 +10892,7 @@ Called by update_net_error_codes.py.-->
<int value="10" label="CONTEXT_LOST_OUT_OF_MEMORY"/> <int value="10" label="CONTEXT_LOST_OUT_OF_MEMORY"/>
<int value="11" label="CONTEXT_LOST_MAKECURRENT_FAILED"/> <int value="11" label="CONTEXT_LOST_MAKECURRENT_FAILED"/>
<int value="12" label="CONTEXT_LOST_INVALID_GPU_MESSAGE"/> <int value="12" label="CONTEXT_LOST_INVALID_GPU_MESSAGE"/>
<int value="13" label="CONTEXT_LOST_RESHAPE_FAILED"/>
</enum> </enum>
<enum name="ContextMenuDelayedElementDetails"> <enum name="ContextMenuDelayedElementDetails">
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