From ef6f7db13d73b89b5338b7a21f969965d4b00ece Mon Sep 17 00:00:00 2001 From: "zhefeng.zhang" <35944775+zhefengzhang@users.noreply.github.com> Date: Fri, 12 Sep 2025 15:55:46 +0800 Subject: [PATCH 01/10] Supports configuring a larger BATCHER2D_MEM_INCREMENT --- cocos/2d/renderer/mesh-buffer.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/cocos/2d/renderer/mesh-buffer.ts b/cocos/2d/renderer/mesh-buffer.ts index 79f953d11d2..6e500c210bf 100644 --- a/cocos/2d/renderer/mesh-buffer.ts +++ b/cocos/2d/renderer/mesh-buffer.ts @@ -27,6 +27,11 @@ import { Device, BufferUsageBit, MemoryUsageBit, Attribute, Buffer, BufferInfo, import { getAttributeStride } from './vertex-format'; import { sys, getError, warnID, assertIsTrue } from '../../core'; import { NativeUIMeshBuffer } from './native-2d'; +import { Feature } from '../../gfx/base/define'; +import { director } from '../../game'; +import { WebGLDevice } from '../../gfx/webgl/webgl-device'; +import { WebGL2Device } from '../../gfx/webgl2/webgl2-device'; +import { WebGPUDevice } from '../../gfx/webgpu/webgpu-device'; interface IIARef { ia: InputAssembler; @@ -251,7 +256,14 @@ export class MeshBuffer { this.floatsPerVertex = getAttributeStride(attrs) >> 2; - assertIsTrue(this._initVDataCount / this._floatsPerVertex < 65536, getError(9005)); + var vDataCountLimit = 65536; // 2^16 - 1 + if (director.root) { + if ( director.root.device instanceof WebGPUDevice || director.root.device instanceof WebGL2Device + || director.root.device instanceof WebGLDevice && director.root.device.hasFeature(Feature.ELEMENT_INDEX_UINT)) { + vDataCountLimit = 4294967295; // 2^32 - 1 + } + } + assertIsTrue(this._initVDataCount / this._floatsPerVertex < vDataCountLimit, getError(9005)); if (!this.vData || !this.iData) { this.vData = new Float32Array(this._initVDataCount); From 255fe2a42515f5f0fffcd90dafd3e0cfd667b15d Mon Sep 17 00:00:00 2001 From: "zhefeng.zhang" <35944775+zhefengzhang@users.noreply.github.com> Date: Fri, 12 Sep 2025 16:02:19 +0800 Subject: [PATCH 02/10] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20BATCHER2D=5FMEM=5FIN?= =?UTF-8?q?CREMENT=20=E9=85=8D=E7=BD=AE=E7=9A=84=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cocos/core/platform/macro.ts | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/cocos/core/platform/macro.ts b/cocos/core/platform/macro.ts index 9d91165fc90..05b6d63c619 100644 --- a/cocos/core/platform/macro.ts +++ b/cocos/core/platform/macro.ts @@ -1066,17 +1066,25 @@ interface Macro { ENABLE_WEBGL_HIGHP_STRUCT_VALUES: boolean; /** - * @zh Batcher2D 中内存增量的大小(KB) - * 这个值决定了当场景中存在的 2d 渲染组件的顶点数量超过当前 batcher2D 中可容纳的顶点数量时,内存扩充的增加量 - * 这个值越大,共用同一个 meshBuffer 的 2d 渲染组件数量会更多,但每次扩充所占用的内存也会更大 - * 默认值在标准格式([[VertexFormat.vfmtPosUvColor]])下可容纳 4096 个顶点(4096*9*4/1024),你可以增加容量来提升每个批次可容纳的元素数量 - * @en The MeshBuffer chunk size in Batcher2D (KB) - * This value determines the increase in memory expansion, - * when the number of vertices of 2d rendering components present in the scene exceeds the number of vertices, - * that can be accommodated in the current batcher2D. - * The larger this value is, the more 2d rendering components will share the same meshBuffer, but the more memory will be used for each expansion - * The default size can contain 4096 standard vertex ([[VertexFormat.vfmtPosUvColor]]) in one buffer, - * you can user larger buffer size to increase the elements count per 2d draw batch. + * @zh Batcher2D 中每个渲染批次的内存增量(KB) + * 增大此值能使参与渲染合批的 2d 渲染组件数量增加,但是每次增加渲染批次的内存增量也会变大。 + * 这个值决定每个 2D 渲染批次的顶点数量,计算公式为 vCount = Math.floor(macro.BATCHER2D_MEM_INCREMENT * 1024 / 9 * 4); + * WebGL2 & WebGPU 等渲染后端的最大顶点数量通常是 2^32 - 1,即 4294967295。 + * WebGL1 渲染后端的最大顶点数量通常是 2^16 - 1,即 65535。引擎使用拓展 OES_element_index_uint 突破了这个限制,最大顶点数量也可达到 2^32 - 1。 + * 所以 macro.BATCHER2D_MEM_INCREMENT 的理论最大值为 150994943,但是因为所运行平台的 js 引擎对 Float32Array|Uint16Array 的最大长度有限制,实际最大值往往会小于 2^32 - 1。 + * 建议最大值不超过 1048576 kb (1GB),否则会因为 js 引擎的限制而导致 buffer 创建失败。 + * @en Memory increment (KB) for each rendering batch in Batcher2D + * Increasing this value can increase the number of 2D rendering components involved in rendering batching, but the memory increment for each additional rendering batch will also become larger. + * This value determines the number of vertices in each 2D rendering batch, calculated as vCount = Math.floor(macro.BATCHER2D_MEM_INCREMENT * 1024 / 9 * 4); + * The maximum number of vertices for rendering backends such as WebGL2 & WebGPU is usually 2^32 - 1, which is 4294967295. + * The maximum number of vertices for the WebGL1 rendering backend is usually 2^16 - 1, which is 65535. The engine uses the extension OES_element_index_uint to break this limit, and the maximum number of vertices can also reach 2^32 - 1. + * Therefore, the theoretical maximum value of macro.BATCHER2D_MEM_INCREMENT is 150994943. However, due to the limitations of the JS engine on the maximum length of Float32Array|Uint16Array on the running platform, the actual maximum value is often less than 2^32 - 1. + * It is recommended that the maximum value does not exceed 1048576 kb (1GB); otherwise, buffer creation will fail due to JS engine limitations. + * @example + * ```typescript + * import { macro } from 'cc'; + * macro.BATCHER2D_MEM_INCREMENT = 4096; //4096 KB + * ``` * @default 144 KB */ BATCHER2D_MEM_INCREMENT: number; From 4ed38e71639d49dceeabcc5fb7bd398eb3ea512f Mon Sep 17 00:00:00 2001 From: "zhefeng.zhang" <35944775+zhefengzhang@users.noreply.github.com> Date: Tue, 16 Sep 2025 17:25:44 +0800 Subject: [PATCH 03/10] Update mesh-buffer.ts --- cocos/2d/renderer/mesh-buffer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cocos/2d/renderer/mesh-buffer.ts b/cocos/2d/renderer/mesh-buffer.ts index 6e500c210bf..cc0bded77eb 100644 --- a/cocos/2d/renderer/mesh-buffer.ts +++ b/cocos/2d/renderer/mesh-buffer.ts @@ -258,7 +258,7 @@ export class MeshBuffer { var vDataCountLimit = 65536; // 2^16 - 1 if (director.root) { - if ( director.root.device instanceof WebGPUDevice || director.root.device instanceof WebGL2Device + if (director.root.device instanceof WebGPUDevice || director.root.device instanceof WebGL2Device || director.root.device instanceof WebGLDevice && director.root.device.hasFeature(Feature.ELEMENT_INDEX_UINT)) { vDataCountLimit = 4294967295; // 2^32 - 1 } From 58d6f3068d292a886ae5c05e2c6ac74536e085d7 Mon Sep 17 00:00:00 2001 From: "zhefeng.zhang" <35944775+zhefengzhang@users.noreply.github.com> Date: Tue, 16 Sep 2025 17:45:34 +0800 Subject: [PATCH 04/10] Update mesh-buffer.ts --- cocos/2d/renderer/mesh-buffer.ts | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/cocos/2d/renderer/mesh-buffer.ts b/cocos/2d/renderer/mesh-buffer.ts index cc0bded77eb..868791a1a95 100644 --- a/cocos/2d/renderer/mesh-buffer.ts +++ b/cocos/2d/renderer/mesh-buffer.ts @@ -29,9 +29,6 @@ import { sys, getError, warnID, assertIsTrue } from '../../core'; import { NativeUIMeshBuffer } from './native-2d'; import { Feature } from '../../gfx/base/define'; import { director } from '../../game'; -import { WebGLDevice } from '../../gfx/webgl/webgl-device'; -import { WebGL2Device } from '../../gfx/webgl2/webgl2-device'; -import { WebGPUDevice } from '../../gfx/webgpu/webgpu-device'; interface IIARef { ia: InputAssembler; @@ -258,10 +255,10 @@ export class MeshBuffer { var vDataCountLimit = 65536; // 2^16 - 1 if (director.root) { - if (director.root.device instanceof WebGPUDevice || director.root.device instanceof WebGL2Device - || director.root.device instanceof WebGLDevice && director.root.device.hasFeature(Feature.ELEMENT_INDEX_UINT)) { + if (director.root.device.gfxAPI === gfx.API.WEBGPU || director.root.device.gfxAPI === gfx.API.WEBGL2 + || director.root.device.gfxAPI === gfx.API.WEBGL && director.root.device.hasFeature(Feature.ELEMENT_INDEX_UINT)) { vDataCountLimit = 4294967295; // 2^32 - 1 - } + } } assertIsTrue(this._initVDataCount / this._floatsPerVertex < vDataCountLimit, getError(9005)); From adc5e76b648f63f2c9b0d98134cbdc8890ab4e46 Mon Sep 17 00:00:00 2001 From: "zhefeng.zhang" <35944775+zhefengzhang@users.noreply.github.com> Date: Wed, 17 Sep 2025 10:13:51 +0800 Subject: [PATCH 05/10] Update mesh-buffer.ts --- cocos/2d/renderer/mesh-buffer.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/cocos/2d/renderer/mesh-buffer.ts b/cocos/2d/renderer/mesh-buffer.ts index 868791a1a95..dbb92b539b6 100644 --- a/cocos/2d/renderer/mesh-buffer.ts +++ b/cocos/2d/renderer/mesh-buffer.ts @@ -25,10 +25,9 @@ import { JSB } from 'internal:constants'; import { Device, BufferUsageBit, MemoryUsageBit, Attribute, Buffer, BufferInfo, InputAssembler, InputAssemblerInfo } from '../../gfx'; import { getAttributeStride } from './vertex-format'; -import { sys, getError, warnID, assertIsTrue } from '../../core'; +import { cclegacy, sys, getError, warnID, assertIsTrue } from '../../core'; import { NativeUIMeshBuffer } from './native-2d'; import { Feature } from '../../gfx/base/define'; -import { director } from '../../game'; interface IIARef { ia: InputAssembler; @@ -254,9 +253,9 @@ export class MeshBuffer { this.floatsPerVertex = getAttributeStride(attrs) >> 2; var vDataCountLimit = 65536; // 2^16 - 1 - if (director.root) { - if (director.root.device.gfxAPI === gfx.API.WEBGPU || director.root.device.gfxAPI === gfx.API.WEBGL2 - || director.root.device.gfxAPI === gfx.API.WEBGL && director.root.device.hasFeature(Feature.ELEMENT_INDEX_UINT)) { + if (cclegacy.director.root) { + if (cclegacy.director.root.device.gfxAPI === cclegacy.gfx.API.WEBGPU || cclegacy.director.root.device.gfxAPI === cclegacy.gfx.API.WEBGL2 + || cclegacy.director.root.device.gfxAPI === cclegacy.gfx.API.WEBGL && cclegacy.director.root.device.hasFeature(Feature.ELEMENT_INDEX_UINT)) { vDataCountLimit = 4294967295; // 2^32 - 1 } } From bf3830d8cd77bbd702b803707d94bdca53a6f6ee Mon Sep 17 00:00:00 2001 From: "zhefeng.zhang" <35944775+zhefengzhang@users.noreply.github.com> Date: Wed, 17 Sep 2025 10:58:42 +0800 Subject: [PATCH 06/10] Update mesh-buffer.ts --- cocos/2d/renderer/mesh-buffer.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/cocos/2d/renderer/mesh-buffer.ts b/cocos/2d/renderer/mesh-buffer.ts index dbb92b539b6..bde01a49a41 100644 --- a/cocos/2d/renderer/mesh-buffer.ts +++ b/cocos/2d/renderer/mesh-buffer.ts @@ -23,11 +23,10 @@ */ import { JSB } from 'internal:constants'; -import { Device, BufferUsageBit, MemoryUsageBit, Attribute, Buffer, BufferInfo, InputAssembler, InputAssemblerInfo } from '../../gfx'; +import { Device, BufferUsageBit, MemoryUsageBit, Attribute, Buffer, BufferInfo, InputAssembler, InputAssemblerInfo, Feature, API } from '../../gfx'; import { getAttributeStride } from './vertex-format'; import { cclegacy, sys, getError, warnID, assertIsTrue } from '../../core'; import { NativeUIMeshBuffer } from './native-2d'; -import { Feature } from '../../gfx/base/define'; interface IIARef { ia: InputAssembler; @@ -254,8 +253,8 @@ export class MeshBuffer { var vDataCountLimit = 65536; // 2^16 - 1 if (cclegacy.director.root) { - if (cclegacy.director.root.device.gfxAPI === cclegacy.gfx.API.WEBGPU || cclegacy.director.root.device.gfxAPI === cclegacy.gfx.API.WEBGL2 - || cclegacy.director.root.device.gfxAPI === cclegacy.gfx.API.WEBGL && cclegacy.director.root.device.hasFeature(Feature.ELEMENT_INDEX_UINT)) { + if (cclegacy.director.root.device.gfxAPI === API.WEBGPU || cclegacy.director.root.device.gfxAPI === API.WEBGL2 + || cclegacy.director.root.device.gfxAPI === API.WEBGL && cclegacy.director.root.device.hasFeature(Feature.ELEMENT_INDEX_UINT)) { vDataCountLimit = 4294967295; // 2^32 - 1 } } From 9ea4629294d92f144eee7626008cc18f0e81ff0f Mon Sep 17 00:00:00 2001 From: "zhefeng.zhang" <35944775+zhefengzhang@users.noreply.github.com> Date: Thu, 25 Sep 2025 10:14:28 +0800 Subject: [PATCH 07/10] Update mesh-buffer.ts --- cocos/2d/renderer/mesh-buffer.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cocos/2d/renderer/mesh-buffer.ts b/cocos/2d/renderer/mesh-buffer.ts index bde01a49a41..f7c26243917 100644 --- a/cocos/2d/renderer/mesh-buffer.ts +++ b/cocos/2d/renderer/mesh-buffer.ts @@ -252,9 +252,10 @@ export class MeshBuffer { this.floatsPerVertex = getAttributeStride(attrs) >> 2; var vDataCountLimit = 65536; // 2^16 - 1 - if (cclegacy.director.root) { - if (cclegacy.director.root.device.gfxAPI === API.WEBGPU || cclegacy.director.root.device.gfxAPI === API.WEBGL2 - || cclegacy.director.root.device.gfxAPI === API.WEBGL && cclegacy.director.root.device.hasFeature(Feature.ELEMENT_INDEX_UINT)) { + const root = cclegacy.director.root; + if (root) { + const glApi = root.device.gfxAPI; + if (glApi === API.WEBGPU || glApi === API.WEBGL2 || glApi === API.WEBGL && root.device.hasFeature(Feature.ELEMENT_INDEX_UINT)) { vDataCountLimit = 4294967295; // 2^32 - 1 } } From 942c9d62d1bcccaeb8f546e9ae974338bcf4057a Mon Sep 17 00:00:00 2001 From: "zhefeng.zhang" <35944775+zhefengzhang@users.noreply.github.com> Date: Thu, 25 Sep 2025 10:19:08 +0800 Subject: [PATCH 08/10] Update mesh-buffer.ts --- cocos/2d/renderer/mesh-buffer.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/cocos/2d/renderer/mesh-buffer.ts b/cocos/2d/renderer/mesh-buffer.ts index f7c26243917..e5e190d5ada 100644 --- a/cocos/2d/renderer/mesh-buffer.ts +++ b/cocos/2d/renderer/mesh-buffer.ts @@ -252,10 +252,9 @@ export class MeshBuffer { this.floatsPerVertex = getAttributeStride(attrs) >> 2; var vDataCountLimit = 65536; // 2^16 - 1 - const root = cclegacy.director.root; - if (root) { - const glApi = root.device.gfxAPI; - if (glApi === API.WEBGPU || glApi === API.WEBGL2 || glApi === API.WEBGL && root.device.hasFeature(Feature.ELEMENT_INDEX_UINT)) { + if (device) { + const glApi = device.gfxAPI; + if (glApi === API.WEBGPU || glApi === API.WEBGL2 || glApi === API.WEBGL && device.hasFeature(Feature.ELEMENT_INDEX_UINT)) { vDataCountLimit = 4294967295; // 2^32 - 1 } } From ac0d98f320a0b1bb7def9cb6b2688aad59d3412b Mon Sep 17 00:00:00 2001 From: "zhefeng.zhang" <35944775+zhefengzhang@users.noreply.github.com> Date: Thu, 25 Sep 2025 10:19:43 +0800 Subject: [PATCH 09/10] Update mesh-buffer.ts --- cocos/2d/renderer/mesh-buffer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cocos/2d/renderer/mesh-buffer.ts b/cocos/2d/renderer/mesh-buffer.ts index e5e190d5ada..e8b855d6681 100644 --- a/cocos/2d/renderer/mesh-buffer.ts +++ b/cocos/2d/renderer/mesh-buffer.ts @@ -25,7 +25,7 @@ import { JSB } from 'internal:constants'; import { Device, BufferUsageBit, MemoryUsageBit, Attribute, Buffer, BufferInfo, InputAssembler, InputAssemblerInfo, Feature, API } from '../../gfx'; import { getAttributeStride } from './vertex-format'; -import { cclegacy, sys, getError, warnID, assertIsTrue } from '../../core'; +import { sys, getError, warnID, assertIsTrue } from '../../core'; import { NativeUIMeshBuffer } from './native-2d'; interface IIARef { From a4cffb52053a4a7e50ae6dacede336364513e811 Mon Sep 17 00:00:00 2001 From: "zhefeng.zhang" <35944775+zhefengzhang@users.noreply.github.com> Date: Thu, 25 Sep 2025 10:23:42 +0800 Subject: [PATCH 10/10] Update mesh-buffer.ts --- cocos/2d/renderer/mesh-buffer.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/cocos/2d/renderer/mesh-buffer.ts b/cocos/2d/renderer/mesh-buffer.ts index e8b855d6681..6800dcb907a 100644 --- a/cocos/2d/renderer/mesh-buffer.ts +++ b/cocos/2d/renderer/mesh-buffer.ts @@ -252,11 +252,9 @@ export class MeshBuffer { this.floatsPerVertex = getAttributeStride(attrs) >> 2; var vDataCountLimit = 65536; // 2^16 - 1 - if (device) { - const glApi = device.gfxAPI; - if (glApi === API.WEBGPU || glApi === API.WEBGL2 || glApi === API.WEBGL && device.hasFeature(Feature.ELEMENT_INDEX_UINT)) { - vDataCountLimit = 4294967295; // 2^32 - 1 - } + const glApi = device.gfxAPI; + if (glApi === API.WEBGPU || glApi === API.WEBGL2 || glApi === API.WEBGL && device.hasFeature(Feature.ELEMENT_INDEX_UINT)) { + vDataCountLimit = 4294967295; // 2^32 - 1 } assertIsTrue(this._initVDataCount / this._floatsPerVertex < vDataCountLimit, getError(9005));