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.
5 #include "gpu/config/gpu_info_collector.h"
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"
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)"
24 // Exclude first "2.0".
25 size_t begin
= version_string
.find_first_of("0123456789");
26 if (begin
== std::string::npos
)
28 size_t end
= version_string
.find_first_not_of("01234567890.", begin
);
30 // Extract number of the form "%d.%d"
31 begin
= version_string
.find_first_of("0123456789", end
);
32 if (begin
== std::string::npos
)
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
);
39 sub_string
= version_string
.substr(begin
);
40 std::vector
<std::string
> pieces
;
41 base::SplitString(sub_string
, '.', &pieces
);
42 if (pieces
.size() < 2)
44 return pieces
[0] + "." + pieces
[1];
47 class ScopedRestoreNonOwnedEGLContext
{
49 ScopedRestoreNonOwnedEGLContext();
50 ~ScopedRestoreNonOwnedEGLContext();
55 EGLSurface draw_surface_
;
56 EGLSurface read_surface_
;
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());
68 context_
= eglGetCurrentContext();
69 display_
= eglGetCurrentDisplay();
70 draw_surface_
= eglGetCurrentSurface(EGL_DRAW
);
71 read_surface_
= eglGetCurrentSurface(EGL_READ
);
74 ScopedRestoreNonOwnedEGLContext::~ScopedRestoreNonOwnedEGLContext() {
75 if (context_
== EGL_NO_CONTEXT
|| display_
== EGL_NO_DISPLAY
||
76 draw_surface_
== EGL_NO_SURFACE
|| read_surface_
== EGL_NO_SURFACE
)
79 if (!eglMakeCurrent(display_
, draw_surface_
, read_surface_
, context_
))
80 LOG(WARNING
) << "Failed to restore EGL context";
87 CollectInfoResult
CollectContextGraphicsInfo(GPUInfo
* gpu_info
) {
88 return CollectBasicGraphicsInfo(gpu_info
);
91 CollectInfoResult
CollectGpuID(uint32
* vendor_id
, uint32
* device_id
) {
92 DCHECK(vendor_id
&& device_id
);
95 return kCollectInfoNonFatalFailure
;
98 CollectInfoResult
CollectBasicGraphicsInfo(GPUInfo
* gpu_info
) {
99 gpu_info
->can_lose_context
= false;
101 gpu_info
->machine_model_name
=
102 base::android::BuildInfo::GetInstance()->model();
104 // Create a short-lived context on the UI thread to collect the GL strings.
105 // Make sure we restore the existing context if there is one.
106 ScopedRestoreNonOwnedEGLContext restore_context
;
107 CollectInfoResult result
= CollectGraphicsInfoGL(gpu_info
);
108 gpu_info
->basic_info_state
= result
;
109 gpu_info
->context_info_state
= result
;
113 CollectInfoResult
CollectDriverInfoGL(GPUInfo
* gpu_info
) {
114 gpu_info
->driver_version
= GetDriverVersionFromString(
115 gpu_info
->gl_version
);
116 gpu_info
->gpu
.vendor_string
= gpu_info
->gl_vendor
;
117 gpu_info
->gpu
.device_string
= gpu_info
->gl_renderer
;
118 return kCollectInfoSuccess
;
121 void MergeGPUInfo(GPUInfo
* basic_gpu_info
,
122 const GPUInfo
& context_gpu_info
) {
123 MergeGPUInfoGL(basic_gpu_info
, context_gpu_info
);