summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llmath/llvolume.cpp34
-rw-r--r--indra/llwindow/llwindowwin32.cpp28
-rw-r--r--indra/newview/llface.cpp46
-rw-r--r--indra/newview/llface.h10
-rw-r--r--indra/newview/llfloaterperms.cpp2
-rw-r--r--indra/newview/llfloaterperms.h1
-rw-r--r--indra/newview/llpanelface.cpp40
-rw-r--r--indra/newview/llpanelvolume.cpp22
-rw-r--r--indra/newview/llselectmgr.cpp57
-rw-r--r--indra/newview/lltexturectrl.cpp17
-rw-r--r--indra/newview/lltexturectrl.h4
-rw-r--r--indra/newview/lltooldraganddrop.cpp2
-rw-r--r--indra/newview/llvovolume.cpp18
13 files changed, 226 insertions, 55 deletions
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 0e3792fda3..6d36daa92a 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -5626,29 +5626,29 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents)
mWeights[dst_idx].loadua(data.w[src_idx].mV);
}
}
+
+ // put back in normalized coordinate frame
+ LLVector4a inv_scale(1.f/mNormalizedScale.mV[0], 1.f / mNormalizedScale.mV[1], 1.f / mNormalizedScale.mV[2]);
+ LLVector4a scale;
+ scale.load3(mNormalizedScale.mV);
+ scale.getF32ptr()[3] = 1.f;
+
+ for (int i = 0; i < mNumVertices; ++i)
+ {
+ mPositions[i].mul(inv_scale);
+ mNormals[i].mul(scale);
+ mNormals[i].normalize3();
+ F32 w = mTangents[i].getF32ptr()[3];
+ mTangents[i].mul(scale);
+ mTangents[i].normalize3();
+ mTangents[i].getF32ptr()[3] = w;
+ }
}
else
{
// blew past the max vertex size limit, use legacy tangent generation which never adds verts
createTangents();
}
-
- // put back in normalized coordinate frame
- LLVector4a inv_scale(1.f/mNormalizedScale.mV[0], 1.f / mNormalizedScale.mV[1], 1.f / mNormalizedScale.mV[2]);
- LLVector4a scale;
- scale.load3(mNormalizedScale.mV);
- scale.getF32ptr()[3] = 1.f;
-
- for (int i = 0; i < mNumVertices; ++i)
- {
- mPositions[i].mul(inv_scale);
- mNormals[i].mul(scale);
- mNormals[i].normalize3();
- F32 w = mTangents[i].getF32ptr()[3];
- mTangents[i].mul(scale);
- mTangents[i].normalize3();
- mTangents[i].getF32ptr()[3] = w;
- }
}
// cache optimize index buffer
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index 1f91cbbaa8..42ec4ee29d 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -352,6 +352,11 @@ struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool
void run() override;
+ void glReady()
+ {
+ mGLReady = true;
+ }
+
// initialzie DXGI adapter (for querying available VRAM)
void initDX();
@@ -410,6 +415,9 @@ struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool
HWND mWindowHandle = NULL;
HDC mhDC = 0;
+ // *HACK: Attempt to prevent startup crashes by deferring memory accounting
+ // until after some graphics setup. See SL-20177. -Cosmic,2023-09-18
+ bool mGLReady = false;
// best guess at available video memory in MB
std::atomic<U32> mAvailableVRAM;
@@ -1720,6 +1728,13 @@ const S32 max_format = (S32)num_formats - 1;
// ok to post quit messages now
mPostQuit = TRUE;
+ // *HACK: Attempt to prevent startup crashes by deferring memory accounting
+ // until after some graphics setup. See SL-20177. -Cosmic,2023-09-18
+ mWindowThread->post([=]()
+ {
+ mWindowThread->glReady();
+ });
+
if (auto_show)
{
show();
@@ -4692,6 +4707,8 @@ void debugEnumerateGraphicsAdapters()
void LLWindowWin32::LLWindowWin32Thread::initDX()
{
+ if (!mGLReady) { return; }
+
if (mDXGIAdapter == NULL)
{
debugEnumerateGraphicsAdapters();
@@ -4726,6 +4743,8 @@ void LLWindowWin32::LLWindowWin32Thread::initDX()
void LLWindowWin32::LLWindowWin32Thread::initD3D()
{
+ if (!mGLReady) { return; }
+
if (mDXGIAdapter == NULL && mD3DDevice == NULL && mWindowHandle != 0)
{
mD3D = Direct3DCreate9(D3D_SDK_VERSION);
@@ -4752,6 +4771,8 @@ void LLWindowWin32::LLWindowWin32Thread::initD3D()
void LLWindowWin32::LLWindowWin32Thread::updateVRAMUsage()
{
LL_PROFILE_ZONE_SCOPED;
+ if (!mGLReady) { return; }
+
if (mDXGIAdapter != nullptr)
{
// NOTE: what lies below is hand wavy math based on compatibility testing and observation against a variety of hardware
@@ -4825,8 +4846,6 @@ void LLWindowWin32::LLWindowWin32Thread::run()
sWindowThreadId = std::this_thread::get_id();
LogChange logger("Window");
- initDX();
-
//as good a place as any to up the MM timer resolution (see ms_sleep)
//attempt to set timer resolution to 1ms
TIMECAPS tc;
@@ -4839,9 +4858,12 @@ void LLWindowWin32::LLWindowWin32Thread::run()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_WIN32;
+ // lazily call initD3D inside this loop to catch when mGLReady has been set to true
+ initDX();
+
if (mWindowHandle != 0)
{
- // lazily call initD3D inside this loop to catch when mWindowHandle has been set
+ // lazily call initD3D inside this loop to catch when mWindowHandle has been set, and mGLReady has been set to true
// *TODO: Shutdown if this fails when mWindowHandle exists
initD3D();
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index cec1f47a4c..c1776705f9 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -1144,22 +1144,32 @@ void push_for_transform(LLVertexBuffer* buff, U32 source_count, U32 dest_count)
}
BOOL LLFace::getGeometryVolume(const LLVolume& volume,
- const S32 &f,
- const LLMatrix4& mat_vert_in, const LLMatrix3& mat_norm_in,
- const U16 &index_offset,
- bool force_rebuild)
+ S32 face_index,
+ const LLMatrix4& mat_vert_in,
+ const LLMatrix3& mat_norm_in,
+ U16 index_offset,
+ bool force_rebuild,
+ bool no_debug_assert)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE;
llassert(verify());
- if (volume.getNumVolumeFaces() <= f) {
- LL_WARNS() << "Attempt get volume face out of range! Total Faces: " << volume.getNumVolumeFaces() << " Attempt get access to: " << f << LL_ENDL;
- return FALSE;
- }
+ if (face_index < 0 || face_index >= volume.getNumVolumeFaces())
+ {
+ if (gDebugGL)
+ {
+ LL_WARNS() << "Face index is out of bounds!" << LL_ENDL;
+ LL_WARNS() << "Attempt get volume face out of range!"
+ " Total Faces: " << volume.getNumVolumeFaces() <<
+ " Attempt get access to: " << face_index << LL_ENDL;
+ llassert(no_debug_assert);
+ }
+ return FALSE;
+ }
bool rigged = isState(RIGGED);
- const LLVolumeFace &vf = volume.getVolumeFace(f);
+ const LLVolumeFace &vf = volume.getVolumeFace(face_index);
S32 num_vertices = (S32)vf.mNumVertices;
S32 num_indices = (S32) vf.mNumIndices;
@@ -1174,14 +1184,14 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
{
if (gDebugGL)
{
- LL_WARNS() << "Index buffer overflow!" << LL_ENDL;
+ LL_WARNS() << "Index buffer overflow!" << LL_ENDL;
LL_WARNS() << "Indices Count: " << mIndicesCount
<< " VF Num Indices: " << num_indices
<< " Indices Index: " << mIndicesIndex
<< " VB Num Indices: " << mVertexBuffer->getNumIndices() << LL_ENDL;
- LL_WARNS() << " Face Index: " << f
+ LL_WARNS() << " Face Index: " << face_index
<< " Pool Type: " << mPoolType << LL_ENDL;
- llassert(false);
+ llassert(no_debug_assert);
}
return FALSE;
}
@@ -1191,7 +1201,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (gDebugGL)
{
LL_WARNS() << "Vertex buffer overflow!" << LL_ENDL;
- llassert(false);
+ llassert(no_debug_assert);
}
return FALSE;
}
@@ -1228,7 +1238,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
bool rebuild_tangent = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TANGENT);
bool rebuild_weights = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_WEIGHT4);
- const LLTextureEntry *tep = mVObjp->getTE(f);
+ const LLTextureEntry *tep = mVObjp->getTE(face_index);
const U8 bump_code = tep ? tep->getBumpmap() : 0;
BOOL is_static = mDrawablep->isStatic();
@@ -1443,7 +1453,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (bump_code)
{
- mVObjp->getVolume()->genTangents(f);
+ mVObjp->getVolume()->genTangents(face_index);
F32 offset_multiple;
switch( bump_code )
{
@@ -1492,7 +1502,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
U8 texgen = getTextureEntry()->getTexGen();
if (rebuild_tcoord && texgen != LLTextureEntry::TEX_GEN_DEFAULT)
{ //planar texgen needs binormals
- mVObjp->getVolume()->genTangents(f);
+ mVObjp->getVolume()->genTangents(face_index);
}
U8 tex_mode = 0;
@@ -1775,7 +1785,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
{
mVertexBuffer->getTexCoord1Strider(tex_coords1, mGeomIndex, mGeomCount);
- mVObjp->getVolume()->genTangents(f);
+ mVObjp->getVolume()->genTangents(face_index);
for (S32 i = 0; i < num_vertices; i++)
{
@@ -1895,7 +1905,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
mVertexBuffer->getTangentStrider(tangent, mGeomIndex, mGeomCount);
F32* tangents = (F32*) tangent.get();
- mVObjp->getVolume()->genTangents(f);
+ mVObjp->getVolume()->genTangents(face_index);
LLVector4Logical mask;
mask.clear();
diff --git a/indra/newview/llface.h b/indra/newview/llface.h
index 0a66dc6ba6..eb3b47d6d6 100644
--- a/indra/newview/llface.h
+++ b/indra/newview/llface.h
@@ -156,10 +156,12 @@ public:
void updateRebuildFlags();
bool canRenderAsMask(); // logic helper
BOOL getGeometryVolume(const LLVolume& volume,
- const S32 &f,
- const LLMatrix4& mat_vert, const LLMatrix3& mat_normal,
- const U16 &index_offset,
- bool force_rebuild = false);
+ S32 face_index,
+ const LLMatrix4& mat_vert,
+ const LLMatrix3& mat_normal,
+ U16 index_offset,
+ bool force_rebuild = false,
+ bool no_debug_assert = false);
// For avatar
U16 getGeometryAvatar(
diff --git a/indra/newview/llfloaterperms.cpp b/indra/newview/llfloaterperms.cpp
index fb55c6c6c4..b53839977e 100644
--- a/indra/newview/llfloaterperms.cpp
+++ b/indra/newview/llfloaterperms.cpp
@@ -122,7 +122,7 @@ const std::string LLFloaterPermsDefault::sCategoryNames[CAT_LAST] =
"Notecards",
"Gestures",
"Wearables",
- "Settings"
+ "Settings",
"Materials"
};
diff --git a/indra/newview/llfloaterperms.h b/indra/newview/llfloaterperms.h
index 02359a256e..97ddec7cba 100644
--- a/indra/newview/llfloaterperms.h
+++ b/indra/newview/llfloaterperms.h
@@ -75,6 +75,7 @@ enum Categories
CAT_GESTURES,
CAT_WEARABLES,
CAT_SETTINGS,
+ CAT_MATERIALS,
CAT_LAST
};
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index df464bc7e5..e1f08915fa 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -1010,6 +1010,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
&& objectp->permModify())
{
BOOL editable = objectp->permModify() && !objectp->isPermanentEnforced();
+ BOOL attachment = objectp->isAttachment();
bool has_pbr_material;
bool has_faces_without_pbr;
@@ -1306,6 +1307,18 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
texture_ctrl->setBakeTextureEnabled(TRUE);
}
+
+ if (attachment)
+ {
+ // attachments are in world and in inventory,
+ // server doesn't support changing permissions
+ // in such case
+ texture_ctrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
+ }
+ else
+ {
+ texture_ctrl->setImmediateFilterPermMask(PERM_NONE);
+ }
}
if (shinytexture_ctrl)
@@ -1313,6 +1326,15 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
shinytexture_ctrl->setTentative( !identical_spec );
shinytexture_ctrl->setEnabled( editable && !has_pbr_material);
shinytexture_ctrl->setImageAssetID( specmap_id );
+
+ if (attachment)
+ {
+ shinytexture_ctrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
+ }
+ else
+ {
+ shinytexture_ctrl->setImmediateFilterPermMask(PERM_NONE);
+ }
}
if (bumpytexture_ctrl)
@@ -1320,6 +1342,15 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
bumpytexture_ctrl->setTentative( !identical_norm );
bumpytexture_ctrl->setEnabled( editable && !has_pbr_material);
bumpytexture_ctrl->setImageAssetID( normmap_id );
+
+ if (attachment)
+ {
+ bumpytexture_ctrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
+ }
+ else
+ {
+ bumpytexture_ctrl->setImmediateFilterPermMask(PERM_NONE);
+ }
}
}
@@ -1904,6 +1935,15 @@ void LLPanelFace::updateUIGLTF(LLViewerObject* objectp, bool& has_pbr_material,
pbr_ctrl->setTentative(identical_pbr ? FALSE : TRUE);
pbr_ctrl->setEnabled(settable);
pbr_ctrl->setImageAssetID(pbr_id);
+
+ if (objectp->isAttachment())
+ {
+ pbr_ctrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER | PERM_MODIFY);
+ }
+ else
+ {
+ pbr_ctrl->setImmediateFilterPermMask(PERM_NONE);
+ }
}
getChildView("pbr_from_inventory")->setEnabled(settable);
diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp
index ed244f773c..d6c36bbfb7 100644
--- a/indra/newview/llpanelvolume.cpp
+++ b/indra/newview/llpanelvolume.cpp
@@ -365,6 +365,15 @@ void LLPanelVolume::getState( )
{
LightTextureCtrl->setEnabled(FALSE);
LightTextureCtrl->setValid(FALSE);
+
+ if (objectp->isAttachment())
+ {
+ LightTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
+ }
+ else
+ {
+ LightTextureCtrl->setImmediateFilterPermMask(PERM_NONE);
+ }
}
getChildView("Light Intensity")->setEnabled(false);
@@ -1409,6 +1418,19 @@ void LLPanelVolume::setLightTextureID(const LLUUID &asset_id, const LLUUID &item
if (volobjp)
{
LLViewerInventoryItem* item = gInventory.getItem(item_id);
+
+ if (item && volobjp->isAttachment())
+ {
+ const LLPermissions& perm = item->getPermissions();
+ BOOL unrestricted = ((perm.getMaskBase() & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED) ? TRUE : FALSE;
+ if (!unrestricted)
+ {
+ // Attachments are in world and in inventory simultaneously,
+ // at the moment server doesn't support such a situation.
+ return;
+ }
+ }
+
if (item && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID()))
{
LLToolDragAndDrop::handleDropMaterialProtections(volobjp, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null);
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 6692d124d8..ecc2783eb1 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -1852,10 +1852,24 @@ bool LLSelectMgr::selectionSetImage(const LLUUID& imageid)
f(LLViewerInventoryItem* item, const LLUUID& id) : mItem(item), mImageID(id) {}
bool apply(LLViewerObject* objectp, S32 te)
{
- if(objectp && !objectp->permModify())
+ if(!objectp || !objectp->permModify())
{
return false;
}
+
+ // Might be better to run willObjectAcceptInventory
+ if (mItem && objectp->isAttachment())
+ {
+ const LLPermissions& perm = mItem->getPermissions();
+ BOOL unrestricted = ((perm.getMaskBase() & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED) ? TRUE : FALSE;
+ if (!unrestricted)
+ {
+ // Attachments are in world and in inventory simultaneously,
+ // at the moment server doesn't support such a situation.
+ return false;
+ }
+ }
+
if (mItem)
{
LLToolDragAndDrop::dropTextureOneFace(objectp,
@@ -1938,10 +1952,21 @@ bool LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id)
f(LLViewerInventoryItem* item, const LLUUID& id) : mItem(item), mMatId(id) {}
bool apply(LLViewerObject* objectp, S32 te)
{
- if (objectp && !objectp->permModify())
+ if (!objectp || !objectp->permModify())
{
return false;
}
+ if (mItem && objectp->isAttachment())
+ {
+ const LLPermissions& perm = mItem->getPermissions();
+ BOOL unrestricted = ((perm.getMaskBase() & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED) ? TRUE : FALSE;
+ if (!unrestricted)
+ {
+ // Attachments are in world and in inventory simultaneously,
+ // at the moment server doesn't support such a situation.
+ return false;
+ }
+ }
LLUUID asset_id = mMatId;
if (mItem)
{
@@ -2256,7 +2281,19 @@ void LLSelectMgr::selectionSetBumpmap(U8 bumpmap, const LLUUID &image_id)
if (item && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID()))
{
LLViewerObject *object = mSelectedObjects->getFirstRootObject();
- if (!object) return;
+ if (!object)
+ {
+ return;
+ }
+ const LLPermissions& perm = item->getPermissions();
+ BOOL unrestricted = ((perm.getMaskBase() & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED) ? TRUE : FALSE;
+ BOOL attached = object->isAttachment();
+ if (attached && !unrestricted)
+ {
+ // Attachments are in world and in inventory simultaneously,
+ // at the moment server doesn't support such a situation.
+ return;
+ }
LLToolDragAndDrop::handleDropMaterialProtections(object, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null);
}
getSelection()->applyToTEs(&setfunc);
@@ -2316,7 +2353,19 @@ void LLSelectMgr::selectionSetShiny(U8 shiny, const LLUUID &image_id)
if (item && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID()))
{
LLViewerObject *object = mSelectedObjects->getFirstRootObject();
- if (!object) return;
+ if (!object)
+ {
+ return;
+ }
+ const LLPermissions& perm = item->getPermissions();
+ BOOL unrestricted = ((perm.getMaskBase() & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED) ? TRUE : FALSE;
+ BOOL attached = object->isAttachment();
+ if (attached && !unrestricted)
+ {
+ // Attachments are in world and in inventory simultaneously,
+ // at the moment server doesn't support such a situation.
+ return;
+ }
LLToolDragAndDrop::handleDropMaterialProtections(object, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null);
}
getSelection()->applyToTEs(&setfunc);
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index c13376d0a6..7e399a6808 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -1339,6 +1339,12 @@ void LLFloaterTexturePicker::setInventoryPickType(LLTextureCtrl::EPickInventoryT
}
}
+void LLFloaterTexturePicker::setImmediateFilterPermMask(PermissionMask mask)
+{
+ mImmediateFilterPermMask = mask;
+ mInventoryPanel->setFilterPermMask(mask);
+}
+
void LLFloaterTexturePicker::onPickerCallback(const std::vector<std::string>& filenames, LLHandle<LLFloater> handle)
{
std::vector<std::string>::const_iterator iter = filenames.begin();
@@ -1526,6 +1532,17 @@ void LLTextureCtrl::setCanApply(bool can_preview, bool can_apply)
}
}
+void LLTextureCtrl::setImmediateFilterPermMask(PermissionMask mask)
+{
+ mImmediateFilterPermMask = mask;
+
+ LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
+ if (floaterp)
+ {
+ floaterp->setImmediateFilterPermMask(mask);
+ }
+}
+
void LLTextureCtrl::setVisible( BOOL visible )
{
if( !visible )
diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h
index ba310dd9a6..d82a167c93 100644
--- a/indra/newview/lltexturectrl.h
+++ b/indra/newview/lltexturectrl.h
@@ -184,8 +184,7 @@ public:
void setCanApply(bool can_preview, bool can_apply);
- void setImmediateFilterPermMask(PermissionMask mask)
- { mImmediateFilterPermMask = mask; }
+ void setImmediateFilterPermMask(PermissionMask mask);
void setDnDFilterPermMask(PermissionMask mask)
{ mDnDFilterPermMask = mask; }
PermissionMask getImmediateFilterPermMask() { return mImmediateFilterPermMask; }
@@ -351,6 +350,7 @@ public:
void setBakeTextureEnabled(BOOL enabled);
void setInventoryPickType(LLTextureCtrl::EPickInventoryType type);
+ void setImmediateFilterPermMask(PermissionMask mask);
static void onPickerCallback(const std::vector<std::string>& filenames, LLHandle<LLFloater> handle);
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index afcdb26f1a..1b65439b2b 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -1648,6 +1648,8 @@ EAcceptance LLToolDragAndDrop::willObjectAcceptInventory(LLViewerObject* obj, LL
BOOL unrestricted = ((perm.getMaskBase() & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED) ? TRUE : FALSE;
if(attached && !unrestricted)
{
+ // Attachments are in world and in inventory simultaneously,
+ // at the moment server doesn't support such a situation.
return ACCEPT_NO_LOCKED;
}
else if(modify && transfer && volume && !worn)
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 34f55d3341..73b00489d4 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -6080,12 +6080,18 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
LLVertexBuffer* buff = face->getVertexBuffer();
if (buff)
{
- if (!face->getGeometryVolume(*volume, face->getTEOffset(),
- vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex()))
- { //something's gone wrong with the vertex buffer accounting, rebuild this group
- group->dirtyGeom();
- gPipeline.markRebuild(group);
- }
+ if (!face->getGeometryVolume(*volume, // volume
+ face->getTEOffset(), // face_index
+ vobj->getRelativeXform(), // mat_vert_in
+ vobj->getRelativeXformInvTrans(), // mat_norm_in
+ face->getGeomIndex(), // index_offset
+ false, // force_rebuild
+ true)) // no_debug_assert
+ { // Something's gone wrong with the vertex buffer accounting,
+ // rebuild this group with no debug assert because MESH_DIRTY
+ group->dirtyGeom();
+ gPipeline.markRebuild(group);
+ }
buff->unmapBuffer();
}