Bug 1095754 - Add a new Layer helper method for retrieving the root clip on a particular layer. r=roc

This commit is contained in:
Jim Mathies 2015-01-29 13:41:55 -06:00
Родитель d353a0d5c1
Коммит fe94f6a867
2 изменённых файлов: 78 добавлений и 0 удалений

Просмотреть файл

@ -851,6 +851,66 @@ Layer::TransformRectToRenderTarget(const LayerIntRect& aRect)
return quad;
}
bool
Layer::GetVisibleRegionRelativeToRootLayer(nsIntRegion& aResult,
nsIntPoint* aLayerOffset)
{
MOZ_ASSERT(aLayerOffset, "invalid offset pointer");
IntPoint offset;
aResult = GetEffectiveVisibleRegion();
for (Layer* layer = this; layer; layer = layer->GetParent()) {
gfx::Matrix matrix;
if (!layer->GetLocalTransform().Is2D(&matrix) ||
!matrix.IsTranslation()) {
return false;
}
// The offset of |layer| to its parent.
IntPoint currentLayerOffset = RoundedToInt(matrix.GetTranslation());
// Translate the accumulated visible region of |this| by the offset of
// |layer|.
aResult.MoveBy(currentLayerOffset.x, currentLayerOffset.y);
// If the parent layer clips its lower layers, clip the visible region
// we're accumulating.
if (layer->GetEffectiveClipRect()) {
aResult.AndWith(*layer->GetEffectiveClipRect());
}
// Now we need to walk across the list of siblings for this parent layer,
// checking to see if any of these layer trees obscure |this|. If so,
// remove these areas from the visible region as well. This will pick up
// chrome overlays like a tab modal prompt.
Layer* sibling;
for (sibling = layer->GetNextSibling(); sibling;
sibling = sibling->GetNextSibling()) {
gfx::Matrix siblingMatrix;
if (!sibling->GetLocalTransform().Is2D(&siblingMatrix) ||
!siblingMatrix.IsTranslation()) {
return false;
}
// Retreive the translation from sibling to |layer|. The accumulated
// visible region is currently oriented with |layer|.
IntPoint siblingOffset = RoundedToInt(siblingMatrix.GetTranslation());
nsIntRegion siblingVisibleRegion(sibling->GetEffectiveVisibleRegion());
// Translate the siblings region to |layer|'s origin.
siblingVisibleRegion.MoveBy(-siblingOffset.x, -siblingOffset.y);
// Subtract the sibling visible region from the visible region of |this|.
aResult.SubOut(siblingVisibleRegion);
}
// Keep track of the total offset for aLayerOffset. We use this in plugin
// positioning code.
offset += currentLayerOffset;
}
*aLayerOffset = nsIntPoint(offset.x, offset.y);
return true;
}
ContainerLayer::ContainerLayer(LayerManager* aManager, void* aImplData)
: Layer(aManager, aImplData),
mFirstChild(nullptr),

Просмотреть файл

@ -1251,6 +1251,24 @@ public:
Layer* GetMaskLayer() const { return mMaskLayer; }
/**
* Retrieve the root level visible region for |this| taking into account
* clipping applied to parent layers of |this| as well as subtracting
* visible regions of higher siblings of this layer and each ancestor.
*
* Note translation values for offsets of visible regions and accumulated
* aLayerOffset are integer rounded using Point's RoundedToInt.
*
* @param aResult - the resulting visible region of this layer.
* @param aLayerOffset - this layer's total offset from the root layer.
* @return - false if during layer tree traversal a parent or sibling
* transform is found to be non-translational. This method returns early
* in this case, results will not be valid. Returns true on successful
* traversal.
*/
bool GetVisibleRegionRelativeToRootLayer(nsIntRegion& aResult,
nsIntPoint* aLayerOffset);
// Note that all lengths in animation data are either in CSS pixels or app
// units and must be converted to device pixels by the compositor.
AnimationArray& GetAnimations() { return mAnimations; }