|
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- |
|
2 * vim: sw=2 ts=8 et : |
|
3 */ |
|
4 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
5 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
7 |
|
8 #include <unistd.h> |
|
9 #include <sys/types.h> |
|
10 #include <sys/wait.h> |
|
11 #include <errno.h> |
|
12 #include <sys/utsname.h> |
|
13 #include "nsCRTGlue.h" |
|
14 #include "prenv.h" |
|
15 |
|
16 #include "GfxInfoX11.h" |
|
17 |
|
18 #ifdef MOZ_CRASHREPORTER |
|
19 #include "nsExceptionHandler.h" |
|
20 #include "nsICrashReporter.h" |
|
21 #endif |
|
22 |
|
23 namespace mozilla { |
|
24 namespace widget { |
|
25 |
|
26 #ifdef DEBUG |
|
27 NS_IMPL_ISUPPORTS_INHERITED(GfxInfo, GfxInfoBase, nsIGfxInfoDebug) |
|
28 #endif |
|
29 |
|
30 // these global variables will be set when firing the glxtest process |
|
31 int glxtest_pipe = 0; |
|
32 pid_t glxtest_pid = 0; |
|
33 |
|
34 nsresult |
|
35 GfxInfo::Init() |
|
36 { |
|
37 mGLMajorVersion = 0; |
|
38 mMajorVersion = 0; |
|
39 mMinorVersion = 0; |
|
40 mRevisionVersion = 0; |
|
41 mIsMesa = false; |
|
42 mIsNVIDIA = false; |
|
43 mIsFGLRX = false; |
|
44 mIsNouveau = false; |
|
45 mIsIntel = false; |
|
46 mIsOldSwrast = false; |
|
47 mIsLlvmpipe = false; |
|
48 mHasTextureFromPixmap = false; |
|
49 return GfxInfoBase::Init(); |
|
50 } |
|
51 |
|
52 void |
|
53 GfxInfo::GetData() |
|
54 { |
|
55 // to understand this function, see bug 639842. We retrieve the OpenGL driver information in a |
|
56 // separate process to protect against bad drivers. |
|
57 |
|
58 // if glxtest_pipe == 0, that means that we already read the information |
|
59 if (!glxtest_pipe) |
|
60 return; |
|
61 |
|
62 enum { buf_size = 1024 }; |
|
63 char buf[buf_size]; |
|
64 ssize_t bytesread = read(glxtest_pipe, |
|
65 &buf, |
|
66 buf_size-1); // -1 because we'll append a zero |
|
67 close(glxtest_pipe); |
|
68 glxtest_pipe = 0; |
|
69 |
|
70 // bytesread < 0 would mean that the above read() call failed. |
|
71 // This should never happen. If it did, the outcome would be to blacklist anyway. |
|
72 if (bytesread < 0) |
|
73 bytesread = 0; |
|
74 |
|
75 // let buf be a zero-terminated string |
|
76 buf[bytesread] = 0; |
|
77 |
|
78 // Wait for the glxtest process to finish. This serves 2 purposes: |
|
79 // * avoid having a zombie glxtest process laying around |
|
80 // * get the glxtest process status info. |
|
81 int glxtest_status = 0; |
|
82 bool wait_for_glxtest_process = true; |
|
83 bool waiting_for_glxtest_process_failed = false; |
|
84 int waitpid_errno = 0; |
|
85 while(wait_for_glxtest_process) { |
|
86 wait_for_glxtest_process = false; |
|
87 if (waitpid(glxtest_pid, &glxtest_status, 0) == -1) { |
|
88 waitpid_errno = errno; |
|
89 if (waitpid_errno == EINTR) { |
|
90 wait_for_glxtest_process = true; |
|
91 } else { |
|
92 // Bug 718629 |
|
93 // ECHILD happens when the glxtest process got reaped got reaped after a PR_CreateProcess |
|
94 // as per bug 227246. This shouldn't matter, as we still seem to get the data |
|
95 // from the pipe, and if we didn't, the outcome would be to blacklist anyway. |
|
96 waiting_for_glxtest_process_failed = (waitpid_errno != ECHILD); |
|
97 } |
|
98 } |
|
99 } |
|
100 |
|
101 bool exited_with_error_code = !waiting_for_glxtest_process_failed && |
|
102 WIFEXITED(glxtest_status) && |
|
103 WEXITSTATUS(glxtest_status) != EXIT_SUCCESS; |
|
104 bool received_signal = !waiting_for_glxtest_process_failed && |
|
105 WIFSIGNALED(glxtest_status); |
|
106 |
|
107 bool error = waiting_for_glxtest_process_failed || exited_with_error_code || received_signal; |
|
108 |
|
109 nsCString textureFromPixmap; |
|
110 nsCString *stringToFill = nullptr; |
|
111 char *bufptr = buf; |
|
112 if (!error) { |
|
113 while(true) { |
|
114 char *line = NS_strtok("\n", &bufptr); |
|
115 if (!line) |
|
116 break; |
|
117 if (stringToFill) { |
|
118 stringToFill->Assign(line); |
|
119 stringToFill = nullptr; |
|
120 } |
|
121 else if(!strcmp(line, "VENDOR")) |
|
122 stringToFill = &mVendor; |
|
123 else if(!strcmp(line, "RENDERER")) |
|
124 stringToFill = &mRenderer; |
|
125 else if(!strcmp(line, "VERSION")) |
|
126 stringToFill = &mVersion; |
|
127 else if(!strcmp(line, "TFP")) |
|
128 stringToFill = &textureFromPixmap; |
|
129 } |
|
130 } |
|
131 |
|
132 if (!strcmp(textureFromPixmap.get(), "TRUE")) |
|
133 mHasTextureFromPixmap = true; |
|
134 |
|
135 // only useful for Linux kernel version check for FGLRX driver. |
|
136 // assumes X client == X server, which is sad. |
|
137 struct utsname unameobj; |
|
138 if (!uname(&unameobj)) |
|
139 { |
|
140 mOS.Assign(unameobj.sysname); |
|
141 mOSRelease.Assign(unameobj.release); |
|
142 } |
|
143 |
|
144 const char *spoofedVendor = PR_GetEnv("MOZ_GFX_SPOOF_GL_VENDOR"); |
|
145 if (spoofedVendor) |
|
146 mVendor.Assign(spoofedVendor); |
|
147 const char *spoofedRenderer = PR_GetEnv("MOZ_GFX_SPOOF_GL_RENDERER"); |
|
148 if (spoofedRenderer) |
|
149 mRenderer.Assign(spoofedRenderer); |
|
150 const char *spoofedVersion = PR_GetEnv("MOZ_GFX_SPOOF_GL_VERSION"); |
|
151 if (spoofedVersion) |
|
152 mVersion.Assign(spoofedVersion); |
|
153 const char *spoofedOS = PR_GetEnv("MOZ_GFX_SPOOF_OS"); |
|
154 if (spoofedOS) |
|
155 mOS.Assign(spoofedOS); |
|
156 const char *spoofedOSRelease = PR_GetEnv("MOZ_GFX_SPOOF_OS_RELEASE"); |
|
157 if (spoofedOSRelease) |
|
158 mOSRelease.Assign(spoofedOSRelease); |
|
159 |
|
160 if (error || |
|
161 mVendor.IsEmpty() || |
|
162 mRenderer.IsEmpty() || |
|
163 mVersion.IsEmpty() || |
|
164 mOS.IsEmpty() || |
|
165 mOSRelease.IsEmpty()) |
|
166 { |
|
167 mAdapterDescription.AppendLiteral("GLXtest process failed"); |
|
168 if (waiting_for_glxtest_process_failed) |
|
169 mAdapterDescription.AppendPrintf(" (waitpid failed with errno=%d for pid %d)", waitpid_errno, glxtest_pid); |
|
170 if (exited_with_error_code) |
|
171 mAdapterDescription.AppendPrintf(" (exited with status %d)", WEXITSTATUS(glxtest_status)); |
|
172 if (received_signal) |
|
173 mAdapterDescription.AppendPrintf(" (received signal %d)", WTERMSIG(glxtest_status)); |
|
174 if (bytesread) { |
|
175 mAdapterDescription.AppendLiteral(": "); |
|
176 mAdapterDescription.Append(nsDependentCString(buf)); |
|
177 mAdapterDescription.AppendLiteral("\n"); |
|
178 } |
|
179 #ifdef MOZ_CRASHREPORTER |
|
180 CrashReporter::AppendAppNotesToCrashReport(mAdapterDescription); |
|
181 #endif |
|
182 return; |
|
183 } |
|
184 |
|
185 mAdapterDescription.Append(mVendor); |
|
186 mAdapterDescription.AppendLiteral(" -- "); |
|
187 mAdapterDescription.Append(mRenderer); |
|
188 |
|
189 nsAutoCString note; |
|
190 note.Append("OpenGL: "); |
|
191 note.Append(mAdapterDescription); |
|
192 note.Append(" -- "); |
|
193 note.Append(mVersion); |
|
194 if (mHasTextureFromPixmap) |
|
195 note.Append(" -- texture_from_pixmap"); |
|
196 note.Append("\n"); |
|
197 #ifdef MOZ_CRASHREPORTER |
|
198 CrashReporter::AppendAppNotesToCrashReport(note); |
|
199 #endif |
|
200 |
|
201 // determine the major OpenGL version. That's the first integer in the version string. |
|
202 mGLMajorVersion = strtol(mVersion.get(), 0, 10); |
|
203 |
|
204 // determine driver type (vendor) and where in the version string |
|
205 // the actual driver version numbers should be expected to be found (whereToReadVersionNumbers) |
|
206 const char *whereToReadVersionNumbers = nullptr; |
|
207 const char *Mesa_in_version_string = strstr(mVersion.get(), "Mesa"); |
|
208 if (Mesa_in_version_string) { |
|
209 mIsMesa = true; |
|
210 // with Mesa, the version string contains "Mesa major.minor" and that's all the version information we get: |
|
211 // there is no actual driver version info. |
|
212 whereToReadVersionNumbers = Mesa_in_version_string + strlen("Mesa"); |
|
213 if (strcasestr(mVendor.get(), "nouveau")) |
|
214 mIsNouveau = true; |
|
215 if (strcasestr(mRenderer.get(), "intel")) // yes, intel is in the renderer string |
|
216 mIsIntel = true; |
|
217 if (strcasestr(mRenderer.get(), "llvmpipe")) |
|
218 mIsLlvmpipe = true; |
|
219 if (strcasestr(mRenderer.get(), "software rasterizer")) |
|
220 mIsOldSwrast = true; |
|
221 } else if (strstr(mVendor.get(), "NVIDIA Corporation")) { |
|
222 mIsNVIDIA = true; |
|
223 // with the NVIDIA driver, the version string contains "NVIDIA major.minor" |
|
224 // note that here the vendor and version strings behave differently, that's why we don't put this above |
|
225 // alongside Mesa_in_version_string. |
|
226 const char *NVIDIA_in_version_string = strstr(mVersion.get(), "NVIDIA"); |
|
227 if (NVIDIA_in_version_string) |
|
228 whereToReadVersionNumbers = NVIDIA_in_version_string + strlen("NVIDIA"); |
|
229 } else if (strstr(mVendor.get(), "ATI Technologies Inc")) { |
|
230 mIsFGLRX = true; |
|
231 // with the FGLRX driver, the version string only gives a OpenGL version :/ so let's return that. |
|
232 // that can at least give a rough idea of how old the driver is. |
|
233 whereToReadVersionNumbers = mVersion.get(); |
|
234 } |
|
235 |
|
236 // read major.minor version numbers of the driver (not to be confused with the OpenGL version) |
|
237 if (whereToReadVersionNumbers) { |
|
238 // copy into writable buffer, for tokenization |
|
239 strncpy(buf, whereToReadVersionNumbers, buf_size); |
|
240 bufptr = buf; |
|
241 |
|
242 // now try to read major.minor version numbers. In case of failure, gracefully exit: these numbers have |
|
243 // been initialized as 0 anyways |
|
244 char *token = NS_strtok(".", &bufptr); |
|
245 if (token) { |
|
246 mMajorVersion = strtol(token, 0, 10); |
|
247 token = NS_strtok(".", &bufptr); |
|
248 if (token) { |
|
249 mMinorVersion = strtol(token, 0, 10); |
|
250 token = NS_strtok(".", &bufptr); |
|
251 if (token) |
|
252 mRevisionVersion = strtol(token, 0, 10); |
|
253 } |
|
254 } |
|
255 } |
|
256 } |
|
257 |
|
258 static inline uint64_t version(uint32_t major, uint32_t minor, uint32_t revision = 0) |
|
259 { |
|
260 return (uint64_t(major) << 32) + (uint64_t(minor) << 16) + uint64_t(revision); |
|
261 } |
|
262 |
|
263 const nsTArray<GfxDriverInfo>& |
|
264 GfxInfo::GetGfxDriverInfo() |
|
265 { |
|
266 // Nothing here yet. |
|
267 //if (!mDriverInfo->Length()) { |
|
268 // |
|
269 //} |
|
270 return *mDriverInfo; |
|
271 } |
|
272 |
|
273 nsresult |
|
274 GfxInfo::GetFeatureStatusImpl(int32_t aFeature, |
|
275 int32_t *aStatus, |
|
276 nsAString & aSuggestedDriverVersion, |
|
277 const nsTArray<GfxDriverInfo>& aDriverInfo, |
|
278 OperatingSystem* aOS /* = nullptr */) |
|
279 |
|
280 { |
|
281 GetData(); |
|
282 |
|
283 NS_ENSURE_ARG_POINTER(aStatus); |
|
284 *aStatus = nsIGfxInfo::FEATURE_STATUS_UNKNOWN; |
|
285 aSuggestedDriverVersion.SetIsVoid(true); |
|
286 OperatingSystem os = DRIVER_OS_LINUX; |
|
287 if (aOS) |
|
288 *aOS = os; |
|
289 |
|
290 if (mGLMajorVersion == 1) { |
|
291 // We're on OpenGL 1. In most cases that indicates really old hardware. |
|
292 // We better block them, rather than rely on them to fail gracefully, because they don't! |
|
293 // see bug 696636 |
|
294 *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DEVICE; |
|
295 return NS_OK; |
|
296 } |
|
297 |
|
298 // Don't evaluate any special cases if we're checking the downloaded blocklist. |
|
299 if (!aDriverInfo.Length()) { |
|
300 // Only check features relevant to Linux. |
|
301 if (aFeature == nsIGfxInfo::FEATURE_OPENGL_LAYERS || |
|
302 aFeature == nsIGfxInfo::FEATURE_WEBGL_OPENGL || |
|
303 aFeature == nsIGfxInfo::FEATURE_WEBGL_MSAA) { |
|
304 |
|
305 // Disable OpenGL layers when we don't have texture_from_pixmap because it regresses performance. |
|
306 if (aFeature == nsIGfxInfo::FEATURE_OPENGL_LAYERS && !mHasTextureFromPixmap) { |
|
307 *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION; |
|
308 aSuggestedDriverVersion.AssignLiteral("<Anything with EXT_texture_from_pixmap support>"); |
|
309 return NS_OK; |
|
310 } |
|
311 |
|
312 // whitelist the linux test slaves' current configuration. |
|
313 // this is necessary as they're still using the slightly outdated 190.42 driver. |
|
314 // this isn't a huge risk, as at least this is the exact setting in which we do continuous testing, |
|
315 // and this only affects GeForce 9400 cards on linux on this precise driver version, which is very few users. |
|
316 // We do the same thing on Windows XP, see in widget/windows/GfxInfo.cpp |
|
317 if (mIsNVIDIA && |
|
318 !strcmp(mRenderer.get(), "GeForce 9400/PCI/SSE2") && |
|
319 !strcmp(mVersion.get(), "3.2.0 NVIDIA 190.42")) |
|
320 { |
|
321 *aStatus = nsIGfxInfo::FEATURE_NO_INFO; |
|
322 return NS_OK; |
|
323 } |
|
324 |
|
325 if (mIsMesa) { |
|
326 if (mIsNouveau && version(mMajorVersion, mMinorVersion) < version(8,0)) { |
|
327 *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION; |
|
328 aSuggestedDriverVersion.AssignLiteral("Mesa 8.0"); |
|
329 } |
|
330 else if (version(mMajorVersion, mMinorVersion, mRevisionVersion) < version(7,10,3)) { |
|
331 *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION; |
|
332 aSuggestedDriverVersion.AssignLiteral("Mesa 7.10.3"); |
|
333 } |
|
334 else if (mIsOldSwrast) { |
|
335 *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION; |
|
336 } |
|
337 else if (mIsLlvmpipe && version(mMajorVersion, mMinorVersion) < version(9, 1)) { |
|
338 // bug 791905, Mesa bug 57733, fixed in Mesa 9.1 according to |
|
339 // https://bugs.freedesktop.org/show_bug.cgi?id=57733#c3 |
|
340 *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION; |
|
341 } |
|
342 else if (aFeature == nsIGfxInfo::FEATURE_WEBGL_MSAA) |
|
343 { |
|
344 if (mIsIntel && version(mMajorVersion, mMinorVersion) < version(8,1)) |
|
345 *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION; |
|
346 aSuggestedDriverVersion.AssignLiteral("Mesa 8.1"); |
|
347 } |
|
348 |
|
349 } else if (mIsNVIDIA) { |
|
350 if (version(mMajorVersion, mMinorVersion, mRevisionVersion) < version(257,21)) { |
|
351 *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION; |
|
352 aSuggestedDriverVersion.AssignLiteral("NVIDIA 257.21"); |
|
353 } |
|
354 } else if (mIsFGLRX) { |
|
355 // FGLRX does not report a driver version number, so we have the OpenGL version instead. |
|
356 // by requiring OpenGL 3, we effectively require recent drivers. |
|
357 if (version(mMajorVersion, mMinorVersion, mRevisionVersion) < version(3, 0)) { |
|
358 *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION; |
|
359 aSuggestedDriverVersion.AssignLiteral("<Something recent>"); |
|
360 } |
|
361 // Bug 724640: FGLRX + Linux 2.6.32 is a crashy combo |
|
362 bool unknownOS = mOS.IsEmpty() || mOSRelease.IsEmpty(); |
|
363 bool badOS = mOS.Find("Linux", true) != -1 && |
|
364 mOSRelease.Find("2.6.32") != -1; |
|
365 if (unknownOS || badOS) { |
|
366 *aStatus = nsIGfxInfo::FEATURE_BLOCKED_OS_VERSION; |
|
367 } |
|
368 } else { |
|
369 // like on windows, let's block unknown vendors. Think of virtual machines. |
|
370 // Also, this case is hit whenever the GLXtest probe failed to get driver info or crashed. |
|
371 *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DEVICE; |
|
372 } |
|
373 } |
|
374 } |
|
375 |
|
376 return GfxInfoBase::GetFeatureStatusImpl(aFeature, aStatus, aSuggestedDriverVersion, aDriverInfo, &os); |
|
377 } |
|
378 |
|
379 |
|
380 NS_IMETHODIMP |
|
381 GfxInfo::GetD2DEnabled(bool *aEnabled) |
|
382 { |
|
383 return NS_ERROR_FAILURE; |
|
384 } |
|
385 |
|
386 NS_IMETHODIMP |
|
387 GfxInfo::GetDWriteEnabled(bool *aEnabled) |
|
388 { |
|
389 return NS_ERROR_FAILURE; |
|
390 } |
|
391 |
|
392 /* readonly attribute DOMString DWriteVersion; */ |
|
393 NS_IMETHODIMP |
|
394 GfxInfo::GetDWriteVersion(nsAString & aDwriteVersion) |
|
395 { |
|
396 return NS_ERROR_FAILURE; |
|
397 } |
|
398 |
|
399 /* readonly attribute DOMString cleartypeParameters; */ |
|
400 NS_IMETHODIMP |
|
401 GfxInfo::GetCleartypeParameters(nsAString & aCleartypeParams) |
|
402 { |
|
403 return NS_ERROR_FAILURE; |
|
404 } |
|
405 |
|
406 /* readonly attribute DOMString adapterDescription; */ |
|
407 NS_IMETHODIMP |
|
408 GfxInfo::GetAdapterDescription(nsAString & aAdapterDescription) |
|
409 { |
|
410 GetData(); |
|
411 AppendASCIItoUTF16(mAdapterDescription, aAdapterDescription); |
|
412 return NS_OK; |
|
413 } |
|
414 |
|
415 /* readonly attribute DOMString adapterDescription2; */ |
|
416 NS_IMETHODIMP |
|
417 GfxInfo::GetAdapterDescription2(nsAString & aAdapterDescription) |
|
418 { |
|
419 return NS_ERROR_FAILURE; |
|
420 } |
|
421 |
|
422 /* readonly attribute DOMString adapterRAM; */ |
|
423 NS_IMETHODIMP |
|
424 GfxInfo::GetAdapterRAM(nsAString & aAdapterRAM) |
|
425 { |
|
426 aAdapterRAM.AssignLiteral(""); |
|
427 return NS_OK; |
|
428 } |
|
429 |
|
430 /* readonly attribute DOMString adapterRAM2; */ |
|
431 NS_IMETHODIMP |
|
432 GfxInfo::GetAdapterRAM2(nsAString & aAdapterRAM) |
|
433 { |
|
434 return NS_ERROR_FAILURE; |
|
435 } |
|
436 |
|
437 /* readonly attribute DOMString adapterDriver; */ |
|
438 NS_IMETHODIMP |
|
439 GfxInfo::GetAdapterDriver(nsAString & aAdapterDriver) |
|
440 { |
|
441 aAdapterDriver.AssignLiteral(""); |
|
442 return NS_OK; |
|
443 } |
|
444 |
|
445 /* readonly attribute DOMString adapterDriver2; */ |
|
446 NS_IMETHODIMP |
|
447 GfxInfo::GetAdapterDriver2(nsAString & aAdapterDriver) |
|
448 { |
|
449 return NS_ERROR_FAILURE; |
|
450 } |
|
451 |
|
452 /* readonly attribute DOMString adapterDriverVersion; */ |
|
453 NS_IMETHODIMP |
|
454 GfxInfo::GetAdapterDriverVersion(nsAString & aAdapterDriverVersion) |
|
455 { |
|
456 GetData(); |
|
457 CopyASCIItoUTF16(mVersion, aAdapterDriverVersion); |
|
458 return NS_OK; |
|
459 } |
|
460 |
|
461 /* readonly attribute DOMString adapterDriverVersion2; */ |
|
462 NS_IMETHODIMP |
|
463 GfxInfo::GetAdapterDriverVersion2(nsAString & aAdapterDriverVersion) |
|
464 { |
|
465 return NS_ERROR_FAILURE; |
|
466 } |
|
467 |
|
468 /* readonly attribute DOMString adapterDriverDate; */ |
|
469 NS_IMETHODIMP |
|
470 GfxInfo::GetAdapterDriverDate(nsAString & aAdapterDriverDate) |
|
471 { |
|
472 aAdapterDriverDate.AssignLiteral(""); |
|
473 return NS_OK; |
|
474 } |
|
475 |
|
476 /* readonly attribute DOMString adapterDriverDate2; */ |
|
477 NS_IMETHODIMP |
|
478 GfxInfo::GetAdapterDriverDate2(nsAString & aAdapterDriverDate) |
|
479 { |
|
480 return NS_ERROR_FAILURE; |
|
481 } |
|
482 |
|
483 /* readonly attribute DOMString adapterVendorID; */ |
|
484 NS_IMETHODIMP |
|
485 GfxInfo::GetAdapterVendorID(nsAString & aAdapterVendorID) |
|
486 { |
|
487 GetData(); |
|
488 CopyUTF8toUTF16(mVendor, aAdapterVendorID); |
|
489 return NS_OK; |
|
490 } |
|
491 |
|
492 /* readonly attribute DOMString adapterVendorID2; */ |
|
493 NS_IMETHODIMP |
|
494 GfxInfo::GetAdapterVendorID2(nsAString & aAdapterVendorID) |
|
495 { |
|
496 return NS_ERROR_FAILURE; |
|
497 } |
|
498 |
|
499 /* readonly attribute DOMString adapterDeviceID; */ |
|
500 NS_IMETHODIMP |
|
501 GfxInfo::GetAdapterDeviceID(nsAString & aAdapterDeviceID) |
|
502 { |
|
503 GetData(); |
|
504 CopyUTF8toUTF16(mRenderer, aAdapterDeviceID); |
|
505 return NS_OK; |
|
506 } |
|
507 |
|
508 /* readonly attribute DOMString adapterDeviceID2; */ |
|
509 NS_IMETHODIMP |
|
510 GfxInfo::GetAdapterDeviceID2(nsAString & aAdapterDeviceID) |
|
511 { |
|
512 return NS_ERROR_FAILURE; |
|
513 } |
|
514 |
|
515 /* readonly attribute boolean isGPU2Active; */ |
|
516 NS_IMETHODIMP |
|
517 GfxInfo::GetIsGPU2Active(bool* aIsGPU2Active) |
|
518 { |
|
519 return NS_ERROR_FAILURE; |
|
520 } |
|
521 |
|
522 #ifdef DEBUG |
|
523 |
|
524 // Implement nsIGfxInfoDebug |
|
525 // We don't support spoofing anything on Linux |
|
526 |
|
527 /* void spoofVendorID (in DOMString aVendorID); */ |
|
528 NS_IMETHODIMP GfxInfo::SpoofVendorID(const nsAString & aVendorID) |
|
529 { |
|
530 CopyUTF16toUTF8(aVendorID, mVendor); |
|
531 return NS_OK; |
|
532 } |
|
533 |
|
534 /* void spoofDeviceID (in unsigned long aDeviceID); */ |
|
535 NS_IMETHODIMP GfxInfo::SpoofDeviceID(const nsAString & aDeviceID) |
|
536 { |
|
537 CopyUTF16toUTF8(aDeviceID, mRenderer); |
|
538 return NS_OK; |
|
539 } |
|
540 |
|
541 /* void spoofDriverVersion (in DOMString aDriverVersion); */ |
|
542 NS_IMETHODIMP GfxInfo::SpoofDriverVersion(const nsAString & aDriverVersion) |
|
543 { |
|
544 CopyUTF16toUTF8(aDriverVersion, mVersion); |
|
545 return NS_OK; |
|
546 } |
|
547 |
|
548 /* void spoofOSVersion (in unsigned long aVersion); */ |
|
549 NS_IMETHODIMP GfxInfo::SpoofOSVersion(uint32_t aVersion) |
|
550 { |
|
551 // We don't support OS versioning on Linux. There's just "Linux". |
|
552 return NS_OK; |
|
553 } |
|
554 |
|
555 #endif |
|
556 |
|
557 } // end namespace widget |
|
558 } // end namespace mozilla |