本文整理汇总了C++中Layer::AsContainerLayer方法的典型用法代码示例。如果您正苦于以下问题:C++ Layer::AsContainerLayer方法的具体用法?C++ Layer::AsContainerLayer怎么用?C++ Layer::AsContainerLayer使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Layer
的用法示例。
在下文中一共展示了Layer::AsContainerLayer方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: Bridge
bool
ClientLayerManager::ProgressiveUpdateCallback(bool aHasPendingNewThebesContent,
gfx::Rect& aViewport,
float& aScaleX,
float& aScaleY,
bool aDrawingCritical)
{
aScaleX = aScaleY = 1.0;
#ifdef MOZ_WIDGET_ANDROID
Layer* primaryScrollable = GetPrimaryScrollableLayer();
if (primaryScrollable) {
const FrameMetrics& metrics = primaryScrollable->AsContainerLayer()->GetFrameMetrics();
// This is derived from the code in
// gfx/layers/ipc/CompositorParent.cpp::TransformShadowTree.
const gfx3DMatrix& rootTransform = GetRoot()->GetTransform();
CSSToLayerScale paintScale = metrics.mDevPixelsPerCSSPixel
/ LayerToLayoutDeviceScale(rootTransform.GetXScale(), rootTransform.GetYScale());
const CSSRect& metricsDisplayPort =
(aDrawingCritical && !metrics.mCriticalDisplayPort.IsEmpty()) ?
metrics.mCriticalDisplayPort : metrics.mDisplayPort;
LayerRect displayPort = (metricsDisplayPort + metrics.mScrollOffset) * paintScale;
return AndroidBridge::Bridge()->ProgressiveUpdateCallback(
aHasPendingNewThebesContent, displayPort, paintScale.scale, aDrawingCritical,
aViewport, aScaleX, aScaleY);
}
#endif
return false;
}
示例2: displayPort
bool
ClientLayerManager::ProgressiveUpdateCallback(bool aHasPendingNewThebesContent,
gfx::Rect& aViewport,
float& aScaleX,
float& aScaleY,
bool aDrawingCritical)
{
#ifdef MOZ_WIDGET_ANDROID
Layer* primaryScrollable = GetPrimaryScrollableLayer();
if (primaryScrollable) {
const FrameMetrics& metrics = primaryScrollable->AsContainerLayer()->GetFrameMetrics();
// This is derived from the code in
// gfx/layers/ipc/CompositorParent.cpp::TransformShadowTree.
const gfx3DMatrix& rootTransform = GetRoot()->GetTransform();
float devPixelRatioX = 1 / rootTransform.GetXScale();
float devPixelRatioY = 1 / rootTransform.GetYScale();
const gfx::Rect& metricsDisplayPort =
(aDrawingCritical && !metrics.mCriticalDisplayPort.IsEmpty()) ?
metrics.mCriticalDisplayPort : metrics.mDisplayPort;
gfx::Rect displayPort((metricsDisplayPort.x + metrics.mScrollOffset.x) * devPixelRatioX,
(metricsDisplayPort.y + metrics.mScrollOffset.y) * devPixelRatioY,
metricsDisplayPort.width * devPixelRatioX,
metricsDisplayPort.height * devPixelRatioY);
return AndroidBridge::Bridge()->ProgressiveUpdateCallback(
aHasPendingNewThebesContent, displayPort, devPixelRatioX, aDrawingCritical,
aViewport, aScaleX, aScaleY);
}
#endif
return false;
}
示例3: Bridge
bool
ClientLayerManager::ProgressiveUpdateCallback(bool aHasPendingNewThebesContent,
ParentLayerRect& aCompositionBounds,
CSSToParentLayerScale& aZoom,
bool aDrawingCritical)
{
aZoom.scale = 1.0;
#ifdef MOZ_WIDGET_ANDROID
Layer* primaryScrollable = GetPrimaryScrollableLayer();
if (primaryScrollable) {
const FrameMetrics& metrics = primaryScrollable->AsContainerLayer()->GetFrameMetrics();
// This is derived from the code in
// gfx/layers/ipc/CompositorParent.cpp::TransformShadowTree.
CSSToLayerScale paintScale = metrics.LayersPixelsPerCSSPixel();
const CSSRect& metricsDisplayPort =
(aDrawingCritical && !metrics.mCriticalDisplayPort.IsEmpty()) ?
metrics.mCriticalDisplayPort : metrics.mDisplayPort;
LayerRect displayPort = (metricsDisplayPort + metrics.GetScrollOffset()) * paintScale;
return AndroidBridge::Bridge()->ProgressiveUpdateCallback(
aHasPendingNewThebesContent, displayPort, paintScale.scale, aDrawingCritical,
aCompositionBounds, aZoom);
}
#endif
return false;
}
示例4:
static gfx3DMatrix
GetTransformToAncestorsParentLayer(Layer* aStart, Layer* aAncestor)
{
gfx::Matrix4x4 transform;
Layer* ancestorParent = aAncestor->GetParent();
for (Layer* iter = aStart; iter != ancestorParent; iter = iter->GetParent()) {
if (iter->AsContainerLayer()) {
// If the layer has a non-transient async transform then we need to apply it here
// because it will get applied by the APZ in the compositor as well
const FrameMetrics& metrics = iter->AsContainerLayer()->GetFrameMetrics();
transform = transform * gfx::Matrix4x4().Scale(metrics.mResolution.scale, metrics.mResolution.scale, 1.f);
}
transform = transform * iter->GetTransform();
}
gfx3DMatrix ret;
gfx::To3DMatrix(transform, ret);
return ret;
}
示例5: GetLayer
Matrix4x4
HostLayer::GetShadowTransform() {
Matrix4x4 transform = mShadowTransform;
Layer* layer = GetLayer();
transform.PostScale(layer->GetPostXScale(), layer->GetPostYScale(), 1.0f);
if (const ContainerLayer* c = layer->AsContainerLayer()) {
transform.PreScale(c->GetPreXScale(), c->GetPreYScale(), 1.0f);
}
return transform;
}
示例6:
static bool
LayerHasNonContainerDescendants(ContainerLayer* aContainer)
{
for (Layer* child = aContainer->GetFirstChild();
child; child = child->GetNextSibling()) {
ContainerLayer* container = child->AsContainerLayer();
if (!container || LayerHasNonContainerDescendants(container)) {
return true;
}
}
return false;
}
示例7: while
// Do a breadth-first search to find the first layer in the tree that is
// scrollable.
Layer*
CompositorParent::GetPrimaryScrollableLayer()
{
Layer* root = mLayerManager->GetRoot();
// FIXME: We're currently getting passed layers that are not part of our content, but
// we are drawing them anyway. This is causing severe rendering corruption to our background
// and checkerboarding. The real fix here is to assert that we don't have any useless layers
// and ensure that layout isn't giving us any. This is being tracked in bug 728284.
// For now just clip them to the empty rect so we don't draw them.
Layer* discardLayer = root->GetFirstChild();
while (discardLayer) {
if (!discardLayer->AsContainerLayer()) {
discardLayer->IntersectClipRect(nsIntRect());
SetShadowProperties(discardLayer);
}
discardLayer = discardLayer->GetNextSibling();
}
nsTArray<Layer*> queue;
queue.AppendElement(root);
while (queue.Length()) {
ContainerLayer* containerLayer = queue[0]->AsContainerLayer();
queue.RemoveElementAt(0);
if (!containerLayer) {
continue;
}
const FrameMetrics& frameMetrics = containerLayer->GetFrameMetrics();
if (frameMetrics.IsScrollable()) {
return containerLayer;
}
Layer* child = containerLayer->GetFirstChild();
while (child) {
queue.AppendElement(child);
child = child->GetNextSibling();
}
}
return root;
}
示例8: cast
bool
LayerTransactionParent::RecvGetTransform(PLayerParent* aParent,
gfx3DMatrix* aTransform)
{
if (mDestroyed || !layer_manager() || layer_manager()->IsDestroyed()) {
return false;
}
// The following code recovers the untranslated transform
// from the shadow transform by undoing the translations in
// AsyncCompositionManager::SampleValue.
Layer* layer = cast(aParent)->AsLayer();
if (!layer) {
return false;
}
gfx::To3DMatrix(layer->AsLayerComposite()->GetShadowTransform(), *aTransform);
if (ContainerLayer* c = layer->AsContainerLayer()) {
aTransform->ScalePost(1.0f/c->GetInheritedXScale(),
1.0f/c->GetInheritedYScale(),
1.0f);
}
float scale = 1;
gfxPoint3D scaledOrigin;
gfxPoint3D transformOrigin;
for (uint32_t i=0; i < layer->GetAnimations().Length(); i++) {
if (layer->GetAnimations()[i].data().type() == AnimationData::TTransformData) {
const TransformData& data = layer->GetAnimations()[i].data().get_TransformData();
scale = data.appUnitsPerDevPixel();
scaledOrigin =
gfxPoint3D(NS_round(NSAppUnitsToFloatPixels(data.origin().x, scale)),
NS_round(NSAppUnitsToFloatPixels(data.origin().y, scale)),
0.0f);
transformOrigin = data.transformOrigin();
break;
}
}
aTransform->Translate(-scaledOrigin);
*aTransform = nsLayoutUtils::ChangeMatrixBasis(-scaledOrigin - transformOrigin, *aTransform);
return true;
}
示例9:
void
ContainerLayer::SortChildrenBy3DZOrder(nsTArray<Layer*>& aArray)
{
nsAutoTArray<Layer*, 10> toSort;
for (Layer* l = GetFirstChild(); l; l = l->GetNextSibling()) {
ContainerLayer* container = l->AsContainerLayer();
if (container && container->GetContentFlags() & CONTENT_PRESERVE_3D) {
toSort.AppendElement(l);
} else {
if (toSort.Length() > 0) {
SortLayersBy3DZOrder(toSort);
aArray.MoveElementsFrom(toSort);
}
aArray.AppendElement(l);
}
}
if (toSort.Length() > 0) {
SortLayersBy3DZOrder(toSort);
aArray.MoveElementsFrom(toSort);
}
}
示例10: cast
bool
LayerTransactionParent::RecvSetAsyncScrollOffset(PLayerParent* aLayer,
const int32_t& aX, const int32_t& aY)
{
if (mDestroyed || !layer_manager() || layer_manager()->IsDestroyed()) {
return false;
}
Layer* layer = cast(aLayer)->AsLayer();
if (!layer) {
return false;
}
ContainerLayer* containerLayer = layer->AsContainerLayer();
if (!containerLayer) {
return false;
}
AsyncPanZoomController* controller = containerLayer->GetAsyncPanZoomController();
if (!controller) {
return false;
}
controller->SetTestAsyncScrollOffset(CSSPoint(aX, aY));
return true;
}
示例11: GetEffectiveTransform
void
ClientTiledThebesLayer::BeginPaint()
{
if (ClientManager()->IsRepeatTransaction()) {
return;
}
mPaintData.mLowPrecisionPaintCount = 0;
mPaintData.mPaintFinished = false;
// Calculate the transform required to convert screen space into layer space
mPaintData.mTransformScreenToLayer = GetEffectiveTransform();
// XXX Not sure if this code for intermediate surfaces is correct.
// It rarely gets hit though, and shouldn't have terrible consequences
// even if it is wrong.
for (ContainerLayer* parent = GetParent(); parent; parent = parent->GetParent()) {
if (parent->UseIntermediateSurface()) {
mPaintData.mTransformScreenToLayer.PreMultiply(parent->GetEffectiveTransform());
}
}
mPaintData.mTransformScreenToLayer.Invert();
// Compute the critical display port in layer space.
mPaintData.mLayerCriticalDisplayPort.SetEmpty();
const gfx::Rect& criticalDisplayPort = GetParent()->GetFrameMetrics().mCriticalDisplayPort;
if (!criticalDisplayPort.IsEmpty()) {
gfxRect transformedCriticalDisplayPort =
mPaintData.mTransformScreenToLayer.TransformBounds(
gfxRect(criticalDisplayPort.x, criticalDisplayPort.y,
criticalDisplayPort.width, criticalDisplayPort.height));
transformedCriticalDisplayPort.RoundOut();
mPaintData.mLayerCriticalDisplayPort = nsIntRect(transformedCriticalDisplayPort.x,
transformedCriticalDisplayPort.y,
transformedCriticalDisplayPort.width,
transformedCriticalDisplayPort.height);
}
// Calculate the frame resolution.
mPaintData.mResolution.SizeTo(1, 1);
for (ContainerLayer* parent = GetParent(); parent; parent = parent->GetParent()) {
const FrameMetrics& metrics = parent->GetFrameMetrics();
mPaintData.mResolution.width *= metrics.mResolution.width;
mPaintData.mResolution.height *= metrics.mResolution.height;
}
// Calculate the scroll offset since the last transaction, and the
// composition bounds.
mPaintData.mCompositionBounds.SetEmpty();
mPaintData.mScrollOffset.MoveTo(0, 0);
Layer* primaryScrollable = ClientManager()->GetPrimaryScrollableLayer();
if (primaryScrollable) {
const FrameMetrics& metrics = primaryScrollable->AsContainerLayer()->GetFrameMetrics();
mPaintData.mScrollOffset = metrics.mScrollOffset;
gfxRect transformedViewport = mPaintData.mTransformScreenToLayer.TransformBounds(
gfxRect(metrics.mCompositionBounds.x, metrics.mCompositionBounds.y,
metrics.mCompositionBounds.width, metrics.mCompositionBounds.height));
transformedViewport.RoundOut();
mPaintData.mCompositionBounds =
nsIntRect(transformedViewport.x, transformedViewport.y,
transformedViewport.width, transformedViewport.height);
}
}
示例12: metricsScrollOffset
void
CompositorParent::TransformShadowTree()
{
Layer* layer = GetPrimaryScrollableLayer();
ShadowLayer* shadow = layer->AsShadowLayer();
ContainerLayer* container = layer->AsContainerLayer();
const FrameMetrics* metrics = &container->GetFrameMetrics();
const gfx3DMatrix& rootTransform = mLayerManager->GetRoot()->GetTransform();
const gfx3DMatrix& currentTransform = layer->GetTransform();
float rootScaleX = rootTransform.GetXScale();
float rootScaleY = rootTransform.GetYScale();
if (mIsFirstPaint && metrics) {
nsIntPoint scrollOffset = metrics->mViewportScrollOffset;
mContentSize = metrics->mContentSize;
SetFirstPaintViewport(scrollOffset.x, scrollOffset.y,
1/rootScaleX,
mContentSize.width,
mContentSize.height,
metrics->mCSSContentSize.width,
metrics->mCSSContentSize.height);
mIsFirstPaint = false;
} else if (metrics && (metrics->mContentSize != mContentSize)) {
mContentSize = metrics->mContentSize;
SetPageSize(1/rootScaleX, mContentSize.width,
mContentSize.height,
metrics->mCSSContentSize.width,
metrics->mCSSContentSize.height);
}
// We synchronise the viewport information with Java after sending the above
// notifications, so that Java can take these into account in its response.
if (metrics) {
// Calculate the absolute display port to send to Java
nsIntRect displayPort = metrics->mDisplayPort;
nsIntPoint scrollOffset = metrics->mViewportScrollOffset;
displayPort.x += scrollOffset.x;
displayPort.y += scrollOffset.y;
SyncViewportInfo(displayPort, 1/rootScaleX, mLayersUpdated,
mScrollOffset, mXScale, mYScale);
mLayersUpdated = false;
}
// Handle transformations for asynchronous panning and zooming. We determine the
// zoom used by Gecko from the transformation set on the root layer, and we
// determine the scroll offset used by Gecko from the frame metrics of the
// primary scrollable layer. We compare this to the desired zoom and scroll
// offset in the view transform we obtained from Java in order to compute the
// transformation we need to apply.
if (metrics) {
float tempScaleDiffX = rootScaleX * mXScale;
float tempScaleDiffY = rootScaleY * mYScale;
nsIntPoint metricsScrollOffset(0, 0);
if (metrics->IsScrollable())
metricsScrollOffset = metrics->mViewportScrollOffset;
nsIntPoint scrollCompensation(
(mScrollOffset.x / tempScaleDiffX - metricsScrollOffset.x) * mXScale,
(mScrollOffset.y / tempScaleDiffY - metricsScrollOffset.y) * mYScale);
ViewTransform treeTransform(-scrollCompensation, mXScale, mYScale);
shadow->SetShadowTransform(gfx3DMatrix(treeTransform) * currentTransform);
} else {
ViewTransform treeTransform(nsIntPoint(0,0), mXScale, mYScale);
shadow->SetShadowTransform(gfx3DMatrix(treeTransform) * currentTransform);
}
}
示例13: screenRect
float
LayerManagerComposite::ComputeRenderIntegrity()
{
// We only ever have incomplete rendering when progressive tiles are enabled.
Layer* root = GetRoot();
if (!gfxPlatform::UseProgressiveTilePainting() || !root) {
return 1.f;
}
const FrameMetrics& rootMetrics = root->AsContainerLayer()->GetFrameMetrics();
nsIntRect screenRect(rootMetrics.mCompositionBounds.x,
rootMetrics.mCompositionBounds.y,
rootMetrics.mCompositionBounds.width,
rootMetrics.mCompositionBounds.height);
float lowPrecisionMultiplier = 1.0f;
float highPrecisionMultiplier = 1.0f;
#ifdef MOZ_ANDROID_OMTC
// Use the transform on the primary scrollable layer and its FrameMetrics
// to find out how much of the viewport the current displayport covers
Layer* primaryScrollable = GetPrimaryScrollableLayer();
if (primaryScrollable) {
// This is derived from the code in
// gfx/layers/ipc/CompositorParent.cpp::TransformShadowTree.
const gfx3DMatrix& rootTransform = root->GetTransform();
float devPixelRatioX = 1 / rootTransform.GetXScale();
float devPixelRatioY = 1 / rootTransform.GetYScale();
gfx3DMatrix transform = primaryScrollable->GetEffectiveTransform();
transform.ScalePost(devPixelRatioX, devPixelRatioY, 1);
const FrameMetrics& metrics = primaryScrollable->AsContainerLayer()->GetFrameMetrics();
// Clip the screen rect to the document bounds
gfxRect documentBounds =
transform.TransformBounds(gfxRect(metrics.mScrollableRect.x - metrics.mScrollOffset.x,
metrics.mScrollableRect.y - metrics.mScrollOffset.y,
metrics.mScrollableRect.width,
metrics.mScrollableRect.height));
documentBounds.RoundOut();
screenRect = screenRect.Intersect(nsIntRect(documentBounds.x, documentBounds.y,
documentBounds.width, documentBounds.height));
// If the screen rect is empty, the user has scrolled entirely into
// over-scroll and so we can be considered to have full integrity.
if (screenRect.IsEmpty()) {
return 1.0f;
}
// Work out how much of the critical display-port covers the screen
bool hasLowPrecision = false;
if (!metrics.mCriticalDisplayPort.IsEmpty()) {
hasLowPrecision = true;
highPrecisionMultiplier =
GetDisplayportCoverage(metrics.mCriticalDisplayPort, transform, screenRect);
}
// Work out how much of the display-port covers the screen
if (!metrics.mDisplayPort.IsEmpty()) {
if (hasLowPrecision) {
lowPrecisionMultiplier =
GetDisplayportCoverage(metrics.mDisplayPort, transform, screenRect);
} else {
lowPrecisionMultiplier = highPrecisionMultiplier =
GetDisplayportCoverage(metrics.mDisplayPort, transform, screenRect);
}
}
}
// If none of the screen is covered, we have zero integrity.
if (highPrecisionMultiplier <= 0.0f && lowPrecisionMultiplier <= 0.0f) {
return 0.0f;
}
#endif // MOZ_ANDROID_OMTC
nsIntRegion screenRegion(screenRect);
nsIntRegion lowPrecisionScreenRegion(screenRect);
gfx3DMatrix transform;
ComputeRenderIntegrityInternal(root, screenRegion,
lowPrecisionScreenRegion, transform);
if (!screenRegion.IsEqual(screenRect)) {
// Calculate the area of the region. All rects in an nsRegion are
// non-overlapping.
float screenArea = screenRect.width * screenRect.height;
float highPrecisionIntegrity = GetRegionArea(screenRegion) / screenArea;
float lowPrecisionIntegrity = 1.f;
if (!lowPrecisionScreenRegion.IsEqual(screenRect)) {
lowPrecisionIntegrity = GetRegionArea(lowPrecisionScreenRegion) / screenArea;
}
return ((highPrecisionIntegrity * highPrecisionMultiplier) +
(lowPrecisionIntegrity * lowPrecisionMultiplier)) / 2;
}
return 1.f;
}
示例14: GetEffectiveTransform
void
ClientTiledThebesLayer::BeginPaint()
{
if (ClientManager()->IsRepeatTransaction()) {
return;
}
mPaintData.mLowPrecisionPaintCount = 0;
mPaintData.mPaintFinished = false;
// Get the metrics of the nearest scroll container.
ContainerLayer* scrollParent = nullptr;
for (ContainerLayer* parent = GetParent(); parent; parent = parent->GetParent()) {
const FrameMetrics& metrics = parent->GetFrameMetrics();
if (metrics.mScrollId != FrameMetrics::NULL_SCROLL_ID) {
scrollParent = parent;
break;
}
}
if (!scrollParent) {
// XXX I don't think this can happen, but if it does, warn and set the
// composition bounds to empty so that progressive updates are disabled.
NS_WARNING("Tiled Thebes layer with no scrollable container parent");
mPaintData.mCompositionBounds.SetEmpty();
return;
}
const FrameMetrics& metrics = scrollParent->GetFrameMetrics();
// Calculate the transform required to convert screen space into transformed
// layout device space.
gfx::Matrix4x4 effectiveTransform = GetEffectiveTransform();
for (ContainerLayer* parent = GetParent(); parent; parent = parent->GetParent()) {
if (parent->UseIntermediateSurface()) {
effectiveTransform = effectiveTransform * parent->GetEffectiveTransform();
}
}
gfx3DMatrix layoutToScreen;
gfx::To3DMatrix(effectiveTransform, layoutToScreen);
layoutToScreen.ScalePost(metrics.mCumulativeResolution.scale,
metrics.mCumulativeResolution.scale,
1.f);
mPaintData.mTransformScreenToLayout = layoutToScreen.Inverse();
// Compute the critical display port in layer space.
mPaintData.mLayoutCriticalDisplayPort.SetEmpty();
if (!metrics.mCriticalDisplayPort.IsEmpty()) {
// Convert the display port to screen space first so that we can transform
// it into layout device space.
const ScreenRect& criticalDisplayPort = metrics.mCriticalDisplayPort * metrics.mZoom;
LayoutDeviceRect transformedCriticalDisplayPort =
ApplyScreenToLayoutTransform(mPaintData.mTransformScreenToLayout, criticalDisplayPort);
mPaintData.mLayoutCriticalDisplayPort =
LayoutDeviceIntRect::ToUntyped(RoundedOut(transformedCriticalDisplayPort));
}
// Calculate the frame resolution. Because this is Gecko-side, before any
// async transforms have occurred, we can use mZoom for this.
mPaintData.mResolution = metrics.mZoom;
// Calculate the scroll offset since the last transaction, and the
// composition bounds.
mPaintData.mCompositionBounds.SetEmpty();
mPaintData.mScrollOffset.MoveTo(0, 0);
Layer* primaryScrollable = ClientManager()->GetPrimaryScrollableLayer();
if (primaryScrollable) {
const FrameMetrics& metrics = primaryScrollable->AsContainerLayer()->GetFrameMetrics();
mPaintData.mScrollOffset = metrics.mScrollOffset * metrics.mZoom;
mPaintData.mCompositionBounds =
ApplyScreenToLayoutTransform(mPaintData.mTransformScreenToLayout,
ScreenRect(metrics.mCompositionBounds));
}
}
示例15: metricsScrollOffset
void
CompositorParent::TransformShadowTree()
{
Layer* layer = GetPrimaryScrollableLayer();
ShadowLayer* shadow = layer->AsShadowLayer();
ContainerLayer* container = layer->AsContainerLayer();
const FrameMetrics& metrics = container->GetFrameMetrics();
const gfx3DMatrix& rootTransform = mLayerManager->GetRoot()->GetTransform();
const gfx3DMatrix& currentTransform = layer->GetTransform();
float rootScaleX = rootTransform.GetXScale();
float rootScaleY = rootTransform.GetYScale();
if (mIsFirstPaint) {
mContentRect = metrics.mContentRect;
SetFirstPaintViewport(metrics.mViewportScrollOffset,
1/rootScaleX,
mContentRect,
metrics.mCSSContentRect);
mIsFirstPaint = false;
} else if (!metrics.mContentRect.IsEqualEdges(mContentRect)) {
mContentRect = metrics.mContentRect;
SetPageRect(1/rootScaleX, mContentRect, metrics.mCSSContentRect);
}
// We synchronise the viewport information with Java after sending the above
// notifications, so that Java can take these into account in its response.
// Calculate the absolute display port to send to Java
nsIntRect displayPort = metrics.mDisplayPort;
nsIntPoint scrollOffset = metrics.mViewportScrollOffset;
displayPort.x += scrollOffset.x;
displayPort.y += scrollOffset.y;
SyncViewportInfo(displayPort, 1/rootScaleX, mLayersUpdated,
mScrollOffset, mXScale, mYScale);
mLayersUpdated = false;
// Handle transformations for asynchronous panning and zooming. We determine the
// zoom used by Gecko from the transformation set on the root layer, and we
// determine the scroll offset used by Gecko from the frame metrics of the
// primary scrollable layer. We compare this to the desired zoom and scroll
// offset in the view transform we obtained from Java in order to compute the
// transformation we need to apply.
float tempScaleDiffX = rootScaleX * mXScale;
float tempScaleDiffY = rootScaleY * mYScale;
nsIntPoint metricsScrollOffset(0, 0);
if (metrics.IsScrollable())
metricsScrollOffset = metrics.mViewportScrollOffset;
nsIntPoint scrollCompensation(
(mScrollOffset.x / tempScaleDiffX - metricsScrollOffset.x) * mXScale,
(mScrollOffset.y / tempScaleDiffY - metricsScrollOffset.y) * mYScale);
ViewTransform treeTransform(-scrollCompensation, mXScale, mYScale);
shadow->SetShadowTransform(gfx3DMatrix(treeTransform) * currentTransform);
// Alter the scroll offset so that fixed position layers remain within
// the page area.
float offsetX = mScrollOffset.x / tempScaleDiffX;
float offsetY = mScrollOffset.y / tempScaleDiffY;
offsetX = NS_MAX((float)mContentRect.x, NS_MIN(offsetX, (float)(mContentRect.XMost() - mWidgetSize.width)));
offsetY = NS_MAX((float)mContentRect.y, NS_MIN(offsetY, (float)(mContentRect.YMost() - mWidgetSize.height)));
gfxPoint reverseViewTranslation(offsetX - metricsScrollOffset.x,
offsetY - metricsScrollOffset.y);
TranslateFixedLayers(layer, reverseViewTranslation);
}