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

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: '' 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
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 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 != NULL && interface->lib_handle != NULL);
118 dlclose(interface->lib_handle); 120 dlclose(interface->lib_handle);
119 delete interface; 121 delete interface;
120 interface = NULL; 122 interface = NULL;
121 } 123 }
122 124
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 }
151
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 gpu_info->SetCanLoseContext(
162 // version, and gl version. 133 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2);
Ken Russell (switch to Gerrit) 2011/01/19 22:11:43 What if we're running on desktop GL and the GL_ARB
Zhenyao Mo 2011/01/19 23:36:22 Added a FIXME here for this. On 2011/01/19 22:11:
163 std::wstring driver_version = L""; 134 gpu_info->SetProgress(GPUInfo::kComplete);
164 uint32 pixel_shader_version = 0; 135 return CollectGraphicsInfoGL(gpu_info);
165 uint32 vertex_shader_version = 0; 136 }
166 uint32 gl_version = 0; 137
167 bool can_lose_context = 138 bool CollectVideoCardInfo(GPUInfo* gpu_info) {
168 (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2); 139 DCHECK(gpu_info);
169 140
170 // TODO(zmo): be more flexible about library name. 141 // TODO(zmo): be more flexible about library name.
171 PciInterface* interface = InitializeLibPci("libpci.so.3"); 142 PciInterface* interface = InitializeLibPci("libpci.so.3");
172 if (interface == NULL) { 143 if (interface == NULL)
173 FinalizeGLContext(context);
174 return false; 144 return false;
175 }
176 145
177 PciAccess* access = (interface->pci_alloc)(); 146 PciAccess* access = (interface->pci_alloc)();
178 DCHECK(access != NULL); 147 DCHECK(access != NULL);
179 (interface->pci_init)(access); 148 (interface->pci_init)(access);
180 (interface->pci_scan_bus)(access); 149 (interface->pci_scan_bus)(access);
181 std::vector<PciDevice*> gpu_list; 150 std::vector<PciDevice*> gpu_list;
182 PciDevice* gpu_active = NULL; 151 PciDevice* gpu_active = NULL;
183 for (PciDevice* device = access->device_list; 152 for (PciDevice* device = access->device_list;
184 device != NULL; device = device->next) { 153 device != NULL; device = device->next) {
185 (interface->pci_fill_info)(device, 33); // Fill the IDs and class fields. 154 (interface->pci_fill_info)(device, 33); // Fill the IDs and class fields.
186 if (device->device_class == 0x0300) { // Device class is DISPLAY_VGA. 155 if (device->device_class == 0x0300) { // Device class is DISPLAY_VGA.
rpetterson 2011/01/20 00:48:03 0x0300 was the most common in my research, but the
187 gpu_list.push_back(device); 156 gpu_list.push_back(device);
188 } 157 }
189 } 158 }
190 if (gpu_list.size() == 1) { 159 if (gpu_list.size() == 1) {
191 gpu_active = gpu_list[0]; 160 gpu_active = gpu_list[0];
192 } else { 161 } else {
193 // If more than one graphics card are identified, find the one that matches 162 // If more than one graphics card are identified, find the one that matches
194 // gl VENDOR and RENDERER info. 163 // gl VENDOR and RENDERER info.
195 std::string gl_vendor_string = 164 std::string gl_vendor_string = gpu_info->gl_vendor();
196 reinterpret_cast<const char*>(glGetString(GL_VENDOR)); 165 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; 166 const int buffer_size = 255;
200 scoped_array<char> buffer(new char[buffer_size]); 167 scoped_array<char> buffer(new char[buffer_size]);
201 std::vector<PciDevice*> candidates; 168 std::vector<PciDevice*> candidates;
202 for (size_t i = 0; i < gpu_list.size(); ++i) { 169 for (size_t i = 0; i < gpu_list.size(); ++i) {
203 PciDevice* gpu = gpu_list[i]; 170 PciDevice* gpu = gpu_list[i];
204 // The current implementation of pci_lookup_name returns the same pointer 171 // 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 172 // as the passed in upon success, and a different one (NULL or a pointer
206 // to an error message) upon failure. 173 // to an error message) upon failure.
207 if ((interface->pci_lookup_name)(access, 174 if ((interface->pci_lookup_name)(access,
208 buffer.get(), 175 buffer.get(),
(...skipping 24 matching lines...) Expand all
233 break; 200 break;
234 } 201 }
235 // If a device's vendor matches gl VENDOR string, we want to consider the 202 // 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 203 // possibility that libpci may not return the exact same name as gl
237 // RENDERER string. 204 // RENDERER string.
238 candidates.push_back(gpu); 205 candidates.push_back(gpu);
239 } 206 }
240 if (gpu_active == NULL && candidates.size() == 1) 207 if (gpu_active == NULL && candidates.size() == 1)
241 gpu_active = candidates[0]; 208 gpu_active = candidates[0];
242 } 209 }
243 if (gpu_active != NULL) { 210 if (gpu_active != NULL)
244 gpu_info->SetGraphicsInfo(gpu_active->vendor_id, 211 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); 212 (interface->pci_cleanup)(access);
254 FinalizeLibPci(interface); 213 FinalizeLibPci(interface);
255 FinalizeGLContext(context);
256 return (gpu_active != NULL); 214 return (gpu_active != NULL);
257 } 215 }
258 216
217 bool CollectDriverInfo(GPUInfo* gpu_info) {
218 DCHECK(gpu_info);
219
220 std::string gl_version_string = gpu_info->gl_version_string();
221 std::vector<std::string> pieces;
222 base::SplitStringAlongWhitespace(gl_version_string, &pieces);
223 // In linux, the gl version string might be in the format of
224 // GLVersion DriverVendor DriverVersion
225 if (pieces.size() < 3)
226 return false;
227
228 std::string driver_version = pieces[2];
229 size_t pos = driver_version.find_first_not_of("0123456789.");
230 if (pos == 0)
231 return false;
232 if (pos != std::string::npos)
233 driver_version = driver_version.substr(0, pos);
234
235 gpu_info->SetDriverInfo(pieces[1], driver_version);
236 return true;
237 }
238
259 } // namespace gpu_info_collector 239 } // namespace gpu_info_collector
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698