1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "gpu/command_buffer/service/async_pixel_transfer_manager.h"
6
7#include "base/debug/trace_event.h"
8#include "base/sys_info.h"
9#include "gpu/command_buffer/service/async_pixel_transfer_manager_egl.h"
10#include "gpu/command_buffer/service/async_pixel_transfer_manager_idle.h"
11#include "gpu/command_buffer/service/async_pixel_transfer_manager_stub.h"
12#include "gpu/command_buffer/service/async_pixel_transfer_manager_sync.h"
13#include "ui/gl/gl_context.h"
14#include "ui/gl/gl_implementation.h"
15
16namespace gpu {
17namespace {
18
19enum GpuType {
20  GPU_BROADCOM,
21  GPU_IMAGINATION,
22  GPU_NVIDIA_ES31,
23  GPU_ADRENO_420,
24  GPU_OTHER,
25};
26
27std::string MakeString(const char* s) {
28  return std::string(s ? s : "");
29}
30
31GpuType GetGpuType() {
32  const std::string vendor = MakeString(
33      reinterpret_cast<const char*>(glGetString(GL_VENDOR)));
34  const std::string renderer = MakeString(
35      reinterpret_cast<const char*>(glGetString(GL_RENDERER)));
36  const std::string version = MakeString(
37      reinterpret_cast<const char*>(glGetString(GL_VERSION)));
38
39  if (vendor.find("Broadcom") != std::string::npos)
40    return GPU_BROADCOM;
41
42  if (vendor.find("Imagination") != std::string::npos)
43    return GPU_IMAGINATION;
44
45  if (vendor.find("NVIDIA") != std::string::npos &&
46      version.find("OpenGL ES 3.1") != std::string::npos) {
47    return GPU_NVIDIA_ES31;
48  }
49
50  if (vendor.find("Qualcomm") != std::string::npos &&
51      renderer.find("Adreno (TM) 420") != std::string::npos) {
52    return GPU_ADRENO_420;
53  }
54
55  return GPU_OTHER;
56}
57
58bool AllowTransferThreadForGpu() {
59  GpuType gpu = GetGpuType();
60  return gpu != GPU_BROADCOM && gpu != GPU_IMAGINATION &&
61         gpu != GPU_NVIDIA_ES31 && gpu != GPU_ADRENO_420;
62}
63
64}
65
66// We only used threaded uploads when we can:
67// - Create EGLImages out of OpenGL textures (EGL_KHR_gl_texture_2D_image)
68// - Bind EGLImages to OpenGL textures (GL_OES_EGL_image)
69// - Use fences (to test for upload completion).
70// - The heap size is large enough.
71// TODO(kaanb|epenner): Remove the IsImagination() check pending the
72// resolution of crbug.com/249147
73// TODO(kaanb|epenner): Remove the IsLowEndDevice() check pending the
74// resolution of crbug.com/271929
75AsyncPixelTransferManager* AsyncPixelTransferManager::Create(
76    gfx::GLContext* context) {
77  DCHECK(context->IsCurrent(NULL));
78  switch (gfx::GetGLImplementation()) {
79    case gfx::kGLImplementationEGLGLES2:
80      DCHECK(context);
81      if (!base::SysInfo::IsLowEndDevice() &&
82          context->HasExtension("EGL_KHR_fence_sync") &&
83          context->HasExtension("EGL_KHR_image") &&
84          context->HasExtension("EGL_KHR_image_base") &&
85          context->HasExtension("EGL_KHR_gl_texture_2D_image") &&
86          context->HasExtension("GL_OES_EGL_image") &&
87          AllowTransferThreadForGpu()) {
88        TRACE_EVENT0("gpu", "AsyncPixelTransferManager_CreateWithThread");
89        return new AsyncPixelTransferManagerEGL;
90      }
91      return new AsyncPixelTransferManagerIdle;
92    case gfx::kGLImplementationOSMesaGL: {
93      TRACE_EVENT0("gpu", "AsyncPixelTransferManager_CreateIdle");
94      return new AsyncPixelTransferManagerIdle;
95    }
96    case gfx::kGLImplementationMockGL:
97      return new AsyncPixelTransferManagerStub;
98    default:
99      NOTREACHED();
100      return NULL;
101  }
102}
103
104}  // namespace gpu
105