Index: gpu/ipc/service/gpu_channel.cc |
diff --git a/gpu/ipc/service/gpu_channel.cc b/gpu/ipc/service/gpu_channel.cc |
index 8926b51e47ed5b3ffca344fa88ad0fbb0729bded..11c6c8bf82d46cec021922ff1b585459fdddb977 100644 |
--- a/gpu/ipc/service/gpu_channel.cc |
+++ b/gpu/ipc/service/gpu_channel.cc |
@@ -34,6 +34,7 @@ |
#include "gpu/command_buffer/service/command_executor.h" |
#include "gpu/command_buffer/service/image_factory.h" |
#include "gpu/command_buffer/service/mailbox_manager.h" |
+#include "gpu/command_buffer/service/program_manager.h" |
#include "gpu/command_buffer/service/sync_point_manager.h" |
#include "gpu/ipc/common/gpu_messages.h" |
#include "gpu/ipc/service/gpu_channel_manager.h" |
@@ -1068,4 +1069,40 @@ scoped_refptr<gl::GLImage> GpuChannel::CreateImageForGpuMemoryBuffer( |
} |
} |
+GpuChannelDeleter::GpuChannelDeleter(std::unique_ptr<GpuChannel> channel) |
+ : channel_(std::move(channel)) { |
+ for (const auto& stub : channel_->stubs_) { |
+ pending_stubs_.push(stub.second); |
+ } |
+} |
+ |
+GpuChannelDeleter::~GpuChannelDeleter() = default; |
+ |
+bool GpuChannelDeleter::DeleteWithTimeout(const base::TimeTicks& timeout) { |
+ for (; pending_stubs_.size() > 0; pending_stubs_.pop()) { |
+ auto* decoder = pending_stubs_.front()->decoder(); |
+ auto* surface = pending_stubs_.front()->surface(); |
+ |
+ if (!decoder) { |
+ continue; |
+ } |
+ |
+ bool have_context = false; |
+ if (decoder->GetGLContext()) { |
+ // Try to make the context current regardless of whether it was lost, so |
+ // we don't leak resources. |
+ have_context = decoder->GetGLContext()->MakeCurrent(surface); |
+ } |
+ |
+ auto* program_manager = decoder->GetContextGroup()->program_manager(); |
+ if (!program_manager->PreDestroyWithTimeout(have_context, timeout)) { |
+ // If PreDestroyWithTimeout returns false, the timeout was reached |
+ // before deletion completed. We should also return false. |
+ return false; |
+ } |
+ } |
+ |
+ return true; |
+} |
+ |
} // namespace gpu |