Bug 678330. Use IOKit to get precise GPU information in GfxInfo on Mac. r=bjacob
authorJeff Muizelaar <jmuizelaar@mozilla.com>
Tue, 27 Sep 2011 09:55:42 -0400
changeset 77713 d747526bd06644be1ec38fc21d8589b4121442e4
parent 77712 37843077ff3d446caad0c795c46d865902b1d18d
child 77714 687e0bbfe996aad72f13fde04ac7f8ea733c16cc
push id3
push userfelipc@gmail.com
push dateFri, 30 Sep 2011 20:09:13 +0000
reviewersbjacob
bugs678330
milestone9.0a1
Bug 678330. Use IOKit to get precise GPU information in GfxInfo on Mac. r=bjacob This lets us get vendor and device ids.
toolkit/content/license.html
widget/src/cocoa/GfxInfo.h
widget/src/cocoa/GfxInfo.mm
--- a/toolkit/content/license.html
+++ b/toolkit/content/license.html
@@ -2214,17 +2214,18 @@ WITH THE USE OR PERFORMANCE OF THIS SOFT
 </pre>
 
 
     <hr>
 
     <h1><a name="chromium"></a>Chromium License</h1>
 
     <p>This license applies to parts of the code in
-      <span class="path">editor/libeditor/base/nsEditorEventListener.cpp</span>
+      <span class="path">editor/libeditor/base/nsEditorEventListener.cpp</span>,
+      <span class="path">widget/src/cocoa/GfxInfo.mm</span>
       and also some files in the directories
       <span class="path">ipc/chromium/</span>,
       <span class="path">dom/plugins/</span>,
       <span class="path">gfx/ots/</span> and
       <span class="path">gfx/ycbcr</span>.
     </p>
 
 <pre>
--- a/widget/src/cocoa/GfxInfo.h
+++ b/widget/src/cocoa/GfxInfo.h
@@ -45,16 +45,18 @@
 #include "nsString.h"
 
 namespace mozilla {
 namespace widget {
 
 class GfxInfo : public GfxInfoBase
 {
 public:
+
+  GfxInfo();
   // We only declare the subset of nsIGfxInfo that we actually implement. The
   // rest is brought forward from GfxInfoBase.
   NS_SCRIPTABLE NS_IMETHOD GetD2DEnabled(PRBool *aD2DEnabled);
   NS_SCRIPTABLE NS_IMETHOD GetDWriteEnabled(PRBool *aDWriteEnabled);
   NS_SCRIPTABLE NS_IMETHOD GetAzureEnabled(PRBool *aAzureEnabled);
   NS_SCRIPTABLE NS_IMETHOD GetDWriteVersion(nsAString & aDwriteVersion);
   NS_SCRIPTABLE NS_IMETHOD GetCleartypeParameters(nsAString & aCleartypeParams);
   NS_SCRIPTABLE NS_IMETHOD GetAdapterDescription(nsAString & aAdapterDescription);
@@ -79,24 +81,28 @@ public:
   virtual nsresult Init();
 
 protected:
 
   virtual nsresult GetFeatureStatusImpl(PRInt32 aFeature, PRInt32 *aStatus, nsAString & aSuggestedDriverVersion, GfxDriverInfo* aDriverInfo = nsnull);
 
 private:
 
+  void GetDeviceInfo();
   void AddCrashReportAnnotations();
   nsString mRendererIDsString;
   nsString mAdapterRAMString;
 
   nsString mDeviceID;
   nsString mDriverVersion;
   nsString mDriverDate;
   nsString mDeviceKey;
 
+  PRUint32 mAdapterVendorID;
+  PRUint32 mAdapterDeviceID;
+
   PRUint32 mRendererIDs[16];
 };
 
 } // namespace widget
 } // namespace mozilla
 
 #endif /* __mozilla_widget_GfxInfo_h__ */
--- a/widget/src/cocoa/GfxInfo.mm
+++ b/widget/src/cocoa/GfxInfo.mm
@@ -39,24 +39,74 @@
 #include <OpenGL/OpenGL.h>
 #include <OpenGL/CGLRenderers.h>
 
 #include "GfxInfo.h"
 #include "nsUnicharUtils.h"
 #include "mozilla/FunctionTimer.h"
 #include "nsToolkit.h"
 
