diff options
Diffstat (limited to 'indra/newview/llviewertexlayer.cpp')
-rw-r--r-- | indra/newview/llviewertexlayer.cpp | 706 |
1 files changed, 353 insertions, 353 deletions
diff --git a/indra/newview/llviewertexlayer.cpp b/indra/newview/llviewertexlayer.cpp index 6e5afc3652..10380fecee 100644 --- a/indra/newview/llviewertexlayer.cpp +++ b/indra/newview/llviewertexlayer.cpp @@ -1,353 +1,353 @@ -/**
- * @file llviewertexlayer.cpp
- * @brief Viewer texture layer. Used for avatars.
- *
- * $LicenseInfo:firstyear=2012&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llviewertexlayer.h"
-
-#include "llagent.h"
-#include "llimagej2c.h"
-#include "llnotificationsutil.h"
-#include "llviewerregion.h"
-#include "llglslshader.h"
-#include "llvoavatarself.h"
-#include "pipeline.h"
-#include "llviewercontrol.h"
-
-// runway consolidate
-extern std::string self_av_string();
-
-//-----------------------------------------------------------------------------
-// LLViewerTexLayerSetBuffer
-// The composite image that a LLViewerTexLayerSet writes to. Each LLViewerTexLayerSet has one.
-//-----------------------------------------------------------------------------
-
-// static
-S32 LLViewerTexLayerSetBuffer::sGLByteCount = 0;
-
-LLViewerTexLayerSetBuffer::LLViewerTexLayerSetBuffer(LLTexLayerSet* const owner,
- S32 width, S32 height) :
- // ORDER_LAST => must render these after the hints are created.
- LLTexLayerSetBuffer(owner),
- LLViewerDynamicTexture(width, height, 4, LLViewerDynamicTexture::ORDER_LAST, false),
- mNeedsUpdate(true),
- mNumLowresUpdates(0)
-{
- mGLTexturep->setNeedsAlphaAndPickMask(false);
-
- LLViewerTexLayerSetBuffer::sGLByteCount += getSize();
- mNeedsUpdateTimer.start();
-}
-
-LLViewerTexLayerSetBuffer::~LLViewerTexLayerSetBuffer()
-{
- LLViewerTexLayerSetBuffer::sGLByteCount -= getSize();
- destroyGLTexture();
- for( S32 order = 0; order < ORDER_COUNT; order++ )
- {
- LLViewerDynamicTexture::sInstances[order].erase(this); // will fail in all but one case.
- }
-}
-
-//virtual
-S8 LLViewerTexLayerSetBuffer::getType() const
-{
- return LLViewerDynamicTexture::LL_TEX_LAYER_SET_BUFFER ;
-}
-
-//virtual
-void LLViewerTexLayerSetBuffer::restoreGLTexture()
-{
- LLViewerDynamicTexture::restoreGLTexture() ;
-}
-
-//virtual
-void LLViewerTexLayerSetBuffer::destroyGLTexture()
-{
- LLViewerDynamicTexture::destroyGLTexture() ;
-}
-
-// static
-void LLViewerTexLayerSetBuffer::dumpTotalByteCount()
-{
- LL_INFOS() << "Composite System GL Buffers: " << (LLViewerTexLayerSetBuffer::sGLByteCount/1024) << "KB" << LL_ENDL;
-}
-
-void LLViewerTexLayerSetBuffer::requestUpdate()
-{
- restartUpdateTimer();
- mNeedsUpdate = true;
- mNumLowresUpdates = 0;
-}
-
-void LLViewerTexLayerSetBuffer::restartUpdateTimer()
-{
- mNeedsUpdateTimer.reset();
- mNeedsUpdateTimer.start();
-}
-
-// virtual
-bool LLViewerTexLayerSetBuffer::needsRender()
-{
- llassert(mTexLayerSet->getAvatarAppearance() == gAgentAvatarp);
- if (!isAgentAvatarValid()) return false;
-
- const bool update_now = mNeedsUpdate && isReadyToUpdate();
-
- // Don't render if we don't want to (or aren't ready to) update.
- if (!update_now)
- {
- return false;
- }
-
- // Don't render if we're animating our appearance.
- if (gAgentAvatarp->getIsAppearanceAnimating())
- {
- return false;
- }
-
- // Don't render if we are trying to create a skirt texture but aren't wearing a skirt.
- if (gAgentAvatarp->getBakedTE(getViewerTexLayerSet()) == LLAvatarAppearanceDefines::TEX_SKIRT_BAKED &&
- !gAgentAvatarp->isWearingWearableType(LLWearableType::WT_SKIRT))
- {
- return false;
- }
-
- // Render if we have at least minimal level of detail for each local texture.
- return getViewerTexLayerSet()->isLocalTextureDataAvailable();
-}
-
-// virtual
-void LLViewerTexLayerSetBuffer::preRenderTexLayerSet()
-{
- LLTexLayerSetBuffer::preRenderTexLayerSet();
-
- // keep depth buffer, we don't need to clear it
- LLViewerDynamicTexture::preRender(false);
-}
-
-// virtual
-void LLViewerTexLayerSetBuffer::postRenderTexLayerSet(bool success)
-{
-
- LLTexLayerSetBuffer::postRenderTexLayerSet(success);
- LLViewerDynamicTexture::postRender(success);
-}
-
-// virtual
-void LLViewerTexLayerSetBuffer::midRenderTexLayerSet(bool success)
-{
- const bool update_now = mNeedsUpdate && isReadyToUpdate();
- if (update_now)
- {
- doUpdate();
- }
-
- // *TODO: Old logic does not check success before setGLTextureCreated
- // we have valid texture data now
- mGLTexturep->setGLTextureCreated(true);
-}
-
-bool LLViewerTexLayerSetBuffer::isInitialized(void) const
-{
- return mGLTexturep.notNull() && mGLTexturep->isGLTextureCreated();
-}
-
-bool LLViewerTexLayerSetBuffer::isReadyToUpdate() const
-{
- // If we requested an update and have the final LOD ready, then update.
- if (getViewerTexLayerSet()->isLocalTextureDataFinal()) return true;
-
- // If we haven't done an update yet, then just do one now regardless of state of textures.
- if (mNumLowresUpdates == 0) return true;
-
- // Update if we've hit a timeout. Unlike for uploads, we can make this timeout fairly small
- // since render unnecessarily doesn't cost much.
- const U32 TEXTURE_TIMEOUT = 10;
- if (TEXTURE_TIMEOUT != 0)
- {
- // If we hit our timeout and have textures available at even lower resolution, then update.
- const bool is_update_textures_timeout = mNeedsUpdateTimer.getElapsedTimeF32() >= TEXTURE_TIMEOUT;
- const bool has_lower_lod = getViewerTexLayerSet()->isLocalTextureDataAvailable();
- if (has_lower_lod && is_update_textures_timeout) return true;
- }
-
- return false;
-}
-
-bool LLViewerTexLayerSetBuffer::requestUpdateImmediate()
-{
- mNeedsUpdate = true;
- bool result = false;
-
- if (needsRender())
- {
- preRender(false);
- result = render();
- postRender(result);
- }
-
- return result;
-}
-
-// Mostly bookkeeping; don't need to actually "do" anything since
-// render() will actually do the update.
-void LLViewerTexLayerSetBuffer::doUpdate()
-{
- LLViewerTexLayerSet* layer_set = getViewerTexLayerSet();
- const bool highest_lod = layer_set->isLocalTextureDataFinal();
- if (highest_lod)
- {
- mNeedsUpdate = false;
- }
- else
- {
- mNumLowresUpdates++;
- }
-
- restartUpdateTimer();
-
- // need to switch to using this layerset if this is the first update
- // after getting the lowest LOD
- layer_set->getAvatar()->updateMeshTextures();
-
- // Print out notification that we updated this texture.
- if (gSavedSettings.getBOOL("DebugAvatarRezTime"))
- {
- const bool highest_lod = layer_set->isLocalTextureDataFinal();
- const std::string lod_str = highest_lod ? "HighRes" : "LowRes";
- LLSD args;
- args["EXISTENCE"] = llformat("%d",(U32)layer_set->getAvatar()->debugGetExistenceTimeElapsedF32());
- args["TIME"] = llformat("%d",(U32)mNeedsUpdateTimer.getElapsedTimeF32());
- args["BODYREGION"] = layer_set->getBodyRegionName();
- args["RESOLUTION"] = lod_str;
- LLNotificationsUtil::add("AvatarRezSelfBakedTextureUpdateNotification",args);
- LL_DEBUGS("Avatar") << self_av_string() << "Locally updating [ name: " << layer_set->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUpdateTimer.getElapsedTimeF32() << " ]" << LL_ENDL;
- }
-}
-
-//-----------------------------------------------------------------------------
-// LLViewerTexLayerSet
-// An ordered set of texture layers that get composited into a single texture.
-//-----------------------------------------------------------------------------
-
-LLViewerTexLayerSet::LLViewerTexLayerSet(LLAvatarAppearance* const appearance) :
- LLTexLayerSet(appearance),
- mUpdatesEnabled( false )
-{
-}
-
-// virtual
-LLViewerTexLayerSet::~LLViewerTexLayerSet()
-{
-}
-
-// Returns true if at least one packet of data has been received for each of the textures that this layerset depends on.
-bool LLViewerTexLayerSet::isLocalTextureDataAvailable() const
-{
- if (!mAvatarAppearance->isSelf()) return false;
- return getAvatar()->isLocalTextureDataAvailable(this);
-}
-
-
-// Returns true if all of the data for the textures that this layerset depends on have arrived.
-bool LLViewerTexLayerSet::isLocalTextureDataFinal() const
-{
- if (!mAvatarAppearance->isSelf()) return false;
- return getAvatar()->isLocalTextureDataFinal(this);
-}
-
-// virtual
-void LLViewerTexLayerSet::requestUpdate()
-{
- if( mUpdatesEnabled )
- {
- createComposite();
- getViewerComposite()->requestUpdate();
- }
-}
-
-void LLViewerTexLayerSet::updateComposite()
-{
- createComposite();
- getViewerComposite()->requestUpdateImmediate();
-}
-
-// virtual
-void LLViewerTexLayerSet::createComposite()
-{
- if(!mComposite)
- {
- S32 width = mInfo->getWidth();
- S32 height = mInfo->getHeight();
- // Composite other avatars at reduced resolution
- if( !mAvatarAppearance->isSelf() )
- {
- LL_ERRS() << "composites should not be created for non-self avatars!" << LL_ENDL;
- }
- mComposite = new LLViewerTexLayerSetBuffer( this, width, height );
- }
-}
-
-void LLViewerTexLayerSet::setUpdatesEnabled( bool b )
-{
- mUpdatesEnabled = b;
-}
-
-LLVOAvatarSelf* LLViewerTexLayerSet::getAvatar()
-{
- return dynamic_cast<LLVOAvatarSelf*> (mAvatarAppearance);
-}
-
-const LLVOAvatarSelf* LLViewerTexLayerSet::getAvatar() const
-{
- return dynamic_cast<const LLVOAvatarSelf*> (mAvatarAppearance);
-}
-
-LLViewerTexLayerSetBuffer* LLViewerTexLayerSet::getViewerComposite()
-{
- return dynamic_cast<LLViewerTexLayerSetBuffer*> (getComposite());
-}
-
-const LLViewerTexLayerSetBuffer* LLViewerTexLayerSet::getViewerComposite() const
-{
- return dynamic_cast<const LLViewerTexLayerSetBuffer*> (getComposite());
-}
-
-
-const std::string LLViewerTexLayerSetBuffer::dumpTextureInfo() const
-{
- if (!isAgentAvatarValid()) return "";
-
- const bool is_high_res = true;
- const U32 num_low_res = 0;
- const std::string local_texture_info = gAgentAvatarp->debugDumpLocalTextureDataInfo(getViewerTexLayerSet());
-
- std::string text = llformat("[HiRes:%d LoRes:%d] %s",
- is_high_res, num_low_res,
- local_texture_info.c_str());
- return text;
-}
+/** + * @file llviewertexlayer.cpp + * @brief Viewer texture layer. Used for avatars. + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llviewertexlayer.h" + +#include "llagent.h" +#include "llimagej2c.h" +#include "llnotificationsutil.h" +#include "llviewerregion.h" +#include "llglslshader.h" +#include "llvoavatarself.h" +#include "pipeline.h" +#include "llviewercontrol.h" + +// runway consolidate +extern std::string self_av_string(); + +//----------------------------------------------------------------------------- +// LLViewerTexLayerSetBuffer +// The composite image that a LLViewerTexLayerSet writes to. Each LLViewerTexLayerSet has one. +//----------------------------------------------------------------------------- + +// static +S32 LLViewerTexLayerSetBuffer::sGLByteCount = 0; + +LLViewerTexLayerSetBuffer::LLViewerTexLayerSetBuffer(LLTexLayerSet* const owner, + S32 width, S32 height) : + // ORDER_LAST => must render these after the hints are created. + LLTexLayerSetBuffer(owner), + LLViewerDynamicTexture(width, height, 4, LLViewerDynamicTexture::ORDER_LAST, false), + mNeedsUpdate(true), + mNumLowresUpdates(0) +{ + mGLTexturep->setNeedsAlphaAndPickMask(false); + + LLViewerTexLayerSetBuffer::sGLByteCount += getSize(); + mNeedsUpdateTimer.start(); +} + +LLViewerTexLayerSetBuffer::~LLViewerTexLayerSetBuffer() +{ + LLViewerTexLayerSetBuffer::sGLByteCount -= getSize(); + destroyGLTexture(); + for( S32 order = 0; order < ORDER_COUNT; order++ ) + { + LLViewerDynamicTexture::sInstances[order].erase(this); // will fail in all but one case. + } +} + +//virtual +S8 LLViewerTexLayerSetBuffer::getType() const +{ + return LLViewerDynamicTexture::LL_TEX_LAYER_SET_BUFFER ; +} + +//virtual +void LLViewerTexLayerSetBuffer::restoreGLTexture() +{ + LLViewerDynamicTexture::restoreGLTexture() ; +} + +//virtual +void LLViewerTexLayerSetBuffer::destroyGLTexture() +{ + LLViewerDynamicTexture::destroyGLTexture() ; +} + +// static +void LLViewerTexLayerSetBuffer::dumpTotalByteCount() +{ + LL_INFOS() << "Composite System GL Buffers: " << (LLViewerTexLayerSetBuffer::sGLByteCount/1024) << "KB" << LL_ENDL; +} + +void LLViewerTexLayerSetBuffer::requestUpdate() +{ + restartUpdateTimer(); + mNeedsUpdate = true; + mNumLowresUpdates = 0; +} + +void LLViewerTexLayerSetBuffer::restartUpdateTimer() +{ + mNeedsUpdateTimer.reset(); + mNeedsUpdateTimer.start(); +} + +// virtual +bool LLViewerTexLayerSetBuffer::needsRender() +{ + llassert(mTexLayerSet->getAvatarAppearance() == gAgentAvatarp); + if (!isAgentAvatarValid()) return false; + + const bool update_now = mNeedsUpdate && isReadyToUpdate(); + + // Don't render if we don't want to (or aren't ready to) update. + if (!update_now) + { + return false; + } + + // Don't render if we're animating our appearance. + if (gAgentAvatarp->getIsAppearanceAnimating()) + { + return false; + } + + // Don't render if we are trying to create a skirt texture but aren't wearing a skirt. + if (gAgentAvatarp->getBakedTE(getViewerTexLayerSet()) == LLAvatarAppearanceDefines::TEX_SKIRT_BAKED && + !gAgentAvatarp->isWearingWearableType(LLWearableType::WT_SKIRT)) + { + return false; + } + + // Render if we have at least minimal level of detail for each local texture. + return getViewerTexLayerSet()->isLocalTextureDataAvailable(); +} + +// virtual +void LLViewerTexLayerSetBuffer::preRenderTexLayerSet() +{ + LLTexLayerSetBuffer::preRenderTexLayerSet(); + + // keep depth buffer, we don't need to clear it + LLViewerDynamicTexture::preRender(false); +} + +// virtual +void LLViewerTexLayerSetBuffer::postRenderTexLayerSet(bool success) +{ + + LLTexLayerSetBuffer::postRenderTexLayerSet(success); + LLViewerDynamicTexture::postRender(success); +} + +// virtual +void LLViewerTexLayerSetBuffer::midRenderTexLayerSet(bool success) +{ + const bool update_now = mNeedsUpdate && isReadyToUpdate(); + if (update_now) + { + doUpdate(); + } + + // *TODO: Old logic does not check success before setGLTextureCreated + // we have valid texture data now + mGLTexturep->setGLTextureCreated(true); +} + +bool LLViewerTexLayerSetBuffer::isInitialized(void) const +{ + return mGLTexturep.notNull() && mGLTexturep->isGLTextureCreated(); +} + +bool LLViewerTexLayerSetBuffer::isReadyToUpdate() const +{ + // If we requested an update and have the final LOD ready, then update. + if (getViewerTexLayerSet()->isLocalTextureDataFinal()) return true; + + // If we haven't done an update yet, then just do one now regardless of state of textures. + if (mNumLowresUpdates == 0) return true; + + // Update if we've hit a timeout. Unlike for uploads, we can make this timeout fairly small + // since render unnecessarily doesn't cost much. + const U32 TEXTURE_TIMEOUT = 10; + if (TEXTURE_TIMEOUT != 0) + { + // If we hit our timeout and have textures available at even lower resolution, then update. + const bool is_update_textures_timeout = mNeedsUpdateTimer.getElapsedTimeF32() >= TEXTURE_TIMEOUT; + const bool has_lower_lod = getViewerTexLayerSet()->isLocalTextureDataAvailable(); + if (has_lower_lod && is_update_textures_timeout) return true; + } + + return false; +} + +bool LLViewerTexLayerSetBuffer::requestUpdateImmediate() +{ + mNeedsUpdate = true; + bool result = false; + + if (needsRender()) + { + preRender(false); + result = render(); + postRender(result); + } + + return result; +} + +// Mostly bookkeeping; don't need to actually "do" anything since +// render() will actually do the update. +void LLViewerTexLayerSetBuffer::doUpdate() +{ + LLViewerTexLayerSet* layer_set = getViewerTexLayerSet(); + const bool highest_lod = layer_set->isLocalTextureDataFinal(); + if (highest_lod) + { + mNeedsUpdate = false; + } + else + { + mNumLowresUpdates++; + } + + restartUpdateTimer(); + + // need to switch to using this layerset if this is the first update + // after getting the lowest LOD + layer_set->getAvatar()->updateMeshTextures(); + + // Print out notification that we updated this texture. + if (gSavedSettings.getBOOL("DebugAvatarRezTime")) + { + const bool highest_lod = layer_set->isLocalTextureDataFinal(); + const std::string lod_str = highest_lod ? "HighRes" : "LowRes"; + LLSD args; + args["EXISTENCE"] = llformat("%d",(U32)layer_set->getAvatar()->debugGetExistenceTimeElapsedF32()); + args["TIME"] = llformat("%d",(U32)mNeedsUpdateTimer.getElapsedTimeF32()); + args["BODYREGION"] = layer_set->getBodyRegionName(); + args["RESOLUTION"] = lod_str; + LLNotificationsUtil::add("AvatarRezSelfBakedTextureUpdateNotification",args); + LL_DEBUGS("Avatar") << self_av_string() << "Locally updating [ name: " << layer_set->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUpdateTimer.getElapsedTimeF32() << " ]" << LL_ENDL; + } +} + +//----------------------------------------------------------------------------- +// LLViewerTexLayerSet +// An ordered set of texture layers that get composited into a single texture. +//----------------------------------------------------------------------------- + +LLViewerTexLayerSet::LLViewerTexLayerSet(LLAvatarAppearance* const appearance) : + LLTexLayerSet(appearance), + mUpdatesEnabled( false ) +{ +} + +// virtual +LLViewerTexLayerSet::~LLViewerTexLayerSet() +{ +} + +// Returns true if at least one packet of data has been received for each of the textures that this layerset depends on. +bool LLViewerTexLayerSet::isLocalTextureDataAvailable() const +{ + if (!mAvatarAppearance->isSelf()) return false; + return getAvatar()->isLocalTextureDataAvailable(this); +} + + +// Returns true if all of the data for the textures that this layerset depends on have arrived. +bool LLViewerTexLayerSet::isLocalTextureDataFinal() const +{ + if (!mAvatarAppearance->isSelf()) return false; + return getAvatar()->isLocalTextureDataFinal(this); +} + +// virtual +void LLViewerTexLayerSet::requestUpdate() +{ + if( mUpdatesEnabled ) + { + createComposite(); + getViewerComposite()->requestUpdate(); + } +} + +void LLViewerTexLayerSet::updateComposite() +{ + createComposite(); + getViewerComposite()->requestUpdateImmediate(); +} + +// virtual +void LLViewerTexLayerSet::createComposite() +{ + if(!mComposite) + { + S32 width = mInfo->getWidth(); + S32 height = mInfo->getHeight(); + // Composite other avatars at reduced resolution + if( !mAvatarAppearance->isSelf() ) + { + LL_ERRS() << "composites should not be created for non-self avatars!" << LL_ENDL; + } + mComposite = new LLViewerTexLayerSetBuffer( this, width, height ); + } +} + +void LLViewerTexLayerSet::setUpdatesEnabled( bool b ) +{ + mUpdatesEnabled = b; +} + +LLVOAvatarSelf* LLViewerTexLayerSet::getAvatar() +{ + return dynamic_cast<LLVOAvatarSelf*> (mAvatarAppearance); +} + +const LLVOAvatarSelf* LLViewerTexLayerSet::getAvatar() const +{ + return dynamic_cast<const LLVOAvatarSelf*> (mAvatarAppearance); +} + +LLViewerTexLayerSetBuffer* LLViewerTexLayerSet::getViewerComposite() +{ + return dynamic_cast<LLViewerTexLayerSetBuffer*> (getComposite()); +} + +const LLViewerTexLayerSetBuffer* LLViewerTexLayerSet::getViewerComposite() const +{ + return dynamic_cast<const LLViewerTexLayerSetBuffer*> (getComposite()); +} + + +const std::string LLViewerTexLayerSetBuffer::dumpTextureInfo() const +{ + if (!isAgentAvatarValid()) return ""; + + const bool is_high_res = true; + const U32 num_low_res = 0; + const std::string local_texture_info = gAgentAvatarp->debugDumpLocalTextureDataInfo(getViewerTexLayerSet()); + + std::string text = llformat("[HiRes:%d LoRes:%d] %s", + is_high_res, num_low_res, + local_texture_info.c_str()); + return text; +} |