зеркало из https://github.com/mozilla/gecko-dev.git
Bug 539356 - Fix mActiveScrolledRootOffset to be offset to the reference frame. r=mattwoodrow
This commit is contained in:
Родитель
48ad68b539
Коммит
c2677882e5
|
@ -138,16 +138,20 @@ public:
|
|||
LayerManager* aManager,
|
||||
FrameLayerBuilder* aLayerBuilder,
|
||||
nsIFrame* aContainerFrame,
|
||||
nsDisplayItem* aContainerItem,
|
||||
ContainerLayer* aContainerLayer,
|
||||
const FrameLayerBuilder::ContainerParameters& aParameters) :
|
||||
mBuilder(aBuilder), mManager(aManager),
|
||||
mLayerBuilder(aLayerBuilder),
|
||||
mContainerFrame(aContainerFrame), mContainerLayer(aContainerLayer),
|
||||
mContainerFrame(aContainerFrame),
|
||||
mContainerLayer(aContainerLayer),
|
||||
mParameters(aParameters),
|
||||
mNextFreeRecycledThebesLayer(0)
|
||||
{
|
||||
nsPresContext* presContext = aContainerFrame->PresContext();
|
||||
mAppUnitsPerDevPixel = presContext->AppUnitsPerDevPixel();
|
||||
mContainerReferenceFrame = aContainerItem ? aContainerItem->ReferenceFrame() :
|
||||
mBuilder->FindReferenceFrameFor(mContainerFrame);
|
||||
// When AllowResidualTranslation is false, display items will be drawn
|
||||
// scaled with a translation by integer pixels, so we know how the snapping
|
||||
// will work.
|
||||
|
@ -306,7 +310,7 @@ protected:
|
|||
* be non-null; all content in a ThebesLayer must have the same
|
||||
* active scrolled root.
|
||||
*/
|
||||
const nsIFrame* mActiveScrolledRoot;
|
||||
const nsIFrame* mActiveScrolledRoot;
|
||||
ThebesLayer* mLayer;
|
||||
/**
|
||||
* If mIsSolidColorInVisibleRegion is true, this is the color of the visible
|
||||
|
@ -367,7 +371,9 @@ protected:
|
|||
* a recycled ThebesLayer, and sets up the transform on the ThebesLayer
|
||||
* to account for scrolling.
|
||||
*/
|
||||
already_AddRefed<ThebesLayer> CreateOrRecycleThebesLayer(const nsIFrame* aActiveScrolledRoot, const nsIFrame *aReferenceFrame);
|
||||
already_AddRefed<ThebesLayer> CreateOrRecycleThebesLayer(const nsIFrame* aActiveScrolledRoot,
|
||||
const nsIFrame *aReferenceFrame,
|
||||
const nsPoint& aTopLeft);
|
||||
/**
|
||||
* Grab the next recyclable ColorLayer, or create one if there are no
|
||||
* more recyclable ColorLayers.
|
||||
|
@ -432,7 +438,8 @@ protected:
|
|||
const nsIntRect& aVisibleRect,
|
||||
const nsIntRect& aDrawRect,
|
||||
const FrameLayerBuilder::Clip& aClip,
|
||||
const nsIFrame* aActiveScrolledRoot);
|
||||
const nsIFrame* aActiveScrolledRoot,
|
||||
const nsPoint& aTopLeft);
|
||||
ThebesLayerData* GetTopThebesLayerData()
|
||||
{
|
||||
return mThebesLayerDataStack.IsEmpty() ? nullptr
|
||||
|
@ -455,6 +462,7 @@ protected:
|
|||
LayerManager* mManager;
|
||||
FrameLayerBuilder* mLayerBuilder;
|
||||
nsIFrame* mContainerFrame;
|
||||
const nsIFrame* mContainerReferenceFrame;
|
||||
ContainerLayer* mContainerLayer;
|
||||
FrameLayerBuilder::ContainerParameters mParameters;
|
||||
/**
|
||||
|
@ -535,8 +543,9 @@ public:
|
|||
|
||||
nsIntRegion mRegionToInvalidate;
|
||||
|
||||
// The result of GetPosition() for the active scrolled root of this layer
|
||||
// for the previous and current paints respectively.
|
||||
// The offset between the active scrolled root of this layer
|
||||
// and the root of the container for the previous and current
|
||||
// paints respectively.
|
||||
nsPoint mLastActiveScrolledRootOrigin;
|
||||
nsPoint mActiveScrolledRootOrigin;
|
||||
|
||||
|
@ -855,6 +864,7 @@ FrameLayerBuilder::RemoveFrameFromLayerManager(nsIFrame* aFrame,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
sDestroyedFrame = aFrame;
|
||||
data->mFramesWithLayers.RemoveEntry(aFrame);
|
||||
sDestroyedFrame = NULL;
|
||||
|
@ -1361,7 +1371,9 @@ InvalidateEntireThebesLayer(ThebesLayer* aLayer, const nsIFrame* aActiveScrolled
|
|||
}
|
||||
|
||||
already_AddRefed<ThebesLayer>
|
||||
ContainerState::CreateOrRecycleThebesLayer(const nsIFrame* aActiveScrolledRoot, const nsIFrame* aReferenceFrame)
|
||||
ContainerState::CreateOrRecycleThebesLayer(const nsIFrame* aActiveScrolledRoot,
|
||||
const nsIFrame* aReferenceFrame,
|
||||
const nsPoint& aTopLeft)
|
||||
{
|
||||
// We need a new thebes layer
|
||||
nsRefPtr<ThebesLayer> layer;
|
||||
|
@ -1423,7 +1435,7 @@ ContainerState::CreateOrRecycleThebesLayer(const nsIFrame* aActiveScrolledRoot,
|
|||
data->mXScale = mParameters.mXScale;
|
||||
data->mYScale = mParameters.mYScale;
|
||||
data->mLastActiveScrolledRootOrigin = data->mActiveScrolledRootOrigin;
|
||||
data->mActiveScrolledRootOrigin = aActiveScrolledRoot->GetPosition();
|
||||
data->mActiveScrolledRootOrigin = aTopLeft;
|
||||
data->mAppUnitsPerDevPixel = mAppUnitsPerDevPixel;
|
||||
layer->SetAllowResidualTranslation(mParameters.AllowResidualTranslation());
|
||||
|
||||
|
@ -1513,30 +1525,6 @@ RestrictVisibleRegionForLayer(Layer* aLayer, const nsIntRect& aItemVisible)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
SetVisibleRegionForLayer(Layer* aLayer, const nsIntRect& aItemVisible, const nsIntRect& aChildBounds)
|
||||
{
|
||||
gfx3DMatrix transform = aLayer->GetTransform();
|
||||
|
||||
// if 'transform' is not invertible, then nothing will be displayed
|
||||
// for the layer, so it doesn't really matter what we do here
|
||||
gfxRect itemVisible(aItemVisible.x, aItemVisible.y, aItemVisible.width, aItemVisible.height);
|
||||
gfxRect layerVisible = transform.Inverse().ProjectRectBounds(itemVisible);
|
||||
layerVisible.RoundOut();
|
||||
|
||||
nsIntRect visibleRect;
|
||||
if (!gfxUtils::GfxRectToIntRect(layerVisible, &visibleRect))
|
||||
return;
|
||||
|
||||
nsIntRegion rgn = aChildBounds;
|
||||
if (!visibleRect.Contains(aChildBounds)) {
|
||||
rgn.And(rgn, visibleRect);
|
||||
aLayer->SetVisibleRegion(rgn);
|
||||
} else {
|
||||
aLayer->SetVisibleRegion(aChildBounds);
|
||||
}
|
||||
}
|
||||
|
||||
nscolor
|
||||
ContainerState::FindOpaqueBackgroundColorFor(int32_t aThebesLayerIndex)
|
||||
{
|
||||
|
@ -1917,7 +1905,8 @@ ContainerState::FindThebesLayerFor(nsDisplayItem* aItem,
|
|||
const nsIntRect& aVisibleRect,
|
||||
const nsIntRect& aDrawRect,
|
||||
const FrameLayerBuilder::Clip& aClip,
|
||||
const nsIFrame* aActiveScrolledRoot)
|
||||
const nsIFrame* aActiveScrolledRoot,
|
||||
const nsPoint& aTopLeft)
|
||||
{
|
||||
int32_t i;
|
||||
int32_t lowestUsableLayerWithScrolledRoot = -1;
|
||||
|
@ -1957,7 +1946,7 @@ ContainerState::FindThebesLayerFor(nsDisplayItem* aItem,
|
|||
nsRefPtr<ThebesLayer> layer;
|
||||
ThebesLayerData* thebesLayerData = nullptr;
|
||||
if (lowestUsableLayerWithScrolledRoot < 0) {
|
||||
layer = CreateOrRecycleThebesLayer(aActiveScrolledRoot, aItem->ReferenceFrame());
|
||||
layer = CreateOrRecycleThebesLayer(aActiveScrolledRoot, aItem->ReferenceFrame(), aTopLeft);
|
||||
|
||||
NS_ASSERTION(!mNewChildLayers.Contains(layer), "Layer already in list???");
|
||||
mNewChildLayers.AppendElement(layer);
|
||||
|
@ -2096,18 +2085,20 @@ ContainerState::ProcessDisplayItems(const nsDisplayList& aList,
|
|||
bool isFixed;
|
||||
bool forceInactive;
|
||||
const nsIFrame* activeScrolledRoot;
|
||||
nsPoint topLeft;
|
||||
if (aFlags & NO_COMPONENT_ALPHA) {
|
||||
// When NO_COMPONENT_ALPHA is set, items will be flattened onto the
|
||||
// reference frame. In this case, force the active scrolled root to
|
||||
// that frame.
|
||||
forceInactive = true;
|
||||
activeScrolledRoot = mBuilder->FindReferenceFrameFor(mContainerFrame);
|
||||
activeScrolledRoot = mContainerReferenceFrame;
|
||||
topLeft = nsPoint(0, 0);
|
||||
isFixed = mBuilder->IsFixedItem(item, nullptr, activeScrolledRoot);
|
||||
} else {
|
||||
forceInactive = false;
|
||||
isFixed = mBuilder->IsFixedItem(item, &activeScrolledRoot);
|
||||
topLeft = activeScrolledRoot->GetOffsetToCrossDoc(mContainerReferenceFrame);
|
||||
}
|
||||
nsPoint topLeft = activeScrolledRoot->GetPosition();
|
||||
|
||||
// Assign the item to a layer
|
||||
if (layerState == LAYER_ACTIVE_FORCE ||
|
||||
|
@ -2200,7 +2191,7 @@ ContainerState::ProcessDisplayItems(const nsDisplayList& aList,
|
|||
} else {
|
||||
ThebesLayerData* data =
|
||||
FindThebesLayerFor(item, itemVisibleRect, itemDrawRect, aClip,
|
||||
activeScrolledRoot);
|
||||
activeScrolledRoot, topLeft);
|
||||
|
||||
data->mLayer->SetIsFixedPosition(isFixed);
|
||||
|
||||
|
@ -2233,10 +2224,7 @@ ContainerState::InvalidateForLayerChange(nsDisplayItem* aItem,
|
|||
Layer* oldLayer = mLayerBuilder->GetOldLayerFor(aItem, &oldGeometry, &oldClip);
|
||||
if (aNewLayer != oldLayer && oldLayer) {
|
||||
// The item has changed layers.
|
||||
// Invalidate the bounds in the old layer and new layer.
|
||||
// The bounds might have changed, but we assume that any difference
|
||||
// in the bounds will have been invalidated for all Thebes layers
|
||||
// in the container via regular frame invalidation.
|
||||
// Invalidate the old bounds in the old layer and new bounds in the new layer.
|
||||
ThebesLayer* t = oldLayer->AsThebesLayer();
|
||||
if (t) {
|
||||
// Note that whenever the layer's scale changes, we invalidate the whole thing,
|
||||
|
@ -2754,36 +2742,6 @@ FrameLayerBuilder::RestoreThebesLayerItemEntries(ThebesLayerItemsEntry* aEntry,
|
|||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
static nsDisplayTransform* FindTransformForContainerFrame(nsIFrame* aContainerFrame,
|
||||
nsDisplayItem* aContainerItem)
|
||||
{
|
||||
if (!aContainerFrame->IsTransformed() ||
|
||||
aContainerItem->GetType() == nsDisplayItem::TYPE_TRANSFORM)
|
||||
return nullptr;
|
||||
|
||||
nsTArray<nsDisplayItem*> queue;
|
||||
queue.AppendElement(aContainerItem);
|
||||
while (queue.Length()) {
|
||||
nsDisplayItem* item = queue[queue.Length() - 1];
|
||||
queue.RemoveElementAt(queue.Length() - 1);
|
||||
|
||||
if (item->GetType() == nsDisplayItem::TYPE_TRANSFORM) {
|
||||
return static_cast<nsDisplayTransform*>(item);
|
||||
}
|
||||
|
||||
if (item->GetList()) {
|
||||
for (nsDisplayItem* child = item->GetList()->GetBottom(); child;
|
||||
child = child->GetAbove()) {
|
||||
if (child->GetUnderlyingFrame() == aContainerFrame) {
|
||||
queue.AppendElement(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
already_AddRefed<ContainerLayer>
|
||||
FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager,
|
||||
|
@ -2793,7 +2751,6 @@ FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder,
|
|||
const ContainerParameters& aParameters,
|
||||
const gfx3DMatrix* aTransform)
|
||||
{
|
||||
FrameProperties props = aContainerFrame->Properties();
|
||||
uint32_t containerDisplayItemKey =
|
||||
aContainerItem ? aContainerItem->GetPerFrameKey() : 0;
|
||||
NS_ASSERTION(aContainerFrame, "Container display items here should have a frame");
|
||||
|
@ -2904,7 +2861,8 @@ FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder,
|
|||
(aManager->GetUserData(&gLayerManagerUserData));
|
||||
while (true) {
|
||||
ContainerState state(aBuilder, aManager, aManager->GetLayerBuilder(),
|
||||
aContainerFrame, containerLayer, scaleParameters);
|
||||
aContainerFrame, aContainerItem,
|
||||
containerLayer, scaleParameters);
|
||||
|
||||
Clip clip;
|
||||
state.ProcessDisplayItems(aChildren, clip, stateFlags);
|
||||
|
|
|
@ -64,9 +64,7 @@ public:
|
|||
* The most important API in this class is BuildContainerLayerFor. This
|
||||
* method takes a display list as input and constructs a ContainerLayer
|
||||
* with child layers that render the contents of the display list. It
|
||||
* also updates userdata for the retained layer manager, and
|
||||
* DisplayItemDataProperty data for frames, to record the relationship
|
||||
* between frames and layers.
|
||||
* records the relationship between frames and layers.
|
||||
*
|
||||
* That data enables us to retain layer trees. When constructing a
|
||||
* ContainerLayer, we first check to see if there's an existing
|
||||
|
@ -85,7 +83,7 @@ public:
|
|||
* FrameLayerBuilder sets up ThebesLayers so that 0,0 in the Thebes layer
|
||||
* corresponds to the (pixel-snapped) top-left of the aActiveScrolledRoot.
|
||||
* It sets up ContainerLayers so that 0,0 in the container layer
|
||||
* corresponds to the snapped top-left of the display list reference frame.
|
||||
* corresponds to the snapped top-left of the display item reference frame.
|
||||
*
|
||||
* When we construct a container layer, we know the transform that will be
|
||||
* applied to the layer. If the transform scales the content, we can get
|
||||
|
@ -266,6 +264,7 @@ public:
|
|||
* @param aLayer Layer that the display item will be rendered into
|
||||
* @param aItem Display item to be drawn.
|
||||
* @param aLayerState What LayerState the item is using.
|
||||
* @param aTopLeft offset from active scrolled root to reference frame
|
||||
* @param aManager If the layer is in the LAYER_INACTIVE state,
|
||||
* then this is the temporary layer manager to draw with.
|
||||
*/
|
||||
|
@ -282,6 +281,7 @@ public:
|
|||
* aLayer, with aClipRect, where aContainerLayerFrame is the frame
|
||||
* for the container layer this ThebesItem belongs to.
|
||||
* aItem must have an underlying frame.
|
||||
* @param aTopLeft offset from active scrolled root to reference frame
|
||||
*/
|
||||
void AddThebesDisplayItem(ThebesLayer* aLayer,
|
||||
nsDisplayItem* aItem,
|
||||
|
@ -574,8 +574,9 @@ protected:
|
|||
|
||||
/**
|
||||
* We accumulate DisplayItemData elements in a hashtable during
|
||||
* the paint process, and store them in the frame property only when
|
||||
* paint is complete. This is the hashentry for that hashtable.
|
||||
* the paint process, one per visible display item.
|
||||
* There is one hashtable per layer manager, and one entry
|
||||
* per frame. This is the hashentry for that hashtable.
|
||||
*/
|
||||
class DisplayItemDataEntry : public nsPtrHashKey<nsIFrame> {
|
||||
public:
|
||||
|
@ -640,8 +641,7 @@ protected:
|
|||
|
||||
/**
|
||||
* A useful hashtable iteration function that removes the
|
||||
* DisplayItemData property for the frame, clears its
|
||||
* NS_FRAME_HAS_CONTAINER_LAYER bit and returns PL_DHASH_REMOVE.
|
||||
* DisplayItemData property for the frame and returns PL_DHASH_REMOVE.
|
||||
* aClosure is ignored.
|
||||
*/
|
||||
static PLDHashOperator RemoveDisplayItemDataForFrame(DisplayItemDataEntry* aEntry,
|
||||
|
|
Загрузка…
Ссылка в новой задаче