diff --git a/indra/llcommon/llprofiler.h b/indra/llcommon/llprofiler.h
index d1ccfa999d..428702e0e7 100644
--- a/indra/llcommon/llprofiler.h
+++ b/indra/llcommon/llprofiler.h
@@ -146,7 +146,7 @@ namespace LLProfiler
#define LL_RECORD_BLOCK_TIME(name) const LLTrace::BlockTimer& LL_GLUE_TOKENS(block_time_recorder, __LINE__)(LLTrace::timeThisBlock(name)); (void)LL_GLUE_TOKENS(block_time_recorder, __LINE__);
#define LL_PROFILE_ZONE_NAMED(name) // LL_PROFILE_ZONE_NAMED is a no-op when Tracy is disabled
- #define LL_PROFILE_ZONE_NAMED_COLOR(name,color) // LL_RECORD_BLOCK_TIME(name)
+ #define LL_PROFILE_ZONE_NAMED_COLOR(name,color) // LL_PROFILE_ZONE_NAMED_COLOR is a no-op when Tracy is disabled
#define LL_PROFILE_ZONE_SCOPED // LL_PROFILE_ZONE_SCOPED is a no-op when Tracy is disabled
#define LL_PROFILE_ZONE_NUM( val ) (void)( val ); // Not supported
diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp
index 3810aa676c..2460af381b 100644
--- a/indra/llcommon/llsdserialize.cpp
+++ b/indra/llcommon/llsdserialize.cpp
@@ -475,6 +475,7 @@ LLSDNotationParser::~LLSDNotationParser()
// virtual
S32 LLSDNotationParser::doParse(std::istream& istr, LLSD& data, S32 max_depth) const
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD
// map: { string:object, string:object }
// array: [ object, object, object ]
// undef: !
@@ -734,6 +735,7 @@ S32 LLSDNotationParser::doParse(std::istream& istr, LLSD& data, S32 max_depth) c
S32 LLSDNotationParser::parseMap(std::istream& istr, LLSD& map, S32 max_depth) const
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD
// map: { string:object, string:object }
map = LLSD::emptyMap();
S32 parse_count = 0;
@@ -794,6 +796,7 @@ S32 LLSDNotationParser::parseMap(std::istream& istr, LLSD& map, S32 max_depth) c
S32 LLSDNotationParser::parseArray(std::istream& istr, LLSD& array, S32 max_depth) const
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD
// array: [ object, object, object ]
array = LLSD::emptyArray();
S32 parse_count = 0;
@@ -833,6 +836,7 @@ S32 LLSDNotationParser::parseArray(std::istream& istr, LLSD& array, S32 max_dept
bool LLSDNotationParser::parseString(std::istream& istr, LLSD& data) const
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD
std::string value;
auto count = deserialize_string(istr, value, mMaxBytesLeft);
if(PARSE_FAILURE == count) return false;
@@ -843,6 +847,7 @@ bool LLSDNotationParser::parseString(std::istream& istr, LLSD& data) const
bool LLSDNotationParser::parseBinary(std::istream& istr, LLSD& data) const
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD
// binary: b##"ff3120ab1"
// or: b(len)"..."
@@ -945,6 +950,7 @@ LLSDBinaryParser::~LLSDBinaryParser()
// virtual
S32 LLSDBinaryParser::doParse(std::istream& istr, LLSD& data, S32 max_depth) const
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD
/**
* Undefined: '!'
* Boolean: '1' for true '0' for false
diff --git a/indra/llcommon/llsdserialize_xml.cpp b/indra/llcommon/llsdserialize_xml.cpp
index 492678a59d..727aad3b96 100644
--- a/indra/llcommon/llsdserialize_xml.cpp
+++ b/indra/llcommon/llsdserialize_xml.cpp
@@ -958,6 +958,8 @@ void LLSDXMLParser::parsePart(const char *buf, llssize len)
// virtual
S32 LLSDXMLParser::doParse(std::istream& input, LLSD& data, S32 max_depth) const
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD
+
#ifdef XML_PARSER_PERFORMANCE_TESTS
XML_Timer timer( &parseTime );
#endif // XML_PARSER_PERFORMANCE_TESTS
diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp
index bc63dfd493..8b39d52b6a 100644
--- a/indra/llinventory/llinventory.cpp
+++ b/indra/llinventory/llinventory.cpp
@@ -982,152 +982,173 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new)
mInventoryType = LLInventoryType::IT_NONE;
mAssetUUID.setNull();
}
- std::string w;
- w = INV_ITEM_ID_LABEL;
- if (sd.has(w))
- {
- mUUID = sd[w];
- }
- w = INV_PARENT_ID_LABEL;
- if (sd.has(w))
- {
- mParentUUID = sd[w];
- }
+ // TODO - figure out if this should be moved into the noclobber fields above
mThumbnailUUID.setNull();
- w = INV_THUMBNAIL_LABEL;
- if (sd.has(w))
+
+ // iterate as map to avoid making unnecessary temp copies of everything
+ LLSD::map_const_iterator i, end;
+ end = sd.endMap();
+ for (i = sd.beginMap(); i != end; ++i)
{
- const LLSD &thumbnail_map = sd[w];
- w = INV_ASSET_ID_LABEL;
- if (thumbnail_map.has(w))
+ if (i->first == INV_ITEM_ID_LABEL)
{
- mThumbnailUUID = thumbnail_map[w];
+ mUUID = i->second;
+ continue;
}
- /* Example:
- asset_id
- acc0ec86 - 17f2 - 4b92 - ab41 - 6718b1f755f7
- perms
- 8
- service
- 3
- version
- 1
- */
- }
- else
- {
- w = INV_THUMBNAIL_ID_LABEL;
- if (sd.has(w))
+
+ if (i->first == INV_PARENT_ID_LABEL)
{
- mThumbnailUUID = sd[w].asUUID();
+ mParentUUID = i->second;
+ continue;
+ }
+
+ if (i->first == INV_THUMBNAIL_LABEL)
+ {
+ const LLSD &thumbnail_map = i->second;
+ const std::string w = INV_ASSET_ID_LABEL;
+ if (thumbnail_map.has(w))
+ {
+ mThumbnailUUID = thumbnail_map[w];
+ }
+ /* Example:
+ asset_id
+ acc0ec86 - 17f2 - 4b92 - ab41 - 6718b1f755f7
+ perms
+ 8
+ service
+ 3
+ version
+ 1
+ */
+ continue;
+ }
+
+ if (i->first == INV_THUMBNAIL_ID_LABEL)
+ {
+ mThumbnailUUID = i->second.asUUID();
+ continue;
+ }
+
+ if (i->first == INV_PERMISSIONS_LABEL)
+ {
+ mPermissions = ll_permissions_from_sd(i->second);
+ continue;
+ }
+
+ if (i->first == INV_SALE_INFO_LABEL)
+ {
+ // Sale info used to contain next owner perm. It is now in
+ // the permissions. Thus, we read that out, and fix legacy
+ // objects. It's possible this op would fail, but it
+ // should pick up the vast majority of the tasks.
+ BOOL has_perm_mask = FALSE;
+ U32 perm_mask = 0;
+ if (!mSaleInfo.fromLLSD(i->second, has_perm_mask, perm_mask))
+ {
+ return false;
+ }
+ if (has_perm_mask)
+ {
+ if (perm_mask == PERM_NONE)
+ {
+ perm_mask = mPermissions.getMaskOwner();
+ }
+ // fair use fix.
+ if (!(perm_mask & PERM_COPY))
+ {
+ perm_mask |= PERM_TRANSFER;
+ }
+ mPermissions.setMaskNext(perm_mask);
+ }
+ continue;
+ }
+
+ if (i->first == INV_SHADOW_ID_LABEL)
+ {
+ mAssetUUID = i->second;
+ LLXORCipher cipher(MAGIC_ID.mData, UUID_BYTES);
+ cipher.decrypt(mAssetUUID.mData, UUID_BYTES);
+ continue;
+ }
+
+ if (i->first == INV_ASSET_ID_LABEL)
+ {
+ mAssetUUID = i->second;
+ continue;
+ }
+
+ if (i->first == INV_LINKED_ID_LABEL)
+ {
+ mAssetUUID = i->second;
+ continue;
+ }
+
+ if (i->first == INV_ASSET_TYPE_LABEL)
+ {
+ LLSD const &label = i->second;
+ if (label.isString())
+ {
+ mType = LLAssetType::lookup(label.asString().c_str());
+ }
+ else if (label.isInteger())
+ {
+ S8 type = (U8) label.asInteger();
+ mType = static_cast(type);
+ }
+ continue;
+ }
+
+ if (i->first == INV_INVENTORY_TYPE_LABEL)
+ {
+ LLSD const &label = i->second;
+ if (label.isString())
+ {
+ mInventoryType = LLInventoryType::lookup(label.asString().c_str());
+ }
+ else if (label.isInteger())
+ {
+ S8 type = (U8) label.asInteger();
+ mInventoryType = static_cast(type);
+ }
+ continue;
+ }
+
+ if (i->first == INV_FLAGS_LABEL)
+ {
+ LLSD const &label = i->second;
+ if (label.isBinary())
+ {
+ mFlags = ll_U32_from_sd(label);
+ }
+ else if (label.isInteger())
+ {
+ mFlags = label.asInteger();
+ }
+ continue;
+ }
+
+ if (i->first == INV_NAME_LABEL)
+ {
+ mName = i->second.asString();
+ LLStringUtil::replaceNonstandardASCII(mName, ' ');
+ LLStringUtil::replaceChar(mName, '|', ' ');
+ continue;
+ }
+
+ if (i->first == INV_DESC_LABEL)
+ {
+ mDescription = i->second.asString();
+ LLStringUtil::replaceNonstandardASCII(mDescription, ' ');
+ continue;
+ }
+
+ if (i->first == INV_CREATION_DATE_LABEL)
+ {
+ mCreationDate = i->second.asInteger();
+ continue;
}
}
- w = INV_PERMISSIONS_LABEL;
- if (sd.has(w))
- {
- mPermissions = ll_permissions_from_sd(sd[w]);
- }
- w = INV_SALE_INFO_LABEL;
- if (sd.has(w))
- {
- // Sale info used to contain next owner perm. It is now in
- // the permissions. Thus, we read that out, and fix legacy
- // objects. It's possible this op would fail, but it
- // should pick up the vast majority of the tasks.
- BOOL has_perm_mask = FALSE;
- U32 perm_mask = 0;
- if (!mSaleInfo.fromLLSD(sd[w], has_perm_mask, perm_mask))
- {
- goto fail;
- }
- if (has_perm_mask)
- {
- if(perm_mask == PERM_NONE)
- {
- perm_mask = mPermissions.getMaskOwner();
- }
- // fair use fix.
- if(!(perm_mask & PERM_COPY))
- {
- perm_mask |= PERM_TRANSFER;
- }
- mPermissions.setMaskNext(perm_mask);
- }
- }
- w = INV_SHADOW_ID_LABEL;
- if (sd.has(w))
- {
- mAssetUUID = sd[w];
- LLXORCipher cipher(MAGIC_ID.mData, UUID_BYTES);
- cipher.decrypt(mAssetUUID.mData, UUID_BYTES);
- }
- w = INV_ASSET_ID_LABEL;
- if (sd.has(w))
- {
- mAssetUUID = sd[w];
- }
- w = INV_LINKED_ID_LABEL;
- if (sd.has(w))
- {
- mAssetUUID = sd[w];
- }
- w = INV_ASSET_TYPE_LABEL;
- if (sd.has(w))
- {
- if (sd[w].isString())
- {
- mType = LLAssetType::lookup(sd[w].asString().c_str());
- }
- else if (sd[w].isInteger())
- {
- S8 type = (U8)sd[w].asInteger();
- mType = static_cast(type);
- }
- }
- w = INV_INVENTORY_TYPE_LABEL;
- if (sd.has(w))
- {
- if (sd[w].isString())
- {
- mInventoryType = LLInventoryType::lookup(sd[w].asString().c_str());
- }
- else if (sd[w].isInteger())
- {
- S8 type = (U8)sd[w].asInteger();
- mInventoryType = static_cast(type);
- }
- }
- w = INV_FLAGS_LABEL;
- if (sd.has(w))
- {
- if (sd[w].isBinary())
- {
- mFlags = ll_U32_from_sd(sd[w]);
- }
- else if(sd[w].isInteger())
- {
- mFlags = sd[w].asInteger();
- }
- }
- w = INV_NAME_LABEL;
- if (sd.has(w))
- {
- mName = sd[w].asString();
- LLStringUtil::replaceNonstandardASCII(mName, ' ');
- LLStringUtil::replaceChar(mName, '|', ' ');
- }
- w = INV_DESC_LABEL;
- if (sd.has(w))
- {
- mDescription = sd[w].asString();
- LLStringUtil::replaceNonstandardASCII(mDescription, ' ');
- }
- w = INV_CREATION_DATE_LABEL;
- if (sd.has(w))
- {
- mCreationDate = sd[w].asInteger();
- }
// Need to convert 1.0 simstate files to a useful inventory type
// and potentially deal with bad inventory tyes eg, a landmark
@@ -1142,9 +1163,6 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new)
mPermissions.initMasks(mInventoryType);
return true;
-fail:
- return false;
-
}
///----------------------------------------------------------------------------
diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp
index f42c11ee21..d2c911a189 100644
--- a/indra/llprimitive/llgltfmaterial.cpp
+++ b/indra/llprimitive/llgltfmaterial.cpp
@@ -89,6 +89,10 @@ LLGLTFMaterial& LLGLTFMaterial::operator=(const LLGLTFMaterial& rhs)
mOverrideDoubleSided = rhs.mOverrideDoubleSided;
mOverrideAlphaMode = rhs.mOverrideAlphaMode;
+ mTrackingIdToLocalTexture = rhs.mTrackingIdToLocalTexture;
+
+ updateTextureTracking();
+
return *this;
}
@@ -601,6 +605,10 @@ void LLGLTFMaterial::applyOverride(const LLGLTFMaterial& override_mat)
mTextureTransform[i].mRotation = override_mat.mTextureTransform[i].mRotation;
}
}
+
+ mTrackingIdToLocalTexture.insert(override_mat.mTrackingIdToLocalTexture.begin(), override_mat.mTrackingIdToLocalTexture.begin());
+
+ updateTextureTracking();
}
void LLGLTFMaterial::getOverrideLLSD(const LLGLTFMaterial& override_mat, LLSD& data)
@@ -765,3 +773,47 @@ LLUUID LLGLTFMaterial::getHash() const
return hash;
}
+void LLGLTFMaterial::addLocalTextureTracking(const LLUUID& tracking_id, const LLUUID& tex_id)
+{
+ mTrackingIdToLocalTexture[tracking_id] = tex_id;
+}
+
+void LLGLTFMaterial::removeLocalTextureTracking(const LLUUID& tracking_id)
+{
+ mTrackingIdToLocalTexture.erase(tracking_id);
+}
+
+bool LLGLTFMaterial::replaceLocalTexture(const LLUUID& tracking_id, const LLUUID& old_id, const LLUUID& new_id)
+{
+ bool res = false;
+
+ for (int i = 0; i < GLTF_TEXTURE_INFO_COUNT; ++i)
+ {
+ if (mTextureId[i] == old_id)
+ {
+ mTextureId[i] = new_id;
+ res = true;
+ }
+ else if (mTextureId[i] == new_id)
+ {
+ res = true;
+ }
+ }
+
+ if (res)
+ {
+ mTrackingIdToLocalTexture[tracking_id] = new_id;
+ }
+ else
+ {
+ mTrackingIdToLocalTexture.erase(tracking_id);
+ }
+
+ return res;
+}
+
+void LLGLTFMaterial::updateTextureTracking()
+{
+ // setTEGLTFMaterialOverride is responsible for tracking
+ // for material overrides editor will set it
+}
diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h
index 822a0aab22..02f62fb08c 100644
--- a/indra/llprimitive/llgltfmaterial.h
+++ b/indra/llprimitive/llgltfmaterial.h
@@ -196,7 +196,7 @@ public:
// write to given tinygltf::Model
void writeToModel(tinygltf::Model& model, S32 mat_index) const;
- void applyOverride(const LLGLTFMaterial& override_mat);
+ virtual void applyOverride(const LLGLTFMaterial& override_mat);
// apply the given LLSD override data
void applyOverrideLLSD(const LLSD& data);
@@ -222,6 +222,17 @@ public:
virtual void addTextureEntry(LLTextureEntry* te) {};
virtual void removeTextureEntry(LLTextureEntry* te) {};
+ // For local textures so that editor will know to track changes
+ void addLocalTextureTracking(const LLUUID& tracking_id, const LLUUID &tex_id);
+ void removeLocalTextureTracking(const LLUUID& tracking_id);
+ bool hasLocalTextures() { return !mTrackingIdToLocalTexture.empty(); }
+ virtual bool replaceLocalTexture(const LLUUID& tracking_id, const LLUUID &old_id, const LLUUID& new_id);
+ virtual void updateTextureTracking();
+
+ // These fields are local to viewer and are a part of local bitmap support
+ typedef std::map local_tex_map_t;
+ local_tex_map_t mTrackingIdToLocalTexture;
+
protected:
static LLVector2 vec2FromJson(const std::map& object, const char* key, const LLVector2& default_value);
static F32 floatFromJson(const std::map& object, const char* key, const F32 default_value);
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 62c462dcf6..7f00ab2f6d 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -194,7 +194,7 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks,
return;
}
- //start with arrow cursor
+ //start with arrow cursor
//initCursors();
initCursors(mUseLegacyCursors); // Legacy cursor setting from main program
setCursor( UI_CURSOR_ARROW );
@@ -646,6 +646,34 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
mGLView = createOpenGLView(mWindow, mFSAASamples, enable_vsync);
mContext = getCGLContextObj(mGLView);
gGLManager.mVRAM = getVramSize(mGLView);
+
+ if(!mPixelFormat)
+ {
+ CGLPixelFormatAttribute attribs[] =
+ {
+ kCGLPFANoRecovery,
+ kCGLPFADoubleBuffer,
+ kCGLPFAClosestPolicy,
+ kCGLPFAAccelerated,
+ kCGLPFAMultisample,
+ kCGLPFASampleBuffers, static_cast((mFSAASamples > 0 ? 1 : 0)),
+ kCGLPFASamples, static_cast(mFSAASamples),
+ kCGLPFAStencilSize, static_cast(8),
+ kCGLPFADepthSize, static_cast(24),
+ kCGLPFAAlphaSize, static_cast(8),
+ kCGLPFAColorSize, static_cast(24),
+ kCGLPFAOpenGLProfile, static_cast(kCGLOGLPVersion_GL4_Core),
+ static_cast(0)
+ };
+
+ GLint numPixelFormats;
+ CGLChoosePixelFormat (attribs, &mPixelFormat, &numPixelFormats);
+
+ if(mPixelFormat == NULL) {
+ CGLChoosePixelFormat (attribs, &mPixelFormat, &numPixelFormats);
+ }
+ }
+
}
// This sets up our view to recieve text from our non-inline text input window.
@@ -1982,6 +2010,11 @@ void* LLWindowMacOSX::createSharedContext()
{
sharedContext* sc = new sharedContext();
CGLCreateContext(mPixelFormat, mContext, &(sc->mContext));
+
+ if (sUseMultGL)
+ {
+ CGLEnable(mContext, kCGLCEMPEngine);
+ }
return (void *)sc;
}
@@ -1989,6 +2022,25 @@ void* LLWindowMacOSX::createSharedContext()
void LLWindowMacOSX::makeContextCurrent(void* context)
{
CGLSetCurrentContext(((sharedContext*)context)->mContext);
+
+ //enable multi-threaded OpenGL
+ if (sUseMultGL)
+ {
+ CGLError cgl_err;
+ CGLContextObj ctx = CGLGetCurrentContext();
+
+ cgl_err = CGLEnable( ctx, kCGLCEMPEngine);
+
+ if (cgl_err != kCGLNoError )
+ {
+ LL_INFOS("GLInit") << "Multi-threaded OpenGL not available." << LL_ENDL;
+ }
+ else
+ {
+ LL_INFOS("GLInit") << "Multi-threaded OpenGL enabled." << LL_ENDL;
+ }
+ }
+
}
void LLWindowMacOSX::destroySharedContext(void* context)
diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt
index 51567a130f..bebc96031d 100644
--- a/indra/newview/featuretable_mac.txt
+++ b/indra/newview/featuretable_mac.txt
@@ -1,4 +1,4 @@
-version 55
+version 56
// The version number above should be incremented IF AND ONLY IF some
// change has been made that is sufficiently important to justify
// resetting the graphics preferences of all users to the recommended
@@ -61,7 +61,7 @@ RenderShaderLightingMaxLevel 1 3
RenderDeferred 1 1
RenderDeferredSSAO 1 1
RenderUseAdvancedAtmospherics 1 0
-RenderShadowDetail 1 0
+RenderShadowDetail 1 2
RenderUseStreamVBO 1 1
RenderFSAASamples 1 16
RenderMaxTextureIndex 1 16
@@ -71,7 +71,7 @@ RenderGLMultiThreadedMedia 1 0
RenderReflectionsEnabled 1 1
RenderReflectionProbeDetail 1 2
RenderScreenSpaceReflections 1 1
-RenderReflectionProbeLevel 1 0
+RenderReflectionProbeLevel 1 3
//
// Low Graphics Settings
diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp
index fc9d42bfb6..1a47293523 100644
--- a/indra/newview/llfetchedgltfmaterial.cpp
+++ b/indra/newview/llfetchedgltfmaterial.cpp
@@ -144,6 +144,83 @@ void LLFetchedGLTFMaterial::bind(LLViewerTexture* media_tex)
}
+LLViewerFetchedTexture* fetch_texture(const LLUUID& id)
+{
+ LLViewerFetchedTexture* img = nullptr;
+ if (id.notNull())
+ {
+ img = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+ img->addTextureStats(64.f * 64.f, TRUE);
+ }
+ return img;
+};
+
+bool LLFetchedGLTFMaterial::replaceLocalTexture(const LLUUID& tracking_id, const LLUUID& old_id, const LLUUID& new_id)
+{
+ bool res = false;
+ if (mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR] == old_id)
+ {
+ mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR] = new_id;
+ mBaseColorTexture = fetch_texture(new_id);
+ res = true;
+ }
+ if (mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL] == old_id)
+ {
+ mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL] = new_id;
+ mNormalTexture = fetch_texture(new_id);
+ res = true;
+ }
+ if (mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS] == old_id)
+ {
+ mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS] = new_id;
+ mMetallicRoughnessTexture = fetch_texture(new_id);
+ res = true;
+ }
+ if (mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE] == old_id)
+ {
+ mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE] = new_id;
+ mEmissiveTexture = fetch_texture(new_id);
+ res = true;
+ }
+
+ for (int i = 0; i < GLTF_TEXTURE_INFO_COUNT; ++i)
+ {
+ if (mTextureId[i] == new_id)
+ {
+ res = true;
+ }
+ }
+
+ if (res)
+ {
+ mTrackingIdToLocalTexture[tracking_id] = new_id;
+ }
+ else
+ {
+ mTrackingIdToLocalTexture.erase(tracking_id);
+ }
+
+ return res;
+}
+
+void LLFetchedGLTFMaterial::addTextureEntry(LLTextureEntry* te)
+{
+ mTextureEntires.insert(te);
+}
+
+void LLFetchedGLTFMaterial::removeTextureEntry(LLTextureEntry* te)
+{
+ mTextureEntires.erase(te);
+}
+
+void LLFetchedGLTFMaterial::updateTextureTracking()
+{
+ for (local_tex_map_t::value_type &val : mTrackingIdToLocalTexture)
+ {
+ LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.first, this);
+ }
+}
+
void LLFetchedGLTFMaterial::materialBegin()
{
llassert(!mFetching);
diff --git a/indra/newview/llfetchedgltfmaterial.h b/indra/newview/llfetchedgltfmaterial.h
index 1668657281..2559aa46cc 100644
--- a/indra/newview/llfetchedgltfmaterial.h
+++ b/indra/newview/llfetchedgltfmaterial.h
@@ -50,12 +50,19 @@ public:
bool isFetching() const { return mFetching; }
+ void addTextureEntry(LLTextureEntry* te) override;
+ void removeTextureEntry(LLTextureEntry* te) override;
+ virtual bool replaceLocalTexture(const LLUUID& tracking_id, const LLUUID& old_id, const LLUUID& new_id) override;
+ virtual void updateTextureTracking() override;
+
// Textures used for fetching/rendering
LLPointer mBaseColorTexture;
LLPointer mNormalTexture;
LLPointer mMetallicRoughnessTexture;
LLPointer mEmissiveTexture;
+ std::set mTextureEntires;
+
protected:
// Lifetime management
diff --git a/indra/newview/llfloaterchangeitemthumbnail.cpp b/indra/newview/llfloaterchangeitemthumbnail.cpp
index b35af001bf..42be15ae37 100644
--- a/indra/newview/llfloaterchangeitemthumbnail.cpp
+++ b/indra/newview/llfloaterchangeitemthumbnail.cpp
@@ -761,7 +761,7 @@ void LLFloaterChangeItemThumbnail::showTexturePicker(const LLUUID &thumbnail_id)
{
//texture_floaterp->setTextureSelectedCallback();
//texture_floaterp->setOnUpdateImageStatsCallback();
- texture_floaterp->setOnFloaterCommitCallback([this](LLTextureCtrl::ETexturePickOp op, LLPickerSource, const LLUUID&, const LLUUID&)
+ texture_floaterp->setOnFloaterCommitCallback([this](LLTextureCtrl::ETexturePickOp op, LLPickerSource, const LLUUID&, const LLUUID&, const LLUUID&)
{
if (op == LLTextureCtrl::TEXTURE_SELECT)
{
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 56af8062e3..c70f2532c8 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -66,6 +66,7 @@
#include "bufferstream.h"
#include "llcorehttputil.h"
#include "hbxxh.h"
+#include "llstartup.h"
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a)
#include "rlvhandler.h"
#include "rlvlocks.h"
@@ -2830,6 +2831,7 @@ bool LLInventoryModel::loadSkeleton(
const LLSD& options,
const LLUUID& owner_id)
{
+ LL_PROFILE_ZONE_SCOPED;
// Purge inventory cache files marked by DELETE_INV_GZ marker files
std::string delete_cache_marker = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, owner_id.asString() + "_DELETE_INV_GZ");
LL_DEBUGS("LLInventoryModel") << "Checking for clear inventory cache marker: " << delete_cache_marker << LL_ENDL;
@@ -3598,6 +3600,8 @@ bool LLInventoryModel::loadFromFile(const std::string& filename,
LLInventoryModel::changed_items_t& cats_to_update,
bool &is_cache_obsolete)
{
+ LL_PROFILE_ZONE_NAMED("inventory load from file");
+
if(filename.empty())
{
LL_ERRS(LOG_INV) << "filename is Null!" << LL_ENDL;
@@ -3615,6 +3619,7 @@ bool LLInventoryModel::loadFromFile(const std::string& filename,
is_cache_obsolete = true; // Obsolete until proven current
+ //U64 lines_count = 0U;
std::string line;
LLPointer parser = new LLSDNotationParser();
while (std::getline(file, line))
@@ -3663,7 +3668,7 @@ bool LLInventoryModel::loadFromFile(const std::string& filename,
{
if(inv_item->getUUID().isNull())
{
- LL_WARNS(LOG_INV) << "Ignoring inventory with null item id: "
+ LL_DEBUGS(LOG_INV) << "Ignoring inventory with null item id: "
<< inv_item->getName() << LL_ENDL;
}
else
@@ -3679,6 +3684,14 @@ bool LLInventoryModel::loadFromFile(const std::string& filename,
}
}
}
+
+// TODO(brad) - figure out how to reenable this without breaking everything else
+// static constexpr U64 BATCH_SIZE = 512U;
+// if ((++lines_count % BATCH_SIZE) == 0)
+// {
+// // SL-19968 - make sure message system code gets a chance to run every so often
+// pump_idle_startup_network();
+// }
}
file.close();
diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp
index 70ed508c69..d1938d62f6 100644
--- a/indra/newview/lllocalbitmaps.cpp
+++ b/indra/newview/lllocalbitmaps.cpp
@@ -46,6 +46,7 @@
#include
/* misc headers */
+#include "llgltfmaterial.h"
#include "llscrolllistctrl.h"
#include "lllocaltextureobject.h"
#include "llviewertexturelist.h"
@@ -131,6 +132,14 @@ LLLocalBitmap::~LLLocalBitmap()
LLLocalBitmapMgr::getInstance()->doRebake();
}
+ for (LLPointer &mat : mGLTFMaterialWithLocalTextures)
+ {
+ mat->removeLocalTextureTracking(getTrackingID());
+ }
+
+ mChangedSignal(getTrackingID(), getWorldID(), LLUUID());
+ mChangedSignal.disconnect_all_slots();
+
// delete self from gimagelist
LLViewerFetchedTexture* image = gTextureList.findImage(mWorldID, TEX_LIST_STANDARD);
gTextureList.deleteImage(image);
@@ -142,27 +151,27 @@ LLLocalBitmap::~LLLocalBitmap()
}
/* accessors */
-std::string LLLocalBitmap::getFilename()
+std::string LLLocalBitmap::getFilename() const
{
return mFilename;
}
-std::string LLLocalBitmap::getShortName()
+std::string LLLocalBitmap::getShortName() const
{
return mShortName;
}
-LLUUID LLLocalBitmap::getTrackingID()
+LLUUID LLLocalBitmap::getTrackingID() const
{
return mTrackingID;
}
-LLUUID LLLocalBitmap::getWorldID()
+LLUUID LLLocalBitmap::getWorldID() const
{
return mWorldID;
}
-bool LLLocalBitmap::getValid()
+bool LLLocalBitmap::getValid() const
{
return mValid;
}
@@ -273,6 +282,41 @@ bool LLLocalBitmap::updateSelf(EUpdateType optional_firstupdate)
return updated;
}
+boost::signals2::connection LLLocalBitmap::setChangedCallback(const LLLocalTextureCallback& cb)
+{
+ return mChangedSignal.connect(cb);
+}
+
+void LLLocalBitmap::addGLTFMaterial(LLGLTFMaterial* mat)
+{
+ if (!mat)
+ {
+ return;
+ }
+
+ mat_list_t::iterator end = mGLTFMaterialWithLocalTextures.end();
+ for (mat_list_t::iterator it = mGLTFMaterialWithLocalTextures.begin(); it != end;)
+ {
+ if (it->get() == mat)
+ {
+ return;
+ }
+
+ if ((*it)->getNumRefs() == 1)
+ {
+ it = mGLTFMaterialWithLocalTextures.erase(it);
+ end = mGLTFMaterialWithLocalTextures.end();
+ }
+ else
+ {
+ it++;
+ }
+ }
+
+ mat->addLocalTextureTracking(getTrackingID(), getWorldID());
+ mGLTFMaterialWithLocalTextures.push_back(mat);
+}
+
bool LLLocalBitmap::decodeBitmap(LLPointer rawimg)
{
bool decode_successful = false;
@@ -340,7 +384,7 @@ bool LLLocalBitmap::decodeBitmap(LLPointer rawimg)
return decode_successful;
}
-void LLLocalBitmap::replaceIDs(LLUUID old_id, LLUUID new_id)
+void LLLocalBitmap::replaceIDs(const LLUUID& old_id, LLUUID new_id)
{
// checking for misuse.
if (old_id == new_id)
@@ -350,6 +394,8 @@ void LLLocalBitmap::replaceIDs(LLUUID old_id, LLUUID new_id)
return;
}
+ mChangedSignal(getTrackingID(), old_id, new_id);
+
// processing updates per channel; makes the process scalable.
// the only actual difference is in SetTE* call i.e. SetTETexture, SetTENormal, etc.
updateUserPrims(old_id, new_id, LLRender::DIFFUSE_MAP);
@@ -381,6 +427,8 @@ void LLLocalBitmap::replaceIDs(LLUUID old_id, LLUUID new_id)
updateUserLayers(old_id, new_id, LLWearableType::WT_UNIVERSAL);
updateUserLayers(old_id, new_id, LLWearableType::WT_UNDERPANTS);
updateUserLayers(old_id, new_id, LLWearableType::WT_UNDERSHIRT);
+
+ updateGLTFMaterials(old_id, new_id);
}
// this function sorts the faces from a getFaceList[getNumFaces] into a list of objects
@@ -587,6 +635,67 @@ void LLLocalBitmap::updateUserLayers(LLUUID old_id, LLUUID new_id, LLWearableTyp
}
}
+void LLLocalBitmap::updateGLTFMaterials(LLUUID old_id, LLUUID new_id)
+{
+ // Might be a better idea to hold this in LLGLTFMaterialList
+ mat_list_t::iterator end = mGLTFMaterialWithLocalTextures.end();
+ for (mat_list_t::iterator it = mGLTFMaterialWithLocalTextures.begin(); it != end;)
+ {
+ if ((*it)->getNumRefs() == 1)
+ {
+ // render and override materials are often recreated,
+ // clean up any remains
+ it = mGLTFMaterialWithLocalTextures.erase(it);
+ end = mGLTFMaterialWithLocalTextures.end();
+ }
+ else if ((*it)->replaceLocalTexture(mTrackingID, old_id, new_id))
+ {
+ it++;
+ }
+ else
+ {
+ // Matching id not found, no longer in use
+ // material would clean itself, remove from the list
+ it = mGLTFMaterialWithLocalTextures.erase(it);
+ end = mGLTFMaterialWithLocalTextures.end();
+ }
+ }
+
+ // Render material consists of base and override materials, make sure replaceLocalTexture
+ // gets called for base and override before applyOverride
+ end = mGLTFMaterialWithLocalTextures.end();
+ for (mat_list_t::iterator it = mGLTFMaterialWithLocalTextures.begin(); it != end;)
+ {
+ LLFetchedGLTFMaterial* fetched_mat = dynamic_cast((*it).get());
+ if (fetched_mat)
+ {
+ for (LLTextureEntry* entry : fetched_mat->mTextureEntires)
+ {
+ // Normally a change in applied material id is supposed to
+ // drop overrides thus reset material, but local materials
+ // currently reuse their existing asset id, and purpose is
+ // to preview how material will work in-world, overrides
+ // included, so do an override to render update instead.
+ LLGLTFMaterial* override_mat = entry->getGLTFMaterialOverride();
+ if (override_mat)
+ {
+ // do not create a new material, reuse existing pointer
+ LLFetchedGLTFMaterial* render_mat = (LLFetchedGLTFMaterial*)entry->getGLTFRenderMaterial();
+ if (render_mat)
+ {
+ llassert(dynamic_cast(entry->getGLTFRenderMaterial()) != nullptr);
+ {
+ *render_mat = *fetched_mat;
+ }
+ render_mat->applyOverride(*override_mat);
+ }
+ }
+ }
+ }
+ ++it;
+ }
+}
+
LLAvatarAppearanceDefines::ETextureIndex LLLocalBitmap::getTexIndex(
LLWearableType::EType type, LLAvatarAppearanceDefines::EBakedTextureIndex baked_texind)
{
@@ -1029,11 +1138,11 @@ void LLLocalBitmapMgr::delUnit(LLUUID tracking_id)
}
}
-LLUUID LLLocalBitmapMgr::getWorldID(LLUUID tracking_id)
+LLUUID LLLocalBitmapMgr::getWorldID(const LLUUID &tracking_id) const
{
LLUUID world_id = LLUUID::null;
- for (local_list_iter iter = mBitmapList.begin(); iter != mBitmapList.end(); iter++)
+ for (local_list_citer iter = mBitmapList.begin(); iter != mBitmapList.end(); iter++)
{
LLLocalBitmap* unit = *iter;
if (unit->getTrackingID() == tracking_id)
@@ -1045,9 +1154,9 @@ LLUUID LLLocalBitmapMgr::getWorldID(LLUUID tracking_id)
return world_id;
}
-bool LLLocalBitmapMgr::isLocal(const LLUUID world_id)
+bool LLLocalBitmapMgr::isLocal(const LLUUID &world_id) const
{
- for (local_list_iter iter = mBitmapList.begin(); iter != mBitmapList.end(); iter++)
+ for (local_list_citer iter = mBitmapList.begin(); iter != mBitmapList.end(); iter++)
{
LLLocalBitmap* unit = *iter;
if (unit->getWorldID() == world_id)
@@ -1058,11 +1167,11 @@ bool LLLocalBitmapMgr::isLocal(const LLUUID world_id)
return false;
}
-std::string LLLocalBitmapMgr::getFilename(LLUUID tracking_id)
+std::string LLLocalBitmapMgr::getFilename(const LLUUID &tracking_id) const
{
std::string filename = "";
- for (local_list_iter iter = mBitmapList.begin(); iter != mBitmapList.end(); iter++)
+ for (local_list_citer iter = mBitmapList.begin(); iter != mBitmapList.end(); iter++)
{
LLLocalBitmap* unit = *iter;
if (unit->getTrackingID() == tracking_id)
@@ -1074,6 +1183,32 @@ std::string LLLocalBitmapMgr::getFilename(LLUUID tracking_id)
return filename;
}
+boost::signals2::connection LLLocalBitmapMgr::setOnChangedCallback(const LLUUID tracking_id, const LLLocalBitmap::LLLocalTextureCallback &cb)
+{
+ for (local_list_iter iter = mBitmapList.begin(); iter != mBitmapList.end(); iter++)
+ {
+ LLLocalBitmap* unit = *iter;
+ if (unit->getTrackingID() == tracking_id)
+ {
+ return unit->setChangedCallback(cb);
+ }
+ }
+
+ return boost::signals2::connection();
+}
+
+void LLLocalBitmapMgr::associateGLTFMaterial(const LLUUID tracking_id, LLGLTFMaterial* mat)
+{
+ for (local_list_iter iter = mBitmapList.begin(); iter != mBitmapList.end(); iter++)
+ {
+ LLLocalBitmap* unit = *iter;
+ if (unit->getTrackingID() == tracking_id)
+ {
+ unit->addGLTFMaterial(mat);
+ }
+ }
+}
+
void LLLocalBitmapMgr::feedScrollList(LLScrollListCtrl* ctrl)
{
if (ctrl)
diff --git a/indra/newview/lllocalbitmaps.h b/indra/newview/lllocalbitmaps.h
index bb026ed3aa..1fdf9dccbf 100644
--- a/indra/newview/lllocalbitmaps.h
+++ b/indra/newview/lllocalbitmaps.h
@@ -36,6 +36,7 @@
class LLScrollListCtrl;
class LLImageRaw;
class LLViewerObject;
+class LLGLTFMaterial;
class LLLocalBitmap
{
@@ -44,11 +45,11 @@ class LLLocalBitmap
~LLLocalBitmap();
public: /* accessors */
- std::string getFilename();
- std::string getShortName();
- LLUUID getTrackingID();
- LLUUID getWorldID();
- bool getValid();
+ std::string getFilename() const;
+ std::string getShortName() const;
+ LLUUID getTrackingID() const;
+ LLUUID getWorldID() const;
+ bool getValid() const;
public: /* self update public section */
enum EUpdateType
@@ -59,13 +60,21 @@ class LLLocalBitmap
bool updateSelf(EUpdateType = UT_REGUPDATE);
+ typedef boost::signals2::signal LLLocalTextureChangedSignal;
+ typedef LLLocalTextureChangedSignal::slot_type LLLocalTextureCallback;
+ boost::signals2::connection setChangedCallback(const LLLocalTextureCallback& cb);
+ void addGLTFMaterial(LLGLTFMaterial* mat);
+
private: /* self update private section */
bool decodeBitmap(LLPointer raw);
- void replaceIDs(LLUUID old_id, LLUUID new_id);
+ void replaceIDs(const LLUUID &old_id, LLUUID new_id);
std::vector prepUpdateObjects(LLUUID old_id, U32 channel);
void updateUserPrims(LLUUID old_id, LLUUID new_id, U32 channel);
void updateUserVolumes(LLUUID old_id, LLUUID new_id, U32 channel);
void updateUserLayers(LLUUID old_id, LLUUID new_id, LLWearableType::EType type);
+ void updateGLTFMaterials(LLUUID old_id, LLUUID new_id);
LLAvatarAppearanceDefines::ETextureIndex getTexIndex(LLWearableType::EType type, LLAvatarAppearanceDefines::EBakedTextureIndex baked_texind);
private: /* private enums */
@@ -93,6 +102,12 @@ class LLLocalBitmap
EExtension mExtension;
ELinkStatus mLinkStatus;
S32 mUpdateRetries;
+ LLLocalTextureChangedSignal mChangedSignal;
+
+ // Store a list of accosiated materials
+ // Might be a better idea to hold this in LLGLTFMaterialList
+ typedef std::vector > mat_list_t;
+ mat_list_t mGLTFMaterialWithLocalTextures;
};
@@ -120,10 +135,12 @@ public:
void delUnit(LLUUID tracking_id);
bool checkTextureDimensions(std::string filename);
- LLUUID getWorldID(LLUUID tracking_id);
- bool isLocal(LLUUID world_id);
- std::string getFilename(LLUUID tracking_id);
-
+ LLUUID getWorldID(const LLUUID &tracking_id) const;
+ bool isLocal(const LLUUID& world_id) const;
+ std::string getFilename(const LLUUID &tracking_id) const;
+ boost::signals2::connection setOnChangedCallback(const LLUUID tracking_id, const LLLocalBitmap::LLLocalTextureCallback& cb);
+ void associateGLTFMaterial(const LLUUID tracking_id, LLGLTFMaterial* mat);
+
void feedScrollList(LLScrollListCtrl* ctrl);
void doUpdates();
void setNeedsRebake();
@@ -134,6 +151,7 @@ private:
LLLocalBitmapTimer mTimer;
bool mNeedsRebake;
typedef std::list::iterator local_list_iter;
+ typedef std::list::const_iterator local_list_citer;
};
#endif
diff --git a/indra/newview/lllocalgltfmaterials.cpp b/indra/newview/lllocalgltfmaterials.cpp
index b7fdead3f9..61e0163798 100644
--- a/indra/newview/lllocalgltfmaterials.cpp
+++ b/indra/newview/lllocalgltfmaterials.cpp
@@ -119,15 +119,6 @@ S32 LLLocalGLTFMaterial::getIndexInFile() const
return mMaterialIndex;
}
-void LLLocalGLTFMaterial::addTextureEntry(LLTextureEntry* te)
-{
- mTextureEntires.insert(te);
-}
-void LLLocalGLTFMaterial::removeTextureEntry(LLTextureEntry* te)
-{
- mTextureEntires.erase(te);
-}
-
/* update functions */
bool LLLocalGLTFMaterial::updateSelf()
{
diff --git a/indra/newview/lllocalgltfmaterials.h b/indra/newview/lllocalgltfmaterials.h
index 1442b83a40..13b7577e96 100644
--- a/indra/newview/lllocalgltfmaterials.h
+++ b/indra/newview/lllocalgltfmaterials.h
@@ -49,9 +49,6 @@ public: /* accessors */
LLUUID getWorldID() const;
S32 getIndexInFile() const;
- void addTextureEntry(LLTextureEntry* te) override;
- void removeTextureEntry(LLTextureEntry* te) override;
-
public:
bool updateSelf();
@@ -81,7 +78,6 @@ private: /* members */
ELinkStatus mLinkStatus;
S32 mUpdateRetries;
S32 mMaterialIndex; // Single file can have more than one
- std::set mTextureEntires;
};
class LLLocalGLTFMaterialTimer : public LLEventTimer
diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp
index 6ffad1de9d..450aded161 100644
--- a/indra/newview/llmaterialeditor.cpp
+++ b/indra/newview/llmaterialeditor.cpp
@@ -343,6 +343,39 @@ bool LLSelectedTEGetMatData::apply(LLViewerObject* objectp, S32 te_index)
return false;
}
+class LLSelectedTEUpdateOverrides: public LLSelectedNodeFunctor
+{
+public:
+ LLSelectedTEUpdateOverrides(LLMaterialEditor* me) : mEditor(me) {}
+
+ virtual bool apply(LLSelectNode* nodep);
+
+ LLMaterialEditor* mEditor;
+};
+
+bool LLSelectedTEUpdateOverrides::apply(LLSelectNode* nodep)
+{
+ LLViewerObject* objectp = nodep->getObject();
+ if (!objectp)
+ {
+ return false;
+ }
+ S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); // avatars have TEs but no faces
+ for (S32 te_index = 0; te_index < num_tes; ++te_index)
+ {
+
+ LLTextureEntry* tep = objectp->getTE(te_index);
+ LLGLTFMaterial* override_mat = tep->getGLTFMaterialOverride();
+ if (mEditor->updateMaterialLocalSubscription(override_mat))
+ {
+ LLGLTFMaterial* render_mat = tep->getGLTFRenderMaterial();
+ mEditor->updateMaterialLocalSubscription(render_mat);
+ }
+ }
+
+ return true;
+}
+
///----------------------------------------------------------------------------
/// Class LLMaterialEditor
///----------------------------------------------------------------------------
@@ -366,6 +399,10 @@ LLMaterialEditor::LLMaterialEditor(const LLSD& key)
}
}
+LLMaterialEditor::~LLMaterialEditor()
+{
+}
+
void LLMaterialEditor::setObjectID(const LLUUID& object_id)
{
LLPreview::setObjectID(object_id);
@@ -534,6 +571,11 @@ void LLMaterialEditor::onClose(bool app_quitting)
{
mSelectionUpdateSlot.disconnect();
}
+ for (mat_connection_map_t::value_type &cn : mTextureChangesUpdates)
+ {
+ cn.second.mConnection.disconnect();
+ }
+ mTextureChangesUpdates.clear();
LLPreview::onClose(app_quitting);
}
@@ -864,6 +906,118 @@ void LLMaterialEditor::setEnableEditing(bool can_modify)
mNormalTextureCtrl->setEnabled(can_modify);
}
+void LLMaterialEditor::subscribeToLocalTexture(S32 dirty_flag, const LLUUID& tracking_id)
+{
+ if (mTextureChangesUpdates[dirty_flag].mTrackingId != tracking_id)
+ {
+ mTextureChangesUpdates[dirty_flag].mConnection.disconnect();
+ mTextureChangesUpdates[dirty_flag].mTrackingId = tracking_id;
+ mTextureChangesUpdates[dirty_flag].mConnection = LLLocalBitmapMgr::getInstance()->setOnChangedCallback(tracking_id,
+ [this, dirty_flag](const LLUUID& tracking_id, const LLUUID& old_id, const LLUUID& new_id)
+ {
+ if (new_id.isNull())
+ {
+ mTextureChangesUpdates[dirty_flag].mConnection.disconnect();
+ //mTextureChangesUpdates.erase(dirty_flag);
+ }
+ else
+ {
+ replaceLocalTexture(old_id, new_id);
+ }
+ });
+ }
+}
+
+LLUUID LLMaterialEditor::getLocalTextureTrackingIdFromFlag(U32 flag)
+{
+ mat_connection_map_t::iterator found = mTextureChangesUpdates.find(flag);
+ if (found != mTextureChangesUpdates.end())
+ {
+ return found->second.mTrackingId;
+ }
+ return LLUUID();
+}
+
+bool LLMaterialEditor::updateMaterialLocalSubscription(LLGLTFMaterial* mat)
+{
+ if (!mat)
+ {
+ return false;
+ }
+
+ bool res = false;
+ for (mat_connection_map_t::value_type& cn : mTextureChangesUpdates)
+ {
+ LLUUID world_id = LLLocalBitmapMgr::getInstance()->getWorldID(cn.second.mTrackingId);
+ if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR])
+ {
+ LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(cn.second.mTrackingId, mat);
+ res = true;
+ continue;
+ }
+ if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS])
+ {
+ LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(cn.second.mTrackingId, mat);
+ res = true;
+ continue;
+ }
+ if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE])
+ {
+ LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(cn.second.mTrackingId, mat);
+ res = true;
+ continue;
+ }
+ if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL])
+ {
+ LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(cn.second.mTrackingId, mat);
+ res = true;
+ continue;
+ }
+ }
+ return res;
+}
+
+void LLMaterialEditor::replaceLocalTexture(const LLUUID& old_id, const LLUUID& new_id)
+{
+ // todo: might be a good idea to set mBaseColorTextureUploadId here
+ // and when texturectrl picks a local texture
+ if (getBaseColorId() == old_id)
+ {
+ mBaseColorTextureCtrl->setValue(new_id);
+ }
+ if (mBaseColorTextureCtrl->getDefaultImageAssetID() == old_id)
+ {
+ mBaseColorTextureCtrl->setDefaultImageAssetID(new_id);
+ }
+
+ if (getMetallicRoughnessId() == old_id)
+ {
+ mMetallicTextureCtrl->setValue(new_id);
+ }
+ if (mMetallicTextureCtrl->getDefaultImageAssetID() == old_id)
+ {
+ mMetallicTextureCtrl->setDefaultImageAssetID(new_id);
+ }
+
+ if (getEmissiveId() == old_id)
+ {
+ mEmissiveTextureCtrl->setValue(new_id);
+ }
+ if (mEmissiveTextureCtrl->getDefaultImageAssetID() == old_id)
+ {
+ mEmissiveTextureCtrl->setDefaultImageAssetID(new_id);
+ }
+
+ if (getNormalId() == old_id)
+ {
+ mNormalTextureCtrl->setValue(new_id);
+ }
+ if (mNormalTextureCtrl->getDefaultImageAssetID() == old_id)
+ {
+ mNormalTextureCtrl->setDefaultImageAssetID(new_id);
+ }
+}
+
void LLMaterialEditor::onCommitTexture(LLUICtrl* ctrl, const LLSD& data, S32 dirty_flag)
{
if (!mIsOverride)
@@ -916,6 +1070,21 @@ void LLMaterialEditor::onCommitTexture(LLUICtrl* ctrl, const LLSD& data, S32 dir
}
}
+ LLTextureCtrl* tex_ctrl = (LLTextureCtrl*)ctrl;
+ if (tex_ctrl->isImageLocal())
+ {
+ subscribeToLocalTexture(dirty_flag, tex_ctrl->getLocalTrackingID());
+ }
+ else
+ {
+ // unsubcribe potential old callabck
+ mat_connection_map_t::iterator found = mTextureChangesUpdates.find(dirty_flag);
+ if (found != mTextureChangesUpdates.end())
+ {
+ found->second.mConnection.disconnect();
+ }
+ }
+
markChangesUnsaved(dirty_flag);
applyToSelection();
}
@@ -926,6 +1095,16 @@ void LLMaterialEditor::onCancelCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_
applyToSelection();
}
+void update_local_texture(LLUICtrl* ctrl, LLGLTFMaterial* mat)
+{
+ LLTextureCtrl* tex_ctrl = (LLTextureCtrl*)ctrl;
+ if (tex_ctrl->isImageLocal())
+ {
+ // subscrive material to updates of local textures
+ LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tex_ctrl->getLocalTrackingID(), mat);
+ }
+}
+
void LLMaterialEditor::onSelectCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_flag)
{
mUnsavedChanges |= dirty_flag;
@@ -961,21 +1140,25 @@ void LLMaterialEditor::onSelectCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_
case MATERIAL_BASE_COLOR_TEX_DIRTY:
{
nodep->mSavedGLTFOverrideMaterials[te]->setBaseColorId(mCtrl->getValue().asUUID(), true);
+ update_local_texture(mCtrl, nodep->mSavedGLTFOverrideMaterials[te].get());
break;
}
case MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY:
{
nodep->mSavedGLTFOverrideMaterials[te]->setOcclusionRoughnessMetallicId(mCtrl->getValue().asUUID(), true);
+ update_local_texture(mCtrl, nodep->mSavedGLTFOverrideMaterials[te].get());
break;
}
case MATERIAL_EMISIVE_TEX_DIRTY:
{
nodep->mSavedGLTFOverrideMaterials[te]->setEmissiveId(mCtrl->getValue().asUUID(), true);
+ update_local_texture(mCtrl, nodep->mSavedGLTFOverrideMaterials[te].get());
break;
}
case MATERIAL_NORMAL_TEX_DIRTY:
{
nodep->mSavedGLTFOverrideMaterials[te]->setNormalId(mCtrl->getValue().asUUID(), true);
+ update_local_texture(mCtrl, nodep->mSavedGLTFOverrideMaterials[te].get());
break;
}
// Colors
@@ -1393,6 +1576,20 @@ void LLMaterialEditor::finishInventoryUpload(LLUUID itemId, LLUUID newAssetId, L
{
me->refreshFromInventory(itemId);
}
+
+ if (me && !me->mTextureChangesUpdates.empty())
+ {
+ const LLInventoryItem* item = me->getItem();
+ if (item)
+ {
+ // local materials were assigned, force load material and init tracking
+ LLGLTFMaterial* mat = gGLTFMaterialList.getMaterial(item->getAssetUUID());
+ for (mat_connection_map_t::value_type &val : me->mTextureChangesUpdates)
+ {
+ LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.second.mTrackingId, mat);
+ }
+ }
+ }
}
}
@@ -1407,6 +1604,16 @@ void LLMaterialEditor::finishTaskUpload(LLUUID itemId, LLUUID newAssetId, LLUUID
me->setAssetId(newAssetId);
me->refreshFromInventory();
me->setEnabled(true);
+
+ if (me && !me->mTextureChangesUpdates.empty())
+ {
+ // local materials were assigned, force load material and init tracking
+ LLGLTFMaterial* mat = gGLTFMaterialList.getMaterial(newAssetId);
+ for (mat_connection_map_t::value_type &val : me->mTextureChangesUpdates)
+ {
+ LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.second.mTrackingId, mat);
+ }
+ }
}
}
@@ -1440,6 +1647,17 @@ void LLMaterialEditor::finishSaveAs(
{
me->loadAsset();
me->setEnabled(true);
+
+ // Local texure support
+ if (!me->mTextureChangesUpdates.empty())
+ {
+ // local materials were assigned, force load material and init tracking
+ LLGLTFMaterial* mat = gGLTFMaterialList.getMaterial(item->getAssetUUID());
+ for (mat_connection_map_t::value_type &val : me->mTextureChangesUpdates)
+ {
+ LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.second.mTrackingId, mat);
+ }
+ }
}
}
else if(has_unsaved_changes)
@@ -2705,28 +2923,58 @@ public:
if (changed_flags & MATERIAL_BASE_COLOR_TEX_DIRTY)
{
material->setBaseColorId(mEditor->getBaseColorId(), true);
+ LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_BASE_COLOR_TEX_DIRTY);
+ if (tracking_id.notNull())
+ {
+ LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material);
+ }
}
else if ((reverted_flags & MATERIAL_BASE_COLOR_TEX_DIRTY) && revert_mat.notNull())
{
material->setBaseColorId(revert_mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR], false);
+ LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_BASE_COLOR_TEX_DIRTY);
+ if (tracking_id.notNull())
+ {
+ LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material);
+ }
}
if (changed_flags & MATERIAL_NORMAL_TEX_DIRTY)
{
material->setNormalId(mEditor->getNormalId(), true);
+ LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_NORMAL_TEX_DIRTY);
+ if (tracking_id.notNull())
+ {
+ LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material);
+ }
}
else if ((reverted_flags & MATERIAL_NORMAL_TEX_DIRTY) && revert_mat.notNull())
{
material->setNormalId(revert_mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL], false);
+ LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_NORMAL_TEX_DIRTY);
+ if (tracking_id.notNull())
+ {
+ LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material);
+ }
}
if (changed_flags & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY)
{
material->setOcclusionRoughnessMetallicId(mEditor->getMetallicRoughnessId(), true);
+ LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY);
+ if (tracking_id.notNull())
+ {
+ LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material);
+ }
}
else if ((reverted_flags & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY) && revert_mat.notNull())
{
material->setOcclusionRoughnessMetallicId(revert_mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS], false);
+ LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY);
+ if (tracking_id.notNull())
+ {
+ LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material);
+ }
}
if (changed_flags & MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY)
@@ -2759,10 +3007,20 @@ public:
if (changed_flags & MATERIAL_EMISIVE_TEX_DIRTY)
{
material->setEmissiveId(mEditor->getEmissiveId(), true);
+ LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_EMISIVE_TEX_DIRTY);
+ if (tracking_id.notNull())
+ {
+ LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material);
+ }
}
else if ((reverted_flags & MATERIAL_EMISIVE_TEX_DIRTY) && revert_mat.notNull())
{
material->setEmissiveId(revert_mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE], false);
+ LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_EMISIVE_TEX_DIRTY);
+ if (tracking_id.notNull())
+ {
+ LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material);
+ }
}
if (changed_flags & MATERIAL_DOUBLE_SIDED_DIRTY)
@@ -2914,6 +3172,34 @@ void LLMaterialEditor::setFromGLTFMaterial(LLGLTFMaterial* mat)
setDoubleSided(mat->mDoubleSided);
setAlphaMode(mat->getAlphaMode());
setAlphaCutoff(mat->mAlphaCutoff);
+
+ if (mat->hasLocalTextures())
+ {
+ for (LLGLTFMaterial::local_tex_map_t::value_type &val : mat->mTrackingIdToLocalTexture)
+ {
+ LLUUID world_id = LLLocalBitmapMgr::getInstance()->getWorldID(val.first);
+ if (val.second != world_id)
+ {
+ LL_WARNS() << "world id mismatch" << LL_ENDL;
+ }
+ if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR])
+ {
+ subscribeToLocalTexture(MATERIAL_BASE_COLOR_TEX_DIRTY, val.first);
+ }
+ if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS])
+ {
+ subscribeToLocalTexture(MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY, val.first);
+ }
+ if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE])
+ {
+ subscribeToLocalTexture(MATERIAL_EMISIVE_TEX_DIRTY, val.first);
+ }
+ if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL])
+ {
+ subscribeToLocalTexture(MATERIAL_NORMAL_TEX_DIRTY, val.first);
+ }
+ }
+ }
}
bool LLMaterialEditor::setFromSelection()
@@ -2932,6 +3218,8 @@ bool LLMaterialEditor::setFromSelection()
const LLViewerInventoryItem* item = selected_object->getInventoryItemByAsset(func.mMaterialId);
const bool allow_modify = !item || canModify(selected_object, item);
setEnableEditing(allow_modify);
+
+ // todo: apply local texture data to all materials in selection
}
else
{
@@ -2954,6 +3242,15 @@ bool LLMaterialEditor::setFromSelection()
// Memorize selection data for filtering further updates
mOverrideObjectId = func.mObjectId;
mOverrideObjectTE = func.mObjectTE;
+
+ // Ovverdired might have been updated,
+ // refresh state of local textures in overrides
+ //
+ // Todo: this probably shouldn't be here, but in localbitmap,
+ // subscried to all material overrides if we want copied
+ // objects to get properly updated as well
+ LLSelectedTEUpdateOverrides local_tex_func(this);
+ selected_objects->applyToNodes(&local_tex_func);
}
return func.mMaterial.notNull();
diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h
index 1c40fcc348..95a4c4572d 100644
--- a/indra/newview/llmaterialeditor.h
+++ b/indra/newview/llmaterialeditor.h
@@ -87,6 +87,7 @@ protected:
class LLMaterialEditor : public LLPreview, public LLVOInventoryListener
{ public:
LLMaterialEditor(const LLSD& key);
+ ~LLMaterialEditor();
bool setFromGltfModel(const tinygltf::Model& model, S32 index, bool set_textures = false);
@@ -219,6 +220,8 @@ class LLMaterialEditor : public LLPreview, public LLVOInventoryListener
void setCanSave(bool value);
void setEnableEditing(bool can_modify);
+ void subscribeToLocalTexture(S32 dirty_flag, const LLUUID& tracking_id);
+ void replaceLocalTexture(const LLUUID& old_id, const LLUUID& new_id); // Local texture support
void onCommitTexture(LLUICtrl* ctrl, const LLSD& data, S32 dirty_flag);
void onCancelCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_flag);
void onSelectCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_flag);
@@ -228,6 +231,8 @@ class LLMaterialEditor : public LLPreview, public LLVOInventoryListener
U32 getUnsavedChangesFlags() { return mUnsavedChanges; }
U32 getRevertedChangesFlags() { return mRevertedChanges; }
+ LLUUID getLocalTextureTrackingIdFromFlag(U32 flag);
+ bool updateMaterialLocalSubscription(LLGLTFMaterial* mat);
static bool capabilitiesAvailable();
@@ -306,5 +311,13 @@ private:
static bool mOverrideInProgress;
static bool mSelectionNeedsUpdate;
boost::signals2::connection mSelectionUpdateSlot;
+
+ struct LocalTextureConnection
+ {
+ LLUUID mTrackingId;
+ boost::signals2::connection mConnection;
+ };
+ typedef std::map mat_connection_map_t;
+ mat_connection_map_t mTextureChangesUpdates;
};
diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp
index 13ec805ce6..b53e49dd8c 100644
--- a/indra/newview/llpanelprofile.cpp
+++ b/indra/newview/llpanelprofile.cpp
@@ -2505,7 +2505,7 @@ void LLPanelProfileSecondLife::onShowTexturePicker()
mFloaterTexturePickerHandle = texture_floaterp->getHandle();
- texture_floaterp->setOnFloaterCommitCallback([this](LLTextureCtrl::ETexturePickOp op, LLPickerSource source, const LLUUID& asset_id, const LLUUID&)
+ texture_floaterp->setOnFloaterCommitCallback([this](LLTextureCtrl::ETexturePickOp op, LLPickerSource source, const LLUUID& asset_id, const LLUUID&, const LLUUID&)
{
if (op == LLTextureCtrl::TEXTURE_SELECT)
{
@@ -2898,7 +2898,7 @@ void LLPanelProfileFirstLife::onChangePhoto()
mFloaterTexturePickerHandle = texture_floaterp->getHandle();
- texture_floaterp->setOnFloaterCommitCallback([this](LLTextureCtrl::ETexturePickOp op, LLPickerSource source, const LLUUID& asset_id, const LLUUID&)
+ texture_floaterp->setOnFloaterCommitCallback([this](LLTextureCtrl::ETexturePickOp op, LLPickerSource source, const LLUUID& asset_id, const LLUUID&, const LLUUID&)
{
if (op == LLTextureCtrl::TEXTURE_SELECT)
{
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 62439c1ce9..103efb2c10 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -352,10 +352,22 @@ void callback_cache_name(const LLUUID& id, const std::string& full_name, bool is
// exported functionality
//
+void pump_idle_startup_network(void)
+{
+ {
+ LockMessageChecker lmc(gMessageSystem);
+ while (lmc.checkAllMessages(gFrameCount, gServicePump))
+ {
+ display_startup();
+ }
+ lmc.processAcks();
+ }
+ display_startup();
+}
+
//
// local classes
//
-
//
static bool sGridListRequestReady = false;
void downloadGridlistComplete( LLSD const &aData )
@@ -2363,15 +2375,7 @@ bool idle_startup()
{
LLStartUp::setStartupState( STATE_AGENT_SEND );
}
- {
- LockMessageChecker lmc(gMessageSystem);
- while (lmc.checkAllMessages(gFrameCount, gServicePump))
- {
- display_startup();
- }
- lmc.processAcks();
- }
- display_startup();
+ pump_idle_startup_network();
return FALSE;
}
@@ -2480,6 +2484,7 @@ bool idle_startup()
//---------------------------------------------------------------------
if (STATE_INVENTORY_SEND == LLStartUp::getStartupState())
{
+ LL_PROFILE_ZONE_NAMED("State inventory send")
display_startup();
// request mute list
@@ -2516,7 +2521,7 @@ bool idle_startup()
}
}
display_startup();
-
+
LLSD inv_lib_owner = response["inventory-lib-owner"];
if(inv_lib_owner.isDefined())
{
@@ -2524,30 +2529,52 @@ bool idle_startup()
LLSD id = inv_lib_owner[0]["agent_id"];
if(id.isDefined())
{
- gInventory.setLibraryOwnerID( LLUUID(id.asUUID()));
+ gInventory.setLibraryOwnerID(LLUUID(id.asUUID()));
}
}
display_startup();
-
- LLSD inv_skel_lib = response["inventory-skel-lib"];
- if(inv_skel_lib.isDefined() && gInventory.getLibraryOwnerID().notNull())
- {
- if(!gInventory.loadSkeleton(inv_skel_lib, gInventory.getLibraryOwnerID()))
- {
- LL_WARNS("AppInit") << "Problem loading inventory-skel-lib" << LL_ENDL;
- }
- }
+ LLStartUp::setStartupState(STATE_INVENTORY_SKEL);
display_startup();
+ return FALSE;
+ }
- LLSD inv_skeleton = response["inventory-skeleton"];
- if(inv_skeleton.isDefined())
- {
- if(!gInventory.loadSkeleton(inv_skeleton, gAgent.getID()))
- {
- LL_WARNS("AppInit") << "Problem loading inventory-skel-targets" << LL_ENDL;
- }
- }
- display_startup();
+ if (STATE_INVENTORY_SKEL == LLStartUp::getStartupState())
+ {
+ LL_PROFILE_ZONE_NAMED("State inventory load skeleton")
+
+ LLSD response = LLLoginInstance::getInstance()->getResponse();
+
+ LLSD inv_skel_lib = response["inventory-skel-lib"];
+ if (inv_skel_lib.isDefined() && gInventory.getLibraryOwnerID().notNull())
+ {
+ LL_PROFILE_ZONE_NAMED("load library inv")
+ if (!gInventory.loadSkeleton(inv_skel_lib, gInventory.getLibraryOwnerID()))
+ {
+ LL_WARNS("AppInit") << "Problem loading inventory-skel-lib" << LL_ENDL;
+ }
+ }
+ display_startup();
+
+ LLSD inv_skeleton = response["inventory-skeleton"];
+ if (inv_skeleton.isDefined())
+ {
+ LL_PROFILE_ZONE_NAMED("load personal inv")
+ if (!gInventory.loadSkeleton(inv_skeleton, gAgent.getID()))
+ {
+ LL_WARNS("AppInit") << "Problem loading inventory-skel-targets" << LL_ENDL;
+ }
+ }
+ display_startup();
+ LLStartUp::setStartupState(STATE_INVENTORY_SEND2);
+ display_startup();
+ return FALSE;
+ }
+
+ if (STATE_INVENTORY_SEND2 == LLStartUp::getStartupState())
+ {
+ LL_PROFILE_ZONE_NAMED("State inventory send2")
+
+ LLSD response = LLLoginInstance::getInstance()->getResponse();
LLSD inv_basic = response["inventory-basic"];
if(inv_basic.isDefined())
diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h
index 4e2940c024..52f259d3ba 100644
--- a/indra/newview/llstartup.h
+++ b/indra/newview/llstartup.h
@@ -40,6 +40,7 @@ class LLSLURL;
bool idle_startup();
void release_start_screen();
bool login_alert_done(const LLSD& notification, const LLSD& response);
+void pump_idle_startup_network();
// start location constants
enum EStartLocation
@@ -82,6 +83,8 @@ typedef enum {
STATE_AGENT_WAIT, // Wait for region
STATE_INVENTORY_SEND, // Do inventory transfer
STATE_INVENTORY_CALLBACKS, // Wait for missing system folders and register callbacks
+ STATE_INVENTORY_SKEL, // Do more inventory skeleton loading
+ STATE_INVENTORY_SEND2, // Do more inventory init after skeleton is loaded
STATE_MISC, // Do more things (set bandwidth, start audio, save location, etc)
STATE_PRECACHE, // Wait a bit for textures to download
STATE_WEARABLES_WAIT, // Wait for clothing to download
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 2a5b2d4716..c26b4c7c53 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -914,6 +914,7 @@ void LLFloaterTexturePicker::commitCallback(LLTextureCtrl::ETexturePickOp op)
}
LLUUID asset_id = mImageAssetID;
LLUUID inventory_id;
+ LLUUID tracking_id;
LLPickerSource mode = (LLPickerSource)mModeSelector->getValue().asInteger();
switch (mode)
@@ -954,16 +955,16 @@ void LLFloaterTexturePicker::commitCallback(LLTextureCtrl::ETexturePickOp op)
if (!mLocalScrollCtrl->getAllSelected().empty())
{
LLSD data = mLocalScrollCtrl->getFirstSelected()->getValue();
- LLUUID temp_id = data["id"];
+ tracking_id = data["id"];
S32 asset_type = data["type"].asInteger();
if (LLAssetType::AT_MATERIAL == asset_type)
{
- asset_id = LLLocalGLTFMaterialMgr::getInstance()->getWorldID(temp_id);
+ asset_id = LLLocalGLTFMaterialMgr::getInstance()->getWorldID(tracking_id);
}
else
{
- asset_id = LLLocalBitmapMgr::getInstance()->getWorldID(temp_id);
+ asset_id = LLLocalBitmapMgr::getInstance()->getWorldID(tracking_id);
}
}
else
@@ -980,13 +981,13 @@ void LLFloaterTexturePicker::commitCallback(LLTextureCtrl::ETexturePickOp op)
break;
}
- mOnFloaterCommitCallback(op, mode, asset_id, inventory_id);
+ mOnFloaterCommitCallback(op, mode, asset_id, inventory_id, tracking_id);
}
void LLFloaterTexturePicker::commitCancel()
{
if (!mNoCopyTextureSelected && mOnFloaterCommitCallback && mCanApply)
{
- mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CANCEL, PICKER_UNKNOWN, mOriginalImageAssetID, LLUUID::null);
+ mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CANCEL, PICKER_UNKNOWN, mOriginalImageAssetID, LLUUID::null, LLUUID::null);
}
}
@@ -1061,7 +1062,7 @@ void LLFloaterTexturePicker::onBtnCancel(void* userdata)
self->setImageID( self->mOriginalImageAssetID );
if (self->mOnFloaterCommitCallback)
{
- self->mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CANCEL, PICKER_UNKNOWN, self->mOriginalImageAssetID, LLUUID::null);
+ self->mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CANCEL, PICKER_UNKNOWN, self->mOriginalImageAssetID, LLUUID::null, LLUUID::null);
}
self->mViewModel->resetDirty();
self->closeFloater();
@@ -1301,7 +1302,7 @@ void LLFloaterTexturePicker::onLocalScrollCommit(LLUICtrl* ctrl, void* userdata)
{
if (self->mOnFloaterCommitCallback)
{
- self->mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CHANGE, PICKER_LOCAL, inworld_id, LLUUID::null);
+ self->mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CHANGE, PICKER_LOCAL, inworld_id, LLUUID::null, tracking_id);
}
}
}
@@ -1969,7 +1970,7 @@ void LLTextureCtrl::showPicker(BOOL take_focus)
}
if (texture_floaterp)
{
- texture_floaterp->setOnFloaterCommitCallback(boost::bind(&LLTextureCtrl::onFloaterCommit, this, _1, _2, _3, _4));
+ texture_floaterp->setOnFloaterCommitCallback(boost::bind(&LLTextureCtrl::onFloaterCommit, this, _1, _2, _3, _4, _5));
texture_floaterp->setSetImageAssetIDCallback(boost::bind(&LLTextureCtrl::setImageAssetID, this, _1));
texture_floaterp->setBakeTextureEnabled(mBakeTextureEnabled);
@@ -2102,7 +2103,7 @@ void LLTextureCtrl::onFloaterClose()
mFloaterHandle.markDead();
}
-void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLPickerSource source, const LLUUID& asset_id, const LLUUID& inv_id)
+void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLPickerSource source, const LLUUID& asset_id, const LLUUID& inv_id, const LLUUID& tracking_id)
{
LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
@@ -2125,16 +2126,23 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLPickerSource source, co
case PICKER_INVENTORY:
mImageItemID = inv_id;
mImageAssetID = asset_id;
+ mLocalTrackingID.setNull();
break;
case PICKER_BAKE:
+ mImageItemID = LLUUID::null;
+ mImageAssetID = asset_id;
+ mLocalTrackingID.setNull();
+ break;
case PICKER_LOCAL:
mImageItemID = LLUUID::null;
mImageAssetID = asset_id;
+ mLocalTrackingID = tracking_id;
break;
case PICKER_UNKNOWN:
default:
mImageItemID = floaterp->findItemID(asset_id, FALSE);
mImageAssetID = asset_id;
+ mLocalTrackingID.setNull();
break;
}
@@ -2192,6 +2200,7 @@ void LLTextureCtrl::setImageAssetID( const LLUUID& asset_id )
{
mImageItemID.setNull();
mImageAssetID = asset_id;
+ mLocalTrackingID.setNull();
LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
if( floaterp && getEnabled() )
{
diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h
index 306b8d51a5..146949d3f7 100644
--- a/indra/newview/lltexturectrl.h
+++ b/indra/newview/lltexturectrl.h
@@ -203,7 +203,11 @@ public:
void closeDependentFloater();
void onFloaterClose();
- void onFloaterCommit(ETexturePickOp op, LLPickerSource source, const LLUUID& local_id, const LLUUID& inv_id);
+ void onFloaterCommit(ETexturePickOp op,
+ LLPickerSource source,
+ const LLUUID& local_id,
+ const LLUUID& inv_id,
+ const LLUUID& tracking_id);
// This call is returned when a drag is detected. Your callback
// should return TRUE if the drag is acceptable.
@@ -233,6 +237,9 @@ public:
void setInventoryPickType(EPickInventoryType type);
EPickInventoryType getInventoryPickType() { return mInventoryPickType; };
+ bool isImageLocal() { return mLocalTrackingID.notNull(); }
+ LLUUID getLocalTrackingID() { return mLocalTrackingID; }
+
// Mask texture if desired
void setIsMasked(BOOL masked) { mIsMasked = masked; }
@@ -253,6 +260,7 @@ private:
LLUUID mImageAssetID;
LLUUID mDefaultImageAssetID;
LLUUID mBlankImageAssetID;
+ LLUUID mLocalTrackingID;
LLUIImagePtr mFallbackImage;
std::string mDefaultImageName;
LLHandle mFloaterHandle;
@@ -282,7 +290,7 @@ private:
//////////////////////////////////////////////////////////////////////////////////////////
// LLFloaterTexturePicker
-typedef boost::function floater_commit_callback;
+typedef boost::function floater_commit_callback;
typedef boost::function floater_close_callback;
typedef boost::function set_image_asset_id_callback;
typedef boost::function texture)> set_on_update_image_stats_callback;
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 2d84288dcb..71cd615f17 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -5654,6 +5654,11 @@ S32 LLViewerObject::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* override_ma
tep->setGLTFRenderMaterial(render_mat);
retval = TEM_CHANGE_TEXTURE;
+ for (LLGLTFMaterial::local_tex_map_t::value_type &val : override_mat->mTrackingIdToLocalTexture)
+ {
+ LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.first, override_mat);
+ }
+
}
else if (tep->setGLTFRenderMaterial(nullptr))
{
@@ -7459,14 +7464,17 @@ void LLViewerObject::rebuildMaterial()
gPipeline.markTextured(mDrawable);
}
-void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool update_server)
+void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool update_server, bool local_origin)
{
// implementation is delicate
// if update is bound for server, should always null out GLTFRenderMaterial and clear GLTFMaterialOverride even if ids haven't changed
// (the case where ids haven't changed indicates the user has reapplied the original material, in which case overrides should be dropped)
// otherwise, should only null out the render material where ids or overrides have changed
- // (the case where ids have changed but overrides are still present is from unsynchronized updates from the simulator)
+ // (the case where ids have changed but overrides are still present is from unsynchronized updates from the simulator, or synchronized
+ // updates with solely transform overrides)
+
+ llassert(!update_server || local_origin);
S32 start_idx = 0;
S32 end_idx = getNumTEs();
@@ -7498,7 +7506,12 @@ void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool updat
{
LLTextureEntry* tep = getTE(te);
- bool material_changed = !param_block || id != param_block->getMaterial(te);
+ // If local_origin=false (i.e. it's from the server), we know the
+ // material has updated or been created, because extra params are
+ // checked for equality on unpacking. In that case, checking the
+ // material ID for inequality won't work, because the material ID has
+ // already been set.
+ bool material_changed = !local_origin || !param_block || id != param_block->getMaterial(te);
if (update_server)
{
@@ -7520,6 +7533,34 @@ void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool updat
{
tep->setGLTFMaterial(new_material, !update_server);
}
+
+ if (material_changed && new_material)
+ {
+ // Sometimes, the material may change out from underneath the overrides.
+ // This is usually due to the server sending a new material ID, but
+ // the overrides have not changed due to being only texture
+ // transforms. Re-apply the overrides to the render material here,
+ // if present.
+ const LLGLTFMaterial* override_material = tep->getGLTFMaterialOverride();
+ if (override_material)
+ {
+ new_material->onMaterialComplete([obj_id = getID(), te]()
+ {
+ LLViewerObject* obj = gObjectList.findObject(obj_id);
+ if (!obj) { return; }
+ LLTextureEntry* tep = obj->getTE(te);
+ if (!tep) { return; }
+ const LLGLTFMaterial* new_material = tep->getGLTFMaterial();
+ if (!new_material) { return; }
+ const LLGLTFMaterial* override_material = tep->getGLTFMaterialOverride();
+ if (!override_material) { return; }
+ LLGLTFMaterial* render_material = new LLFetchedGLTFMaterial();
+ *render_material = *new_material;
+ render_material->applyOverride(*override_material);
+ tep->setGLTFRenderMaterial(render_material);
+ });
+ }
+ }
}
// signal to render pipe that render batches must be rebuilt for this object
@@ -7579,7 +7620,9 @@ void LLViewerObject::setRenderMaterialIDs(const LLRenderMaterialParams* material
for (S32 te = 0; te < getNumTEs(); ++te)
{
const LLUUID& id = material_params ? material_params->getMaterial(te) : LLUUID::null;
- setRenderMaterialID(te, id, false);
+ // We know material_params has updated or been created, because
+ // extra params are checked for equality on unpacking.
+ setRenderMaterialID(te, id, false, false);
}
}
}
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index bb06cddd48..2c3db85093 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -192,7 +192,7 @@ public:
// te - TextureEntry index to set, or -1 for all TEs
// id - asset id of material asset
// update_server - if true, will send updates to server and clear most overrides
- void setRenderMaterialID(S32 te, const LLUUID& id, bool update_server = true);
+ void setRenderMaterialID(S32 te, const LLUUID& id, bool update_server = true, bool local_origin = true);
void setRenderMaterialIDs(const LLUUID& id);
virtual BOOL isHUDAttachment() const { return FALSE; }
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index f192c0302c..ce1ce5849a 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -393,8 +393,8 @@ void LLViewerShaderMgr::setShaders()
static LLCachedControl max_texture_index(gSavedSettings, "RenderMaxTextureIndex", 16);
- // when using indexed texture rendering, leave 8 texture units available for shadow and reflection maps
- LLGLSLShader::sIndexedTextureChannels = llmax(llmin(gGLManager.mNumTextureImageUnits-8, (S32) max_texture_index), 1);
+ // when using indexed texture rendering, leave some texture units available for shadow and reflection maps
+ LLGLSLShader::sIndexedTextureChannels = llmax(llmin(gGLManager.mNumTextureImageUnits-12, (S32) max_texture_index), 1);
reentrance = true;
diff --git a/indra/newview/skins/default/xui/de/panel_tools_texture.xml b/indra/newview/skins/default/xui/de/panel_tools_texture.xml
index 8dc8ae7e23..41556286de 100644
--- a/indra/newview/skins/default/xui/de/panel_tools_texture.xml
+++ b/indra/newview/skins/default/xui/de/panel_tools_texture.xml
@@ -36,7 +36,7 @@
Material
-
+
diff --git a/indra/newview/skins/default/xui/en/panel_tools_texture.xml b/indra/newview/skins/default/xui/en/panel_tools_texture.xml
index d0aad5b14d..e9350c9a08 100644
--- a/indra/newview/skins/default/xui/en/panel_tools_texture.xml
+++ b/indra/newview/skins/default/xui/en/panel_tools_texture.xml
@@ -156,7 +156,7 @@
top="80"
width="100">