Introduce gfxVars for sharing graphics variables across processes. (bug 1288259 part 2, r=jrmuizel,billm)

--HG--
extra : rebase_source : cbac742f7165a2fbdec3e4d1179c9ed49324579f
This commit is contained in:
David Anderson 2016-08-04 11:33:42 -07:00
Родитель 7bdb79f9ac
Коммит 9e49bc37bb
17 изменённых файлов: 397 добавлений и 7 удалений

Просмотреть файл

@ -35,6 +35,7 @@
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/workers/ServiceWorkerManager.h"
#include "mozilla/dom/nsIContentChild.h"
#include "mozilla/gfx/gfxVars.h"
#include "mozilla/psm/PSMContentListener.h"
#include "mozilla/hal_sandbox/PHalChild.h"
#include "mozilla/ipc/BackgroundChild.h"
@ -2275,6 +2276,13 @@ ContentChild::RecvPreferenceUpdate(const PrefSetting& aPref)
return true;
}
bool
ContentChild::RecvVarUpdate(const GfxVarUpdate& aVar)
{
gfx::gfxVars::ApplyUpdate(aVar);
return true;
}
bool
ContentChild::RecvDataStoragePut(const nsString& aFilename,
const DataStorageItem& aItem)

Просмотреть файл

@ -409,6 +409,7 @@ public:
const uint32_t& aMemoryAvailable) override;
virtual bool RecvPreferenceUpdate(const PrefSetting& aPref) override;
virtual bool RecvVarUpdate(const GfxVarUpdate& pref) override;
virtual bool RecvDataStoragePut(const nsString& aFilename,
const DataStorageItem& aItem) override;

Просмотреть файл

