| Index: gpu/ipc/client/command_buffer_proxy_impl.cc
|
| diff --git a/gpu/ipc/client/command_buffer_proxy_impl.cc b/gpu/ipc/client/command_buffer_proxy_impl.cc
|
| index 8f9c3a58e6386c7a4b9d108bb2abcf9e59c9265a..7587212837fdca100c8ab632038e33b45ebce2b4 100644
|
| --- a/gpu/ipc/client/command_buffer_proxy_impl.cc
|
| +++ b/gpu/ipc/client/command_buffer_proxy_impl.cc
|
| @@ -10,7 +10,6 @@
|
| #include "base/callback.h"
|
| #include "base/logging.h"
|
| #include "base/memory/shared_memory.h"
|
| -#include "base/optional.h"
|
| #include "base/stl_util.h"
|
| #include "base/thread_task_runner_handle.h"
|
| #include "base/trace_event/trace_event.h"
|
| @@ -106,12 +105,26 @@
|
| if (last_state_.error == gpu::error::kLostContext)
|
| context_lost_reason = last_state_.context_lost_reason;
|
| }
|
| - OnLostContextNoReentrancy(context_lost_reason, gpu::error::kLostContext);
|
| + OnDestroyed(context_lost_reason, gpu::error::kLostContext);
|
| }
|
|
|
| void CommandBufferProxyImpl::OnDestroyed(gpu::error::ContextLostReason reason,
|
| gpu::error::Error error) {
|
| - OnLostContextNoReentrancy(reason, error);
|
| + CheckLock();
|
| +
|
| + // When the client sees that the context is lost, they should delete this
|
| + // CommandBufferProxyImpl and create a new one.
|
| + last_state_.error = error;
|
| + last_state_.context_lost_reason = reason;
|
| +
|
| + // Prevent any further messages from being sent, and ensure we only call
|
| + // the client for lost context a single time.
|
| + if (channel_) {
|
| + channel_->DestroyCommandBuffer(this);
|
| + channel_ = nullptr;
|
| + if (gpu_control_client_)
|
| + gpu_control_client_->OnGpuControlLostContext();
|
| + }
|
| }
|
|
|
| void CommandBufferProxyImpl::OnConsoleMessage(
|
| @@ -493,6 +506,10 @@
|
| lock_ = lock;
|
| }
|
|
|
| +bool CommandBufferProxyImpl::IsGpuChannelLost() {
|
| + return !channel_ || channel_->IsLost();
|
| +}
|
| +
|
| void CommandBufferProxyImpl::EnsureWorkVisible() {
|
| if (channel_)
|
| channel_->ValidateFlushIDReachedServer(stream_id_, true);
|
| @@ -687,62 +704,25 @@
|
|
|
| void CommandBufferProxyImpl::InvalidGpuMessage() {
|
| LOG(ERROR) << "Received invalid message from the GPU process.";
|
| - OnLostContextNoReentrancy(gpu::error::kInvalidGpuMessage,
|
| - gpu::error::kLostContext);
|
| + OnDestroyed(gpu::error::kInvalidGpuMessage, gpu::error::kLostContext);
|
| }
|
|
|
| void CommandBufferProxyImpl::InvalidGpuReply() {
|
| + CheckLock();
|
| LOG(ERROR) << "Received invalid reply from the GPU process.";
|
| - // This method may be inside a callstack from the GpuControlClient (we got a
|
| - // bad reply to something we are sending to the GPU process). So avoid
|
| - // re-entering the GpuControlClient here.
|
| - OnLostContextAvoidReentrancy(gpu::error::kInvalidGpuMessage,
|
| - gpu::error::kLostContext);
|
| -}
|
| -
|
| -void CommandBufferProxyImpl::OnLostContextAvoidReentrancy(
|
| - gpu::error::ContextLostReason reason,
|
| - gpu::error::Error error) {
|
| - CheckLock();
|
| - // Set the error and reason immediately, in case clients want to query them
|
| - // as we unwind the stack.
|
| - last_state_.error = error;
|
| - last_state_.context_lost_reason = reason;
|
| - // Create a fresh call stack to call back to the GpuControlClient. For
|
| - // cases where we're inside a method that the GpuControlClient called
|
| - // on us and we don't want to re-enter it.
|
| + last_state_.error = gpu::error::kLostContext;
|
| + last_state_.context_lost_reason = gpu::error::kInvalidGpuMessage;
|
| callback_thread_->PostTask(
|
| FROM_HERE,
|
| - base::Bind(&CommandBufferProxyImpl::OnLostContextImplFromAvoidReentrancy,
|
| + base::Bind(&CommandBufferProxyImpl::InvalidGpuReplyOnClientThread,
|
| weak_this_));
|
| }
|
|
|
| -void CommandBufferProxyImpl::OnLostContextNoReentrancy(
|
| - gpu::error::ContextLostReason reason,
|
| - gpu::error::Error error) {
|
| - last_state_.error = error;
|
| - last_state_.context_lost_reason = reason;
|
| - OnLostContextImpl();
|
| -}
|
| -
|
| -void CommandBufferProxyImpl::OnLostContextImplFromAvoidReentrancy() {
|
| - // This is a fresh call stack so we need to grab the lock.
|
| - base::Optional<base::AutoLock> hold;
|
| +void CommandBufferProxyImpl::InvalidGpuReplyOnClientThread() {
|
| + std::unique_ptr<base::AutoLock> lock;
|
| if (lock_)
|
| - hold.emplace(*lock_);
|
| - OnLostContextImpl();
|
| -}
|
| -
|
| -void CommandBufferProxyImpl::OnLostContextImpl() {
|
| - CheckLock();
|
| - // Prevent any further messages from being sent, and ensure we only call
|
| - // the client for lost context a single time.
|
| - if (!channel_)
|
| - return;
|
| - channel_->DestroyCommandBuffer(this);
|
| - channel_ = nullptr;
|
| - if (gpu_control_client_)
|
| - gpu_control_client_->OnGpuControlLostContext();
|
| + lock.reset(new base::AutoLock(*lock_));
|
| + OnDestroyed(gpu::error::kInvalidGpuMessage, gpu::error::kLostContext);
|
| }
|
|
|
| } // namespace gpu
|
|
|