From 163e9e5fd470c745b03a58d895ac967748b677c0 Mon Sep 17 00:00:00 2001 From: Vladimir Vukicevic Date: Fri, 1 Oct 2010 20:55:19 -0700 Subject: [PATCH] b=600863; implement rough mac gfx blocklist; r=joe --- widget/public/nsIGfxInfo.idl | 3 + widget/src/cocoa/GfxInfo.h | 76 +++++++++++ widget/src/cocoa/GfxInfo.mm | 199 ++++++++++++++++++++++++++++ widget/src/cocoa/Makefile.in | 1 + widget/src/cocoa/nsWidgetFactory.mm | 11 ++ 5 files changed, 290 insertions(+) create mode 100644 widget/src/cocoa/GfxInfo.h create mode 100644 widget/src/cocoa/GfxInfo.mm diff --git a/widget/public/nsIGfxInfo.idl b/widget/public/nsIGfxInfo.idl index e18f6a592d6..e35125221d7 100644 --- a/widget/public/nsIGfxInfo.idl +++ b/widget/public/nsIGfxInfo.idl @@ -43,6 +43,9 @@ [scriptable, uuid(d2bfa0fd-8f73-4660-9609-f999680243b1)] interface nsIGfxInfo : nsISupports { + /* + * These are win32-specific + */ readonly attribute boolean D2DEnabled; readonly attribute boolean DWriteEnabled; diff --git a/widget/src/cocoa/GfxInfo.h b/widget/src/cocoa/GfxInfo.h new file mode 100644 index 00000000000..366d388d4ca --- /dev/null +++ b/widget/src/cocoa/GfxInfo.h @@ -0,0 +1,76 @@ +/* vim: se cin sw=2 ts=2 et : */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef __mozilla_widget_GfxInfo_h__ +#define __mozilla_widget_GfxInfo_h__ + +#include + +#include "nsString.h" + +namespace mozilla { +namespace widget { + +class GfxInfo : public nsIGfxInfo +{ +public: + GfxInfo() {Init();} + virtual ~GfxInfo() {} + + NS_DECL_ISUPPORTS + NS_DECL_NSIGFXINFO +private: + + void Init(); + void AddCrashReportAnnotations(); + nsString mRendererIDsString; + nsString mAdapterRAMString; + + nsString mDeviceID; + nsString mDriverVersion; + nsString mDriverDate; + nsString mDeviceKey; + + PRUint32 mRendererIDs[16]; +}; + +} // namespace widget +} // namespace mozilla + +#endif /* __mozilla_widget_GfxInfo_h__ */ diff --git a/widget/src/cocoa/GfxInfo.mm b/widget/src/cocoa/GfxInfo.mm new file mode 100644 index 00000000000..6a710273ef6 --- /dev/null +++ b/widget/src/cocoa/GfxInfo.mm @@ -0,0 +1,199 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Jonathan Griffin + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include +#include + +#include "GfxInfo.h" +#include "nsUnicharUtils.h" +#include "mozilla/FunctionTimer.h" + +#if defined(MOZ_CRASHREPORTER) && defined(MOZ_ENABLE_LIBXUL) +#include "nsExceptionHandler.h" +#include "nsICrashReporter.h" +#define NS_CRASHREPORTER_CONTRACTID "@mozilla.org/toolkit/crash-reporter;1" +#include "nsIPrefService.h" +#endif + + +using namespace mozilla::widget; + +NS_IMPL_ISUPPORTS1(GfxInfo, nsIGfxInfo) + +void +GfxInfo::Init() +{ + NS_TIME_FUNCTION; + + CGLRendererInfoObj renderer = 0; + GLint rendererCount = 0; + + memset(mRendererIDs, 0, sizeof(mRendererIDs)); + + if (CGLQueryRendererInfo(0xffffffff, &renderer, &rendererCount) != kCGLNoError) + return; + + rendererCount = (GLint) PR_MIN(rendererCount, (GLint) NS_ARRAY_LENGTH(mRendererIDs)); + for (GLint i = 0; i < rendererCount; i++) { + GLint prop = 0; + + if (!mRendererIDsString.IsEmpty()) + mRendererIDsString.AppendLiteral(","); + if (CGLDescribeRenderer(renderer, i, kCGLRPRendererID, &prop) == kCGLNoError) { +#ifdef kCGLRendererIDMatchingMask + prop = prop & kCGLRendererIDMatchingMask; +#else + prop = prop & 0x00FE7F00; // this is the mask token above, but it doesn't seem to exist everywhere? +#endif + mRendererIDs[i] = prop; + mRendererIDsString.AppendPrintf("0x%04x", prop); + } else { + mRendererIDs[i] = -1; + mRendererIDsString.AppendPrintf("???"); + } + } + + CGLDestroyRendererInfo(renderer); + + AddCrashReportAnnotations(); +} + +NS_IMETHODIMP +GfxInfo::GetD2DEnabled(PRBool *aEnabled) +{ + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +GfxInfo::GetDWriteEnabled(PRBool *aEnabled) +{ + return NS_ERROR_FAILURE; +} + +/* readonly attribute DOMString adapterDescription; */ +NS_IMETHODIMP +GfxInfo::GetAdapterDescription(nsAString & aAdapterDescription) +{ + aAdapterDescription = mRendererIDsString; + return NS_OK; +} + +/* readonly attribute DOMString adapterRAM; */ +NS_IMETHODIMP +GfxInfo::GetAdapterRAM(nsAString & aAdapterRAM) +{ + aAdapterRAM = mAdapterRAMString; + return NS_OK; +} + +/* readonly attribute DOMString adapterDriver; */ +NS_IMETHODIMP +GfxInfo::GetAdapterDriver(nsAString & aAdapterDriver) +{ + aAdapterDriver.AssignLiteral(""); + return NS_OK; +} + +/* readonly attribute DOMString adapterDriverVersion; */ +NS_IMETHODIMP +GfxInfo::GetAdapterDriverVersion(nsAString & aAdapterDriverVersion) +{ + aAdapterDriverVersion.AssignLiteral(""); + return NS_OK; +} + +/* readonly attribute DOMString adapterDriverDate; */ +NS_IMETHODIMP +GfxInfo::GetAdapterDriverDate(nsAString & aAdapterDriverDate) +{ + aAdapterDriverDate.AssignLiteral(""); + return NS_OK; +} + +/* readonly attribute unsigned long adapterVendorID; */ +NS_IMETHODIMP +GfxInfo::GetAdapterVendorID(PRUint32 *aAdapterVendorID) +{ + *aAdapterVendorID = mRendererIDs[0]; + return NS_OK; +} + +/* readonly attribute unsigned long adapterDeviceID; */ +NS_IMETHODIMP +GfxInfo::GetAdapterDeviceID(PRUint32 *aAdapterDeviceID) +{ + *aAdapterDeviceID = mRendererIDs[0]; + return NS_OK; +} + +void +GfxInfo::AddCrashReportAnnotations() +{ +#if defined(MOZ_CRASHREPORTER) && defined(MOZ_ENABLE_LIBXUL) + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterRendererIDs"), + NS_LossyConvertUTF16toASCII(mRendererIDsString)); + + /* Add an App Note for now so that we get the data immediately. These + * can go away after we store the above in the socorro db */ + nsCAutoString note; + /* AppendPrintf only supports 32 character strings, mrghh. */ + note.AppendLiteral("Renderers: "); + note.Append(NS_LossyConvertUTF16toASCII(mRendererIDsString)); + + CrashReporter::AppendAppNotesToCrashReport(note); +#endif +} + +NS_IMETHODIMP +GfxInfo::GetFeatureStatus(PRInt32 aFeature, PRInt32 *aStatus) +{ + PRInt32 status = nsIGfxInfo::FEATURE_STATUS_UNKNOWN; + + for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(mRendererIDs); ++i) { + PRUint32 r = mRendererIDs[i]; + + if (aFeature == nsIGfxInfo::FEATURE_OPENGL_LAYERS) { + if (r == kCGLRendererATIRadeonX1000ID) + status = nsIGfxInfo::FEATURE_BLOCKED; + } + } + + *aStatus = status; + return NS_OK; +} + diff --git a/widget/src/cocoa/Makefile.in b/widget/src/cocoa/Makefile.in index 02e7902a21c..d7965d21dfd 100644 --- a/widget/src/cocoa/Makefile.in +++ b/widget/src/cocoa/Makefile.in @@ -92,6 +92,7 @@ CMMSRCS = \ nsCocoaTextInputHandler.mm \ nsMacDockSupport.mm \ nsStandaloneNativeMenu.mm \ + GfxInfo.mm \ $(NULL) ifeq (x86_64,$(TARGET_CPU)) diff --git a/widget/src/cocoa/nsWidgetFactory.mm b/widget/src/cocoa/nsWidgetFactory.mm index d81e63ccb25..e6242540538 100644 --- a/widget/src/cocoa/nsWidgetFactory.mm +++ b/widget/src/cocoa/nsWidgetFactory.mm @@ -99,6 +99,14 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsMacDockSupport) #include "nsStandaloneNativeMenu.h" NS_GENERIC_FACTORY_CONSTRUCTOR(nsStandaloneNativeMenu) +#include "GfxInfo.h" +namespace mozilla { +namespace widget { +NS_GENERIC_FACTORY_CONSTRUCTOR(GfxInfo) +} +} + + NS_DEFINE_NAMED_CID(NS_WINDOW_CID); NS_DEFINE_NAMED_CID(NS_POPUP_CID); NS_DEFINE_NAMED_CID(NS_CHILD_CID); @@ -123,6 +131,7 @@ NS_DEFINE_NAMED_CID(NS_IDLE_SERVICE_CID); NS_DEFINE_NAMED_CID(NS_NATIVEMENUSERVICE_CID); NS_DEFINE_NAMED_CID(NS_MACDOCKSUPPORT_CID); NS_DEFINE_NAMED_CID(NS_STANDALONENATIVEMENU_CID); +NS_DEFINE_NAMED_CID(NS_GFXINFO_CID); static const mozilla::Module::CIDEntry kWidgetCIDs[] = { @@ -150,6 +159,7 @@ static const mozilla::Module::CIDEntry kWidgetCIDs[] = { { &kNS_NATIVEMENUSERVICE_CID, false, NULL, nsNativeMenuServiceXConstructor }, { &kNS_MACDOCKSUPPORT_CID, false, NULL, nsMacDockSupportConstructor }, { &kNS_STANDALONENATIVEMENU_CID, false, NULL, nsStandaloneNativeMenuConstructor }, + { &kNS_GFXINFO_CID, false, NULL, mozilla::widget::GfxInfoConstructor }, { NULL } }; @@ -178,6 +188,7 @@ static const mozilla::Module::ContractIDEntry kWidgetContracts[] = { { "@mozilla.org/widget/nativemenuservice;1", &kNS_NATIVEMENUSERVICE_CID }, { "@mozilla.org/widget/macdocksupport;1", &kNS_MACDOCKSUPPORT_CID }, { "@mozilla.org/widget/standalonenativemenu;1", &kNS_STANDALONENATIVEMENU_CID }, + { "@mozilla.org/gfx/info;1", &kNS_GFXINFO_CID }, { NULL } };