Merge branch 'DRTVWR-546' of https://bitbucket.org/lindenlab/viewer
# Conflicts: # indra/llrender/llimagegl.cpp # indra/newview/llagentcamera.cpp # indra/newview/llagentcamera.h # indra/newview/lltracker.cpp # indra/newview/llviewertexture.cpp # indra/newview/llvoavatar.cpp # indra/newview/llvoavatar.hmeow-7.2.2
commit
8c2deb6f8d
|
|
@ -2155,95 +2155,6 @@ LLGLUserClipPlane::~LLGLUserClipPlane()
|
|||
disable();
|
||||
}
|
||||
|
||||
LLGLNamePool::LLGLNamePool()
|
||||
{
|
||||
}
|
||||
|
||||
LLGLNamePool::~LLGLNamePool()
|
||||
{
|
||||
}
|
||||
|
||||
void LLGLNamePool::upkeep()
|
||||
{
|
||||
std::sort(mNameList.begin(), mNameList.end(), CompareUsed());
|
||||
}
|
||||
|
||||
void LLGLNamePool::cleanup()
|
||||
{
|
||||
for (name_list_t::iterator iter = mNameList.begin(); iter != mNameList.end(); ++iter)
|
||||
{
|
||||
releaseName(iter->name);
|
||||
}
|
||||
|
||||
mNameList.clear();
|
||||
}
|
||||
|
||||
GLuint LLGLNamePool::allocate()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
|
||||
#if LL_GL_NAME_POOLING
|
||||
for (name_list_t::iterator iter = mNameList.begin(); iter != mNameList.end(); ++iter)
|
||||
{
|
||||
if (!iter->used)
|
||||
{
|
||||
iter->used = TRUE;
|
||||
return iter->name;
|
||||
}
|
||||
}
|
||||
|
||||
NameEntry entry;
|
||||
entry.name = allocateName();
|
||||
entry.used = TRUE;
|
||||
mNameList.push_back(entry);
|
||||
|
||||
return entry.name;
|
||||
#else
|
||||
return allocateName();
|
||||
#endif
|
||||
}
|
||||
|
||||
void LLGLNamePool::release(GLuint name)
|
||||
{
|
||||
#if LL_GL_NAME_POOLING
|
||||
for (name_list_t::iterator iter = mNameList.begin(); iter != mNameList.end(); ++iter)
|
||||
{
|
||||
if (iter->name == name)
|
||||
{
|
||||
if (iter->used)
|
||||
{
|
||||
iter->used = FALSE;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_ERRS() << "Attempted to release a pooled name that is not in use!" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
LL_ERRS() << "Attempted to release a non pooled name!" << LL_ENDL;
|
||||
#else
|
||||
releaseName(name);
|
||||
#endif
|
||||
}
|
||||
|
||||
//static
|
||||
void LLGLNamePool::upkeepPools()
|
||||
{
|
||||
for (auto& pool : instance_snapshot())
|
||||
{
|
||||
pool.upkeep();
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void LLGLNamePool::cleanupPools()
|
||||
{
|
||||
for (auto& pool : instance_snapshot())
|
||||
{
|
||||
pool.cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
LLGLDepthTest::LLGLDepthTest(GLboolean depth_enabled, GLboolean write_enabled, GLenum depth_func)
|
||||
: mPrevDepthEnabled(sDepthEnabled), mPrevDepthFunc(sDepthFunc), mPrevWriteEnabled(sWriteEnabled)
|
||||
{
|
||||
|
|
@ -2465,3 +2376,4 @@ extern "C"
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -376,51 +376,6 @@ public:
|
|||
~LLGLSquashToFarClip();
|
||||
};
|
||||
|
||||
/*
|
||||
Generic pooling scheme for things which use GL names (used for occlusion queries and vertex buffer objects).
|
||||
Prevents thrashing of GL name caches by avoiding calls to glGenFoo and glDeleteFoo.
|
||||
*/
|
||||
class LLGLNamePool : public LLInstanceTracker<LLGLNamePool>
|
||||
{
|
||||
public:
|
||||
typedef LLInstanceTracker<LLGLNamePool> tracker_t;
|
||||
|
||||
struct NameEntry
|
||||
{
|
||||
GLuint name;
|
||||
BOOL used;
|
||||
};
|
||||
|
||||
struct CompareUsed
|
||||
{
|
||||
bool operator()(const NameEntry& lhs, const NameEntry& rhs)
|
||||
{
|
||||
return lhs.used < rhs.used; //FALSE entries first
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::vector<NameEntry> name_list_t;
|
||||
name_list_t mNameList;
|
||||
|
||||
LLGLNamePool();
|
||||
virtual ~LLGLNamePool();
|
||||
|
||||
void upkeep();
|
||||
void cleanup();
|
||||
|
||||
GLuint allocate();
|
||||
void release(GLuint name);
|
||||
|
||||
static void upkeepPools();
|
||||
static void cleanupPools();
|
||||
|
||||
protected:
|
||||
typedef std::vector<LLGLNamePool*> pool_list_t;
|
||||
|
||||
virtual GLuint allocateName() = 0;
|
||||
virtual void releaseName(GLuint name) = 0;
|
||||
};
|
||||
|
||||
/*
|
||||
Interface for objects that need periodic GL updates applied to them.
|
||||
Used to synchronize GL updates with GL thread.
|
||||
|
|
|
|||
|
|
@ -164,11 +164,11 @@ BOOL LLGLTexture::createGLTexture()
|
|||
return mGLTexturep->createGLTexture() ;
|
||||
}
|
||||
|
||||
BOOL LLGLTexture::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename, BOOL to_create, S32 category, bool defer_copy)
|
||||
BOOL LLGLTexture::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename, BOOL to_create, S32 category, bool defer_copy, LLGLuint* tex_name)
|
||||
{
|
||||
llassert(mGLTexturep.notNull()) ;
|
||||
llassert(mGLTexturep.notNull());
|
||||
|
||||
BOOL ret = mGLTexturep->createGLTexture(discard_level, imageraw, usename, to_create, category, defer_copy) ;
|
||||
BOOL ret = mGLTexturep->createGLTexture(discard_level, imageraw, usename, to_create, category, defer_copy, tex_name) ;
|
||||
|
||||
if(ret)
|
||||
{
|
||||
|
|
@ -260,20 +260,20 @@ LLTexUnit::eTextureType LLGLTexture::getTarget(void) const
|
|||
return mGLTexturep->getTarget() ;
|
||||
}
|
||||
|
||||
BOOL LLGLTexture::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, bool use_new_name /* = false */)
|
||||
BOOL LLGLTexture::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, LLGLuint use_name)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
llassert(mGLTexturep.notNull()) ;
|
||||
|
||||
return mGLTexturep->setSubImage(imageraw, x_pos, y_pos, width, height, 0, use_new_name) ;
|
||||
return mGLTexturep->setSubImage(imageraw, x_pos, y_pos, width, height, 0, use_name) ;
|
||||
}
|
||||
|
||||
BOOL LLGLTexture::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, bool use_new_name /* = false */)
|
||||
BOOL LLGLTexture::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, LLGLuint use_name)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
llassert(mGLTexturep.notNull()) ;
|
||||
|
||||
return mGLTexturep->setSubImage(datap, data_width, data_height, x_pos, y_pos, width, height, 0, use_new_name) ;
|
||||
return mGLTexturep->setSubImage(datap, data_width, data_height, x_pos, y_pos, width, height, 0, use_name) ;
|
||||
}
|
||||
|
||||
void LLGLTexture::setGLTextureCreated (bool initialized)
|
||||
|
|
|
|||
|
|
@ -132,13 +132,14 @@ public:
|
|||
// to_create - set to FALSE to force gl texture to not be created
|
||||
// category - LLGLTexture category for this LLGLTexture
|
||||
// defer_copy - set to true to allocate GL texture but NOT initialize with imageraw data
|
||||
BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE, S32 category = LLGLTexture::OTHER, bool defer_copy = false);
|
||||
// tex_name - if not null, will be set to the GL name of the texture created
|
||||
BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE, S32 category = LLGLTexture::OTHER, bool defer_copy = false, LLGLuint* tex_name = nullptr);
|
||||
|
||||
void setFilteringOption(LLTexUnit::eTextureFilterOptions option);
|
||||
void setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, BOOL swap_bytes = FALSE);
|
||||
void setAddressMode(LLTexUnit::eTextureAddressMode mode);
|
||||
BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, bool use_new_name = false);
|
||||
BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, bool use_new_name = false);
|
||||
BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, LLGLuint use_name = 0);
|
||||
BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, LLGLuint use_name = 0);
|
||||
void setGLTextureCreated (bool initialized);
|
||||
void setCategory(S32 category) ;
|
||||
void setTexName(LLGLuint); // for forcing w/ externally created textures only
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
#include "llglslshader.h"
|
||||
#include "llrender.h"
|
||||
#include "llwindow.h"
|
||||
#include "llframetimer.h"
|
||||
|
||||
#if !LL_IMAGEGL_THREAD_CHECK
|
||||
#define checkActiveThread()
|
||||
|
|
@ -1083,14 +1084,15 @@ void LLImageGL::postAddToAtlas()
|
|||
stop_glerror();
|
||||
}
|
||||
|
||||
BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update /* = FALSE */, bool use_new_name /* = false */)
|
||||
BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update /* = FALSE */, LLGLuint use_name)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
if (!width || !height)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
if (0 == (use_new_name ? mNewTexName : mTexName))
|
||||
LLGLuint tex_name = use_name != 0 ? use_name : mTexName;
|
||||
if (0 == tex_name)
|
||||
{
|
||||
// *TODO: Re-enable warning? Ran into thread locking issues? DK 2011-02-18
|
||||
//LL_WARNS() << "Setting subimage on image without GL texture" << LL_ENDL;
|
||||
|
|
@ -1106,7 +1108,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
|
|||
// HACK: allow the caller to explicitly force the fast path (i.e. using glTexSubImage2D here instead of calling setImage) even when updating the full texture.
|
||||
if (!force_fast_update && x_pos == 0 && y_pos == 0 && width == getWidth() && height == getHeight() && data_width == width && data_height == height)
|
||||
{
|
||||
setImage(datap, FALSE, use_new_name ? mNewTexName : mTexName);
|
||||
setImage(datap, FALSE, tex_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1158,7 +1160,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
|
|||
|
||||
datap += (y_pos * data_width + x_pos) * getComponents();
|
||||
// Update the GL texture
|
||||
BOOL res = gGL.getTexUnit(0)->bindManual(mBindTarget, use_new_name ? mNewTexName : mTexName);
|
||||
BOOL res = gGL.getTexUnit(0)->bindManual(mBindTarget, tex_name);
|
||||
if (!res) LL_ERRS() << "LLImageGL::setSubImage(): bindTexture failed" << LL_ENDL;
|
||||
stop_glerror();
|
||||
|
||||
|
|
@ -1179,10 +1181,10 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LLImageGL::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update /* = FALSE */, bool use_new_name /* = false */)
|
||||
BOOL LLImageGL::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update /* = FALSE */, LLGLuint use_name)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
return setSubImage(imageraw->getData(), imageraw->getWidth(), imageraw->getHeight(), x_pos, y_pos, width, height, force_fast_update, use_new_name);
|
||||
return setSubImage(imageraw->getData(), imageraw->getWidth(), imageraw->getHeight(), x_pos, y_pos, width, height, force_fast_update, use_name);
|
||||
}
|
||||
|
||||
// Copy sub image from frame buffer
|
||||
|
|
@ -1369,7 +1371,7 @@ BOOL LLImageGL::createGLTexture()
|
|||
return TRUE ;
|
||||
}
|
||||
|
||||
BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename/*=0*/, BOOL to_create, S32 category, bool defer_copy)
|
||||
BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename/*=0*/, BOOL to_create, S32 category, bool defer_copy, LLGLuint* tex_name)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
checkActiveThread();
|
||||
|
|
@ -1482,15 +1484,17 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
|
|||
|
||||
setCategory(category);
|
||||
const U8* rawdata = imageraw->getData();
|
||||
return createGLTexture(discard_level, rawdata, FALSE, usename, defer_copy);
|
||||
return createGLTexture(discard_level, rawdata, FALSE, usename, defer_copy, tex_name);
|
||||
}
|
||||
|
||||
BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_hasmips, S32 usename, bool defer_copy)
|
||||
BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_hasmips, S32 usename, bool defer_copy, LLGLuint* tex_name)
|
||||
// Call with void data, vmem is allocated but unitialized
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
checkActiveThread();
|
||||
|
||||
bool main_thread = on_main_thread();
|
||||
|
||||
if (defer_copy)
|
||||
{
|
||||
data_in = nullptr;
|
||||
|
|
@ -1509,29 +1513,40 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
|
|||
}
|
||||
discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel);
|
||||
|
||||
if (!defer_copy // <--- hacky way to force creation of mNewTexName from media texture update
|
||||
if (main_thread // <--- always force creation of mNewTexName when not on main thread
|
||||
&& mTexName != 0 && discard_level == mCurrentDiscardLevel)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("cglt - early setImage");
|
||||
// This will only be true if the size has not changed
|
||||
if (tex_name != nullptr)
|
||||
{
|
||||
*tex_name = mTexName;
|
||||
}
|
||||
return setImage(data_in, data_hasmips);
|
||||
}
|
||||
|
||||
GLuint old_texname = mTexName;
|
||||
|
||||
GLuint new_texname = 0;
|
||||
if (usename != 0)
|
||||
{
|
||||
mNewTexName = usename;
|
||||
llassert(main_thread);
|
||||
new_texname = usename;
|
||||
}
|
||||
else
|
||||
{
|
||||
LLImageGL::generateTextures(1, &mNewTexName);
|
||||
LLImageGL::generateTextures(1, &new_texname);
|
||||
{
|
||||
gGL.getTexUnit(0)->bind(this, false, false, mNewTexName);
|
||||
gGL.getTexUnit(0)->bind(this, false, false, new_texname);
|
||||
glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAX_LEVEL, mMaxDiscardLevel - discard_level);
|
||||
}
|
||||
}
|
||||
|
||||
if (tex_name != nullptr)
|
||||
{
|
||||
*tex_name = new_texname;
|
||||
}
|
||||
|
||||
if (mUseMipMaps)
|
||||
{
|
||||
mAutoGenMips = gGLManager.mHasMipMapGeneration;
|
||||
|
|
@ -1539,9 +1554,12 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
|
|||
|
||||
mCurrentDiscardLevel = discard_level;
|
||||
|
||||
if (!setImage(data_in, data_hasmips, mNewTexName))
|
||||
{
|
||||
return FALSE;
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("cglt - late setImage");
|
||||
if (!setImage(data_in, data_hasmips, new_texname))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// Set texture options to our defaults.
|
||||
|
|
@ -1558,11 +1576,11 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
|
|||
}
|
||||
|
||||
//if we're on the image loading thread, be sure to delete old_texname and update mTexName on the main thread
|
||||
if (!on_main_thread())
|
||||
if (!main_thread)
|
||||
{
|
||||
if (!defer_copy)
|
||||
{
|
||||
syncToMainThread();
|
||||
syncToMainThread(new_texname);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -1572,8 +1590,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
|
|||
{
|
||||
LLImageGL::deleteTextures(1, &old_texname);
|
||||
}
|
||||
mTexName = mNewTexName;
|
||||
mNewTexName = 0;
|
||||
mTexName = new_texname;
|
||||
}
|
||||
|
||||
mTextureMemory = (S32Bytes)getMipBytes(mCurrentDiscardLevel);
|
||||
|
|
@ -1587,13 +1604,36 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
void LLImageGL::syncToMainThread()
|
||||
void update_free_vram()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
|
||||
if (gGLManager.mHasATIMemInfo)
|
||||
{
|
||||
S32 meminfo[4];
|
||||
glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo);
|
||||
LLImageGLThread::sFreeVRAMMegabytes = meminfo[0];
|
||||
|
||||
}
|
||||
else if (gGLManager.mHasNVXMemInfo)
|
||||
{
|
||||
S32 free_memory;
|
||||
glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &free_memory);
|
||||
LLImageGLThread::sFreeVRAMMegabytes = free_memory / 1024;
|
||||
}
|
||||
}
|
||||
|
||||
void LLImageGL::syncToMainThread(LLGLuint new_tex_name)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("cglt - sync");
|
||||
if (gGLManager.mHasSync)
|
||||
{
|
||||
// post a sync to the main thread (will execute before tex name swap lambda below)
|
||||
// glFlush calls here are partly superstitious and partly backed by observation
|
||||
// on AMD hardware
|
||||
glFlush();
|
||||
auto sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||
glFlush();
|
||||
LL::WorkQueue::postMaybe(
|
||||
|
|
@ -1623,17 +1663,27 @@ void LLImageGL::syncToMainThread()
|
|||
[=]()
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("cglt - delete callback");
|
||||
if (mNewTexName != 0)
|
||||
if (new_tex_name != 0)
|
||||
{
|
||||
if (mTexName != 0)
|
||||
{
|
||||
LLImageGL::deleteTextures(1, &mTexName);
|
||||
}
|
||||
mTexName = mNewTexName;
|
||||
mNewTexName = 0;
|
||||
mTexName = new_tex_name;
|
||||
unref();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
//update free vram periodically
|
||||
static LLFrameTimer timer;
|
||||
|
||||
if (timer.getElapsedTimeF32() > 1.f) //call this once per second.
|
||||
{
|
||||
update_free_vram();
|
||||
timer.reset();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) const
|
||||
|
|
@ -1764,14 +1814,6 @@ void LLImageGL::destroyGLTexture()
|
|||
mTexName = 0;
|
||||
mGLTextureCreated = FALSE ;
|
||||
}
|
||||
|
||||
// clean up any in-flight name change
|
||||
if (0 != mNewTexName)
|
||||
{
|
||||
// Memory is transient, not tracked by sGlobalTextuerMemory
|
||||
LLImageGL::deleteTextures(1, &mNewTexName);
|
||||
mNewTexName = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//force to invalidate the gl texture, most likely a sculpty texture
|
||||
|
|
@ -2317,6 +2359,8 @@ void LLImageGL::checkActiveThread()
|
|||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, nummips);
|
||||
*/
|
||||
|
||||
std::atomic<S32> LLImageGLThread::sFreeVRAMMegabytes;
|
||||
|
||||
LLImageGLThread::LLImageGLThread(LLWindow* window)
|
||||
// We want exactly one thread, but a very large capacity: we never want
|
||||
// anyone, especially inner-loop render code, to have to block on post()
|
||||
|
|
@ -2343,3 +2387,14 @@ void LLImageGLThread::run()
|
|||
gGL.shutdown();
|
||||
mWindow->destroySharedContext(mContext);
|
||||
}
|
||||
|
||||
S32 LLImageGLThread::getFreeVRAMMegabytes()
|
||||
{
|
||||
if (!sEnabled)
|
||||
{
|
||||
update_free_vram();
|
||||
}
|
||||
|
||||
return sFreeVRAMMegabytes;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -113,17 +113,17 @@ public:
|
|||
|
||||
BOOL createGLTexture() ;
|
||||
BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE,
|
||||
S32 category = sMaxCategories-1, bool defer_copy = false);
|
||||
BOOL createGLTexture(S32 discard_level, const U8* data, BOOL data_hasmips = FALSE, S32 usename = 0, bool defer_copy = false);
|
||||
S32 category = sMaxCategories-1, bool defer_copy = false, LLGLuint* tex_name = nullptr);
|
||||
BOOL createGLTexture(S32 discard_level, const U8* data, BOOL data_hasmips = FALSE, S32 usename = 0, bool defer_copy = false, LLGLuint* tex_name = nullptr);
|
||||
void setImage(const LLImageRaw* imageraw);
|
||||
BOOL setImage(const U8* data_in, BOOL data_hasmips = FALSE, S32 usename = 0);
|
||||
BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE, bool use_new_name = false);
|
||||
BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE, bool use_new_name = false);
|
||||
BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE, LLGLuint use_name = 0);
|
||||
BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE, LLGLuint use_name = 0);
|
||||
BOOL setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos, S32 width, S32 height);
|
||||
|
||||
// wait for gl commands to finish on current thread and push
|
||||
// a lambda to main thread to swap mNewTexName and mTexName
|
||||
void syncToMainThread();
|
||||
void syncToMainThread(LLGLuint new_tex_name);
|
||||
|
||||
// Read back a raw image for this discard level, if it exists
|
||||
BOOL readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) const;
|
||||
|
|
@ -230,7 +230,7 @@ private:
|
|||
|
||||
bool mGLTextureCreated ;
|
||||
LLGLuint mTexName;
|
||||
LLGLuint mNewTexName = 0; // tex name set by background thread to be applied in main thread
|
||||
//LLGLuint mNewTexName = 0; // tex name set by background thread to be applied in main thread
|
||||
U16 mWidth;
|
||||
U16 mHeight;
|
||||
S8 mCurrentDiscardLevel;
|
||||
|
|
@ -335,6 +335,9 @@ public:
|
|||
// follows gSavedSettings "RenderGLMultiThreaded"
|
||||
static bool sEnabled;
|
||||
|
||||
// free video memory in megabytes
|
||||
static std::atomic<S32> sFreeVRAMMegabytes;
|
||||
|
||||
LLImageGLThread(LLWindow* window);
|
||||
|
||||
// post a function to be executed on the LLImageGL background thread
|
||||
|
|
@ -346,6 +349,8 @@ public:
|
|||
|
||||
void run() override;
|
||||
|
||||
static S32 getFreeVRAMMegabytes();
|
||||
|
||||
private:
|
||||
LLWindow* mWindow;
|
||||
void* mContext = nullptr;
|
||||
|
|
|
|||
|
|
@ -115,6 +115,10 @@ LLComboBox::LLComboBox(const LLComboBox::Params& p)
|
|||
}
|
||||
|
||||
mArrowImage = button_params.image_unselected;
|
||||
if (mArrowImage.notNull())
|
||||
{
|
||||
mImageLoadedConnection = mArrowImage->addLoadedCallback(boost::bind(&LLComboBox::imageLoaded, this));
|
||||
}
|
||||
|
||||
mButton = LLUICtrlFactory::create<LLButton>(button_params);
|
||||
|
||||
|
|
@ -186,6 +190,7 @@ LLComboBox::~LLComboBox()
|
|||
|
||||
// explicitly disconect this signal, since base class destructor might fire top lost
|
||||
mTopLostSignalConnection.disconnect();
|
||||
mImageLoadedConnection.disconnect();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1102,6 +1107,30 @@ void LLComboBox::onSetHighlight() const
|
|||
}
|
||||
}
|
||||
|
||||
void LLComboBox::imageLoaded()
|
||||
{
|
||||
static LLUICachedControl<S32> drop_shadow_button("DropShadowButton", 0);
|
||||
|
||||
if (mAllowTextEntry)
|
||||
{
|
||||
LLRect rect = getLocalRect();
|
||||
S32 arrow_width = mArrowImage ? mArrowImage->getWidth() : 0;
|
||||
S32 shadow_size = drop_shadow_button;
|
||||
mButton->setRect(LLRect(getRect().getWidth() - llmax(8, arrow_width) - 2 * shadow_size,
|
||||
rect.mTop, rect.mRight, rect.mBottom));
|
||||
if (mButton->getVisible())
|
||||
{
|
||||
// recalculate field size
|
||||
if (mTextEntry)
|
||||
{
|
||||
LLRect text_entry_rect(0, getRect().getHeight(), getRect().getWidth(), 0);
|
||||
text_entry_rect.mRight -= llmax(8, arrow_width) + 2 * drop_shadow_button;
|
||||
mTextEntry->reshape(text_entry_rect.getWidth(), text_entry_rect.getHeight(), TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
// LLCtrlListInterface functions
|
||||
|
||||
|
|
|
|||
|
|
@ -106,6 +106,8 @@ protected:
|
|||
virtual std::string _getSearchText() const;
|
||||
virtual void onSetHighlight() const;
|
||||
|
||||
void imageLoaded();
|
||||
|
||||
public:
|
||||
// LLView interface
|
||||
virtual void onFocusLost();
|
||||
|
|
@ -248,6 +250,7 @@ private:
|
|||
commit_callback_t mTextChangedCallback;
|
||||
commit_callback_t mSelectionCallback;
|
||||
boost::signals2::connection mTopLostSignalConnection;
|
||||
boost::signals2::connection mImageLoadedConnection;
|
||||
commit_signal_t mOnReturnSignal;
|
||||
S32 mLastSelectedIndex;
|
||||
bool mForceDisableFulltextSearch; // <FS:Ansariel> Allow fulltext search in comboboxes
|
||||
|
|
|
|||
|
|
@ -3641,6 +3641,7 @@ void LLWindowWin32::swapBuffers()
|
|||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_WIN32;
|
||||
ASSERT_MAIN_THREAD();
|
||||
glFlush(); //superstitious flush for maybe frame stall removal?
|
||||
SwapBuffers(mhDC);
|
||||
|
||||
LL_PROFILER_GPU_COLLECT
|
||||
|
|
|
|||
|
|
@ -219,11 +219,7 @@ void LLAgentCamera::init()
|
|||
|
||||
mCameraPreset = (ECameraPreset) gSavedSettings.getU32("CameraPresetType");
|
||||
|
||||
// mCameraOffsetInitial = gSavedSettings.getControl("CameraOffsetRearView");
|
||||
// mFocusOffsetInitial = gSavedSettings.getControl("FocusOffsetRearView");
|
||||
// [RLVa:KB] - @setcam_eyeoffset, @setcam_focusoffset and @setcam_eyeoffsetscale
|
||||
mCameraOffsetInitialControl = gSavedSettings.getControl("CameraOffsetRearView");
|
||||
mFocusOffsetInitialControl = gSavedSettings.getControl("FocusOffsetRearView");
|
||||
if (RlvActions::isRlvEnabled())
|
||||
{
|
||||
mRlvCameraOffsetInitialControl = gSavedSettings.declareVec3("CameraOffsetRLVaView", LLVector3::zero, "Declared in code", LLControlVariable::PERSIST_NO);
|
||||
|
|
@ -1779,11 +1775,11 @@ LLVector3d LLAgentCamera::calcThirdPersonFocusOffset()
|
|||
agent_rot *= ((LLViewerObject*)(gAgentAvatarp->getParent()))->getRenderRotation();
|
||||
}
|
||||
|
||||
// focus_offset = convert_from_llsd<LLVector3d>(mFocusOffsetInitial->get(), TYPE_VEC3D, "");
|
||||
// static LLCachedControl<LLVector3d> focus_offset_initial(gSavedSettings, "FocusOffsetRearView", LLVector3d());
|
||||
// [RLVa:KB] - @setcam_focusoffset
|
||||
focus_offset = getFocusOffsetInitial();
|
||||
LLVector3d focus_offset_initial = getFocusOffsetInitial();
|
||||
// [/RLVa:KB]
|
||||
return focus_offset * agent_rot;
|
||||
return focus_offset_initial * agent_rot;
|
||||
}
|
||||
|
||||
void LLAgentCamera::setupSitCamera()
|
||||
|
|
@ -1923,11 +1919,12 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit)
|
|||
}
|
||||
else
|
||||
{
|
||||
// static LLCachedControl<F32> camera_offset_scale(gSavedSettings, "CameraOffsetScale");
|
||||
// local_camera_offset = mCameraZoomFraction * getCameraOffsetInitial() * camera_offset_scale;
|
||||
// [RLVa:KB] - @setcam_eyeoffsetscale
|
||||
local_camera_offset = mCameraZoomFraction * getCameraOffsetInitial() * getCameraOffsetScale();
|
||||
// [/RLVa:KB]
|
||||
// local_camera_offset = mCameraZoomFraction * getCameraOffsetInitial() * gSavedSettings.getF32("CameraOffsetScale");
|
||||
|
||||
|
||||
// are we sitting down?
|
||||
if (isAgentAvatarValid() && gAgentAvatarp->getParent())
|
||||
{
|
||||
|
|
@ -2232,18 +2229,21 @@ bool LLAgentCamera::isJoystickCameraUsed()
|
|||
|
||||
LLVector3 LLAgentCamera::getCameraOffsetInitial()
|
||||
{
|
||||
// getCameraOffsetInitial and getFocusOffsetInitial can be called on update from idle before init()
|
||||
static LLCachedControl<LLVector3> camera_offset_initial (gSavedSettings, "CameraOffsetRearView", LLVector3());
|
||||
// return camera_offset_initial;
|
||||
// [RLVa:KB] - @setcam_eyeoffset
|
||||
return convert_from_llsd<LLVector3>( (ECameraPreset::CAMERA_RLV_SETCAM_VIEW != mCameraPreset) ? mCameraOffsetInitialControl->get() : mRlvCameraOffsetInitialControl->get(), TYPE_VEC3, "");
|
||||
return ECameraPreset::CAMERA_RLV_SETCAM_VIEW != mCameraPreset ? camera_offset_initial() : convert_from_llsd<LLVector3>(mRlvCameraOffsetInitialControl->get(), TYPE_VEC3, "");
|
||||
// [/RLVa:KB]
|
||||
// return convert_from_llsd<LLVector3>(mCameraOffsetInitial->get(), TYPE_VEC3, "");
|
||||
}
|
||||
|
||||
LLVector3d LLAgentCamera::getFocusOffsetInitial()
|
||||
{
|
||||
static LLCachedControl<LLVector3d> focus_offset_initial(gSavedSettings, "FocusOffsetRearView", LLVector3d());
|
||||
// return focus_offset_initial;
|
||||
// [RLVa:KB] - @setcam_focusoffset
|
||||
return convert_from_llsd<LLVector3d>( (ECameraPreset::CAMERA_RLV_SETCAM_VIEW != mCameraPreset) ? mFocusOffsetInitialControl->get() : mRlvFocusOffsetInitialControl->get(), TYPE_VEC3D, "");
|
||||
return ECameraPreset::CAMERA_RLV_SETCAM_VIEW != mCameraPreset ? focus_offset_initial() : convert_from_llsd<LLVector3d>(mRlvFocusOffsetInitialControl->get(), TYPE_VEC3D, "");
|
||||
// [/RLVa:KB]
|
||||
// return convert_from_llsd<LLVector3d>(mFocusOffsetInitial->get(), TYPE_VEC3D, "");
|
||||
}
|
||||
|
||||
// [RLVa:KB] - @setcam_eyeoffsetscale
|
||||
|
|
|
|||
|
|
@ -147,11 +147,7 @@ private:
|
|||
/** Camera preset in Third Person Mode */
|
||||
ECameraPreset mCameraPreset;
|
||||
|
||||
/** Initial camera offset */
|
||||
// LLPointer<LLControlVariable> mCameraOffsetInitial;
|
||||
// [RLVa:KB] - @setcam_eyeoffset
|
||||
// Renamed to catch their uses
|
||||
LLPointer<LLControlVariable> mCameraOffsetInitialControl;
|
||||
LLPointer<LLControlVariable> mRlvCameraOffsetInitialControl;
|
||||
// [/RLVa:KB]
|
||||
|
||||
|
|
@ -159,11 +155,8 @@ private:
|
|||
LLPointer<LLControlVariable> mRlvCameraOffsetScaleControl;
|
||||
// [/RLVa:KB]
|
||||
|
||||
/** Initial focus offset */
|
||||
// LLPointer<LLControlVariable> mFocusOffsetInitial;
|
||||
// [RLVa:KB] - @setcam_focusoffset
|
||||
// Renamed to catch their uses
|
||||
LLPointer<LLControlVariable> mFocusOffsetInitialControl;
|
||||
LLPointer<LLControlVariable> mRlvFocusOffsetInitialControl;
|
||||
// [/RLVa:KB]
|
||||
|
||||
|
|
|
|||
|
|
@ -55,6 +55,8 @@
|
|||
|
||||
// static
|
||||
LLStandardBumpmap gStandardBumpmapList[TEM_BUMPMAP_COUNT];
|
||||
LL::WorkQueue::weak_t LLBumpImageList::sMainQueue;
|
||||
LL::WorkQueue::weak_t LLBumpImageList::sTexUpdateQueue;
|
||||
|
||||
// static
|
||||
U32 LLStandardBumpmap::sStandardBumpmapCount = 0;
|
||||
|
|
@ -529,7 +531,7 @@ void LLDrawPoolBump::endFullbrightShiny()
|
|||
|
||||
void LLDrawPoolBump::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
|
||||
LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type];
|
||||
|
||||
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> render time capture
|
||||
|
|
@ -791,6 +793,8 @@ void LLBumpImageList::init()
|
|||
LLStandardBumpmap::init();
|
||||
|
||||
LLStandardBumpmap::restoreGL();
|
||||
sMainQueue = LL::WorkQueue::getInstance("mainloop");
|
||||
sTexUpdateQueue = LL::WorkQueue::getInstance("LLImageGL"); // Share work queue with tex loader.
|
||||
}
|
||||
|
||||
void LLBumpImageList::clear()
|
||||
|
|
@ -939,10 +943,7 @@ LLViewerTexture* LLBumpImageList::getBrightnessDarknessImage(LLViewerFetchedText
|
|||
}
|
||||
else
|
||||
{
|
||||
LLPointer<LLImageRaw> raw = new LLImageRaw(1,1,1);
|
||||
raw->clear(0x77, 0x77, 0xFF, 0xFF);
|
||||
|
||||
(*entries_list)[src_image->getID()] = LLViewerTextureManager::getLocalTexture( raw.get(), TRUE);
|
||||
(*entries_list)[src_image->getID()] = LLViewerTextureManager::getLocalTexture( TRUE );
|
||||
bump = (*entries_list)[src_image->getID()]; // In case callback was called immediately and replaced the image
|
||||
}
|
||||
|
||||
|
|
@ -1077,10 +1078,7 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI
|
|||
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
|
||||
LLPointer<LLImageRaw> raw = new LLImageRaw(1,1,1);
|
||||
raw->clear(0x77, 0x77, 0xFF, 0xFF);
|
||||
|
||||
entries_list[src_vi->getID()] = LLViewerTextureManager::getLocalTexture( raw.get(), TRUE);
|
||||
entries_list[src_vi->getID()] = LLViewerTextureManager::getLocalTexture(TRUE);
|
||||
iter = entries_list.find(src_vi->getID());
|
||||
}
|
||||
}
|
||||
|
|
@ -1200,108 +1198,165 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI
|
|||
}
|
||||
|
||||
//---------------------------------------------------
|
||||
// immediately assign bump to a global smart pointer in case some local smart pointer
|
||||
// immediately assign bump to a smart pointer in case some local smart pointer
|
||||
// accidentally releases it.
|
||||
LLPointer<LLViewerTexture> bump = LLViewerTextureManager::getLocalTexture( TRUE );
|
||||
LLPointer<LLViewerTexture> bump = iter->second;
|
||||
|
||||
if (!LLPipeline::sRenderDeferred)
|
||||
{
|
||||
bump->setExplicitFormat(GL_ALPHA8, GL_ALPHA);
|
||||
bump->createGLTexture(0, dst_image);
|
||||
|
||||
auto tex_queue = LLImageGLThread::sEnabled ? 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_CATEGORY_DRAWPOOL("bil - create texture");
|
||||
bump_ptr->createGLTexture(0, dst_ptr);
|
||||
bump_ptr->unref();
|
||||
dst_ptr->unref();
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
bump->createGLTexture(0, dst_image);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ //convert to normal map
|
||||
|
||||
//disable compression on normal maps to prevent errors below
|
||||
bump->getGLTexture()->setAllowCompression(false);
|
||||
bump->getGLTexture()->setUseMipMaps(TRUE);
|
||||
|
||||
{
|
||||
bump->setExplicitFormat(GL_RGBA8, GL_ALPHA);
|
||||
bump->createGLTexture(0, dst_image);
|
||||
}
|
||||
auto* bump_ptr = bump.get();
|
||||
auto* dst_ptr = dst_image.get();
|
||||
|
||||
{
|
||||
gPipeline.mScreen.bindTarget();
|
||||
|
||||
LLGLDepthTest depth(GL_FALSE);
|
||||
LLGLDisable cull(GL_CULL_FACE);
|
||||
LLGLDisable blend(GL_BLEND);
|
||||
gGL.setColorMask(TRUE, TRUE);
|
||||
gNormalMapGenProgram.bind();
|
||||
bump_ptr->ref();
|
||||
dst_ptr->ref();
|
||||
|
||||
static LLStaticHashedString sNormScale("norm_scale");
|
||||
static LLStaticHashedString sStepX("stepX");
|
||||
static LLStaticHashedString sStepY("stepY");
|
||||
bump_ptr->setExplicitFormat(GL_RGBA8, GL_ALPHA);
|
||||
|
||||
gNormalMapGenProgram.uniform1f(sNormScale, gSavedSettings.getF32("RenderNormalMapScale"));
|
||||
gNormalMapGenProgram.uniform1f(sStepX, 1.f/bump->getWidth());
|
||||
gNormalMapGenProgram.uniform1f(sStepY, 1.f/bump->getHeight());
|
||||
auto create_texture = [bump_ptr, dst_ptr]()
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("bil - create texture deferred");
|
||||
bump_ptr->createGLTexture(0, dst_ptr);
|
||||
};
|
||||
|
||||
LLVector2 v((F32) bump->getWidth()/gPipeline.mScreen.getWidth(),
|
||||
(F32) bump->getHeight()/gPipeline.mScreen.getHeight());
|
||||
auto gen_normal_map = [bump_ptr, dst_ptr]()
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("bil - generate normal map");
|
||||
if (gNormalMapGenProgram.mProgramObject == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
gPipeline.mScreen.bindTarget();
|
||||
|
||||
gGL.getTexUnit(0)->bind(bump);
|
||||
|
||||
S32 width = bump->getWidth();
|
||||
S32 height = bump->getHeight();
|
||||
LLGLDepthTest depth(GL_FALSE);
|
||||
LLGLDisable cull(GL_CULL_FACE);
|
||||
LLGLDisable blend(GL_BLEND);
|
||||
gGL.setColorMask(TRUE, TRUE);
|
||||
gNormalMapGenProgram.bind();
|
||||
|
||||
S32 screen_width = gPipeline.mScreen.getWidth();
|
||||
S32 screen_height = gPipeline.mScreen.getHeight();
|
||||
static LLStaticHashedString sNormScale("norm_scale");
|
||||
static LLStaticHashedString sStepX("stepX");
|
||||
static LLStaticHashedString sStepY("stepY");
|
||||
|
||||
glViewport(0, 0, screen_width, screen_height);
|
||||
gNormalMapGenProgram.uniform1f(sNormScale, gSavedSettings.getF32("RenderNormalMapScale"));
|
||||
gNormalMapGenProgram.uniform1f(sStepX, 1.f / bump_ptr->getWidth());
|
||||
gNormalMapGenProgram.uniform1f(sStepY, 1.f / bump_ptr->getHeight());
|
||||
|
||||
for (S32 left = 0; left < width; left += screen_width)
|
||||
{
|
||||
S32 right = left + screen_width;
|
||||
right = llmin(right, width);
|
||||
|
||||
F32 left_tc = (F32) left/ width;
|
||||
F32 right_tc = (F32) right/width;
|
||||
LLVector2 v((F32)bump_ptr->getWidth() / gPipeline.mScreen.getWidth(),
|
||||
(F32)bump_ptr->getHeight() / gPipeline.mScreen.getHeight());
|
||||
|
||||
for (S32 bottom = 0; bottom < height; bottom += screen_height)
|
||||
{
|
||||
S32 top = bottom+screen_height;
|
||||
top = llmin(top, height);
|
||||
gGL.getTexUnit(0)->bind(bump_ptr);
|
||||
|
||||
F32 bottom_tc = (F32) bottom/height;
|
||||
F32 top_tc = (F32)(bottom+screen_height)/height;
|
||||
top_tc = llmin(top_tc, 1.f);
|
||||
S32 width = bump_ptr->getWidth();
|
||||
S32 height = bump_ptr->getHeight();
|
||||
|
||||
F32 screen_right = (F32) (right-left)/screen_width;
|
||||
F32 screen_top = (F32) (top-bottom)/screen_height;
|
||||
S32 screen_width = gPipeline.mScreen.getWidth();
|
||||
S32 screen_height = gPipeline.mScreen.getHeight();
|
||||
|
||||
gGL.begin(LLRender::TRIANGLE_STRIP);
|
||||
gGL.texCoord2f(left_tc, bottom_tc);
|
||||
gGL.vertex2f(0, 0);
|
||||
glViewport(0, 0, screen_width, screen_height);
|
||||
|
||||
gGL.texCoord2f(left_tc, top_tc);
|
||||
gGL.vertex2f(0, screen_top);
|
||||
for (S32 left = 0; left < width; left += screen_width)
|
||||
{
|
||||
S32 right = left + screen_width;
|
||||
right = llmin(right, width);
|
||||
|
||||
gGL.texCoord2f(right_tc, bottom_tc);
|
||||
gGL.vertex2f(screen_right, 0);
|
||||
F32 left_tc = (F32)left / width;
|
||||
F32 right_tc = (F32)right / width;
|
||||
|
||||
gGL.texCoord2f(right_tc, top_tc);
|
||||
gGL.vertex2f(screen_right, screen_top);
|
||||
for (S32 bottom = 0; bottom < height; bottom += screen_height)
|
||||
{
|
||||
S32 top = bottom + screen_height;
|
||||
top = llmin(top, height);
|
||||
|
||||
gGL.end();
|
||||
F32 bottom_tc = (F32)bottom / height;
|
||||
F32 top_tc = (F32)(bottom + screen_height) / height;
|
||||
top_tc = llmin(top_tc, 1.f);
|
||||
|
||||
gGL.flush();
|
||||
F32 screen_right = (F32)(right - left) / screen_width;
|
||||
F32 screen_top = (F32)(top - bottom) / screen_height;
|
||||
|
||||
S32 w = right-left;
|
||||
S32 h = top-bottom;
|
||||
gGL.begin(LLRender::TRIANGLE_STRIP);
|
||||
gGL.texCoord2f(left_tc, bottom_tc);
|
||||
gGL.vertex2f(0, 0);
|
||||
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, left, bottom, 0, 0, w, h);
|
||||
}
|
||||
}
|
||||
gGL.texCoord2f(left_tc, top_tc);
|
||||
gGL.vertex2f(0, screen_top);
|
||||
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
gGL.texCoord2f(right_tc, bottom_tc);
|
||||
gGL.vertex2f(screen_right, 0);
|
||||
|
||||
gPipeline.mScreen.flush();
|
||||
gGL.texCoord2f(right_tc, top_tc);
|
||||
gGL.vertex2f(screen_right, screen_top);
|
||||
|
||||
gNormalMapGenProgram.unbind();
|
||||
|
||||
//generateNormalMapFromAlpha(dst_image, nrm_image);
|
||||
}
|
||||
gGL.end();
|
||||
|
||||
gGL.flush();
|
||||
|
||||
S32 w = right - left;
|
||||
S32 h = top - bottom;
|
||||
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, left, bottom, 0, 0, w, h);
|
||||
}
|
||||
}
|
||||
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
|
||||
gPipeline.mScreen.flush();
|
||||
|
||||
gNormalMapGenProgram.unbind();
|
||||
|
||||
//generateNormalMapFromAlpha(dst_image, nrm_image);
|
||||
|
||||
bump_ptr->unref();
|
||||
dst_ptr->unref();
|
||||
};
|
||||
|
||||
auto main_queue = LLImageGLThread::sEnabled ? sMainQueue.lock() : nullptr;
|
||||
|
||||
if (main_queue)
|
||||
{ //dispatch creation to background thread
|
||||
LLImageRaw* dst_ptr = dst_image;
|
||||
LLViewerTexture* bump_ptr = bump;
|
||||
dst_ptr->ref();
|
||||
bump_ptr->ref();
|
||||
|
||||
main_queue->postTo(sTexUpdateQueue, create_texture, gen_normal_map);
|
||||
}
|
||||
else
|
||||
{
|
||||
create_texture();
|
||||
gen_normal_map();
|
||||
}
|
||||
}
|
||||
|
||||
iter->second = bump; // derefs (and deletes) old image
|
||||
|
|
|
|||
|
|
@ -161,6 +161,8 @@ private:
|
|||
typedef std::unordered_map<LLUUID, LLPointer<LLViewerTexture> > bump_image_map_t;
|
||||
bump_image_map_t mBrightnessEntries;
|
||||
bump_image_map_t mDarknessEntries;
|
||||
static LL::WorkQueue::weak_t sMainQueue;
|
||||
static LL::WorkQueue::weak_t sTexUpdateQueue;
|
||||
};
|
||||
|
||||
extern LLBumpImageList gBumpImageList;
|
||||
|
|
|
|||
|
|
@ -288,6 +288,10 @@ void LLNetMap::setScale( F32 scale )
|
|||
|
||||
void LLNetMap::draw()
|
||||
{
|
||||
if (!LLWorld::instanceExists())
|
||||
{
|
||||
return;
|
||||
}
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
static LLFrameTimer map_timer;
|
||||
|
||||
|
|
|
|||
|
|
@ -243,17 +243,8 @@ BOOL LLVisualParamHint::render()
|
|||
|
||||
LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE);
|
||||
|
||||
if (gAgentAvatarp->mDrawable.notNull() &&
|
||||
gAgentAvatarp->mDrawable->getFace(0))
|
||||
{
|
||||
LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)gAgentAvatarp->mDrawable->getFace(0)->getPool();
|
||||
LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE);
|
||||
gGL.flush();
|
||||
gGL.setSceneBlendType(LLRender::BT_REPLACE);
|
||||
avatarPoolp->renderAvatars(gAgentAvatarp); // renders only one avatar
|
||||
gGL.setSceneBlendType(LLRender::BT_ALPHA);
|
||||
gGL.flush();
|
||||
}
|
||||
gPipeline.previewAvatar(gAgentAvatarp);
|
||||
|
||||
gAgentAvatarp->setVisualParamWeight(mVisualParam->getID(), mLastParamWeight);
|
||||
// <FS:Ansariel> [Legacy Bake]
|
||||
//mWearablePtr->setVisualParamWeight(mVisualParam->getID(), mLastParamWeight);
|
||||
|
|
|
|||
|
|
@ -110,11 +110,16 @@ void LLTracker::stopTracking(bool clear_ui)
|
|||
// static virtual
|
||||
void LLTracker::drawHUDArrow()
|
||||
{
|
||||
// <FS:Ansariel> Performance improvement
|
||||
//if (!gSavedSettings.getBOOL("RenderTrackerBeacon")) return;
|
||||
static LLCachedControl<bool> renderTrackerBeacon(gSavedSettings, "RenderTrackerBeacon");
|
||||
if (!renderTrackerBeacon) return;
|
||||
// </FS:Ansariel>
|
||||
if (!LLWorld::instanceExists())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static LLCachedControl<bool> render_beacon(gSavedSettings, "RenderTrackerBeacon", true);
|
||||
if (!render_beacon)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (gViewerWindow->getProgressView()->getVisible()) return;
|
||||
|
||||
|
|
|
|||
|
|
@ -764,9 +764,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
|
|||
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD_PARTICLES);
|
||||
}
|
||||
|
||||
//upkeep gl name pools
|
||||
LLGLNamePool::upkeepPools();
|
||||
|
||||
stop_glerror();
|
||||
display_update_camera();
|
||||
stop_glerror();
|
||||
|
|
|
|||
|
|
@ -3047,11 +3047,12 @@ void LLViewerMediaImpl::doMediaTexUpdate(LLViewerMediaTexture* media_tex, U8* da
|
|||
LLPointer<LLImageRaw> raw = new LLImageRaw(data, media_tex->getWidth(), media_tex->getHeight(), media_tex->getComponents(), true);
|
||||
|
||||
// Allocate GL texture based on LLImageRaw but do NOT copy to GL
|
||||
media_tex->createGLTexture(0, raw, 0, TRUE, LLGLTexture::OTHER, true);
|
||||
LLGLuint tex_name = 0;
|
||||
media_tex->createGLTexture(0, raw, 0, TRUE, LLGLTexture::OTHER, true, &tex_name);
|
||||
|
||||
// copy just the subimage covered by the image raw to GL
|
||||
media_tex->setSubImage(data, data_width, data_height, x_pos, y_pos, width, height, sync);
|
||||
media_tex->getGLTexture()->syncToMainThread();
|
||||
media_tex->setSubImage(data, data_width, data_height, x_pos, y_pos, width, height, tex_name);
|
||||
media_tex->getGLTexture()->syncToMainThread(tex_name);
|
||||
|
||||
// release the data pointer before freeing raw so LLImageRaw destructor doesn't
|
||||
// free memory at data pointer
|
||||
|
|
|
|||
|
|
@ -787,42 +787,39 @@ void LLViewerOctreeGroup::checkStates()
|
|||
//occulsion culling functions and classes
|
||||
//-------------------------------------------------------------------------------------------
|
||||
std::set<U32> LLOcclusionCullingGroup::sPendingQueries;
|
||||
class LLOcclusionQueryPool : public LLGLNamePool
|
||||
{
|
||||
public:
|
||||
LLOcclusionQueryPool()
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
static std::queue<GLuint> sFreeQueries;
|
||||
|
||||
virtual GLuint allocateName()
|
||||
{
|
||||
GLuint ret = 0;
|
||||
#define QUERY_POOL_SIZE 1024
|
||||
|
||||
glGenQueriesARB(1, &ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
virtual void releaseName(GLuint name)
|
||||
{
|
||||
#if LL_TRACK_PENDING_OCCLUSION_QUERIES
|
||||
LLOcclusionCullingGroup::sPendingQueries.erase(name);
|
||||
#endif
|
||||
glDeleteQueriesARB(1, &name);
|
||||
}
|
||||
};
|
||||
|
||||
static LLOcclusionQueryPool sQueryPool;
|
||||
U32 LLOcclusionCullingGroup::getNewOcclusionQueryObjectName()
|
||||
{
|
||||
return sQueryPool.allocate();
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_OCTREE;
|
||||
|
||||
if (sFreeQueries.empty())
|
||||
{
|
||||
//seed 1024 query names into the free query pool
|
||||
GLuint queries[1024];
|
||||
glGenQueriesARB(1024, queries);
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
sFreeQueries.push(queries[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// pull from pool
|
||||
GLuint ret = sFreeQueries.front();
|
||||
sFreeQueries.pop();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void LLOcclusionCullingGroup::releaseOcclusionQueryObjectName(GLuint name)
|
||||
{
|
||||
sQueryPool.release(name);
|
||||
if (name != 0)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_OCTREE;
|
||||
sFreeQueries.push(name);
|
||||
}
|
||||
}
|
||||
|
||||
//=====================================
|
||||
|
|
@ -1243,7 +1240,14 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh
|
|||
//store which frame this query was issued on
|
||||
mOcclusionIssued[LLViewerCamera::sCurCameraID] = gFrameCount;
|
||||
|
||||
glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]);
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_OCTREE("glBeginQuery");
|
||||
|
||||
//get an occlusion query that hasn't been used in awhile
|
||||
releaseOcclusionQueryObjectName(mOcclusionQuery[LLViewerCamera::sCurCameraID]);
|
||||
mOcclusionQuery[LLViewerCamera::sCurCameraID] = getNewOcclusionQueryObjectName();
|
||||
glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]);
|
||||
}
|
||||
|
||||
LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
|
||||
llassert(shader);
|
||||
|
|
@ -1282,7 +1286,10 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh
|
|||
}
|
||||
}
|
||||
|
||||
glEndQueryARB(mode);
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_OCTREE("glEndQuery");
|
||||
glEndQueryARB(mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -551,9 +551,10 @@ void LLViewerTexture::getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &p
|
|||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
static LLFrameTimer timer;
|
||||
|
||||
static S32Megabytes gpu_res = S32Megabytes(S32_MAX);
|
||||
static S32Megabytes physical_res = S32Megabytes(S32_MAX);
|
||||
|
||||
|
||||
if (timer.getElapsedTimeF32() < GPU_MEMORY_CHECK_WAIT_TIME) //call this once per second.
|
||||
{
|
||||
gpu = gpu_res;
|
||||
|
|
@ -563,30 +564,11 @@ void LLViewerTexture::getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &p
|
|||
timer.reset();
|
||||
|
||||
{
|
||||
if (gGLManager.mHasATIMemInfo)
|
||||
{
|
||||
S32 meminfo[4];
|
||||
glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo);
|
||||
gpu_res = (S32Megabytes)meminfo[0];
|
||||
|
||||
// <FS:Ansariel> Maybe do this independently from AMD cards????
|
||||
//check main memory, only works for windows.
|
||||
//LLMemory::updateMemoryInfo();
|
||||
//physical_res = LLMemory::getAvailableMemKB();
|
||||
// </FS:Ansariel>
|
||||
}
|
||||
else if (gGLManager.mHasNVXMemInfo)
|
||||
{
|
||||
S32 free_memory;
|
||||
glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &free_memory);
|
||||
gpu_res = (S32Megabytes)(free_memory / 1024);
|
||||
}
|
||||
|
||||
// <FS:Ansariel> Maybe do this independently from AMD cards????
|
||||
gpu_res = (S32Megabytes) LLImageGLThread::getFreeVRAMMegabytes();
|
||||
|
||||
//check main memory, only works for windows.
|
||||
LLMemory::updateMemoryInfo();
|
||||
physical_res = LLMemory::getAvailableMemKB();
|
||||
// </FS:Ansariel>
|
||||
|
||||
gpu = gpu_res;
|
||||
physical = physical_res;
|
||||
|
|
|
|||
|
|
@ -639,6 +639,7 @@ F32 LLVOAvatar::sUnbakedTime = 0.f;
|
|||
F32 LLVOAvatar::sUnbakedUpdateTime = 0.f;
|
||||
F32 LLVOAvatar::sGreyTime = 0.f;
|
||||
F32 LLVOAvatar::sGreyUpdateTime = 0.f;
|
||||
LLPointer<LLViewerTexture> LLVOAvatar::sCloudTexture = NULL;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Helper functions
|
||||
|
|
@ -1220,6 +1221,7 @@ void LLVOAvatar::initClass()
|
|||
|
||||
LLControlAvatar::sRegionChangedSlot = gAgent.addRegionChangedCallback(&LLControlAvatar::onRegionChanged);
|
||||
|
||||
sCloudTexture = LLViewerTextureManager::getFetchedTextureFromFile("cloud-particle.j2c");
|
||||
initCloud();
|
||||
}
|
||||
|
||||
|
|
@ -1248,8 +1250,7 @@ void LLVOAvatar::initCloud()
|
|||
// </FS:ND>
|
||||
LLSDSerialize::fromXMLDocument(cloud, in_file);
|
||||
sCloud.fromLLSD(cloud);
|
||||
LLViewerTexture* cloud_texture = LLViewerTextureManager::getFetchedTextureFromFile("cloud-particle.j2c");
|
||||
sCloud.mPartImageID = cloud_texture->getID();
|
||||
sCloud.mPartImageID = sCloudTexture->getID();
|
||||
|
||||
//Todo: have own image, de-copy-pasta
|
||||
LLSD cloud_muted;
|
||||
|
|
@ -3316,8 +3317,7 @@ void LLVOAvatar::idleUpdateLoadingEffect()
|
|||
// particle_parameters.mPartData.mStartColor = LLColor4(1, 1, 1, 0.5f);
|
||||
// particle_parameters.mPartData.mEndColor = LLColor4(1, 1, 1, 0.0f);
|
||||
// particle_parameters.mPartData.mStartScale.mV[VX] = 0.8f;
|
||||
// LLViewerTexture* cloud = LLViewerTextureManager::getFetchedTextureFromFile("cloud-particle.j2c");
|
||||
// particle_parameters.mPartImageID = cloud->getID();
|
||||
// particle_parameters.mPartImageID = sCloudTexture->getID();
|
||||
// particle_parameters.mMaxAge = 0.f;
|
||||
// particle_parameters.mPattern = LLPartSysData::LL_PART_SRC_PATTERN_ANGLE_CONE;
|
||||
// particle_parameters.mInnerAngle = F_PI;
|
||||
|
|
|
|||
|
|
@ -352,10 +352,11 @@ public:
|
|||
static F32 sLODFactor; // user-settable LOD factor
|
||||
static F32 sPhysicsLODFactor; // user-settable physics LOD factor
|
||||
static BOOL sJointDebug; // output total number of joints being touched for each avatar
|
||||
static BOOL sDebugAvatarRotation;
|
||||
static U64 sRenderTimeLimit_ns; // <FS:Beq/> nanosecond time limit for avatar rendering 0 is unlimited.
|
||||
static LLPartSysData sCloud;
|
||||
|
||||
static LLPointer<LLViewerTexture> sCloudTexture;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Region state
|
||||
//--------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -242,6 +242,7 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re
|
|||
mNumFaces = 0;
|
||||
mLODChanged = FALSE;
|
||||
mSculptChanged = FALSE;
|
||||
mColorChanged = FALSE;
|
||||
mSpotLightPriority = 0.f;
|
||||
|
||||
mMediaImplList.resize(getNumTEs());
|
||||
|
|
@ -2216,7 +2217,7 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
|
|||
was_regen_faces = lodOrSculptChanged(drawable, compiled);
|
||||
drawable->setState(LLDrawable::REBUILD_VOLUME);
|
||||
}
|
||||
else if (mSculptChanged || mLODChanged)
|
||||
else if (mSculptChanged || mLODChanged || mColorChanged)
|
||||
{
|
||||
compiled = TRUE;
|
||||
was_regen_faces = lodOrSculptChanged(drawable, compiled);
|
||||
|
|
@ -2228,7 +2229,7 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
|
|||
|
||||
genBBoxes(FALSE);
|
||||
}
|
||||
else if (mLODChanged || mSculptChanged)
|
||||
else if (mLODChanged || mSculptChanged || mColorChanged)
|
||||
{
|
||||
dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1));
|
||||
compiled = TRUE;
|
||||
|
|
@ -2267,6 +2268,7 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
|
|||
mLODChanged = FALSE;
|
||||
mSculptChanged = FALSE;
|
||||
mFaceMappingChanged = FALSE;
|
||||
mColorChanged = FALSE;
|
||||
|
||||
return LLViewerObject::updateGeometry(drawable);
|
||||
}
|
||||
|
|
@ -2405,6 +2407,7 @@ S32 LLVOVolume::setTEColor(const U8 te, const LLColor4& color)
|
|||
if (mDrawable.notNull() && retval)
|
||||
{
|
||||
// These should only happen on updates which are not the initial update.
|
||||
mColorChanged = TRUE;
|
||||
mDrawable->setState(LLDrawable::REBUILD_COLOR);
|
||||
dirtyMesh();
|
||||
}
|
||||
|
|
@ -6226,23 +6229,25 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
|
|||
|
||||
U32 geometryBytes = 0;
|
||||
|
||||
// generate render batches for static geometry
|
||||
U32 extra_mask = LLVertexBuffer::MAP_TEXTURE_INDEX;
|
||||
geometryBytes += genDrawInfo(group, simple_mask | extra_mask, sSimpleFaces[0], simple_count[0], FALSE, batch_textures);
|
||||
geometryBytes += genDrawInfo(group, fullbright_mask | extra_mask, sFullbrightFaces[0], fullbright_count[0], FALSE, batch_textures);
|
||||
geometryBytes += genDrawInfo(group, alpha_mask | extra_mask, sAlphaFaces[0], alpha_count[0], TRUE, batch_textures);
|
||||
geometryBytes += genDrawInfo(group, bump_mask | extra_mask, sBumpFaces[0], bump_count[0], FALSE, FALSE);
|
||||
geometryBytes += genDrawInfo(group, norm_mask | extra_mask, sNormFaces[0], norm_count[0], FALSE, FALSE);
|
||||
geometryBytes += genDrawInfo(group, spec_mask | extra_mask, sSpecFaces[0], spec_count[0], FALSE, FALSE);
|
||||
geometryBytes += genDrawInfo(group, normspec_mask | extra_mask, sNormSpecFaces[0], normspec_count[0], FALSE, FALSE);
|
||||
BOOL alpha_sort = TRUE;
|
||||
BOOL rigged = FALSE;
|
||||
for (int i = 0; i < 2; ++i) //two sets, static and rigged)
|
||||
{
|
||||
geometryBytes += genDrawInfo(group, simple_mask | extra_mask, sSimpleFaces[i], simple_count[i], FALSE, batch_textures, rigged);
|
||||
geometryBytes += genDrawInfo(group, fullbright_mask | extra_mask, sFullbrightFaces[i], fullbright_count[i], FALSE, batch_textures, rigged);
|
||||
geometryBytes += genDrawInfo(group, alpha_mask | extra_mask, sAlphaFaces[i], alpha_count[i], alpha_sort, batch_textures, rigged);
|
||||
geometryBytes += genDrawInfo(group, bump_mask | extra_mask, sBumpFaces[i], bump_count[i], FALSE, FALSE, rigged);
|
||||
geometryBytes += genDrawInfo(group, norm_mask | extra_mask, sNormFaces[i], norm_count[i], FALSE, FALSE, rigged);
|
||||
geometryBytes += genDrawInfo(group, spec_mask | extra_mask, sSpecFaces[i], spec_count[i], FALSE, FALSE, rigged);
|
||||
geometryBytes += genDrawInfo(group, normspec_mask | extra_mask, sNormSpecFaces[i], normspec_count[i], FALSE, FALSE, rigged);
|
||||
|
||||
extra_mask |= LLVertexBuffer::MAP_WEIGHT4;
|
||||
geometryBytes += genDrawInfo(group, simple_mask | extra_mask, sSimpleFaces[1], simple_count[1], FALSE, batch_textures, TRUE);
|
||||
geometryBytes += genDrawInfo(group, fullbright_mask | extra_mask, sFullbrightFaces[1], fullbright_count[1], FALSE, batch_textures, TRUE);
|
||||
geometryBytes += genDrawInfo(group, alpha_mask | extra_mask, sAlphaFaces[1], alpha_count[1], TRUE, batch_textures, TRUE);
|
||||
geometryBytes += genDrawInfo(group, bump_mask | extra_mask, sBumpFaces[1], bump_count[1], FALSE, TRUE);
|
||||
geometryBytes += genDrawInfo(group, norm_mask | extra_mask, sNormFaces[1], norm_count[1], FALSE, TRUE);
|
||||
geometryBytes += genDrawInfo(group, spec_mask | extra_mask, sSpecFaces[1], spec_count[1], FALSE, TRUE);
|
||||
geometryBytes += genDrawInfo(group, normspec_mask | extra_mask, sNormSpecFaces[1], normspec_count[1], FALSE, TRUE);
|
||||
// for rigged set, add weights and disable alpha sorting (rigged items use depth buffer)
|
||||
extra_mask |= LLVertexBuffer::MAP_WEIGHT4;
|
||||
alpha_sort = FALSE;
|
||||
rigged = TRUE;
|
||||
}
|
||||
|
||||
group->mGeometryBytes = geometryBytes;
|
||||
|
||||
|
|
|
|||
|
|
@ -423,6 +423,7 @@ private:
|
|||
S32 mLOD;
|
||||
BOOL mLODChanged;
|
||||
BOOL mSculptChanged;
|
||||
BOOL mColorChanged;
|
||||
F32 mSpotLightPriority;
|
||||
LLMatrix4 mRelativeXform;
|
||||
LLMatrix3 mRelativeXformInvTrans;
|
||||
|
|
|
|||
|
|
@ -7492,11 +7492,6 @@ void LLPipeline::doResetVertexBuffers(bool forced)
|
|||
|
||||
SUBSYSTEM_CLEANUP(LLVertexBuffer);
|
||||
|
||||
//delete all name pool caches
|
||||
LLGLNamePool::cleanupPools();
|
||||
|
||||
|
||||
|
||||
if (LLVertexBuffer::sGLCount > 0)
|
||||
{
|
||||
LL_WARNS() << "VBO wipe failed -- " << LLVertexBuffer::sGLCount << " buffers remaining." << LL_ENDL;
|
||||
|
|
@ -11503,6 +11498,176 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
|
|||
LLGLState::checkTextureChannels();
|
||||
}
|
||||
|
||||
static LLTrace::BlockTimerStatHandle FTM_PREVIEW_AVATAR("Preview Avatar");
|
||||
|
||||
void LLPipeline::previewAvatar(LLVOAvatar* avatar)
|
||||
{
|
||||
LL_RECORD_BLOCK_TIME(FTM_PREVIEW_AVATAR);
|
||||
|
||||
LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE);
|
||||
gGL.flush();
|
||||
gGL.setSceneBlendType(LLRender::BT_REPLACE);
|
||||
|
||||
LLGLState::checkStates();
|
||||
LLGLState::checkTextureChannels();
|
||||
|
||||
static LLCullResult result;
|
||||
result.clear();
|
||||
grabReferences(result);
|
||||
|
||||
if (!avatar || !avatar->mDrawable)
|
||||
{
|
||||
LL_WARNS_ONCE("AvatarRenderPipeline") << "Avatar is " << (avatar ? "not drawable" : "null") << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
LL_DEBUGS_ONCE("AvatarRenderPipeline") << "Avatar " << avatar->getID() << " is drawable" << LL_ENDL;
|
||||
|
||||
assertInitialized();
|
||||
|
||||
pushRenderTypeMask();
|
||||
|
||||
{
|
||||
//hide world geometry
|
||||
clearRenderTypeMask(
|
||||
RENDER_TYPE_SKY,
|
||||
RENDER_TYPE_WL_SKY,
|
||||
RENDER_TYPE_GROUND,
|
||||
RENDER_TYPE_TERRAIN,
|
||||
RENDER_TYPE_GRASS,
|
||||
RENDER_TYPE_CONTROL_AV, // Animesh
|
||||
RENDER_TYPE_TREE,
|
||||
RENDER_TYPE_VOIDWATER,
|
||||
RENDER_TYPE_WATER,
|
||||
RENDER_TYPE_PASS_GRASS,
|
||||
RENDER_TYPE_HUD,
|
||||
RENDER_TYPE_PARTICLES,
|
||||
RENDER_TYPE_CLOUDS,
|
||||
RENDER_TYPE_HUD_PARTICLES,
|
||||
END_RENDER_TYPES
|
||||
);
|
||||
}
|
||||
|
||||
S32 occlusion = sUseOcclusion;
|
||||
sUseOcclusion = 0;
|
||||
|
||||
sReflectionRender = !sRenderDeferred;
|
||||
|
||||
sShadowRender = true;
|
||||
sImpostorRender = true; // Likely not needed for previews
|
||||
|
||||
LLViewerCamera* viewer_camera = LLViewerCamera::getInstance();
|
||||
|
||||
{
|
||||
markVisible(avatar->mDrawable, *viewer_camera);
|
||||
|
||||
LLVOAvatar::attachment_map_t::iterator iter;
|
||||
for (iter = avatar->mAttachmentPoints.begin();
|
||||
iter != avatar->mAttachmentPoints.end();
|
||||
++iter)
|
||||
{
|
||||
LLViewerJointAttachment *attachment = iter->second;
|
||||
for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
|
||||
attachment_iter != attachment->mAttachedObjects.end();
|
||||
++attachment_iter)
|
||||
{
|
||||
if (LLViewerObject* attached_object = attachment_iter->get())
|
||||
{
|
||||
markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stateSort(*LLViewerCamera::getInstance(), result);
|
||||
|
||||
LLCamera camera = *viewer_camera;
|
||||
|
||||
F32 old_alpha = LLDrawPoolAvatar::sMinimumAlpha;
|
||||
|
||||
if (LLPipeline::sRenderDeferred)
|
||||
{
|
||||
renderGeomDeferred(camera);
|
||||
|
||||
renderGeomPostDeferred(camera);
|
||||
}
|
||||
else
|
||||
{
|
||||
renderGeom(camera);
|
||||
}
|
||||
|
||||
LLDrawPoolAvatar::sMinimumAlpha = old_alpha;
|
||||
|
||||
{ //create alpha mask based on depth buffer
|
||||
if (LLPipeline::sRenderDeferred)
|
||||
{
|
||||
GLuint buff = GL_COLOR_ATTACHMENT0;
|
||||
LL_PROFILER_GPU_ZONEC("gl.DrawBuffersARB", 0x8000FF);
|
||||
glDrawBuffersARB(1, &buff);
|
||||
}
|
||||
|
||||
LLGLDisable blend(GL_BLEND);
|
||||
|
||||
gGL.setColorMask(false, true);
|
||||
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
|
||||
LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_GREATER);
|
||||
|
||||
gGL.flush();
|
||||
|
||||
gGL.pushMatrix();
|
||||
gGL.loadIdentity();
|
||||
gGL.matrixMode(LLRender::MM_PROJECTION);
|
||||
gGL.pushMatrix();
|
||||
gGL.loadIdentity();
|
||||
|
||||
static const F32 clip_plane = 0.99999f;
|
||||
|
||||
gDebugProgram.bind();
|
||||
|
||||
// <FS:Ansariel> Remove QUADS rendering mode
|
||||
//gGL.begin(LLRender::QUADS);
|
||||
//gGL.vertex3f(-1, -1, clip_plane);
|
||||
//gGL.vertex3f(1, -1, clip_plane);
|
||||
//gGL.vertex3f(1, 1, clip_plane);
|
||||
//gGL.vertex3f(-1, 1, clip_plane);
|
||||
gGL.begin(LLRender::TRIANGLES);
|
||||
gGL.vertex3f(-1, -1, clip_plane);
|
||||
gGL.vertex3f(1, -1, clip_plane);
|
||||
gGL.vertex3f(1, 1, clip_plane);
|
||||
gGL.vertex3f(-1, -1, clip_plane);
|
||||
gGL.vertex3f(1, 1, clip_plane);
|
||||
gGL.vertex3f(-1, 1, clip_plane);
|
||||
// </FS:Ansariel>
|
||||
gGL.end();
|
||||
gGL.flush();
|
||||
|
||||
gDebugProgram.unbind();
|
||||
|
||||
gGL.popMatrix();
|
||||
gGL.matrixMode(LLRender::MM_MODELVIEW);
|
||||
gGL.popMatrix();
|
||||
}
|
||||
|
||||
sUseOcclusion = occlusion;
|
||||
sReflectionRender = false;
|
||||
sImpostorRender = false;
|
||||
sShadowRender = false;
|
||||
popRenderTypeMask();
|
||||
|
||||
gGL.matrixMode(LLRender::MM_PROJECTION);
|
||||
gGL.popMatrix();
|
||||
gGL.matrixMode(LLRender::MM_MODELVIEW);
|
||||
gGL.popMatrix();
|
||||
|
||||
LLVertexBuffer::unbind();
|
||||
LLGLState::checkStates();
|
||||
LLGLState::checkTextureChannels();
|
||||
|
||||
gGL.setSceneBlendType(LLRender::BT_ALPHA);
|
||||
gGL.flush();
|
||||
}
|
||||
|
||||
bool LLPipeline::hasRenderBatches(const U32 type) const
|
||||
{
|
||||
return sCull->getRenderMapSize(type) > 0;
|
||||
|
|
|
|||
|
|
@ -135,6 +135,7 @@ public:
|
|||
|
||||
void resetVertexBuffers(LLDrawable* drawable);
|
||||
void generateImpostor(LLVOAvatar* avatar);
|
||||
void previewAvatar(LLVOAvatar* avatar);
|
||||
void bindScreenToTexture();
|
||||
void renderFinalize();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue