From 4b772da5effe671b216499d22569bab4707dc848 Mon Sep 17 00:00:00 2001 From: Brad Werth Date: Tue, 22 Feb 2022 19:17:20 +0000 Subject: [PATCH] Bug 1745492 Part 2: Update MacIOSurface handling to deal with 10-bit formats. r=media-playback-reviewers,gfx-reviewers,lsalzman,alwu This fixes an issue caused by landing Bug 1679927. Now that it's possible to get 10-bit formats in macOS, the texture pipeline has to be updated to pass those surfaces to WebRender. This also contains a drive-by comment on D3D11 handing of 10-bit WebRender display items. It was not clear why specifing 16-bit color depth for P010 format was correct there, but should be specified as 10-bit color elsewhere. This also contains another drive-by fix to comments in webrender describing the RG16 enum. Differential Revision: https://phabricator.services.mozilla.com/D136823 --- gfx/2d/MacIOSurface.cpp | 11 ++++++++ gfx/layers/d3d11/TextureD3D11.cpp | 5 ++++ .../opengl/MacIOSurfaceTextureHostOGL.cpp | 27 +++++++++++++++---- gfx/wr/webrender_api/src/image.rs | 2 +- 4 files changed, 39 insertions(+), 6 deletions(-) diff --git a/gfx/2d/MacIOSurface.cpp b/gfx/2d/MacIOSurface.cpp index 59ecee8a48b6..dc19bf7d36dc 100644 --- a/gfx/2d/MacIOSurface.cpp +++ b/gfx/2d/MacIOSurface.cpp @@ -404,10 +404,21 @@ already_AddRefed MacIOSurface::GetAsDrawTargetLocked( } SurfaceFormat MacIOSurface::GetFormat() const { +#if !defined(MAC_OS_VERSION_10_13) || \ + MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_VERSION_10_13 + enum : OSType { + kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange = 'x420', + kCVPixelFormatType_420YpCbCr10BiPlanarFullRange = 'xf20', + }; +#endif + switch (GetPixelFormat()) { case kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange: case kCVPixelFormatType_420YpCbCr8BiPlanarFullRange: return SurfaceFormat::NV12; + case kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange: + case kCVPixelFormatType_420YpCbCr10BiPlanarFullRange: + return SurfaceFormat::P010; case kCVPixelFormatType_422YpCbCr8_yuvs: case kCVPixelFormatType_422YpCbCr8FullRange: return SurfaceFormat::YUV422; diff --git a/gfx/layers/d3d11/TextureD3D11.cpp b/gfx/layers/d3d11/TextureD3D11.cpp index d3a0b8e0d6e1..4ec9717a02fc 100644 --- a/gfx/layers/d3d11/TextureD3D11.cpp +++ b/gfx/layers/d3d11/TextureD3D11.cpp @@ -1034,6 +1034,11 @@ void DXGITextureHostD3D11::PushDisplayItems( case gfx::SurfaceFormat::P010: case gfx::SurfaceFormat::P016: case gfx::SurfaceFormat::NV12: { + // DXGI_FORMAT_P010 stores its 10 bit value in the most significant bits + // of each 16 bit word with the unused lower bits cleared to zero so that + // it may be handled as if it was DXGI_FORMAT_P016. This is approximately + // perceptually correct. However, due to rounding error, the precise + // quantized value after sampling may be off by 1. MOZ_ASSERT(aImageKeys.length() == 2); aBuilder.PushNV12Image( aBounds, aClip, true, aImageKeys[0], aImageKeys[1], diff --git a/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp b/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp index 64c067e4223e..83070c7db31d 100644 --- a/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp +++ b/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp @@ -92,7 +92,8 @@ uint32_t MacIOSurfaceTextureHostOGL::NumSubTextures() { case gfx::SurfaceFormat::YUV422: { return 1; } - case gfx::SurfaceFormat::NV12: { + case gfx::SurfaceFormat::NV12: + case gfx::SurfaceFormat::P010: { return 2; } default: { @@ -153,6 +154,21 @@ void MacIOSurfaceTextureHostOGL::PushResourceUpdates( (aResources.*method)(aImageKeys[1], descriptor1, aExtID, imageType, 1); break; } + case gfx::SurfaceFormat::P010: { + MOZ_ASSERT(aImageKeys.length() == 2); + MOZ_ASSERT(mSurface->GetPlaneCount() == 2); + wr::ImageDescriptor descriptor0( + gfx::IntSize(mSurface->GetDevicePixelWidth(0), + mSurface->GetDevicePixelHeight(0)), + gfx::SurfaceFormat::A16); + wr::ImageDescriptor descriptor1( + gfx::IntSize(mSurface->GetDevicePixelWidth(1), + mSurface->GetDevicePixelHeight(1)), + gfx::SurfaceFormat::R16G16); + (aResources.*method)(aImageKeys[0], descriptor0, aExtID, imageType, 0); + (aResources.*method)(aImageKeys[1], descriptor1, aExtID, imageType, 1); + break; + } default: { MOZ_ASSERT_UNREACHABLE("unexpected to be called"); } @@ -191,14 +207,15 @@ void MacIOSurfaceTextureHostOGL::PushDisplayItems( /* aSupportsExternalCompositing */ true); break; } - case gfx::SurfaceFormat::NV12: { + case gfx::SurfaceFormat::NV12: + case gfx::SurfaceFormat::P010: { MOZ_ASSERT(aImageKeys.length() == 2); MOZ_ASSERT(mSurface->GetPlaneCount() == 2); - // Those images can only be generated at present by the Apple H264 decoder - // which only supports 8 bits color depth. aBuilder.PushNV12Image( aBounds, aClip, true, aImageKeys[0], aImageKeys[1], - wr::ColorDepth::Color8, wr::ToWrYuvColorSpace(GetYUVColorSpace()), + GetFormat() == gfx::SurfaceFormat::NV12 ? wr::ColorDepth::Color8 + : wr::ColorDepth::Color10, + wr::ToWrYuvColorSpace(GetYUVColorSpace()), wr::ToWrColorRange(GetColorRange()), aFilter, preferCompositorSurface, /* aSupportsExternalCompositing */ true); break; diff --git a/gfx/wr/webrender_api/src/image.rs b/gfx/wr/webrender_api/src/image.rs index e03a5d88ae18..8d86ef1d7b88 100644 --- a/gfx/wr/webrender_api/src/image.rs +++ b/gfx/wr/webrender_api/src/image.rs @@ -160,7 +160,7 @@ pub enum ImageFormat { /// Two-channels, byte storage. Similar to `R8`, this just means /// "two channels" rather than "red and green". RG8 = 5, - /// Two-channels, byte storage. Similar to `R16`, this just means + /// Two-channels, short storage. Similar to `R16`, this just means /// "two channels" rather than "red and green". RG16 = 6,