зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1866020 - Override buggy colorspace conversion on Pixel devices. r=gw,padenot,geckoview-reviewers,owlish
Pixel 6, 7, and 8 devices running Android 14 are affected by a bug where video frames with SMPTE 432 color primaries are rendered incorrectly when sampled from an external texture in GLES. To work around this, we force these frames to be converted to RGB using BT709 colorspace instead. While this won't look exactly right, it is much better than the current situation. When we detect that a frame is decoded with that color space on an affected device, we set a "ForceBT709" flag which gets passed through to webrender as a new ImageBufferKind. Rendering this ImageBufferKind is handled via a new shader feature TEXTURE_EXTERNAL_BT709, which works much like the existing TEXTURE_EXTERNAL feature, but additionally uses the EXT_YUV_TARGET extension to override the colorspace transformation. This approach could be extended in the future to handle additional colorspace transformations, but for now only handles the one required to workaround this particular driver bug. Differential Revision: https://phabricator.services.mozilla.com/D195800
This commit is contained in:
Родитель
61791160ef
Коммит
d20809a078
|
@ -67,6 +67,17 @@ class RenderOrReleaseOutput {
|
||||||
java::Sample::GlobalRef mSample;
|
java::Sample::GlobalRef mSample;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static bool areSmpte432ColorPrimariesBuggy() {
|
||||||
|
if (jni::GetAPIVersion() >= 34) {
|
||||||
|
const auto socManufacturer =
|
||||||
|
java::sdk::Build::SOC_MANUFACTURER()->ToString();
|
||||||
|
if (socManufacturer.EqualsASCII("Google")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
class RemoteVideoDecoder final : public RemoteDataDecoder {
|
class RemoteVideoDecoder final : public RemoteDataDecoder {
|
||||||
public:
|
public:
|
||||||
// Render the output to the surface when the frame is sent
|
// Render the output to the surface when the frame is sent
|
||||||
|
@ -402,9 +413,16 @@ class RemoteVideoDecoder final : public RemoteDataDecoder {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ok && (size > 0 || presentationTimeUs >= 0)) {
|
if (ok && (size > 0 || presentationTimeUs >= 0)) {
|
||||||
|
// On certain devices SMPTE 432 color primaries are rendered incorrectly,
|
||||||
|
// so we force BT709 to be used instead. The magic number 10 comes from
|
||||||
|
// libstagefright's kColorStandardDCI_P3.
|
||||||
|
static bool isSmpte432Buggy = areSmpte432ColorPrimariesBuggy();
|
||||||
|
bool forceBT709ColorSpace = isSmpte432Buggy && mColorSpace == Some(10);
|
||||||
|
|
||||||
RefPtr<layers::Image> img = new layers::SurfaceTextureImage(
|
RefPtr<layers::Image> img = new layers::SurfaceTextureImage(
|
||||||
mSurfaceHandle, inputInfo.mImageSize, false /* NOT continuous */,
|
mSurfaceHandle, inputInfo.mImageSize, false /* NOT continuous */,
|
||||||
gl::OriginPos::BottomLeft, mConfig.HasAlpha(), mTransformOverride);
|
gl::OriginPos::BottomLeft, mConfig.HasAlpha(), forceBT709ColorSpace,
|
||||||
|
mTransformOverride);
|
||||||
img->AsSurfaceTextureImage()->RegisterSetCurrentCallback(
|
img->AsSurfaceTextureImage()->RegisterSetCurrentCallback(
|
||||||
std::move(releaseSample));
|
std::move(releaseSample));
|
||||||
|
|
||||||
|
|
|
@ -254,7 +254,8 @@ Maybe<layers::SurfaceDescriptor>
|
||||||
SharedSurface_SurfaceTexture::ToSurfaceDescriptor() {
|
SharedSurface_SurfaceTexture::ToSurfaceDescriptor() {
|
||||||
return Some(layers::SurfaceTextureDescriptor(
|
return Some(layers::SurfaceTextureDescriptor(
|
||||||
mSurface->GetHandle(), mDesc.size, gfx::SurfaceFormat::R8G8B8A8,
|
mSurface->GetHandle(), mDesc.size, gfx::SurfaceFormat::R8G8B8A8,
|
||||||
false /* NOT continuous */, Nothing() /* Do not override transform */));
|
false /* Do NOT override colorspace */, false /* NOT continuous */,
|
||||||
|
Nothing() /* Do not override transform */));
|
||||||
}
|
}
|
||||||
|
|
||||||
SurfaceFactory_SurfaceTexture::SurfaceFactory_SurfaceTexture(GLContext& gl)
|
SurfaceFactory_SurfaceTexture::SurfaceFactory_SurfaceTexture(GLContext& gl)
|
||||||
|
|
|
@ -111,13 +111,14 @@ nsresult GLImage::BuildSurfaceDescriptorBuffer(
|
||||||
SurfaceTextureImage::SurfaceTextureImage(
|
SurfaceTextureImage::SurfaceTextureImage(
|
||||||
AndroidSurfaceTextureHandle aHandle, const gfx::IntSize& aSize,
|
AndroidSurfaceTextureHandle aHandle, const gfx::IntSize& aSize,
|
||||||
bool aContinuous, gl::OriginPos aOriginPos, bool aHasAlpha,
|
bool aContinuous, gl::OriginPos aOriginPos, bool aHasAlpha,
|
||||||
Maybe<gfx::Matrix4x4> aTransformOverride)
|
bool aForceBT709ColorSpace, Maybe<gfx::Matrix4x4> aTransformOverride)
|
||||||
: GLImage(ImageFormat::SURFACE_TEXTURE),
|
: GLImage(ImageFormat::SURFACE_TEXTURE),
|
||||||
mHandle(aHandle),
|
mHandle(aHandle),
|
||||||
mSize(aSize),
|
mSize(aSize),
|
||||||
mContinuous(aContinuous),
|
mContinuous(aContinuous),
|
||||||
mOriginPos(aOriginPos),
|
mOriginPos(aOriginPos),
|
||||||
mHasAlpha(aHasAlpha),
|
mHasAlpha(aHasAlpha),
|
||||||
|
mForceBT709ColorSpace(aForceBT709ColorSpace),
|
||||||
mTransformOverride(aTransformOverride) {
|
mTransformOverride(aTransformOverride) {
|
||||||
MOZ_ASSERT(mHandle);
|
MOZ_ASSERT(mHandle);
|
||||||
}
|
}
|
||||||
|
@ -126,7 +127,7 @@ Maybe<SurfaceDescriptor> SurfaceTextureImage::GetDesc() {
|
||||||
SurfaceDescriptor sd = SurfaceTextureDescriptor(
|
SurfaceDescriptor sd = SurfaceTextureDescriptor(
|
||||||
mHandle, mSize,
|
mHandle, mSize,
|
||||||
mHasAlpha ? gfx::SurfaceFormat::R8G8B8A8 : gfx::SurfaceFormat::R8G8B8X8,
|
mHasAlpha ? gfx::SurfaceFormat::R8G8B8A8 : gfx::SurfaceFormat::R8G8B8X8,
|
||||||
false /* NOT continuous */, mTransformOverride);
|
mForceBT709ColorSpace, false /* NOT continuous */, mTransformOverride);
|
||||||
return Some(sd);
|
return Some(sd);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -54,6 +54,7 @@ class SurfaceTextureImage final : public GLImage {
|
||||||
SurfaceTextureImage(AndroidSurfaceTextureHandle aHandle,
|
SurfaceTextureImage(AndroidSurfaceTextureHandle aHandle,
|
||||||
const gfx::IntSize& aSize, bool aContinuous,
|
const gfx::IntSize& aSize, bool aContinuous,
|
||||||
gl::OriginPos aOriginPos, bool aHasAlpha,
|
gl::OriginPos aOriginPos, bool aHasAlpha,
|
||||||
|
bool aForceBT709ColorSpace,
|
||||||
Maybe<gfx::Matrix4x4> aTransformOverride);
|
Maybe<gfx::Matrix4x4> aTransformOverride);
|
||||||
|
|
||||||
gfx::IntSize GetSize() const override { return mSize; }
|
gfx::IntSize GetSize() const override { return mSize; }
|
||||||
|
@ -61,6 +62,7 @@ class SurfaceTextureImage final : public GLImage {
|
||||||
bool GetContinuous() const { return mContinuous; }
|
bool GetContinuous() const { return mContinuous; }
|
||||||
gl::OriginPos GetOriginPos() const { return mOriginPos; }
|
gl::OriginPos GetOriginPos() const { return mOriginPos; }
|
||||||
bool GetHasAlpha() const { return mHasAlpha; }
|
bool GetHasAlpha() const { return mHasAlpha; }
|
||||||
|
bool GetForceBT709ColorSpace() const { return mForceBT709ColorSpace; }
|
||||||
const Maybe<gfx::Matrix4x4>& GetTransformOverride() const {
|
const Maybe<gfx::Matrix4x4>& GetTransformOverride() const {
|
||||||
return mTransformOverride;
|
return mTransformOverride;
|
||||||
}
|
}
|
||||||
|
@ -102,6 +104,7 @@ class SurfaceTextureImage final : public GLImage {
|
||||||
bool mContinuous;
|
bool mContinuous;
|
||||||
gl::OriginPos mOriginPos;
|
gl::OriginPos mOriginPos;
|
||||||
const bool mHasAlpha;
|
const bool mHasAlpha;
|
||||||
|
const bool mForceBT709ColorSpace;
|
||||||
const Maybe<gfx::Matrix4x4> mTransformOverride;
|
const Maybe<gfx::Matrix4x4> mTransformOverride;
|
||||||
UniquePtr<SetCurrentCallback> mSetCurrentCallback;
|
UniquePtr<SetCurrentCallback> mSetCurrentCallback;
|
||||||
};
|
};
|
||||||
|
|
|
@ -120,6 +120,7 @@ already_AddRefed<TextureClient> ImageClient::CreateTextureClientForImage(
|
||||||
texture = AndroidSurfaceTextureData::CreateTextureClient(
|
texture = AndroidSurfaceTextureData::CreateTextureClient(
|
||||||
typedImage->GetHandle(), size, typedImage->GetContinuous(),
|
typedImage->GetHandle(), size, typedImage->GetContinuous(),
|
||||||
typedImage->GetOriginPos(), typedImage->GetHasAlpha(),
|
typedImage->GetOriginPos(), typedImage->GetHasAlpha(),
|
||||||
|
typedImage->GetForceBT709ColorSpace(),
|
||||||
typedImage->GetTransformOverride(),
|
typedImage->GetTransformOverride(),
|
||||||
aKnowsCompositor->GetTextureForwarder(), TextureFlags::DEFAULT);
|
aKnowsCompositor->GetTextureForwarder(), TextureFlags::DEFAULT);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -88,6 +88,7 @@ namespace layers {
|
||||||
IntSize size;
|
IntSize size;
|
||||||
SurfaceFormat format;
|
SurfaceFormat format;
|
||||||
bool continuous;
|
bool continuous;
|
||||||
|
bool forceBT709ColorSpace;
|
||||||
Matrix4x4? transformOverride;
|
Matrix4x4? transformOverride;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ class CompositableForwarder;
|
||||||
|
|
||||||
already_AddRefed<TextureClient> AndroidSurfaceTextureData::CreateTextureClient(
|
already_AddRefed<TextureClient> AndroidSurfaceTextureData::CreateTextureClient(
|
||||||
AndroidSurfaceTextureHandle aHandle, gfx::IntSize aSize, bool aContinuous,
|
AndroidSurfaceTextureHandle aHandle, gfx::IntSize aSize, bool aContinuous,
|
||||||
gl::OriginPos aOriginPos, bool aHasAlpha,
|
gl::OriginPos aOriginPos, bool aHasAlpha, bool aForceBT709ColorSpace,
|
||||||
Maybe<gfx::Matrix4x4> aTransformOverride, LayersIPCChannel* aAllocator,
|
Maybe<gfx::Matrix4x4> aTransformOverride, LayersIPCChannel* aAllocator,
|
||||||
TextureFlags aFlags) {
|
TextureFlags aFlags) {
|
||||||
if (aOriginPos == gl::OriginPos::BottomLeft) {
|
if (aOriginPos == gl::OriginPos::BottomLeft) {
|
||||||
|
@ -47,17 +47,19 @@ already_AddRefed<TextureClient> AndroidSurfaceTextureData::CreateTextureClient(
|
||||||
|
|
||||||
return TextureClient::CreateWithData(
|
return TextureClient::CreateWithData(
|
||||||
new AndroidSurfaceTextureData(aHandle, aSize, aContinuous, aHasAlpha,
|
new AndroidSurfaceTextureData(aHandle, aSize, aContinuous, aHasAlpha,
|
||||||
aTransformOverride),
|
aForceBT709ColorSpace, aTransformOverride),
|
||||||
aFlags, aAllocator);
|
aFlags, aAllocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
AndroidSurfaceTextureData::AndroidSurfaceTextureData(
|
AndroidSurfaceTextureData::AndroidSurfaceTextureData(
|
||||||
AndroidSurfaceTextureHandle aHandle, gfx::IntSize aSize, bool aContinuous,
|
AndroidSurfaceTextureHandle aHandle, gfx::IntSize aSize, bool aContinuous,
|
||||||
bool aHasAlpha, Maybe<gfx::Matrix4x4> aTransformOverride)
|
bool aHasAlpha, bool aForceBT709ColorSpace,
|
||||||
|
Maybe<gfx::Matrix4x4> aTransformOverride)
|
||||||
: mHandle(aHandle),
|
: mHandle(aHandle),
|
||||||
mSize(aSize),
|
mSize(aSize),
|
||||||
mContinuous(aContinuous),
|
mContinuous(aContinuous),
|
||||||
mHasAlpha(aHasAlpha),
|
mHasAlpha(aHasAlpha),
|
||||||
|
mForceBT709ColorSpace(aForceBT709ColorSpace),
|
||||||
mTransformOverride(aTransformOverride) {
|
mTransformOverride(aTransformOverride) {
|
||||||
MOZ_ASSERT(mHandle);
|
MOZ_ASSERT(mHandle);
|
||||||
}
|
}
|
||||||
|
@ -76,7 +78,7 @@ bool AndroidSurfaceTextureData::Serialize(SurfaceDescriptor& aOutDescriptor) {
|
||||||
aOutDescriptor = SurfaceTextureDescriptor(
|
aOutDescriptor = SurfaceTextureDescriptor(
|
||||||
mHandle, mSize,
|
mHandle, mSize,
|
||||||
mHasAlpha ? gfx::SurfaceFormat::R8G8B8A8 : gfx::SurfaceFormat::R8G8B8X8,
|
mHasAlpha ? gfx::SurfaceFormat::R8G8B8A8 : gfx::SurfaceFormat::R8G8B8X8,
|
||||||
mContinuous, mTransformOverride);
|
mContinuous, mForceBT709ColorSpace, mTransformOverride);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,6 +161,7 @@ bool AndroidNativeWindowTextureData::Serialize(
|
||||||
SurfaceDescriptor& aOutDescriptor) {
|
SurfaceDescriptor& aOutDescriptor) {
|
||||||
aOutDescriptor = SurfaceTextureDescriptor(
|
aOutDescriptor = SurfaceTextureDescriptor(
|
||||||
mSurface->GetHandle(), mSize, mFormat, false /* not continuous */,
|
mSurface->GetHandle(), mSize, mFormat, false /* not continuous */,
|
||||||
|
false /* do not override colorspace */,
|
||||||
Some(gfx::Matrix4x4()) /* always use identity transform */);
|
Some(gfx::Matrix4x4()) /* always use identity transform */);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ class AndroidSurfaceTextureData : public TextureData {
|
||||||
public:
|
public:
|
||||||
static already_AddRefed<TextureClient> CreateTextureClient(
|
static already_AddRefed<TextureClient> CreateTextureClient(
|
||||||
AndroidSurfaceTextureHandle aHandle, gfx::IntSize aSize, bool aContinuous,
|
AndroidSurfaceTextureHandle aHandle, gfx::IntSize aSize, bool aContinuous,
|
||||||
gl::OriginPos aOriginPos, bool aHasAlpha,
|
gl::OriginPos aOriginPos, bool aHasAlpha, bool aForceBT709ColorSpace,
|
||||||
Maybe<gfx::Matrix4x4> aTransformOverride, LayersIPCChannel* aAllocator,
|
Maybe<gfx::Matrix4x4> aTransformOverride, LayersIPCChannel* aAllocator,
|
||||||
TextureFlags aFlags);
|
TextureFlags aFlags);
|
||||||
|
|
||||||
|
@ -62,13 +62,14 @@ class AndroidSurfaceTextureData : public TextureData {
|
||||||
protected:
|
protected:
|
||||||
AndroidSurfaceTextureData(AndroidSurfaceTextureHandle aHandle,
|
AndroidSurfaceTextureData(AndroidSurfaceTextureHandle aHandle,
|
||||||
gfx::IntSize aSize, bool aContinuous,
|
gfx::IntSize aSize, bool aContinuous,
|
||||||
bool aHasAlpha,
|
bool aHasAlpha, bool aForceBT709ColorSpace,
|
||||||
Maybe<gfx::Matrix4x4> aTransformOverride);
|
Maybe<gfx::Matrix4x4> aTransformOverride);
|
||||||
|
|
||||||
const AndroidSurfaceTextureHandle mHandle;
|
const AndroidSurfaceTextureHandle mHandle;
|
||||||
const gfx::IntSize mSize;
|
const gfx::IntSize mSize;
|
||||||
const bool mContinuous;
|
const bool mContinuous;
|
||||||
const bool mHasAlpha;
|
const bool mHasAlpha;
|
||||||
|
const bool mForceBT709ColorSpace;
|
||||||
const Maybe<gfx::Matrix4x4> mTransformOverride;
|
const Maybe<gfx::Matrix4x4> mTransformOverride;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -67,9 +67,9 @@ already_AddRefed<TextureHost> CreateTextureHostOGL(
|
||||||
java::GeckoSurfaceTexture::LocalRef surfaceTexture =
|
java::GeckoSurfaceTexture::LocalRef surfaceTexture =
|
||||||
java::GeckoSurfaceTexture::Lookup(desc.handle());
|
java::GeckoSurfaceTexture::Lookup(desc.handle());
|
||||||
|
|
||||||
result = new SurfaceTextureHost(aFlags, surfaceTexture, desc.size(),
|
result = new SurfaceTextureHost(
|
||||||
desc.format(), desc.continuous(),
|
aFlags, surfaceTexture, desc.size(), desc.format(), desc.continuous(),
|
||||||
desc.transformOverride());
|
desc.forceBT709ColorSpace(), desc.transformOverride());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SurfaceDescriptor::TSurfaceDescriptorAndroidHardwareBuffer: {
|
case SurfaceDescriptor::TSurfaceDescriptorAndroidHardwareBuffer: {
|
||||||
|
@ -495,12 +495,13 @@ void SurfaceTextureSource::DeallocateDeviceData() { mSurfTex = nullptr; }
|
||||||
SurfaceTextureHost::SurfaceTextureHost(
|
SurfaceTextureHost::SurfaceTextureHost(
|
||||||
TextureFlags aFlags, mozilla::java::GeckoSurfaceTexture::Ref& aSurfTex,
|
TextureFlags aFlags, mozilla::java::GeckoSurfaceTexture::Ref& aSurfTex,
|
||||||
gfx::IntSize aSize, gfx::SurfaceFormat aFormat, bool aContinuousUpdate,
|
gfx::IntSize aSize, gfx::SurfaceFormat aFormat, bool aContinuousUpdate,
|
||||||
Maybe<Matrix4x4> aTransformOverride)
|
bool aForceBT709ColorSpace, Maybe<Matrix4x4> aTransformOverride)
|
||||||
: TextureHost(TextureHostType::AndroidSurfaceTexture, aFlags),
|
: TextureHost(TextureHostType::AndroidSurfaceTexture, aFlags),
|
||||||
mSurfTex(aSurfTex),
|
mSurfTex(aSurfTex),
|
||||||
mSize(aSize),
|
mSize(aSize),
|
||||||
mFormat(aFormat),
|
mFormat(aFormat),
|
||||||
mContinuousUpdate(aContinuousUpdate),
|
mContinuousUpdate(aContinuousUpdate),
|
||||||
|
mForceBT709ColorSpace(aForceBT709ColorSpace),
|
||||||
mTransformOverride(aTransformOverride) {
|
mTransformOverride(aTransformOverride) {
|
||||||
if (!mSurfTex) {
|
if (!mSurfTex) {
|
||||||
return;
|
return;
|
||||||
|
@ -560,11 +561,15 @@ void SurfaceTextureHost::PushResourceUpdates(
|
||||||
TextureHost::NativeTexturePolicy policy =
|
TextureHost::NativeTexturePolicy policy =
|
||||||
TextureHost::BackendNativeTexturePolicy(aResources.GetBackendType(),
|
TextureHost::BackendNativeTexturePolicy(aResources.GetBackendType(),
|
||||||
GetSize());
|
GetSize());
|
||||||
auto imageType = policy == TextureHost::NativeTexturePolicy::REQUIRE
|
auto imageType = wr::ExternalImageType::TextureHandle(
|
||||||
? wr::ExternalImageType::TextureHandle(
|
wr::ImageBufferKind::TextureExternal);
|
||||||
wr::ImageBufferKind::TextureRect)
|
if (policy == TextureHost::NativeTexturePolicy::REQUIRE) {
|
||||||
: wr::ExternalImageType::TextureHandle(
|
imageType =
|
||||||
wr::ImageBufferKind::TextureExternal);
|
wr::ExternalImageType::TextureHandle(wr::ImageBufferKind::TextureRect);
|
||||||
|
} else if (mForceBT709ColorSpace) {
|
||||||
|
imageType = wr::ExternalImageType::TextureHandle(
|
||||||
|
wr::ImageBufferKind::TextureExternalBT709);
|
||||||
|
}
|
||||||
|
|
||||||
switch (GetFormat()) {
|
switch (GetFormat()) {
|
||||||
case gfx::SurfaceFormat::R8G8B8X8:
|
case gfx::SurfaceFormat::R8G8B8X8:
|
||||||
|
|
|
@ -387,7 +387,7 @@ class SurfaceTextureHost : public TextureHost {
|
||||||
SurfaceTextureHost(TextureFlags aFlags,
|
SurfaceTextureHost(TextureFlags aFlags,
|
||||||
mozilla::java::GeckoSurfaceTexture::Ref& aSurfTex,
|
mozilla::java::GeckoSurfaceTexture::Ref& aSurfTex,
|
||||||
gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||||
bool aContinuousUpdate,
|
bool aContinuousUpdate, bool aForceBT709ColorSpace,
|
||||||
Maybe<gfx::Matrix4x4> aTransformOverride);
|
Maybe<gfx::Matrix4x4> aTransformOverride);
|
||||||
|
|
||||||
virtual ~SurfaceTextureHost();
|
virtual ~SurfaceTextureHost();
|
||||||
|
@ -438,6 +438,7 @@ class SurfaceTextureHost : public TextureHost {
|
||||||
const gfx::IntSize mSize;
|
const gfx::IntSize mSize;
|
||||||
const gfx::SurfaceFormat mFormat;
|
const gfx::SurfaceFormat mFormat;
|
||||||
bool mContinuousUpdate;
|
bool mContinuousUpdate;
|
||||||
|
const bool mForceBT709ColorSpace;
|
||||||
const Maybe<gfx::Matrix4x4> mTransformOverride;
|
const Maybe<gfx::Matrix4x4> mTransformOverride;
|
||||||
RefPtr<CompositorOGL> mCompositor;
|
RefPtr<CompositorOGL> mCompositor;
|
||||||
RefPtr<SurfaceTextureSource> mTextureSource;
|
RefPtr<SurfaceTextureSource> mTextureSource;
|
||||||
|
|
|
@ -150,6 +150,8 @@ fn write_optimized_shaders(
|
||||||
) {
|
) {
|
||||||
flags.remove(ShaderFeatureFlags::TEXTURE_EXTERNAL_ESSL1);
|
flags.remove(ShaderFeatureFlags::TEXTURE_EXTERNAL_ESSL1);
|
||||||
}
|
}
|
||||||
|
// The optimizer cannot handle the required EXT_YUV_target extension
|
||||||
|
flags.remove(ShaderFeatureFlags::TEXTURE_EXTERNAL_BT709);
|
||||||
flags.remove(ShaderFeatureFlags::DITHERING);
|
flags.remove(ShaderFeatureFlags::DITHERING);
|
||||||
|
|
||||||
for (shader_name, configs) in get_shader_features(flags) {
|
for (shader_name, configs) in get_shader_features(flags) {
|
||||||
|
|
|
@ -15,6 +15,10 @@
|
||||||
#extension GL_OES_EGL_image_external : require
|
#extension GL_OES_EGL_image_external : require
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef WR_FEATURE_TEXTURE_EXTERNAL_BT709
|
||||||
|
#extension GL_EXT_YUV_target : require
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef WR_FEATURE_ADVANCED_BLEND
|
#ifdef WR_FEATURE_ADVANCED_BLEND
|
||||||
#extension GL_KHR_blend_equation_advanced : require
|
#extension GL_KHR_blend_equation_advanced : require
|
||||||
#endif
|
#endif
|
||||||
|
@ -31,6 +35,9 @@
|
||||||
|
|
||||||
#if defined(WR_FEATURE_TEXTURE_EXTERNAL_ESSL1)
|
#if defined(WR_FEATURE_TEXTURE_EXTERNAL_ESSL1)
|
||||||
#define TEX_SAMPLE(sampler, tex_coord) texture2D(sampler, tex_coord.xy)
|
#define TEX_SAMPLE(sampler, tex_coord) texture2D(sampler, tex_coord.xy)
|
||||||
|
#elif defined(WR_FEATURE_TEXTURE_EXTERNAL_BT709)
|
||||||
|
// Force conversion from yuv to rgb using BT709 colorspace
|
||||||
|
#define TEX_SAMPLE(sampler, tex_coord) vec4(yuv_2_rgb(texture(sampler, tex_coord.xy).xyz, itu_709), 1.0)
|
||||||
#else
|
#else
|
||||||
#define TEX_SAMPLE(sampler, tex_coord) texture(sampler, tex_coord.xy)
|
#define TEX_SAMPLE(sampler, tex_coord) texture(sampler, tex_coord.xy)
|
||||||
#endif
|
#endif
|
||||||
|
@ -207,6 +214,10 @@ uniform sampler2DRect sColor2;
|
||||||
uniform samplerExternalOES sColor0;
|
uniform samplerExternalOES sColor0;
|
||||||
uniform samplerExternalOES sColor1;
|
uniform samplerExternalOES sColor1;
|
||||||
uniform samplerExternalOES sColor2;
|
uniform samplerExternalOES sColor2;
|
||||||
|
#elif defined(WR_FEATURE_TEXTURE_EXTERNAL_BT709)
|
||||||
|
uniform __samplerExternal2DY2YEXT sColor0;
|
||||||
|
uniform __samplerExternal2DY2YEXT sColor1;
|
||||||
|
uniform __samplerExternal2DY2YEXT sColor2;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WR_FEATURE_DITHERING
|
#ifdef WR_FEATURE_DITHERING
|
||||||
|
|
|
@ -155,6 +155,7 @@ pub fn get_gl_target(target: ImageBufferKind) -> gl::GLuint {
|
||||||
ImageBufferKind::Texture2D => gl::TEXTURE_2D,
|
ImageBufferKind::Texture2D => gl::TEXTURE_2D,
|
||||||
ImageBufferKind::TextureRect => gl::TEXTURE_RECTANGLE,
|
ImageBufferKind::TextureRect => gl::TEXTURE_RECTANGLE,
|
||||||
ImageBufferKind::TextureExternal => gl::TEXTURE_EXTERNAL_OES,
|
ImageBufferKind::TextureExternal => gl::TEXTURE_EXTERNAL_OES,
|
||||||
|
ImageBufferKind::TextureExternalBT709 => gl::TEXTURE_EXTERNAL_OES,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,23 +39,27 @@ fn get_feature_string(kind: ImageBufferKind, texture_external_version: TextureEx
|
||||||
(ImageBufferKind::TextureRect, _) => "TEXTURE_RECT",
|
(ImageBufferKind::TextureRect, _) => "TEXTURE_RECT",
|
||||||
(ImageBufferKind::TextureExternal, TextureExternalVersion::ESSL3) => "TEXTURE_EXTERNAL",
|
(ImageBufferKind::TextureExternal, TextureExternalVersion::ESSL3) => "TEXTURE_EXTERNAL",
|
||||||
(ImageBufferKind::TextureExternal, TextureExternalVersion::ESSL1) => "TEXTURE_EXTERNAL_ESSL1",
|
(ImageBufferKind::TextureExternal, TextureExternalVersion::ESSL1) => "TEXTURE_EXTERNAL_ESSL1",
|
||||||
|
(ImageBufferKind::TextureExternalBT709, _) => "TEXTURE_EXTERNAL_BT709",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn has_platform_support(kind: ImageBufferKind, gl_type: &GlType) -> bool {
|
fn has_platform_support(kind: ImageBufferKind, device: &Device) -> bool {
|
||||||
match (kind, gl_type) {
|
match (kind, device.gl().get_type()) {
|
||||||
(ImageBufferKind::Texture2D, _) => true,
|
(ImageBufferKind::Texture2D, _) => true,
|
||||||
(ImageBufferKind::TextureRect, &GlType::Gles) => false,
|
(ImageBufferKind::TextureRect, GlType::Gles) => false,
|
||||||
(ImageBufferKind::TextureRect, &GlType::Gl) => true,
|
(ImageBufferKind::TextureRect, GlType::Gl) => true,
|
||||||
(ImageBufferKind::TextureExternal, &GlType::Gles) => true,
|
(ImageBufferKind::TextureExternal, GlType::Gles) => true,
|
||||||
(ImageBufferKind::TextureExternal, &GlType::Gl) => false,
|
(ImageBufferKind::TextureExternal, GlType::Gl) => false,
|
||||||
|
(ImageBufferKind::TextureExternalBT709, GlType::Gles) => device.supports_extension("GL_EXT_YUV_target"),
|
||||||
|
(ImageBufferKind::TextureExternalBT709, GlType::Gl) => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const IMAGE_BUFFER_KINDS: [ImageBufferKind; 3] = [
|
pub const IMAGE_BUFFER_KINDS: [ImageBufferKind; 4] = [
|
||||||
ImageBufferKind::Texture2D,
|
ImageBufferKind::Texture2D,
|
||||||
ImageBufferKind::TextureRect,
|
ImageBufferKind::TextureRect,
|
||||||
ImageBufferKind::TextureExternal,
|
ImageBufferKind::TextureExternal,
|
||||||
|
ImageBufferKind::TextureExternalBT709,
|
||||||
];
|
];
|
||||||
|
|
||||||
const ADVANCED_BLEND_FEATURE: &str = "ADVANCED_BLEND";
|
const ADVANCED_BLEND_FEATURE: &str = "ADVANCED_BLEND";
|
||||||
|
@ -830,7 +834,7 @@ impl Shaders {
|
||||||
cs_scale.push(None);
|
cs_scale.push(None);
|
||||||
}
|
}
|
||||||
for image_buffer_kind in &IMAGE_BUFFER_KINDS {
|
for image_buffer_kind in &IMAGE_BUFFER_KINDS {
|
||||||
if has_platform_support(*image_buffer_kind, &gl_type) {
|
if has_platform_support(*image_buffer_kind, device) {
|
||||||
let feature_string = get_feature_string(
|
let feature_string = get_feature_string(
|
||||||
*image_buffer_kind,
|
*image_buffer_kind,
|
||||||
texture_external_version,
|
texture_external_version,
|
||||||
|
@ -933,7 +937,7 @@ impl Shaders {
|
||||||
brush_fast_image.push(None);
|
brush_fast_image.push(None);
|
||||||
}
|
}
|
||||||
for buffer_kind in 0 .. IMAGE_BUFFER_KINDS.len() {
|
for buffer_kind in 0 .. IMAGE_BUFFER_KINDS.len() {
|
||||||
if !has_platform_support(IMAGE_BUFFER_KINDS[buffer_kind], &gl_type)
|
if !has_platform_support(IMAGE_BUFFER_KINDS[buffer_kind], device)
|
||||||
// Brush shaders are not ESSL1 compatible
|
// Brush shaders are not ESSL1 compatible
|
||||||
|| (IMAGE_BUFFER_KINDS[buffer_kind] == ImageBufferKind::TextureExternal
|
|| (IMAGE_BUFFER_KINDS[buffer_kind] == ImageBufferKind::TextureExternal
|
||||||
&& texture_external_version == TextureExternalVersion::ESSL1)
|
&& texture_external_version == TextureExternalVersion::ESSL1)
|
||||||
|
@ -988,7 +992,7 @@ impl Shaders {
|
||||||
brush_yuv_image.push(None);
|
brush_yuv_image.push(None);
|
||||||
}
|
}
|
||||||
for image_buffer_kind in &IMAGE_BUFFER_KINDS {
|
for image_buffer_kind in &IMAGE_BUFFER_KINDS {
|
||||||
if has_platform_support(*image_buffer_kind, &gl_type) {
|
if has_platform_support(*image_buffer_kind, device) {
|
||||||
yuv_features.push("YUV");
|
yuv_features.push("YUV");
|
||||||
fast_path_features.push("FAST_PATH");
|
fast_path_features.push("FAST_PATH");
|
||||||
|
|
||||||
|
@ -1361,7 +1365,7 @@ impl CompositorShaders {
|
||||||
}
|
}
|
||||||
|
|
||||||
for image_buffer_kind in &IMAGE_BUFFER_KINDS {
|
for image_buffer_kind in &IMAGE_BUFFER_KINDS {
|
||||||
if !has_platform_support(*image_buffer_kind, &gl_type) {
|
if !has_platform_support(*image_buffer_kind, device) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1486,7 +1490,10 @@ fn get_shader_feature_flags(gl_type: GlType, texture_external_version: TextureEx
|
||||||
GlType::Gl => ShaderFeatureFlags::GL,
|
GlType::Gl => ShaderFeatureFlags::GL,
|
||||||
GlType::Gles => {
|
GlType::Gles => {
|
||||||
let texture_external_flag = match texture_external_version {
|
let texture_external_flag = match texture_external_version {
|
||||||
TextureExternalVersion::ESSL3 => ShaderFeatureFlags::TEXTURE_EXTERNAL,
|
TextureExternalVersion::ESSL3 => {
|
||||||
|
ShaderFeatureFlags::TEXTURE_EXTERNAL
|
||||||
|
| ShaderFeatureFlags::TEXTURE_EXTERNAL_BT709
|
||||||
|
}
|
||||||
TextureExternalVersion::ESSL1 => ShaderFeatureFlags::TEXTURE_EXTERNAL_ESSL1,
|
TextureExternalVersion::ESSL1 => ShaderFeatureFlags::TEXTURE_EXTERNAL_ESSL1,
|
||||||
};
|
};
|
||||||
ShaderFeatureFlags::GLES | texture_external_flag
|
ShaderFeatureFlags::GLES | texture_external_flag
|
||||||
|
|
|
@ -117,6 +117,10 @@ pub enum ImageBufferKind {
|
||||||
/// understand, particularly YUV. See
|
/// understand, particularly YUV. See
|
||||||
/// https://www.khronos.org/registry/OpenGL/extensions/OES/OES_EGL_image_external.txt
|
/// https://www.khronos.org/registry/OpenGL/extensions/OES/OES_EGL_image_external.txt
|
||||||
TextureExternal = 2,
|
TextureExternal = 2,
|
||||||
|
/// External texture which is forced to be converted from YUV to RGB using BT709 colorspace.
|
||||||
|
/// This maps to GL_TEXTURE_EXTERNAL_OES in OpenGL, using the EXT_YUV_TARGET extension.
|
||||||
|
/// https://registry.khronos.org/OpenGL/extensions/EXT/EXT_YUV_target.txt
|
||||||
|
TextureExternalBT709 = 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Storage format identifier for externally-managed images.
|
/// Storage format identifier for externally-managed images.
|
||||||
|
|
|
@ -15,7 +15,8 @@ bitflags! {
|
||||||
const DITHERING = 1 << 10;
|
const DITHERING = 1 << 10;
|
||||||
const TEXTURE_EXTERNAL = 1 << 11;
|
const TEXTURE_EXTERNAL = 1 << 11;
|
||||||
const TEXTURE_EXTERNAL_ESSL1 = 1 << 12;
|
const TEXTURE_EXTERNAL_ESSL1 = 1 << 12;
|
||||||
const DEBUG = 1 << 13;
|
const TEXTURE_EXTERNAL_BT709 = 1 << 13;
|
||||||
|
const DEBUG = 1 << 14;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,6 +139,9 @@ pub fn get_shader_features(flags: ShaderFeatureFlags) -> ShaderFeatures {
|
||||||
if flags.contains(ShaderFeatureFlags::TEXTURE_EXTERNAL) {
|
if flags.contains(ShaderFeatureFlags::TEXTURE_EXTERNAL) {
|
||||||
texture_types.push("TEXTURE_EXTERNAL");
|
texture_types.push("TEXTURE_EXTERNAL");
|
||||||
}
|
}
|
||||||
|
if flags.contains(ShaderFeatureFlags::TEXTURE_EXTERNAL_BT709) {
|
||||||
|
texture_types.push("TEXTURE_EXTERNAL_BT709");
|
||||||
|
}
|
||||||
let mut image_features: Vec<String> = Vec::new();
|
let mut image_features: Vec<String> = Vec::new();
|
||||||
for texture_type in &texture_types {
|
for texture_type in &texture_types {
|
||||||
let mut fast = FeatureList::new();
|
let mut fast = FeatureList::new();
|
||||||
|
|
|
@ -126,6 +126,8 @@ pub fn test_shaders() {
|
||||||
}
|
}
|
||||||
// glsl-lang crate fails to parse advanced blend shaders
|
// glsl-lang crate fails to parse advanced blend shaders
|
||||||
flags.remove(ShaderFeatureFlags::ADVANCED_BLEND_EQUATION);
|
flags.remove(ShaderFeatureFlags::ADVANCED_BLEND_EQUATION);
|
||||||
|
// glsl-lang crate fails to parse texture external BT709 shaders
|
||||||
|
flags.remove(ShaderFeatureFlags::TEXTURE_EXTERNAL_BT709);
|
||||||
|
|
||||||
for (shader, configs) in get_shader_features(flags) {
|
for (shader, configs) in get_shader_features(flags) {
|
||||||
for config in configs {
|
for config in configs {
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
package org.mozilla.gecko.media;
|
package org.mozilla.gecko.media;
|
||||||
|
|
||||||
import android.media.MediaFormat;
|
import android.media.MediaFormat;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
|
@ -26,6 +27,8 @@ import java.nio.ByteBuffer;
|
||||||
* <li>{@link MediaFormat#KEY_I_FRAME_INTERVAL}
|
* <li>{@link MediaFormat#KEY_I_FRAME_INTERVAL}
|
||||||
* <li>{@link MediaFormat#KEY_STRIDE}
|
* <li>{@link MediaFormat#KEY_STRIDE}
|
||||||
* <li>{@link MediaFormat#KEY_SLICE_HEIGHT}
|
* <li>{@link MediaFormat#KEY_SLICE_HEIGHT}
|
||||||
|
* <li>{@link MediaFormat#KEY_COLOR_RANGE
|
||||||
|
* <li>{@link MediaFormat#KEY_COLOR_STANDARD}
|
||||||
* <li>"csd-0"
|
* <li>"csd-0"
|
||||||
* <li>"csd-1"
|
* <li>"csd-1"
|
||||||
* </ul>
|
* </ul>
|
||||||
|
@ -118,6 +121,15 @@ public final class FormatParam implements Parcelable {
|
||||||
if (bundle.containsKey(MediaFormat.KEY_SLICE_HEIGHT)) {
|
if (bundle.containsKey(MediaFormat.KEY_SLICE_HEIGHT)) {
|
||||||
mFormat.setInteger(MediaFormat.KEY_SLICE_HEIGHT, bundle.getInt(MediaFormat.KEY_SLICE_HEIGHT));
|
mFormat.setInteger(MediaFormat.KEY_SLICE_HEIGHT, bundle.getInt(MediaFormat.KEY_SLICE_HEIGHT));
|
||||||
}
|
}
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
|
if (bundle.containsKey(MediaFormat.KEY_COLOR_RANGE)) {
|
||||||
|
mFormat.setInteger(MediaFormat.KEY_COLOR_RANGE, bundle.getInt(MediaFormat.KEY_COLOR_RANGE));
|
||||||
|
}
|
||||||
|
if (bundle.containsKey(MediaFormat.KEY_COLOR_STANDARD)) {
|
||||||
|
mFormat.setInteger(
|
||||||
|
MediaFormat.KEY_COLOR_STANDARD, bundle.getInt(MediaFormat.KEY_COLOR_STANDARD));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -173,6 +185,15 @@ public final class FormatParam implements Parcelable {
|
||||||
if (mFormat.containsKey(MediaFormat.KEY_SLICE_HEIGHT)) {
|
if (mFormat.containsKey(MediaFormat.KEY_SLICE_HEIGHT)) {
|
||||||
bundle.putInt(MediaFormat.KEY_SLICE_HEIGHT, mFormat.getInteger(MediaFormat.KEY_SLICE_HEIGHT));
|
bundle.putInt(MediaFormat.KEY_SLICE_HEIGHT, mFormat.getInteger(MediaFormat.KEY_SLICE_HEIGHT));
|
||||||
}
|
}
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
|
if (mFormat.containsKey(MediaFormat.KEY_COLOR_RANGE)) {
|
||||||
|
bundle.putInt(MediaFormat.KEY_COLOR_RANGE, mFormat.getInteger(MediaFormat.KEY_COLOR_RANGE));
|
||||||
|
}
|
||||||
|
if (mFormat.containsKey(MediaFormat.KEY_COLOR_STANDARD)) {
|
||||||
|
bundle.putInt(
|
||||||
|
MediaFormat.KEY_COLOR_STANDARD, mFormat.getInteger(MediaFormat.KEY_COLOR_STANDARD));
|
||||||
|
}
|
||||||
|
}
|
||||||
return bundle;
|
return bundle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче