Bug 795674 - Remove mNewDisplayItemData. r=roc

This commit is contained in:
Matt Woodrow 2012-10-12 15:39:46 +13:00
parent fad4d60944
commit 8760ddc9ae
2 changed files with 149 additions and 306 deletions

View File

@ -39,7 +39,7 @@ using namespace mozilla::gfx;
namespace mozilla {
FrameLayerBuilder::DisplayItemData::DisplayItemData(LayerManagerData* aParent, nsIFrame* aFrame, uint32_t aKey,
FrameLayerBuilder::DisplayItemData::DisplayItemData(LayerManagerData* aParent, uint32_t aKey,
Layer* aLayer, LayerState aLayerState, uint32_t aGeneration)
: mParent(aParent)
@ -47,10 +47,8 @@ FrameLayerBuilder::DisplayItemData::DisplayItemData(LayerManagerData* aParent, n
, mDisplayItemKey(aKey)
, mContainerLayerGeneration(aGeneration)
, mLayerState(aLayerState)
, mUsed(false)
, mCopiedInto(nullptr)
, mUsed(true)
{
AddFrame(aFrame);
}
FrameLayerBuilder::DisplayItemData::DisplayItemData(DisplayItemData &toCopy)
@ -67,36 +65,42 @@ FrameLayerBuilder::DisplayItemData::DisplayItemData(DisplayItemData &toCopy)
mContainerLayerGeneration = toCopy.mContainerLayerGeneration;
mLayerState = toCopy.mLayerState;
mUsed = toCopy.mUsed;
mCopiedInto = toCopy.mCopiedInto;
}
void
FrameLayerBuilder::DisplayItemData::CopyInto(DisplayItemData* aOther)
FrameLayerBuilder::DisplayItemData::AddFrame(nsIFrame* aFrame)
{
if (mCopiedInto) {
NS_ASSERTION(mCopiedInto == aOther, "Can't copy a single DisplayItemData into multiple places!");
return;
mFrameList.AppendElement(aFrame);
nsTArray<DisplayItemData*> *array =
reinterpret_cast<nsTArray<DisplayItemData*>*>(aFrame->Properties().Get(FrameLayerBuilder::LayerManagerDataProperty()));
if (!array) {
array = new nsTArray<DisplayItemData*>();
aFrame->Properties().Set(FrameLayerBuilder::LayerManagerDataProperty(), array);
}
NS_ABORT_IF_FALSE(mParent == aOther->mParent, "Must be a matching display item to copy!");
aOther->mLayer = mLayer;
aOther->mOptLayer = mOptLayer;
aOther->mInactiveManager = mInactiveManager;
NS_ABORT_IF_FALSE(mDisplayItemKey == aOther->mDisplayItemKey, "Must be a matching display item to copy!");
NS_ABORT_IF_FALSE(FrameListMatches(aOther), "Must be a matching display item to copy!");
mFrameList.Clear();
aOther->mGeometry = mGeometry;
aOther->mClip = mClip;
aOther->mLayerState = mLayerState;
aOther->mUsed = false;
mCopiedInto = aOther;
array->AppendElement(this);
}
void
FrameLayerBuilder::DisplayItemData::RemoveFrameData(nsIFrame* aSkip /* = nullptr */)
FrameLayerBuilder::DisplayItemData::UpdateContents(Layer* aLayer, LayerState aState, uint32_t aContainerLayerGeneration)
{
mLayer = aLayer;
mOptLayer = nullptr;
mInactiveManager = nullptr;
mLayerState = aState;
mContainerLayerGeneration = aContainerLayerGeneration;
mGeometry = nullptr;
mClip.mHaveClipRect = false;
mClip.mRoundedClipRects.Clear();
mUsed = true;
}
static nsIFrame* sDestroyedFrame = NULL;
FrameLayerBuilder::DisplayItemData::~DisplayItemData()
{
for (uint32_t i = 0; i < mFrameList.Length(); i++) {
nsIFrame* frame = mFrameList[i];
if (frame == aSkip) {
if (frame == sDestroyedFrame) {
continue;
}
nsTArray<DisplayItemData*> *array =
@ -105,39 +109,6 @@ FrameLayerBuilder::DisplayItemData::RemoveFrameData(nsIFrame* aSkip /* = nullptr
}
}
static nsIFrame* sDestroyedFrame = NULL;
FrameLayerBuilder::DisplayItemData::~DisplayItemData()
{
#ifdef DEBUG
/* TODO: Sanity check that we've removed our reference from all frames in mFrameList */
for (uint32_t i = 0; i < mFrameList.Length(); i++) {
if (mFrameList[i] == sDestroyedFrame) {
continue;
}
nsTArray<DisplayItemData*> *array =
reinterpret_cast<nsTArray<DisplayItemData*>*>(mFrameList[i]->Properties().Get(LayerManagerDataProperty()));
if (!array) {
continue;
}
NS_ABORT_IF_FALSE(!array->Contains(this), "Must have removed ourselves from the frames!");
}
#endif
}
bool
FrameLayerBuilder::DisplayItemData::FrameListMatches(DisplayItemData* aOther)
{
nsAutoTArray<nsIFrame*, 4> copy = mFrameList;
for (uint32_t i = 0; i < aOther->mFrameList.Length(); ++i) {
if (!copy.RemoveElement(aOther->mFrameList[i])) {
return false;
}
}
return copy.IsEmpty();
}
bool
FrameLayerBuilder::DisplayItemData::FrameListMatches(nsDisplayItem* aOther)
{
@ -164,7 +135,9 @@ class LayerManagerData : public LayerUserData {
public:
LayerManagerData(LayerManager *aManager)
: mLayerManager(aManager)
#ifdef DEBUG_DISPLAY_ITEM_DATA
, mParent(nullptr)
#endif
, mInvalidateAllLayers(false)
{
MOZ_COUNT_CTOR(LayerManagerData);
@ -172,10 +145,6 @@ public:
}
~LayerManagerData() {
MOZ_COUNT_DTOR(LayerManagerData);
// Remove display item data properties now, since we won't be able
// to find these frames again without mFramesWithLayers.
mDisplayItems.EnumerateEntries(
FrameLayerBuilder::RemoveDisplayItemDataForFrame, nullptr);
}
#ifdef DEBUG_DISPLAY_ITEM_DATA
@ -193,7 +162,9 @@ public:
* Tracks which frames have layers associated with them.
*/
LayerManager *mLayerManager;
#ifdef DEBUG_DISPLAY_ITEM_DATA
LayerManagerData *mParent;
#endif
nsTHashtable<nsRefPtrHashKey<FrameLayerBuilder::DisplayItemData> > mDisplayItems;
bool mInvalidateAllLayers;
};
@ -847,7 +818,7 @@ GetTranslationForThebesLayer(ThebesLayer* aLayer)
* If one of these frames has just been destroyed, we will free the inner
* layer manager when removing the entry from mFramesWithLayers. Destroying
* the layer manager destroys the LayerManagerData and calls into
* RemoveDisplayItemDataForFrame. If the inner layer manager had any
* the DisplayItemData destructor. If the inner layer manager had any
* items with the same frame, then we attempt to retrieve properties
* from the deleted frame.
*
@ -895,7 +866,6 @@ FrameLayerBuilder::RemoveFrameFromLayerManager(nsIFrame* aFrame,
}
}
data->RemoveFrameData(aFrame);
data->mParent->mDisplayItems.RemoveEntry(data);
}
@ -919,14 +889,15 @@ FrameLayerBuilder::DidBeginRetainedLayerTransaction(LayerManager* aManager)
}
void
FrameLayerBuilder::StoreOptimizedLayerForFrame(nsIFrame* aFrame, uint32_t aDisplayItemKey, Layer* aImage)
FrameLayerBuilder::StoreOptimizedLayerForFrame(nsDisplayItem* aItem, Layer* aLayer)
{
DisplayItemKey key(aFrame, aDisplayItemKey);
DisplayItemHashData *entry = mNewDisplayItemData.GetEntry(key);
if (!entry)
if (!mRetainingManager) {
return;
}
entry->mData->mOptLayer = aImage;
DisplayItemData* data = GetDisplayItemDataForManager(aItem, aLayer->Manager());
NS_ASSERTION(data, "Must have already stored data for this item!");
data->mOptLayer = aLayer;
}
void
@ -947,12 +918,7 @@ FrameLayerBuilder::WillEndTransaction()
(mRetainingManager->GetUserData(&gLayerManagerUserData));
NS_ASSERTION(data, "Must have data!");
// Update all the frames that used to have layers.
data->mDisplayItems.EnumerateEntries(UpdateDisplayItemDataForFrame, this);
// Now go through all the frames that didn't have any retained
// display items before, and record those retained display items.
// This also empties mNewDisplayItemData.
mNewDisplayItemData.EnumerateEntries(StoreNewDisplayItemData, data);
data->mDisplayItems.EnumerateEntries(UpdateDisplayItemDataForFrame, nullptr);
data->mInvalidateAllLayers = false;
}
@ -997,44 +963,16 @@ FrameLayerBuilder::ProcessRemovedDisplayItems(nsRefPtrHashKey<DisplayItemData>*
FrameLayerBuilder::UpdateDisplayItemDataForFrame(nsRefPtrHashKey<DisplayItemData>* aEntry,
void* aUserArg)
{
FrameLayerBuilder* builder = static_cast<FrameLayerBuilder*>(aUserArg);
DisplayItemData* data = aEntry->GetKey();
DisplayItemKey key(data->mFrameList[0], data->mDisplayItemKey);
DisplayItemHashData* newDisplayItems =
builder ? builder->mNewDisplayItemData.GetEntry(key) : nullptr;
if (!newDisplayItems || !newDisplayItems->mData->FrameListMatches(data)) {
if (!data->mUsed) {
// This item was visible, but isn't anymore.
// Go through all frames on the DisplayItemData, and then remove ourselves from that frame.
data->RemoveFrameData();
return PL_DHASH_REMOVE;
}
// Our frame(s) already have a pointer to the current DisplayItemData, so
// copy the contents of the new into it rather than replacing it.
newDisplayItems->mData->CopyInto(data);
// Don't need to process this frame again
builder->mNewDisplayItemData.RawRemoveEntry(newDisplayItems);
for (uint32_t i = 1; i < data->mFrameList.Length(); i++) {
key.mFrame = data->mFrameList[i];
builder->mNewDisplayItemData.RemoveEntry(key);
}
data->mUsed = false;
return PL_DHASH_NEXT;
}
/* static */ PLDHashOperator
FrameLayerBuilder::RemoveDisplayItemDataForFrame(nsRefPtrHashKey<DisplayItemData>* aEntry,
void* aClosure)
{
DisplayItemData* data = aEntry->GetKey();
// If this was called from a frame destructor then the prop is definitely already gone,
// and we could crash trying to check. See the definition of sDestroyedFrame.
data->RemoveFrameData(sDestroyedFrame);
return PL_DHASH_REMOVE;
}
/* static */ PLDHashOperator
FrameLayerBuilder::DumpDisplayItemDataForFrame(nsRefPtrHashKey<DisplayItemData>* aEntry,
void* aClosure)
@ -1091,26 +1029,6 @@ FrameLayerBuilder::DumpDisplayItemDataForFrame(nsRefPtrHashKey<DisplayItemData>*
return PL_DHASH_NEXT;
}
/* static */ PLDHashOperator
FrameLayerBuilder::StoreNewDisplayItemData(DisplayItemHashData* aEntry,
void* aUserArg)
{
LayerManagerData* data = static_cast<LayerManagerData*>(aUserArg);
const DisplayItemKey& key = aEntry->GetKey();
// Remember that this frame has display items in retained layers
data->mDisplayItems.PutEntry(aEntry->mData);
nsTArray<DisplayItemData*> *array =
reinterpret_cast<nsTArray<DisplayItemData*>*>(key.mFrame->Properties().Get(LayerManagerDataProperty()));
if (!array) {
array = new nsTArray<DisplayItemData*>();
key.mFrame->Properties().Set(LayerManagerDataProperty(), array);
}
array->AppendElement(aEntry->mData);
return PL_DHASH_REMOVE;
}
/* static */ FrameLayerBuilder::DisplayItemData*
FrameLayerBuilder::GetDisplayItemDataForManager(nsDisplayItem* aItem,
LayerManager* aManager)
@ -1567,8 +1485,7 @@ ContainerState::PopThebesLayerData()
imageLayer->IntersectClipRect(clip);
}
layer = imageLayer;
mLayerBuilder->StoreOptimizedLayerForFrame(data->mImage->GetUnderlyingFrame(),
data->mImage->GetPerFrameKey(),
mLayerBuilder->StoreOptimizedLayerForFrame(data->mImage,
imageLayer);
} else {
nsRefPtr<ColorLayer> colorLayer = CreateOrRecycleColorLayer(data->mLayer);
@ -2070,22 +1987,29 @@ ContainerState::ProcessDisplayItems(const nsDisplayList& aList,
itemVisibleRect.IsEmpty(),
"State is LAYER_ACTIVE_EMPTY but visible rect is not.");
// As long as the new layer isn't going to be a ThebesLayer,
// InvalidateForLayerChange doesn't need the new layer pointer.
// We also need to check the old data now, because BuildLayer
// can overwrite it.
InvalidateForLayerChange(item, nullptr, aClip, topLeft, geometry);
// If the item would have its own layer but is invisible, just hide it.
// Note that items without their own layers can't be skipped this
// way, since their ThebesLayer may decide it wants to draw them
// into its buffer even if they're currently covered.
if (itemVisibleRect.IsEmpty() && layerState != LAYER_ACTIVE_EMPTY) {
InvalidateForLayerChange(item, nullptr, aClip, topLeft, geometry);
continue;
}
// Just use its layer.
nsRefPtr<Layer> ownLayer = item->BuildLayer(mBuilder, mManager, mParameters);
if (!ownLayer) {
InvalidateForLayerChange(item, ownLayer, aClip, topLeft, geometry);
continue;
}
NS_ASSERTION(!ownLayer->AsThebesLayer(),
"Should never have created a dedicated Thebes layer!");
nsRect invalid;
if (item->IsInvalid(invalid)) {
ownLayer->SetInvalidRectToVisibleRegion();
@ -2140,8 +2064,6 @@ ContainerState::ProcessDisplayItems(const nsDisplayList& aList,
NS_ASSERTION(!mNewChildLayers.Contains(ownLayer),
"Layer already in list???");
InvalidateForLayerChange(item, ownLayer, aClip, topLeft, geometry);
mNewChildLayers.AppendElement(ownLayer);
mLayerBuilder->AddLayerDisplayItem(ownLayer, item,
aClip, layerState,
@ -2346,15 +2268,14 @@ FrameLayerBuilder::AddThebesDisplayItem(ThebesLayer* aLayer,
// If BuildLayer didn't call BuildContainerLayerFor, then our new layer won't have been
// stored in layerBuilder. Manually add it now.
if (mRetainingManager) {
#ifdef DEBUG_DISPLAY_ITEM_DATA
LayerManagerData* parentLmd = static_cast<LayerManagerData*>
(aLayer->Manager()->GetUserData(&gLayerManagerUserData));
LayerManagerData* lmd = static_cast<LayerManagerData*>
(tempManager->GetUserData(&gLayerManagerUserData));
lmd->mParent = parentLmd;
nsRefPtr<DisplayItemData> data =
new DisplayItemData(lmd, aItem->GetUnderlyingFrame(), aItem->GetPerFrameKey(),
layer, LAYER_ACTIVE, mContainerLayerGeneration);
layerBuilder->StoreDataForFrame(aItem, data);
#endif
layerBuilder->StoreDataForFrame(aItem, layer, LAYER_ACTIVE);
}
tempManager->SetRoot(layer);
@ -2384,33 +2305,59 @@ FrameLayerBuilder::AddThebesDisplayItem(ThebesLayer* aLayer,
}
}
void
FrameLayerBuilder::StoreDataForFrame(nsDisplayItem* aItem, DisplayItemData* aData)
FrameLayerBuilder::DisplayItemData*
FrameLayerBuilder::StoreDataForFrame(nsDisplayItem* aItem, Layer* aLayer, LayerState aState)
{
DisplayItemKey key(aItem->GetUnderlyingFrame(), aItem->GetPerFrameKey());
DisplayItemHashData *entry = mNewDisplayItemData.GetEntry(key);
if (entry) {
return;
}
entry = mNewDisplayItemData.PutEntry(key);
if (entry) {
entry->mData = aData;
entry->mContainerLayerGeneration = mContainerLayerGeneration;
DisplayItemData* oldData = GetDisplayItemDataForManager(aItem, mRetainingManager);
if (oldData) {
if (!oldData->mUsed) {
oldData->UpdateContents(aLayer, aState, mContainerLayerGeneration);
}
return oldData;
}
LayerManagerData* lmd = static_cast<LayerManagerData*>
(mRetainingManager->GetUserData(&gLayerManagerUserData));
nsRefPtr<DisplayItemData> data =
new DisplayItemData(lmd, aItem->GetPerFrameKey(),
aLayer, aState, mContainerLayerGeneration);
data->AddFrame(aItem->GetUnderlyingFrame());
nsAutoTArray<nsIFrame*,4> mergedFrames;
aItem->GetMergedFrames(&mergedFrames);
for (uint32_t i = 0; i < mergedFrames.Length(); ++i) {
nsIFrame* mergedFrame = mergedFrames[i];
DisplayItemKey key(mergedFrame, aItem->GetPerFrameKey());
entry = mNewDisplayItemData.PutEntry(key);
if (entry) {
entry->mData = aData;
entry->mContainerLayerGeneration = mContainerLayerGeneration;
aData->AddFrame(mergedFrame);
}
data->AddFrame(mergedFrames[i]);
}
lmd->mDisplayItems.PutEntry(data);
return data;
}
void
FrameLayerBuilder::StoreDataForFrame(nsIFrame* aFrame,
uint32_t aDisplayItemKey,
Layer* aLayer,
LayerState aState)
{
DisplayItemData* oldData = GetDisplayItemData(aFrame, aDisplayItemKey);
if (oldData && oldData->mFrameList.Length() == 1) {
oldData->UpdateContents(aLayer, aState, mContainerLayerGeneration);
return;
}
LayerManagerData* lmd = static_cast<LayerManagerData*>
(mRetainingManager->GetUserData(&gLayerManagerUserData));
nsRefPtr<DisplayItemData> data =
new DisplayItemData(lmd, aDisplayItemKey, aLayer,
aState, mContainerLayerGeneration);
data->AddFrame(aFrame);
lmd->mDisplayItems.PutEntry(data);
}
FrameLayerBuilder::ClippedDisplayItem::~ClippedDisplayItem()
@ -2439,25 +2386,13 @@ FrameLayerBuilder::AddLayerDisplayItem(Layer* aLayer,
if (aLayer->Manager() != mRetainingManager)
return;
LayerManagerData* lmd = static_cast<LayerManagerData*>
(aLayer->Manager()->GetUserData(&gLayerManagerUserData));
nsRefPtr<DisplayItemData> data =
new DisplayItemData(lmd, aItem->GetUnderlyingFrame(), aItem->GetPerFrameKey(),
aLayer, aLayerState, mContainerLayerGeneration);
DisplayItemData *data = StoreDataForFrame(aItem, aLayer, aLayerState);
ThebesLayer *t = aLayer->AsThebesLayer();
if (t) {
data->mGeometry = aGeometry;
data->mClip = aClip;
}
data->mInactiveManager = aManager;
StoreDataForFrame(aItem, data);
DisplayItemData* oldData = GetDisplayItemDataForManager(aItem, mRetainingManager);
if (oldData) {
oldData->mUsed = true;
}
}
nsIntPoint
@ -2679,11 +2614,12 @@ ChooseScaleAndSetTransform(FrameLayerBuilder* aLayerBuilder,
}
/* static */ PLDHashOperator
FrameLayerBuilder::RestoreDisplayItemData(DisplayItemHashData* aEntry, void* aUserArg)
FrameLayerBuilder::RestoreDisplayItemData(nsRefPtrHashKey<DisplayItemData>* aEntry, void* aUserArg)
{
DisplayItemData* data = aEntry->GetKey();
uint32_t *generation = static_cast<uint32_t*>(aUserArg);
if (aEntry->mContainerLayerGeneration >= *generation) {
if (data->mUsed && data->mContainerLayerGeneration >= *generation) {
return PL_DHASH_REMOVE;
}
@ -2696,6 +2632,9 @@ FrameLayerBuilder::RestoreThebesLayerItemEntries(ThebesLayerItemsEntry* aEntry,
uint32_t *generation = static_cast<uint32_t*>(aUserArg);
if (aEntry->mContainerLayerGeneration >= *generation) {
// We can just remove these items rather than attempting to revert them
// because we're going to want to invalidate everything when transitioning
// to component alpha flattening.
return PL_DHASH_REMOVE;
}
@ -2725,10 +2664,6 @@ FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder,
aContainerItem->GetUnderlyingFrame() == aContainerFrame,
"Container display item must match given frame");
LayerManagerData* data = static_cast<LayerManagerData*>
(aManager->GetUserData(&gLayerManagerUserData));
nsRefPtr<ContainerLayer> containerLayer;
if (aManager == mRetainingManager) {
// Using GetOldLayerFor will search merged frames, as well as the underlying
@ -2788,32 +2723,15 @@ FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder,
nsRefPtr<RefCountedRegion> thebesLayerInvalidRegion = nullptr;
if (mRetainingManager) {
nsRefPtr<DisplayItemData> did =
new DisplayItemData(data, aContainerFrame, containerDisplayItemKey, containerLayer,
LAYER_ACTIVE, mContainerLayerGeneration);
DisplayItemKey key(aContainerFrame, containerDisplayItemKey);
DisplayItemHashData* entry = mNewDisplayItemData.PutEntry(key);
if (entry) {
entry->mData = did;
entry->mContainerLayerGeneration = mContainerLayerGeneration;
}
nsAutoTArray<nsIFrame*,4> mergedFrames;
if (aContainerItem) {
aContainerItem->GetMergedFrames(&mergedFrames);
}
for (uint32_t i = 0; i < mergedFrames.Length(); ++i) {
nsIFrame* mergedFrame = mergedFrames[i];
DisplayItemKey key(mergedFrame, containerDisplayItemKey);
DisplayItemHashData* mergedEntry = mNewDisplayItemData.PutEntry(key);
if (mergedEntry) {
mergedEntry->mData = did;
mergedEntry->mContainerLayerGeneration = mContainerLayerGeneration;
did->AddFrame(mergedFrame);
}
StoreDataForFrame(aContainerItem, containerLayer, LAYER_ACTIVE);
} else {
StoreDataForFrame(aContainerFrame, containerDisplayItemKey, containerLayer, LAYER_ACTIVE);
}
}
LayerManagerData* data = static_cast<LayerManagerData*>
(aManager->GetUserData(&gLayerManagerUserData));
nsRect bounds;
nsIntRect pixBounds;
@ -2847,7 +2765,7 @@ FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder,
// We restore the previous FrameLayerBuilder state since the first set
// of layer building will have changed it.
stateFlags = ContainerState::NO_COMPONENT_ALPHA;
mNewDisplayItemData.EnumerateEntries(RestoreDisplayItemData,
data->mDisplayItems.EnumerateEntries(RestoreDisplayItemData,
&mContainerLayerGeneration);
mThebesLayerItems.EnumerateEntries(RestoreThebesLayerItemEntries,
&mContainerLayerGeneration);
@ -2932,12 +2850,16 @@ FrameLayerBuilder::GetDedicatedLayer(nsIFrame* aFrame, uint32_t aDisplayItemKey)
reinterpret_cast<nsTArray<DisplayItemData*>*>(aFrame->Properties().Get(LayerManagerDataProperty()));
if (array) {
for (uint32_t i = 0; i < array->Length(); i++) {
if (array->ElementAt(i)->mDisplayItemKey == aDisplayItemKey) {
if (array->ElementAt(i)->mOptLayer) {
return array->ElementAt(i)->mOptLayer;
DisplayItemData *element = array->ElementAt(i);
if (!element->mParent->mLayerManager->IsWidgetLayerManager()) {
continue;
}
if (element->mDisplayItemKey == aDisplayItemKey) {
if (element->mOptLayer) {
return element->mOptLayer;
}
Layer* layer = array->ElementAt(i)->mLayer;
Layer* layer = element->mLayer;
if (!layer->HasUserData(&gColorLayerUserData) &&
!layer->HasUserData(&gImageLayerUserData) &&
!layer->HasUserData(&gThebesDisplayItemLayerUserData)) {

View File

@ -105,7 +105,6 @@ public:
mMaxContainerLayerGeneration(0)
{
MOZ_COUNT_CTOR(FrameLayerBuilder);
mNewDisplayItemData.Init();
mThebesLayerItems.Init();
}
~FrameLayerBuilder()
@ -362,7 +361,7 @@ public:
* Used when we optimize a ThebesLayer into an ImageLayer and want to retroactively update the
* DisplayItemData so we can retrieve the layer from within layout.
*/
void StoreOptimizedLayerForFrame(nsIFrame* aFrame, uint32_t aDisplayItemKey, Layer* aImage);
void StoreOptimizedLayerForFrame(nsDisplayItem* aItem, Layer* aLayer);
/**
* Clip represents the intersection of an optional rectangle with a
@ -467,68 +466,45 @@ protected:
* 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.
* created for that frame. DisplayItemData objects manage these lists automatically.
*
* 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.
* During layer construction we update the data in the LayerManagerData object, marking
* items that are modified. At the end we sweep the LayerManagerData hash-set and remove
* all items that haven't been modified.
*/
/**
* 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 {
public:
DisplayItemData(LayerManagerData* aParent, nsIFrame* aFrame, uint32_t aKey, Layer* aLayer, LayerState aLayerState, uint32_t aGeneration);
DisplayItemData(LayerManagerData* aParent, uint32_t aKey, Layer* aLayer, LayerState aLayerState, uint32_t aGeneration);
DisplayItemData(DisplayItemData &toCopy);
/**
* Removes any references to this object from frames
* in mFrameList.
*/
~DisplayItemData();
NS_INLINE_DECL_REFCOUNTING(DisplayItemData)
void AddFrame(nsIFrame* aFrame)
{
mFrameList.AppendElement(aFrame);
}
/**
* Check for this item stored under the LayerManagerDataProperty
* for every frame in mFrameList and remove it.
* Optionally skips aSkip
/**
* Associates this DisplayItemData with a frame, and adds it
* to the LayerManagerDataProperty list on the frame.
*/
void RemoveFrameData(nsIFrame* aSkip = nullptr);
void AddFrame(nsIFrame* aFrame);
bool FrameListMatches(nsDisplayItem* aOther);
bool FrameListMatches(DisplayItemData* aOther);
/**
* Copies the contents of this item into aDest and
* leaves this item invalid.
* Updates the contents of this item to a new set of data, instead of allocating a new
* object.
* Set the passed in parameters, and clears the opt layer, inactive manager, geometry
* and clip.
* Parent, frame list and display item key are assumed to be the same.
*/
void CopyInto(DisplayItemData* aDest);
void UpdateContents(Layer* aLayer, LayerState aState, uint32_t aContainerLayerGeneration);
LayerManagerData* mParent;
nsRefPtr<Layer> mLayer;
@ -543,53 +519,9 @@ protected:
/**
* Used to track if data currently stored in mFramesWithLayers (from an existing
* paint) is also used in the current paint and has an equivalent data object
* in mNewDisplayItemData.
* paint) has been updated in the current paint.
*/
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;
@ -609,7 +541,11 @@ protected:
* Stores DisplayItemData associated with aFrame, stores the data in
* mNewDisplayItemData.
*/
void StoreDataForFrame(nsDisplayItem* aItem, DisplayItemData* data);
DisplayItemData* StoreDataForFrame(nsDisplayItem* aItem, Layer* aLayer, LayerState aState);
void StoreDataForFrame(nsIFrame* aFrame,
uint32_t aDisplayItemKey,
Layer* aLayer,
LayerState aState);
// Flash the area within the context clip if paint flashing is enabled.
static void FlashPaint(gfxContext *aContext);
@ -637,14 +573,6 @@ protected:
uint32_t aDisplayItemKey,
LayerManagerData* aData);
/**
* A useful hashtable iteration function that removes the
* DisplayItemData property for the frame and returns PL_DHASH_REMOVE.
* aClosure is ignored.
*/
static PLDHashOperator RemoveDisplayItemDataForFrame(nsRefPtrHashKey<DisplayItemData>* aEntry,
void* aClosure);
static PLDHashOperator DumpDisplayItemDataForFrame(nsRefPtrHashKey<DisplayItemData>* aEntry,
void* aClosure);
/**
@ -729,9 +657,7 @@ protected:
static PLDHashOperator UpdateDisplayItemDataForFrame(nsRefPtrHashKey<DisplayItemData>* aEntry,
void* aUserArg);
static PLDHashOperator StoreNewDisplayItemData(DisplayItemHashData* aEntry,
void* aUserArg);
static PLDHashOperator RestoreDisplayItemData(DisplayItemHashData* aEntry,
static PLDHashOperator RestoreDisplayItemData(nsRefPtrHashKey<DisplayItemData>* aEntry,
void *aUserArg);
static PLDHashOperator RestoreThebesLayerItemEntries(ThebesLayerItemsEntry* aEntry,
@ -758,11 +684,6 @@ protected:
* The display list builder being used.
*/
nsDisplayListBuilder* mDisplayListBuilder;
/**
* 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.
*/
nsTHashtable<DisplayItemHashData> mNewDisplayItemData;
/**
* A map from ThebesLayers to the list of display items (plus
* clipping data) to be rendered in the layer.