Merge remote-tracking branch 'upstream/master'
This commit is contained in:
@@ -138,7 +138,7 @@ namespace HACD
|
||||
if (m_callBack)
|
||||
{
|
||||
char msg[1024];
|
||||
sprintf(msg, "nCC %lu\n", m_graph.m_nCCs);
|
||||
sprintf(msg, "nCC %zu\n", m_graph.m_nCCs);
|
||||
(*m_callBack)(msg, 0.0, 0.0, m_graph.GetNVertices());
|
||||
|
||||
}
|
||||
@@ -879,7 +879,7 @@ namespace HACD
|
||||
if (m_callBack)
|
||||
{
|
||||
char msg[1024];
|
||||
sprintf(msg, "\t CH(%zu) \t %zu \t %lf \t %zu \t %f \t %zu\n", v, static_cast<unsigned long>(p), m_graph.m_vertices[v].m_concavity, m_graph.m_vertices[v].m_distPoints.Size(), m_graph.m_vertices[v].m_surf*100.0/m_area, m_graph.m_vertices[v].m_ancestors.size());
|
||||
sprintf(msg, "\t CH(%zu) \t %zu \t %lf \t %zu \t %f \t %zu\n", v, p, m_graph.m_vertices[v].m_concavity, m_graph.m_vertices[v].m_distPoints.Size(), m_graph.m_vertices[v].m_surf*100.0/m_area, m_graph.m_vertices[v].m_ancestors.size());
|
||||
(*m_callBack)(msg, 0.0, 0.0, m_nClusters);
|
||||
p++;
|
||||
}
|
||||
|
||||
@@ -1126,7 +1126,10 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height)
|
||||
// *TODO: Is this correct?
|
||||
//gPipeline.disableLights();
|
||||
stop_glerror();
|
||||
glDisable(GL_LIGHTING);
|
||||
if (!LLGLSLShader::sNoFixedFunction)
|
||||
{
|
||||
glDisable(GL_LIGHTING);
|
||||
}
|
||||
stop_glerror();
|
||||
|
||||
bool use_shaders = LLGLSLShader::sNoFixedFunction;
|
||||
|
||||
@@ -284,13 +284,14 @@ void LLAudioEngine::updateChannels()
|
||||
checkStates();
|
||||
}
|
||||
|
||||
typedef std::pair<LLAudioSource*,F32> audio_source_t;
|
||||
struct SourcePriorityComparator
|
||||
{
|
||||
bool operator() (const audio_source_t& lhs, const audio_source_t& rhs) const
|
||||
bool operator() (const LLAudioSource* lhs, const LLAudioSource* rhs) const
|
||||
{
|
||||
//Sort by priority value. If equal, sync masters get higher priority.
|
||||
return lhs.second < rhs.second || (lhs.second == rhs.second && !lhs.first->isSyncMaster() && rhs.first->isSyncMaster());
|
||||
if(rhs->getPriority() != lhs->getPriority())
|
||||
return rhs->getPriority() > lhs->getPriority();
|
||||
else
|
||||
return ((rhs->isSyncMaster() && !lhs->isSyncMaster()) || (rhs->isSyncSlave() && (!lhs->isSyncMaster() && !lhs->isSyncSlave())));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -319,10 +320,21 @@ void LLAudioEngine::idle(F32 max_decode_time)
|
||||
LLAudioSource *sync_masterp = NULL; //Highest priority syncmaster
|
||||
LLAudioSource *sync_slavep = NULL; //Highest priority syncslave
|
||||
|
||||
//Priority queue that will be filled with soundsources that have a high likeleyhood of being able to start [re]playing this idle tick.
|
||||
//Sort order: Primary: priority. Secondary: syncmaster. Tertiary: syncslave
|
||||
std::priority_queue<LLAudioSource*,std::vector<LLAudioSource*,boost::pool_allocator<LLAudioSource*> >,SourcePriorityComparator> queue;
|
||||
|
||||
//Have to put syncslaves into a temporary list until the syncmaster state is determined.
|
||||
//If the syncmaster might be started, or just looped, insert all pending/looping syncslaves into the priority queue.
|
||||
//If the there is no active syncmaster, then stop any currently looping syncslaves and add none to the priority queue.
|
||||
//This is necessary as any looping soundsources to be stopped, MUST be stopped before iterating down the priority queue.
|
||||
static std::vector<LLAudioSource*> slave_list;
|
||||
slave_list.clear();
|
||||
|
||||
//Iterate over all sources. Update their decode or 'done' state, as well as their priorities.
|
||||
//Also add sources that might be able to start playing to a priority queue.
|
||||
//Only sources without channels, or are waiting for a syncmaster, should be added to this queue.
|
||||
std::priority_queue<audio_source_t,std::vector<audio_source_t,boost::pool_allocator<audio_source_t> >,SourcePriorityComparator> queue;
|
||||
//Also add sources that might be able to start playing to the priority queue.
|
||||
//Only sources without channels should be added to priority queue.
|
||||
//Syncslaves must put into the slave list instead of the priority queue.
|
||||
for (source_map::iterator iter = mAllSources.begin(); iter != mAllSources.end();)
|
||||
{
|
||||
LLAudioSource *sourcep = iter->second;
|
||||
@@ -360,34 +372,32 @@ void LLAudioEngine::idle(F32 max_decode_time)
|
||||
{
|
||||
if(!sync_masterp || sourcep->getPriority() > sync_masterp->getPriority())
|
||||
{
|
||||
if(sync_masterp && !sync_masterp->getChannel())
|
||||
queue.push(sync_masterp); //Add lower-priority soundmaster to the queue as a normal sound.
|
||||
sync_masterp = sourcep;
|
||||
//Don't add master to the queue yet.
|
||||
//Add it after highest-priority sound slave is found so we can outrank its priority.
|
||||
continue;
|
||||
}
|
||||
//This is a hack. Don't add master to the queue yet.
|
||||
//Add it after highest-priority sound slave is found so we can outrank its priority.
|
||||
continue;
|
||||
//Else fall through like a normal sound.
|
||||
}
|
||||
else if(sourcep->isSyncSlave())
|
||||
{
|
||||
//Only care about syncslaves without channel, or are looping.
|
||||
if(!sourcep->getChannel() || sourcep->isLoop() )
|
||||
if(!sync_slavep || sourcep->getPriority() > sync_slavep->getPriority())
|
||||
{
|
||||
if(!sync_slavep || sourcep->getPriority() > sync_slavep->getPriority())
|
||||
{
|
||||
sync_slavep = sourcep;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
sync_slavep = sourcep;
|
||||
}
|
||||
//Don't add to the priority queue quite yet. Best primary syncmaster candidate may not have been determined yet.
|
||||
slave_list.push_back(sourcep);
|
||||
continue;
|
||||
}
|
||||
else if(sourcep->getChannel())
|
||||
if(sourcep->getChannel())
|
||||
{
|
||||
//If this is just a regular sound and is currently playing then do nothing special.
|
||||
continue;
|
||||
}
|
||||
//Add to our queue. Highest priority will be at the front.
|
||||
queue.push(std::make_pair(sourcep,sourcep->getPriority()));
|
||||
queue.push(sourcep);
|
||||
}
|
||||
|
||||
// Do this BEFORE we update the channels
|
||||
@@ -395,47 +405,71 @@ void LLAudioEngine::idle(F32 max_decode_time)
|
||||
// such as changing what sound was playing.
|
||||
updateChannels();
|
||||
|
||||
//Syncmaster must have priority greater than or equal to priority of highest priority syncslave.
|
||||
if(sync_masterp && !sync_masterp->getChannel())
|
||||
//Loop over all syncsaves. If no syncmaster, stop looping ones, else add ones that need [re]started to the priority queue.
|
||||
//Normally there are zero to one syncslaves, so this loop isn't typically expensive.
|
||||
for(std::vector<LLAudioSource*>::iterator iter=slave_list.begin();iter!=slave_list.end();++iter)
|
||||
{
|
||||
if(!sync_masterp)
|
||||
{
|
||||
//Stop any looping syncslaves. I'm not sure this behavior is correct, but letting looping syncslaves run
|
||||
//off on their own seems wrong. The lsl documentation is unclear.
|
||||
if((*iter)->getChannel() && (*iter)->isLoop())
|
||||
{
|
||||
(*iter)->getChannel()->cleanup();
|
||||
}
|
||||
}
|
||||
//If the syncmaster already has a channel and hasn't looped, then we can skip syncslaves this idle tick (there's nothing to do).
|
||||
else if((!sync_masterp->getChannel() || sync_masterp->getChannel()->mLoopedThisFrame))
|
||||
{
|
||||
//Add syncslaves that we might want to [re]start.
|
||||
if(!(*iter)->getChannel() || (*iter)->isLoop())
|
||||
queue.push((*iter));
|
||||
}
|
||||
}
|
||||
|
||||
if(sync_masterp)
|
||||
{
|
||||
//Syncmaster must have priority greater than or equal to priority of highest priority syncslave.
|
||||
//The case of slave priority equaling master priority is handled in the comparator (SourcePriorityComparator).
|
||||
//Could have added an arbiturary small value to the priority, but the extra logic in the comparator is more correct.
|
||||
if(sync_slavep)
|
||||
queue.push(std::make_pair(sync_masterp, llmax(sync_slavep->getPriority(), sync_masterp->getPriority())));
|
||||
else
|
||||
queue.push(std::make_pair(sync_masterp, sync_masterp->getPriority()));
|
||||
sync_masterp->setPriority(sync_slavep->getPriority());
|
||||
if(!sync_masterp->getChannel())
|
||||
{
|
||||
queue.push(sync_masterp);
|
||||
}
|
||||
}
|
||||
|
||||
// Dispatch all soundsources.
|
||||
bool syncmaster_started = false;
|
||||
bool syncmaster_started = sync_masterp && sync_masterp->getChannel() && sync_masterp->getChannel()->mLoopedThisFrame;
|
||||
while(!queue.empty())
|
||||
{
|
||||
// This is lame, instead of this I could actually iterate through all the sources
|
||||
// attached to each channel, since only those with active channels
|
||||
// can have anything interesting happen with their queue? (Maybe not true)
|
||||
LLAudioSource *sourcep = queue.top().first;
|
||||
LLAudioSource *sourcep = queue.top();
|
||||
queue.pop();
|
||||
|
||||
if (sourcep->isSyncSlave())
|
||||
//If the syncmaster hasn't just started playing, or hasn't just looped then skip this soundslave,
|
||||
//as there's nothing to do with it yet.
|
||||
if (sourcep->isSyncSlave() && !syncmaster_started)
|
||||
{
|
||||
//If the syncmaster hasn't just started playing, or hasn't just looped then skip this soundslave.
|
||||
if(!sync_masterp || (!syncmaster_started && !(sync_masterp->getChannel() && sync_masterp->getChannel()->mLoopedThisFrame)))
|
||||
continue;
|
||||
continue;
|
||||
}
|
||||
|
||||
LLAudioChannel *channelp = sourcep->getChannel();
|
||||
|
||||
if (!channelp)
|
||||
{
|
||||
if(!(channelp = gAudiop->getFreeChannel(sourcep->getPriority())))
|
||||
continue; //No more channels. Don't abort the whole loop, however. Soundslaves might want to start up!
|
||||
|
||||
//If this is the syncmaster that just started then we need to update non-playing syncslaves.
|
||||
if(sourcep == sync_masterp)
|
||||
//No more channels. We can break here, as in theory, any lower priority sounds should have had their
|
||||
//channel already stolen. There should be nothing playing, nor playable, when iterating beyond this point.
|
||||
if(!(channelp = getFreeChannel(sourcep->getPriority())))
|
||||
{
|
||||
syncmaster_started = true;
|
||||
break;
|
||||
}
|
||||
channelp->setSource(sourcep); //setSource calls updateBuffer and update3DPosition, and resets the source mAgeTimer
|
||||
|
||||
//If this is the primary syncmaster that we just started, then [re]start syncslaves further down in the priority queue.
|
||||
//Due to sorting and priority fudgery, the syncmaster is ALWAYS before any syncslaves in this loop.
|
||||
syncmaster_started |= (sourcep == sync_masterp);
|
||||
|
||||
//setSource calls updateBuffer and update3DPosition, and resets the source mAgeTimer
|
||||
channelp->setSource(sourcep);
|
||||
}
|
||||
|
||||
if(sourcep->isSyncSlave())
|
||||
@@ -594,7 +628,7 @@ LLAudioChannel * LLAudioEngine::getFreeChannel(const F32 priority)
|
||||
}
|
||||
}
|
||||
|
||||
if (min_priority > priority || !min_channelp)
|
||||
if (!min_channelp || min_priority >= priority)
|
||||
{
|
||||
// All playing channels have higher priority, return.
|
||||
return NULL;
|
||||
@@ -1252,6 +1286,9 @@ void LLAudioEngine::startNextTransfer()
|
||||
// static
|
||||
void LLAudioEngine::assetCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type, void *user_data, S32 result_code, LLExtStat ext_status)
|
||||
{
|
||||
if(!gAudiop)
|
||||
return;
|
||||
|
||||
if (result_code)
|
||||
{
|
||||
LL_INFOS("AudioEngine") << "Boom, error in audio file transfer: " << LLAssetStorage::getErrorString( result_code ) << " (" << result_code << ")" << LL_ENDL;
|
||||
@@ -1408,11 +1445,11 @@ void LLAudioSource::updatePriority()
|
||||
{
|
||||
if (isAmbient())
|
||||
{
|
||||
mPriority = 1.f;
|
||||
setPriority(1.f);
|
||||
}
|
||||
else if (isMuted())
|
||||
{
|
||||
mPriority = 0.f;
|
||||
setPriority(0.f);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1422,7 +1459,7 @@ void LLAudioSource::updatePriority()
|
||||
dist_vec -= gAudiop->getListenerPos();
|
||||
F32 dist_squared = llmax(1.f, dist_vec.magVecSquared());
|
||||
|
||||
mPriority = mGain / dist_squared;
|
||||
setPriority(mGain / dist_squared);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1472,6 +1509,19 @@ bool LLAudioSource::play(const LLUUID &audio_uuid)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if(mCurrentDatap == adp) //Desired sound did not change. Just re-play it.
|
||||
{
|
||||
if(getChannel() && getChannel()->isPlaying())
|
||||
getChannel()->play();
|
||||
return true;
|
||||
}
|
||||
else //Desired sound did change. Release the old channel if set.
|
||||
{
|
||||
if(getChannel())
|
||||
getChannel()->cleanup();
|
||||
mPlayedOnce = false; //Reset the played flag so the new sound is actually started up.
|
||||
}
|
||||
|
||||
mCurrentDatap = adp;
|
||||
|
||||
// Make sure the audio engine knows that we want to request this sound.
|
||||
|
||||
@@ -316,6 +316,7 @@ public:
|
||||
LLVector3d getPositionGlobal() const { return mPositionGlobal; }
|
||||
LLVector3 getVelocity() const { return mVelocity; }
|
||||
F32 getPriority() const { return mPriority; }
|
||||
void setPriority(F32 priority) { mPriority = priority; }
|
||||
|
||||
// Gain should always be clamped between 0 and 1.
|
||||
F32 getGain() const { return mGain; }
|
||||
|
||||
@@ -590,6 +590,7 @@ void LLAudioChannelFMOD::cleanup()
|
||||
}
|
||||
|
||||
mChannelID = 0;
|
||||
mLastSamplePos = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -600,6 +601,12 @@ void LLAudioChannelFMOD::play()
|
||||
llwarns << "Playing without a channelID, aborting" << llendl;
|
||||
return;
|
||||
}
|
||||
|
||||
if(!FSOUND_IsPaused(mChannelID))
|
||||
{
|
||||
FSOUND_SetPaused(mChannelID, true);
|
||||
FSOUND_SetCurrentPosition(mChannelID, 0);
|
||||
}
|
||||
|
||||
if (!FSOUND_SetPaused(mChannelID, false))
|
||||
{
|
||||
|
||||
@@ -810,6 +810,7 @@ void LLAudioChannelFMODEX::cleanup()
|
||||
Check_FMOD_Error(mChannelp->stop(),"FMOD::Channel::stop");
|
||||
|
||||
mChannelp = NULL;
|
||||
mLastSamplePos = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -823,6 +824,13 @@ void LLAudioChannelFMODEX::play()
|
||||
|
||||
gSoundCheck.assertActiveState(this,true);
|
||||
|
||||
bool paused=true;
|
||||
Check_FMOD_Error(mChannelp->getPaused(&paused), "FMOD::Channel::getPaused");
|
||||
if(!paused)
|
||||
{
|
||||
Check_FMOD_Error(mChannelp->setPaused(true), "FMOD::Channel::setPaused");
|
||||
Check_FMOD_Error(mChannelp->setPosition(0,FMOD_TIMEUNIT_PCMBYTES), "FMOD::Channel::setPosition");
|
||||
}
|
||||
Check_FMOD_Error(mChannelp->setPaused(false), "FMOD::Channel::setPaused");
|
||||
|
||||
if(sVerboseDebugging)
|
||||
|
||||
@@ -189,6 +189,7 @@ void LLAudioChannelOpenAL::cleanup()
|
||||
LLAudioChannel::cleanup();
|
||||
alSourceStop(mALSource);
|
||||
alSourcei(mALSource, AL_BUFFER, AL_NONE);
|
||||
mLastSamplePos = 0;
|
||||
}
|
||||
|
||||
void LLAudioChannelOpenAL::play()
|
||||
@@ -199,11 +200,13 @@ void LLAudioChannelOpenAL::play()
|
||||
return;
|
||||
}
|
||||
|
||||
if(!isPlaying())
|
||||
if(isPlaying())
|
||||
{
|
||||
alSourcePlay(mALSource);
|
||||
getSource()->setPlayedOnce(true);
|
||||
alSourceStop(mALSource);
|
||||
}
|
||||
|
||||
alSourcePlay(mALSource);
|
||||
getSource()->setPlayedOnce(true);
|
||||
}
|
||||
|
||||
void LLAudioChannelOpenAL::playSynced(LLAudioChannel *channelp)
|
||||
|
||||
@@ -307,46 +307,12 @@ void LLApp::setupErrorHandling()
|
||||
// Install the Google Breakpad crash handler for Windows
|
||||
if(mExceptionHandler == 0)
|
||||
{
|
||||
llwarns << "adding breakpad exception handler" << llendl;
|
||||
|
||||
std::wostringstream ws;
|
||||
ws << mCrashReportPipeStr << getPid();
|
||||
std::wstring wpipe_name = ws.str();
|
||||
std::string ptmp = std::string(wpipe_name.begin(), wpipe_name.end());
|
||||
|
||||
::Sleep(2000); //HACK hopefully a static wait won't blow up in my face before google fixes their implementation.
|
||||
|
||||
//HACK this for loop is ueless. Breakpad dumbly returns success when the OOP handler isn't initialized.
|
||||
for (int retries=0;retries<5;++retries)
|
||||
{
|
||||
mExceptionHandler = new google_breakpad::ExceptionHandler(
|
||||
L"",
|
||||
NULL, //No filter
|
||||
windows_post_minidump_callback,
|
||||
0,
|
||||
google_breakpad::ExceptionHandler::HANDLER_ALL,
|
||||
MiniDumpNormal, //Generate a 'normal' minidump.
|
||||
(WCHAR *)wpipe_name.c_str(),
|
||||
NULL); //No custom client info.
|
||||
if (mExceptionHandler)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
::Sleep(100); //Wait a tick and try again.
|
||||
}
|
||||
}
|
||||
if (!mExceptionHandler)
|
||||
{
|
||||
llwarns << "Failed to initialize OOP exception handler. Defaulting to In Process handling" << llendl;
|
||||
mExceptionHandler = new google_breakpad::ExceptionHandler(
|
||||
std::wstring(mDumpPath.begin(),mDumpPath.end()), //Dump path
|
||||
0, //dump filename
|
||||
windows_post_minidump_callback,
|
||||
0,
|
||||
google_breakpad::ExceptionHandler::HANDLER_ALL);
|
||||
}
|
||||
mExceptionHandler = new google_breakpad::ExceptionHandler(
|
||||
std::wstring(mDumpPath.begin(),mDumpPath.end()), //Dump path
|
||||
0, //dump filename
|
||||
windows_post_minidump_callback,
|
||||
0,
|
||||
google_breakpad::ExceptionHandler::HANDLER_ALL);
|
||||
if (mExceptionHandler)
|
||||
{
|
||||
mExceptionHandler->set_handle_debug_exceptions(true);
|
||||
|
||||
@@ -81,7 +81,7 @@ void LLCubeMap::initGL()
|
||||
{
|
||||
U32 texname = 0;
|
||||
|
||||
LLImageGL::generateTextures(LLTexUnit::TT_CUBE_MAP, GL_RGB8, 1, &texname);
|
||||
LLImageGL::generateTextures(1, &texname);
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
|
||||
@@ -54,8 +54,6 @@ S32 LLImageGL::sGlobalTextureMemoryInBytes = 0;
|
||||
S32 LLImageGL::sBoundTextureMemoryInBytes = 0;
|
||||
S32 LLImageGL::sCurBoundTextureMemory = 0;
|
||||
S32 LLImageGL::sCount = 0;
|
||||
LLImageGL::dead_texturelist_t LLImageGL::sDeadTextureList[LLTexUnit::TT_NONE];
|
||||
U32 LLImageGL::sCurTexName = 1;
|
||||
|
||||
BOOL LLImageGL::sGlobalUseAnisotropic = FALSE;
|
||||
F32 LLImageGL::sLastFrameTime = 0.f;
|
||||
@@ -791,8 +789,13 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
|
||||
|
||||
mMipLevels = wpo2(llmax(w, h));
|
||||
|
||||
//use legacy mipmap generation mode
|
||||
glTexParameteri(mTarget, GL_GENERATE_MIPMAP, GL_TRUE);
|
||||
//use legacy mipmap generation mode (note: making this condional can cause rendering issues)
|
||||
// -- but making it not conditional triggers deprecation warnings when core profile is enabled
|
||||
// (some rendering issues while core profile is enabled are acceptable at this point in time)
|
||||
if (!LLRender::sGLCoreProfile)
|
||||
{
|
||||
glTexParameteri(mTarget, GL_GENERATE_MIPMAP, GL_TRUE);
|
||||
}
|
||||
|
||||
LLImageGL::setManualImage(mTarget, 0, mFormatInternal,
|
||||
w, h,
|
||||
@@ -1055,66 +1058,19 @@ BOOL LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_
|
||||
|
||||
// static
|
||||
static LLFastTimer::DeclareTimer FTM_GENERATE_TEXTURES("generate textures");
|
||||
void LLImageGL::generateTextures(LLTexUnit::eTextureType type, U32 format, S32 numTextures, U32 *textures)
|
||||
void LLImageGL::generateTextures(S32 numTextures, U32 *textures)
|
||||
{
|
||||
LLFastTimer t(FTM_GENERATE_TEXTURES);
|
||||
bool empty = true;
|
||||
|
||||
dead_texturelist_t::iterator iter = sDeadTextureList[type].find(format);
|
||||
|
||||
if (iter != sDeadTextureList[type].end())
|
||||
{
|
||||
empty = iter->second.empty();
|
||||
}
|
||||
|
||||
for (S32 i = 0; i < numTextures; ++i)
|
||||
{
|
||||
if (!empty)
|
||||
{
|
||||
textures[i] = iter->second.front();
|
||||
iter->second.pop_front();
|
||||
empty = iter->second.empty();
|
||||
}
|
||||
else
|
||||
{
|
||||
textures[i] = sCurTexName++;
|
||||
}
|
||||
}
|
||||
glGenTextures(numTextures, textures);
|
||||
}
|
||||
|
||||
// static
|
||||
void LLImageGL::deleteTextures(LLTexUnit::eTextureType type, U32 format, S32 mip_levels, S32 numTextures, U32 *textures, bool immediate)
|
||||
void LLImageGL::deleteTextures(S32 numTextures, U32 *textures)
|
||||
{
|
||||
if (gGLManager.mInited)
|
||||
{
|
||||
if (format == 0 || type == LLTexUnit::TT_CUBE_MAP || mip_levels == -1)
|
||||
{ //unknown internal format or unknown number of mip levels, not safe to reuse
|
||||
glDeleteTextures(numTextures, textures);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (S32 i = 0; i < numTextures; ++i)
|
||||
{ //remove texture from VRAM by setting its size to zero
|
||||
for (S32 j = 0; j <= mip_levels; j++)
|
||||
{
|
||||
gGL.getTexUnit(0)->bindManual(type, textures[i]);
|
||||
|
||||
glTexImage2D(LLTexUnit::getInternalType(type), j, format, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
}
|
||||
|
||||
llassert(std::find(sDeadTextureList[type][format].begin(),
|
||||
sDeadTextureList[type][format].end(), textures[i]) ==
|
||||
sDeadTextureList[type][format].end());
|
||||
|
||||
sDeadTextureList[type][format].push_back(textures[i]);
|
||||
}
|
||||
}
|
||||
glDeleteTextures(numTextures, textures);
|
||||
}
|
||||
|
||||
/*if (immediate)
|
||||
{
|
||||
LLImageGL::deleteDeadTextures();
|
||||
}*/
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -1242,11 +1198,11 @@ BOOL LLImageGL::createGLTexture()
|
||||
|
||||
if(mTexName)
|
||||
{
|
||||
LLImageGL::deleteTextures(mBindTarget, mFormatInternal, mMipLevels, 1, (reinterpret_cast<GLuint*>(&mTexName))) ;
|
||||
LLImageGL::deleteTextures(1, (reinterpret_cast<GLuint*>(&mTexName))) ;
|
||||
}
|
||||
|
||||
|
||||
LLImageGL::generateTextures(mBindTarget, mFormatInternal, 1, &mTexName);
|
||||
LLImageGL::generateTextures(1, &mTexName);
|
||||
stop_glerror();
|
||||
if (!mTexName)
|
||||
{
|
||||
@@ -1363,7 +1319,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
|
||||
}
|
||||
else
|
||||
{
|
||||
LLImageGL::generateTextures(mBindTarget, mFormatInternal, 1, &mTexName);
|
||||
LLImageGL::generateTextures(1, &mTexName);
|
||||
stop_glerror();
|
||||
{
|
||||
llverify(gGL.getTexUnit(0)->bind(this));
|
||||
@@ -1413,7 +1369,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
|
||||
decTextureCounter(mTextureMemory, mComponents, mCategory) ;
|
||||
}
|
||||
|
||||
LLImageGL::deleteTextures(mBindTarget, mFormatInternal, mMipLevels, 1, &old_name);
|
||||
LLImageGL::deleteTextures(1, &old_name);
|
||||
|
||||
stop_glerror();
|
||||
}
|
||||
@@ -1548,34 +1504,6 @@ void LLImageGL::deleteDeadTextures()
|
||||
{
|
||||
bool reset = false;
|
||||
|
||||
/*for(U32 i=0;i<LLTexUnit::TT_NONE;++i)
|
||||
{
|
||||
for(dead_texturelist_t::iterator it=sDeadTextureList[i].begin();it!=sDeadTextureList[i].end();++it)
|
||||
{
|
||||
while(!it->second.empty())
|
||||
{
|
||||
GLuint tex = it->second.front();
|
||||
it->second.pop_front();
|
||||
for (int j = 0; j < gGLManager.mNumTextureImageUnits; j++)
|
||||
{
|
||||
LLTexUnit* tex_unit = gGL.getTexUnit(j);
|
||||
if (tex_unit && tex_unit->getCurrTexture() == tex)
|
||||
{
|
||||
tex_unit->unbind(tex_unit->getCurrType());
|
||||
stop_glerror();
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
reset = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
glDeleteTextures(1, &tex);
|
||||
stop_glerror();
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
if (reset)
|
||||
{
|
||||
gGL.getTexUnit(0)->activate();
|
||||
@@ -1596,7 +1524,7 @@ void LLImageGL::destroyGLTexture()
|
||||
mTextureMemory = 0;
|
||||
}
|
||||
|
||||
LLImageGL::deleteTextures(mBindTarget, mFormatInternal, mMipLevels, 1, &mTexName);
|
||||
LLImageGL::deleteTextures(1, &mTexName);
|
||||
mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel.
|
||||
mTexName = 0;
|
||||
mGLTextureCreated = FALSE ;
|
||||
|
||||
@@ -45,16 +45,9 @@ class LLImageGL : public LLRefCount
|
||||
{
|
||||
friend class LLTexUnit;
|
||||
public:
|
||||
static U32 sCurTexName;
|
||||
|
||||
//previously used but now available texture names
|
||||
// sDeadTextureList[<usage>][<internal format>]
|
||||
typedef std::map<U32, std::list<U32> > dead_texturelist_t;
|
||||
static dead_texturelist_t sDeadTextureList[LLTexUnit::TT_NONE];
|
||||
|
||||
// These 2 functions replace glGenTextures() and glDeleteTextures()
|
||||
static void generateTextures(LLTexUnit::eTextureType type, U32 format, S32 numTextures, U32 *textures);
|
||||
static void deleteTextures(LLTexUnit::eTextureType type, U32 format, S32 mip_levels, S32 numTextures, U32 *textures, bool immediate = false);
|
||||
static void generateTextures(S32 numTextures, U32 *textures);
|
||||
static void deleteTextures(S32 numTextures, U32 *textures);
|
||||
static void deleteDeadTextures();
|
||||
|
||||
// Size calculation
|
||||
|
||||
@@ -407,13 +407,13 @@ void LLPostProcess::createScreenTextures()
|
||||
stop_glerror();
|
||||
|
||||
if(mDepthTexture)
|
||||
LLImageGL::deleteTextures(type, 0, 0, 1, &mDepthTexture, true);
|
||||
LLImageGL::deleteTextures(1, &mDepthTexture);
|
||||
|
||||
for(std::list<LLPointer<LLPostProcessShader> >::iterator it=mShaders.begin();it!=mShaders.end();++it)
|
||||
{
|
||||
if((*it)->getDepthChannel()>=0)
|
||||
{
|
||||
LLImageGL::generateTextures(type, GL_DEPTH_COMPONENT24, 1, &mDepthTexture);
|
||||
LLImageGL::generateTextures(1, &mDepthTexture);
|
||||
gGL.getTexUnit(0)->bindManual(type, mDepthTexture);
|
||||
LLImageGL::setManualImage(LLTexUnit::getInternalType(type), 0, GL_DEPTH_COMPONENT24, mScreenWidth, mScreenHeight, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL, false);
|
||||
stop_glerror();
|
||||
@@ -438,7 +438,7 @@ void LLPostProcess::createNoiseTexture()
|
||||
if(mNoiseTexture->createGLTexture())
|
||||
{
|
||||
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseTexture->getTexName());
|
||||
LLImageGL::setManualImage(GL_TEXTURE_2D, 0, GL_LUMINANCE, NOISE_SIZE, NOISE_SIZE, GL_LUMINANCE, GL_UNSIGNED_BYTE, &buffer[0]);
|
||||
LLImageGL::setManualImage(GL_TEXTURE_2D, 0, GL_RED, NOISE_SIZE, NOISE_SIZE, GL_RED, GL_UNSIGNED_BYTE, &buffer[0]);
|
||||
stop_glerror();
|
||||
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
|
||||
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_WRAP);
|
||||
@@ -451,7 +451,7 @@ void LLPostProcess::destroyGL()
|
||||
mRenderTarget[0].release();
|
||||
mRenderTarget[1].release();
|
||||
if(mDepthTexture)
|
||||
LLImageGL::deleteTextures(LLTexUnit::TT_RECT_TEXTURE, 0, 0, 1, &mDepthTexture, true);
|
||||
LLImageGL::deleteTextures(1, &mDepthTexture);
|
||||
mDepthTexture=0;
|
||||
mNoiseTexture = NULL ;
|
||||
mVBO = NULL ;
|
||||
|
||||
@@ -51,7 +51,7 @@ void check_framebuffer_status()
|
||||
}
|
||||
|
||||
bool LLRenderTarget::sUseFBO = false;
|
||||
U32 LLRenderTarget::sCurFBO = 0;
|
||||
LLRenderTarget* LLRenderTarget::sCurFBO = 0;
|
||||
|
||||
LLRenderTarget::LLRenderTarget() :
|
||||
mResX(0),
|
||||
@@ -161,7 +161,7 @@ bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, boo
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), mDepth, 0);
|
||||
stop_glerror();
|
||||
}
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO ? sCurFBO->getFBO() : 0);
|
||||
}
|
||||
|
||||
stop_glerror();
|
||||
@@ -194,7 +194,7 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
|
||||
}
|
||||
|
||||
U32 tex;
|
||||
LLImageGL::generateTextures(mUsage, color_fmt, 1, &tex);
|
||||
LLImageGL::generateTextures(1, &tex);
|
||||
gGL.getTexUnit(0)->bindManual(mUsage, tex);
|
||||
|
||||
stop_glerror();
|
||||
@@ -248,7 +248,7 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
|
||||
|
||||
check_framebuffer_status();
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO ? sCurFBO->getFBO() : 0);
|
||||
}
|
||||
|
||||
mTex.push_back(tex);
|
||||
@@ -277,10 +277,7 @@ bool LLRenderTarget::allocateDepth()
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!mStencil)
|
||||
LLImageGL::generateTextures(mUsage, GL_DEPTH_COMPONENT24, 1, &mDepth);
|
||||
else
|
||||
LLImageGL::generateTextures(mUsage, GL_DEPTH24_STENCIL8, 1, &mDepth);
|
||||
LLImageGL::generateTextures(1, &mDepth);
|
||||
gGL.getTexUnit(0)->bindManual(mUsage, mDepth);
|
||||
|
||||
U32 internal_type = LLTexUnit::getInternalType(mUsage);
|
||||
@@ -343,7 +340,7 @@ void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target)
|
||||
|
||||
check_framebuffer_status();
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO ? sCurFBO->getFBO() : 0);
|
||||
|
||||
target.mUseDepth = true;
|
||||
}
|
||||
@@ -365,8 +362,9 @@ void LLRenderTarget::release()
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), 0, 0);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER,0);
|
||||
}
|
||||
LLImageGL::deleteTextures(mUsage, 0, 0, 1, &mDepth, true);
|
||||
LLImageGL::deleteTextures(1, &mDepth);
|
||||
stop_glerror();
|
||||
}
|
||||
mDepth = 0;
|
||||
@@ -386,6 +384,7 @@ void LLRenderTarget::release()
|
||||
{ //attached as a texture
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), 0, 0);
|
||||
}
|
||||
glBindFramebuffer(GL_FRAMEBUFFER,0);
|
||||
mUseDepth = false;
|
||||
}
|
||||
|
||||
@@ -398,7 +397,7 @@ void LLRenderTarget::release()
|
||||
if (mTex.size() > 0)
|
||||
{
|
||||
sBytesAllocated -= mResX*mResY*4*mTex.size();
|
||||
LLImageGL::deleteTextures(mUsage, mInternalFormat[0], 0, mTex.size(), &mTex[0], true);
|
||||
LLImageGL::deleteTextures(mTex.size(), &mTex[0]);
|
||||
mTex.clear();
|
||||
mInternalFormat.clear();
|
||||
}
|
||||
@@ -414,17 +413,18 @@ void LLRenderTarget::bindTarget()
|
||||
if (mFBO)
|
||||
{
|
||||
stop_glerror();
|
||||
|
||||
mPreviousFBO = sCurFBO;
|
||||
if (mSampleBuffer)
|
||||
{
|
||||
mSampleBuffer->bindTarget(this);
|
||||
sCurFBO = mSampleBuffer->mFBO;
|
||||
sCurFBO = mSampleBuffer;
|
||||
stop_glerror();
|
||||
}
|
||||
else
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
|
||||
sCurFBO = mFBO;
|
||||
sCurFBO = this;
|
||||
|
||||
stop_glerror();
|
||||
if (gGLManager.mHasDrawBuffers)
|
||||
@@ -577,8 +577,18 @@ void LLRenderTarget::flush(bool fetch_depth)
|
||||
}
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||
}
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mPreviousFBO);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mPreviousFBO ? mPreviousFBO->getFBO() : 0);
|
||||
sCurFBO = mPreviousFBO;
|
||||
|
||||
if(mPreviousFBO)
|
||||
{
|
||||
glViewport(0, 0, mPreviousFBO->mResX, mPreviousFBO->mResY);
|
||||
mPreviousFBO = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
glViewport(gGLViewport[0],gGLViewport[1],gGLViewport[2],gGLViewport[3]);
|
||||
}
|
||||
stop_glerror();
|
||||
}
|
||||
}
|
||||
@@ -613,7 +623,7 @@ void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0,
|
||||
stop_glerror();
|
||||
glCopyTexSubImage2D(LLTexUnit::getInternalType(mUsage), 0, srcX0, srcY0, dstX0, dstY0, dstX1, dstY1);
|
||||
stop_glerror();
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO ? sCurFBO->getFBO() : 0);
|
||||
stop_glerror();
|
||||
}
|
||||
else
|
||||
@@ -636,7 +646,7 @@ void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0,
|
||||
stop_glerror();
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
stop_glerror();
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO ? sCurFBO->getFBO() : 0);
|
||||
stop_glerror();
|
||||
}
|
||||
}
|
||||
@@ -670,7 +680,7 @@ void LLRenderTarget::copyContentsToFramebuffer(LLRenderTarget& source, S32 srcX0
|
||||
if(mask)
|
||||
glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
|
||||
stop_glerror();
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO ? sCurFBO->getFBO() : 0);
|
||||
stop_glerror();
|
||||
}
|
||||
}
|
||||
@@ -819,7 +829,7 @@ bool LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth
|
||||
}
|
||||
|
||||
stop_glerror();
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO ? sCurFBO->getFBO() : 0);
|
||||
stop_glerror();
|
||||
|
||||
|
||||
@@ -898,7 +908,7 @@ bool LLMultisampleBuffer::addColorAttachment(U32 color_fmt)
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+offset, GL_RENDERBUFFER, tex);
|
||||
check_framebuffer_status();
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO ? sCurFBO->getFBO() : 0);
|
||||
}
|
||||
|
||||
mTex.push_back(tex);
|
||||
|
||||
@@ -65,7 +65,7 @@ public:
|
||||
//whether or not to use FBO implementation
|
||||
static bool sUseFBO;
|
||||
static U32 sBytesAllocated;
|
||||
static U32 sCurFBO;
|
||||
static LLRenderTarget* sCurFBO;
|
||||
|
||||
LLRenderTarget();
|
||||
virtual ~LLRenderTarget();
|
||||
@@ -154,7 +154,7 @@ protected:
|
||||
std::vector<U32> mTex;
|
||||
std::vector<U32> mInternalFormat;
|
||||
U32 mFBO;
|
||||
U32 mPreviousFBO;
|
||||
LLRenderTarget* mPreviousFBO;
|
||||
U32 mDepth;
|
||||
bool mStencil;
|
||||
bool mUseDepth;
|
||||
|
||||
@@ -90,7 +90,6 @@ LLVBOPool LLVertexBuffer::sDynamicIBOPool(GL_DYNAMIC_DRAW_ARB, GL_ELEMENT_ARRAY_
|
||||
|
||||
U32 LLVBOPool::sBytesPooled = 0;
|
||||
U32 LLVBOPool::sIndexBytesPooled = 0;
|
||||
U32 LLVBOPool::sCurGLName = 1;
|
||||
|
||||
std::list<U32> LLVertexBuffer::sAvailableVAOName;
|
||||
U32 LLVertexBuffer::sCurVAOName = 1;
|
||||
@@ -124,16 +123,8 @@ U32 LLVBOPool::genBuffer()
|
||||
{
|
||||
U32 ret = 0;
|
||||
|
||||
if (mGLNamePool.empty())
|
||||
{
|
||||
ret = sCurGLName++;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = mGLNamePool.front();
|
||||
mGLNamePool.pop_front();
|
||||
}
|
||||
|
||||
glGenBuffersARB(1, &ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -145,12 +136,9 @@ void LLVBOPool::deleteBuffer(U32 name)
|
||||
|
||||
glBindBufferARB(mType, name);
|
||||
glBufferDataARB(mType, 0, NULL, mUsage);
|
||||
|
||||
llassert(std::find(mGLNamePool.begin(), mGLNamePool.end(), name) == mGLNamePool.end());
|
||||
|
||||
mGLNamePool.push_back(name);
|
||||
|
||||
glBindBufferARB(mType, 0);
|
||||
|
||||
glDeleteBuffersARB(1, &name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1304,7 +1292,7 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
|
||||
//actually allocate space for the vertex buffer if using VBO mapping
|
||||
flush();
|
||||
|
||||
if (gGLManager.mHasVertexArrayObject && useVBOs() && (LLRender::sGLCoreProfile || sUseVAO))
|
||||
if (gGLManager.mHasVertexArrayObject && useVBOs() && sUseVAO)
|
||||
{
|
||||
#if GL_ARB_vertex_array_object
|
||||
mGLArray = getVAOName();
|
||||
|
||||
@@ -57,8 +57,6 @@ public:
|
||||
static U32 sBytesPooled;
|
||||
static U32 sIndexBytesPooled;
|
||||
|
||||
static U32 sCurGLName;
|
||||
|
||||
LLVBOPool(U32 vboUsage, U32 vboType);
|
||||
|
||||
const U32 mUsage;
|
||||
@@ -86,8 +84,6 @@ public:
|
||||
volatile U8* mClientData;
|
||||
};
|
||||
|
||||
std::list<U32> mGLNamePool;
|
||||
|
||||
typedef std::list<Record> record_list_t;
|
||||
std::vector<record_list_t> mFreeList;
|
||||
std::vector<U32> mMissCount;
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
</array>
|
||||
<key>tags</key>
|
||||
<array>
|
||||
<string>ShaderLoading</string>
|
||||
<!--string>ShaderLoading</string-->
|
||||
<string>Openjpeg</string>
|
||||
<!-- Debug output about messages received from plugins: -->
|
||||
<string>Plugin</string> <!-- Everything except what is listed below -->
|
||||
|
||||
@@ -127,7 +127,8 @@ void LLPrefsAscentSys::onCommitCheckBox(LLUICtrl* ctrl, const LLSD& value)
|
||||
if (enabled)
|
||||
{
|
||||
LLVector3d lpos_global = gAgent.getPositionGlobal();
|
||||
gAudiop->triggerSound(LLUUID("58a38e89-44c6-c52b-deb8-9f1ddc527319"), gAgent.getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_UI, lpos_global);
|
||||
if(gAudiop)
|
||||
gAudiop->triggerSound(LLUUID("58a38e89-44c6-c52b-deb8-9f1ddc527319"), gAgent.getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_UI, lpos_global);
|
||||
LLChat chat;
|
||||
chat.mSourceType = CHAT_SOURCE_SYSTEM;
|
||||
chat.mText = LLTrans::getString("PowerUser1") + "\n" + LLTrans::getString("PowerUser2") + "\n" + LLTrans::getString("Unlocked:") + "\n" + LLTrans::getString("PowerUser3") + "\n- " + LLTrans::getString("RightClick") + " > " + LLTrans::getString("PowerUser4") + "\n- " + LLTrans::getString("RightClick") + " > " + LLTrans::getString("PowerUser5");
|
||||
|
||||
@@ -522,61 +522,7 @@ bool LLAppViewerWin32::restoreErrorTrap()
|
||||
|
||||
void LLAppViewerWin32::initCrashReporting(bool reportFreeze)
|
||||
{
|
||||
/* Singu Note: don't fork the crash logger on start
|
||||
const char* logger_name = "win_crash_logger.exe";
|
||||
std::string exe_path = gDirUtilp->getExecutableDir();
|
||||
exe_path += gDirUtilp->getDirDelimiter();
|
||||
exe_path += logger_name;
|
||||
|
||||
std::stringstream pid_str;
|
||||
pid_str << LLApp::getPid();
|
||||
std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, "");
|
||||
std::string appname = gDirUtilp->getExecutableFilename();
|
||||
|
||||
S32 slen = logdir.length() -1;
|
||||
S32 end = slen;
|
||||
while (logdir.at(end) == '/' || logdir.at(end) == '\\') end--;
|
||||
|
||||
if (slen !=end)
|
||||
{
|
||||
logdir = logdir.substr(0,end+1);
|
||||
}
|
||||
std::string arg_str = "\"" + exe_path + "\" -dumpdir \"" + logdir + "\" -procname \"" + appname + "\" -pid " + pid_str.str();
|
||||
llinfos << "spawning " << arg_str << llendl;
|
||||
_spawnl(_P_NOWAIT, exe_path.c_str(), arg_str.c_str(), NULL);
|
||||
*/
|
||||
|
||||
/* STARTUPINFO siStartupInfo;
|
||||
|
||||
std::string arg_str = "-dumpdir \"" + logdir + "\" -procname \"" + appname + "\" -pid " + pid_str.str();
|
||||
|
||||
memset(&siStartupInfo, 0, sizeof(siStartupInfo));
|
||||
memset(&mCrashReporterProcessInfo, 0, sizeof(mCrashReporterProcessInfo));
|
||||
|
||||
siStartupInfo.cb = sizeof(siStartupInfo);
|
||||
|
||||
std::wstring exe_wstr;
|
||||
exe_wstr.assign(exe_path.begin(), exe_path.end());
|
||||
|
||||
std::wstring arg_wstr;
|
||||
arg_wstr.assign(arg_str.begin(), arg_str.end());
|
||||
|
||||
if(CreateProcess(&exe_wstr[0],
|
||||
&arg_wstr[0], // Application arguments
|
||||
0,
|
||||
0,
|
||||
FALSE,
|
||||
CREATE_DEFAULT_ERROR_MODE,
|
||||
0,
|
||||
0, // Working directory
|
||||
&siStartupInfo,
|
||||
&mCrashReporterProcessInfo) == FALSE)
|
||||
// Could not start application -> call 'GetLastError()'
|
||||
{
|
||||
//llinfos << "CreateProcess failed " << GetLastError() << llendl;
|
||||
return;
|
||||
}
|
||||
*/
|
||||
// Singu Note: we don't fork the crash logger on start
|
||||
}
|
||||
|
||||
//virtual
|
||||
|
||||
@@ -40,7 +40,10 @@
|
||||
#include "llhttpclient.h"
|
||||
#include "llsdserialize.h"
|
||||
#include "llproxy.h"
|
||||
#include "llwindow.h"
|
||||
#include "lltrans.h"
|
||||
#include "aistatemachine.h"
|
||||
#include "boost/filesystem.hpp"
|
||||
|
||||
class AIHTTPTimeoutPolicy;
|
||||
extern AIHTTPTimeoutPolicy crashLoggerResponder_timeout;
|
||||
@@ -144,6 +147,36 @@ std::string getStartupStateFromLog(std::string& sllog)
|
||||
return startup_state;
|
||||
}
|
||||
|
||||
bool miniDumpExists(const std::string& dumpDir)
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
try
|
||||
{
|
||||
if (!boost::filesystem::exists(dumpDir))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
boost::filesystem::directory_iterator end_itr;
|
||||
for (boost::filesystem::directory_iterator i(dumpDir); i != end_itr; ++i)
|
||||
{
|
||||
if (!boost::filesystem::is_regular_file(i->status())) continue;
|
||||
if (".dmp" == i->path().extension())
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const boost::filesystem::filesystem_error& e)
|
||||
{
|
||||
llwarns << "Failed to determine existance of the minidump file: '" + e.code().message() +"'" << llendl;
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
bool LLCrashLogger::readDebugFromXML(LLSD& dest, const std::string& filename )
|
||||
{
|
||||
std::string db_file_name = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,filename);
|
||||
@@ -350,20 +383,29 @@ bool LLCrashLogger::sendCrashLog(std::string dump_dir)
|
||||
|
||||
void LLCrashLogger::checkCrashDump()
|
||||
{
|
||||
mCrashHost = gSavedSettings.getString("CrashHostUrl");
|
||||
|
||||
std::string dumpDir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "") + "singularity-debug";
|
||||
if (gDirUtilp->fileExists(dumpDir))
|
||||
{
|
||||
#if LL_SEND_CRASH_REPORTS
|
||||
if (!mCrashHost.empty() && gSavedSettings.getS32("CrashSubmitBehavior") != 2)
|
||||
// 0 - ask, 1 - always send, 2 - never send
|
||||
S32 pref = gSavedSettings.getS32("CrashSubmitBehavior");
|
||||
if (pref == 2) return; //never send
|
||||
|
||||
mCrashHost = gSavedSettings.getString("CrashHostUrl");
|
||||
std::string dumpDir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "") + "singularity-debug";
|
||||
|
||||
// Do we have something to send, and somewhere to send it
|
||||
if (!mCrashHost.empty() && miniDumpExists(dumpDir))
|
||||
{
|
||||
if (pref == 1) // always send
|
||||
{
|
||||
sendCrashLog(dumpDir);
|
||||
}
|
||||
else // ask
|
||||
{
|
||||
U32 response = OSMessageBox(LLTrans::getString("MBFrozenCrashed"), LLTrans::getString("MBAlert"), OSMB_YESNO);
|
||||
if (response == OSBTN_YES)
|
||||
{
|
||||
sendCrashLog(dumpDir);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
llinfos << "No crash dump found frome previous run, not sending report" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5841,7 +5841,7 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
|
||||
}
|
||||
// [/RLVa:KB]*/
|
||||
|
||||
bool not_modifiable = !gAgentWearables.isWearableModifiable(item->getUUID());
|
||||
bool not_modifiable = !item || !gAgentWearables.isWearableModifiable(item->getUUID());
|
||||
if (((flags & FIRST_SELECTED_ITEM) == 0) || not_modifiable)
|
||||
{
|
||||
disabled_items.push_back(std::string("Wearable Edit"));
|
||||
|
||||
@@ -1839,12 +1839,9 @@ void LLPanelAvatar::sendAvatarPropertiesUpdate()
|
||||
{
|
||||
llinfos << "Sending avatarinfo update" << llendl;
|
||||
BOOL allow_publish = FALSE;
|
||||
BOOL mature = FALSE;
|
||||
if (LLPanelAvatar::sAllowFirstLife)
|
||||
{
|
||||
allow_publish = childGetValue("allow_publish");
|
||||
//A profile should never be mature.
|
||||
mature = FALSE;
|
||||
}
|
||||
|
||||
LLUUID first_life_image_id;
|
||||
@@ -1867,7 +1864,6 @@ void LLPanelAvatar::sendAvatarPropertiesUpdate()
|
||||
avatar_data.about_text = about_text;
|
||||
avatar_data.fl_about_text = first_life_about_text;
|
||||
avatar_data.allow_publish = allow_publish;
|
||||
//avatar_data.mature = mature;
|
||||
avatar_data.profile_url = mPanelWeb->childGetText("url_edit");
|
||||
LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesUpdate(&avatar_data);
|
||||
|
||||
|
||||
@@ -162,7 +162,7 @@ BOOL LLPanelDirFind::postBuild()
|
||||
}
|
||||
|
||||
if (LLUICtrl* ctrl = findChild<LLUICtrl>("filter_gaming"))
|
||||
ctrl->setVisible((gAgent.getRegion()->getGamingFlags() & REGION_GAMING_PRESENT) && !(gAgent.getRegion()->getGamingFlags() & REGION_GAMING_HIDE_FIND_ALL));
|
||||
ctrl->setVisible(gAgent.getRegion() && (gAgent.getRegion()->getGamingFlags() & REGION_GAMING_PRESENT) && !(gAgent.getRegion()->getGamingFlags() & REGION_GAMING_HIDE_FIND_ALL));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -558,7 +558,7 @@ BOOL LLPanelDirFindAllOld::postBuild()
|
||||
setDefaultBtn( "Search" );
|
||||
|
||||
if (LLUICtrl* ctrl = findChild<LLUICtrl>("filter_gaming"))
|
||||
ctrl->setVisible((gAgent.getRegion()->getGamingFlags() & REGION_GAMING_PRESENT) && !(gAgent.getRegion()->getGamingFlags() & REGION_GAMING_HIDE_FIND_ALL_CLASSIC));
|
||||
ctrl->setVisible(gAgent.getRegion() && (gAgent.getRegion()->getGamingFlags() & REGION_GAMING_PRESENT) && !(gAgent.getRegion()->getGamingFlags() & REGION_GAMING_HIDE_FIND_ALL_CLASSIC));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -95,27 +95,15 @@ class LLOcclusionQueryPool : public LLGLNamePool
|
||||
public:
|
||||
LLOcclusionQueryPool()
|
||||
{
|
||||
mCurQuery = 1;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
std::queue<GLuint> mAvailableName; //Use queue, because this usage is FIFO, which queue is desgined for
|
||||
GLuint mCurQuery;
|
||||
|
||||
virtual GLuint allocateName()
|
||||
{
|
||||
GLuint ret = 0;
|
||||
|
||||
if (!mAvailableName.empty())
|
||||
{
|
||||
ret = mAvailableName.front();
|
||||
mAvailableName.pop();
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = mCurQuery++;
|
||||
}
|
||||
glGenQueriesARB(1, &ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -125,8 +113,7 @@ protected:
|
||||
#if LL_TRACK_PENDING_OCCLUSION_QUERIES
|
||||
LLSpatialGroup::sPendingQueries.erase(name);
|
||||
#endif
|
||||
//llassert(std::find(mAvailableName.begin(), mAvailableName.end(), name) == mAvailableName.end());
|
||||
mAvailableName.push(name);
|
||||
glDeleteQueriesARB(1, &name);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -2815,24 +2815,33 @@ void LLViewerObject::processTaskInvFile(void** user_data, S32 error_code, LLExtS
|
||||
if(ft && (0 == error_code) &&
|
||||
(object = gObjectList.findObject(ft->mTaskID)))
|
||||
{
|
||||
object->loadTaskInvFile(ft->mFilename);
|
||||
|
||||
LLInventoryObject::object_list_t::iterator it = object->mInventory->begin();
|
||||
LLInventoryObject::object_list_t::iterator end = object->mInventory->end();
|
||||
std::list<LLUUID>& pending_lst = object->mPendingInventoryItemsIDs;
|
||||
|
||||
for (; it != end && pending_lst.size(); ++it)
|
||||
if (object->loadTaskInvFile(ft->mFilename))
|
||||
{
|
||||
LLViewerInventoryItem* item = dynamic_cast<LLViewerInventoryItem*>(it->get());
|
||||
if(item && item->getType() != LLAssetType::AT_CATEGORY)
|
||||
|
||||
LLInventoryObject::object_list_t::iterator it = object->mInventory->begin();
|
||||
LLInventoryObject::object_list_t::iterator end = object->mInventory->end();
|
||||
std::list<LLUUID>& pending_lst = object->mPendingInventoryItemsIDs;
|
||||
|
||||
for (; it != end && pending_lst.size(); ++it)
|
||||
{
|
||||
std::list<LLUUID>::iterator id_it = std::find(pending_lst.begin(), pending_lst.begin(), item->getAssetUUID());
|
||||
if (id_it != pending_lst.end())
|
||||
LLViewerInventoryItem* item = dynamic_cast<LLViewerInventoryItem*>(it->get());
|
||||
if(item && item->getType() != LLAssetType::AT_CATEGORY)
|
||||
{
|
||||
pending_lst.erase(id_it);
|
||||
std::list<LLUUID>::iterator id_it = std::find(pending_lst.begin(), pending_lst.begin(), item->getAssetUUID());
|
||||
if (id_it != pending_lst.end())
|
||||
{
|
||||
pending_lst.erase(id_it);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// MAINT-2597 - crash when trying to edit a no-mod object
|
||||
// Somehow get an contents inventory response, but with an invalid stream (possibly 0 size?)
|
||||
// Stated repro was specific to no-mod objects so failing without user interaction should be safe.
|
||||
llwarns << "Trying to load invalid task inventory file. Ignoring file contents." << llendl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2844,7 +2853,7 @@ void LLViewerObject::processTaskInvFile(void** user_data, S32 error_code, LLExtS
|
||||
delete ft;
|
||||
}
|
||||
|
||||
void LLViewerObject::loadTaskInvFile(const std::string& filename)
|
||||
BOOL LLViewerObject::loadTaskInvFile(const std::string& filename)
|
||||
{
|
||||
std::string filename_and_local_path = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, filename);
|
||||
llifstream ifs(filename_and_local_path);
|
||||
@@ -2875,6 +2884,7 @@ void LLViewerObject::loadTaskInvFile(const std::string& filename)
|
||||
{
|
||||
LLPointer<LLInventoryObject> inv = new LLInventoryObject;
|
||||
inv->importLegacyStream(ifs);
|
||||
inv->rename("Contents");
|
||||
mInventory->push_front(inv);
|
||||
}
|
||||
else
|
||||
@@ -2890,8 +2900,11 @@ void LLViewerObject::loadTaskInvFile(const std::string& filename)
|
||||
{
|
||||
llwarns << "unable to load task inventory: " << filename_and_local_path
|
||||
<< llendl;
|
||||
return FALSE;
|
||||
}
|
||||
doInventoryCallback();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLViewerObject::doInventoryCallback()
|
||||
@@ -4904,11 +4917,7 @@ void LLViewerObject::setAttachedSound(const LLUUID &audio_uuid, const LLUUID& ow
|
||||
mAudioSourcep->setSyncMaster(flags & LL_SOUND_FLAG_SYNC_MASTER);
|
||||
mAudioSourcep->setSyncSlave(flags & LL_SOUND_FLAG_SYNC_SLAVE);
|
||||
mAudioSourcep->setQueueSounds(queue);
|
||||
if(!queue) // stop any current sound first to avoid "farts of doom" (SL-1541) -MG
|
||||
{
|
||||
mAudioSourcep->play(LLUUID::null);
|
||||
}
|
||||
|
||||
|
||||
// Play this sound if region maturity permits
|
||||
if( gAgent.canAccessMaturityAtGlobal(this->getPositionGlobal()) )
|
||||
{
|
||||
|
||||
@@ -673,7 +673,7 @@ protected:
|
||||
//
|
||||
|
||||
static void processTaskInvFile(void** user_data, S32 error_code, LLExtStat ext_status);
|
||||
void loadTaskInvFile(const std::string& filename);
|
||||
BOOL loadTaskInvFile(const std::string& filename);
|
||||
void doInventoryCallback();
|
||||
|
||||
BOOL isOnMap();
|
||||
|
||||
@@ -1238,7 +1238,7 @@ void LLVOAvatar::deleteLayerSetCaches(bool clearAll)
|
||||
}
|
||||
if (mBakedTextureDatas[i].mMaskTexName)
|
||||
{
|
||||
LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, 0, -1, 1, (GLuint*)&(mBakedTextureDatas[i].mMaskTexName));
|
||||
LLImageGL::deleteTextures(1, (GLuint*)&(mBakedTextureDatas[i].mMaskTexName));
|
||||
mBakedTextureDatas[i].mMaskTexName = 0 ;
|
||||
}
|
||||
}
|
||||
@@ -2529,11 +2529,19 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
|
||||
{{
|
||||
LLViewerJointAttachment* attachment = attachment_iter->second;
|
||||
LLViewerObject* attached_object = attachment_iter->first;
|
||||
BOOL visibleAttachment = visible || (attached_object && attached_object->mDrawable.notNull() &&
|
||||
!(attached_object->mDrawable->getSpatialBridge() &&
|
||||
attached_object->mDrawable->getSpatialBridge()->getRadius() < 2.0));
|
||||
|
||||
if (visibleAttachment && attached_object && attached_object->mDrawable && !attached_object->isDead() && attachment->getValid())
|
||||
if( !attached_object ||
|
||||
attached_object->isDead() ||
|
||||
!attached_object->mDrawable ||
|
||||
!attachment ||
|
||||
!attachment->getValid())
|
||||
continue;
|
||||
|
||||
BOOL visibleAttachment = visible ||
|
||||
!attached_object->mDrawable->getSpatialBridge() ||
|
||||
attached_object->mDrawable->getSpatialBridge()->getRadius() >= 2.f;
|
||||
|
||||
if (visibleAttachment)
|
||||
{
|
||||
// if selecting any attachments, update all of them as non-damped
|
||||
if (LLSelectMgr::getInstance()->getSelection()->getObjectCount() && LLSelectMgr::getInstance()->getSelection()->isAttachment())
|
||||
@@ -8136,7 +8144,7 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture
|
||||
}
|
||||
|
||||
U32 gl_name;
|
||||
LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_ALPHA8, 1, &gl_name );
|
||||
LLImageGL::generateTextures(1, &gl_name );
|
||||
stop_glerror();
|
||||
|
||||
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, gl_name);
|
||||
@@ -8173,7 +8181,7 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture
|
||||
maskData->mLastDiscardLevel = discard_level;
|
||||
if (self->mBakedTextureDatas[baked_index].mMaskTexName)
|
||||
{
|
||||
LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, 0, -1, 1, &(self->mBakedTextureDatas[baked_index].mMaskTexName));
|
||||
LLImageGL::deleteTextures(1, &(self->mBakedTextureDatas[baked_index].mMaskTexName));
|
||||
}
|
||||
self->mBakedTextureDatas[baked_index].mMaskTexName = gl_name;
|
||||
found_texture_id = true;
|
||||
|
||||
@@ -3168,7 +3168,7 @@ void LLVOAvatarSelf::deleteScratchTextures()
|
||||
namep;
|
||||
namep = sScratchTexNames.getNextData() )
|
||||
{
|
||||
LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, 0, -1, 1, (U32 *)namep );
|
||||
LLImageGL::deleteTextures(1, (U32 *)namep );
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
|
||||
@@ -851,7 +851,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
|
||||
|
||||
|
||||
if (!mScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false;
|
||||
if(samples > 1)
|
||||
if(samples > 1 && mScreen.getFBO())
|
||||
{
|
||||
if(mSampleBuffer.allocate(resX,resY,GL_RGBA,TRUE,TRUE,LLTexUnit::TT_RECT_TEXTURE,FALSE,samples))
|
||||
mScreen.setSampleBuffer(&mSampleBuffer);
|
||||
@@ -923,13 +923,13 @@ void LLPipeline::releaseGLBuffers()
|
||||
|
||||
if (mNoiseMap)
|
||||
{
|
||||
LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, GL_RGB16F_ARB, 0, 1, &mNoiseMap);
|
||||
LLImageGL::deleteTextures(1, &mNoiseMap);
|
||||
mNoiseMap = 0;
|
||||
}
|
||||
|
||||
if (mTrueNoiseMap)
|
||||
{
|
||||
LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, GL_RGB16F_ARB, 0, 1, &mTrueNoiseMap);
|
||||
LLImageGL::deleteTextures(1, &mTrueNoiseMap);
|
||||
mTrueNoiseMap = 0;
|
||||
}
|
||||
|
||||
@@ -956,13 +956,7 @@ void LLPipeline::releaseLUTBuffers()
|
||||
{
|
||||
if (mLightFunc)
|
||||
{
|
||||
U32 pix_format = GL_R16F;
|
||||
#if LL_DARWIN
|
||||
// Need to work around limited precision with 10.6.8 and older drivers
|
||||
//
|
||||
pix_format = GL_R32F;
|
||||
#endif
|
||||
LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, pix_format, 0, 1, &mLightFunc);
|
||||
LLImageGL::deleteTextures(1, &mLightFunc);
|
||||
mLightFunc = 0;
|
||||
}
|
||||
}
|
||||
@@ -1048,7 +1042,7 @@ void LLPipeline::createGLBuffers()
|
||||
noise[i].mV[2] = ll_frand()*scaler+1.f-scaler/2.f;
|
||||
}
|
||||
|
||||
LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_RGB16F_ARB, 1, &mNoiseMap);
|
||||
LLImageGL::generateTextures(1, &mNoiseMap);
|
||||
|
||||
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseMap);
|
||||
LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB, GL_FLOAT, noise, false);
|
||||
@@ -1064,7 +1058,7 @@ void LLPipeline::createGLBuffers()
|
||||
noise[i] = ll_frand()*2.0-1.0;
|
||||
}
|
||||
|
||||
LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_RGB16F_ARB, 1, &mTrueNoiseMap);
|
||||
LLImageGL::generateTextures(1, &mTrueNoiseMap);
|
||||
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mTrueNoiseMap);
|
||||
LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB,GL_FLOAT, noise, false);
|
||||
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
|
||||
@@ -1128,7 +1122,7 @@ void LLPipeline::createLUTBuffers()
|
||||
//
|
||||
pix_format = GL_R32F;
|
||||
#endif
|
||||
LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, pix_format, 1, &mLightFunc);
|
||||
LLImageGL::generateTextures(1, &mLightFunc);
|
||||
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc);
|
||||
LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, pix_format, lightResX, lightResY, GL_RED, GL_FLOAT, ls, false);
|
||||
//LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_UNSIGNED_BYTE, lightResX, lightResY, GL_RED, GL_UNSIGNED_BYTE, ls, false);
|
||||
|
||||
Reference in New Issue
Block a user