HdDirtyList::~HdDirtyList() { HD_TRACE_FUNCTION(); HF_MALLOC_TAG_FUNCTION(); HD_PERF_COUNTER_DECR(HdPerfTokens->dirtyLists); }
bool HdSt_DrawBatch::_DrawingProgram::CompileShader( HdStDrawItem const *drawItem, bool indirect, HdStResourceRegistrySharedPtr const &resourceRegistry) { HD_TRACE_FUNCTION(); HF_MALLOC_TAG_FUNCTION(); // glew has to be initialized if (!glLinkProgram) { return false; } if (!_geometricShader) { TF_CODING_ERROR("Can not compile a shader without a geometric shader"); return false; } // determine binding points and populate metaData HdBindingRequestVector customBindings; bool instanceDraw = true; _GetCustomBindings(&customBindings, &instanceDraw); // also (surface, renderPass) shaders use their bindings HdStShaderCodeSharedPtrVector shaders = GetComposedShaders(); TF_FOR_ALL(it, shaders) { (*it)->AddBindings(&customBindings); }
void Hd_PrimTypeIndex<PrimType>::RemovePrim(const TfToken &typeId, const SdfPath &primId, HdChangeTracker &tracker, HdRenderDelegate *renderDelegate) { HD_TRACE_FUNCTION(); HF_MALLOC_TAG_FUNCTION(); typename _TypeIndex::iterator typeIt = _index.find(typeId); if (typeIt ==_index.end()) { TF_CODING_ERROR("Unsupported prim type: %s", typeId.GetText()); return; } _PrimTypeEntry &typeEntry = _entries[typeIt->second]; typename _PrimMap::iterator primIt = typeEntry.primMap.find(primId); if (primIt == typeEntry.primMap.end()) { return; } _TrackerRemovePrim(tracker, primId); _PrimInfo &primInfo = primIt->second; _RenderDelegateDestroyPrim(renderDelegate, primInfo.prim); primInfo.prim = nullptr; typeEntry.primMap.erase(primIt); typeEntry.primIds.Remove(primId); }
void HdxColorCorrectionTask::Sync(HdSceneDelegate* delegate, HdTaskContext* ctx, HdDirtyBits* dirtyBits) { HD_TRACE_FUNCTION(); HF_MALLOC_TAG_FUNCTION(); if ((*dirtyBits) & HdChangeTracker::DirtyParams) { HdxColorCorrectionTaskParams params; if (_GetTaskParams(delegate, ¶ms)) { _framebufferSize = params.framebufferSize; _colorCorrectionMode = params.colorCorrectionMode; _displayOCIO = params.displayOCIO; _viewOCIO = params.viewOCIO; _colorspaceOCIO = params.colorspaceOCIO; _looksOCIO = params.looksOCIO; _lut3dSizeOCIO = params.lut3dSizeOCIO; // Rebuild shader with new OCIO settings / shader-code. _shaderProgram.reset(); } } *dirtyBits = HdChangeTracker::Clean; }
/* virtual */ std::string HdSt_FallbackLightingShader::GetSource(TfToken const &shaderStageKey) const { HD_TRACE_FUNCTION(); HF_MALLOC_TAG_FUNCTION(); return _glslfx->GetSource(shaderStageKey); }
TfTokenVector const & HdRenderPass::GetRenderTags() { HD_TRACE_FUNCTION(); HF_MALLOC_TAG_FUNCTION(); return _collection.GetRenderTags(); }
void HdxSelectionTask::_Execute(HdTaskContext* ctx) { HD_TRACE_FUNCTION(); HF_MALLOC_TAG_FUNCTION(); // Note that selectionTask comes after renderTask. }
/* virtual */ std::string HdSt_TestLightingShader::GetSource(TfToken const &shaderStageKey) const { HD_TRACE_FUNCTION(); HF_MALLOC_TAG_FUNCTION(); std::string source = _glslfx->GetSource(shaderStageKey); return source; }
void HdRenderPass::Sync() { HD_TRACE_FUNCTION(); HF_MALLOC_TAG_FUNCTION(); // Sync the dirty list of prims _renderIndex->Sync(_dirtyList); }
void UsdImagingMeshAdapter::_GetPoints(UsdPrim const& prim, VtValue* value, UsdTimeCode time) { HD_TRACE_FUNCTION(); HF_MALLOC_TAG_FUNCTION(); if (!prim.GetAttribute(UsdGeomTokens->points).Get(value, time)) { *value = VtVec3fArray(); } }
void Hd_PrimTypeIndex<PrimType>::DestroyFallbackPrims(HdRenderDelegate *renderDelegate) { HD_TRACE_FUNCTION(); HF_MALLOC_TAG_FUNCTION(); size_t numTypes = _entries.size(); for (size_t typeIdx = 0; typeIdx < numTypes; ++typeIdx) { _PrimTypeEntry &typeEntry = _entries[typeIdx]; _RenderDelegateDestroyPrim(renderDelegate, typeEntry.fallbackPrim); typeEntry.fallbackPrim = nullptr; } }
void Hd_PrimTypeIndex<PrimType>::InsertPrim(const TfToken &typeId, HdSceneDelegate *sceneDelegate, const SdfPath &primId, HdChangeTracker &tracker, HdRenderDelegate *renderDelegate) { HD_TRACE_FUNCTION(); HF_MALLOC_TAG_FUNCTION(); typename _TypeIndex::iterator typeIt = _index.find(typeId); if (typeIt ==_index.end()) { TF_CODING_ERROR("Unsupported prim type: %s", typeId.GetText()); return; } SdfPath const &sceneDelegateId = sceneDelegate->GetDelegateID(); if (!primId.HasPrefix(sceneDelegateId)) { TF_CODING_ERROR("Scene Delegate Id (%s) must prefix prim Id (%s)", sceneDelegateId.GetText(), primId.GetText()); return; } PrimType *prim = _RenderDelegateCreatePrim(renderDelegate, typeId, primId); if (prim == nullptr) { // Render Delegate is responsible for reporting reason creation failed. return; } HdDirtyBits initialDirtyState = prim->GetInitialDirtyBitsMask(); _TrackerInsertPrim(tracker, primId, initialDirtyState); _PrimTypeEntry &typeEntry = _entries[typeIt->second]; const bool emplaced = typeEntry.primMap.emplace(primId, _PrimInfo{sceneDelegate, prim}).second; if (emplaced) { // Only add the primId if this is the first instance in the map. typeEntry.primIds.Insert(primId); } else { // The emplace failed so we should destroy the render prim. _RenderDelegateDestroyPrim(renderDelegate, prim); } }
void UsdImagingMeshAdapter::_GetSubdivTags(UsdPrim const& prim, SubdivTags* tags, UsdTimeCode time) { HD_TRACE_FUNCTION(); HF_MALLOC_TAG_FUNCTION(); if(!prim.IsA<UsdGeomMesh>()) return; TfToken token; VtIntArray iarray; VtFloatArray farray; _GetPtr(prim, UsdGeomTokens->interpolateBoundary, time, &token); tags->SetVertexInterpolationRule(token); auto meshPrim = UsdGeomMesh(prim); token = meshPrim.GetFaceVaryingLinearInterpolation(time); tags->SetFaceVaryingInterpolationRule(token); // XXX uncomment after fixing USD schema //_GetPtr(prim, UsdGeomTokens->creaseMethod, time, &token); //tags->SetCreaseMethod(token); _GetPtr(prim, UsdGeomTokens->triangleSubdivisionRule, time, &token); tags->SetTriangleSubdivision(token); _GetPtr(prim, UsdGeomTokens->creaseIndices, time, &iarray); tags->SetCreaseIndices(iarray); _GetPtr(prim, UsdGeomTokens->creaseLengths, time, &iarray); tags->SetCreaseLengths(iarray); _GetPtr(prim, UsdGeomTokens->creaseSharpnesses, time, &farray); tags->SetCreaseWeights(farray); _GetPtr(prim, UsdGeomTokens->cornerIndices, time, &iarray); tags->SetCornerIndices(iarray); _GetPtr(prim, UsdGeomTokens->cornerSharpnesses, time, &farray); tags->SetCornerWeights(farray); _GetPtr(prim, UsdGeomTokens->holeIndices, time, &iarray); tags->SetHoleIndices(iarray); }
void UsdImagingMeshAdapter::_GetMeshTopology(UsdPrim const& prim, VtValue* topo, UsdTimeCode time) { HD_TRACE_FUNCTION(); HF_MALLOC_TAG_FUNCTION(); TfToken schemeToken; _GetPtr(prim, UsdGeomTokens->subdivisionScheme, time, &schemeToken); *topo = HdMeshTopology( schemeToken, _Get<TfToken>(prim, UsdGeomTokens->orientation, time), _Get<VtIntArray>(prim, UsdGeomTokens->faceVertexCounts, time), _Get<VtIntArray>(prim, UsdGeomTokens->faceVertexIndices, time), _Get<VtIntArray>(prim, UsdGeomTokens->holeIndices, time)); }
void HdRenderPass::Execute(HdRenderPassStateSharedPtr const &renderPassState) { HD_TRACE_FUNCTION(); HF_MALLOC_TAG_FUNCTION(); // CPU frustum culling (if chosen) _PrepareCommandBuffer(renderPassState); // GPU frustum culling (if chosen) for (_HdCommandBufferMap::iterator it = _cmdBuffers.begin(); it != _cmdBuffers.end(); it++) { it->second.PrepareDraw(renderPassState); it->second.ExecuteDraw(renderPassState); } }
void HdRenderIndex::InsertRprim(TfToken const& typeId, HdSceneDelegate* sceneDelegate, SdfPath const& rprimId, SdfPath const& instancerId /*= SdfPath()*/) { HD_TRACE_FUNCTION(); HF_MALLOC_TAG_FUNCTION(); if (ARCH_UNLIKELY(TfMapLookupPtr(_rprimMap, rprimId))) { return; } SdfPath const &sceneDelegateId = sceneDelegate->GetDelegateID(); if (!rprimId.HasPrefix(sceneDelegateId)) { TF_CODING_ERROR("Scene Delegate Id (%s) must prefix prim Id (%s)", sceneDelegateId.GetText(), rprimId.GetText()); return; } HdRprim *rprim = _renderDelegate->CreateRprim(typeId, rprimId, instancerId); if (rprim == nullptr) { return; } _rprimIds.Insert(rprimId); _tracker.RprimInserted(rprimId, rprim->GetInitialDirtyBitsMask()); _AllocatePrimId(rprim); _RprimInfo info = { sceneDelegate, rprim }; _rprimMap[rprimId] = std::move(info); SdfPath instanceId = rprim->GetInstancerId(); if (!instanceId.IsEmpty()) { _tracker.InstancerRPrimInserted(instanceId, rprimId); } }
/* virtual */ std::string HdxSimpleLightingShader::GetSource(TfToken const &shaderStageKey) const { HD_TRACE_FUNCTION(); HF_MALLOC_TAG_FUNCTION(); std::string source = _glslfx->GetSource(shaderStageKey); if (source.empty()) return source; std::stringstream defineStream; size_t numLights = _useLighting ? _lightingContext->GetNumLightsUsed() : 0; bool useShadows = _useLighting ? _lightingContext->GetUseShadows() : false; defineStream << "#define NUM_LIGHTS " << numLights<< "\n"; defineStream << "#define USE_SHADOWS " << (int)(useShadows) << "\n"; return defineStream.str() + source; }
void Hd_PrimTypeIndex<PrimType>::GetPrimSubtree(const TfToken &typeId, const SdfPath &rootPath, SdfPathVector *outPaths) { HD_TRACE_FUNCTION(); HF_MALLOC_TAG_FUNCTION(); typename _TypeIndex::const_iterator typeIt = _index.find(typeId); if (typeIt ==_index.end()) { TF_CODING_ERROR("Unsupported prim type: %s", typeId.GetText()); return; } _PrimTypeEntry &typeEntry = _entries[typeIt->second]; HdPrimGather gather; gather.Subtree(typeEntry.primIds.GetIds(), rootPath, outPaths); }
void HdxColorCorrectionTask::Execute(HdTaskContext* ctx) { HD_TRACE_FUNCTION(); HF_MALLOC_TAG_FUNCTION(); if (!_CreateBufferResources()) { return; } if (!_CreateShaderResources()) { return; } _CreateFramebufferResources(&_texture); _CopyTexture(); _ApplyColorCorrection(); }
/*virtual*/ void HdRenderPass::Execute(HdRenderPassStateSharedPtr const &renderPassState, TfToken const &renderTag) { HD_TRACE_FUNCTION(); HF_MALLOC_TAG_FUNCTION(); // CPU frustum culling (if chosen) _PrepareCommandBuffer(renderPassState); // Check if the render tag has a command buffer associated with it if( _cmdBuffers.count(renderTag)==0 ) { return; } // GPU frustum culling (if chosen) _cmdBuffers[renderTag].PrepareDraw(renderPassState); _cmdBuffers[renderTag].ExecuteDraw(renderPassState); }
void HdxShadowTask::_Execute(HdTaskContext* ctx) { HD_TRACE_FUNCTION(); HF_MALLOC_TAG_FUNCTION(); // Extract the lighting context information from the task context GlfSimpleLightingContextRefPtr lightingContext; if (!_GetTaskContextData(ctx, HdxTokens->lightingContext, &lightingContext)) { return; } if (_depthBiasEnable) { glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(_depthBiasSlopeFactor, _depthBiasConstantFactor); } else { glDisable(GL_POLYGON_OFFSET_FILL); } // XXX: Move conversion to sync time once Task header becomes private. glDepthFunc(HdConversions::GetGlDepthFunc(_depthFunc)); glEnable(GL_PROGRAM_POINT_SIZE); // Generate the actual shadow maps GlfSimpleShadowArrayRefPtr const shadows = lightingContext->GetShadows(); for(size_t shadowId = 0; shadowId < shadows->GetNumLayers(); shadowId++) { // Bind the framebuffer that will store shadowId shadow map shadows->BeginCapture(shadowId, true); // Render the actual geometry in the collection _passes[shadowId]->Execute(_renderPassStates[shadowId], HdTokens->geometry); // Unbind the buffer and move on to the next shadow map shadows->EndCapture(shadowId); } // restore GL states to default glDisable(GL_PROGRAM_POINT_SIZE); glDisable(GL_POLYGON_OFFSET_FILL); }
bool Hd_PrimTypeIndex<PrimType>::CreateFallbackPrims(HdRenderDelegate *renderDelegate) { HD_TRACE_FUNCTION(); HF_MALLOC_TAG_FUNCTION(); bool success = true; for (_TypeIndex::const_iterator typeIt = _index.begin(); typeIt != _index.end(); ++typeIt) { _PrimTypeEntry &typeEntry = _entries[typeIt->second]; typeEntry.fallbackPrim = _RenderDelegateCreateFallbackPrim(renderDelegate, typeIt->first); success &= (typeEntry.fallbackPrim != nullptr); } return success; }
bool Hd_AdjacencyBuilderForGPUComputation::Resolve() { if (!_adjacencyBuilder->IsResolved()) return false; if (!_TryLock()) return false; HD_TRACE_FUNCTION(); HF_MALLOC_TAG_FUNCTION(); // prepare buffer source to be transferred. std::vector<int> const &adjacency = _adjacency->GetAdjacencyTable(); // create buffer source VtIntArray array(adjacency.size()); for (size_t i = 0; i < adjacency.size(); ++i) { array[i] = adjacency[i]; } _SetResult(HdBufferSourceSharedPtr(new HdVtBufferSource(HdTokens->adjacency, VtValue(array)))); _SetResolved(); return true; }
void Hd_PrimTypeIndex<PrimType>::Clear(HdChangeTracker &tracker, HdRenderDelegate *renderDelegate) { HD_TRACE_FUNCTION(); HF_MALLOC_TAG_FUNCTION(); size_t primTypeCount = _entries.size(); for (size_t typeIdx = 0; typeIdx < primTypeCount; ++typeIdx) { _PrimTypeEntry &typeEntry = _entries[typeIdx]; for (typename _PrimMap::iterator primIt = typeEntry.primMap.begin(); primIt != typeEntry.primMap.end(); ++primIt) { _TrackerRemovePrim(tracker, primIt->first); _PrimInfo &primInfo = primIt->second; _RenderDelegateDestroyPrim(renderDelegate, primInfo.prim); primInfo.prim = nullptr; } typeEntry.primMap.clear(); typeEntry.primIds.Clear(); } }
void HdxCompositor::UpdateColor(int width, int height, uint8_t *data) { HD_TRACE_FUNCTION(); HF_MALLOC_TAG_FUNCTION(); if (width == 0 || height == 0) { if (_colorTexture != 0) { glDeleteTextures(1, &_colorTexture); _colorTexture = 0; } return; } if (_colorTexture == 0) { _CreateTextureResources(&_colorTexture); } glBindTexture(GL_TEXTURE_2D, _colorTexture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); glBindTexture(GL_TEXTURE_2D, 0); GLF_POST_PENDING_GL_ERRORS(); }
void HdxCompositor::UpdateDepth(int width, int height, uint8_t *data) { HD_TRACE_FUNCTION(); HF_MALLOC_TAG_FUNCTION(); if (width == 0 || height == 0) { if (_depthTexture != 0) { glDeleteTextures(1, &_depthTexture); _depthTexture = 0; } return; } if (_depthTexture == 0) { _CreateTextureResources(&_depthTexture); } glBindTexture(GL_TEXTURE_2D, _depthTexture); glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, width, height, 0, GL_RED, GL_FLOAT, data); glBindTexture(GL_TEXTURE_2D, 0); GLF_POST_PENDING_GL_ERRORS(); }
/* virtual */ void HdxLight::Sync(HdSceneDelegate *sceneDelegate, HdRenderParam *renderParam, HdDirtyBits *dirtyBits) { HD_TRACE_FUNCTION(); HF_MALLOC_TAG_FUNCTION(); TF_UNUSED(renderParam); SdfPath const &id = GetID(); if (!TF_VERIFY(sceneDelegate != nullptr)) { return; } // HdxLight communicates to the scene graph and caches all interesting // values within this class. // later on Get() is called from TaskState (RenderPass) to perform // aggregation/pre-computation, in order to make the shader execution // efficient. HdDirtyBits bits = *dirtyBits; // Change tracking // Transform if (bits & DirtyTransform) { VtValue transform = sceneDelegate->Get(id, HdxLightTokens->transform); if (transform.IsHolding<GfMatrix4d>()) { _params[HdxLightTokens->transform] = transform; } else { _params[HdxLightTokens->transform] = GfMatrix4d(1); } } // Lighting Params if (bits & DirtyParams) { _params[HdxLightTokens->params] = sceneDelegate->Get(id, HdxLightTokens->params); } // Shadow Params if (bits & DirtyShadowParams) { _params[HdxLightTokens->shadowParams] = sceneDelegate->Get(id, HdxLightTokens->shadowParams); } // Shadow Collection if (bits & DirtyCollection) { VtValue vtShadowCollection = sceneDelegate->Get(id, HdxLightTokens->shadowCollection); // Optional if (vtShadowCollection.IsHolding<HdRprimCollection>()) { HdRprimCollection newCollection = vtShadowCollection.UncheckedGet<HdRprimCollection>(); if (_params[HdxLightTokens->shadowCollection] != newCollection) { _params[HdxLightTokens->shadowCollection] = newCollection; HdChangeTracker& changeTracker = sceneDelegate->GetRenderIndex().GetChangeTracker(); changeTracker.MarkCollectionDirty(newCollection.GetName()); } } else { _params[HdxLightTokens->shadowCollection] = HdRprimCollection(); } } *dirtyBits = Clean; }
/* virtual */ void HdStLight::Sync(HdSceneDelegate *sceneDelegate, HdRenderParam *renderParam, HdDirtyBits *dirtyBits) { HD_TRACE_FUNCTION(); HF_MALLOC_TAG_FUNCTION(); TF_UNUSED(renderParam); SdfPath const &id = GetId(); if (!TF_VERIFY(sceneDelegate != nullptr)) { return; } // HdStLight communicates to the scene graph and caches all interesting // values within this class. Later on Get() is called from // TaskState (RenderPass) to perform aggregation/pre-computation, // in order to make the shader execution efficient. // Change tracking HdDirtyBits bits = *dirtyBits; // Transform if (bits & DirtyTransform) { VtValue transform = sceneDelegate->Get(id, HdLightTokens->transform); if (transform.IsHolding<GfMatrix4d>()) { _params[HdLightTokens->transform] = transform; } else { _params[HdLightTokens->transform] = GfMatrix4d(1); } } // Lighting Params if (bits & DirtyParams) { // If it is an area light we will extract the parameters and convert // them to a gl friendly representation. if (_lightType == HdPrimTypeTokens->simpleLight) { _params[HdLightTokens->params] = sceneDelegate->Get(id, HdLightTokens->params); } else { _params[HdLightTokens->params] = _ApproximateAreaLight(id, sceneDelegate); } } // Shadow Params if (bits & DirtyShadowParams) { _params[HdLightTokens->shadowParams] = sceneDelegate->Get(id, HdLightTokens->shadowParams); } // Shadow Collection if (bits & DirtyCollection) { VtValue vtShadowCollection = sceneDelegate->Get(id, HdLightTokens->shadowCollection); // Optional if (vtShadowCollection.IsHolding<HdRprimCollection>()) { HdRprimCollection newCollection = vtShadowCollection.UncheckedGet<HdRprimCollection>(); if (_params[HdLightTokens->shadowCollection] != newCollection) { _params[HdLightTokens->shadowCollection] = newCollection; HdChangeTracker& changeTracker = sceneDelegate->GetRenderIndex().GetChangeTracker(); changeTracker.MarkCollectionDirty(newCollection.GetName()); } } else { _params[HdLightTokens->shadowCollection] = HdRprimCollection(); } } *dirtyBits = Clean; }
SdfPathVector const& HdDirtyList::GetDirtyRprims() { HD_TRACE_FUNCTION(); HF_MALLOC_TAG_FUNCTION(); /* HdDirtyList has 3-states: - initialization list (any dirty bits) - stable varying list (Varying bit) - empty (isEmpty = true) MarkDirtyStable -----------+ ^ | [init list build] <-+- CollectionChange | | | ^ ^ | | v | | | +-------+ | +---------+ | +<----------------+<---| empty | | |init list|--> MarkDirty | | +-------+ | +---------+ | | ^ [reuse] | | | | | Clean v | Clean | | MarkDirtyUnstable | ^ | v | | | | +-------+ | | | | | empty | | +---------------+ | +-------+ | | varying list | <-----+ | | +---------------+ MarkDirty | ^ | v | +-----------> [varying list build] --------+ */ // see if there's any variability change or not. HdChangeTracker &changeTracker = _renderIndex.GetChangeTracker(); unsigned int currentCollectionVersion = changeTracker.GetCollectionVersion(_collection.GetName()); unsigned int currentVaryingStateVersion = changeTracker.GetVaryingStateVersion(); unsigned int currentChangeCount = changeTracker.GetChangeCount(); // if nothing changed, and if it's clean, returns empty. if (_isEmpty && _changeCount == currentChangeCount) { static SdfPathVector _EMPTY; return _EMPTY; } // if nothing changed, but not yet cleaned, returns the cached result. // this list can be either initialization-set or varying-set if (_changeCount == currentChangeCount) { return _dirtyIds; } if (_collectionVersion != currentCollectionVersion) { TF_DEBUG(HD_DIRTY_LIST).Msg("DirtyList(%p): collection version" " changed (%s, %d -> %d)\n", (void*)this, _collection.GetName().GetText(), _collectionVersion, currentCollectionVersion); // populate dirty rprims in the collection _UpdateIDs(&_dirtyIds, 0); TF_FOR_ALL(it, _dirtyIds) { changeTracker.MarkRprimDirty(*it, HdChangeTracker::InitRepr); }
void HdRprim::_PopulateConstantPrimVars(HdSceneDelegate* delegate, HdDrawItem *drawItem, HdDirtyBits *dirtyBits) { HD_TRACE_FUNCTION(); HF_MALLOC_TAG_FUNCTION(); SdfPath const& id = GetId(); HdRenderIndex &renderIndex = delegate->GetRenderIndex(); HdResourceRegistry *resourceRegistry = &HdResourceRegistry::GetInstance(); // XXX: this should be in a different method // XXX: This should be in HdSt getting the HdSt Shader const HdShader *shader = static_cast<const HdShader *>( renderIndex.GetSprim(HdPrimTypeTokens->shader, _surfaceShaderID)); if (shader == nullptr) { shader = static_cast<const HdShader *>( renderIndex.GetFallbackSprim(HdPrimTypeTokens->shader)); } _sharedData.surfaceShader = shader->GetShaderCode(); // update uniforms HdBufferSourceVector sources; if (HdChangeTracker::IsTransformDirty(*dirtyBits, id)) { GfMatrix4d transform = delegate->GetTransform(id); _sharedData.bounds.SetMatrix(transform); // for CPU frustum culling HdBufferSourceSharedPtr source(new HdVtBufferSource( HdTokens->transform, transform)); sources.push_back(source); source.reset(new HdVtBufferSource(HdTokens->transformInverse, transform.GetInverse())); sources.push_back(source); // if this is a prototype (has instancer), // also push the instancer transform separately. if (!_instancerID.IsEmpty()) { // gather all instancer transforms in the instancing hierarchy VtMatrix4dArray rootTransforms = _GetInstancerTransforms(delegate); VtMatrix4dArray rootInverseTransforms(rootTransforms.size()); bool leftHanded = transform.IsLeftHanded(); for (size_t i = 0; i < rootTransforms.size(); ++i) { rootInverseTransforms[i] = rootTransforms[i].GetInverse(); // flip the handedness if necessary leftHanded ^= rootTransforms[i].IsLeftHanded(); } source.reset(new HdVtBufferSource( HdTokens->instancerTransform, rootTransforms, /*staticArray=*/true)); sources.push_back(source); source.reset(new HdVtBufferSource( HdTokens->instancerTransformInverse, rootInverseTransforms, /*staticArray=*/true)); sources.push_back(source); // XXX: It might be worth to consider to have isFlipped // for non-instanced prims as well. It can improve // the drawing performance on older-GPUs by reducing // fragment shader cost, although it needs more GPU memory. // set as int (GLSL needs 32-bit align for bool) source.reset(new HdVtBufferSource( HdTokens->isFlipped, VtValue(int(leftHanded)))); sources.push_back(source); } } if (HdChangeTracker::IsExtentDirty(*dirtyBits, id)) { _sharedData.bounds.SetRange(GetExtent(delegate)); GfVec3d const & localMin = drawItem->GetBounds().GetBox().GetMin(); HdBufferSourceSharedPtr sourceMin(new HdVtBufferSource( HdTokens->bboxLocalMin, VtValue(GfVec4f( localMin[0], localMin[1], localMin[2], 0)))); sources.push_back(sourceMin); GfVec3d const & localMax = drawItem->GetBounds().GetBox().GetMax(); HdBufferSourceSharedPtr sourceMax(new HdVtBufferSource( HdTokens->bboxLocalMax, VtValue(GfVec4f( localMax[0], localMax[1], localMax[2], 0)))); sources.push_back(sourceMax); } if (HdChangeTracker::IsPrimIdDirty(*dirtyBits, id)) { GfVec4f primIdColor; int32_t primId = GetPrimId(); HdBufferSourceSharedPtr source(new HdVtBufferSource( HdTokens->primID, VtValue(primId))); sources.push_back(source); } if (HdChangeTracker::IsAnyPrimVarDirty(*dirtyBits, id)) { TfTokenVector primVarNames = delegate->GetPrimVarConstantNames(id); sources.reserve(sources.size()+primVarNames.size()); TF_FOR_ALL(nameIt, primVarNames) { if (HdChangeTracker::IsPrimVarDirty(*dirtyBits, id, *nameIt)) { VtValue value = delegate->Get(id, *nameIt); // XXX Hydra doesn't support string primvar yet if (value.IsHolding<std::string>()) continue; if (!value.IsEmpty()) { HdBufferSourceSharedPtr source( new HdVtBufferSource(*nameIt, value)); // if it's an unacceptable type, skip it (e.g. std::string) if (source->GetNumComponents() > 0) { sources.push_back(source); } } } } }