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

spine/dragonbones support batch mode in web platform #12847

Merged
merged 5 commits into from
Sep 26, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 75 additions & 31 deletions cocos/2d/renderer/batcher-2d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,13 @@ export class Batcher2D implements IBatcher {
private _currIsStatic = false;
private _currHash = 0;

//for middleware
private _currIsMiddleware = false;
private _middlewareEnableBatch = false;
private _middlewareBuffer: MeshBuffer | null = null;
private _middlewareIndexStart = 0;
private _middlewareIndexCount = 0;

private _pOpacity = 1;
private _opacityDirty = 0;

Expand Down Expand Up @@ -426,46 +433,49 @@ export class Batcher2D implements IBatcher {

/**
* @en
* Render component data submission process for individual [[gfx.InputAssembler]]
* Render component data submission process for middleware2d components
* @zh
* 渲染组件中针对独立 [[gfx.InputAssembler]] 的提交流程
* 例如:Spine 和 DragonBones 等包含动态数据和材质的组件在内部管理 IA 并提交批次
* 渲染组件中针对2D中间件组件渲染数据的提交流程
* 例如:Spine 和 DragonBones 包含动态数据和材质的组件
* @param comp - The committed renderable component
* @param ia - The committed [[gfx.InputAssembler]]
* @param meshBuffer - The MeshBuffer used
* @param indexOffset - indices offset
* @param indexCount - indices count
* @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
* @param enableBatch - component support multi draw batch or not
*/
public commitIA (renderComp: UIRenderer, ia: InputAssembler, tex?: TextureBase, mat?: Material, transform?: Node) {
// if the last comp is spriteComp, previous comps should be batched.
if (this._currMaterial !== this._emptyMaterial) {
public commitMiddleware (comp: UIRenderer, meshBuffer: MeshBuffer, indexOffset: number,
indexCount: number, tex: TextureBase, mat: Material, enableBatch: boolean) {
// check if need merge draw batch
const texture = tex.getGFXTexture();
if (enableBatch && this._middlewareEnableBatch && this._middlewareBuffer === meshBuffer
&& this._currTexture === texture
&& this._currMaterial.hash === mat.hash
&& this._middlewareIndexStart + this._middlewareIndexCount === indexOffset
&& this._currLayer === comp.node.layer) {
this._middlewareIndexCount += indexCount;
} else {
this.autoMergeBatches(this._currComponent!);
this.resetRenderStates();
}
let depthStencil;
let dssHash = 0;
if (renderComp) {
renderComp.stencilStage = StencilManager.sharedManager!.stage;
if (renderComp.customMaterial !== null) {
depthStencil = StencilManager.sharedManager!.getStencilStage(renderComp.stencilStage, mat);
} else {
depthStencil = StencilManager.sharedManager!.getStencilStage(renderComp.stencilStage);
}
dssHash = StencilManager.sharedManager!.getStencilHash(renderComp.stencilStage);
}

const curDrawBatch = this._currStaticRoot ? this._currStaticRoot._requireDrawBatch() : this._drawBatchPool.alloc();
curDrawBatch.visFlags = renderComp.node.layer;
curDrawBatch.inputAssembler = ia;
curDrawBatch.useLocalData = transform || null;
if (tex) {
curDrawBatch.texture = tex.getGFXTexture();
curDrawBatch.sampler = tex.getGFXSampler();
curDrawBatch.textureHash = tex.getHash();
curDrawBatch.samplerHash = curDrawBatch.sampler.hash;
this._currComponent = comp;
this._currTexture = texture;
this._currSampler = tex.getGFXSampler();
this._currTextureHash = tex.getHash();
this._currLayer = comp.node.layer;
this._currSamplerHash = this._currSampler.hash;
this._currHash = 0;
this._currTransform = enableBatch ? null : comp.node;

this._middlewareEnableBatch = enableBatch;
this._middlewareBuffer = meshBuffer;
this._currMaterial = mat;
this._middlewareIndexStart = indexOffset;
this._middlewareIndexCount = indexCount;
}
curDrawBatch.fillPasses(mat || null, depthStencil, dssHash, null);
this._batches.push(curDrawBatch);

this._currIsMiddleware = true;
}

/**
Expand Down Expand Up @@ -561,6 +571,10 @@ export class Batcher2D implements IBatcher {
* 根据合批条件,结束一段渲染数据并提交。
*/
public autoMergeBatches (renderComp?: UIRenderer) {
if (this._currIsMiddleware) {
this.mergeBatchesForMiddleware(renderComp!);
return;
}
const mat = this._currMaterial;
if (!mat) {
return;
Expand Down Expand Up @@ -623,6 +637,36 @@ export class Batcher2D implements IBatcher {
this._batches.push(curDrawBatch);
}

private mergeBatchesForMiddleware (renderComp: UIRenderer) {
let depthStencil;
let dssHash = 0;
renderComp.stencilStage = StencilManager.sharedManager!.stage;
if (renderComp.customMaterial !== null) {
depthStencil = StencilManager.sharedManager!.getStencilStage(renderComp.stencilStage, this._currMaterial);
} else {
depthStencil = StencilManager.sharedManager!.getStencilStage(renderComp.stencilStage);
}
dssHash = StencilManager.sharedManager!.getStencilHash(renderComp.stencilStage);

const curDrawBatch = this._currStaticRoot ? this._currStaticRoot._requireDrawBatch() : this._drawBatchPool.alloc();
curDrawBatch.visFlags = renderComp.node.layer;
const ia = this._middlewareBuffer!.requireFreeIA(this.device);
ia.firstIndex = this._middlewareIndexStart;
ia.indexCount = this._middlewareIndexCount;

curDrawBatch.inputAssembler = ia;
curDrawBatch.useLocalData = this._currTransform;
curDrawBatch.texture = this._currTexture;
curDrawBatch.sampler = this._currSampler;
curDrawBatch.textureHash = this._currTextureHash;
curDrawBatch.samplerHash = this._currSamplerHash;
curDrawBatch.fillPasses(this._currMaterial || null, depthStencil, dssHash, null);
this._batches.push(curDrawBatch);

this._currIsMiddleware = false;
this._middlewareBuffer = null;
}

/**
* @en
* Force changes to current batch data and merge
Expand Down
14 changes: 6 additions & 8 deletions cocos/dragon-bones/ArmatureDisplay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -639,27 +639,25 @@ export class ArmatureDisplay extends UIRenderer {
}

protected _render (batcher: Batcher2D) {
let indicesCount = 0;
if (this.renderData && this._drawList) {
const rd = this.renderData;
const chunk = rd.chunk;
const accessor = chunk.vertexAccessor;
const meshBuffer = rd.getMeshBuffer()!;
const origin = meshBuffer.indexOffset;
// Fill index buffer
accessor.appendIndices(chunk.bufferId, rd.indices!);
for (let i = 0; i < this._drawList.length; i++) {
this._drawIdx = i;
const dc = this._drawList.data[i];
if (dc.texture) {
// Construct IA
const ia = meshBuffer.requireFreeIA(batcher.device);
ia.firstIndex = origin + dc.indexOffset;
ia.indexCount = dc.indexCount;
// Commit IA
batcher.commitIA(this, ia, dc.texture, dc.material!, this.node);
batcher.commitMiddleware(this, meshBuffer, origin + dc.indexOffset,
dc.indexCount, dc.texture, dc.material!, this._enableBatch);
}
indicesCount += dc.indexCount;
}
// this.node._static = true;
const subIndices = rd.indices!.subarray(0, indicesCount);
accessor.appendIndices(chunk.bufferId, subIndices);
}
}

Expand Down
14 changes: 6 additions & 8 deletions cocos/spine/skeleton.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1432,27 +1432,25 @@ export class Skeleton extends UIRenderer {
}

protected _render (batcher: Batcher2D) {
let indicesCount = 0;
if (this.renderData && this._drawList) {
const rd = this.renderData;
const chunk = rd.chunk;
const accessor = chunk.vertexAccessor;
const meshBuffer = rd.getMeshBuffer()!;
const origin = meshBuffer.indexOffset;
// Fill index buffer
accessor.appendIndices(chunk.bufferId, rd.indices!);
for (let i = 0; i < this._drawList.length; i++) {
this._drawIdx = i;
const dc = this._drawList.data[i];
if (dc.texture) {
// Construct IA
const ia = meshBuffer.requireFreeIA(batcher.device);
ia.firstIndex = origin + dc.indexOffset;
ia.indexCount = dc.indexCount;
// Commit IA
batcher.commitIA(this, ia, dc.texture, dc.material!, this.node);
batcher.commitMiddleware(this, meshBuffer, origin + dc.indexOffset,
dc.indexCount, dc.texture, dc.material!, this._enableBatch);
}
indicesCount += dc.indexCount;
}
// this.node._static = true;
const subIndices = rd.indices!.subarray(0, indicesCount);
accessor.appendIndices(chunk.bufferId, subIndices);
}
}

Expand Down