1 // Copyright (c) 2012 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/config/gpu_info_collector.h"
6
7 #include "base/android/build_info.h"
8 #include "base/command_line.h"
9 #include "base/logging.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/string_piece.h"
12 #include "base/strings/string_split.h"
13 #include "base/strings/string_util.h"
14 #include "ui/gl/gl_bindings.h"
15 #include "ui/gl/gl_context.h"
16 #include "ui/gl/gl_surface.h"
17
18 namespace {
19
GetDriverVersionFromString(const std::string & version_string)20 std::string GetDriverVersionFromString(const std::string& version_string) {
21 // Extract driver version from the second number in a string like:
22 // "OpenGL ES 2.0 V@6.0 AU@ (CL@2946718)"
23
24 // Exclude first "2.0".
25 size_t begin = version_string.find_first_of("0123456789");
26 if (begin == std::string::npos)
27 return "0";
28 size_t end = version_string.find_first_not_of("01234567890.", begin);
29
30 // Extract number of the form "%d.%d"
31 begin = version_string.find_first_of("0123456789", end);
32 if (begin == std::string::npos)
33 return "0";
34 end = version_string.find_first_not_of("01234567890.", begin);
35 std::string sub_string;
36 if (end != std::string::npos)
37 sub_string = version_string.substr(begin, end - begin);
38 else
39 sub_string = version_string.substr(begin);
40 std::vector<std::string> pieces;
41 base::SplitString(sub_string, '.', &pieces);
42 if (pieces.size() < 2)
43 return "0";
44 return pieces[0] + "." + pieces[1];
45 }
46
47 class ScopedRestoreNonOwnedEGLContext {
48 public:
49 ScopedRestoreNonOwnedEGLContext();
50 ~ScopedRestoreNonOwnedEGLContext();
51
52 private:
53 EGLContext context_;
54 EGLDisplay display_;
55 EGLSurface draw_surface_;
56 EGLSurface read_surface_;
57 };
58
ScopedRestoreNonOwnedEGLContext()59 ScopedRestoreNonOwnedEGLContext::ScopedRestoreNonOwnedEGLContext()
60 : context_(EGL_NO_CONTEXT),
61 display_(EGL_NO_DISPLAY),
62 draw_surface_(EGL_NO_SURFACE),
63 read_surface_(EGL_NO_SURFACE) {
64 // This should only used to restore a context that is not created or owned by
65 // Chromium native code, but created by Android system itself.
66 DCHECK(!gfx::GLContext::GetCurrent());
67
68 if (gfx::GLSurface::InitializeOneOff()) {
69 context_ = eglGetCurrentContext();
70 display_ = eglGetCurrentDisplay();
71 draw_surface_ = eglGetCurrentSurface(EGL_DRAW);
72 read_surface_ = eglGetCurrentSurface(EGL_READ);
73 }
74 }
75
~ScopedRestoreNonOwnedEGLContext()76 ScopedRestoreNonOwnedEGLContext::~ScopedRestoreNonOwnedEGLContext() {
77 if (context_ == EGL_NO_CONTEXT || display_ == EGL_NO_DISPLAY ||
78 draw_surface_ == EGL_NO_SURFACE || read_surface_ == EGL_NO_SURFACE) {
79 return;
80 }
81
82 if (!eglMakeCurrent(display_, draw_surface_, read_surface_, context_)) {
83 LOG(WARNING) << "Failed to restore EGL context";
84 }
85 }
86
87 }
88
89 namespace gpu {
90
CollectContextGraphicsInfo(GPUInfo * gpu_info)91 bool CollectContextGraphicsInfo(GPUInfo* gpu_info) {
92 return CollectBasicGraphicsInfo(gpu_info);
93 }
94
CollectGpuID(uint32 * vendor_id,uint32 * device_id)95 GpuIDResult CollectGpuID(uint32* vendor_id, uint32* device_id) {
96 DCHECK(vendor_id && device_id);
97 *vendor_id = 0;
98 *device_id = 0;
99 return kGpuIDNotSupported;
100 }
101
CollectBasicGraphicsInfo(GPUInfo * gpu_info)102 bool CollectBasicGraphicsInfo(GPUInfo* gpu_info) {
103 gpu_info->can_lose_context = false;
104 gpu_info->finalized = true;
105
106 gpu_info->machine_model = base::android::BuildInfo::GetInstance()->model();
107
108 // Create a short-lived context on the UI thread to collect the GL strings.
109 // Make sure we restore the existing context if there is one.
110 ScopedRestoreNonOwnedEGLContext restore_context;
111 return CollectGraphicsInfoGL(gpu_info);
112 }
113
CollectDriverInfoGL(GPUInfo * gpu_info)114 bool CollectDriverInfoGL(GPUInfo* gpu_info) {
115 gpu_info->driver_version = GetDriverVersionFromString(
116 gpu_info->gl_version_string);
117 gpu_info->gpu.vendor_string = gpu_info->gl_vendor;
118 gpu_info->gpu.device_string = gpu_info->gl_renderer;
119 return true;
120 }
121
MergeGPUInfo(GPUInfo * basic_gpu_info,const GPUInfo & context_gpu_info)122 void MergeGPUInfo(GPUInfo* basic_gpu_info,
123 const GPUInfo& context_gpu_info) {
124 MergeGPUInfoGL(basic_gpu_info, context_gpu_info);
125 }
126
DetermineActiveGPU(GPUInfo * gpu_info)127 bool DetermineActiveGPU(GPUInfo* gpu_info) {
128 DCHECK(gpu_info);
129 if (gpu_info->secondary_gpus.size() == 0)
130 return true;
131 // TODO(zmo): implement this when Android starts to support more
132 // than one GPUs.
133 return false;
134 }
135
136 } // namespace gpu
137