summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/mus/gles2/command_buffer_impl.cc19
-rw-r--r--components/mus/gles2/command_buffer_impl.h1
-rw-r--r--components/mus/gles2/command_buffer_local.cc11
-rw-r--r--components/mus/gles2/command_buffer_local.h2
4 files changed, 25 insertions, 8 deletions
diff --git a/components/mus/gles2/command_buffer_impl.cc b/components/mus/gles2/command_buffer_impl.cc
index adb5845..13ce77c 100644
--- a/components/mus/gles2/command_buffer_impl.cc
+++ b/components/mus/gles2/command_buffer_impl.cc
@@ -280,10 +280,17 @@ void CommandBufferImpl::OnConnectionError() {
binding_.reset();
// Objects we own (such as CommandBufferDriver) need to be destroyed on the
- // thread we were created on.
- gpu_state_->command_buffer_task_runner()->PostTask(
- driver_.get(), base::Bind(&CommandBufferImpl::DeleteOnGpuThread,
- base::Unretained(this)));
+ // thread we were created on. It's entirely possible we haven't or are in the
+ // process of creating |driver_|.
+ if (driver_) {
+ gpu_state_->command_buffer_task_runner()->PostTask(
+ driver_.get(), base::Bind(&CommandBufferImpl::DeleteOnGpuThread,
+ base::Unretained(this)));
+ } else {
+ gpu_state_->command_buffer_task_runner()->task_runner()->PostTask(
+ FROM_HERE, base::Bind(&CommandBufferImpl::DeleteOnGpuThread2,
+ base::Unretained(this)));
+ }
}
bool CommandBufferImpl::DeleteOnGpuThread() {
@@ -291,4 +298,8 @@ bool CommandBufferImpl::DeleteOnGpuThread() {
return true;
}
+void CommandBufferImpl::DeleteOnGpuThread2() {
+ delete this;
+}
+
} // namespace mus
diff --git a/components/mus/gles2/command_buffer_impl.h b/components/mus/gles2/command_buffer_impl.h
index ad57596..6bdbef8 100644
--- a/components/mus/gles2/command_buffer_impl.h
+++ b/components/mus/gles2/command_buffer_impl.h
@@ -102,6 +102,7 @@ class CommandBufferImpl : public mojom::CommandBuffer {
void OnConnectionError();
bool DeleteOnGpuThread();
+ void DeleteOnGpuThread2();
scoped_refptr<GpuState> gpu_state_;
scoped_ptr<CommandBufferDriver> driver_;
diff --git a/components/mus/gles2/command_buffer_local.cc b/components/mus/gles2/command_buffer_local.cc
index b0e09a4..d4b2b03 100644
--- a/components/mus/gles2/command_buffer_local.cc
+++ b/components/mus/gles2/command_buffer_local.cc
@@ -96,10 +96,14 @@ void CommandBufferLocal::Destroy() {
weak_factory_.InvalidateWeakPtrs();
// CommandBufferLocal is initialized on the GPU thread with
// InitializeOnGpuThread(), so we need delete memebers on the GPU thread
- // too.
+ // too. Additionally we need to make sure we are deleted before returning,
+ // otherwise we may attempt to use the AcceleratedWidget which has since been
+ // destroyed.
+ base::WaitableEvent event(true, false);
gpu_state_->command_buffer_task_runner()->PostTask(
driver_.get(), base::Bind(&CommandBufferLocal::DeleteOnGpuThread,
- base::Unretained(this)));
+ base::Unretained(this), &event));
+ event.Wait();
}
bool CommandBufferLocal::Initialize() {
@@ -512,8 +516,9 @@ bool CommandBufferLocal::MakeProgressOnGpuThread(
return true;
}
-bool CommandBufferLocal::DeleteOnGpuThread() {
+bool CommandBufferLocal::DeleteOnGpuThread(base::WaitableEvent* event) {
delete this;
+ event->Signal();
return true;
}
diff --git a/components/mus/gles2/command_buffer_local.h b/components/mus/gles2/command_buffer_local.h
index 2777654..bfc9e77 100644
--- a/components/mus/gles2/command_buffer_local.h
+++ b/components/mus/gles2/command_buffer_local.h
@@ -128,7 +128,7 @@ class CommandBufferLocal : public gpu::CommandBuffer,
bool DestroyImageOnGpuThread(int32_t id);
bool MakeProgressOnGpuThread(base::WaitableEvent* event,
gpu::CommandBuffer::State* state);
- bool DeleteOnGpuThread();
+ bool DeleteOnGpuThread(base::WaitableEvent* event);
bool SignalQueryOnGpuThread(uint32_t query_id, const base::Closure& callback);
// Helper functions are called in the client thread.