slate总结
2022-06-11 21:41 kk20161206 阅读(118) 评论(0) 编辑 收藏 举报
TArray< TSharedRef<FSlateWindowElementList> > WindowElementLists; // List of window element lists that we store from the previous frame // that we restore if they're requested again. TArray< TSharedRef<FSlateWindowElementList> > WindowElementListsPool;
通过AddWindow得到了windowElementList,如下函数:
FSlateWindowElementList& AddWindowElementList(TSharedRef<SWindow> ForWindow); //如果pool里有这个wiNdow对应的,则将该list挪到list数组,将pool里那个删掉。如果没有,则new一个放到list数组。
void RemoveUnusedWindowElements(const TArray<SWindow*>& AllWindows);//遍历所有list对应的paintWindow,如果该window无效,则从list删除。
调用的地方:
void FSlateApplication::DrawWindowAndChildren( const TSharedRef<SWindow>& WindowToDraw, FDrawWindowArgs& DrawWindowArgs )
父:
void FSlateApplication::PrivateDrawWindows( TSharedPtr<SWindow> DrawOnlyThisWindow )
SLateRHIRender类,slateD3DRenderer.h类,SlateOpenGLRenderer类,都包含DrawBuffer类型数据。其中,FSlateRHIRenderer里包含了数组、指针:
/** Keep a pointer around for when we have deferred drawing happening */ FSlateDrawBuffer* EnqueuedWindowDrawBuffer; /** Double buffered draw buffers so that the rendering thread can be rendering windows while the game thread is setting up for next frame */ FSlateDrawBuffer DrawBuffers[NumDrawBuffers];
FSlateWindowElementList类,代表一个顶层的window和他的所有draw elements。
获取其绘制的窗口:
SWindow* GetPaintWindow() const
batchData:
FSlateBatchData BatchData;
drawElement数组:
FSlateDrawElementArray UncachedDrawElements;
FSlateDrawElementArray 即TArray<FSlateDrawElement>;
要渲染到的窗口,可能和绘制的窗口不一样:
SWindow* RenderTargetWindow;
裁剪管理类:
FSlateClippingManager ClippingManager;
TArray<FWidgetDrawElementState, TInlineAllocator<50>> WidgetDrawStack; TArray<FSlateCachedElementData*, TInlineAllocator<4>> CachedElementDataList;
TArray<int32, TInlineAllocator<4>> CachedElementDataListStack; //liist和stack是对应的,push进去一个data就会放到stack里面一个index。
几个缓存相关函数:
/** * Pushes the current widget that is painting onto the widget stack so we know what elements belong to each widget * This information is used for caching later. * */ SLATECORE_API void PushPaintingWidget(const SWidget& CurrentWidget, int32 StartingLayerId, FSlateCachedElementsHandle& CurrentCacheHandle); /** * Pops the current painted widget off the stack * @return true if an element was added while the widget was pushed */ SLATECORE_API FSlateCachedElementsHandle PopPaintingWidget(const SWidget& CurrentWidget);
//上两个函数会把cacheHandle和对应的widget放到wdigetDrawElementState的数组里和弹出来。 /** Pushes cached element data onto the stack. Any draw elements cached after will use this cached element data until popped */ void PushCachedElementData(FSlateCachedElementData& CachedElementData); void PopCachedElementData();
其中的FSlateCachedElementData类型包含了
TSparseArray<FSlateRenderBatch> CachedBatches; TArray<TSharedPtr<FSlateCachedElementList>> CachedElementLists; TArray<FSlateCachedElementList*, TInlineAllocator<50>> ListsWithNewData; TArray<FSlateCachedClipState> CachedClipStates;
FSlateCachedElementsHandle FSlateCachedElementData::AddCache(const SWidget* Widget);//该函数传入一个widget,返回一个包含cachedElementList的handle。
//如果当前裁剪状态不为空,则list里加入当前cached裁剪状态。新添加元素的cachedClippingState设为该状态。
FSlateRenderBatch& FSlateCachedElementData::AddCachedRenderBatch(FSlateRenderBatch&& NewBatch, int32& OutIndex); //cachedBatches里面新加这个newBatch。
void FSlateCachedElementData::RemoveCachedRenderBatches(const TArray<int32>& CachedRenderBatchIndices); //从CachedBatches里面删除数组的index位置的元素。
FSlateDrawElement& FSlateCachedElementData::AddCachedElement(FSlateCachedElementsHandle& CacheHandle, const FSlateClippingManager& ParentClipManager, const SWidget* CurrentWidget); //cachedhandle的nlist的drawelements里面新建一个drawelement,isCached为true。listWithNewData里面加入这个list。如果当前裁剪状态为存在,则list加入缓存裁剪状态。newelement的裁剪状态设为该状态,返回这个新建的drawelement.
void RemoveList(FSlateCachedElementsHandle& CacheHandle);
FSLateCachedElementList中包含了它的父类elementData,和用来创建batch的源drawElement数据,创建batches之后,batch数据存在此类的fastPathRenderingData中,返回的renderbatch放到parentData的batch数组中,list里只放indices数组。这些drawElement所属的widget,快速渲染的缓存数据。后者包含clip列表,vertex数组,index数组等。
/** List of source draw elements to create batches from */ FSlateDrawElementArray DrawElements; TArray<int32> CachedRenderBatchIndices; /** The widget whose draw elements are in this list */ const SWidget* OwningWidget; FSlateCachedElementData* ParentData; FSlateCachedFastPathRenderingData* CachedRenderingData;
FSlateRenderBatch& AddRenderBatch(int32 InLayer, const FShaderParams& InShaderParams, const FSlateShaderResource* InResource, ESlateDrawPrimitive InPrimitiveType, ESlateShader InShaderType, ESlateDrawEffect InDrawEffects, ESlateBatchDrawFlag InDrawFlags, int8 SceneIndex);
SLATECORE_API void DestroyCachedData();
struct FSlateCachedElementsHandle这个结构通过上面的FSLateCachedElementList构造的:
struct FSlateCachedElementsHandle { friend struct FSlateCachedElementData; static FSlateCachedElementsHandle Invalid; void ClearCachedElements(); void RemoveFromCache(); bool IsOwnedByWidget(const SWidget* Widget) const; bool IsValid() const { return Ptr.IsValid(); } bool operator!=(FSlateCachedElementsHandle& Other) const { return Ptr != Other.Ptr; } FSlateCachedElementsHandle() {} private: FSlateCachedElementsHandle(TSharedRef<FSlateCachedElementList>& DataPtr) : Ptr(DataPtr) { } private: TWeakPtr<FSlateCachedElementList> Ptr; };
其中的FSLateCachedFastPathRenderingData类包含了这些东西:
TArray<FSlateCachedClipState, TInlineAllocator<1>> CachedClipStates; FSlateVertexArray Vertices; FSlateIndexArray Indices;
FSlateRenderBatch& FSlateCachedElementList::AddRenderBatch(int32 InLayer, const FShaderParams& InShaderParams, const FSlateShaderResource* InResource, ESlateDrawPrimitive InPrimitiveType, ESlateShader InShaderType, ESlateDrawEffect InDrawEffects, ESlateBatchDrawFlag InDrawFlags, int8 SceneIndex) { FSlateRenderBatch NewRenderBatch(InLayer, InShaderParams, InResource, InPrimitiveType, InShaderType, InDrawEffects, InDrawFlags, SceneIndex, &CachedRenderingData->Vertices, &CachedRenderingData->Indices, CachedRenderingData->Vertices.Num(), CachedRenderingData->Indices.Num()); int32 RenderBatchIndex = INDEX_NONE; FSlateRenderBatch& AddedBatchRef = ParentData->AddCachedRenderBatch(MoveTemp(NewRenderBatch), RenderBatchIndex); check(RenderBatchIndex != INDEX_NONE); CachedRenderBatchIndices.Add(RenderBatchIndex); return AddedBatchRef; //return CachedBatches.Emplace_GetRef(InLayer, InShaderParams, InResource, InPrimitiveType, InShaderType, InDrawEffects, InDrawFlags, SceneIndex, &CachedRenderingData->Vertices, &CachedRenderingData->Indices, CachedRenderingData->Vertices.Num(), CachedRenderingData->Indices.Num()); }
看看这个函数调用的地方,哪些东西存有cache数据。
slate调用堆栈
privateDrawWindows函数里创建FDrawWindowArgs类型参数,然后作为引用类型传入DrawWindowAndChildren函数,该函数参数为SWindow引用类型参数和前面创建的FDrawWIndowArgs类型参数,后者里面包含DrawBuffer,其类内部有windowList成员,通过这个DrawWindowAndCHildren函数,将window对应的slateWindowElementList放到了DrawBuffer里面了就。这个DrawWindowANdChildren函数 还会递归调用这个window的所有children。执行完这个函数之后,DrawWIndowArgs.OutDrawBuffer里面就存放了数据。privateDrawWindows函数里面最后一句执行了Renderer->DrawWindows(DrawWindowArgs.OutDrawBuffer);
即
FSlateRHIRenderer::DrawWindows(FSlateDrawBuffer& WindowDrawBuffer)
{
DrawWindows_Private(WindowDrawBuffer);
}
在这个DrawWindows_Private函数里面,对WIndowDrawBuffer里的每个windowElementList,执行ElementBatcher->AddElements(ElementList);(FSLateELmentBatcher类型的ElementBatcher) 在ElementBatcher.cpp文件中,该函数对于windowElementList的uncachedDrawElements直接AddElementsInternal参数是drawElements数组和viewportSIze,对于cachedElementDataList,执行AddCachedElements,该函数遍历cachedElementData的所有listsWIthNewData,调用AddElementsInternal,将这些list里的DrawElements传入函数中去。
privateDrawWindows里面有个DrawPrepass设置dpiScale*ApplicationScale.
AddElement函数会创建一个FSlateRenderBatch类,里面放入vertex和index,createRenderBatch函数用来创建这个FSlateRenderBatch对象,判断currentCachedElementList是否为空,如果不为空,则currentCachedElementList的AddBatch,,否则BatchData的AddBatch,BatchData属于FSlateBatchData类,是FSlateElementBatch类型。如果是前者,FSlateCachedElementList的AddBatch,新建的RenderBatch会放到FSlateCachedElementData中;如果是后者,FSlateBatchData的renderbatches里会放入新建的renderBatch。
SlateElementBatcher作为一个中间枢纽的存在,他AddWindow的时候,batchData指针执行elementList的batchData,完成后清空,再处理下一个windowList。FSlateElementBatcher能创建FSlateRenderBatch。
SLATECORE_API void AddElements( FSlateWindowElementList& ElementList ); void AddElementsInternal(const FSlateDrawElementArray& DrawElements, const FVector2D& ViewportSize); void AddCachedElements(FSlateCachedElementData& CachedElementData, const FVector2D& ViewportSize); FSlateRenderBatch& CreateRenderBatch( int32 Layer, const FShaderParams& ShaderParams, const FSlateShaderResource* InResource, ESlateDrawPrimitive PrimitiveType, ESlateShader ShaderType, ESlateDrawEffect DrawEffects, ESlateBatchDrawFlag DrawFlags, const FSlateDrawElement& DrawElement); //具体创建vertices的函数 /** * Creates vertices necessary to draw a string (one quad per character) */ template<ESlateVertexRounding Rounding> void AddTextElement( const FSlateDrawElement& DrawElement ); private: /** Uncached Batch data currently being filled in */ FSlateBatchData* BatchData; /** Cached batches currently being filled in */ FSlateCachedElementList* CurrentCachedElementList;
FSLateBtachData属于windowLIst。还能合renderBatch。
FSlateElementBatch代表一系列batch到一起的slateDrawElement渲染需要的一些信息,shaderResource、shaderParam、DrawFlag、PrimitiveType、shaderType、DrawEffect、instanceCount、instanceOffset、FBatchKey用来决定是否两个batch能合并,BATCH里element的数量,顶点数组index,index数组索引。引用的地方没找到,哈哈哈。估计弃用了。删掉后确实没问题。
FSlateDrawElement类存渲染drawElement需要的数据,makeBoxInternal,makeText等,内部会调用其Init函数,
------------恢复内容结束------------