Use MailboxManagerSync on android.

Egl fences seem to be required for proper cross-context synchronization
on android/qualcomm.

Fixes flickering seen when using surfaces composition on various
android devices (domokit/sky_engine#36).

R=jamesr@chromium.org

Review URL: https://codereview.chromium.org/1348283004 .
diff --git a/services/gles2/BUILD.gn b/services/gles2/BUILD.gn
index 43e8cc0..e8244d1 100644
--- a/services/gles2/BUILD.gn
+++ b/services/gles2/BUILD.gn
@@ -19,6 +19,8 @@
     "gpu_impl.h",
     "gpu_state.cc",
     "gpu_state.h",
+    "mailbox_manager_factory.cc",
+    "mailbox_manager_factory.h",
   ]
 
   public_deps = [
diff --git a/services/gles2/command_buffer_driver.cc b/services/gles2/command_buffer_driver.cc
index 4720bf6..1c3f9f6 100644
--- a/services/gles2/command_buffer_driver.cc
+++ b/services/gles2/command_buffer_driver.cc
@@ -236,6 +236,8 @@
 bool CommandBufferDriver::OnWaitSyncPoint(uint32_t sync_point) {
   if (!sync_point)
     return true;
+  if (mailbox_manager_->UsesSync())
+    mailbox_manager_->PullTextureUpdates(sync_point);
   if (sync_point_manager_->IsSyncPointRetired(sync_point))
     return true;
   scheduler_->SetScheduled(false);
@@ -249,6 +251,12 @@
   scheduler_->SetScheduled(true);
 }
 
+void CommandBufferDriver::RetireSyncPointOnGpuThread(uint32 sync_point) {
+  if (mailbox_manager_->UsesSync())
+    mailbox_manager_->PushTextureUpdates(sync_point);
+  sync_point_manager_->RetireSyncPoint(sync_point);
+}
+
 void CommandBufferDriver::OnContextLost(uint32_t reason) {
   loss_observer_->DidLoseContext(reason);
   client_->DidLoseContext();
diff --git a/services/gles2/command_buffer_driver.h b/services/gles2/command_buffer_driver.h
index c3d6501..7775d7b 100644
--- a/services/gles2/command_buffer_driver.h
+++ b/services/gles2/command_buffer_driver.h
@@ -69,6 +69,7 @@
                               uint32_t size);
   void DestroyTransferBuffer(int32_t id);
   void Echo(const mojo::Callback<void()>& callback);
+  void RetireSyncPointOnGpuThread(uint32_t sync_point);
 
  private:
   bool DoInitialize(mojo::ScopedSharedBufferHandle shared_state);
diff --git a/services/gles2/command_buffer_impl.cc b/services/gles2/command_buffer_impl.cc
index 72a27d0..f999c8e 100644
--- a/services/gles2/command_buffer_impl.cc
+++ b/services/gles2/command_buffer_impl.cc
@@ -124,15 +124,15 @@
   sync_point_client_->DidInsertSyncPoint(sync_point);
   if (retire) {
     driver_task_runner_->PostTask(
-        FROM_HERE, base::Bind(&gpu::SyncPointManager::RetireSyncPoint,
-                              sync_point_manager_, sync_point));
+        FROM_HERE, base::Bind(&CommandBufferDriver::RetireSyncPointOnGpuThread,
+                              base::Unretained(driver_.get()), sync_point));
   }
 }
 
 void CommandBufferImpl::RetireSyncPoint(uint32_t sync_point) {
   driver_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&gpu::SyncPointManager::RetireSyncPoint,
-                            sync_point_manager_, sync_point));
+      FROM_HERE, base::Bind(&CommandBufferDriver::RetireSyncPointOnGpuThread,
+                            base::Unretained(driver_.get()), sync_point));
 }
 
 void CommandBufferImpl::Echo(const mojo::Callback<void()>& callback) {
diff --git a/services/gles2/gpu_state.cc b/services/gles2/gpu_state.cc
index 47439fe..9114771 100644
--- a/services/gles2/gpu_state.cc
+++ b/services/gles2/gpu_state.cc
@@ -5,13 +5,15 @@
 
 #include "services/gles2/gpu_state.h"
 
+#include "services/gles2/mailbox_manager_factory.h"
+
 namespace gles2 {
 
 GpuState::GpuState()
     : control_thread_("gpu_command_buffer_control"),
       sync_point_manager_(gpu::SyncPointManager::Create(true)),
       share_group_(new gfx::GLShareGroup),
-      mailbox_manager_(new gpu::gles2::MailboxManagerImpl) {
+      mailbox_manager_(MailboxManagerFactory::Create()) {
   control_thread_.Start();
 }
 
diff --git a/services/gles2/gpu_state.h b/services/gles2/gpu_state.h
index 1d75318..29a04f9 100644
--- a/services/gles2/gpu_state.h
+++ b/services/gles2/gpu_state.h
@@ -8,7 +8,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/single_thread_task_runner.h"
 #include "base/threading/thread.h"
-#include "gpu/command_buffer/service/mailbox_manager_impl.h"
+#include "gpu/command_buffer/service/mailbox_manager.h"
 #include "gpu/command_buffer/service/sync_point_manager.h"
 #include "ui/gl/gl_share_group.h"
 
diff --git a/services/gles2/mailbox_manager_factory.cc b/services/gles2/mailbox_manager_factory.cc
new file mode 100644
index 0000000..1e8fe34
--- /dev/null
+++ b/services/gles2/mailbox_manager_factory.cc
@@ -0,0 +1,24 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "services/gles2/mailbox_manager_factory.h"
+
+#include "gpu/command_buffer/service/mailbox_manager_impl.h"
+#include "gpu/command_buffer/service/mailbox_manager_sync.h"
+
+namespace gles2 {
+
+gpu::gles2::MailboxManager* MailboxManagerFactory::Create() {
+#if defined(OS_ANDROID)
+  // Use egl fences for synchronization of textures across contexts on android.
+  // TODO(cstout): see if enabling context virtualization removes the need for
+  // fences.
+  return new gpu::gles2::MailboxManagerSync;
+#else
+  return new gpu::gles2::MailboxManagerImpl;
+#endif
+}
+
+}  // namespace gles2
diff --git a/services/gles2/mailbox_manager_factory.h b/services/gles2/mailbox_manager_factory.h
new file mode 100644
index 0000000..0411eef
--- /dev/null
+++ b/services/gles2/mailbox_manager_factory.h
@@ -0,0 +1,19 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SERVICES_GLES2_MAILBOX_MANAGER_FACTORY_H_
+#define SERVICES_GLES2_MAILBOX_MANAGER_FACTORY_H_
+
+#include "gpu/command_buffer/service/mailbox_manager.h"
+
+namespace gles2 {
+
+class MailboxManagerFactory {
+ public:
+  static gpu::gles2::MailboxManager* Create();
+};
+
+}  // namespace gles2
+
+#endif  // SERVICES_GLES2_MAILBOX_MANAGER_FACTORY_H_