mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 539356 - Part 9e - FrameLayerBuilder changes for display list invalidation. r=roc
* * * imported patch move-by-correctly
This commit is contained in:
parent
f49711f24b
commit
4e75c1edde
File diff suppressed because it is too large
Load Diff
@ -11,6 +11,7 @@
|
||||
#include "nsTArray.h"
|
||||
#include "nsRegion.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsDisplayListInvalidation.h"
|
||||
|
||||
class nsDisplayListBuilder;
|
||||
class nsDisplayList;
|
||||
@ -26,6 +27,7 @@ class ThebesLayer;
|
||||
}
|
||||
|
||||
class FrameLayerBuilder;
|
||||
class LayerManagerData;
|
||||
|
||||
enum LayerState {
|
||||
LAYER_NONE,
|
||||
@ -48,8 +50,9 @@ public:
|
||||
};
|
||||
|
||||
/**
|
||||
* The FrameLayerBuilder belongs to an nsDisplayListBuilder and is
|
||||
* responsible for converting display lists into layer trees.
|
||||
* The FrameLayerBuilder is responsible for converting display lists
|
||||
* into layer trees. Every LayerManager needs a unique FrameLayerBuilder
|
||||
* to build layers.
|
||||
*
|
||||
* The most important API in this class is BuildContainerLayerFor. This
|
||||
* method takes a display list as input and constructs a ContainerLayer
|
||||
@ -120,18 +123,14 @@ public:
|
||||
void DidBeginRetainedLayerTransaction(LayerManager* aManager);
|
||||
|
||||
/**
|
||||
* Call this just before we end a transaction on aManager. If aManager
|
||||
* is not the retained layer manager then it must be a temporary layer
|
||||
* manager that will not be used again.
|
||||
* Call this just before we end a transaction.
|
||||
*/
|
||||
void WillEndTransaction(LayerManager* aManager);
|
||||
void WillEndTransaction();
|
||||
|
||||
/**
|
||||
* Call this after we end a transaction on aManager. If aManager
|
||||
* is not the retained layer manager then it must be a temporary layer
|
||||
* manager that will not be used again.
|
||||
* Call this after we end a transaction.
|
||||
*/
|
||||
void DidEndTransaction(LayerManager* aManager);
|
||||
void DidEndTransaction();
|
||||
|
||||
struct ContainerParameters {
|
||||
ContainerParameters() :
|
||||
@ -212,33 +211,8 @@ public:
|
||||
* region.
|
||||
*/
|
||||
Layer* GetLeafLayerFor(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager,
|
||||
nsDisplayItem* aItem);
|
||||
|
||||
/**
|
||||
* Call this during invalidation if aFrame has
|
||||
* the NS_FRAME_HAS_CONTAINER_LAYER state bit. Only the nearest
|
||||
* ancestor frame of the damaged frame that has
|
||||
* NS_FRAME_HAS_CONTAINER_LAYER needs to be invalidated this way.
|
||||
* It is assumed that aRect does NOT have the frame's transforms applied.
|
||||
*/
|
||||
static void InvalidateThebesLayerContents(nsIFrame* aFrame,
|
||||
const nsRect& aRect);
|
||||
|
||||
/**
|
||||
* For any descendant frame of aFrame (including across documents) that
|
||||
* has an associated container layer, invalidate all the contents of
|
||||
* all ThebesLayer children of the container. Useful when aFrame is
|
||||
* being moved and we need to invalidate everything in aFrame's subtree.
|
||||
*/
|
||||
static void InvalidateThebesLayersInSubtree(nsIFrame* aFrame);
|
||||
|
||||
/**
|
||||
* As InvalidateThebesLayersInSubtree, but don't trust frame geometry
|
||||
* (e.g. because appunits-per-dev-pixel changed).
|
||||
*/
|
||||
static void InvalidateThebesLayersInSubtreeWithUntrustedFrameGeometry(nsIFrame* aFrame);
|
||||
|
||||
/**
|
||||
* Call this to force all retained layers to be discarded and recreated at
|
||||
* the next paint.
|
||||
@ -279,18 +253,18 @@ public:
|
||||
|
||||
/**
|
||||
* Record aItem as a display item that is rendered by aLayer.
|
||||
*
|
||||
* @param aLayer Layer that the display item will be rendered into
|
||||
* @param aItem Display item to be drawn.
|
||||
* @param aLayerState What LayerState the item is using.
|
||||
* @param aManager If the layer is in the LAYER_INACTIVE state,
|
||||
* then this is the temporary layer manager to draw with.
|
||||
*/
|
||||
void AddLayerDisplayItem(Layer* aLayer,
|
||||
nsDisplayItem* aItem,
|
||||
LayerState aLayerState);
|
||||
|
||||
/**
|
||||
* Record aFrame as a frame that is rendered by an item on aLayer.
|
||||
*/
|
||||
void AddLayerDisplayItemForFrame(Layer* aLayer,
|
||||
nsIFrame* aFrame,
|
||||
uint32_t aDisplayItemKey,
|
||||
LayerState aLayerState);
|
||||
LayerState aLayerState,
|
||||
const nsPoint& aTopLeft,
|
||||
LayerManager* aManager = nullptr);
|
||||
|
||||
/**
|
||||
* Record aItem as a display item that is rendered by the ThebesLayer
|
||||
@ -303,25 +277,25 @@ public:
|
||||
nsDisplayItem* aItem,
|
||||
const Clip& aClip,
|
||||
nsIFrame* aContainerLayerFrame,
|
||||
LayerState aLayerState);
|
||||
|
||||
/**
|
||||
* 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
|
||||
* render that display item. Returns null if there is no such layer.
|
||||
* This could be a dedicated layer for the display item, or a ThebesLayer
|
||||
* that renders many display items.
|
||||
*/
|
||||
Layer* GetOldLayerForFrame(nsIFrame* aFrame, uint32_t aDisplayItemKey);
|
||||
LayerState aLayerState,
|
||||
const nsPoint& aTopLeft);
|
||||
|
||||
/**
|
||||
* Calls GetOldLayerForFrame on the underlying frame of the display item,
|
||||
* and each subsequent merged frame if no layer is found for the underlying
|
||||
* frame.
|
||||
*/
|
||||
Layer* GetOldLayerFor(nsDisplayItem* aItem);
|
||||
Layer* GetOldLayerFor(nsDisplayItem* aItem, nsDisplayItemGeometry** aOldGeometry = nullptr);
|
||||
|
||||
static Layer* GetDebugOldLayerFor(nsIFrame* aFrame, uint32_t aDisplayItemKey);
|
||||
|
||||
/**
|
||||
* If the display item was previously drawn as an inactive layer,
|
||||
* then return the layer manager used for the inactive transaction.
|
||||
* Returns nullptr if no manager could be found.
|
||||
*/
|
||||
LayerManager* GetInactiveLayerManagerFor(nsDisplayItem* aItem);
|
||||
|
||||
/**
|
||||
* Try to determine whether the ThebesLayer aLayer paints an opaque
|
||||
* single color everywhere it's visible in aRect.
|
||||
@ -356,11 +330,15 @@ public:
|
||||
* into a retained layer.
|
||||
* Returns false if it was rendered into a temporary layer manager and then
|
||||
* into a retained layer.
|
||||
*
|
||||
* Since display items can belong to multiple retained LayerManagers, we need to
|
||||
* specify which LayerManager to check.
|
||||
*/
|
||||
static bool HasRetainedLayerFor(nsIFrame* aFrame, uint32_t aDisplayItemKey);
|
||||
static bool HasRetainedLayerFor(nsIFrame* aFrame, uint32_t aDisplayItemKey, LayerManager* aManager);
|
||||
|
||||
/**
|
||||
* Save transform that was in aLayer when we last painted. It must be an integer
|
||||
* Save transform that was in aLayer when we last painted, and the position
|
||||
* of the active scrolled root frame. It must be an integer
|
||||
* translation.
|
||||
*/
|
||||
void SaveLastPaintOffset(ThebesLayer* aLayer);
|
||||
@ -471,16 +449,48 @@ protected:
|
||||
class DisplayItemData {
|
||||
public:
|
||||
DisplayItemData(Layer* aLayer, uint32_t aKey, LayerState aLayerState, uint32_t aGeneration);
|
||||
DisplayItemData()
|
||||
: mUsed(false)
|
||||
{}
|
||||
DisplayItemData(DisplayItemData &toCopy);
|
||||
~DisplayItemData();
|
||||
|
||||
NS_INLINE_DECL_REFCOUNTING(DisplayItemData)
|
||||
|
||||
void AddFrame(nsIFrame* aFrame)
|
||||
{
|
||||
mFrameList.AppendElement(aFrame);
|
||||
}
|
||||
|
||||
bool FrameListMatches(nsDisplayItem* aOther);
|
||||
|
||||
nsRefPtr<Layer> mLayer;
|
||||
nsRefPtr<LayerManager> mInactiveManager;
|
||||
nsAutoTArray<nsIFrame*, 2> mFrameList;
|
||||
nsAutoPtr<nsDisplayItemGeometry> mGeometry;
|
||||
uint32_t mDisplayItemKey;
|
||||
uint32_t mContainerLayerGeneration;
|
||||
LayerState mLayerState;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
bool mUsed;
|
||||
};
|
||||
|
||||
static void RemoveFrameFromLayerManager(nsIFrame* aFrame, void* aPropertyValue);
|
||||
|
||||
/**
|
||||
* 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
|
||||
* render that display item. Returns null if there is no such layer.
|
||||
* This could be a dedicated layer for the display item, or a ThebesLayer
|
||||
* that renders many display items.
|
||||
*/
|
||||
DisplayItemData* GetOldLayerForFrame(nsIFrame* aFrame, uint32_t aDisplayItemKey);
|
||||
|
||||
NS_DECLARE_FRAME_PROPERTY_WITH_FRAME_IN_DTOR(LayerManagerDataProperty,
|
||||
RemoveFrameFromLayerManager)
|
||||
|
||||
@ -493,21 +503,23 @@ protected:
|
||||
public:
|
||||
DisplayItemDataEntry(const nsIFrame *key)
|
||||
: nsPtrHashKey<nsIFrame>(key)
|
||||
{}
|
||||
{
|
||||
MOZ_COUNT_CTOR(DisplayItemDataEntry);
|
||||
}
|
||||
DisplayItemDataEntry(DisplayItemDataEntry &toCopy)
|
||||
: nsPtrHashKey<nsIFrame>(toCopy.mKey)
|
||||
{
|
||||
MOZ_COUNT_CTOR(DisplayItemDataEntry);
|
||||
// This isn't actually a copy-constructor; notice that it steals toCopy's
|
||||
// array and invalid region. Be careful.
|
||||
mData.SwapElements(toCopy.mData);
|
||||
mInvalidRegion.swap(toCopy.mInvalidRegion);
|
||||
mContainerLayerGeneration = toCopy.mContainerLayerGeneration;
|
||||
}
|
||||
~DisplayItemDataEntry() { MOZ_COUNT_DTOR(DisplayItemDataEntry); }
|
||||
|
||||
bool HasNonEmptyContainerLayer();
|
||||
|
||||
nsAutoTArray<DisplayItemData, 1> mData;
|
||||
nsRefPtr<RefCountedRegion> mInvalidRegion;
|
||||
nsAutoTArray<nsRefPtr<DisplayItemData>, 1> mData;
|
||||
uint32_t mContainerLayerGeneration;
|
||||
|
||||
enum { ALLOW_MEMMOVE = false };
|
||||
@ -516,6 +528,12 @@ protected:
|
||||
// LayerManagerData needs to see DisplayItemDataEntry.
|
||||
friend class LayerManagerData;
|
||||
|
||||
/**
|
||||
* Stores DisplayItemData associated with aFrame, stores the data in
|
||||
* mNewDisplayItemData.
|
||||
*/
|
||||
void StoreDataForFrame(nsIFrame* aFrame, DisplayItemData* data);
|
||||
|
||||
// Flash the area within the context clip if paint flashing is enabled.
|
||||
static void FlashPaint(gfxContext *aContext);
|
||||
|
||||
@ -526,7 +544,16 @@ protected:
|
||||
* Note that the pointer returned here is only valid so long as you don't
|
||||
* poke the LayerManagerData's mFramesWithLayers hashtable.
|
||||
*/
|
||||
static nsTArray<DisplayItemData>* GetDisplayItemDataArrayForFrame(nsIFrame *aFrame);
|
||||
nsTArray<nsRefPtr<DisplayItemData> >* GetDisplayItemDataArrayForFrame(nsIFrame *aFrame);
|
||||
|
||||
/*
|
||||
* Get the DisplayItemData associated with this frame / display item pair,
|
||||
* using the LayerManager instead of FrameLayerBuilder.
|
||||
*/
|
||||
static DisplayItemData* GetDisplayItemDataForManager(nsIFrame* aFrame,
|
||||
uint32_t aDisplayItemKey,
|
||||
LayerManager* aManager);
|
||||
static DisplayItemData* GetDisplayItemDataForManager(nsDisplayItem* aItem, LayerManager* aManager);
|
||||
|
||||
/**
|
||||
* A useful hashtable iteration function that removes the
|
||||
@ -535,10 +562,7 @@ protected:
|
||||
* aClosure is ignored.
|
||||
*/
|
||||
static PLDHashOperator RemoveDisplayItemDataForFrame(DisplayItemDataEntry* aEntry,
|
||||
void* aClosure)
|
||||
{
|
||||
return UpdateDisplayItemDataForFrame(aEntry, nullptr);
|
||||
}
|
||||
void* aClosure);
|
||||
|
||||
/**
|
||||
* We store one of these for each display item associated with a
|
||||
@ -556,10 +580,19 @@ protected:
|
||||
{
|
||||
}
|
||||
|
||||
~ClippedDisplayItem();
|
||||
|
||||
nsDisplayItem* mItem;
|
||||
|
||||
/**
|
||||
* If the display item is being rendered as an inactive
|
||||
* layer, then this stores the layer manager being
|
||||
* used for the inactive transaction.
|
||||
*/
|
||||
nsRefPtr<LayerManager> mInactiveLayer;
|
||||
|
||||
Clip mClip;
|
||||
uint32_t mContainerLayerGeneration;
|
||||
bool mInactiveLayer;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -604,6 +637,8 @@ public:
|
||||
return mThebesLayerItems.GetEntry(aLayer);
|
||||
}
|
||||
|
||||
static PLDHashOperator ProcessRemovedDisplayItems(DisplayItemDataEntry* aEntry,
|
||||
void* aUserArg);
|
||||
protected:
|
||||
void RemoveThebesItemsAndOwnerDataForLayerSubtree(Layer* aLayer,
|
||||
bool aRemoveThebesItems,
|
||||
@ -636,6 +671,11 @@ protected:
|
||||
* The root prescontext for the display list builder reference frame
|
||||
*/
|
||||
nsRootPresContext* mRootPresContext;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
|
@ -1064,12 +1064,12 @@ void nsDisplayList::PaintForFrame(nsDisplayListBuilder* aBuilder,
|
||||
}
|
||||
|
||||
layerManager->SetRoot(root);
|
||||
layerBuilder->WillEndTransaction(layerManager);
|
||||
layerBuilder->WillEndTransaction();
|
||||
bool temp = aBuilder->SetIsCompositingCheap(layerManager->IsCompositingCheap());
|
||||
layerManager->EndTransaction(FrameLayerBuilder::DrawThebesLayer,
|
||||
aBuilder, (aFlags & PAINT_NO_COMPOSITE) ? LayerManager::END_NO_COMPOSITE : LayerManager::END_DEFAULT);
|
||||
aBuilder->SetIsCompositingCheap(temp);
|
||||
layerBuilder->DidEndTransaction(layerManager);
|
||||
layerBuilder->DidEndTransaction();
|
||||
|
||||
if (aFlags & PAINT_FLUSH_LAYERS) {
|
||||
FrameLayerBuilder::InvalidateAllLayers(layerManager);
|
||||
|
@ -770,6 +770,12 @@ public:
|
||||
return GetUnderlyingFrame()->GetContentRectRelativeToSelf() + ToReferenceFrame();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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; }
|
||||
|
||||
/**
|
||||
* Creates and initializes an nsDisplayItemGeometry object that retains the current
|
||||
* areas covered by this display item. These need to retain enough information
|
||||
@ -1999,6 +2005,18 @@ public:
|
||||
{
|
||||
aFrames->AppendElements(mMergedFrames);
|
||||
}
|
||||
virtual bool IsInvalid()
|
||||
{
|
||||
if (mFrame->IsInvalid()) {
|
||||
return true;
|
||||
}
|
||||
for (uint32_t i = 0; i < mMergedFrames.Length(); i++) {
|
||||
if (mMergedFrames[i]->IsInvalid()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
NS_DISPLAY_DECL_NAME("WrapList", TYPE_WRAP_LIST)
|
||||
|
||||
virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder);
|
||||
|
@ -40,17 +40,6 @@ public:
|
||||
*/
|
||||
virtual void MoveBy(const nsPoint& aOffset) = 0;
|
||||
|
||||
/**
|
||||
* The appunits per dev pixel for the item's frame.
|
||||
*/
|
||||
nscoord mAppUnitsPerDevPixel;
|
||||
|
||||
/**
|
||||
* The offset (in pixels) of the TopLeft() of the ThebesLayer
|
||||
* this display item was drawn into.
|
||||
*/
|
||||
nsIntPoint mPaintOffset;
|
||||
|
||||
/**
|
||||
* Bounds of the display item
|
||||
*/
|
||||
|
@ -7978,14 +7978,6 @@ nsFrame::SetParent(nsIFrame* aParent)
|
||||
} else {
|
||||
RemoveInPopupStateBitFromDescendants(this);
|
||||
}
|
||||
|
||||
if (GetStateBits() & NS_FRAME_HAS_CONTAINER_LAYER_DESCENDANT) {
|
||||
for (nsIFrame* f = aParent;
|
||||
f && !(f->GetStateBits() & NS_FRAME_HAS_CONTAINER_LAYER_DESCENDANT);
|
||||
f = nsLayoutUtils::GetCrossDocParentFrame(f)) {
|
||||
f->AddStateBits(NS_FRAME_HAS_CONTAINER_LAYER_DESCENDANT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -264,7 +264,7 @@ nsHTMLCanvasFrame::BuildLayer(nsDisplayListBuilder* aBuilder,
|
||||
return nullptr;
|
||||
|
||||
CanvasLayer* oldLayer = static_cast<CanvasLayer*>
|
||||
(aManager->GetLayerBuilder()->GetLeafLayerFor(aBuilder, aManager, aItem));
|
||||
(aManager->GetLayerBuilder()->GetLeafLayerFor(aBuilder, aItem));
|
||||
nsRefPtr<CanvasLayer> layer = element->GetCanvasLayer(aBuilder, oldLayer, aManager);
|
||||
if (!layer)
|
||||
return nullptr;
|
||||
|
@ -138,10 +138,6 @@ typedef uint64_t nsFrameState;
|
||||
// continuation, e.g. a bidi continuation.
|
||||
#define NS_FRAME_IS_FLUID_CONTINUATION NS_FRAME_STATE_BIT(2)
|
||||
|
||||
// This bit is set whenever the frame has one or more associated
|
||||
// container layers.
|
||||
#define NS_FRAME_HAS_CONTAINER_LAYER NS_FRAME_STATE_BIT(3)
|
||||
|
||||
// If this bit is set, then a reference to the frame is being held
|
||||
// elsewhere. The frame may want to send a notification when it is
|
||||
// destroyed to allow these references to be cleared.
|
||||
@ -253,10 +249,6 @@ typedef uint64_t nsFrameState;
|
||||
// This bit acts as a loop flag for recursive paint server drawing.
|
||||
#define NS_FRAME_DRAWING_AS_PAINTSERVER NS_FRAME_STATE_BIT(33)
|
||||
|
||||
// Frame or one of its (cross-doc) descendants may have the
|
||||
// NS_FRAME_HAS_CONTAINER_LAYER bit.
|
||||
#define NS_FRAME_HAS_CONTAINER_LAYER_DESCENDANT NS_FRAME_STATE_BIT(34)
|
||||
|
||||
// Frame's overflow area was clipped by the 'clip' property.
|
||||
#define NS_FRAME_HAS_CLIP NS_FRAME_STATE_BIT(35)
|
||||
|
||||
|
@ -1638,7 +1638,7 @@ nsObjectFrame::BuildLayer(nsDisplayListBuilder* aBuilder,
|
||||
// to provide crisper and faster drawing.
|
||||
r.Round();
|
||||
nsRefPtr<Layer> layer =
|
||||
(aManager->GetLayerBuilder()->GetLeafLayerFor(aBuilder, aManager, aItem));
|
||||
(aManager->GetLayerBuilder()->GetLeafLayerFor(aBuilder, aItem));
|
||||
|
||||
if (aItem->GetType() == nsDisplayItem::TYPE_PLUGIN) {
|
||||
if (!layer) {
|
||||
|
@ -196,7 +196,7 @@ nsVideoFrame::BuildLayer(nsDisplayListBuilder* aBuilder,
|
||||
container->SetScaleHint(scaleHint);
|
||||
|
||||
nsRefPtr<ImageLayer> layer = static_cast<ImageLayer*>
|
||||
(aManager->GetLayerBuilder()->GetLeafLayerFor(aBuilder, aManager, aItem));
|
||||
(aManager->GetLayerBuilder()->GetLeafLayerFor(aBuilder, aItem));
|
||||
if (!layer) {
|
||||
layer = aManager->CreateImageLayer();
|
||||
if (!layer)
|
||||
|
@ -646,7 +646,7 @@ RenderFrameParent::BuildLayer(nsDisplayListBuilder* aBuilder,
|
||||
MOZ_ASSERT(!GetRootLayer());
|
||||
|
||||
nsRefPtr<Layer> layer =
|
||||
(aManager->GetLayerBuilder()->GetLeafLayerFor(aBuilder, aManager, aItem));
|
||||
(aManager->GetLayerBuilder()->GetLeafLayerFor(aBuilder, aItem));
|
||||
if (!layer) {
|
||||
layer = aManager->CreateRefLayer();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user