зеркало из https://github.com/mozilla/gecko-dev.git
Bug 798964 - Don't invalidate nsDisplayBackgroundColor if only the image changed. r=roc
This commit is contained in:
Родитель
fe45b184c8
Коммит
ced424bb37
|
@ -48,6 +48,7 @@ FrameLayerBuilder::DisplayItemData::DisplayItemData(LayerManagerData* aParent, u
|
|||
, mContainerLayerGeneration(aGeneration)
|
||||
, mLayerState(aLayerState)
|
||||
, mUsed(true)
|
||||
, mIsInvalid(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -1020,6 +1021,7 @@ FrameLayerBuilder::UpdateDisplayItemDataForFrame(nsRefPtrHashKey<DisplayItemData
|
|||
}
|
||||
|
||||
data->mUsed = false;
|
||||
data->mIsInvalid = false;
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
|
@ -1112,6 +1114,20 @@ FrameLayerBuilder::HasRetainedDataFor(nsIFrame* aFrame, uint32_t aDisplayItemKey
|
|||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
FrameLayerBuilder::IterateRetainedDataFor(nsIFrame* aFrame, DisplayItemDataCallback aCallback)
|
||||
{
|
||||
nsTArray<DisplayItemData*> *array =
|
||||
reinterpret_cast<nsTArray<DisplayItemData*>*>(aFrame->Properties().Get(LayerManagerDataProperty()));
|
||||
if (!array) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < array->Length(); i++) {
|
||||
aCallback(aFrame, array->ElementAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
FrameLayerBuilder::DisplayItemData*
|
||||
FrameLayerBuilder::GetOldLayerForFrame(nsIFrame* aFrame, uint32_t aDisplayItemKey)
|
||||
{
|
||||
|
@ -1132,7 +1148,8 @@ Layer*
|
|||
FrameLayerBuilder::GetOldLayerFor(nsDisplayItem* aItem,
|
||||
nsDisplayItemGeometry** aOldGeometry,
|
||||
Clip** aOldClip,
|
||||
nsTArray<nsIFrame*>* aChangedFrames)
|
||||
nsTArray<nsIFrame*>* aChangedFrames,
|
||||
bool *aIsInvalid)
|
||||
{
|
||||
uint32_t key = aItem->GetPerFrameKey();
|
||||
nsIFrame* frame = aItem->GetUnderlyingFrame();
|
||||
|
@ -1149,6 +1166,9 @@ FrameLayerBuilder::GetOldLayerFor(nsDisplayItem* aItem,
|
|||
if (aChangedFrames) {
|
||||
oldData->GetFrameListChanges(aItem, *aChangedFrames);
|
||||
}
|
||||
if (aIsInvalid) {
|
||||
*aIsInvalid = oldData->mIsInvalid;
|
||||
}
|
||||
return oldData->mLayer;
|
||||
}
|
||||
}
|
||||
|
@ -2196,7 +2216,8 @@ ContainerState::InvalidateForLayerChange(nsDisplayItem* aItem,
|
|||
nsDisplayItemGeometry *oldGeometry = NULL;
|
||||
FrameLayerBuilder::Clip* oldClip = NULL;
|
||||
nsAutoTArray<nsIFrame*,4> changedFrames;
|
||||
Layer* oldLayer = mLayerBuilder->GetOldLayerFor(aItem, &oldGeometry, &oldClip, &changedFrames);
|
||||
bool isInvalid = false;
|
||||
Layer* oldLayer = mLayerBuilder->GetOldLayerFor(aItem, &oldGeometry, &oldClip, &changedFrames, &isInvalid);
|
||||
if (aNewLayer != oldLayer && oldLayer) {
|
||||
// The item has changed layers.
|
||||
// Invalidate the old bounds in the old layer and new bounds in the new layer.
|
||||
|
@ -2248,7 +2269,7 @@ ContainerState::InvalidateForLayerChange(nsDisplayItem* aItem,
|
|||
#ifdef DEBUG_INVALIDATIONS
|
||||
printf("Display item type %s(%p) added to layer %p!\n", aItem->Name(), aItem->GetUnderlyingFrame(), aNewLayer);
|
||||
#endif
|
||||
} else if (aItem->IsInvalid(invalid) && invalid.IsEmpty()) {
|
||||
} else if (isInvalid || (aItem->IsInvalid(invalid) && invalid.IsEmpty())) {
|
||||
// Either layout marked item as needing repainting, invalidate the entire old and new areas.
|
||||
combined = oldClip->ApplyNonRoundedIntersection(oldGeometry->ComputeInvalidationRegion());
|
||||
combined.MoveBy(shift);
|
||||
|
|
|
@ -300,7 +300,8 @@ public:
|
|||
Layer* GetOldLayerFor(nsDisplayItem* aItem,
|
||||
nsDisplayItemGeometry** aOldGeometry = nullptr,
|
||||
Clip** aOldClip = nullptr,
|
||||
nsTArray<nsIFrame*>* aChangedFrames = nullptr);
|
||||
nsTArray<nsIFrame*>* aChangedFrames = nullptr,
|
||||
bool *aIsInvalid = nullptr);
|
||||
|
||||
static Layer* GetDebugOldLayerFor(nsIFrame* aFrame, uint32_t aDisplayItemKey);
|
||||
|
||||
|
@ -336,6 +337,11 @@ public:
|
|||
*/
|
||||
static bool HasRetainedDataFor(nsIFrame* aFrame, uint32_t aDisplayItemKey);
|
||||
|
||||
class DisplayItemData;
|
||||
typedef void (*DisplayItemDataCallback)(nsIFrame *aFrame, DisplayItemData* aItem);
|
||||
|
||||
static void IterateRetainedDataFor(nsIFrame* aFrame, DisplayItemDataCallback aCallback);
|
||||
|
||||
/**
|
||||
* Save transform that was in aLayer when we last painted, and the position
|
||||
* of the active scrolled root frame. It must be an integer
|
||||
|
@ -466,7 +472,6 @@ public:
|
|||
NS_DECLARE_FRAME_PROPERTY_WITH_FRAME_IN_DTOR(LayerManagerDataProperty,
|
||||
RemoveFrameFromLayerManager)
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Retained data storage:
|
||||
*
|
||||
|
@ -485,6 +490,12 @@ protected:
|
|||
*/
|
||||
class DisplayItemData {
|
||||
public:
|
||||
friend class FrameLayerBuilder;
|
||||
|
||||
uint32_t GetDisplayItemKey() { return mDisplayItemKey; }
|
||||
Layer* GetLayer() { return mLayer; }
|
||||
void Invalidate() { mIsInvalid = true; }
|
||||
protected:
|
||||
|
||||
DisplayItemData(LayerManagerData* aParent, uint32_t aKey, Layer* aLayer, LayerState aLayerState, uint32_t aGeneration);
|
||||
DisplayItemData(DisplayItemData &toCopy);
|
||||
|
@ -497,6 +508,7 @@ protected:
|
|||
|
||||
NS_INLINE_DECL_REFCOUNTING(DisplayItemData)
|
||||
|
||||
|
||||
/**
|
||||
* Associates this DisplayItemData with a frame, and adds it
|
||||
* to the LayerManagerDataProperty list on the frame.
|
||||
|
@ -531,8 +543,11 @@ protected:
|
|||
* paint) has been updated in the current paint.
|
||||
*/
|
||||
bool mUsed;
|
||||
bool mIsInvalid;
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
friend class LayerManagerData;
|
||||
|
||||
static void RemoveFrameFromLayerManager(nsIFrame* aFrame, void* aPropertyValue);
|
||||
|
|
|
@ -18,8 +18,10 @@ enum Type {
|
|||
TYPE_ZERO = 0, /** Spacer so that the first item starts at 1 */
|
||||
|
||||
#define DECLARE_DISPLAY_ITEM_TYPE(name) TYPE_##name,
|
||||
#define DECLARE_DISPLAY_ITEM_TYPE_FLAGS(name,flags) TYPE_##name,
|
||||
#include "nsDisplayItemTypesList.h"
|
||||
#undef DECLARE_DISPLAY_ITEM_TYPE
|
||||
#undef DECLARE_DISPLAY_ITEM_TYPE_FLAGS
|
||||
|
||||
TYPE_MAX
|
||||
};
|
||||
|
@ -29,13 +31,41 @@ enum {
|
|||
TYPE_BITS = 8
|
||||
};
|
||||
|
||||
enum DisplayItemFlags {
|
||||
TYPE_RENDERS_NO_IMAGES = 1 << 0
|
||||
};
|
||||
|
||||
static const char* DisplayItemTypeName(Type aType)
|
||||
{
|
||||
switch (aType) {
|
||||
#define DECLARE_DISPLAY_ITEM_TYPE(name) case TYPE_##name: return #name;
|
||||
#define DECLARE_DISPLAY_ITEM_TYPE_FLAGS(name,flags) case TYPE_##name: return #name;
|
||||
#include "nsDisplayItemTypesList.h"
|
||||
#undef DECLARE_DISPLAY_ITEM_TYPE
|
||||
#undef DECLARE_DISPLAY_ITEM_TYPE_FLAGS
|
||||
|
||||
default: return "TYPE_UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t GetDisplayItemFlagsForType(Type aType)
|
||||
{
|
||||
static const uint8_t flags[TYPE_MAX] = {
|
||||
0
|
||||
#define DECLARE_DISPLAY_ITEM_TYPE(name) ,0
|
||||
#define DECLARE_DISPLAY_ITEM_TYPE_FLAGS(name,flags) ,flags
|
||||
#include "nsDisplayItemTypesList.h"
|
||||
#undef DECLARE_DISPLAY_ITEM_TYPE
|
||||
#undef DECLARE_DISPLAY_ITEM_TYPE_FLAGS
|
||||
};
|
||||
|
||||
return flags[aType];
|
||||
}
|
||||
|
||||
static Type GetDisplayItemTypeFromKey(uint32_t aDisplayItemKey)
|
||||
{
|
||||
static const uint32_t typeMask = (1 << TYPE_BITS) - 1;
|
||||
Type type = static_cast<Type>(aDisplayItemKey & typeMask);
|
||||
NS_ASSERTION(type > TYPE_ZERO && type < TYPE_MAX, "Invalid display item type!");
|
||||
return type;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
DECLARE_DISPLAY_ITEM_TYPE(ALT_FEEDBACK)
|
||||
DECLARE_DISPLAY_ITEM_TYPE(BACKGROUND)
|
||||
DECLARE_DISPLAY_ITEM_TYPE(BACKGROUND_COLOR)
|
||||
DECLARE_DISPLAY_ITEM_TYPE_FLAGS(BACKGROUND_COLOR,TYPE_RENDERS_NO_IMAGES)
|
||||
DECLARE_DISPLAY_ITEM_TYPE(BORDER)
|
||||
DECLARE_DISPLAY_ITEM_TYPE(BOX_SHADOW_OUTER)
|
||||
DECLARE_DISPLAY_ITEM_TYPE(BOX_SHADOW_INNER)
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#include "nsContentUtils.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsError.h"
|
||||
#include "nsDisplayList.h"
|
||||
#include "FrameLayerBuilder.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace css {
|
||||
|
@ -314,6 +316,20 @@ ImageLoader::GetPresContext()
|
|||
return shell->GetPresContext();
|
||||
}
|
||||
|
||||
void InvalidateImagesCallback(nsIFrame* aFrame,
|
||||
FrameLayerBuilder::DisplayItemData* aItem)
|
||||
{
|
||||
nsDisplayItem::Type type = nsDisplayItem::GetDisplayItemTypeFromKey(aItem->GetDisplayItemKey());
|
||||
uint8_t flags = nsDisplayItem::GetDisplayItemFlagsForType(type);
|
||||
|
||||
if (flags & nsDisplayItem::TYPE_RENDERS_NO_IMAGES) {
|
||||
return;
|
||||
}
|
||||
|
||||
aItem->Invalidate();
|
||||
aFrame->SchedulePaint();
|
||||
}
|
||||
|
||||
void
|
||||
ImageLoader::DoRedraw(FrameSet* aFrameSet)
|
||||
{
|
||||
|
@ -325,7 +341,7 @@ ImageLoader::DoRedraw(FrameSet* aFrameSet)
|
|||
nsIFrame* frame = aFrameSet->ElementAt(i);
|
||||
|
||||
if (frame->GetStyleVisibility()->IsVisible()) {
|
||||
frame->InvalidateFrame();
|
||||
FrameLayerBuilder::IterateRetainedDataFor(frame, InvalidateImagesCallback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче