gfxRect ThebesLayerComposite::GetDisplayPort() { // We use GetTransform instead of GetEffectiveTransform in this function // as we want the transform of the shadowable layers and not that of the // shadow layers, which may have been modified due to async scrolling/ // zooming. gfx3DMatrix transform = GetTransform(); // Find out the area of the nearest display-port to invalidate retained // tiles. gfxRect displayPort; gfxSize parentResolution = GetEffectiveResolution(); for (ContainerLayer* parent = GetParent(); parent; parent = parent->GetParent()) { const FrameMetrics& metrics = parent->GetFrameMetrics(); if (displayPort.IsEmpty()) { if (!metrics.mDisplayPort.IsEmpty()) { // We use the bounds to cut down on complication/computation time. // This will be incorrect when the transform involves rotation, but // it'd be quite hard to retain invalid tiles correctly in this // situation anyway. displayPort = gfxRect(metrics.mDisplayPort.x, metrics.mDisplayPort.y, metrics.mDisplayPort.width, metrics.mDisplayPort.height); displayPort.ScaleRoundOut(parentResolution.width, parentResolution.height); } parentResolution.width /= metrics.mResolution.scale; parentResolution.height /= metrics.mResolution.scale; } if (parent->UseIntermediateSurface()) { transform.PreMultiply(parent->GetTransform()); } } // If no display port was found, use the widget size from the layer manager. if (displayPort.IsEmpty()) { LayerManagerComposite* manager = static_cast<LayerManagerComposite*>(Manager()); const nsIntSize& widgetSize = manager->GetWidgetSize(); displayPort.width = widgetSize.width; displayPort.height = widgetSize.height; } // Transform the display port into layer space. displayPort = transform.Inverse().TransformBounds(displayPort); return displayPort; }