Bug 795674 - Refactor DisplayItemData storage in FrameLayerBuilder. r=roc

This commit is contained in:
Matt Woodrow 2012-10-12 12:38:24 +13:00
parent 65e7938e9c
commit 8b3fa0303c
3 changed files with 456 additions and 579 deletions

File diff suppressed because it is too large Load Diff

View File

@ -44,11 +44,6 @@ enum LayerState {
LAYER_SVG_EFFECTS LAYER_SVG_EFFECTS
}; };
extern uint8_t gLayerManagerSecondary;
class LayerManagerSecondary : public layers::LayerUserData {
};
class RefCountedRegion : public RefCounted<RefCountedRegion> { class RefCountedRegion : public RefCounted<RefCountedRegion> {
public: public:
RefCountedRegion() : mIsInfinite(false) {} RefCountedRegion() : mIsInfinite(false) {}
@ -274,7 +269,8 @@ public:
const Clip& aClip, const Clip& aClip,
LayerState aLayerState, LayerState aLayerState,
const nsPoint& aTopLeft, const nsPoint& aTopLeft,
LayerManager* aManager = nullptr); LayerManager* aManager,
nsAutoPtr<nsDisplayItemGeometry> aGeometry);
/** /**
* Record aItem as a display item that is rendered by the ThebesLayer * Record aItem as a display item that is rendered by the ThebesLayer
@ -288,18 +284,8 @@ public:
const Clip& aClip, const Clip& aClip,
nsIFrame* aContainerLayerFrame, nsIFrame* aContainerLayerFrame,
LayerState aLayerState, LayerState aLayerState,
const nsPoint& aTopLeft); const nsPoint& aTopLeft,
nsAutoPtr<nsDisplayItemGeometry> aGeometry);
/**
* Set the current top-level LayerManager for the widget being
* painted.
*/
static void SetWidgetLayerManager(LayerManager* aManager)
{
LayerManagerSecondary* secondary =
static_cast<LayerManagerSecondary*>(aManager->GetUserData(&gLayerManagerSecondary));
sWidgetManagerSecondary = !!secondary;
}
/** /**
* Gets the frame property descriptor for the given manager, or for the current * Gets the frame property descriptor for the given manager, or for the current
@ -307,30 +293,6 @@ public:
*/ */
static const FramePropertyDescriptor* GetDescriptorForManager(LayerManager* aManager); static const FramePropertyDescriptor* GetDescriptorForManager(LayerManager* aManager);
/**
* Get the LayerManagerData for a given frame and layer manager. If no layer manager
* is passed, then the current widget layer manager is used.
*/
static LayerManagerData* GetManagerData(nsIFrame* aFrame, LayerManager* aManager = nullptr);
/**
* Set the LayerManagerData for a given frame and current widget layer manager.
* This replaces any existing data for the same frame/layer manager pair.
*/
static void SetManagerData(nsIFrame* aFrame, LayerManagerData* aData);
/**
* Clears the current LayerManagerData for the given frame and current widget
* layer manager.
*/
static void ClearManagerData(nsIFrame* aFrame);
/**
* Clears any references to the given LayerManagerData for the given frame
* and belonging to any layer manager.
*/
static void ClearManagerData(nsIFrame* aFrame, LayerManagerData* aData);
/** /**
* Calls GetOldLayerForFrame on the underlying frame of the display item, * Calls GetOldLayerForFrame on the underlying frame of the display item,
* and each subsequent merged frame if no layer is found for the underlying * and each subsequent merged frame if no layer is found for the underlying
@ -340,13 +302,6 @@ public:
static Layer* GetDebugOldLayerFor(nsIFrame* aFrame, uint32_t aDisplayItemKey); static Layer* GetDebugOldLayerFor(nsIFrame* aFrame, uint32_t aDisplayItemKey);
/**
* If the display item was previously drawn as an inactive layer,
* then return the layer manager used for the inactive transaction.
* Returns nullptr if no manager could be found.
*/
LayerManager* GetInactiveLayerManagerFor(nsDisplayItem* aItem);
/** /**
* Try to determine whether the ThebesLayer aLayer paints an opaque * Try to determine whether the ThebesLayer aLayer paints an opaque
* single color everywhere it's visible in aRect. * single color everywhere it's visible in aRect.
@ -373,17 +328,6 @@ public:
static bool NeedToInvalidateFixedDisplayItem(nsDisplayListBuilder* aBuilder, static bool NeedToInvalidateFixedDisplayItem(nsDisplayListBuilder* aBuilder,
nsDisplayItem* aItem); nsDisplayItem* aItem);
/**
* Returns true if the given display item was rendered directly
* into a retained layer.
* Returns false if it was rendered into a temporary layer manager and then
* into a retained layer.
*
* Since display items can belong to multiple retained LayerManagers, we need to
* specify which LayerManager to check.
*/
static bool HasRetainedLayerFor(nsIFrame* aFrame, uint32_t aDisplayItemKey, LayerManager* aManager);
/** /**
* Returns true if the given display item was rendered during the previous * Returns true if the given display item was rendered during the previous
* paint. Returns false otherwise. * paint. Returns false otherwise.
@ -516,21 +460,50 @@ public:
NS_DECLARE_FRAME_PROPERTY_WITH_FRAME_IN_DTOR(LayerManagerDataProperty, NS_DECLARE_FRAME_PROPERTY_WITH_FRAME_IN_DTOR(LayerManagerDataProperty,
RemoveFrameFromLayerManager) RemoveFrameFromLayerManager)
NS_DECLARE_FRAME_PROPERTY_WITH_FRAME_IN_DTOR(LayerManagerSecondaryDataProperty,
RemoveFrameFromLayerManager)
protected: protected:
/** /**
* We store an array of these for each frame that is associated with * Retained data storage:
* one or more retained layers. Each DisplayItemData records the layer *
* used to render one of the frame's display items. * Each layer manager (widget, and inactive) stores a LayerManagerData object
* that keeps a hash-set of DisplayItemData items that were drawn into it.
* Each frame also keeps a list of DisplayItemData pointers that were
* created for that frame.
*
* During layer construction we build a hashtable of DisplayItemHashData items, keyed
* using (frame,display item key). Since some display items can be associated with multiple
* frames (because of merging), multiple entries in this hashtable can refer to the same
* DisplayItemData.
*
* Once layer building is complete, we sync the new items into the retained storage and update
* any frames that have changed lists.
*/
/**
* nsIFrame/display item 'per frame key' pair used to key our hashtable of DisplayItemHashData items.
*/
class DisplayItemKey {
public:
DisplayItemKey(nsIFrame* aFrame, uint32_t aKey)
: mFrame(aFrame)
, mKey(aKey)
{ }
bool operator==(const DisplayItemKey& aOther) const {
return mFrame == aOther.mFrame &&
mKey == aOther.mKey;
}
nsIFrame* mFrame;
uint32_t mKey;
};
/**
* Retained data for a display item.
*/ */
class DisplayItemData { class DisplayItemData {
public: public:
DisplayItemData(Layer* aLayer, uint32_t aKey, LayerState aLayerState, uint32_t aGeneration);
DisplayItemData() DisplayItemData(LayerManagerData* aParent, nsIFrame* aFrame, uint32_t aKey, Layer* aLayer, LayerState aLayerState, uint32_t aGeneration);
: mUsed(false)
{}
DisplayItemData(DisplayItemData &toCopy); DisplayItemData(DisplayItemData &toCopy);
~DisplayItemData(); ~DisplayItemData();
@ -541,12 +514,27 @@ protected:
mFrameList.AppendElement(aFrame); mFrameList.AppendElement(aFrame);
} }
bool FrameListMatches(nsDisplayItem* aOther); /**
* Check for this item stored under the LayerManagerDataProperty
* for every frame in mFrameList and remove it.
* Optionally skips aSkip
*/
void RemoveFrameData(nsIFrame* aSkip = nullptr);
bool FrameListMatches(nsDisplayItem* aOther);
bool FrameListMatches(DisplayItemData* aOther);
/**
* Copies the contents of this item into aDest and
* leaves this item invalid.
*/
void CopyInto(DisplayItemData* aDest);
LayerManagerData* mParent;
nsRefPtr<Layer> mLayer; nsRefPtr<Layer> mLayer;
nsRefPtr<Layer> mOptLayer; nsRefPtr<Layer> mOptLayer;
nsRefPtr<LayerManager> mInactiveManager; nsRefPtr<LayerManager> mInactiveManager;
nsAutoTArray<nsIFrame*, 2> mFrameList; nsAutoTArray<nsIFrame*, 1> mFrameList;
nsAutoPtr<nsDisplayItemGeometry> mGeometry; nsAutoPtr<nsDisplayItemGeometry> mGeometry;
Clip mClip; Clip mClip;
uint32_t mDisplayItemKey; uint32_t mDisplayItemKey;
@ -559,8 +547,53 @@ protected:
* in mNewDisplayItemData. * in mNewDisplayItemData.
*/ */
bool mUsed; bool mUsed;
DisplayItemData *mCopiedInto;
}; };
/**
* Hashtable entry wrapping a DisplayItemData.
*
* Implemented as a separate class so that we can have multiple entries
* for a single DisplayItemData (in the case of merged display items).
*/
class DisplayItemHashData : public PLDHashEntryHdr {
public:
typedef const DisplayItemKey& KeyType;
typedef const DisplayItemKey* KeyTypePointer;
DisplayItemHashData(KeyTypePointer aKey)
: mKey(*aKey)
, mContainerLayerGeneration(0)
{ }
DisplayItemHashData(DisplayItemHashData &toCopy)
: mKey(toCopy.mKey)
, mData(toCopy.mData)
, mContainerLayerGeneration(toCopy.mContainerLayerGeneration)
{
toCopy.mData = nullptr;
}
KeyType GetKey() const {
return mKey;
}
bool KeyEquals(KeyTypePointer aKey) const {
return *aKey == mKey;
}
static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
static PLDHashNumber HashKey(const KeyTypePointer aKey) {
return mozilla::HashGeneric(aKey->mFrame, aKey->mKey);
}
enum { ALLOW_MEMMOVE = false };
DisplayItemKey mKey;
nsRefPtr<DisplayItemData> mData;
uint32_t mContainerLayerGeneration;
};
friend class LayerManagerData;
static void RemoveFrameFromLayerManager(nsIFrame* aFrame, void* aPropertyValue); static void RemoveFrameFromLayerManager(nsIFrame* aFrame, void* aPropertyValue);
/** /**
@ -572,46 +605,11 @@ protected:
*/ */
DisplayItemData* GetOldLayerForFrame(nsIFrame* aFrame, uint32_t aDisplayItemKey); DisplayItemData* GetOldLayerForFrame(nsIFrame* aFrame, uint32_t aDisplayItemKey);
/**
* We accumulate DisplayItemData elements in a hashtable during
* 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:
DisplayItemDataEntry(const nsIFrame *key)
: nsPtrHashKey<nsIFrame>(key)
{
MOZ_COUNT_CTOR(DisplayItemDataEntry);
}
DisplayItemDataEntry(DisplayItemDataEntry &toCopy)
: nsPtrHashKey<nsIFrame>(toCopy.mKey)
{
MOZ_COUNT_CTOR(DisplayItemDataEntry);
// This isn't actually a copy-constructor; notice that it steals toCopy's
// array and invalid region. Be careful.
mData.SwapElements(toCopy.mData);
mContainerLayerGeneration = toCopy.mContainerLayerGeneration;
}
~DisplayItemDataEntry() { MOZ_COUNT_DTOR(DisplayItemDataEntry); }
bool HasNonEmptyContainerLayer();
nsAutoTArray<nsRefPtr<DisplayItemData>, 1> mData;
uint32_t mContainerLayerGeneration;
enum { ALLOW_MEMMOVE = false };
};
// LayerManagerData needs to see DisplayItemDataEntry.
friend class LayerManagerData;
/** /**
* Stores DisplayItemData associated with aFrame, stores the data in * Stores DisplayItemData associated with aFrame, stores the data in
* mNewDisplayItemData. * mNewDisplayItemData.
*/ */
void StoreDataForFrame(nsIFrame* aFrame, DisplayItemData* data); void StoreDataForFrame(nsDisplayItem* aItem, DisplayItemData* data);
// Flash the area within the context clip if paint flashing is enabled. // Flash the area within the context clip if paint flashing is enabled.
static void FlashPaint(gfxContext *aContext); static void FlashPaint(gfxContext *aContext);
@ -623,7 +621,7 @@ protected:
* Note that the pointer returned here is only valid so long as you don't * Note that the pointer returned here is only valid so long as you don't
* poke the LayerManagerData's mFramesWithLayers hashtable. * poke the LayerManagerData's mFramesWithLayers hashtable.
*/ */
nsTArray<nsRefPtr<DisplayItemData> >* GetDisplayItemDataArrayForFrame(nsIFrame *aFrame); DisplayItemData* GetDisplayItemData(nsIFrame *aFrame, uint32_t aKey);
/* /*
* Get the DisplayItemData associated with this frame / display item pair, * Get the DisplayItemData associated with this frame / display item pair,
@ -644,7 +642,7 @@ protected:
* DisplayItemData property for the frame and returns PL_DHASH_REMOVE. * DisplayItemData property for the frame and returns PL_DHASH_REMOVE.
* aClosure is ignored. * aClosure is ignored.
*/ */
static PLDHashOperator RemoveDisplayItemDataForFrame(DisplayItemDataEntry* aEntry, static PLDHashOperator RemoveDisplayItemDataForFrame(nsRefPtrHashKey<DisplayItemData>* aEntry,
void* aClosure); void* aClosure);
/** /**
@ -720,19 +718,18 @@ public:
return mThebesLayerItems.GetEntry(aLayer); return mThebesLayerItems.GetEntry(aLayer);
} }
static PLDHashOperator ProcessRemovedDisplayItems(DisplayItemDataEntry* aEntry, static PLDHashOperator ProcessRemovedDisplayItems(nsRefPtrHashKey<DisplayItemData>* aEntry,
void* aUserArg); void* aUserArg);
protected: protected:
void RemoveThebesItemsAndOwnerDataForLayerSubtree(Layer* aLayer, void RemoveThebesItemsAndOwnerDataForLayerSubtree(Layer* aLayer,
bool aRemoveThebesItems, bool aRemoveThebesItems,
bool aRemoveOwnerData); bool aRemoveOwnerData);
static void SetAndClearInvalidRegion(DisplayItemDataEntry* aEntry); static PLDHashOperator UpdateDisplayItemDataForFrame(nsRefPtrHashKey<DisplayItemData>* aEntry,
static PLDHashOperator UpdateDisplayItemDataForFrame(DisplayItemDataEntry* aEntry,
void* aUserArg); void* aUserArg);
static PLDHashOperator StoreNewDisplayItemData(DisplayItemDataEntry* aEntry, static PLDHashOperator StoreNewDisplayItemData(DisplayItemHashData* aEntry,
void* aUserArg); void* aUserArg);
static PLDHashOperator RestoreDisplayItemData(DisplayItemDataEntry* aEntry, static PLDHashOperator RestoreDisplayItemData(DisplayItemHashData* aEntry,
void *aUserArg); void *aUserArg);
static PLDHashOperator RestoreThebesLayerItemEntries(ThebesLayerItemsEntry* aEntry, static PLDHashOperator RestoreThebesLayerItemEntries(ThebesLayerItemsEntry* aEntry,
@ -763,7 +760,7 @@ protected:
* A map from frames to a list of (display item key, layer) pairs that * A map from frames to a list of (display item key, layer) pairs that
* describes what layers various parts of the frame are assigned to. * describes what layers various parts of the frame are assigned to.
*/ */
nsTHashtable<DisplayItemDataEntry> mNewDisplayItemData; nsTHashtable<DisplayItemHashData> mNewDisplayItemData;
/** /**
* A map from ThebesLayers to the list of display items (plus * A map from ThebesLayers to the list of display items (plus
* clipping data) to be rendered in the layer. * clipping data) to be rendered in the layer.
@ -786,12 +783,6 @@ protected:
uint32_t mContainerLayerGeneration; uint32_t mContainerLayerGeneration;
uint32_t mMaxContainerLayerGeneration; uint32_t mMaxContainerLayerGeneration;
/**
* True if the current top-level LayerManager for the widget being
* painted is marked as being a 'secondary' LayerManager.
*/
static bool sWidgetManagerSecondary;
}; };
} }

View File

@ -993,7 +993,6 @@ void nsDisplayList::PaintForFrame(nsDisplayListBuilder* aBuilder,
layerManager = window->GetLayerManager(&allowRetaining); layerManager = window->GetLayerManager(&allowRetaining);
if (layerManager) { if (layerManager) {
doBeginTransaction = !(aFlags & PAINT_EXISTING_TRANSACTION); doBeginTransaction = !(aFlags & PAINT_EXISTING_TRANSACTION);
FrameLayerBuilder::SetWidgetLayerManager(layerManager);
widgetTransaction = true; widgetTransaction = true;
} }
} }
@ -1020,7 +1019,7 @@ void nsDisplayList::PaintForFrame(nsDisplayListBuilder* aBuilder,
layerManager->BeginTransaction(); layerManager->BeginTransaction();
} }
} }
if (allowRetaining) { if (widgetTransaction) {
layerBuilder->DidBeginRetainedLayerTransaction(layerManager); layerBuilder->DidBeginRetainedLayerTransaction(layerManager);
} }