Make TakeFrontBuffer a deferred message

If TakeFrontBuffer is sent as an independent IPC message, it's possible
for it to be sequenced incorrectly with the preceding ReturnFrontBuffer
message if there was no flush in between.

This is a speculative fix for legacy ARC app rendering issues.

Bug: 937524
Change-Id: I17792ed28e5c97e337c60a9c1f3dc440239c51b9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1517160
Reviewed-by: Antoine Labour <piman@chromium.org>
Commit-Queue: Antoine Labour <piman@chromium.org>
Commit-Queue: Sunny Sachanandani <sunnyps@chromium.org>
Auto-Submit: Sunny Sachanandani <sunnyps@chromium.org>
Cr-Commit-Position: refs/heads/master@{#640177}
diff --git a/gpu/ipc/client/command_buffer_proxy_impl.cc b/gpu/ipc/client/command_buffer_proxy_impl.cc
index 5ab597b..1f72c9a 100644
--- a/gpu/ipc/client/command_buffer_proxy_impl.cc
+++ b/gpu/ipc/client/command_buffer_proxy_impl.cc
@@ -645,7 +645,10 @@
   if (last_state_.error != gpu::error::kNoError)
     return;
 
-  Send(new GpuCommandBufferMsg_TakeFrontBuffer(route_id_, mailbox));
+  // TakeFrontBuffer should be a deferred message so that it's sequenced
+  // correctly with respect to preceding ReturnFrontBuffer messages.
+  last_flush_id_ = channel_->EnqueueDeferredMessage(
+      GpuCommandBufferMsg_TakeFrontBuffer(route_id_, mailbox));
 }
 
 void CommandBufferProxyImpl::ReturnFrontBuffer(const gpu::Mailbox& mailbox,
diff --git a/gpu/ipc/service/gpu_channel.cc b/gpu/ipc/service/gpu_channel.cc
index adee5e3..d1f36aa 100644
--- a/gpu/ipc/service/gpu_channel.cc
+++ b/gpu/ipc/service/gpu_channel.cc
@@ -242,6 +242,7 @@
     case GpuCommandBufferMsg_AsyncFlush::ID:
     case GpuCommandBufferMsg_DestroyTransferBuffer::ID:
     case GpuCommandBufferMsg_ReturnFrontBuffer::ID:
+    case GpuCommandBufferMsg_TakeFrontBuffer::ID:
     case GpuChannelMsg_CreateSharedImage::ID:
     case GpuChannelMsg_DestroySharedImage::ID:
       return MessageErrorHandler(message, "Invalid message");