| |
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 |