diff options
| author | Cosmic Linden <cosmic@lindenlab.com> | 2023-01-24 17:48:18 -0800 | 
|---|---|---|
| committer | Cosmic Linden <cosmic@lindenlab.com> | 2023-01-25 12:34:35 -0800 | 
| commit | 2aaa15fef15243e6b38f46426d8ebb355ccfb807 (patch) | |
| tree | 718f00f4f3c5eb412199ab1b4c530e3308a647c2 | |
| parent | a851aa83e705fa4a1c78919cfcac6709cfb1a875 (diff) | |
SL-19012: Fix new material IDs sometimes not applying when set via LSL
| -rw-r--r-- | indra/newview/llfetchedgltfmaterial.cpp | 32 | ||||
| -rw-r--r-- | indra/newview/llfetchedgltfmaterial.h | 10 | ||||
| -rw-r--r-- | indra/newview/llgltfmateriallist.cpp | 10 | ||||
| -rw-r--r-- | indra/newview/llgltfmateriallist.h | 2 | ||||
| -rw-r--r-- | indra/newview/llviewerobject.cpp | 36 | ||||
| -rw-r--r-- | indra/newview/llviewerobject.h | 1 | 
6 files changed, 76 insertions, 15 deletions
| diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp index b095b74519..047f1a4965 100644 --- a/indra/newview/llfetchedgltfmaterial.cpp +++ b/indra/newview/llfetchedgltfmaterial.cpp @@ -115,3 +115,35 @@ void LLFetchedGLTFMaterial::bind()      }  } + +void LLFetchedGLTFMaterial::materialBegin() +{ +    llassert(!mFetching); +    mFetching = true; +} + +void LLFetchedGLTFMaterial::onMaterialComplete(std::function<void()> material_complete) +{ +    if (!material_complete) { return; } + +    if (!mFetching) +    { +        material_complete(); +        return; +    } + +    materialCompleteCallbacks.push_back(material_complete); +} + +void LLFetchedGLTFMaterial::materialComplete() +{ +    llassert(mFetching); +    mFetching = false; + +    for (std::function<void()> material_complete : materialCompleteCallbacks) +    { +        material_complete(); +    } +    materialCompleteCallbacks.clear(); +    materialCompleteCallbacks.shrink_to_fit(); +} diff --git a/indra/newview/llfetchedgltfmaterial.h b/indra/newview/llfetchedgltfmaterial.h index 4f6c56012e..f784f19c4f 100644 --- a/indra/newview/llfetchedgltfmaterial.h +++ b/indra/newview/llfetchedgltfmaterial.h @@ -39,6 +39,9 @@ public:      LLFetchedGLTFMaterial();      virtual ~LLFetchedGLTFMaterial(); +    // If this material is loaded, fire the given function +    void onMaterialComplete(std::function<void()> material_complete); +      // bind this material for rendering      void bind(); @@ -49,9 +52,14 @@ public:      LLPointer<LLViewerFetchedTexture> mEmissiveTexture;  protected: -    //Lifetime management +    // Lifetime management +     +    void materialBegin(); +    void materialComplete(); +      F64 mExpectedFlusTime; // since epoch in seconds      bool mActive;      bool mFetching; +    std::vector<std::function<void()>> materialCompleteCallbacks;  }; diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp index 4cf1562042..bc094ac838 100644 --- a/indra/newview/llgltfmateriallist.cpp +++ b/indra/newview/llgltfmateriallist.cpp @@ -525,7 +525,7 @@ void LLGLTFMaterialList::onAssetLoadComplete(const LLUUID& id, LLAssetType::ETyp      if (status != LL_ERR_NOERR)      {          LL_WARNS("GLTF") << "Error getting material asset data: " << LLAssetStorage::getErrorString(status) << " (" << status << ")" << LL_ENDL; -        asset_data->mMaterial->mFetching = false; +        asset_data->mMaterial->materialComplete();          delete asset_data;      }      else @@ -611,13 +611,15 @@ void LLGLTFMaterialList::onAssetLoadComplete(const LLUUID& id, LLAssetType::ETyp              {                  LL_DEBUGS("GLTF") << "Failed to get material " << id << LL_ENDL;              } -            asset_data->mMaterial->mFetching = false; + +            asset_data->mMaterial->materialComplete(); +              delete asset_data;          });      }  } -LLGLTFMaterial* LLGLTFMaterialList::getMaterial(const LLUUID& id) +LLFetchedGLTFMaterial* LLGLTFMaterialList::getMaterial(const LLUUID& id)  {      LL_PROFILE_ZONE_SCOPED;      uuid_mat_map_t::iterator iter = mList.find(id); @@ -629,7 +631,7 @@ LLGLTFMaterial* LLGLTFMaterialList::getMaterial(const LLUUID& id)          if (!mat->mFetching)          { -            mat->mFetching = true; +            mat->materialBegin();              AssetLoadUserData *user_data = new AssetLoadUserData();              user_data->mMaterial = mat; diff --git a/indra/newview/llgltfmateriallist.h b/indra/newview/llgltfmateriallist.h index 5ce0e324f5..85e60aa17f 100644 --- a/indra/newview/llgltfmateriallist.h +++ b/indra/newview/llgltfmateriallist.h @@ -45,7 +45,7 @@ public:      LLGLTFMaterialList() {} -    LLGLTFMaterial* getMaterial(const LLUUID& id); +    LLFetchedGLTFMaterial* getMaterial(const LLUUID& id);      void addMaterial(const LLUUID& id, LLFetchedGLTFMaterial* material);      void removeMaterial(const LLUUID& id); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index f416080f9e..5a365c79ea 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -7160,6 +7160,14 @@ const LLUUID& LLViewerObject::getRenderMaterialID(U8 te) const      return LLUUID::null;  } +void LLViewerObject::rebuildMaterial() +{ +    llassert(!isDead()); + +    faceMappingChanged(); +    gPipeline.markTextured(mDrawable); +} +  void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool update_server)  {      // implementation is delicate @@ -7188,17 +7196,16 @@ void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool updat      } +    LLFetchedGLTFMaterial* new_material = nullptr; +    if (id.notNull()) +    { +        new_material = gGLTFMaterialList.getMaterial(id); +    } +              // update local state      for (S32 te = start_idx; te < end_idx; ++te)      { -         -        LLGLTFMaterial* new_material = nullptr;          LLTextureEntry* tep = getTE(te); - -        if (id.notNull()) -        { -            new_material = gGLTFMaterialList.getMaterial(id); -        }          bool material_changed = !param_block || id != param_block->getMaterial(te); @@ -7225,8 +7232,19 @@ void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool updat      }      // signal to render pipe that render batches must be rebuilt for this object -    faceMappingChanged(); -    gPipeline.markTextured(mDrawable); +    if (!new_material) +    { +        rebuildMaterial(); +    } +    else +    { +        LLPointer<LLViewerObject> this_ptr = this; +        new_material->onMaterialComplete([this_ptr]() mutable { +            if (this_ptr->isDead()) { return; } + +            this_ptr->rebuildMaterial(); +        }); +    }      if (update_server)      { diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index fae29c3bc2..93b17361ab 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -226,6 +226,7 @@ public:  private:  	void				resetRotTime();      void				setRenderMaterialIDs(const LLRenderMaterialParams* material_params, bool local_origin); +    void                rebuildMaterial();  public:  	void				resetRot();  	void				applyAngularVelocity(F32 dt); | 
