void AndroidCompositorWidget::SyncFrameMetrics(const ParentLayerPoint& aScrollOffset, const CSSToParentLayerScale& aZoom, const CSSRect& aCssPageRect, const CSSRect& aDisplayPort, const CSSToLayerScale& aPaintedResolution, bool aLayersUpdated, int32_t aPaintSyncId, ScreenMargin& aFixedLayerMargins) { auto layerClient = static_cast<nsWindow*>(RealWidget())->GetLayerClient(); if (!layerClient) { return; } // convert the displayport rect from document-relative CSS pixels to // document-relative device pixels LayerIntRect dp = gfx::RoundedToInt(aDisplayPort * aPaintedResolution); java::ViewTransform::LocalRef viewTransform = layerClient->SyncFrameMetrics( aScrollOffset.x, aScrollOffset.y, aZoom.scale, aCssPageRect.x, aCssPageRect.y, aCssPageRect.XMost(), aCssPageRect.YMost(), dp.x, dp.y, dp.width, dp.height, aPaintedResolution.scale, aLayersUpdated, aPaintSyncId); MOZ_ASSERT(viewTransform, "No view transform object!"); aFixedLayerMargins.top = viewTransform->FixedLayerMarginTop(); aFixedLayerMargins.right = viewTransform->FixedLayerMarginRight(); aFixedLayerMargins.bottom = viewTransform->FixedLayerMarginBottom(); aFixedLayerMargins.left = viewTransform->FixedLayerMarginLeft(); }
bool AsyncCompositionManager::ApplyAsyncContentTransformToTree(TimeStamp aCurrentFrame, Layer *aLayer, bool* aWantNextFrame) { bool appliedTransform = false; for (Layer* child = aLayer->GetFirstChild(); child; child = child->GetNextSibling()) { appliedTransform |= ApplyAsyncContentTransformToTree(aCurrentFrame, child, aWantNextFrame); } ContainerLayer* container = aLayer->AsContainerLayer(); if (!container) { return appliedTransform; } if (AsyncPanZoomController* controller = container->GetAsyncPanZoomController()) { LayerComposite* layerComposite = aLayer->AsLayerComposite(); gfx3DMatrix oldTransform = aLayer->GetTransform(); ViewTransform treeTransform; ScreenPoint scrollOffset; *aWantNextFrame |= controller->SampleContentTransformForFrame(aCurrentFrame, &treeTransform, scrollOffset); const gfx3DMatrix& rootTransform = mLayerManager->GetRoot()->GetTransform(); const FrameMetrics& metrics = container->GetFrameMetrics(); // XXX We use rootTransform instead of metrics.mResolution here because on // Fennec the resolution is set on the root layer rather than the scrollable layer. // The SyncFrameMetrics call and the paintScale variable are used on Fennec only // so it doesn't affect any other platforms. See bug 732971. CSSToLayerScale paintScale = metrics.mDevPixelsPerCSSPixel / LayerToLayoutDeviceScale(rootTransform.GetXScale(), rootTransform.GetYScale()); CSSRect displayPort(metrics.mCriticalDisplayPort.IsEmpty() ? metrics.mDisplayPort : metrics.mCriticalDisplayPort); LayerMargin fixedLayerMargins(0, 0, 0, 0); ScreenPoint offset(0, 0); SyncFrameMetrics(scrollOffset, treeTransform.mScale.scale, metrics.mScrollableRect, mLayersUpdated, displayPort, paintScale, mIsFirstPaint, fixedLayerMargins, offset); mIsFirstPaint = false; mLayersUpdated = false; // Apply the render offset mLayerManager->GetCompositor()->SetScreenRenderOffset(offset); gfx3DMatrix transform(gfx3DMatrix(treeTransform) * aLayer->GetTransform()); // The transform already takes the resolution scale into account. Since we // will apply the resolution scale again when computing the effective // transform, we must apply the inverse resolution scale here. transform.Scale(1.0f/container->GetPreXScale(), 1.0f/container->GetPreYScale(), 1); transform.ScalePost(1.0f/aLayer->GetPostXScale(), 1.0f/aLayer->GetPostYScale(), 1); layerComposite->SetShadowTransform(transform); NS_ASSERTION(!layerComposite->GetShadowTransformSetByAnimation(), "overwriting animated transform!"); // Apply resolution scaling to the old transform - the layer tree as it is // doesn't have the necessary transform to display correctly. #ifdef MOZ_WIDGET_ANDROID // XXX We use rootTransform instead of the resolution on the individual layer's // FrameMetrics on Fennec because the resolution is set on the root layer rather // than the scrollable layer. See bug 732971. On non-Fennec we do the right thing. LayoutDeviceToLayerScale resolution(1.0 / rootTransform.GetXScale(), 1.0 / rootTransform.GetYScale()); #else LayoutDeviceToLayerScale resolution = metrics.mResolution; #endif oldTransform.Scale(resolution.scale, resolution.scale, 1); AlignFixedLayersForAnchorPoint(aLayer, aLayer, oldTransform, fixedLayerMargins); appliedTransform = true; } return appliedTransform; }