00001 // 00002 // Redistribution and use in source and binary forms, with or without 00003 // modification, are permitted provided that the following conditions 00004 // are met: 00005 // * Redistributions of source code must retain the above copyright 00006 // notice, this list of conditions and the following disclaimer. 00007 // * Redistributions in binary form must reproduce the above copyright 00008 // notice, this list of conditions and the following disclaimer in the 00009 // documentation and/or other materials provided with the distribution. 00010 // * Neither the name of NVIDIA CORPORATION nor the names of its 00011 // contributors may be used to endorse or promote products derived 00012 // from this software without specific prior written permission. 00013 // 00014 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY 00015 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00016 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00017 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 00018 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00019 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00020 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00021 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 00022 // OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00023 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00024 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00025 // 00026 // Copyright (c) 2008-2018 NVIDIA Corporation. All rights reserved. 00027 00028 #ifndef PXTASK_PXTASK_H 00029 #define PXTASK_PXTASK_H 00030 00031 #include "task/PxTaskDefine.h" 00032 #include "task/PxTaskManager.h" 00033 #include "task/PxCpuDispatcher.h" 00034 #include "task/PxGpuDispatcher.h" 00035 #include "foundation/PxAssert.h" 00036 00037 namespace physx 00038 { 00039 00045 class PxBaseTask 00046 { 00047 public: 00048 PxBaseTask() : mContextID(0), mTm(NULL) {} 00049 virtual ~PxBaseTask() {} 00050 00057 virtual void run() = 0; 00058 00066 virtual const char* getName() const = 0; 00067 00069 virtual void addReference() = 0; 00071 virtual void removeReference() = 0; 00073 virtual int32_t getReference() const = 0; 00074 00081 virtual void release() = 0; 00082 00089 PX_FORCE_INLINE PxTaskManager* getTaskManager() const 00090 { 00091 return mTm; 00092 } 00093 00094 PX_FORCE_INLINE void setContextId(PxU64 id) { mContextID = id; } 00095 PX_FORCE_INLINE PxU64 getContextId() const { return mContextID; } 00096 00097 protected: 00098 PxU64 mContextID; 00099 PxTaskManager* mTm; 00100 00101 friend class PxTaskMgr; 00102 }; 00103 00104 00111 class PxTask : public PxBaseTask 00112 { 00113 public: 00114 PxTask() : mTaskID(0) {} 00115 virtual ~PxTask() {} 00116 00118 virtual void release() 00119 { 00120 PX_ASSERT(mTm); 00121 00122 // clear mTm before calling taskCompleted() for safety 00123 PxTaskManager* save = mTm; 00124 mTm = NULL; 00125 save->taskCompleted( *this ); 00126 } 00127 00129 // task is allowed to start. 00130 PX_INLINE void finishBefore( PxTaskID taskID ) 00131 { 00132 PX_ASSERT(mTm); 00133 mTm->finishBefore( *this, taskID); 00134 } 00135 00137 // task has completed. 00138 PX_INLINE void startAfter( PxTaskID taskID ) 00139 { 00140 PX_ASSERT(mTm); 00141 mTm->startAfter( *this, taskID ); 00142 } 00143 00148 PX_INLINE void addReference() 00149 { 00150 PX_ASSERT(mTm); 00151 mTm->addReference( mTaskID ); 00152 } 00153 00158 PX_INLINE void removeReference() 00159 { 00160 PX_ASSERT(mTm); 00161 mTm->decrReference( mTaskID ); 00162 } 00163 00167 PX_INLINE int32_t getReference() const 00168 { 00169 return mTm->getReference( mTaskID ); 00170 } 00171 00175 PX_INLINE PxTaskID getTaskID() const 00176 { 00177 return mTaskID; 00178 } 00179 00185 virtual void submitted() 00186 { 00187 mStreamIndex = 0; 00188 mPreSyncRequired = false; 00189 } 00190 00194 PX_INLINE void requestSyncPoint() 00195 { 00196 mPreSyncRequired = true; 00197 } 00198 00199 00200 protected: 00201 PxTaskID mTaskID; 00202 uint32_t mStreamIndex; 00203 bool mPreSyncRequired; 00204 00205 friend class PxTaskMgr; 00206 friend class PxGpuWorkerThread; 00207 }; 00208 00209 00223 class PxLightCpuTask : public PxBaseTask 00224 { 00225 public: 00226 PxLightCpuTask() 00227 : mCont( NULL ) 00228 , mRefCount( 0 ) 00229 { 00230 } 00231 virtual ~PxLightCpuTask() 00232 { 00233 mTm = NULL; 00234 } 00235 00245 PX_INLINE void setContinuation(PxTaskManager& tm, PxBaseTask* c) 00246 { 00247 PX_ASSERT( mRefCount == 0 ); 00248 mRefCount = 1; 00249 mCont = c; 00250 mTm = &tm; 00251 if( mCont ) 00252 { 00253 mCont->addReference(); 00254 } 00255 } 00256 00264 PX_INLINE void setContinuation( PxBaseTask* c ) 00265 { 00266 PX_ASSERT( c ); 00267 PX_ASSERT( mRefCount == 0 ); 00268 mRefCount = 1; 00269 mCont = c; 00270 if( mCont ) 00271 { 00272 mCont->addReference(); 00273 mTm = mCont->getTaskManager(); 00274 PX_ASSERT( mTm ); 00275 } 00276 } 00277 00281 PX_INLINE PxBaseTask* getContinuation() const 00282 { 00283 return mCont; 00284 } 00285 00290 PX_INLINE void removeReference() 00291 { 00292 mTm->decrReference(*this); 00293 } 00294 00296 PX_INLINE int32_t getReference() const 00297 { 00298 return mRefCount; 00299 } 00300 00305 PX_INLINE void addReference() 00306 { 00307 mTm->addReference(*this); 00308 } 00309 00315 PX_INLINE void release() 00316 { 00317 if( mCont ) 00318 { 00319 mCont->removeReference(); 00320 } 00321 } 00322 00323 protected: 00324 00325 PxBaseTask* mCont; 00326 volatile int32_t mRefCount; 00327 00328 friend class PxTaskMgr; 00329 }; 00330 00331 00332 }// end physx namespace 00333 00334 00335 #endif // PXTASK_PXTASK_H