Cherry-pick: android: Disable transfer thread on Adreno 420

Cherry-pick of chromium crrev.com/b46831d14f773db39a3e90dc01281bff3c269649

Conflicts:
	gpu/command_buffer/service/async_pixel_transfer_manager_android.cc

Change-Id: I088f1a397f623d7acb59308494459163decf1432

BUG: 18178303
diff --git a/gpu/command_buffer/service/async_pixel_transfer_manager_android.cc b/gpu/command_buffer/service/async_pixel_transfer_manager_android.cc
index a2b2255..046ecc3 100644
--- a/gpu/command_buffer/service/async_pixel_transfer_manager_android.cc
+++ b/gpu/command_buffer/service/async_pixel_transfer_manager_android.cc
@@ -16,26 +16,49 @@
 namespace gpu {
 namespace {
 
-bool IsBroadcom() {
-  const char* vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR));
-  if (vendor)
-    return std::string(vendor).find("Broadcom") != std::string::npos;
-  return false;
+enum GpuType {
+  GPU_BROADCOM,
+  GPU_IMAGINATION,
+  GPU_NVIDIA_ES31,
+  GPU_ADRENO_420,
+  GPU_OTHER,
+};
+
+std::string MakeString(const char* s) {
+  return std::string(s ? s : "");
 }
 
-bool IsImagination() {
-  const char* vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR));
-  if (vendor)
-    return std::string(vendor).find("Imagination") != std::string::npos;
-  return false;
+GpuType GetGpuType() {
+  const std::string vendor = MakeString(
+      reinterpret_cast<const char*>(glGetString(GL_VENDOR)));
+  const std::string renderer = MakeString(
+      reinterpret_cast<const char*>(glGetString(GL_RENDERER)));
+  const std::string version = MakeString(
+      reinterpret_cast<const char*>(glGetString(GL_VERSION)));
+
+  if (vendor.find("Broadcom") != std::string::npos)
+    return GPU_BROADCOM;
+
+  if (vendor.find("Imagination") != std::string::npos)
+    return GPU_IMAGINATION;
+
+  if (vendor.find("NVIDIA") != std::string::npos &&
+      version.find("OpenGL ES 3.1") != std::string::npos) {
+    return GPU_NVIDIA_ES31;
+  }
+
+  if (vendor.find("Qualcomm") != std::string::npos &&
+      renderer.find("Adreno (TM) 420") != std::string::npos) {
+    return GPU_ADRENO_420;
+  }
+
+  return GPU_OTHER;
 }
 
-bool IsNvidia31() {
-  const char* vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR));
-  const char* version = reinterpret_cast<const char*>(glGetString(GL_VERSION));
-  return vendor && version &&
-         std::string(vendor).find("NVIDIA") != std::string::npos &&
-         std::string(version).find("OpenGL ES 3.1") != std::string::npos;
+bool AllowTransferThreadForGpu() {
+  GpuType gpu = GetGpuType();
+  return gpu != GPU_BROADCOM && gpu != GPU_IMAGINATION &&
+         gpu != GPU_NVIDIA_ES31 && gpu != GPU_ADRENO_420;
 }
 
 }
@@ -51,24 +74,25 @@
 // resolution of crbug.com/271929
 AsyncPixelTransferManager* AsyncPixelTransferManager::Create(
     gfx::GLContext* context) {
-  TRACE_EVENT0("gpu", "AsyncPixelTransferManager::Create");
+  DCHECK(context->IsCurrent(NULL));
   switch (gfx::GetGLImplementation()) {
     case gfx::kGLImplementationEGLGLES2:
       DCHECK(context);
-      if (context->HasExtension("EGL_KHR_fence_sync") &&
+      if (!base::android::SysUtils::IsLowEndDevice() &&
+          context->HasExtension("EGL_KHR_fence_sync") &&
           context->HasExtension("EGL_KHR_image") &&
           context->HasExtension("EGL_KHR_image_base") &&
           context->HasExtension("EGL_KHR_gl_texture_2D_image") &&
           context->HasExtension("GL_OES_EGL_image") &&
-          !IsBroadcom() &&
-          !IsImagination() &&
-          !IsNvidia31() &&
-          !base::android::SysUtils::IsLowEndDevice()) {
+          AllowTransferThreadForGpu()) {
+        TRACE_EVENT0("gpu", "AsyncPixelTransferManager_CreateWithThread");
         return new AsyncPixelTransferManagerEGL;
       }
       return new AsyncPixelTransferManagerIdle;
-    case gfx::kGLImplementationOSMesaGL:
+    case gfx::kGLImplementationOSMesaGL: {
+      TRACE_EVENT0("gpu", "AsyncPixelTransferManager_CreateIdle");
       return new AsyncPixelTransferManagerIdle;
+    }
     case gfx::kGLImplementationMockGL:
       return new AsyncPixelTransferManagerStub;
     default: