Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shared vb accessor for spine #10077

Merged
merged 17 commits into from
Feb 18, 2022
Merged

Shared vb accessor for spine #10077

merged 17 commits into from
Feb 18, 2022

Conversation

pandamicro
Copy link
Contributor

Improve general web performance for large amount of spine elements

@github-actions
Copy link

github-actions bot commented Feb 11, 2022

Interface Check Report

! WARNING this pull request has changed these public interfaces:

@@ -916,17 +916,16 @@
         BATCHER2D_MEM_INCREMENT: number;
     };
     export function murmurhash2_32_gc(input: string | Uint8Array, seed: number): number;
     export class MeshBuffer {
-        static IB_SCALE: number;
         get attributes(): gfx.Attribute[];
         get vertexFormatBytes(): number;
         byteOffset: number;
         vertexOffset: number;
         indexOffset: number;
         vData: Float32Array;
         iData: Uint16Array;
-        initialize(device: gfx.Device, attrs: gfx.Attribute[]): void;
+        initialize(device: gfx.Device, attrs: gfx.Attribute[], vFloatCount: number, iCount: number): void;
         reset(): void;
         destroy(): void;
         setDirty(): void;
         /**
@@ -2706,9 +2705,9 @@
          */
         markAsDirty(): void;
         _requireDrawBatch(): UIDrawBatch;
         protected _clearData(): void;
-        protected _getBatcher(): __private._cocos_2d_renderer_i_batcher__IBatcher | null;
+        protected _getBatcher(): UI | null;
     }
     /**
      * @en Shadow effect for Label component, only for system fonts or TTF fonts
      * @zh 用于给 Label 组件添加阴影效果,只能用于系统字体或 ttf 字体
@@ -3151,16 +3150,16 @@
         protected _floatStride: number;
         protected _vertexFormat: gfx.Attribute[];
         constructor(vertexFormat?: gfx.Attribute[]);
         isValid(): false | __private._cocos_2d_renderer_static_vb_accessor__StaticVBAccessor;
-        resize(vertexCount: number, indexCount: number): void;
     }
     export class RenderData extends BaseRenderData {
-        static add(vertexFormat?: gfx.Attribute[]): RenderData;
+        static add(vertexFormat?: gfx.Attribute[], accessor?: __private._cocos_2d_renderer_static_vb_accessor__StaticVBAccessor): RenderData;
         static remove(data: RenderData): void;
         get dataLength(): number;
         set dataLength(length: number);
         get data(): IRenderData[];
+        indices: Uint16Array | null;
         vertDirty: boolean;
         frame: any;
         layer: number;
         blendHash: number;
@@ -3168,9 +3167,13 @@
         nodeDirty: boolean;
         passDirty: boolean;
         textureDirty: boolean;
         hashDirty: boolean;
+        protected _accessor: __private._cocos_2d_renderer_static_vb_accessor__StaticVBAccessor;
+        constructor(vertexFormat?: gfx.Attribute[], accessor?: __private._cocos_2d_renderer_static_vb_accessor__StaticVBAccessor);
         resize(vertexCount: number, indexCount: number): void;
+        resizeAndCopy(vertexCount: number, indexCount: number): void;
+        getMeshBuffer(): MeshBuffer | null;
         updateNode(comp: Renderable2D): void;
         updatePass(comp: Renderable2D): void;
         updateTexture(frame: SpriteFrame | __private._cocos_core_assets_texture_base__TextureBase): void;
         updateHash(): void;
@@ -3281,8 +3284,9 @@
          * Switch the mesh buffer for corresponding vertex layout if necessary.
          * @param attributes use [[VertexFormat.vfmtPosUvColor]] by default
          */
         switchBufferAccessor(attributes?: gfx.Attribute[]): __private._cocos_2d_renderer_static_vb_accessor__StaticVBAccessor;
+        registerBufferAccessor(key: number, accessor: __private._cocos_2d_renderer_static_vb_accessor__StaticVBAccessor): void;
         updateBuffer(attributes: gfx.Attribute[], bid: number): void;
         /**
          * @en
          * Render component data submission process of UI.
@@ -3292,25 +3296,40 @@
          * @zh
          * UI 渲染组件数据提交流程(针对提交的顶点数据是世界坐标的提交流程,例如:除 Graphics 和 UIModel 的大部分 ui 组件)。
          * 此处的数据最终会生成需要提交渲染的 model 数据。
          *
-         * @param comp - 当前执行组件。
-         * @param frame - 当前执行组件贴图。
-         * @param assembler - 当前组件渲染数据组装器。
+         * @param comp - The committed renderable component
+         * @param renderData - The render data being committed
+         * @param frame - Texture or sprite frame related to the draw batch, could be null
+         * @param assembler - The assembler for the current component, could be null
+         * @param transform - Node type transform, if passed, then batcher will consider it's using model matrix, could be null
          */
         commitComp(comp: Renderable2D, renderData: BaseRenderData | null, frame: __private._cocos_core_assets_texture_base__TextureBase | SpriteFrame | null, assembler: any, transform: Node | null): void;
         /**
          * @en
+         * Render component data submission process for individual [[InputAssembler]]
+         * @zh
+         * 渲染组件中针对独立 [[InputAssembler]] 的提交流程
+         * 例如:Spine 和 DragonBones 等包含动态数据和材质的组件在内部管理 IA 并提交批次
+         * @param comp - The committed renderable component
+         * @param ia - The committed [[InputAssembler]]
+         * @param tex - The texture used
+         * @param mat - The material used
+         * @param [transform] - The related node transform if the render data is based on node's local coordinates
+         */
+        commitIA(renderComp: Renderable2D, ia: gfx.InputAssembler, tex?: __private._cocos_core_assets_texture_base__TextureBase, mat?: Material, transform?: Node): void;
+        /**
+         * @en
          * Render component data submission process of UI.
          * The submitted vertex data is the UI for local coordinates.
          * For example: The UI components of Graphics and UIModel.
          *
          * @zh
          * UI 渲染组件数据提交流程(针对例如: Graphics 和 UIModel 等数据量较为庞大的 ui 组件)。
          *
-         * @param comp - 当前执行组件。
-         * @param model - 提交渲染的 model 数据。
-         * @param mat - 提交渲染的材质。
+         * @param comp - The committed renderable component
+         * @param model - The committed model
+         * @param mat - The material used, could be null
          */
         commitModel(comp: UIMeshRenderer | Renderable2D, model: codec | null, mat: Material | null): void;
         setupStaticBatch(staticComp: UIStaticBatch, bufferAccessor: __private._cocos_2d_renderer_static_vb_accessor__StaticVBAccessor): void;
         endStaticBatch(): void;
@@ -3342,8 +3361,9 @@
          * @param material - 当前批次的材质。
          * @param sprite - 当前批次的精灵帧。
          */
         forceMergeBatches(material: Material, frame: __private._cocos_core_assets_texture_base__TextureBase | SpriteFrame | null, renderComp: Renderable2D): void;
+        resetRenderStates(): void;
         /**
          * @en
          * Forced to merge the data of the previous batch to start a new batch.
          *
@@ -27795,12 +27815,14 @@
         export interface ArmatureFrameSegment {
             indexCount: number;
             vfCount: number;
             vertexCount: number;
-            tex: __private._cocos_core_assets_texture_base__TextureBase;
+            tex: Texture2D;
             blendMode: BlendMode;
         }
         export class AnimationCache {
+            maxVertexCount: number;
+            maxIndexCount: number;
             _privateMode: boolean;
             _inited: boolean;
             _invalid: boolean;
             _enableCacheAttachedInfo: boolean;
@@ -27824,9 +27846,9 @@
             isInvalid(): boolean;
             invalidAllFrame(): void;
             updateAllFrame(): void;
             enableCacheAttachedInfo(): void;
-            _updateFrame(armature: any, index: any): void;
+            updateFrame(armature: any, index: any): void;
             _traverseArmature(armature: Armature, parentOpacity: any): void;
         }
         export class ArmatureCache {
             protected _privateMode: boolean;
@@ -27923,11 +27945,13 @@
              * @property {Number} PRIVATE_CACHE
              */
             PRIVATE_CACHE = 2
         }
-        export interface ArmatureDisplayMeshData {
-            renderData: MeshRenderData;
+        export interface ArmatureDisplayDrawData {
+            material: Material | null;
             texture: Texture2D | null;
+            indexOffset: number;
+            indexCount: number;
         }
         export class DragonBoneSocket {
             /**
              * @en Path of the target joint.
@@ -28059,9 +28083,9 @@
             set sockets(val: DragonBoneSocket[]);
             get socketNodes(): Map<string, Node>;
             _armature: Armature | null;
             attachUtil: AttachUtil;
-            get meshRenderDataArray(): ArmatureDisplayMeshData[];
+            get drawList(): memop.RecyclePool<ArmatureDisplayDrawData>;
             protected _defaultArmatureIndexValue: __private._cocos_dragon_bones_ArmatureDisplay__DefaultArmaturesEnum;
             _dragonAsset: DragonBonesAsset | null;
             _dragonAtlasAsset: DragonBonesAtlasAsset | null;
             _armatureName: string;
@@ -28074,19 +28098,43 @@
             protected _playTimes: number;
             protected _debugBones: boolean;
             _debugDraw: Graphics | null;
             _enableBatch: boolean;
+            /**
+             * @internal
+             */
             protected _armatureKey: string;
+            /**
+             * @internal
+             */
             protected _accTime: number;
+            /**
+             * @internal
+             */
             protected _playCount: number;
+            /**
+             * @internal
+             */
             protected _frameCache: AnimationCache | null;
+            /**
+             * @internal
+             */
             _curFrame: ArmatureFrame | null;
             protected _playing: boolean;
             protected _armatureCache: ArmatureCache | null;
             protected _eventTarget: EventTarget;
             protected _factory: CCFactory | null;
             protected _displayProxy: CCArmatureDisplay | null;
-            protected _meshRenderDataArray: ArmatureDisplayMeshData[];
+            protected _drawIdx: number;
+            protected _drawList: memop.RecyclePool<ArmatureDisplayDrawData>;
+            /**
+             * @internal
+             */
+            maxVertexCount: number;
+            /**
+             * @internal
+             */
+            maxIndexCount: number;
             protected _materialCache: {
                 [key: string]: renderer.MaterialInstance;
             };
             protected _enumArmatures: any;
@@ -28096,14 +28144,15 @@
             protected _sockets: DragonBoneSocket[];
             constructor();
             initFactory(): void;
             onLoad(): void;
-            requestMeshRenderData(): ArmatureDisplayMeshData;
+            /**
+             * @internal
+             */
+            _requestDrawData(material: Material, texture: Texture2D, indexOffset: number, indexCount: number): ArmatureDisplayDrawData;
             destroyRenderData(): void;
-            resetRenderData(): void;
             getMaterialForBlend(src: gfx.BlendFactor, dst: gfx.BlendFactor): renderer.MaterialInstance;
-            _meshRenderDataArrayIdx: number;
-            protected _render(ui: __private._cocos_2d_renderer_i_batcher__IBatcher): void;
+            protected _render(batcher: UI): void;
             _updateBatch(): void;
             _updateMaterial(): void;
             disableRender(): void;
             _validateRender(): boolean;
@@ -40292,11 +40341,13 @@
         export enum SpineMaterialType {
             COLORED_TEXTURED = 0,
             TWO_COLORED = 1
         }
-        export interface SkeletonMeshData {
-            renderData: MeshRenderData;
-            texture?: Texture2D;
+        export interface SkeletonDrawData {
+            material: Material | null;
+            texture: Texture2D | null;
+            indexOffset: number;
+            indexCount: number;
         }
         export class SpineSocket {
             /**
              * @en Path of the target joint.
@@ -40329,11 +40380,18 @@
          */
         export class Skeleton extends Renderable2D {
             static SpineSocket: typeof SpineSocket;
             static AnimationCacheMode: typeof AnimationCacheMode;
-            get meshRenderDataArray(): SkeletonMeshData[];
+            get drawList(): memop.RecyclePool<SkeletonDrawData>;
             get customMaterial(): Material | null;
             set customMaterial(val: Material | null);
+            /**
+             * @en The skeletal animation is paused?
+             * @zh 该骨骼动画是否暂停。
+             * @property paused
+             * @type {Boolean}
+             * @default false
+             */
             get paused(): boolean;
             set paused(value: boolean);
             /** dstBlendFactor
              * @en
@@ -40354,21 +40412,31 @@
              * @property {String} animation
              */
             get animation(): string;
             set animation(value: string);
+            /**
+             * @internal
+             */
             get _defaultSkinIndex(): number;
             set _defaultSkinIndex(value: number);
+            /**
+             * @internal
+             */
             get _animationIndex(): number;
             set _animationIndex(value: number);
             get defaultCacheMode(): AnimationCacheMode;
             set defaultCacheMode(mode: AnimationCacheMode);
             /**
-             * @en TODO
+             * @en Whether play animations in loop mode
              * @zh 是否循环播放当前骨骼动画。
              */
             loop: boolean;
             get premultipliedAlpha(): boolean;
             set premultipliedAlpha(v: boolean);
+            /**
+             * @en The time scale of this skeleton.
+             * @zh 当前骨骼中所有动画的时间缩放率。
+             */
             get timeScale(): number;
             set timeScale(value: number);
             /**
              * @en Indicates whether open debug slots.
@@ -40403,36 +40471,75 @@
              */
             get sockets(): SpineSocket[];
             set sockets(val: SpineSocket[]);
             get socketNodes(): Map<number, Node>;
+            enableBatch: boolean;
             /**
-             * @en Enabled batch model, if skeleton is complex, do not enable batch, or will lower performance.
-             * @zh 开启合批,如果渲染大量相同纹理,且结构简单的骨骼动画,开启合批可以降低drawcall,否则请不要开启,cpu消耗会上升。
+             * @internal
              */
-            enableBatch: boolean;
             _frameCache: __private._cocos_spine_skeleton_cache__AnimationCache | null;
+            /**
+             * @internal
+             */
             _curFrame: __private._cocos_spine_skeleton_cache__AnimationFrame | null;
+            /**
+             * @internal
+             */
             _effectDelegate: VertexEffectDelegate | null | undefined;
+            /**
+             * @internal
+             */
             _skeleton: spine.Skeleton | null;
+            /**
+             * @internal
+             */
             _clipper?: spine.SkeletonClipping;
+            /**
+             * @internal
+             */
             _debugRenderer: Graphics | null;
+            /**
+             * @internal
+             */
             _startSlotIndex: any;
+            /**
+             * @internal
+             */
             _endSlotIndex: any;
+            /**
+             * @internal
+             */
             _startEntry: any;
+            /**
+             * @internal
+             */
             _endEntry: any;
+            /**
+             * @internal
+             */
             attachUtil: __private._cocos_spine_attach_util__AttachUtil;
+            /**
+             * @internal
+             */
+            maxVertexCount: number;
+            /**
+             * @internal
+             */
+            maxIndexCount: number;
             protected _materialCache: {
                 [key: string]: renderer.MaterialInstance;
             };
             protected _enumSkins: any;
             protected _enumAnimations: any;
+            protected _playTimes: number;
+            protected _timeScale: number;
+            protected _paused: boolean;
             protected _accTime: number;
             protected _playCount: number;
             protected _skeletonCache: __private._cocos_spine_skeleton_cache__SkeletonCache | null;
             protected _animationName: string;
             protected _animationQueue: __private._cocos_spine_skeleton__AnimationItem[];
             protected _headAniInfo: __private._cocos_spine_skeleton__AnimationItem | null;
-            protected _playTimes: number;
             protected _isAniComplete: boolean;
             protected _useTint: boolean;
             protected _preCacheMode: number;
             protected _cacheMode: AnimationCacheMode;
@@ -40440,8 +40547,16 @@
             protected _debugBones: boolean;
             protected _debugSlots: boolean;
             protected _skeletonData: SkeletonData | null;
             /**
+             * @en Indicates whether to enable premultiplied alpha.
+             * You should disable this option when image's transparent area appears to have opaque pixels,
+             * or enable this option when image's half transparent area appears to be darken.
+             * @zh 是否启用贴图预乘。
+             * 当图片的透明区域出现色块时需要关闭该选项,当图片的半透明区域颜色变黑时需要启用该选项。
+             */
+            protected _premultipliedAlpha: boolean;
+            /**
              * @en The name of default skin.
              * @zh 默认的皮肤名称。
              * @property {String} defaultSkin
              */
@@ -40452,9 +40567,10 @@
              * @property {String} defaultAnimation
              */
             protected defaultAnimation: string;
             protected _sockets: SpineSocket[];
-            protected _meshRenderDataArray: SkeletonMeshData[];
+            protected _drawIdx: number;
+            protected _drawList: memop.RecyclePool<SkeletonDrawData>;
             protected _debugMesh: boolean;
             protected _rootBone: spine.Bone | null;
             protected _state?: spine.AnimationState;
             protected _listener: spine.AnimationStateListener | null;
@@ -40801,17 +40917,19 @@
             getState(): spine.AnimationState | undefined;
             onEnable(): void;
             onDisable(): void;
             onDestroy(): void;
-            requestMeshRenderData(vertexFormat: gfx.Attribute[]): SkeletonMeshData;
             destroyRenderData(): void;
             getMaterialForBlendAndTint(src: gfx.BlendFactor, dst: gfx.BlendFactor, type: SpineMaterialType): renderer.MaterialInstance;
             onRestore(): void;
             protected updateMaterial(): void;
             querySockets(): string[];
-            _meshRenderDataArrayIdx: number;
-            protected _render(ui: __private._cocos_2d_renderer_i_batcher__IBatcher): void;
             /**
+             * @internal
+             */
+            _requestDrawData(material: Material, texture: Texture2D, indexOffset: number, indexCount: number): SkeletonDrawData;
+            protected _render(batcher: UI): void;
+            /**
              * @en Computes the world SRT from the local SRT for each bone.
              * @zh 重新更新所有骨骼的世界 Transform,
              * 当获取 bone 的数值未更新时,即可使用该函数进行更新数值。
              * @method updateWorldTransform
@@ -46139,16 +46257,17 @@
             uploadBuffers(): void;
             destroy(): void;
         }
         export class _cocos_2d_renderer_static_vb_accessor__StaticVBAccessor extends _cocos_2d_renderer_buffer_accessor__BufferAccessor {
-            constructor(device: gfx.Device, attributes: gfx.Attribute[]);
+            static IB_SCALE: number;
+            constructor(device: gfx.Device, attributes: gfx.Attribute[], vCount?: number, iCount?: number);
             destroy(): void;
             reset(): void;
             getVertexBuffer(bid: number): Float32Array;
             getIndexBuffer(bid: number): Uint16Array;
             getMeshBuffer(bid: number): MeshBuffer;
             uploadBuffers(): void;
-            appendIndices(vbChunk: _cocos_2d_renderer_static_vb_accessor__StaticVBChunk): void;
+            appendIndices(bufferId: number, indices: Uint16Array): void;
             allocateChunk(vertexCount: number, indexCount: number): _cocos_2d_renderer_static_vb_accessor__StaticVBChunk | null;
             recycleChunk(chunk: _cocos_2d_renderer_static_vb_accessor__StaticVBChunk): void;
         }
         export interface _cocos_2d_renderer_i_batcher__IBatcher {
@@ -46887,9 +47006,9 @@
              * @zh
              * UI实例
              * 引擎内部使用,用户无需调用此接口
              */
-            get batcher2D(): _cocos_2d_renderer_i_batcher__IBatcher;
+            get batcher2D(): UI;
             /**
              * @zh
              * 场景列表
              */
@@ -52805,8 +52924,10 @@
         export class _cocos_spine_skeleton_cache__AnimationCache {
             frames: _cocos_spine_skeleton_cache__AnimationFrame[];
             totalTime: number;
             isCompleted: boolean;
+            maxVertexCount: number;
+            maxIndexCount: number;
             _privateMode: boolean;
             protected _inited: boolean;
             protected _invalid: boolean;
             protected _enableCacheAttachedInfo: boolean;

cocos/2d/assembler/utils.ts Show resolved Hide resolved
if (renderComp) {
blendState = renderComp.blendHash === -1 ? null : renderComp.getBlendState();
bsHash = renderComp.blendHash;
if (renderComp.customMaterial !== null) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

为啥要在这里判断,组件层里面不能处理好么

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这是在设置 depthStencil 状态,是和节点树遍历相关的,所以需要在 batcher 里面做

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

有自定义材质和没有材质是什么区别

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个我不确定,是之前的逻辑遗留下来的,应该是取 material instance 的方法不一样

@@ -544,7 +592,13 @@ export class Skeleton extends Renderable2D {
@serializable
protected _sockets: SpineSocket[] = [];

protected _meshRenderDataArray: SkeletonMeshData[] = [];
protected _drawIdx = 0;
protected _drawList = new RecyclePool<SkeletonDrawData>(() => ({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

每个组件都有个池子?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里池子只有 1 还好,确实可以复用,但是不好做全局的重置

cocos/spine/assembler/simple.ts Outdated Show resolved Hide resolved
* Shared vb accessor for dragonbones

* fix code style

* add explanation why need resize render data in realTimeTraverse
@pandamicro pandamicro merged commit 50a43e1 into cocos:v3.4.2 Feb 18, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants