SInvalidationPanel 代码简析

版权声明:翻译:yarswang 转载请保留 https://blog.csdn.net/wangyars/article/details/84561115

什么是SInvalidationPanel

『失效面板』中的控件可以对子控件几何图形进行缓存,以加快Slate的渲染速度。任何由失效面板缓存的控件都不会进行Prepassed(预渲染), Ticked(更新) 或 Painted(描画)。

对应UserWidget控件为 InValidationBox

主要功能

其主旨简要来说就是:『缓存』。包含了(What)『缓存什么信息』,(When)『什么时机进行缓存』以及(How)『如何缓存』

What

CachedWindowElements:子控件OnPaint返回的FSlateWindowElementList

CachedMaxChildLayer:子控件OnPaint返回的渲染层ID

CachedResourcesCachedWindowElements的图片资源信息

CachedAbsolutePosition 父控件为其分配的几何信息之渲染位置

When

首次调用OnPaint

由父控件分配的几何信息改变时

裁切信息改变时

子控件手动失效时

How

SlateApplication的缓存池词典TMap< const ILayoutCache*, TSharedPtr<FCacheElementPools>> CachedElementLists中,以自身指针为Key,申请一段新的缓存FCacheElementPools. 在每次因需遍历子控件的OnPaint方法后,缓存其返回的WindowElements信息,然后遍历WindowElements,获取并缓存其BrushResource信息。

工作原理

SlateApplication 每帧会对所有的SWindow界面,遍历其子控件,搜集FSlateWindowElementList& OutDrawElements

SinvalidationPanel会在 IsCachingNeeded == true 的时候进行一遍正常的OnPaint,并把自己传递进去,如下图代码所示:

 

SInvalidationPanel* MutableThis = const_cast<SInvalidationPanel*>( this );

TSharedRef<SInvalidationPanel> SharedMutableThis = SharedThis(MutableThis);

// 在Args中将当前控件作为参数传入

CachedMaxChildLayer = SCompoundWidget::OnPaint(

    Args.EnableCaching(SharedMutableThis, RootCacheNode, true, false),

    AllottedGeometry,

    MyCullingRect,

    *CachedWindowElements.Get(),

    LayerId,

    InWidgetStyle,

    bParentEnabled);

 

子控件中的处理:

// 存储Args中传入的参数(即InvalidationPanel

TWeakPtr<ILayoutCache> LayoutCache = Args.GetLayoutCache();

 

// 自身进行失效时,进行通知

FORCEINLINE void Advanced_ForceInvalidateLayout()

{

    TSharedPtr<ILayoutCache> SharedLayoutCache = LayoutCache.Pin();

    if (SharedLayoutCache.IsValid() )

    {

        SharedLayoutCache->InvalidateWidget(this);

    }

}

IsCachingNeededPanel初始化时为True,确保首次调用OnPaint时进行缓存;

当父控件分配的几何信息或裁切信息改变时,IsCachingNeededTrue

当其直接负责的子控件进行手动失效时,会根据Args.EnableCaching的信息,通知当前此面板进行处理,如上述代码所示

特别说明

标记为IsVolatile的子控件会被特殊处理,会被放入CachedWindowElementsVolatileElements列表中,InvalidationPanel会在后续专门调用PaintVolatile方法来绘制它们。

// SWidget.cpp

if ( IsVolatile() && Args.IsCaching() && !Args.IsVolatilityPass() )

{

    const int32 VolatileLayerId = UseDefaultLayerPolicy() ? LayerId + 1 : LayerId;

    OutDrawElements.QueueVolatilePainting(

    FSlateWindowElementList::FVolatilePaint(SharedThis(this), Args, AllottedGeometry, CullingBounds, OutDrawElements.GetClippingState(), VolatileLayerId, InWidgetStyle, bParentEnabled));

    NotifyEndPaint();

    return VolatileLayerId;

}

// SInvalidationPanel.cpp

// After normal Paint pass

if ( CachedWindowElements.IsValid() )

    { int32 VolatileLayerId = CachedWindowElements->PaintVolatile(xxx)}


工作流程图

猜你喜欢

转载自blog.csdn.net/wangyars/article/details/84561115