Add compositor, layers, and rendering info to nsIGfxInfo. (bug 1179051 part 5, r=mattwoodrow)

This commit is contained in:
David Anderson 2015-07-19 14:50:35 -07:00
parent 9988952a0a
commit dc0138c34a
13 changed files with 371 additions and 21 deletions

36
gfx/src/gfxTelemetry.cpp Normal file
View File

@ -0,0 +1,36 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "gfxTelemetry.h"
namespace mozilla {
namespace gfx {
const char*
FeatureStatusToString(FeatureStatus aStatus)
{
switch (aStatus) {
case FeatureStatus::Unused:
return "unused";
case FeatureStatus::Unavailable:
return "unavailable";
case FeatureStatus::Blocked:
return "blocked";
case FeatureStatus::Blacklisted:
return "blacklisted";
case FeatureStatus::Failed:
return "failed";
case FeatureStatus::Disabled:
return "disabled";
case FeatureStatus::Available:
return "available";
default:
MOZ_ASSERT_UNREACHABLE("missing status case");
return "unknown";
}
}
} // namespace gfx
} // namespace mozilla

46
gfx/src/gfxTelemetry.h Normal file
View File

@ -0,0 +1,46 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef gfx_src_gfxTelemetry_h__
#define gfx_src_gfxTelemetry_h__
namespace mozilla {
namespace gfx {
// Describes the status of a graphics feature, in terms of whether or not we've
// attempted to initialize the feature, and if so, whether or not it succeeded
// (and if not, why).
enum class FeatureStatus
{
// This feature has not been requested.
Unused,
// This feature is unavailable due to Safe Mode or not being included with
// the operating system.
Unavailable,
// This feature was blocked for reasons outside the blacklist, such as a
// runtime test failing.
Blocked,
// This feature has been blocked by the graphics blacklist.
Blacklisted,
// This feature was attempted but failed to activate.
Failed,
// This feature was explicitly disabled by the user.
Disabled,
// This feature is available for use.
Available
};
const char* FeatureStatusToString(FeatureStatus aStatus);
} // namespace gfx
} // namespace mozilla
#endif // gfx_src_gfxTelemetry_h__

View File

