// // Copyright 2013 Pixar // // Licensed under the Apache License, Version 2.0 (the "Apache License") // with the following modification; you may not use this file except in // compliance with the Apache License and the following modification to it: // Section 6. Trademarks. is deleted and replaced with: // // 6. Trademarks. This License does not grant permission to use the trade // names, trademarks, service marks, or product names of the Licensor // and its affiliates, except as required to comply with Section 4(c) of // the License and to reproduce the content of the NOTICE file. // // You may obtain a copy of the Apache License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the Apache License with the above modification is // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the Apache License for the specific // language governing permissions and limitations under the Apache License. // #include "../osd/tbbEvalStencilsController.h" #include #include #include namespace OpenSubdiv { namespace OPENSUBDIV_VERSION { #define grain_size 200 OsdTbbEvalStencilsController::OsdTbbEvalStencilsController(int numThreads) { _numThreads = numThreads > 0 ? numThreads : tbb::task_scheduler_init::automatic; tbb::task_scheduler_init init(numThreads); } OsdTbbEvalStencilsController::~OsdTbbEvalStencilsController() { } class StencilKernel { public: enum Mode { UNDEFINED, POINT, U_DERIV, V_DERIV }; StencilKernel( FarStencilTables const * stencils, OsdVertexBufferDescriptor ctrlDesc, float const * ctrlData ) : _stencils(stencils), _mode(UNDEFINED), _ctrlDesc(ctrlDesc), _length(0), _outStride(0), _outData(0) { _ctrlData = ctrlData + ctrlDesc.offset; } bool SetOutput(Mode mode, OsdVertexBufferDescriptor outDesc, float * outData) { if (_ctrlDesc.CanEval(outDesc)) { _mode = mode; _length = outDesc.length; _outStride = outDesc.stride; _outData = outData + outDesc.offset; return true; } return false; } void operator() (tbb::blocked_range const &r) const { assert(_stencils and _ctrlData and _length and _outStride and _outData); int offset = _stencils->GetOffsets()[r.begin()]; int const * sizes = &_stencils->GetSizes()[r.begin()], * index = &_stencils->GetControlIndices()[offset]; float const * weight; switch (_mode) { case POINT : weight = &_stencils->GetWeights()[offset]; break; case U_DERIV : weight = &_stencils->GetDuWeights()[offset]; break; case V_DERIV : weight = &_stencils->GetDvWeights()[offset]; break; default: return; } assert( weight); float * out = _outData + r.begin() * _outStride; for (int i=r.begin(); iGetStencilTables(); if (not stencils) return 0; int nstencils = stencils->GetNumStencils(); if (not nstencils) return 0; StencilKernel kernel( stencils, context->GetControlDataDescriptor(), context->GetControlData() ); if (not kernel.SetOutput( StencilKernel::POINT, context->GetOutputDataDescriptor(), context->GetOutputData() )) return 0; tbb::blocked_range range(0, nstencils, grain_size); tbb::parallel_for(range, kernel); return nstencils; } int OsdTbbEvalStencilsController::_UpdateDerivs( OsdCpuEvalStencilsContext * context ) { FarStencilTables const * stencils = context->GetStencilTables(); if (not stencils) return 0; int nstencils = stencils->GetNumStencils(); if (not nstencils) return 0; tbb::blocked_range range(0, nstencils, grain_size); StencilKernel kernel( stencils, context->GetControlDataDescriptor(), context->GetControlData() ); if (not kernel.SetOutput( StencilKernel::U_DERIV, context->GetDuDataDescriptor(), context->GetOutputUDerivData() ) ) return 0; tbb::parallel_for(range, kernel); if (not kernel.SetOutput( StencilKernel::V_DERIV, context->GetDvDataDescriptor(), context->GetOutputVDerivData() ) ) return 0; tbb::parallel_for(range, kernel); return nstencils; } void OsdTbbEvalStencilsController::Synchronize() { } } // end namespace OPENSUBDIV_VERSION } // end namespace OpenSubdiv