Commit e4eb1a1d authored by kylechar's avatar kylechar Committed by Commit Bot

Use synthetic context lost with SkiaRenderer.

Change SkiaRenderer to use similar logic to GLRenderer on context loss
where the loss is considered a synthetic loss unless it was triggered by
the GL robustness extension. Synthetic loss doesn't trigger GPU process
restart.

Bug: 1091787
Change-Id: Ie3613dff69f9a0e8816d17f344ff690b297153de
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2302924
Commit-Queue: kylechar <kylechar@chromium.org>
Reviewed-by: default avatarJonathan Backer <backer@chromium.org>
Reviewed-by: default avatarBo <boliu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#790407}
parent c1eec15b
......@@ -28,7 +28,7 @@ namespace android_webview {
namespace {
void OnContextLost() {
void OnContextLost(bool synthetic_loss) {
NOTREACHED() << "Non owned context lost!";
}
......
......@@ -853,12 +853,17 @@ SkiaOutputSurfaceImplOnGpu::SkiaOutputSurfaceImplOnGpu(
SkiaOutputSurfaceImplOnGpu::~SkiaOutputSurfaceImplOnGpu() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
// |context_provider_| and clients want either the context to be lost or made
// current on destruction.
if (context_state_ && MakeCurrent(false /* need_fbo0 */)) {
// This ensures any outstanding callbacks for promise images are performed.
gr_context()->flushAndSubmit();
release_current_last_.emplace(gl_surface_, context_state_);
if (context_state_) {
context_state_->RemoveContextLostObserver(this);
// |context_provider_| and clients want either the context to be lost or
// made current on destruction.
if (MakeCurrent(false /* need_fbo0 */)) {
// This ensures any outstanding callbacks for promise images are
// performed.
gr_context()->flushAndSubmit();
release_current_last_.emplace(gl_surface_, context_state_);
}
}
if (copier_) {
......@@ -1478,6 +1483,9 @@ bool SkiaOutputSurfaceImplOnGpu::Initialize() {
!features::IsUsingSkiaForGLReadback();
max_resource_cache_bytes_ =
context_state_->gr_context()->getResourceCacheLimit();
if (context_state_)
context_state_->AddContextLostObserver(this);
return true;
}
......@@ -1827,6 +1835,10 @@ SkiaOutputSurfaceImplOnGpu::GetDidSwapBuffersCompleteCallback() {
&SkiaOutputSurfaceImplOnGpu::DidSwapBuffersCompleteInternal, weak_ptr_);
}
void SkiaOutputSurfaceImplOnGpu::OnContextLost() {
MarkContextLost(ContextLostReason::CONTEXT_LOST_UNKNOWN);
}
void SkiaOutputSurfaceImplOnGpu::MarkContextLost(ContextLostReason reason) {
// This function potentially can be re-entered during from
// SharedContextState::MarkContextLost(). This guards against it.
......
......@@ -70,7 +70,9 @@ struct RenderPassGeometry;
// The SkiaOutputSurface implementation running on the GPU thread. This class
// should be created, used and destroyed on the GPU thread.
class SkiaOutputSurfaceImplOnGpu : public gpu::ImageTransportSurfaceDelegate {
class SkiaOutputSurfaceImplOnGpu
: public gpu::ImageTransportSurfaceDelegate,
public gpu::SharedContextState::ContextLostObserver {
public:
class ScopedUseContextProvider;
......@@ -186,6 +188,9 @@ class SkiaOutputSurfaceImplOnGpu : public gpu::ImageTransportSurfaceDelegate {
bool IsDisplayedAsOverlay();
// gpu::SharedContextState::ContextLostObserver implementation:
void OnContextLost() override;
// gpu::ImageTransportSurfaceDelegate implementation:
#if defined(OS_WIN)
void DidCreateAcceleratedSurfaceChildWindow(
......
......@@ -104,7 +104,7 @@ SharedContextState::SharedContextState(
scoped_refptr<gl::GLSurface> surface,
scoped_refptr<gl::GLContext> context,
bool use_virtualized_gl_contexts,
base::OnceClosure context_lost_callback,
ContextLostCallback context_lost_callback,
GrContextType gr_context_type,
viz::VulkanContextProvider* vulkan_context_provider,
viz::MetalContextProvider* metal_context_provider,
......@@ -490,7 +490,8 @@ void SharedContextState::MarkContextLost(error::ContextLostReason reason) {
gr_context_ = nullptr;
}
UpdateSkiaOwnedMemorySize();
std::move(context_lost_callback_).Run();
std::move(context_lost_callback_)
.Run(!context_lost_by_robustness_extension);
for (auto& observer : context_lost_observers_)
observer.OnContextLost();
}
......@@ -738,6 +739,7 @@ bool SharedContextState::CheckResetStatus(bool needs_gl) {
LOG(ERROR) << "SharedContextState context lost via ARB/EXT_robustness. Reset "
"status = "
<< gles2::GLES2Util::GetStringEnum(driver_status);
context_lost_by_robustness_extension = true;
switch (driver_status) {
case GL_GUILTY_CONTEXT_RESET_ARB:
......
......@@ -61,6 +61,8 @@ class GPU_GLES2_EXPORT SharedContextState
public base::RefCounted<SharedContextState>,
public GrContextOptions::ShaderErrorHandler {
public:
using ContextLostCallback = base::OnceCallback<void(bool)>;
// TODO: Refactor code to have seperate constructor for GL and Vulkan and not
// initialize/use GL related info for vulkan and vice-versa.
SharedContextState(
......@@ -68,7 +70,7 @@ class GPU_GLES2_EXPORT SharedContextState
scoped_refptr<gl::GLSurface> surface,
scoped_refptr<gl::GLContext> context,
bool use_virtualized_gl_contexts,
base::OnceClosure context_lost_callback,
ContextLostCallback context_lost_callback,
GrContextType gr_context_type = GrContextType::kGL,
viz::VulkanContextProvider* vulkan_context_provider = nullptr,
viz::MetalContextProvider* metal_context_provider = nullptr,
......@@ -250,7 +252,7 @@ class GPU_GLES2_EXPORT SharedContextState
bool use_virtualized_gl_contexts_ = false;
bool support_vulkan_external_object_ = false;
base::OnceClosure context_lost_callback_;
ContextLostCallback context_lost_callback_;
GrContextType gr_context_type_ = GrContextType::kGL;
MemoryTracker memory_tracker_;
viz::VulkanContextProvider* const vk_context_provider_;
......@@ -289,6 +291,7 @@ class GPU_GLES2_EXPORT SharedContextState
base::MRUCache<void*, sk_sp<SkSurface>> sk_surface_cache_;
bool device_needs_reset_ = false;
bool context_lost_by_robustness_extension = false;
base::Time last_gl_check_graphics_reset_status_;
bool disable_check_reset_status_throttling_for_test_ = false;
......
......@@ -170,6 +170,7 @@ void DeleteGrBackendTexture(SharedContextState* context_state,
DCHECK(!context_state->gr_context()->abandoned());
if (!context_state->GrContextIsVulkan()) {
DCHECK(context_state->gr_context());
context_state->gr_context()->deleteBackendTexture(
std::move(*backend_texture));
return;
......
......@@ -446,6 +446,9 @@ std::unique_ptr<SharedImageRepresentationSkia> WrappedSkImage::ProduceSkia(
SharedImageManager* manager,
MemoryTypeTracker* tracker,
scoped_refptr<SharedContextState> context_state) {
if (context_state_->context_lost())
return nullptr;
DCHECK_EQ(context_state_, context_state.get());
return std::make_unique<WrappedSkImageRepresentation>(manager, this, tracker);
}
......
......@@ -740,8 +740,7 @@ scoped_refptr<SharedContextState> GpuChannelManager::GetSharedContextState(
auto shared_context_state = base::MakeRefCounted<SharedContextState>(
std::move(share_group), std::move(surface), std::move(context),
use_virtualized_gl_contexts,
base::BindOnce(&GpuChannelManager::OnContextLost, base::Unretained(this),
/*synthetic_loss=*/false),
base::BindOnce(&GpuChannelManager::OnContextLost, base::Unretained(this)),
gpu_preferences_.gr_context_type, vulkan_context_provider_,
metal_context_provider_, dawn_context_provider_,
peak_memory_monitor_.GetWeakPtr());
......
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