зеркало из https://github.com/mozilla/gecko-dev.git
Bug 950312 - Part 6: Share code for computing layers component alpha support. r=roc
This commit is contained in:
Родитель
96efeab991
Коммит
f05c7aef5f
|
@ -31,6 +31,7 @@
|
|||
#include "nsCSSValue.h" // for nsCSSValue::Array, etc
|
||||
#include "nsPrintfCString.h" // for nsPrintfCString
|
||||
#include "nsStyleStruct.h" // for nsTimingFunction, etc
|
||||
#include "gfxPrefs.h"
|
||||
|
||||
using namespace mozilla::layers;
|
||||
using namespace mozilla::gfx;
|
||||
|
@ -1001,6 +1002,38 @@ ContainerLayer::DefaultComputeEffectiveTransforms(const Matrix4x4& aTransformToS
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
ContainerLayer::DefaultComputeSupportsComponentAlphaChildren(bool* aNeedsSurfaceCopy)
|
||||
{
|
||||
bool supportsComponentAlphaChildren = false;
|
||||
bool needsSurfaceCopy = false;
|
||||
if (UseIntermediateSurface()) {
|
||||
if (GetEffectiveVisibleRegion().GetNumRects() == 1 &&
|
||||
(GetContentFlags() & Layer::CONTENT_OPAQUE))
|
||||
{
|
||||
supportsComponentAlphaChildren = true;
|
||||
} else {
|
||||
gfx::Matrix transform;
|
||||
if (HasOpaqueAncestorLayer(this) &&
|
||||
GetEffectiveTransform().Is2D(&transform) &&
|
||||
!gfx::ThebesMatrix(transform).HasNonIntegerTranslation()) {
|
||||
supportsComponentAlphaChildren = true;
|
||||
needsSurfaceCopy = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
supportsComponentAlphaChildren =
|
||||
(GetContentFlags() & Layer::CONTENT_OPAQUE) ||
|
||||
(GetParent() && GetParent()->SupportsComponentAlphaChildren());
|
||||
}
|
||||
|
||||
mSupportsComponentAlphaChildren = supportsComponentAlphaChildren &&
|
||||
gfxPrefs::ComponentAlphaEnabled();
|
||||
if (aNeedsSurfaceCopy) {
|
||||
*aNeedsSurfaceCopy = mSupportsComponentAlphaChildren && needsSurfaceCopy;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ContainerLayer::ComputeEffectiveTransformsForChildren(const Matrix4x4& aTransformToSurface)
|
||||
{
|
||||
|
|
|
@ -1760,6 +1760,14 @@ protected:
|
|||
*/
|
||||
void DefaultComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface);
|
||||
|
||||
/**
|
||||
* A default implementation to compute and set the value for SupportsComponentAlphaChildren().
|
||||
*
|
||||
* If aNeedsSurfaceCopy is provided, then it is set to true if the caller needs to copy the background
|
||||
* up into the intermediate surface created, false otherwise.
|
||||
*/
|
||||
void DefaultComputeSupportsComponentAlphaChildren(bool* aNeedsSurfaceCopy = nullptr);
|
||||
|
||||
/**
|
||||
* Loops over the children calling ComputeEffectiveTransforms on them.
|
||||
*/
|
||||
|
|
|
@ -47,25 +47,7 @@ public:
|
|||
ToClientLayer(GetMaskLayer())->RenderLayer();
|
||||
}
|
||||
|
||||
// Setup mSupportsComponentAlphaChildren in the same way
|
||||
// that ContainerLayerComposite will do.
|
||||
if (UseIntermediateSurface()) {
|
||||
if (GetEffectiveVisibleRegion().GetNumRects() != 1 ||
|
||||
!(GetContentFlags() & Layer::CONTENT_OPAQUE))
|
||||
{
|
||||
gfx::Matrix transform;
|
||||
if (HasOpaqueAncestorLayer(this) &&
|
||||
GetEffectiveTransform().Is2D(&transform) &&
|
||||
!gfx::ThebesMatrix(transform).HasNonIntegerTranslation()) {
|
||||
SetSupportsComponentAlphaChildren(
|
||||
gfxPrefs::ComponentAlphaEnabled());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
SetSupportsComponentAlphaChildren(
|
||||
(GetContentFlags() & Layer::CONTENT_OPAQUE) ||
|
||||
(GetParent() && GetParent()->SupportsComponentAlphaChildren()));
|
||||
}
|
||||
DefaultComputeSupportsComponentAlphaChildren();
|
||||
|
||||
nsAutoTArray<Layer*, 12> children;
|
||||
SortChildrenBy3DZOrder(children);
|
||||
|
|
|
@ -252,17 +252,15 @@ ContainerRender(ContainerT* aContainer,
|
|||
|
||||
nsIntRect visibleRect = aContainer->GetEffectiveVisibleRegion().GetBounds();
|
||||
|
||||
aContainer->mSupportsComponentAlphaChildren = false;
|
||||
|
||||
float opacity = aContainer->GetEffectiveOpacity();
|
||||
|
||||
bool needsSurface = aContainer->UseIntermediateSurface();
|
||||
bool surfaceCopyNeeded;
|
||||
aContainer->DefaultComputeSupportsComponentAlphaChildren(&surfaceCopyNeeded);
|
||||
if (needsSurface) {
|
||||
SurfaceInitMode mode = INIT_MODE_CLEAR;
|
||||
bool surfaceCopyNeeded = false;
|
||||
gfx::IntRect surfaceRect = gfx::IntRect(visibleRect.x, visibleRect.y,
|
||||
visibleRect.width, visibleRect.height);
|
||||
gfx::IntPoint sourcePoint = gfx::IntPoint(visibleRect.x, visibleRect.y);
|
||||
// we're about to create a framebuffer backed by textures to use as an intermediate
|
||||
// surface. What to do if its size (as given by framebufferRect) would exceed the
|
||||
// maximum texture size supported by the GL? The present code chooses the compromise
|
||||
|
@ -275,28 +273,19 @@ ContainerRender(ContainerT* aContainer,
|
|||
if (aContainer->GetEffectiveVisibleRegion().GetNumRects() == 1 &&
|
||||
(aContainer->GetContentFlags() & Layer::CONTENT_OPAQUE))
|
||||
{
|
||||
// don't need a background, we're going to paint all opaque stuff
|
||||
aContainer->mSupportsComponentAlphaChildren = true;
|
||||
mode = INIT_MODE_NONE;
|
||||
} else {
|
||||
const gfx::Matrix4x4& transform3D = aContainer->GetEffectiveTransform();
|
||||
gfx::Matrix transform;
|
||||
// If we have an opaque ancestor layer, then we can be sure that
|
||||
// all the pixels we draw into are either opaque already or will be
|
||||
// covered by something opaque. Otherwise copying up the background is
|
||||
// not safe.
|
||||
if (ContainerLayer::HasOpaqueAncestorLayer(aContainer) &&
|
||||
transform3D.Is2D(&transform) && !ThebesMatrix(transform).HasNonIntegerTranslation()) {
|
||||
surfaceCopyNeeded = gfxPrefs::ComponentAlphaEnabled();
|
||||
sourcePoint.x += transform._31;
|
||||
sourcePoint.y += transform._32;
|
||||
aContainer->mSupportsComponentAlphaChildren
|
||||
= gfxPrefs::ComponentAlphaEnabled();
|
||||
}
|
||||
}
|
||||
|
||||
sourcePoint -= compositor->GetCurrentRenderTarget()->GetOrigin();
|
||||
if (surfaceCopyNeeded) {
|
||||
gfx::IntPoint sourcePoint = gfx::IntPoint(visibleRect.x, visibleRect.y);
|
||||
|
||||
gfx::Matrix4x4 transform = aContainer->GetEffectiveTransform();
|
||||
DebugOnly<gfx::Matrix> transform2d;
|
||||
MOZ_ASSERT(transform.Is2D(&transform2d) && !gfx::ThebesMatrix(transform2d).HasNonIntegerTranslation());
|
||||
sourcePoint += gfx::IntPoint(transform._41, transform._42);
|
||||
|
||||
sourcePoint -= compositor->GetCurrentRenderTarget()->GetOrigin();
|
||||
|
||||
surface = compositor->CreateRenderTargetFromSource(surfaceRect, previousTarget, sourcePoint);
|
||||
} else {
|
||||
surface = compositor->CreateRenderTarget(surfaceRect, mode);
|
||||
|
@ -309,8 +298,6 @@ ContainerRender(ContainerT* aContainer,
|
|||
compositor->SetRenderTarget(surface);
|
||||
} else {
|
||||
surface = previousTarget;
|
||||
aContainer->mSupportsComponentAlphaChildren = (aContainer->GetContentFlags() & Layer::CONTENT_OPAQUE) ||
|
||||
(aContainer->GetParent() && aContainer->GetParent()->SupportsComponentAlphaChildren());
|
||||
}
|
||||
|
||||
nsAutoTArray<Layer*, 12> children;
|
||||
|
|
Загрузка…
Ссылка в новой задаче