@ -18,6 +18,7 @@ EXPORTS += [
'FilterSupport.h', 'FilterSupport.h',
'gfxCore.h', 'gfxCore.h',
'gfxCrashReporterUtils.h', 'gfxCrashReporterUtils.h',
'gfxTelemetry.h',
'nsBoundingMetrics.h', 'nsBoundingMetrics.h',
'nsColor.h', 'nsColor.h',
'nsColorNameList.h', 'nsColorNameList.h',
@ -56,6 +57,7 @@ UNIFIED_SOURCES += [
'DriverInitCrashDetection.cpp', 'DriverInitCrashDetection.cpp',
'FilterSupport.cpp', 'FilterSupport.cpp',
'gfxCrashReporterUtils.cpp', 'gfxCrashReporterUtils.cpp',
'gfxTelemetry.cpp',
'nsColor.cpp', 'nsColor.cpp',
'nsFont.cpp', 'nsFont.cpp',
'nsFontMetrics.cpp', 'nsFontMetrics.cpp',

View File

@ -379,6 +379,7 @@ gfxPlatform::gfxPlatform()
, mTileHeight(-1) , mTileHeight(-1)
, mAzureCanvasBackendCollector(this, &gfxPlatform::GetAzureBackendInfo) , mAzureCanvasBackendCollector(this, &gfxPlatform::GetAzureBackendInfo)
, mApzSupportCollector(this, &gfxPlatform::GetApzSupportInfo) , mApzSupportCollector(this, &gfxPlatform::GetApzSupportInfo)
, mCompositorBackend(layers::LayersBackend::LAYERS_NONE)
{ {
mAllowDownloadableFonts = UNINITIALIZED_VALUE; mAllowDownloadableFonts = UNINITIALIZED_VALUE;
mFallbackUsesCmaps = UNINITIALIZED_VALUE; mFallbackUsesCmaps = UNINITIALIZED_VALUE;
@ -410,6 +411,12 @@ gfxPlatform::GetPlatform()
return gPlatform; return gPlatform;
} }
bool
gfxPlatform::Initialized()
{
return !!gPlatform;
}
void RecordingPrefChanged(const char *aPrefName, void *aClosure) void RecordingPrefChanged(const char *aPrefName, void *aClosure)
{ {
if (Preferences::GetBool("gfx.2d.recording", false)) { if (Preferences::GetBool("gfx.2d.recording", false)) {
@ -2444,3 +2451,21 @@ gfxPlatform::GetCompositorBackends(bool useAcceleration, nsTArray<mozilla::layer
aBackends.AppendElement(LayersBackend::LAYERS_BASIC); aBackends.AppendElement(LayersBackend::LAYERS_BASIC);
} }
} }
void
gfxPlatform::NotifyCompositorCreated(LayersBackend aBackend)
{
if (mCompositorBackend == aBackend) {
return;
}
NS_ASSERTION(mCompositorBackend == LayersBackend::LAYERS_NONE, "Compositor backend changed.");
// Set the backend before we notify so it's available immediately.
mCompositorBackend = aBackend;
// Notify that we created a compositor, so telemetry can update.
if (nsCOMPtr<nsIObserverService> obsvc = services::GetObserverService()) {
obsvc->NotifyObservers(nullptr, "compositor:created", nullptr);
}
}

View File

@ -159,6 +159,12 @@ public:
*/ */
static gfxPlatform *GetPlatform(); static gfxPlatform *GetPlatform();
/**
* Returns whether or not graphics has been initialized yet. This is
* intended for Telemetry where we don't necessarily want to initialize
* graphics just to observe its state.
*/
static bool Initialized();
/** /**
* Shut down Thebes. * Shut down Thebes.
@ -631,6 +637,11 @@ public:
*/ */
static bool PerfWarnings(); static bool PerfWarnings();
void NotifyCompositorCreated(mozilla::layers::LayersBackend aBackend);
mozilla::layers::LayersBackend GetCompositorBackend() const {
return mCompositorBackend;
}
protected: protected:
gfxPlatform(); gfxPlatform();
virtual ~gfxPlatform(); virtual ~gfxPlatform();
@ -751,6 +762,10 @@ private:
mozilla::RefPtr<mozilla::gfx::DrawEventRecorder> mRecorder; mozilla::RefPtr<mozilla::gfx::DrawEventRecorder> mRecorder;
mozilla::RefPtr<mozilla::gl::SkiaGLGlue> mSkiaGlue; mozilla::RefPtr<mozilla::gl::SkiaGLGlue> mSkiaGlue;
// Backend that we are compositing with. NONE, if no compositor has been
// created yet.
mozilla::layers::LayersBackend mCompositorBackend;
}; };
#endif /* GFX_PLATFORM_H */ #endif /* GFX_PLATFORM_H */

View File

@ -377,6 +377,8 @@ gfxWindowsPlatform::gfxWindowsPlatform()
, mIsWARP(false) , mIsWARP(false)
, mHasDeviceReset(false) , mHasDeviceReset(false)
, mDoesD3D11TextureSharingWork(false) , mDoesD3D11TextureSharingWork(false)
, mD3D11Status(FeatureStatus::Unused)
, mD2DStatus(FeatureStatus::Unused)
{ {
mUseClearTypeForDownloadableFonts = UNINITIALIZED_VALUE; mUseClearTypeForDownloadableFonts = UNINITIALIZED_VALUE;
mUseClearTypeAlways = UNINITIALIZED_VALUE; mUseClearTypeAlways = UNINITIALIZED_VALUE;
@ -436,7 +438,7 @@ gfxWindowsPlatform::CanUseHardwareVideoDecoding()
return !IsWARP() && gfxPlatform::CanUseHardwareVideoDecoding(); return !IsWARP() && gfxPlatform::CanUseHardwareVideoDecoding();
} }
void FeatureStatus
gfxWindowsPlatform::InitD2DSupport() gfxWindowsPlatform::InitD2DSupport()
{ {
#ifdef CAIRO_HAS_D2D_SURFACE #ifdef CAIRO_HAS_D2D_SURFACE
@ -458,30 +460,41 @@ gfxWindowsPlatform::InitD2DSupport()
// If D2D is blocked or D3D9 is prefered, and D2D is not force-enabled, then // If D2D is blocked or D3D9 is prefered, and D2D is not force-enabled, then
// we don't attempt to use D2D. // we don't attempt to use D2D.
if ((d2dBlocked || gfxPrefs::LayersPreferD3D9()) && !gfxPrefs::Direct2DForceEnabled()) { if (!gfxPrefs::Direct2DForceEnabled()) {
return; if (d2dBlocked) {
return FeatureStatus::Blacklisted;
}
if (gfxPrefs::LayersPreferD3D9()) {
return FeatureStatus::Disabled;
}
} }
// Do not ever try to use D2D if it's explicitly disabled or if we're not // Do not ever try to use D2D if it's explicitly disabled or if we're not
// using DWrite fonts. // using DWrite fonts.
if (gfxPrefs::Direct2DDisabled() || mUsingGDIFonts) { if (gfxPrefs::Direct2DDisabled() || mUsingGDIFonts) {
return; return FeatureStatus::Disabled;
} }
ID3D11Device* device = GetD3D11Device(); if (!IsVistaOrLater() || !GetD3D11Device()) {
if (IsVistaOrLater() && return FeatureStatus::Unavailable;
!InSafeMode() &&
device &&
mDoesD3D11TextureSharingWork)
{
VerifyD2DDevice(gfxPrefs::Direct2DForceEnabled());
if (mD3D10Device && GetD3D11Device()) {
mRenderMode = RENDER_DIRECT2D;
mUseDirectWrite = true;
}
} else {
mD3D10Device = nullptr;
} }
if (!mDoesD3D11TextureSharingWork) {
return FeatureStatus::Failed;
}
if (InSafeMode()) {
return FeatureStatus::Blocked;
}
VerifyD2DDevice(gfxPrefs::Direct2DForceEnabled());
if (!mD3D10Device || !GetD3D11Device()) {
return FeatureStatus::Failed;
}
mRenderMode = RENDER_DIRECT2D;
mUseDirectWrite = true;
return FeatureStatus::Available;
#else
return FeatureStatus::Unavailable;
#endif #endif
} }
@ -552,7 +565,7 @@ gfxWindowsPlatform::UpdateRenderMode()
mRenderMode = RENDER_GDI; mRenderMode = RENDER_GDI;
mUseDirectWrite = gfxPrefs::DirectWriteFontRenderingEnabled(); mUseDirectWrite = gfxPrefs::DirectWriteFontRenderingEnabled();
InitD2DSupport(); mD2DStatus = InitD2DSupport();
InitDWriteSupport(); InitDWriteSupport();
uint32_t canvasMask = BackendTypeBit(BackendType::CAIRO); uint32_t canvasMask = BackendTypeBit(BackendType::CAIRO);
@ -2056,15 +2069,17 @@ gfxWindowsPlatform::InitD3D11Devices()
mD3D11DeviceInitialized = true; mD3D11DeviceInitialized = true;
mDoesD3D11TextureSharingWork = false; mDoesD3D11TextureSharingWork = false;
MOZ_ASSERT(!mD3D11Device); MOZ_ASSERT(!mD3D11Device);
DriverInitCrashDetection detectCrashes; DriverInitCrashDetection detectCrashes;
if (InSafeMode() || detectCrashes.DisableAcceleration()) { if (InSafeMode() || detectCrashes.DisableAcceleration()) {
mD3D11Status = FeatureStatus::Blocked;
return; return;
} }
D3D11Status status = CheckD3D11Support(); D3D11Status status = CheckD3D11Support();
if (status == D3D11Status::Blocked) { if (status == D3D11Status::Blocked) {
mD3D11Status = FeatureStatus::Blacklisted;
return; return;
} }
@ -2074,6 +2089,7 @@ gfxWindowsPlatform::InitD3D11Devices()
if (!sD3D11CreateDeviceFn) { if (!sD3D11CreateDeviceFn) {
// We should just be on Windows Vista or XP in this case. // We should just be on Windows Vista or XP in this case.
mD3D11Status = FeatureStatus::Unavailable;
return; return;
} }
@ -2097,6 +2113,7 @@ gfxWindowsPlatform::InitD3D11Devices()
(status == D3D11Status::TryWARP || status == D3D11Status::ForceWARP)) (status == D3D11Status::TryWARP || status == D3D11Status::ForceWARP))
{ {
AttemptWARPDeviceCreation(featureLevels); AttemptWARPDeviceCreation(featureLevels);
mD3D11Status = FeatureStatus::Failed;
} }
if (!mD3D11Device) { if (!mD3D11Device) {
@ -2105,6 +2122,7 @@ gfxWindowsPlatform::InitD3D11Devices()
} }
mD3D11Device->SetExceptionMode(0); mD3D11Device->SetExceptionMode(0);
mD3D11Status = FeatureStatus::Available;
// We create our device for D2D content drawing here. Normally we don't use // We create our device for D2D content drawing here. Normally we don't use
// D2D content drawing when using WARP. However when WARP is forced by // D2D content drawing when using WARP. However when WARP is forced by
@ -2409,3 +2427,32 @@ gfxWindowsPlatform::GetAcceleratedCompositorBackends(nsTArray<LayersBackend>& aB
} }
} }
} }
FeatureStatus
gfxWindowsPlatform::GetD2D1Status()
{
if (GetD2DStatus() != FeatureStatus::Available ||
!Factory::SupportsD2D1())
{
return FeatureStatus::Unavailable;
}
if (!GetD3D11ContentDevice()) {
return FeatureStatus::Failed;
}
if (!gfxPrefs::Direct2DUse1_1()) {
return FeatureStatus::Disabled;
}
return FeatureStatus::Available;
}
unsigned
gfxWindowsPlatform::GetD3D11Version()
{
ID3D11Device* device = GetD3D11Device();
if (!device) {
return 0;
}
return device->GetFeatureLevel();
}

