зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1016539. Add support for accelerated a11y filters. r=mwoodrow
This adds the ability to render to a temporary surface and use that to apply a filter effect to all of the content.
This commit is contained in:
Родитель
deb2e761b1
Коммит
df48ffb1b7
|
@ -143,6 +143,7 @@ MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(DiagnosticFlags)
|
|||
MOZ_BEGIN_ENUM_CLASS(EffectTypes, uint8_t)
|
||||
MASK,
|
||||
BLEND_MODE,
|
||||
COLOR_MATRIX,
|
||||
MAX_SECONDARY, // sentinel for the count of secondary effect types
|
||||
RGB,
|
||||
YCBCR,
|
||||
|
|
|
@ -61,3 +61,11 @@ EffectBlendMode::PrintInfo(std::stringstream& aStream, const char* aPrefix)
|
|||
aStream << nsPrintfCString("EffectBlendMode (0x%p) [blendmode=%i]", this, (int)mBlendMode).get();
|
||||
}
|
||||
|
||||
void
|
||||
EffectColorMatrix::PrintInfo(std::stringstream& aStream, const char* aPrefix)
|
||||
{
|
||||
aStream << aPrefix;
|
||||
aStream << nsPrintfCString("EffectColorMatrix (0x%p)", this).get();
|
||||
AppendToString(aStream, mColorMatrix, " [matrix=", "]");
|
||||
}
|
||||
|
||||
|
|
|
@ -121,8 +121,29 @@ struct EffectRenderTarget : public TexturedEffect
|
|||
virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix);
|
||||
|
||||
RefPtr<CompositingRenderTarget> mRenderTarget;
|
||||
|
||||
protected:
|
||||
EffectRenderTarget(EffectTypes aType, CompositingRenderTarget *aRenderTarget)
|
||||
: TexturedEffect(aType, aRenderTarget, true, gfx::Filter::LINEAR)
|
||||
, mRenderTarget(aRenderTarget)
|
||||
{}
|
||||
|
||||
};
|
||||
|
||||
// Render to a render target rather than the screen.
|
||||
struct EffectColorMatrix : public Effect
|
||||
{
|
||||
EffectColorMatrix(gfx::Matrix5x4 aMatrix)
|
||||
: Effect(EffectTypes::COLOR_MATRIX)
|
||||
, mColorMatrix(aMatrix)
|
||||
{}
|
||||
|
||||
virtual const char* Name() { return "EffectColorMatrix"; }
|
||||
virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix);
|
||||
const gfx::Matrix5x4 mColorMatrix;
|
||||
};
|
||||
|
||||
|
||||
struct EffectRGB : public TexturedEffect
|
||||
{
|
||||
EffectRGB(TextureSource *aTexture,
|
||||
|
|
|
@ -169,6 +169,22 @@ AppendToString(std::stringstream& aStream, const Matrix4x4& m,
|
|||
aStream << sfx;
|
||||
}
|
||||
|
||||
void
|
||||
AppendToString(std::stringstream& aStream, const Matrix5x4& m,
|
||||
const char* pfx, const char* sfx)
|
||||
{
|
||||
aStream << pfx;
|
||||
aStream << nsPrintfCString(
|
||||
"[ %g %g %g %g; %g %g %g %g; %g %g %g %g; %g %g %g %g; %g %g %g %g]",
|
||||
m._11, m._12, m._13, m._14,
|
||||
m._21, m._22, m._23, m._24,
|
||||
m._31, m._32, m._33, m._34,
|
||||
m._41, m._42, m._43, m._44,
|
||||
m._51, m._52, m._53, m._54).get();
|
||||
aStream << sfx;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AppendToString(std::stringstream& aStream, const Filter filter,
|
||||
const char* pfx, const char* sfx)
|
||||
|
|
|
@ -139,6 +139,10 @@ void
|
|||
AppendToString(std::stringstream& aStream, const mozilla::gfx::Matrix4x4& m,
|
||||
const char* pfx="", const char* sfx="");
|
||||
|
||||
void
|
||||
AppendToString(std::stringstream& aStream, const mozilla::gfx::Matrix5x4& m,
|
||||
const char* pfx="", const char* sfx="");
|
||||
|
||||
void
|
||||
AppendToString(std::stringstream& aStream, const mozilla::gfx::Filter filter,
|
||||
const char* pfx="", const char* sfx="");
|
||||
|
|
|
@ -410,6 +410,58 @@ LayerManagerComposite::RenderDebugOverlay(const Rect& aBounds)
|
|||
}
|
||||
}
|
||||
|
||||
RefPtr<CompositingRenderTarget>
|
||||
LayerManagerComposite::PushGroup()
|
||||
{
|
||||
RefPtr<CompositingRenderTarget> previousTarget = mCompositor->GetCurrentRenderTarget();
|
||||
// make our render target the same size as the destination target
|
||||
// so that we don't have to change size if the drawing area changes.
|
||||
IntRect rect(previousTarget->GetOrigin(), previousTarget->GetSize());
|
||||
// XXX: I'm not sure if this is true or not...
|
||||
MOZ_ASSERT(rect.x == 0 && rect.y == 0);
|
||||
if (!mTwoPassTmpTarget ||
|
||||
mTwoPassTmpTarget->GetSize() != previousTarget->GetSize() ||
|
||||
mTwoPassTmpTarget->GetOrigin() != previousTarget->GetOrigin()) {
|
||||
mTwoPassTmpTarget = mCompositor->CreateRenderTarget(rect, INIT_MODE_NONE);
|
||||
}
|
||||
mCompositor->SetRenderTarget(mTwoPassTmpTarget);
|
||||
return previousTarget;
|
||||
}
|
||||
void LayerManagerComposite::PopGroup(RefPtr<CompositingRenderTarget> aPreviousTarget, nsIntRect aClipRect)
|
||||
{
|
||||
mCompositor->SetRenderTarget(aPreviousTarget);
|
||||
|
||||
EffectChain effectChain(RootLayer());
|
||||
Matrix5x4 matrix;
|
||||
if (gfxPrefs::Grayscale()) {
|
||||
matrix._11 = matrix._12 = matrix._13 = 0.2126f;
|
||||
matrix._21 = matrix._22 = matrix._23 = 0.7152f;
|
||||
matrix._31 = matrix._32 = matrix._33 = 0.0722f;
|
||||
}
|
||||
|
||||
if (gfxPrefs::Invert()) {
|
||||
matrix._11 = -matrix._11;
|
||||
matrix._12 = -matrix._12;
|
||||
matrix._13 = -matrix._13;
|
||||
matrix._21 = -matrix._21;
|
||||
matrix._22 = -matrix._22;
|
||||
matrix._23 = -matrix._23;
|
||||
matrix._31 = -matrix._31;
|
||||
matrix._32 = -matrix._32;
|
||||
matrix._33 = -matrix._33;
|
||||
matrix._51 = 1;
|
||||
matrix._52 = 1;
|
||||
matrix._53 = 1;
|
||||
}
|
||||
|
||||
effectChain.mPrimaryEffect = new EffectRenderTarget(mTwoPassTmpTarget);
|
||||
effectChain.mSecondaryEffects[EffectTypes::COLOR_MATRIX] = new EffectColorMatrix(matrix);
|
||||
|
||||
gfx::Rect clipRectF(aClipRect.x, aClipRect.y, aClipRect.width, aClipRect.height);
|
||||
mCompositor->DrawQuad(Rect(Point(0, 0), Size(mTwoPassTmpTarget->GetSize())), clipRectF, effectChain, 1.,
|
||||
Matrix4x4());
|
||||
}
|
||||
|
||||
void
|
||||
LayerManagerComposite::Render()
|
||||
{
|
||||
|
@ -442,6 +494,10 @@ LayerManagerComposite::Render()
|
|||
LayerScope::SendLayerDump(Move(packet));
|
||||
}
|
||||
|
||||
if (gfxPrefs::Invert() || gfxPrefs::Grayscale()) {
|
||||
composer2D = nullptr;
|
||||
}
|
||||
|
||||
if (!mTarget && composer2D && composer2D->TryRender(mRoot, mWorldMatrix, mGeometryChanged)) {
|
||||
if (mFPS) {
|
||||
double fps = mFPS->mCompositionFps.AddFrameAndGetFps(TimeStamp::Now());
|
||||
|
@ -501,6 +557,13 @@ LayerManagerComposite::Render()
|
|||
actualBounds.width,
|
||||
actualBounds.height));
|
||||
|
||||
RefPtr<CompositingRenderTarget> previousTarget;
|
||||
if (gfxPrefs::Invert() || gfxPrefs::Grayscale()) {
|
||||
previousTarget = PushGroup();
|
||||
} else {
|
||||
mTwoPassTmpTarget = nullptr;
|
||||
}
|
||||
|
||||
// Render our layers.
|
||||
RootLayer()->Prepare(clipRect);
|
||||
RootLayer()->RenderLayer(clipRect);
|
||||
|
@ -513,6 +576,10 @@ LayerManagerComposite::Render()
|
|||
}
|
||||
}
|
||||
|
||||
if (mTwoPassTmpTarget) {
|
||||
PopGroup(previousTarget, clipRect);
|
||||
}
|
||||
|
||||
// Allow widget to render a custom foreground.
|
||||
mCompositor->GetWidget()->DrawWindowOverlay(this, nsIntRect(actualBounds.x,
|
||||
actualBounds.y,
|
||||
|
|
|
@ -63,6 +63,7 @@ class SurfaceDescriptor;
|
|||
class ThebesLayerComposite;
|
||||
class TiledLayerComposer;
|
||||
class TextRenderer;
|
||||
class CompositingRenderTarget;
|
||||
struct FPSState;
|
||||
|
||||
class LayerManagerComposite : public LayerManager
|
||||
|
@ -268,6 +269,9 @@ private:
|
|||
|
||||
void WorldTransformRect(nsIntRect& aRect);
|
||||
|
||||
RefPtr<CompositingRenderTarget> PushGroup();
|
||||
void PopGroup(RefPtr<CompositingRenderTarget> aPreviousTarget, nsIntRect aClipRect);
|
||||
|
||||
RefPtr<Compositor> mCompositor;
|
||||
nsAutoPtr<LayerProperties> mClonedLayerTreeProperties;
|
||||
|
||||
|
@ -285,6 +289,7 @@ private:
|
|||
bool mIsCompositorReady;
|
||||
bool mDebugOverlayWantsNextFrame;
|
||||
|
||||
RefPtr<CompositingRenderTarget> mTwoPassTmpTarget;
|
||||
RefPtr<TextRenderer> mTextRenderer;
|
||||
bool mGeometryChanged;
|
||||
};
|
||||
|
|
|
@ -137,9 +137,7 @@ public:
|
|||
}
|
||||
gfx::IntSize GetSize() const MOZ_OVERRIDE
|
||||
{
|
||||
// XXX - Bug 900770
|
||||
MOZ_ASSERT(false, "CompositingRenderTargetOGL should not be used as a TextureSource");
|
||||
return gfx::IntSize(0, 0);
|
||||
return mInitParams.mSize;
|
||||
}
|
||||
|
||||
gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE
|
||||
|
|
|
@ -897,7 +897,8 @@ CompositorOGL::CreateFBOWithTexture(const IntRect& aRect, bool aCopyFromSource,
|
|||
ShaderConfigOGL
|
||||
CompositorOGL::GetShaderConfigFor(Effect *aEffect,
|
||||
MaskType aMask,
|
||||
gfx::CompositionOp aOp) const
|
||||
gfx::CompositionOp aOp,
|
||||
bool aColorMatrix) const
|
||||
{
|
||||
ShaderConfigOGL config;
|
||||
|
||||
|
@ -944,6 +945,7 @@ CompositorOGL::GetShaderConfigFor(Effect *aEffect,
|
|||
break;
|
||||
}
|
||||
}
|
||||
config.SetColorMatrix(aColorMatrix);
|
||||
config.SetMask2D(aMask == MaskType::Mask2d);
|
||||
config.SetMask3D(aMask == MaskType::Mask3d);
|
||||
return config;
|
||||
|
@ -1091,12 +1093,20 @@ CompositorOGL::DrawQuad(const Rect& aRect,
|
|||
blendMode = blendEffect->mBlendMode;
|
||||
}
|
||||
|
||||
ShaderConfigOGL config = GetShaderConfigFor(aEffectChain.mPrimaryEffect, maskType, blendMode);
|
||||
bool colorMatrix = aEffectChain.mSecondaryEffects[EffectTypes::COLOR_MATRIX];
|
||||
ShaderConfigOGL config = GetShaderConfigFor(aEffectChain.mPrimaryEffect, maskType, blendMode, colorMatrix);
|
||||
config.SetOpacity(aOpacity != 1.f);
|
||||
ShaderProgramOGL *program = GetShaderProgramFor(config);
|
||||
program->Activate();
|
||||
program->SetProjectionMatrix(mProjMatrix);
|
||||
program->SetLayerTransform(aTransform);
|
||||
|
||||
if (colorMatrix) {
|
||||
EffectColorMatrix* effectColorMatrix =
|
||||
static_cast<EffectColorMatrix*>(aEffectChain.mSecondaryEffects[EffectTypes::COLOR_MATRIX].get());
|
||||
program->SetColorMatrix(effectColorMatrix->mColorMatrix);
|
||||
}
|
||||
|
||||
IntPoint offset = mCurrentRenderTarget->GetOrigin();
|
||||
program->SetRenderOffset(offset.x, offset.y);
|
||||
if (aOpacity != 1.f)
|
||||
|
|
|
@ -333,7 +333,8 @@ private:
|
|||
|
||||
ShaderConfigOGL GetShaderConfigFor(Effect *aEffect,
|
||||
MaskType aMask = MaskType::MaskNone,
|
||||
gfx::CompositionOp aOp = gfx::CompositionOp::OP_OVER) const;
|
||||
gfx::CompositionOp aOp = gfx::CompositionOp::OP_OVER,
|
||||
bool aColorMatrix = false) const;
|
||||
ShaderProgramOGL* GetShaderProgramFor(const ShaderConfigOGL &aConfig);
|
||||
|
||||
/**
|
||||
|
|
|
@ -47,6 +47,8 @@ AddUniforms(ProgramProfileOGL& aProfile)
|
|||
"uRenderColor",
|
||||
"uTexCoordMultiplier",
|
||||
"uTexturePass2",
|
||||
"uColorMatrix",
|
||||
"uColorMatrixVector",
|
||||
nullptr
|
||||
};
|
||||
|
||||
|
|
|
@ -68,6 +68,8 @@ public:
|
|||
RenderColor,
|
||||
TexCoordMultiplier,
|
||||
TexturePass2,
|
||||
ColorMatrix,
|
||||
ColorMatrixVector,
|
||||
|
||||
KnownUniformCount
|
||||
};
|
||||
|
@ -369,6 +371,12 @@ public:
|
|||
SetUniform(KnownUniform::RenderColor, aColor);
|
||||
}
|
||||
|
||||
void SetColorMatrix(const gfx::Matrix5x4& aColorMatrix)
|
||||
{
|
||||
SetMatrixUniform(KnownUniform::ColorMatrix, &aColorMatrix._11);
|
||||
SetUniform(KnownUniform::ColorMatrixVector, 4, &aColorMatrix._51);
|
||||
}
|
||||
|
||||
void SetTexCoordMultiplier(float aWidth, float aHeight) {
|
||||
float f[] = {aWidth, aHeight};
|
||||
SetUniform(KnownUniform::TexCoordMultiplier, 2, f);
|
||||
|
@ -432,7 +440,7 @@ protected:
|
|||
}
|
||||
}
|
||||
|
||||
void SetUniform(KnownUniform::KnownUniformName aKnownUniform, int aLength, float *aFloatValues)
|
||||
void SetUniform(KnownUniform::KnownUniformName aKnownUniform, int aLength, const float *aFloatValues)
|
||||
{
|
||||
ASSERT_THIS_PROGRAM;
|
||||
NS_ASSERTION(aKnownUniform >= 0 && aKnownUniform < KnownUniform::KnownUniformCount, "Invalid known uniform");
|
||||
|
|
|
@ -250,6 +250,8 @@ private:
|
|||
DECL_GFX_PREF(Once, "layers.progressive-paint", UseProgressiveTilePainting, bool, false);
|
||||
DECL_GFX_PREF(Once, "layers.scroll-graph", LayersScrollGraph, bool, false);
|
||||
DECL_GFX_PREF(Once, "layers.uniformity-info", UniformityInfo, bool, false);
|
||||
DECL_GFX_PREF(Live, "layers.invert", Invert, bool, false);
|
||||
DECL_GFX_PREF(Live, "layers.grayscale", Grayscale, bool, false);
|
||||
|
||||
DECL_GFX_PREF(Live, "layout.css.scroll-behavior.damping-ratio", ScrollBehaviorDampingRatio, float, 1.0f);
|
||||
DECL_GFX_PREF(Live, "layout.css.scroll-behavior.enabled", ScrollBehaviorEnabled, bool, false);
|
||||
|
|
Загрузка…
Ссылка в новой задаче