mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 795674 - Remove mNewDisplayItemData. r=roc
This commit is contained in:
parent
fad4d60944
commit
8760ddc9ae
@ -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)) {
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user