Skip to content

Commit fce05ec

Browse files
authored
Fix the issue in Spine 4.2 where setSlotTexture with createNew: true affects other instances and causes abnormal rendering (#18680)
1 parent a1243b4 commit fce05ec

File tree

7 files changed

+90
-81
lines changed

7 files changed

+90
-81
lines changed

native/cocos/editor-support/spine-creator-support/SkeletonRenderer.cpp

Lines changed: 41 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,6 @@ static const std::string TEXTURE_KEY = "texture";
5757

5858
static Cocos2dTextureLoader textureLoader;
5959

60-
#if CC_USE_SPINE_3_8
61-
static void deleteAttachmentVertices(void *vertices) {
62-
delete static_cast<AttachmentVertices *>(vertices);
63-
}
64-
#endif
65-
6660
enum DebugType {
6761
NONE = 0,
6862
SLOTS,
@@ -181,16 +175,22 @@ SkeletonRenderer::~SkeletonRenderer() {
181175

182176
for (auto iter: _slotTextureSet) {
183177
auto &info = iter.second;
184-
if (info.isOwner && info.attachment) {
185-
delete info.attachment;
186-
info.attachment = nullptr;
187-
}
178+
releaseSlotCacheInfo(info);
188179
}
189180

190181
_entity = nullptr;
191182
stopSchedule();
192183
}
193184

185+
void SkeletonRenderer::releaseSlotCacheInfo(SlotCacheInfo &info) {
186+
if (info.isOwner && info.attachment) {
187+
delete info.attachment;
188+
info.attachment = nullptr;
189+
delete info.attachmentVertices;
190+
info.attachmentVertices = nullptr;
191+
}
192+
}
193+
194194
void SkeletonRenderer::initWithUUID(const std::string &uuid) {
195195
_ownsSkeleton = true;
196196
_uuid = uuid;
@@ -440,18 +440,22 @@ void SkeletonRenderer::render(float /*deltaTime*/) {
440440

441441
cc::middleware::Triangles triangles;
442442
cc::middleware::TwoColorTriangles trianglesTwoColor;
443+
attachmentVertices = nullptr;
443444

444445
auto iter = _slotTextureSet.find(slot);
445446
if (iter != _slotTextureSet.end()) {
446447
tmpAttachment = iter->second.attachment;
448+
attachmentVertices = iter->second.attachmentVertices;
447449
}
448450
if (tmpAttachment->getRTTI().isExactly(RegionAttachment::rtti)) {
449451
auto *attachment = dynamic_cast<RegionAttachment *>(tmpAttachment);
452+
if (!attachmentVertices) {
450453
#if CC_USE_SPINE_3_8
451-
attachmentVertices = reinterpret_cast<AttachmentVertices *>(attachment->getRendererObject());
454+
attachmentVertices = reinterpret_cast<AttachmentVertices *>(attachment->getRendererObject());
452455
#else
453-
attachmentVertices = reinterpret_cast<AttachmentVertices *>(attachment->getRegion()->rendererObject);
456+
attachmentVertices = reinterpret_cast<AttachmentVertices *>(attachment->getRegion()->rendererObject);
454457
#endif
458+
}
455459

456460
// Early exit if attachment is invisible
457461
if (attachment->getColor().a == 0) {
@@ -516,11 +520,13 @@ void SkeletonRenderer::render(float /*deltaTime*/) {
516520
}
517521
} else if (tmpAttachment->getRTTI().isExactly(MeshAttachment::rtti)) {
518522
auto *attachment = dynamic_cast<MeshAttachment *>(tmpAttachment);
523+
if (!attachmentVertices) {
519524
#if CC_USE_SPINE_3_8
520-
attachmentVertices = static_cast<AttachmentVertices *>(attachment->getRendererObject());
525+
attachmentVertices = static_cast<AttachmentVertices *>(attachment->getRendererObject());
521526
#else
522-
attachmentVertices = static_cast<AttachmentVertices *>(attachment->getRegion()->rendererObject);
527+
attachmentVertices = static_cast<AttachmentVertices *>(attachment->getRegion()->rendererObject);
523528
#endif
529+
}
524530

525531
// Early exit if attachment is invisible
526532
if (attachment->getColor().a == 0) {
@@ -1130,8 +1136,8 @@ void SkeletonRenderer::setSlotTexture(const std::string &slotName, cc::Texture2D
11301136

11311137
if (createAttachment) {
11321138
attachment = attachment->copy();
1133-
slot->setAttachment(attachment);
11341139
}
1140+
SlotCacheInfo slotCacheInfo{createAttachment, attachment, nullptr};
11351141
AttachmentVertices *attachmentVertices = nullptr;
11361142
if (attachment->getRTTI().isExactly(spine::RegionAttachment::rtti)) {
11371143
auto region = static_cast<RegionAttachment *>(attachment);
@@ -1147,7 +1153,7 @@ void SkeletonRenderer::setSlotTexture(const std::string &slotName, cc::Texture2D
11471153
attachmentVertices = static_cast<AttachmentVertices *>(region->getRendererObject());
11481154
if (createAttachment) {
11491155
attachmentVertices = attachmentVertices->copy();
1150-
region->setRendererObject(attachmentVertices, deleteAttachmentVertices);
1156+
slotCacheInfo.attachmentVertices = attachmentVertices;
11511157
}
11521158
#else
11531159
auto *textureRegion = region->getRegion();
@@ -1156,6 +1162,11 @@ void SkeletonRenderer::setSlotTexture(const std::string &slotName, cc::Texture2D
11561162
textureRegion->height = height;
11571163
textureRegion->originalWidth = width;
11581164
textureRegion->originalHeight = height;
1165+
1166+
textureRegion->u = 0;
1167+
textureRegion->v = 0;
1168+
textureRegion->u2 = 1.0f;
1169+
textureRegion->v2 = 1.0f;
11591170
}
11601171
region->setWidth(width);
11611172
region->setHeight(height);
@@ -1172,7 +1183,7 @@ void SkeletonRenderer::setSlotTexture(const std::string &slotName, cc::Texture2D
11721183
attachmentVertices = static_cast<AttachmentVertices *>(textureRegion->rendererObject);
11731184
if (createAttachment) {
11741185
attachmentVertices = attachmentVertices->copy();
1175-
textureRegion->rendererObject = attachmentVertices;
1186+
slotCacheInfo.attachmentVertices = attachmentVertices;
11761187
}
11771188
#endif
11781189
V3F_T2F_C4B *vertices = attachmentVertices->_triangles->verts;
@@ -1200,7 +1211,7 @@ void SkeletonRenderer::setSlotTexture(const std::string &slotName, cc::Texture2D
12001211
attachmentVertices = static_cast<AttachmentVertices *>(mesh->getRendererObject());
12011212
if (createAttachment) {
12021213
attachmentVertices = attachmentVertices->copy();
1203-
mesh->setRendererObject(attachmentVertices, deleteAttachmentVertices);
1214+
slotCacheInfo.attachmentVertices = attachmentVertices;
12041215
}
12051216
#else
12061217
auto *region = mesh->getRegion();
@@ -1221,7 +1232,7 @@ void SkeletonRenderer::setSlotTexture(const std::string &slotName, cc::Texture2D
12211232
attachmentVertices = static_cast<AttachmentVertices *>(mesh->getRegion()->rendererObject);
12221233
if (createAttachment) {
12231234
attachmentVertices = attachmentVertices->copy();
1224-
mesh->getRegion()->rendererObject = attachmentVertices;
1235+
slotCacheInfo.attachmentVertices = attachmentVertices;
12251236
}
12261237
#endif
12271238
V3F_T2F_C4B *vertices = attachmentVertices->_triangles->verts;
@@ -1236,29 +1247,19 @@ void SkeletonRenderer::setSlotTexture(const std::string &slotName, cc::Texture2D
12361247
auto iter = _slotTextureSet.find(slot);
12371248
if (iter != _slotTextureSet.end()) {
12381249
auto info = iter->second;
1239-
AttachmentVertices *tmpAttachmentVertices = nullptr;
1240-
auto *cacheAttachment = info.attachment;
1241-
if (cacheAttachment->getRTTI().isExactly(spine::RegionAttachment::rtti)) {
1242-
auto *tmpRegion = static_cast<RegionAttachment *>(cacheAttachment);
1243-
#if CC_USE_SPINE_3_8
1244-
tmpAttachmentVertices = reinterpret_cast<AttachmentVertices *>(tmpRegion->getRendererObject());
1245-
#else
1246-
tmpAttachmentVertices = reinterpret_cast<AttachmentVertices *>(tmpRegion->getRegion()->rendererObject);
1247-
#endif
1248-
} else if (cacheAttachment->getRTTI().isExactly(spine::MeshAttachment::rtti)) {
1249-
auto *meshAttachment = static_cast<MeshAttachment *>(cacheAttachment);
1250-
#if CC_USE_SPINE_3_8
1251-
tmpAttachmentVertices = reinterpret_cast<AttachmentVertices *>(meshAttachment->getRendererObject());
1252-
#else
1253-
tmpAttachmentVertices = reinterpret_cast<AttachmentVertices *>(meshAttachment->getRegion()->rendererObject);
1254-
#endif
1255-
}
1256-
auto *realTex2d = tmpAttachmentVertices ? (tmpAttachmentVertices->_texture ? tmpAttachmentVertices->_texture->getRealTexture() : nullptr) : nullptr;
1257-
if (realTex2d == tex2d) {
1258-
return;
1250+
auto *cachedattachmentVertices = info.attachmentVertices;
1251+
if (cachedattachmentVertices) {
1252+
auto *realTex2d = cachedattachmentVertices->_texture ? cachedattachmentVertices->_texture->getRealTexture() : nullptr;
1253+
if (realTex2d == tex2d) {
1254+
return;
1255+
}
12591256
}
12601257
}
1261-
_slotTextureSet[slot] = {createAttachment, attachment};
1258+
if (_slotTextureSet.find(slot) != _slotTextureSet.end()) {
1259+
auto &info = _slotTextureSet[slot];
1260+
releaseSlotCacheInfo(info);
1261+
}
1262+
_slotTextureSet[slot] = slotCacheInfo;
12621263
if (!middlewareTexture) {
12631264
middlewareTexture = new middleware::Texture2D();
12641265
middlewareTexture->addRef();

native/cocos/editor-support/spine-creator-support/SkeletonRenderer.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ class AttachmentVertices;
5252

5353
struct SlotCacheInfo {
5454
bool isOwner{false};
55-
spine::Attachment* attachment{nullptr};
55+
spine::Attachment *attachment{nullptr};
56+
AttachmentVertices *attachmentVertices{nullptr};
5657
};
5758

5859
/** Draws a skeleton.
@@ -160,6 +161,7 @@ class SkeletonRenderer : public cc::RefCounted, public cc::middleware::IMiddlewa
160161

161162
protected:
162163
void setSkeletonData(spine::SkeletonData *skeletonData, bool ownsSkeletonData);
164+
void releaseSlotCacheInfo(SlotCacheInfo &info);
163165

164166
bool _ownsSkeletonData = false;
165167
bool _ownsSkeleton = false;

native/cocos/editor-support/spine-wasm/spine-skeleton-instance.cpp

Lines changed: 38 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,6 @@ extern void spineTrackListenerCallback();
1212
}
1313
using namespace spine;
1414

15-
#ifdef CC_SPINE_VERSION_3_8
16-
static void deleteAttachmentVertices(void *vertices) {
17-
delete static_cast<AttachmentVertices *>(vertices);
18-
}
19-
#endif
20-
2115
static void animationCallback(AnimationState *state, EventType type, TrackEntry *entry, Event *event) {
2216
SpineSkeletonInstance *instance = (static_cast<SpineSkeletonInstance *>(state->getRendererObject()));
2317
if (instance) {
@@ -70,10 +64,7 @@ SpineSkeletonInstance::~SpineSkeletonInstance() {
7064
while (entries.hasNext()) {
7165
auto entry = entries.next();
7266
auto info = entry.value;
73-
if (info.attachment && info.isOwner) {
74-
delete info.attachment;
75-
info.attachment = nullptr;
76-
}
67+
releaseSlotCacheInfo(info);
7768
}
7869
}
7970
}
@@ -157,6 +148,7 @@ SpineModel *SpineSkeletonInstance::updateRenderData() {
157148
_model->byteStride = sizeof(V3F_T2F_C4B);
158149
}
159150
collectMeshData();
151+
globalMesh.textureID = "";
160152
_model->setBufferPtr(SpineMeshData::vb(), SpineMeshData::ib());
161153
return _model;
162154
}
@@ -202,19 +194,24 @@ void SpineSkeletonInstance::collectMeshData() {
202194
color.b = _userData.color.b;
203195
color.a = _userData.color.a;
204196
spine::Attachment* attachmentSlot = slot->getAttachment();
197+
AttachmentVertices *cacheSlotAttachmentVertices = nullptr;
205198
if (_userData.useSlotTexture && _slotTextureSet.containsKey(slot)) {
206199
auto info = _slotTextureSet[slot];
207200
attachmentSlot = info.attachment;
201+
cacheSlotAttachmentVertices = info.attachmentVertices;
208202
}
209203
const spine::RTTI& attachmentRTTI = attachmentSlot->getRTTI();
210204
if (attachmentRTTI.isExactly(spine::RegionAttachment::rtti)) {
211205
debugShapeType = DEBUG_SHAPE_TYPE::DEBUG_REGION;
212206
auto *attachment = static_cast<spine::RegionAttachment *>(attachmentSlot);
207+
auto *attachmentVertices = cacheSlotAttachmentVertices;
208+
if (!attachmentVertices) {
213209
#ifdef CC_SPINE_VERSION_3_8
214-
auto *attachmentVertices = reinterpret_cast<AttachmentVertices *>(attachment->getRendererObject());
210+
attachmentVertices = reinterpret_cast<AttachmentVertices *>(attachment->getRendererObject());
215211
#else
216-
auto *attachmentVertices = reinterpret_cast<AttachmentVertices *>(attachment->getRegion()->rendererObject);
212+
attachmentVertices = reinterpret_cast<AttachmentVertices *>(attachment->getRegion()->rendererObject);
217213
#endif
214+
}
218215

219216
auto *triangles = attachmentVertices->_triangles;
220217
auto vertCount = triangles->vertCount;
@@ -249,11 +246,14 @@ void SpineSkeletonInstance::collectMeshData() {
249246
} else if (attachmentRTTI.isExactly(spine::MeshAttachment::rtti)) {
250247
debugShapeType = DEBUG_SHAPE_TYPE::DEBUG_MESH;
251248
auto *attachment = static_cast<spine::MeshAttachment *>(attachmentSlot);
249+
auto *attachmentVertices = cacheSlotAttachmentVertices;
250+
if (!attachmentVertices) {
252251
#ifdef CC_SPINE_VERSION_3_8
253-
auto *attachmentVertices = static_cast<AttachmentVertices *>(attachment->getRendererObject());
252+
attachmentVertices = static_cast<AttachmentVertices *>(attachment->getRendererObject());
254253
#else
255-
auto *attachmentVertices = static_cast<AttachmentVertices *>(attachment->getRegion()->rendererObject);
254+
attachmentVertices = static_cast<AttachmentVertices *>(attachment->getRegion()->rendererObject);
256255
#endif
256+
}
257257

258258
auto *triangles = attachmentVertices->_triangles;
259259
auto vertCount = triangles->vertCount;
@@ -534,12 +534,10 @@ void SpineSkeletonInstance::resizeSlotRegion(const spine::String &slotName, uint
534534
if (!attachment) return;
535535
if (createNew) {
536536
attachment = attachment->copy();
537-
slot->setAttachment(attachment);
538537
}
539538
SlotCacheInfo info;
540539
info.attachment = attachment;
541540
info.isOwner = createNew;
542-
_slotTextureSet.put(slot, info);
543541
if (attachment->getRTTI().isExactly(spine::RegionAttachment::rtti)) {
544542
auto *region = static_cast<RegionAttachment *>(attachment);
545543
#ifdef CC_SPINE_VERSION_3_8
@@ -554,7 +552,7 @@ void SpineSkeletonInstance::resizeSlotRegion(const spine::String &slotName, uint
554552
auto *attachmentVertices = static_cast<AttachmentVertices *>(region->getRendererObject());
555553
if (createNew) {
556554
attachmentVertices = attachmentVertices->copy();
557-
region->setRendererObject(attachmentVertices, deleteAttachmentVertices);
555+
info.attachmentVertices = attachmentVertices;
558556
}
559557
#else
560558
auto *textureRegion = region->getRegion();
@@ -563,6 +561,11 @@ void SpineSkeletonInstance::resizeSlotRegion(const spine::String &slotName, uint
563561
textureRegion->height = height;
564562
textureRegion->originalWidth = width;
565563
textureRegion->originalHeight = height;
564+
565+
textureRegion->u = 0;
566+
textureRegion->v = 0;
567+
textureRegion->u2 = 1.0f;
568+
textureRegion->v2 = 1.0f;
566569
}
567570
region->setWidth(width);
568571
region->setHeight(height);
@@ -579,7 +582,7 @@ void SpineSkeletonInstance::resizeSlotRegion(const spine::String &slotName, uint
579582
auto *attachmentVertices = static_cast<AttachmentVertices *>(region->getRegion()->rendererObject);
580583
if (createNew) {
581584
attachmentVertices = attachmentVertices->copy();
582-
region->getRegion()->rendererObject = attachmentVertices;
585+
info.attachmentVertices = attachmentVertices;
583586
}
584587
#endif
585588
V3F_T2F_C4B *vertices = attachmentVertices->_triangles->verts;
@@ -607,7 +610,7 @@ void SpineSkeletonInstance::resizeSlotRegion(const spine::String &slotName, uint
607610
auto *attachmentVertices = static_cast<AttachmentVertices *>(mesh->getRendererObject());
608611
if (createNew) {
609612
attachmentVertices = attachmentVertices->copy();
610-
mesh->setRendererObject(attachmentVertices, deleteAttachmentVertices);
613+
info.attachmentVertices = attachmentVertices;
611614
}
612615
#else
613616
auto *region = mesh->getRegion();
@@ -628,7 +631,7 @@ void SpineSkeletonInstance::resizeSlotRegion(const spine::String &slotName, uint
628631
auto *attachmentVertices = static_cast<AttachmentVertices *>(mesh->getRegion()->rendererObject);
629632
if (createNew) {
630633
attachmentVertices = attachmentVertices->copy();
631-
mesh->getRegion()->rendererObject = attachmentVertices;
634+
info.attachmentVertices = attachmentVertices;
632635
}
633636
#endif
634637
V3F_T2F_C4B *vertices = attachmentVertices->_triangles->verts;
@@ -638,6 +641,11 @@ void SpineSkeletonInstance::resizeSlotRegion(const spine::String &slotName, uint
638641
vertices[i].texCoord.v = UVs[ii + 1];
639642
}
640643
}
644+
if (_slotTextureSet.containsKey(slot)) {
645+
auto cacheInfo = _slotTextureSet[slot];
646+
releaseSlotCacheInfo(cacheInfo);
647+
}
648+
_slotTextureSet.put(slot, info);
641649
_skeleton->updateCache();
642650
}
643651

@@ -647,23 +655,7 @@ void SpineSkeletonInstance::setSlotTexture(const spine::String &slotName, const
647655
if (!slot) return;
648656
_userData.useSlotTexture = true;
649657
if (_slotTextureSet.containsKey(slot)) {
650-
AttachmentVertices *attachmentVertices = nullptr;
651-
auto* attachment = _slotTextureSet[slot].attachment;
652-
if (attachment->getRTTI().isExactly(spine::RegionAttachment::rtti)) {
653-
auto *regionAttachment = static_cast<RegionAttachment *>(attachment);
654-
#ifdef CC_SPINE_VERSION_3_8
655-
attachmentVertices = static_cast<AttachmentVertices *>(regionAttachment->getRendererObject());
656-
#else
657-
attachmentVertices = static_cast<AttachmentVertices *>(regionAttachment->getRegion()->rendererObject);
658-
#endif
659-
} else if(attachment->getRTTI().isExactly(spine::MeshAttachment::rtti)) {
660-
auto *meshAttachment = static_cast<MeshAttachment *>(attachment);
661-
#ifdef CC_SPINE_VERSION_3_8
662-
attachmentVertices = static_cast<AttachmentVertices *>(meshAttachment->getRendererObject());
663-
#else
664-
attachmentVertices = static_cast<AttachmentVertices *>(meshAttachment->getRegion()->rendererObject);
665-
#endif
666-
}
658+
AttachmentVertices *attachmentVertices = _slotTextureSet[slot].attachmentVertices;
667659
if (attachmentVertices) {
668660
attachmentVertices->_textureUUID = textureUuid;
669661
}
@@ -691,4 +683,13 @@ void SpineSkeletonInstance::dispatchEvents() {
691683
auto& info = vecTrackEvents[i];
692684
onTrackEntryEvent(info.entry, info.eventType, info.event);
693685
}
686+
}
687+
688+
void SpineSkeletonInstance::releaseSlotCacheInfo(SlotCacheInfo &info) {
689+
if (info.attachment && info.isOwner) {
690+
delete info.attachment;
691+
info.attachment = nullptr;
692+
delete info.attachmentVertices;
693+
info.attachmentVertices = nullptr;
694+
}
694695
}

0 commit comments

Comments
 (0)