Bug 1322746 - Expose DXGI HANDLEs for GPU_VIDEO. - r=mattwoodrow
MozReview-Commit-ID: Aea0xGesaQi
--- a/dom/media/ipc/VideoDecoderManagerParent.cpp
+++ b/dom/media/ipc/VideoDecoderManagerParent.cpp
@@ -28,19 +28,22 @@ namespace dom {
using namespace ipc;
using namespace layers;
using namespace gfx;
SurfaceDescriptorGPUVideo
VideoDecoderManagerParent::StoreImage(Image* aImage, TextureClient* aTexture)
{
- mImageMap[aTexture->GetSerial()] = aImage;
- mTextureMap[aTexture->GetSerial()] = aTexture;
- return SurfaceDescriptorGPUVideo(aTexture->GetSerial());
+ SurfaceDescriptorGPUVideo ret;
+ aTexture->GPUVideoDesc(&ret);
+
+ mImageMap[ret.handle()] = aImage;
+ mTextureMap[ret.handle()] = aTexture;
+ return Move(ret);
}
StaticRefPtr<nsIThread> sVideoDecoderManagerThread;
StaticRefPtr<TaskQueue> sManagerTaskQueue;
class VideoDecoderManagerThreadHolder
{
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VideoDecoderManagerThreadHolder)
--- a/dom/media/ipc/VideoDecoderParent.cpp
+++ b/dom/media/ipc/VideoDecoderParent.cpp
@@ -194,17 +194,17 @@ VideoDecoderParent::ProcessDecodedData(
VideoDataIPDL output(
MediaDataIPDL(data->mOffset, data->mTime.ToMicroseconds(),
data->mTimecode.ToMicroseconds(),
data->mDuration.ToMicroseconds(),
data->mFrames, data->mKeyframe),
video->mDisplay,
texture ? texture->GetSize() : IntSize(),
texture ? mParent->StoreImage(video->mImage, texture)
- : SurfaceDescriptorGPUVideo(0),
+ : SurfaceDescriptorGPUVideo(0, null_t()),
video->mFrameID);
Unused << SendOutput(output);
}
}
mozilla::ipc::IPCResult
VideoDecoderParent::RecvFlush()
{
--- a/gfx/layers/client/TextureClient.cpp
+++ b/gfx/layers/client/TextureClient.cpp
@@ -157,17 +157,17 @@ private:
// The locking pattern of TextureClient may in some case upset deadlock detection
// tools such as TSan.
// Typically our tile rendering code will lock all of its tiles, render into them
// and unlock them all right after that, which looks something like:
//
// Lock tile A
// Lock tile B
// Lock tile C
- // Apply drawing commands to tiles A, B and C
+ // Apply drawing commands to tiles A, B and C
// Unlock tile A
// Unlock tile B
// Unlock tile C
//
// And later, we may end up rendering a tile buffer that has the same tiles,
// in a different order, for example:
//
// Lock tile B
@@ -1397,16 +1397,28 @@ TextureClient::PrintInfo(std::stringstre
RefPtr<gfx::DataSourceSurface> dSurf = GetAsSurface();
if (dSurf) {
aStream << gfxUtils::GetAsLZ4Base64Str(dSurf).get();
}
}
#endif
}
+void
+TextureClient::GPUVideoDesc(SurfaceDescriptorGPUVideo* const aOutDesc)
+{
+ const auto handle = GetSerial();
+
+ GPUVideoSubDescriptor subDesc = null_t();
+ MOZ_RELEASE_ASSERT(mData);
+ mData->GetSubDescriptor(&subDesc);
+
+ *aOutDesc = SurfaceDescriptorGPUVideo(handle, Move(subDesc));
+}
+
class MemoryTextureReadLock : public NonBlockingTextureReadLock {
public:
MemoryTextureReadLock();
~MemoryTextureReadLock();
virtual bool ReadLock() override;
--- a/gfx/layers/client/TextureClient.h
+++ b/gfx/layers/client/TextureClient.h
@@ -261,16 +261,17 @@ public:
virtual bool BorrowMappedYCbCrData(MappedYCbCrTextureData&) { return false; }
virtual void Deallocate(LayersIPCChannel* aAllocator) = 0;
/// Depending on the texture's flags either Deallocate or Forget is called.
virtual void Forget(LayersIPCChannel* aAllocator) {}
virtual bool Serialize(SurfaceDescriptor& aDescriptor) = 0;
+ virtual void GetSubDescriptor(GPUVideoSubDescriptor* aOutDesc) { }
virtual TextureData*
CreateSimilar(LayersIPCChannel* aAllocator,
LayersBackend aLayersBackend,
TextureFlags aFlags = TextureFlags::DEFAULT,
TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const { return nullptr; }
virtual bool UpdateFromSurface(gfx::SourceSurface* aSurface) { return false; };
@@ -593,22 +594,23 @@ public:
ITextureClientRecycleAllocator* GetRecycleAllocator() { return mRecycleAllocator; }
void SetRecycleAllocator(ITextureClientRecycleAllocator* aAllocator);
/// If you add new code that uses this method, you are probably doing something wrong.
TextureData* GetInternalData() { return mData; }
const TextureData* GetInternalData() const { return mData; }
uint64_t GetSerial() const { return mSerial; }
+ void GPUVideoDesc(SurfaceDescriptorGPUVideo* aOutDesc);
void CancelWaitForRecycle();
/**
* Set last transaction id of CompositableForwarder.
- *
+ *
* Called when TextureClient has TextureFlags::RECYCLE flag.
* When CompositableForwarder forwards the TextureClient with
* TextureFlags::RECYCLE, it holds TextureClient's ref until host side
* releases it. The host side sends TextureClient release message.
* The id is used to check if the message is for the last TextureClient
* forwarding.
*/
void SetLastFwdTransactionId(uint64_t aTransactionId)
@@ -637,32 +639,32 @@ public:
void AddPaintThreadRef();
// Mark that the TextureClient is no longer in use by the PaintThread. This
// must only be called from the PaintThread.
void DropPaintThreadRef();
private:
static void TextureClientRecycleCallback(TextureClient* aClient, void* aClosure);
-
+
// Internal helpers for creating texture clients using the actual forwarder instead
// of KnowsCompositor. TextureClientPool uses these to let it cache texture clients
// per-process instead of per ShadowLayerForwarder, but everyone else should
// use the public functions instead.
friend class TextureClientPool;
static already_AddRefed<TextureClient>
CreateForDrawing(TextureForwarder* aAllocator,
gfx::SurfaceFormat aFormat,
gfx::IntSize aSize,
LayersBackend aLayersBackend,
int32_t aMaxTextureSize,
BackendSelector aSelector,
TextureFlags aTextureFlags,
TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT);
-
+
static already_AddRefed<TextureClient>
CreateForRawBufferAccess(LayersIPCChannel* aAllocator,
gfx::SurfaceFormat aFormat,
gfx::IntSize aSize,
gfx::BackendType aMoz2dBackend,
LayersBackend aLayersBackend,
TextureFlags aTextureFlags,
TextureAllocationFlags flags = ALLOC_DEFAULT);
--- a/gfx/layers/d3d11/TextureD3D11.cpp
+++ b/gfx/layers/d3d11/TextureD3D11.cpp
@@ -368,34 +368,55 @@ D3D11TextureData::SyncWithObject(SyncObj
}
MOZ_ASSERT(aSyncObject->GetSyncType() == SyncObjectClient::SyncType::D3D11);
SyncObjectD3D11Client* sync = static_cast<SyncObjectD3D11Client*>(aSyncObject);
sync->RegisterTexture(mTexture);
}
bool
-DXGITextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
+DXGITextureData::SerializeSpecific(SurfaceDescriptorD3D10* const aOutDesc)
{
RefPtr<IDXGIResource> resource;
GetDXGIResource((IDXGIResource**)getter_AddRefs(resource));
if (!resource) {
return false;
}
HANDLE sharedHandle;
HRESULT hr = resource->GetSharedHandle(&sharedHandle);
if (FAILED(hr)) {
LOGD3D11("Error getting shared handle for texture.");
return false;
}
- aOutDescriptor = SurfaceDescriptorD3D10((WindowsHandle)sharedHandle, mFormat, mSize);
+ *aOutDesc = SurfaceDescriptorD3D10((WindowsHandle)sharedHandle, mFormat, mSize);
return true;
}
+bool
+DXGITextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
+{
+ SurfaceDescriptorD3D10 desc;
+ if (!SerializeSpecific(&desc))
+ return false;
+
+ aOutDescriptor = Move(desc);
+ return true;
+}
+
+void
+DXGITextureData::GetSubDescriptor(GPUVideoSubDescriptor* const aOutDesc)
+{
+ SurfaceDescriptorD3D10 ret;
+ if (!SerializeSpecific(&ret))
+ return;
+
+ *aOutDesc = Move(ret);
+}
+
DXGITextureData*
DXGITextureData::Create(IntSize aSize, SurfaceFormat aFormat, TextureAllocationFlags aFlags)
{
if (aFormat == SurfaceFormat::A8) {
// Currently we don't support A8 surfaces. Fallback.
return nullptr;
}
@@ -654,27 +675,45 @@ DXGIYCbCrTextureData::FillInfo(TextureDa
{
aInfo.size = mSize;
aInfo.format = gfx::SurfaceFormat::YUV;
aInfo.supportsMoz2D = false;
aInfo.hasIntermediateBuffer = false;
aInfo.hasSynchronization = false;
}
+void
+DXGIYCbCrTextureData::SerializeSpecific(SurfaceDescriptorDXGIYCbCr* const aOutDesc)
+{
+ *aOutDesc = SurfaceDescriptorDXGIYCbCr(
+ (WindowsHandle)mHandles[0], (WindowsHandle)mHandles[1], (WindowsHandle)mHandles[2],
+ mSize, mSizeY, mSizeCbCr
+ );
+}
+
bool
DXGIYCbCrTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
{
- aOutDescriptor = SurfaceDescriptorDXGIYCbCr(
- (WindowsHandle)mHandles[0], (WindowsHandle)mHandles[1], (WindowsHandle)mHandles[2],
- mSize, mSizeY, mSizeCbCr
- );
+ SurfaceDescriptorDXGIYCbCr desc;
+ SerializeSpecific(&desc);
+
+ aOutDescriptor = Move(desc);
return true;
}
void
+DXGIYCbCrTextureData::GetSubDescriptor(GPUVideoSubDescriptor* const aOutDesc)
+{
+ SurfaceDescriptorDXGIYCbCr desc;
+ SerializeSpecific(&desc);
+
+ *aOutDesc = Move(desc);
+}
+
+void
DXGIYCbCrTextureData::Deallocate(LayersIPCChannel*)
{
mD3D9Textures[0] = nullptr;
mD3D9Textures[1] = nullptr;
mD3D9Textures[2] = nullptr;
mD3D11Textures[0] = nullptr;
mD3D11Textures[1] = nullptr;
mD3D11Textures[2] = nullptr;
--- a/gfx/layers/d3d11/TextureD3D11.h
+++ b/gfx/layers/d3d11/TextureD3D11.h
@@ -34,17 +34,19 @@ private:
class CompositorD3D11;
class DXGITextureData : public TextureData
{
public:
virtual void FillInfo(TextureData::Info& aInfo) const override;
+ bool SerializeSpecific(SurfaceDescriptorD3D10* aOutDesc);
virtual bool Serialize(SurfaceDescriptor& aOutDescrptor) override;
+ virtual void GetSubDescriptor(GPUVideoSubDescriptor* aOutDesc) override;
static DXGITextureData*
Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, TextureAllocationFlags aFlags);
protected:
bool PrepareDrawTargetInLock(OpenMode aMode);
DXGITextureData(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
@@ -147,17 +149,19 @@ public:
const gfx::IntSize& aSizeCbCr);
virtual bool Lock(OpenMode) override { return true; }
virtual void Unlock() override {}
virtual void FillInfo(TextureData::Info& aInfo) const override;
+ void SerializeSpecific(SurfaceDescriptorDXGIYCbCr* aOutDesc);
virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
+ virtual void GetSubDescriptor(GPUVideoSubDescriptor* aOutDesc) override;
virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() override { return nullptr; }
virtual void Deallocate(LayersIPCChannel* aAllocator) override;
virtual bool UpdateFromSurface(gfx::SourceSurface*) override { return false; }
virtual TextureFlags GetTextureFlags() const override
--- a/gfx/layers/ipc/LayersSurfaces.ipdlh
+++ b/gfx/layers/ipc/LayersSurfaces.ipdlh
@@ -75,18 +75,26 @@ struct EGLImageDescriptor {
struct SurfaceDescriptorSharedGLTexture {
uint32_t texture;
uint32_t target;
uintptr_t fence;
IntSize size;
bool hasAlpha;
};
+
+union GPUVideoSubDescriptor {
+ SurfaceDescriptorD3D10;
+ SurfaceDescriptorDXGIYCbCr;
+ null_t;
+};
+
struct SurfaceDescriptorGPUVideo {
uint64_t handle;
+ GPUVideoSubDescriptor desc;
};
struct RGBDescriptor {
IntSize size;
SurfaceFormat format;
bool hasIntermediateBuffer;
};