Bug 687868. Redo blacklisting to use device ids instead of renderer info.
authorJeff Muizelaar <jmuizelaar@mozilla.com>
Tue, 27 Sep 2011 10:18:41 -0400
changeset 77715 9ba53832faf28544329de3bb0834cb8f25ef23af
parent 77714 687e0bbfe996aad72f13fde04ac7f8ea733c16cc
child 77716 8671e54153ffc82a7020e5079372c95fda5d9011
push id3
push userfelipc@gmail.com
push dateFri, 30 Sep 2011 20:09:13 +0000
bugs687868
milestone9.0a1
Bug 687868. Redo blacklisting to use device ids instead of renderer info. This avoids using CGLQueryRendererInfo which cause cause us to switch to the discrete GPU. It also allows us to be more specific about black listing particular devices.
widget/src/cocoa/GfxInfo.mm
--- a/widget/src/cocoa/GfxInfo.mm
+++ b/widget/src/cocoa/GfxInfo.mm
@@ -97,23 +97,41 @@ GfxInfo::GetDeviceInfo()
   }
   CFTypeRef device_id_ref = SearchPortForProperty(dsp_port, CFSTR("device-id"));
   if (device_id_ref) {
     mAdapterDeviceID = IntValueOfCFData((CFDataRef)device_id_ref);
     CFRelease(device_id_ref);
   }
 }
 
+static bool
+IsATIRadeonX1000(PRUint32 aVendorID, PRUint32 aDeviceID)
+{
+  if (aVendorID == 0x1002) {
+    // this list is from the ATIRadeonX1000.kext Info.plist
+    PRUint32 devices[] = {0x7187, 0x7210, 0x71DE, 0x7146, 0x7142, 0x7109, 0x71C5, 0x71C0, 0x7240, 0x7249, 0x7291};
+    for (size_t i = 0; i < NS_ARRAY_LENGTH(devices); i++) {
+      if (aDeviceID == devices[i])
+        return true;
+    }
+  }
+  return false;
+}
+
 nsresult
 GfxInfo::Init()
 {
   NS_TIME_FUNCTION;
 
   nsresult rv = GfxInfoBase::Init();
 
+  // Calling CGLQueryRendererInfo causes us to switch to the discrete GPU
+  // even when we don't want to. We'll avoid doing so for now and just
+  // use the device ids.
+#if 0
   CGLRendererInfoObj renderer = 0;
   GLint rendererCount = 0;
 
   memset(mRendererIDs, 0, sizeof(mRendererIDs));
 
   if (CGLQueryRendererInfo(0xffffffff, &renderer, &rendererCount) != kCGLNoError)
     return rv;
 
@@ -133,16 +151,17 @@ GfxInfo::Init()
       mRendererIDsString.AppendPrintf("0x%04x", prop);
     } else {
       mRendererIDs[i] = 0;
       mRendererIDsString.AppendPrintf("???");
     }
   }
 
   CGLDestroyRendererInfo(renderer);
+#endif
 
   GetDeviceInfo();
 
   AddCrashReportAnnotations();
 
   return rv;
 }
 
@@ -330,25 +349,31 @@ GfxInfo::GetFeatureStatusImpl(PRInt32 aF
   //   * bug 618848: Post process shaders and texture mapping crash OS X 10.5
   if (aFeature == nsIGfxInfo::FEATURE_WEBGL_OPENGL &&
       !nsToolkit::OnSnowLeopardOrLater())
   {
     status = nsIGfxInfo::FEATURE_BLOCKED_OS_VERSION;
   }
 
   if (aFeature == nsIGfxInfo::FEATURE_OPENGL_LAYERS) {
+    PRBool foundGoodDevice = PR_FALSE;
+
+    if (!IsATIRadeonX1000(mAdapterVendorID, mAdapterDeviceID)) {
+      foundGoodDevice = PR_TRUE;
+    }
+
+#if 0
     // CGL reports a list of renderers, some renderers are slow (e.g. software)
     // and AFAIK we can't decide which one will be used among them, so let's implement this by returning NO_INFO
     // if any not-known-to-be-bad renderer is found.
     // The assumption that we make here is that the system will spontaneously use the best/fastest renderer in the list.
     // Note that the presence of software renderer fallbacks means that slow software rendering may be automatically
     // used, which seems to be the case in bug 611292 where the user had a Intel GMA 945 card (non programmable hardware).
     // Therefore we need to explicitly blacklist non-OpenGL2 hardware, which could result in a software renderer
     // being used.
-    PRBool foundGoodDevice = PR_FALSE;
 
     for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(mRendererIDs); ++i) {
       switch (mRendererIDs[i]) {
         case kCGLRendererATIRage128ID: // non-programmable
         case kCGLRendererATIRadeonID: // non-programmable
         case kCGLRendererATIRageProID: // non-programmable
         case kCGLRendererATIRadeon8500ID: // no OpenGL 2 support, http://en.wikipedia.org/wiki/Radeon_R200
         case kCGLRendererATIRadeon9700ID: // no OpenGL 2 support, http://en.wikipedia.org/wiki/Radeon_R200
@@ -365,34 +390,29 @@ GfxInfo::GetFeatureStatusImpl(PRInt32 aF
         case kCGLRendererGenericID: // software renderer
         case kCGLRendererAppleSWID: // software renderer
           break;
         default:
           if (mRendererIDs[i])
             foundGoodDevice = PR_TRUE;
       }
     }
+#endif
     if (!foundGoodDevice)
       status = nsIGfxInfo::FEATURE_BLOCKED_DEVICE;
   }
 
   if (aFeature == nsIGfxInfo::FEATURE_WEBGL_OPENGL) {
     // same comment as above for FEATURE_OPENGL_LAYERS.
-    bool foundGoodDevice = false;
+    bool foundGoodDevice = true;
 
-    for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(mRendererIDs); ++i) {
-      switch (mRendererIDs[i]) {
-        case kCGLRendererGeForceFXID: // bug 678053. We must blacklist Geforce 7300 GT. This family
-                                      // covers all Geforce FX, 6, 7 series. Need bug 678330 for finer
-                                      // blacklisting.
-          break;
-        default:
-          if (mRendererIDs[i])
-            foundGoodDevice = true;
-      }
+    // Blacklist the Geforce 7300 GT because of bug 678053
+    if (mAdapterVendorID == 0x10de && mAdapterDeviceID == 0x0393) {
+      foundGoodDevice = false;
     }
+
     if (!foundGoodDevice)
       status = nsIGfxInfo::FEATURE_BLOCKED_DEVICE;
   }
 
   *aStatus = status;
   return NS_OK;
 }