+#import <Foundation/Foundation.h>
+#import <IOKit/IOKitLib.h>
+
 #if defined(MOZ_CRASHREPORTER)
 #include "nsExceptionHandler.h"
 #include "nsICrashReporter.h"
 #define NS_CRASHREPORTER_CONTRACTID "@mozilla.org/toolkit/crash-reporter;1"
 #endif
 
 using namespace mozilla::widget;
 
+GfxInfo::GfxInfo()
+  : mAdapterVendorID(0),
+    mAdapterDeviceID(0)
+{
+}
+
+// The following three functions are derived from Chromium code
+static CFTypeRef SearchPortForProperty(io_registry_entry_t dspPort,
+                                       CFStringRef propertyName)
+{
+  return IORegistryEntrySearchCFProperty(dspPort,
+                                         kIOServicePlane,
+                                         propertyName,
+                                         kCFAllocatorDefault,
+                                         kIORegistryIterateRecursively |
+                                         kIORegistryIterateParents);
+}
+
+static PRUint32 IntValueOfCFData(CFDataRef d)
+{
+  PRUint32 value = 0;
+
+  if (d) {
+    const PRUint32 *vp = reinterpret_cast<const PRUint32*>(CFDataGetBytePtr(d));
+    if (vp != NULL)
+      value = *vp;
+  }
+
+  return value;
+}
+
+void
+GfxInfo::GetDeviceInfo()
+{
+  io_registry_entry_t dsp_port = CGDisplayIOServicePort(kCGDirectMainDisplay);
+  CFTypeRef vendor_id_ref = SearchPortForProperty(dsp_port, CFSTR("vendor-id"));
+  if (vendor_id_ref) {
+    mAdapterVendorID = IntValueOfCFData((CFDataRef)vendor_id_ref);
+    CFRelease(vendor_id_ref);
+  }
+  CFTypeRef device_id_ref = SearchPortForProperty(dsp_port, CFSTR("device-id"));
+  if (device_id_ref) {
+    mAdapterDeviceID = IntValueOfCFData((CFDataRef)device_id_ref);
+    CFRelease(device_id_ref);
+  }
+}
+
 nsresult
 GfxInfo::Init()
 {
   NS_TIME_FUNCTION;
 
   nsresult rv = GfxInfoBase::Init();
 
   CGLRendererInfoObj renderer = 0;
@@ -84,16 +134,18 @@ GfxInfo::Init()
     } else {
       mRendererIDs[i] = 0;
       mRendererIDsString.AppendPrintf("???");
     }
   }
 
   CGLDestroyRendererInfo(renderer);
 
+  GetDeviceInfo();
+
   AddCrashReportAnnotations();
 
   return rv;
 }
 
 NS_IMETHODIMP
 GfxInfo::GetD2DEnabled(PRBool *aEnabled)
 {
@@ -200,32 +252,32 @@ GfxInfo::GetAdapterDriverDate2(nsAString
 {
   return NS_ERROR_FAILURE;
 }
 
 /* readonly attribute unsigned long adapterVendorID; */
 NS_IMETHODIMP
 GfxInfo::GetAdapterVendorID(PRUint32 *aAdapterVendorID)
 {
-  *aAdapterVendorID = 0;
+  *aAdapterVendorID = mAdapterVendorID;
   return NS_OK;
 }
 
 /* readonly attribute unsigned long adapterVendorID2; */
 NS_IMETHODIMP
 GfxInfo::GetAdapterVendorID2(PRUint32 *aAdapterVendorID)
 {
   return NS_ERROR_FAILURE;
 }
 
 /* readonly attribute unsigned long adapterDeviceID; */
 NS_IMETHODIMP
 GfxInfo::GetAdapterDeviceID(PRUint32 *aAdapterDeviceID)
 {
-  *aAdapterDeviceID = 0;
+  *aAdapterDeviceID = mAdapterDeviceID;
   return NS_OK;
 }
 
 /* readonly attribute unsigned long adapterDeviceID2; */
 NS_IMETHODIMP
 GfxInfo::GetAdapterDeviceID2(PRUint32 *aAdapterDeviceID)
 {
   return NS_ERROR_FAILURE;