blob: beda6fd5b96951f75415860d851951ba52db1bf5 [file] [log] [blame]
[email protected]c9e2cbbb2012-05-12 21:17:271// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]7004d7eb2011-01-21 00:27:532// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]d7b5cc72013-05-23 20:05:005#include "gpu/config/gpu_info_collector.h"
[email protected]7004d7eb2011-01-21 00:27:536
7#include <string>
8#include <vector>
9
[email protected]7004d7eb2011-01-21 00:27:5310#include "base/logging.h"
[email protected]c9e2cbbb2012-05-12 21:17:2711#include "base/memory/scoped_ptr.h"
senorblanco930f690f2015-09-18 16:18:0312#include "base/metrics/sparse_histogram.h"
[email protected]f4390962013-06-11 07:29:2213#include "base/strings/string_number_conversions.h"
[email protected]b9e7c479f2013-04-12 04:33:2414#include "base/strings/string_piece.h"
[email protected]27c05732013-02-15 21:55:4915#include "base/strings/string_split.h"
primiano05dadf012015-01-28 13:10:3216#include "base/trace_event/trace_event.h"
[email protected]c9e2cbbb2012-05-12 21:17:2717#include "ui/gl/gl_bindings.h"
18#include "ui/gl/gl_context.h"
[email protected]45895032013-05-30 17:06:4319#include "ui/gl/gl_implementation.h"
[email protected]c9e2cbbb2012-05-12 21:17:2720#include "ui/gl/gl_surface.h"
j.isorce246d1be52015-12-03 21:53:3621#include "ui/gl/gl_version_info.h"
[email protected]7004d7eb2011-01-21 00:27:5322
23namespace {
24
[email protected]fbe20372011-06-01 01:46:3825scoped_refptr<gfx::GLSurface> InitializeGLSurface() {
26 scoped_refptr<gfx::GLSurface> surface(
[email protected]772aa832014-05-30 01:27:4727 gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size()));
[email protected]7cd76fd2013-06-02 21:11:1128 if (!surface.get()) {
[email protected]ffae4022011-05-12 22:54:2929 LOG(ERROR) << "gfx::GLContext::CreateOffscreenGLSurface failed";
[email protected]7004d7eb2011-01-21 00:27:5330 return NULL;
31 }
[email protected]ffae4022011-05-12 22:54:2932
[email protected]fbe20372011-06-01 01:46:3833 return surface;
[email protected]f62a5ab2011-05-23 20:34:1534}
35
[email protected]fbe20372011-06-01 01:46:3836scoped_refptr<gfx::GLContext> InitializeGLContext(gfx::GLSurface* surface) {
[email protected]f62a5ab2011-05-23 20:34:1537
[email protected]7196e012011-06-16 20:54:5338 scoped_refptr<gfx::GLContext> context(
[email protected]276f89062011-10-13 22:55:5039 gfx::GLContext::CreateGLContext(NULL,
40 surface,
[email protected]56403c22012-10-04 18:27:0441 gfx::PreferIntegratedGpu));
[email protected]7cd76fd2013-06-02 21:11:1142 if (!context.get()) {
[email protected]ffae4022011-05-12 22:54:2943 LOG(ERROR) << "gfx::GLContext::CreateGLContext failed";
44 return NULL;
45 }
46
[email protected]f62a5ab2011-05-23 20:34:1547 if (!context->MakeCurrent(surface)) {
[email protected]7004d7eb2011-01-21 00:27:5348 LOG(ERROR) << "gfx::GLContext::MakeCurrent() failed";
[email protected]7004d7eb2011-01-21 00:27:5349 return NULL;
50 }
[email protected]7004d7eb2011-01-21 00:27:5351
[email protected]fbe20372011-06-01 01:46:3852 return context;
[email protected]7004d7eb2011-01-21 00:27:5353}
54
55std::string GetGLString(unsigned int pname) {
56 const char* gl_string =
57 reinterpret_cast<const char*>(glGetString(pname));
58 if (gl_string)
59 return std::string(gl_string);
[email protected]007b3f82013-04-09 08:46:4560 return std::string();
[email protected]7004d7eb2011-01-21 00:27:5361}
62
[email protected]6cc8ece62011-03-14 20:05:4763// Return a version string in the format of "major.minor".
64std::string GetVersionFromString(const std::string& version_string) {
[email protected]7004d7eb2011-01-21 00:27:5365 size_t begin = version_string.find_first_of("0123456789");
66 if (begin != std::string::npos) {
67 size_t end = version_string.find_first_not_of("01234567890.", begin);
68 std::string sub_string;
69 if (end != std::string::npos)
70 sub_string = version_string.substr(begin, end - begin);
71 else
72 sub_string = version_string.substr(begin);
brettw26dab8f02015-08-08 00:28:4773 std::vector<std::string> pieces = base::SplitString(
74 sub_string, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
[email protected]6cc8ece62011-03-14 20:05:4775 if (pieces.size() >= 2)
76 return pieces[0] + "." + pieces[1];
[email protected]7004d7eb2011-01-21 00:27:5377 }
[email protected]007b3f82013-04-09 08:46:4578 return std::string();
[email protected]7004d7eb2011-01-21 00:27:5379}
80
81} // namespace anonymous
82
[email protected]d7b5cc72013-05-23 20:05:0083namespace gpu {
[email protected]7004d7eb2011-01-21 00:27:5384
[email protected]0e8cac72014-03-22 00:37:1885CollectInfoResult CollectGraphicsInfoGL(GPUInfo* gpu_info) {
[email protected]aa328c72013-05-03 10:55:4386 TRACE_EVENT0("startup", "gpu_info_collector::CollectGraphicsInfoGL");
[email protected]93389042014-02-11 03:46:5287 DCHECK_NE(gfx::GetGLImplementation(), gfx::kGLImplementationNone);
[email protected]f62a5ab2011-05-23 20:34:1588
[email protected]fbe20372011-06-01 01:46:3889 scoped_refptr<gfx::GLSurface> surface(InitializeGLSurface());
[email protected]0e8cac72014-03-22 00:37:1890 if (!surface.get()) {
91 LOG(ERROR) << "Could not create surface for info collection.";
92 return kCollectInfoFatalFailure;
93 }
[email protected]f62a5ab2011-05-23 20:34:1594
[email protected]fbe20372011-06-01 01:46:3895 scoped_refptr<gfx::GLContext> context(InitializeGLContext(surface.get()));
[email protected]0e8cac72014-03-22 00:37:1896 if (!context.get()) {
97 LOG(ERROR) << "Could not create context for info collection.";
98 return kCollectInfoFatalFailure;
99 }
[email protected]7004d7eb2011-01-21 00:27:53100
[email protected]a61508e52011-03-08 17:59:42101 gpu_info->gl_renderer = GetGLString(GL_RENDERER);
102 gpu_info->gl_vendor = GetGLString(GL_VENDOR);
kbr53edb992015-08-06 01:16:29103 gpu_info->gl_extensions = gfx::GetGLExtensionsFromCurrentContext();
[email protected]39c542622014-05-07 22:16:36104 gpu_info->gl_version = GetGLString(GL_VERSION);
[email protected]4df0884f2012-12-17 21:10:09105 std::string glsl_version_string = GetGLString(GL_SHADING_LANGUAGE_VERSION);
j.isorce246d1be52015-12-03 21:53:36106
107 gfx::GLVersionInfo gl_info(gpu_info->gl_version.c_str(),
108 gpu_info->gl_renderer.c_str(),
109 gpu_info->gl_extensions.c_str());
senorblancob7a64d52015-04-08 16:59:02110 GLint max_samples = 0;
j.isorce246d1be52015-12-03 21:53:36111 if (gl_info.IsAtLeastGL(3, 0) || gl_info.IsAtLeastGLES(3, 0) ||
112 gpu_info->gl_extensions.find("GL_ANGLE_framebuffer_multisample") !=
113 std::string::npos ||
114 gpu_info->gl_extensions.find("GL_APPLE_framebuffer_multisample") !=
115 std::string::npos ||
116 gpu_info->gl_extensions.find("GL_EXT_framebuffer_multisample") !=
117 std::string::npos ||
118 gpu_info->gl_extensions.find("GL_EXT_multisampled_render_to_texture") !=
119 std::string::npos ||
120 gpu_info->gl_extensions.find("GL_NV_framebuffer_multisample") !=
121 std::string::npos) {
122 glGetIntegerv(GL_MAX_SAMPLES, &max_samples);
123 }
riceaa01edead2015-07-01 15:56:50124 gpu_info->max_msaa_samples = base::IntToString(max_samples);
senorblanco930f690f2015-09-18 16:18:03125 UMA_HISTOGRAM_SPARSE_SLOWLY("GPU.MaxMSAASampleCount", max_samples);
[email protected]45895032013-05-30 17:06:43126
127 gfx::GLWindowSystemBindingInfo window_system_binding_info;
128 if (GetGLWindowSystemBindingInfo(&window_system_binding_info)) {
129 gpu_info->gl_ws_vendor = window_system_binding_info.vendor;
130 gpu_info->gl_ws_version = window_system_binding_info.version;
131 gpu_info->gl_ws_extensions = window_system_binding_info.extensions;
[email protected]0e8cac72014-03-22 00:37:18132 gpu_info->direct_rendering = window_system_binding_info.direct_rendering;
[email protected]45895032013-05-30 17:06:43133 }
134
[email protected]6c7784e2013-08-01 22:41:28135 bool supports_robustness =
136 gpu_info->gl_extensions.find("GL_EXT_robustness") != std::string::npos ||
dongseong.hwange1cb2aa2015-02-11 09:33:33137 gpu_info->gl_extensions.find("GL_KHR_robustness") != std::string::npos ||
[email protected]6c7784e2013-08-01 22:41:28138 gpu_info->gl_extensions.find("GL_ARB_robustness") != std::string::npos;
139 if (supports_robustness) {
140 glGetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_ARB,
141 reinterpret_cast<GLint*>(&gpu_info->gl_reset_notification_strategy));
142 }
143
[email protected]2436a6b2012-04-13 21:08:51144 // TODO(kbr): remove once the destruction of a current context automatically
145 // clears the current context.
146 context->ReleaseCurrent(surface.get());
147
[email protected]6cc8ece62011-03-14 20:05:47148 std::string glsl_version = GetVersionFromString(glsl_version_string);
[email protected]a61508e52011-03-08 17:59:42149 gpu_info->pixel_shader_version = glsl_version;
150 gpu_info->vertex_shader_version = glsl_version;
[email protected]7004d7eb2011-01-21 00:27:53151
[email protected]4df0884f2012-12-17 21:10:09152 return CollectDriverInfoGL(gpu_info);
153}
154
[email protected]d7b5cc72013-05-23 20:05:00155void MergeGPUInfoGL(GPUInfo* basic_gpu_info,
156 const GPUInfo& context_gpu_info) {
[email protected]4df0884f2012-12-17 21:10:09157 DCHECK(basic_gpu_info);
158 basic_gpu_info->gl_renderer = context_gpu_info.gl_renderer;
159 basic_gpu_info->gl_vendor = context_gpu_info.gl_vendor;
[email protected]4df0884f2012-12-17 21:10:09160 basic_gpu_info->gl_version = context_gpu_info.gl_version;
[email protected]39c542622014-05-07 22:16:36161 basic_gpu_info->gl_extensions = context_gpu_info.gl_extensions;
[email protected]4df0884f2012-12-17 21:10:09162 basic_gpu_info->pixel_shader_version =
163 context_gpu_info.pixel_shader_version;
164 basic_gpu_info->vertex_shader_version =
165 context_gpu_info.vertex_shader_version;
senorblancob7a64d52015-04-08 16:59:02166 basic_gpu_info->max_msaa_samples =
167 context_gpu_info.max_msaa_samples;
[email protected]45895032013-05-30 17:06:43168 basic_gpu_info->gl_ws_vendor = context_gpu_info.gl_ws_vendor;
169 basic_gpu_info->gl_ws_version = context_gpu_info.gl_ws_version;
170 basic_gpu_info->gl_ws_extensions = context_gpu_info.gl_ws_extensions;
[email protected]6c7784e2013-08-01 22:41:28171 basic_gpu_info->gl_reset_notification_strategy =
172 context_gpu_info.gl_reset_notification_strategy;
[email protected]4df0884f2012-12-17 21:10:09173
174 if (!context_gpu_info.driver_vendor.empty())
175 basic_gpu_info->driver_vendor = context_gpu_info.driver_vendor;
176 if (!context_gpu_info.driver_version.empty())
177 basic_gpu_info->driver_version = context_gpu_info.driver_version;
178
179 basic_gpu_info->can_lose_context = context_gpu_info.can_lose_context;
180 basic_gpu_info->sandboxed = context_gpu_info.sandboxed;
[email protected]0e8cac72014-03-22 00:37:18181 basic_gpu_info->direct_rendering = context_gpu_info.direct_rendering;
bajonese3677b642015-07-25 00:41:56182 basic_gpu_info->in_process_gpu = context_gpu_info.in_process_gpu;
zmo84eae5e2014-09-05 01:36:23183 basic_gpu_info->context_info_state = context_gpu_info.context_info_state;
[email protected]4df0884f2012-12-17 21:10:09184 basic_gpu_info->initialization_time = context_gpu_info.initialization_time;
henryhsud1185442015-04-10 06:39:14185 basic_gpu_info->video_decode_accelerator_supported_profiles =
186 context_gpu_info.video_decode_accelerator_supported_profiles;
wuchengli79808322014-09-23 05:58:14187 basic_gpu_info->video_encode_accelerator_supported_profiles =
188 context_gpu_info.video_encode_accelerator_supported_profiles;
henryhsu74f6ef12015-07-23 08:34:37189 basic_gpu_info->jpeg_decode_accelerator_supported =
190 context_gpu_info.jpeg_decode_accelerator_supported;
[email protected]7004d7eb2011-01-21 00:27:53191}
192
[email protected]d7b5cc72013-05-23 20:05:00193} // namespace gpu
[email protected]7004d7eb2011-01-21 00:27:53194