Add an NPN_GetValue query to find the browser's DXGI adapter. (bug 1217665 part 10, r=aklotz,mattwoodrow)

--HG--
extra : rebase_source : 55d8f4541524298232b219ab29938c62d69d56af
This commit is contained in:
David Anderson 2015-12-02 11:31:17 -08:00
parent ca5122668a
commit b49b27b9a6
10 changed files with 95 additions and 6 deletions

View File

@ -426,6 +426,7 @@ typedef enum {
, NPNVsupportsAsyncBitmapSurfaceBool = 2007
#if defined(XP_WIN)
, NPNVsupportsAsyncWindowsDXGISurfaceBool = 2008
, NPNVpreferredDXGIAdapter = 2009
#endif
#if defined(XP_MACOSX)
#ifndef NP_NO_CARBON

View File

@ -30,6 +30,7 @@ using mozilla::plugins::WindowsSharedMemoryHandle from "mozilla/plugins/PluginMe
using mozilla::layers::SurfaceDescriptorX11 from "gfxipc/ShadowLayerUtils.h";
using nsIntRect from "nsRect.h";
using mozilla::gfx::SurfaceFormat from "mozilla/gfx/Types.h";
using struct DxgiAdapterDesc from "mozilla/D3DMessageUtils.h";
namespace mozilla {
namespace plugins {
@ -153,6 +154,8 @@ parent:
returns (bool value);
intr NPN_GetValue_SupportsAsyncDXGISurface()
returns (bool value);
intr NPN_GetValue_PreferredDXGIAdapter()
returns (DxgiAdapterDesc desc);
intr NPN_SetValue_NPPVpluginWindow(bool windowed)
returns (NPError result);

View File

@ -20,8 +20,10 @@
#include "gfxXlibSurface.h"
#endif
#ifdef XP_WIN
#include "mozilla/D3DMessageUtils.h"
#include "mozilla/gfx/SharedDIBSurface.h"
#include "nsCrashOnException.h"
#include "gfxWindowsPlatform.h"
extern const wchar_t* kFlashFullscreenClass;
using mozilla::gfx::SharedDIBSurface;
#endif
@ -459,6 +461,17 @@ PluginInstanceChild::NPN_GetValue(NPNVariable aVar,
}
#endif
#ifdef XP_WIN
case NPNVpreferredDXGIAdapter: {
DxgiAdapterDesc desc;
if (!CallNPN_GetValue_PreferredDXGIAdapter(&desc)) {
return NPERR_GENERIC_ERROR;
}
*reinterpret_cast<DXGI_ADAPTER_DESC*>(aValue) = desc.ToDesc();
return NPERR_NO_ERROR;
}
#endif
#ifdef XP_MACOSX
case NPNVsupportsCoreGraphicsBool: {
*((NPBool*)aValue) = true;

View File

@ -397,6 +397,39 @@ PluginInstanceParent::AnswerNPN_GetValue_SupportsAsyncDXGISurface(bool* value)
return true;
}
bool
PluginInstanceParent::AnswerNPN_GetValue_PreferredDXGIAdapter(DxgiAdapterDesc* aOutDesc)
{
PodZero(aOutDesc);
#ifdef XP_WIN
if (!AllowDirectDXGISurfaceDrawing()) {
return false;
}
ID3D11Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D11ContentDevice();
if (!device) {
return false;
}
RefPtr<IDXGIDevice> dxgi;
if (FAILED(device->QueryInterface(__uuidof(IDXGIDevice), getter_AddRefs(dxgi))) || !dxgi) {
return false;
}
RefPtr<IDXGIAdapter> adapter;
if (FAILED(dxgi->GetAdapter(getter_AddRefs(adapter))) || !adapter) {
return false;
}
DXGI_ADAPTER_DESC desc;
if (FAILED(adapter->GetDesc(&desc))) {
return false;
}
*aOutDesc = DxgiAdapterDesc::From(desc);
#endif
return true;
}
bool
PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginWindow(
const bool& windowed, NPError* result)

View File

@ -123,6 +123,9 @@ public:
virtual bool
AnswerNPN_GetValue_SupportsAsyncDXGISurface(bool* value) override;
virtual bool
AnswerNPN_GetValue_PreferredDXGIAdapter(DxgiAdapterDesc* desc) override;
virtual bool
AnswerNPN_SetValue_NPPVpluginWindow(const bool& windowed, NPError* result) override;
virtual bool

View File

@ -1198,7 +1198,7 @@ NPP_SetWindow(NPP instance, NPWindow* window)
#if defined(XP_WIN)
if (instanceData->asyncDrawing == AD_DXGI) {
if (!setupDxgiSurfaces(instanceData)) {
if (!setupDxgiSurfaces(instance, instanceData)) {
return NPERR_GENERIC_ERROR;
}
}

View File

@ -161,7 +161,7 @@ typedef struct InstanceData {
void notifyDidPaint(InstanceData* instanceData);
#if defined(XP_WIN)
bool setupDxgiSurfaces(InstanceData* instanceData);
bool setupDxgiSurfaces(NPP npp, InstanceData* instanceData);
void drawDxgiBitmapColor(InstanceData* instanceData);
#endif

View File

@ -105,9 +105,39 @@ typedef HRESULT (WINAPI*D2D1CreateFactoryFunc)(
void **factory
);
static IDXGIAdapter1*
FindDXGIAdapter(NPP npp, IDXGIFactory1* factory)
{
DXGI_ADAPTER_DESC preferred;
if (NPN_GetValue(npp, NPNVpreferredDXGIAdapter, &preferred) != NPERR_NO_ERROR) {
return nullptr;
}
UINT index = 0;
for (;;) {
IDXGIAdapter1* adapter = nullptr;
if (FAILED(factory->EnumAdapters1(index, &adapter)) || !adapter) {
return nullptr;
}
DXGI_ADAPTER_DESC desc;
if (SUCCEEDED(adapter->GetDesc(&desc)) &&
desc.AdapterLuid.LowPart == preferred.AdapterLuid.LowPart &&
desc.AdapterLuid.HighPart == preferred.AdapterLuid.HighPart &&
desc.VendorId == preferred.VendorId &&
desc.DeviceId == preferred.DeviceId)
{
return adapter;
}
adapter->Release();
index++;
}
}
// Note: we leak modules since we need them anyway.
bool
setupDxgiSurfaces(InstanceData* instanceData)
setupDxgiSurfaces(NPP npp, InstanceData* instanceData)
{
HMODULE dxgi = LoadLibraryA("dxgi.dll");
if (!dxgi) {
@ -125,9 +155,8 @@ setupDxgiSurfaces(InstanceData* instanceData)
return false;
}
hr = factory1->EnumAdapters1(0, &instanceData->platformData->adapter);
factory1->Release();
if (FAILED(hr) || !instanceData->platformData->adapter) {
instanceData->platformData->adapter = FindDXGIAdapter(npp, factory1);
if (!instanceData->platformData->adapter) {
return false;
}

View File

@ -23,6 +23,12 @@ DxgiAdapterDesc::From(const DXGI_ADAPTER_DESC& aDesc)
{
return reinterpret_cast<const DxgiAdapterDesc&>(aDesc);
}
const DXGI_ADAPTER_DESC&
DxgiAdapterDesc::ToDesc() const
{
return reinterpret_cast<const DXGI_ADAPTER_DESC&>(*this);
}
#endif
namespace IPC {

View File

@ -27,6 +27,7 @@ struct DxgiAdapterDesc
LUID AdapterLuid;
static const DxgiAdapterDesc& From(const DXGI_ADAPTER_DESC& aDesc);
const DXGI_ADAPTER_DESC& ToDesc() const;
#endif
bool operator ==(const DxgiAdapterDesc& aOther) const;