summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/llprimitive/CMakeLists.txt1
-rw-r--r--indra/llprimitive/llgltfmaterial.cpp161
-rw-r--r--indra/llprimitive/llgltfmaterial.h38
-rw-r--r--indra/llprimitive/llgltfmaterial_templates.h142
-rw-r--r--indra/llui/llfolderview.h1
-rw-r--r--indra/newview/llfloaterimcontainer.cpp3
-rw-r--r--indra/newview/llfloaterimsessiontab.cpp2
-rw-r--r--indra/newview/llinventorypanel.cpp86
-rw-r--r--indra/newview/llinventorypanel.h2
-rw-r--r--indra/newview/lllogchat.cpp2
-rw-r--r--indra/newview/llselectmgr.cpp8
-rw-r--r--indra/newview/lltexturectrl.cpp223
-rw-r--r--indra/newview/lltexturectrl.h4
-rw-r--r--indra/newview/lltexturefetch.cpp95
14 files changed, 481 insertions, 287 deletions
diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt
index 76d261ab3e..2bd1edaacc 100644
--- a/indra/llprimitive/CMakeLists.txt
+++ b/indra/llprimitive/CMakeLists.txt
@@ -34,6 +34,7 @@ set(llprimitive_HEADER_FILES
lldaeloader.h
llgltfloader.h
llgltfmaterial.h
+ llgltfmaterial_templates.h
legacy_object_types.h
llmaterial.h
llmaterialid.h
diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp
index 19b7413934..f42c11ee21 100644
--- a/indra/llprimitive/llgltfmaterial.cpp
+++ b/indra/llprimitive/llgltfmaterial.cpp
@@ -24,25 +24,28 @@
* $/LicenseInfo$
*/
+
#include "linden_common.h"
#include "llgltfmaterial.h"
+
#include "llsdserialize.h"
// NOTE -- this should be the one and only place tiny_gltf.h is included
#include "tinygltf/tiny_gltf.h"
+#include "llgltfmaterial_templates.h"
const char* const LLGLTFMaterial::ASSET_VERSION = "1.1";
const char* const LLGLTFMaterial::ASSET_TYPE = "GLTF 2.0";
const std::array<std::string, 2> LLGLTFMaterial::ACCEPTED_ASSET_VERSIONS = { "1.0", "1.1" };
-const char* const GLTF_FILE_EXTENSION_TRANSFORM = "KHR_texture_transform";
-const char* const GLTF_FILE_EXTENSION_TRANSFORM_SCALE = "scale";
-const char* const GLTF_FILE_EXTENSION_TRANSFORM_OFFSET = "offset";
-const char* const GLTF_FILE_EXTENSION_TRANSFORM_ROTATION = "rotation";
+const char* const LLGLTFMaterial::GLTF_FILE_EXTENSION_TRANSFORM = "KHR_texture_transform";
+const char* const LLGLTFMaterial::GLTF_FILE_EXTENSION_TRANSFORM_SCALE = "scale";
+const char* const LLGLTFMaterial::GLTF_FILE_EXTENSION_TRANSFORM_OFFSET = "offset";
+const char* const LLGLTFMaterial::GLTF_FILE_EXTENSION_TRANSFORM_ROTATION = "rotation";
// special UUID that indicates a null UUID in override data
-static const LLUUID GLTF_OVERRIDE_NULL_UUID = LLUUID("ffffffff-ffff-ffff-ffff-ffffffffffff");
+const LLUUID LLGLTFMaterial::GLTF_OVERRIDE_NULL_UUID = LLUUID("ffffffff-ffff-ffff-ffff-ffffffffffff");
void LLGLTFMaterial::TextureTransform::getPacked(F32 (&packed)[8]) const
{
@@ -68,14 +71,14 @@ LLGLTFMaterial::LLGLTFMaterial(const LLGLTFMaterial& rhs)
LLGLTFMaterial& LLGLTFMaterial::operator=(const LLGLTFMaterial& rhs)
{
- //have to do a manual operator= because of LLRefCount
+ //have to do a manual operator= because of LLRefCount
mTextureId = rhs.mTextureId;
mTextureTransform = rhs.mTextureTransform;
mBaseColor = rhs.mBaseColor;
mEmissiveColor = rhs.mEmissiveColor;
-
+
mMetallicFactor = rhs.mMetallicFactor;
mRoughnessFactor = rhs.mRoughnessFactor;
mAlphaCutoff = rhs.mAlphaCutoff;
@@ -97,7 +100,7 @@ bool LLGLTFMaterial::operator==(const LLGLTFMaterial& rhs) const
mBaseColor == rhs.mBaseColor &&
mEmissiveColor == rhs.mEmissiveColor &&
-
+
mMetallicFactor == rhs.mMetallicFactor &&
mRoughnessFactor == rhs.mRoughnessFactor &&
mAlphaCutoff == rhs.mAlphaCutoff &&
@@ -122,6 +125,7 @@ bool LLGLTFMaterial::fromJSON(const std::string& json, std::string& warn_msg, st
return true;
}
+
return false;
}
@@ -190,7 +194,8 @@ void LLGLTFMaterial::setFromModel(const tinygltf::Model& model, S32 mat_index)
}
}
-LLVector2 vec2_from_json(const tinygltf::Value::Object& object, const char* key, const LLVector2& default_value)
+// static
+LLVector2 LLGLTFMaterial::vec2FromJson(const tinygltf::Value::Object& object, const char* key, const LLVector2& default_value)
{
const auto it = object.find(key);
if (it == object.end())
@@ -215,7 +220,8 @@ LLVector2 vec2_from_json(const tinygltf::Value::Object& object, const char* key,
return value;
}
-F32 float_from_json(const tinygltf::Value::Object& object, const char* key, const F32 default_value)
+// static
+F32 LLGLTFMaterial::floatFromJson(const tinygltf::Value::Object& object, const char* key, const F32 default_value)
{
const auto it = object.find(key);
if (it == object.end())
@@ -230,52 +236,6 @@ F32 float_from_json(const tinygltf::Value::Object& object, const char* key, cons
return (F32)real_json.GetNumberAsDouble();
}
-template<typename T>
-std::string gltf_get_texture_image(const tinygltf::Model& model, const T& texture_info)
-{
- const S32 texture_idx = texture_info.index;
- if (texture_idx < 0 || texture_idx >= model.textures.size())
- {
- return "";
- }
- const tinygltf::Texture& texture = model.textures[texture_idx];
-
- // Ignore texture.sampler for now
-
- const S32 image_idx = texture.source;
- if (image_idx < 0 || image_idx >= model.images.size())
- {
- return "";
- }
- const tinygltf::Image& image = model.images[image_idx];
-
- return image.uri;
-}
-
-// *NOTE: Use template here as workaround for the different similar texture info classes
-template<typename T>
-void LLGLTFMaterial::setFromTexture(const tinygltf::Model& model, const T& texture_info, TextureInfo texture_info_id)
-{
- LL_PROFILE_ZONE_SCOPED;
- const std::string uri = gltf_get_texture_image(model, texture_info);
- mTextureId[texture_info_id].set(uri);
-
- const tinygltf::Value::Object& extensions_object = texture_info.extensions;
- const auto transform_it = extensions_object.find(GLTF_FILE_EXTENSION_TRANSFORM);
- if (transform_it != extensions_object.end())
- {
- const tinygltf::Value& transform_json = std::get<1>(*transform_it);
- if (transform_json.IsObject())
- {
- const tinygltf::Value::Object& transform_object = transform_json.Get<tinygltf::Value::Object>();
- TextureTransform& transform = mTextureTransform[texture_info_id];
- transform.mOffset = vec2_from_json(transform_object, GLTF_FILE_EXTENSION_TRANSFORM_OFFSET, getDefaultTextureOffset());
- transform.mScale = vec2_from_json(transform_object, GLTF_FILE_EXTENSION_TRANSFORM_SCALE, getDefaultTextureScale());
- transform.mRotation = float_from_json(transform_object, GLTF_FILE_EXTENSION_TRANSFORM_ROTATION, getDefaultTextureRotation());
- }
- }
-}
-
void LLGLTFMaterial::writeToModel(tinygltf::Model& model, S32 mat_index) const
{
LL_PROFILE_ZONE_SCOPED;
@@ -302,7 +262,7 @@ void LLGLTFMaterial::writeToModel(tinygltf::Model& model, S32 mat_index) const
material_out.alphaMode = getAlphaMode();
material_out.alphaCutoff = mAlphaCutoff;
-
+
mBaseColor.write(material_out.pbrMetallicRoughness.baseColorFactor);
if (mEmissiveColor != LLGLTFMaterial::getDefaultEmissiveColor())
@@ -320,7 +280,7 @@ void LLGLTFMaterial::writeToModel(tinygltf::Model& model, S32 mat_index) const
tinygltf::Value::Object extras;
bool write_extras = false;
if (mOverrideAlphaMode && mAlphaMode == getDefaultAlphaMode())
- {
+ {
extras["override_alpha_mode"] = tinygltf::Value(mOverrideAlphaMode);
write_extras = true;
}
@@ -339,57 +299,6 @@ void LLGLTFMaterial::writeToModel(tinygltf::Model& model, S32 mat_index) const
model.asset.version = "2.0";
}
-template<typename T>
-void gltf_allocate_texture_image(tinygltf::Model& model, T& texture_info, const std::string& uri)
-{
- const S32 image_idx = model.images.size();
- model.images.emplace_back();
- model.images[image_idx].uri = uri;
-
- // The texture, not to be confused with the texture info
- const S32 texture_idx = model.textures.size();
- model.textures.emplace_back();
- tinygltf::Texture& texture = model.textures[texture_idx];
- texture.source = image_idx;
-
- texture_info.index = texture_idx;
-}
-
-template<typename T>
-void LLGLTFMaterial::writeToTexture(tinygltf::Model& model, T& texture_info, TextureInfo texture_info_id, bool force_write) const
-{
- LL_PROFILE_ZONE_SCOPED;
- const LLUUID& texture_id = mTextureId[texture_info_id];
- const TextureTransform& transform = mTextureTransform[texture_info_id];
- const bool is_blank_transform = transform == sDefault.mTextureTransform[0];
- // Check if this material matches all the fallback values, and if so, then
- // skip including it to reduce material size
- if (!force_write && texture_id.isNull() && is_blank_transform)
- {
- return;
- }
-
- // tinygltf will discard this texture info if there is no valid texture,
- // causing potential loss of information for overrides, so ensure one is
- // defined. -Cosmic,2023-01-30
- gltf_allocate_texture_image(model, texture_info, texture_id.asString());
-
- if (!is_blank_transform)
- {
- tinygltf::Value::Object transform_map;
- transform_map[GLTF_FILE_EXTENSION_TRANSFORM_OFFSET] = tinygltf::Value(tinygltf::Value::Array({
- tinygltf::Value(transform.mOffset.mV[VX]),
- tinygltf::Value(transform.mOffset.mV[VY])
- }));
- transform_map[GLTF_FILE_EXTENSION_TRANSFORM_SCALE] = tinygltf::Value(tinygltf::Value::Array({
- tinygltf::Value(transform.mScale.mV[VX]),
- tinygltf::Value(transform.mScale.mV[VY])
- }));
- transform_map[GLTF_FILE_EXTENSION_TRANSFORM_ROTATION] = tinygltf::Value(transform.mRotation);
- texture_info.extensions[GLTF_FILE_EXTENSION_TRANSFORM] = tinygltf::Value(transform_map);
- }
-}
-
void LLGLTFMaterial::sanitizeAssetMaterial()
{
mTextureTransform = sDefault.mTextureTransform;
@@ -403,19 +312,19 @@ bool LLGLTFMaterial::setBaseMaterial()
return *this != old_override;
}
-bool LLGLTFMaterial::isClearedForBaseMaterial()
-{
- LLGLTFMaterial cleared_override = sDefault;
- cleared_override.setBaseMaterial(*this);
- return *this == cleared_override;
-}
-
// For material overrides only. Copies transforms from the old override.
void LLGLTFMaterial::setBaseMaterial(const LLGLTFMaterial& old_override_mat)
{
mTextureTransform = old_override_mat.mTextureTransform;
}
+bool LLGLTFMaterial::isClearedForBaseMaterial() const
+{
+ LLGLTFMaterial cleared_override = sDefault;
+ cleared_override.setBaseMaterial(*this);
+ return *this == cleared_override;
+}
+
// static
void LLGLTFMaterial::hackOverrideUUID(LLUUID& id)
@@ -516,7 +425,7 @@ void LLGLTFMaterial::setAlphaMode(const std::string& mode, bool for_override)
{
m = ALPHA_MODE_BLEND;
}
-
+
setAlphaMode(m, for_override);
}
@@ -709,7 +618,6 @@ void LLGLTFMaterial::getOverrideLLSD(const LLGLTFMaterial& override_mat, LLSD& d
{
data["tex"][i] = LLSD::UUID(override_texture_id);
}
-
}
if (override_mat.mBaseColor != getDefaultBaseColor())
@@ -764,23 +672,6 @@ void LLGLTFMaterial::getOverrideLLSD(const LLGLTFMaterial& override_mat, LLSD& d
data["ti"][i]["r"] = override_mat.mTextureTransform[i].mRotation;
}
}
-
-#if 0
- {
- std::ostringstream ostr;
- LLSDSerialize::serialize(data, ostr, LLSDSerialize::LLSD_NOTATION);
- std::string param_str(ostr.str());
- LL_INFOS() << param_str << LL_ENDL;
- LL_INFOS() << "Notation size: " << param_str.size() << LL_ENDL;
- }
-
- {
- std::ostringstream ostr;
- LLSDSerialize::serialize(data, ostr, LLSDSerialize::LLSD_BINARY);
- std::string param_str(ostr.str());
- LL_INFOS() << "Binary size: " << param_str.size() << LL_ENDL;
- }
-#endif
}
diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h
index ca27507707..a078a530a4 100644
--- a/indra/llprimitive/llgltfmaterial.h
+++ b/indra/llprimitive/llgltfmaterial.h
@@ -35,10 +35,13 @@
#include "hbxxh.h"
#include <string>
+#include <map>
namespace tinygltf
{
class Model;
+ struct TextureInfo;
+ class Value;
}
class LLTextureEntry;
@@ -52,6 +55,9 @@ public:
static const char* const ASSET_VERSION;
static const char* const ASSET_TYPE;
+ // Max allowed size of a GLTF material asset or override, when serialized
+ // as a minified JSON string
+ static constexpr size_t MAX_ASSET_LENGTH = 2048;
static const std::array<std::string, 2> ACCEPTED_ASSET_VERSIONS;
static bool isAcceptedVersion(const std::string& version) { return std::find(ACCEPTED_ASSET_VERSIONS.cbegin(), ACCEPTED_ASSET_VERSIONS.cend(), version) != ACCEPTED_ASSET_VERSIONS.cend(); }
@@ -64,6 +70,7 @@ public:
void getPacked(F32 (&packed)[8]) const;
bool operator==(const TextureTransform& other) const;
+ bool operator!=(const TextureTransform& other) const { return !(*this == other); }
};
enum AlphaMode
@@ -96,8 +103,13 @@ public:
GLTF_TEXTURE_INFO_COUNT
};
- std::array<LLUUID, GLTF_TEXTURE_INFO_COUNT> mTextureId;
+ static const char* const GLTF_FILE_EXTENSION_TRANSFORM;
+ static const char* const GLTF_FILE_EXTENSION_TRANSFORM_SCALE;
+ static const char* const GLTF_FILE_EXTENSION_TRANSFORM_OFFSET;
+ static const char* const GLTF_FILE_EXTENSION_TRANSFORM_ROTATION;
+ static const LLUUID GLTF_OVERRIDE_NULL_UUID;
+ std::array<LLUUID, GLTF_TEXTURE_INFO_COUNT> mTextureId;
std::array<TextureTransform, GLTF_TEXTURE_INFO_COUNT> mTextureTransform;
// NOTE: initialize values to defaults according to the GLTF spec
@@ -137,7 +149,7 @@ public:
void setAlphaMode(S32 mode, bool for_override = false);
void setDoubleSided(bool double_sided, bool for_override = false);
- //NOTE: texture offsets only exist in overrides, so "for_override" is not needed
+ // *NOTE: texture offsets only exist in overrides, so "for_override" is not needed
void setTextureOffset(TextureInfo texture_info, const LLVector2& offset);
void setTextureScale(TextureInfo texture_info, const LLVector2& scale);
@@ -155,7 +167,6 @@ public:
static LLVector2 getDefaultTextureScale();
static F32 getDefaultTextureRotation();
-
static void hackOverrideUUID(LLUUID& id);
static void applyOverrideUUID(LLUUID& dst_id, const LLUUID& override_id);
@@ -164,7 +175,7 @@ public:
void setAlphaMode(const std::string& mode, bool for_override = false);
const char* getAlphaMode() const;
-
+
// set the contents of this LLGLTFMaterial from the given json
// returns true if successful
// if unsuccessful, the contents of this LLGLTFMaterial should be left unchanged and false is returned
@@ -176,7 +187,6 @@ public:
// get the contents of this LLGLTFMaterial as a json string
std::string asJSON(bool prettyprint = false) const;
-
// initialize from given tinygltf::Model
// model - the model to reference
// mat_index - index of material in model's material array
@@ -202,21 +212,29 @@ public:
// For material overrides only. Clears most properties to
// default/fallthrough, but preserves the transforms.
bool setBaseMaterial();
+ void setBaseMaterial(const LLGLTFMaterial& old_override_mat);
// True if setBaseMaterial() was just called
- bool isClearedForBaseMaterial();
+ bool isClearedForBaseMaterial() const;
// For local materials, they have to keep track of where
// they are assigned to for full updates
virtual void addTextureEntry(LLTextureEntry* te) {};
virtual void removeTextureEntry(LLTextureEntry* te) {};
-private:
+protected:
+ static LLVector2 vec2FromJson(const std::map<std::string, tinygltf::Value>& object, const char* key, const LLVector2& default_value);
+ static F32 floatFromJson(const std::map<std::string, tinygltf::Value>& object, const char* key, const F32 default_value);
+
+ template<typename T>
+ static void allocateTextureImage(tinygltf::Model& model, T& texture_info, const std::string& uri);
+
template<typename T>
void setFromTexture(const tinygltf::Model& model, const T& texture_info, TextureInfo texture_info_id);
+ template<typename T>
+ static void setFromTexture(const tinygltf::Model& model, const T& texture_info, LLUUID& texture_id, TextureTransform& transform);
template<typename T>
void writeToTexture(tinygltf::Model& model, T& texture_info, TextureInfo texture_info_id, bool force_write = false) const;
-
- void setBaseMaterial(const LLGLTFMaterial& old_override_mat);
+ template<typename T>
+ static void writeToTexture(tinygltf::Model& model, T& texture_info, const LLUUID& texture_id, const TextureTransform& transform, bool force_write = false);
};
-
diff --git a/indra/llprimitive/llgltfmaterial_templates.h b/indra/llprimitive/llgltfmaterial_templates.h
new file mode 100644
index 0000000000..f607dfe967
--- /dev/null
+++ b/indra/llprimitive/llgltfmaterial_templates.h
@@ -0,0 +1,142 @@
+/**
+ * @file llgltfmaterial_templates.h
+ * @brief Material template definition
+ *
+ * $LicenseInfo:firstyear=2023&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2023, 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"
+
+// Use templates here as workaround for the different similar texture info classes in tinygltf
+// Includer must first include tiny_gltf.h with the desired flags
+
+template<typename T>
+std::string gltf_get_texture_image(const tinygltf::Model& model, const T& texture_info)
+{
+ const S32 texture_idx = texture_info.index;
+ if (texture_idx < 0 || texture_idx >= model.textures.size())
+ {
+ return "";
+ }
+ const tinygltf::Texture& texture = model.textures[texture_idx];
+
+ // Ignore texture.sampler for now
+
+ const S32 image_idx = texture.source;
+ if (image_idx < 0 || image_idx >= model.images.size())
+ {
+ return "";
+ }
+ const tinygltf::Image& image = model.images[image_idx];
+
+ return image.uri;
+}
+
+template<typename T>
+void LLGLTFMaterial::setFromTexture(const tinygltf::Model& model, const T& texture_info, TextureInfo texture_info_id)
+{
+ setFromTexture(model, texture_info, mTextureId[texture_info_id], mTextureTransform[texture_info_id]);
+ const std::string uri = gltf_get_texture_image(model, texture_info);
+}
+
+// static
+template<typename T>
+void LLGLTFMaterial::setFromTexture(const tinygltf::Model& model, const T& texture_info, LLUUID& texture_id, TextureTransform& transform)
+{
+ LL_PROFILE_ZONE_SCOPED;
+ const std::string uri = gltf_get_texture_image(model, texture_info);
+ texture_id.set(uri);
+
+ const tinygltf::Value::Object& extensions_object = texture_info.extensions;
+ const auto transform_it = extensions_object.find(GLTF_FILE_EXTENSION_TRANSFORM);
+ if (transform_it != extensions_object.end())
+ {
+ const tinygltf::Value& transform_json = std::get<1>(*transform_it);
+ if (transform_json.IsObject())
+ {
+ const tinygltf::Value::Object& transform_object = transform_json.Get<tinygltf::Value::Object>();
+ transform.mOffset = vec2FromJson(transform_object, GLTF_FILE_EXTENSION_TRANSFORM_OFFSET, getDefaultTextureOffset());
+ transform.mScale = vec2FromJson(transform_object, GLTF_FILE_EXTENSION_TRANSFORM_SCALE, getDefaultTextureScale());
+ transform.mRotation = floatFromJson(transform_object, GLTF_FILE_EXTENSION_TRANSFORM_ROTATION, getDefaultTextureRotation());
+ }
+ }
+}
+
+// static
+template<typename T>
+void LLGLTFMaterial::allocateTextureImage(tinygltf::Model& model, T& texture_info, const std::string& uri)
+{
+ const S32 image_idx = model.images.size();
+ model.images.emplace_back();
+ model.images[image_idx].uri = uri;
+
+ // The texture, not to be confused with the texture info
+ const S32 texture_idx = model.textures.size();
+ model.textures.emplace_back();
+ tinygltf::Texture& texture = model.textures[texture_idx];
+ texture.source = image_idx;
+
+ texture_info.index = texture_idx;
+}
+
+// static
+template<typename T>
+void LLGLTFMaterial::writeToTexture(tinygltf::Model& model, T& texture_info, TextureInfo texture_info_id, bool force_write) const
+{
+ writeToTexture(model, texture_info, mTextureId[texture_info_id], mTextureTransform[texture_info_id], force_write);
+}
+
+// static
+template<typename T>
+void LLGLTFMaterial::writeToTexture(tinygltf::Model& model, T& texture_info, const LLUUID& texture_id, const TextureTransform& transform, bool force_write)
+{
+ LL_PROFILE_ZONE_SCOPED;
+ const bool is_blank_transform = transform == sDefault.mTextureTransform[0];
+ // Check if this material matches all the fallback values, and if so, then
+ // skip including it to reduce material size
+ if (!force_write && texture_id.isNull() && is_blank_transform)
+ {
+ return;
+ }
+
+ // tinygltf will discard this texture info if there is no valid texture,
+ // causing potential loss of information for overrides, so ensure one is
+ // defined. -Cosmic,2023-01-30
+ allocateTextureImage(model, texture_info, texture_id.asString());
+
+ if (!is_blank_transform)
+ {
+ tinygltf::Value::Object transform_map;
+ transform_map[GLTF_FILE_EXTENSION_TRANSFORM_OFFSET] = tinygltf::Value(tinygltf::Value::Array({
+ tinygltf::Value(transform.mOffset.mV[VX]),
+ tinygltf::Value(transform.mOffset.mV[VY])
+ }));
+ transform_map[GLTF_FILE_EXTENSION_TRANSFORM_SCALE] = tinygltf::Value(tinygltf::Value::Array({
+ tinygltf::Value(transform.mScale.mV[VX]),
+ tinygltf::Value(transform.mScale.mV[VY])
+ }));
+ transform_map[GLTF_FILE_EXTENSION_TRANSFORM_ROTATION] = tinygltf::Value(transform.mRotation);
+ texture_info.extensions[GLTF_FILE_EXTENSION_TRANSFORM] = tinygltf::Value(transform_map);
+ }
+}
diff --git a/indra/llui/llfolderview.h b/indra/llui/llfolderview.h
index 6de366044c..5f8a173889 100644
--- a/indra/llui/llfolderview.h
+++ b/indra/llui/llfolderview.h
@@ -217,6 +217,7 @@ public:
virtual void draw();
virtual void deleteAllChildren();
+ void stopAutoScollining() {mNeedsScroll = false;}
void scrollToShowSelection();
void scrollToShowItem(LLFolderViewItem* item, const LLRect& constraint_rect);
void setScrollContainer( LLScrollContainer* parent ) { mScrollContainer = parent; }
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 2720b7fcf7..011ad67011 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -289,6 +289,9 @@ void LLFloaterIMContainer::onOpen(const LLSD& key)
LLMultiFloater::onOpen(key);
reSelectConversation();
assignResizeLimits();
+
+ LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(mSelectedSession);
+ session_floater->onOpen(key);
}
// virtual
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index af4e7f5aff..0b0dce29fb 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -986,6 +986,8 @@ void LLFloaterIMSessionTab::onOpen(const LLSD& key)
}
mInputButtonPanel->setVisible(isTornOff());
+
+ setFocus(TRUE);
}
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 355d222b27..154d8e2e18 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -1449,45 +1449,6 @@ void LLInventoryPanel::onFocusReceived()
// inventory now handles cut/copy/paste/delete
LLEditMenuHandler::gEditMenuHandler = mFolderRoot.get();
- // Tab support, when tabbing into this view, select first item
- // (ideally needs to account for scroll)
- bool select_first = mSelectThisID.isNull() && mFolderRoot.get() && mFolderRoot.get()->getSelectedCount() == 0;
-
- if (select_first)
- {
- LLFolderViewFolder::folders_t::const_iterator folders_it = mFolderRoot.get()->getFoldersBegin();
- LLFolderViewFolder::folders_t::const_iterator folders_end = mFolderRoot.get()->getFoldersEnd();
-
- for (; folders_it != folders_end; ++folders_it)
- {
- const LLFolderViewFolder* folder_view = *folders_it;
- if (folder_view->getVisible())
- {
- const LLFolderViewModelItemInventory* modelp = static_cast<const LLFolderViewModelItemInventory*>(folder_view->getViewModelItem());
- setSelectionByID(modelp->getUUID(), TRUE);
- select_first = false;
- break;
- }
- }
- }
-
- if (select_first)
- {
- LLFolderViewFolder::items_t::const_iterator items_it = mFolderRoot.get()->getItemsBegin();
- LLFolderViewFolder::items_t::const_iterator items_end = mFolderRoot.get()->getItemsEnd();
-
- for (; items_it != items_end; ++items_it)
- {
- const LLFolderViewItem* item_view = *items_it;
- if (item_view->getVisible())
- {
- const LLFolderViewModelItemInventory* modelp = static_cast<const LLFolderViewModelItemInventory*>(item_view->getViewModelItem());
- setSelectionByID(modelp->getUUID(), TRUE);
- break;
- }
- }
- }
-
LLPanel::onFocusReceived();
}
@@ -2258,6 +2219,53 @@ void LLInventorySingleFolderPanel::initFromParams(const Params& p)
LLPanel::initFromParams(mParams);
}
+void LLInventorySingleFolderPanel::onFocusReceived()
+{
+ // Tab support, when tabbing into this view, select first item
+ // (ideally needs to account for scroll)
+ bool select_first = mSelectThisID.isNull() && mFolderRoot.get() && mFolderRoot.get()->getSelectedCount() == 0;
+
+ if (select_first)
+ {
+ LLFolderViewFolder::folders_t::const_iterator folders_it = mFolderRoot.get()->getFoldersBegin();
+ LLFolderViewFolder::folders_t::const_iterator folders_end = mFolderRoot.get()->getFoldersEnd();
+
+ for (; folders_it != folders_end; ++folders_it)
+ {
+ const LLFolderViewFolder* folder_view = *folders_it;
+ if (folder_view->getVisible())
+ {
+ const LLFolderViewModelItemInventory* modelp = static_cast<const LLFolderViewModelItemInventory*>(folder_view->getViewModelItem());
+ setSelectionByID(modelp->getUUID(), TRUE);
+ // quick and dirty fix: don't scroll on switching focus
+ // todo: better 'tab' support, one that would work for LLInventoryPanel
+ mFolderRoot.get()->stopAutoScollining();
+ select_first = false;
+ break;
+ }
+ }
+ }
+
+ if (select_first)
+ {
+ LLFolderViewFolder::items_t::const_iterator items_it = mFolderRoot.get()->getItemsBegin();
+ LLFolderViewFolder::items_t::const_iterator items_end = mFolderRoot.get()->getItemsEnd();
+
+ for (; items_it != items_end; ++items_it)
+ {
+ const LLFolderViewItem* item_view = *items_it;
+ if (item_view->getVisible())
+ {
+ const LLFolderViewModelItemInventory* modelp = static_cast<const LLFolderViewModelItemInventory*>(item_view->getViewModelItem());
+ setSelectionByID(modelp->getUUID(), TRUE);
+ mFolderRoot.get()->stopAutoScollining();
+ break;
+ }
+ }
+ }
+ LLInventoryPanel::onFocusReceived();
+}
+
void LLInventorySingleFolderPanel::initFolderRoot(const LLUUID& start_folder_id)
{
if(mRootInited) return;
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index 4d69bdf17d..b68433bab0 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -404,6 +404,8 @@ public:
{};
void initFromParams(const Params& p);
+ void onFocusReceived() override;
+
bool isSelectionRemovable() { return false; }
void initFolderRoot(const LLUUID& start_folder_id = LLUUID::null);
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index ba82ff0b0f..07825c1b0c 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -59,7 +59,7 @@
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time/local_time_adjustor.hpp>
-const S32 LOG_RECALL_SIZE = 2048;
+const S32 LOG_RECALL_SIZE = 20480;
const std::string LL_IM_TIME("time");
const std::string LL_IM_DATE_TIME("datetime");
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 98ee6a6859..c86e43333c 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -1780,6 +1780,10 @@ bool LLObjectSelection::applyRestrictedPbrMaterialToTEs(LLViewerInventoryItem* i
}
LLUUID asset_id = item->getAssetUUID();
+ if (asset_id.isNull())
+ {
+ asset_id = LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID;
+ }
bool material_copied_all_faces = true;
@@ -1976,6 +1980,10 @@ bool LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id)
return false;
}
asset_id = mItem->getAssetUUID();
+ if (asset_id.isNull())
+ {
+ asset_id = LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID;
+ }
}
// Blank out most override data on the object and send to server
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 8a8abc222f..10667b02d9 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -138,6 +138,8 @@ bool get_can_copy_texture(LLUUID asset_id)
return get_is_predefined_texture(asset_id) || get_copy_free_item_by_asset_id(asset_id).notNull();
}
+S32 LLFloaterTexturePicker::sLastPickerMode = 0;
+
LLFloaterTexturePicker::LLFloaterTexturePicker(
LLView* owner,
LLUUID image_asset_id,
@@ -213,15 +215,38 @@ void LLFloaterTexturePicker::setImageID(const LLUUID& image_id, bool set_selecti
mModeSelector->selectByValue(0);
onModeSelect(0,this);
}
-
- LLUUID item_id = findItemID(mImageAssetID, FALSE);
+
+ LLUUID item_id;
+ LLFolderView* root_folder = mInventoryPanel->getRootFolder();
+ if (root_folder && root_folder->getCurSelectedItem())
+ {
+ LLFolderViewItem* last_selected = root_folder->getCurSelectedItem();
+ LLFolderViewModelItemInventory* inv_view = static_cast<LLFolderViewModelItemInventory*>(last_selected->getViewModelItem());
+
+ LLInventoryItem* itemp = gInventory.getItem(inv_view->getUUID());
+
+ if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL
+ && mImageAssetID == LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID
+ && itemp && itemp->getAssetUUID().isNull())
+ {
+ item_id = inv_view->getUUID();
+ }
+ else if (itemp && itemp->getAssetUUID() == mImageAssetID)
+ {
+ item_id = inv_view->getUUID();
+ }
+ }
+ if (item_id.isNull())
+ {
+ item_id = findItemID(mImageAssetID, FALSE);
+ }
if (item_id.isNull())
{
mInventoryPanel->getRootFolder()->clearSelection();
}
else
{
- LLInventoryItem* itemp = gInventory.getItem(image_id);
+ LLInventoryItem* itemp = gInventory.getItem(item_id);
if (itemp && !itemp->getPermissions().allowCopyBy(gAgent.getID()))
{
// no copy texture
@@ -492,6 +517,15 @@ BOOL LLFloaterTexturePicker::handleKeyHere(KEY key, MASK mask)
return LLFloater::handleKeyHere(key, mask);
}
+void LLFloaterTexturePicker::onOpen(const LLSD& key)
+{
+ if (sLastPickerMode != 0
+ && mModeSelector->selectByValue(sLastPickerMode))
+ {
+ changeMode();
+ }
+}
+
void LLFloaterTexturePicker::onClose(bool app_quitting)
{
if (mOwner && mOnFloaterCloseCallback)
@@ -499,6 +533,7 @@ void LLFloaterTexturePicker::onClose(bool app_quitting)
mOnFloaterCloseCallback();
}
stopUsingPipette();
+ sLastPickerMode = mModeSelector->getValue().asInteger();
}
// virtual
@@ -741,14 +776,22 @@ void LLFloaterTexturePicker::draw()
const LLUUID& LLFloaterTexturePicker::findItemID(const LLUUID& asset_id, BOOL copyable_only, BOOL ignore_library)
{
- if (asset_id.isNull())
+ LLUUID loockup_id = asset_id;
+ if (loockup_id.isNull())
{
- return LLUUID::null;
+ if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL)
+ {
+ loockup_id = LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID;
+ }
+ else
+ {
+ return LLUUID::null;
+ }
}
LLViewerInventoryCategory::cat_array_t cats;
LLViewerInventoryItem::item_array_t items;
- LLAssetIDMatches asset_id_matches(asset_id);
+ LLAssetIDMatches asset_id_matches(loockup_id);
gInventory.collectDescendentsIf(LLUUID::null,
cats,
items,
@@ -816,7 +859,14 @@ void LLFloaterTexturePicker::commitCallback(LLTextureCtrl::ETexturePickOp op)
LLFolderViewModelItemInventory* inv_view = static_cast<LLFolderViewModelItemInventory*>(last_selected->getViewModelItem());
LLInventoryItem* itemp = gInventory.getItem(inv_view->getUUID());
- if (itemp && itemp->getAssetUUID() == mImageAssetID)
+
+ if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL
+ && mImageAssetID == LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID
+ && itemp && itemp->getAssetUUID().isNull())
+ {
+ inventory_id = inv_view->getUUID();
+ }
+ else if (itemp && itemp->getAssetUUID() == mImageAssetID)
{
inventory_id = inv_view->getUUID();
}
@@ -994,85 +1044,8 @@ void LLFloaterTexturePicker::onSelectionChange(const std::deque<LLFolderViewItem
// static
void LLFloaterTexturePicker::onModeSelect(LLUICtrl* ctrl, void *userdata)
{
- LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
- int index = self->mModeSelector->getValue().asInteger();
-
- self->mDefaultBtn->setVisible(index == PICKER_INVENTORY ? TRUE : FALSE);
- self->mBlankBtn->setVisible(index == PICKER_INVENTORY ? TRUE : FALSE);
- self->mNoneBtn->setVisible(index == PICKER_INVENTORY ? TRUE : FALSE);
- self->getChild<LLFilterEditor>("inventory search editor")->setVisible(index == PICKER_INVENTORY ? TRUE : FALSE);
- self->getChild<LLInventoryPanel>("inventory panel")->setVisible(index == PICKER_INVENTORY ? TRUE : FALSE);
-
- /*self->getChild<LLCheckBox>("show_folders_check")->setVisible(mode);
- no idea under which conditions the above is even shown, needs testing. */
-
- self->getChild<LLButton>("l_add_btn")->setVisible(index == PICKER_LOCAL ? TRUE : FALSE);
- self->getChild<LLButton>("l_rem_btn")->setVisible(index == PICKER_LOCAL ? TRUE : FALSE);
- self->getChild<LLButton>("l_upl_btn")->setVisible(index == PICKER_LOCAL ? TRUE : FALSE);
- self->getChild<LLScrollListCtrl>("l_name_list")->setVisible(index == PICKER_LOCAL ? TRUE : FALSE);
-
- self->getChild<LLComboBox>("l_bake_use_texture_combo_box")->setVisible(index == PICKER_BAKE ? TRUE : FALSE);
- self->getChild<LLCheckBoxCtrl>("hide_base_mesh_region")->setVisible(FALSE);// index == 2 ? TRUE : FALSE);
-
- bool pipette_visible = (index == PICKER_INVENTORY)
- && (self->mInventoryPickType != LLTextureCtrl::PICK_MATERIAL);
- self->mPipetteBtn->setVisible(pipette_visible);
-
- if (index == PICKER_BAKE)
- {
- self->stopUsingPipette();
-
- S8 val = -1;
-
- LLUUID imageID = self->mImageAssetID;
- if (imageID == IMG_USE_BAKED_HEAD)
- {
- val = 0;
- }
- else if (imageID == IMG_USE_BAKED_UPPER)
- {
- val = 1;
- }
- else if (imageID == IMG_USE_BAKED_LOWER)
- {
- val = 2;
- }
- else if (imageID == IMG_USE_BAKED_EYES)
- {
- val = 3;
- }
- else if (imageID == IMG_USE_BAKED_SKIRT)
- {
- val = 4;
- }
- else if (imageID == IMG_USE_BAKED_HAIR)
- {
- val = 5;
- }
- else if (imageID == IMG_USE_BAKED_LEFTARM)
- {
- val = 6;
- }
- else if (imageID == IMG_USE_BAKED_LEFTLEG)
- {
- val = 7;
- }
- else if (imageID == IMG_USE_BAKED_AUX1)
- {
- val = 8;
- }
- else if (imageID == IMG_USE_BAKED_AUX2)
- {
- val = 9;
- }
- else if (imageID == IMG_USE_BAKED_AUX3)
- {
- val = 10;
- }
-
-
- self->getChild<LLComboBox>("l_bake_use_texture_combo_box")->setSelectedByValue(val, TRUE);
- }
+ LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
+ self->changeMode();
}
// static
@@ -1348,6 +1321,84 @@ void LLFloaterTexturePicker::onFilterEdit(const std::string& search_string )
mInventoryPanel->setFilterSubString(search_string);
}
+void LLFloaterTexturePicker::changeMode()
+{
+ int index = mModeSelector->getValue().asInteger();
+
+ mDefaultBtn->setVisible(index == PICKER_INVENTORY ? TRUE : FALSE);
+ mBlankBtn->setVisible(index == PICKER_INVENTORY ? TRUE : FALSE);
+ mNoneBtn->setVisible(index == PICKER_INVENTORY ? TRUE : FALSE);
+ mFilterEdit->setVisible(index == PICKER_INVENTORY ? TRUE : FALSE);
+ mInventoryPanel->setVisible(index == PICKER_INVENTORY ? TRUE : FALSE);
+
+ getChild<LLButton>("l_add_btn")->setVisible(index == PICKER_LOCAL ? TRUE : FALSE);
+ getChild<LLButton>("l_rem_btn")->setVisible(index == PICKER_LOCAL ? TRUE : FALSE);
+ getChild<LLButton>("l_upl_btn")->setVisible(index == PICKER_LOCAL ? TRUE : FALSE);
+ getChild<LLScrollListCtrl>("l_name_list")->setVisible(index == PICKER_LOCAL ? TRUE : FALSE);
+
+ getChild<LLComboBox>("l_bake_use_texture_combo_box")->setVisible(index == PICKER_BAKE ? TRUE : FALSE);
+ getChild<LLCheckBoxCtrl>("hide_base_mesh_region")->setVisible(FALSE);// index == 2 ? TRUE : FALSE);
+
+ bool pipette_visible = (index == PICKER_INVENTORY)
+ && (mInventoryPickType != LLTextureCtrl::PICK_MATERIAL);
+ mPipetteBtn->setVisible(pipette_visible);
+
+ if (index == PICKER_BAKE)
+ {
+ stopUsingPipette();
+
+ S8 val = -1;
+
+ LLUUID imageID = mImageAssetID;
+ if (imageID == IMG_USE_BAKED_HEAD)
+ {
+ val = 0;
+ }
+ else if (imageID == IMG_USE_BAKED_UPPER)
+ {
+ val = 1;
+ }
+ else if (imageID == IMG_USE_BAKED_LOWER)
+ {
+ val = 2;
+ }
+ else if (imageID == IMG_USE_BAKED_EYES)
+ {
+ val = 3;
+ }
+ else if (imageID == IMG_USE_BAKED_SKIRT)
+ {
+ val = 4;
+ }
+ else if (imageID == IMG_USE_BAKED_HAIR)
+ {
+ val = 5;
+ }
+ else if (imageID == IMG_USE_BAKED_LEFTARM)
+ {
+ val = 6;
+ }
+ else if (imageID == IMG_USE_BAKED_LEFTLEG)
+ {
+ val = 7;
+ }
+ else if (imageID == IMG_USE_BAKED_AUX1)
+ {
+ val = 8;
+ }
+ else if (imageID == IMG_USE_BAKED_AUX2)
+ {
+ val = 9;
+ }
+ else if (imageID == IMG_USE_BAKED_AUX3)
+ {
+ val = 10;
+ }
+
+ getChild<LLComboBox>("l_bake_use_texture_combo_box")->setSelectedByValue(val, TRUE);
+ }
+}
+
void LLFloaterTexturePicker::refreshLocalList()
{
mLocalScrollCtrl->clearRows();
diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h
index b742ea2da3..180c4fa4b8 100644
--- a/indra/newview/lltexturectrl.h
+++ b/indra/newview/lltexturectrl.h
@@ -306,6 +306,7 @@ public:
// LLFloater overrides
/*virtual*/ BOOL postBuild();
+ /*virtual*/ void onOpen(const LLSD& key);
/*virtual*/ void onClose(bool app_settings);
// New functions
@@ -365,6 +366,7 @@ public:
static void onPickerCallback(const std::vector<std::string>& filenames, LLHandle<LLFloater> handle);
protected:
+ void changeMode();
void refreshLocalList();
void refreshInventoryFilter();
void setImageIDFromItem(const LLInventoryItem* itemp, bool set_selection = true);
@@ -427,6 +429,8 @@ private:
set_on_update_image_stats_callback mOnUpdateImageStatsCallback;
BOOL mBakeTextureEnabled;
+
+ static S32 sLastPickerMode;
};
#endif // LL_LLTEXTURECTRL_H
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index fd46d54a1d..e669393dba 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -239,6 +239,10 @@ static const S32 HTTP_NONPIPE_REQUESTS_LOW_WATER = 20;
// request (e.g. 'Range: <start>-') which seems to fix the problem.
static const S32 HTTP_REQUESTS_RANGE_END_MAX = 20000000;
+// stop after 720 seconds, might be overkill, but cap request can keep going forever.
+static const S32 MAX_CAP_MISSING_RETRIES = 720;
+static const S32 CAP_MISSING_EXPIRATION_DELAY = 1; // seconds
+
//////////////////////////////////////////////////////////////////////////////
namespace
{
@@ -526,6 +530,7 @@ private:
e_state mState;
void setState(e_state new_state);
+ LLViewerRegion* getRegion();
e_write_to_cache_state mWriteToCacheState;
LLTextureFetch* mFetcher;
@@ -579,6 +584,10 @@ private:
LLCore::HttpStatus mGetStatus;
std::string mGetReason;
LLAdaptiveRetryPolicy mFetchRetryPolicy;
+ bool mCanUseCapability;
+ LLTimer mRegionRetryTimer;
+ S32 mRegionRetryAttempt;
+ LLUUID mLastRegionId;
// Work Data
@@ -928,7 +937,9 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
mCacheReadCount(0U),
mCacheWriteCount(0U),
mResourceWaitCount(0U),
- mFetchRetryPolicy(10.f,3600.f,2.f,10)
+ mFetchRetryPolicy(10.f,3600.f,2.f,10),
+ mCanUseCapability(true),
+ mRegionRetryAttempt(0)
{
mType = host.isOk() ? LLImageBase::TYPE_AVATAR_BAKE : LLImageBase::TYPE_NORMAL;
// LL_INFOS(LOG_TXT) << "Create: " << mID << " mHost:" << host << " Discard=" << discard << LL_ENDL;
@@ -1089,6 +1100,18 @@ bool LLTextureFetchWorker::doWork(S32 param)
return true; // abort
}
}
+ if (mState > CACHE_POST && !mCanUseCapability && mCanUseHTTP)
+ {
+ if (mRegionRetryAttempt > MAX_CAP_MISSING_RETRIES)
+ {
+ mCanUseHTTP = false;
+ }
+ else if (!mRegionRetryTimer.hasExpired())
+ {
+ return false;
+ }
+ // else retry
+ }
if(mState > CACHE_POST && !mCanUseHTTP)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - state > cache_post");
@@ -1290,16 +1313,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
// if (mHost.isInvalid()) get_url = false;
if ( use_http && mCanUseHTTP && mUrl.empty())//get http url.
{
- LLViewerRegion* region = NULL;
- if (mHost.isInvalid())
- {
- region = gAgent.getRegion();
- }
- else if (LLWorld::instanceExists())
- {
- region = LLWorld::getInstance()->getRegion(mHost);
- }
-
+ LLViewerRegion* region = getRegion();
if (region)
{
std::string http_url = region->getViewerAssetUrl();
@@ -1312,19 +1326,27 @@ bool LLTextureFetchWorker::doWork(S32 param)
setUrl(http_url + "/?texture_id=" + mID.asString().c_str());
LL_DEBUGS(LOG_TXT) << "Texture URL: " << mUrl << LL_ENDL;
mWriteToCacheState = CAN_WRITE ; //because this texture has a fixed texture id.
+ mCanUseCapability = true;
+ mRegionRetryAttempt = 0;
+ mLastRegionId = region->getRegionID();
}
else
{
- mCanUseHTTP = false ;
- LL_WARNS(LOG_TXT) << "Texture not available via HTTP: empty URL." << LL_ENDL;
+ mCanUseCapability = false;
+ mRegionRetryAttempt++;
+ mRegionRetryTimer.setTimerExpirySec(CAP_MISSING_EXPIRATION_DELAY);
+ // ex: waiting for caps
+ LL_INFOS_ONCE(LOG_TXT) << "Texture not available via HTTP: empty URL." << LL_ENDL;
}
}
else
{
+ mCanUseCapability = false;
+ mRegionRetryAttempt++;
+ mRegionRetryTimer.setTimerExpirySec(CAP_MISSING_EXPIRATION_DELAY);
// This will happen if not logged in or if a region deoes not have HTTP Texture enabled
//LL_WARNS(LOG_TXT) << "Region not found for host: " << mHost << LL_ENDL;
- LL_WARNS(LOG_TXT) << "Texture not available via HTTP: no region " << mUrl << LL_ENDL;
- mCanUseHTTP = false;
+ LL_INFOS_ONCE(LOG_TXT) << "Texture not available via HTTP: no region " << mUrl << LL_ENDL;
}
}
else if (mFTType == FTT_SERVER_BAKE)
@@ -1332,7 +1354,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
mWriteToCacheState = CAN_WRITE;
}
- if (mCanUseHTTP && !mUrl.empty())
+ if (mCanUseCapability && mCanUseHTTP && !mUrl.empty())
{
setState(WAIT_HTTP_RESOURCE);
if(mWriteToCacheState != NOT_WRITE)
@@ -1534,10 +1556,37 @@ bool LLTextureFetchWorker::doWork(S32 param)
}
return true;
}
+
+ if (mCanUseHTTP && !mUrl.empty() && cur_size <= 0)
+ {
+ LLViewerRegion* region = getRegion();
+ if (!region || mLastRegionId != region->getRegionID())
+ {
+ // cap failure? try on new region.
+ mUrl.clear();
+ ++mRetryAttempt;
+ mLastRegionId.setNull();
+ setState(INIT);
+ return false;
+ }
+ }
}
else if (http_service_unavail == mGetStatus)
{
LL_INFOS_ONCE(LOG_TXT) << "Texture server busy (503): " << mUrl << LL_ENDL;
+ if (mCanUseHTTP && !mUrl.empty() && cur_size <= 0)
+ {
+ LLViewerRegion* region = getRegion();
+ if (!region || mLastRegionId != region->getRegionID())
+ {
+ // try on new region.
+ mUrl.clear();
+ ++mRetryAttempt;
+ mLastRegionId.setNull();
+ setState(INIT);
+ return false;
+ }
+ }
}
else if (http_not_sat == mGetStatus)
{
@@ -3054,6 +3103,20 @@ void LLTextureFetchWorker::setState(e_state new_state)
mState = new_state;
}
+LLViewerRegion* LLTextureFetchWorker::getRegion()
+{
+ LLViewerRegion* region = NULL;
+ if (mHost.isInvalid())
+ {
+ region = gAgent.getRegion();
+ }
+ else if (LLWorld::instanceExists())
+ {
+ region = LLWorld::getInstance()->getRegion(mHost);
+ }
+ return region;
+}
+
//////////////////////////////////////////////////////////////////////////////
// Threads: T*