Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(45)

Side by Side Diff: chrome/gpu/gpu_info_collector_linux.cc

Issue 6346007: Refactor and improve gpu_info_collector: collect information on linux;... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: This should turn three trybots green Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/gpu/gpu_info_collector.cc ('k') | chrome/gpu/gpu_info_collector_mac.mm » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/gpu/gpu_info_collector.h" 5 #include "chrome/gpu/gpu_info_collector.h"
6 6
7 #include <dlfcn.h> 7 #include <dlfcn.h>
8 #include <vector> 8 #include <vector>
9 9
10 #include "app/gfx/gl/gl_bindings.h" 10 #include "app/gfx/gl/gl_bindings.h"
11 #include "app/gfx/gl/gl_context.h" 11 #include "app/gfx/gl/gl_context.h"
12 #include "app/gfx/gl/gl_implementation.h" 12 #include "app/gfx/gl/gl_implementation.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/scoped_ptr.h" 14 #include "base/scoped_ptr.h"
15 #include "base/string_piece.h"
16 #include "base/string_split.h"
15 #include "base/string_util.h" 17 #include "base/string_util.h"
16 18
17 namespace { 19 namespace {
18 20
19 // PciDevice and PciAccess are defined to access libpci functions. Their 21 // PciDevice and PciAccess are defined to access libpci functions. Their
20 // members match the corresponding structures defined by libpci in size up to 22 // members match the corresponding structures defined by libpci in size up to
21 // fields we may access. For those members we don't use, their names are 23 // fields we may access. For those members we don't use, their names are
22 // defined as "fieldX", etc., or, left out if they are declared after the 24 // defined as "fieldX", etc., or, left out if they are declared after the
23 // members we care about in libpci. 25 // members we care about in libpci.
24 26
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 interface->pci_lookup_name == NULL) { 108 interface->pci_lookup_name == NULL) {
107 LOG(ERROR) << "Missing required function(s) from libpci"; 109 LOG(ERROR) << "Missing required function(s) from libpci";
108 dlclose(handle); 110 dlclose(handle);
109 delete interface; 111 delete interface;
110 return NULL; 112 return NULL;
111 } 113 }
112 return interface; 114 return interface;
113 } 115 }
114 116
115 // This close the dynamically opened libpci and delete the interface. 117 // This close the dynamically opened libpci and delete the interface.
116 void FinalizeLibPci(PciInterface*& interface) { 118 void FinalizeLibPci(PciInterface** interface) {
117 DCHECK(interface != NULL && interface->lib_handle != NULL); 119 DCHECK(interface && *interface && (*interface)->lib_handle);
118 dlclose(interface->lib_handle); 120 dlclose((*interface)->lib_handle);
119 delete interface; 121 delete (*interface);
120 interface = NULL; 122 *interface = NULL;
121 }
122
123 // This creates an offscreen GL context for gl queries. Returned GLContext
124 // should be deleted in FinalizeGLContext.
125 gfx::GLContext* InitializeGLContext() {
126 if (!gfx::GLContext::InitializeOneOff()) {
127 LOG(ERROR) << "gfx::GLContext::InitializeOneOff() failed";
128 return NULL;
129 }
130 gfx::GLContext* context = gfx::GLContext::CreateOffscreenGLContext(NULL);
131 if (context == NULL) {
132 LOG(ERROR) << "gfx::GLContext::CreateOffscreenGLContext(NULL) failed";
133 return NULL;
134 }
135 if (!context->MakeCurrent()) {
136 LOG(ERROR) << "gfx::GLContext::MakeCurrent() failed";
137 context->Destroy();
138 delete context;
139 return NULL;
140 }
141 return context;
142 }
143
144 // This destroy and delete the GL context.
145 void FinalizeGLContext(gfx::GLContext*& context) {
146 DCHECK(context != NULL);
147 context->Destroy();
148 delete context;
149 context = NULL;
150 } 123 }
151 124
152 } // namespace anonymous 125 } // namespace anonymous
153 126
154 namespace gpu_info_collector { 127 namespace gpu_info_collector {
155 128
156 bool CollectGraphicsInfo(GPUInfo* gpu_info) { 129 bool CollectGraphicsInfo(GPUInfo* gpu_info) {
157 gfx::GLContext* context = InitializeGLContext(); 130 DCHECK(gpu_info);
158 if (context == NULL)
159 return false;
160 131
161 // TODO(zmo): collect driver version, pixel shader version, vertex shader 132 // TODO(zmo): need to consider the case where we are running on top of
162 // version, and gl version. 133 // desktop GL and GL_ARB_robustness extension is available.
163 std::wstring driver_version = L""; 134 gpu_info->SetCanLoseContext(
164 uint32 pixel_shader_version = 0; 135 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2);
165 uint32 vertex_shader_version = 0; 136 gpu_info->SetProgress(GPUInfo::kComplete);
166 uint32 gl_version = 0; 137 return CollectGraphicsInfoGL(gpu_info);
167 bool can_lose_context = 138 }
168 (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2); 139
140 bool CollectVideoCardInfo(GPUInfo* gpu_info) {
141 DCHECK(gpu_info);
169 142
170 // TODO(zmo): be more flexible about library name. 143 // TODO(zmo): be more flexible about library name.
171 PciInterface* interface = InitializeLibPci("libpci.so.3"); 144 PciInterface* interface = InitializeLibPci("libpci.so.3");
172 if (interface == NULL) { 145 if (interface == NULL)
173 FinalizeGLContext(context);
174 return false; 146 return false;
175 }
176 147
177 PciAccess* access = (interface->pci_alloc)(); 148 PciAccess* access = (interface->pci_alloc)();
178 DCHECK(access != NULL); 149 DCHECK(access != NULL);
179 (interface->pci_init)(access); 150 (interface->pci_init)(access);
180 (interface->pci_scan_bus)(access); 151 (interface->pci_scan_bus)(access);
181 std::vector<PciDevice*> gpu_list; 152 std::vector<PciDevice*> gpu_list;
182 PciDevice* gpu_active = NULL; 153 PciDevice* gpu_active = NULL;
183 for (PciDevice* device = access->device_list; 154 for (PciDevice* device = access->device_list;
184 device != NULL; device = device->next) { 155 device != NULL; device = device->next) {
185 (interface->pci_fill_info)(device, 33); // Fill the IDs and class fields. 156 (interface->pci_fill_info)(device, 33); // Fill the IDs and class fields.
157 // TODO(zmo): there might be other classes that qualify as display devices.
186 if (device->device_class == 0x0300) { // Device class is DISPLAY_VGA. 158 if (device->device_class == 0x0300) { // Device class is DISPLAY_VGA.
187 gpu_list.push_back(device); 159 gpu_list.push_back(device);
188 } 160 }
189 } 161 }
190 if (gpu_list.size() == 1) { 162 if (gpu_list.size() == 1) {
191 gpu_active = gpu_list[0]; 163 gpu_active = gpu_list[0];
192 } else { 164 } else {
193 // If more than one graphics card are identified, find the one that matches 165 // If more than one graphics card are identified, find the one that matches
194 // gl VENDOR and RENDERER info. 166 // gl VENDOR and RENDERER info.
195 std::string gl_vendor_string = 167 std::string gl_vendor_string = gpu_info->gl_vendor();
196 reinterpret_cast<const char*>(glGetString(GL_VENDOR)); 168 std::string gl_renderer_string = gpu_info->gl_renderer();
197 std::string gl_renderer_string =
198 reinterpret_cast<const char*>(glGetString(GL_RENDERER));
199 const int buffer_size = 255; 169 const int buffer_size = 255;
200 scoped_array<char> buffer(new char[buffer_size]); 170 scoped_array<char> buffer(new char[buffer_size]);
201 std::vector<PciDevice*> candidates; 171 std::vector<PciDevice*> candidates;
202 for (size_t i = 0; i < gpu_list.size(); ++i) { 172 for (size_t i = 0; i < gpu_list.size(); ++i) {
203 PciDevice* gpu = gpu_list[i]; 173 PciDevice* gpu = gpu_list[i];
204 // The current implementation of pci_lookup_name returns the same pointer 174 // The current implementation of pci_lookup_name returns the same pointer
205 // as the passed in upon success, and a different one (NULL or a pointer 175 // as the passed in upon success, and a different one (NULL or a pointer
206 // to an error message) upon failure. 176 // to an error message) upon failure.
207 if ((interface->pci_lookup_name)(access, 177 if ((interface->pci_lookup_name)(access,
208 buffer.get(), 178 buffer.get(),
(...skipping 24 matching lines...) Expand all
233 break; 203 break;
234 } 204 }
235 // If a device's vendor matches gl VENDOR string, we want to consider the 205 // If a device's vendor matches gl VENDOR string, we want to consider the
236 // possibility that libpci may not return the exact same name as gl 206 // possibility that libpci may not return the exact same name as gl
237 // RENDERER string. 207 // RENDERER string.
238 candidates.push_back(gpu); 208 candidates.push_back(gpu);
239 } 209 }
240 if (gpu_active == NULL && candidates.size() == 1) 210 if (gpu_active == NULL && candidates.size() == 1)
241 gpu_active = candidates[0]; 211 gpu_active = candidates[0];
242 } 212 }
243 if (gpu_active != NULL) { 213 if (gpu_active != NULL)
244 gpu_info->SetGraphicsInfo(gpu_active->vendor_id, 214 gpu_info->SetVideoCardInfo(gpu_active->vendor_id, gpu_active->device_id);
245 gpu_active->device_id,
246 driver_version,
247 pixel_shader_version,
248 vertex_shader_version,
249 gl_version,
250 can_lose_context);
251 gpu_info->SetProgress(GPUInfo::kComplete);
252 }
253 (interface->pci_cleanup)(access); 215 (interface->pci_cleanup)(access);
254 FinalizeLibPci(interface); 216 FinalizeLibPci(&interface);
255 FinalizeGLContext(context);
256 return (gpu_active != NULL); 217 return (gpu_active != NULL);
257 } 218 }
258 219
220 bool CollectDriverInfo(GPUInfo* gpu_info) {
221 DCHECK(gpu_info);
222
223 std::string gl_version_string = gpu_info->gl_version_string();
224 std::vector<std::string> pieces;
225 base::SplitStringAlongWhitespace(gl_version_string, &pieces);
226 // In linux, the gl version string might be in the format of
227 // GLVersion DriverVendor DriverVersion
228 if (pieces.size() < 3)
229 return false;
230
231 std::string driver_version = pieces[2];
232 size_t pos = driver_version.find_first_not_of("0123456789.");
233 if (pos == 0)
234 return false;
235 if (pos != std::string::npos)
236 driver_version = driver_version.substr(0, pos);
237
238 gpu_info->SetDriverInfo(pieces[1], driver_version);
239 return true;
240 }
241
259 } // namespace gpu_info_collector 242 } // namespace gpu_info_collector
OLDNEW
« no previous file with comments | « chrome/gpu/gpu_info_collector.cc ('k') | chrome/gpu/gpu_info_collector_mac.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698