diff options
| -rw-r--r-- | indra/newview/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | indra/newview/llfetchedgltfmaterial.cpp | 42 | ||||
| -rw-r--r-- | indra/newview/llfetchedgltfmaterial.h | 48 | ||||
| -rw-r--r-- | indra/newview/llgltfmateriallist.cpp | 82 | ||||
| -rw-r--r-- | indra/newview/llgltfmateriallist.h | 13 | ||||
| -rw-r--r-- | indra/newview/lllocalgltfmaterials.cpp | 6 | ||||
| -rw-r--r-- | indra/newview/llmaterialeditor.cpp | 5 | ||||
| -rw-r--r-- | indra/newview/llviewerdisplay.cpp | 14 | 
8 files changed, 189 insertions, 23 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 1882f75de9..374db7fdf8 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -208,6 +208,7 @@ set(viewer_SOURCE_FILES      llfasttimerview.cpp      llfavoritesbar.cpp      llfeaturemanager.cpp +    llfetchedgltfmaterial.cpp      llfilepicker.cpp      llfilteredwearablelist.cpp      llfirstuse.cpp @@ -853,6 +854,7 @@ set(viewer_HEADER_FILES      llfasttimerview.h      llfavoritesbar.h      llfeaturemanager.h +    llfetchedgltfmaterial.h      llfilepicker.h      llfilteredwearablelist.h      llfirstuse.h diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp new file mode 100644 index 0000000000..a06dd276cd --- /dev/null +++ b/indra/newview/llfetchedgltfmaterial.cpp @@ -0,0 +1,42 @@ +/** + * @file   llfetchedgltfmaterial.cpp + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2022, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfetchedgltfmaterial.h" + +LLFetchedGLTFMaterial::LLFetchedGLTFMaterial() +    : LLGLTFMaterial() +    , mExpectedFlusTime(0.f) +    , mActive(true) +    , mFetching(false) +{ + +} + +LLFetchedGLTFMaterial::~LLFetchedGLTFMaterial() +{ + +} diff --git a/indra/newview/llfetchedgltfmaterial.h b/indra/newview/llfetchedgltfmaterial.h new file mode 100644 index 0000000000..115e85a5e2 --- /dev/null +++ b/indra/newview/llfetchedgltfmaterial.h @@ -0,0 +1,48 @@ +/** + * @file   llfetchedgltfmaterial.h + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2022, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + + +#pragma once + +#include "llgltfmaterial.h" +#include "llpointer.h" + +class LLFetchedGLTFMaterial : public LLGLTFMaterial +{ +    friend class LLGLTFMaterialList; // for lifetime management +public: +    LLFetchedGLTFMaterial(); +    virtual ~LLFetchedGLTFMaterial(); + +protected: +    //Lifetime management +    F64 mExpectedFlusTime; // since epoch in seconds +    bool mActive; +    bool mFetching; +}; + +extern LLGLTFMaterialList gGLTFMaterialList; + + diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp index a433644e0e..84cf746198 100644 --- a/indra/newview/llgltfmateriallist.cpp +++ b/indra/newview/llgltfmateriallist.cpp @@ -29,9 +29,11 @@  #include "llassetstorage.h"  #include "lldispatcher.h" +#include "llfetchedgltfmaterial.h"  #include "llfilesystem.h"  #include "llsdserialize.h"  #include "lltinygltfhelper.h" +#include "llviewercontrol.h"  #include "llviewergenericmessage.h"  #include "tinygltf/tiny_gltf.h" @@ -73,19 +75,25 @@ LLGLTFMaterialList gGLTFMaterialList;  LLGLTFMaterial* LLGLTFMaterialList::getMaterial(const LLUUID& id)  { -    List::iterator iter = mList.find(id); +    uuid_mat_map_t::iterator iter = mList.find(id);      if (iter == mList.end())      { -        LLGLTFMaterial* mat = new LLGLTFMaterial(); +        LLFetchedGLTFMaterial* mat = new LLFetchedGLTFMaterial();          mList[id] = mat; -        mat->ref(); - -        gAssetStorage->getAssetData(id, LLAssetType::AT_MATERIAL, -            [=](const LLUUID& id, LLAssetType::EType asset_type, void* user_data, S32 status, LLExtStat ext_status) +        if (!mat->mFetching) +        { +            // if we do multiple getAssetData calls, +            // some will get distched, messing ref counter +            // Todo: get rid of mat->ref() +            mat->mFetching = true; +            mat->ref(); + +            gAssetStorage->getAssetData(id, LLAssetType::AT_MATERIAL, +                [=](const LLUUID& id, LLAssetType::EType asset_type, void* user_data, S32 status, LLExtStat ext_status)              {                  if (status) -                {  +                {                      LL_WARNS() << "Error getting material asset data: " << LLAssetStorage::getErrorString(status) << " (" << status << ")" << LL_ENDL;                  } @@ -94,6 +102,7 @@ LLGLTFMaterial* LLGLTFMaterialList::getMaterial(const LLUUID& id)                  if (!size)                  {                      LL_DEBUGS() << "Zero size material." << LL_ENDL; +                    mat->mFetching = false;                      mat->unref();                      return;                  } @@ -134,8 +143,10 @@ LLGLTFMaterial* LLGLTFMaterialList::getMaterial(const LLUUID& id)                      LL_WARNS() << "Failed to deserialize material LLSD" << LL_ENDL;                  } +                mat->mFetching = false;                  mat->unref();              }, nullptr); +        }          return mat;      } @@ -143,7 +154,7 @@ LLGLTFMaterial* LLGLTFMaterialList::getMaterial(const LLUUID& id)      return iter->second;  } -void LLGLTFMaterialList::addMaterial(const LLUUID& id, LLGLTFMaterial* material) +void LLGLTFMaterialList::addMaterial(const LLUUID& id, LLFetchedGLTFMaterial* material)  {      mList[id] = material;  } @@ -153,6 +164,61 @@ void LLGLTFMaterialList::removeMaterial(const LLUUID& id)      mList.erase(id);  } +void LLGLTFMaterialList::flushMaterials() +{ +    // Similar variant to what textures use +    static const S32 MIN_UPDATE_COUNT = gSavedSettings.getS32("TextureFetchUpdateMinCount");       // default: 32 +    //update MIN_UPDATE_COUNT or 5% of materials, whichever is greater +    U32 update_count = llmax((U32)MIN_UPDATE_COUNT, (U32)mList.size() / 20); +    update_count = llmin(update_count, (U32)mList.size()); + +    const F64 MAX_INACTIVE_TIME = 30.f; +    F64 cur_time = LLTimer::getTotalSeconds(); + +    uuid_mat_map_t::iterator iter = mList.upper_bound(mLastUpdateKey); +    while (update_count-- > 0) +    { +        if (iter == mList.end()) +        { +            iter = mList.begin(); +        } + +        LLPointer<LLFetchedGLTFMaterial> material = iter->second; +        if (material->getNumRefs() == 2) // this one plus one from the list +        { + +            if (!material->mActive +                && cur_time > material->mExpectedFlusTime) +            { +                iter = mList.erase(iter); +            } +            else +            { +                if (material->mActive) +                { +                    material->mExpectedFlusTime = cur_time + MAX_INACTIVE_TIME; +                    material->mActive = false; +                } +                ++iter; +            } +        } +        else +        { +            material->mActive = true; +            ++iter; +        } +    } + +    if (iter != mList.end()) +    { +        mLastUpdateKey = iter->first; +    } +    else +    { +        mLastUpdateKey.setNull(); +    } +} +  // static  void LLGLTFMaterialList::registerCallbacks()  { diff --git a/indra/newview/llgltfmateriallist.h b/indra/newview/llgltfmateriallist.h index 4aed4b009d..4b905e32c9 100644 --- a/indra/newview/llgltfmateriallist.h +++ b/indra/newview/llgltfmateriallist.h @@ -26,26 +26,33 @@  #pragma once +#include "llfetchedgltfmaterial.h"  #include "llgltfmaterial.h"  #include "llpointer.h"  #include <unordered_map> +class LLFetchedGLTFMaterial; +  class LLGLTFMaterialList  {  public:      LLGLTFMaterialList() {} -    typedef std::unordered_map<LLUUID, LLPointer<LLGLTFMaterial > > List; -    List mList;      LLGLTFMaterial* getMaterial(const LLUUID& id); -    void addMaterial(const LLUUID& id, LLGLTFMaterial* material); +    void addMaterial(const LLUUID& id, LLFetchedGLTFMaterial* material);      void removeMaterial(const LLUUID& id); +    void flushMaterials(); +      static void registerCallbacks(); +private: +    typedef std::unordered_map<LLUUID, LLPointer<LLFetchedGLTFMaterial > > uuid_mat_map_t; +    uuid_mat_map_t mList; +    LLUUID mLastUpdateKey;  };  extern LLGLTFMaterialList gGLTFMaterialList; diff --git a/indra/newview/lllocalgltfmaterials.cpp b/indra/newview/lllocalgltfmaterials.cpp index fe2b7ac816..f292844313 100644 --- a/indra/newview/lllocalgltfmaterials.cpp +++ b/indra/newview/lllocalgltfmaterials.cpp @@ -152,16 +152,16 @@ bool LLLocalGLTFMaterial::updateSelf()              if (mLastModified.asString() != new_last_modified.asString())              { -                LLPointer<LLGLTFMaterial> raw_material; +                LLPointer<LLFetchedGLTFMaterial> raw_material;                  if (mWorldID.notNull())                  {                      // update existing material                      // will create a new one if material doesn't exist yet -                    raw_material = gGLTFMaterialList.getMaterial(mWorldID); +                    raw_material = (LLFetchedGLTFMaterial*)gGLTFMaterialList.getMaterial(mWorldID);                  }                  else                  { -                    raw_material = new LLGLTFMaterial(); +                    raw_material = new LLFetchedGLTFMaterial();                  }                  if (loadMaterial(raw_material, mMaterialIndex))                  { diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 319f98b816..c5cdb81d67 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1422,7 +1422,8 @@ void LLMaterialEditor::loadFromGLTFMaterial(LLUUID &asset_id)          return;      }      LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor"); -    me->setTitle(LLTrans::getString("New Material")); +    me->mMaterialName = LLTrans::getString("New Material"); +    me->setTitle(me->mMaterialName);      me->setHasUnsavedChanges(true);      me->setFromGLTFMaterial(gGLTFMaterialList.getMaterial(asset_id));      me->openFloater(); @@ -1943,7 +1944,7 @@ void LLMaterialEditor::applyToSelection()          LL_WARNS() << "not connected to materials capable region, missing ModifyMaterialParams cap" << LL_ENDL;          // Fallback local preview. Will be removed once override systems is finished and new cap is deployed everywhere. -        LLPointer<LLGLTFMaterial> mat = new LLGLTFMaterial(); +        LLPointer<LLFetchedGLTFMaterial> mat = new LLFetchedGLTFMaterial();          getGLTFMaterial(mat);          static const LLUUID placeholder("984e183e-7811-4b05-a502-d79c6f978a98");          gGLTFMaterialList.addMaterial(placeholder, mat); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 46e25b18b7..ed3631be99 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -31,6 +31,7 @@  #include "llgl.h"  #include "llrender.h"  #include "llglheaders.h" +#include "llgltfmateriallist.h"  #include "llagent.h"  #include "llagentcamera.h"  #include "llviewercontrol.h" @@ -254,7 +255,7 @@ static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE("Update Images");  static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE_CLASS("Class");  static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE_BUMP("Image Update Bump");  static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE_LIST("List"); -static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE_DELETE("Delete"); +static LLTrace::BlockTimerStatHandle FTM_MATERIALS_FLUSH("GLTF Materials Cleanup");  static LLTrace::BlockTimerStatHandle FTM_RESIZE_WINDOW("Resize Window");  static LLTrace::BlockTimerStatHandle FTM_HUD_UPDATE("HUD Update");  static LLTrace::BlockTimerStatHandle FTM_DISPLAY_UPDATE_GEOM("Update Geom"); @@ -807,12 +808,11 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  				gTextureList.updateImages(max_image_decode_time);  			} -			/*{ -				LL_RECORD_BLOCK_TIME(FTM_IMAGE_UPDATE_DELETE); -				//remove dead textures from GL -				LLImageGL::deleteDeadTextures(); -				stop_glerror(); -			}*/ +			{ +				LL_RECORD_BLOCK_TIME(FTM_MATERIALS_FLUSH); +				//remove dead gltf materials +                gGLTFMaterialList.flushMaterials(); +			}  		}  		LLGLState::checkStates();  | 
