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.

Depends on D136046

Differential Revision: https://phabricator.services.mozilla.com/D136823
This commit is contained in:
Brad Werth 2022-03-05 17:31:18 +00:00
Родитель 8434fb5f3d
Коммит 418ae64bbb
4 изменённых файлов: 66 добавлений и 6 удалений

Просмотреть файл

@ -404,10 +404,21 @@ already_AddRefed<mozilla::gfx::DrawTarget> 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;
@ -439,6 +450,14 @@ CGLError MacIOSurface::CGLTexImageIOSurface2D(CGLContextObj ctx, GLenum target,
CGLError MacIOSurface::CGLTexImageIOSurface2D(
mozilla::gl::GLContext* aGL, CGLContextObj ctx, size_t plane,
mozilla::gfx::SurfaceFormat* aOutReadFormat) {
#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
MOZ_ASSERT(plane >= 0);
bool isCompatibilityProfile = aGL->IsCompatibilityProfile();
OSType pixelFormat = GetPixelFormat();
@ -465,6 +484,25 @@ CGLError MacIOSurface::CGLTexImageIOSurface2D(
if (aOutReadFormat) {
*aOutReadFormat = mozilla::gfx::SurfaceFormat::NV12;
}
} else if (pixelFormat == kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange ||
pixelFormat == kCVPixelFormatType_420YpCbCr10BiPlanarFullRange) {
MOZ_ASSERT(GetPlaneCount() == 2);
MOZ_ASSERT(plane < 2);
// The LOCAL_GL_LUMINANCE and LOCAL_GL_LUMINANCE_ALPHA are the deprecated
// format. So, use LOCAL_GL_RED and LOCAL_GL_RB if we use core profile.
// https://www.khronos.org/opengl/wiki/Image_Format#Legacy_Image_Formats
if (plane == 0) {
internalFormat = format =
(isCompatibilityProfile) ? (LOCAL_GL_LUMINANCE) : (LOCAL_GL_RED);
} else {
internalFormat = format =
(isCompatibilityProfile) ? (LOCAL_GL_LUMINANCE_ALPHA) : (LOCAL_GL_RG);
}
type = LOCAL_GL_UNSIGNED_SHORT;
if (aOutReadFormat) {
*aOutReadFormat = mozilla::gfx::SurfaceFormat::P010;
}
} else if (pixelFormat == kCVPixelFormatType_422YpCbCr8_yuvs ||
pixelFormat == kCVPixelFormatType_422YpCbCr8FullRange) {
MOZ_ASSERT(plane == 0);

Просмотреть файл

@ -1052,6 +1052,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],

Просмотреть файл

@ -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;

Просмотреть файл

@ -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,