Skip to content

Commit cc8e615

Browse files
committed
Merge branch 'SpineFix' of https://github.com/zxx43/cocos4 into SpineFix
2 parents c9e7ab7 + edbec00 commit cc8e615

35 files changed

Lines changed: 239 additions & 111 deletions

.github/workflows/native-compile-platforms.yml

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -483,8 +483,8 @@ jobs:
483483
echo "set(CC_USE_GLES3 OFF)" >> build-mac/proj/cfg.cmake
484484
echo "set(CC_USE_METAL ON)" >> build-mac/proj/cfg.cmake
485485
# Test JSVM v8 backend on macOS.
486-
echo "set(USE_SE_V8 OFF)" >> build-mac/proj/cfg.cmake
487-
echo "set(USE_SE_JSVM ON)" >> build-mac/proj/cfg.cmake
486+
echo "set(USE_SE_V8 ON)" >> build-mac/proj/cfg.cmake
487+
echo "set(USE_SE_JSVM OFF)" >> build-mac/proj/cfg.cmake
488488
echo "set(USE_WEBSOCKET_SERVER OFF)" >> build-mac/proj/cfg.cmake
489489
echo "set(CMAKE_CXX_STANDARD_REQUIRED ON)" >> build-mac/proj/cfg.cmake
490490
echo "set(CC_EXECUTABLE_NAME \"\")" >> build-mac/proj/cfg.cmake
@@ -493,7 +493,6 @@ jobs:
493493
RES_DIR=$GITHUB_WORKSPACE/templates/mac/build-mac
494494
cd build-mac
495495
cmake ../ -GXcode -DCMAKE_OSX_ARCHITECTURES=${{ matrix.config.arch }} -DRES_DIR=$RES_DIR -DCOCOS_X_PATH=$NATIVE_ROOT
496-
set +e
497496
cmake --build . --config Release -- -jobs $NUM_OF_CORES -arch ${{ matrix.config.arch }}
498497
echo "Compile MacOSX Release Done!"
499498
@@ -534,7 +533,7 @@ jobs:
534533
echo "set(CC_USE_VULKAN OFF)" >> build-ios/proj/cfg.cmake
535534
echo "set(CC_USE_GLES2 OFF)" >> build-ios/proj/cfg.cmake
536535
echo "set(CC_USE_METAL ON)" >> build-ios/proj/cfg.cmake
537-
echo "set(TARGET_IOS_VERSION 12.0)" >> build-ios/proj/cfg.cmake
536+
echo "set(TARGET_IOS_VERSION 13.0)" >> build-ios/proj/cfg.cmake
538537
echo "set(USE_WEBSOCKET_SERVER OFF)" >> build-ios/proj/cfg.cmake
539538
echo "set(USE_DRAGONBONES OFF)" >> build-ios/proj/cfg.cmake
540539
echo "set(CMAKE_CXX_STANDARD_REQUIRED OFF)" >> build-ios/proj/cfg.cmake
@@ -548,7 +547,6 @@ jobs:
548547
-DCMAKE_OSX_ARCHITECTURES=${{ matrix.config.arch }} \
549548
-DRES_DIR=$RES_DIR \
550549
-DCOCOS_X_PATH=$NATIVE_ROOT
551-
set +e
552550
#cmake --build . --config Debug -- -quiet -jobs $NUM_OF_CORES -allowProvisioningUpdates CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO
553551
cmake --build . --config Debug -- -jobs $NUM_OF_CORES CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO
554552
echo "Compile iOS Done!"

EngineErrorMap.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3980,3 +3980,7 @@ Debug bones or slots is invalid in cached mode.
39803980
### 16419
39813981

39823982
Spine version not supported.
3983+
3984+
### 16420
3985+
3986+
Start time must bigger than end time.

cocos/2d/components/graphics.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,15 @@ export class Graphics extends UIRenderer {
266266
this._updateMtlForGraphics();
267267
}
268268

