| 446 | } |
| 447 | |
| 448 | Material::UpdateFlags MaterialSystem::update(bool forceUpdate) |
| 449 | { |
| 450 | // Some materials only determine the required number of textures during their update. |
| 451 | // If the number of required textures is greated than getMaxTextureCount() reported, |
| 452 | // we could run out of texture slots. This is why metadata is reupdated again, |
| 453 | // after the material's update() has been called. (A typical example is UDIM, the number |
| 454 | // of actually used texture slots depends on the number of files on drive) |
| 455 | bool reupdateMetadata = false; |
| 456 | |
| 457 | // If materials were added/removed since last update, we update all metadata |
| 458 | // and trigger re-creation of the parameter block and update of all materials. |
| 459 | if (forceUpdate || mMaterialsChanged) |
| 460 | { |
| 461 | updateMetadata(); |
| 462 | updateUI(); |
| 463 | |
| 464 | mpMaterialsBlock = nullptr; |
| 465 | mMaterialsChanged = false; |
| 466 | forceUpdate = true; |
| 467 | reupdateMetadata = true; |
| 468 | } |
| 469 | |
| 470 | // Update all materials. |
| 471 | // Do either a full update of all materials with deferred texture loading, or an update of just the dynamic materials. |
| 472 | // We track per-material update flags along with the combined update flags across all materials. |
| 473 | // Note that materials can record updates in between calls to update() and/or return flags from their update() calls. |
| 474 | Material::UpdateFlags updateFlags = Material::UpdateFlags::None; |
| 475 | mMaterialsUpdateFlags.resize(mMaterials.size()); |
| 476 | std::fill(mMaterialsUpdateFlags.begin(), mMaterialsUpdateFlags.end(), Material::UpdateFlags::None); |
| 477 | |
| 478 | auto updateMaterial = [&](const MaterialID materialID) { |
| 479 | auto& pMaterial = getMaterial(materialID); |
| 480 | if (pMaterial->mpDevice != mpDevice) |
| 481 | FALCOR_THROW("Material '{}' was created with a different device than the MaterialSystem.", pMaterial->getName()); |
| 482 | Material::UpdateFlags flags = pMaterial->update(this); |
| 483 | // Record update flags. |
| 484 | mMaterialsUpdateFlags[materialID.get()] = flags; |
| 485 | updateFlags |= flags; |
| 486 | }; |
| 487 | |
| 488 | if (forceUpdate || mMaterialUpdates != Material::UpdateFlags::None) |
| 489 | { |
| 490 | mpTextureManager->beginDeferredLoading(); |
| 491 | |
| 492 | for (size_t materialIdx = 0; materialIdx < mMaterials.size(); ++materialIdx) |
| 493 | updateMaterial(MaterialID{ materialIdx }); |
| 494 | |
| 495 | mpTextureManager->endDeferredLoading(); |
| 496 | } |
| 497 | else |
| 498 | { |
| 499 | for (const auto& materialID : mDynamicMaterialIDs) |
| 500 | updateMaterial(materialID); |
| 501 | } |
| 502 | |
| 503 | if (reupdateMetadata) |
| 504 | { |
| 505 | updateMetadata(); |
nothing calls this directly
no test coverage detected