/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef MOZILLA_GFX_RENDERD3D11TEXTUREHOST_H #define MOZILLA_GFX_RENDERD3D11TEXTUREHOST_H #include #include "GLTypes.h" #include "mozilla/gfx/FileHandleWrapper.h" #include "RenderTextureHostSWGL.h" struct ID3D11Texture2D; struct IDXGIKeyedMutex; namespace mozilla { namespace layers { class FenceD3D11; } // namespace layers namespace wr { class RenderDXGITextureHost final : public RenderTextureHostSWGL { public: RenderDXGITextureHost( const RefPtr aHandle, const Maybe& aGpuProcessTextureId, const uint32_t aArrayIndex, const gfx::SurfaceFormat aFormat, const gfx::ColorSpace2 aColorSpace, const gfx::ColorRange aColorRange, const gfx::IntSize aSize, const bool aHasKeyedMutex, const Maybe& aFencesHolderId); wr::WrExternalImage Lock(uint8_t aChannelIndex, gl::GLContext* aGL) override; void Unlock() override; void ClearCachedResources() override; gfx::IntSize GetSize(uint8_t aChannelIndex) const; GLuint GetGLHandle(uint8_t aChannelIndex) const; bool SyncObjectNeeded() override; RenderDXGITextureHost* AsRenderDXGITextureHost() override { return this; } gfx::ColorRange GetColorRange() const { return mColorRange; } ID3D11Texture2D* GetD3D11Texture2DWithGL(); ID3D11Texture2D* GetD3D11Texture2D() { return mTexture; } // RenderTextureHostSWGL gfx::SurfaceFormat GetFormat() const override { return mFormat; } gfx::ColorDepth GetColorDepth() const override { if (mFormat == gfx::SurfaceFormat::P010) { return gfx::ColorDepth::COLOR_10; } if (mFormat == gfx::SurfaceFormat::P016) { return gfx::ColorDepth::COLOR_16; } return gfx::ColorDepth::COLOR_8; } size_t GetPlaneCount() const override; bool MapPlane(RenderCompositor* aCompositor, uint8_t aChannelIndex, PlaneInfo& aPlaneInfo) override; void UnmapPlanes() override; gfx::YUVRangedColorSpace GetYUVColorSpace() const override { return ToYUVRangedColorSpace(ToYUVColorSpace(mColorSpace), mColorRange); } bool EnsureD3D11Texture2D(ID3D11Device* aDevice); bool LockInternal(); size_t Bytes() override { size_t bytes = 0; size_t bpp = GetPlaneCount() > 1 ? (GetColorDepth() == gfx::ColorDepth::COLOR_8 ? 1 : 2) : 4; for (size_t i = 0; i < GetPlaneCount(); i++) { gfx::IntSize size = GetSize(i); bytes += size.width * size.height * bpp; } return bytes; } uint32_t ArrayIndex() const { return mArrayIndex; } void SetIsSoftwareDecodedVideo() override { mIsSoftwareDecodedVideo = true; } bool IsSoftwareDecodedVideo() override { return mIsSoftwareDecodedVideo; } private: virtual ~RenderDXGITextureHost(); bool EnsureD3D11Texture2DWithGL(); bool EnsureLockable(); void DeleteTextureHandle(); RefPtr mGL; const RefPtr mHandle; const Maybe mGpuProcessTextureId; RefPtr mTexture; const uint32_t mArrayIndex; RefPtr mKeyedMutex; // Temporary state between MapPlane and UnmapPlanes. RefPtr mDeviceContext; RefPtr mCpuTexture; D3D11_MAPPED_SUBRESOURCE mMappedSubresource; EGLSurface mSurface; EGLStreamKHR mStream; // We could use NV12 format for this texture. So, we might have 2 gl texture // handles for Y and CbCr data. GLuint mTextureHandle[2]; bool mIsSoftwareDecodedVideo = false; public: const gfx::SurfaceFormat mFormat; const gfx::ColorSpace2 mColorSpace; const gfx::ColorRange mColorRange; const gfx::IntSize mSize; const bool mHasKeyedMutex; const Maybe mFencesHolderId; private: bool mLocked; }; class RenderDXGIYCbCrTextureHost final : public RenderTextureHostSWGL { public: explicit RenderDXGIYCbCrTextureHost( RefPtr (&aHandles)[3], const gfx::YUVColorSpace aYUVColorSpace, const gfx::ColorDepth aColorDepth, const gfx::ColorRange aColorRange, const gfx::IntSize aSizeY, const gfx::IntSize aSizeCbCr, const layers::CompositeProcessFencesHolderId aFencesHolderId); RenderDXGIYCbCrTextureHost* AsRenderDXGIYCbCrTextureHost() override { return this; } wr::WrExternalImage Lock(uint8_t aChannelIndex, gl::GLContext* aGL) override; void Unlock() override; void ClearCachedResources() override; gfx::IntSize GetSize(uint8_t aChannelIndex) const; GLuint GetGLHandle(uint8_t aChannelIndex) const; bool SyncObjectNeeded() override { return true; } gfx::ColorRange GetColorRange() const { return mColorRange; } // RenderTextureHostSWGL gfx::SurfaceFormat GetFormat() const override { return gfx::SurfaceFormat::YUV420; } gfx::ColorDepth GetColorDepth() const override { return mColorDepth; } size_t GetPlaneCount() const override { return 3; } bool MapPlane(RenderCompositor* aCompositor, uint8_t aChannelIndex, PlaneInfo& aPlaneInfo) override; void UnmapPlanes() override; gfx::YUVRangedColorSpace GetYUVColorSpace() const override { return ToYUVRangedColorSpace(mYUVColorSpace, GetColorRange()); } bool EnsureD3D11Texture2D(ID3D11Device* aDevice); bool LockInternal(); ID3D11Texture2D* GetD3D11Texture2D(uint8_t aChannelIndex) { return mTextures[aChannelIndex]; } size_t Bytes() override { size_t bytes = 0; size_t bpp = mColorDepth == gfx::ColorDepth::COLOR_8 ? 1 : 2; for (size_t i = 0; i < GetPlaneCount(); i++) { gfx::IntSize size = GetSize(i); bytes += size.width * size.height * bpp; } return bytes; } private: virtual ~RenderDXGIYCbCrTextureHost(); bool EnsureLockable(); void DeleteTextureHandle(); RefPtr mGL; RefPtr mHandles[3]; RefPtr mTextures[3]; RefPtr mDevice; EGLSurface mSurfaces[3]; EGLStreamKHR mStreams[3]; // The gl handles for Y, Cb and Cr data. GLuint mTextureHandles[3]; // Temporary state between MapPlane and UnmapPlanes. RefPtr mDeviceContext; RefPtr mCpuTexture[3]; const gfx::YUVColorSpace mYUVColorSpace; const gfx::ColorDepth mColorDepth; const gfx::ColorRange mColorRange; const gfx::IntSize mSizeY; const gfx::IntSize mSizeCbCr; const layers::CompositeProcessFencesHolderId mFencesHolderId; bool mLocked = false; }; } // namespace wr } // namespace mozilla #endif // MOZILLA_GFX_RENDERD3D11TEXTUREHOST_H