Bug 1119942 - Hoist nsDisplayScrollInfoLayer items out of inactive layermanagers into their parent. r=tnikkel,mattwoodrow

This commit is contained in:
Kartikaya Gupta 2015-01-20 09:49:30 -05:00
parent bcfda0904e
commit 5b15a36695
5 changed files with 66 additions and 11 deletions

View File

@ -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());

View File

@ -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) {

View File

@ -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.

View File

@ -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;

View File

@ -3223,6 +3223,11 @@ public:
nsDisplayItem* aItem) MOZ_OVERRIDE;
virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
void MarkHoisted() { mHoisted = true; }
private:
bool mHoisted;
};
/**