2017-10-28 01:55:37 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
2017-10-28 02:10:06 +03:00
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
2016-04-29 07:52:54 +03:00
|
|
|
/* 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 "gfxConfig.h"
|
2016-06-03 21:54:56 +03:00
|
|
|
#include "mozilla/UniquePtr.h"
|
2017-07-11 10:13:26 +03:00
|
|
|
#include "mozilla/Unused.h"
|
|
|
|
#include "mozilla/gfx/GPUParent.h"
|
2016-08-21 06:59:11 +03:00
|
|
|
#include "mozilla/gfx/GraphicsMessages.h"
|
2016-04-29 07:52:56 +03:00
|
|
|
#include "plstr.h"
|
2016-04-29 07:52:54 +03:00
|
|
|
|
|
|
|
namespace mozilla {
|
|
|
|
namespace gfx {
|
|
|
|
|
2016-06-03 21:54:56 +03:00
|
|
|
static UniquePtr<gfxConfig> sConfig;
|
2016-04-29 07:52:54 +03:00
|
|
|
|
2016-04-29 07:52:55 +03:00
|
|
|
/* static */ FeatureState& gfxConfig::GetFeature(Feature aFeature) {
|
2016-06-03 21:54:56 +03:00
|
|
|
return sConfig->GetState(aFeature);
|
2016-04-29 07:52:54 +03:00
|
|
|
}
|
|
|
|
|
2019-02-26 01:07:19 +03:00
|
|
|
/* static */
|
|
|
|
bool gfxConfig::IsEnabled(Feature aFeature) {
|
2016-06-03 21:54:56 +03:00
|
|
|
const FeatureState& state = sConfig->GetState(aFeature);
|
2016-04-29 07:52:55 +03:00
|
|
|
return state.IsEnabled();
|
2016-04-29 07:52:54 +03:00
|
|
|
}
|
|
|
|
|
2019-02-26 01:07:19 +03:00
|
|
|
/* static */
|
|
|
|
bool gfxConfig::IsDisabledByDefault(Feature aFeature) {
|
2016-06-03 21:54:56 +03:00
|
|
|
const FeatureState& state = sConfig->GetState(aFeature);
|
2016-04-29 07:52:54 +03:00
|
|
|
return state.DisabledByDefault();
|
|
|
|
}
|
|
|
|
|
2019-02-26 01:07:19 +03:00
|
|
|
/* static */
|
|
|
|
bool gfxConfig::IsForcedOnByUser(Feature aFeature) {
|
2016-06-03 21:54:56 +03:00
|
|
|
const FeatureState& state = sConfig->GetState(aFeature);
|
2016-04-29 07:52:54 +03:00
|
|
|
return state.IsForcedOnByUser();
|
|
|
|
}
|
|
|
|
|
2019-02-26 01:07:19 +03:00
|
|
|
/* static */
|
|
|
|
FeatureStatus gfxConfig::GetValue(Feature aFeature) {
|
2016-06-03 21:54:56 +03:00
|
|
|
const FeatureState& state = sConfig->GetState(aFeature);
|
2016-04-29 07:52:54 +03:00
|
|
|
return state.GetValue();
|
|
|
|
}
|
|
|
|
|
2019-02-26 01:07:19 +03:00
|
|
|
/* static */
|
|
|
|
bool gfxConfig::SetDefault(Feature aFeature, bool aEnable,
|
|
|
|
FeatureStatus aDisableStatus,
|
|
|
|
const char* aDisableMessage) {
|
2016-06-03 21:54:56 +03:00
|
|
|
FeatureState& state = sConfig->GetState(aFeature);
|
2016-04-29 07:52:55 +03:00
|
|
|
return state.SetDefault(aEnable, aDisableStatus, aDisableMessage);
|
|
|
|
}
|
|
|
|
|
2019-02-26 01:07:19 +03:00
|
|
|
/* static */
|
|
|
|
void gfxConfig::DisableByDefault(Feature aFeature, FeatureStatus aDisableStatus,
|
|
|
|
const char* aDisableMessage,
|
|
|
|
const nsACString& aFailureId) {
|
2016-06-03 21:54:56 +03:00
|
|
|
FeatureState& state = sConfig->GetState(aFeature);
|
|
|
|
state.DisableByDefault(aDisableStatus, aDisableMessage, aFailureId);
|
2016-04-29 07:52:55 +03:00
|
|
|
}
|
|
|
|
|
2019-02-26 01:07:19 +03:00
|
|
|
/* static */
|
|
|
|
void gfxConfig::EnableByDefault(Feature aFeature) {
|
2016-06-03 21:54:56 +03:00
|
|
|
FeatureState& state = sConfig->GetState(aFeature);
|
2016-04-29 07:52:54 +03:00
|
|
|
state.EnableByDefault();
|
|
|
|
}
|
|
|
|
|
2019-02-26 01:07:19 +03:00
|
|
|
/* static */
|
|
|
|
void gfxConfig::SetDefaultFromPref(Feature aFeature, const char* aPrefName,
|
|
|
|
bool aIsEnablePref, bool aDefaultValue) {
|
2016-06-03 21:54:56 +03:00
|
|
|
FeatureState& state = sConfig->GetState(aFeature);
|
2016-04-29 07:52:56 +03:00
|
|
|
return state.SetDefaultFromPref(aPrefName, aIsEnablePref, aDefaultValue);
|
|
|
|
}
|
|
|
|
|
2019-02-26 01:07:19 +03:00
|
|
|
/* static */
|
|
|
|
bool gfxConfig::InitOrUpdate(Feature aFeature, bool aEnable,
|
|
|
|
FeatureStatus aDisableStatus,
|
|
|
|
const char* aDisableMessage) {
|
2016-06-03 21:54:56 +03:00
|
|
|
FeatureState& state = sConfig->GetState(aFeature);
|
2016-04-29 07:52:55 +03:00
|
|
|
return state.InitOrUpdate(aEnable, aDisableStatus, aDisableMessage);
|
2016-04-29 07:52:55 +03:00
|
|
|
}
|
|
|
|
|
2019-02-26 01:07:19 +03:00
|
|
|
/* static */
|
|
|
|
void gfxConfig::SetFailed(Feature aFeature, FeatureStatus aStatus,
|
|
|
|
const char* aMessage, const nsACString& aFailureId) {
|
2016-06-03 21:54:56 +03:00
|
|
|
FeatureState& state = sConfig->GetState(aFeature);
|
|
|
|
state.SetFailed(aStatus, aMessage, aFailureId);
|
2016-04-29 07:52:54 +03:00
|
|
|
}
|
|
|
|
|
2019-02-26 01:07:19 +03:00
|
|
|
/* static */
|
|
|
|
void gfxConfig::Disable(Feature aFeature, FeatureStatus aStatus,
|
|
|
|
const char* aMessage, const nsACString& aFailureId) {
|
2016-06-03 21:54:56 +03:00
|
|
|
FeatureState& state = sConfig->GetState(aFeature);
|
|
|
|
state.Disable(aStatus, aMessage, aFailureId);
|
2016-04-29 07:52:55 +03:00
|
|
|
}
|
|
|
|
|
2019-02-26 01:07:19 +03:00
|
|
|
/* static */
|
|
|
|
void gfxConfig::UserEnable(Feature aFeature, const char* aMessage) {
|
2016-06-03 21:54:56 +03:00
|
|
|
FeatureState& state = sConfig->GetState(aFeature);
|
2016-04-29 07:52:55 +03:00
|
|
|
state.UserEnable(aMessage);
|
2016-04-29 07:52:54 +03:00
|
|
|
}
|
2016-04-29 07:52:55 +03:00
|
|
|
|
2019-02-26 01:07:19 +03:00
|
|
|
/* static */
|
|
|
|
void gfxConfig::UserForceEnable(Feature aFeature, const char* aMessage) {
|
2016-06-03 21:54:56 +03:00
|
|
|
FeatureState& state = sConfig->GetState(aFeature);
|
2016-04-29 07:52:55 +03:00
|
|
|
state.UserForceEnable(aMessage);
|
2016-04-29 07:52:54 +03:00
|
|
|
}
|
|
|
|
|
2019-02-26 01:07:19 +03:00
|
|
|
/* static */
|
|
|
|
void gfxConfig::UserDisable(Feature aFeature, const char* aMessage,
|
|
|
|
const nsACString& aFailureId) {
|
2016-06-03 21:54:56 +03:00
|
|
|
FeatureState& state = sConfig->GetState(aFeature);
|
|
|
|
state.UserDisable(aMessage, aFailureId);
|
2016-04-29 07:52:54 +03:00
|
|
|
}
|
|
|
|
|
2019-02-26 01:07:19 +03:00
|
|
|
/* static */
|
|
|
|
void gfxConfig::Reenable(Feature aFeature, Fallback aFallback) {
|
2016-06-03 21:54:56 +03:00
|
|
|
FeatureState& state = sConfig->GetState(aFeature);
|
2016-04-29 07:52:55 +03:00
|
|
|
MOZ_ASSERT(IsFeatureStatusFailure(state.GetValue()));
|
|
|
|
|
|
|
|
const char* message = state.GetRuntimeMessage();
|
|
|
|
EnableFallback(aFallback, message);
|
2020-09-25 17:11:52 +03:00
|
|
|
state.SetRuntime(FeatureStatus::Available, nullptr, nsCString());
|
2016-04-29 07:52:55 +03:00
|
|
|
}
|
|
|
|
|
2019-02-26 01:07:19 +03:00
|
|
|
/* static */
|
|
|
|
void gfxConfig::Reset(Feature aFeature) {
|
2017-07-11 05:30:58 +03:00
|
|
|
FeatureState& state = sConfig->GetState(aFeature);
|
|
|
|
state.Reset();
|
|
|
|
}
|
|
|
|
|
2019-02-26 01:07:19 +03:00
|
|
|
/* static */
|
|
|
|
void gfxConfig::Inherit(Feature aFeature, FeatureStatus aStatus) {
|
2016-08-21 06:59:10 +03:00
|
|
|
FeatureState& state = sConfig->GetState(aFeature);
|
|
|
|
|
2016-08-21 06:59:11 +03:00
|
|
|
state.Reset();
|
|
|
|
|
2016-08-21 06:59:10 +03:00
|
|
|
switch (aStatus) {
|
|
|
|
case FeatureStatus::Unused:
|
|
|
|
break;
|
|
|
|
case FeatureStatus::Available:
|
|
|
|
gfxConfig::EnableByDefault(aFeature);
|
|
|
|
break;
|
|
|
|
case FeatureStatus::ForceEnabled:
|
|
|
|
gfxConfig::EnableByDefault(aFeature);
|
|
|
|
gfxConfig::UserForceEnable(aFeature, "Inherited from parent process");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
gfxConfig::SetDefault(aFeature, false, aStatus,
|
|
|
|
"Disabled in parent process");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-21 02:26:52 +03:00
|
|
|
/* static */
|
|
|
|
void gfxConfig::Inherit(EnumSet<Feature> aFeatures,
|
|
|
|
const DevicePrefs& aDevicePrefs) {
|
|
|
|
for (Feature feature : aFeatures) {
|
|
|
|
FeatureStatus status = FeatureStatus::Unused;
|
|
|
|
switch (feature) {
|
|
|
|
case Feature::HW_COMPOSITING:
|
|
|
|
status = aDevicePrefs.hwCompositing();
|
|
|
|
break;
|
|
|
|
case Feature::D3D11_COMPOSITING:
|
|
|
|
status = aDevicePrefs.d3d11Compositing();
|
|
|
|
break;
|
|
|
|
case Feature::OPENGL_COMPOSITING:
|
|
|
|
status = aDevicePrefs.oglCompositing();
|
|
|
|
break;
|
|
|
|
case Feature::DIRECT2D:
|
|
|
|
status = aDevicePrefs.useD2D1();
|
|
|
|
break;
|
|
|
|
case Feature::WEBGPU:
|
|
|
|
status = aDevicePrefs.webGPU();
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
gfxConfig::Inherit(feature, status);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-26 01:07:19 +03:00
|
|
|
/* static */
|
|
|
|
bool gfxConfig::UseFallback(Fallback aFallback) {
|
2016-06-03 21:54:56 +03:00
|
|
|
return sConfig->UseFallbackImpl(aFallback);
|
2016-04-29 07:52:54 +03:00
|
|
|
}
|
|
|
|
|
2019-02-26 01:07:19 +03:00
|
|
|
/* static */
|
|
|
|
void gfxConfig::EnableFallback(Fallback aFallback, const char* aMessage) {
|
2017-07-11 10:13:26 +03:00
|
|
|
if (!NS_IsMainThread()) {
|
|
|
|
nsCString message(aMessage);
|
|
|
|
NS_DispatchToMainThread(
|
|
|
|
NS_NewRunnableFunction("gfxConfig::EnableFallback", [=]() -> void {
|
|
|
|
gfxConfig::EnableFallback(aFallback, message.get());
|
|
|
|
}));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (XRE_IsGPUProcess()) {
|
|
|
|
nsCString message(aMessage);
|
|
|
|
Unused << GPUParent::GetSingleton()->SendUsedFallback(aFallback, message);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-06-03 21:54:56 +03:00
|
|
|
sConfig->EnableFallbackImpl(aFallback, aMessage);
|
2016-04-29 07:52:54 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
bool gfxConfig::UseFallbackImpl(Fallback aFallback) const {
|
|
|
|
return !!(mFallbackBits & (uint64_t(1) << uint64_t(aFallback)));
|
|
|
|
}
|
|
|
|
|
2016-04-29 07:52:56 +03:00
|
|
|
void gfxConfig::EnableFallbackImpl(Fallback aFallback, const char* aMessage) {
|
|
|
|
if (!UseFallbackImpl(aFallback)) {
|
|
|
|
MOZ_ASSERT(mNumFallbackLogEntries < kNumFallbacks);
|
|
|
|
|
|
|
|
FallbackLogEntry& entry = mFallbackLog[mNumFallbackLogEntries];
|
|
|
|
mNumFallbackLogEntries++;
|
|
|
|
|
|
|
|
entry.mFallback = aFallback;
|
|
|
|
PL_strncpyz(entry.mMessage, aMessage, sizeof(entry.mMessage));
|
|
|
|
}
|
2016-04-29 07:52:54 +03:00
|
|
|
mFallbackBits |= (uint64_t(1) << uint64_t(aFallback));
|
|
|
|
}
|
|
|
|
|
2016-04-29 07:52:56 +03:00
|
|
|
struct FeatureInfo {
|
|
|
|
const char* name;
|
|
|
|
const char* description;
|
|
|
|
};
|
|
|
|
static const FeatureInfo sFeatureInfo[] = {
|
|
|
|
#define FOR_EACH_FEATURE(name, type, desc) {#name, desc},
|
|
|
|
GFX_FEATURE_MAP(FOR_EACH_FEATURE)
|
|
|
|
#undef FOR_EACH_FEATURE
|
|
|
|
{nullptr, nullptr}};
|
|
|
|
|
2019-02-26 01:07:19 +03:00
|
|
|
/* static */
|
|
|
|
void gfxConfig::ForEachFeature(const FeatureIterCallback& aCallback) {
|
2016-04-29 07:52:56 +03:00
|
|
|
for (size_t i = 0; i < kNumFeatures; i++) {
|
|
|
|
FeatureState& state = GetFeature(static_cast<Feature>(i));
|
|
|
|
if (!state.IsInitialized()) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
aCallback(sFeatureInfo[i].name, sFeatureInfo[i].description, state);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char* sFallbackNames[] = {
|
|
|
|
#define FOR_EACH_FALLBACK(name) #name,
|
|
|
|
GFX_FALLBACK_MAP(FOR_EACH_FALLBACK)
|
|
|
|
#undef FOR_EACH_FALLBACK
|
|
|
|
nullptr};
|
|
|
|
|
2019-02-26 01:07:19 +03:00
|
|
|
/* static */
|
|
|
|
void gfxConfig::ForEachFallback(const FallbackIterCallback& aCallback) {
|
2016-06-03 21:54:56 +03:00
|
|
|
sConfig->ForEachFallbackImpl(aCallback);
|
2016-04-29 07:52:56 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void gfxConfig::ForEachFallbackImpl(const FallbackIterCallback& aCallback) {
|
|
|
|
for (size_t i = 0; i < mNumFallbackLogEntries; i++) {
|
|
|
|
const FallbackLogEntry& entry = mFallbackLog[i];
|
|
|
|
aCallback(sFallbackNames[size_t(entry.mFallback)], entry.mMessage);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-03 21:54:56 +03:00
|
|
|
/* static */ const nsCString& gfxConfig::GetFailureId(Feature aFeature) {
|
|
|
|
const FeatureState& state = sConfig->GetState(aFeature);
|
|
|
|
return state.GetFailureId();
|
|
|
|
}
|
|
|
|
|
2019-02-26 01:07:19 +03:00
|
|
|
/* static */
|
2019-03-29 00:13:53 +03:00
|
|
|
void gfxConfig::ImportChange(Feature aFeature,
|
|
|
|
const Maybe<FeatureFailure>& aChange) {
|
|
|
|
if (aChange.isNothing()) {
|
2016-08-21 06:59:11 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-03-29 00:13:53 +03:00
|
|
|
const FeatureFailure& failure = aChange.ref();
|
2016-08-21 06:59:11 +03:00
|
|
|
gfxConfig::SetFailed(aFeature, failure.status(), failure.message().get(),
|
|
|
|
failure.failureId());
|
|
|
|
}
|
|
|
|
|
2019-02-26 01:07:19 +03:00
|
|
|
/* static */
|
|
|
|
void gfxConfig::Init() { sConfig = mozilla::MakeUnique<gfxConfig>(); }
|
2016-06-03 21:54:56 +03:00
|
|
|
|
2019-02-26 01:07:19 +03:00
|
|
|
/* static */
|
|
|
|
void gfxConfig::Shutdown() { sConfig = nullptr; }
|
2016-06-03 21:54:56 +03:00
|
|
|
|
2016-04-29 07:52:54 +03:00
|
|
|
} // namespace gfx
|
|
|
|
} // namespace mozilla
|