1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "AndroidBuild.h"
9 #include "GLContextProvider.h"
10 #include "nsUnicharUtils.h"
12 #include "nsExceptionHandler.h"
13 #include "nsHashKeys.h"
14 #include "nsVersionComparator.h"
15 #include "nsServiceManagerUtils.h"
17 #include "mozilla/Preferences.h"
18 #include "mozilla/java/GeckoAppShellWrappers.h"
19 #include "mozilla/java/HardwareCodecCapabilityUtilsWrappers.h"
24 class GfxInfo::GLStrings
{
28 nsTArray
<nsCString
> mExtensions
;
32 GLStrings() : mReady(false) {}
34 const nsCString
& Vendor() {
39 // This spoofed value wins, even if the environment variable
40 // MOZ_GFX_SPOOF_GL_VENDOR was set.
41 void SpoofVendor(const nsCString
& s
) { mVendor
= s
; }
43 const nsCString
& Renderer() {
48 // This spoofed value wins, even if the environment variable
49 // MOZ_GFX_SPOOF_GL_RENDERER was set.
50 void SpoofRenderer(const nsCString
& s
) { mRenderer
= s
; }
52 const nsCString
& Version() {
57 // This spoofed value wins, even if the environment variable
58 // MOZ_GFX_SPOOF_GL_VERSION was set.
59 void SpoofVersion(const nsCString
& s
) { mVersion
= s
; }
61 const nsTArray
<nsCString
>& Extensions() {
66 void EnsureInitialized() {
71 RefPtr
<gl::GLContext
> gl
;
72 nsCString discardFailureId
;
73 gl
= gl::GLContextProvider::CreateHeadless(
74 {gl::CreateContextFlags::REQUIRE_COMPAT_PROFILE
}, &discardFailureId
);
77 // Setting mReady to true here means that we won't retry. Everything will
78 // remain blocklisted forever. Ideally, we would like to update that once
79 // any GLContext is successfully created, like the compositor's GLContext.
86 if (mVendor
.IsEmpty()) {
87 const char* spoofedVendor
= PR_GetEnv("MOZ_GFX_SPOOF_GL_VENDOR");
89 mVendor
.Assign(spoofedVendor
);
91 mVendor
.Assign((const char*)gl
->fGetString(LOCAL_GL_VENDOR
));
95 if (mRenderer
.IsEmpty()) {
96 const char* spoofedRenderer
= PR_GetEnv("MOZ_GFX_SPOOF_GL_RENDERER");
97 if (spoofedRenderer
) {
98 mRenderer
.Assign(spoofedRenderer
);
100 mRenderer
.Assign((const char*)gl
->fGetString(LOCAL_GL_RENDERER
));
104 if (mVersion
.IsEmpty()) {
105 const char* spoofedVersion
= PR_GetEnv("MOZ_GFX_SPOOF_GL_VERSION");
106 if (spoofedVersion
) {
107 mVersion
.Assign(spoofedVersion
);
109 mVersion
.Assign((const char*)gl
->fGetString(LOCAL_GL_VERSION
));
113 if (mExtensions
.IsEmpty()) {
114 nsCString rawExtensions
;
115 rawExtensions
.Assign((const char*)gl
->fGetString(LOCAL_GL_EXTENSIONS
));
116 rawExtensions
.Trim(" ");
118 for (auto extension
: rawExtensions
.Split(' ')) {
119 mExtensions
.AppendElement(extension
);
128 NS_IMPL_ISUPPORTS_INHERITED(GfxInfo
, GfxInfoBase
, nsIGfxInfoDebug
)
132 : mInitialized(false),
133 mGLStrings(new GLStrings
),
134 mOSVersionInteger(0),
137 GfxInfo::~GfxInfo() {}
139 /* GetD2DEnabled and GetDwriteEnabled shouldn't be called until after
140 * gfxPlatform initialization has occurred because they depend on it for
141 * information. (See bug 591561) */
142 nsresult
GfxInfo::GetD2DEnabled(bool* aEnabled
) { return NS_ERROR_FAILURE
; }
144 nsresult
GfxInfo::GetDWriteEnabled(bool* aEnabled
) { return NS_ERROR_FAILURE
; }
146 nsresult
GfxInfo::GetHasBattery(bool* aHasBattery
) {
147 return NS_ERROR_NOT_IMPLEMENTED
;
151 GfxInfo::GetDWriteVersion(nsAString
& aDwriteVersion
) {
152 return NS_ERROR_FAILURE
;
156 GfxInfo::GetEmbeddedInFirefoxReality(bool* aEmbeddedInFirefoxReality
) {
157 return NS_ERROR_FAILURE
;
161 GfxInfo::GetCleartypeParameters(nsAString
& aCleartypeParams
) {
162 return NS_ERROR_FAILURE
;
166 GfxInfo::GetWindowProtocol(nsAString
& aWindowProtocol
) {
167 return NS_ERROR_NOT_IMPLEMENTED
;
171 GfxInfo::GetTestType(nsAString
& aTestType
) { return NS_ERROR_NOT_IMPLEMENTED
; }
173 void GfxInfo::EnsureInitialized() {
174 if (mInitialized
) return;
176 if (!jni::IsAvailable()) {
177 gfxWarning() << "JNI missing during initialization";
181 jni::String::LocalRef model
= java::sdk::Build::MODEL();
182 mModel
= model
->ToString();
183 mAdapterDescription
.AppendPrintf("Model: %s",
184 NS_LossyConvertUTF16toASCII(mModel
).get());
186 jni::String::LocalRef product
= java::sdk::Build::PRODUCT();
187 mProduct
= product
->ToString();
188 mAdapterDescription
.AppendPrintf(", Product: %s",
189 NS_LossyConvertUTF16toASCII(mProduct
).get());
191 jni::String::LocalRef manufacturer
=
192 mozilla::java::sdk::Build::MANUFACTURER();
193 mManufacturer
= manufacturer
->ToString();
194 mAdapterDescription
.AppendPrintf(
195 ", Manufacturer: %s", NS_LossyConvertUTF16toASCII(mManufacturer
).get());
197 mSDKVersion
= java::sdk::Build::VERSION::SDK_INT();
198 jni::String::LocalRef hardware
= java::sdk::Build::HARDWARE();
199 mHardware
= hardware
->ToString();
200 mAdapterDescription
.AppendPrintf(
201 ", Hardware: %s", NS_LossyConvertUTF16toASCII(mHardware
).get());
203 jni::String::LocalRef release
= java::sdk::Build::VERSION::RELEASE();
204 mOSVersion
= release
->ToCString();
206 mOSVersionInteger
= 0;
207 char a
[5], b
[5], c
[5], d
[5];
208 SplitDriverVersion(mOSVersion
.get(), a
, b
, c
, d
);
209 uint8_t na
= atoi(a
);
210 uint8_t nb
= atoi(b
);
211 uint8_t nc
= atoi(c
);
212 uint8_t nd
= atoi(d
);
214 mOSVersionInteger
= (uint32_t(na
) << 24) | (uint32_t(nb
) << 16) |
215 (uint32_t(nc
) << 8) | uint32_t(nd
);
217 mAdapterDescription
.AppendPrintf(
218 ", OpenGL: %s -- %s -- %s", mGLStrings
->Vendor().get(),
219 mGLStrings
->Renderer().get(), mGLStrings
->Version().get());
221 AddCrashReportAnnotations();
226 GfxInfo::GetAdapterDescription(nsAString
& aAdapterDescription
) {
228 aAdapterDescription
= NS_ConvertASCIItoUTF16(mAdapterDescription
);
233 GfxInfo::GetAdapterDescription2(nsAString
& aAdapterDescription
) {
235 return NS_ERROR_FAILURE
;
239 GfxInfo::GetAdapterRAM(uint32_t* aAdapterRAM
) {
246 GfxInfo::GetAdapterRAM2(uint32_t* aAdapterRAM
) {
248 return NS_ERROR_FAILURE
;
252 GfxInfo::GetAdapterDriver(nsAString
& aAdapterDriver
) {
254 aAdapterDriver
.Truncate();
259 GfxInfo::GetAdapterDriver2(nsAString
& aAdapterDriver
) {
261 return NS_ERROR_FAILURE
;
265 GfxInfo::GetAdapterDriverVendor(nsAString
& aAdapterDriverVendor
) {
267 aAdapterDriverVendor
.Truncate();
272 GfxInfo::GetAdapterDriverVendor2(nsAString
& aAdapterDriverVendor
) {
274 return NS_ERROR_FAILURE
;
278 GfxInfo::GetAdapterDriverVersion(nsAString
& aAdapterDriverVersion
) {
280 aAdapterDriverVersion
= NS_ConvertASCIItoUTF16(mGLStrings
->Version());
285 GfxInfo::GetAdapterDriverVersion2(nsAString
& aAdapterDriverVersion
) {
287 return NS_ERROR_FAILURE
;
291 GfxInfo::GetAdapterDriverDate(nsAString
& aAdapterDriverDate
) {
293 aAdapterDriverDate
.Truncate();
298 GfxInfo::GetAdapterDriverDate2(nsAString
& aAdapterDriverDate
) {
300 return NS_ERROR_FAILURE
;
304 GfxInfo::GetAdapterVendorID(nsAString
& aAdapterVendorID
) {
306 aAdapterVendorID
= NS_ConvertASCIItoUTF16(mGLStrings
->Vendor());
311 GfxInfo::GetAdapterVendorID2(nsAString
& aAdapterVendorID
) {
313 return NS_ERROR_FAILURE
;
317 GfxInfo::GetAdapterDeviceID(nsAString
& aAdapterDeviceID
) {
319 aAdapterDeviceID
= NS_ConvertASCIItoUTF16(mGLStrings
->Renderer());
324 GfxInfo::GetAdapterDeviceID2(nsAString
& aAdapterDeviceID
) {
326 return NS_ERROR_FAILURE
;
330 GfxInfo::GetAdapterSubsysID(nsAString
& aAdapterSubsysID
) {
332 return NS_ERROR_FAILURE
;
336 GfxInfo::GetAdapterSubsysID2(nsAString
& aAdapterSubsysID
) {
338 return NS_ERROR_FAILURE
;
342 GfxInfo::GetIsGPU2Active(bool* aIsGPU2Active
) {
344 return NS_ERROR_FAILURE
;
348 GfxInfo::GetDrmRenderDevice(nsACString
& aDrmRenderDevice
) {
349 return NS_ERROR_NOT_IMPLEMENTED
;
352 void GfxInfo::AddCrashReportAnnotations() {
353 CrashReporter::RecordAnnotationNSCString(
354 CrashReporter::Annotation::AdapterVendorID
, mGLStrings
->Vendor());
355 CrashReporter::RecordAnnotationNSCString(
356 CrashReporter::Annotation::AdapterDeviceID
, mGLStrings
->Renderer());
357 CrashReporter::RecordAnnotationNSCString(
358 CrashReporter::Annotation::AdapterDriverVersion
, mGLStrings
->Version());
361 const nsTArray
<GfxDriverInfo
>& GfxInfo::GetGfxDriverInfo() {
362 if (sDriverInfo
->IsEmpty()) {
363 APPEND_TO_DRIVER_BLOCKLIST2(
364 OperatingSystem::Android
, DeviceFamily::All
,
365 nsIGfxInfo::FEATURE_OPENGL_LAYERS
, nsIGfxInfo::FEATURE_STATUS_OK
,
366 DRIVER_COMPARISON_IGNORED
, GfxDriverInfo::allDriverVersions
,
367 "FEATURE_OK_FORCE_OPENGL");
373 nsresult
GfxInfo::GetFeatureStatusImpl(
374 int32_t aFeature
, int32_t* aStatus
, nsAString
& aSuggestedDriverVersion
,
375 const nsTArray
<GfxDriverInfo
>& aDriverInfo
, nsACString
& aFailureId
,
376 OperatingSystem
* aOS
/* = nullptr */) {
377 NS_ENSURE_ARG_POINTER(aStatus
);
378 aSuggestedDriverVersion
.SetIsVoid(true);
379 *aStatus
= nsIGfxInfo::FEATURE_STATUS_UNKNOWN
;
380 OperatingSystem os
= OperatingSystem::Android
;
383 if (sShutdownOccurred
) {
387 // OpenGL layers are never blocklisted on Android.
388 // This early return is so we avoid potentially slow
389 // GLStrings initialization on startup when we initialize GL layers.
390 if (aFeature
== nsIGfxInfo::FEATURE_OPENGL_LAYERS
) {
391 *aStatus
= nsIGfxInfo::FEATURE_STATUS_OK
;
397 if (mGLStrings
->Vendor().IsEmpty() || mGLStrings
->Renderer().IsEmpty()) {
398 if (OnlyAllowFeatureOnKnownConfig(aFeature
)) {
399 *aStatus
= nsIGfxInfo::FEATURE_BLOCKED_DEVICE
;
400 aFailureId
= "FEATURE_FAILURE_EMPTY_VENDOR_OR_RENDERER";
402 *aStatus
= nsIGfxInfo::FEATURE_STATUS_OK
;
407 // Don't evaluate special cases when evaluating the downloaded blocklist.
408 if (aDriverInfo
.IsEmpty()) {
409 if (aFeature
== nsIGfxInfo::FEATURE_CANVAS2D_ACCELERATION
) {
410 if (mGLStrings
->Renderer().Find("Vivante GC1000") != -1) {
411 // Blocklist Vivante GC1000. See bug 1248183.
412 *aStatus
= nsIGfxInfo::FEATURE_BLOCKED_DEVICE
;
413 aFailureId
= "FEATURE_FAILED_CANVAS_2D_HW";
415 *aStatus
= nsIGfxInfo::FEATURE_STATUS_OK
;
420 if (aFeature
== FEATURE_WEBGL_OPENGL
) {
421 if (mGLStrings
->Renderer().Find("Adreno 200") != -1 ||
422 mGLStrings
->Renderer().Find("Adreno 205") != -1) {
423 *aStatus
= nsIGfxInfo::FEATURE_BLOCKED_DEVICE
;
424 aFailureId
= "FEATURE_FAILURE_ADRENO_20x";
428 if (mHardware
.EqualsLiteral("ville")) {
429 *aStatus
= nsIGfxInfo::FEATURE_BLOCKED_DEVICE
;
430 aFailureId
= "FEATURE_FAILURE_VILLE";
435 if (aFeature
== FEATURE_STAGEFRIGHT
) {
436 NS_LossyConvertUTF16toASCII
cManufacturer(mManufacturer
);
437 NS_LossyConvertUTF16toASCII
cModel(mModel
);
438 NS_LossyConvertUTF16toASCII
cHardware(mHardware
);
440 if (cHardware
.EqualsLiteral("antares") ||
441 cHardware
.EqualsLiteral("harmony") ||
442 cHardware
.EqualsLiteral("picasso") ||
443 cHardware
.EqualsLiteral("picasso_e") ||
444 cHardware
.EqualsLiteral("ventana") ||
445 cHardware
.EqualsLiteral("rk30board")) {
446 *aStatus
= nsIGfxInfo::FEATURE_BLOCKED_DEVICE
;
447 aFailureId
= "FEATURE_FAILURE_STAGE_HW";
451 if (CompareVersions(mOSVersion
.get(), "4.1.0") < 0) {
453 // All Samsung ICS devices, except for:
454 // Samsung SGH-I717 (Bug 845729)
455 // Samsung SGH-I727 (Bug 845729)
456 // Samsung SGH-I757 (Bug 845729)
457 // All Galaxy nexus ICS devices
458 // Sony Xperia Ion (LT28) ICS devices
460 cModel
.Equals("LT28h", nsCaseInsensitiveCStringComparator
) ||
461 cManufacturer
.Equals("samsung",
462 nsCaseInsensitiveCStringComparator
) ||
465 nsCaseInsensitiveCStringComparator
); // some Galaxy Nexus
467 // manufacturer=amazon
469 if (cModel
.LowerCaseFindASCII("sgh-i717") != -1 ||
470 cModel
.LowerCaseFindASCII("sgh-i727") != -1 ||
471 cModel
.LowerCaseFindASCII("sgh-i757") != -1) {
472 isWhitelisted
= false;
475 if (!isWhitelisted
) {
476 *aStatus
= nsIGfxInfo::FEATURE_BLOCKED_DEVICE
;
477 aFailureId
= "FEATURE_FAILURE_4_1_HW";
480 } else if (CompareVersions(mOSVersion
.get(), "4.2.0") < 0) {
482 // All JB phones except for those in blocklist below
484 // Samsung devices from bug 812881 and 853522.
485 // Motorola XT890 from bug 882342.
486 bool isBlocklisted
= cModel
.LowerCaseFindASCII("gt-p3100") != -1 ||
487 cModel
.LowerCaseFindASCII("gt-p3110") != -1 ||
488 cModel
.LowerCaseFindASCII("gt-p3113") != -1 ||
489 cModel
.LowerCaseFindASCII("gt-p5100") != -1 ||
490 cModel
.LowerCaseFindASCII("gt-p5110") != -1 ||
491 cModel
.LowerCaseFindASCII("gt-p5113") != -1 ||
492 cModel
.LowerCaseFindASCII("xt890") != -1;
495 *aStatus
= nsIGfxInfo::FEATURE_BLOCKED_DEVICE
;
496 aFailureId
= "FEATURE_FAILURE_4_2_HW";
499 } else if (CompareVersions(mOSVersion
.get(), "4.3.0") < 0) {
500 // Blocklist all Sony devices
501 if (cManufacturer
.LowerCaseFindASCII("sony") != -1) {
502 *aStatus
= nsIGfxInfo::FEATURE_BLOCKED_DEVICE
;
503 aFailureId
= "FEATURE_FAILURE_4_3_SONY";
509 if (aFeature
== FEATURE_WEBRTC_HW_ACCELERATION_ENCODE
) {
510 if (jni::IsAvailable()) {
511 *aStatus
= WebRtcHwVp8EncodeSupported();
512 aFailureId
= "FEATURE_FAILURE_WEBRTC_ENCODE";
516 if (aFeature
== FEATURE_WEBRTC_HW_ACCELERATION_DECODE
) {
517 if (jni::IsAvailable()) {
518 *aStatus
= WebRtcHwVp8DecodeSupported();
519 aFailureId
= "FEATURE_FAILURE_WEBRTC_DECODE";
523 if (aFeature
== FEATURE_WEBRTC_HW_ACCELERATION_H264
) {
524 if (jni::IsAvailable()) {
525 *aStatus
= WebRtcHwH264Supported();
526 aFailureId
= "FEATURE_FAILURE_WEBRTC_H264";
530 if (aFeature
== FEATURE_VP8_HW_DECODE
||
531 aFeature
== FEATURE_VP9_HW_DECODE
) {
532 NS_LossyConvertUTF16toASCII
model(mModel
);
534 // GIFV crash, see bug 1232911.
535 model
.Equals("GT-N8013", nsCaseInsensitiveCStringComparator
);
538 *aStatus
= nsIGfxInfo::FEATURE_BLOCKED_DEVICE
;
539 aFailureId
= "FEATURE_FAILURE_VPx";
541 *aStatus
= nsIGfxInfo::FEATURE_STATUS_OK
;
546 if (aFeature
== FEATURE_WEBRENDER
) {
547 const bool isMali4xx
=
548 mGLStrings
->Renderer().LowerCaseFindASCII("mali-4") >= 0;
550 const bool isPowerVrG6110
=
551 mGLStrings
->Renderer().LowerCaseFindASCII("powervr rogue g6110") >= 0;
553 const bool isVivanteGC7000UL
=
554 mGLStrings
->Renderer().LowerCaseFindASCII("vivante gc7000ul") >= 0;
556 const bool isPowerVrFenceSyncCrash
=
557 (mGLStrings
->Renderer().LowerCaseFindASCII("powervr rogue g6200") >=
559 mGLStrings
->Renderer().LowerCaseFindASCII("powervr rogue g6430") >=
561 mGLStrings
->Renderer().LowerCaseFindASCII("powervr rogue gx6250") >=
563 (mGLStrings
->Version().Find("3283119") >= 0 ||
564 mGLStrings
->Version().Find("3443629") >= 0 ||
565 mGLStrings
->Version().Find("3573678") >= 0 ||
566 mGLStrings
->Version().Find("3830101") >= 0);
569 // Mali 4xx does not support GLES 3.
570 *aStatus
= nsIGfxInfo::FEATURE_BLOCKED_DEVICE
;
571 aFailureId
= "FEATURE_FAILURE_NO_GLES_3";
572 } else if (isPowerVrG6110
) {
573 // Blocked on PowerVR Rogue G6110 due to bug 1742986 and bug 1717863.
574 *aStatus
= nsIGfxInfo::FEATURE_BLOCKED_DEVICE
;
575 aFailureId
= "FEATURE_FAILURE_POWERVR_G6110";
576 } else if (isVivanteGC7000UL
) {
577 // Blocked on Vivante GC7000UL due to bug 1719327.
578 *aStatus
= nsIGfxInfo::FEATURE_BLOCKED_DEVICE
;
579 aFailureId
= "FEATURE_FAILURE_VIVANTE_GC7000UL";
580 } else if (isPowerVrFenceSyncCrash
) {
581 // Blocked on various PowerVR GPUs due to bug 1773128.
582 *aStatus
= nsIGfxInfo::FEATURE_BLOCKED_DEVICE
;
583 aFailureId
= "FEATURE_FAILURE_POWERVR_FENCE_SYNC_CRASH";
585 *aStatus
= nsIGfxInfo::FEATURE_STATUS_OK
;
590 if (aFeature
== FEATURE_WEBRENDER_SCISSORED_CACHE_CLEARS
) {
591 // Emulator with SwiftShader is buggy when attempting to clear picture
592 // cache textures with a scissor rect set.
593 const bool isEmulatorSwiftShader
=
594 mGLStrings
->Renderer().Find(
595 "Android Emulator OpenGL ES Translator (Google SwiftShader)") >=
597 if (isEmulatorSwiftShader
) {
598 *aStatus
= nsIGfxInfo::FEATURE_BLOCKED_DEVICE
;
599 aFailureId
= "FEATURE_FAILURE_BUG_1603515";
601 *aStatus
= nsIGfxInfo::FEATURE_STATUS_OK
;
606 if (aFeature
== FEATURE_WEBRENDER_SHADER_CACHE
) {
607 // Program binaries are known to be buggy on Adreno 3xx. While we haven't
608 // encountered any correctness or stability issues with them, loading them
609 // fails more often than not, so is a waste of time. Better to just not
610 // even attempt to cache them. See bug 1615574.
611 const bool isAdreno3xx
=
612 mGLStrings
->Renderer().LowerCaseFindASCII("adreno (tm) 3") >= 0;
614 *aStatus
= nsIGfxInfo::FEATURE_BLOCKED_DEVICE
;
615 aFailureId
= "FEATURE_FAILURE_ADRENO_3XX";
617 *aStatus
= nsIGfxInfo::FEATURE_STATUS_OK
;
621 if (aFeature
== FEATURE_WEBRENDER_OPTIMIZED_SHADERS
) {
622 // Optimized shaders result in completely broken rendering on some Mali-T
623 // devices. We have seen this on T6xx, T7xx, and T8xx on android versions
624 // up to 5.1, and on T6xx on versions up to android 7.1. As a precaution
625 // disable for all Mali-T regardless of version. See bug 1689064 and bug
626 // 1707283 for details.
628 mGLStrings
->Renderer().LowerCaseFindASCII("mali-t") >= 0;
630 *aStatus
= nsIGfxInfo::FEATURE_BLOCKED_DEVICE
;
631 aFailureId
= "FEATURE_FAILURE_BUG_1689064";
633 *aStatus
= nsIGfxInfo::FEATURE_STATUS_OK
;
638 if (aFeature
== FEATURE_WEBRENDER_PARTIAL_PRESENT
) {
639 // Block partial present on some devices due to rendering issues.
640 // On Mali-Txxx due to bug 1680087 and bug 1707815.
641 // On Adreno 3xx GPUs due to bug 1695771.
643 mGLStrings
->Renderer().LowerCaseFindASCII("mali-t") >= 0;
644 const bool isAdreno3xx
=
645 mGLStrings
->Renderer().LowerCaseFindASCII("adreno (tm) 3") >= 0;
646 if (isMaliT
|| isAdreno3xx
) {
647 *aStatus
= nsIGfxInfo::FEATURE_BLOCKED_DEVICE
;
648 aFailureId
= "FEATURE_FAILURE_BUG_1680087_1695771_1707815";
650 *aStatus
= nsIGfxInfo::FEATURE_STATUS_OK
;
656 if (aFeature
== FEATURE_GL_SWIZZLE
) {
657 // Swizzling appears to be buggy on PowerVR Rogue devices with webrender.
659 const bool isPowerVRRogue
=
660 mGLStrings
->Renderer().LowerCaseFindASCII("powervr rogue") >= 0;
661 if (isPowerVRRogue
) {
662 *aStatus
= nsIGfxInfo::FEATURE_BLOCKED_DEVICE
;
663 aFailureId
= "FEATURE_FAILURE_POWERVR_ROGUE";
665 *aStatus
= nsIGfxInfo::FEATURE_STATUS_OK
;
670 return GfxInfoBase::GetFeatureStatusImpl(
671 aFeature
, aStatus
, aSuggestedDriverVersion
, aDriverInfo
, aFailureId
, &os
);
674 static nsCString
FeatureCacheOsVerPrefName(int32_t aFeature
) {
675 nsCString osPrefName
;
676 osPrefName
.AppendASCII("gfxinfo.cache.");
677 osPrefName
.AppendInt(aFeature
);
678 osPrefName
.AppendASCII(".osver");
682 static nsCString
FeatureCacheAppVerPrefName(int32_t aFeature
) {
683 nsCString osPrefName
;
684 osPrefName
.AppendASCII("gfxinfo.cache.");
685 osPrefName
.AppendInt(aFeature
);
686 osPrefName
.AppendASCII(".appver");
690 static nsCString
FeatureCacheValuePrefName(int32_t aFeature
) {
691 nsCString osPrefName
;
692 osPrefName
.AppendASCII("gfxinfo.cache.");
693 osPrefName
.AppendInt(aFeature
);
694 osPrefName
.AppendASCII(".value");
698 static bool GetCachedFeatureVal(int32_t aFeature
, uint32_t aExpectedOsVer
,
699 const nsCString
& aCurrentAppVer
,
700 int32_t& aOutStatus
) {
703 Preferences::GetUint(FeatureCacheOsVerPrefName(aFeature
).get(), &osVer
);
704 if (NS_FAILED(rv
) || osVer
!= aExpectedOsVer
) {
707 // Bug 1804287 requires we invalidate cached values for new builds to allow
708 // for code changes to modify the features support.
709 nsAutoCString cachedAppVersion
;
710 rv
= Preferences::GetCString(FeatureCacheAppVerPrefName(aFeature
).get(),
712 if (NS_FAILED(rv
) || !aCurrentAppVer
.Equals(cachedAppVersion
)) {
716 rv
= Preferences::GetInt(FeatureCacheValuePrefName(aFeature
).get(), &status
);
724 static void SetCachedFeatureVal(int32_t aFeature
, uint32_t aOsVer
,
725 const nsCString
& aCurrentAppVer
,
727 // Ignore failures; not much we can do anyway.
728 Preferences::SetUint(FeatureCacheOsVerPrefName(aFeature
).get(), aOsVer
);
729 Preferences::SetCString(FeatureCacheAppVerPrefName(aFeature
).get(),
731 Preferences::SetInt(FeatureCacheValuePrefName(aFeature
).get(), aStatus
);
734 int32_t GfxInfo::WebRtcHwVp8EncodeSupported() {
735 MOZ_ASSERT(jni::IsAvailable());
737 // The Android side of this calculation is very slow, so we cache the result
738 // in preferences, invalidating if the OS version changes.
741 const auto& currentAppVersion
= GfxInfoBase::GetApplicationVersion();
742 if (GetCachedFeatureVal(FEATURE_WEBRTC_HW_ACCELERATION_ENCODE
,
743 mOSVersionInteger
, currentAppVersion
, status
)) {
747 status
= java::GeckoAppShell::HasHWVP8Encoder()
748 ? nsIGfxInfo::FEATURE_STATUS_OK
749 : nsIGfxInfo::FEATURE_BLOCKED_DEVICE
;
751 SetCachedFeatureVal(FEATURE_WEBRTC_HW_ACCELERATION_ENCODE
, mOSVersionInteger
,
752 currentAppVersion
, status
);
757 int32_t GfxInfo::WebRtcHwVp8DecodeSupported() {
758 MOZ_ASSERT(jni::IsAvailable());
760 // The Android side of this caclulation is very slow, so we cache the result
761 // in preferences, invalidating if the OS version changes.
764 const auto& appVersion
= GfxInfoBase::GetApplicationVersion();
765 if (GetCachedFeatureVal(FEATURE_WEBRTC_HW_ACCELERATION_DECODE
,
766 mOSVersionInteger
, appVersion
, status
)) {
770 status
= java::GeckoAppShell::HasHWVP8Decoder()
771 ? nsIGfxInfo::FEATURE_STATUS_OK
772 : nsIGfxInfo::FEATURE_BLOCKED_DEVICE
;
774 SetCachedFeatureVal(FEATURE_WEBRTC_HW_ACCELERATION_DECODE
, mOSVersionInteger
,
780 int32_t GfxInfo::WebRtcHwH264Supported() {
781 MOZ_ASSERT(jni::IsAvailable());
783 // The Android side of this calculation is very slow, so we cache the result
784 // in preferences, invalidating if the OS version changes.
787 const auto& currentAppVersion
= GfxInfoBase::GetApplicationVersion();
788 if (GetCachedFeatureVal(FEATURE_WEBRTC_HW_ACCELERATION_H264
,
789 mOSVersionInteger
, currentAppVersion
, status
)) {
793 status
= java::HardwareCodecCapabilityUtils::HasHWH264()
794 ? nsIGfxInfo::FEATURE_STATUS_OK
795 : nsIGfxInfo::FEATURE_BLOCKED_DEVICE
;
797 SetCachedFeatureVal(FEATURE_WEBRTC_HW_ACCELERATION_H264
, mOSVersionInteger
,
798 currentAppVersion
, status
);
805 // Implement nsIGfxInfoDebug
807 NS_IMETHODIMP
GfxInfo::SpoofVendorID(const nsAString
& aVendorID
) {
808 mGLStrings
->SpoofVendor(NS_LossyConvertUTF16toASCII(aVendorID
));
812 NS_IMETHODIMP
GfxInfo::SpoofDeviceID(const nsAString
& aDeviceID
) {
813 mGLStrings
->SpoofRenderer(NS_LossyConvertUTF16toASCII(aDeviceID
));
817 NS_IMETHODIMP
GfxInfo::SpoofDriverVersion(const nsAString
& aDriverVersion
) {
818 mGLStrings
->SpoofVersion(NS_LossyConvertUTF16toASCII(aDriverVersion
));
822 NS_IMETHODIMP
GfxInfo::SpoofOSVersion(uint32_t aVersion
) {
824 mOSVersion
= aVersion
;
830 nsString
GfxInfo::Model() {
835 nsString
GfxInfo::Hardware() {
840 nsString
GfxInfo::Product() {
845 nsString
GfxInfo::Manufacturer() {
847 return mManufacturer
;
850 uint32_t GfxInfo::OperatingSystemVersion() {
852 return mOSVersionInteger
;
855 } // namespace widget
856 } // namespace mozilla