When mix-blending, only copy intersecting backdrop pixels. (bug 1235995 part 2, r=mattwoodrow)

This commit is contained in:
David Anderson 2016-01-19 13:28:08 +07:00
parent cf1d101569
commit 92ea5e02b0
6 changed files with 64 additions and 12 deletions

View File

@ -357,6 +357,28 @@ DecomposeIntoNoRepeatRects(const gfx::Rect& aRect,
return 4;
}
gfx::IntRect
Compositor::ComputeBackdropCopyRect(const gfx::Rect& aRect,
const gfx::Rect& aClipRect,
const gfx::Matrix4x4& aTransform)
{
gfx::Rect renderBounds = mRenderBounds;
// Compute the clip.
renderBounds.IntersectRect(renderBounds, aClipRect);
// Apply the layer transform.
gfx::Rect dest = aTransform.TransformAndClipBounds(aRect, renderBounds);
dest.RoundOut();
gfx::IntRect result;
dest.ToIntRect(&result);
gfx::IntPoint offset = GetCurrentRenderTarget()->GetOrigin();
result.MoveBy(-offset);
return result;
}
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
void
Compositor::SetDispAcquireFence(Layer* aLayer, nsIWidget* aWidget)

View File

@ -514,6 +514,16 @@ protected:
bool ShouldDrawDiagnostics(DiagnosticFlags);
/**
* Given a layer rect, clip, and transform, compute the area of the backdrop that
* needs to be copied for mix-blending. The output transform translates from 0..1
* space into the backdrop rect space.
*/
gfx::IntRect ComputeBackdropCopyRect(
const gfx::Rect& aRect,
const gfx::Rect& aClipRect,
const gfx::Matrix4x4& aTransform);
/**
* Render time for the current composition.
*/
@ -542,6 +552,8 @@ protected:
RefPtr<gfx::DrawTarget> mTarget;
gfx::IntRect mTargetBounds;
gfx::Rect mRenderBounds;
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
FenceHandle mReleaseFenceHandle;
#endif

View File

@ -486,7 +486,7 @@ CompositorOGL::PrepareViewport(CompositingRenderTargetOGL* aRenderTarget)
// Set the viewport correctly.
mGLContext->fViewport(0, 0, size.width, size.height);
mRenderBound = Rect(0, 0, size.width, size.height);
mRenderBounds = Rect(0, 0, size.width, size.height);
mViewportSize = size;
@ -1007,7 +1007,7 @@ CompositorOGL::DrawQuad(const Rect& aRect,
}
IntPoint offset = mCurrentRenderTarget->GetOrigin();
Rect renderBound = mRenderBound;
Rect renderBound = mRenderBounds;
renderBound.IntersectRect(renderBound, aClipRect);
renderBound.MoveBy(offset);
@ -1021,7 +1021,7 @@ CompositorOGL::DrawQuad(const Rect& aRect,
// Inflate a small size to avoid some numerical imprecision issue.
destRect.Inflate(1, 1);
destRect.MoveBy(-offset);
if (!mRenderBound.Intersects(destRect)) {
if (!mRenderBounds.Intersects(destRect)) {
return;
}
@ -1099,11 +1099,6 @@ CompositorOGL::DrawQuad(const Rect& aRect,
EffectBlendMode *blendEffect =
static_cast<EffectBlendMode*>(aEffectChain.mSecondaryEffects[EffectTypes::BLEND_MODE].get());
blendMode = blendEffect->mBlendMode;
if (BlendOpIsMixBlendMode(blendMode)) {
gfx::IntRect rect(gfx::IntPoint(0, 0), mCurrentRenderTarget->GetSize());
mixBlendBackdrop = CreateTexture(rect, true, mCurrentRenderTarget->GetFBO());
}
}
// Only apply DEAA to quads that have been transformed such that aliasing
@ -1127,6 +1122,20 @@ CompositorOGL::DrawQuad(const Rect& aRect,
program->SetColorMatrix(effectColorMatrix->mColorMatrix);
}
if (BlendOpIsMixBlendMode(blendMode)) {
gfx::IntRect rect = ComputeBackdropCopyRect(aRect, aClipRect, aTransform);
mixBlendBackdrop = CreateTexture(rect, true, mCurrentRenderTarget->GetFBO());
// Create a transform from adjusted clip space to render target space,
// translate it for the backdrop rect, then transform it into the backdrop's
// uv-space.
gfx::Matrix4x4 transform;
transform.PostScale(mRenderBounds.width, mRenderBounds.height, 1.0);
transform.PostTranslate(-rect.x, -rect.y, 0.0);
transform.PostScale(1 / float(rect.width), 1 / float(rect.height), 1.0);
program->SetBackdropTransform(transform);
}
program->SetRenderOffset(offset.x, offset.y);
LayerScope::SetRenderOffset(offset.x, offset.y);

View File

@ -488,8 +488,6 @@ private:
ShaderProgramOGL *mCurrentProgram;
gfx::Rect mRenderBound;
CompositorOGLVRObjects mVR;
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 21

View File

@ -30,6 +30,7 @@ AddUniforms(ProgramProfileOGL& aProfile)
"uLayerTransform",
"uLayerTransformInverse",
"uMaskTransform",
"uBackdropTransform",
"uLayerRects",
"uMatrixProj",
"uTextureTransform",
@ -200,6 +201,7 @@ ProgramProfileOGL::GetProfileFor(ShaderConfigOGL aConfig)
}
if (BlendOpIsMixBlendMode(blendOp)) {
vs << "uniform mat4 uBackdropTransform;" << endl;
vs << "varying vec2 vBackdropCoord;" << endl;
}
@ -287,8 +289,12 @@ ProgramProfileOGL::GetProfileFor(ShaderConfigOGL aConfig)
vs << " finalPosition.xy -= uRenderTargetOffset * finalPosition.w;" << endl;
vs << " finalPosition = uMatrixProj * finalPosition;" << endl;
if (BlendOpIsMixBlendMode(blendOp)) {
// Move from clip space coordinates into texture/uv-coordinates.
vs << " vBackdropCoord = (finalPosition.xy + vec2(1.0, 1.0)) / 2.0;" << endl;
// Translate from clip space (-1, 1) to (0..1), apply the backdrop
// transform, then invert the y-axis.
vs << " vBackdropCoord.x = (finalPosition.x + 1.0) / 2.0;" << endl;
vs << " vBackdropCoord.y = 1.0 - (finalPosition.y + 1.0) / 2.0;" << endl;
vs << " vBackdropCoord = (uBackdropTransform * vec4(vBackdropCoord.xy, 0.0, 1.0)).xy;" << endl;
vs << " vBackdropCoord.y = 1.0 - vBackdropCoord.y;" << endl;
}
vs << " gl_Position = finalPosition;" << endl;
vs << "}" << endl;

View File

@ -52,6 +52,7 @@ public:
LayerTransform = 0,
LayerTransformInverse,
MaskTransform,
BackdropTransform,
LayerRects,
MatrixProj,
TextureTransform,
@ -352,6 +353,10 @@ public:
SetMatrixUniform(KnownUniform::MaskTransform, aMatrix);
}
void SetBackdropTransform(const gfx::Matrix4x4& aMatrix) {
SetMatrixUniform(KnownUniform::BackdropTransform, aMatrix);
}
void SetDEAAEdges(const gfx::Point3D* aEdges) {
SetArrayUniform(KnownUniform::SSEdges, 4, aEdges);
}