mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-14 13:55:43 +00:00
Bug 539356 - Add an option for frames to invalid just a rect instead of the frame bounds. r=roc
This commit is contained in:
parent
68d1759f83
commit
daef8103fd
@ -2114,7 +2114,8 @@ ContainerState::ProcessDisplayItems(const nsDisplayList& aList,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (item->IsInvalid()) {
|
||||
nsRect invalid;
|
||||
if (item->IsInvalid(invalid)) {
|
||||
ownLayer->SetInvalidRectToVisibleRegion();
|
||||
}
|
||||
|
||||
@ -2252,8 +2253,10 @@ ContainerState::InvalidateForLayerChange(nsDisplayItem* aItem,
|
||||
|
||||
ThebesDisplayItemLayerUserData* data =
|
||||
static_cast<ThebesDisplayItemLayerUserData*>(newThebesLayer->GetUserData(&gThebesDisplayItemLayerUserData));
|
||||
// If the frame is marked as invalidated then we want to invalidate both the old and new bounds,
|
||||
// otherwise we only want to invalidate the changed areas.
|
||||
// If the frame is marked as invalidated, and didn't specify a rect to invalidate then we want to
|
||||
// invalidate both the old and new bounds, otherwise we only want to invalidate the changed areas.
|
||||
// If we do get an invalid rect, then we want to add this on top of the change areas.
|
||||
nsRect invalid;
|
||||
nsRegion combined;
|
||||
if (!oldLayer) {
|
||||
// This item is being added for the first time, invalidate its entire area.
|
||||
@ -2262,7 +2265,7 @@ ContainerState::InvalidateForLayerChange(nsDisplayItem* aItem,
|
||||
#ifdef DEBUG_INVALIDATIONS
|
||||
printf("Display item type %s(%p) added to layer %p!\n", aItem->Name(), f, aNewLayer);
|
||||
#endif
|
||||
} else if (aItem->IsInvalid()) {
|
||||
} else if (aItem->IsInvalid(invalid) && invalid.IsEmpty()) {
|
||||
// Either layout marked item as needing repainting, invalidate the entire old and new areas.
|
||||
combined.Or(geometry->ComputeInvalidationRegion(), oldGeometry->ComputeInvalidationRegion());
|
||||
#ifdef DEBUG_INVALIDATIONS
|
||||
@ -2277,6 +2280,9 @@ ContainerState::InvalidateForLayerChange(nsDisplayItem* aItem,
|
||||
oldClip->AddOffsetAndComputeDifference(shift, oldGeometry->ComputeInvalidationRegion(),
|
||||
aClip, geometry->ComputeInvalidationRegion(),
|
||||
&combined);
|
||||
|
||||
// Add in any rect that the frame specified
|
||||
combined = combined.Or(combined, invalid);
|
||||
#ifdef DEBUG_INVALIDATIONS
|
||||
if (!combined.IsEmpty()) {
|
||||
printf("Display item type %s(%p) (in layer %p) changed geometry!\n", aItem->Name(), f, aNewLayer);
|
||||
|
@ -774,7 +774,11 @@ public:
|
||||
* Checks if the frame(s) owning this display item have been marked as invalid,
|
||||
* and needing repainting.
|
||||
*/
|
||||
virtual bool IsInvalid() { return mFrame ? mFrame->IsInvalid() : false; }
|
||||
virtual bool IsInvalid(nsRect& aRect) {
|
||||
bool result = mFrame ? mFrame->IsInvalid(aRect) : false;
|
||||
aRect += ToReferenceFrame();
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and initializes an nsDisplayItemGeometry object that retains the current
|
||||
@ -2005,17 +2009,21 @@ public:
|
||||
{
|
||||
aFrames->AppendElements(mMergedFrames);
|
||||
}
|
||||
virtual bool IsInvalid()
|
||||
virtual bool IsInvalid(nsRect& aRect)
|
||||
{
|
||||
if (mFrame->IsInvalid()) {
|
||||
if (mFrame->IsInvalid(aRect) && aRect.IsEmpty()) {
|
||||
return true;
|
||||
}
|
||||
nsRect temp;
|
||||
for (uint32_t i = 0; i < mMergedFrames.Length(); i++) {
|
||||
if (mMergedFrames[i]->IsInvalid()) {
|
||||
if (mMergedFrames[i]->IsInvalid(temp) && temp.IsEmpty()) {
|
||||
aRect.SetEmpty();
|
||||
return true;
|
||||
}
|
||||
aRect = aRect.Union(temp);
|
||||
}
|
||||
return false;
|
||||
aRect += ToReferenceFrame();
|
||||
return !aRect.IsEmpty();
|
||||
}
|
||||
NS_DISPLAY_DECL_NAME("WrapList", TYPE_WRAP_LIST)
|
||||
|
||||
|
@ -4806,12 +4806,50 @@ nsIFrame::InvalidateFrame()
|
||||
if (!parent) {
|
||||
SchedulePaint();
|
||||
}
|
||||
if (HasAnyStateBits(NS_FRAME_HAS_INVALID_RECT)) {
|
||||
Properties().Delete(InvalidationRect());
|
||||
RemoveStateBits(NS_FRAME_HAS_INVALID_RECT);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsIFrame::InvalidateFrameWithRect(const nsRect& aRect)
|
||||
{
|
||||
bool alreadyInvalid = false;
|
||||
if (!HasAnyStateBits(NS_FRAME_NEEDS_PAINT)) {
|
||||
InvalidateFrame();
|
||||
} else {
|
||||
alreadyInvalid = true;
|
||||
}
|
||||
|
||||
nsRect *rect = static_cast<nsRect*>(Properties().Get(InvalidationRect()));
|
||||
if (!rect) {
|
||||
if (alreadyInvalid) {
|
||||
return;
|
||||
}
|
||||
rect = new nsRect();
|
||||
Properties().Set(InvalidationRect(), rect);
|
||||
AddStateBits(NS_FRAME_HAS_INVALID_RECT);
|
||||
}
|
||||
|
||||
*rect = rect->Union(aRect);
|
||||
}
|
||||
|
||||
bool
|
||||
nsIFrame::IsInvalid()
|
||||
nsIFrame::IsInvalid(nsRect& aRect)
|
||||
{
|
||||
return HasAnyStateBits(NS_FRAME_NEEDS_PAINT);
|
||||
if (!HasAnyStateBits(NS_FRAME_NEEDS_PAINT)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (HasAnyStateBits(NS_FRAME_HAS_INVALID_RECT)) {
|
||||
nsRect *rect = static_cast<nsRect*>(Properties().Get(InvalidationRect()));
|
||||
NS_ASSERTION(rect, "Must have an invalid rect if NS_FRAME_HAS_INVALID_RECT is set!");
|
||||
aRect = *rect;
|
||||
} else {
|
||||
aRect.SetEmpty();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -319,6 +319,10 @@ typedef uint64_t nsFrameState;
|
||||
// have no display items.
|
||||
#define NS_FRAME_ALL_DESCENDANTS_NEED_PAINT NS_FRAME_STATE_BIT(51)
|
||||
|
||||
// Frame is marked as NS_FRAME_NEEDS_PAINT and also has an explicit
|
||||
// rect stored to invalidate.
|
||||
#define NS_FRAME_HAS_INVALID_RECT NS_FRAME_STATE_BIT(52)
|
||||
|
||||
// Box layout bits
|
||||
#define NS_STATE_IS_HORIZONTAL NS_FRAME_STATE_BIT(22)
|
||||
#define NS_STATE_IS_DIRECTION_NORMAL NS_FRAME_STATE_BIT(31)
|
||||
@ -955,6 +959,8 @@ public:
|
||||
|
||||
NS_DECLARE_FRAME_PROPERTY(CachedBackgroundImage, DestroySurface)
|
||||
|
||||
NS_DECLARE_FRAME_PROPERTY(InvalidationRect, DestroyRect)
|
||||
|
||||
/**
|
||||
* Return the distance between the border edge of the frame and the
|
||||
* margin edge of the frame. Like GetRect(), returns the dimensions
|
||||
@ -2179,6 +2185,15 @@ public:
|
||||
* container types.
|
||||
*/
|
||||
virtual void InvalidateFrame();
|
||||
|
||||
/**
|
||||
* Same as InvalidateFrame(), but only mark a fixed rect as needing
|
||||
* repainting.
|
||||
*
|
||||
* @param aRect The rect to invalidate, relative to the TopLeft of the
|
||||
* frame's border box.
|
||||
*/
|
||||
virtual void InvalidateFrameWithRect(const nsRect& aRect);
|
||||
|
||||
/**
|
||||
* Calls InvalidateFrame() on all frames descendant frames (including
|
||||
@ -2192,8 +2207,13 @@ public:
|
||||
/**
|
||||
* Checks if a frame has had InvalidateFrame() called on it since the
|
||||
* last paint.
|
||||
*
|
||||
* If true, then the invalid rect is returned in aRect, with an
|
||||
* empty rect meaning all pixels drawn by this frame should be
|
||||
* invalidated.
|
||||
* If false, aRect is left unchanged.
|
||||
*/
|
||||
bool IsInvalid();
|
||||
bool IsInvalid(nsRect& aRect);
|
||||
|
||||
/**
|
||||
* Check if any frame within the frame subtree (including this frame)
|
||||
|
@ -587,12 +587,16 @@ nsImageFrame::OnDataAvailable(imgIRequest *aRequest,
|
||||
// from
|
||||
if (!aCurrentFrame)
|
||||
return NS_OK;
|
||||
|
||||
|
||||
#ifdef DEBUG_decode
|
||||
printf("Source rect (%d,%d,%d,%d)\n",
|
||||
aRect->x, aRect->y, aRect->width, aRect->height);
|
||||
#endif
|
||||
InvalidateFrame();
|
||||
if (aRect->IsEqualInterior(nsIntRect::GetMaxSizedIntRect())) {
|
||||
InvalidateFrame();
|
||||
} else {
|
||||
InvalidateFrameWithRect(SourceRectToDest(*aRect));
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -671,8 +675,11 @@ nsImageFrame::FrameChanged(imgIRequest *aRequest,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Update border+content to account for image change
|
||||
InvalidateFrame();
|
||||
if (aDirtyRect->IsEqualInterior(nsIntRect::GetMaxSizedIntRect())) {
|
||||
InvalidateFrame();
|
||||
} else {
|
||||
InvalidateFrameWithRect(SourceRectToDest(*aDirtyRect));
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -155,7 +155,8 @@ public:
|
||||
void ClearInvalidRegion() { mInvalidRegion.SetEmpty(); }
|
||||
|
||||
const nsRegion& GetInvalidRegion() {
|
||||
if (!IsInvalid()) {
|
||||
nsRect rect;
|
||||
if (!IsInvalid(rect)) {
|
||||
mInvalidRegion.SetEmpty();
|
||||
}
|
||||
return mInvalidRegion;
|
||||
|
Loading…
Reference in New Issue
Block a user