mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 11:55:49 +00:00
Bug 1119942 - Hoist nsDisplayScrollInfoLayer items out of inactive layermanagers into their parent. r=tnikkel,mattwoodrow
This commit is contained in:
parent
bcfda0904e
commit
5b15a36695
@ -292,6 +292,10 @@ static EventRegions
|
||||
GetEventRegions(const LayerMetricsWrapper& aLayer)
|
||||
{
|
||||
if (gfxPrefs::LayoutEventRegionsEnabled()) {
|
||||
if (aLayer.IsScrollInfoLayer()) {
|
||||
return EventRegions(nsIntRegion(ParentLayerIntRect::ToUntyped(
|
||||
RoundedToInt(aLayer.Metrics().mCompositionBounds))));
|
||||
}
|
||||
return aLayer.GetEventRegions();
|
||||
}
|
||||
return EventRegions(aLayer.GetVisibleRegion());
|
||||
|
@ -643,6 +643,11 @@ public:
|
||||
CollectOldLayers();
|
||||
}
|
||||
|
||||
~ContainerState()
|
||||
{
|
||||
MOZ_ASSERT(mHoistedItems.IsEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the method that actually walks a display list and builds
|
||||
* the child layers.
|
||||
@ -719,6 +724,11 @@ public:
|
||||
const nsIntRegion& aOuterVisibleRegion,
|
||||
const nsIntRect* aLayerContentsVisibleRect = nullptr) const;
|
||||
|
||||
void AddHoistedItem(nsDisplayItem* aItem)
|
||||
{
|
||||
mHoistedItems.AppendToTop(aItem);
|
||||
}
|
||||
|
||||
protected:
|
||||
friend class PaintedLayerData;
|
||||
|
||||
@ -925,6 +935,11 @@ protected:
|
||||
nscoord mAppUnitsPerDevPixel;
|
||||
bool mSnappingEnabled;
|
||||
bool mFlattenToSingleLayer;
|
||||
/**
|
||||
* In some cases we need to hoist nsDisplayScrollInfoLayer items out from a
|
||||
* nested inactive container. This holds the items hoisted up from children.
|
||||
*/
|
||||
nsDisplayList mHoistedItems;
|
||||
};
|
||||
|
||||
class PaintedDisplayItemLayerUserData : public LayerUserData
|
||||
@ -1093,7 +1108,7 @@ FrameLayerBuilder::Shutdown()
|
||||
|
||||
void
|
||||
FrameLayerBuilder::Init(nsDisplayListBuilder* aBuilder, LayerManager* aManager,
|
||||
PaintedLayerData* aLayerData)
|
||||
PaintedLayerData* aLayerData, ContainerState* aContainingContainerState)
|
||||
{
|
||||
mDisplayListBuilder = aBuilder;
|
||||
mRootPresContext = aBuilder->RootReferenceFrame()->PresContext()->GetRootPresContext();
|
||||
@ -1101,6 +1116,7 @@ FrameLayerBuilder::Init(nsDisplayListBuilder* aBuilder, LayerManager* aManager,
|
||||
mInitialDOMGeneration = mRootPresContext->GetDOMGeneration();
|
||||
}
|
||||
mContainingPaintedLayer = aLayerData;
|
||||
mContainingContainerState = aContainingContainerState;
|
||||
aManager->SetUserData(&gLayerManagerLayerBuilder, this);
|
||||
}
|
||||
|
||||
@ -2867,6 +2883,20 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
|
||||
continue;
|
||||
}
|
||||
|
||||
nsDisplayItem::Type itemType = item->GetType();
|
||||
if (itemType == nsDisplayItem::TYPE_SCROLL_INFO_LAYER &&
|
||||
mLayerBuilder->GetContainingContainerState()) {
|
||||
// We have encountered a scrollable area inside a nested (inactive)
|
||||
// layer manager, so we need to hoist the item out into the parent; that
|
||||
// way we will still generate a scrollinfo layer for it and the APZ can
|
||||
// drive main-thread sync scrolling.
|
||||
// Note: |item| is removed from aList and will be attached into the parent
|
||||
// list, so we don't delete it here.
|
||||
static_cast<nsDisplayScrollInfoLayer*>(item)->MarkHoisted();
|
||||
mLayerBuilder->GetContainingContainerState()->AddHoistedItem(item);
|
||||
continue;
|
||||
}
|
||||
|
||||
savedItems.AppendToTop(item);
|
||||
|
||||
NS_ASSERTION(mAppUnitsPerDevPixel == AppUnitsPerDevPixel(item),
|
||||
@ -2881,7 +2911,6 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
|
||||
bool snap;
|
||||
nsRect itemContent = item->GetBounds(mBuilder, &snap);
|
||||
nsIntRect itemDrawRect = ScaleToOutsidePixels(itemContent, snap);
|
||||
nsDisplayItem::Type itemType = item->GetType();
|
||||
bool prerenderedTransform = itemType == nsDisplayItem::TYPE_TRANSFORM &&
|
||||
static_cast<nsDisplayTransform*>(item)->ShouldPrerender(mBuilder);
|
||||
nsIntRect clipRect;
|
||||
@ -3132,6 +3161,10 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
|
||||
}
|
||||
}
|
||||
|
||||
// Finish the hoisting process by taking the items from the child and adding
|
||||
// them to the list here.
|
||||
aList->AppendToBottom(&mHoistedItems);
|
||||
|
||||
if (itemSameCoordinateSystemChildren &&
|
||||
itemSameCoordinateSystemChildren->NeedsTransparentSurface()) {
|
||||
aList->SetNeedsTransparentSurface();
|
||||
@ -3139,6 +3172,7 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
|
||||
}
|
||||
|
||||
aList->AppendToTop(&savedItems);
|
||||
MOZ_ASSERT(mHoistedItems.IsEmpty());
|
||||
}
|
||||
|
||||
void
|
||||
@ -3283,7 +3317,7 @@ FrameLayerBuilder::AddPaintedDisplayItem(PaintedLayerData* aLayerData,
|
||||
nsDisplayItem* aItem,
|
||||
const DisplayItemClip& aClip,
|
||||
const nsIntRect& aItemVisibleRect,
|
||||
const ContainerState& aContainerState,
|
||||
ContainerState& aContainerState,
|
||||
LayerState aLayerState,
|
||||
const nsPoint& aTopLeft)
|
||||
{
|
||||
@ -3329,7 +3363,7 @@ FrameLayerBuilder::AddPaintedDisplayItem(PaintedLayerData* aLayerData,
|
||||
if (tempManager) {
|
||||
FLB_LOG_PAINTED_LAYER_DECISION(aLayerData, "Creating nested FLB for item %p\n", aItem);
|
||||
FrameLayerBuilder* layerBuilder = new FrameLayerBuilder();
|
||||
layerBuilder->Init(mDisplayListBuilder, tempManager, aLayerData);
|
||||
layerBuilder->Init(mDisplayListBuilder, tempManager, aLayerData, &aContainerState);
|
||||
|
||||
tempManager->BeginTransaction();
|
||||
if (mRetainingManager) {
|
||||
|
@ -177,7 +177,8 @@ public:
|
||||
static void Shutdown();
|
||||
|
||||
void Init(nsDisplayListBuilder* aBuilder, LayerManager* aManager,
|
||||
PaintedLayerData* aLayerData = nullptr);
|
||||
PaintedLayerData* aLayerData = nullptr,
|
||||
ContainerState* aContainingContainerState = nullptr);
|
||||
|
||||
/**
|
||||
* Call this to notify that we have just started a transaction on the
|
||||
@ -306,7 +307,7 @@ public:
|
||||
nsDisplayItem* aItem,
|
||||
const DisplayItemClip& aClip,
|
||||
const nsIntRect& aItemVisibleRect,
|
||||
const ContainerState& aContainerState,
|
||||
ContainerState& aContainerState,
|
||||
LayerState aLayerState,
|
||||
const nsPoint& aTopLeft);
|
||||
|
||||
@ -636,6 +637,11 @@ public:
|
||||
return !mContainingPaintedLayer && mRetainingManager;
|
||||
}
|
||||
|
||||
ContainerState* GetContainingContainerState()
|
||||
{
|
||||
return mContainingContainerState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to build the most compressed layer tree possible, even if it means
|
||||
* throwing away existing retained buffers.
|
||||
@ -689,7 +695,9 @@ protected:
|
||||
* When building layers for an inactive layer, this is where the
|
||||
* inactive layer will be placed.
|
||||
*/
|
||||
PaintedLayerData* mContainingPaintedLayer;
|
||||
PaintedLayerData* mContainingPaintedLayer;
|
||||
|
||||
ContainerState* mContainingContainerState;
|
||||
|
||||
/**
|
||||
* Saved generation counter so we can detect DOM changes.
|
||||
|
@ -4602,6 +4602,7 @@ nsDisplayScrollInfoLayer::nsDisplayScrollInfoLayer(
|
||||
nsIFrame* aScrolledFrame,
|
||||
nsIFrame* aScrollFrame)
|
||||
: nsDisplayScrollLayer(aBuilder, aScrollFrame, aScrolledFrame, aScrollFrame)
|
||||
, mHoisted(false)
|
||||
{
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
MOZ_COUNT_CTOR(nsDisplayScrollInfoLayer);
|
||||
@ -4626,9 +4627,12 @@ nsDisplayScrollInfoLayer::BuildLayer(nsDisplayListBuilder* aBuilder,
|
||||
{
|
||||
// Only build scrollinfo layers if event-regions are disabled, so that the
|
||||
// compositor knows where the inactive scrollframes are. When event-regions
|
||||
// are enabled, the dispatch-to-content regions provide this information to
|
||||
// the APZ code.
|
||||
if (gfxPrefs::LayoutEventRegionsEnabled()) {
|
||||
// are enabled, the dispatch-to-content regions generally provide this
|
||||
// information to the APZ code. However, in some cases, there might be
|
||||
// content that cannot be layerized, and so needs to scroll synchronously.
|
||||
// To handle those cases (which are indicated by setting mHoisted to true), we
|
||||
// still want to generate scrollinfo layers.
|
||||
if (gfxPrefs::LayoutEventRegionsEnabled() && !mHoisted) {
|
||||
return nullptr;
|
||||
}
|
||||
return nsDisplayScrollLayer::BuildLayer(aBuilder, aManager, aContainerParameters);
|
||||
@ -4640,7 +4644,7 @@ nsDisplayScrollInfoLayer::GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||
const ContainerLayerParameters& aParameters)
|
||||
{
|
||||
// See comment in BuildLayer
|
||||
if (gfxPrefs::LayoutEventRegionsEnabled()) {
|
||||
if (gfxPrefs::LayoutEventRegionsEnabled() && !mHoisted) {
|
||||
return LAYER_NONE;
|
||||
}
|
||||
return LAYER_ACTIVE_EMPTY;
|
||||
|
@ -3223,6 +3223,11 @@ public:
|
||||
nsDisplayItem* aItem) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
|
||||
|
||||
void MarkHoisted() { mHoisted = true; }
|
||||
|
||||
private:
|
||||
bool mHoisted;
|
||||
};
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user