Bug 1335971: Allow uploading on the client side on Intel hardware. r=mattwoodrow
MozReview-Commit-ID: GeVYccWK7xY
--- a/gfx/layers/IMFYCbCrImage.cpp
+++ b/gfx/layers/IMFYCbCrImage.cpp
@@ -241,16 +241,28 @@ IMFYCbCrImage::GetTextureClient(KnowsCom
LayersBackend backend = aForwarder->GetCompositorBackendType();
if (!device || backend != LayersBackend::LAYERS_D3D11) {
if (backend == LayersBackend::LAYERS_D3D9 ||
backend == LayersBackend::LAYERS_D3D11) {
return GetD3D9TextureClient(aForwarder);
}
return nullptr;
}
+
+ HRESULT hr;
+ RefPtr<ID3D10Multithread> mt;
+ hr = device->QueryInterface((ID3D10Multithread**)getter_AddRefs(mt));
+
+ if (FAILED(hr)) {
+ return nullptr;
+ }
+
+ if (!mt->GetMultithreadProtected()) {
+ return nullptr;
+ }
if (!gfx::DeviceManagerDx::Get()->CanInitializeKeyedMutexTextures()) {
return nullptr;
}
if (mData.mYStride < 0 || mData.mCbCrStride < 0) {
// D3D11 only supports unsigned stride values.
return nullptr;
@@ -261,39 +273,61 @@ IMFYCbCrImage::GetTextureClient(KnowsCom
if (device == gfx::DeviceManagerDx::Get()->GetCompositorDevice()) {
newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
} else {
newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
}
RefPtr<ID3D11Texture2D> textureY;
- D3D11_SUBRESOURCE_DATA yData = { mData.mYChannel, (UINT)mData.mYStride, 0 };
- HRESULT hr = device->CreateTexture2D(&newDesc, &yData, getter_AddRefs(textureY));
+ hr = device->CreateTexture2D(&newDesc, nullptr, getter_AddRefs(textureY));
NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr);
newDesc.Width = mData.mCbCrSize.width;
newDesc.Height = mData.mCbCrSize.height;
RefPtr<ID3D11Texture2D> textureCb;
- D3D11_SUBRESOURCE_DATA cbData = { mData.mCbChannel, (UINT)mData.mCbCrStride, 0 };
- hr = device->CreateTexture2D(&newDesc, &cbData, getter_AddRefs(textureCb));
+ hr = device->CreateTexture2D(&newDesc, nullptr, getter_AddRefs(textureCb));
NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr);
+
RefPtr<ID3D11Texture2D> textureCr;
- D3D11_SUBRESOURCE_DATA crData = { mData.mCrChannel, (UINT)mData.mCbCrStride, 0 };
- hr = device->CreateTexture2D(&newDesc, &crData, getter_AddRefs(textureCr));
+ hr = device->CreateTexture2D(&newDesc, nullptr, getter_AddRefs(textureCr));
NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr);
- // Even though the textures we created are meant to be protected by a keyed mutex,
- // it appears that D3D doesn't include the initial memory upload within this
- // synchronization. Add an empty lock/unlock pair since that appears to
- // be sufficient to make sure we synchronize.
+ // The documentation here seems to suggest using the immediate mode context
+ // on more than one thread is not allowed:
+ // https://msdn.microsoft.com/en-us/library/windows/desktop/ff476891(v=vs.85).aspx
+ // The Debug Layer seems to imply it is though. When the ID3D10Multithread
+ // layer is on. The Enter/Leave of the critical section shouldn't even be
+ // required but were added for extra security.
+
{
+ AutoLockTexture lockY(textureY);
AutoLockTexture lockCr(textureCr);
+ AutoLockTexture lockCb(textureCb);
+
+ mt->Enter();
+
+ RefPtr<ID3D11DeviceContext> ctx;
+ device->GetImmediateContext((ID3D11DeviceContext**)getter_AddRefs(ctx));
+
+ D3D11_BOX box;
+ box.front = box.top = box.left = 0;
+ box.back = 1;
+ box.right = mData.mYSize.width;
+ box.bottom = mData.mYSize.height;
+ ctx->UpdateSubresource(textureY, 0, &box, mData.mYChannel, mData.mYStride, 0);
+
+ box.right = mData.mCbCrSize.width;
+ box.bottom = mData.mCbCrSize.height;
+ ctx->UpdateSubresource(textureCb, 0, &box, mData.mCbChannel, mData.mCbCrStride, 0);
+ ctx->UpdateSubresource(textureCr, 0, &box, mData.mCrChannel, mData.mCbCrStride, 0);
+
+ mt->Leave();
}
mTextureClient = TextureClient::CreateWithData(
DXGIYCbCrTextureData::Create(TextureFlags::DEFAULT,
textureY, textureCb, textureCr,
GetSize(), mData.mYSize, mData.mCbCrSize),
TextureFlags::DEFAULT,
aForwarder->GetTextureForwarder()
--- a/gfx/thebes/DeviceManagerDx.cpp
+++ b/gfx/thebes/DeviceManagerDx.cpp
@@ -787,17 +787,17 @@ bool
DeviceManagerDx::CanInitializeKeyedMutexTextures()
{
MutexAutoLock lock(mDeviceLock);
if (!mDeviceStatus) {
return false;
}
// Disable this on all Intel devices because of crashes.
// See bug 1292923.
- return mDeviceStatus->adapter().VendorId != 0x8086;
+ return (mDeviceStatus->adapter().VendorId != 0x8086 || gfxPrefs::Direct3D11AllowIntelMutex());
}
bool
DeviceManagerDx::CheckRemotePresentSupport()
{
MOZ_ASSERT(XRE_IsParentProcess());
RefPtr<IDXGIAdapter1> adapter = GetDXGIAdapter();
--- a/gfx/thebes/gfxPrefs.h
+++ b/gfx/thebes/gfxPrefs.h
@@ -376,16 +376,17 @@ private:
DECL_GFX_PREF(Live, "gfx.color_management.rendering_intent", CMSRenderingIntent, int32_t, 0);
DECL_GFX_PREF(Once, "gfx.device-reset.limit", DeviceResetLimitCount, int32_t, 10);
DECL_GFX_PREF(Once, "gfx.device-reset.threshold-ms", DeviceResetThresholdMilliseconds, int32_t, -1);
DECL_GFX_PREF(Once, "gfx.direct2d.disabled", Direct2DDisabled, bool, false);
DECL_GFX_PREF(Once, "gfx.direct2d.force-enabled", Direct2DForceEnabled, bool, false);
DECL_GFX_PREF(Live, "gfx.direct3d11.reuse-decoder-device", Direct3D11ReuseDecoderDevice, int32_t, -1);
+ DECL_GFX_PREF(Live, "gfx.direct3d11.allow-intel-mutex", Direct3D11AllowIntelMutex, bool, true);
DECL_GFX_PREF(Live, "gfx.draw-color-bars", CompositorDrawColorBars, bool, false);
DECL_GFX_PREF(Once, "gfx.e10s.hide-plugins-for-scroll", HidePluginsForScroll, bool, true);
DECL_GFX_PREF(Live, "gfx.layerscope.enabled", LayerScopeEnabled, bool, false);
DECL_GFX_PREF(Live, "gfx.layerscope.port", LayerScopePort, int32_t, 23456);
// Note that "gfx.logging.level" is defined in Logging.h.
DECL_GFX_PREF(Live, "gfx.logging.level", GfxLoggingLevel, int32_t, mozilla::gfx::LOG_DEFAULT);
DECL_GFX_PREF(Once, "gfx.logging.crash.length", GfxLoggingCrashLength, uint32_t, 16);
DECL_GFX_PREF(Live, "gfx.logging.painted-pixel-count.enabled",GfxLoggingPaintedPixelCountEnabled, bool, false);