@ -74,6 +74,7 @@
#include "mozilla/dom/time/DateCacheCleaner.h"
#include "mozilla/dom/voicemail/VoicemailParent.h"
#include "mozilla/embedding/printingui/PrintingParent.h"
#include "mozilla/gfx/gfxVars.h"
#include "mozilla/gfx/GPUProcessManager.h"
#include "mozilla/hal_sandbox/PHalParent.h"
#include "mozilla/ipc/BackgroundChild.h"
@ -1850,6 +1851,7 @@ ContentParent::ActorDestroy(ActorDestroyReason why)
// remove the global remote preferences observers
Preferences::RemoveObserver(this, "");
gfxVars::RemoveReceiver(this);
RecvRemoveGeolocationListener();
@ -2398,6 +2400,29 @@ ContentParent::RecvReadPrefsArray(InfallibleTArray<PrefSetting>* aPrefs)
return true;
}
bool
ContentParent::RecvGetGfxVars(InfallibleTArray<GfxVarUpdate>* aVars)
{
// Ensure gfxVars is initialized (for xpcshell tests).
gfxVars::Initialize();
*aVars = gfxVars::FetchNonDefaultVars();
// Now that content has initialized gfxVars, we can start listening for
// updates.
gfxVars::AddReceiver(this);
return true;
}
void
ContentParent::OnVarChanged(const GfxVarUpdate& aVar)
{
if (!mIPCOpen) {
return;
}
Unused << SendVarUpdate(aVar);
}
bool
ContentParent::RecvReadFontList(InfallibleTArray<FontListEntry>* retValue)
{

Просмотреть файл

@ -9,6 +9,7 @@
#include "mozilla/dom/PContentParent.h"
#include "mozilla/dom/nsIContentParent.h"
#include "mozilla/gfx/gfxVarReceiver.h"
#include "mozilla/ipc/GeckoChildProcessHost.h"
#include "mozilla/Attributes.h"
#include "mozilla/FileUtils.h"
@ -89,6 +90,7 @@ class ContentParent final : public PContentParent
, public nsIObserver
, public nsIDOMGeoPositionCallback
, public nsIDOMGeoPositionErrorCallback
, public gfx::gfxVarReceiver
, public mozilla::LinkedListElement<ContentParent>
{
typedef mozilla::ipc::GeckoChildProcessHost GeckoChildProcessHost;
@ -568,6 +570,8 @@ protected:
bool ShouldContinueFromReplyTimeout() override;
void OnVarChanged(const GfxVarUpdate& aVar) override;
private:
static nsDataHashtable<nsStringHashKey, ContentParent*> *sAppContentParents;
static nsTArray<ContentParent*>* sNonAppContentParents;
@ -908,6 +912,7 @@ private:
DeallocPWebBrowserPersistDocumentParent(PWebBrowserPersistDocumentParent* aActor) override;
virtual bool RecvReadPrefsArray(InfallibleTArray<PrefSetting>* aPrefs) override;
virtual bool RecvGetGfxVars(InfallibleTArray<GfxVarUpdate>* aVars) override;
virtual bool RecvReadFontList(InfallibleTArray<FontListEntry>* retValue) override;

Просмотреть файл

@ -519,6 +519,7 @@ child:
async SystemMemoryAvailable(uint64_t getterId, uint32_t memoryAvailable);
async PreferenceUpdate(PrefSetting pref);
async VarUpdate(GfxVarUpdate var);
async DataStoragePut(nsString aFilename, DataStorageItem aItem);
async DataStorageRemove(nsString aFilename, nsCString aKey, DataStorageType aType);
@ -880,6 +881,7 @@ parent:
// PrefService message
sync ReadPrefsArray() returns (PrefSetting[] prefs) verify;
sync GetGfxVars() returns (GfxVarUpdate[] vars);
sync ReadFontList() returns (FontListEntry[] retValue);

Просмотреть файл

@ -0,0 +1,25 @@
/* -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set sts=2 ts=8 sw=2 tw=99 et: */
/* 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 mozilla_gfx_config_gfxVarReceiver_h
#define mozilla_gfx_config_gfxVarReceiver_h
namespace mozilla {
namespace gfx {
class GfxVarUpdate;
// This allows downstream processes (such as PContent, PGPU) to listen for
// updates on gfxVarReceiver.
class gfxVarReceiver
{
public:
virtual void OnVarChanged(const GfxVarUpdate& aVar) = 0;
};
} // namespace gfx
} // namespace mozilla
#endif // mozilla_gfx_config_gfxVarReceiver_h

125
gfx/config/gfxVars.cpp Normal file
Просмотреть файл

@ -0,0 +1,125 @@
/* -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set sts=2 ts=8 sw=2 tw=99 et: */
/* 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 "gfxVars.h"
#include "gfxVarReceiver.h"
#include "mozilla/dom/ContentChild.h"
namespace mozilla {
namespace gfx {
StaticAutoPtr<gfxVars> gfxVars::sInstance;
StaticAutoPtr<nsTArray<gfxVars::VarBase*>> gfxVars::sVarList;
void
gfxVars::Initialize()
{
if (sInstance) {
return;
}
// sVarList must be initialized first since it's used in the constructor for
// sInstance.
sVarList = new nsTArray<gfxVars::VarBase*>();
sInstance = new gfxVars;
// Like Preferences, we want content to synchronously get initial data on
// init. Note the GPU process is not handled here - it cannot send sync
// messages, so instead the initial data is pushed down.
if (XRE_IsContentProcess()) {
InfallibleTArray<GfxVarUpdate> vars;
dom::ContentChild::GetSingleton()->SendGetGfxVars(&vars);
for (const auto& var : vars) {
ApplyUpdate(var);
}
}
}
gfxVars::gfxVars()
{
}
void
gfxVars::Shutdown()
{
sInstance = nullptr;
sVarList = nullptr;
}
/* static */ void
gfxVars::ApplyUpdate(const GfxVarUpdate& aUpdate)
{
// Only subprocesses receive updates and apply them locally.
MOZ_ASSERT(!XRE_IsParentProcess());
sVarList->ElementAt(aUpdate.index())->SetValue(aUpdate.value());
}
/* static */ void
gfxVars::AddReceiver(gfxVarReceiver* aReceiver)
{
MOZ_ASSERT(NS_IsMainThread());
// Don't double-add receivers, in case a broken content process sends two
// init messages.
if (!sInstance->mReceivers.Contains(aReceiver)) {
sInstance->mReceivers.AppendElement(aReceiver);
}
}
/* static */ void
gfxVars::RemoveReceiver(gfxVarReceiver* aReceiver)
{
MOZ_ASSERT(NS_IsMainThread());
if (sInstance) {
sInstance->mReceivers.RemoveElement(aReceiver);
}
}
/* static */ nsTArray<GfxVarUpdate>
gfxVars::FetchNonDefaultVars()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(sVarList);
nsTArray<GfxVarUpdate> updates;
for (size_t i = 0; i < sVarList->Length(); i++) {
VarBase* var = sVarList->ElementAt(i);
if (var->HasDefaultValue()) {
continue;
}
GfxVarValue value;
var->GetValue(&value);
updates.AppendElement(GfxVarUpdate(i, value));
}
return updates;
}
gfxVars::VarBase::VarBase()
{
mIndex = gfxVars::sVarList->Length();
gfxVars::sVarList->AppendElement(this);
}
void
gfxVars::NotifyReceivers(VarBase* aVar)
{
MOZ_ASSERT(NS_IsMainThread());
GfxVarValue value;
aVar->GetValue(&value);
GfxVarUpdate update(aVar->Index(), value);
for (auto& receiver : mReceivers) {
receiver->OnVarChanged(update);
}
}
} // namespace gfx
} // namespace mozilla

