diff options
29 files changed, 512 insertions, 491 deletions
diff --git a/.gitignore b/.gitignore index 839d14bc0d..e9b544a6ce 100755 --- a/.gitignore +++ b/.gitignore @@ -7,9 +7,18 @@ *.pyc *.rej *.swp +*.vcxproj +*.filters +*.sln +*.depend +*.stamp +*.rc + *~ # Specific paths and/or names +CMakeCache.txt +cmake_install.cmake LICENSES build-darwin-* build-linux-* @@ -17,6 +26,10 @@ debian/files debian/secondlife-appearance-utility* debian/secondlife-viewer* indra/.distcc +indra/cmake/* +indra/out/* + +indra/packages/* build-vc80/ build-vc100/ build-vc120/ diff --git a/indra/llwindow/llwindow.cpp b/indra/llwindow/llwindow.cpp index f4678a70c5..66be3efffc 100644 --- a/indra/llwindow/llwindow.cpp +++ b/indra/llwindow/llwindow.cpp @@ -406,7 +406,10 @@ LLWindow* LLWindowManager::createWindow( BOOL enable_vsync, BOOL use_gl, BOOL ignore_pixel_depth, - U32 fsaa_samples) + U32 fsaa_samples, + U32 max_cores, + U32 max_vram, + F32 max_gl_version) { LLWindow* new_window; @@ -423,7 +426,7 @@ LLWindow* LLWindowManager::createWindow( #elif LL_WINDOWS new_window = new LLWindowWin32(callbacks, title, name, x, y, width, height, flags, - fullscreen, clearBg, enable_vsync, use_gl, ignore_pixel_depth, fsaa_samples); + fullscreen, clearBg, enable_vsync, use_gl, ignore_pixel_depth, fsaa_samples, max_cores, max_vram, max_gl_version); #elif LL_DARWIN new_window = new LLWindowMacOSX(callbacks, title, name, x, y, width, height, flags, diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h index 2c538a60c9..862897a48c 100644 --- a/indra/llwindow/llwindow.h +++ b/indra/llwindow/llwindow.h @@ -302,7 +302,10 @@ public: BOOL enable_vsync = FALSE, BOOL use_gl = TRUE, BOOL ignore_pixel_depth = FALSE, - U32 fsaa_samples = 0); + U32 fsaa_samples = 0, + U32 max_cores = 0, + U32 max_vram = 0, + F32 max_gl_version = 4.6f); static BOOL destroyWindow(LLWindow* window); static BOOL isWindowValid(LLWindow *window); }; diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 950043dff2..c0d3424141 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -418,6 +418,8 @@ struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool // best guess at available video memory in MB std::atomic<U32> mAvailableVRAM; + U32 mMaxVRAM = 0; // maximum amount of vram to allow in the "budget", or 0 for no maximum (see updateVRAMUsage) + IDXGIAdapter3* mDXGIAdapter = nullptr; LPDIRECT3D9 mD3D = nullptr; LPDIRECT3DDEVICE9 mD3DDevice = nullptr; @@ -430,13 +432,36 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks, BOOL fullscreen, BOOL clearBg, BOOL enable_vsync, BOOL use_gl, BOOL ignore_pixel_depth, - U32 fsaa_samples) - : LLWindow(callbacks, fullscreen, flags) + U32 fsaa_samples, + U32 max_cores, + U32 max_vram, + F32 max_gl_version) + : + LLWindow(callbacks, fullscreen, flags), + mMaxGLVersion(max_gl_version), + mMaxCores(max_cores) { sMainThreadId = LLThread::currentID(); mWindowThread = new LLWindowWin32Thread(); + mWindowThread->mMaxVRAM = max_vram; + //MAINT-516 -- force a load of opengl32.dll just in case windows went sideways LoadLibrary(L"opengl32.dll"); + + + if (mMaxCores != 0) + { + HANDLE hProcess = GetCurrentProcess(); + mMaxCores = llmin(mMaxCores, (U32) 64); + DWORD_PTR mask = 0; + + for (int i = 0; i < mMaxCores; ++i) + { + mask |= ((DWORD_PTR) 1) << i; + } + + SetProcessAffinityMask(hProcess, mask); + } #if 0 // this is probably a bad idea, but keep it in your back pocket if you see what looks like // process deprioritization during profiles @@ -1833,10 +1858,15 @@ void LLWindowWin32::recreateWindow(RECT window_rect, DWORD dw_ex_style, DWORD dw void* LLWindowWin32::createSharedContext() { + mMaxGLVersion = llclamp(mMaxGLVersion, 3.2f, 4.6f); + + S32 version_major = llfloor(mMaxGLVersion); + S32 version_minor = llround((mMaxGLVersion-version_major)*10); + S32 attribs[] = { - WGL_CONTEXT_MAJOR_VERSION_ARB, 4, - WGL_CONTEXT_MINOR_VERSION_ARB, 6, + WGL_CONTEXT_MAJOR_VERSION_ARB, version_major, + WGL_CONTEXT_MINOR_VERSION_ARB, version_minor, WGL_CONTEXT_PROFILE_MASK_ARB, LLRender::sGLCoreProfile ? WGL_CONTEXT_CORE_PROFILE_BIT_ARB : WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, WGL_CONTEXT_FLAGS_ARB, gDebugGL ? WGL_CONTEXT_DEBUG_BIT_ARB : 0, 0 @@ -4815,6 +4845,11 @@ void LLWindowWin32::LLWindowWin32Thread::updateVRAMUsage() budget_mb = llclamp(afr_mb, (U32) 512, (U32) 2048); } + if ( mMaxVRAM != 0) + { + budget_mb = llmin(budget_mb, mMaxVRAM); + } + U32 cu_mb = info.CurrentUsage / 1024 / 1024; // get an estimated usage based on texture bytes allocated @@ -4826,7 +4861,7 @@ void LLWindowWin32::LLWindowWin32Thread::updateVRAMUsage() } F32 eu_error = (F32)((S32)eu_mb - (S32)cu_mb) / (F32)cu_mb; - U32 target_mb = info.Budget / 1024 / 1024; + U32 target_mb = budget_mb; if (target_mb > 4096) // if 4GB are installed, try to leave 2GB free { diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h index bd53b3e92a..ff287a140e 100644 --- a/indra/llwindow/llwindowwin32.h +++ b/indra/llwindow/llwindowwin32.h @@ -139,7 +139,7 @@ protected: LLWindowWin32(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, int x, int y, int width, int height, U32 flags, BOOL fullscreen, BOOL clearBg, BOOL enable_vsync, BOOL use_gl, - BOOL ignore_pixel_depth, U32 fsaa_samples); + BOOL ignore_pixel_depth, U32 fsaa_samples, U32 max_cores, U32 max_vram, F32 max_gl_version); ~LLWindowWin32(); void initCursors(); @@ -210,6 +210,8 @@ protected: F32 mCurrentGamma; U32 mFSAASamples; + U32 mMaxCores; // for debugging only -- maximum number of CPU cores to use, or 0 for no limit + F32 mMaxGLVersion; // maximum OpenGL version to attempt to use (clamps to 3.2 - 4.6) WORD mPrevGammaRamp[3][256]; WORD mCurrentGammaRamp[3][256]; BOOL mCustomGammaSet; diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 9f10e5cac5..bea54f0b69 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -9221,6 +9221,28 @@ <key>Value</key> <integer>0</integer> </map> + <key>RenderMaxOpenGLVersion</key> + <map> + <key>Comment</key> + <string>Maximum OpenGL version to attempt use (minimum 3.2 maximum 4.6). Requires restart.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>4.6</real> + </map> + <key>RenderMaxVRAMBudget</key> + <map> + <key>Comment</key> + <string>Maximum amount of texture memory to budget for (in MB), or 0 for autodetect. Requires restart.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>0</integer> + </map> <key>RenderMaxTextureIndex</key> <map> <key>Comment</key> @@ -16901,5 +16923,16 @@ <key>Value</key> <string></string> </map> + <key>EmulateCoreCount</key> + <map> + <key>Comment</key> + <string>For debugging -- number of cores to restrict the main process to, or 0 for no limit. Requires restart.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>0</integer> + </map> </map> </llsd> diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index cd9ff0192e..684cf55b6b 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -535,7 +535,6 @@ void LLDrawPoolBump::endFullbrightShiny() if( cube_map ) { cube_map->disable(); - cube_map->restoreMatrix(); if (shader->mFeatures.hasReflectionProbes) { gPipeline.unbindReflectionProbes(*shader); diff --git a/indra/newview/lldrawpoolsky.cpp b/indra/newview/lldrawpoolsky.cpp index dba400d095..a7b5ec5fc8 100644 --- a/indra/newview/lldrawpoolsky.cpp +++ b/indra/newview/lldrawpoolsky.cpp @@ -51,7 +51,7 @@ LLDrawPoolSky::LLDrawPoolSky() void LLDrawPoolSky::prerender() { mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT); - if (gSky.mVOSkyp->mDrawable) + if (gSky.mVOSkyp && gSky.mVOSkyp->mDrawable) { gSky.mVOSkyp->updateGeometry(gSky.mVOSkyp->mDrawable); } diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 6557bcb81d..878022a2c8 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -342,34 +342,6 @@ void LLFace::dirtyTexture() gPipeline.markTextured(drawablep); } -void LLFace::notifyAboutCreatingTexture(LLViewerTexture *texture) -{ - LLDrawable* drawablep = getDrawable(); - if(mVObjp.notNull() && mVObjp->getVolume()) - { - LLVOVolume *vobj = drawablep->getVOVolume(); - if(vobj && vobj->notifyAboutCreatingTexture(texture)) - { - gPipeline.markTextured(drawablep); - gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_VOLUME); - } - } -} - -void LLFace::notifyAboutMissingAsset(LLViewerTexture *texture) -{ - LLDrawable* drawablep = getDrawable(); - if(mVObjp.notNull() && mVObjp->getVolume()) - { - LLVOVolume *vobj = drawablep->getVOVolume(); - if(vobj && vobj->notifyAboutMissingAsset(texture)) - { - gPipeline.markTextured(drawablep); - gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_VOLUME); - } - } -} - void LLFace::switchTexture(U32 ch, LLViewerTexture* new_texture) { llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); diff --git a/indra/newview/llface.h b/indra/newview/llface.h index a5ea460061..0cb986b8ed 100644 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -228,9 +228,6 @@ public: LLVertexBuffer* getVertexBuffer() const { return mVertexBuffer; } S32 getRiggedIndex(U32 type) const; - void notifyAboutCreatingTexture(LLViewerTexture *texture); - void notifyAboutMissingAsset(LLViewerTexture *texture); - // used to preserve draw order of faces that are batched together. // Allows content creators to manipulate linked sets and face ordering // for consistent alpha sorting results, particularly for rigged attachments diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index b3403fda0f..81b3c23417 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -1215,6 +1215,16 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState() ctrl_shadow->setEnabled(enabled); shadow_text->setEnabled(enabled); + if (!LLFeatureManager::instance().isFeatureAvailable("RenderFSAASamples")) + { + getChildView("fsaa")->setEnabled(FALSE); + } + + if (!LLFeatureManager::instance().isFeatureAvailable("RenderReflectionProbeDetail")) + { + getChildView("ReflectionDetail")->setEnabled(FALSE); + } + // Hardware settings if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderCompressTextures")) diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp index 45de0b71ae..d04a674e91 100644 --- a/indra/newview/llgltfmateriallist.cpp +++ b/indra/newview/llgltfmateriallist.cpp @@ -32,7 +32,6 @@ #include "lldispatcher.h" #include "llfetchedgltfmaterial.h" #include "llfilesystem.h" -#include "llmaterialeditor.h" #include "llsdserialize.h" #include "lltinygltfhelper.h" #include "llviewercontrol.h" @@ -147,6 +146,11 @@ public: LLGLTFMaterialOverrideDispatchHandler() = default; ~LLGLTFMaterialOverrideDispatchHandler() override = default; + void addCallback(void(*callback)(const LLUUID& object_id, S32 side)) + { + mSelectionCallbacks.push_back(callback); + } + bool operator()(const LLDispatcher* dispatcher, const std::string& key, const LLUUID& invoice, const sparam_t& strings) override { LL_PROFILE_ZONE_SCOPED; @@ -210,7 +214,15 @@ public: return true; } - static void applyData(const LLGLTFOverrideCacheEntry &object_override) + void doSelectionCallbacks(const LLUUID& object_id, S32 side) + { + for (auto& callback : mSelectionCallbacks) + { + callback(object_id, side); + } + } + + void applyData(const LLGLTFOverrideCacheEntry &object_override) { // Parse the data @@ -264,7 +276,7 @@ public: } return results; }, - [object_override](std::vector<ReturnData> results) // Callback to main thread + [object_override, this](std::vector<ReturnData> results) // Callback to main thread { LLViewerObject * obj = gObjectList.findObject(object_override.mObjectId); @@ -285,32 +297,31 @@ public: // object not ready to receive override data, queue for later gGLTFMaterialList.queueOverrideUpdate(object_override.mObjectId, results[i].mSide, results[i].mMaterial); } - else if (obj && obj->isAnySelected()) + else if (obj && obj->getTE(i) && obj->getTE(i)->isSelected()) { - LLMaterialEditor::updateLive(object_override.mObjectId, results[i].mSide); + doSelectionCallbacks(object_override.mObjectId, results[i].mSide); } } else { // unblock material editor - if (obj && obj->isAnySelected()) + if (obj && obj->getTE(i) && obj->getTE(i)->isSelected()) { - LLMaterialEditor::updateLive(object_override.mObjectId, results[i].mSide); + doSelectionCallbacks(object_override.mObjectId, results[i].mSide); } } } if (obj && side_set.size() != obj->getNumTEs()) { // object exists and at least one texture entry needs to have its override data nulled out - bool object_has_selection = obj->isAnySelected(); for (int i = 0; i < obj->getNumTEs(); ++i) { if (side_set.find(i) == side_set.end()) { obj->setTEGLTFMaterialOverride(i, nullptr); - if (object_has_selection) + if (obj->getTE(i) && obj->getTE(i)->isSelected()) { - LLMaterialEditor::updateLive(object_override.mObjectId, i); + doSelectionCallbacks(object_override.mObjectId, i); } } } @@ -318,18 +329,21 @@ public: } else if (obj) { // override list was empty or an error occurred, null out all overrides for this object - bool object_has_selection = obj->isAnySelected(); for (int i = 0; i < obj->getNumTEs(); ++i) { obj->setTEGLTFMaterialOverride(i, nullptr); - if (object_has_selection) + if (obj->getTE(i) && obj->getTE(i)->isSelected()) { - LLMaterialEditor::updateLive(obj->getID(), i); + doSelectionCallbacks(obj->getID(), i); } } } }); } + +private: + + std::vector<void(*)(const LLUUID& object_id, S32 side)> mSelectionCallbacks; }; namespace @@ -357,20 +371,19 @@ void LLGLTFMaterialList::applyQueuedOverrides(LLViewerObject* obj) if (iter != mQueuedOverrides.end()) { - bool object_has_selection = obj->isAnySelected(); override_list_t& overrides = iter->second; for (int i = 0; i < overrides.size(); ++i) { if (overrides[i].notNull()) { - if (!obj->getTE(i)->getGLTFMaterial()) + if (!obj->getTE(i) || !obj->getTE(i)->getGLTFMaterial()) { // object doesn't have its base GLTF material yet, don't apply override (yet) return; } obj->setTEGLTFMaterialOverride(i, overrides[i]); - if (object_has_selection) + if (obj->getTE(i)->isSelected()) { - LLMaterialEditor::updateLive(id, i); + handle_gltf_override_message.doSelectionCallbacks(id, i); } } } @@ -459,6 +472,11 @@ void LLGLTFMaterialList::flushUpdates(void(*done_callback)(bool)) } } +void LLGLTFMaterialList::addSelectionUpdateCallback(void(*update_callback)(const LLUUID& object_id, S32 side)) +{ + handle_gltf_override_message.addCallback(update_callback); +} + class AssetLoadUserData { public: @@ -713,5 +731,5 @@ void LLGLTFMaterialList::modifyMaterialCoro(std::string cap_url, LLSD overrides, void LLGLTFMaterialList::loadCacheOverrides(const LLGLTFOverrideCacheEntry& override) { - LLGLTFMaterialOverrideDispatchHandler::applyData(override); + handle_gltf_override_message.applyData(override); } diff --git a/indra/newview/llgltfmateriallist.h b/indra/newview/llgltfmateriallist.h index 0f0edf7414..abbb755599 100644 --- a/indra/newview/llgltfmateriallist.h +++ b/indra/newview/llgltfmateriallist.h @@ -74,6 +74,8 @@ public: // Automatically called once per frame, but may be called explicitly // for cases that care about the done_callback forwarded to LLCoros::instance().launch static void flushUpdates(void(*done_callback)(bool) = nullptr); + + static void addSelectionUpdateCallback(void(*update_callback)(const LLUUID& object_id, S32 side)); // Queue an explicit LLSD ModifyMaterialParams update apply given override data // overrides -- LLSD map (or array of maps) in the format: diff --git a/indra/newview/lllocalgltfmaterials.cpp b/indra/newview/lllocalgltfmaterials.cpp index b07efff827..89f14c6cfa 100644 --- a/indra/newview/lllocalgltfmaterials.cpp +++ b/indra/newview/lllocalgltfmaterials.cpp @@ -93,27 +93,27 @@ LLLocalGLTFMaterial::~LLLocalGLTFMaterial() } /* accessors */ -std::string LLLocalGLTFMaterial::getFilename() +std::string LLLocalGLTFMaterial::getFilename() const { return mFilename; } -std::string LLLocalGLTFMaterial::getShortName() +std::string LLLocalGLTFMaterial::getShortName() const { return mShortName; } -LLUUID LLLocalGLTFMaterial::getTrackingID() +LLUUID LLLocalGLTFMaterial::getTrackingID() const { return mTrackingID; } -LLUUID LLLocalGLTFMaterial::getWorldID() +LLUUID LLLocalGLTFMaterial::getWorldID() const { return mWorldID; } -S32 LLLocalGLTFMaterial::getIndexInFile() +S32 LLLocalGLTFMaterial::getIndexInFile() const { return mMaterialIndex; } diff --git a/indra/newview/lllocalgltfmaterials.h b/indra/newview/lllocalgltfmaterials.h index 3bdccbbf3d..6919b9b4b2 100644 --- a/indra/newview/lllocalgltfmaterials.h +++ b/indra/newview/lllocalgltfmaterials.h @@ -42,11 +42,11 @@ public: /* main */ virtual ~LLLocalGLTFMaterial(); public: /* accessors */ - std::string getFilename(); - std::string getShortName(); - LLUUID getTrackingID(); - LLUUID getWorldID(); - S32 getIndexInFile(); + std::string getFilename() const; + std::string getShortName() const; + LLUUID getTrackingID() const; + LLUUID getWorldID() const; + S32 getIndexInFile() const; public: bool updateSelf(); diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index d5339777c4..07c283e9c2 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -46,6 +46,7 @@ #include "llsdutil.h" #include "llselectmgr.h" #include "llstatusbar.h" // can_afford_transaction() +#include "lltoolpie.h" #include "llviewerinventory.h" #include "llinventory.h" #include "llviewerregion.h" @@ -322,9 +323,17 @@ bool LLSelectedTEGetMatData::apply(LLViewerObject* objectp, S32 te_index) mLocalMaterial = local_mat; } mMaterial = tep->getGLTFRenderMaterial(); + + if (mMaterial.isNull()) + { + // Shouldn't be possible? + LL_WARNS("MaterialEditor") << "Object has material id, but no material" << LL_ENDL; + mMaterial = gGLTFMaterialList.getMaterial(mat_id); + } } + return true; } - return true; + return false; } ///---------------------------------------------------------------------------- @@ -399,6 +408,9 @@ BOOL LLMaterialEditor::postBuild() if (mIsOverride) { + // Material override change success callback + LLGLTFMaterialList::addSelectionUpdateCallback(&LLMaterialEditor::updateLive); + // Live editing needs a recovery mechanism on cancel mBaseColorTextureCtrl->setOnCancelCallback(boost::bind(&LLMaterialEditor::onCancelCtrl, this, _1, _2, MATERIAL_BASE_COLOR_TEX_DIRTY)); mMetallicTextureCtrl->setOnCancelCallback(boost::bind(&LLMaterialEditor::onCancelCtrl, this, _1, _2, MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY)); @@ -1816,58 +1828,95 @@ void LLMaterialEditor::loadLive() void LLMaterialEditor::saveObjectsMaterialAs() { - - // Find an applicable material. - // Do this before showing message, because - // message is going to drop selection. LLSelectedTEGetMatData func(false); LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func, true /*first applicable*/); + saveMaterialAs(func.mMaterial, func.mLocalMaterial); +} +void LLMaterialEditor::savePickedMaterialAs() +{ + LLPickInfo pick = LLToolPie::getInstance()->getPick(); + if (pick.mPickType != LLPickInfo::PICK_OBJECT || !pick.getObject()) + { + return; + } + + LLPointer<LLGLTFMaterial> render_material; + LLPointer<LLLocalGLTFMaterial> local_material; - if (func.mLocalMaterial.notNull()) + LLViewerObject *objectp = pick.getObject(); + LLUUID mat_id = objectp->getRenderMaterialID(pick.mObjectFace); + if (mat_id.notNull() && objectp->permCopy()) + { + // Try a face user picked first + // (likely the only method we need, but in such case + // enable_object_save_gltf_material will need to check this) + LLTextureEntry *tep = objectp->getTE(pick.mObjectFace); + LLGLTFMaterial *mat = tep->getGLTFMaterial(); + LLLocalGLTFMaterial *local_mat = dynamic_cast<LLLocalGLTFMaterial*>(mat); + + if (local_mat) + { + local_material = local_mat; + } + render_material = tep->getGLTFRenderMaterial(); + } + else + { + // Find an applicable material. + // Do this before showing message, because + // message is going to drop selection. + LLSelectedTEGetMatData func(false); + LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func, true /*first applicable*/); + local_material = func.mLocalMaterial; + render_material = func.mMaterial; + } + + saveMaterialAs(render_material, local_material); +} + +void LLMaterialEditor::saveMaterialAs(const LLGLTFMaterial* render_material, const LLLocalGLTFMaterial *local_material) +{ + if (local_material) { // This is a local material, reload it from file // so that user won't end up with grey textures // on next login. - LLMaterialEditor::loadMaterialFromFile(func.mLocalMaterial->getFilename(), func.mLocalMaterial->getIndexInFile()); + LLMaterialEditor::loadMaterialFromFile(local_material->getFilename(), local_material->getIndexInFile()); LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor"); if (me) { - // apply differences on top - LLGLTFMaterial* local_mat = func.mLocalMaterial.get(); - // don't use override mat here, it has 'hacked ids' - // and values, use end result. - LLGLTFMaterial* cmp_mat = func.mMaterial.get(); - - me->setBaseColor(cmp_mat->mBaseColor); - me->setMetalnessFactor(cmp_mat->mMetallicFactor); - me->setRoughnessFactor(cmp_mat->mRoughnessFactor); - me->setEmissiveColor(cmp_mat->mEmissiveColor); - me->setDoubleSided(cmp_mat->mDoubleSided); - me->setAlphaMode(cmp_mat->getAlphaMode()); - me->setAlphaCutoff(cmp_mat->mAlphaCutoff); + // don't use override material here, it has 'hacked ids' + // and values, use end result, apply it on top of local. + me->setBaseColor(render_material->mBaseColor); + me->setMetalnessFactor(render_material->mMetallicFactor); + me->setRoughnessFactor(render_material->mRoughnessFactor); + me->setEmissiveColor(render_material->mEmissiveColor); + me->setDoubleSided(render_material->mDoubleSided); + me->setAlphaMode(render_material->getAlphaMode()); + me->setAlphaCutoff(render_material->mAlphaCutoff); // most things like colors we can apply without verifying // but texture ids are going to be different from both, base and override // so only apply override id if there is actually a difference - if (local_mat->mBaseColorId != cmp_mat->mBaseColorId) + if (local_material->mBaseColorId != render_material->mBaseColorId) { - me->setBaseColorId(cmp_mat->mBaseColorId); + me->setBaseColorId(render_material->mBaseColorId); me->childSetValue("base_color_upload_fee", me->getString("no_upload_fee_string")); } - if (local_mat->mNormalId != cmp_mat->mNormalId) + if (local_material->mNormalId != render_material->mNormalId) { - me->setNormalId(cmp_mat->mNormalId); + me->setNormalId(render_material->mNormalId); me->childSetValue("normal_upload_fee", me->getString("no_upload_fee_string")); } - if (local_mat->mMetallicRoughnessId != cmp_mat->mMetallicRoughnessId) + if (local_material->mMetallicRoughnessId != render_material->mMetallicRoughnessId) { - me->setMetallicRoughnessId(cmp_mat->mMetallicRoughnessId); + me->setMetallicRoughnessId(render_material->mMetallicRoughnessId); me->childSetValue("metallic_upload_fee", me->getString("no_upload_fee_string")); } - if (local_mat->mEmissiveId != cmp_mat->mEmissiveId) + if (local_material->mEmissiveId != render_material->mEmissiveId) { - me->setEmissiveId(cmp_mat->mEmissiveId); + me->setEmissiveId(render_material->mEmissiveId); me->childSetValue("emissive_upload_fee", me->getString("no_upload_fee_string")); } @@ -1879,9 +1928,9 @@ void LLMaterialEditor::saveObjectsMaterialAs() } LLSD payload; - if (func.mMaterial.notNull()) + if (render_material) { - payload["data"] = func.mMaterial->asJSON(); + payload["data"] = render_material->asJSON(); } else { diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h index 23d5434ff7..6deda5df50 100644 --- a/indra/newview/llmaterialeditor.h +++ b/indra/newview/llmaterialeditor.h @@ -35,6 +35,7 @@ class LLButton; class LLColorSwatchCtrl; class LLComboBox; class LLGLTFMaterial; +class LLLocalGLTFMaterial; class LLTextureCtrl; class LLTextBox; @@ -111,6 +112,7 @@ public: static void loadLive(); static void saveObjectsMaterialAs(); + static void savePickedMaterialAs(); static void onSaveObjectsMaterialAsMsgCallback(const LLSD& notification, const LLSD& response); static void loadFromGLTFMaterial(LLUUID &asset_id); @@ -232,6 +234,8 @@ public: static bool capabilitiesAvailable(); private: + static void saveMaterialAs(const LLGLTFMaterial *render_material, const LLLocalGLTFMaterial *local_material); + static bool updateInventoryItem(const std::string &buffer, const LLUUID &item_id, const LLUUID &task_id); static void createInventoryItem(const std::string &buffer, const std::string &name, const std::string &desc); diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 84b1ff63f4..3d72865f69 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -32,7 +32,6 @@ // library includes #include "llcalc.h" #include "llerror.h" -#include "llfocusmgr.h" #include "llrect.h" #include "llstring.h" #include "llfontgl.h" @@ -95,6 +94,8 @@ using namespace std::literals; +LLPanelFace::Selection LLPanelFace::sMaterialOverrideSelection; + // // Constant definitions for comboboxes // Must match the commbobox definitions in panel_tools_texture.xml @@ -136,7 +137,7 @@ LLGLTFMaterial::TextureInfo texture_info_from_pbrtype(S32 pbr_type) } } -void updateSelectedGLTFMaterials(std::function<void(LLGLTFMaterial*)> func) +void LLPanelFace::updateSelectedGLTFMaterials(std::function<void(LLGLTFMaterial*)> func) { struct LLSelectedTEGLTFMaterialFunctor : public LLSelectedTEFunctor { @@ -158,6 +159,7 @@ void updateSelectedGLTFMaterials(std::function<void(LLGLTFMaterial*)> func) std::function<void(LLGLTFMaterial*)> mFunc; } select_func(func); + LLSelectMgr::getInstance()->getSelection()->applyToTEs(&select_func); } @@ -268,11 +270,14 @@ BOOL LLPanelFace::postBuild() childSetCommitCallback("add_media", &LLPanelFace::onClickBtnAddMedia, this); childSetCommitCallback("delete_media", &LLPanelFace::onClickBtnDeleteMedia, this); - childSetCommitCallback("gltfTextureScaleU", boost::bind(&LLPanelFace::onCommitGLTFTextureScaleU, this, _1), nullptr); - childSetCommitCallback("gltfTextureScaleV", boost::bind(&LLPanelFace::onCommitGLTFTextureScaleV, this, _1), nullptr); - childSetCommitCallback("gltfTextureRotation", boost::bind(&LLPanelFace::onCommitGLTFRotation, this, _1), nullptr); - childSetCommitCallback("gltfTextureOffsetU", boost::bind(&LLPanelFace::onCommitGLTFTextureOffsetU, this, _1), nullptr); - childSetCommitCallback("gltfTextureOffsetV", boost::bind(&LLPanelFace::onCommitGLTFTextureOffsetV, this, _1), nullptr); + getChild<LLUICtrl>("gltfTextureScaleU")->setCommitCallback(boost::bind(&LLPanelFace::onCommitGLTFTextureScaleU, this, _1), nullptr); + getChild<LLUICtrl>("gltfTextureScaleV")->setCommitCallback(boost::bind(&LLPanelFace::onCommitGLTFTextureScaleV, this, _1), nullptr); + getChild<LLUICtrl>("gltfTextureRotation")->setCommitCallback(boost::bind(&LLPanelFace::onCommitGLTFRotation, this, _1), nullptr); + getChild<LLUICtrl>("gltfTextureOffsetU")->setCommitCallback(boost::bind(&LLPanelFace::onCommitGLTFTextureOffsetU, this, _1), nullptr); + getChild<LLUICtrl>("gltfTextureOffsetV")->setCommitCallback(boost::bind(&LLPanelFace::onCommitGLTFTextureOffsetV, this, _1), nullptr); + + LLGLTFMaterialList::addSelectionUpdateCallback(&LLPanelFace::onMaterialOverrideReceived); + sMaterialOverrideSelection.connect(); childSetAction("button align",&LLPanelFace::onClickAutoFix,this); childSetAction("button align textures", &LLPanelFace::onAlignTexture, this); @@ -486,6 +491,11 @@ void LLPanelFace::draw() updateMediaTitle(); LLPanel::draw(); + + if (sMaterialOverrideSelection.update()) + { + setMaterialOverridesFromSelection(); + } } void LLPanelFace::sendTexture() @@ -1773,7 +1783,7 @@ void LLPanelFace::updateUIGLTF(LLViewerObject* objectp, bool& has_pbr_material, { has_pbr_material = false; - BOOL editable = objectp->permModify() && !objectp->isPermanentEnforced(); + const bool editable = objectp->permModify() && !objectp->isPermanentEnforced(); bool has_pbr_capabilities = LLMaterialEditor::capabilitiesAvailable(); // pbr material @@ -1784,10 +1794,11 @@ void LLPanelFace::updateUIGLTF(LLViewerObject* objectp, bool& has_pbr_material, bool identical_pbr; LLSelectedTE::getPbrMaterialId(pbr_id, identical_pbr); + has_pbr_material = pbr_id.notNull(); + pbr_ctrl->setTentative(identical_pbr ? FALSE : TRUE); pbr_ctrl->setEnabled(editable && has_pbr_capabilities); pbr_ctrl->setImageAssetID(pbr_id); - has_pbr_material = pbr_id.notNull(); } getChildView("pbr_from_inventory")->setEnabled(editable && has_pbr_capabilities); @@ -1797,14 +1808,13 @@ void LLPanelFace::updateUIGLTF(LLViewerObject* objectp, bool& has_pbr_material, const bool show_pbr = mComboMatMedia->getCurrentIndex() == MATMEDIA_PBR && mComboMatMedia->getEnabled(); if (show_pbr) { - const U32 pbr_type = findChild<LLRadioGroup>("radio_pbr_type")->getSelectedIndex(); const LLGLTFMaterial::TextureInfo texture_info = texture_info_from_pbrtype(pbr_type); const bool show_texture_info = texture_info != LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; LLUICtrl* gltfCtrlTextureScaleU = getChild<LLUICtrl>("gltfTextureScaleU"); - LLUICtrl* gltfCtrlTextureScaleV = getChild<LLUICtrl>("gltfTextureScaleV"); - LLUICtrl* gltfCtrlTextureRotation = getChild<LLUICtrl>("gltfTextureRotation"); + LLUICtrl* gltfCtrlTextureScaleV = getChild<LLUICtrl>("gltfTextureScaleV"); + LLUICtrl* gltfCtrlTextureRotation = getChild<LLUICtrl>("gltfTextureRotation"); LLUICtrl* gltfCtrlTextureOffsetU = getChild<LLUICtrl>("gltfTextureOffsetU"); LLUICtrl* gltfCtrlTextureOffsetV = getChild<LLUICtrl>("gltfTextureOffsetV"); @@ -1814,48 +1824,7 @@ void LLPanelFace::updateUIGLTF(LLViewerObject* objectp, bool& has_pbr_material, gltfCtrlTextureOffsetU->setEnabled(show_texture_info && has_pbr_capabilities); gltfCtrlTextureOffsetV->setEnabled(show_texture_info && has_pbr_capabilities); - if (show_texture_info) - { - LLGLTFMaterial::TextureTransform transform; - bool scale_u_same = true; - bool scale_v_same = true; - bool rotation_same = true; - bool offset_u_same = true; - bool offset_v_same = true; - - readSelectedGLTFMaterial<float>([&](const LLGLTFMaterial* mat) - { - return mat ? mat->mTextureTransform[texture_info].mScale[VX] : 0.f; - }, transform.mScale[VX], scale_u_same, true, 1e-3f); - readSelectedGLTFMaterial<float>([&](const LLGLTFMaterial* mat) - { - return mat ? mat->mTextureTransform[texture_info].mScale[VY] : 0.f; - }, transform.mScale[VY], scale_v_same, true, 1e-3f); - readSelectedGLTFMaterial<float>([&](const LLGLTFMaterial* mat) - { - return mat ? mat->mTextureTransform[texture_info].mRotation : 0.f; - }, transform.mRotation, rotation_same, true, 1e-3f); - readSelectedGLTFMaterial<float>([&](const LLGLTFMaterial* mat) - { - return mat ? mat->mTextureTransform[texture_info].mOffset[VX] : 0.f; - }, transform.mOffset[VX], offset_u_same, true, 1e-3f); - readSelectedGLTFMaterial<float>([&](const LLGLTFMaterial* mat) - { - return mat ? mat->mTextureTransform[texture_info].mOffset[VY] : 0.f; - }, transform.mOffset[VY], offset_v_same, true, 1e-3f); - - gltfCtrlTextureScaleU->setValue(transform.mScale[VX]); - gltfCtrlTextureScaleV->setValue(transform.mScale[VY]); - gltfCtrlTextureRotation->setValue(transform.mRotation * RAD_TO_DEG); - gltfCtrlTextureOffsetU->setValue(transform.mOffset[VX]); - gltfCtrlTextureOffsetV->setValue(transform.mOffset[VY]); - - gltfCtrlTextureScaleU->setTentative(!scale_u_same); - gltfCtrlTextureScaleV->setTentative(!scale_v_same); - gltfCtrlTextureRotation->setTentative(!rotation_same); - gltfCtrlTextureOffsetU->setTentative(!offset_u_same); - gltfCtrlTextureOffsetV->setTentative(!offset_v_same); - } + // Control values are set in setMaterialOverridesFromSelection } } @@ -2084,6 +2053,12 @@ void LLPanelFace::unloadMedia() mTitleMedia->unloadMediaSource(); } +// static +void LLPanelFace::onMaterialOverrideReceived(const LLUUID& object_id, S32 side) +{ + sMaterialOverrideSelection.onSelectedObjectUpdated(object_id, side); +} + ////////////////////////////////////////////////////////////////////////////// // void LLPanelFace::navigateToTitleMedia( const std::string url ) @@ -2828,6 +2803,7 @@ void LLPanelFace::onCommitPbrType(LLUICtrl* ctrl, void* userdata) // and generally reflecting old state when switching tabs or objects // self->updateUI(); + self->setMaterialOverridesFromSelection(); } // static @@ -4677,7 +4653,7 @@ void LLPanelFace::onCommitPlanarAlign(LLUICtrl* ctrl, void* userdata) self->sendTextureInfo(); } -void updateGLTFTextureTransform(float value, U32 pbr_type, std::function<void(LLGLTFMaterial::TextureTransform*)> edit) +void LLPanelFace::updateGLTFTextureTransform(float value, U32 pbr_type, std::function<void(LLGLTFMaterial::TextureTransform*)> edit) { U32 texture_info_start; U32 texture_info_end; @@ -4699,6 +4675,148 @@ void updateGLTFTextureTransform(float value, U32 pbr_type, std::function<void(LL edit(&new_transform); } }); + + LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode(); + if (node) + { + LLViewerObject* object = node->getObject(); + sMaterialOverrideSelection.setObjectUpdatePending(object->getID(), node->getLastSelectedTE()); + } +} + +void LLPanelFace::setMaterialOverridesFromSelection() +{ + const U32 pbr_type = findChild<LLRadioGroup>("radio_pbr_type")->getSelectedIndex(); + const LLGLTFMaterial::TextureInfo texture_info = texture_info_from_pbrtype(pbr_type); + if (texture_info == LLGLTFMaterial::TextureInfo::GLTF_TEXTURE_INFO_COUNT) + { + return; + } + + LLGLTFMaterial::TextureTransform transform; + bool scale_u_same = true; + bool scale_v_same = true; + bool rotation_same = true; + bool offset_u_same = true; + bool offset_v_same = true; + + readSelectedGLTFMaterial<float>([&](const LLGLTFMaterial* mat) + { + return mat ? mat->mTextureTransform[texture_info].mScale[VX] : 0.f; + }, transform.mScale[VX], scale_u_same, true, 1e-3f); + readSelectedGLTFMaterial<float>([&](const LLGLTFMaterial* mat) + { + return mat ? mat->mTextureTransform[texture_info].mScale[VY] : 0.f; + }, transform.mScale[VY], scale_v_same, true, 1e-3f); + readSelectedGLTFMaterial<float>([&](const LLGLTFMaterial* mat) + { + return mat ? mat->mTextureTransform[texture_info].mRotation : 0.f; + }, transform.mRotation, rotation_same, true, 1e-3f); + readSelectedGLTFMaterial<float>([&](const LLGLTFMaterial* mat) + { + return mat ? mat->mTextureTransform[texture_info].mOffset[VX] : 0.f; + }, transform.mOffset[VX], offset_u_same, true, 1e-3f); + readSelectedGLTFMaterial<float>([&](const LLGLTFMaterial* mat) + { + return mat ? mat->mTextureTransform[texture_info].mOffset[VY] : 0.f; + }, transform.mOffset[VY], offset_v_same, true, 1e-3f); + + LLUICtrl* gltfCtrlTextureScaleU = getChild<LLUICtrl>("gltfTextureScaleU"); + LLUICtrl* gltfCtrlTextureScaleV = getChild<LLUICtrl>("gltfTextureScaleV"); + LLUICtrl* gltfCtrlTextureRotation = getChild<LLUICtrl>("gltfTextureRotation"); + LLUICtrl* gltfCtrlTextureOffsetU = getChild<LLUICtrl>("gltfTextureOffsetU"); + LLUICtrl* gltfCtrlTextureOffsetV = getChild<LLUICtrl>("gltfTextureOffsetV"); + + gltfCtrlTextureScaleU->setValue(transform.mScale[VX]); + gltfCtrlTextureScaleV->setValue(transform.mScale[VY]); + gltfCtrlTextureRotation->setValue(transform.mRotation * RAD_TO_DEG); + gltfCtrlTextureOffsetU->setValue(transform.mOffset[VX]); + gltfCtrlTextureOffsetV->setValue(transform.mOffset[VY]); + + gltfCtrlTextureScaleU->setTentative(!scale_u_same); + gltfCtrlTextureScaleV->setTentative(!scale_v_same); + gltfCtrlTextureRotation->setTentative(!rotation_same); + gltfCtrlTextureOffsetU->setTentative(!offset_u_same); + gltfCtrlTextureOffsetV->setTentative(!offset_v_same); +} + +void LLPanelFace::Selection::connect() +{ + if (!mSelectConnection.connected()) + { + mSelectConnection = LLSelectMgr::instance().mUpdateSignal.connect(boost::bind(&LLPanelFace::Selection::onSelectionChanged, this)); + } +} + +bool LLPanelFace::Selection::update() +{ + const bool selection_changed = compareSelection(); + if (selection_changed) + { + clearObjectUpdatePending(); + } + else if (isObjectUpdatePending()) + { + return false; + } + + const bool changed = mChanged; + mChanged = false; + return changed; +} + +void LLPanelFace::Selection::setObjectUpdatePending(const LLUUID &object_id, S32 side) +{ + mPendingObjectID = object_id; + mPendingSide = side; +} + +void LLPanelFace::Selection::onSelectedObjectUpdated(const LLUUID& object_id, S32 side) +{ + if (object_id == mSelectedObjectID && side == mSelectedSide) + { + mChanged = true; + clearObjectUpdatePending(); + } +} + +void LLPanelFace::Selection::clearObjectUpdatePending() +{ + mPendingObjectID = LLUUID::null; + mPendingSide = -1; +} + +bool LLPanelFace::Selection::compareSelection() +{ + if (!mNeedsSelectionCheck) + { + return false; + } + mNeedsSelectionCheck = false; + + const S32 old_object_count = mSelectedObjectCount; + const LLUUID old_object_id = mSelectedObjectID; + const S32 old_side = mSelectedSide; + + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); + LLSelectNode* node = selection->getFirstNode(); + if (node) + { + LLViewerObject* object = node->getObject(); + mSelectedObjectCount = selection->getObjectCount(); + mSelectedObjectID = object->getID(); + mSelectedSide = node->getLastSelectedTE(); + } + else + { + mSelectedObjectCount = 0; + mSelectedObjectID = LLUUID::null; + mSelectedSide = -1; + } + + const bool selection_changed = old_object_count != mSelectedObjectCount || old_object_id != mSelectedObjectID || old_side != mSelectedSide; + mChanged = mChanged || selection_changed; + return selection_changed; } void LLPanelFace::onCommitGLTFTextureScaleU(LLUICtrl* ctrl) diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index 69744689b5..c0afc79cbe 100644 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -29,6 +29,7 @@ #include "v4color.h" #include "llpanel.h" +#include "llgltfmaterial.h" #include "llmaterial.h" #include "llmaterialmgr.h" #include "lltextureentry.h" @@ -102,7 +103,7 @@ public: void refreshMedia(); void unloadMedia(); - static void onGLTFMaterialUpdate(const LLUUID& object_id, S32 side); + static void onMaterialOverrideReceived(const LLUUID& object_id, S32 side); /*virtual*/ void draw(); @@ -176,7 +177,6 @@ protected: // // @param force_set_values forces spinners to set value even if they are focused void updateUI(bool force_set_values = false); - void updateUIGLTF(LLViewerObject* objectp, bool& has_pbr_material, bool force_set_values); // Convenience func to determine if all faces in selection have // identical planar texgen settings during edits @@ -229,11 +229,13 @@ protected: static void onCommitGlow( LLUICtrl* ctrl, void *userdata); static void onCommitPlanarAlign( LLUICtrl* ctrl, void* userdata); static void onCommitRepeatsPerMeter( LLUICtrl* ctrl, void* userinfo); + void onCommitGLTFTextureScaleU(LLUICtrl* ctrl); void onCommitGLTFTextureScaleV(LLUICtrl* ctrl); void onCommitGLTFRotation(LLUICtrl* ctrl); void onCommitGLTFTextureOffsetU(LLUICtrl* ctrl); void onCommitGLTFTextureOffsetV(LLUICtrl* ctrl); + static void onClickAutoFix(void*); static void onAlignTexture(void*); static void onClickBtnLoadInvPBR(void* userdata); @@ -291,7 +293,6 @@ private: // Do NOT call updateUI from within this function. // void updateVisibility(); - void updateVisibilityGLTF(); // Hey look everyone, a type-safe alternative to copy and paste! :) // @@ -451,29 +452,62 @@ private: void onTextureSelectionChanged(LLInventoryItem* itemp); void onPbrSelectionChanged(LLInventoryItem* itemp); + void updateUIGLTF(LLViewerObject* objectp, bool& has_pbr_material, bool force_set_values); + void updateVisibilityGLTF(); + + void updateSelectedGLTFMaterials(std::function<void(LLGLTFMaterial*)> func); + void updateGLTFTextureTransform(float value, U32 pbr_type, std::function<void(LLGLTFMaterial::TextureTransform*)> edit); + + void setMaterialOverridesFromSelection(); + LLMenuButton* mMenuClipboardColor; LLMenuButton* mMenuClipboardTexture; bool mIsAlpha; - /* These variables interlock processing of materials updates sent to - * the sim. mUpdateInFlight is set to flag that an update has been - * sent to the sim and not acknowledged yet, and cleared when an - * update is received from the sim. mUpdatePending is set when - * there's an update in flight and another UI change has been made - * that needs to be sent as a materials update, and cleared when the - * update is sent. This prevents the sim from getting spammed with - * update messages when, for example, the user holds down the - * up-arrow on a spinner, and avoids running afoul of its throttle. - */ - bool mUpdateInFlight; - bool mUpdatePending; - LLSD mClipboardParams; LLSD mMediaSettings; bool mNeedMediaTitle; + class Selection + { + public: + void connect(); + + // Returns true if the selected objects or sides have changed since + // this was last called, and no object update is pending + bool update(); + + // Prevents update() returning true until the provided object is + // updated. Necessary to prevent controls updating when the mouse is + // held down. + void setObjectUpdatePending(const LLUUID &object_id, S32 side); + + // Callbacks + void onSelectionChanged() { mNeedsSelectionCheck = true; } + void onSelectedObjectUpdated(const LLUUID &object_id, S32 side); + + protected: + void clearObjectUpdatePending(); + bool isObjectUpdatePending() { return mPendingSide != -1; } + + bool compareSelection(); + + bool mChanged = false; + + boost::signals2::scoped_connection mSelectConnection; + bool mNeedsSelectionCheck = true; + S32 mSelectedObjectCount = 0; + LLUUID mSelectedObjectID; + S32 mSelectedSide = -1; + + LLUUID mPendingObjectID; + S32 mPendingSide = -1; + }; + + static Selection sMaterialOverrideSelection; + public: #if defined(DEF_GET_MAT_STATE) #undef DEF_GET_MAT_STATE diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index c67d76100a..8d0dd505bf 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -2962,7 +2962,7 @@ void handle_object_edit_gltf_material() void handle_object_save_gltf_material() { - LLMaterialEditor::saveObjectsMaterialAs(); + LLMaterialEditor::savePickedMaterialAs(); } void handle_attachment_edit(const LLUUID& inv_item_id) diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h index 0673652e61..7142763451 100644 --- a/indra/newview/llviewermenu.h +++ b/indra/newview/llviewermenu.h @@ -135,7 +135,6 @@ bool anyone_copy_selection(LLSelectNode* nodep); // *TODO: Move to separate file bool for_sale_selection(LLSelectNode* nodep); -void handle_save_snapshot(void *); void handle_toggle_flycam(); void handle_object_sit_or_stand(); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 47cb9e9732..2e76103773 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -4062,7 +4062,7 @@ void LLViewerObject::updateTextures() void LLViewerObject::boostTexturePriority(BOOL boost_children /* = TRUE */) { - if (isDead()) + if (isDead() || !getVolume()) { return; } diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 955979e605..816fa6607e 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -789,7 +789,33 @@ void LLViewerObjectList::updateApparentAngles(LLAgent &agent) max_value = llmin((S32) mObjects.size(), mCurLazyUpdateIndex + num_updates); } + // Iterate through some of the objects and lazy update their texture priorities + for (i = mCurLazyUpdateIndex; i < max_value; i++) + { + objectp = mObjects[i]; + if (!objectp->isDead()) + { + num_objects++; + + // Update distance & gpw + objectp->setPixelAreaAndAngle(agent); // Also sets the approx. pixel area + objectp->updateTextures(); // Update the image levels of textures for this object. + } + } + mCurLazyUpdateIndex = max_value; + if (mCurLazyUpdateIndex == mObjects.size()) + { + // restart + mCurLazyUpdateIndex = 0; + mCurBin = 0; // keep in sync with index (mObjects.size() could have changed) + } + else + { + mCurBin = (mCurBin + 1) % NUM_BINS; + } + +#if 1 // Slam priorities for textures that we care about (hovered, selected, and focused) // Hovered // Assumes only one level deep of parenting @@ -820,32 +846,7 @@ void LLViewerObjectList::updateApparentAngles(LLAgent &agent) } } func; LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func); - - // Iterate through some of the objects and lazy update their texture priorities - for (i = mCurLazyUpdateIndex; i < max_value; i++) - { - objectp = mObjects[i]; - if (!objectp->isDead()) - { - num_objects++; - - // Update distance & gpw - objectp->setPixelAreaAndAngle(agent); // Also sets the approx. pixel area - objectp->updateTextures(); // Update the image levels of textures for this object. - } - } - - mCurLazyUpdateIndex = max_value; - if (mCurLazyUpdateIndex == mObjects.size()) - { - // restart - mCurLazyUpdateIndex = 0; - mCurBin = 0; // keep in sync with index (mObjects.size() could have changed) - } - else - { - mCurBin = (mCurBin + 1) % NUM_BINS; - } +#endif LLVOAvatar::cullAvatarsByPixelArea(); } diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index c2e09b2882..0fd796afba 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -659,8 +659,6 @@ S8 LLViewerTexture::getType() const void LLViewerTexture::cleanup() { - notifyAboutMissingAsset(); - if (LLAppViewer::getTextureFetch()) { LLAppViewer::getTextureFetch()->updateRequestPriority(mID, 0.f); @@ -673,30 +671,6 @@ void LLViewerTexture::cleanup() mVolumeList[LLRender::SCULPT_TEX].clear(); } -void LLViewerTexture::notifyAboutCreatingTexture() -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - for(U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch) - { - for(U32 f = 0; f < mNumFaces[ch]; f++) - { - mFaceList[ch][f]->notifyAboutCreatingTexture(this); - } - } -} - -void LLViewerTexture::notifyAboutMissingAsset() -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - for(U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch) - { - for(U32 f = 0; f < mNumFaces[ch]; f++) - { - mFaceList[ch][f]->notifyAboutMissingAsset(this); - } - } -} - // virtual void LLViewerTexture::dump() { @@ -1579,8 +1553,6 @@ void LLViewerFetchedTexture::postCreateTexture() mGLTexturep->checkActiveThread(); #endif - notifyAboutCreatingTexture(); - setActive(); if (!needsToSaveRawImage()) @@ -2221,8 +2193,6 @@ void LLViewerFetchedTexture::setIsMissingAsset(BOOL is_missing) } if (is_missing) { - notifyAboutMissingAsset(); - if (mUrl.empty()) { LL_WARNS() << mID << ": Marking image as missing" << LL_ENDL; diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index 312e2ca365..5fa5d893e7 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -177,10 +177,7 @@ protected: void cleanup() ; void init(bool firstinit) ; void reorganizeFaceList() ; - void reorganizeVolumeList() ; - - void notifyAboutMissingAsset(); - void notifyAboutCreatingTexture(); + void reorganizeVolumeList(); private: friend class LLBumpImageList; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 88058d1137..5bbb18ed30 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1878,6 +1878,11 @@ LLViewerWindow::LLViewerWindow(const Params& p) U32 fsaa_samples) */ // create window + + U32 max_core_count = gSavedSettings.getU32("EmulateCoreCount"); + U32 max_vram = gSavedSettings.getU32("RenderMaxVRAMBudget"); + F32 max_gl_version = gSavedSettings.getF32("RenderMaxOpenGLVersion"); + mWindow = LLWindowManager::createWindow(this, p.title, p.name, p.x, p.y, p.width, p.height, 0, p.fullscreen, @@ -1885,7 +1890,10 @@ LLViewerWindow::LLViewerWindow(const Params& p) gSavedSettings.getBOOL("RenderVSyncEnable"), !gHeadlessClient, p.ignore_pixel_depth, - 0); //don't use window level anti-aliasing + 0, + max_core_count, + max_vram, + max_gl_version); //don't use window level anti-aliasing if (NULL == mWindow) { diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 41b57b8a6b..f06719634e 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -800,7 +800,13 @@ void LLVOVolume::updateTextureVirtualSize(bool forced) { continue; } - + + // clear out boost selected periodically + if (imagep->getBoostLevel() == LLGLTexture::BOOST_SELECTED) + { + imagep->setBoostLevel(LLGLTexture::BOOST_NONE); + } + F32 vsize; F32 old_size = face->getVirtualSize(); @@ -2361,243 +2367,11 @@ S32 LLVOVolume::setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID) return res; } -bool LLVOVolume::notifyAboutCreatingTexture(LLViewerTexture *texture) -{ //Ok, here we have confirmation about texture creation, check our wait-list - //and make changes, or return false - - std::pair<mmap_UUID_MAP_t::iterator, mmap_UUID_MAP_t::iterator> range = mWaitingTextureInfo.equal_range(texture->getID()); - - typedef std::map<U8, LLMaterialPtr> map_te_material; - map_te_material new_material; - - for(mmap_UUID_MAP_t::iterator range_it = range.first; range_it != range.second; ++range_it) - { - LLMaterialPtr cur_material = getTEMaterialParams(range_it->second.te); - - //here we just interesting in DIFFUSE_MAP only! - if(NULL != cur_material.get() && LLRender::DIFFUSE_MAP == range_it->second.map && GL_RGBA != texture->getPrimaryFormat()) - { //ok let's check the diffuse mode - switch(cur_material->getDiffuseAlphaMode()) - { - case LLMaterial::DIFFUSE_ALPHA_MODE_BLEND: - case LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE: - case LLMaterial::DIFFUSE_ALPHA_MODE_MASK: - { //uups... we have non 32 bit texture with LLMaterial::DIFFUSE_ALPHA_MODE_* => LLMaterial::DIFFUSE_ALPHA_MODE_NONE - - LLMaterialPtr mat = NULL; - map_te_material::iterator it = new_material.find(range_it->second.te); - if(new_material.end() == it) { - mat = new LLMaterial(cur_material->asLLSD()); - new_material.insert(map_te_material::value_type(range_it->second.te, mat)); - } else { - mat = it->second; - } - - mat->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE); - - } break; - } //switch - } //if - } //for - - //setup new materials - for(map_te_material::const_iterator it = new_material.begin(), end = new_material.end(); it != end; ++it) - { - LLMaterialMgr::getInstance()->put(getID(), it->first, *it->second); - LLViewerObject::setTEMaterialParams(it->first, it->second); - } - - //clear wait-list - mWaitingTextureInfo.erase(range.first, range.second); - - return 0 != new_material.size(); -} - -bool LLVOVolume::notifyAboutMissingAsset(LLViewerTexture *texture) -{ //Ok, here if we wait information about texture and it's missing - //then depending from the texture map (diffuse, normal, or specular) - //make changes in material and confirm it. If not return false. - std::pair<mmap_UUID_MAP_t::iterator, mmap_UUID_MAP_t::iterator> range = mWaitingTextureInfo.equal_range(texture->getID()); - if(range.first == range.second) return false; - - typedef std::map<U8, LLMaterialPtr> map_te_material; - map_te_material new_material; - - for(mmap_UUID_MAP_t::iterator range_it = range.first; range_it != range.second; ++range_it) - { - LLMaterialPtr cur_material = getTEMaterialParams(range_it->second.te); - if (cur_material.isNull()) - continue; - - switch(range_it->second.map) - { - case LLRender::DIFFUSE_MAP: - { - if(LLMaterial::DIFFUSE_ALPHA_MODE_NONE != cur_material->getDiffuseAlphaMode()) - { //missing texture + !LLMaterial::DIFFUSE_ALPHA_MODE_NONE => LLMaterial::DIFFUSE_ALPHA_MODE_NONE - LLMaterialPtr mat = NULL; - map_te_material::iterator it = new_material.find(range_it->second.te); - if(new_material.end() == it) { - mat = new LLMaterial(cur_material->asLLSD()); - new_material.insert(map_te_material::value_type(range_it->second.te, mat)); - } else { - mat = it->second; - } - - mat->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE); - } - } break; - case LLRender::NORMAL_MAP: - { //missing texture => reset material texture id - LLMaterialPtr mat = NULL; - map_te_material::iterator it = new_material.find(range_it->second.te); - if(new_material.end() == it) { - mat = new LLMaterial(cur_material->asLLSD()); - new_material.insert(map_te_material::value_type(range_it->second.te, mat)); - } else { - mat = it->second; - } - - mat->setNormalID(LLUUID::null); - } break; - case LLRender::SPECULAR_MAP: - { //missing texture => reset material texture id - LLMaterialPtr mat = NULL; - map_te_material::iterator it = new_material.find(range_it->second.te); - if(new_material.end() == it) { - mat = new LLMaterial(cur_material->asLLSD()); - new_material.insert(map_te_material::value_type(range_it->second.te, mat)); - } else { - mat = it->second; - } - - mat->setSpecularID(LLUUID::null); - } break; - case LLRender::NUM_TEXTURE_CHANNELS: - //nothing to do, make compiler happy - break; - } //switch - } //for - - //setup new materials - for(map_te_material::const_iterator it = new_material.begin(), end = new_material.end(); it != end; ++it) - { - LLMaterialMgr::getInstance()->setLocalMaterial(getRegion()->getRegionID(), it->second); - LLViewerObject::setTEMaterialParams(it->first, it->second); - } - - //clear wait-list - mWaitingTextureInfo.erase(range.first, range.second); - - return 0 != new_material.size(); -} - S32 LLVOVolume::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams) { - LLMaterialPtr pMaterial = const_cast<LLMaterialPtr&>(pMaterialParams); - - if(pMaterialParams) - { //check all of them according to material settings - - LLViewerTexture *img_diffuse = getTEImage(te); - LLViewerTexture *img_normal = getTENormalMap(te); - LLViewerTexture *img_specular = getTESpecularMap(te); - - llassert(NULL != img_diffuse); - - LLMaterialPtr new_material = NULL; - - //diffuse - if(NULL != img_diffuse) - { //guard - if(0 == img_diffuse->getPrimaryFormat() && !img_diffuse->isMissingAsset()) - { //ok here we don't have information about texture, let's belief and leave material settings - //but we remember this case - mWaitingTextureInfo.insert(mmap_UUID_MAP_t::value_type(img_diffuse->getID(), material_info(LLRender::DIFFUSE_MAP, te))); - } - else - { - bool bSetDiffuseNone = false; - if(img_diffuse->isMissingAsset()) - { - bSetDiffuseNone = true; - } - else - { - switch(pMaterialParams->getDiffuseAlphaMode()) - { - case LLMaterial::DIFFUSE_ALPHA_MODE_BLEND: - case LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE: - case LLMaterial::DIFFUSE_ALPHA_MODE_MASK: - { //all of them modes available only for 32 bit textures - LLTextureEntry* tex_entry = getTE(te); - bool bIsBakedImageId = false; - if (tex_entry && LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(tex_entry->getID())) - { - bIsBakedImageId = true; - } - if (GL_RGBA != img_diffuse->getPrimaryFormat() && !bIsBakedImageId) - { - bSetDiffuseNone = true; - } - } break; - } - } //else - - - if(bSetDiffuseNone) - { //upps... we should substitute this material with LLMaterial::DIFFUSE_ALPHA_MODE_NONE - new_material = new LLMaterial(pMaterialParams->asLLSD()); - new_material->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE); - } - } - } - - //normal - if(LLUUID::null != pMaterialParams->getNormalID()) - { - if(img_normal && img_normal->isMissingAsset() && img_normal->getID() == pMaterialParams->getNormalID()) - { - if(!new_material) { - new_material = new LLMaterial(pMaterialParams->asLLSD()); - } - new_material->setNormalID(LLUUID::null); - } - else if(NULL == img_normal || 0 == img_normal->getPrimaryFormat()) - { //ok here we don't have information about texture, let's belief and leave material settings - //but we remember this case - mWaitingTextureInfo.insert(mmap_UUID_MAP_t::value_type(pMaterialParams->getNormalID(), material_info(LLRender::NORMAL_MAP,te))); - } - - } - - - //specular - if(LLUUID::null != pMaterialParams->getSpecularID()) - { - if(img_specular && img_specular->isMissingAsset() && img_specular->getID() == pMaterialParams->getSpecularID()) - { - if(!new_material) { - new_material = new LLMaterial(pMaterialParams->asLLSD()); - } - new_material->setSpecularID(LLUUID::null); - } - else if(NULL == img_specular || 0 == img_specular->getPrimaryFormat()) - { //ok here we don't have information about texture, let's belief and leave material settings - //but we remember this case - mWaitingTextureInfo.insert(mmap_UUID_MAP_t::value_type(pMaterialParams->getSpecularID(), material_info(LLRender::SPECULAR_MAP, te))); - } - } - - if(new_material) { - pMaterial = new_material; - LLMaterialMgr::getInstance()->setLocalMaterial(getRegion()->getRegionID(), pMaterial); - } - } - - S32 res = LLViewerObject::setTEMaterialParams(te, pMaterial); + S32 res = LLViewerObject::setTEMaterialParams(te, pMaterialParams); - LL_DEBUGS("MaterialTEs") << "te " << (S32)te << " material " << ((pMaterial) ? pMaterial->asLLSD() : LLSD("null")) << " res " << res + LL_DEBUGS("MaterialTEs") << "te " << (S32)te << " material " << ((pMaterialParams) ? pMaterialParams->asLLSD() : LLSD("null")) << " res " << res << ( LLSelectMgr::getInstance()->getSelection()->contains(const_cast<LLVOVolume*>(this), te) ? " selected" : " not selected" ) << LL_ENDL; setChanged(ALL_CHANGED); diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 003ab38d64..2c269d745d 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -476,26 +476,6 @@ protected: static S32 sNumLODChanges; friend class LLVolumeImplFlexible; - -public: - bool notifyAboutCreatingTexture(LLViewerTexture *texture); - bool notifyAboutMissingAsset(LLViewerTexture *texture); - -private: - struct material_info - { - LLRender::eTexIndex map; - U8 te; - - material_info(LLRender::eTexIndex map_, U8 te_) - : map(map_) - , te(te_) - {} - }; - - typedef std::multimap<LLUUID, material_info> mmap_UUID_MAP_t; - mmap_UUID_MAP_t mWaitingTextureInfo; - }; #endif // LL_LLVOVOLUME_H diff --git a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml index 4a08cc5285..75b50c0e39 100644 --- a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml +++ b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml @@ -666,7 +666,7 @@ layout="topleft" left_delta="130" top_delta="0" - name="ReflectionDetial" + name="ReflectionDetail" width="150"> <combo_box.item label="Disabled" |