mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 12:51:06 +00:00
Communicate GPU process device information across processes. (bug 1294988 part 5, r=mattwoodrow)
This commit is contained in:
parent
396d5d1191
commit
2e46480cbf
@ -5,6 +5,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#include "gfxConfig.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/gfx/GraphicsMessages.h"
|
||||
#include "plstr.h"
|
||||
|
||||
namespace mozilla {
|
||||
@ -250,13 +251,28 @@ gfxConfig::ForEachFallbackImpl(const FallbackIterCallback& aCallback)
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ const nsACString&
|
||||
/* static */ const nsCString&
|
||||
gfxConfig::GetFailureId(Feature aFeature)
|
||||
{
|
||||
const FeatureState& state = sConfig->GetState(aFeature);
|
||||
return state.GetFailureId();
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
gfxConfig::ImportChange(Feature aFeature, const FeatureChange& aChange)
|
||||
{
|
||||
if (aChange.type() == FeatureChange::Tnull_t) {
|
||||
return;
|
||||
}
|
||||
|
||||
const FeatureFailure& failure = aChange.get_FeatureFailure();
|
||||
gfxConfig::SetFailed(
|
||||
aFeature,
|
||||
failure.status(),
|
||||
failure.message().get(),
|
||||
failure.failureId());
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
gfxConfig::Init()
|
||||
{
|
||||
|
@ -14,6 +14,9 @@
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
// Defined in GraphicsMessages.ipdlh.
|
||||
class FeatureChange;
|
||||
|
||||
// Manages the history and state of a graphics feature. The flow of a feature
|
||||
// is:
|
||||
// - A default value, set by all.js, gfxPrefs, or gfxPlatform.
|
||||
@ -44,6 +47,9 @@ public:
|
||||
// IsDisabledByDefault returns whether or not the initial status of the
|
||||
// feature, before adding user prefs and runtime decisions, was disabled.
|
||||
static bool IsForcedOnByUser(Feature aFeature);
|
||||
|
||||
// This returns true if the feature was disabled by default, or was never
|
||||
// initialized to begin with.
|
||||
static bool IsDisabledByDefault(Feature aFeature);
|
||||
|
||||
// Query the status value of a parameter. This is computed similar to
|
||||
@ -173,7 +179,9 @@ public:
|
||||
static void ForEachFallback(const FallbackIterCallback& aCallback);
|
||||
|
||||
// Get the most descriptive failure id message for this feature.
|
||||
static const nsACString& GetFailureId(Feature aFeature);
|
||||
static const nsCString& GetFailureId(Feature aFeature);
|
||||
|
||||
static void ImportChange(Feature aFeature, const FeatureChange& aChange);
|
||||
|
||||
static void Init();
|
||||
static void Shutdown();
|
||||
|
@ -160,7 +160,6 @@ FeatureState::MaybeSetFailed(FeatureStatus aStatus, const char* aMessage,
|
||||
bool
|
||||
FeatureState::DisabledByDefault() const
|
||||
{
|
||||
AssertInitialized();
|
||||
return mDefault.mStatus != FeatureStatus::Available;
|
||||
}
|
||||
|
||||
@ -256,7 +255,33 @@ FeatureState::SetFailureId(const nsACString& aFailureId)
|
||||
}
|
||||
}
|
||||
|
||||
const nsACString&
|
||||
const char*
|
||||
FeatureState::GetFailureMessage() const
|
||||
{
|
||||
AssertInitialized();
|
||||
MOZ_ASSERT(!IsEnabled());
|
||||
|
||||
if (mRuntime.mStatus != FeatureStatus::Unused &&
|
||||
IsFeatureStatusFailure(mRuntime.mStatus))
|
||||
{
|
||||
return mRuntime.mMessage;
|
||||
}
|
||||
if (mEnvironment.mStatus != FeatureStatus::Unused &&
|
||||
IsFeatureStatusFailure(mEnvironment.mStatus))
|
||||
{
|
||||
return mEnvironment.mMessage;
|
||||
}
|
||||
if (mUser.mStatus != FeatureStatus::Unused &&
|
||||
IsFeatureStatusFailure(mUser.mStatus))
|
||||
{
|
||||
return mUser.mMessage;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(IsFeatureStatusFailure(mDefault.mStatus));
|
||||
return mDefault.mMessage;
|
||||
}
|
||||
|
||||
const nsCString&
|
||||
FeatureState::GetFailureId() const
|
||||
{
|
||||
MOZ_ASSERT(!IsEnabled());
|
||||
|
@ -68,14 +68,16 @@ class FeatureState
|
||||
const char* aMessage)> StatusIterCallback;
|
||||
void ForEachStatusChange(const StatusIterCallback& aCallback) const;
|
||||
|
||||
const nsACString& GetFailureId() const;
|
||||
const char* GetFailureMessage() const;
|
||||
const nsCString& GetFailureId() const;
|
||||
|
||||
bool DisabledByDefault() const;
|
||||
|
||||
private:
|
||||
void SetUser(FeatureStatus aStatus, const char* aMessage);
|
||||
void SetEnvironment(FeatureStatus aStatus, const char* aMessage);
|
||||
void SetRuntime(FeatureStatus aStatus, const char* aMessage);
|
||||
bool IsForcedOnByUser() const;
|
||||
bool DisabledByDefault() const;
|
||||
const char* GetRuntimeMessage() const;
|
||||
bool IsInitialized() const {
|
||||
return mDefault.IsInitialized();
|
||||
|
@ -8,12 +8,16 @@
|
||||
#include "gfxPrefs.h"
|
||||
#include "GPUProcessHost.h"
|
||||
#include "mozilla/gfx/gfxVars.h"
|
||||
#if defined(XP_WIN)
|
||||
# include "mozilla/gfx/DeviceManagerD3D11.h"
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
GPUChild::GPUChild(GPUProcessHost* aHost)
|
||||
: mHost(aHost)
|
||||
: mHost(aHost),
|
||||
mGPUReady(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(GPUChild);
|
||||
}
|
||||
@ -62,6 +66,33 @@ GPUChild::OnVarChanged(const GfxVarUpdate& aVar)
|
||||
SendUpdateVar(aVar);
|
||||
}
|
||||
|
||||
void
|
||||
GPUChild::EnsureGPUReady()
|
||||
{
|
||||
if (mGPUReady) {
|
||||
return;
|
||||
}
|
||||
|
||||
GPUDeviceData data;
|
||||
SendGetDeviceStatus(&data);
|
||||
|
||||
gfxPlatform::GetPlatform()->ImportGPUDeviceData(data);
|
||||
mGPUReady = true;
|
||||
}
|
||||
|
||||
bool
|
||||
GPUChild::RecvInitComplete(const GPUDeviceData& aData)
|
||||
{
|
||||
// We synchronously requested GPU parameters before this arrived.
|
||||
if (mGPUReady) {
|
||||
return true;
|
||||
}
|
||||
|
||||
gfxPlatform::GetPlatform()->ImportGPUDeviceData(aData);
|
||||
mGPUReady = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
GPUChild::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
|
@ -26,16 +26,20 @@ public:
|
||||
|
||||
void Init();
|
||||
|
||||
void EnsureGPUReady();
|
||||
|
||||
// gfxVarReceiver overrides.
|
||||
void OnVarChanged(const GfxVarUpdate& aVar) override;
|
||||
|
||||
// PGPUChild overrides.
|
||||
bool RecvInitComplete(const GPUDeviceData& aData) override;
|
||||
void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
static void Destroy(UniquePtr<GPUChild>&& aChild);
|
||||
|
||||
private:
|
||||
GPUProcessHost* mHost;
|
||||
bool mGPUReady;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
|
@ -84,6 +84,11 @@ GPUParent::RecvInit(nsTArray<GfxPrefSetting>&& prefs,
|
||||
}
|
||||
#endif
|
||||
|
||||
// Send a message to the UI process that we're done.
|
||||
GPUDeviceData data;
|
||||
RecvGetDeviceStatus(&data);
|
||||
Unused << SendInitComplete(data);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -123,6 +128,43 @@ GPUParent::RecvUpdateVar(const GfxVarUpdate& aUpdate)
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
CopyFeatureChange(Feature aFeature, FeatureChange* aOut)
|
||||
{
|
||||
FeatureState& feature = gfxConfig::GetFeature(aFeature);
|
||||
if (feature.DisabledByDefault() || feature.IsEnabled()) {
|
||||
// No change:
|
||||
// - Disabled-by-default means the parent process told us not to use this feature.
|
||||
// - Enabled means we were told to use this feature, and we didn't discover anything
|
||||
// that would prevent us from doing so.
|
||||
*aOut = null_t();
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!feature.IsEnabled());
|
||||
|
||||
nsCString message;
|
||||
message.AssignASCII(feature.GetFailureMessage());
|
||||
|
||||
*aOut = FeatureFailure(feature.GetValue(), message, feature.GetFailureId());
|
||||
}
|
||||
|
||||
bool
|
||||
GPUParent::RecvGetDeviceStatus(GPUDeviceData* aOut)
|
||||
{
|
||||
CopyFeatureChange(Feature::D3D11_COMPOSITING, &aOut->d3d11Compositing());
|
||||
CopyFeatureChange(Feature::D3D9_COMPOSITING, &aOut->d3d9Compositing());
|
||||
CopyFeatureChange(Feature::OPENGL_COMPOSITING, &aOut->oglCompositing());
|
||||
|
||||
#if defined(XP_WIN)
|
||||
if (DeviceManagerD3D11* dm = DeviceManagerD3D11::Get()) {
|
||||
dm->ExportDeviceInfo(&aOut->d3d11Device());
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
OpenParent(RefPtr<CompositorBridgeParent> aParent,
|
||||
Endpoint<PCompositorBridgeParent>&& aEndpoint)
|
||||
|
@ -42,6 +42,7 @@ public:
|
||||
bool RecvNewContentImageBridge(Endpoint<PImageBridgeParent>&& aEndpoint) override;
|
||||
bool RecvNewContentVRManager(Endpoint<PVRManagerParent>&& aEndpoint) override;
|
||||
bool RecvDeallocateLayerTreeId(const uint64_t& aLayersId) override;
|
||||
bool RecvGetDeviceStatus(GPUDeviceData* aOutStatus) override;
|
||||
|
||||
void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
|
@ -134,6 +134,10 @@ GPUProcessManager::EnsureGPUReady()
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (mGPUChild) {
|
||||
mGPUChild->EnsureGPUReady();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -143,6 +147,8 @@ GPUProcessManager::EnsureImageBridgeChild()
|
||||
return;
|
||||
}
|
||||
|
||||
EnsureGPUReady();
|
||||
|
||||
if (!mGPUChild) {
|
||||
ImageBridgeChild::InitSameProcess();
|
||||
return;
|
||||
@ -171,6 +177,8 @@ GPUProcessManager::EnsureVRManager()
|
||||
return;
|
||||
}
|
||||
|
||||
EnsureGPUReady();
|
||||
|
||||
if (!mGPUChild) {
|
||||
VRManagerChild::InitSameProcess();
|
||||
return;
|
||||
@ -288,6 +296,7 @@ GPUProcessManager::CreateTopLevelCompositor(nsBaseWidget* aWidget,
|
||||
{
|
||||
uint64_t layerTreeId = AllocateLayerTreeId();
|
||||
|
||||
EnsureGPUReady();
|
||||
EnsureImageBridgeChild();
|
||||
EnsureVRManager();
|
||||
|
||||
@ -391,6 +400,8 @@ bool
|
||||
GPUProcessManager::CreateContentCompositorBridge(base::ProcessId aOtherProcess,
|
||||
ipc::Endpoint<PCompositorBridgeChild>* aOutEndpoint)
|
||||
{
|
||||
EnsureGPUReady();
|
||||
|
||||
ipc::Endpoint<PCompositorBridgeParent> parentPipe;
|
||||
ipc::Endpoint<PCompositorBridgeChild> childPipe;
|
||||
|
||||
|
@ -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";
|
||||
using mozilla::gfx::FeatureStatus from "gfxTelemetry.h";
|
||||
using mozilla::gfx::BackendType from "mozilla/gfx/Types.h";
|
||||
using mozilla::gfx::IntSize from "mozilla/gfx/Point.h";
|
||||
@ -35,6 +36,30 @@ struct ContentDeviceData
|
||||
D3D11DeviceStatus d3d11;
|
||||
};
|
||||
|
||||
// Represents the state of a feature that has failed to initialize.
|
||||
struct FeatureFailure
|
||||
{
|
||||
FeatureStatus status;
|
||||
nsCString message;
|
||||
nsCString failureId;
|
||||
};
|
||||
|
||||
// If a feature state has changed from Enabled -> Failure, this will be non-
|
||||
// null.
|
||||
union FeatureChange
|
||||
{
|
||||
null_t;
|
||||
FeatureFailure;
|
||||
};
|
||||
|
||||
struct GPUDeviceData
|
||||
{
|
||||
FeatureChange d3d11Compositing;
|
||||
FeatureChange d3d9Compositing;
|
||||
FeatureChange oglCompositing;
|
||||
D3D11DeviceStatus d3d11Device;
|
||||
};
|
||||
|
||||
union GfxVarValue
|
||||
{
|
||||
BackendType;
|
||||
|
@ -57,6 +57,15 @@ parent:
|
||||
async NewContentVRManager(Endpoint<PVRManagerParent> endpoint);
|
||||
|
||||
async DeallocateLayerTreeId(uint64_t layersId);
|
||||
|
||||
// Request the current DeviceStatus from the GPU process. This blocks until
|
||||
// one is available (i.e., Init has completed).
|
||||
sync GetDeviceStatus() returns (GPUDeviceData status);
|
||||
|
||||
child:
|
||||
// Sent when the GPU process has initialized devices. This occurs once, after
|
||||
// Init().
|
||||
async InitComplete(GPUDeviceData data);
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
|
@ -142,8 +142,10 @@ DeviceManagerD3D11::ImportDeviceInfo(const D3D11DeviceStatus& aDeviceStatus)
|
||||
void
|
||||
DeviceManagerD3D11::ExportDeviceInfo(D3D11DeviceStatus* aOut)
|
||||
{
|
||||
MOZ_ASSERT(ProcessOwnsCompositor());
|
||||
MOZ_ASSERT(!!mCompositorDevice == !!mDeviceStatus);
|
||||
// Even though the parent process might not own the compositor, we still
|
||||
// populate DeviceManagerD3D11 with device statistics (for simplicity).
|
||||
// That means it still gets queried for compositor information.
|
||||
MOZ_ASSERT(XRE_IsParentProcess() || XRE_GetProcessType() == GeckoProcessType_GPU);
|
||||
|
||||
if (mDeviceStatus) {
|
||||
*aOut = mDeviceStatus.value();
|
||||
|
@ -2447,10 +2447,22 @@ void
|
||||
gfxPlatform::BuildContentDeviceData(mozilla::gfx::ContentDeviceData* aOut)
|
||||
{
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
// Make sure our settings are synchronized from the GPU process.
|
||||
GPUProcessManager::Get()->EnsureGPUReady();
|
||||
|
||||
aOut->prefs().hwCompositing() = gfxConfig::GetValue(Feature::HW_COMPOSITING);
|
||||
aOut->prefs().oglCompositing() = gfxConfig::GetValue(Feature::OPENGL_COMPOSITING);
|
||||
}
|
||||
|
||||
void
|
||||
gfxPlatform::ImportGPUDeviceData(const mozilla::gfx::GPUDeviceData& aData)
|
||||
{
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
gfxConfig::ImportChange(Feature::OPENGL_COMPOSITING, aData.oglCompositing());
|
||||
}
|
||||
|
||||
bool
|
||||
gfxPlatform::SupportsApzDragInput() const
|
||||
{
|
||||
|
@ -52,6 +52,7 @@ class ScaledFont;
|
||||
class DrawEventRecorder;
|
||||
class VsyncSource;
|
||||
class ContentDeviceData;
|
||||
class GPUDeviceData;
|
||||
|
||||
inline uint32_t
|
||||
BackendTypeBit(BackendType b)
|
||||
@ -674,6 +675,12 @@ public:
|
||||
*/
|
||||
virtual void BuildContentDeviceData(mozilla::gfx::ContentDeviceData* aOut);
|
||||
|
||||
/**
|
||||
* Imports settings from the GPU process. This should only be called through
|
||||
* GPUProcessManager, in the UI process.
|
||||
*/
|
||||
virtual void ImportGPUDeviceData(const mozilla::gfx::GPUDeviceData& aData);
|
||||
|
||||
protected:
|
||||
gfxPlatform();
|
||||
virtual ~gfxPlatform();
|
||||
|
@ -2029,6 +2029,39 @@ gfxWindowsPlatform::GetAcceleratedCompositorBackends(nsTArray<LayersBackend>& aB
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gfxWindowsPlatform::ImportGPUDeviceData(const mozilla::gfx::GPUDeviceData& aData)
|
||||
{
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
gfxPlatform::ImportGPUDeviceData(aData);
|
||||
|
||||
gfxConfig::ImportChange(Feature::D3D11_COMPOSITING, aData.d3d11Compositing());
|
||||
gfxConfig::ImportChange(Feature::D3D9_COMPOSITING, aData.d3d9Compositing());
|
||||
|
||||
DeviceManagerD3D11* dm = DeviceManagerD3D11::Get();
|
||||
if (gfxConfig::IsEnabled(Feature::D3D11_COMPOSITING)) {
|
||||
dm->ImportDeviceInfo(aData.d3d11Device());
|
||||
} else {
|
||||
// There should be no devices, so this just takes away the device status.
|
||||
dm->ResetDevices();
|
||||
|
||||
// Make sure we disable D2D if content processes might use it.
|
||||
FeatureState& d2d1 = gfxConfig::GetFeature(Feature::DIRECT2D);
|
||||
if (d2d1.IsEnabled()) {
|
||||
d2d1.SetFailed(
|
||||
FeatureStatus::Unavailable,
|
||||
"Direct2D requires Direct3D 11 compositing",
|
||||
NS_LITERAL_CSTRING("FEATURE_FAILURE_D2D_D3D11_COMP"));
|
||||
}
|
||||
}
|
||||
|
||||
// For completeness (and messaging in about:support). Content recomputes this
|
||||
// on its own, and we won't use ANGLE in the UI process if we're using a GPU
|
||||
// process.
|
||||
UpdateANGLEConfig();
|
||||
}
|
||||
|
||||
void
|
||||
gfxWindowsPlatform::ImportContentDeviceData(const mozilla::gfx::ContentDeviceData& aData)
|
||||
{
|
||||
|
@ -252,6 +252,7 @@ protected:
|
||||
void GetAcceleratedCompositorBackends(nsTArray<mozilla::layers::LayersBackend>& aBackends) override;
|
||||
virtual void GetPlatformCMSOutputProfile(void* &mem, size_t &size) override;
|
||||
|
||||
void ImportGPUDeviceData(const mozilla::gfx::GPUDeviceData& aData) override;
|
||||
void ImportContentDeviceData(const mozilla::gfx::ContentDeviceData& aData) override;
|
||||
void BuildContentDeviceData(mozilla::gfx::ContentDeviceData* aOut) override;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user