From 8e06ddd10e8851154b95b679599459ac023983a0 Mon Sep 17 00:00:00 2001 From: Matt Woodrow Date: Mon, 3 Aug 2015 17:57:39 -0400 Subject: [PATCH] Bug 1061525 - Part 4: Add an NV12 effect, and implement it for CompositorOGL. r=nical --- gfx/layers/CompositorTypes.h | 1 + gfx/layers/Effects.h | 12 +++++++++ gfx/layers/opengl/CompositorOGL.cpp | 38 +++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+) diff --git a/gfx/layers/CompositorTypes.h b/gfx/layers/CompositorTypes.h index 10f5a9fbbcc3..e6e56abef3e2 100644 --- a/gfx/layers/CompositorTypes.h +++ b/gfx/layers/CompositorTypes.h @@ -121,6 +121,7 @@ enum class EffectTypes : uint8_t { MAX_SECONDARY, // sentinel for the count of secondary effect types RGB, YCBCR, + NV12, COMPONENT_ALPHA, SOLID_COLOR, RENDER_TARGET, diff --git a/gfx/layers/Effects.h b/gfx/layers/Effects.h index 7fb206b49ea4..53d397a19558 100644 --- a/gfx/layers/Effects.h +++ b/gfx/layers/Effects.h @@ -197,6 +197,15 @@ struct EffectYCbCr : public TexturedEffect virtual const char* Name() { return "EffectYCbCr"; } }; +struct EffectNV12 : public TexturedEffect +{ + EffectNV12(TextureSource *aSource, gfx::Filter aFilter) + : TexturedEffect(EffectTypes::NV12, aSource, false, aFilter) + {} + + virtual const char* Name() { return "EffectNV12"; } +}; + struct EffectComponentAlpha : public TexturedEffect { EffectComponentAlpha(TextureSource *aOnBlack, @@ -265,6 +274,9 @@ CreateTexturedEffect(gfx::SurfaceFormat aFormat, case gfx::SurfaceFormat::YUV: result = new EffectYCbCr(aSource, aFilter); break; + case gfx::SurfaceFormat::NV12: + result = new EffectNV12(aSource, aFilter); + break; default: NS_WARNING("unhandled program type"); break; diff --git a/gfx/layers/opengl/CompositorOGL.cpp b/gfx/layers/opengl/CompositorOGL.cpp index d4e8ddc9f1b8..a043b8cdc5eb 100644 --- a/gfx/layers/opengl/CompositorOGL.cpp +++ b/gfx/layers/opengl/CompositorOGL.cpp @@ -812,6 +812,10 @@ CompositorOGL::GetShaderConfigFor(Effect *aEffect, case EffectTypes::YCBCR: config.SetYCbCr(true); break; + case EffectTypes::NV12: + config.SetNV12(true); + config.SetTextureTarget(LOCAL_GL_TEXTURE_RECTANGLE_ARB); + break; case EffectTypes::COMPONENT_ALPHA: { config.SetComponentAlpha(true); @@ -1251,6 +1255,40 @@ CompositorOGL::DrawQuad(const Rect& aRect, sourceYCbCr->GetSubSource(Y)); } break; + case EffectTypes::NV12: { + EffectNV12* effectNV12 = + static_cast(aEffectChain.mPrimaryEffect.get()); + TextureSource* sourceNV12 = effectNV12->mTexture; + const int Y = 0, CbCr = 1; + TextureSourceOGL* sourceY = sourceNV12->GetSubSource(Y)->AsSourceOGL(); + TextureSourceOGL* sourceCbCr = sourceNV12->GetSubSource(CbCr)->AsSourceOGL(); + + if (!sourceY || !sourceCbCr) { + NS_WARNING("Invalid layer texture."); + return; + } + + sourceY->BindTexture(LOCAL_GL_TEXTURE0, effectNV12->mFilter); + sourceCbCr->BindTexture(LOCAL_GL_TEXTURE1, effectNV12->mFilter); + + if (config.mFeatures & ENABLE_TEXTURE_RECT) { + // This is used by IOSurface that use 0,0...w,h coordinate rather then 0,0..1,1. + program->SetCbCrTexCoordMultiplier(sourceCbCr->GetSize().width, sourceCbCr->GetSize().height); + } + + program->SetNV12TextureUnits(Y, CbCr); + program->SetTextureTransform(Matrix4x4()); + + if (maskType != MaskType::MaskNone) { + BindMaskForProgram(program, sourceMask, LOCAL_GL_TEXTURE2, maskQuadTransform); + } + didSetBlendMode = SetBlendMode(gl(), blendMode); + BindAndDrawQuadWithTextureRect(program, + aRect, + effectNV12->mTextureCoords, + sourceNV12->GetSubSource(Y)); + } + break; case EffectTypes::RENDER_TARGET: { EffectRenderTarget* effectRenderTarget = static_cast(aEffectChain.mPrimaryEffect.get());