139
gfx/config/gfxVars.h Normal file
Просмотреть файл

@ -0,0 +1,139 @@
/* -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set sts=2 ts=8 sw=2 tw=99 et: */
/* 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 mozilla_gfx_config_gfxVars_h
#define mozilla_gfx_config_gfxVars_h
#include <stdint.h>
#include "mozilla/Assertions.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/gfx/GraphicsMessages.h"
#include "mozilla/gfx/Point.h"
#include "mozilla/gfx/Types.h"
#include "nsTArray.h"
#include "nsXULAppAPI.h"
namespace mozilla {
namespace gfx {
class gfxVarReceiver;
// Generator for graphics vars.
#define GFX_VARS_LIST(_) \
/* C++ Name, Data Type, Default Value */ \
/* Add new entries above this line. */
// Some graphics settings are computed on the UI process and must be
// communicated to content and GPU processes. gfxVars helps facilitate
// this. Its function is similar to gfxPrefs, except rather than hold
// user preferences, it holds dynamically computed values.
//
// Each variable in GFX_VARS_LIST exposes the following static methods:
//
// const DataType& CxxName();
// void SetCxxName(const DataType& aValue);
//
// Note that the setter may only be called in the UI process; a gfxVar must be
// a variable that is determined in the UI process and pushed to child
// processes.
class gfxVars final
{
public:
static void Initialize();
static void Shutdown();
static void ApplyUpdate(const GfxVarUpdate& aUpdate);
static void AddReceiver(gfxVarReceiver* aReceiver);
static void RemoveReceiver(gfxVarReceiver* aReceiver);
// Return a list of updates for all variables with non-default values.
static nsTArray<GfxVarUpdate> FetchNonDefaultVars();
public:
// Each variable must expose Set and Get methods for IPDL.
class VarBase
{
public:
VarBase();
virtual void SetValue(const GfxVarValue& aValue) = 0;
virtual void GetValue(GfxVarValue* aOutValue) = 0;
virtual bool HasDefaultValue() const = 0;
size_t Index() const {
return mIndex;
}
private:
size_t mIndex;
};
private:
static StaticAutoPtr<gfxVars> sInstance;
static StaticAutoPtr<nsTArray<VarBase*>> sVarList;
template <typename T, T Default()>
class VarImpl final : public VarBase
{
public:
VarImpl()
: mValue(Default())
{}
void SetValue(const GfxVarValue& aValue) override {
aValue.get(&mValue);
}
void GetValue(GfxVarValue* aOutValue) override {
*aOutValue = GfxVarValue(mValue);
}
bool HasDefaultValue() const override {
return mValue == Default();
}
const T& Get() const {
return mValue;
}
// Return true if the value changed, false otherwise.
bool Set(const T& aValue) {
MOZ_ASSERT(XRE_IsParentProcess());
if (mValue == aValue) {
return false;
}
mValue = aValue;
return true;
}
private:
T mValue;
};
#define GFX_VAR_DECL(CxxName, DataType, DefaultValue) \
private: \
static DataType Get##CxxName##Default() { \
return DefaultValue; \
} \
VarImpl<DataType, Get##CxxName##Default> mVar##CxxName; \
public: \
static const DataType& CxxName() { \
return sInstance->mVar##CxxName.Get(); \
} \
static void Set##CxxName(const DataType& aValue) { \
if (sInstance->mVar##CxxName.Set(aValue)) { \
sInstance->NotifyReceivers(&sInstance->mVar##CxxName); \
} \
}
GFX_VARS_LIST(GFX_VAR_DECL)
#undef GFX_VAR_DECL
private:
gfxVars();
void NotifyReceivers(VarBase* aVar);
private:
nsTArray<gfxVarReceiver*> mReceivers;
};
#undef GFX_VARS_LIST
} // namespace gfx
} // namespace mozilla
#endif // mozilla_gfx_config_gfxVars_h

