From 823937adadf48d087bead95702acfaa63baf7c2d Mon Sep 17 00:00:00 2001 From: Pawel Wojtasik Date: Wed, 23 Nov 2016 16:45:04 +0100 Subject: [PATCH] !B (Animation) Fixed a potential race condition in CSkeletonAnim::PushPoseModifier() - modifier instances pushed during animation processing are now always appended to the correct queue. (Approved by samuelk) Review: ID 63041 by Author: Pawel Wojtasik, Reviewer: Hilko Cords, Observer: Timur Davidenko, Observer: Jan Hellwig Copied from Perforce Change: 1470384 --- .../CryAnimation/CharacterInstanceProcessing.cpp | 13 ++++++++----- .../CryAnimation/CharacterInstanceProcessing.h | 21 +++++++++++++++------ Code/CryEngine/CryAnimation/SkeletonAnim.cpp | 8 +++++--- 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/Code/CryEngine/CryAnimation/CharacterInstanceProcessing.cpp b/Code/CryEngine/CryAnimation/CharacterInstanceProcessing.cpp index 5c280ef76..be0c305c4 100644 --- a/Code/CryEngine/CryAnimation/CharacterInstanceProcessing.cpp +++ b/Code/CryEngine/CryAnimation/CharacterInstanceProcessing.cpp @@ -177,11 +177,7 @@ SContext::EState SFinishAnimationComputations::operator()(const SContext& ctx) return SContext::EState::Finished; } -void SContext::Initialize( - CCharInstance* _pInst, - const CAttachmentBONE* _pBone, - const CCharInstance* _pParent, - int _numChildren) +void SContext::Initialize(CCharInstance* _pInst, const CAttachmentBONE* _pBone, const CCharInstance* _pParent, int _numChildren) { pInstance = _pInst; pBone = _pBone; @@ -191,6 +187,13 @@ void SContext::Initialize( job = CJob(this); } +bool SContext::IsInProgress() const +{ + return (state != EState::Unstarted) + && (state != EState::Finished) + && (state != EState::Failure); +} + SContext& CContextQueue::AppendContext() { CRY_ASSERT(m_numContexts < kMaxNumberOfCharacterInstanceProcessingContexts - 1); diff --git a/Code/CryEngine/CryAnimation/CharacterInstanceProcessing.h b/Code/CryEngine/CryAnimation/CharacterInstanceProcessing.h index 28c8c8925..fc643ef57 100644 --- a/Code/CryEngine/CryAnimation/CharacterInstanceProcessing.h +++ b/Code/CryEngine/CryAnimation/CharacterInstanceProcessing.h @@ -35,13 +35,22 @@ private: struct SContext { SContext() - : pInstance(nullptr), pBone(nullptr), pParent(nullptr), numChildren(0), slot(-1), pCommandBuffer(nullptr), job(nullptr), state(EState::Unstarted) {} + : pInstance(nullptr) + , pBone(nullptr) + , pParent(nullptr) + , numChildren(0) + , slot(-1) + , pCommandBuffer(nullptr) + , job(nullptr) + , state(EState::Unstarted) + { + } + + void Initialize(CCharInstance* pInst, const CAttachmentBONE* pBone, const CCharInstance* pParent, int numChildren); - void Initialize( - CCharInstance* pInst, - const CAttachmentBONE* pBone, - const CCharInstance* pParent, - int numChildren); + //! Checks if computation of this processing context is currently in progress. + //! \return True if computation is still in progress. False if computation did not yet start or already finished for the current frame. + bool IsInProgress() const; _smart_ptr pInstance; const CAttachmentBONE* pBone; diff --git a/Code/CryEngine/CryAnimation/SkeletonAnim.cpp b/Code/CryEngine/CryAnimation/SkeletonAnim.cpp index ab2648ecb..795614ce7 100644 --- a/Code/CryEngine/CryAnimation/SkeletonAnim.cpp +++ b/Code/CryEngine/CryAnimation/SkeletonAnim.cpp @@ -94,15 +94,17 @@ bool CSkeletonAnim::PushPoseModifier(uint32 layer, IAnimationPoseModifierPtr pos return true; } const CharacterInstanceProcessing::SContext* pCtx = m_pInstance->GetProcessingContext(); - bool isStarted = pCtx && pCtx->state == CharacterInstanceProcessing::SContext::EState::StartAnimationProcessed; + + const bool isInProgress = pCtx && pCtx->IsInProgress(); + if (layer == uint32(-1)) { - return m_poseModifierQueue.Push(poseModifier, name, isStarted); + return m_poseModifierQueue.Push(poseModifier, name, isInProgress); } if (layer < numVIRTUALLAYERS) { - return m_layers[layer].m_poseModifierQueue.Push(poseModifier, name, isStarted); + return m_layers[layer].m_poseModifierQueue.Push(poseModifier, name, isInProgress); } } -- 2.11.4.GIT