Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / gpu / config / gpu_info_collector.cc
blob2b7eaef5b4e797579bf87900d3781466058e7557
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 <string>
8 #include <vector>
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"
22 namespace {
24 scoped_refptr<gfx::GLSurface> InitializeGLSurface() {
25 scoped_refptr<gfx::GLSurface> surface(
26 gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size()));
27 if (!surface.get()) {
28 LOG(ERROR) << "gfx::GLContext::CreateOffscreenGLSurface failed";
29 return NULL;
32 return surface;
35 scoped_refptr<gfx::GLContext> InitializeGLContext(gfx::GLSurface* surface) {
37 scoped_refptr<gfx::GLContext> context(
38 gfx::GLContext::CreateGLContext(NULL,
39 surface,
40 gfx::PreferIntegratedGpu));
41 if (!context.get()) {
42 LOG(ERROR) << "gfx::GLContext::CreateGLContext failed";
43 return NULL;
46 if (!context->MakeCurrent(surface)) {
47 LOG(ERROR) << "gfx::GLContext::MakeCurrent() failed";
48 return NULL;
51 return context;
54 std::string GetGLString(unsigned int pname) {
55 const char* gl_string =
56 reinterpret_cast<const char*>(glGetString(pname));
57 if (gl_string)
58 return std::string(gl_string);
59 return std::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);
70 else
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];
77 return std::string();
80 } // namespace anonymous
82 namespace gpu {
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());
89 if (!surface.get()) {
90 LOG(ERROR) << "Could not create surface for info collection.";
91 return kCollectInfoFatalFailure;
94 scoped_refptr<gfx::GLContext> context(InitializeGLContext(surface.get()));
95 if (!context.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;
176 } // namespace gpu