Просмотреть файл

@ -10,9 +10,17 @@ EXPORTS += [
'gfxFeature.h',
]
EXPORTS.mozilla.gfx += [
'gfxVarReceiver.h',
'gfxVars.h',
]
UNIFIED_SOURCES += [
'gfxConfig.cpp',
'gfxFeature.cpp',
'gfxVars.cpp',
]
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul'

Просмотреть файл

@ -6,6 +6,7 @@
#include "GPUChild.h"
#include "gfxPrefs.h"
#include "GPUProcessHost.h"
#include "mozilla/gfx/gfxVars.h"
namespace mozilla {
namespace gfx {
@ -40,12 +41,22 @@ GPUChild::Init()
prefs.AppendElement(GfxPrefSetting(pref->Index(), value));
}
SendInit(prefs);
nsTArray<GfxVarUpdate> updates = gfxVars::FetchNonDefaultVars();
SendInit(prefs, updates);
gfxVars::AddReceiver(this);
}
void
GPUChild::OnVarChanged(const GfxVarUpdate& aVar)
{
SendUpdateVar(aVar);
}
void
GPUChild::ActorDestroy(ActorDestroyReason aWhy)
{
gfxVars::RemoveReceiver(this);
mHost->OnChannelClosed();
}

Просмотреть файл

