// Use shadow layer tree to build display list for the browser's frame. static void BuildListForLayer(Layer* aLayer, nsFrameLoader* aRootFrameLoader, const gfx3DMatrix& aTransform, nsDisplayListBuilder* aBuilder, nsDisplayList& aShadowTree, nsIFrame* aSubdocFrame) { const FrameMetrics* metrics = GetFrameMetrics(aLayer); gfx3DMatrix transform; if (metrics && metrics->IsScrollable()) { const ViewID scrollId = metrics->mScrollId; // We need to figure out the bounds of the scrollable region using the // shadow layer tree from the remote process. The metrics viewport is // defined based on all the transformations of its parent layers and // the scale of the current layer. // Calculate transform for this layer. nsContentView* view = aRootFrameLoader->GetCurrentRemoteFrame()->GetContentView(scrollId); // XXX why don't we include aLayer->GetTransform() in the inverse-scale here? // This seems wrong, but it doesn't seem to cause bugs! gfx3DMatrix applyTransform = ComputeShadowTreeTransform( aSubdocFrame, aRootFrameLoader, metrics, view->GetViewConfig(), 1 / GetXScale(aTransform), 1 / GetYScale(aTransform)); gfx3DMatrix layerTransform; To3DMatrix(aLayer->GetTransform(), layerTransform); transform = applyTransform * layerTransform * aTransform; // As mentioned above, bounds calculation also depends on the scale // of this layer. gfx3DMatrix tmpTransform = aTransform; Scale(tmpTransform, GetXScale(applyTransform), GetYScale(applyTransform)); // Calculate rect for this layer based on aTransform. nsRect bounds; { bounds = CSSRect::ToAppUnits(metrics->mViewport); nscoord auPerDevPixel = aSubdocFrame->PresContext()->AppUnitsPerDevPixel(); ApplyTransform(bounds, tmpTransform, auPerDevPixel); } aShadowTree.AppendToTop( new (aBuilder) nsDisplayRemoteShadow(aBuilder, aSubdocFrame, bounds, scrollId)); } else { gfx3DMatrix layerTransform; To3DMatrix(aLayer->GetTransform(), layerTransform); transform = layerTransform * aTransform; } for (Layer* child = aLayer->GetFirstChild(); child; child = child->GetNextSibling()) { BuildListForLayer(child, aRootFrameLoader, transform, aBuilder, aShadowTree, aSubdocFrame); } }