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"
10 #include "base/logging.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/metrics/sparse_histogram.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "base/strings/string_piece.h"
15 #include "base/strings/string_split.h"
16 #include "base/trace_event/trace_event.h"
17 #include "ui/gl/gl_bindings.h"
18 #include "ui/gl/gl_context.h"
19 #include "ui/gl/gl_implementation.h"
20 #include "ui/gl/gl_surface.h"
24 scoped_refptr
<gfx::GLSurface
> InitializeGLSurface() {
25 scoped_refptr
<gfx::GLSurface
> surface(
26 gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size()));
28 LOG(ERROR
) << "gfx::GLContext::CreateOffscreenGLSurface failed";
35 scoped_refptr
<gfx::GLContext
> InitializeGLContext(gfx::GLSurface
* surface
) {
37 scoped_refptr
<gfx::GLContext
> context(
38 gfx::GLContext::CreateGLContext(NULL
,
40 gfx::PreferIntegratedGpu
));
42 LOG(ERROR
) << "gfx::GLContext::CreateGLContext failed";
46 if (!context
->MakeCurrent(surface
)) {
47 LOG(ERROR
) << "gfx::GLContext::MakeCurrent() failed";
54 std::string
GetGLString(unsigned int pname
) {
55 const char* gl_string
=
56 reinterpret_cast<const char*>(glGetString(pname
));
58 return std::string(gl_string
);
62 // Return a version string in the format of "major.minor".
63 std::string
GetVersionFromString(const std::string
& version_string
) {
64 size_t begin
= version_string
.find_first_of("0123456789");
65 if (begin
!= std::string::npos
) {
66 size_t end
= version_string
.find_first_not_of("01234567890.", begin
);
67 std::string sub_string
;
68 if (end
!= std::string::npos
)
69 sub_string
= version_string
.substr(begin
, end
- begin
);
71 sub_string
= version_string
.substr(begin
);
72 std::vector
<std::string
> pieces
= base::SplitString(
73 sub_string
, ".", base::TRIM_WHITESPACE
, base::SPLIT_WANT_ALL
);
74 if (pieces
.size() >= 2)
75 return pieces
[0] + "." + pieces
[1];
80 } // namespace anonymous
84 CollectInfoResult
CollectGraphicsInfoGL(GPUInfo
* gpu_info
) {
85 TRACE_EVENT0("startup", "gpu_info_collector::CollectGraphicsInfoGL");
86 DCHECK_NE(gfx::GetGLImplementation(), gfx::kGLImplementationNone
);
88 scoped_refptr
<gfx::GLSurface
> surface(InitializeGLSurface());
90 LOG(ERROR
) << "Could not create surface for info collection.";
91 return kCollectInfoFatalFailure
;
94 scoped_refptr
<gfx::GLContext
> context(InitializeGLContext(surface
.get()));
96 LOG(ERROR
) << "Could not create context for info collection.";
97 return kCollectInfoFatalFailure
;
100 gpu_info
->gl_renderer
= GetGLString(GL_RENDERER
);
101 gpu_info
->gl_vendor
= GetGLString(GL_VENDOR
);
102 gpu_info
->gl_extensions
= gfx::GetGLExtensionsFromCurrentContext();
103 gpu_info
->gl_version
= GetGLString(GL_VERSION
);
104 std::string glsl_version_string
= GetGLString(GL_SHADING_LANGUAGE_VERSION
);
105 GLint max_samples
= 0;
106 glGetIntegerv(GL_MAX_SAMPLES
, &max_samples
);
107 gpu_info
->max_msaa_samples
= base::IntToString(max_samples
);
108 UMA_HISTOGRAM_SPARSE_SLOWLY("GPU.MaxMSAASampleCount", max_samples
);
110 gfx::GLWindowSystemBindingInfo window_system_binding_info
;
111 if (GetGLWindowSystemBindingInfo(&window_system_binding_info
)) {
112 gpu_info
->gl_ws_vendor
= window_system_binding_info
.vendor
;
113 gpu_info
->gl_ws_version
= window_system_binding_info
.version
;
114 gpu_info
->gl_ws_extensions
= window_system_binding_info
.extensions
;
115 gpu_info
->direct_rendering
= window_system_binding_info
.direct_rendering
;
118 bool supports_robustness
=
119 gpu_info
->gl_extensions
.find("GL_EXT_robustness") != std::string::npos
||
120 gpu_info
->gl_extensions
.find("GL_KHR_robustness") != std::string::npos
||
121 gpu_info
->gl_extensions
.find("GL_ARB_robustness") != std::string::npos
;
122 if (supports_robustness
) {
123 glGetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_ARB
,
124 reinterpret_cast<GLint
*>(&gpu_info
->gl_reset_notification_strategy
));
127 // TODO(kbr): remove once the destruction of a current context automatically
128 // clears the current context.
129 context
->ReleaseCurrent(surface
.get());
131 std::string glsl_version
= GetVersionFromString(glsl_version_string
);
132 gpu_info
->pixel_shader_version
= glsl_version
;
133 gpu_info
->vertex_shader_version
= glsl_version
;
135 return CollectDriverInfoGL(gpu_info
);
138 void MergeGPUInfoGL(GPUInfo
* basic_gpu_info
,
139 const GPUInfo
& context_gpu_info
) {
140 DCHECK(basic_gpu_info
);
141 basic_gpu_info
->gl_renderer
= context_gpu_info
.gl_renderer
;
142 basic_gpu_info
->gl_vendor
= context_gpu_info
.gl_vendor
;
143 basic_gpu_info
->gl_version
= context_gpu_info
.gl_version
;
144 basic_gpu_info
->gl_extensions
= context_gpu_info
.gl_extensions
;
145 basic_gpu_info
->pixel_shader_version
=
146 context_gpu_info
.pixel_shader_version
;
147 basic_gpu_info
->vertex_shader_version
=
148 context_gpu_info
.vertex_shader_version
;
149 basic_gpu_info
->max_msaa_samples
=
150 context_gpu_info
.max_msaa_samples
;
151 basic_gpu_info
->gl_ws_vendor
= context_gpu_info
.gl_ws_vendor
;
152 basic_gpu_info
->gl_ws_version
= context_gpu_info
.gl_ws_version
;
153 basic_gpu_info
->gl_ws_extensions
= context_gpu_info
.gl_ws_extensions
;
154 basic_gpu_info
->gl_reset_notification_strategy
=
155 context_gpu_info
.gl_reset_notification_strategy
;
157 if (!context_gpu_info
.driver_vendor
.empty())
158 basic_gpu_info
->driver_vendor
= context_gpu_info
.driver_vendor
;
159 if (!context_gpu_info
.driver_version
.empty())
160 basic_gpu_info
->driver_version
= context_gpu_info
.driver_version
;
162 basic_gpu_info
->can_lose_context
= context_gpu_info
.can_lose_context
;
163 basic_gpu_info
->sandboxed
= context_gpu_info
.sandboxed
;
164 basic_gpu_info
->direct_rendering
= context_gpu_info
.direct_rendering
;
165 basic_gpu_info
->in_process_gpu
= context_gpu_info
.in_process_gpu
;
166 basic_gpu_info
->context_info_state
= context_gpu_info
.context_info_state
;
167 basic_gpu_info
->initialization_time
= context_gpu_info
.initialization_time
;
168 basic_gpu_info
->video_decode_accelerator_supported_profiles
=
169 context_gpu_info
.video_decode_accelerator_supported_profiles
;
170 basic_gpu_info
->video_encode_accelerator_supported_profiles
=
171 context_gpu_info
.video_encode_accelerator_supported_profiles
;
172 basic_gpu_info
->jpeg_decode_accelerator_supported
=
173 context_gpu_info
.jpeg_decode_accelerator_supported
;