OLD | NEW |
| (Empty) |
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/command_line.h" | |
8 #include "base/sys_info.h" | |
9 #include "base/trace_event/trace_event.h" | |
10 #include "gpu/command_buffer/service/async_pixel_transfer_manager_egl.h" | |
11 #include "gpu/command_buffer/service/async_pixel_transfer_manager_idle.h" | |
12 #include "gpu/command_buffer/service/async_pixel_transfer_manager_stub.h" | |
13 #include "gpu/command_buffer/service/async_pixel_transfer_manager_sync.h" | |
14 #include "gpu/command_buffer/service/gpu_switches.h" | |
15 #include "ui/gl/gl_context.h" | |
16 #include "ui/gl/gl_implementation.h" | |
17 | |
18 namespace gpu { | |
19 namespace { | |
20 | |
21 enum GpuType { | |
22 GPU_BROADCOM, | |
23 GPU_IMAGINATION, | |
24 GPU_NVIDIA_ES31, | |
25 GPU_ADRENO_420, | |
26 GPU_OTHER, | |
27 }; | |
28 | |
29 std::string MakeString(const char* s) { | |
30 return std::string(s ? s : ""); | |
31 } | |
32 | |
33 GpuType GetGpuType() { | |
34 const std::string vendor = MakeString( | |
35 reinterpret_cast<const char*>(glGetString(GL_VENDOR))); | |
36 const std::string renderer = MakeString( | |
37 reinterpret_cast<const char*>(glGetString(GL_RENDERER))); | |
38 const std::string version = MakeString( | |
39 reinterpret_cast<const char*>(glGetString(GL_VERSION))); | |
40 | |
41 if (vendor.find("Broadcom") != std::string::npos) | |
42 return GPU_BROADCOM; | |
43 | |
44 if (vendor.find("Imagination") != std::string::npos) | |
45 return GPU_IMAGINATION; | |
46 | |
47 if (vendor.find("NVIDIA") != std::string::npos && | |
48 version.find("OpenGL ES 3.1") != std::string::npos) { | |
49 return GPU_NVIDIA_ES31; | |
50 } | |
51 | |
52 if (vendor.find("Qualcomm") != std::string::npos && | |
53 renderer.find("Adreno (TM) 420") != std::string::npos) { | |
54 return GPU_ADRENO_420; | |
55 } | |
56 | |
57 return GPU_OTHER; | |
58 } | |
59 | |
60 bool AllowTransferThreadForGpu() { | |
61 GpuType gpu = GetGpuType(); | |
62 return gpu != GPU_BROADCOM && gpu != GPU_IMAGINATION && | |
63 gpu != GPU_NVIDIA_ES31 && gpu != GPU_ADRENO_420; | |
64 } | |
65 | |
66 } | |
67 | |
68 // We only used threaded uploads when we can: | |
69 // - Create EGLImages out of OpenGL textures (EGL_KHR_gl_texture_2D_image) | |
70 // - Bind EGLImages to OpenGL textures (GL_OES_EGL_image) | |
71 // - Use fences (to test for upload completion). | |
72 // - The heap size is large enough. | |
73 // TODO(kaanb|epenner): Remove the IsImagination() check pending the | |
74 // resolution of crbug.com/249147 | |
75 // TODO(kaanb|epenner): Remove the IsLowEndDevice() check pending the | |
76 // resolution of crbug.com/271929 | |
77 AsyncPixelTransferManager* AsyncPixelTransferManager::Create( | |
78 gfx::GLContext* context) { | |
79 DCHECK(context->IsCurrent(NULL)); | |
80 base::CommandLine* cl = base::CommandLine::ForCurrentProcess(); | |
81 | |
82 // Threaded mailbox uses EGLImage which conflicts with EGL uploader. | |
83 // The spec only allows one EGL image per sibling group, but currently the | |
84 // image handle cannot be shared between the threaded mailbox code and | |
85 // AsyncPixelTransferManagerEGL. | |
86 bool uses_threaded_mailboxes = | |
87 cl->HasSwitch(switches::kEnableThreadedTextureMailboxes); | |
88 // TexImage2D orphans the EGLImage used for threaded mailbox sharing. | |
89 bool use_teximage2d_over_texsubimage2d = !uses_threaded_mailboxes; | |
90 switch (gfx::GetGLImplementation()) { | |
91 case gfx::kGLImplementationEGLGLES2: | |
92 DCHECK(context); | |
93 if (!base::SysInfo::IsLowEndDevice() && | |
94 context->HasExtension("EGL_KHR_fence_sync") && | |
95 context->HasExtension("EGL_KHR_image") && | |
96 context->HasExtension("EGL_KHR_image_base") && | |
97 context->HasExtension("EGL_KHR_gl_texture_2D_image") && | |
98 context->HasExtension("GL_OES_EGL_image") && | |
99 !uses_threaded_mailboxes && AllowTransferThreadForGpu()) { | |
100 TRACE_EVENT0("gpu", "AsyncPixelTransferManager_CreateWithThread"); | |
101 return new AsyncPixelTransferManagerEGL; | |
102 } | |
103 return new AsyncPixelTransferManagerIdle( | |
104 use_teximage2d_over_texsubimage2d); | |
105 case gfx::kGLImplementationOSMesaGL: { | |
106 TRACE_EVENT0("gpu", "AsyncPixelTransferManager_CreateIdle"); | |
107 return new AsyncPixelTransferManagerIdle( | |
108 use_teximage2d_over_texsubimage2d); | |
109 } | |
110 case gfx::kGLImplementationMockGL: | |
111 return new AsyncPixelTransferManagerStub; | |
112 default: | |
113 NOTREACHED(); | |
114 return NULL; | |
115 } | |
116 } | |
117 | |
118 } // namespace gpu | |
OLD | NEW |