269+
protected override get _keepRenderData (): boolean {
270+
// Graphics is a retained-mode renderer: its MeshRenderData is the result of the
271+
// user's previous fill()/stroke() calls. Destroying it here would leave Impl's
272+
// render-data list pointing at cleared geometry, so re-enabling the node on native
273+
// platforms would require the user to draw the paths again. Keep it attached to the
274+
// disabled RenderEntity; clear() and onDestroy() remain the owning release points.
275+
return true;
276+
}
277+
269278
public onDestroy (): void {
270279
this._sceneGetter = null;
271280
if (JSB) {

cocos/2d/framework/ui-renderer.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,12 +398,23 @@ export class UIRenderer extends Renderer {
398398
this.node.off(NodeEventType.ANCHOR_CHANGED, this._nodeStateChange, this);
399399
this.node.off(NodeEventType.SIZE_CHANGED, this._nodeStateChange, this);
400400
this.node.off(NodeEventType.PARENT_CHANGED, this._colorDirty, this);
401-
this.destroyRenderData();
401+
if (!this._keepRenderData) {
402+
this.destroyRenderData();
403+
}
402404
uiRendererManager.removeRenderer(this);
403405
this._renderFlag = false;
404406
this._renderEntity.enabled = false;
405407
}
406408

409+
/**
410+
* Whether to keep render data when the component leaves the active hierarchy.
411+
* Retained-mode renderers may override this policy and keep their render data until
412+
* the content is explicitly cleared or the component is destroyed.
413+
*/
414+
protected get _keepRenderData (): boolean {
415+
return false;
416+
}
417+
407418
public onDestroy (): void {
408419
this._renderEntity.setNode(null);
409420
if (this.node._uiProps.uiComp === this) {

cocos/2d/renderer/static-vb-accessor.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,10 @@ export class StaticVBAccessor extends BufferAccessor {
165165
errorID(9004, byteLength);
166166
return null;
167167
}
168+
if (vertexCount > 65536) { // Vertex count must less than 65536 for index is uint16 (0 to 65535)
169+
errorID(9004, byteLength);
170+
return null;
171+
}
168172
let buf: MeshBuffer = null!;
169173
let freeList: IFreeEntry[];
170174
let bid = 0;
@@ -176,9 +180,11 @@ export class StaticVBAccessor extends BufferAccessor {
176180
freeList = this._freeLists[i];
177181
// Loop entries
178182
for (let e = 0; e < freeList.length; ++e) {
183+
const freeEntry = freeList[e];
184+
const vertexOffset: number = freeEntry.offset / this.vertexFormatBytes;
179185
// Found suitable free entry
180-
if (freeList[e].length >= byteLength) {
181-
entry = freeList[e];
186+
if (freeEntry.length >= byteLength && vertexOffset + (vertexCount - 1) <= 65535) {
187+
entry = freeEntry;
182188
bid = i;
183189
eid = e;
184190
break;

cocos/gfx/webgl2/webgl2-swapchain.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ export class WebGL2Swapchain extends Swapchain {
185185
self._canvas = info.windowHandle;
186186

187187
self._webGL2ContextLostHandler = self._onWebGLContextLost.bind(self);
188-
self._canvas.addEventListener(eventWebGLContextLost, self._onWebGLContextLost);
188+
self._canvas.addEventListener(eventWebGLContextLost, self._webGL2ContextLostHandler);
189189

190190
const { instance } = WebGL2DeviceManager;
191191
const { gl, capabilities } = instance;

cocos/particle/particle-system.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -233,8 +233,8 @@ export class ParticleSystem extends ModelRenderer {
233233
public startLifetime = new CurveRange();
234234

235235
/**
236-
* @en Particle system duration time.
237-
* @zh 粒子系统运行时间
236+
* @en Particle system emitter duration time.
237+
* @zh 粒子系统发射器运行时间
238238
*/
239239
@serializable
240240
@displayOrder(0)

cocos/particle/renderer/trail.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,10 @@ export default class TrailModule {
377377
if (this.lifeTime.getMax() < 1.0) {
378378
warnID(6036);
379379
}
380-
this._trailNum = Math.ceil(psTime * Math.ceil(this.lifeTime.getMax()) * 60 * (psRate * duration + burstCount));
380+
let pCount: number = psRate * duration; // potential particle count
381+
pCount = ps.prewarm ? pCount * 2 : pCount; // if prewarm we need double space
382+
pCount = pCount > ps.capacity ? ps.capacity : pCount; // max particle count is less/equal than capacity
383+
this._trailNum = Math.ceil(psTime * Math.ceil(this.lifeTime.getMax()) * 60 * (pCount + burstCount));
381384
this._trailSegments = new Pool(
382385
(): TrailSegment => new TrailSegment(10),
383386
Math.ceil(psRate * duration),

cocos/rendering/planar-shadow-queue.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ import { PipelineStateManager } from './pipeline-state-manager';
2929
import { Model, Camera, SubModel } from '../render-scene/scene';
3030
import { RenderInstancedQueue } from './render-instanced-queue';
3131
import { ShadowType } from '../render-scene/scene/shadows';
32-
import { Layers } from '../scene-graph/layers';
3332
import { PipelineRuntime } from './custom/pipeline';
3433
import { BatchingSchemes, Pass } from '../render-scene/core/pass';
3534
import { getPhaseID } from './pass-phase';
@@ -83,18 +82,16 @@ export class PlanarShadowQueue {
8382

8483
const scene = camera.scene!;
8584
const frustum = camera.frustum;
86-
const shadowVisible = (camera.visibility & Layers.BitMask.DEFAULT) !== 0;
85+
const shadowVisible = camera.visibility !== 0;
8786
if (!scene.mainLight || !shadowVisible) { return; }
8887

8988
const models = scene.models;
90-
const visibility = camera.visibility;
9189
for (let i = 0; i < models.length; i++) {
9290
const model = models[i];
9391
if (scene.isCulledByLod(camera, model)) {
9492
continue;
9593
}
96-
if (model.enabled && model.node && model.castShadow
97-
&& (model.node && ((visibility & model.node.layer) === model.node.layer))) {
94+
if (model.enabled && model.node && model.castShadow) {
9895
this._castModels.push(model);
9996
}
10097
}

cocos/rendering/render-additive-light-queue.ts

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ export class RenderAdditiveLightQueue {
126126
private declare _lightBuffer: Buffer;
127127
private declare _firstLightBufferView: Buffer;
128128
private declare _lightBufferData: Float32Array;
129-
private _instancedQueues: RenderInstancedQueue[] = [];
129+
private _instancedQueues: (RenderInstancedQueue | undefined)[] = [];
130130
private _lightMeterScale = 10000.0;
131131

132132
constructor (pipeline: PipelineRuntime) {
@@ -151,7 +151,9 @@ export class RenderAdditiveLightQueue {
151151

152152
public clear (): void {
153153
this._instancedQueues.forEach((instancedQueue) => {
154-
instancedQueue.clear();
154+
if (instancedQueue) {
155+
instancedQueue.clear();
156+
}
155157
});
156158
this._instancedQueues.length = 0;
157159

@@ -196,7 +198,7 @@ export class RenderAdditiveLightQueue {
196198

197199
this._lightCulling(model, validPunctualLights);
198200

199-
if (!_lightIndices.length && validPunctualLights.length > 0) { continue; }
201+
if (!_lightIndices.length) { continue; }
200202

201203
for (let j = 0; j < subModels.length; j++) {
202204
const lightPassIdx = _lightPassIndices[j];
@@ -219,15 +221,14 @@ export class RenderAdditiveLightQueue {
219221
public gatherLightPasses (camera: Camera, cmdBuff: CommandBuffer, passLayout = 'default'): void {
220222
this.clear();
221223

222-
const validPunctualLights = this._pipeline.pipelineSceneData.validPunctualLights;
223-
if (!validPunctualLights.length) {
224-
this._bindForwardAddLight(validPunctualLights, passLayout);
225-
return;
226-
}
227-
228224
this._updateUBOs(camera, cmdBuff);
229225
this._updateLightDescriptorSet(camera, cmdBuff);
226+
227+
const validPunctualLights = this._pipeline.pipelineSceneData.validPunctualLights;
228+
if (!validPunctualLights.length) { return; }
229+
230230
this._bindForwardAddLight(validPunctualLights, passLayout);
231+
231232
// only for instanced and batched, no light culling applied
232233
for (let l = 0; l < validPunctualLights.length; l++) {
233234
const light = validPunctualLights[l];
@@ -236,17 +237,21 @@ export class RenderAdditiveLightQueue {
236237
}
237238

238239
this._instancedQueues.forEach((instancedQueue) => {
239-
instancedQueue.uploadBuffers(cmdBuff);
240+
if (instancedQueue) {
241+
instancedQueue.uploadBuffers(cmdBuff);
242+
}
240243
});
241244
}
242245

243246
public recordCommandBuffer (device: Device, renderPass: RenderPass, cmdBuff: CommandBuffer): void {
244247
const globalDSManager: GlobalDSManager = this._pipeline.globalDSManager;
245248
for (let j = 0; j < this._instancedQueues.length; ++j) {
249+
const queue = this._instancedQueues[j];
250+
if (!queue) { continue; }
246251
const light = this._instancedLightPassPool.lights[j];
247252
_dynamicOffsets[0] = this._instancedLightPassPool.dynamicOffsets[j];
248253
const descriptorSet = globalDSManager.getOrCreateDescriptorSet(light);
249-
this._instancedQueues[j].recordCommandBuffer(device, renderPass, cmdBuff, descriptorSet, _dynamicOffsets);
254+
queue.recordCommandBuffer(device, renderPass, cmdBuff, descriptorSet, _dynamicOffsets);
250255
}
251256

252257
for (let i = 0; i < this._lightPasses.length; i++) {
@@ -315,14 +320,18 @@ export class RenderAdditiveLightQueue {
315320
const lightIdx = _lightIndices[l];
316321
const light = validPunctualLights[lightIdx];
317322
const visibility = light.visibility;
318-
if (((visibility & model.node.layer) === model.node.layer)) {
323+
if (((visibility & model.node.layer) === model.node.layer)
324+
|| (visibility & model.visFlags)) {
319325
switch (batchingScheme) {
320326
case BatchingSchemes.INSTANCING: {
321-
const buffer = pass.getInstancedBuffer(l);
327+
const buffer = pass.getInstancedBuffer(lightIdx);
322328
buffer.merge(subModel, lightPassIdx);
323-
buffer.dynamicOffsets[0] = this._lightBufferStride;
324-
if (!this._instancedQueues[l]) { this._instancedQueues[l] = new RenderInstancedQueue(); }
325-
this._instancedQueues[l].queue.add(buffer);
329+
buffer.dynamicOffsets[0] = this._lightBufferStride * lightIdx;
330+
if (this._instancedQueues.length <= lightIdx || !this._instancedQueues[lightIdx]) {
331+
this._instancedQueues.length = lightIdx + 1;
332+
this._instancedQueues[lightIdx] = new RenderInstancedQueue();
333+
}
334+
this._instancedQueues[lightIdx]!.queue.add(buffer);
326335
} break;
327336
default:
328337
lp!.lights.push(light);
@@ -370,9 +379,6 @@ export class RenderAdditiveLightQueue {
370379
this._shadowUBO[UBOShadowEnum.SHADOW_LIGHT_PACKING_NBIAS_NULL_INFO_OFFSET + 1] = packing;
371380
this._shadowUBO[UBOShadowEnum.SHADOW_LIGHT_PACKING_NBIAS_NULL_INFO_OFFSET + 2] = 0.0;
372381
this._shadowUBO[UBOShadowEnum.SHADOW_LIGHT_PACKING_NBIAS_NULL_INFO_OFFSET + 3] = 0.0;
373-
374-
// Reserve sphere light shadow interface
375-
Color.toArray(this._shadowUBO, shadowInfo.shadowColor, UBOShadowEnum.SHADOW_COLOR_OFFSET);
376382
break;
377383
}
378384
case LightType.SPOT: {
@@ -437,8 +443,6 @@ export class RenderAdditiveLightQueue {
437443
this._shadowUBO[UBOShadowEnum.SHADOW_PROJ_INFO_OFFSET + 2] = 1.0 / matShadowProj.m00;
438444
this._shadowUBO[UBOShadowEnum.SHADOW_PROJ_INFO_OFFSET + 3] = 1.0 / matShadowProj.m05;
439445

440-
Color.toArray(this._shadowUBO, shadowInfo.shadowColor, UBOShadowEnum.SHADOW_COLOR_OFFSET);
441-
442446
// Spot light sampler binding
443447
if (shadowFrameBufferMap.has(light)) {
444448
const texture = shadowFrameBufferMap.get(light)?.colorTextures[0];
@@ -463,15 +467,15 @@ export class RenderAdditiveLightQueue {
463467
this._shadowUBO[UBOShadowEnum.SHADOW_LIGHT_PACKING_NBIAS_NULL_INFO_OFFSET + 1] = packing;
464468
this._shadowUBO[UBOShadowEnum.SHADOW_LIGHT_PACKING_NBIAS_NULL_INFO_OFFSET + 2] = 0.0;
465469
this._shadowUBO[UBOShadowEnum.SHADOW_LIGHT_PACKING_NBIAS_NULL_INFO_OFFSET + 3] = 0.0;
466-
467-
// Reserve point light shadow interface
468-
Color.toArray(this._shadowUBO, shadowInfo.shadowColor, UBOShadowEnum.SHADOW_COLOR_OFFSET);
469470
break;
470471
}
471472
default:
472473
}
473-
globalDSManager.update();
474-
cmdBuff.updateBuffer(descriptorSet.getBuffer(UBOShadow.BINDING)!, this._shadowUBO);
474+
Color.toArray(this._shadowUBO, shadowInfo.shadowColor, UBOShadowEnum.SHADOW_COLOR_OFFSET);
475+
476+
descriptorSet.update();
477+
478+
cmdBuff.updateBuffer(descriptorSet.getBuffer(UBOShadow.BINDING)!, this._shadowUBO.buffer, this._shadowUBO.byteLength);
475479
}
476480
}
477481

@@ -627,6 +631,6 @@ export class RenderAdditiveLightQueue {
627631
}
628632
}
629633

630-
cmdBuff.updateBuffer(this._lightBuffer, this._lightBufferData);
634+
cmdBuff.updateBuffer(this._lightBuffer, this._lightBufferData.buffer as ArrayBuffer, this._lightBufferData.byteLength);
631635
}
632636
}

0 commit comments

Comments
 (0)