View File

@ -20,6 +20,7 @@
#include "gfxDWriteFonts.h" #include "gfxDWriteFonts.h"
#endif #endif
#include "gfxPlatform.h" #include "gfxPlatform.h"
#include "gfxTelemetry.h"
#include "gfxTypes.h" #include "gfxTypes.h"
#include "mozilla/Attributes.h" #include "mozilla/Attributes.h"
#include "mozilla/Atomics.h" #include "mozilla/Atomics.h"
@ -261,6 +262,18 @@ public:
} }
bool SupportsApzTouchInput() const override; bool SupportsApzTouchInput() const override;
// Return the diagnostic status of DirectX initialization. If
// initialization has not been attempted, this returns
// FeatureStatus::Unused.
mozilla::gfx::FeatureStatus GetD3D11Status() const {
return mD3D11Status;
}
mozilla::gfx::FeatureStatus GetD2DStatus() const {
return mD2DStatus;
}
unsigned GetD3D11Version();
mozilla::gfx::FeatureStatus GetD2D1Status();
virtual already_AddRefed<mozilla::gfx::VsyncSource> CreateHardwareVsyncSource() override; virtual already_AddRefed<mozilla::gfx::VsyncSource> CreateHardwareVsyncSource() override;
static mozilla::Atomic<size_t> sD3D11MemoryUsed; static mozilla::Atomic<size_t> sD3D11MemoryUsed;
static mozilla::Atomic<size_t> sD3D9MemoryUsed; static mozilla::Atomic<size_t> sD3D9MemoryUsed;
@ -298,7 +311,7 @@ private:
bool AttemptD3D11ContentDeviceCreation(const nsTArray<D3D_FEATURE_LEVEL>& aFeatureLevels); bool AttemptD3D11ContentDeviceCreation(const nsTArray<D3D_FEATURE_LEVEL>& aFeatureLevels);
// Used by UpdateRenderMode(). // Used by UpdateRenderMode().
void InitD2DSupport(); mozilla::gfx::FeatureStatus InitD2DSupport();
void InitDWriteSupport(); void InitDWriteSupport();
IDXGIAdapter1 *GetDXGIAdapter(); IDXGIAdapter1 *GetDXGIAdapter();
@ -326,6 +339,9 @@ private:
bool mDoesD3D11TextureSharingWork; bool mDoesD3D11TextureSharingWork;
DeviceResetReason mDeviceResetReason; DeviceResetReason mDeviceResetReason;
mozilla::gfx::FeatureStatus mD3D11Status;
mozilla::gfx::FeatureStatus mD2DStatus;
virtual void GetPlatformCMSOutputProfile(void* &mem, size_t &size); virtual void GetPlatformCMSOutputProfile(void* &mem, size_t &size);
}; };

