зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1322746 - Support PLANAR_YCBCR, GPU_VIDEO, and D3D11_YCBCR_IMAGE in GLBlitHelper. - r=jerry
MozReview-Commit-ID: FNsmq0RPvYB
This commit is contained in:
Родитель
816740fb9e
Коммит
8a890b29aa
|
@ -5249,9 +5249,17 @@ CanvasRenderingContext2D::DrawImage(const CanvasImageSource& aImage,
|
|||
gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_LINEAR);
|
||||
|
||||
const gl::OriginPos destOrigin = gl::OriginPos::TopLeft;
|
||||
bool ok = gl->BlitHelper()->BlitImageToTexture(srcImage, srcImage->GetSize(),
|
||||
videoTexture, LOCAL_GL_TEXTURE_2D,
|
||||
destOrigin);
|
||||
bool ok = false;
|
||||
do {
|
||||
const gl::ScopedFramebufferForTexture autoFBForTex(gl, videoTexture);
|
||||
if (!autoFBForTex.IsComplete()) {
|
||||
MOZ_ASSERT(false, "ScopedFramebufferForTexture not complete.");
|
||||
break;
|
||||
}
|
||||
const gl::ScopedBindFramebuffer bindFB(gl, autoFBForTex.FB());
|
||||
ok = gl->BlitHelper()->BlitImageToFramebuffer(srcImage, srcImage->GetSize(),
|
||||
destOrigin);
|
||||
} while (false);
|
||||
if (ok) {
|
||||
NativeSurface texSurf;
|
||||
texSurf.mType = NativeSurfaceType::OPENGL_TEXTURE;
|
||||
|
|
|
@ -701,9 +701,7 @@ TexUnpackImage::TexOrSubImage(bool isSubImage, bool needsRespec, const char* fun
|
|||
const gfx::IntSize destSize(mWidth, mHeight);
|
||||
const auto dstOrigin = (webgl->mPixelStore_FlipY ? gl::OriginPos::TopLeft
|
||||
: gl::OriginPos::BottomLeft);
|
||||
if (!gl->BlitHelper()->BlitImageToFramebuffer(mImage, destSize, scopedFB.FB(),
|
||||
dstOrigin))
|
||||
{
|
||||
if (!gl->BlitHelper()->BlitImageToFramebuffer(mImage, destSize, dstOrigin)) {
|
||||
fallbackReason = "likely bug: failed to blit";
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -721,6 +721,12 @@ WebGLContext::InitAndValidateGL(FailureReason* const out_failReason)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!gl->IsSupported(GLFeature::vertex_array_object)) {
|
||||
*out_failReason = { "FEATURE_FAILURE_WEBGL_VAOS",
|
||||
"Requires vertex_array_object." };
|
||||
return false;
|
||||
}
|
||||
|
||||
mDefaultVertexArray = WebGLVertexArray::Create(this);
|
||||
mDefaultVertexArray->mAttribs.SetLength(mGLMaxVertexAttribs);
|
||||
mBoundVertexArray = mDefaultVertexArray;
|
||||
|
|
|
@ -1833,8 +1833,11 @@ ScopedCopyTexImageSource::ScopedCopyTexImageSource(WebGLContext* webgl,
|
|||
|
||||
// Draw-blit rgbaTex into rgbaFB.
|
||||
const gfx::IntSize srcSize(srcWidth, srcHeight);
|
||||
gl->BlitHelper()->DrawBlitTextureToFramebuffer(scopedTex.Texture(), rgbaFB,
|
||||
srcSize, srcSize);
|
||||
{
|
||||
const gl::ScopedBindFramebuffer bindFB(gl, rgbaFB);
|
||||
gl->BlitHelper()->DrawBlitTextureToFramebuffer(scopedTex.Texture(), srcSize,
|
||||
srcSize);
|
||||
}
|
||||
|
||||
// Restore Tex2D binding and destroy the temp tex.
|
||||
scopedBindTex.Unwrap();
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -10,152 +10,178 @@
|
|||
#include "GLContextTypes.h"
|
||||
#include "GLConsts.h"
|
||||
#include "nsSize.h"
|
||||
#include "ipc/IPCMessageUtils.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/gfx/Point.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace layers {
|
||||
class D3D11YCbCrImage;
|
||||
class Image;
|
||||
class GPUVideoImage;
|
||||
class PlanarYCbCrImage;
|
||||
class SurfaceTextureImage;
|
||||
class MacIOSurfaceImage;
|
||||
class EGLImageImage;
|
||||
class SurfaceDescriptorD3D10;
|
||||
class SurfaceDescriptorDXGIYCbCr;
|
||||
} // namespace layers
|
||||
|
||||
namespace gl {
|
||||
|
||||
class BindAnglePlanes;
|
||||
class GLContext;
|
||||
|
||||
bool
|
||||
GuessDivisors(const gfx::IntSize& ySize, const gfx::IntSize& uvSize,
|
||||
gfx::IntSize* const out_divisors);
|
||||
|
||||
class DrawBlitProg final
|
||||
{
|
||||
GLBlitHelper& mParent;
|
||||
const GLuint mProg;
|
||||
const GLint mLoc_u1ForYFlip;
|
||||
const GLint mLoc_uClipRect;
|
||||
const GLint mLoc_uTexSize0;
|
||||
const GLint mLoc_uTexSize1;
|
||||
const GLint mLoc_uDivisors;
|
||||
const GLint mLoc_uColorMatrix;
|
||||
|
||||
public:
|
||||
DrawBlitProg(GLBlitHelper* parent, GLuint prog);
|
||||
~DrawBlitProg();
|
||||
|
||||
struct BaseArgs final {
|
||||
gfx::IntSize destSize;
|
||||
bool yFlip;
|
||||
gfx::IntRect clipRect;
|
||||
gfx::IntSize texSize0;
|
||||
};
|
||||
struct YUVArgs final {
|
||||
gfx::IntSize texSize1;
|
||||
gfx::IntSize divisors;
|
||||
YUVColorSpace colorSpace;
|
||||
};
|
||||
|
||||
void Draw(const BaseArgs& args, const YUVArgs* argsYUV = nullptr) const;
|
||||
};
|
||||
|
||||
class ScopedSaveMultiTex final
|
||||
{
|
||||
GLContext& mGL;
|
||||
const uint8_t mTexCount;
|
||||
const GLenum mTexTarget;
|
||||
const GLuint mOldTexUnit;
|
||||
GLuint mOldTexSampler[3];
|
||||
GLuint mOldTex[3];
|
||||
|
||||
public:
|
||||
ScopedSaveMultiTex(GLContext* gl, uint8_t texCount, GLenum texTarget);
|
||||
~ScopedSaveMultiTex();
|
||||
};
|
||||
|
||||
/** Buffer blitting helper */
|
||||
class GLBlitHelper final
|
||||
{
|
||||
enum Channel
|
||||
friend class BindAnglePlanes;
|
||||
friend class DrawBlitProg;
|
||||
friend class GLContext;
|
||||
|
||||
enum class DrawBlitType : uint8_t
|
||||
{
|
||||
Channel_Y = 0,
|
||||
Channel_Cb,
|
||||
Channel_Cr,
|
||||
Channel_Max,
|
||||
Tex2DRGBA,
|
||||
Tex2DPlanarYUV,
|
||||
TexRectRGBA,
|
||||
//TexExtYUV,
|
||||
TexExtNV12,
|
||||
TexExtPlanarYUV,
|
||||
};
|
||||
|
||||
/**
|
||||
* BlitTex2D is used to copy blit the content of a GL_TEXTURE_2D object,
|
||||
* BlitTexRect is used to copy blit the content of a GL_TEXTURE_RECT object,
|
||||
* The difference between BlitTex2D and BlitTexRect is the texture type, which affect
|
||||
* the fragment shader a bit.
|
||||
*
|
||||
* ConvertPlnarYcbCr is used to color convert copy blit the PlanarYCbCrImage
|
||||
* into a normal RGB texture by create textures of each color channel, and
|
||||
* convert it in GPU.
|
||||
* Convert type is created for canvas.
|
||||
*/
|
||||
enum BlitType
|
||||
{
|
||||
BlitTex2D,
|
||||
BlitTexRect,
|
||||
ConvertPlanarYCbCr,
|
||||
ConvertSurfaceTexture,
|
||||
ConvertEGLImage,
|
||||
ConvertMacIOSurfaceImage
|
||||
};
|
||||
// The GLContext is the sole owner of the GLBlitHelper.
|
||||
GLContext* mGL;
|
||||
GLContext* const mGL;
|
||||
std::map<uint8_t, UniquePtr<DrawBlitProg>> mDrawBlitProgs;
|
||||
|
||||
GLuint mTexBlit_Buffer;
|
||||
GLuint mTexBlit_VertShader;
|
||||
GLuint mTex2DBlit_FragShader;
|
||||
GLuint mTex2DRectBlit_FragShader;
|
||||
GLuint mTex2DBlit_Program;
|
||||
GLuint mTex2DRectBlit_Program;
|
||||
GLuint mQuadVAO;
|
||||
|
||||
GLint mYFlipLoc;
|
||||
GLuint mYuvUploads[3];
|
||||
gfx::IntSize mYuvUploads_YSize;
|
||||
gfx::IntSize mYuvUploads_UVSize;
|
||||
|
||||
GLint mTextureTransformLoc;
|
||||
#ifdef XP_WIN
|
||||
mutable RefPtr<ID3D11Device> mD3D11;
|
||||
|
||||
// Data for image blit path
|
||||
GLuint mTexExternalBlit_FragShader;
|
||||
GLuint mTexYUVPlanarBlit_FragShader;
|
||||
GLuint mTexNV12PlanarBlit_FragShader;
|
||||
GLuint mTexExternalBlit_Program;
|
||||
GLuint mTexYUVPlanarBlit_Program;
|
||||
GLuint mTexNV12PlanarBlit_Program;
|
||||
GLuint mFBO;
|
||||
GLuint mSrcTexY;
|
||||
GLuint mSrcTexCb;
|
||||
GLuint mSrcTexCr;
|
||||
GLuint mSrcTexEGL;
|
||||
GLint mYTexScaleLoc;
|
||||
GLint mCbCrTexScaleLoc;
|
||||
GLint mYuvColorMatrixLoc;
|
||||
int mTexWidth;
|
||||
int mTexHeight;
|
||||
ID3D11Device* GetD3D11() const;
|
||||
#endif
|
||||
|
||||
// Cache some uniform values
|
||||
float mCurYScale;
|
||||
float mCurCbCrScale;
|
||||
|
||||
void UseBlitProgram();
|
||||
void SetBlitFramebufferForDestTexture(GLuint aTexture);
|
||||
|
||||
bool UseTexQuadProgram(BlitType target, const gfx::IntSize& srcSize);
|
||||
bool InitTexQuadProgram(BlitType target = BlitTex2D);
|
||||
void DeleteTexBlitProgram();
|
||||
void BindAndUploadYUVTexture(Channel which, uint32_t width, uint32_t height, void* data, bool allocation);
|
||||
void BindAndUploadEGLImage(EGLImage image, GLuint target);
|
||||
const DrawBlitProg* GetDrawBlitProg(DrawBlitType type) const;
|
||||
|
||||
bool BlitPlanarYCbCrImage(layers::PlanarYCbCrImage* yuvImage);
|
||||
bool BlitImage(layers::PlanarYCbCrImage* yuvImage, const gfx::IntSize& destSize,
|
||||
OriginPos destOrigin);
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
// Blit onto the current FB.
|
||||
bool BlitSurfaceTextureImage(layers::SurfaceTextureImage* stImage);
|
||||
bool BlitEGLImageImage(layers::EGLImageImage* eglImage);
|
||||
bool BlitImage(layers::SurfaceTextureImage* stImage);
|
||||
bool BlitImage(layers::EGLImageImage* eglImage);
|
||||
#endif
|
||||
#ifdef XP_MACOSX
|
||||
bool BlitMacIOSurfaceImage(layers::MacIOSurfaceImage* ioImage);
|
||||
bool BlitImage(layers::MacIOSurfaceImage* ioImage);
|
||||
#endif
|
||||
|
||||
explicit GLBlitHelper(GLContext* gl);
|
||||
|
||||
friend class GLContext;
|
||||
|
||||
public:
|
||||
~GLBlitHelper();
|
||||
|
||||
// If you don't have |srcFormats| for the 2nd definition,
|
||||
// then you'll need the framebuffer_blit extensions to use
|
||||
// the first BlitFramebufferToFramebuffer.
|
||||
void BlitFramebuffer(const gfx::IntSize& srcSize,
|
||||
const gfx::IntSize& destSize) const;
|
||||
void BlitFramebufferToFramebuffer(GLuint srcFB, GLuint destFB,
|
||||
const gfx::IntSize& srcSize,
|
||||
const gfx::IntSize& destSize,
|
||||
bool internalFBs = false);
|
||||
void BlitFramebufferToFramebuffer(GLuint srcFB, GLuint destFB,
|
||||
const gfx::IntSize& srcSize,
|
||||
const gfx::IntSize& destSize,
|
||||
const GLFormats& srcFormats,
|
||||
bool internalFBs = false);
|
||||
void BlitTextureToFramebuffer(GLuint srcTex, GLuint destFB,
|
||||
const gfx::IntSize& srcSize,
|
||||
const gfx::IntSize& destSize) const;
|
||||
void BlitFramebufferToTexture(GLuint destTex, const gfx::IntSize& srcSize,
|
||||
const gfx::IntSize& destSize,
|
||||
GLenum srcTarget = LOCAL_GL_TEXTURE_2D,
|
||||
bool internalFBs = false);
|
||||
void DrawBlitTextureToFramebuffer(GLuint srcTex, GLuint destFB,
|
||||
const gfx::IntSize& srcSize,
|
||||
const gfx::IntSize& destSize,
|
||||
GLenum srcTarget = LOCAL_GL_TEXTURE_2D,
|
||||
bool internalFBs = false);
|
||||
void BlitFramebufferToTexture(GLuint srcFB, GLuint destTex,
|
||||
const gfx::IntSize& srcSize,
|
||||
GLenum destTarget = LOCAL_GL_TEXTURE_2D) const;
|
||||
void BlitTextureToFramebuffer(GLuint srcTex, const gfx::IntSize& srcSize,
|
||||
const gfx::IntSize& destSize,
|
||||
GLenum destTarget = LOCAL_GL_TEXTURE_2D,
|
||||
bool internalFBs = false);
|
||||
GLenum srcTarget = LOCAL_GL_TEXTURE_2D) const;
|
||||
void BlitTextureToTexture(GLuint srcTex, GLuint destTex,
|
||||
const gfx::IntSize& srcSize,
|
||||
const gfx::IntSize& destSize,
|
||||
GLenum srcTarget = LOCAL_GL_TEXTURE_2D,
|
||||
GLenum destTarget = LOCAL_GL_TEXTURE_2D);
|
||||
GLenum destTarget = LOCAL_GL_TEXTURE_2D) const;
|
||||
|
||||
|
||||
void DrawBlitTextureToFramebuffer(GLuint srcTex, const gfx::IntSize& srcSize,
|
||||
const gfx::IntSize& destSize,
|
||||
GLenum srcTarget = LOCAL_GL_TEXTURE_2D) const;
|
||||
|
||||
bool BlitImageToFramebuffer(layers::Image* srcImage, const gfx::IntSize& destSize,
|
||||
GLuint destFB, OriginPos destOrigin);
|
||||
bool BlitImageToTexture(layers::Image* srcImage, const gfx::IntSize& destSize,
|
||||
GLuint destTex, GLenum destTarget, OriginPos destOrigin);
|
||||
OriginPos destOrigin);
|
||||
|
||||
private:
|
||||
#ifdef XP_WIN
|
||||
// GLBlitHelperD3D.cpp:
|
||||
bool BlitImage(layers::GPUVideoImage* srcImage, const gfx::IntSize& destSize,
|
||||
OriginPos destOrigin) const;
|
||||
bool BlitImage(layers::D3D11YCbCrImage* srcImage, const gfx::IntSize& destSize,
|
||||
OriginPos destOrigin) const;
|
||||
|
||||
bool BlitDescriptor(const layers::SurfaceDescriptorD3D10& desc,
|
||||
const gfx::IntSize& destSize, OriginPos destOrigin) const;
|
||||
|
||||
bool BlitAngleYCbCr(const WindowsHandle (&handleList)[3],
|
||||
const gfx::IntRect& clipRect,
|
||||
const gfx::IntSize& ySize, const gfx::IntSize& uvSize,
|
||||
const YUVColorSpace colorSpace,
|
||||
const gfx::IntSize& destSize, OriginPos destOrigin) const;
|
||||
|
||||
bool BlitAnglePlanes(uint8_t numPlanes, const RefPtr<ID3D11Texture2D>* texD3DList,
|
||||
const DrawBlitProg* prog, const DrawBlitProg::BaseArgs& baseArgs,
|
||||
const DrawBlitProg::YUVArgs* const yuvArgs) const;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace gl
|
||||
|
|
|
@ -0,0 +1,334 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim: set ts=8 sts=4 et sw=4 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/. */
|
||||
|
||||
#include "GLBlitHelper.h"
|
||||
|
||||
#include <d3d11.h>
|
||||
|
||||
#include "GLContext.h"
|
||||
#include "GLLibraryEGL.h"
|
||||
#include "GPUVideoImage.h"
|
||||
#include "ScopedGLHelpers.h"
|
||||
|
||||
#include "mozilla/layers/D3D11YCbCrImage.h"
|
||||
#include "mozilla/layers/TextureD3D11.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
|
||||
static EGLStreamKHR
|
||||
StreamFromD3DTexture(ID3D11Texture2D* const texD3D,
|
||||
const EGLAttrib* const postAttribs)
|
||||
{
|
||||
auto& egl = sEGLLibrary;
|
||||
const auto& display = egl.Display();
|
||||
const auto stream = egl.fCreateStreamKHR(display, nullptr);
|
||||
MOZ_ASSERT(stream);
|
||||
if (!stream)
|
||||
return 0;
|
||||
bool ok = true;
|
||||
MOZ_ALWAYS_TRUE( ok &= bool(egl.fStreamConsumerGLTextureExternalAttribsNV(display,
|
||||
stream,
|
||||
nullptr)) );
|
||||
MOZ_ALWAYS_TRUE( ok &= bool(egl.fCreateStreamProducerD3DTextureNV12ANGLE(display,
|
||||
stream,
|
||||
nullptr)) );
|
||||
MOZ_ALWAYS_TRUE( ok &= bool(egl.fStreamPostD3DTextureNV12ANGLE(display, stream,
|
||||
texD3D,
|
||||
postAttribs)) );
|
||||
if (ok)
|
||||
return stream;
|
||||
|
||||
(void)egl.fDestroyStreamKHR(display, stream);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static RefPtr<ID3D11Texture2D>
|
||||
OpenSharedTexture(ID3D11Device* const d3d, const WindowsHandle handle)
|
||||
{
|
||||
RefPtr<ID3D11Texture2D> tex;
|
||||
auto hr = d3d->OpenSharedResource((HANDLE)handle, __uuidof(ID3D11Texture2D),
|
||||
(void**)(ID3D11Texture2D**)getter_AddRefs(tex));
|
||||
if (FAILED(hr)) {
|
||||
MOZ_ASSERT(false, "OpenSharedResource should not fail");
|
||||
return nullptr;
|
||||
}
|
||||
return tex;
|
||||
}
|
||||
|
||||
// -------------------------------------
|
||||
|
||||
class BindAnglePlanes final
|
||||
{
|
||||
const GLBlitHelper& mParent;
|
||||
const uint8_t mNumPlanes;
|
||||
const ScopedSaveMultiTex mMultiTex;
|
||||
GLuint mTempTexs[3];
|
||||
EGLStreamKHR mStreams[3];
|
||||
RefPtr<IDXGIKeyedMutex> mMutexList[3];
|
||||
bool mSuccess;
|
||||
|
||||
public:
|
||||
BindAnglePlanes(const GLBlitHelper* const parent, const uint8_t numPlanes,
|
||||
const RefPtr<ID3D11Texture2D>* const texD3DList,
|
||||
const EGLAttrib* const* postAttribsList = nullptr)
|
||||
: mParent(*parent)
|
||||
, mNumPlanes(numPlanes)
|
||||
, mMultiTex(mParent.mGL, mNumPlanes, LOCAL_GL_TEXTURE_EXTERNAL)
|
||||
, mTempTexs{0}
|
||||
, mStreams{0}
|
||||
, mSuccess(true)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(numPlanes >= 1 && numPlanes <= 3);
|
||||
|
||||
const auto& gl = mParent.mGL;
|
||||
auto& egl = sEGLLibrary;
|
||||
const auto& display = egl.Display();
|
||||
|
||||
gl->fGenTextures(numPlanes, mTempTexs);
|
||||
|
||||
for (uint8_t i = 0; i < mNumPlanes; i++) {
|
||||
gl->fActiveTexture(LOCAL_GL_TEXTURE0 + i);
|
||||
gl->fBindTexture(LOCAL_GL_TEXTURE_EXTERNAL, mTempTexs[i]);
|
||||
const EGLAttrib* postAttribs = nullptr;
|
||||
if (postAttribsList) {
|
||||
postAttribs = postAttribsList[i];
|
||||
}
|
||||
mStreams[i] = StreamFromD3DTexture(texD3DList[i], postAttribs);
|
||||
mSuccess &= bool(mStreams[i]);
|
||||
}
|
||||
|
||||
if (mSuccess) {
|
||||
for (uint8_t i = 0; i < mNumPlanes; i++) {
|
||||
MOZ_ALWAYS_TRUE( egl.fStreamConsumerAcquireKHR(display, mStreams[i]) );
|
||||
|
||||
auto& mutex = mMutexList[i];
|
||||
texD3DList[i]->QueryInterface(_uuidof(IDXGIKeyedMutex),
|
||||
(void**)getter_AddRefs(mutex));
|
||||
if (mutex) {
|
||||
const auto hr = mutex->AcquireSync(0, 100);
|
||||
if (FAILED(hr)) {
|
||||
NS_WARNING("BindAnglePlanes failed to acquire KeyedMutex.");
|
||||
mSuccess = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
~BindAnglePlanes()
|
||||
{
|
||||
const auto& gl = mParent.mGL;
|
||||
auto& egl = sEGLLibrary;
|
||||
const auto& display = egl.Display();
|
||||
|
||||
if (mSuccess) {
|
||||
for (uint8_t i = 0; i < mNumPlanes; i++) {
|
||||
MOZ_ALWAYS_TRUE( egl.fStreamConsumerReleaseKHR(display, mStreams[i]) );
|
||||
if (mMutexList[i]) {
|
||||
mMutexList[i]->ReleaseSync(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < mNumPlanes; i++) {
|
||||
(void)egl.fDestroyStreamKHR(display, mStreams[i]);
|
||||
}
|
||||
|
||||
gl->fDeleteTextures(mNumPlanes, mTempTexs);
|
||||
}
|
||||
|
||||
const bool& Success() const { return mSuccess; }
|
||||
};
|
||||
|
||||
// -------------------------------------
|
||||
|
||||
ID3D11Device*
|
||||
GLBlitHelper::GetD3D11() const
|
||||
{
|
||||
if (mD3D11)
|
||||
return mD3D11;
|
||||
|
||||
if (!mGL->IsANGLE())
|
||||
return nullptr;
|
||||
|
||||
auto& egl = sEGLLibrary;
|
||||
EGLDeviceEXT deviceEGL = 0;
|
||||
MOZ_ALWAYS_TRUE( egl.fQueryDisplayAttribEXT(egl.Display(), LOCAL_EGL_DEVICE_EXT,
|
||||
(EGLAttrib*)&deviceEGL) );
|
||||
if (!egl.fQueryDeviceAttribEXT(deviceEGL, LOCAL_EGL_D3D11_DEVICE_ANGLE,
|
||||
(EGLAttrib*)(ID3D11Device**)getter_AddRefs(mD3D11)))
|
||||
{
|
||||
MOZ_ASSERT(false, "d3d9?");
|
||||
return nullptr;
|
||||
}
|
||||
return mD3D11;
|
||||
}
|
||||
|
||||
// -------------------------------------
|
||||
|
||||
bool
|
||||
GLBlitHelper::BlitImage(layers::GPUVideoImage* const srcImage,
|
||||
const gfx::IntSize& destSize, const OriginPos destOrigin) const
|
||||
{
|
||||
const auto& data = srcImage->GetData();
|
||||
if (!data)
|
||||
return false;
|
||||
|
||||
const auto& desc = data->SD();
|
||||
const auto& subdescUnion = desc.subdesc();
|
||||
switch (subdescUnion.type()) {
|
||||
case subdescUnion.TSurfaceDescriptorD3D10:
|
||||
{
|
||||
const auto& subdesc = subdescUnion.get_SurfaceDescriptorD3D10();
|
||||
return BlitDescriptor(subdesc, destSize, destOrigin);
|
||||
}
|
||||
case subdescUnion.TSurfaceDescriptorDXGIYCbCr:
|
||||
{
|
||||
const auto& subdesc = subdescUnion.get_SurfaceDescriptorDXGIYCbCr();
|
||||
|
||||
const auto& clipSize = subdesc.size();
|
||||
const auto& ySize = subdesc.sizeY();
|
||||
const auto& uvSize = subdesc.sizeCbCr();
|
||||
|
||||
const gfx::IntRect clipRect(0, 0, clipSize.width, clipSize.height);
|
||||
const auto colorSpace = YUVColorSpace::BT601;
|
||||
|
||||
const WindowsHandle handles[3] = {
|
||||
subdesc.handleY(),
|
||||
subdesc.handleCb(),
|
||||
subdesc.handleCr()
|
||||
};
|
||||
return BlitAngleYCbCr(handles, clipRect, ySize, uvSize, colorSpace, destSize,
|
||||
destOrigin);
|
||||
}
|
||||
default:
|
||||
gfxCriticalError() << "Unhandled subdesc type: " << uint32_t(subdescUnion.type());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------
|
||||
|
||||
bool
|
||||
GLBlitHelper::BlitImage(layers::D3D11YCbCrImage* const srcImage,
|
||||
const gfx::IntSize& destSize, const OriginPos destOrigin) const
|
||||
{
|
||||
const auto& data = srcImage->GetData();
|
||||
if (!data)
|
||||
return false;
|
||||
|
||||
const auto& clipRect = srcImage->mPictureRect;
|
||||
const auto& colorSpace = srcImage->mColorSpace;
|
||||
|
||||
const WindowsHandle handles[3] = {
|
||||
(WindowsHandle)data->mHandles[0],
|
||||
(WindowsHandle)data->mHandles[1],
|
||||
(WindowsHandle)data->mHandles[2]
|
||||
};
|
||||
return BlitAngleYCbCr(handles, srcImage->mPictureRect, srcImage->mYSize,
|
||||
srcImage->mCbCrSize, srcImage->mColorSpace, destSize,
|
||||
destOrigin);
|
||||
}
|
||||
|
||||
// -------------------------------------
|
||||
|
||||
bool
|
||||
GLBlitHelper::BlitDescriptor(const layers::SurfaceDescriptorD3D10& desc,
|
||||
const gfx::IntSize& destSize, OriginPos destOrigin) const
|
||||
{
|
||||
const auto& d3d = GetD3D11();
|
||||
if (!d3d)
|
||||
return false;
|
||||
|
||||
const auto& handle = desc.handle();
|
||||
const auto& format = desc.format();
|
||||
const auto& clipSize = desc.size();
|
||||
|
||||
const auto srcOrigin = OriginPos::BottomLeft;
|
||||
const gfx::IntRect clipRect(0, 0, clipSize.width, clipSize.height);
|
||||
const auto colorSpace = YUVColorSpace::BT601;
|
||||
|
||||
if (format != gfx::SurfaceFormat::NV12) {
|
||||
gfxCriticalError() << "Non-NV12 format for SurfaceDescriptorD3D10: "
|
||||
<< uint32_t(format);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const auto tex = OpenSharedTexture(d3d, handle);
|
||||
const RefPtr<ID3D11Texture2D> texList[2] = { tex, tex };
|
||||
const EGLAttrib postAttribs0[] = {
|
||||
LOCAL_EGL_NATIVE_BUFFER_PLANE_OFFSET_IMG, 0,
|
||||
LOCAL_EGL_NONE
|
||||
};
|
||||
const EGLAttrib postAttribs1[] = {
|
||||
LOCAL_EGL_NATIVE_BUFFER_PLANE_OFFSET_IMG, 1,
|
||||
LOCAL_EGL_NONE
|
||||
};
|
||||
const EGLAttrib* const postAttribsList[2] = { postAttribs0, postAttribs1 };
|
||||
// /layers/d3d11/CompositorD3D11.cpp uses bt601 for EffectTypes::NV12.
|
||||
//return BlitAngleNv12(tex, YUVColorSpace::BT601, destSize, destOrigin);
|
||||
|
||||
const BindAnglePlanes bindPlanes(this, 2, texList, postAttribsList);
|
||||
|
||||
D3D11_TEXTURE2D_DESC texDesc = {0};
|
||||
tex->GetDesc(&texDesc);
|
||||
|
||||
const gfx::IntSize ySize(texDesc.Width, texDesc.Height);
|
||||
const gfx::IntSize divisors(2, 2);
|
||||
MOZ_ASSERT(ySize.width % divisors.width == 0);
|
||||
MOZ_ASSERT(ySize.height % divisors.height == 0);
|
||||
const gfx::IntSize uvSize(ySize.width / divisors.width,
|
||||
ySize.height / divisors.height);
|
||||
|
||||
const bool yFlip = destOrigin != srcOrigin;
|
||||
const DrawBlitProg::BaseArgs baseArgs = { destSize, yFlip, clipRect, ySize };
|
||||
const DrawBlitProg::YUVArgs yuvArgs = { uvSize, divisors, colorSpace };
|
||||
|
||||
const auto& prog = GetDrawBlitProg(DrawBlitType::TexExtNV12);
|
||||
MOZ_RELEASE_ASSERT(prog);
|
||||
prog->Draw(baseArgs, &yuvArgs);
|
||||
return true;
|
||||
}
|
||||
|
||||
// --
|
||||
|
||||
bool
|
||||
GLBlitHelper::BlitAngleYCbCr(const WindowsHandle (&handleList)[3],
|
||||
const gfx::IntRect& clipRect,
|
||||
const gfx::IntSize& ySize, const gfx::IntSize& uvSize,
|
||||
const YUVColorSpace colorSpace,
|
||||
const gfx::IntSize& destSize, OriginPos destOrigin) const
|
||||
{
|
||||
const auto& d3d = GetD3D11();
|
||||
if (!d3d)
|
||||
return false;
|
||||
|
||||
const auto srcOrigin = OriginPos::BottomLeft;
|
||||
|
||||
gfx::IntSize divisors;
|
||||
if (!GuessDivisors(ySize, uvSize, &divisors))
|
||||
return false;
|
||||
|
||||
const RefPtr<ID3D11Texture2D> texList[3] = {
|
||||
OpenSharedTexture(d3d, handleList[0]),
|
||||
OpenSharedTexture(d3d, handleList[1]),
|
||||
OpenSharedTexture(d3d, handleList[2])
|
||||
};
|
||||
const BindAnglePlanes bindPlanes(this, 3, texList);
|
||||
|
||||
const bool yFlip = destOrigin != srcOrigin;
|
||||
const DrawBlitProg::BaseArgs baseArgs = { destSize, yFlip, clipRect, ySize };
|
||||
const DrawBlitProg::YUVArgs yuvArgs = { uvSize, divisors, colorSpace };
|
||||
|
||||
const auto& prog = GetDrawBlitProg(DrawBlitType::TexExtPlanarYUV);
|
||||
MOZ_RELEASE_ASSERT(prog);
|
||||
prog->Draw(baseArgs, &yuvArgs);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace gl
|
||||
} // namespace mozilla
|
|
@ -1417,6 +1417,22 @@ public:
|
|||
return retval;
|
||||
}
|
||||
|
||||
void SetEnabled(const GLenum cap, const bool val) {
|
||||
if (val) {
|
||||
fEnable(cap);
|
||||
} else {
|
||||
fDisable(cap);
|
||||
}
|
||||
}
|
||||
|
||||
bool PushEnabled(const GLenum cap, const bool newVal) {
|
||||
const bool oldVal = fIsEnabled(cap);
|
||||
if (oldVal != newVal) {
|
||||
SetEnabled(cap, newVal);
|
||||
}
|
||||
return oldVal;
|
||||
}
|
||||
|
||||
realGLboolean fIsProgram(GLuint program) {
|
||||
BEFORE_GL_CALL;
|
||||
realGLboolean retval = mSymbols.fIsProgram(program);
|
||||
|
|
|
@ -114,7 +114,7 @@ protected:
|
|||
friend class GLContextEGLFactory;
|
||||
|
||||
public:
|
||||
const EGLConfig mConfig;
|
||||
const EGLConfig mConfig;
|
||||
protected:
|
||||
EGLSurface mSurface;
|
||||
public:
|
||||
|
|
|
@ -610,6 +610,7 @@ GLLibraryEGL::EnsureInitialized(bool forceAccel, nsACString* const out_failureId
|
|||
|
||||
if (IsExtensionSupported(KHR_stream_consumer_gltexture)) {
|
||||
const GLLibraryLoader::SymLoadStruct streamConsumerSymbols[] = {
|
||||
SYMBOL(StreamConsumerGLTextureExternalKHR),
|
||||
SYMBOL(StreamConsumerAcquireKHR),
|
||||
SYMBOL(StreamConsumerReleaseKHR),
|
||||
END_OF_SYMBOLS
|
||||
|
|
|
@ -300,6 +300,9 @@ public:
|
|||
WRAP( fQueryStreamKHR(dpy, stream, attribute, value) )
|
||||
|
||||
// KHR_stream_consumer_gltexture
|
||||
EGLBoolean fStreamConsumerGLTextureExternalKHR(EGLDisplay dpy, EGLStreamKHR stream) const
|
||||
WRAP( fStreamConsumerGLTextureExternalKHR(dpy, stream) )
|
||||
|
||||
EGLBoolean fStreamConsumerAcquireKHR(EGLDisplay dpy, EGLStreamKHR stream) const
|
||||
WRAP( fStreamConsumerAcquireKHR(dpy, stream) )
|
||||
|
||||
|
@ -467,6 +470,8 @@ private:
|
|||
EGLenum attribute,
|
||||
EGLint* value);
|
||||
// KHR_stream_consumer_gltexture
|
||||
EGLBoolean (GLAPIENTRY * fStreamConsumerGLTextureExternalKHR)(EGLDisplay dpy,
|
||||
EGLStreamKHR stream);
|
||||
EGLBoolean (GLAPIENTRY * fStreamConsumerAcquireKHR)(EGLDisplay dpy,
|
||||
EGLStreamKHR stream);
|
||||
EGLBoolean (GLAPIENTRY * fStreamConsumerReleaseKHR)(EGLDisplay dpy,
|
||||
|
|
|
@ -23,7 +23,7 @@ class HeapCopyOfStackArray
|
|||
{
|
||||
public:
|
||||
template<size_t N>
|
||||
MOZ_IMPLICIT HeapCopyOfStackArray(ElemType (&array)[N])
|
||||
MOZ_IMPLICIT HeapCopyOfStackArray(const ElemType (&array)[N])
|
||||
: mArrayLength(N)
|
||||
, mArrayData(MakeUnique<ElemType[]>(N))
|
||||
{
|
||||
|
|
|
@ -423,75 +423,6 @@ ScopedVertexAttribPointer::UnwrapImpl()
|
|||
mGL->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mBoundBuffer);
|
||||
}
|
||||
|
||||
ScopedGLDrawState::ScopedGLDrawState(GLContext* aGL)
|
||||
: blend (aGL, LOCAL_GL_BLEND, false)
|
||||
, cullFace (aGL, LOCAL_GL_CULL_FACE, false)
|
||||
, depthTest (aGL, LOCAL_GL_DEPTH_TEST, false)
|
||||
, dither (aGL, LOCAL_GL_DITHER, false)
|
||||
, polyOffsFill(aGL, LOCAL_GL_POLYGON_OFFSET_FILL, false)
|
||||
, sampleAToC (aGL, LOCAL_GL_SAMPLE_ALPHA_TO_COVERAGE, false)
|
||||
, sampleCover (aGL, LOCAL_GL_SAMPLE_COVERAGE, false)
|
||||
, scissor (aGL, LOCAL_GL_SCISSOR_TEST, false)
|
||||
, stencil (aGL, LOCAL_GL_STENCIL_TEST, false)
|
||||
, mGL(aGL)
|
||||
{
|
||||
mGL->GetUIntegerv(LOCAL_GL_CURRENT_PROGRAM, &boundProgram);
|
||||
mGL->GetUIntegerv(LOCAL_GL_ARRAY_BUFFER_BINDING, &boundBuffer);
|
||||
mGL->GetUIntegerv(LOCAL_GL_MAX_VERTEX_ATTRIBS, &maxAttrib);
|
||||
attrib_enabled = MakeUnique<GLint[]>(maxAttrib);
|
||||
|
||||
for (GLuint i = 0; i < maxAttrib; i++) {
|
||||
mGL->fGetVertexAttribiv(i, LOCAL_GL_VERTEX_ATTRIB_ARRAY_ENABLED, &attrib_enabled[i]);
|
||||
mGL->fDisableVertexAttribArray(i);
|
||||
}
|
||||
// Only Attrib0's client side state affected
|
||||
mGL->fGetVertexAttribiv(0, LOCAL_GL_VERTEX_ATTRIB_ARRAY_SIZE, &attrib0_size);
|
||||
mGL->fGetVertexAttribiv(0, LOCAL_GL_VERTEX_ATTRIB_ARRAY_STRIDE, &attrib0_stride);
|
||||
mGL->fGetVertexAttribiv(0, LOCAL_GL_VERTEX_ATTRIB_ARRAY_TYPE, &attrib0_type);
|
||||
mGL->fGetVertexAttribiv(0, LOCAL_GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &attrib0_normalized);
|
||||
mGL->fGetVertexAttribiv(0, LOCAL_GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &attrib0_bufferBinding);
|
||||
mGL->fGetVertexAttribPointerv(0, LOCAL_GL_VERTEX_ATTRIB_ARRAY_POINTER, &attrib0_pointer);
|
||||
mGL->fGetBooleanv(LOCAL_GL_COLOR_WRITEMASK, colorMask);
|
||||
mGL->fGetIntegerv(LOCAL_GL_VIEWPORT, viewport);
|
||||
mGL->fGetIntegerv(LOCAL_GL_SCISSOR_BOX, scissorBox);
|
||||
}
|
||||
|
||||
ScopedGLDrawState::~ScopedGLDrawState()
|
||||
{
|
||||
MOZ_ASSERT(mGL->IsCurrent());
|
||||
|
||||
mGL->fScissor(scissorBox[0], scissorBox[1],
|
||||
scissorBox[2], scissorBox[3]);
|
||||
|
||||
mGL->fViewport(viewport[0], viewport[1],
|
||||
viewport[2], viewport[3]);
|
||||
|
||||
mGL->fColorMask(colorMask[0],
|
||||
colorMask[1],
|
||||
colorMask[2],
|
||||
colorMask[3]);
|
||||
|
||||
for (unsigned int i = 0; i < maxAttrib; i++) {
|
||||
if (attrib_enabled[i])
|
||||
mGL->fEnableVertexAttribArray(i);
|
||||
else
|
||||
mGL->fDisableVertexAttribArray(i);
|
||||
}
|
||||
|
||||
|
||||
mGL->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, attrib0_bufferBinding);
|
||||
mGL->fVertexAttribPointer(0,
|
||||
attrib0_size,
|
||||
attrib0_type,
|
||||
attrib0_normalized,
|
||||
attrib0_stride,
|
||||
attrib0_pointer);
|
||||
|
||||
mGL->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, boundBuffer);
|
||||
|
||||
mGL->fUseProgram(boundProgram);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// ScopedPackState
|
||||
|
||||
|
|
|
@ -122,7 +122,7 @@ protected:
|
|||
|
||||
public:
|
||||
explicit ScopedTexture(GLContext* aGL);
|
||||
GLuint Texture() { return mTexture; }
|
||||
GLuint Texture() const { return mTexture; }
|
||||
|
||||
protected:
|
||||
void UnwrapImpl();
|
||||
|
@ -309,39 +309,6 @@ protected:
|
|||
void UnwrapImpl();
|
||||
};
|
||||
|
||||
struct ScopedGLDrawState
|
||||
{
|
||||
explicit ScopedGLDrawState(GLContext* gl);
|
||||
~ScopedGLDrawState();
|
||||
|
||||
GLuint boundProgram;
|
||||
GLuint boundBuffer;
|
||||
|
||||
ScopedGLState blend;
|
||||
ScopedGLState cullFace;
|
||||
ScopedGLState depthTest;
|
||||
ScopedGLState dither;
|
||||
ScopedGLState polyOffsFill;
|
||||
ScopedGLState sampleAToC;
|
||||
ScopedGLState sampleCover;
|
||||
ScopedGLState scissor;
|
||||
ScopedGLState stencil;
|
||||
|
||||
GLuint maxAttrib;
|
||||
UniquePtr<GLint[]> attrib_enabled;
|
||||
GLint attrib0_size;
|
||||
GLint attrib0_stride;
|
||||
GLint attrib0_type;
|
||||
GLint attrib0_normalized;
|
||||
GLint attrib0_bufferBinding;
|
||||
void* attrib0_pointer;
|
||||
|
||||
realGLboolean colorMask[4];
|
||||
GLint viewport[4];
|
||||
GLint scissorBox[4];
|
||||
GLContext* const mGL;
|
||||
};
|
||||
|
||||
struct ScopedPackState
|
||||
: public ScopedGLWrapper<ScopedPackState>
|
||||
{
|
||||
|
|
|
@ -65,7 +65,9 @@ SharedSurface::ProdCopy(SharedSurface* src, SharedSurface* dest,
|
|||
GLuint destTex = dest->ProdTexture();
|
||||
GLenum destTarget = dest->ProdTextureTarget();
|
||||
|
||||
gl->BlitHelper()->BlitFramebufferToTexture(0, destTex,
|
||||
const ScopedBindFramebuffer bindFB(gl, 0);
|
||||
|
||||
gl->BlitHelper()->BlitFramebufferToTexture(destTex,
|
||||
src->mSize,
|
||||
dest->mSize,
|
||||
destTarget,
|
||||
|
@ -110,7 +112,9 @@ SharedSurface::ProdCopy(SharedSurface* src, SharedSurface* dest,
|
|||
GLuint srcTex = src->ProdTexture();
|
||||
GLenum srcTarget = src->ProdTextureTarget();
|
||||
|
||||
gl->BlitHelper()->BlitTextureToFramebuffer(srcTex, 0,
|
||||
const ScopedBindFramebuffer bindFB(gl, 0);
|
||||
|
||||
gl->BlitHelper()->BlitTextureToFramebuffer(srcTex,
|
||||
src->mSize,
|
||||
dest->mSize,
|
||||
srcTarget,
|
||||
|
@ -158,9 +162,9 @@ SharedSurface::ProdCopy(SharedSurface* src, SharedSurface* dest,
|
|||
if (dest->mAttachType == AttachmentType::GLRenderbuffer) {
|
||||
GLuint destRB = dest->ProdRenderbuffer();
|
||||
ScopedFramebufferForRenderbuffer destWrapper(gl, destRB);
|
||||
|
||||
gl->BlitHelper()->BlitTextureToFramebuffer(srcTex, destWrapper.FB(),
|
||||
src->mSize, dest->mSize, srcTarget);
|
||||
const ScopedBindFramebuffer bindFB(gl, destWrapper.FB());
|
||||
gl->BlitHelper()->BlitTextureToFramebuffer(srcTex, src->mSize, dest->mSize,
|
||||
srcTarget);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -175,9 +179,10 @@ SharedSurface::ProdCopy(SharedSurface* src, SharedSurface* dest,
|
|||
if (dest->mAttachType == AttachmentType::GLTexture) {
|
||||
GLuint destTex = dest->ProdTexture();
|
||||
GLenum destTarget = dest->ProdTextureTarget();
|
||||
const ScopedBindFramebuffer bindFB(gl, srcWrapper.FB());
|
||||
|
||||
gl->BlitHelper()->BlitFramebufferToTexture(srcWrapper.FB(), destTex,
|
||||
src->mSize, dest->mSize, destTarget);
|
||||
gl->BlitHelper()->BlitFramebufferToTexture(destTex, src->mSize, dest->mSize,
|
||||
destTarget);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -471,8 +471,8 @@ SharedSurface_D3D11Interop::ProducerReleaseImpl()
|
|||
MOZ_ASSERT(mLockedForGL);
|
||||
|
||||
if (mProdTex) {
|
||||
mGL->BlitHelper()->DrawBlitTextureToFramebuffer(mProdTex, mInteropFB, mSize,
|
||||
mSize);
|
||||
const ScopedBindFramebuffer bindFB(mGL, mInteropFB);
|
||||
mGL->BlitHelper()->DrawBlitTextureToFramebuffer(mProdTex, mSize, mSize);
|
||||
}
|
||||
|
||||
if (mNeedsFinish) {
|
||||
|
|
|
@ -69,6 +69,7 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
|||
'WGLLibrary.h',
|
||||
]
|
||||
UNIFIED_SOURCES += [
|
||||
'GLBlitHelperD3D.cpp',
|
||||
'GLContextProviderWGL.cpp',
|
||||
'SharedSurfaceANGLE.cpp',
|
||||
'SharedSurfaceD3D11Interop.cpp',
|
||||
|
|
|
@ -97,7 +97,7 @@ D3D11YCbCrImage::SetData(KnowsCompositor* aAllocator,
|
|||
aData.mCbCrStride,
|
||||
aData.mCbCrStride * aData.mCbCrSize.height);
|
||||
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -113,6 +113,15 @@ D3D11YCbCrImage::GetTextureClient(KnowsCompositor* aForwarder)
|
|||
return mTextureClient;
|
||||
}
|
||||
|
||||
const DXGIYCbCrTextureData*
|
||||
D3D11YCbCrImage::GetData() const
|
||||
{
|
||||
if (!mTextureClient)
|
||||
return nullptr;
|
||||
|
||||
return static_cast<DXGIYCbCrTextureData*>(mTextureClient->GetInternalData());
|
||||
}
|
||||
|
||||
already_AddRefed<SourceSurface>
|
||||
D3D11YCbCrImage::GetAsSourceSurface()
|
||||
{
|
||||
|
|
|
@ -12,10 +12,14 @@
|
|||
#include "ImageContainer.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
class GLBlitHelper;
|
||||
}
|
||||
namespace layers {
|
||||
|
||||
class ImageContainer;
|
||||
class DXGIYCbCrTextureClient;
|
||||
class DXGIYCbCrTextureData;
|
||||
|
||||
class D3D11YCbCrRecycleAllocator : public TextureClientRecycleAllocator
|
||||
{
|
||||
|
@ -46,6 +50,7 @@ protected:
|
|||
|
||||
class D3D11YCbCrImage : public Image
|
||||
{
|
||||
friend class gl::GLBlitHelper;
|
||||
public:
|
||||
D3D11YCbCrImage();
|
||||
virtual ~D3D11YCbCrImage();
|
||||
|
@ -65,6 +70,8 @@ public:
|
|||
gfx::IntRect GetPictureRect() override { return mPictureRect; }
|
||||
|
||||
private:
|
||||
const DXGIYCbCrTextureData* GetData() const;
|
||||
|
||||
gfx::IntSize mYSize;
|
||||
gfx::IntSize mCbCrSize;
|
||||
gfx::IntRect mPictureRect;
|
||||
|
|
|
@ -78,12 +78,11 @@ GLImage::GetAsSourceSurface()
|
|||
}
|
||||
|
||||
const gl::OriginPos destOrigin = gl::OriginPos::TopLeft;
|
||||
|
||||
if (!sSnapshotContext->BlitHelper()->BlitImageToFramebuffer(this, size,
|
||||
autoFBForTex.FB(),
|
||||
destOrigin))
|
||||
{
|
||||
return nullptr;
|
||||
const ScopedBindFramebuffer bindFB(sSnapshotContext, autoFBForTex.FB());
|
||||
if (!sSnapshotContext->BlitHelper()->BlitImageToFramebuffer(this, size, destOrigin)) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<gfx::DataSourceSurface> source =
|
||||
|
|
|
@ -16,11 +16,15 @@ namespace mozilla {
|
|||
namespace dom {
|
||||
class VideoDecoderManagerChild;
|
||||
}
|
||||
namespace gl {
|
||||
class GLBlitHelper;
|
||||
}
|
||||
namespace layers {
|
||||
|
||||
// Image class that refers to a decoded video frame within
|
||||
// the GPU process.
|
||||
class GPUVideoImage final : public Image {
|
||||
friend class gl::GLBlitHelper;
|
||||
public:
|
||||
GPUVideoImage(dom::VideoDecoderManagerChild* aManager,
|
||||
const SurfaceDescriptorGPUVideo& aSD,
|
||||
|
@ -45,12 +49,21 @@ public:
|
|||
|
||||
gfx::IntSize GetSize() override { return mSize; }
|
||||
|
||||
virtual already_AddRefed<gfx::SourceSurface> GetAsSourceSurface() override
|
||||
{
|
||||
private:
|
||||
GPUVideoTextureData* GetData() const {
|
||||
if (!mTextureClient) {
|
||||
return nullptr;
|
||||
}
|
||||
GPUVideoTextureData* data = mTextureClient->GetInternalData()->AsGPUVideoTextureData();
|
||||
return mTextureClient->GetInternalData()->AsGPUVideoTextureData();
|
||||
}
|
||||
|
||||
public:
|
||||
virtual already_AddRefed<gfx::SourceSurface> GetAsSourceSurface() override
|
||||
{
|
||||
GPUVideoTextureData* data = GetData();
|
||||
if (!data) {
|
||||
return nullptr;
|
||||
}
|
||||
return data->GetAsSourceSurface();
|
||||
}
|
||||
|
||||
|
|
|
@ -48,6 +48,9 @@ protected:
|
|||
RefPtr<dom::VideoDecoderManagerChild> mManager;
|
||||
SurfaceDescriptorGPUVideo mSD;
|
||||
gfx::IntSize mSize;
|
||||
|
||||
public:
|
||||
const decltype(mSD)& SD() const { return mSD; }
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
|
|
|
@ -18,6 +18,10 @@
|
|||
#include <vector>
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
class GLBlitHelper;
|
||||
}
|
||||
|
||||
namespace layers {
|
||||
|
||||
class MOZ_RAII AutoTextureLock
|
||||
|
@ -128,6 +132,7 @@ CreateD3D11extureClientWithDevice(gfx::IntSize aSize, gfx::SurfaceFormat aFormat
|
|||
|
||||
class DXGIYCbCrTextureData : public TextureData
|
||||
{
|
||||
friend class gl::GLBlitHelper;
|
||||
public:
|
||||
static DXGIYCbCrTextureData*
|
||||
Create(IDirect3DTexture9* aTextureY,
|
||||
|
|
|
@ -89,7 +89,7 @@ union GPUVideoSubDescriptor {
|
|||
|
||||
struct SurfaceDescriptorGPUVideo {
|
||||
uint64_t handle;
|
||||
GPUVideoSubDescriptor desc;
|
||||
GPUVideoSubDescriptor subdesc;
|
||||
};
|
||||
|
||||
struct RGBDescriptor {
|
||||
|
|
|
@ -1111,47 +1111,29 @@ gfxUtils::EncodeSourceSurface(SourceSurface* aSurface,
|
|||
aBinaryOrData, aFile, nullptr);
|
||||
}
|
||||
|
||||
/* From Rec601:
|
||||
[R] [1.1643835616438356, 0.0, 1.5960267857142858] [ Y - 16]
|
||||
[G] = [1.1643835616438358, -0.3917622900949137, -0.8129676472377708] x [Cb - 128]
|
||||
[B] [1.1643835616438356, 2.017232142857143, 8.862867620416422e-17] [Cr - 128]
|
||||
|
||||
For [0,1] instead of [0,255], and to 5 places:
|
||||
[R] [1.16438, 0.00000, 1.59603] [ Y - 0.06275]
|
||||
[G] = [1.16438, -0.39176, -0.81297] x [Cb - 0.50196]
|
||||
[B] [1.16438, 2.01723, 0.00000] [Cr - 0.50196]
|
||||
|
||||
From Rec709:
|
||||
[R] [1.1643835616438356, 4.2781193979771426e-17, 1.7927410714285714] [ Y - 16]
|
||||
[G] = [1.1643835616438358, -0.21324861427372963, -0.532909328559444] x [Cb - 128]
|
||||
[B] [1.1643835616438356, 2.1124017857142854, 0.0] [Cr - 128]
|
||||
|
||||
For [0,1] instead of [0,255], and to 5 places:
|
||||
[R] [1.16438, 0.00000, 1.79274] [ Y - 0.06275]
|
||||
[G] = [1.16438, -0.21325, -0.53291] x [Cb - 0.50196]
|
||||
[B] [1.16438, 2.11240, 0.00000] [Cr - 0.50196]
|
||||
*/
|
||||
|
||||
static const float kRec601[9] = {
|
||||
1.16438f, 0.00000f, 1.59603f,
|
||||
1.16438f,-0.39176f,-0.81297f,
|
||||
1.16438f, 2.01723f, 0.00000f,
|
||||
// https://jdashg.github.io/misc/colors/from-coeffs.html
|
||||
const float kBT601NarrowYCbCrToRGB_RowMajor[16] = {
|
||||
1.16438f, 0.00000f, 1.59603f,-0.87420f,
|
||||
1.16438f,-0.39176f,-0.81297f, 0.53167f,
|
||||
1.16438f, 2.01723f, 0.00000f,-1.08563f,
|
||||
0.00000f, 0.00000f, 0.00000f, 1.00000f
|
||||
};
|
||||
static const float kRec709[9] = {
|
||||
1.16438f, 0.00000f, 1.79274f,
|
||||
1.16438f,-0.21325f,-0.53291f,
|
||||
1.16438f, 2.11240f, 0.00000f,
|
||||
const float kBT709NarrowYCbCrToRGB_RowMajor[16] = {
|
||||
1.16438f, 0.00000f, 1.79274f,-0.97295f,
|
||||
1.16438f,-0.21325f,-0.53291f, 0.30148f,
|
||||
1.16438f, 2.11240f, 0.00000f,-1.13340f,
|
||||
0.00000f, 0.00000f, 0.00000f, 1.00000f
|
||||
};
|
||||
|
||||
/* static */ const float*
|
||||
gfxUtils::YuvToRgbMatrix4x3RowMajor(YUVColorSpace aYUVColorSpace)
|
||||
{
|
||||
#define X(x) { x[0], x[1], x[2], 0.0f, \
|
||||
x[3], x[4], x[5], 0.0f, \
|
||||
x[6], x[7], x[8], 0.0f }
|
||||
#define X(x) { x[0], x[1], x[ 2], 0.0f, \
|
||||
x[4], x[5], x[ 6], 0.0f, \
|
||||
x[8], x[9], x[10], 0.0f }
|
||||
|
||||
static const float rec601[12] = X(kRec601);
|
||||
static const float rec709[12] = X(kRec709);
|
||||
static const float rec601[12] = X(kBT601NarrowYCbCrToRGB_RowMajor);
|
||||
static const float rec709[12] = X(kBT709NarrowYCbCrToRGB_RowMajor);
|
||||
|
||||
#undef X
|
||||
|
||||
|
@ -1169,12 +1151,36 @@ gfxUtils::YuvToRgbMatrix4x3RowMajor(YUVColorSpace aYUVColorSpace)
|
|||
/* static */ const float*
|
||||
gfxUtils::YuvToRgbMatrix3x3ColumnMajor(YUVColorSpace aYUVColorSpace)
|
||||
{
|
||||
#define X(x) { x[0], x[3], x[6], \
|
||||
x[1], x[4], x[7], \
|
||||
x[2], x[5], x[8] }
|
||||
#define X(x) { x[0], x[4], x[ 8], \
|
||||
x[1], x[5], x[ 9], \
|
||||
x[2], x[6], x[10] }
|
||||
|
||||
static const float rec601[9] = X(kRec601);
|
||||
static const float rec709[9] = X(kRec709);
|
||||
static const float rec601[9] = X(kBT601NarrowYCbCrToRGB_RowMajor);
|
||||
static const float rec709[9] = X(kBT709NarrowYCbCrToRGB_RowMajor);
|
||||
|
||||
#undef X
|
||||
|
||||
switch (aYUVColorSpace) {
|
||||
case YUVColorSpace::BT601:
|
||||
return rec601;
|
||||
case YUVColorSpace::BT709:
|
||||
return rec709;
|
||||
default: // YUVColorSpace::UNKNOWN
|
||||
MOZ_ASSERT(false, "unknown aYUVColorSpace");
|
||||
return rec601;
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ const float*
|
||||
gfxUtils::YuvToRgbMatrix4x4ColumnMajor(YUVColorSpace aYUVColorSpace)
|
||||
{
|
||||
#define X(x) { x[0], x[4], x[ 8], x[12], \
|
||||
x[1], x[5], x[ 9], x[13], \
|
||||
x[2], x[6], x[10], x[14], \
|
||||
x[3], x[7], x[11], x[15] }
|
||||
|
||||
static const float rec601[16] = X(kBT601NarrowYCbCrToRGB_RowMajor);
|
||||
static const float rec709[16] = X(kBT709NarrowYCbCrToRGB_RowMajor);
|
||||
|
||||
#undef X
|
||||
|
||||
|
|
|
@ -158,6 +158,7 @@ public:
|
|||
|
||||
static const float* YuvToRgbMatrix4x3RowMajor(mozilla::YUVColorSpace aYUVColorSpace);
|
||||
static const float* YuvToRgbMatrix3x3ColumnMajor(mozilla::YUVColorSpace aYUVColorSpace);
|
||||
static const float* YuvToRgbMatrix4x4ColumnMajor(mozilla::YUVColorSpace aYUVColorSpace);
|
||||
|
||||
/**
|
||||
* Creates a copy of aSurface, but having the SurfaceFormat aFormat.
|
||||
|
|
Загрузка…
Ссылка в новой задаче