mirror of
https://github.com/galacean/engine.git
synced 2026-06-16 09:57:30 +08:00
fix(ui): skip re-batching of canvas-internal leaders in main pipeline
UICanvas pre-batches its children into leaders that carry a self-contained draw range. When two canvases sharing the same atlas push their leaders into the transparent queue, the main-pipeline batcher previously fed those leaders back into `_canBatch`/`_batch` as if they were single sub-elements. That corrupted `subMesh.count` and re-appended already-written indices, dropping draws or overlapping ranges. The batch boundary is the canvas — matches Unity uGUI's behavior — so detect already-batched leaders at the batcher entry and pass them through.
This commit is contained in:
@@ -56,30 +56,34 @@ export class BatcherManager {
|
||||
let preConstructor: Function;
|
||||
for (let i = 0, n = input.length; i < n; ++i) {
|
||||
const curElement = input[i];
|
||||
|
||||
// Already-batched leaders (e.g. produced by UICanvas pre-batching) are terminal —
|
||||
// each carries an opaque, self-contained draw range that must not be merged again.
|
||||
// Flush any pending pre and pass the leader straight through
|
||||
if (curElement._isBatched) {
|
||||
preElement && (BatcherManager._flush(output, preElement), (preElement = null));
|
||||
output.push(curElement);
|
||||
continue;
|
||||
}
|
||||
|
||||
const renderer = curElement.component;
|
||||
const constructor = renderer.constructor;
|
||||
if (preElement) {
|
||||
if (preConstructor === constructor && preRenderer._canBatch(preElement, curElement)) {
|
||||
preRenderer._batch(preElement, curElement);
|
||||
} else {
|
||||
preElement._isBatched = true;
|
||||
output.push(preElement);
|
||||
preElement = curElement;
|
||||
preRenderer = renderer;
|
||||
preConstructor = constructor;
|
||||
renderer._batch(null, curElement);
|
||||
}
|
||||
if (preElement && preConstructor === constructor && preRenderer._canBatch(preElement, curElement)) {
|
||||
preRenderer._batch(preElement, curElement);
|
||||
} else {
|
||||
preElement && BatcherManager._flush(output, preElement);
|
||||
preElement = curElement;
|
||||
preRenderer = renderer;
|
||||
preConstructor = constructor;
|
||||
renderer._batch(null, curElement);
|
||||
}
|
||||
}
|
||||
if (preElement) {
|
||||
preElement._isBatched = true;
|
||||
output.push(preElement);
|
||||
}
|
||||
preElement && BatcherManager._flush(output, preElement);
|
||||
}
|
||||
|
||||
private static _flush(output: RenderElement[], element: RenderElement): void {
|
||||
element._isBatched = true;
|
||||
output.push(element);
|
||||
}
|
||||
|
||||
uploadBuffer() {
|
||||
|
||||
Reference in New Issue
Block a user