diff --git a/gfx/gl/GLContext.cpp b/gfx/gl/GLContext.cpp index 859411b539ff..2e8b379a1d6c 100644 --- a/gfx/gl/GLContext.cpp +++ b/gfx/gl/GLContext.cpp @@ -3017,7 +3017,8 @@ GetBytesPerTexel(GLenum format, GLenum type) } } else if (type == LOCAL_GL_UNSIGNED_SHORT_4_4_4_4 || type == LOCAL_GL_UNSIGNED_SHORT_5_5_5_1 || - type == LOCAL_GL_UNSIGNED_SHORT_5_6_5) + type == LOCAL_GL_UNSIGNED_SHORT_5_6_5 || + type == LOCAL_GL_UNSIGNED_SHORT) { return 2; } diff --git a/gfx/gl/GLUploadHelpers.cpp b/gfx/gl/GLUploadHelpers.cpp index ef255d823c50..48d025013850 100644 --- a/gfx/gl/GLUploadHelpers.cpp +++ b/gfx/gl/GLUploadHelpers.cpp @@ -464,6 +464,14 @@ UploadImageDataToTexture(GLContext* gl, // We don't have a specific luminance shader surfaceFormat = SurfaceFormat::A8; break; + case SurfaceFormat::A16: + format = LOCAL_GL_LUMINANCE; + internalFormat = LOCAL_GL_LUMINANCE16; + type = LOCAL_GL_UNSIGNED_SHORT; + // We don't have a specific luminance shader + surfaceFormat = SurfaceFormat::A8; + pixelSize = 2; + break; default: NS_ASSERTION(false, "Unhandled image surface format!"); } diff --git a/gfx/layers/opengl/CompositorOGL.cpp b/gfx/layers/opengl/CompositorOGL.cpp index 94e1592f5962..a7863cc3d99c 100644 --- a/gfx/layers/opengl/CompositorOGL.cpp +++ b/gfx/layers/opengl/CompositorOGL.cpp @@ -832,8 +832,18 @@ CompositorOGL::GetShaderConfigFor(Effect *aEffect, config.SetRenderColor(true); break; case EffectTypes::YCBCR: + { config.SetYCbCr(true); + EffectYCbCr* effectYCbCr = + static_cast(aEffect); + uint32_t pixelBits = (8 * BytesPerPixel(SurfaceFormatForAlphaBitDepth(effectYCbCr->mBitDepth))); + uint32_t paddingBits = pixelBits - effectYCbCr->mBitDepth; + // OpenGL expects values between [0,255], this range needs to be adjusted + // according to the bit depth. + // So we will scale the YUV values by this amount. + config.SetColorMultiplier(pow(2, paddingBits)); break; + } case EffectTypes::NV12: config.SetNV12(true); config.SetTextureTarget(LOCAL_GL_TEXTURE_RECTANGLE_ARB); diff --git a/gfx/layers/opengl/OGLShaderProgram.cpp b/gfx/layers/opengl/OGLShaderProgram.cpp index d87a87bb124d..9244d5e9d839 100644 --- a/gfx/layers/opengl/OGLShaderProgram.cpp +++ b/gfx/layers/opengl/OGLShaderProgram.cpp @@ -114,6 +114,13 @@ ShaderConfigOGL::SetYCbCr(bool aEnabled) MOZ_ASSERT(!(mFeatures & ENABLE_TEXTURE_NV12)); } +void +ShaderConfigOGL::SetColorMultiplier(uint32_t aMultiplier) +{ + MOZ_ASSERT(mFeatures & ENABLE_TEXTURE_YCBCR, "Multiplier only supported with YCbCr!"); + mMultiplier = aMultiplier; +} + void ShaderConfigOGL::SetNV12(bool aEnabled) { @@ -441,11 +448,12 @@ ProgramProfileOGL::GetProfileFor(ShaderConfigOGL aConfig) fs << " COLOR_PRECISION float cr = " << texture2D << "(uCbTexture, coord).a;" << endl; } } - - fs << " y = y - 0.06275;" << endl; - fs << " cb = cb - 0.50196;" << endl; - fs << " cr = cr - 0.50196;" << endl; fs << " vec3 yuv = vec3(y, cb, cr);" << endl; + if (aConfig.mMultiplier != 1) { + fs << " yuv *= " << aConfig.mMultiplier << ".0;" << endl; + } + fs << " vec3 coeff = vec3(0.06275, 0.50196, 0.50196 );" << endl; + fs << " yuv -= coeff;" << endl; fs << " color.rgb = uYuvColorMatrix * yuv;" << endl; fs << " color.a = 1.0;" << endl; } else if (aConfig.mFeatures & ENABLE_TEXTURE_COMPONENT_ALPHA) { diff --git a/gfx/layers/opengl/OGLShaderProgram.h b/gfx/layers/opengl/OGLShaderProgram.h index 97098f1a309f..7698117fecb3 100644 --- a/gfx/layers/opengl/OGLShaderProgram.h +++ b/gfx/layers/opengl/OGLShaderProgram.h @@ -212,10 +212,12 @@ public: class ShaderConfigOGL { public: - ShaderConfigOGL() : - mFeatures(0), - mCompositionOp(gfx::CompositionOp::OP_OVER) - {} + ShaderConfigOGL() + : mFeatures(0) + , mMultiplier(1) + , mCompositionOp(gfx::CompositionOp::OP_OVER) + { + } void SetRenderColor(bool aEnabled); void SetTextureTarget(GLenum aTarget); @@ -232,15 +234,21 @@ public: void SetCompositionOp(gfx::CompositionOp aOp); void SetNoPremultipliedAlpha(); void SetDynamicGeometry(bool aEnabled); + void SetColorMultiplier(uint32_t aMultiplier); - bool operator< (const ShaderConfigOGL& other) const { + bool operator< (const ShaderConfigOGL& other) const + { return mFeatures < other.mFeatures || (mFeatures == other.mFeatures && - (int)mCompositionOp < (int)other.mCompositionOp); + (int)mCompositionOp < (int)other.mCompositionOp) || + (mFeatures == other.mFeatures && + (int)mCompositionOp == (int)other.mCompositionOp && + mMultiplier < other.mMultiplier); } public: - void SetFeature(int aBitmask, bool aState) { + void SetFeature(int aBitmask, bool aState) + { if (aState) mFeatures |= aBitmask; else @@ -248,6 +256,7 @@ public: } int mFeatures; + uint32_t mMultiplier; gfx::CompositionOp mCompositionOp; }; @@ -399,7 +408,7 @@ public: float vals[16] = { aRects[0].x, aRects[0].y, aRects[0].Width(), aRects[0].Height(), aRects[1].x, aRects[1].y, aRects[1].Width(), aRects[1].Height(), aRects[2].x, aRects[2].y, aRects[2].Width(), aRects[2].Height(), - aRects[3].x, aRects[3].y, aRects[3].Width(), aRects[3].Height() }; + aRects[3].x, aRects[3].y, aRects[3].Width(), aRects[3].Height() }; SetUniform(KnownUniform::TextureRects, 16, vals); }