Bug 1577336: Part 3 - Fetch Windows plugin async graphics capabilities from gpu or main process r=jmathies,mattwoodrow,froydnj

These operations report whether certain async plugin drawing modes are supported on the host architecture.  They use kernel graphics operations to decide this so they need to be removed from the content process for sandboxing.  We just bounce the requests to the gpu process (or main process on systems without a GPU process).

Differential Revision: https://phabricator.services.mozilla.com/D46085

--HG--
extra : moz-landing-system : lando
This commit is contained in:
David Parks 2019-11-20 21:33:55 +00:00
Родитель beb56ea7bc
Коммит 446170c593
10 изменённых файлов: 102 добавлений и 60 удалений

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

@ -58,6 +58,7 @@
# include "nsIWidget.h"
# include "nsPluginNativeWindow.h"
# include "PluginQuirks.h"
# include "mozilla/layers/CompositorBridgeChild.h"
extern const wchar_t* kFlashFullscreenClass;
#elif defined(MOZ_WIDGET_GTK)
# include "mozilla/dom/ContentChild.h"
@ -318,17 +319,6 @@ static inline bool AllowDirectBitmapSurfaceDrawing() {
return gfxPlatform::GetPlatform()->SupportsPluginDirectBitmapDrawing();
}
static inline bool AllowDirectDXGISurfaceDrawing() {
if (!StaticPrefs::dom_ipc_plugins_asyncdrawing_enabled()) {
return false;
}
#if defined(XP_WIN)
return gfxWindowsPlatform::GetPlatform()->SupportsPluginDirectDXGIDrawing();
#else
return false;
#endif
}
mozilla::ipc::IPCResult
PluginInstanceParent::AnswerNPN_GetValue_SupportsAsyncBitmapSurface(
bool* value) {
@ -336,47 +326,29 @@ PluginInstanceParent::AnswerNPN_GetValue_SupportsAsyncBitmapSurface(
return IPC_OK();
}
mozilla::ipc::IPCResult
PluginInstanceParent::AnswerNPN_GetValue_SupportsAsyncDXGISurface(bool* value) {
if (!StaticPrefs::dom_ipc_plugins_allow_dxgi_surface()) {
*value = false;
} else {
*value = AllowDirectDXGISurfaceDrawing();
/* static */
bool PluginInstanceParent::SupportsPluginDirectDXGISurfaceDrawing() {
bool value = false;
#if defined(XP_WIN)
if (StaticPrefs::dom_ipc_plugins_allow_dxgi_surface()) {
auto cbc = CompositorBridgeChild::Get();
if (cbc) {
cbc->SendSupportsAsyncDXGISurface(&value);
}
}
return IPC_OK();
#endif
return value;
}
mozilla::ipc::IPCResult
PluginInstanceParent::AnswerNPN_GetValue_PreferredDXGIAdapter(
DxgiAdapterDesc* aOutDesc) {
PodZero(aOutDesc);
#ifdef XP_WIN
if (!AllowDirectDXGISurfaceDrawing()) {
return IPC_FAIL_NO_REASON(this);
#if defined(XP_WIN)
auto cbc = CompositorBridgeChild::Get();
if (cbc) {
cbc->SendPreferredDXGIAdapter(aOutDesc);
}
RefPtr<ID3D11Device> device = DeviceManagerDx::Get()->GetContentDevice();
if (!device) {
return IPC_FAIL_NO_REASON(this);
}
RefPtr<IDXGIDevice> dxgi;
if (FAILED(device->QueryInterface(__uuidof(IDXGIDevice),
getter_AddRefs(dxgi))) ||
!dxgi) {
return IPC_FAIL_NO_REASON(this);
}
RefPtr<IDXGIAdapter> adapter;
if (FAILED(dxgi->GetAdapter(getter_AddRefs(adapter))) || !adapter) {
return IPC_FAIL_NO_REASON(this);
}
DXGI_ADAPTER_DESC desc;
if (FAILED(adapter->GetDesc(&desc))) {
return IPC_FAIL_NO_REASON(this);
}
*aOutDesc = DxgiAdapterDesc::From(desc);
#endif
return IPC_OK();
}
@ -426,7 +398,7 @@ PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginDrawingModel(
allowed = true;
break;
case NPDrawingModelAsyncWindowsDXGISurface:
allowed = AllowDirectDXGISurfaceDrawing();
allowed = SupportsPluginDirectDXGISurfaceDrawing();
break;
#elif defined(MOZ_X11)
case NPDrawingModelSyncX:

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

@ -101,8 +101,12 @@ class PluginInstanceParent : public PPluginInstanceParent {
mozilla::ipc::IPCResult AnswerNPN_GetValue_SupportsAsyncBitmapSurface(
bool* value);
static bool SupportsPluginDirectDXGISurfaceDrawing();
mozilla::ipc::IPCResult AnswerNPN_GetValue_SupportsAsyncDXGISurface(
bool* value);
bool* value) {
*value = SupportsPluginDirectDXGISurfaceDrawing();
return IPC_OK();
}
mozilla::ipc::IPCResult AnswerNPN_GetValue_PreferredDXGIAdapter(
DxgiAdapterDesc* desc);

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

@ -2119,7 +2119,7 @@ nsresult PluginModuleParent::NPP_NewInternal(
// direct path for flash objects that have wmode=window or no wmode
// specified.
if (supportsAsyncRender && supportsForceDirect &&
gfxWindowsPlatform::GetPlatform()->SupportsPluginDirectDXGIDrawing()) {
PluginInstanceParent::SupportsPluginDirectDXGISurfaceDrawing()) {
ForceDirect(names, values);
}
#endif

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

@ -289,6 +289,14 @@ class CompositorBridgeParentBase : public PCompositorBridgeParent,
Endpoint<PCanvasParent>&& aEndpoint) = 0;
virtual mozilla::ipc::IPCResult RecvReleasePCanvasParent() = 0;
virtual mozilla::ipc::IPCResult RecvSupportsAsyncDXGISurface(bool* value) {
return IPC_FAIL_NO_REASON(this);
}
virtual mozilla::ipc::IPCResult RecvPreferredDXGIAdapter(
DxgiAdapterDesc* desc) {
return IPC_FAIL_NO_REASON(this);
}
bool mCanSend;
private:

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

@ -16,6 +16,7 @@
#include "gfxUtils.h"
#ifdef XP_WIN
# include "mozilla/gfx/DeviceManagerDx.h" // for DeviceManagerDx
# include "mozilla/layers/ImageDataSerializer.h"
#endif
#include "mozilla/ipc/Transport.h" // for Transport
#include "mozilla/layers/AnimationHelper.h" // for CompositorAnimationStorage
@ -707,5 +708,61 @@ void ContentCompositorBridgeParent::ObserveLayersUpdate(
Unused << state->mParent->SendObserveLayersUpdate(aLayersId, aEpoch, aActive);
}
static inline bool AllowDirectDXGISurfaceDrawing() {
if (!StaticPrefs::dom_ipc_plugins_asyncdrawing_enabled()) {
return false;
}
#if defined(XP_WIN)
DeviceManagerDx* dm = DeviceManagerDx::Get();
MOZ_ASSERT(dm);
if (!dm || !dm->GetCompositorDevice() || !dm->TextureSharingWorks()) {
return false;
}
return true;
#else
return false;
#endif
}
mozilla::ipc::IPCResult
ContentCompositorBridgeParent::RecvSupportsAsyncDXGISurface(bool* value) {
*value = AllowDirectDXGISurfaceDrawing();
return IPC_OK();
}
mozilla::ipc::IPCResult ContentCompositorBridgeParent::RecvPreferredDXGIAdapter(
DxgiAdapterDesc* aOutDesc) {
PodZero(aOutDesc);
#ifdef XP_WIN
if (!AllowDirectDXGISurfaceDrawing()) {
return IPC_FAIL_NO_REASON(this);
}
RefPtr<ID3D11Device> device = DeviceManagerDx::Get()->GetCompositorDevice();
if (!device) {
return IPC_FAIL_NO_REASON(this);
}
RefPtr<IDXGIDevice> dxgi;
if (FAILED(device->QueryInterface(__uuidof(IDXGIDevice),
getter_AddRefs(dxgi))) ||
!dxgi) {
return IPC_FAIL_NO_REASON(this);
}
RefPtr<IDXGIAdapter> adapter;
if (FAILED(dxgi->GetAdapter(getter_AddRefs(adapter))) || !adapter) {
return IPC_FAIL_NO_REASON(this);
}
DXGI_ADAPTER_DESC desc;
if (FAILED(adapter->GetDesc(&desc))) {
return IPC_FAIL_NO_REASON(this);
}
*aOutDesc = DxgiAdapterDesc::From(desc);
#endif
return IPC_OK();
}
} // namespace layers
} // namespace mozilla

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

@ -221,6 +221,10 @@ class ContentCompositorBridgeParent final : public CompositorBridgeParentBase {
UniquePtr<SurfaceDescriptor> LookupSurfaceDescriptorForClientDrawTarget(
const uintptr_t aDrawTarget) final;
mozilla::ipc::IPCResult RecvSupportsAsyncDXGISurface(bool* value) override;
mozilla::ipc::IPCResult RecvPreferredDXGIAdapter(
DxgiAdapterDesc* desc) override;
private:
// Private destructor, to discourage deletion outside of Release():
virtual ~ContentCompositorBridgeParent();

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

@ -46,6 +46,7 @@ using base::ProcessId from "base/process.h";
using mozilla::wr::MaybeExternalImageId from "mozilla/webrender/WebRenderTypes.h";
using mozilla::layers::LayersObserverEpoch from "mozilla/layers/LayersTypes.h";
using mozilla::layers::TransactionId from "mozilla/layers/LayersTypes.h";
using struct DxgiAdapterDesc from "mozilla/D3DMessageUtils.h";
namespace mozilla {
namespace layers {
@ -285,6 +286,11 @@ parent:
async EndRecordingToMemory()
returns (CollectedFramesParams? frames);
sync SupportsAsyncDXGISurface()
returns (bool value);
sync PreferredDXGIAdapter()
returns (DxgiAdapterDesc desc);
// To set up sharing the composited output to Firefox Reality on Desktop
async RequestFxrOutput();

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

@ -2022,18 +2022,6 @@ void gfxWindowsPlatform::BuildContentDeviceData(ContentDeviceData* aOut) {
}
}
bool gfxWindowsPlatform::SupportsPluginDirectDXGIDrawing() {
// Ensure devices initialization for plugin's DXGISurface. The devices are
// lazily initialized with WebRender to reduce memory usage.
EnsureDevicesInitialized();
DeviceManagerDx* dm = DeviceManagerDx::Get();
if (!dm->GetContentDevice() || !dm->TextureSharingWorks()) {
return false;
}
return true;
}
bool gfxWindowsPlatform::CheckVariationFontSupport() {
// Variation font support is only available on Fall Creators Update or later.
return IsWin10FallCreatorsUpdateOrLater();

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

@ -209,7 +209,6 @@ class gfxWindowsPlatform : public gfxPlatform {
static mozilla::Atomic<size_t> sD3D9SharedTextures;
bool SupportsPluginDirectBitmapDrawing() override { return true; }
bool SupportsPluginDirectDXGIDrawing();
static void RecordContentDeviceFailure(
mozilla::gfx::TelemetryDeviceCode aDevice);

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

@ -1110,6 +1110,10 @@ platform = win
[PCompositorWidget::LeavePresentLock]
description =
platform = win
[PCompositorBridge::SupportsAsyncDXGISurface]
description =
[PCompositorBridge::PreferredDXGIAdapter]
description =
[PCompositorWidget::ClearTransparentWindow]
description =
platform = win