Bug 590294, part 10: Implement <browser>-configured viewport drawing for shadow layers. r=tn

This commit is contained in:
Chris Jones 2010-09-03 15:10:46 -05:00
parent aea040c795
commit a107db4800

View File

@ -47,6 +47,7 @@
#include "nsFrameLoader.h"
#include "nsViewportFrame.h"
typedef nsFrameLoader::ViewportConfig ViewportConfig;
using namespace mozilla::layers;
namespace mozilla {
@ -68,19 +69,34 @@ AssertInTopLevelChromeDoc(ContainerLayer* aContainer,
// it's rendering to top-left=<0, 0> (which is good!).
static void
SetTransformFor(ContainerLayer* aContainer, nsIFrame* aContainedFrame,
const FrameMetrics& aMetrics,
const FrameMetrics& aMetrics, const ViewportConfig& aConfig,
nsDisplayListBuilder* aBuilder)
{
NS_ABORT_IF_FALSE(aContainer && aContainedFrame, "args must be nonnull");
AssertInTopLevelChromeDoc(aContainer, aContainedFrame);
nscoord auPerDevPixel = aContainedFrame->PresContext()->AppUnitsPerDevPixel();
// Offset to the content rect in case we have borders or padding
nsPoint offset = aBuilder->ToReferenceFrame(aContainedFrame->GetParent()) +
aContainedFrame->GetContentRect().TopLeft();
nsIntPoint intOffset = offset.ToNearestPixels(
aContainedFrame->PresContext()->AppUnitsPerCSSPixel());
nsPoint frameOffset =
(aBuilder->ToReferenceFrame(aContainedFrame->GetParent()) +
aContainedFrame->GetContentRect().TopLeft());
nsIntPoint translation = frameOffset.ToNearestPixels(auPerDevPixel);
aContainer->SetTransform(gfx3DMatrix::Translation(intOffset.x, intOffset.y, 0));
// |aMetrics.mViewportScrollOffset| was the content document's
// scroll offset when it was painted (the document pixel at CSS
// viewport (0,0)). |aConfig.mScrollOffset| is what our user
// expects, or wants, the content-document scroll offset to be. So
// we set a compensating translation that moves the content document
// pixels to where the user wants them to be.
nsIntPoint scrollCompensation =
(aConfig.mScrollOffset.ToNearestPixels(auPerDevPixel) -
aMetrics.mViewportScrollOffset);
translation -= scrollCompensation;
gfxMatrix transform;
transform.Translate(gfxPoint(translation.x, translation.y));
transform.Scale(aConfig.mXScale, aConfig.mYScale);
aContainer->SetTransform(gfx3DMatrix::From2D(transform));
}
static void
@ -95,14 +111,14 @@ AssertValidContainerOfShadowTree(ContainerLayer* aContainer,
}
static Layer*
RootOf(ContainerLayer* aContainer)
ShadowRootOf(ContainerLayer* aContainer)
{
NS_ABORT_IF_FALSE(aContainer, "need a non-null container");
Layer* first = aContainer->GetFirstChild();
NS_ABORT_IF_FALSE(!first || nsnull == first->GetNextSibling(),
"'root' container may only have 0 or 1 children");
return first;
Layer* shadowRoot = aContainer->GetFirstChild();
NS_ABORT_IF_FALSE(!shadowRoot || nsnull == shadowRoot->GetNextSibling(),
"shadow root container may only have 0 or 1 children");
return shadowRoot;
}
// Return true iff |aManager| is a "temporary layer manager". They're
@ -173,23 +189,23 @@ RenderFrameParent::BuildLayer(nsDisplayListBuilder* aBuilder,
return nsnull;
}
Layer* containerRoot = mContainer ? RootOf(mContainer) : nsnull;
Layer* containerShadowRoot = mContainer ? ShadowRootOf(mContainer) : nsnull;
ContainerLayer* shadowRoot = GetRootLayer();
NS_ABORT_IF_FALSE(!shadowRoot || shadowRoot->Manager() == aManager,
"retaining manager changed out from under us ... HELP!");
if (mContainer && shadowRoot != containerRoot) {
if (mContainer && shadowRoot != containerShadowRoot) {
// Shadow root changed. Remove it from the container, if it
// existed.
if (containerRoot) {
mContainer->RemoveChild(containerRoot);
if (containerShadowRoot) {
mContainer->RemoveChild(containerShadowRoot);
}
}
if (!shadowRoot) {
// No shadow layer tree at the moment.
mContainer = nsnull;
} else if (shadowRoot != containerRoot) {
} else if (shadowRoot != containerShadowRoot) {
// Wrap the shadow layer tree in mContainer.
if (!mContainer) {
mContainer = aManager->CreateContainerLayer();
@ -201,7 +217,10 @@ RenderFrameParent::BuildLayer(nsDisplayListBuilder* aBuilder,
}
if (mContainer) {
SetTransformFor(mContainer, aFrame, shadowRoot->GetFrameMetrics(), aBuilder);
SetTransformFor(mContainer, aFrame,
shadowRoot->GetFrameMetrics(),
mFrameLoader->GetViewportConfig(),
aBuilder);
mContainer->SetClipRect(nsnull);
}