diff options
36 files changed, 464 insertions, 1686 deletions
diff --git a/indra/llrender/llgltexture.cpp b/indra/llrender/llgltexture.cpp index e614f45986..4dcca5a726 100644 --- a/indra/llrender/llgltexture.cpp +++ b/indra/llrender/llgltexture.cpp @@ -351,20 +351,6 @@ void LLGLTexture::forceUpdateBindStats(void) const return mGLTexturep->forceUpdateBindStats() ; } -U32 LLGLTexture::getTexelsInAtlas() const -{ - llassert(mGLTexturep.notNull()) ; - - return mGLTexturep->getTexelsInAtlas() ; -} - -U32 LLGLTexture::getTexelsInGLTexture() const -{ - llassert(mGLTexturep.notNull()) ; - - return mGLTexturep->getTexelsInGLTexture() ; -} - bool LLGLTexture::isGLTextureCreated() const { llassert(mGLTexturep.notNull()) ; @@ -372,13 +358,6 @@ bool LLGLTexture::isGLTextureCreated() const return mGLTexturep->isGLTextureCreated() ; } -S32 LLGLTexture::getDiscardLevelInAtlas() const -{ - llassert(mGLTexturep.notNull()) ; - - return mGLTexturep->getDiscardLevelInAtlas() ; -} - void LLGLTexture::destroyGLTexture() { if(mGLTexturep.notNull() && mGLTexturep->getHasGLTexture()) diff --git a/indra/llrender/llgltexture.h b/indra/llrender/llgltexture.h index 0901243f8f..a7de20dc5c 100644 --- a/indra/llrender/llgltexture.h +++ b/indra/llrender/llgltexture.h @@ -51,10 +51,10 @@ public: BOOST_NONE = 0, BOOST_AVATAR , BOOST_AVATAR_BAKED , - BOOST_SCULPTED , BOOST_TERRAIN , // Needed for minimap generation for now. Lower than BOOST_HIGH so the texture stats don't get forced, i.e. texture stats are manually managed by minimap/terrain instead. BOOST_HIGH = 10, + BOOST_SCULPTED , BOOST_BUMP , BOOST_UNUSED_1 , // Placeholder to avoid disrupting habits around texture debug BOOST_SELECTED , @@ -75,7 +75,6 @@ public: AVATAR_SCRATCH_TEX, DYNAMIC_TEX, MEDIA, - ATLAS, OTHER, MAX_GL_IMAGE_CATEGORY }; @@ -156,10 +155,7 @@ public: bool isJustBound()const ; void forceUpdateBindStats(void) const; - U32 getTexelsInAtlas() const ; - U32 getTexelsInGLTexture() const ; bool isGLTextureCreated() const ; - S32 getDiscardLevelInAtlas() const ; LLGLTextureState getTextureState() const { return mTextureState; } //--------------------------------------------------------------------------------------------- diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 7e5cd628c1..956bcef352 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -41,6 +41,7 @@ #include "llrender.h" #include "llwindow.h" #include "llframetimer.h" +#include <unordered_set> extern LL_COMMON_API bool on_main_thread(); @@ -130,10 +131,9 @@ S32 LLImageGL::sCount = 0; bool LLImageGL::sGlobalUseAnisotropic = false; F32 LLImageGL::sLastFrameTime = 0.f; -bool LLImageGL::sAllowReadBackRaw = false ; LLImageGL* LLImageGL::sDefaultGLTexture = NULL ; bool LLImageGL::sCompressTextures = false; -std::set<LLImageGL*> LLImageGL::sImageList; +std::unordered_set<LLImageGL*> LLImageGL::sImageList; bool LLImageGLThread::sEnabledTextures = false; @@ -150,6 +150,9 @@ S32 LLImageGL::sMaxCategories = 1 ; //optimization for when we don't need to calculate mIsMask bool LLImageGL::sSkipAnalyzeAlpha; +U32 LLImageGL::sScratchPBO = 0; +U32 LLImageGL::sScratchPBOSize = 0; + //------------------------ //**************************************************************************************************** @@ -159,20 +162,6 @@ bool LLImageGL::sSkipAnalyzeAlpha; //************************************************************************************** //below are functions for debug use //do not delete them even though they are not currently being used. -void check_all_images() -{ - for (std::set<LLImageGL*>::iterator iter = LLImageGL::sImageList.begin(); - iter != LLImageGL::sImageList.end(); iter++) - { - LLImageGL* glimage = *iter; - if (glimage->getTexName() && glimage->isGLTextureCreated()) - { - gGL.getTexUnit(0)->bind(glimage) ; - glimage->checkTexSize() ; - gGL.getTexUnit(0)->unbind(glimage->getTarget()) ; - } - } -} void LLImageGL::checkTexSize(bool forced) const { @@ -252,6 +241,11 @@ void LLImageGL::initClass(LLWindow* window, S32 num_catagories, bool skip_analyz LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; sSkipAnalyzeAlpha = skip_analyze_alpha; + if (sScratchPBO == 0) + { + glGenBuffers(1, &sScratchPBO); + } + if (thread_texture_loads || thread_media_updates) { LLImageGLThread::createInstance(window); @@ -265,6 +259,12 @@ void LLImageGL::cleanupClass() { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; LLImageGLThread::deleteSingleton(); + if (sScratchPBO != 0) + { + glDeleteBuffers(1, &sScratchPBO); + sScratchPBO = 0; + sScratchPBOSize = 0; + } } @@ -360,66 +360,19 @@ void LLImageGL::updateStats(F32 current_time) //---------------------------------------------------------------------------- //static -void LLImageGL::destroyGL(bool save_state) +void LLImageGL::destroyGL() { for (S32 stage = 0; stage < gGLManager.mNumTextureImageUnits; stage++) { gGL.getTexUnit(stage)->unbind(LLTexUnit::TT_TEXTURE); } - - sAllowReadBackRaw = true ; - for (std::set<LLImageGL*>::iterator iter = sImageList.begin(); - iter != sImageList.end(); iter++) - { - LLImageGL* glimage = *iter; - if (glimage->mTexName) - { - if (save_state && glimage->isGLTextureCreated() && glimage->mComponents) - { - glimage->mSaveData = new LLImageRaw; - if(!glimage->readBackRaw(glimage->mCurrentDiscardLevel, glimage->mSaveData, false)) //necessary, keep it. - { - glimage->mSaveData = NULL ; - } - } - - glimage->destroyGLTexture(); - stop_glerror(); - } - } - sAllowReadBackRaw = false ; -} - -//static -void LLImageGL::restoreGL() -{ - for (std::set<LLImageGL*>::iterator iter = sImageList.begin(); - iter != sImageList.end(); iter++) - { - LLImageGL* glimage = *iter; - if(glimage->getTexName()) - { - LL_ERRS() << "tex name is not 0." << LL_ENDL ; - } - if (glimage->mSaveData.notNull()) - { - if (glimage->getComponents() && glimage->mSaveData->getComponents()) - { - glimage->createGLTexture(glimage->mCurrentDiscardLevel, glimage->mSaveData, 0, true, glimage->getCategory()); - stop_glerror(); - } - glimage->mSaveData = NULL; // deletes data - } - } } //static void LLImageGL::dirtyTexOptions() { - for (std::set<LLImageGL*>::iterator iter = sImageList.begin(); - iter != sImageList.end(); iter++) + for (auto& glimage : sImageList) { - LLImageGL* glimage = *iter; glimage->mTexOptionsDirty = true; stop_glerror(); } @@ -542,10 +495,6 @@ void LLImageGL::init(bool usemipmaps) mHeight = 0; mCurrentDiscardLevel = -1; - mDiscardLevelInAtlas = -1 ; - mTexelsInAtlas = 0 ; - mTexelsInGLTexture = 0 ; - mAllowCompression = true; mTarget = GL_TEXTURE_2D; @@ -622,9 +571,6 @@ bool LLImageGL::setSize(S32 width, S32 height, S32 ncomponents, S32 discard_leve return false; } - // pickmask validity depends on old image size, delete it - freePickMask(); - mWidth = width; mHeight = height; mComponents = ncomponents; @@ -1025,98 +971,6 @@ bool LLImageGL::setImage(const U8* data_in, bool data_hasmips /* = false */, S32 return true; } -bool LLImageGL::preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image) -{ - //not compatible with core GL profile - llassert(!LLRender::sGLCoreProfile); - - if (gGLManager.mIsDisabled) - { - LL_WARNS() << "Trying to create a texture while GL is disabled!" << LL_ENDL; - return false; - } - llassert(gGLManager.mInited); - stop_glerror(); - - if (discard_level < 0) - { - llassert(mCurrentDiscardLevel >= 0); - discard_level = mCurrentDiscardLevel; - } - - // Actual image width/height = raw image width/height * 2^discard_level - S32 w = raw_image->getWidth() << discard_level; - S32 h = raw_image->getHeight() << discard_level; - - // setSize may call destroyGLTexture if the size does not match - if (!setSize(w, h, raw_image->getComponents(), discard_level)) - { - LL_WARNS() << "Trying to create a texture with incorrect dimensions!" << LL_ENDL; - return false; - } - - if (!mHasExplicitFormat) - { - switch (mComponents) - { - case 1: - // Use luminance alpha (for fonts) - mFormatInternal = GL_LUMINANCE8; - mFormatPrimary = GL_LUMINANCE; - mFormatType = GL_UNSIGNED_BYTE; - break; - case 2: - // Use luminance alpha (for fonts) - mFormatInternal = GL_LUMINANCE8_ALPHA8; - mFormatPrimary = GL_LUMINANCE_ALPHA; - mFormatType = GL_UNSIGNED_BYTE; - break; - case 3: - mFormatInternal = GL_RGB8; - mFormatPrimary = GL_RGB; - mFormatType = GL_UNSIGNED_BYTE; - break; - case 4: - mFormatInternal = GL_RGBA8; - mFormatPrimary = GL_RGBA; - mFormatType = GL_UNSIGNED_BYTE; - break; - default: - LL_ERRS() << "Bad number of components for texture: " << (U32) getComponents() << LL_ENDL; - } - } - - mCurrentDiscardLevel = discard_level; - mDiscardLevelInAtlas = discard_level; - mTexelsInAtlas = raw_image->getWidth() * raw_image->getHeight() ; - mLastBindTime = sLastFrameTime; - mGLTextureCreated = false ; - - glPixelStorei(GL_UNPACK_ROW_LENGTH, raw_image->getWidth()); - stop_glerror(); - - if(mFormatSwapBytes) - { - glPixelStorei(GL_UNPACK_SWAP_BYTES, 1); - stop_glerror(); - } - - return true ; -} - -void LLImageGL::postAddToAtlas() -{ - if(mFormatSwapBytes) - { - glPixelStorei(GL_UNPACK_SWAP_BYTES, 0); - stop_glerror(); - } - - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - gGL.getTexUnit(0)->setTextureFilteringOption(mFilterOption); - stop_glerror(); -} - U32 type_width_from_pixtype(U32 pixtype) { U32 type_width = 0; @@ -1752,7 +1606,6 @@ bool LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, bool data_ mTextureMemory = (S64Bytes)getMipBytes(mCurrentDiscardLevel); - mTexelsInGLTexture = getWidth() * getHeight(); // mark this as bound at this point, so we don't throw it out immediately mLastBindTime = sLastFrameTime; @@ -1830,8 +1683,7 @@ void LLImageGL::syncTexName(LLGLuint texname) bool LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) const { - llassert_always(sAllowReadBackRaw) ; - //LL_ERRS() << "should not call this function!" << LL_ENDL ; + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; if (discard_level < 0) { @@ -2297,6 +2149,8 @@ void LLImageGL::analyzeAlpha(const void* data_in, U32 w, U32 h) //---------------------------------------------------------------------------- U32 LLImageGL::createPickMask(S32 pWidth, S32 pHeight) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; + freePickMask(); U32 pick_width = pWidth/2 + 1; U32 pick_height = pHeight/2 + 1; @@ -2314,7 +2168,6 @@ U32 LLImageGL::createPickMask(S32 pWidth, S32 pHeight) //---------------------------------------------------------------------------- void LLImageGL::freePickMask() { - // pickmask validity depends on old image size, delete it if (mPickMask != NULL) { delete [] mPickMask; @@ -2352,16 +2205,16 @@ void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in) return ; } - freePickMask(); - if (mFormatType != GL_UNSIGNED_BYTE || ((mFormatPrimary != GL_RGBA) && (mFormatPrimary != GL_SRGB_ALPHA))) { //cannot generate a pick mask for this texture + freePickMask(); return; } + #ifdef SHOW_ASSERT const U32 pickSize = createPickMask(width, height); #else // SHOW_ASSERT @@ -2460,6 +2313,73 @@ void LLImageGL::resetCurTexSizebar() sCurTexSizeBar = -1 ; sCurTexPickSize = -1 ; } + +bool LLImageGL::scaleDown(S32 desired_discard) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; + + if (mTarget != GL_TEXTURE_2D) + { + return false; + } + + desired_discard = llmin(desired_discard, mMaxDiscardLevel); + + if (desired_discard <= mCurrentDiscardLevel) + { + return false; + } + + S32 mip = desired_discard - mCurrentDiscardLevel; + + S32 desired_width = getWidth(desired_discard); + S32 desired_height = getHeight(desired_discard); + + U64 size = getBytes(desired_discard); + llassert(size <= 2048*2048*4); // we shouldn't be using this method to downscale huge textures, but it'll work + gGL.getTexUnit(0)->bind(this); + + + if (sScratchPBO == 0) + { + glGenBuffers(1, &sScratchPBO); + sScratchPBOSize = 0; + } + + glBindBuffer(GL_PIXEL_PACK_BUFFER, sScratchPBO); + + if (size > sScratchPBOSize) + { + glBufferData(GL_PIXEL_PACK_BUFFER, size, NULL, GL_STREAM_COPY); + sScratchPBOSize = size; + } + + glGetTexImage(mTarget, mip, mFormatPrimary, mFormatType, nullptr); + + free_tex_image(mTexName); + + glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); + + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, sScratchPBO); + glTexImage2D(mTarget, 0, mFormatPrimary, desired_width, desired_height, 0, mFormatPrimary, mFormatType, nullptr); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + + alloc_tex_image(desired_width, desired_height, mFormatPrimary); + + if (mHasMipMaps) + { + LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("scaleDown - glGenerateMipmap"); + glGenerateMipmap(mTarget); + } + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + mCurrentDiscardLevel = desired_discard; + + return true; +} + + //---------------------------------------------------------------------------- #if LL_IMAGEGL_THREAD_CHECK void LLImageGL::checkActiveThread() diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index 5c7a5ce821..3892e9c014 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -39,6 +39,7 @@ #include "llrender.h" #include "threadpool.h" #include "workqueue.h" +#include <unordered_set> #define LL_IMAGEGL_THREAD_CHECK 0 //set to 1 to enable thread debugging for ImageGL @@ -83,9 +84,8 @@ public: // needs to be called every frame static void updateStats(F32 current_time); - // Save off / restore GL textures - static void destroyGL(bool save_state = true); - static void restoreGL(); + // cleanup GL state + static void destroyGL(); static void dirtyTexOptions(); static bool checkSize(S32 width, S32 height); @@ -148,6 +148,10 @@ public: S32 getDiscardLevel() const { return mCurrentDiscardLevel; } S32 getMaxDiscardLevel() const { return mMaxDiscardLevel; } + // override the current discard level + // should only be used for local textures where you know exactly what you're doing + void setDiscardLevel(S32 level) { mCurrentDiscardLevel = level; } + S32 getCurrentWidth() const { return mWidth ;} S32 getCurrentHeight() const { return mHeight ;} S32 getWidth(S32 discard_level = -1) const; @@ -194,26 +198,26 @@ public: void setFilteringOption(LLTexUnit::eTextureFilterOptions option); LLTexUnit::eTextureFilterOptions getFilteringOption(void) const { return mFilterOption; } - LLGLenum getTexTarget()const { return mTarget ;} - S8 getDiscardLevelInAtlas()const {return mDiscardLevelInAtlas;} - U32 getTexelsInAtlas()const { return mTexelsInAtlas ;} - U32 getTexelsInGLTexture()const {return mTexelsInGLTexture;} - + LLGLenum getTexTarget()const { return mTarget; } void init(bool usemipmaps); virtual void cleanup(); // Clean up the LLImageGL so it can be reinitialized. Be careful when using this in derived class destructors void setNeedsAlphaAndPickMask(bool need_mask); - bool preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image); - void postAddToAtlas() ; - #if LL_IMAGEGL_THREAD_CHECK // thread debugging std::thread::id mActiveThread; void checkActiveThread(); #endif + // scale down to the desired discard level using GPU + // returns true if texture was scaled down + // desired discard will be clamped to max discard + // if desired discard is less than or equal to current discard, no scaling will occur + // only works for GL_TEXTURE_2D target + bool scaleDown(S32 desired_discard); + public: // Various GL/Rendering options S64Bytes mTextureMemory; @@ -240,15 +244,10 @@ private: bool mGLTextureCreated ; LLGLuint mTexName; - //LLGLuint mNewTexName = 0; // tex name set by background thread to be applied in main thread U16 mWidth; U16 mHeight; S8 mCurrentDiscardLevel; - S8 mDiscardLevelInAtlas; - U32 mTexelsInAtlas ; - U32 mTexelsInGLTexture; - bool mAllowCompression; protected: @@ -275,7 +274,7 @@ protected: // STATICS public: - static std::set<LLImageGL*> sImageList; + static std::unordered_set<LLImageGL*> sImageList; static S32 sCount; static F32 sLastFrameTime; @@ -301,6 +300,8 @@ public: private: static S32 sMaxCategories; static bool sSkipAnalyzeAlpha; + static U32 sScratchPBO; + static U32 sScratchPBOSize; //the flag to allow to call readBackRaw(...). //can be removed if we do not use that function at all. diff --git a/indra/newview/app_settings/shaders/class1/deferred/normgenF.glsl b/indra/newview/app_settings/shaders/class1/deferred/normgenF.glsl index 902746366d..6d05d983f3 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/normgenF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/normgenF.glsl @@ -25,24 +25,53 @@ /*[EXTRA_CODE_HERE]*/ + + +// generate a normal map using an approximation of the old emboss bump map "brightness/darkness" technique +// srcMap is a source color image, output should be a normal + out vec4 frag_color; -uniform sampler2D alphaMap; +uniform sampler2D srcMap; in vec2 vary_texcoord0; uniform float stepX; uniform float stepY; uniform float norm_scale; +uniform int bump_code; + +#define BE_BRIGHTNESS 1 +#define BE_DARKNESS 2 + +// get luminance or inverse luminance depending on bump_code +float getBumpValue(vec2 texcoord) +{ + vec3 c = texture(srcMap, texcoord).rgb; + + vec3 WEIGHT = vec3(0.2995, 0.5875, 0.1145); + + float l = dot(c, WEIGHT); + + if (bump_code == BE_DARKNESS) + { + l = 1.0 - l; + } + + return l; +} + void main() { - float c = texture(alphaMap, vary_texcoord0).r; + float c = getBumpValue(vary_texcoord0).r; + + float scaler = 512.0; - vec3 right = vec3(norm_scale, 0, (texture(alphaMap, vary_texcoord0+vec2(stepX, 0)).r-c)*255); - vec3 left = vec3(-norm_scale, 0, (texture(alphaMap, vary_texcoord0-vec2(stepX, 0)).r-c)*255); - vec3 up = vec3(0, -norm_scale, (texture(alphaMap, vary_texcoord0-vec2(0, stepY)).r-c)*255); - vec3 down = vec3(0, norm_scale, (texture(alphaMap, vary_texcoord0+vec2(0, stepY)).r-c)*255); + vec3 right = vec3(norm_scale, 0, (getBumpValue(vary_texcoord0+vec2(stepX, 0)).r-c)*scaler); + vec3 left = vec3(-norm_scale, 0, (getBumpValue(vary_texcoord0-vec2(stepX, 0)).r-c)*scaler); + vec3 up = vec3(0, -norm_scale, (getBumpValue(vary_texcoord0-vec2(0, stepY)).r-c)*scaler); + vec3 down = vec3(0, norm_scale, (getBumpValue(vary_texcoord0+vec2(0, stepY)).r-c)*scaler); vec3 norm = cross(right, down) + cross(down, left) + cross(left,up) + cross(up, right); diff --git a/indra/newview/gltf/buffer_util.h b/indra/newview/gltf/buffer_util.h index 40f9448aaf..89cedf4a47 100644 --- a/indra/newview/gltf/buffer_util.h +++ b/indra/newview/gltf/buffer_util.h @@ -181,6 +181,16 @@ namespace LL } template<> + inline void copyVec4<U8, U64>(U8* src, U64& dst) + { + U8* data = (U8*)&dst; + data[0] = src[0]; + data[1] = src[1]; + data[2] = src[2]; + data[3] = src[3]; + } + + template<> inline void copyVec4<U16, LLColor4U>(U16* src, LLColor4U& dst) { dst.set(src[0], src[1], src[2], src[3]); diff --git a/indra/newview/gltfscenemanager.cpp b/indra/newview/gltfscenemanager.cpp index 7b2de4d6de..a0cbe9290c 100644 --- a/indra/newview/gltfscenemanager.cpp +++ b/indra/newview/gltfscenemanager.cpp @@ -144,7 +144,7 @@ void GLTFSceneManager::uploadSelection() } else { - raw = image.mTexture->getCachedRawImage(); + raw = image.mTexture->getRawImage(); } if (raw.notNull()) @@ -339,6 +339,7 @@ void GLTFSceneManager::renderAlpha() void GLTFSceneManager::addGLTFObject(LLViewerObject* obj, LLUUID gltf_id) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_GLTF; llassert(obj->getVolume()->getParams().getSculptID() == gltf_id); llassert(obj->getVolume()->getParams().getSculptType() == LL_SCULPT_TYPE_GLTF); diff --git a/indra/newview/lldebugview.cpp b/indra/newview/lldebugview.cpp index b88d11886a..0596a8fe7d 100644 --- a/indra/newview/lldebugview.cpp +++ b/indra/newview/lldebugview.cpp @@ -105,10 +105,7 @@ void LLDebugView::init() addChild(gSceneMonitorView); gSceneMonitorView->setRect(rect); - r.setLeftTopAndSize(25, rect.getHeight() - 50, (S32) (gViewerWindow->getWindowRectScaled().getWidth() * 0.75f), - (S32) (gViewerWindow->getWindowRectScaled().getHeight() * 0.75f)); - - r.set(150, rect.getHeight() - 50, 820, 100); + r.set(150, rect.getHeight() - 60, 820, 110); LLTextureView::Params tvp; tvp.name("gTextureView"); tvp.rect(r); @@ -116,7 +113,6 @@ void LLDebugView::init() tvp.visible(false); gTextureView = LLUICtrlFactory::create<LLTextureView>(tvp); addChild(gTextureView); - //gTextureView->reshape(r.getWidth(), r.getHeight(), true); } void LLDebugView::draw() diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index 055f99d764..7289e95b6e 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -79,11 +79,6 @@ static S32 diffuse_channel = -1; static S32 bump_channel = -1; static bool shiny = false; -// Enabled after changing LLViewerTexture::mNeedsCreateTexture to an -// LLAtomicBool; this should work just fine, now. HB -#define LL_BUMPLIST_MULTITHREADED 1 - - // static void LLStandardBumpmap::shutdown() { @@ -764,24 +759,21 @@ LLViewerTexture* LLBumpImageList::getBrightnessDarknessImage(LLViewerFetchedText LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; llassert( (bump_code == BE_BRIGHTNESS) || (bump_code == BE_DARKNESS) ); - LLViewerTexture* bump = NULL; + LLViewerTexture* bump = nullptr; - bump_image_map_t* entries_list = NULL; - void (*callback_func)( bool success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, bool final, void* userdata ) = NULL; + bump_image_map_t* entries_list = nullptr; switch( bump_code ) { case BE_BRIGHTNESS: entries_list = &mBrightnessEntries; - callback_func = LLBumpImageList::onSourceBrightnessLoaded; break; case BE_DARKNESS: entries_list = &mDarknessEntries; - callback_func = LLBumpImageList::onSourceDarknessLoaded; break; default: llassert(0); - return NULL; + return nullptr; } bump_image_map_t::iterator iter = entries_list->find(src_image->getID()); @@ -789,51 +781,18 @@ LLViewerTexture* LLBumpImageList::getBrightnessDarknessImage(LLViewerFetchedText { bump = iter->second; } - else - { - (*entries_list)[src_image->getID()] = LLViewerTextureManager::getLocalTexture( true ); - bump = (*entries_list)[src_image->getID()]; // In case callback was called immediately and replaced the image - } - - if (!src_image->hasCallbacks()) - { //if image has no callbacks but resolutions don't match, trigger raw image loaded callback again - if (src_image->getWidth() != bump->getWidth() || - src_image->getHeight() != bump->getHeight())// || - //(LLPipeline::sRenderDeferred && bump->getComponents() != 4)) - { - src_image->setBoostLevel(LLGLTexture::BOOST_BUMP) ; - src_image->setLoadedCallback( callback_func, 0, true, false, new LLUUID(src_image->getID()), NULL ); - src_image->forceToSaveRawImage(0) ; - } - } - - return bump; -} - -// static -void LLBumpImageList::onSourceBrightnessLoaded( bool success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, bool final, void* userdata ) -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; - LLUUID* source_asset_id = (LLUUID*)userdata; - LLBumpImageList::onSourceLoaded( success, src_vi, src, *source_asset_id, BE_BRIGHTNESS ); - if( final ) + if (bump == nullptr || + src_image->getWidth() != bump->getWidth() || + src_image->getHeight() != bump->getHeight()) { - delete source_asset_id; + onSourceUpdated(src_image, (EBumpEffect) bump_code); } -} -// static -void LLBumpImageList::onSourceDarknessLoaded( bool success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, bool final, void* userdata ) -{ - LLUUID* source_asset_id = (LLUUID*)userdata; - LLBumpImageList::onSourceLoaded( success, src_vi, src, *source_asset_id, BE_DARKNESS ); - if( final ) - { - delete source_asset_id; - } + return (*entries_list)[src_image->getID()]; } + void LLBumpImageList::onSourceStandardLoaded( bool success, LLViewerFetchedTexture* src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, bool final, void* userdata) { if (success && LLPipeline::sRenderDeferred) @@ -909,289 +868,108 @@ void LLBumpImageList::generateNormalMapFromAlpha(LLImageRaw* src, LLImageRaw* nr } // static -void LLBumpImageList::onSourceLoaded( bool success, LLViewerTexture *src_vi, LLImageRaw* src, LLUUID& source_asset_id, EBumpEffect bump_code ) +void LLBumpImageList::onSourceUpdated(LLViewerTexture* src, EBumpEffect bump_code) { - LL_PROFILE_ZONE_SCOPED; - - if( success ) - { - LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; - - LLImageDataSharedLock lock(src); - - bump_image_map_t& entries_list(bump_code == BE_BRIGHTNESS ? gBumpImageList.mBrightnessEntries : gBumpImageList.mDarknessEntries ); - bump_image_map_t::iterator iter = entries_list.find(source_asset_id); - - { - if (iter == entries_list.end() || - iter->second.isNull() || - iter->second->getWidth() != src->getWidth() || - iter->second->getHeight() != src->getHeight()) // bump not cached yet or has changed resolution - { //make sure an entry exists for this image - entries_list[src_vi->getID()] = LLViewerTextureManager::getLocalTexture(true); - iter = entries_list.find(src_vi->getID()); - } - } - - if (iter->second->getWidth() != src->getWidth() || - iter->second->getHeight() != src->getHeight()) // bump not cached yet or has changed resolution - { - LLPointer<LLImageRaw> dst_image = new LLImageRaw(src->getWidth(), src->getHeight(), 1); - U8* dst_data = dst_image->getData(); - S32 dst_data_size = dst_image->getDataSize(); - - const U8* src_data = src->getData(); - S32 src_data_size = src->getDataSize(); - - S32 src_components = src->getComponents(); - - // Convert to luminance and then scale and bias that to get ready for - // embossed bump mapping. (0-255 maps to 127-255) - - // Convert to fixed point so we don't have to worry about precision/clamping. - const S32 FIXED_PT = 8; - const S32 R_WEIGHT = S32(0.2995f * (1<<FIXED_PT)); - const S32 G_WEIGHT = S32(0.5875f * (1<<FIXED_PT)); - const S32 B_WEIGHT = S32(0.1145f * (1<<FIXED_PT)); - - S32 minimum = 255; - S32 maximum = 0; - - switch( src_components ) - { - case 1: - case 2: - { - if( src_data_size == dst_data_size * src_components ) - { - for( S32 i = 0, j=0; i < dst_data_size; i++, j+= src_components ) - { - dst_data[i] = src_data[j]; - if( dst_data[i] < minimum ) - { - minimum = dst_data[i]; - } - if( dst_data[i] > maximum ) - { - maximum = dst_data[i]; - } - } - } - else - { - llassert(0); - dst_image->clear(); - } - } - break; - case 3: - case 4: - { - if( src_data_size == dst_data_size * src_components ) - { - for( S32 i = 0, j=0; i < dst_data_size; i++, j+= src_components ) - { - // RGB to luminance - dst_data[i] = (R_WEIGHT * src_data[j] + G_WEIGHT * src_data[j+1] + B_WEIGHT * src_data[j+2]) >> FIXED_PT; - //llassert( dst_data[i] <= 255 );true because it's 8bit - if( dst_data[i] < minimum ) - { - minimum = dst_data[i]; - } - if( dst_data[i] > maximum ) - { - maximum = dst_data[i]; - } - } - } - else - { - llassert(0); - dst_image->clear(); - } - } - break; - default: - llassert(0); - dst_image->clear(); - break; - } - - if( maximum > minimum ) - { - U8 bias_and_scale_lut[256]; - F32 twice_one_over_range = 2.f / (maximum - minimum); - S32 i; - - const F32 ARTIFICIAL_SCALE = 2.f; // Advantage: exaggerates the effect in midrange. Disadvantage: clamps at the extremes. - if (BE_DARKNESS == bump_code) - { - for( i = minimum; i <= maximum; i++ ) - { - F32 minus_one_to_one = F32(maximum - i) * twice_one_over_range - 1.f; - bias_and_scale_lut[i] = llclampb(ll_round(127 * minus_one_to_one * ARTIFICIAL_SCALE + 128)); - } - } - else - { - for( i = minimum; i <= maximum; i++ ) - { - F32 minus_one_to_one = F32(i - minimum) * twice_one_over_range - 1.f; - bias_and_scale_lut[i] = llclampb(ll_round(127 * minus_one_to_one * ARTIFICIAL_SCALE + 128)); - } - } - - for( i = 0; i < dst_data_size; i++ ) - { - dst_data[i] = bias_and_scale_lut[dst_data[i]]; - } - } - - //--------------------------------------------------- - // immediately assign bump to a smart pointer in case some local smart pointer - // accidentally releases it. - LLPointer<LLViewerTexture> bump = iter->second; - - if (!LLPipeline::sRenderDeferred) - { - bump->setExplicitFormat(GL_ALPHA8, GL_ALPHA); - -#if LL_BUMPLIST_MULTITHREADED - auto tex_queue = LLImageGLThread::sEnabledTextures ? sTexUpdateQueue.lock() : nullptr; - - if (tex_queue) - { //dispatch creation to background thread - LLImageRaw* dst_ptr = dst_image; - LLViewerTexture* bump_ptr = bump; - dst_ptr->ref(); - bump_ptr->ref(); - tex_queue->post( - [=]() - { - LL_PROFILE_ZONE_NAMED("bil - create texture"); - bump_ptr->createGLTexture(0, dst_ptr); - bump_ptr->unref(); - dst_ptr->unref(); - }); - - } - else -#endif - { - bump->createGLTexture(0, dst_image); - } - } - else - { //convert to normal map - LL_PROFILE_ZONE_NAMED("bil - create normal map"); - LLImageGL* img = bump->getGLTexture(); - LLImageRaw* dst_ptr = dst_image.get(); - LLGLTexture* bump_ptr = bump.get(); - - dst_ptr->ref(); - img->ref(); - bump_ptr->ref(); - auto create_func = [=]() - { - img->setUseMipMaps(true); - // upload dst_image to GPU (greyscale in red channel) - img->setExplicitFormat(GL_RED, GL_RED); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; - bump_ptr->createGLTexture(0, dst_ptr); - dst_ptr->unref(); - }; + const LLUUID& src_id = src->getID(); - auto generate_func = [=]() - { - // Allocate an empty RGBA texture at "tex_name" the same size as bump - // Note: bump will still point at GPU copy of dst_image - bump_ptr->setExplicitFormat(GL_RGBA, GL_RGBA); - LLGLuint tex_name; - img->createGLTexture(0, nullptr, false, 0, true, &tex_name); + bump_image_map_t& entries_list(bump_code == BE_BRIGHTNESS ? gBumpImageList.mBrightnessEntries : gBumpImageList.mDarknessEntries); + bump_image_map_t::iterator iter = entries_list.find(src_id); - // point render target at empty buffer - sRenderTarget.setColorAttachment(img, tex_name); + if (iter == entries_list.end()) + { //make sure an entry exists for this image + entries_list[src_id] = LLViewerTextureManager::getLocalTexture(true); + iter = entries_list.find(src_id); + } - // generate normal map in empty texture - { - sRenderTarget.bindTarget(); + //--------------------------------------------------- + // immediately assign bump to a smart pointer in case some local smart pointer + // accidentally releases it. + LLPointer<LLViewerTexture> bump = iter->second; - LLGLDepthTest depth(GL_FALSE); - LLGLDisable cull(GL_CULL_FACE); - LLGLDisable blend(GL_BLEND); - gGL.setColorMask(true, true); + if (bump->getWidth() != src->getWidth() || + bump->getHeight() != src->getHeight()) // bump not cached yet or has changed resolution + { + //convert to normal map + LL_PROFILE_ZONE_NAMED("bil - create normal map"); - gNormalMapGenProgram.bind(); + bump->setExplicitFormat(GL_RGBA, GL_RGBA); - static LLStaticHashedString sNormScale("norm_scale"); - static LLStaticHashedString sStepX("stepX"); - static LLStaticHashedString sStepY("stepY"); + LLImageGL* src_img = src->getGLTexture(); + LLImageGL* dst_img = bump->getGLTexture(); + dst_img->setSize(src->getWidth(), src->getHeight(), 4, 0); + dst_img->setUseMipMaps(true); + dst_img->setDiscardLevel(0); + dst_img->createGLTexture(); - gNormalMapGenProgram.uniform1f(sNormScale, gSavedSettings.getF32("RenderNormalMapScale")); - gNormalMapGenProgram.uniform1f(sStepX, 1.f / bump_ptr->getWidth()); - gNormalMapGenProgram.uniform1f(sStepY, 1.f / bump_ptr->getHeight()); + gGL.getTexUnit(0)->bind(bump); - gGL.getTexUnit(0)->bind(bump_ptr); + LLImageGL::setManualImage(GL_TEXTURE_2D, 0, dst_img->getPrimaryFormat(), dst_img->getWidth(), dst_img->getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, nullptr, false); - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.texCoord2f(0, 0); - gGL.vertex2f(0, 0); + LLGLuint tex_name = dst_img->getTexName(); + // point render target at empty buffer + sRenderTarget.setColorAttachment(bump->getGLTexture(), tex_name); - gGL.texCoord2f(0, 1); - gGL.vertex2f(0, 1); + // generate normal map in empty texture + { + sRenderTarget.bindTarget(); - gGL.texCoord2f(1, 0); - gGL.vertex2f(1, 0); + LLGLDepthTest depth(GL_FALSE); + LLGLDisable cull(GL_CULL_FACE); + LLGLDisable blend(GL_BLEND); + gGL.setColorMask(true, true); - gGL.texCoord2f(1, 1); - gGL.vertex2f(1, 1); + LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; + gNormalMapGenProgram.bind(); - gGL.end(); + static LLStaticHashedString sNormScale("norm_scale"); + static LLStaticHashedString sStepX("stepX"); + static LLStaticHashedString sStepY("stepY"); + static LLStaticHashedString sBumpCode("bump_code"); - gGL.flush(); + gNormalMapGenProgram.uniform1f(sNormScale, gSavedSettings.getF32("RenderNormalMapScale")); + gNormalMapGenProgram.uniform1f(sStepX, 1.f / bump->getWidth()); + gNormalMapGenProgram.uniform1f(sStepY, 1.f / bump->getHeight()); + gNormalMapGenProgram.uniform1i(sBumpCode, bump_code); - gNormalMapGenProgram.unbind(); + gGL.getTexUnit(0)->bind(src); - sRenderTarget.flush(); - sRenderTarget.releaseColorAttachment(); - } + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.texCoord2f(0, 0); + gGL.vertex2f(0, 0); - // point bump at normal map and free gpu copy of dst_image - img->syncTexName(tex_name); + gGL.texCoord2f(0, 1); + gGL.vertex2f(0, 1); - // generate mipmap - gGL.getTexUnit(0)->bind(img); - glGenerateMipmap(GL_TEXTURE_2D); - gGL.getTexUnit(0)->disable(); + gGL.texCoord2f(1, 0); + gGL.vertex2f(1, 0); - bump_ptr->unref(); - img->unref(); - }; + gGL.texCoord2f(1, 1); + gGL.vertex2f(1, 1); -#if LL_BUMPLIST_MULTITHREADED - auto main_queue = LLImageGLThread::sEnabledTextures ? sMainQueue.lock() : nullptr; + gGL.end(); - if (main_queue) - { //dispatch texture upload to background thread, issue GPU commands to generate normal map on main thread - main_queue->postTo( - sTexUpdateQueue, - create_func, - generate_func); - } - else -#endif - { // immediate upload texture and generate normal map - create_func(); - generate_func(); - } + gGL.flush(); + sRenderTarget.flush(); + sRenderTarget.releaseColorAttachment(); + if (shader) + { + shader->bind(); } - - iter->second = bump; // derefs (and deletes) old image - //--------------------------------------------------- } + + // generate mipmap + gGL.getTexUnit(0)->bind(bump); + glGenerateMipmap(GL_TEXTURE_2D); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } + + iter->second = bump; // derefs (and deletes) old image + //--------------------------------------------------- + } void LLDrawPoolBump::pushBumpBatches(U32 type) diff --git a/indra/newview/lldrawpoolbump.h b/indra/newview/lldrawpoolbump.h index 65cb9af015..15976884ca 100644 --- a/indra/newview/lldrawpoolbump.h +++ b/indra/newview/lldrawpoolbump.h @@ -140,14 +140,13 @@ public: LLViewerTexture* getBrightnessDarknessImage(LLViewerFetchedTexture* src_image, U8 bump_code); void addTextureStats(U8 bump, const LLUUID& base_image_id, F32 virtual_size); - static void onSourceBrightnessLoaded( bool success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, bool final, void* userdata ); - static void onSourceDarknessLoaded( bool success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, bool final, void* userdata ); static void onSourceStandardLoaded( bool success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, bool final, void* userdata ); static void generateNormalMapFromAlpha(LLImageRaw* src, LLImageRaw* nrm_image); private: - static void onSourceLoaded( bool success, LLViewerTexture *src_vi, LLImageRaw* src, LLUUID& source_asset_id, EBumpEffect bump ); + // should be called whenever resolution of src_vi changes compared to the current entry + static void onSourceUpdated( LLViewerTexture *src_vi, EBumpEffect bump ); private: typedef std::unordered_map<LLUUID, LLPointer<LLViewerTexture> > bump_image_map_t; diff --git a/indra/newview/llfloaterchangeitemthumbnail.cpp b/indra/newview/llfloaterchangeitemthumbnail.cpp index 3e2e7cb7a3..fb31361fd9 100644 --- a/indra/newview/llfloaterchangeitemthumbnail.cpp +++ b/indra/newview/llfloaterchangeitemthumbnail.cpp @@ -951,8 +951,8 @@ void LLFloaterChangeItemThumbnail::onTexturePickerCommit() || texturep->getFullWidth() == 0) { if (texturep->isFullyLoaded() - && (texturep->getCachedRawImageLevel() == 0 || texturep->getRawImageLevel() == 0) - && (texturep->isCachedRawImageReady() || texturep->isRawImageValid())) + && (texturep->getRawImageLevel() == 0) + && (texturep->isRawImageValid())) { LLUUID task_id = mTaskId; uuid_set_t inventory_ids = mItemList; @@ -962,20 +962,10 @@ void LLFloaterChangeItemThumbnail::onTexturePickerCommit() { onUploadComplete(asset_id, task_id, inventory_ids, handle); }; - if (texturep->isRawImageValid()) - { - LLFloaterSimpleSnapshot::uploadThumbnail(texturep->getRawImage(), - *mItemList.begin(), - mTaskId, - callback); - } - else - { - LLFloaterSimpleSnapshot::uploadThumbnail(texturep->getCachedRawImage(), - *mItemList.begin(), - mTaskId, - callback); - } + LLFloaterSimpleSnapshot::uploadThumbnail(texturep->getRawImage(), + *mItemList.begin(), + mTaskId, + callback); } else { diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp index 6ab5e05b7d..0e2b3cb409 100644 --- a/indra/newview/lllocalbitmaps.cpp +++ b/indra/newview/lllocalbitmaps.cpp @@ -215,7 +215,6 @@ bool LLLocalBitmap::updateSelf(EUpdateType optional_firstupdate) ("file://"+mFilename, FTT_LOCAL_FILE, mWorldID, LL_LOCAL_USE_MIPMAPS); texture->createGLTexture(LL_LOCAL_DISCARD_LEVEL, raw_image); - texture->setCachedRawImage(LL_LOCAL_DISCARD_LEVEL, raw_image); texture->ref(); gTextureList.addImage(texture, TEX_LIST_STANDARD); diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index 1410232a0f..fd968d9027 100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -296,8 +296,6 @@ void LLNetMap::draw() gGL.color4f(1.f, 0.5f, 0.5f, 1.f); } - - // Draw using texture. gGL.getTexUnit(0)->bind(regionp->getLand().getSTexture()); gGL.begin(LLRender::QUADS); @@ -311,24 +309,6 @@ void LLNetMap::draw() gGL.vertex2f(right, top); gGL.end(); - // Draw water - gGL.flush(); - { - if (regionp->getLand().getWaterTexture()) - { - gGL.getTexUnit(0)->bind(regionp->getLand().getWaterTexture()); - gGL.begin(LLRender::QUADS); - gGL.texCoord2f(0.f, 1.f); - gGL.vertex2f(left, top); - gGL.texCoord2f(0.f, 0.f); - gGL.vertex2f(left, bottom); - gGL.texCoord2f(1.f, 0.f); - gGL.vertex2f(right, bottom); - gGL.texCoord2f(1.f, 1.f); - gGL.vertex2f(right, top); - gGL.end(); - } - } gGL.flush(); } diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp index e6bced5c92..1826885069 100644 --- a/indra/newview/llsurface.cpp +++ b/indra/newview/llsurface.cpp @@ -54,6 +54,7 @@ #include "llglheaders.h" #include "lldrawpoolterrain.h" #include "lldrawable.h" +#include "llworldmipmap.h" extern LLPipeline gPipeline; extern bool gShiftFrame; @@ -74,7 +75,6 @@ LLSurface::LLSurface(U32 type, LLViewerRegion *regionp) : mDetailTextureScale(0.f), mOriginGlobal(0.0, 0.0, 0.0), mSTexturep(NULL), - mWaterTexturep(NULL), mGridsPerPatchEdge(0), mMetersPerGrid(1.0f), mMetersPerEdge(1.0f), @@ -129,14 +129,7 @@ LLSurface::~LLSurface() { gPipeline.removePool(poolp); // Don't enable this until we blitz the draw pool for it as well. -- djs - if (mSTexturep) - { - mSTexturep = NULL; - } - if (mWaterTexturep) - { - mWaterTexturep = NULL; - } + mSTexturep = NULL; } else { @@ -216,62 +209,17 @@ LLViewerTexture* LLSurface::getSTexture() return mSTexturep; } -LLViewerTexture* LLSurface::getWaterTexture() -{ - if (mWaterTexturep.notNull() && !mWaterTexturep->hasGLTexture()) - { - createWaterTexture(); - } - return mWaterTexturep; -} - void LLSurface::createSTexture() { if (!mSTexturep) { - // Fill with dummy gray data. - // GL NOT ACTIVE HERE - LLPointer<LLImageRaw> raw = new LLImageRaw(sTextureSize, sTextureSize, 3); - U8 *default_texture = raw->getData(); - for (S32 i = 0; i < sTextureSize; i++) - { - for (S32 j = 0; j < sTextureSize; j++) - { - *(default_texture + (i*sTextureSize + j)*3) = 128; - *(default_texture + (i*sTextureSize + j)*3 + 1) = 128; - *(default_texture + (i*sTextureSize + j)*3 + 2) = 128; - } - } + U64 handle = mRegionp->getHandle(); - mSTexturep = LLViewerTextureManager::getLocalTexture(raw.get(), false); - mSTexturep->dontDiscard(); - gGL.getTexUnit(0)->bind(mSTexturep); - mSTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); - } -} + U32 grid_x, grid_y; -void LLSurface::createWaterTexture() -{ - if (!mWaterTexturep) - { - // Create the water texture - LLPointer<LLImageRaw> raw = new LLImageRaw(sTextureSize/2, sTextureSize/2, 4); - U8 *default_texture = raw->getData(); - for (S32 i = 0; i < sTextureSize/2; i++) - { - for (S32 j = 0; j < sTextureSize/2; j++) - { - *(default_texture + (i*sTextureSize/2 + j)*4) = MAX_WATER_COLOR.mV[0]; - *(default_texture + (i*sTextureSize/2 + j)*4 + 1) = MAX_WATER_COLOR.mV[1]; - *(default_texture + (i*sTextureSize/2 + j)*4 + 2) = MAX_WATER_COLOR.mV[2]; - *(default_texture + (i*sTextureSize/2 + j)*4 + 3) = MAX_WATER_COLOR.mV[3]; - } - } + grid_from_region_handle(handle, &grid_x, &grid_y); - mWaterTexturep = LLViewerTextureManager::getLocalTexture(raw.get(), false); - mWaterTexturep->dontDiscard(); - gGL.getTexUnit(0)->bind(mWaterTexturep); - mWaterTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); + mSTexturep = LLWorldMipmap::loadObjectsTile(grid_x, grid_y, 1); } } @@ -285,11 +233,10 @@ void LLSurface::initTextures() /////////////////////// // - // Water texture + // Water object // if (gSavedSettings.getBOOL("RenderWater") ) { - createWaterTexture(); mWaterObjp = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_WATER, mRegionp); gPipeline.createObject(mWaterObjp); LLVector3d water_pos_global = from_region_handle(mRegionp->getHandle()); @@ -683,11 +630,8 @@ bool LLSurface::idleUpdate(F32 max_update_time) } } - if (did_update) - { - // some patches changed, update region reflection probes - mRegionp->updateReflectionProbes(); - } + // some patches changed, update region reflection probes + mRegionp->updateReflectionProbes(did_update); return did_update; } @@ -1221,98 +1165,3 @@ F32 LLSurface::getWaterHeight() const } } - -bool LLSurface::generateWaterTexture(const F32 x, const F32 y, - const F32 width, const F32 height) -{ - LL_PROFILE_ZONE_SCOPED - if (!getWaterTexture()) - { - return false; - } - - S32 tex_width = mWaterTexturep->getWidth(); - S32 tex_height = mWaterTexturep->getHeight(); - S32 tex_comps = mWaterTexturep->getComponents(); - S32 tex_stride = tex_width * tex_comps; - LLPointer<LLImageRaw> raw = new LLImageRaw(tex_width, tex_height, tex_comps); - U8 *rawp = raw->getData(); - - F32 scale = 256.f * getMetersPerGrid() / (F32)tex_width; - F32 scale_inv = 1.f / scale; - - S32 x_begin, y_begin, x_end, y_end; - - x_begin = ll_round(x * scale_inv); - y_begin = ll_round(y * scale_inv); - x_end = ll_round((x + width) * scale_inv); - y_end = ll_round((y + width) * scale_inv); - - if (x_end > tex_width) - { - x_end = tex_width; - } - if (y_end > tex_width) - { - y_end = tex_width; - } - - // OK, for now, just have the composition value equal the height at the point. - LLVector3 location; - LLColor4U coloru; - - const F32 WATER_HEIGHT = getWaterHeight(); - - S32 i, j, offset; - for (j = y_begin; j < y_end; j++) - { - for (i = x_begin; i < x_end; i++) - { - //F32 nv[2]; - //nv[0] = i/256.f; - //nv[1] = j/256.f; - // const S32 modulation = noise2(nv)*40; - offset = j*tex_stride + i*tex_comps; - location.mV[VX] = i*scale; - location.mV[VY] = j*scale; - - // Sample multiple points - const F32 height = resolveHeightRegion(location); - - if (height > WATER_HEIGHT) - { - // Above water... - coloru = MAX_WATER_COLOR; - coloru.mV[3] = ABOVE_WATERLINE_ALPHA; - *(rawp + offset++) = coloru.mV[0]; - *(rawp + offset++) = coloru.mV[1]; - *(rawp + offset++) = coloru.mV[2]; - *(rawp + offset++) = coloru.mV[3]; - } - else - { - // Want non-linear curve for transparency gradient - coloru = MAX_WATER_COLOR; - const F32 frac = 1.f - 2.f/(2.f - (height - WATER_HEIGHT)); - S32 alpha = 64 + ll_round((255-64)*frac); - - alpha = llmin(ll_round((F32)MAX_WATER_COLOR.mV[3]), alpha); - alpha = llmax(64, alpha); - - coloru.mV[3] = alpha; - *(rawp + offset++) = coloru.mV[0]; - *(rawp + offset++) = coloru.mV[1]; - *(rawp + offset++) = coloru.mV[2]; - *(rawp + offset++) = coloru.mV[3]; - } - } - } - - if (!mWaterTexturep->hasGLTexture()) - { - mWaterTexturep->createGLTexture(0, raw); - } - - mWaterTexturep->setSubImage(raw, x_begin, y_begin, x_end - x_begin, y_end - y_begin); - return true; -} diff --git a/indra/newview/llsurface.h b/indra/newview/llsurface.h index 324296a4d3..68295225b6 100644 --- a/indra/newview/llsurface.h +++ b/indra/newview/llsurface.h @@ -128,7 +128,7 @@ public: F32 getWaterHeight() const; LLViewerTexture *getSTexture(); - LLViewerTexture *getWaterTexture(); + bool hasZData() const { return mHasZData; } void dirtyAllPatches(); // Use this to dirty all patches when changing terrain parameters @@ -171,19 +171,11 @@ public: protected: void createSTexture(); - void createWaterTexture(); void initTextures(); - void initWater(); - void createPatchData(); // Allocates memory for patches. void destroyPatchData(); // Deallocates memory for patches. - bool generateWaterTexture(const F32 x, const F32 y, - const F32 width, const F32 height); // Generate texture from composition values. - - //F32 updateTexture(LLSurfacePatch *ppatch); - LLSurfacePatch *getPatch(const S32 x, const S32 y) const; protected: @@ -201,7 +193,6 @@ protected: // The textures should never be directly initialized - use the setter methods! LLPointer<LLViewerTexture> mSTexturep; // Texture for surface - LLPointer<LLViewerTexture> mWaterTexturep; // Water texture LLPointer<LLVOWater> mWaterObjp; diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp index 042d770550..2a21170b07 100644 --- a/indra/newview/llsurfacepatch.cpp +++ b/indra/newview/llsurfacepatch.cpp @@ -906,15 +906,8 @@ void LLSurfacePatch::updateGL() updateCompositionStats(); F32 tex_patch_size = meters_per_grid*grids_per_patch_edge; - if (comp->generateMinimapTileLand((F32)origin_region[VX], (F32)origin_region[VY], - tex_patch_size, tex_patch_size)) - { - mSTexUpdate = false; - // Also generate the water texture - mSurfacep->generateWaterTexture((F32)origin_region.mdV[VX], (F32)origin_region.mdV[VY], - tex_patch_size, tex_patch_size); - } + mSTexUpdate = false; } void LLSurfacePatch::dirtyZ() diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index b51bcc5601..9d7319d5b8 100644 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -461,7 +461,7 @@ public: : texture_view("texture_view") { S32 line_height = LLFontGL::getFontMonospace()->getLineHeight(); - changeDefault(rect, LLRect(0,0,100,line_height * 4)); + changeDefault(rect, LLRect(0,0,0,line_height * 7)); } }; @@ -492,19 +492,51 @@ void LLGLTexMemBar::draw() U32 total_objects = gObjectList.getNumObjects(); F32 x_right = 0.0; + U32 image_count = gTextureList.getNumImages(); + U32 raw_image_count = 0; + U64 raw_image_bytes = 0; + + U32 saved_raw_image_count = 0; + U64 saved_raw_image_bytes = 0; + + U32 aux_raw_image_count = 0; + U64 aux_raw_image_bytes = 0; + + for (auto& image : gTextureList) + { + const LLImageRaw* raw_image = image->getRawImage(); + + if (raw_image) + { + raw_image_count++; + raw_image_bytes += raw_image->getDataSize(); + } + + raw_image = image->getSavedRawImage(); + if (raw_image) + { + saved_raw_image_count++; + saved_raw_image_bytes += raw_image->getDataSize(); + } + + raw_image = image->getAuxRawImage(); + if (raw_image) + { + aux_raw_image_count++; + aux_raw_image_bytes += raw_image->getDataSize(); + } + } + + F64 raw_image_bytes_MB = raw_image_bytes / (1024.0 * 1024.0); + F64 saved_raw_image_bytes_MB = saved_raw_image_bytes / (1024.0 * 1024.0); + F64 aux_raw_image_bytes_MB = aux_raw_image_bytes / (1024.0 * 1024.0); + //---------------------------------------------------------------------------- LLGLSUIDefault gls_ui; LLColor4 text_color(1.f, 1.f, 1.f, 0.75f); LLColor4 color; - // Gray background using completely magic numbers - gGL.color4f(0.f, 0.f, 0.f, 0.25f); - // const LLRect & rect(getRect()); - // gl_rect_2d(-4, v_offset, rect.mRight - rect.mLeft + 2, v_offset + line_height*4); - std::string text = ""; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*6, - text_color, LLFontGL::LEFT, LLFontGL::TOP); LLTrace::Recording& recording = LLViewerStats::instance().getRecording(); @@ -525,6 +557,10 @@ void LLGLTexMemBar::draw() U32 texFetchLatMed = U32(recording.getMean(LLTextureFetch::sTexFetchLatency).value() * 1000.0f); U32 texFetchLatMax = U32(recording.getMax(LLTextureFetch::sTexFetchLatency).value() * 1000.0f); + // draw a background above first line.... no idea where the rest of the background comes from for the below text + gGL.color4f(0.f, 0.f, 0.f, 0.25f); + gl_rect_2d(-10, getRect().getHeight() + line_height + 1, getRect().getWidth()+2, getRect().getHeight()+2); + text = llformat("Est. Free: %d MB Sys Free: %d MB FBO: %d MB Bias: %.2f Cache: %.1f/%.1f MB", (S32)LLViewerTexture::sFreeVRAMMegabytes, LLMemory::getAvailableMemKB()/1024, @@ -532,11 +568,15 @@ void LLGLTexMemBar::draw() discard_bias, cache_usage, cache_max_usage); - //, cache_entries, cache_max_entries - - LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*6, + LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*7, text_color, LLFontGL::LEFT, LLFontGL::TOP); + text = llformat("Images: %d Raw: %d (%.2f MB) Saved: %d (%.2f MB) Aux: %d (%.2f MB)", image_count, raw_image_count, raw_image_bytes_MB, + saved_raw_image_count, saved_raw_image_bytes_MB, + aux_raw_image_count, aux_raw_image_bytes_MB); + LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height * 6, + text_color, LLFontGL::LEFT, LLFontGL::TOP); + U32 cache_read(0U), cache_write(0U), res_wait(0U); LLAppViewer::getTextureFetch()->getStateStats(&cache_read, &cache_write, &res_wait); @@ -549,7 +589,6 @@ void LLGLTexMemBar::draw() cache_read, cache_write, res_wait); - LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*5, text_color, LLFontGL::LEFT, LLFontGL::TOP); @@ -789,7 +828,7 @@ void LLTextureView::draw() LL_INFOS() << "ID\tMEM\tBOOST\tPRI\tWIDTH\tHEIGHT\tDISCARD" << LL_ENDL; } - for (LLViewerTextureList::image_priority_list_t::iterator iter = gTextureList.mImageList.begin(); + for (LLViewerTextureList::image_list_t::iterator iter = gTextureList.mImageList.begin(); iter != gTextureList.mImageList.end(); ) { LLPointer<LLViewerFetchedTexture> imagep = *iter++; diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 23931ecf03..f62d929e9a 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -1253,41 +1253,46 @@ void LLViewerMedia::getOpenIDCookieCoro(std::string url) hostEnd = authority.size(); } - LLViewerMedia* inst = getInstance(); if (url.length()) { - LLMediaCtrl* media_instance = LLFloaterReg::getInstance("destinations")->getChild<LLMediaCtrl>("destination_guide_contents"); - if (media_instance) - { - std::string cookie_host = authority.substr(hostStart, hostEnd - hostStart); - std::string cookie_name = ""; - std::string cookie_value = ""; - std::string cookie_path = ""; - bool httponly = true; - bool secure = true; - if (inst->parseRawCookie(inst->mOpenIDCookie, cookie_name, cookie_value, cookie_path, httponly, secure) && - media_instance->getMediaPlugin()) + LLAppViewer::instance()->postToMainCoro([=]() { - // MAINT-5711 - inexplicably, the CEF setCookie function will no longer set the cookie if the - // url and domain are not the same. This used to be my.sl.com and id.sl.com respectively and worked. - // For now, we use the URL for the OpenID POST request since it will have the same authority - // as the domain field. - // (Feels like there must be a less dirty way to construct a URL from component LLURL parts) - // MAINT-6392 - Rider: Do not change, however, the original URI requested, since it is used further - // down. - std::string cefUrl(std::string(inst->mOpenIDURL.mURI) + "://" + std::string(inst->mOpenIDURL.mAuthority)); - - media_instance->getMediaPlugin()->setCookie(cefUrl, cookie_name, cookie_value, cookie_host, - cookie_path, httponly, secure); - - // Now that we have parsed the raw cookie, we must store it so that each new media instance - // can also get a copy and faciliate logging into internal SL sites. - media_instance->getMediaPlugin()->storeOpenIDCookie(cefUrl, cookie_name, cookie_value, - cookie_host, cookie_path, httponly, secure); - } - } + LLMediaCtrl* media_instance = LLFloaterReg::getInstance("destinations")->getChild<LLMediaCtrl>("destination_guide_contents"); + if (media_instance) + { + LLViewerMedia* inst = getInstance(); + std::string cookie_host = authority.substr(hostStart, hostEnd - hostStart); + std::string cookie_name = ""; + std::string cookie_value = ""; + std::string cookie_path = ""; + bool httponly = true; + bool secure = true; + if (inst->parseRawCookie(inst->mOpenIDCookie, cookie_name, cookie_value, cookie_path, httponly, secure) && + media_instance->getMediaPlugin()) + { + // MAINT-5711 - inexplicably, the CEF setCookie function will no longer set the cookie if the + // url and domain are not the same. This used to be my.sl.com and id.sl.com respectively and worked. + // For now, we use the URL for the OpenID POST request since it will have the same authority + // as the domain field. + // (Feels like there must be a less dirty way to construct a URL from component LLURL parts) + // MAINT-6392 - Rider: Do not change, however, the original URI requested, since it is used further + // down. + std::string cefUrl(std::string(inst->mOpenIDURL.mURI) + "://" + std::string(inst->mOpenIDURL.mAuthority)); + + media_instance->getMediaPlugin()->setCookie(cefUrl, cookie_name, cookie_value, cookie_host, + cookie_path, httponly, secure); + + // Now that we have parsed the raw cookie, we must store it so that each new media instance + // can also get a copy and faciliate logging into internal SL sites. + media_instance->getMediaPlugin()->storeOpenIDCookie(cefUrl, cookie_name, cookie_value, + cookie_host, cookie_path, httponly, secure); + } + } + }); } + LLViewerMedia* inst = getInstance(); + // Note: Rider: MAINT-6392 - Some viewer code requires access to the my.sl.com openid cookie for such // actions as posting snapshots to the feed. This is handled through HTTPCore rather than CEF and so // we must learn to SHARE the cookies. diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 8af0057c88..232b020d3d 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -3676,7 +3676,9 @@ bool LLViewerObject::updateLOD() bool LLViewerObject::updateGeometry(LLDrawable *drawable) { - return false; + // return true means "update complete", return false means "try again next frame" + // default should be return true + return true; } void LLViewerObject::updateGL() diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 19a1990665..39244c8246 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1269,8 +1269,12 @@ U32 LLViewerRegion::getNumOfVisibleGroups() const return mImpl ? static_cast<U32>(mImpl->mVisibleGroups.size()) : 0; } -void LLViewerRegion::updateReflectionProbes() +void LLViewerRegion::updateReflectionProbes(bool full_update) { + if (!full_update && mReflectionMaps.empty()) + { + return; + } LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; const F32 probe_spacing = 32.f; const F32 probe_radius = sqrtf((probe_spacing * 0.5f) * (probe_spacing * 0.5f) * 3.f); diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index 68247dc18e..d0ec1fe877 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -428,7 +428,7 @@ public: static bool isNewObjectCreationThrottleDisabled() {return sNewObjectCreationThrottle < 0;} // rebuild reflection probe list - void updateReflectionProbes(); + void updateReflectionProbes(bool full_update); private: void addToVOCacheTree(LLVOCacheEntry* entry); diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index c716eb4e86..b2ed86707c 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -414,8 +414,6 @@ void LLViewerTextureManager::init() } } imagep->createGLTexture(0, image_raw); - //cache the raw image - imagep->setCachedRawImage(0, image_raw); image_raw = NULL; #else LLViewerFetchedTexture::sDefaultImagep = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, true, LLGLTexture::BOOST_UI); @@ -728,9 +726,6 @@ bool LLViewerTexture::bindDefaultImage(S32 stage) } stop_glerror(); - //check if there is cached raw image and switch to it if possible - switchToCachedImage(); - LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName); if (tester) { @@ -931,18 +926,6 @@ void LLViewerTexture::reorganizeVolumeList() } } -//virtual -void LLViewerTexture::switchToCachedImage() -{ - //nothing here. -} - -//virtual -void LLViewerTexture::setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) -{ - //nothing here. -} - bool LLViewerTexture::isLargeImage() { return (S32)mTexelsPerImage > LLViewerTexture::sMinLargeImageSize; @@ -1077,10 +1060,6 @@ void LLViewerFetchedTexture::init(bool firstinit) mIsFetched = false; mInFastCacheList = false; - mCachedRawImage = NULL; - mCachedRawDiscardLevel = -1; - mCachedRawImageReady = false; - mSavedRawImage = NULL; mForceToSaveRawImage = false; mSaveRawImage = false; @@ -1138,9 +1117,6 @@ void LLViewerFetchedTexture::cleanup() // Clean up image data destroyRawImage(); - mCachedRawImage = NULL; - mCachedRawDiscardLevel = -1; - mCachedRawImageReady = false; mSavedRawImage = NULL; mSavedRawDiscardLevel = -1; } @@ -1220,13 +1196,17 @@ void LLViewerFetchedTexture::setForSculpt() { static const S32 MAX_INTERVAL = 8; //frames + forceToSaveRawImage(0, F32_MAX); + + setBoostLevel(llmax((S32)getBoostLevel(), + (S32)LLGLTexture::BOOST_SCULPTED)); + mForSculpt = true; if(isForSculptOnly() && hasGLTexture() && !getBoundRecently()) { destroyGLTexture(); //sculpt image does not need gl texture. mTextureState = ACTIVE; } - checkCachedRawSculptImage(); setMaxVirtualSizeResetInterval(MAX_INTERVAL); } @@ -1339,10 +1319,6 @@ void LLViewerFetchedTexture::addToCreateTexture() } } - //discard the cached raw image and the saved raw image - mCachedRawImageReady = false; - mCachedRawDiscardLevel = -1; - mCachedRawImage = NULL; mSavedRawDiscardLevel = -1; mSavedRawImage = NULL; } @@ -2043,13 +2019,6 @@ bool LLViewerFetchedTexture::updateFetch() LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - current < min"); make_request = false; } - else if(mCachedRawImage.notNull() // can be empty - && mCachedRawImageReady - && (current_discard < 0 || current_discard > mCachedRawDiscardLevel)) - { - make_request = false; - switchToCachedImage(); //use the cached raw data first - } if (make_request) { @@ -2543,20 +2512,6 @@ bool LLViewerFetchedTexture::doLoadedCallbacks() } // - // Do a readback if required, OR start off a texture decode - // - if (need_readback && (getMaxDiscardLevel() > gl_discard)) - { - // Do a readback to get the GL data into the raw image - // We have GL data. - - destroyRawImage(); - reloadRawImage(mLoadedCallbackDesiredDiscardLevel); - llassert(mRawImage.notNull()); - llassert(!mNeedsAux || mAuxRawImage.notNull()); - } - - // // Run raw/auxiliary data callbacks // if (run_raw_callbacks && mIsRawImageValid && (mRawDiscardLevel <= getMaxDiscardLevel())) @@ -2663,61 +2618,6 @@ void LLViewerFetchedTexture::forceImmediateUpdate() return; } -LLImageRaw* LLViewerFetchedTexture::reloadRawImage(S8 discard_level) -{ - llassert(mGLTexturep.notNull()); - llassert(discard_level >= 0); - llassert(mComponents > 0); - - if (mRawImage.notNull()) - { - //mRawImage is in use by somebody else, do not delete it. - return NULL; - } - - if(mSavedRawDiscardLevel >= 0 && mSavedRawDiscardLevel <= discard_level) - { - if (mSavedRawDiscardLevel != discard_level - && mBoostLevel != BOOST_ICON - && mBoostLevel != BOOST_THUMBNAIL) - { - mRawImage = new LLImageRaw(getWidth(discard_level), getHeight(discard_level), getComponents()); - mRawImage->copy(getSavedRawImage()); - } - else - { - mRawImage = getSavedRawImage(); - } - mRawDiscardLevel = discard_level; - } - else - { - //force to fetch raw image again if cached raw image is not good enough. - if(mCachedRawDiscardLevel > discard_level) - { - mRawImage = mCachedRawImage; - mRawDiscardLevel = mCachedRawDiscardLevel; - } - else //cached raw image is good enough, copy it. - { - if(mCachedRawDiscardLevel != discard_level) - { - mRawImage = new LLImageRaw(getWidth(discard_level), getHeight(discard_level), getComponents()); - mRawImage->copy(mCachedRawImage); - } - else - { - mRawImage = mCachedRawImage; - } - mRawDiscardLevel = discard_level; - } - } - mIsRawImageValid = true; - sRawCount++; - - return mRawImage; -} - bool LLViewerFetchedTexture::needsToSaveRawImage() { return mForceToSaveRawImage || mSaveRawImage; @@ -2742,7 +2642,6 @@ void LLViewerFetchedTexture::destroyRawImage() { saveRawImage(); } - setCachedRawImage(); } mRawImage = NULL; @@ -2752,151 +2651,6 @@ void LLViewerFetchedTexture::destroyRawImage() } } -//use the mCachedRawImage to (re)generate the gl texture. -//virtual -void LLViewerFetchedTexture::switchToCachedImage() -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - if(mCachedRawImage.notNull() && - !mNeedsCreateTexture) // <--- texture creation is pending, don't step on it - { - mRawImage = mCachedRawImage; - - if (getComponents() != mRawImage->getComponents()) - { - // We've changed the number of components, so we need to move any - // objects using this pool to a different pool. - mComponents = mRawImage->getComponents(); - mGLTexturep->setComponents(mComponents); - gTextureList.dirtyImage(this); - } - - mIsRawImageValid = true; - mRawDiscardLevel = mCachedRawDiscardLevel; - - scheduleCreateTexture(); - } -} - -//cache the imageraw forcefully. -//virtual -void LLViewerFetchedTexture::setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) -{ - if(imageraw != mRawImage.get()) - { - if (mBoostLevel == LLGLTexture::BOOST_ICON) - { - S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_ICON_DIMENSIONS; - S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_ICON_DIMENSIONS; - if (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height) - { - mCachedRawImage = new LLImageRaw(expected_width, expected_height, imageraw->getComponents()); - mCachedRawImage->copyScaled(imageraw); - } - else - { - mCachedRawImage = imageraw; - } - } - else if (mBoostLevel == LLGLTexture::BOOST_THUMBNAIL) - { - S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_THUMBNAIL_DIMENSIONS; - S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_THUMBNAIL_DIMENSIONS; - if (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height) - { - mCachedRawImage = new LLImageRaw(expected_width, expected_height, imageraw->getComponents()); - mCachedRawImage->copyScaled(imageraw); - } - else - { - mCachedRawImage = imageraw; - } - } - else - { - mCachedRawImage = imageraw; - } - mCachedRawDiscardLevel = discard_level; - mCachedRawImageReady = true; - } -} - -void LLViewerFetchedTexture::setCachedRawImage() -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - if(mRawImage == mCachedRawImage) - { - return; - } - if(!mIsRawImageValid) - { - return; - } - - if(mCachedRawImageReady) - { - return; - } - - if(mCachedRawDiscardLevel < 0 || mCachedRawDiscardLevel > mRawDiscardLevel) - { - S32 i = 0; - S32 w = mRawImage->getWidth(); - S32 h = mRawImage->getHeight(); - - S32 max_size = MAX_CACHED_RAW_IMAGE_AREA; - if(LLGLTexture::BOOST_TERRAIN == mBoostLevel) - { - max_size = MAX_CACHED_RAW_TERRAIN_IMAGE_AREA; - } - if(mForSculpt) - { - max_size = MAX_CACHED_RAW_SCULPT_IMAGE_AREA; - mCachedRawImageReady = !mRawDiscardLevel; - } - else - { - mCachedRawImageReady = (!mRawDiscardLevel || ((w * h) >= max_size)); - } - - while(((w >> i) * (h >> i)) > max_size) - { - ++i; - } - - if(i) - { - if(!(w >> i) || !(h >> i)) - { - --i; - } - - { - //make a duplicate in case somebody else is using this raw image - mRawImage = mRawImage->scaled(w >> i, h >> i); - } - } - mCachedRawImage = mRawImage; - mRawDiscardLevel += i; - mCachedRawDiscardLevel = mRawDiscardLevel; - } -} - -void LLViewerFetchedTexture::checkCachedRawSculptImage() -{ - if(mCachedRawImageReady && mCachedRawDiscardLevel > 0) - { - if(getDiscardLevel() != 0) - { - mCachedRawImageReady = false; - } - else if(isForSculptOnly()) - { - resetTextureStats(); //do not update this image any more. - } - } -} - void LLViewerFetchedTexture::saveRawImage() { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; @@ -2936,6 +2690,20 @@ void LLViewerFetchedTexture::saveRawImage() mSavedRawImage = new LLImageRaw(mRawImage->getData(), mRawImage->getWidth(), mRawImage->getHeight(), mRawImage->getComponents()); } } + else if (mBoostLevel == LLGLTexture::BOOST_SCULPTED) + { + S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : sMaxSculptRez; + S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : sMaxSculptRez; + if (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height) + { + mSavedRawImage = new LLImageRaw(expected_width, expected_height, mRawImage->getComponents()); + mSavedRawImage->copyScaled(mRawImage); + } + else + { + mSavedRawImage = new LLImageRaw(mRawImage->getData(), mRawImage->getWidth(), mRawImage->getHeight(), mRawImage->getComponents()); + } + } else { mSavedRawImage = new LLImageRaw(mRawImage->getData(), mRawImage->getWidth(), mRawImage->getHeight(), mRawImage->getComponents()); @@ -2981,20 +2749,23 @@ void LLViewerFetchedTexture::forceToSaveRawImage(S32 desired_discard, F32 kept_t { mForceToSaveRawImage = true; mDesiredSavedRawDiscardLevel = desired_discard; + } +} - //copy from the cached raw image if exists. - if(mCachedRawImage.notNull() && mRawImage.isNull() ) - { - mRawImage = mCachedRawImage; - mRawDiscardLevel = mCachedRawDiscardLevel; - - saveRawImage(); +void LLViewerFetchedTexture::readbackRawImage() +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - mRawImage = NULL; - mRawDiscardLevel = INVALID_DISCARD_LEVEL; + if (mGLTexturep.notNull() && mGLTexturep->getTexName() != 0 && mRawImage.isNull()) + { + mRawImage = new LLImageRaw(); + if (!mGLTexturep->readBackRaw(-1, mRawImage, false)) + { + mRawImage = nullptr; } } } + void LLViewerFetchedTexture::destroySavedRawImage() { if(mLastReferencedSavedRawImageTime < mKeptSavedRawImageTime) @@ -3029,6 +2800,11 @@ LLImageRaw* LLViewerFetchedTexture::getSavedRawImage() return mSavedRawImage; } +const LLImageRaw* LLViewerFetchedTexture::getSavedRawImage() const +{ + return mSavedRawImage; +} + bool LLViewerFetchedTexture::hasSavedRawImage() const { return mSavedRawImage.notNull(); @@ -3205,20 +2981,14 @@ void LLViewerLODTexture::processTextureStats() bool LLViewerLODTexture::scaleDown() { - if(hasGLTexture() && mCachedRawDiscardLevel > getDiscardLevel()) + if (mGLTexturep.isNull()) { - switchToCachedImage(); - - LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName); - if (tester) - { - tester->setStablizingTime(); - } - - return true; + return false; } - return false; + + return mGLTexturep->scaleDown(mDesiredDiscardLevel); } + //---------------------------------------------------------------------------------------------- //end of LLViewerLODTexture //---------------------------------------------------------------------------------------------- diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index 9963626ada..b1e0494a30 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -166,8 +166,6 @@ public: S32 getNumVolumes(U32 channel) const; const ll_volume_list_t* getVolumeList(U32 channel) const { return &mVolumeList[channel]; } - - virtual void setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) ; bool isLargeImage() ; void setParcelMedia(LLViewerMediaTexture* media) {mParcelMedia = media;} @@ -185,8 +183,6 @@ private: friend class LLBumpImageList; friend class LLUIImageList; - virtual void switchToCachedImage(); - protected: friend class LLViewerTextureList; LLUUID mID; @@ -371,7 +367,6 @@ public: U32 getFetchPriority() const { return mFetchPriority ;} F32 getDownloadProgress() const {return mDownloadProgress ;} - LLImageRaw* reloadRawImage(S8 discard_level) ; void destroyRawImage(); bool needsToSaveRawImage(); @@ -390,17 +385,20 @@ public: bool isForSculptOnly() const; //raw image management - void checkCachedRawSculptImage() ; LLImageRaw* getRawImage()const { return mRawImage ;} S32 getRawImageLevel() const {return mRawDiscardLevel;} - LLImageRaw* getCachedRawImage() const { return mCachedRawImage ;} - S32 getCachedRawImageLevel() const {return mCachedRawDiscardLevel;} - bool isCachedRawImageReady() const {return mCachedRawImageReady ;} bool isRawImageValid()const { return mIsRawImageValid ; } void forceToSaveRawImage(S32 desired_discard = 0, F32 kept_time = 0.f) ; - /*virtual*/ void setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) override; + + // readback the raw image from OpenGL if mRawImage is not valid + void readbackRawImage(); + void destroySavedRawImage() ; LLImageRaw* getSavedRawImage() ; + S32 getSavedRawImageLevel() const {return mSavedRawDiscardLevel; } + + const LLImageRaw* getSavedRawImage() const; + const LLImageRaw* getAuxRawImage() const { return mAuxRawImage; } bool hasSavedRawImage() const ; F32 getElapsedLastReferencedSavedRawImageTime() const ; bool isFullyLoaded() const; @@ -417,7 +415,6 @@ public: /*virtual*/bool isActiveFetching() override; //is actively in fetching by the fetching pipeline. protected: - /*virtual*/ void switchToCachedImage() override; S32 getCurrentDiscardLevelForFetching() ; void forceToRefetchTexture(S32 desired_discard = 0, F32 kept_time = 60.f); @@ -426,7 +423,6 @@ private: void cleanup() ; void saveRawImage() ; - void setCachedRawImage() ; //for atlas void resetFaceAtlas() ; @@ -498,11 +494,6 @@ protected: F32 mLastReferencedSavedRawImageTime ; F32 mKeptSavedRawImageTime ; - //a small version of the copy of the raw image (<= 64 * 64) - LLPointer<LLImageRaw> mCachedRawImage; - S32 mCachedRawDiscardLevel; - bool mCachedRawImageReady; //the rez of the mCachedRawImage reaches the upper limit. - LLHost mTargetHost; // if invalid, just request from agent's simulator // Timers diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index b90c1868fc..4d8fd8ddd5 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -296,7 +296,7 @@ void LLViewerTextureList::shutdown() // Write out list of currently loaded textures for precaching on startup typedef std::set<std::pair<S32,LLViewerFetchedTexture*> > image_area_list_t; image_area_list_t image_area_list; - for (image_priority_list_t::iterator iter = mImageList.begin(); + for (image_list_t::iterator iter = mImageList.begin(); iter != mImageList.end(); ++iter) { LLViewerFetchedTexture* image = *iter; @@ -367,7 +367,7 @@ void LLViewerTextureList::dump() { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; LL_INFOS() << "LLViewerTextureList::dump()" << LL_ENDL; - for (image_priority_list_t::iterator it = mImageList.begin(); it != mImageList.end(); ++it) + for (image_list_t::iterator it = mImageList.begin(); it != mImageList.end(); ++it) { LLViewerFetchedTexture* image = *it; @@ -381,15 +381,9 @@ void LLViewerTextureList::dump() } } -void LLViewerTextureList::destroyGL(bool save_state) +void LLViewerTextureList::destroyGL() { - LLImageGL::destroyGL(save_state); -} - -void LLViewerTextureList::restoreGL() -{ - llassert_always(mInitialized) ; - LLImageGL::restoreGL(); + LLImageGL::destroyGL(); } /* Vertical tab container button image IDs @@ -895,7 +889,7 @@ void LLViewerTextureList::clearFetchingRequests() LLAppViewer::getTextureFetch()->deleteAllRequests(); - for (image_priority_list_t::iterator iter = mImageList.begin(); + for (image_list_t::iterator iter = mImageList.begin(); iter != mImageList.end(); ++iter) { LLViewerFetchedTexture* imagep = *iter; @@ -1208,7 +1202,7 @@ void LLViewerTextureList::updateImagesUpdateStats() LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; if (mForceResetTextureStats) { - for (image_priority_list_t::iterator iter = mImageList.begin(); + for (image_list_t::iterator iter = mImageList.begin(); iter != mImageList.end(); ) { LLViewerFetchedTexture* imagep = *iter++; @@ -1228,7 +1222,7 @@ void LLViewerTextureList::decodeAllImages(F32 max_time) // Update texture stats and priorities std::vector<LLPointer<LLViewerFetchedTexture> > image_list; - for (image_priority_list_t::iterator iter = mImageList.begin(); + for (image_list_t::iterator iter = mImageList.begin(); iter != mImageList.end(); ) { LLViewerFetchedTexture* imagep = *iter++; @@ -1248,7 +1242,7 @@ void LLViewerTextureList::decodeAllImages(F32 max_time) image_list.clear(); // Update fetch (decode) - for (image_priority_list_t::iterator iter = mImageList.begin(); + for (image_list_t::iterator iter = mImageList.begin(); iter != mImageList.end(); ) { LLViewerFetchedTexture* imagep = *iter++; @@ -1275,7 +1269,7 @@ void LLViewerTextureList::decodeAllImages(F32 max_time) } } // Update fetch again - for (image_priority_list_t::iterator iter = mImageList.begin(); + for (image_list_t::iterator iter = mImageList.begin(); iter != mImageList.end(); ) { LLViewerFetchedTexture* imagep = *iter++; diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h index e4ebb7b0e8..2779ad9f91 100644 --- a/indra/newview/llviewertexturelist.h +++ b/indra/newview/llviewertexturelist.h @@ -33,7 +33,7 @@ #include "llviewertexture.h" #include "llui.h" #include <list> -#include <set> +#include <unordered_set> #include "lluiimage.h" const U32 LL_IMAGE_REZ_LOSSLESS_CUTOFF = 128; @@ -115,8 +115,7 @@ public: void init(); void shutdown(); void dump(); - void destroyGL(bool save_state = true); - void restoreGL(); + void destroyGL(); bool isInitialized() const {return mInitialized;} void findTexturesByID(const LLUUID &image_id, std::vector<LLViewerFetchedTexture*> &output); @@ -188,7 +187,7 @@ private: LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE, // Get the requested level immediately upon creation. S8 texture_type = LLViewerTexture::FETCHED_TEXTURE, LLGLint internal_format = 0, - LLGLenum primary_format = 0, + LLGLenum primary_format = 0, const LLUUID& force_id = LLUUID::null ); @@ -211,7 +210,7 @@ private: { return getImage(image_id, f_type, true, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, host); } public: - typedef std::set<LLPointer<LLViewerFetchedTexture> > image_list_t; + typedef std::unordered_set<LLPointer<LLViewerFetchedTexture> > image_list_t; image_list_t mLoadingStreamList; image_list_t mCreateTextureList; image_list_t mCallbackList; @@ -222,16 +221,19 @@ public: bool mForceResetTextureStats; + // to make "for (auto& imagep : gTextureList)" work + const image_list_t::iterator begin() const { return mImageList.begin(); } + const image_list_t::iterator end() const { return mImageList.end(); } + private: typedef std::map< LLTextureKey, LLPointer<LLViewerFetchedTexture> > uuid_map_t; uuid_map_t mUUIDMap; LLTextureKey mLastUpdateKey; - typedef std::set < LLPointer<LLViewerFetchedTexture> > image_priority_list_t; - image_priority_list_t mImageList; + image_list_t mImageList; // simply holds on to LLViewerFetchedTexture references to stop them from being purged too soon - std::set<LLPointer<LLViewerFetchedTexture> > mImagePreloads; + std::unordered_set<LLPointer<LLViewerFetchedTexture> > mImagePreloads; bool mInitialized ; LLFrameTimer mForceDecodeTimer; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index cfa12bf178..ef85d57416 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1827,10 +1827,8 @@ LLViewerWindow::LLViewerWindow(const Params& p) mToolStored( NULL ), mHideCursorPermanent( false ), mCursorHidden(false), - mIgnoreActivate( false ), mResDirty(false), mStatesDirty(false), - mCurrResolutionIndex(0), mProgressView(NULL) { // gKeyboard is still NULL, so it doesn't do LLWindowListener any good to @@ -2402,7 +2400,7 @@ void LLViewerWindow::shutdownGL() LLSelectMgr::getInstance()->cleanup(); LL_INFOS() << "Stopping GL during shutdown" << LL_ENDL; - stopGL(false); + stopGL(); stop_glerror(); gGL.shutdown(); @@ -5715,7 +5713,7 @@ void LLViewerWindow::dumpState() << LL_ENDL; } -void LLViewerWindow::stopGL(bool save_state) +void LLViewerWindow::stopGL() { //Note: --bao //if not necessary, do not change the order of the function calls in this function. @@ -5761,7 +5759,7 @@ void LLViewerWindow::stopGL(bool save_state) gPostProcess->invalidate(); } - gTextureList.destroyGL(save_state); + gTextureList.destroyGL(); stop_glerror(); gGLManager.mIsDisabled = true; @@ -5778,6 +5776,14 @@ void LLViewerWindow::stopGL(bool save_state) void LLViewerWindow::restoreGL(const std::string& progress_message) { + llassert(false); + // DEPRECATED -- this is left over from when we would completely destroy and restore a GL context + // when switching from windowed to fullscreen. None of this machinery has been exercised in years + // and is unreliable. If we ever *do* have another use case where completely unloading and reloading + // everthing is necessary, requiring a viewer restart for that operation is a fine thing to do. + // -- davep + + //Note: --bao //if not necessary, do not change the order of the function calls in this function. //if change something, make sure it will not break anything. @@ -5790,8 +5796,6 @@ void LLViewerWindow::restoreGL(const std::string& progress_message) initGLDefaults(); LLGLState::restoreGL(); - gTextureList.restoreGL(); - // for future support of non-square pixels, and fonts that are properly stretched //LLFontGL::destroyDefaultFonts(); initFonts(); @@ -5867,122 +5871,6 @@ void LLViewerWindow::checkSettings() } } -void LLViewerWindow::restartDisplay(bool show_progress_bar) -{ - LL_INFOS() << "Restaring GL" << LL_ENDL; - stopGL(); - if (show_progress_bar) - { - restoreGL(LLTrans::getString("ProgressChangingResolution")); - } - else - { - restoreGL(); - } -} - -bool LLViewerWindow::changeDisplaySettings(LLCoordScreen size, bool enable_vsync, bool show_progress_bar) -{ - //bool was_maximized = gSavedSettings.getBOOL("WindowMaximized"); - - //gResizeScreenTexture = true; - - - //U32 fsaa = gSavedSettings.getU32("RenderFSAASamples"); - //U32 old_fsaa = mWindow->getFSAASamples(); - - // if not maximized, use the request size - if (!mWindow->getMaximized()) - { - mWindow->setSize(size); - } - - //if (fsaa == old_fsaa) - { - return true; - } - -/* - - // Close floaters that don't handle settings change - LLFloaterReg::hideInstance("snapshot"); - - bool result_first_try = false; - bool result_second_try = false; - - LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus(); - send_agent_pause(); - LL_INFOS() << "Stopping GL during changeDisplaySettings" << LL_ENDL; - stopGL(); - mIgnoreActivate = true; - LLCoordScreen old_size; - LLCoordScreen old_pos; - mWindow->getSize(&old_size); - - //mWindow->setFSAASamples(fsaa); - - result_first_try = mWindow->switchContext(false, size, disable_vsync); - if (!result_first_try) - { - // try to switch back - //mWindow->setFSAASamples(old_fsaa); - result_second_try = mWindow->switchContext(false, old_size, disable_vsync); - - if (!result_second_try) - { - // we are stuck...try once again with a minimal resolution? - send_agent_resume(); - mIgnoreActivate = false; - return false; - } - } - send_agent_resume(); - - LL_INFOS() << "Restoring GL during resolution change" << LL_ENDL; - if (show_progress_bar) - { - restoreGL(LLTrans::getString("ProgressChangingResolution")); - } - else - { - restoreGL(); - } - - if (!result_first_try) - { - LLSD args; - args["RESX"] = llformat("%d",size.mX); - args["RESY"] = llformat("%d",size.mY); - LLNotificationsUtil::add("ResolutionSwitchFail", args); - size = old_size; // for reshape below - } - - bool success = result_first_try || result_second_try; - - if (success) - { - // maximize window if was maximized, else reposition - if (was_maximized) - { - mWindow->maximize(); - } - else - { - S32 windowX = gSavedSettings.getS32("WindowX"); - S32 windowY = gSavedSettings.getS32("WindowY"); - - mWindow->setPosition(LLCoordScreen ( windowX, windowY ) ); - } - } - - mIgnoreActivate = false; - gFocusMgr.setKeyboardFocus(keyboard_focus); - - return success; - - */ -} - F32 LLViewerWindow::getWorldViewAspectRatio() const { F32 world_aspect = (F32)mWorldViewRectRaw.getWidth() / (F32)mWorldViewRectRaw.getHeight(); diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index 4a6b901b33..ba59ce4141 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -455,9 +455,7 @@ public: // handle shutting down GL and bringing it back up void requestResolutionUpdate(); void checkSettings(); - void restartDisplay(bool show_progress_bar); - bool changeDisplaySettings(LLCoordScreen size, bool enable_vsync, bool show_progress_bar); - bool getIgnoreDestroyWindow() { return mIgnoreActivate; } + F32 getWorldViewAspectRatio() const; const LLVector2& getDisplayScale() const { return mDisplayScale; } void calcDisplayScale(); @@ -471,7 +469,7 @@ private: void switchToolByMask(MASK mask); void destroyWindow(); void drawMouselookInstructions(); - void stopGL(bool save_state = true); + void stopGL(); void restoreGL(const std::string& progress_message = LLStringUtil::null); void initFonts(F32 zoom_factor = 1.f); void schedulePick(LLPickInfo& pick_info); @@ -528,8 +526,6 @@ private: std::string mOverlayTitle; // Used for special titles such as "Second Life - Special E3 2003 Beta" - bool mIgnoreActivate; - std::string mInitAlert; // Window / GL initialization requires an alert LLHandle<LLView> mWorldViewPlaceholder; // widget that spans the portion of screen dedicated to rendering the 3d world @@ -542,7 +538,6 @@ private: bool mResDirty; bool mStatesDirty; - U32 mCurrResolutionIndex; std::unique_ptr<LLWindowListener> mWindowListener; std::unique_ptr<LLViewerWindowListener> mViewerWindowListener; diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index ba255f2b24..f5f058a080 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -317,7 +317,7 @@ bool LLTerrainMaterials::makeMaterialsReady(bool boost, bool strict) // static bool LLTerrainMaterials::makeTextureReady(LLPointer<LLViewerFetchedTexture>& tex, bool boost) { - llassert(tex); + //llassert(tex); ??? maybe ok ??? if (!tex) { return false; } if (tex->getDiscardLevel() < 0) @@ -571,416 +571,6 @@ bool LLVLComposition::generateComposition() return LLTerrainMaterials::generateMaterials(); } -namespace -{ - void prepare_fallback_image(LLImageRaw* raw_image) - { - raw_image->resize(BASE_SIZE, BASE_SIZE, 4); - raw_image->fill(LLColor4U::white); - } - - // Check if the raw image is loaded for this texture at a discard - // level the minimap can use, and if not then try to get it loaded. - bool prepare_raw_image(LLPointer<LLImageRaw>& raw_image, bool emissive, LLViewerFetchedTexture* tex, bool& delete_raw_post) - { - if (!tex) - { - if (!emissive) - { - prepare_fallback_image(raw_image); - } - else - { - llassert(!raw_image); - raw_image = nullptr; - } - return true; - } - if (raw_image) - { - // Callback already initiated - if (raw_image->getDataSize() > 0) - { - // Callback finished - delete_raw_post = true; - return true; - } - else - { - return false; - } - } - - raw_image = new LLImageRaw(); - - S32 ddiscard = 0; - { - S32 min_dim = llmin(tex->getFullWidth(), tex->getFullHeight()); - while (min_dim > BASE_SIZE && ddiscard < MAX_DISCARD_LEVEL) - { - ddiscard++; - min_dim /= 2; - } - } - - struct PendingImage - { - LLImageRaw* mRawImage; - S32 mDesiredDiscard; - LLUUID mTextureId; - PendingImage(LLImageRaw* raw_image, S32 ddiscard, const LLUUID& texture_id) - : mRawImage(raw_image) - , mDesiredDiscard(ddiscard) - , mTextureId(texture_id) - { - mRawImage->ref(); - } - ~PendingImage() - { - mRawImage->unref(); - } - }; - PendingImage* pending_image = new PendingImage(raw_image, ddiscard, tex->getID()); - - loaded_callback_func cb = [](bool success, LLViewerFetchedTexture * src_vi, LLImageRaw * src, LLImageRaw * src_aux, S32 discard_level, bool is_final, void* userdata) { - PendingImage* pending = (PendingImage*)userdata; - // Owning LLVLComposition still exists - - // Assume mRawImage only used by single LLVLComposition for now - const bool in_use_by_composition = pending->mRawImage->getNumRefs() > 1; - llassert(pending->mRawImage->getNumRefs()); - llassert(pending->mRawImage->getNumRefs() <= 2); - const bool needs_data = !pending->mRawImage->getDataSize(); - if (in_use_by_composition && needs_data) - { - if (success && pending->mDesiredDiscard == discard_level) - { - pending->mRawImage->resize(BASE_SIZE, BASE_SIZE, src->getComponents()); - pending->mRawImage->copyScaled(src); - } - else if (is_final) - { - prepare_fallback_image(pending->mRawImage); - } - } - - if (is_final) { delete pending; } - }; - tex->setLoadedCallback(cb, ddiscard, true, false, pending_image, nullptr); - tex->forceToSaveRawImage(ddiscard); - - return false; - } -}; - -bool LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, - const F32 width, const F32 height) -{ - LL_PROFILE_ZONE_SCOPED - llassert(mSurfacep); - llassert(x >= 0.f); - llassert(y >= 0.f); - - /////////////////////////// - // - // Generate raw data arrays for surface textures - // - // - - // These have already been validated by generateComposition. - U8* st_data[ASSET_COUNT]; - S32 st_data_size[ASSET_COUNT]; // for debugging - - const bool use_textures = getMaterialType() != LLTerrainMaterials::Type::PBR; - if (use_textures) - { - if (!makeTexturesReady(true, true)) { return false; } - } - else - { - if (!makeMaterialsReady(true, true)) { return false; } - } - - for (S32 i = 0; i < ASSET_COUNT; i++) - { - if (mRawImages[i].isNull()) - { - // Read back a raw image for this discard level, if it exists - LLViewerFetchedTexture* tex; - LLViewerFetchedTexture* tex_emissive; // Can be null - bool has_base_color_factor; - bool has_emissive_factor; - bool has_alpha; - LLColor3 base_color_factor; - LLColor3 emissive_factor; - if (use_textures) - { - tex = mDetailTextures[i]; - tex_emissive = nullptr; - has_base_color_factor = false; - has_emissive_factor = false; - has_alpha = false; - llassert(tex); - } - else - { - LLPointer<LLFetchedGLTFMaterial>& mat = mDetailRenderMaterials[i]; - tex = mat->mBaseColorTexture; - tex_emissive = mat->mEmissiveTexture; - base_color_factor = LLColor3(mat->mBaseColor); - // *HACK: Treat alpha as black - base_color_factor *= (mat->mBaseColor.mV[VW]); - emissive_factor = mat->mEmissiveColor; - has_base_color_factor = (base_color_factor.mV[VX] != 1.f || - base_color_factor.mV[VY] != 1.f || - base_color_factor.mV[VZ] != 1.f); - has_emissive_factor = (emissive_factor.mV[VX] != 1.f || - emissive_factor.mV[VY] != 1.f || - emissive_factor.mV[VZ] != 1.f); - has_alpha = mat->mAlphaMode != LLGLTFMaterial::ALPHA_MODE_OPAQUE; - } - - if (!tex) { tex = LLViewerFetchedTexture::sWhiteImagep; } - - bool delete_raw_post = false; - bool delete_raw_post_emissive = false; - if (!prepare_raw_image(mRawImagesBaseColor[i], false, tex, delete_raw_post)) { return false; } - if (tex_emissive && !prepare_raw_image(mRawImagesEmissive[i], true, tex_emissive, delete_raw_post_emissive)) { return false; } - // tex_emissive can be null, and then will be ignored - - // In the simplest case, the minimap image is just the base color. - // This will be replaced if we need to do any tinting/compositing. - mRawImages[i] = mRawImagesBaseColor[i]; - - // *TODO: This isn't quite right for PBR: - // 1) It does not convert the color images from SRGB to linear - // before mixing (which will always require copying the image). - // 2) It mixes emissive and base color before mixing terrain - // materials, but it should be the other way around - // Long-term, we should consider a method that is more - // maintainable. Shaders, perhaps? Bake shaders to textures? - LLPointer<LLImageRaw> raw_emissive; - if (tex_emissive) - { - raw_emissive = mRawImagesEmissive[i]; - if (has_emissive_factor || - tex_emissive->getWidth(tex_emissive->getRawImageLevel()) != BASE_SIZE || - tex_emissive->getHeight(tex_emissive->getRawImageLevel()) != BASE_SIZE || - tex_emissive->getComponents() != 4) - { - LLPointer<LLImageRaw> newraw_emissive = new LLImageRaw(BASE_SIZE, BASE_SIZE, 4); - // Copy RGB, leave alpha alone (set to opaque by default) - newraw_emissive->copy(mRawImagesEmissive[i]); - if (has_emissive_factor) - { - newraw_emissive->tint(emissive_factor); - } - raw_emissive = newraw_emissive; - } - } - if (has_base_color_factor || - raw_emissive || - has_alpha || - tex->getWidth(tex->getRawImageLevel()) != BASE_SIZE || - tex->getHeight(tex->getRawImageLevel()) != BASE_SIZE || - tex->getComponents() != 3) - { - LLPointer<LLImageRaw> newraw = new LLImageRaw(BASE_SIZE, BASE_SIZE, 3); - if (has_alpha) - { - // Approximate the water underneath terrain alpha with solid water color - newraw->clear( - MAX_WATER_COLOR.mV[VX], - MAX_WATER_COLOR.mV[VY], - MAX_WATER_COLOR.mV[VZ], - 255); - } - newraw->composite(mRawImagesBaseColor[i]); - if (has_base_color_factor) - { - newraw->tint(base_color_factor); - } - // Apply emissive texture - if (raw_emissive) - { - newraw->addEmissive(raw_emissive); - } - - mRawImages[i] = newraw; // deletes old - } - - if (delete_raw_post) - { - tex->destroyRawImage(); - } - if (delete_raw_post_emissive) - { - tex_emissive->destroyRawImage(); - } - - // Remove intermediary image references - mRawImagesBaseColor[i] = nullptr; - mRawImagesEmissive[i] = nullptr; - } - st_data[i] = mRawImages[i]->getData(); - st_data_size[i] = mRawImages[i]->getDataSize(); - } - - /////////////////////////////////////// - // - // Generate and clamp x/y bounding box. - // - // - - S32 x_begin, y_begin, x_end, y_end; - x_begin = (S32)(x * mScaleInv); - y_begin = (S32)(y * mScaleInv); - x_end = ll_round( (x + width) * mScaleInv ); - y_end = ll_round( (y + width) * mScaleInv ); - - if (x_end > mWidth) - { - llassert(false); - x_end = mWidth; - } - if (y_end > mWidth) - { - llassert(false); - y_end = mWidth; - } - - - /////////////////////////////////////////// - // - // Generate target texture information, stride ratios. - // - // - - LLViewerTexture *texturep; - U32 tex_width, tex_height, tex_comps; - U32 tex_stride; - F32 tex_x_scalef, tex_y_scalef; - S32 tex_x_begin, tex_y_begin, tex_x_end, tex_y_end; - F32 tex_x_ratiof, tex_y_ratiof; - - texturep = mSurfacep->getSTexture(); - tex_width = texturep->getWidth(); - tex_height = texturep->getHeight(); - tex_comps = texturep->getComponents(); - tex_stride = tex_width * tex_comps; - - U32 st_comps = 3; - U32 st_width = BASE_SIZE; - U32 st_height = BASE_SIZE; - - if (tex_comps != st_comps) - { - llassert(false); - return false; - } - - tex_x_scalef = (F32)tex_width / (F32)mWidth; - tex_y_scalef = (F32)tex_height / (F32)mWidth; - tex_x_begin = (S32)((F32)x_begin * tex_x_scalef); - tex_y_begin = (S32)((F32)y_begin * tex_y_scalef); - tex_x_end = (S32)((F32)x_end * tex_x_scalef); - tex_y_end = (S32)((F32)y_end * tex_y_scalef); - - tex_x_ratiof = (F32)mWidth*mScale / (F32)tex_width; - tex_y_ratiof = (F32)mWidth*mScale / (F32)tex_height; - - LLPointer<LLImageRaw> raw = new LLImageRaw(tex_width, tex_height, tex_comps); - U8 *rawp = raw->getData(); - - F32 st_x_stride, st_y_stride; - st_x_stride = ((F32)st_width / (F32)mTexScaleX)*((F32)mWidth / (F32)tex_width); - st_y_stride = ((F32)st_height / (F32)mTexScaleY)*((F32)mWidth / (F32)tex_height); - - llassert(st_x_stride > 0.f); - llassert(st_y_stride > 0.f); - //////////////////////////////// - // - // Iterate through the target texture, striding through the - // subtextures and interpolating appropriately. - // - // - - F32 sti, stj; - S32 st_offset; - sti = (tex_x_begin * st_x_stride) - st_width*(llfloor((tex_x_begin * st_x_stride)/st_width)); - stj = (tex_y_begin * st_y_stride) - st_height*(llfloor((tex_y_begin * st_y_stride)/st_height)); - - st_offset = (llfloor(stj * st_width) + llfloor(sti)) * st_comps; - for (S32 j = tex_y_begin; j < tex_y_end; j++) - { - U32 offset = j * tex_stride + tex_x_begin * tex_comps; - sti = (tex_x_begin * st_x_stride) - st_width*((U32)(tex_x_begin * st_x_stride)/st_width); - for (S32 i = tex_x_begin; i < tex_x_end; i++) - { - S32 tex0, tex1; - F32 composition = getValueScaled(i*tex_x_ratiof, j*tex_y_ratiof); - - tex0 = llfloor( composition ); - tex0 = llclamp(tex0, 0, 3); - composition -= tex0; - tex1 = tex0 + 1; - tex1 = llclamp(tex1, 0, 3); - - st_offset = (lltrunc(sti) + lltrunc(stj)*st_width) * st_comps; - for (U32 k = 0; k < tex_comps; k++) - { - // Linearly interpolate based on composition. - if (st_offset >= st_data_size[tex0] || st_offset >= st_data_size[tex1]) - { - // SJB: This shouldn't be happening, but does... Rounding error? - //LL_WARNS() << "offset 0 [" << tex0 << "] =" << st_offset << " >= size=" << st_data_size[tex0] << LL_ENDL; - //LL_WARNS() << "offset 1 [" << tex1 << "] =" << st_offset << " >= size=" << st_data_size[tex1] << LL_ENDL; - } - else - { - F32 a = *(st_data[tex0] + st_offset); - F32 b = *(st_data[tex1] + st_offset); - rawp[ offset ] = (U8)lltrunc( a + composition * (b - a) ); - } - offset++; - st_offset++; - } - - sti += st_x_stride; - if (sti >= st_width) - { - sti -= st_width; - } - } - - stj += st_y_stride; - if (stj >= st_height) - { - stj -= st_height; - } - } - - if (!texturep->hasGLTexture()) - { - texturep->createGLTexture(0, raw); - } - texturep->setSubImage(raw, tex_x_begin, tex_y_begin, tex_x_end - tex_x_begin, tex_y_end - tex_y_begin); - - // Un-boost detail textures (will get re-boosted if rendering in high detail) - for (S32 i = 0; i < ASSET_COUNT; i++) - { - unboost_minimap_texture(mDetailTextures[i]); - } - - // Un-boost textures for each detail material (will get re-boosted if rendering in high detail) - for (S32 i = 0; i < ASSET_COUNT; i++) - { - unboost_minimap_material(mDetailMaterials[i]); - } - - return true; -} - F32 LLVLComposition::getStartHeight(S32 corner) { return mStartHeight[corner]; diff --git a/indra/newview/llvlcomposition.h b/indra/newview/llvlcomposition.h index 61c35ade28..2637d77183 100644 --- a/indra/newview/llvlcomposition.h +++ b/indra/newview/llvlcomposition.h @@ -114,8 +114,6 @@ public: // Viewer side hack to generate composition values bool generateHeights(const F32 x, const F32 y, const F32 width, const F32 height); bool generateComposition(); - // Generate texture from composition values. - bool generateMinimapTileLand(const F32 x, const F32 y, const F32 width, const F32 height); // Use these as indeces ito the get/setters below that use 'corner' enum ECorner diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index de62256134..7d9a3378f9 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -851,19 +851,9 @@ void LLVOVolume::updateTextureVirtualSize(bool forced) if (mSculptTexture.notNull()) { - mSculptTexture->setBoostLevel(llmax((S32)mSculptTexture->getBoostLevel(), - (S32)LLGLTexture::BOOST_SCULPTED)); mSculptTexture->setForSculpt() ; - if(!mSculptTexture->isCachedRawImageReady()) - { - S32 lod = llmin(mLOD, 3); - F32 lodf = ((F32)(lod + 1.0f)/4.f); - F32 tex_size = lodf * LLViewerTexture::sMaxSculptRez ; - mSculptTexture->addTextureStats(2.f * tex_size * tex_size, false); - } - - S32 texture_discard = mSculptTexture->getCachedRawImageLevel(); //try to match the texture + S32 texture_discard = mSculptTexture->getRawImageLevel(); //try to match the texture S32 current_discard = getVolume() ? getVolume()->getSculptLevel() : -2 ; if (texture_discard >= 0 && //texture has some data available @@ -1159,7 +1149,9 @@ void LLVOVolume::updateSculptTexture() LLUUID id = sculpt_params->getSculptTexture(); if (id.notNull()) { - mSculptTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, true, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + mSculptTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, true, LLGLTexture::BOOST_SCULPTED, LLViewerTexture::LOD_TEXTURE); + mSculptTexture->forceToSaveRawImage(0, F32_MAX); + mSculptTexture->addTextureStats(256.f*256.f); } mSkinInfoUnavaliable = false; @@ -1252,8 +1244,22 @@ void LLVOVolume::sculpt() S8 sculpt_components = 0; const U8* sculpt_data = NULL; - S32 discard_level = mSculptTexture->getCachedRawImageLevel() ; - LLImageRaw* raw_image = mSculptTexture->getCachedRawImage() ; + S32 discard_level = mSculptTexture->getRawImageLevel() ; + LLImageRaw* raw_image = mSculptTexture->getRawImage() ; + + if (!raw_image) + { + raw_image = mSculptTexture->getSavedRawImage(); + S32 discard_level = mSculptTexture->getSavedRawImageLevel(); + } + + if (!raw_image) + { + // last resort, read back from GL + mSculptTexture->readbackRawImage(); + raw_image = mSculptTexture->getRawImage(); + discard_level = mSculptTexture->getRawImageLevel(); + } S32 max_discard = mSculptTexture->getMaxDiscardLevel(); if (discard_level > max_discard) @@ -1310,8 +1316,6 @@ void LLVOVolume::sculpt() if(!raw_image) { - llassert(discard_level < 0) ; - sculpt_width = 0; sculpt_height = 0; sculpt_data = NULL ; diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp index 34040e1aca..2bc849a74f 100644 --- a/indra/newview/llvowater.cpp +++ b/indra/newview/llvowater.cpp @@ -59,7 +59,6 @@ LLVOWater::LLVOWater(const LLUUID &id, mbCanSelect = false; setScale(LLVector3(256.f, 256.f, 0.f)); // Hack for setting scale for bounding boxes/visibility. - mUseTexture = true; mIsEdgePatch = false; } @@ -101,14 +100,7 @@ LLDrawable *LLVOWater::createDrawable(LLPipeline *pipeline) LLDrawPoolWater *pool = (LLDrawPoolWater*) gPipeline.getPool(LLDrawPool::POOL_WATER); - if (mUseTexture) - { - mDrawable->setNumFaces(1, pool, mRegionp->getLand().getWaterTexture()); - } - else - { - mDrawable->setNumFaces(1, pool, LLWorld::getInstance()->getDefaultWaterTexture()); - } + mDrawable->setNumFaces(1, pool, LLWorld::getInstance()->getDefaultWaterTexture()); return mDrawable; } @@ -249,11 +241,6 @@ void setVecZ(LLVector3& v) v.mV[VZ] = 1; } -void LLVOWater::setUseTexture(const bool use_texture) -{ - mUseTexture = use_texture; -} - void LLVOWater::setIsEdgePatch(const bool edge_patch) { mIsEdgePatch = edge_patch; diff --git a/indra/newview/llvowater.h b/indra/newview/llvowater.h index adae86691a..ba3da510c4 100644 --- a/indra/newview/llvowater.h +++ b/indra/newview/llvowater.h @@ -70,13 +70,10 @@ public: /*virtual*/ bool isActive() const; // Whether this object needs to do an idleUpdate. - void setUseTexture(const bool use_texture); void setIsEdgePatch(const bool edge_patch); - bool getUseTexture() const { return mUseTexture; } bool getIsEdgePatch() const { return mIsEdgePatch; } protected: - bool mUseTexture; bool mIsEdgePatch; S32 mRenderType; }; diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 2eadea20ef..6470c81aaa 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -961,7 +961,6 @@ void LLWorld::updateWaterObjects() if (!getRegionFromHandle(region_handle)) { // No region at that area, so make water LLVOWater* waterp = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_WATER, gAgent.getRegion()); - waterp->setUseTexture(false); waterp->setPositionGlobal(LLVector3d(x + rwidth/2, y + rwidth/2, 256.f + water_height)); @@ -1015,7 +1014,6 @@ void LLWorld::updateWaterObjects() mEdgeWaterObjects[dir] = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_VOID_WATER, gAgent.getRegion()); waterp = mEdgeWaterObjects[dir]; - waterp->setUseTexture(false); waterp->setIsEdgePatch(true); gPipeline.createObject(waterp); } diff --git a/indra/newview/llworldmipmap.cpp b/indra/newview/llworldmipmap.cpp index e226fd4748..d8ea2b884f 100644 --- a/indra/newview/llworldmipmap.cpp +++ b/indra/newview/llworldmipmap.cpp @@ -178,6 +178,7 @@ LLPointer<LLViewerFetchedTexture> LLWorldMipmap::getObjectsTile(U32 grid_x, U32 } } +//static LLPointer<LLViewerFetchedTexture> LLWorldMipmap::loadObjectsTile(U32 grid_x, U32 grid_y, S32 level) { // Get the grid coordinates diff --git a/indra/newview/llworldmipmap.h b/indra/newview/llworldmipmap.h index ab98b55b72..907f24d1e7 100644 --- a/indra/newview/llworldmipmap.h +++ b/indra/newview/llworldmipmap.h @@ -74,11 +74,13 @@ public: // Convert world coordinates to mipmap grid coordinates at a given level static void globalToMipmap(F64 global_x, F64 global_y, S32 level, U32* grid_x, U32* grid_y); + // Load the relevant tile from S3 + static LLPointer<LLViewerFetchedTexture> loadObjectsTile(U32 grid_x, U32 grid_y, S32 level); + private: // Get a handle (key) from grid coordinates U64 convertGridToHandle(U32 grid_x, U32 grid_y) { return to_region_handle(grid_x * REGION_WIDTH_UNITS, grid_y * REGION_WIDTH_UNITS); } - // Load the relevant tile from S3 - LLPointer<LLViewerFetchedTexture> loadObjectsTile(U32 grid_x, U32 grid_y, S32 level); + // Clear a level from its "missing" tiles void cleanMissedTilesFromLevel(S32 level); diff --git a/scripts/messages/message_template.msg.sha1 b/scripts/messages/message_template.msg.sha1 index 9d5517ab68..efa5f3cf48 100755 --- a/scripts/messages/message_template.msg.sha1 +++ b/scripts/messages/message_template.msg.sha1 @@ -1 +1 @@ -d7915d67467e59287857630bd89bf9529d065199 +d7915d67467e59287857630bd89bf9529d065199
\ No newline at end of file |