• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <string>
8 #include <vector>
9 
10 #include "base/debug/trace_event.h"
11 #include "base/logging.h"
12 #include "base/memory/scoped_ptr.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 "ui/gl/gl_bindings.h"
17 #include "ui/gl/gl_context.h"
18 #include "ui/gl/gl_implementation.h"
19 #include "ui/gl/gl_surface.h"
20 
21 namespace {
22 
InitializeGLSurface()23 scoped_refptr<gfx::GLSurface> InitializeGLSurface() {
24   scoped_refptr<gfx::GLSurface> surface(
25       gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size()));
26   if (!surface.get()) {
27     LOG(ERROR) << "gfx::GLContext::CreateOffscreenGLSurface failed";
28     return NULL;
29   }
30 
31   return surface;
32 }
33 
InitializeGLContext(gfx::GLSurface * surface)34 scoped_refptr<gfx::GLContext> InitializeGLContext(gfx::GLSurface* surface) {
35 
36   scoped_refptr<gfx::GLContext> context(
37       gfx::GLContext::CreateGLContext(NULL,
38                                       surface,
39                                       gfx::PreferIntegratedGpu));
40   if (!context.get()) {
41     LOG(ERROR) << "gfx::GLContext::CreateGLContext failed";
42     return NULL;
43   }
44 
45   if (!context->MakeCurrent(surface)) {
46     LOG(ERROR) << "gfx::GLContext::MakeCurrent() failed";
47     return NULL;
48   }
49 
50   return context;
51 }
52 
GetGLString(unsigned int pname)53 std::string GetGLString(unsigned int pname) {
54   const char* gl_string =
55       reinterpret_cast<const char*>(glGetString(pname));
56   if (gl_string)
57     return std::string(gl_string);
58   return std::string();
59 }
60 
61 // Return a version string in the format of "major.minor".
GetVersionFromString(const std::string & version_string)62 std::string GetVersionFromString(const std::string& version_string) {
63   size_t begin = version_string.find_first_of("0123456789");
64   if (begin != std::string::npos) {
65     size_t end = version_string.find_first_not_of("01234567890.", begin);
66     std::string sub_string;
67     if (end != std::string::npos)
68       sub_string = version_string.substr(begin, end - begin);
69     else
70       sub_string = version_string.substr(begin);
71     std::vector<std::string> pieces;
72     base::SplitString(sub_string, '.', &pieces);
73     if (pieces.size() >= 2)
74       return pieces[0] + "." + pieces[1];
75   }
76   return std::string();
77 }
78 
79 }  // namespace anonymous
80 
81 namespace gpu {
82 
CollectGraphicsInfoGL(GPUInfo * gpu_info)83 CollectInfoResult CollectGraphicsInfoGL(GPUInfo* gpu_info) {
84   TRACE_EVENT0("startup", "gpu_info_collector::CollectGraphicsInfoGL");
85   DCHECK_NE(gfx::GetGLImplementation(), gfx::kGLImplementationNone);
86 
87   scoped_refptr<gfx::GLSurface> surface(InitializeGLSurface());
88   if (!surface.get()) {
89     LOG(ERROR) << "Could not create surface for info collection.";
90     return kCollectInfoFatalFailure;
91   }
92 
93   scoped_refptr<gfx::GLContext> context(InitializeGLContext(surface.get()));
94   if (!context.get()) {
95     LOG(ERROR) << "Could not create context for info collection.";
96     return kCollectInfoFatalFailure;
97   }
98 
99   gpu_info->gl_renderer = GetGLString(GL_RENDERER);
100   gpu_info->gl_vendor = GetGLString(GL_VENDOR);
101   gpu_info->gl_extensions = GetGLString(GL_EXTENSIONS);
102   gpu_info->gl_version = GetGLString(GL_VERSION);
103   std::string glsl_version_string = GetGLString(GL_SHADING_LANGUAGE_VERSION);
104 
105   gfx::GLWindowSystemBindingInfo window_system_binding_info;
106   if (GetGLWindowSystemBindingInfo(&window_system_binding_info)) {
107     gpu_info->gl_ws_vendor = window_system_binding_info.vendor;
108     gpu_info->gl_ws_version = window_system_binding_info.version;
109     gpu_info->gl_ws_extensions = window_system_binding_info.extensions;
110     gpu_info->direct_rendering = window_system_binding_info.direct_rendering;
111   }
112 
113   bool supports_robustness =
114       gpu_info->gl_extensions.find("GL_EXT_robustness") != std::string::npos ||
115       gpu_info->gl_extensions.find("GL_ARB_robustness") != std::string::npos;
116   if (supports_robustness) {
117     glGetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_ARB,
118         reinterpret_cast<GLint*>(&gpu_info->gl_reset_notification_strategy));
119   }
120 
121   // TODO(kbr): remove once the destruction of a current context automatically
122   // clears the current context.
123   context->ReleaseCurrent(surface.get());
124 
125   std::string glsl_version = GetVersionFromString(glsl_version_string);
126   gpu_info->pixel_shader_version = glsl_version;
127   gpu_info->vertex_shader_version = glsl_version;
128 
129   return CollectDriverInfoGL(gpu_info);
130 }
131 
MergeGPUInfoGL(GPUInfo * basic_gpu_info,const GPUInfo & context_gpu_info)132 void MergeGPUInfoGL(GPUInfo* basic_gpu_info,
133                     const GPUInfo& context_gpu_info) {
134   DCHECK(basic_gpu_info);
135   basic_gpu_info->gl_renderer = context_gpu_info.gl_renderer;
136   basic_gpu_info->gl_vendor = context_gpu_info.gl_vendor;
137   basic_gpu_info->gl_version = context_gpu_info.gl_version;
138   basic_gpu_info->gl_extensions = context_gpu_info.gl_extensions;
139   basic_gpu_info->pixel_shader_version =
140       context_gpu_info.pixel_shader_version;
141   basic_gpu_info->vertex_shader_version =
142       context_gpu_info.vertex_shader_version;
143   basic_gpu_info->gl_ws_vendor = context_gpu_info.gl_ws_vendor;
144   basic_gpu_info->gl_ws_version = context_gpu_info.gl_ws_version;
145   basic_gpu_info->gl_ws_extensions = context_gpu_info.gl_ws_extensions;
146   basic_gpu_info->gl_reset_notification_strategy =
147       context_gpu_info.gl_reset_notification_strategy;
148 
149   if (!context_gpu_info.driver_vendor.empty())
150     basic_gpu_info->driver_vendor = context_gpu_info.driver_vendor;
151   if (!context_gpu_info.driver_version.empty())
152     basic_gpu_info->driver_version = context_gpu_info.driver_version;
153 
154   basic_gpu_info->can_lose_context = context_gpu_info.can_lose_context;
155   basic_gpu_info->sandboxed = context_gpu_info.sandboxed;
156   basic_gpu_info->direct_rendering = context_gpu_info.direct_rendering;
157   basic_gpu_info->finalized = context_gpu_info.finalized;
158   basic_gpu_info->initialization_time = context_gpu_info.initialization_time;
159 }
160 
161 }  // namespace gpu
162 
163