Backout changeset 0c75abcb72ff (bug 539356) because of performance and correctness regressions

This commit is contained in:
Ehsan Akhgari 2012-07-03 20:17:01 -04:00
parent 675fd1091f
commit 388ec767e6
3 changed files with 69 additions and 175 deletions

View File

@ -45,11 +45,11 @@ public:
mFramesWithLayers.Init();
}
~LayerManagerData() {
MOZ_COUNT_DTOR(LayerManagerData);
// Remove display item data properties now, since we won't be able
// to find these frames again without mFramesWithLayers.
mFramesWithLayers.EnumerateEntries(
FrameLayerBuilder::RemoveDisplayItemDataForFrame, this);
MOZ_COUNT_DTOR(LayerManagerData);
}
/**
@ -59,14 +59,6 @@ public:
bool mInvalidateAllLayers;
};
/* static */ void
FrameLayerBuilder::DestroyDisplayItemDataFor(nsIFrame* aFrame)
{
FrameProperties props = aFrame->Properties();
props.Delete(LayerManagerDataProperty());
props.Delete(LayerManagerSecondaryDataProperty());
}
namespace {
// a global cache of image containers used for mask layers
@ -527,61 +519,6 @@ ThebesDisplayItemLayerUserData* GetThebesDisplayItemLayerUserData(Layer* aLayer)
} // anonymous namespace
PRUint8 gLayerManagerLayerBuilder;
PRUint8 gLayerManagerSecondary;
bool FrameLayerBuilder::sWidgetManagerSecondary = nsnull;
/* static */ const FramePropertyDescriptor*
FrameLayerBuilder::GetDescriptorForManager(LayerManager* aManager)
{
bool secondary = sWidgetManagerSecondary;
if (aManager) {
secondary = !!static_cast<LayerManagerSecondary*>(aManager->GetUserData(&gLayerManagerSecondary));
}
return secondary ? LayerManagerSecondaryDataProperty() : LayerManagerDataProperty();
}
LayerManagerData*
FrameLayerBuilder::GetManagerData(nsIFrame* aFrame, LayerManager* aManager)
{
FrameProperties props = aFrame->Properties();
return static_cast<LayerManagerData*>(props.Get(GetDescriptorForManager(aManager)));
}
void
FrameLayerBuilder::SetManagerData(nsIFrame* aFrame, LayerManagerData* aData)
{
FrameProperties props = aFrame->Properties();
const FramePropertyDescriptor* desc = GetDescriptorForManager(nsnull);
props.Remove(desc);
if (aData) {
props.Set(desc, aData);
}
}
void
FrameLayerBuilder::ClearManagerData(nsIFrame* aFrame)
{
SetManagerData(aFrame, nsnull);
}
void
FrameLayerBuilder::ClearManagerData(nsIFrame* aFrame, LayerManagerData* aData)
{
NS_ABORT_IF_FALSE(aData, "Must have a widget manager to check for manager data!");
FrameProperties props = aFrame->Properties();
if (aData == static_cast<LayerManagerData*>(props.Get(LayerManagerDataProperty()))) {
props.Remove(LayerManagerDataProperty());
return;
}
if (aData == static_cast<LayerManagerData*>(props.Get(LayerManagerSecondaryDataProperty()))) {
props.Remove(LayerManagerSecondaryDataProperty());
return;
}
}
/* static */ void
FrameLayerBuilder::Shutdown()
@ -748,9 +685,6 @@ FrameLayerBuilder::DidBeginRetainedLayerTransaction(LayerManager* aManager)
(aManager->GetUserData(&gLayerManagerUserData));
if (data) {
mInvalidateAllLayers = data->mInvalidateAllLayers;
} else {
data = new LayerManagerData();
aManager->SetUserData(&gLayerManagerUserData, data);
}
}
@ -789,10 +723,13 @@ FrameLayerBuilder::WillEndTransaction()
// We need to save the data we'll need to support retaining.
LayerManagerData* data = static_cast<LayerManagerData*>
(mRetainingManager->GetUserData(&gLayerManagerUserData));
NS_ASSERTION(data, "Must have data!");
// Update all the frames that used to have layers.
data->mFramesWithLayers.EnumerateEntries(UpdateDisplayItemDataForFrame, this);
if (data) {
// Update all the frames that used to have layers.
data->mFramesWithLayers.EnumerateEntries(UpdateDisplayItemDataForFrame, this);
} else {
data = new LayerManagerData();
mRetainingManager->SetUserData(&gLayerManagerUserData, data);
}
// 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.
@ -830,23 +767,27 @@ FrameLayerBuilder::UpdateDisplayItemDataForFrame(DisplayItemDataEntry* aEntry,
{
FrameLayerBuilder* builder = static_cast<FrameLayerBuilder*>(aUserArg);
nsIFrame* f = aEntry->GetKey();
FrameProperties props = f->Properties();
DisplayItemDataEntry* newDisplayItems =
builder ? builder->mNewDisplayItemData.GetEntry(f) : nsnull;
LayerManagerData* managerData = static_cast<LayerManagerData*>
(builder->GetRetainingLayerManager()->GetUserData(&gLayerManagerUserData));
LayerManagerData* data = GetManagerData(f);
LayerManagerData* data = static_cast<LayerManagerData*>(props.Get(LayerManagerDataProperty()));
if (!newDisplayItems || newDisplayItems->mData.IsEmpty()) {
// This frame was visible, but isn't anymore.
if (newDisplayItems) {
builder->mNewDisplayItemData.RawRemoveEntry(newDisplayItems);
}
if (data == managerData) {
ClearManagerData(f);
props.Remove(LayerManagerDataProperty());
}
return PL_DHASH_REMOVE;
}
SetManagerData(f, managerData);
if (data) {
props.Remove(LayerManagerDataProperty());
}
props.Set(LayerManagerDataProperty(), managerData);
// Steal the list of display item layers
aEntry->mData.SwapElements(newDisplayItems->mData);
@ -864,7 +805,12 @@ FrameLayerBuilder::RemoveDisplayItemDataForFrame(DisplayItemDataEntry* aEntry,
// 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.
if (f != sDestroyedFrame) {
ClearManagerData(f, managerData);
FrameProperties props = f->Properties();
bool found;
LayerManagerData* data = static_cast<LayerManagerData*>(props.Get(LayerManagerDataProperty()));
if (data == managerData) {
props.Remove(LayerManagerDataProperty(), &found);
}
}
return PL_DHASH_REMOVE;
}
@ -875,6 +821,7 @@ FrameLayerBuilder::StoreNewDisplayItemData(DisplayItemDataEntry* aEntry,
{
LayerManagerData* data = static_cast<LayerManagerData*>(aUserArg);
nsIFrame* f = aEntry->GetKey();
FrameProperties props = f->Properties();
// Remember that this frame has display items in retained layers
NS_ASSERTION(!data->mFramesWithLayers.GetEntry(f),
"We shouldn't get here if we're already in mFramesWithLayers");
@ -886,36 +833,21 @@ FrameLayerBuilder::StoreNewDisplayItemData(DisplayItemDataEntry* aEntry,
// When a frame has multiple layer managers (main, inactive, svg), we
// only need to store the outermost one since that will be enough to
// invalidate the entire region covered by all the children.
SetManagerData(f, data);
props.Remove(LayerManagerDataProperty());
props.Set(LayerManagerDataProperty(), data);
return PL_DHASH_REMOVE;
}
/**
* Attempts to find the LayerManagerData for the widget manager
* for the given frame, nsnull otherwise.
*/
static LayerManagerData*
GetDefaultLayerManagerDataForFrame(nsIFrame* aFrame)
{
FrameProperties props = aFrame->Properties();
return static_cast<LayerManagerData*>(props.Get(FrameLayerBuilder::LayerManagerDataProperty()));
}
/* static */ FrameLayerBuilder::DisplayItemData*
FrameLayerBuilder::GetDisplayItemDataForManager(nsIFrame* aFrame, PRUint32 aDisplayItemKey, LayerManager* aManager)
{
LayerManagerData *data;
if (!aManager) {
data = GetDefaultLayerManagerDataForFrame(aFrame);
} else {
data = static_cast<LayerManagerData*>(aManager->GetUserData(&gLayerManagerUserData));
}
if (!data) {
LayerManagerData* managerData = static_cast<LayerManagerData*>
(aManager->GetUserData(&gLayerManagerUserData));
if (!managerData) {
return nsnull;
}
DisplayItemDataEntry *entry = data->mFramesWithLayers.GetEntry(aFrame);
DisplayItemDataEntry *entry = managerData->mFramesWithLayers.GetEntry(aFrame);
if (!entry) {
return nsnull;
}
@ -978,7 +910,8 @@ FrameLayerBuilder::GetOldLayerFor(nsIFrame* aFrame, PRUint32 aDisplayItemKey, ns
/* static */ Layer*
FrameLayerBuilder::GetDebugOldLayerFor(nsIFrame* aFrame, PRUint32 aDisplayItemKey)
{
LayerManagerData* data = GetManagerData(aFrame);
FrameProperties props = aFrame->Properties();
LayerManagerData* data = static_cast<LayerManagerData*>(props.Get(LayerManagerDataProperty()));
if (!data) {
return nsnull;
}
@ -2620,20 +2553,24 @@ FrameLayerBuilder::InvalidateAllLayers(LayerManager* aManager)
Layer*
FrameLayerBuilder::GetDedicatedLayer(nsIFrame* aFrame, PRUint32 aDisplayItemKey)
{
//TODO: This isn't completely correct, since a frame could exist as a layer
// in the normal widget manager, and as a different layer (or no layer)
// in the secondary manager
DisplayItemData *data = GetDisplayItemDataForManager(aFrame, aDisplayItemKey, nsnull);
FrameProperties props = aFrame->Properties();
LayerManagerData* data = static_cast<LayerManagerData*>(props.Get(LayerManagerDataProperty()));
if (!data) {
return nsnull;
}
Layer* layer = data->mLayer;
if (!layer->HasUserData(&gColorLayerUserData) &&
!layer->HasUserData(&gImageLayerUserData) &&
!layer->HasUserData(&gThebesDisplayItemLayerUserData)) {
return layer;
DisplayItemDataEntry *entry = data->mFramesWithLayers.GetEntry(aFrame);
if (!entry) {
return nsnull;
}
for (PRUint32 i = 0; i < entry->mData.Length(); ++i) {
if (entry->mData.ElementAt(i).mDisplayItemKey == aDisplayItemKey) {
Layer* layer = entry->mData.ElementAt(i).mLayer;
if (!layer->HasUserData(&gColorLayerUserData) &&
!layer->HasUserData(&gImageLayerUserData) &&
!layer->HasUserData(&gThebesDisplayItemLayerUserData))
return layer;
}
}
return nsnull;
}
@ -2643,12 +2580,23 @@ FrameLayerBuilder::GetThebesLayerResolutionForFrame(nsIFrame* aFrame,
double* aXres, double* aYres,
gfxPoint* aPoint)
{
LayerManagerData *data = GetDefaultLayerManagerDataForFrame(aFrame);
if (!data) {
nsRefPtr<LayerManager> layerManager;
nsIFrame* referenceFrame = nsLayoutUtils::GetDisplayRootFrame(aFrame);
nsIWidget* window = referenceFrame->GetNearestWidget();
if (window) {
layerManager = window->GetLayerManager();
}
if (!layerManager) {
return false;
}
LayerManagerData* managerData = static_cast<LayerManagerData*>
(layerManager->GetUserData(&gLayerManagerUserData));
if (!managerData) {
return false;
}
DisplayItemDataEntry *entry = data->mFramesWithLayers.GetEntry(aFrame);
DisplayItemDataEntry *entry = managerData->mFramesWithLayers.GetEntry(aFrame);
if (!entry)
return false;

View File

@ -40,10 +40,6 @@ enum LayerState {
};
extern PRUint8 gLayerManagerLayerBuilder;
extern PRUint8 gLayerManagerSecondary;
class LayerManagerSecondary : public layers::LayerUserData {
};
/**
* The FrameLayerBuilder belongs to an nsDisplayListBuilder and is
@ -267,47 +263,6 @@ public:
nsIFrame* aContainerLayerFrame,
LayerState aLayerState);
/**
* 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
* widget layer manager if nsnull is passed.
*/
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 = nsnull);
/**
* 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);
/**
* Given a frame and a display item key that uniquely identifies a
* display item for the frame, find the layer that was last used to
@ -338,7 +293,10 @@ public:
* Destroy any stored LayerManagerDataProperty and the associated data for
* aFrame.
*/
static void DestroyDisplayItemDataFor(nsIFrame* aFrame);
static void DestroyDisplayItemDataFor(nsIFrame* aFrame)
{
aFrame->Properties().Delete(LayerManagerDataProperty());
}
LayerManager* GetRetainingLayerManager() { return mRetainingManager; }
@ -467,12 +425,6 @@ public:
return !(*this == aOther);
}
};
NS_DECLARE_FRAME_PROPERTY_WITH_FRAME_IN_DTOR(LayerManagerDataProperty,
RemoveFrameFromLayerManager)
NS_DECLARE_FRAME_PROPERTY_WITH_FRAME_IN_DTOR(LayerManagerSecondaryDataProperty,
RemoveFrameFromLayerManager)
protected:
/**
@ -520,12 +472,12 @@ protected:
*/
bool mUsed;
};
// LayerManagerData needs to see DisplayItemDataEntry.
friend class LayerManagerData;
static void RemoveFrameFromLayerManager(nsIFrame* aFrame, void* aPropertyValue);
NS_DECLARE_FRAME_PROPERTY_WITH_FRAME_IN_DTOR(LayerManagerDataProperty,
RemoveFrameFromLayerManager)
/**
* We accumulate DisplayItemData elements in a hashtable during
* the paint process, and store them in the frame property only when
@ -553,6 +505,9 @@ protected:
enum { ALLOW_MEMMOVE = false };
};
// LayerManagerData needs to see DisplayItemDataEntry.
friend class LayerManagerData;
/**
* Stores DisplayItemData associated with aFrame, stores the data in
* mNewDisplayItemData.
@ -726,12 +681,6 @@ protected:
PRUint32 mContainerLayerGeneration;
PRUint32 mMaxContainerLayerGeneration;
/**
* True if the current top-level LayerManager for the widget being
* painted is marked as being a 'secondary' LayerManager.
*/
static bool sWidgetManagerSecondary;
};
static inline FrameLayerBuilder *GetLayerBuilderForManager(layers::LayerManager* aManager)

View File

@ -564,7 +564,6 @@ void nsDisplayList::PaintForFrame(nsDisplayListBuilder* aBuilder,
"Must call ComputeVisibility before calling Paint");
nsRefPtr<LayerManager> layerManager;
bool widgetTransaction = false;
bool allowRetaining = false;
bool doBeginTransaction = true;
nsIView *view = nsnull;
@ -578,8 +577,6 @@ void nsDisplayList::PaintForFrame(nsDisplayListBuilder* aBuilder,
layerManager = window->GetLayerManager(&allowRetaining);
if (layerManager) {
doBeginTransaction = !(aFlags & PAINT_EXISTING_TRANSACTION);
FrameLayerBuilder::SetWidgetLayerManager(layerManager);
widgetTransaction = true;
}
}
}