更新计算 vDataCountLimit 的逻辑.#19105
Conversation
There was a problem hiding this comment.
Additional Comments (3)
-
cocos/2d/renderer/mesh-buffer.ts, line 254-259 (link)logic: Unit mismatch in comparison:
vDataCountLimitis in floats but compared against vertex countvDataCountLimit = macro.BATCHER2D_MEM_INCREMENT * 256calculates max float count (KB * 1024 / 4 bytes per float).But line 259 compares
this._initVDataCount / this._floatsPerVertex(vertex count) againstvDataCountLimit(float count).Fix by dividing by
this._floatsPerVertex: -
cocos/2d/renderer/mesh-buffer.ts, line 259 (link)logic: Should use
<=instead of<since exactly reaching the limit is valid (65536 vertices with indices 0-65535 fits in 16-bit indices) -
cocos/2d/renderer/mesh-buffer.ts, line 254 (link)style: Error message 9005 in
EngineErrorMap.md:3190assumes fixed 9 floats per vertex, but actual vertex format varies. Consider updating error message to reflect dynamicfloatsPerVertex.
1 file reviewed, 3 comments
Code Size Check Report
Interface Check ReportThis pull request does not change any public interfaces ! |
详见 #19104 中的讨论
Re: #
Changelog
Continuous Integration
This pull request:
Compatibility Check
This pull request:
Greptile Summary
This PR refactors the
vDataCountLimitcalculation inMeshBuffer.initialize()to address issues identified in #19104:Key Changes:
<(not<=), 65536 is correct to allow vertices 0-65535. The new comment correctly states "2^16"macro.BATCHER2D_MEM_INCREMENT * 256, which represents the maximum float count that fits in the allocated memoryhasFeature(ELEMENT_INDEX_UINT)check, which is cleaner and more maintainableAPIenum import since it's no longer neededHow it works:
The new formula
vDataCountLimit = macro.BATCHER2D_MEM_INCREMENT * 256calculates the total number of floats that fit in memory (sinceBATCHER2D_MEM_INCREMENTis in KB, and each float is 4 bytes:KB * 1024 / 4 = KB * 256). For devices withoutELEMENT_INDEX_UINTsupport, this is capped at 65536 vertices (the Uint16 index limit). The assertioninitVDataCount / floatsPerVertex < vDataCountLimitensures the requested vertex count doesn't exceed either the memory-based limit or the GPU indexing limit.Confidence Score: 5/5
BATCHER2D_MEM_INCREMENTinstead of hardcoding magic numbers, fixes comment accuracy (2^16 vs 2^16-1), and simplifies GPU feature detection. The logic is mathematically sound and the check correctly prevents buffer overflow by ensuring vertex counts don't exceed either memory allocation or GPU indexing limitsImportant Files Changed
Sequence Diagram
sequenceDiagram participant Caller as BufferAccessor participant MB as MeshBuffer participant Device as GPU Device participant Macro as macro.BATCHER2D_MEM_INCREMENT Caller->>Macro: Read BATCHER2D_MEM_INCREMENT (144 KB default) Caller->>Caller: Calculate vCount = floor(144 * 1024 / vertexFormatBytes) Caller->>Caller: Calculate initVDataCount = vCount * floatsPerVertex Caller->>MB: initialize(device, attrs, initVDataCount, iCount) MB->>MB: Calculate floatsPerVertex from attrs MB->>Macro: Read BATCHER2D_MEM_INCREMENT MB->>MB: vDataCountLimit = BATCHER2D_MEM_INCREMENT * 256 MB->>Device: Check hasFeature(ELEMENT_INDEX_UINT) alt Device lacks ELEMENT_INDEX_UINT Device-->>MB: false (WebGL1 without extension) MB->>MB: vDataCountLimit = min(vDataCountLimit, 65536) Note over MB: Cap at 2^16 vertices (Uint16 indices 0-65535) else Device has ELEMENT_INDEX_UINT Device-->>MB: true (WebGL2/WebGPU/WebGL1+ext) Note over MB: Use full memory-based limit end MB->>MB: Assert: initVDataCount / floatsPerVertex < vDataCountLimit alt Assertion passes MB->>MB: Allocate vData and iData buffers MB-->>Caller: Initialization complete else Assertion fails MB->>MB: Throw error 9005 Note over MB: BATCHER2D_MEM_INCREMENT too large<br/>for GPU capabilities end