@ -9,13 +9,16 @@
#include "mozilla/RefPtr.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/gfx/PGPUChild.h"
#include "mozilla/gfx/gfxVarReceiver.h"
namespace mozilla {
namespace gfx {
class GPUProcessHost;
class GPUChild final : public PGPUChild
class GPUChild final
: public PGPUChild,
public gfxVarReceiver
{
public:
explicit GPUChild(GPUProcessHost* aHost);
@ -23,10 +26,14 @@ public:
void Init();
static void Destroy(UniquePtr<GPUChild>&& aChild);
// gfxVarReceiver overrides.
void OnVarChanged(const GfxVarUpdate& aVar) override;
// PGPUChild overrides.
void ActorDestroy(ActorDestroyReason aWhy) override;
static void Destroy(UniquePtr<GPUChild>&& aChild);
private:
GPUProcessHost* mHost;
};

Просмотреть файл

@ -9,6 +9,7 @@
#include "gfxPrefs.h"
#include "GPUProcessHost.h"
#include "mozilla/Assertions.h"
#include "mozilla/gfx/gfxVars.h"
#include "mozilla/ipc/ProcessChild.h"
#include "mozilla/layers/CompositorBridgeParent.h"
#include "mozilla/layers/CompositorThread.h"
@ -42,6 +43,7 @@ GPUParent::Init(base::ProcessId aParentPid,
// Ensure gfxPrefs are initialized.
gfxPrefs::GetSingleton();
gfxVars::Initialize();
CompositorThreadHolder::Start();
VRManager::ManagerInit();
gfxPlatform::InitNullMetadata();
@ -49,13 +51,17 @@ GPUParent::Init(base::ProcessId aParentPid,
}
bool
GPUParent::RecvInit(nsTArray<GfxPrefSetting>&& prefs)
GPUParent::RecvInit(nsTArray<GfxPrefSetting>&& prefs,
nsTArray<GfxVarUpdate>&& vars)
{
const nsTArray<gfxPrefs::Pref*>& globalPrefs = gfxPrefs::all();
for (auto& setting : prefs) {
gfxPrefs::Pref* pref = globalPrefs[setting.index()];
pref->SetCachedValue(setting.value());
}
for (const auto& var : vars) {
gfxVars::ApplyUpdate(var);
}
return true;
}
@ -88,6 +94,13 @@ GPUParent::RecvUpdatePref(const GfxPrefSetting& setting)
return true;
}
bool
GPUParent::RecvUpdateVar(const GfxVarUpdate& aUpdate)
{
gfxVars::ApplyUpdate(aUpdate);
return true;
}
static void
OpenParent(RefPtr<CompositorBridgeParent> aParent,
Endpoint<PCompositorBridgeParent>&& aEndpoint)

Просмотреть файл

@ -24,11 +24,13 @@ public:
MessageLoop* aIOLoop,
IPC::Channel* aChannel);
bool RecvInit(nsTArray<GfxPrefSetting>&& prefs) override;
bool RecvInit(nsTArray<GfxPrefSetting>&& prefs,
nsTArray<GfxVarUpdate>&& vars) override;
bool RecvInitVsyncBridge(Endpoint<PVsyncBridgeParent>&& aVsyncEndpoint) override;
bool RecvInitImageBridge(Endpoint<PImageBridgeParent>&& aEndpoint) override;
bool RecvInitVRManager(Endpoint<PVRManagerParent>&& aEndpoint) override;
bool RecvUpdatePref(const GfxPrefSetting& pref) override;
bool RecvUpdateVar(const GfxVarUpdate& pref) override;
bool RecvNewWidgetCompositor(
Endpoint<PCompositorBridgeParent>&& aEndpoint,
const CSSToLayoutDeviceScale& aScale,

Просмотреть файл

@ -6,6 +6,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
using struct DxgiAdapterDesc from "mozilla/D3DMessageUtils.h";
using struct mozilla::null_t from "ipc/IPCMessageUtils.h";
namespace mozilla {
namespace gfx {
@ -22,5 +23,16 @@ struct DeviceInitData
DxgiAdapterDesc adapter;
};
union GfxVarValue
{
null_t;
};
struct GfxVarUpdate
{
size_t index;
GfxVarValue value;
};
} // namespace gfx
} // namespace mozilla

Просмотреть файл

@ -3,6 +3,7 @@
* 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 GraphicsMessages;
include protocol PCompositorBridge;
include protocol PImageBridge;
include protocol PVRManager;
@ -31,14 +32,15 @@ sync protocol PGPU
{
parent:
// Sent by the UI process to initiate core settings.
async Init(GfxPrefSetting[] prefs);
async Init(GfxPrefSetting[] prefs, GfxVarUpdate[] vars);
async InitVsyncBridge(Endpoint<PVsyncBridgeParent> endpoint);
async InitImageBridge(Endpoint<PImageBridgeParent> endpoint);
async InitVRManager(Endpoint<PVRManagerParent> endpoint);
// Called to update a gfx preference.
// Called to update a gfx preference or variable.
async UpdatePref(GfxPrefSetting pref);
async UpdateVar(GfxVarUpdate var);
// Create a new top-level compositor.
async NewWidgetCompositor(Endpoint<PCompositorBridgeParent> endpoint,

Просмотреть файл

@ -8,6 +8,7 @@
#include "mozilla/layers/ImageBridgeChild.h"
#include "mozilla/layers/SharedBufferManagerChild.h"
#include "mozilla/layers/ISurfaceAllocator.h" // for GfxMemoryImageReporter
#include "mozilla/gfx/gfxVars.h"
#include "mozilla/gfx/GPUProcessManager.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/Telemetry.h"
@ -593,6 +594,7 @@ gfxPlatform::Init()
// Initialize the preferences by creating the singleton.
gfxPrefs::GetSingleton();
MediaPrefs::GetSingleton();
gfxVars::Initialize();
gfxConfig::Init();
@ -872,6 +874,7 @@ gfxPlatform::Shutdown()
delete gGfxPlatformPrefsLock;
gfxVars::Shutdown();
gfxPrefs::DestroySingleton();
gfxFont::DestroySingletons();

Просмотреть файл

@ -51,6 +51,7 @@
#include "ThirdPartyUtil.h"
#include "nsStructuredCloneContainer.h"
#include "gfxPlatform.h"
#include "mozilla/gfx/gfxVars.h"
#include "nsIEventListenerService.h"
#include "nsIMessageManager.h"
@ -1373,6 +1374,7 @@ LayoutModuleDtor()
// these modules are shut down after all the layout cleanup runs.
mozilla::image::ShutdownModule();
gfxPlatform::Shutdown();
gfx::gfxVars::Shutdown();
nsScriptSecurityManager::Shutdown();
xpcModuleDtor();