View File

@ -33,6 +33,7 @@
#include "mozilla/gfx/2D.h" #include "mozilla/gfx/2D.h"
#include "mozilla/gfx/Logging.h" #include "mozilla/gfx/Logging.h"
#include "gfxPrefs.h" #include "gfxPrefs.h"
#include "gfxPlatform.h"
#if defined(MOZ_CRASHREPORTER) #if defined(MOZ_CRASHREPORTER)
#include "nsExceptionHandler.h" #include "nsExceptionHandler.h"
@ -1179,6 +1180,92 @@ GfxInfoBase::GetMonitors(JSContext* aCx, JS::MutableHandleValue aResult)
return NS_OK; return NS_OK;
} }
static const char*
GetLayersBackendName(layers::LayersBackend aBackend)
{
switch (aBackend) {
case layers::LayersBackend::LAYERS_NONE:
return "none";
case layers::LayersBackend::LAYERS_OPENGL:
return "opengl";
case layers::LayersBackend::LAYERS_D3D9:
return "d3d9";
case layers::LayersBackend::LAYERS_D3D11:
return "d3d11";
case layers::LayersBackend::LAYERS_CLIENT:
return "client";
case layers::LayersBackend::LAYERS_BASIC:
return "basic";
default:
MOZ_ASSERT_UNREACHABLE("unknown layers backend");
return "unknown";
}
}
nsresult
GfxInfoBase::GetFeatures(JSContext* aCx, JS::MutableHandle<JS::Value> aOut)
{
JS::Rooted<JSObject*> obj(aCx, JS_NewPlainObject(aCx));
if (!obj) {
return NS_ERROR_OUT_OF_MEMORY;
}
aOut.setObject(*obj);
layers::LayersBackend backend = gfxPlatform::Initialized()
? gfxPlatform::GetPlatform()->GetCompositorBackend()
: layers::LayersBackend::LAYERS_NONE;
const char* backendName = GetLayersBackendName(backend);
{
JS::Rooted<JSString*> str(aCx, JS_NewStringCopyZ(aCx, backendName));
JS::Rooted<JS::Value> val(aCx, StringValue(str));
JS_SetProperty(aCx, obj, "compositor", val);
}
// If graphics isn't initialized yet, just stop now.
if (!gfxPlatform::Initialized()) {
return NS_OK;
}
DescribeFeatures(aCx, obj);
return NS_OK;
}
void
GfxInfoBase::DescribeFeatures(JSContext* cx, JS::Handle<JSObject*> aOut)
{
}
bool
GfxInfoBase::InitFeatureObject(JSContext* aCx,
JS::Handle<JSObject*> aContainer,
const char* aName,
mozilla::gfx::FeatureStatus aFeatureStatus,
JS::MutableHandle<JSObject*> aOutObj)
{
JS::Rooted<JSObject*> obj(aCx, JS_NewPlainObject(aCx));
if (!obj) {
return false;
}
const char* status = FeatureStatusToString(aFeatureStatus);
// Set "status".
{
JS::Rooted<JSString*> str(aCx, JS_NewStringCopyZ(aCx, status));
JS::Rooted<JS::Value> val(aCx, JS::StringValue(str));
JS_SetProperty(aCx, obj, "status", val);
}
// Add the feature object to the container.
{
JS::Rooted<JS::Value> val(aCx, JS::ObjectValue(*obj));
JS_SetProperty(aCx, aContainer, aName, val);
}
aOutObj.set(obj);
return true;
}
GfxInfoCollectorBase::GfxInfoCollectorBase() GfxInfoCollectorBase::GfxInfoCollectorBase()
{ {
GfxInfoBase::AddCollector(this); GfxInfoBase::AddCollector(this);

View File

@ -19,6 +19,7 @@
#include "nsTArray.h" #include "nsTArray.h"
#include "nsString.h" #include "nsString.h"
#include "GfxInfoCollector.h" #include "GfxInfoCollector.h"
#include "gfxTelemetry.h"
#include "nsIGfxInfoDebug.h" #include "nsIGfxInfoDebug.h"
#include "mozilla/Mutex.h" #include "mozilla/Mutex.h"
#include "js/Value.h" #include "js/Value.h"
@ -58,6 +59,7 @@ public:
NS_IMETHOD GetFailures(uint32_t *failureCount, int32_t** indices, char ***failures) override; NS_IMETHOD GetFailures(uint32_t *failureCount, int32_t** indices, char ***failures) override;
NS_IMETHOD_(void) LogFailure(const nsACString &failure) override; NS_IMETHOD_(void) LogFailure(const nsACString &failure) override;
NS_IMETHOD GetInfo(JSContext*, JS::MutableHandle<JS::Value>) override; NS_IMETHOD GetInfo(JSContext*, JS::MutableHandle<JS::Value>) override;
NS_IMETHOD GetFeatures(JSContext*, JS::MutableHandle<JS::Value>) override;
// Initialization function. If you override this, you must call this class's // Initialization function. If you override this, you must call this class's
// version of Init first. // version of Init first.
@ -103,6 +105,14 @@ protected:
// (while subclasses check for more specific ones). // (while subclasses check for more specific ones).
virtual const nsTArray<GfxDriverInfo>& GetGfxDriverInfo() = 0; virtual const nsTArray<GfxDriverInfo>& GetGfxDriverInfo() = 0;
virtual void DescribeFeatures(JSContext* aCx, JS::Handle<JSObject*> obj);
bool InitFeatureObject(
JSContext* aCx,
JS::Handle<JSObject*> aContainer,
const char* aName,
mozilla::gfx::FeatureStatus aFeatureStatus,
JS::MutableHandle<JSObject*> aOutObj);
private: private:
virtual int32_t FindBlocklistedDeviceInList(const nsTArray<GfxDriverInfo>& aDriverInfo, virtual int32_t FindBlocklistedDeviceInList(const nsTArray<GfxDriverInfo>& aDriverInfo,
nsAString& aSuggestedVersion, nsAString& aSuggestedVersion,

View File

@ -1131,6 +1131,8 @@ void nsBaseWidget::CreateCompositor(int aWidth, int aHeight)
WindowUsesOMTC(); WindowUsesOMTC();
mLayerManager = lm.forget(); mLayerManager = lm.forget();
gfxPlatform::GetPlatform()->NotifyCompositorCreated(mLayerManager->GetCompositorBackendType());
} }
bool nsBaseWidget::ShouldUseOffMainThreadCompositing() bool nsBaseWidget::ShouldUseOffMainThreadCompositing()

View File

@ -8,7 +8,7 @@
/* NOTE: this interface is completely undesigned, not stable and likely to change */ /* NOTE: this interface is completely undesigned, not stable and likely to change */
[scriptable, uuid(47eedfa0-f7cb-445b-b5cf-a2ca83600560)] [scriptable, uuid(98690931-c9a5-4675-9ab4-90932ec32bf2)]
interface nsIGfxInfo : nsISupports interface nsIGfxInfo : nsISupports
{ {
/* /*
@ -147,5 +147,31 @@ interface nsIGfxInfo : nsISupports
[implicit_jscontext] [implicit_jscontext]
jsval getInfo(); jsval getInfo();
// Returns an object containing information about graphics features. It is
// intended to be directly included into the Telemetry environment.
//
// "layers":
// {
// "compositor": "d3d9", "d3d11", "opengl", "basic", or "none"
// // ("none" indicates no compositors have been created)
// // Feature is one of "d3d9", "d3d11", "opengl", "basic", or "d2d".
// "<feature>": {
// // Each backend can have one of the following statuses:
// // "unused" - This feature has not been requested.
// // "unavailable" - OS version or restriction prevents use.
// // "blocked" - An internal condition (such as safe mode) prevents use.
// // "blacklisted" - Blocked due to a blacklist restriction.
// // "disabled" - User explicitly disabled this default feature.
// // "failed" - Feature failed to initialize.
// // "available" - User has this feature available by default.
// "status": "<status>",
// "version": "<version>",
// "warp": true|false, // D3D11 only.
// "textureSharing": true|false, // D3D11 only.
// }
// }
[implicit_jscontext]
jsval getFeatures();
}; };

View File

@ -1255,6 +1255,42 @@ GfxInfo::FindMonitors(JSContext* aCx, JS::HandleObject aOutArray)
return NS_OK; return NS_OK;
} }
void
GfxInfo::DescribeFeatures(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
JS::Rooted<JSObject*> obj(aCx);
gfxWindowsPlatform* platform = gfxWindowsPlatform::GetPlatform();
gfx::FeatureStatus d3d11 = platform->GetD3D11Status();
if (!InitFeatureObject(aCx, aObj, "d3d11", d3d11, &obj)) {
return;
}
if (d3d11 == gfx::FeatureStatus::Available) {
JS::Rooted<JS::Value> val(aCx, JS::Int32Value(platform->GetD3D11Version()));
JS_SetProperty(aCx, obj, "version", val);
val = JS::BooleanValue(platform->IsWARP());
JS_SetProperty(aCx, obj, "warp", val);
val = JS::BooleanValue(platform->DoesD3D11TextureSharingWork());
JS_SetProperty(aCx, obj, "textureSharing", val);
}
gfx::FeatureStatus d2d = platform->GetD2DStatus();
if (!InitFeatureObject(aCx, aObj, "d2d", d2d, &obj)) {
return;
}
{
const char* version = "1.0";
if (platform->GetD2D1Status() == gfx::FeatureStatus::Available)
version = "1.1";
JS::Rooted<JSString*> str(aCx, JS_NewStringCopyZ(aCx, version));
JS::Rooted<JS::Value> val(aCx, JS::StringValue(str));
JS_SetProperty(aCx, obj, "version", val);
}
}
#ifdef DEBUG #ifdef DEBUG
// Implement nsIGfxInfoDebug // Implement nsIGfxInfoDebug

View File

@ -68,6 +68,8 @@ protected:
OperatingSystem* aOS = nullptr); OperatingSystem* aOS = nullptr);
virtual const nsTArray<GfxDriverInfo>& GetGfxDriverInfo(); virtual const nsTArray<GfxDriverInfo>& GetGfxDriverInfo();
void DescribeFeatures(JSContext* cx, JS::Handle<JSObject*> aOut) override;
private: private:
void AddCrashReportAnnotations(); void AddCrashReportAnnotations();