diff options
Diffstat (limited to 'indra')
72 files changed, 1448 insertions, 301 deletions
| diff --git a/indra/llcommon/llfasttimer_class.cpp b/indra/llcommon/llfasttimer_class.cpp index bd594b06cf..675eda2fc5 100644 --- a/indra/llcommon/llfasttimer_class.cpp +++ b/indra/llcommon/llfasttimer_class.cpp @@ -228,6 +228,14 @@ void LLFastTimer::DeclareTimer::updateCachedPointers()  		// update cached pointer  		it->mFrameState = &it->mTimer.getFrameState();  	} + +	// also update frame states of timers on stack
 +	LLFastTimer* cur_timerp = LLFastTimer::sCurTimerData.mCurTimer;
 +	while(cur_timerp->mLastTimerData.mCurTimer != cur_timerp)	
 +	{
 +		cur_timerp->mFrameState = &cur_timerp->mFrameState->mTimer->getFrameState();
 +		cur_timerp = cur_timerp->mLastTimerData.mCurTimer;
 +	}  }  //static diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index d9400fb5b3..4063cc730b 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -323,7 +323,8 @@ LLMutex::LLMutex(apr_pool_t *poolp) :  LLMutex::~LLMutex()  {  #if MUTEX_DEBUG -	llassert_always(!isLocked()); // better not be locked! +	//bad assertion, the subclass LLSignal might be "locked", and that's OK +	//llassert_always(!isLocked()); // better not be locked!  #endif  	apr_thread_mutex_destroy(mAPRMutexp);  	mAPRMutexp = NULL; diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index 7c8b7e3584..0735842dcd 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -579,11 +579,18 @@ void LLCurl::Easy::prepRequest(const std::string& url,  //////////////////////////////////////////////////////////////////////////// -class LLCurl::Multi +class LLCurl::Multi : public LLThread  {  	LOG_CLASS(Multi);  public: -	 + +	typedef enum +	{ +		PERFORM_STATE_READY=0, +		PERFORM_STATE_PERFORMING=1, +		PERFORM_STATE_COMPLETED=2 +	} ePerformState; +  	Multi();  	~Multi(); @@ -593,13 +600,20 @@ public:  	void removeEasy(Easy* easy);  	S32 process(); -	S32 perform(); +	void perform(); +	virtual void run(); +  	CURLMsg* info_read(S32* msgs_in_queue);  	S32 mQueued;  	S32 mErrorCount; +	S32 mPerformState; + +	LLCondition* mSignal; +	bool mQuitting; +  private:  	void easyFree(Easy*); @@ -614,9 +628,14 @@ private:  };  LLCurl::Multi::Multi() -	: mQueued(0), -	  mErrorCount(0) +	: LLThread("Curl Multi"), +	  mQueued(0), +	  mErrorCount(0), +	  mPerformState(PERFORM_STATE_READY)  { +	mQuitting = false; +	mSignal = new LLCondition(NULL); +  	mCurlMultiHandle = curl_multi_init();  	if (!mCurlMultiHandle)  	{ @@ -630,6 +649,11 @@ LLCurl::Multi::Multi()  LLCurl::Multi::~Multi()  { +	llassert(isStopped()); + +	delete mSignal; +	mSignal = NULL; +  	// Clean up active  	for(easy_active_list_t::iterator iter = mEasyActiveList.begin();  		iter != mEasyActiveList.end(); ++iter) @@ -655,30 +679,50 @@ CURLMsg* LLCurl::Multi::info_read(S32* msgs_in_queue)  	return curlmsg;  } +void LLCurl::Multi::perform() +{ +	if (mPerformState == PERFORM_STATE_READY) +	{ +		mSignal->signal(); +	} +} -S32 LLCurl::Multi::perform() +void LLCurl::Multi::run()  { -	S32 q = 0; -	for (S32 call_count = 0; -		 call_count < MULTI_PERFORM_CALL_REPEAT; -		 call_count += 1) +	while (!mQuitting)  	{ -		CURLMcode code = curl_multi_perform(mCurlMultiHandle, &q); -		if (CURLM_CALL_MULTI_PERFORM != code || q == 0) +		mSignal->wait(); +		mPerformState = PERFORM_STATE_PERFORMING; +		if (!mQuitting)  		{ -			check_curl_multi_code(code); -			break; -		} +			S32 q = 0; +			for (S32 call_count = 0; +				 call_count < MULTI_PERFORM_CALL_REPEAT; +				 call_count += 1) +			{ +				CURLMcode code = curl_multi_perform(mCurlMultiHandle, &q); +				if (CURLM_CALL_MULTI_PERFORM != code || q == 0) +				{ +					check_curl_multi_code(code); +					break; +				} +			} +			mQueued = q; +			mPerformState = PERFORM_STATE_COMPLETED; +		}  	} -	mQueued = q; -	return q;  }  S32 LLCurl::Multi::process()  {  	perform(); -	 + +	if (mPerformState != PERFORM_STATE_COMPLETED) +	{ +		return 0; +	} +  	CURLMsg* msg;  	int msgs_in_queue; @@ -709,6 +753,8 @@ S32 LLCurl::Multi::process()  			}  		}  	} + +	mPerformState = PERFORM_STATE_READY;  	return processed;  } @@ -787,6 +833,18 @@ LLCurlRequest::LLCurlRequest() :  LLCurlRequest::~LLCurlRequest()  {  	llassert_always(mThreadID == LLThread::currentID()); + +	//stop all Multi handle background threads +	for (curlmulti_set_t::iterator iter = mMultiSet.begin(); iter != mMultiSet.end(); ++iter) +	{ +		LLCurl::Multi* multi = *iter; +		multi->mQuitting = true; +		while (!multi->isStopped()) +		{ +			multi->mSignal->signal(); +			apr_sleep(1000); +		} +	}  	for_each(mMultiSet.begin(), mMultiSet.end(), DeletePointer());  } @@ -794,6 +852,7 @@ void LLCurlRequest::addMulti()  {  	llassert_always(mThreadID == LLThread::currentID());  	LLCurl::Multi* multi = new LLCurl::Multi(); +	multi->start();  	mMultiSet.insert(multi);  	mActiveMulti = multi;  	mActiveRequestCount = 0; @@ -923,6 +982,13 @@ S32 LLCurlRequest::process()  		if (multi != mActiveMulti && tres == 0 && multi->mQueued == 0)  		{  			mMultiSet.erase(curiter); +			multi->mQuitting = true; +			while (!multi->isStopped()) +			{ +				multi->mSignal->signal(); +				apr_sleep(1000); +			} +  			delete multi;  		}  	} @@ -953,6 +1019,7 @@ LLCurlEasyRequest::LLCurlEasyRequest()  	  mResultReturned(false)  {  	mMulti = new LLCurl::Multi(); +	mMulti->start();  	mEasy = mMulti->allocEasy();  	if (mEasy)  	{ @@ -963,6 +1030,12 @@ LLCurlEasyRequest::LLCurlEasyRequest()  LLCurlEasyRequest::~LLCurlEasyRequest()  { +	mMulti->mQuitting = true; +	while (!mMulti->isStopped()) +	{ +		mMulti->mSignal->signal(); +		apr_sleep(1000); +	}  	delete mMulti;  } @@ -1059,14 +1132,20 @@ void LLCurlEasyRequest::requestComplete()  	}  } -S32 LLCurlEasyRequest::perform() +void LLCurlEasyRequest::perform()  { -	return mMulti->perform(); +	mMulti->perform();  }  // Usage: Call getRestult until it returns false (no more messages)  bool LLCurlEasyRequest::getResult(CURLcode* result, LLCurl::TransferInfo* info)  { +	if (mMulti->mPerformState != LLCurl::Multi::PERFORM_STATE_COMPLETED) +	{ //we're busy, try again later +		return false; +	} +	mMulti->mPerformState = LLCurl::Multi::PERFORM_STATE_READY; +  	if (!mEasy)  	{  		// Special case - we failed to initialize a curl_easy (can happen if too many open files) diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h index 4ce3fa1078..2f951d6ab8 100644 --- a/indra/llmessage/llcurl.h +++ b/indra/llmessage/llcurl.h @@ -236,7 +236,7 @@ public:  	void slist_append(const char* str);  	void sendRequest(const std::string& url);  	void requestComplete(); -	S32 perform(); +	void perform();  	bool getResult(CURLcode* result, LLCurl::TransferInfo* info = NULL);  	std::string getErrorString(); diff --git a/indra/llmessage/llfiltersd2xmlrpc.cpp b/indra/llmessage/llfiltersd2xmlrpc.cpp index 812ef7c151..e0ca056a5f 100644 --- a/indra/llmessage/llfiltersd2xmlrpc.cpp +++ b/indra/llmessage/llfiltersd2xmlrpc.cpp @@ -308,6 +308,7 @@ LLFilterSD2XMLRPCResponse::~LLFilterSD2XMLRPCResponse()  } +static LLFastTimer::DeclareTimer FTM_PROCESS_SD2XMLRPC_RESPONSE("SD2XMLRPC Response");  // virtual  LLIOPipe::EStatus LLFilterSD2XMLRPCResponse::process_impl(  	const LLChannelDescriptors& channels, @@ -316,6 +317,8 @@ LLIOPipe::EStatus LLFilterSD2XMLRPCResponse::process_impl(  	LLSD& context,  	LLPumpIO* pump)  { +	LLFastTimer t(FTM_PROCESS_SD2XMLRPC_RESPONSE); +  	PUMP_DEBUG;  	// This pipe does not work if it does not have everyting. This  	// could be addressed by making a stream parser for llsd which @@ -382,6 +385,8 @@ LLFilterSD2XMLRPCRequest::~LLFilterSD2XMLRPCRequest()  {  } +static LLFastTimer::DeclareTimer FTM_PROCESS_SD2XMLRPC_REQUEST("S22XMLRPC Request"); +  // virtual  LLIOPipe::EStatus LLFilterSD2XMLRPCRequest::process_impl(  	const LLChannelDescriptors& channels, @@ -390,6 +395,7 @@ LLIOPipe::EStatus LLFilterSD2XMLRPCRequest::process_impl(  	LLSD& context,  	LLPumpIO* pump)  { +	LLFastTimer t(FTM_PROCESS_SD2XMLRPC_REQUEST);  	// This pipe does not work if it does not have everyting. This  	// could be addressed by making a stream parser for llsd which  	// handled partial information. @@ -586,6 +592,8 @@ LLFilterXMLRPCResponse2LLSD::~LLFilterXMLRPCResponse2LLSD()  {  } +static LLFastTimer::DeclareTimer FTM_PROCESS_XMLRPC2LLSD_RESPONSE("XMLRPC2LLSD Response"); +  LLIOPipe::EStatus LLFilterXMLRPCResponse2LLSD::process_impl(  	const LLChannelDescriptors& channels,  	buffer_ptr_t& buffer, @@ -593,6 +601,8 @@ LLIOPipe::EStatus LLFilterXMLRPCResponse2LLSD::process_impl(  	LLSD& context,  	LLPumpIO* pump)  { +	LLFastTimer t(FTM_PROCESS_XMLRPC2LLSD_RESPONSE); +  	PUMP_DEBUG;  	if(!eos) return STATUS_BREAK;  	if(!buffer) return STATUS_ERROR; @@ -668,6 +678,7 @@ LLFilterXMLRPCRequest2LLSD::~LLFilterXMLRPCRequest2LLSD()  {  } +static LLFastTimer::DeclareTimer FTM_PROCESS_XMLRPC2LLSD_REQUEST("XMLRPC2LLSD Request");  LLIOPipe::EStatus LLFilterXMLRPCRequest2LLSD::process_impl(  	const LLChannelDescriptors& channels,  	buffer_ptr_t& buffer, @@ -675,6 +686,7 @@ LLIOPipe::EStatus LLFilterXMLRPCRequest2LLSD::process_impl(  	LLSD& context,  	LLPumpIO* pump)  { +	LLFastTimer t(FTM_PROCESS_XMLRPC2LLSD_REQUEST);  	PUMP_DEBUG;  	if(!eos) return STATUS_BREAK;  	if(!buffer) return STATUS_ERROR; diff --git a/indra/llmessage/lliohttpserver.cpp b/indra/llmessage/lliohttpserver.cpp index 3b18a9177c..73e8a69085 100644 --- a/indra/llmessage/lliohttpserver.cpp +++ b/indra/llmessage/lliohttpserver.cpp @@ -140,6 +140,7 @@ private:  	LLSD mHeaders;  }; +static LLFastTimer::DeclareTimer FTM_PROCESS_HTTP_PIPE("HTTP Pipe");  LLIOPipe::EStatus LLHTTPPipe::process_impl(  	const LLChannelDescriptors& channels,      buffer_ptr_t& buffer, @@ -147,6 +148,7 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl(      LLSD& context,      LLPumpIO* pump)  { +	LLFastTimer t(FTM_PROCESS_HTTP_PIPE);  	PUMP_DEBUG;      lldebugs << "LLSDHTTPServer::process_impl" << llendl; @@ -428,6 +430,9 @@ protected:  /**   * LLHTTPResponseHeader   */ + +static LLFastTimer::DeclareTimer FTM_PROCESS_HTTP_HEADER("HTTP Header"); +  // virtual  LLIOPipe::EStatus LLHTTPResponseHeader::process_impl(  	const LLChannelDescriptors& channels, @@ -436,6 +441,7 @@ LLIOPipe::EStatus LLHTTPResponseHeader::process_impl(  	LLSD& context,  	LLPumpIO* pump)  { +	LLFastTimer t(FTM_PROCESS_HTTP_HEADER);  	PUMP_DEBUG;  	LLMemType m1(LLMemType::MTYPE_IO_HTTP_SERVER);  	if(eos) @@ -630,6 +636,8 @@ void LLHTTPResponder::markBad(  		<< "</body>\n</html>\n";  } +static LLFastTimer::DeclareTimer FTM_PROCESS_HTTP_RESPONDER("HTTP Responder"); +  // virtual  LLIOPipe::EStatus LLHTTPResponder::process_impl(  	const LLChannelDescriptors& channels, @@ -638,6 +646,7 @@ LLIOPipe::EStatus LLHTTPResponder::process_impl(  	LLSD& context,  	LLPumpIO* pump)  { +	LLFastTimer t(FTM_PROCESS_HTTP_RESPONDER);  	PUMP_DEBUG;  	LLMemType m1(LLMemType::MTYPE_IO_HTTP_SERVER);  	LLIOPipe::EStatus status = STATUS_OK; diff --git a/indra/llmessage/lliosocket.cpp b/indra/llmessage/lliosocket.cpp index 8c752fbe30..b717e321bf 100644 --- a/indra/llmessage/lliosocket.cpp +++ b/indra/llmessage/lliosocket.cpp @@ -301,6 +301,8 @@ LLIOSocketReader::~LLIOSocketReader()  	//lldebugs << "Destroying LLIOSocketReader" << llendl;  } +static LLFastTimer::DeclareTimer FTM_PROCESS_SOCKET_READER("Socket Reader"); +  // virtual  LLIOPipe::EStatus LLIOSocketReader::process_impl(  	const LLChannelDescriptors& channels, @@ -309,6 +311,7 @@ LLIOPipe::EStatus LLIOSocketReader::process_impl(  	LLSD& context,  	LLPumpIO* pump)  { +	LLFastTimer t(FTM_PROCESS_SOCKET_READER);  	PUMP_DEBUG;  	LLMemType m1(LLMemType::MTYPE_IO_TCP);  	if(!mSource) return STATUS_PRECONDITION_NOT_MET; @@ -401,6 +404,7 @@ LLIOSocketWriter::~LLIOSocketWriter()  	//lldebugs << "Destroying LLIOSocketWriter" << llendl;  } +static LLFastTimer::DeclareTimer FTM_PROCESS_SOCKET_WRITER("Socket Writer");  // virtual  LLIOPipe::EStatus LLIOSocketWriter::process_impl(  	const LLChannelDescriptors& channels, @@ -409,6 +413,7 @@ LLIOPipe::EStatus LLIOSocketWriter::process_impl(  	LLSD& context,  	LLPumpIO* pump)  { +	LLFastTimer t(FTM_PROCESS_SOCKET_WRITER);  	PUMP_DEBUG;  	LLMemType m1(LLMemType::MTYPE_IO_TCP);  	if(!mDestination) return STATUS_PRECONDITION_NOT_MET; @@ -555,6 +560,7 @@ void LLIOServerSocket::setResponseTimeout(F32 timeout_secs)  	mResponseTimeout = timeout_secs;  } +static LLFastTimer::DeclareTimer FTM_PROCESS_SERVER_SOCKET("Server Socket");  // virtual  LLIOPipe::EStatus LLIOServerSocket::process_impl(  	const LLChannelDescriptors& channels, @@ -563,6 +569,7 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl(  	LLSD& context,  	LLPumpIO* pump)  { +	LLFastTimer t(FTM_PROCESS_SERVER_SOCKET);  	PUMP_DEBUG;  	LLMemType m1(LLMemType::MTYPE_IO_TCP);  	if(!pump) diff --git a/indra/llmessage/llioutil.cpp b/indra/llmessage/llioutil.cpp index 2e6ee59ff2..8c50fd5069 100644 --- a/indra/llmessage/llioutil.cpp +++ b/indra/llmessage/llioutil.cpp @@ -43,6 +43,8 @@ LLIOPipe::EStatus LLIOFlush::process_impl(  	return STATUS_OK;  } + +static LLFastTimer::DeclareTimer FTM_PROCESS_SLEEP("IO Sleep");  /**    * @class LLIOSleep   */ @@ -53,6 +55,7 @@ LLIOPipe::EStatus LLIOSleep::process_impl(  	LLSD& context,  	LLPumpIO* pump)  { +	LLFastTimer t(FTM_PROCESS_SLEEP);  	if(mSeconds > 0.0)  	{  		if(pump) pump->sleepChain(mSeconds); @@ -62,6 +65,7 @@ LLIOPipe::EStatus LLIOSleep::process_impl(  	return STATUS_DONE;  } +static LLFastTimer::DeclareTimer FTM_PROCESS_ADD_CHAIN("Add Chain");  /**    * @class LLIOAddChain   */ @@ -72,6 +76,7 @@ LLIOPipe::EStatus LLIOAddChain::process_impl(  	LLSD& context,  	LLPumpIO* pump)  { +	LLFastTimer t(FTM_PROCESS_ADD_CHAIN);  	pump->addChain(mChain, mTimeout);  	return STATUS_DONE;  } diff --git a/indra/llmessage/llsdrpcclient.cpp b/indra/llmessage/llsdrpcclient.cpp index 86fe5c7912..91fd070f07 100644 --- a/indra/llmessage/llsdrpcclient.cpp +++ b/indra/llmessage/llsdrpcclient.cpp @@ -82,6 +82,8 @@ bool LLSDRPCResponse::extractResponse(const LLSD& sd)  	return rv;  } +static LLFastTimer::DeclareTimer FTM_SDRPC_RESPONSE("SDRPC Response"); +  // virtual  LLIOPipe::EStatus LLSDRPCResponse::process_impl(  	const LLChannelDescriptors& channels, @@ -90,6 +92,7 @@ LLIOPipe::EStatus LLSDRPCResponse::process_impl(  	LLSD& context,  	LLPumpIO* pump)  { +	LLFastTimer t(FTM_SDRPC_RESPONSE);  	PUMP_DEBUG;  	LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);  	if(mIsError) @@ -178,6 +181,8 @@ bool LLSDRPCClient::call(  	return true;  } +static LLFastTimer::DeclareTimer FTM_PROCESS_SDRPC_CLIENT("SDRPC Client"); +  // virtual  LLIOPipe::EStatus LLSDRPCClient::process_impl(  	const LLChannelDescriptors& channels, @@ -186,6 +191,7 @@ LLIOPipe::EStatus LLSDRPCClient::process_impl(  	LLSD& context,  	LLPumpIO* pump)  { +	LLFastTimer t(FTM_PROCESS_SDRPC_CLIENT);  	PUMP_DEBUG;  	LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);  	if((STATE_NONE == mState) || (!pump)) diff --git a/indra/llmessage/llsdrpcserver.cpp b/indra/llmessage/llsdrpcserver.cpp index f87c418fb1..9f776aca72 100644 --- a/indra/llmessage/llsdrpcserver.cpp +++ b/indra/llmessage/llsdrpcserver.cpp @@ -97,6 +97,8 @@ void LLSDRPCServer::clearLock()  	}  } +static LLFastTimer::DeclareTimer FTM_PROCESS_SDRPC_SERVER("SDRPC Server"); +  // virtual  LLIOPipe::EStatus LLSDRPCServer::process_impl(  	const LLChannelDescriptors& channels, @@ -105,6 +107,7 @@ LLIOPipe::EStatus LLSDRPCServer::process_impl(  	LLSD& context,  	LLPumpIO* pump)  { +	LLFastTimer t(FTM_PROCESS_SDRPC_SERVER);  	PUMP_DEBUG;  	LLMemType m1(LLMemType::MTYPE_IO_SD_SERVER);  //	lldebugs << "LLSDRPCServer::process_impl" << llendl; diff --git a/indra/llmessage/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp index 28bd09fc4c..e8e35d00a2 100644 --- a/indra/llmessage/llurlrequest.cpp +++ b/indra/llmessage/llurlrequest.cpp @@ -270,6 +270,8 @@ LLIOPipe::EStatus LLURLRequest::handleError(  	return status;  } +static LLFastTimer::DeclareTimer FTM_PROCESS_URL_REQUEST("URL Request"); +  // virtual  LLIOPipe::EStatus LLURLRequest::process_impl(  	const LLChannelDescriptors& channels, @@ -278,6 +280,7 @@ LLIOPipe::EStatus LLURLRequest::process_impl(  	LLSD& context,  	LLPumpIO* pump)  { +	LLFastTimer t(FTM_PROCESS_URL_REQUEST);  	PUMP_DEBUG;  	LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);  	//llinfos << "LLURLRequest::process_impl()" << llendl; @@ -288,6 +291,8 @@ LLIOPipe::EStatus LLURLRequest::process_impl(  	const S32 MIN_ACCUMULATION = 100000;  	if(pump && (mDetail->mByteAccumulator > MIN_ACCUMULATION))  	{ +		static LLFastTimer::DeclareTimer FTM_URL_ADJUST_TIMEOUT("Adjust Timeout"); +		LLFastTimer t(FTM_URL_ADJUST_TIMEOUT);  		 // This is a pretty sloppy calculation, but this  		 // tries to make the gross assumption that if data  		 // is coming in at 56kb/s, then this transfer will @@ -335,16 +340,30 @@ LLIOPipe::EStatus LLURLRequest::process_impl(  	{  		PUMP_DEBUG;  		LLIOPipe::EStatus status = STATUS_BREAK; -		mDetail->mCurlRequest->perform(); +		static LLFastTimer::DeclareTimer FTM_URL_PERFORM("Perform"); +		{ +			LLFastTimer t(FTM_URL_PERFORM); +			mDetail->mCurlRequest->perform(); +		} +  		while(1)  		{  			CURLcode result; -			bool newmsg = mDetail->mCurlRequest->getResult(&result); + +			static LLFastTimer::DeclareTimer FTM_PROCESS_URL_REQUEST_GET_RESULT("Get Result"); + +			bool newmsg = false; +			{ +				LLFastTimer t(FTM_PROCESS_URL_REQUEST_GET_RESULT); +				newmsg = mDetail->mCurlRequest->getResult(&result); +			} +		  			if(!newmsg)  			{  				// keep processing  				break;  			} +		  			mState = STATE_HAVE_RESPONSE;  			context[CONTEXT_REQUEST][CONTEXT_TRANSFERED_BYTES] = mRequestTransferedBytes; @@ -370,7 +389,11 @@ LLIOPipe::EStatus LLURLRequest::process_impl(  						link.mChannels = LLBufferArray::makeChannelConsumer(  							channels);  						chain.push_back(link); -						pump->respond(chain, buffer, context); +						static LLFastTimer::DeclareTimer FTM_PROCESS_URL_PUMP_RESPOND("Pump Respond"); +						{ +							LLFastTimer t(FTM_PROCESS_URL_PUMP_RESPOND); +							pump->respond(chain, buffer, context); +						}  						mCompletionCallback = NULL;  					}  					break; @@ -422,8 +445,11 @@ void LLURLRequest::initialize()  	mResponseTransferedBytes = 0;  } +static LLFastTimer::DeclareTimer FTM_URL_REQUEST_CONFIGURE("URL Configure");  bool LLURLRequest::configure()  { +	LLFastTimer t(FTM_URL_REQUEST_CONFIGURE); +	  	LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);  	bool rv = false;  	S32 bytes = mDetail->mResponseBuffer->countAfter( @@ -624,6 +650,7 @@ static size_t headerCallback(void* data, size_t size, size_t nmemb, void* user)  	return header_len;  } +static LLFastTimer::DeclareTimer FTM_PROCESS_URL_EXTRACTOR("URL Extractor");  /**   * LLContextURLExtractor   */ @@ -635,6 +662,7 @@ LLIOPipe::EStatus LLContextURLExtractor::process_impl(  	LLSD& context,  	LLPumpIO* pump)  { +	LLFastTimer t(FTM_PROCESS_URL_EXTRACTOR);  	PUMP_DEBUG;  	LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);  	// The destination host is in the context. @@ -713,6 +741,7 @@ void LLURLRequestComplete::responseStatus(LLIOPipe::EStatus status)  	mRequestStatus = status;  } +static LLFastTimer::DeclareTimer FTM_PROCESS_URL_COMPLETE("URL Complete");  // virtual  LLIOPipe::EStatus LLURLRequestComplete::process_impl(  	const LLChannelDescriptors& channels, @@ -721,6 +750,7 @@ LLIOPipe::EStatus LLURLRequestComplete::process_impl(  	LLSD& context,  	LLPumpIO* pump)  { +	LLFastTimer t(FTM_PROCESS_URL_COMPLETE);  	PUMP_DEBUG;  	complete(channels, buffer);  	return STATUS_OK; diff --git a/indra/llrender/llcubemap.cpp b/indra/llrender/llcubemap.cpp index fb22d7f1f5..1b10354c22 100644 --- a/indra/llrender/llcubemap.cpp +++ b/indra/llrender/llcubemap.cpp @@ -259,7 +259,7 @@ void LLCubeMap::setMatrix(S32 stage)  	if (mMatrixStage < 0) return; -	if (stage > 0) +	//if (stage > 0)  	{  		gGL.getTexUnit(stage)->activate();  	} @@ -278,17 +278,17 @@ void LLCubeMap::setMatrix(S32 stage)  	glLoadMatrixf((F32 *)trans.mMatrix);  	glMatrixMode(GL_MODELVIEW); -	if (stage > 0) +	/*if (stage > 0)  	{  		gGL.getTexUnit(0)->activate(); -	} +	}*/  }  void LLCubeMap::restoreMatrix()  {  	if (mMatrixStage < 0) return; -	if (mMatrixStage > 0) +	//if (mMatrixStage > 0)  	{  		gGL.getTexUnit(mMatrixStage)->activate();  	} @@ -296,10 +296,10 @@ void LLCubeMap::restoreMatrix()  	glPopMatrix();  	glMatrixMode(GL_MODELVIEW); -	if (mMatrixStage > 0) +	/*if (mMatrixStage > 0)  	{  		gGL.getTexUnit(0)->activate(); -	} +	}*/  }  void LLCubeMap::setReflection (void) diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index c224ab0e9b..8937726209 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -128,9 +128,21 @@ PFNGLGETBUFFERPARAMETERIVARBPROC	glGetBufferParameterivARB = NULL;  PFNGLGETBUFFERPOINTERVARBPROC		glGetBufferPointervARB = NULL;  // GL_ARB_map_buffer_range -PFNGLMAPBUFFERRANGEPROC			glMapBufferRange; -PFNGLFLUSHMAPPEDBUFFERRANGEPROC	glFlushMappedBufferRange; - +PFNGLMAPBUFFERRANGEPROC			glMapBufferRange = NULL; +PFNGLFLUSHMAPPEDBUFFERRANGEPROC	glFlushMappedBufferRange = NULL; + +// GL_ARB_sync +PFNGLFENCESYNCPROC				glFenceSync = NULL; +PFNGLISSYNCPROC					glIsSync = NULL; +PFNGLDELETESYNCPROC				glDeleteSync = NULL; +PFNGLCLIENTWAITSYNCPROC			glClientWaitSync = NULL; +PFNGLWAITSYNCPROC				glWaitSync = NULL; +PFNGLGETINTEGER64VPROC			glGetInteger64v = NULL; +PFNGLGETSYNCIVPROC				glGetSynciv = NULL; + +// GL_APPLE_flush_buffer_range +PFNGLBUFFERPARAMETERIAPPLEPROC	glBufferParameteriAPPLE = NULL; +PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC glFlushMappedBufferRangeAPPLE = NULL;  // vertex object prototypes  PFNGLNEWOBJECTBUFFERATIPROC			glNewObjectBufferATI = NULL; @@ -334,9 +346,10 @@ LLGLManager::LLGLManager() :  	mHasFramebufferObject(FALSE),  	mMaxSamples(0),  	mHasBlendFuncSeparate(FALSE), - +	mHasSync(FALSE),  	mHasVertexBufferObject(FALSE),  	mHasMapBufferRange(FALSE), +	mHasFlushBufferRange(FALSE),  	mHasPBuffer(FALSE),  	mHasShaderObjects(FALSE),  	mHasVertexShader(FALSE), @@ -774,7 +787,9 @@ void LLGLManager::initExtensions()  	mHasOcclusionQuery = ExtensionExists("GL_ARB_occlusion_query", gGLHExts.mSysExts);  	mHasOcclusionQuery2 = ExtensionExists("GL_ARB_occlusion_query2", gGLHExts.mSysExts);  	mHasVertexBufferObject = ExtensionExists("GL_ARB_vertex_buffer_object", gGLHExts.mSysExts); +	mHasSync = ExtensionExists("GL_ARB_sync", gGLHExts.mSysExts);  	mHasMapBufferRange = ExtensionExists("GL_ARB_map_buffer_range", gGLHExts.mSysExts); +	mHasFlushBufferRange = ExtensionExists("GL_APPLE_flush_buffer_range", gGLHExts.mSysExts);  	mHasDepthClamp = ExtensionExists("GL_ARB_depth_clamp", gGLHExts.mSysExts) || ExtensionExists("GL_NV_depth_clamp", gGLHExts.mSysExts);  	// mask out FBO support when packed_depth_stencil isn't there 'cause we need it for LLRenderTarget -Brad  #ifdef GL_ARB_framebuffer_object @@ -969,6 +984,16 @@ void LLGLManager::initExtensions()  			mHasVertexBufferObject = FALSE;  		}  	} +	if (mHasSync) +	{ +		glFenceSync = (PFNGLFENCESYNCPROC) GLH_EXT_GET_PROC_ADDRESS("glFenceSync"); +		glIsSync = (PFNGLISSYNCPROC) GLH_EXT_GET_PROC_ADDRESS("glIsSync"); +		glDeleteSync = (PFNGLDELETESYNCPROC) GLH_EXT_GET_PROC_ADDRESS("glDeleteSync"); +		glClientWaitSync = (PFNGLCLIENTWAITSYNCPROC) GLH_EXT_GET_PROC_ADDRESS("glClientWaitSync"); +		glWaitSync = (PFNGLWAITSYNCPROC) GLH_EXT_GET_PROC_ADDRESS("glWaitSync"); +		glGetInteger64v = (PFNGLGETINTEGER64VPROC) GLH_EXT_GET_PROC_ADDRESS("glGetInteger64v"); +		glGetSynciv = (PFNGLGETSYNCIVPROC) GLH_EXT_GET_PROC_ADDRESS("glGetSynciv"); +	}  	if (mHasMapBufferRange)  	{  		glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC) GLH_EXT_GET_PROC_ADDRESS("glMapBufferRange"); @@ -1354,6 +1379,8 @@ void LLGLState::checkStates(const std::string& msg)  	glGetIntegerv(GL_BLEND_SRC, &src);  	glGetIntegerv(GL_BLEND_DST, &dst); +	stop_glerror(); +  	BOOL error = FALSE;  	if (src != GL_SRC_ALPHA || dst != GL_ONE_MINUS_SRC_ALPHA) @@ -1374,7 +1401,9 @@ void LLGLState::checkStates(const std::string& msg)  	{  		LLGLenum state = iter->first;  		LLGLboolean cur_state = iter->second; +		stop_glerror();  		LLGLboolean gl_state = glIsEnabled(state); +		stop_glerror();  		if(cur_state != gl_state)  		{  			dumpStates(); @@ -1399,11 +1428,11 @@ void LLGLState::checkStates(const std::string& msg)  void LLGLState::checkTextureChannels(const std::string& msg)  { +#if 0  	if (!gDebugGL)  	{  		return;  	} -  	stop_glerror();  	GLint activeTexture; @@ -1569,6 +1598,7 @@ void LLGLState::checkTextureChannels(const std::string& msg)  			LL_GL_ERRS << "GL texture state corruption detected.  " << msg << LL_ENDL;  		}  	} +#endif  }  void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask) @@ -1685,7 +1715,7 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)  		}  	} -	if (glIsEnabled(GL_TEXTURE_2D)) +	/*if (glIsEnabled(GL_TEXTURE_2D))  	{  		if (!(data_mask & 0x0008))  		{ @@ -1708,7 +1738,7 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)  				gFailLog << "GL does not have GL_TEXTURE_2D enabled on channel 1." << std::endl;  			}  		} -	} +	}*/  	glClientActiveTextureARB(GL_TEXTURE0_ARB);  	gGL.getTexUnit(0)->activate(); diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index d1bee00161..d736133f3f 100644 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -88,7 +88,9 @@ public:  	// ARB Extensions  	BOOL mHasVertexBufferObject; +	BOOL mHasSync;  	BOOL mHasMapBufferRange; +	BOOL mHasFlushBufferRange;  	BOOL mHasPBuffer;  	BOOL mHasShaderObjects;  	BOOL mHasVertexShader; diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h index f35f329f00..851a75629e 100644 --- a/indra/llrender/llglheaders.h +++ b/indra/llrender/llglheaders.h @@ -68,6 +68,19 @@ extern PFNGLUNMAPBUFFERARBPROC		glUnmapBufferARB;  extern PFNGLGETBUFFERPARAMETERIVARBPROC	glGetBufferParameterivARB;  extern PFNGLGETBUFFERPOINTERVARBPROC	glGetBufferPointervARB; +// GL_ARB_sync +extern PFNGLFENCESYNCPROC				glFenceSync; +extern PFNGLISSYNCPROC					glIsSync; +extern PFNGLDELETESYNCPROC				glDeleteSync; +extern PFNGLCLIENTWAITSYNCPROC			glClientWaitSync; +extern PFNGLWAITSYNCPROC				glWaitSync; +extern PFNGLGETINTEGER64VPROC			glGetInteger64v; +extern PFNGLGETSYNCIVPROC				glGetSynciv; + +// GL_APPLE_flush_buffer_range +extern PFNGLBUFFERPARAMETERIAPPLEPROC	glBufferParameteriAPPLE; +extern PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC glFlushMappedBufferRangeAPPLE; +  // GL_ARB_map_buffer_range  extern PFNGLMAPBUFFERRANGEPROC			glMapBufferRange;  extern PFNGLFLUSHMAPPEDBUFFERRANGEPROC	glFlushMappedBufferRange; @@ -310,6 +323,19 @@ extern PFNGLUNMAPBUFFERARBPROC		glUnmapBufferARB;  extern PFNGLGETBUFFERPARAMETERIVARBPROC	glGetBufferParameterivARB;  extern PFNGLGETBUFFERPOINTERVARBPROC	glGetBufferPointervARB; +// GL_ARB_sync +extern PFNGLFENCESYNCPROC				glFenceSync; +extern PFNGLISSYNCPROC					glIsSync; +extern PFNGLDELETESYNCPROC				glDeleteSync; +extern PFNGLCLIENTWAITSYNCPROC			glClientWaitSync; +extern PFNGLWAITSYNCPROC				glWaitSync; +extern PFNGLGETINTEGER64VPROC			glGetInteger64v; +extern PFNGLGETSYNCIVPROC				glGetSynciv; + +// GL_APPLE_flush_buffer_range +extern PFNGLBUFFERPARAMETERIAPPLEPROC	glBufferParameteriAPPLE; +extern PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC glFlushMappedBufferRangeAPPLE; +  // GL_ARB_map_buffer_range  extern PFNGLMAPBUFFERRANGEPROC			glMapBufferRange;  extern PFNGLFLUSHMAPPEDBUFFERRANGEPROC	glFlushMappedBufferRange; @@ -519,6 +545,19 @@ extern PFNGLUNMAPBUFFERARBPROC		glUnmapBufferARB;  extern PFNGLGETBUFFERPARAMETERIVARBPROC	glGetBufferParameterivARB;  extern PFNGLGETBUFFERPOINTERVARBPROC	glGetBufferPointervARB; +// GL_ARB_sync +extern PFNGLFENCESYNCPROC				glFenceSync; +extern PFNGLISSYNCPROC					glIsSync; +extern PFNGLDELETESYNCPROC				glDeleteSync; +extern PFNGLCLIENTWAITSYNCPROC			glClientWaitSync; +extern PFNGLWAITSYNCPROC				glWaitSync; +extern PFNGLGETINTEGER64VPROC			glGetInteger64v; +extern PFNGLGETSYNCIVPROC				glGetSynciv; + +// GL_APPLE_flush_buffer_range +extern PFNGLBUFFERPARAMETERIAPPLEPROC	glBufferParameteriAPPLE; +extern PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC glFlushMappedBufferRangeAPPLE; +  // GL_ARB_map_buffer_range  extern PFNGLMAPBUFFERRANGEPROC			glMapBufferRange;  extern PFNGLFLUSHMAPPEDBUFFERRANGEPROC	glFlushMappedBufferRange; diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index ad2c662dfc..80c93bb0d2 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -49,6 +49,11 @@ using std::make_pair;  using std::string;  GLhandleARB LLGLSLShader::sCurBoundShader = 0; +bool LLGLSLShader::sNoFixedFunction = false; + +//UI shader -- declared here so llui_libtest will link properly +LLGLSLShader	gUIProgram; +LLGLSLShader	gSolidColorProgram;  BOOL shouldChange(const LLVector4& v1, const LLVector4& v2)  { @@ -376,6 +381,7 @@ BOOL LLGLSLShader::link(BOOL suppress_errors)  void LLGLSLShader::bind()  { +	gGL.flush();  	if (gGLManager.mHasShaderObjects)  	{  		glUseProgramObjectARB(mProgramObject); @@ -390,6 +396,7 @@ void LLGLSLShader::bind()  void LLGLSLShader::unbind()  { +	gGL.flush();  	if (gGLManager.mHasShaderObjects)  	{  		stop_glerror(); diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h index 4922eb6d67..621e0b82ee 100644 --- a/indra/llrender/llglslshader.h +++ b/indra/llrender/llglslshader.h @@ -67,6 +67,7 @@ public:  	LLGLSLShader();  	static GLhandleARB sCurBoundShader; +	static bool sNoFixedFunction;  	void unload();  	BOOL createShader(std::vector<std::string> * attributes, @@ -141,4 +142,10 @@ public:  	std::string mName;  }; +//UI shader (declared here so llui_libtest will link properly) +extern LLGLSLShader			gUIProgram; +//output vec4(color.rgb,color.a*tex0[tc0].a) +extern LLGLSLShader			gSolidColorProgram; + +  #endif diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 60a5962234..9ca3a23d52 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -1414,6 +1414,8 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre  void LLImageGL::deleteDeadTextures()  { +	bool reset = false; +  	while (!sDeadTextureList.empty())  	{  		GLuint tex = sDeadTextureList.front(); @@ -1426,12 +1428,22 @@ void LLImageGL::deleteDeadTextures()  			{  				tex_unit->unbind(tex_unit->getCurrType());  				stop_glerror(); + +				if (i > 0) +				{ +					reset = true; +				}  			}  		}  		glDeleteTextures(1, &tex);  		stop_glerror();  	} + +	if (reset) +	{ +		gGL.getTexUnit(0)->activate(); +	}  }  void LLImageGL::destroyGLTexture() diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 1d82dda30f..70df1dd1d1 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -46,6 +46,7 @@ S32	gGLViewport[4];  U32 LLRender::sUICalls = 0;  U32 LLRender::sUIVerts = 0; +U32 LLTexUnit::sWhiteTexture = 0;  static const U32 LL_NUM_TEXTURE_LAYERS = 32;   static const U32 LL_NUM_LIGHT_UNITS = 8; @@ -126,7 +127,8 @@ void LLTexUnit::refreshState(void)  	// Per apple spec, don't call glEnable/glDisable when index exceeds max texture units  	// http://www.mailinglistarchive.com/html/mac-opengl@lists.apple.com/2008-07/msg00653.html  	// -	bool enableDisable = (mIndex < gGLManager.mNumTextureUnits) && mCurrTexType != LLTexUnit::TT_MULTISAMPLE_TEXTURE; +	bool enableDisable = !LLGLSLShader::sNoFixedFunction &&  +		(mIndex < gGLManager.mNumTextureUnits) && mCurrTexType != LLTexUnit::TT_MULTISAMPLE_TEXTURE;  	if (mCurrTexType != TT_NONE)  	{ @@ -184,7 +186,8 @@ void LLTexUnit::enable(eTextureType type)  		mCurrTexType = type;  		gGL.flush(); -		if (type != LLTexUnit::TT_MULTISAMPLE_TEXTURE && +		if (!LLGLSLShader::sNoFixedFunction &&  +			type != LLTexUnit::TT_MULTISAMPLE_TEXTURE &&  			mIndex < gGLManager.mNumTextureUnits)  		{  			glEnable(sGLTextureType[type]); @@ -201,7 +204,8 @@ void LLTexUnit::disable(void)  		activate();  		unbind(mCurrTexType);  		gGL.flush(); -		if (mCurrTexType != LLTexUnit::TT_MULTISAMPLE_TEXTURE && +		if (!LLGLSLShader::sNoFixedFunction && +			mCurrTexType != LLTexUnit::TT_MULTISAMPLE_TEXTURE &&  			mIndex < gGLManager.mNumTextureUnits)  		{  			glDisable(sGLTextureType[mCurrTexType]); @@ -403,7 +407,14 @@ void LLTexUnit::unbind(eTextureType type)  		activate();  		mCurrTexture = 0; -		glBindTexture(sGLTextureType[type], 0); +		if (LLGLSLShader::sNoFixedFunction && type == LLTexUnit::TT_TEXTURE) +		{ +			glBindTexture(sGLTextureType[type], sWhiteTexture); +		} +		else +		{ +			glBindTexture(sGLTextureType[type], 0); +		}  		stop_glerror();  	}  } @@ -474,6 +485,11 @@ void LLTexUnit::setTextureFilteringOption(LLTexUnit::eTextureFilterOptions optio  void LLTexUnit::setTextureBlendType(eTextureBlendType type)  { +	if (LLGLSLShader::sNoFixedFunction) +	{ //texture blend type means nothing when using shaders +		return; +	} +  	if (mIndex < 0) return;  	// Do nothing if it's already correctly set. @@ -594,6 +610,11 @@ GLint LLTexUnit::getTextureSourceType(eTextureBlendSrc src, bool isAlpha)  void LLTexUnit::setTextureCombiner(eTextureBlendOp op, eTextureBlendSrc src1, eTextureBlendSrc src2, bool isAlpha)  { +	if (LLGLSLShader::sNoFixedFunction) +	{ //register combiners do nothing when not using fixed function +		return; +	}	 +  	if (mIndex < 0) return;  	activate(); diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index 41e7b35341..9eedebe2ce 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -52,6 +52,8 @@ class LLTexUnit  {  	friend class LLRender;  public: +	static U32 sWhiteTexture; +  	typedef enum  	{  		TT_TEXTURE = 0,			// Standard 2D Texture diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index b6463309e1..8c0d3592df 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -72,11 +72,11 @@ LLRenderTarget::~LLRenderTarget()  	release();  } -void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo, S32 samples) +bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo, S32 samples)  {  	stop_glerror(); -	  	release(); +	stop_glerror();  	mResX = resx;  	mResY = resy; @@ -103,9 +103,11 @@ void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, boo  	{  		if (depth)  		{ -			stop_glerror(); -			allocateDepth(); -			stop_glerror(); +			if (!allocateDepth()) +			{ +				llwarns << "Failed to allocate depth buffer for render target." << llendl; +				return false; +			}  		}  		glGenFramebuffers(1, (GLuint *) &mFBO); @@ -131,14 +133,14 @@ void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, boo  		stop_glerror();  	} -	addColorAttachment(color_fmt); +	return addColorAttachment(color_fmt);  } -void LLRenderTarget::addColorAttachment(U32 color_fmt) +bool LLRenderTarget::addColorAttachment(U32 color_fmt)  {  	if (color_fmt == 0)  	{ -		return; +		return true;  	}  	U32 offset = mTex.size(); @@ -158,14 +160,26 @@ void LLRenderTarget::addColorAttachment(U32 color_fmt)  #ifdef GL_ARB_texture_multisample  	if (mSamples > 1)  	{ +		clear_glerror();  		glTexImage2DMultisample(LLTexUnit::getInternalType(mUsage), mSamples, color_fmt, mResX, mResY, GL_TRUE); +		if (glGetError() != GL_NO_ERROR) +		{ +			llwarns << "Could not allocate multisample color buffer for render target." << llendl; +			return false; +		}  	}  	else  #else  	llassert_always(mSamples <= 1);  #endif  	{ +		clear_glerror();  		LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL); +		if (glGetError() != GL_NO_ERROR) +		{ +			llwarns << "Could not allocate color buffer for render target." << llendl; +			return false; +		}  	}  	stop_glerror(); @@ -217,15 +231,18 @@ void LLRenderTarget::addColorAttachment(U32 color_fmt)  		flush();  	} +	return true;  } -void LLRenderTarget::allocateDepth() +bool LLRenderTarget::allocateDepth()  {  	if (mStencil)  	{  		//use render buffers where stencil buffers are in play  		glGenRenderbuffers(1, (GLuint *) &mDepth);  		glBindRenderbuffer(GL_RENDERBUFFER, mDepth); +		stop_glerror(); +		clear_glerror();  		glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, mResX, mResY);  		glBindRenderbuffer(GL_RENDERBUFFER, 0);  	} @@ -237,17 +254,29 @@ void LLRenderTarget::allocateDepth()  		{  			U32 internal_type = LLTexUnit::getInternalType(mUsage);  			gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); +			stop_glerror(); +			clear_glerror();  			LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT32, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);  		}  #ifdef GL_ARB_texture_multisample  		else  		{ +			stop_glerror(); +			clear_glerror();  			glTexImage2DMultisample(LLTexUnit::getInternalType(mUsage), mSamples, GL_DEPTH_COMPONENT32, mResX, mResY, GL_TRUE);  		}  #else  		llassert_always(mSamples <= 1);  #endif  	} + +	if (glGetError() != GL_NO_ERROR) +	{ +		llwarns << "Unable to allocate depth buffer for render target." << llendl; +		return false; +	} + +	return true;  }  void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target) diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h index 094b58b562..dea1de12d8 100644 --- a/indra/llrender/llrendertarget.h +++ b/indra/llrender/llrendertarget.h @@ -66,30 +66,30 @@ public:  	static bool sUseFBO;   	LLRenderTarget(); -	virtual ~LLRenderTarget(); +	~LLRenderTarget();  	//allocate resources for rendering  	//must be called before use  	//multiple calls will release previously allocated resources -	void allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE, bool use_fbo = false, S32 samples = 0); +	bool allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE, bool use_fbo = false, S32 samples = 0);  	//add color buffer attachment  	//limit of 4 color attachments per render target -	virtual void addColorAttachment(U32 color_fmt); +	bool addColorAttachment(U32 color_fmt);  	//allocate a depth texture -	virtual void allocateDepth(); +	bool allocateDepth();  	//share depth buffer with provided render target -	virtual void shareDepthBuffer(LLRenderTarget& target); +	void shareDepthBuffer(LLRenderTarget& target);  	//free any allocated resources  	//safe to call redundantly -	virtual void release(); +	void release();  	//bind target for rendering  	//applies appropriate viewport -	virtual void bindTarget(); +	void bindTarget();  	//unbind target for rendering  	static void unbindTarget(); diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 4a0b964e61..1180afa631 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -35,6 +35,8 @@  #include "llmemtype.h"  #include "llrender.h"  #include "llvector4a.h" +#include "llglslshader.h" +  //============================================================================ @@ -65,6 +67,60 @@ S32	LLVertexBuffer::sWeight4Loc = -1;  std::vector<U32> LLVertexBuffer::sDeleteList; +const U32 FENCE_WAIT_TIME_NANOSECONDS = 10000;  //1 ms + +class LLGLSyncFence : public LLGLFence +{ +public: +#ifdef GL_ARB_sync +	GLsync mSync; +#endif +	 +	LLGLSyncFence() +	{ +#ifdef GL_ARB_sync +		mSync = 0; +#endif +	} + +	~LLGLSyncFence() +	{ +#ifdef GL_ARB_sync +		if (mSync) +		{ +			glDeleteSync(mSync); +		} +#endif +	} + +	void placeFence() +	{ +#ifdef GL_ARB_sync +		if (mSync) +		{ +			glDeleteSync(mSync); +		} +		mSync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); +#endif +	} + +	void wait() +	{ +#ifdef GL_ARB_sync +		if (mSync) +		{ +			while (glClientWaitSync(mSync, 0, FENCE_WAIT_TIME_NANOSECONDS) == GL_TIMEOUT_EXPIRED) +			{ //track the number of times we've waited here +				static S32 waits = 0; +				waits++; +			} +		} +#endif +	} + + +}; +  S32 LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_MAX] =  {  	sizeof(LLVector4), // TYPE_VERTEX, @@ -309,6 +365,7 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi  	glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT,   		idx);  	stop_glerror(); +	placeFence();  }  void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const @@ -340,6 +397,7 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const  	glDrawElements(sGLMode[mode], count, GL_UNSIGNED_SHORT,  		((U16*) getIndicesPointer()) + indices_offset);  	stop_glerror(); +	placeFence();  }  void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const @@ -365,6 +423,7 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const  	stop_glerror();  	glDrawArrays(sGLMode[mode], first, count);  	stop_glerror(); +	placeFence();  }  //static @@ -444,9 +503,11 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :  	mFilthy(FALSE),  	mEmpty(TRUE),  	mResized(FALSE), -	mDynamicSize(FALSE) +	mDynamicSize(FALSE), +	mFence(NULL)  {  	LLMemType mt2(LLMemType::MTYPE_VERTEX_CONSTRUCTOR); +	mFence = NULL;  	if (!sEnableVBOs)  	{  		mUsage = 0 ;  @@ -527,9 +588,40 @@ LLVertexBuffer::~LLVertexBuffer()  	destroyGLIndices();  	sCount--; +	if (mFence) +	{ +		delete mFence; +	} +	 +	mFence = NULL; +  	llassert_always(!mMappedData && !mMappedIndexData) ;  }; +void LLVertexBuffer::placeFence() const +{ +	/*if (!mFence && useVBOs()) +	{ +		if (gGLManager.mHasSync) +		{ +			mFence = new LLGLSyncFence(); +		} +	} + +	if (mFence) +	{ +		mFence->placeFence(); +	}*/ +} + +void LLVertexBuffer::waitFence() const +{ +	/*if (mFence) +	{ +		mFence->wait(); +	}*/ +} +  //----------------------------------------------------------------------------  void LLVertexBuffer::genBuffer() @@ -892,17 +984,11 @@ BOOL LLVertexBuffer::useVBOs() const  {  	//it's generally ineffective to use VBO for things that are streaming on apple -#if LL_DARWIN -	if (!mUsage || mUsage == GL_STREAM_DRAW_ARB) -	{ -		return FALSE; -	} -#else  	if (!mUsage)  	{  		return FALSE;  	} -#endif +  	return TRUE;  } @@ -967,8 +1053,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran  	if (useVBOs())  	{ - -		if (sDisableVBOMapping || gGLManager.mHasMapBufferRange) +		if (sDisableVBOMapping || gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange)  		{  			if (count == -1)  			{ @@ -1008,6 +1093,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran  			LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_VERTICES);  			setBuffer(0, type);  			mVertexLocked = TRUE; +			sMappedCount++;  			stop_glerror();	  			if(sDisableVBOMapping) @@ -1018,29 +1104,50 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran  			else  			{  				U8* src = NULL; -#ifdef GL_ARB_map_buffer_range +				waitFence();  				if (gGLManager.mHasMapBufferRange)  				{  					if (map_range)  					{ +#ifdef GL_ARB_map_buffer_range  						S32 offset = mOffsets[type] + sTypeSize[type]*index;  						S32 length = (sTypeSize[type]*count+0xF) & ~0xF; -						src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER_ARB, offset, length, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_INVALIDATE_RANGE_BIT); +						src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER_ARB, offset, length,  +							GL_MAP_WRITE_BIT |  +							GL_MAP_FLUSH_EXPLICIT_BIT |  +							GL_MAP_INVALIDATE_RANGE_BIT); +#endif  					}  					else  					{ -						src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER_ARB, 0, mSize, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT); +#ifdef GL_ARB_map_buffer_range +						src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER_ARB, 0, mSize,  +							GL_MAP_WRITE_BIT |  +							GL_MAP_FLUSH_EXPLICIT_BIT); +#endif +					} +				} +				else if (gGLManager.mHasFlushBufferRange) +				{ +					if (map_range) +					{ +						glBufferParameteriAPPLE(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE); +						glBufferParameteriAPPLE(GL_ARRAY_BUFFER_ARB, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE); +						src = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); +					} +					else +					{ +						src = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);  					}  				}  				else -#else -				llassert_always(!gGLManager.mHasMapBufferRange); -#endif  				{  					map_range = false;  					src = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);  				} +				llassert(src != NULL); +  				mMappedData = LL_NEXT_ALIGNED_ADDRESS<U8>(src);  				mAlignedOffset = mMappedData - src; @@ -1082,7 +1189,6 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran  					llerrs << "memory allocation for vertex data failed." << llendl ;  				}  			} -			sMappedCount++;  		}  	}  	else @@ -1090,7 +1196,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran  		map_range = false;  	} -	if (map_range && !sDisableVBOMapping) +	if (map_range && gGLManager.mHasMapBufferRange && !sDisableVBOMapping)  	{  		return mMappedData;  	} @@ -1114,7 +1220,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)  	if (useVBOs())  	{ -		if (sDisableVBOMapping || gGLManager.mHasMapBufferRange) +		if (sDisableVBOMapping || gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange)  		{  			if (count == -1)  			{ @@ -1152,6 +1258,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)  			setBuffer(0, TYPE_INDEX);  			mIndexLocked = TRUE; +			sMappedCount++;  			stop_glerror();	  			if(sDisableVBOMapping) @@ -1162,29 +1269,51 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)  			else  			{  				U8* src = NULL; -#ifdef GL_ARB_map_buffer_range +				waitFence();  				if (gGLManager.mHasMapBufferRange)  				{  					if (map_range)  					{ +#ifdef GL_ARB_map_buffer_range  						S32 offset = sizeof(U16)*index;  						S32 length = sizeof(U16)*count; -						src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_INVALIDATE_RANGE_BIT); +						src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length,  +							GL_MAP_WRITE_BIT |  +							GL_MAP_FLUSH_EXPLICIT_BIT |  +							GL_MAP_INVALIDATE_RANGE_BIT); +#endif +					} +					else +					{ +#ifdef GL_ARB_map_buffer_range +						src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, sizeof(U16)*mNumIndices,  +							GL_MAP_WRITE_BIT |  +							GL_MAP_FLUSH_EXPLICIT_BIT); +#endif +					} +				} +				else if (gGLManager.mHasFlushBufferRange) +				{ +					if (map_range) +					{ +						glBufferParameteriAPPLE(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE); +						glBufferParameteriAPPLE(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE); +						src = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);  					}  					else  					{ -						src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, sizeof(U16)*mNumIndices, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT); +						src = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);  					}  				}  				else -#else -				llassert_always(!gGLManager.mHasMapBufferRange); -#endif  				{  					map_range = false;  					src = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);  				} +				llassert(src != NULL); + +  				mMappedIndexData = src; //LL_NEXT_ALIGNED_ADDRESS<U8>(src);  				mAlignedIndexOffset = mMappedIndexData - src;  				stop_glerror(); @@ -1211,15 +1340,13 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)  				llerrs << "memory allocation for Index data failed. " << llendl ;  			}  		} - -		sMappedCount++;  	}  	else  	{  		map_range = false;  	} -	if (map_range && !sDisableVBOMapping) +	if (map_range && gGLManager.mHasMapBufferRange && !sDisableVBOMapping)  	{  		return mMappedIndexData;  	} @@ -1268,8 +1395,7 @@ void LLVertexBuffer::unmapBuffer(S32 type)  		}  		else  		{ -#ifdef GL_ARB_map_buffer_range -			if (gGLManager.mHasMapBufferRange) +			if (gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange)  			{  				if (!mMappedVertexRegions.empty())  				{ @@ -1279,16 +1405,22 @@ void LLVertexBuffer::unmapBuffer(S32 type)  						const MappedRegion& region = mMappedVertexRegions[i];  						S32 offset = region.mIndex >= 0 ? mOffsets[region.mType]+sTypeSize[region.mType]*region.mIndex : 0;  						S32 length = sTypeSize[region.mType]*region.mCount; -						glFlushMappedBufferRange(GL_ARRAY_BUFFER_ARB, offset, length); +						if (gGLManager.mHasMapBufferRange) +						{ +#ifdef GL_ARB_map_buffer_range +							glFlushMappedBufferRange(GL_ARRAY_BUFFER_ARB, offset, length); +#endif +						} +						else if (gGLManager.mHasFlushBufferRange) +						{ +							glFlushMappedBufferRangeAPPLE(GL_ARRAY_BUFFER_ARB, offset, length); +						}  						stop_glerror();  					}  					mMappedVertexRegions.clear();  				}  			} -#else -			llassert_always(!gGLManager.mHasMapBufferRange); -#endif  			stop_glerror();  			glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);  			stop_glerror(); @@ -1326,8 +1458,7 @@ void LLVertexBuffer::unmapBuffer(S32 type)  		}  		else  		{ -#ifdef GL_ARB_map_buffer_range -			if (gGLManager.mHasMapBufferRange) +			if (gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange)  			{  				if (!mMappedIndexRegions.empty())  				{ @@ -1336,16 +1467,24 @@ void LLVertexBuffer::unmapBuffer(S32 type)  						const MappedRegion& region = mMappedIndexRegions[i];  						S32 offset = region.mIndex >= 0 ? sizeof(U16)*region.mIndex : 0;  						S32 length = sizeof(U16)*region.mCount; -						glFlushMappedBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length); +						if (gGLManager.mHasMapBufferRange) +						{ +#ifdef GL_ARB_map_buffer_range +							glFlushMappedBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length); +#endif +						} +						else if (gGLManager.mHasFlushBufferRange) +						{ +#ifdef GL_APPLE_flush_buffer_range +							glFlushMappedBufferRangeAPPLE(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length); +#endif +						}  						stop_glerror();  					}  					mMappedIndexRegions.clear();  				}  			} -#else -			llassert_always(!gGLManager.mHasMapBufferRange); -#endif  			stop_glerror();  			glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);  			stop_glerror(); diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index aa5df305a6..cc5d11e1c2 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -70,6 +70,12 @@ protected:  	}  }; +class LLGLFence +{ +public: +	virtual void placeFence() = 0; +	virtual void wait() = 0; +};  //============================================================================  // base class  @@ -270,6 +276,12 @@ protected:  	std::vector<MappedRegion> mMappedVertexRegions;  	std::vector<MappedRegion> mMappedIndexRegions; +	mutable LLGLFence* mFence; + +	void placeFence() const; +	void waitFence() const; + +  public:  	static S32 sCount;  	static S32 sGLCount; diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index 8020ca802b..28d7e0a5ba 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -95,7 +95,6 @@ static LLDefaultChildRegistry::Register<LLSearchEditor> register_search_editor("  // register other widgets which otherwise may not be linked in  static LLDefaultChildRegistry::Register<LLLoadingIndicator> register_loading_indicator("loading_indicator"); -  //  // Functions  // @@ -524,8 +523,15 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTex  	if (solid_color)  	{ -		gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR); -		gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_ALPHA, LLTexUnit::TBS_VERT_ALPHA); +		if (LLGLSLShader::sNoFixedFunction) +		{ +			gSolidColorProgram.bind(); +		} +		else +		{ +			gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR); +			gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_ALPHA, LLTexUnit::TBS_VERT_ALPHA); +		}  	}  	gGL.getTexUnit(0)->bind(image); @@ -699,7 +705,14 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTex  	if (solid_color)  	{ -		gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); +		if (LLGLSLShader::sNoFixedFunction) +		{ +			gUIProgram.bind(); +		} +		else +		{ +			gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); +		}  	}  } diff --git a/indra/llui/llui.h b/indra/llui/llui.h index c583d58d5a..a04b232a28 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -33,6 +33,7 @@  #include "llrect.h"  #include "llcontrol.h"  #include "llcoord.h" +#include "llglslshader.h"  #include "llinitparam.h"  #include "llregistry.h"  #include "lluicolor.h" @@ -47,6 +48,7 @@  // for initparam specialization  #include "llfontgl.h" +  class LLColor4;   class LLVector3;  class LLVector2; @@ -484,4 +486,7 @@ namespace LLInitParam  	};  } +extern LLGLSLShader gSolidColorProgram; +extern LLGLSLShader gUIProgram; +  #endif diff --git a/indra/newview/app_settings/logcontrol.xml b/indra/newview/app_settings/logcontrol.xml index 9f4e89691f..ae72dee900 100644 --- a/indra/newview/app_settings/logcontrol.xml +++ b/indra/newview/app_settings/logcontrol.xml @@ -44,7 +44,6 @@  						<array>  							<!-- sample entry for debugging a specific item	-->  <!--						<string>Voice</string>							--> -              <string>Capabilities</string>  						</array>  				</map>  			</array> diff --git a/indra/newview/app_settings/shaders/class1/interface/customalphaF.glsl b/indra/newview/app_settings/shaders/class1/interface/customalphaF.glsl new file mode 100644 index 0000000000..3827c72f4c --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/customalphaF.glsl @@ -0,0 +1,17 @@ +/**  + * @file customalphaF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  +uniform sampler2D diffuseMap; + +uniform float custom_alpha; + +void main()  +{ +	vec4 color = gl_Color*texture2D(diffuseMap, gl_TexCoord[0].xy); +	color.a *= custom_alpha; +	gl_FragColor = color; +} diff --git a/indra/newview/app_settings/shaders/class1/interface/customalphaV.glsl b/indra/newview/app_settings/shaders/class1/interface/customalphaV.glsl new file mode 100644 index 0000000000..04bfff22c1 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/customalphaV.glsl @@ -0,0 +1,16 @@ +/**  + * @file customalphaV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  + + +void main() +{ +	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; +	gl_TexCoord[0] = gl_MultiTexCoord0; +	gl_FrontColor = gl_Color; +} + diff --git a/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl b/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl new file mode 100644 index 0000000000..a60fb1eaa7 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl @@ -0,0 +1,17 @@ +/**  + * @file glowcombineF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2D glowMap; +uniform sampler2DRect screenMap; + +void main()  +{ +	gl_FragColor = texture2D(glowMap, gl_TexCoord[0].xy) + +					texture2DRect(screenMap, gl_TexCoord[1].xy); +} diff --git a/indra/newview/app_settings/shaders/class1/interface/glowcombineV.glsl b/indra/newview/app_settings/shaders/class1/interface/glowcombineV.glsl new file mode 100644 index 0000000000..ce183ec154 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/glowcombineV.glsl @@ -0,0 +1,15 @@ +/**  + * @file glowcombineV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  + +void main() +{ +	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; +	gl_TexCoord[0] = gl_MultiTexCoord0; +	gl_TexCoord[1] = gl_MultiTexCoord1; +} + diff --git a/indra/newview/app_settings/shaders/class1/interface/occlusionF.glsl b/indra/newview/app_settings/shaders/class1/interface/occlusionF.glsl new file mode 100644 index 0000000000..b140712f18 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/occlusionF.glsl @@ -0,0 +1,11 @@ +/**  + * @file occlusionF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  +void main()  +{ +	gl_FragColor = vec4(1,1,1,1); +} diff --git a/indra/newview/app_settings/shaders/class1/interface/occlusionV.glsl b/indra/newview/app_settings/shaders/class1/interface/occlusionV.glsl new file mode 100644 index 0000000000..5a5d0ec506 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/occlusionV.glsl @@ -0,0 +1,12 @@ +/**  + * @file uiV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +void main() +{ +	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; +} + diff --git a/indra/newview/app_settings/shaders/class1/interface/solidcolorF.glsl b/indra/newview/app_settings/shaders/class1/interface/solidcolorF.glsl new file mode 100644 index 0000000000..ae943cc438 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/solidcolorF.glsl @@ -0,0 +1,15 @@ +/**  + * @file twotextureaddF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  +uniform sampler2D tex0; + +void main()  +{ +	float alpha = texture2D(tex0, gl_TexCoord[0].xy).a; + +	gl_FragColor = vec4(gl_Color.rgb, alpha); +} diff --git a/indra/newview/app_settings/shaders/class1/interface/solidcolorV.glsl b/indra/newview/app_settings/shaders/class1/interface/solidcolorV.glsl new file mode 100644 index 0000000000..5a854b4e02 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/solidcolorV.glsl @@ -0,0 +1,15 @@ +/**  + * @file solidcolorV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  + + +void main() +{ +	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; +	gl_TexCoord[0] = gl_MultiTexCoord0; +} + diff --git a/indra/newview/app_settings/shaders/class1/interface/twotextureaddF.glsl b/indra/newview/app_settings/shaders/class1/interface/twotextureaddF.glsl new file mode 100644 index 0000000000..d81b56fdb9 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/twotextureaddF.glsl @@ -0,0 +1,14 @@ +/**  + * @file twotextureaddF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  +uniform sampler2D tex0; +uniform sampler2D tex1; + +void main()  +{ +	gl_FragColor = texture2D(tex0, gl_TexCoord[0].xy)+texture2D(tex1, gl_TexCoord[1].xy); +} diff --git a/indra/newview/app_settings/shaders/class1/interface/twotextureaddV.glsl b/indra/newview/app_settings/shaders/class1/interface/twotextureaddV.glsl new file mode 100644 index 0000000000..f685b112b4 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/twotextureaddV.glsl @@ -0,0 +1,16 @@ +/**  + * @file twotextureaddV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  + + +void main() +{ +	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; +	gl_TexCoord[0] = gl_MultiTexCoord0; +	gl_TexCoord[1] = gl_MultiTexCoord1; +} + diff --git a/indra/newview/app_settings/shaders/class1/interface/uiF.glsl b/indra/newview/app_settings/shaders/class1/interface/uiF.glsl new file mode 100644 index 0000000000..9dec7a56ba --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/uiF.glsl @@ -0,0 +1,13 @@ +/**  + * @file uiF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  +uniform sampler2D diffuseMap; + +void main()  +{ +	gl_FragColor = gl_Color*texture2D(diffuseMap, gl_TexCoord[0].xy); +} diff --git a/indra/newview/app_settings/shaders/class1/interface/uiV.glsl b/indra/newview/app_settings/shaders/class1/interface/uiV.glsl new file mode 100644 index 0000000000..9ca6cae5c5 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/uiV.glsl @@ -0,0 +1,16 @@ +/**  + * @file uiV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  + + +void main() +{ +	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; +	gl_TexCoord[0] = gl_MultiTexCoord0; +	gl_FrontColor = gl_Color; +} + diff --git a/indra/newview/app_settings/shaders/class1/objects/bumpF.glsl b/indra/newview/app_settings/shaders/class1/objects/bumpF.glsl new file mode 100644 index 0000000000..587ab93a80 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/objects/bumpF.glsl @@ -0,0 +1,17 @@ +/**  + * @file bumpF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  +uniform sampler2D texture0; +uniform sampler2D texture1; + +void main()  +{ +	float tex0 = texture2D(texture0, gl_TexCoord[0].xy).a; +	float tex1 = texture2D(texture1, gl_TexCoord[1].xy).a; + +	gl_FragColor = vec4(tex0+(1.0-tex1)-0.5); +} diff --git a/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl b/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl new file mode 100644 index 0000000000..056d1a9582 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl @@ -0,0 +1,16 @@ +/**  + * @file bumpV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  + +void main() +{ +	//transform vertex +	gl_Position = gl_ModelViewProjectionMatrix*gl_Vertex; +	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; +	gl_TexCoord[1] = gl_TextureMatrix[1] * gl_MultiTexCoord1; +	gl_FrontColor = gl_Color; +} diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index 22c79a4cbd..67c8b977cf 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -1,4 +1,4 @@ -version 30 +version 32  // NOTE: This is mostly identical to featuretable_mac.txt with a few differences  // Should be combined into one table @@ -244,10 +244,10 @@ RenderDeferredSSAO			0	0  RenderShadowDetail			0	0  // -// No GL_ARB_map_buffer_range +// GL_ARB_map_buffer_range exists  // -list NoMapBufferRange -RenderVBOMappingDisable		1	0 +list MapBufferRange +RenderVBOMappingDisable		1	1  // diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt index 649f5ebd18..6e962f3c56 100644 --- a/indra/newview/featuretable_linux.txt +++ b/indra/newview/featuretable_linux.txt @@ -1,4 +1,4 @@ -version 25 +version 27  // NOTE: This is mostly identical to featuretable_mac.txt with a few differences  // Should be combined into one table @@ -242,10 +242,10 @@ RenderDeferredSSAO			0	0  RenderShadowDetail			0	0  // -// No GL_ARB_map_buffer_range +// GL_ARB_map_buffer_range exists  // -list NoMapBufferRange -RenderVBOMappingDisable		1	0 +list MapBufferRange +RenderVBOMappingDisable		1	1 diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index ee08e78af5..fa67ee547c 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -1,4 +1,4 @@ -version 26 +version 29  // NOTE: This is mostly identical to featuretable_mac.txt with a few differences  // Should be combined into one table @@ -47,8 +47,8 @@ RenderTerrainLODFactor			1	2.0  RenderTransparentWater			1	1  RenderTreeLODFactor				1	1.0  RenderUseImpostors				1	1 -RenderVBOEnable					1	1 -RenderVBOMappingDisable		1	1 +RenderVBOEnable					1	0 +RenderVBOMappingDisable		1	0  RenderVolumeLODFactor			1	2.0  UseStartScreen				1	1  UseOcclusion					1	1 @@ -63,7 +63,7 @@ RenderDeferred				1	1  RenderDeferredSSAO			1	1  RenderShadowDetail			1	2  WatchdogDisabled				1	1 -RenderUseStreamVBO			1	1 +RenderUseStreamVBO			1	0  RenderFSAASamples			1	16  // @@ -244,13 +244,6 @@ RenderDeferredSSAO			0	0  RenderShadowDetail			0	0  // -// No GL_ARB_map_buffer_range -// -list NoMapBufferRange -RenderVBOMappingDisable		1	0 - - -//  // "Default" setups for safe, low, medium, high  //  list safe diff --git a/indra/newview/featuretable_xp.txt b/indra/newview/featuretable_xp.txt index ba74f9a6c2..a0245f5369 100644 --- a/indra/newview/featuretable_xp.txt +++ b/indra/newview/featuretable_xp.txt @@ -1,4 +1,4 @@ -version 30 +version 31  // NOTE: This is mostly identical to featuretable_mac.txt with a few differences  // Should be combined into one table @@ -244,10 +244,10 @@ RenderDeferredSSAO			0	0  RenderShadowDetail			0	0  // -// No GL_ARB_map_buffer_range +// GL_ARB_map_buffer_range exists  // -list NoMapBufferRange -RenderVBOMappingDisable		1	0 +list MapBufferRange +RenderVBOMappingDisable		1	1  // diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 862fc49c0e..b65933f8a1 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -4003,6 +4003,8 @@ public:  static LLFastTimer::DeclareTimer FTM_AUDIO_UPDATE("Update Audio");  static LLFastTimer::DeclareTimer FTM_CLEANUP("Cleanup"); +static LLFastTimer::DeclareTimer FTM_CLEANUP_DRAWABLES("Drawables"); +static LLFastTimer::DeclareTimer FTM_CLEANUP_OBJECTS("Objects");  static LLFastTimer::DeclareTimer FTM_IDLE_CB("Idle Callbacks");  static LLFastTimer::DeclareTimer FTM_LOD_UPDATE("Update LOD");  static LLFastTimer::DeclareTimer FTM_OBJECTLIST_UPDATE("Update Objectlist"); @@ -4279,8 +4281,14 @@ void LLAppViewer::idle()  	{  		LLFastTimer t(FTM_CLEANUP); -		gObjectList.cleanDeadObjects(); -		LLDrawable::cleanupDeadDrawables(); +		{ +			LLFastTimer t(FTM_CLEANUP_OBJECTS); +			gObjectList.cleanDeadObjects(); +		} +		{ +			LLFastTimer t(FTM_CLEANUP_DRAWABLES); +			LLDrawable::cleanupDeadDrawables(); +		}  	}  	// diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index fa7d6e2a40..286284f828 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -190,15 +190,16 @@ void LLDrawPool::renderPostDeferred(S32 pass)  //virtual  void LLDrawPool::endRenderPass( S32 pass )  { -	for (U32 i = 0; i < gGLManager.mNumTextureImageUnits; i++) +	/*for (U32 i = 0; i < gGLManager.mNumTextureImageUnits; i++)  	{ //dummy cleanup of any currently bound textures  		if (gGL.getTexUnit(i)->getCurrType() != LLTexUnit::TT_NONE)  		{  			gGL.getTexUnit(i)->unbind(gGL.getTexUnit(i)->getCurrType());  			gGL.getTexUnit(i)->disable();  		} -	} +	}*/ +	//make sure channel 0 is active channel  	gGL.getTexUnit(0)->activate();  } diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index ad7e3ad593..ddcf42e523 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -138,6 +138,7 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)  		gPipeline.mDeferredDepth.bindTarget();  		simple_shader = NULL;  		fullbright_shader = NULL; +		gObjectFullbrightProgram.bind();  	}  	deferred_render = TRUE; @@ -156,6 +157,7 @@ void LLDrawPoolAlpha::endPostDeferredPass(S32 pass)  	{  		gPipeline.mDeferredDepth.flush();  		gPipeline.mScreen.bindTarget(); +		gObjectFullbrightProgram.unbind();  	}  	deferred_render = FALSE; @@ -238,7 +240,7 @@ void LLDrawPoolAlpha::render(S32 pass)  				fullbright_shader->bind();  			}  			pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); -			LLGLSLShader::bindNoShader(); +			//LLGLSLShader::bindNoShader();  		}  		else  		{ diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index 813b3820ee..d801f6df18 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -464,11 +464,15 @@ void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32&  			}  		}  	} -	gGL.getTexUnit(diffuse_channel)->disable(); -	gGL.getTexUnit(cube_channel)->disable(); -	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); -	gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); +	if (!LLGLSLShader::sNoFixedFunction) +	{ +		gGL.getTexUnit(diffuse_channel)->disable(); +		gGL.getTexUnit(cube_channel)->disable(); + +		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +		gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); +	}  }  void LLDrawPoolBump::endShiny(bool invisible) @@ -583,19 +587,19 @@ void LLDrawPoolBump::endFullbrightShiny()  		cube_map->disable();  		cube_map->restoreMatrix(); -		if (diffuse_channel != 0) +		/*if (diffuse_channel != 0)  		{  			shader->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);  		}  		gGL.getTexUnit(0)->activate(); -		gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); +		gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);*/  		shader->unbind(); -		gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); +		//gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);  	} -	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); -	gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); +	//gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +	//gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);  	diffuse_channel = -1;  	cube_channel = 0; @@ -706,36 +710,44 @@ void LLDrawPoolBump::beginBump(U32 pass)  	// Optional second pass: emboss bump map  	stop_glerror(); -	// TEXTURE UNIT 0 -	// Output.rgb = texture at texture coord 0 -	gGL.getTexUnit(0)->activate(); +	if (LLGLSLShader::sNoFixedFunction) +	{ +		gObjectBumpProgram.bind(); +	} +	else +	{ +		// TEXTURE UNIT 0 +		// Output.rgb = texture at texture coord 0 +		gGL.getTexUnit(0)->activate(); -	gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_ALPHA); -	gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_ALPHA); +		gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_ALPHA); +		gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_ALPHA); -	// TEXTURE UNIT 1 -	gGL.getTexUnit(1)->activate(); +		// TEXTURE UNIT 1 +		gGL.getTexUnit(1)->activate(); -	gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE); +		gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE); + +		gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_ADD_SIGNED, LLTexUnit::TBS_PREV_COLOR, LLTexUnit::TBS_ONE_MINUS_TEX_ALPHA); +		gGL.getTexUnit(1)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_ALPHA); -	gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_ADD_SIGNED, LLTexUnit::TBS_PREV_COLOR, LLTexUnit::TBS_ONE_MINUS_TEX_ALPHA); -	gGL.getTexUnit(1)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_ALPHA); +		// src	= tex0 + (1 - tex1) - 0.5 +		//		= (bump0/2 + 0.5) + (1 - (bump1/2 + 0.5)) - 0.5 +		//		= (1 + bump0 - bump1) / 2 -	// src	= tex0 + (1 - tex1) - 0.5 -	//		= (bump0/2 + 0.5) + (1 - (bump1/2 + 0.5)) - 0.5 -	//		= (1 + bump0 - bump1) / 2 +		// Blend: src * dst + dst * src +		//		= 2 * src * dst +		//		= 2 * ((1 + bump0 - bump1) / 2) * dst   [0 - 2 * dst] +		//		= (1 + bump0 - bump1) * dst.rgb +		//		= dst.rgb + dst.rgb * (bump0 - bump1) + +		gGL.getTexUnit(0)->activate(); +		gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE); +	} -	// Blend: src * dst + dst * src -	//		= 2 * src * dst -	//		= 2 * ((1 + bump0 - bump1) / 2) * dst   [0 - 2 * dst] -	//		= (1 + bump0 - bump1) * dst.rgb -	//		= dst.rgb + dst.rgb * (bump0 - bump1)  	gGL.setSceneBlendType(LLRender::BT_MULT_X2); -	gGL.getTexUnit(0)->activate();  	stop_glerror(); - -	gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);  }  //static @@ -765,14 +777,21 @@ void LLDrawPoolBump::endBump(U32 pass)  		return;  	} -	// Disable texture unit 1 -	gGL.getTexUnit(1)->activate(); -	gGL.getTexUnit(1)->disable(); -	gGL.getTexUnit(1)->setTextureBlendType(LLTexUnit::TB_MULT); +	if (LLGLSLShader::sNoFixedFunction) +	{ +		gObjectBumpProgram.unbind(); +	} +	else +	{ +		// Disable texture blending on unit 1 +		gGL.getTexUnit(1)->activate(); +		//gGL.getTexUnit(1)->disable(); +		gGL.getTexUnit(1)->setTextureBlendType(LLTexUnit::TB_MULT); -	// Disable texture unit 0 -	gGL.getTexUnit(0)->activate(); -	gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); +		// Disable texture blending on unit 0 +		gGL.getTexUnit(0)->activate(); +		gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); +	}  	gGL.setSceneBlendType(LLRender::BT_ALPHA);  } @@ -1407,6 +1426,11 @@ void LLDrawPoolInvisible::render(S32 pass)  { //render invisiprims  	LLFastTimer t(FTM_RENDER_INVISIBLE); +	if (gPipeline.canUseVertexShaders()) +	{ +		gOcclusionProgram.bind(); +	} +  	U32 invisi_mask = LLVertexBuffer::MAP_VERTEX;  	glStencilMask(0);  	gGL.setColorMask(false, false); @@ -1414,6 +1438,11 @@ void LLDrawPoolInvisible::render(S32 pass)  	gGL.setColorMask(true, false);  	glStencilMask(0xFFFFFFFF); +	if (gPipeline.canUseVertexShaders()) +	{ +		gOcclusionProgram.unbind(); +	} +  	if (gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY))  	{  		beginShiny(true); diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp index 5dbb27cabb..224f149c6b 100644 --- a/indra/newview/lldrawpoolsimple.cpp +++ b/indra/newview/lldrawpoolsimple.cpp @@ -49,6 +49,8 @@ void LLDrawPoolGlow::beginPostDeferredPass(S32 pass)  	gDeferredFullbrightProgram.bind();  } +static LLFastTimer::DeclareTimer FTM_RENDER_GLOW_PUSH("Glow Push"); +  void LLDrawPoolGlow::renderPostDeferred(S32 pass)  {  	LLFastTimer t(FTM_RENDER_GLOW); @@ -62,7 +64,11 @@ void LLDrawPoolGlow::renderPostDeferred(S32 pass)  	LLGLDepthTest depth(GL_TRUE, GL_FALSE);  	gGL.setColorMask(false, true); -	pushBatches(LLRenderPass::PASS_GLOW, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + +	{ +		LLFastTimer t(FTM_RENDER_GLOW_PUSH); +		pushBatches(LLRenderPass::PASS_GLOW, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +	}  	gGL.setColorMask(true, false);  	gGL.setSceneBlendType(LLRender::BT_ALPHA);	 @@ -374,10 +380,14 @@ void LLDrawPoolFullbright::endRenderPass(S32 pass)  	LLFastTimer t(FTM_RENDER_FULLBRIGHT);  	LLRenderPass::endRenderPass(pass); +	stop_glerror(); +  	if (mVertexShaderLevel > 0)  	{  		fullbright_shader->unbind();  	} + +	stop_glerror();  }  void LLDrawPoolFullbright::render(S32 pass) @@ -385,6 +395,8 @@ void LLDrawPoolFullbright::render(S32 pass)  	LLFastTimer t(FTM_RENDER_FULLBRIGHT);  	gGL.setSceneBlendType(LLRender::BT_ALPHA); +	stop_glerror(); +  	if (mVertexShaderLevel > 0)  	{  		fullbright_shader->bind(); @@ -398,6 +410,8 @@ void LLDrawPoolFullbright::render(S32 pass)  		U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR;  		renderTexture(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask);  	} + +	stop_glerror();  }  S32 LLDrawPoolFullbright::getNumPasses() diff --git a/indra/newview/lldrawpoolsky.cpp b/indra/newview/lldrawpoolsky.cpp index 030d6e1110..efffb2df9e 100644 --- a/indra/newview/lldrawpoolsky.cpp +++ b/indra/newview/lldrawpoolsky.cpp @@ -82,6 +82,10 @@ void LLDrawPoolSky::render(S32 pass)  		mShader = &gObjectFullbrightWaterProgram;  		mShader->bind();  	} +	else if (LLGLSLShader::sNoFixedFunction) +	{ //just use the UI shader (generic single texture no lighting) +		gUIProgram.bind(); +	}  	else  	{  		// don't use shaders! @@ -139,6 +143,7 @@ void LLDrawPoolSky::renderSkyCubeFace(U8 side)  	if (LLSkyTex::doInterpolate())  	{ +		  		LLGLEnable blend(GL_BLEND);  		mSkyTex[side].bindTexture(FALSE);  		glColor4f(1, 1, 1, LLSkyTex::getInterpVal()); // lighting is disabled diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp index 81c796b146..429e06b227 100644 --- a/indra/newview/lldrawpooltree.cpp +++ b/indra/newview/lldrawpooltree.cpp @@ -73,7 +73,7 @@ void LLDrawPoolTree::beginRenderPass(S32 pass)  		shader = &gObjectSimpleNonIndexedProgram;  	} -	if (gPipeline.canUseWindLightShadersOnObjects()) +	if (gPipeline.canUseVertexShaders())  	{  		shader->bind();  	} diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp index bf79c2100c..f9fd501072 100644 --- a/indra/newview/lldrawpoolwlsky.cpp +++ b/indra/newview/lldrawpoolwlsky.cpp @@ -189,16 +189,31 @@ void LLDrawPoolWLSky::renderStars(void) const  	glRotatef(gFrameTimeSeconds*0.01f, 0.f, 0.f, 1.f);  	// gl_FragColor.rgb = gl_Color.rgb;  	// gl_FragColor.a = gl_Color.a * star_alpha.a; -	gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_VERT_COLOR); -	gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_MULT_X2, LLTexUnit::TBS_CONST_ALPHA, LLTexUnit::TBS_TEX_ALPHA); -	glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, star_alpha.mV); +	if (LLGLSLShader::sNoFixedFunction) +	{ +		gCustomAlphaProgram.bind(); +		gCustomAlphaProgram.uniform1f("custom_alpha", star_alpha.mV[3]); +	} +	else +	{ +		gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_VERT_COLOR); +		gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_MULT_X2, LLTexUnit::TBS_CONST_ALPHA, LLTexUnit::TBS_TEX_ALPHA); +		glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, star_alpha.mV); +	}  	gSky.mVOWLSkyp->drawStars();  	gGL.popMatrix(); -	 -	// and disable the combiner states -	gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); + +	if (LLGLSLShader::sNoFixedFunction) +	{ +		gCustomAlphaProgram.unbind(); +	} +	else +	{ +		// and disable the combiner states +		gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); +	}  }  void LLDrawPoolWLSky::renderSkyClouds(F32 camHeightLocal) const @@ -242,6 +257,10 @@ void LLDrawPoolWLSky::renderHeavenlyBodies()  	if (gSky.mVOSkyp->getMoon().getDraw() && face->getGeomCount())  	{ +		if (gPipeline.canUseVertexShaders()) +		{ +			gUIProgram.bind(); +		}  		// *NOTE: even though we already bound this texture above for the  		// stars register combiners, we bind again here for defensive reasons,  		// since LLImageGL::bind detects that it's a noop, and optimizes it out. @@ -257,6 +276,11 @@ void LLDrawPoolWLSky::renderHeavenlyBodies()  		LLFacePool::LLOverrideFaceColor color_override(this, color);  		face->renderIndexed(); + +		if (gPipeline.canUseVertexShaders()) +		{ +			gUIProgram.unbind(); +		}  	}  } diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index b6566fcbd0..432e61f6d8 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -1051,6 +1051,13 @@ bool LLFace::canRenderAsMask()  static LLFastTimer::DeclareTimer FTM_FACE_GET_GEOM("Face Geom"); +static LLFastTimer::DeclareTimer FTM_FACE_GEOM_POSITION("Position"); +static LLFastTimer::DeclareTimer FTM_FACE_GEOM_NORMAL("Normal"); +static LLFastTimer::DeclareTimer FTM_FACE_GEOM_TEXTURE("Texture"); +static LLFastTimer::DeclareTimer FTM_FACE_GEOM_COLOR("Color"); +static LLFastTimer::DeclareTimer FTM_FACE_GEOM_WEIGHTS("Weights"); +static LLFastTimer::DeclareTimer FTM_FACE_GEOM_BINORMAL("Binormal"); +static LLFastTimer::DeclareTimer FTM_FACE_GEOM_INDEX("Index");  BOOL LLFace::getGeometryVolume(const LLVolume& volume,  							   const S32 &f, @@ -1064,6 +1071,8 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  	S32 num_vertices = (S32)vf.mNumVertices;  	S32 num_indices = (S32) vf.mNumIndices; +	bool map_range = gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange; +  	if (mVertexBuffer.notNull())  	{  		if (num_indices + (S32) mIndicesIndex > mVertexBuffer->getNumIndices()) @@ -1182,7 +1191,8 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  	// INDICES  	if (full_rebuild)  	{ -		mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex, mIndicesCount, true); +		LLFastTimer t(FTM_FACE_GEOM_INDEX); +		mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex, mIndicesCount, map_range);  		__m128i* dst = (__m128i*) indicesp.get();  		__m128i* src = (__m128i*) vf.mIndices; @@ -1201,7 +1211,10 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			indicesp[i] = vf.mIndices[i]+index_offset;  		} -		mVertexBuffer->setBuffer(0); +		if (map_range) +		{ +			mVertexBuffer->setBuffer(0); +		}  	}  	LLMatrix4a mat_normal; @@ -1215,6 +1228,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  	if (rebuild_tcoord)  	{ +		LLFastTimer t(FTM_FACE_GEOM_TEXTURE);  		bool do_xform;  		if (tep) @@ -1422,11 +1436,14 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  				}  			} -			mVertexBuffer->setBuffer(0); +			if (map_range) +			{ +				mVertexBuffer->setBuffer(0); +			}  		}  		else  		{ //either bump mapped or in atlas, just do the whole expensive loop -			mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount, true); +			mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount, map_range);  			std::vector<LLVector2> bump_tc; @@ -1566,12 +1583,14 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  				}  			} -			mVertexBuffer->setBuffer(0); - +			if (map_range) +			{ +				mVertexBuffer->setBuffer(0); +			}  			if (do_bump)  			{ -				mVertexBuffer->getTexCoord1Strider(tex_coords2, mGeomIndex, mGeomCount, true); +				mVertexBuffer->getTexCoord1Strider(tex_coords2, mGeomIndex, mGeomCount, map_range);  				for (S32 i = 0; i < num_vertices; i++)  				{ @@ -1601,14 +1620,20 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  					*tex_coords2++ = tc;  				} -				mVertexBuffer->setBuffer(0); +				if (map_range) +				{ +					mVertexBuffer->setBuffer(0); +				}  			}  		}  	}  	if (rebuild_pos)  	{ -		mVertexBuffer->getVertexStrider(vert, mGeomIndex, mGeomCount, true); +		LLFastTimer t(FTM_FACE_GEOM_POSITION); +		llassert(num_vertices > 0); +		 +		mVertexBuffer->getVertexStrider(vert, mGeomIndex, mGeomCount, map_range);  		vertices = (LLVector4a*) vert.get();  		LLMatrix4a mat_vert; @@ -1636,13 +1661,25 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			index_dst += 4;  		}  		while (index_dst < index_end); - -		mVertexBuffer->setBuffer(0); +		 +		S32 aligned_pad_vertices = mGeomCount - num_vertices; +		LLVector4a* last_vec = end - 1; +		while (aligned_pad_vertices > 0) +		{ +			--aligned_pad_vertices; +			*dst++ = *last_vec; +		} +		 +		if (map_range) +		{ +			mVertexBuffer->setBuffer(0); +		}  	}  	if (rebuild_normal)  	{ -		mVertexBuffer->getNormalStrider(norm, mGeomIndex, mGeomCount, true); +		LLFastTimer t(FTM_FACE_GEOM_NORMAL); +		mVertexBuffer->getNormalStrider(norm, mGeomIndex, mGeomCount, map_range);  		normals = (LLVector4a*) norm.get();  		for (S32 i = 0; i < num_vertices; i++) @@ -1653,12 +1690,16 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			normals[i] = normal;  		} -		mVertexBuffer->setBuffer(0); +		if (map_range) +		{ +			mVertexBuffer->setBuffer(0); +		}  	}  	if (rebuild_binormal)  	{ -		mVertexBuffer->getBinormalStrider(binorm, mGeomIndex, mGeomCount, true); +		LLFastTimer t(FTM_FACE_GEOM_BINORMAL); +		mVertexBuffer->getBinormalStrider(binorm, mGeomIndex, mGeomCount, map_range);  		binormals = (LLVector4a*) binorm.get();  		for (S32 i = 0; i < num_vertices; i++) @@ -1669,20 +1710,28 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			binormals[i] = binormal;  		} -		mVertexBuffer->setBuffer(0); +		if (map_range) +		{ +			mVertexBuffer->setBuffer(0); +		}  	}  	if (rebuild_weights && vf.mWeights)  	{ -		mVertexBuffer->getWeight4Strider(wght, mGeomIndex, mGeomCount, true); +		LLFastTimer t(FTM_FACE_GEOM_WEIGHTS); +		mVertexBuffer->getWeight4Strider(wght, mGeomIndex, mGeomCount, map_range);  		weights = (LLVector4a*) wght.get();  		LLVector4a::memcpyNonAliased16((F32*) weights, (F32*) vf.mWeights, num_vertices*4*sizeof(F32)); -		mVertexBuffer->setBuffer(0); +		if (map_range) +		{ +			mVertexBuffer->setBuffer(0); +		}  	}  	if (rebuild_color)  	{ -		mVertexBuffer->getColorStrider(colors, mGeomIndex, mGeomCount, true); +		LLFastTimer t(FTM_FACE_GEOM_COLOR); +		mVertexBuffer->getColorStrider(colors, mGeomIndex, mGeomCount, map_range);  		LLVector4a src; @@ -1703,7 +1752,10 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			dst[i] = src;  		} -		mVertexBuffer->setBuffer(0); +		if (map_range) +		{ +			mVertexBuffer->setBuffer(0); +		}  	}  	if (rebuild_tcoord) diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index 83844048d1..0ea0e41dfa 100644 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -769,6 +769,10 @@ void LLFeatureManager::applyBaseMasks()  	{  		maskFeatures("TexUnit8orLess");  	} +	if (gGLManager.mHasMapBufferRange) +	{ +		maskFeatures("MapBufferRange"); +	}  	// now mask by gpu string  	// Replaces ' ' with '_' in mGPUString to deal with inability for parser to handle spaces diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp index 82e1f2dfb5..482294c8a6 100644 --- a/indra/newview/llhudnametag.cpp +++ b/indra/newview/llhudnametag.cpp @@ -477,7 +477,7 @@ void LLHUDNameTag::renderText(BOOL for_select)  	// Render label  	{ -		gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); +		//gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);  		for(std::vector<LLHUDTextSegment>::iterator segment_iter = mLabelSegments.begin();  			segment_iter != mLabelSegments.end(); ++segment_iter ) diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index f99afa923b..e23b431457 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -47,6 +47,7 @@  #include "llvoavatar.h"  #include "llvolumemgr.h"  #include "lltextureatlas.h" +#include "llglslshader.h"  static LLFastTimer::DeclareTimer FTM_FRUSTUM_CULL("Frustum Culling");  static LLFastTimer::DeclareTimer FTM_CULL_REBOUND("Cull Rebound"); @@ -3176,6 +3177,8 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)  				glColor4fv(line_color.mV);  				LLVertexBuffer::unbind(); +				llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShader != 0); +  				glVertexPointer(3, GL_FLOAT, 16, phys_volume->mHullPoints);  				glDrawElements(GL_TRIANGLES, phys_volume->mNumHullIndices, GL_UNSIGNED_SHORT, phys_volume->mHullIndices); @@ -3257,7 +3260,7 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)  		if (phys_volume->mHullPoints && phys_volume->mHullIndices)  		{  			glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); -			 +			llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShader != 0);  			LLVertexBuffer::unbind();  			glVertexPointer(3, GL_FLOAT, 16, phys_volume->mHullPoints);  			glColor4fv(line_color.mV); diff --git a/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp index bd41aa64f0..e8abee2fb7 100644 --- a/indra/newview/lltexlayer.cpp +++ b/indra/newview/lltexlayer.cpp @@ -45,6 +45,7 @@  #include "llagentwearables.h"  #include "llwearable.h"  #include "llviewercontrol.h" +#include "llviewershadermgr.h"  #include "llviewervisualparam.h"  //#include "../tools/imdebug/imdebug.h" @@ -294,11 +295,17 @@ BOOL LLTexLayerSetBuffer::render()  	BOOL success = TRUE; +	//hack to use fixed function when updating tex layer sets +	bool no_ff = LLGLSLShader::sNoFixedFunction; +	LLGLSLShader::sNoFixedFunction = false; +	  	// Composite the color data  	LLGLSUIDefault gls_ui;  	success &= mTexLayerSet->render( mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight );  	gGL.flush(); +	LLGLSLShader::sNoFixedFunction = no_ff; +	  	if(upload_now)  	{  		if (!success) diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 911fc8e1ed..39053fe9e4 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -616,6 +616,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  				&& LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion")   				&& gSavedSettings.getBOOL("UseOcclusion")   				&& gGLManager.mHasOcclusionQuery) ? 2 : 0; +		LLTexUnit::sWhiteTexture = LLViewerFetchedTexture::sWhiteImagep->getTexName();  		/*if (LLPipeline::sUseOcclusion && LLPipeline::sRenderDeferred)  		{ //force occlusion on for all render types if doing deferred render (tighter shadow frustum) @@ -709,6 +710,9 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  			glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);  		} +		LLGLState::checkStates(); +		LLGLState::checkClientArrays(); +  		//if (!for_snapshot)  		{  			LLMemType mt_gw(LLMemType::MTYPE_DISPLAY_GEN_REFLECTION); @@ -717,6 +721,9 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  			gPipeline.generateHighlight(*LLViewerCamera::getInstance());  		} +		LLGLState::checkStates(); +		LLGLState::checkClientArrays(); +  		//////////////////////////////////////  		//  		// Update images, using the image stats generated during object update/culling @@ -743,6 +750,10 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  			LLImageGL::deleteDeadTextures();  			stop_glerror();  		} + +		LLGLState::checkStates(); +		LLGLState::checkClientArrays(); +  		///////////////////////////////////  		//  		// StateSort @@ -770,6 +781,9 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  			}  		} +		LLGLState::checkStates(); +		LLGLState::checkClientArrays(); +  		LLPipeline::sUseOcclusion = occlusion;  		{ @@ -828,6 +842,9 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  		LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? TRUE : FALSE;  		LLPipeline::refreshRenderDeferred(); +		LLGLState::checkStates(); +		LLGLState::checkClientArrays(); +  		stop_glerror();  		if (to_texture) @@ -878,6 +895,14 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  			stop_glerror();  		} +		for (U32 i = 0; i < gGLManager.mNumTextureImageUnits; i++) +		{ //dummy cleanup of any currently bound textures +			if (gGL.getTexUnit(i)->getCurrType() != LLTexUnit::TT_NONE) +			{ +				gGL.getTexUnit(i)->unbind(gGL.getTexUnit(i)->getCurrType()); +				gGL.getTexUnit(i)->disable(); +			} +		}  		LLAppViewer::instance()->pingMainloopTimeout("Display:RenderFlush");		  		if (to_texture) @@ -1339,7 +1364,7 @@ void render_ui_2d()  	}  	stop_glerror(); -	gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); +	//gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);  	// render outline for HUD  	if (isAgentAvatarValid() && gAgentCamera.mHUDCurZoom < 0.98f) diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 9f882ee732..48ccc7d035 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -1339,18 +1339,29 @@ void LLViewerObjectList::cleanDeadObjects(BOOL use_timer)  	S32 num_removed = 0;  	LLViewerObject *objectp; -	for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ) +	 +	vobj_list_t::reverse_iterator target = mObjects.rbegin(); + +	vobj_list_t::iterator iter = mObjects.begin(); +	for ( ; iter != mObjects.end(); )  	{ -		// Scan for all of the dead objects and remove any "global" references to them. +		// Scan for all of the dead objects and put them all on the end of the list with no ref count ops  		objectp = *iter; +		if (objectp == NULL) +		{ //we caught up to the dead tail +			break; +		} +  		if (objectp->isDead())  		{ -			iter = mObjects.erase(iter); +			LLPointer<LLViewerObject>::swap(*iter, *target); +			*target = NULL; +			++target;  			num_removed++; -			if (num_removed == mNumDeadObjects) +			if (num_removed == mNumDeadObjects || iter->isNull())  			{ -				// We've cleaned up all of the dead objects. +				// We've cleaned up all of the dead objects or caught up to the dead tail  				break;  			}  		} @@ -1360,6 +1371,11 @@ void LLViewerObjectList::cleanDeadObjects(BOOL use_timer)  		}  	} +	llassert(num_removed == mNumDeadObjects); + +	//erase as a block +	mObjects.erase(mObjects.begin()+(mObjects.size()-mNumDeadObjects), mObjects.end()); +  	// We've cleaned the global object list, now let's do some paranoia testing on objects  	// before blowing away the dead list.  	mDeadObjects.clear(); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index e473901609..62d83b516f 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -61,6 +61,12 @@ BOOL				LLViewerShaderMgr::sInitialized = FALSE;  LLVector4			gShinyOrigin; +//utility shaders +LLGLSLShader	gOcclusionProgram; +LLGLSLShader	gCustomAlphaProgram; +LLGLSLShader	gGlowCombineProgram; +LLGLSLShader	gTwoTextureAddProgram; +  //object shaders  LLGLSLShader		gObjectSimpleProgram;  LLGLSLShader		gObjectSimpleWaterProgram; @@ -70,6 +76,7 @@ LLGLSLShader		gObjectFullbrightShinyProgram;  LLGLSLShader		gObjectFullbrightShinyWaterProgram;  LLGLSLShader		gObjectShinyProgram;  LLGLSLShader		gObjectShinyWaterProgram; +LLGLSLShader		gObjectBumpProgram;  LLGLSLShader		gObjectSimpleNonIndexedProgram;  LLGLSLShader		gObjectSimpleNonIndexedWaterProgram; @@ -166,14 +173,24 @@ LLViewerShaderMgr::LLViewerShaderMgr() :  	mShaderList.push_back(&gWLCloudProgram);  	mShaderList.push_back(&gAvatarProgram);  	mShaderList.push_back(&gObjectShinyProgram); +	mShaderList.push_back(&gObjectShinyNonIndexedProgram);  	mShaderList.push_back(&gWaterProgram);  	mShaderList.push_back(&gAvatarEyeballProgram);   	mShaderList.push_back(&gObjectSimpleProgram); +	mShaderList.push_back(&gObjectBumpProgram); +	mShaderList.push_back(&gUIProgram); +	mShaderList.push_back(&gCustomAlphaProgram); +	mShaderList.push_back(&gGlowCombineProgram); +	mShaderList.push_back(&gTwoTextureAddProgram); +	mShaderList.push_back(&gSolidColorProgram); +	mShaderList.push_back(&gOcclusionProgram);  	mShaderList.push_back(&gObjectFullbrightProgram);  	mShaderList.push_back(&gObjectFullbrightShinyProgram);  	mShaderList.push_back(&gObjectFullbrightShinyWaterProgram);  	mShaderList.push_back(&gObjectSimpleNonIndexedProgram); +	mShaderList.push_back(&gObjectSimpleNonIndexedWaterProgram);  	mShaderList.push_back(&gObjectFullbrightNonIndexedProgram); +	mShaderList.push_back(&gObjectFullbrightNonIndexedWaterProgram);  	mShaderList.push_back(&gObjectFullbrightShinyNonIndexedProgram);  	mShaderList.push_back(&gObjectFullbrightShinyNonIndexedWaterProgram);  	mShaderList.push_back(&gSkinnedObjectSimpleProgram); @@ -190,6 +207,7 @@ LLViewerShaderMgr::LLViewerShaderMgr() :  	mShaderList.push_back(&gObjectFullbrightWaterProgram);  	mShaderList.push_back(&gAvatarWaterProgram);  	mShaderList.push_back(&gObjectShinyWaterProgram); +	mShaderList.push_back(&gObjectShinyNonIndexedWaterProgram);  	mShaderList.push_back(&gUnderWaterProgram);  	mShaderList.push_back(&gDeferredSunProgram);  	mShaderList.push_back(&gDeferredBlurLightProgram); @@ -410,9 +428,13 @@ void LLViewerShaderMgr::setShaders()  	}  	mMaxAvatarShaderLevel = 0; +	LLGLSLShader::sNoFixedFunction = false;  	if (LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable")   		&& gSavedSettings.getBOOL("VertexShaderEnable"))  	{ +		//using shaders, disable fixed function +		LLGLSLShader::sNoFixedFunction = true; +  		S32 light_class = 2;  		S32 env_class = 2;  		S32 obj_class = 2; @@ -554,6 +576,7 @@ void LLViewerShaderMgr::setShaders()  		}  		else  		{ +			LLGLSLShader::sNoFixedFunction = false;  			gPipeline.mVertexShadersEnabled = FALSE;  			gPipeline.mVertexShadersLoaded = 0;  			mVertexShaderLevel[SHADER_LIGHTING] = 0; @@ -568,6 +591,7 @@ void LLViewerShaderMgr::setShaders()  	}  	else  	{ +		LLGLSLShader::sNoFixedFunction = false;  		gPipeline.mVertexShadersEnabled = FALSE;  		gPipeline.mVertexShadersLoaded = 0;  		mVertexShaderLevel[SHADER_LIGHTING] = 0; @@ -591,7 +615,15 @@ void LLViewerShaderMgr::setShaders()  void LLViewerShaderMgr::unloadShaders()  { +	gOcclusionProgram.unload(); +	gUIProgram.unload(); +	gCustomAlphaProgram.unload(); +	gGlowCombineProgram.unload(); +	gTwoTextureAddProgram.unload(); +	gSolidColorProgram.unload(); +  	gObjectSimpleProgram.unload(); +	gObjectBumpProgram.unload();  	gObjectSimpleWaterProgram.unload();  	gObjectFullbrightProgram.unload();  	gObjectFullbrightWaterProgram.unload(); @@ -1581,6 +1613,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectFullbrightShinyWaterProgram.unload();  		gObjectShinyWaterProgram.unload();  		gObjectSimpleProgram.unload(); +		gObjectBumpProgram.unload();  		gObjectSimpleWaterProgram.unload();  		gObjectFullbrightProgram.unload();  		gObjectFullbrightWaterProgram.unload(); @@ -1753,6 +1786,22 @@ BOOL LLViewerShaderMgr::loadShadersObject()  	if (success)  	{ +		gObjectBumpProgram.mName = "Bump Shader"; +		/*gObjectBumpProgram.mFeatures.calculatesLighting = true; +		gObjectBumpProgram.mFeatures.calculatesAtmospherics = true; +		gObjectBumpProgram.mFeatures.hasGamma = true; +		gObjectBumpProgram.mFeatures.hasAtmospherics = true; +		gObjectBumpProgram.mFeatures.hasLighting = true; +		gObjectBumpProgram.mFeatures.mIndexedTextureChannels = 0;*/ +		gObjectBumpProgram.mShaderFiles.clear(); +		gObjectBumpProgram.mShaderFiles.push_back(make_pair("objects/bumpV.glsl", GL_VERTEX_SHADER_ARB)); +		gObjectBumpProgram.mShaderFiles.push_back(make_pair("objects/bumpF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gObjectBumpProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		success = gObjectBumpProgram.createShader(NULL, NULL); +	} +	 +	if (success) +	{  		gObjectSimpleWaterProgram.mName = "Simple Water Shader";  		gObjectSimpleWaterProgram.mFeatures.calculatesLighting = true;  		gObjectSimpleWaterProgram.mFeatures.calculatesAtmospherics = true; @@ -2135,6 +2184,85 @@ BOOL LLViewerShaderMgr::loadShadersInterface()  		success = gHighlightProgram.createShader(NULL, NULL);  	} +	if (success) +	{ +		gUIProgram.mName = "UI Shader"; +		gUIProgram.mShaderFiles.clear(); +		gUIProgram.mShaderFiles.push_back(make_pair("interface/uiV.glsl", GL_VERTEX_SHADER_ARB)); +		gUIProgram.mShaderFiles.push_back(make_pair("interface/uiF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gUIProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE]; +		success = gUIProgram.createShader(NULL, NULL); +	} + +	if (success) +	{ +		gCustomAlphaProgram.mName = "Custom Alpha Shader"; +		gCustomAlphaProgram.mShaderFiles.clear(); +		gCustomAlphaProgram.mShaderFiles.push_back(make_pair("interface/customalphaV.glsl", GL_VERTEX_SHADER_ARB)); +		gCustomAlphaProgram.mShaderFiles.push_back(make_pair("interface/customalphaF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gCustomAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE]; +		success = gCustomAlphaProgram.createShader(NULL, NULL); +	} + +	if (success) +	{ +		gGlowCombineProgram.mName = "Glow Combine Shader"; +		gGlowCombineProgram.mShaderFiles.clear(); +		gGlowCombineProgram.mShaderFiles.push_back(make_pair("interface/glowcombineV.glsl", GL_VERTEX_SHADER_ARB)); +		gGlowCombineProgram.mShaderFiles.push_back(make_pair("interface/glowcombineF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gGlowCombineProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE]; +		success = gGlowCombineProgram.createShader(NULL, NULL); +		if (success) +		{ +			gGlowCombineProgram.bind(); +			gGlowCombineProgram.uniform1i("glowMap", 0); +			gGlowCombineProgram.uniform1i("screenMap", 1); +			gGlowCombineProgram.unbind(); +		} +	} + +	if (success) +	{ +		gTwoTextureAddProgram.mName = "Two Texture Add Shader"; +		gTwoTextureAddProgram.mShaderFiles.clear(); +		gTwoTextureAddProgram.mShaderFiles.push_back(make_pair("interface/twotextureaddV.glsl", GL_VERTEX_SHADER_ARB)); +		gTwoTextureAddProgram.mShaderFiles.push_back(make_pair("interface/twotextureaddF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gTwoTextureAddProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE]; +		success = gTwoTextureAddProgram.createShader(NULL, NULL); +		if (success) +		{ +			gTwoTextureAddProgram.bind(); +			gTwoTextureAddProgram.uniform1i("tex0", 0); +			gTwoTextureAddProgram.uniform1i("tex1", 1); +		} +	} + +	if (success) +	{ +		gSolidColorProgram.mName = "Solid Color Shader"; +		gSolidColorProgram.mShaderFiles.clear(); +		gSolidColorProgram.mShaderFiles.push_back(make_pair("interface/solidcolorV.glsl", GL_VERTEX_SHADER_ARB)); +		gSolidColorProgram.mShaderFiles.push_back(make_pair("interface/solidcolorF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gSolidColorProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE]; +		success = gSolidColorProgram.createShader(NULL, NULL); +		if (success) +		{ +			gSolidColorProgram.bind(); +			gSolidColorProgram.uniform1i("tex0", 0); +			gSolidColorProgram.unbind(); +		} +	} + +	if (success) +	{ +		gOcclusionProgram.mName = "Occlusion Shader"; +		gOcclusionProgram.mShaderFiles.clear(); +		gOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionV.glsl", GL_VERTEX_SHADER_ARB)); +		gOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gOcclusionProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE]; +		success = gOcclusionProgram.createShader(NULL, NULL); +	} +  	if( !success )  	{  		mVertexShaderLevel[SHADER_INTERFACE] = 0; diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index efef9ec5b2..93a0ecc4f0 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -287,6 +287,14 @@ inline bool operator != (LLViewerShaderMgr::shader_iter const & a, LLViewerShade  extern LLVector4			gShinyOrigin; +//utility shaders +extern LLGLSLShader			gOcclusionProgram; +extern LLGLSLShader			gCustomAlphaProgram; +extern LLGLSLShader			gGlowCombineProgram; + +//output tex0[tc0] + tex1[tc1] +extern LLGLSLShader			gTwoTextureAddProgram; +								  //object shaders  extern LLGLSLShader			gObjectSimpleProgram;  extern LLGLSLShader			gObjectSimpleWaterProgram; @@ -296,6 +304,7 @@ extern LLGLSLShader			gObjectFullbrightProgram;  extern LLGLSLShader			gObjectFullbrightWaterProgram;  extern LLGLSLShader			gObjectFullbrightNonIndexedProgram;  extern LLGLSLShader			gObjectFullbrightNonIndexedWaterProgram; +extern LLGLSLShader			gObjectBumpProgram;  extern LLGLSLShader			gObjectSimpleLODProgram;  extern LLGLSLShader			gObjectFullbrightLODProgram; diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 4da0f80a00..5fcc57bc91 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -599,7 +599,7 @@ bool LLViewerTexture::bindDefaultImage(S32 stage)  	}  	if (!res && LLViewerTexture::sNullImagep.notNull() && (this != LLViewerTexture::sNullImagep))  	{ -		res = gGL.getTexUnit(stage)->bind(LLViewerTexture::sNullImagep) ; +		res = gGL.getTexUnit(stage)->bind(LLViewerTexture::sNullImagep);  	}  	if (!res)  	{ diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index d24174adea..30ef8b8a29 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -115,7 +115,7 @@ void LLViewerTextureList::doPreloadImages()  	// Set the "white" image  	LLViewerFetchedTexture::sWhiteImagep = LLViewerTextureManager::getFetchedTextureFromFile("white.tga", MIPMAP_NO, LLViewerFetchedTexture::BOOST_UI); -	 +	LLTexUnit::sWhiteTexture = LLViewerFetchedTexture::sWhiteImagep->getTexName();  	LLUIImageList* image_list = LLUIImageList::getInstance();  	image_list->initFromFile(); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index c31e1c3ba9..988c4ed1a2 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -2302,6 +2302,11 @@ void LLViewerWindow::draw()  	// Draw all nested UI views.  	// No translation needed, this view is glued to 0,0 +	if (LLGLSLShader::sNoFixedFunction) +	{ +		gUIProgram.bind(); +	} +  	gGL.pushMatrix();  	LLUI::pushMatrix();  	{ @@ -2376,6 +2381,11 @@ void LLViewerWindow::draw()  	LLUI::popMatrix();  	gGL.popMatrix(); +	if (LLGLSLShader::sNoFixedFunction) +	{ +		gUIProgram.unbind(); +	} +  //#if LL_DEBUG  	LLView::sIsDrawing = FALSE;  //#endif diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index cd2bbad620..0db0010688 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -7049,6 +7049,8 @@ LLVivoxProtocolParser::~LLVivoxProtocolParser()  		XML_ParserFree(parser);  } +static LLFastTimer::DeclareTimer FTM_VIVOX_PROCESS("Vivox Process"); +  // virtual  LLIOPipe::EStatus LLVivoxProtocolParser::process_impl(  													  const LLChannelDescriptors& channels, @@ -7057,6 +7059,7 @@ LLIOPipe::EStatus LLVivoxProtocolParser::process_impl(  													  LLSD& context,  													  LLPumpIO* pump)  { +	LLFastTimer t(FTM_VIVOX_PROCESS);  	LLBufferStream istr(channels, buffer.get());  	std::ostringstream ostr;  	while (istr.good()) diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp index 3c7fe708e6..890861df71 100644 --- a/indra/newview/llvotree.cpp +++ b/indra/newview/llvotree.cpp @@ -51,6 +51,7 @@  #include "llspatialpartition.h"  #include "llnotificationsutil.h"  #include "raytrace.h" +#include "llglslshader.h"  extern LLPipeline gPipeline; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index e6da8eb89d..4c137d3394 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -3743,6 +3743,11 @@ bool can_batch_texture(LLFace* facep)  		return false;  	} +	if (facep->getTexture() && facep->getTexture()->getPrimaryFormat() == GL_ALPHA) +	{ //can't batch invisiprims +		return false; +	} +  	if (facep->isState(LLFace::TEXTURE_ANIM) && facep->getVirtualSize() > MIN_TEX_ANIM_SIZE)  	{ //texture animation breaks batches  		return false; @@ -4361,6 +4366,8 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)  		group->mBuilt = 1.f; +		std::set<LLVertexBuffer*> mapped_buffers; +  		for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)  		{  			LLFastTimer t(FTM_VOLUME_GEOM_PARTIAL); @@ -4375,35 +4382,31 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)  				for (S32 i = 0; i < drawablep->getNumFaces(); ++i)  				{  					LLFace* face = drawablep->getFace(i); -					if (face && face->getVertexBuffer()) +					if (face)  					{ -						face->getGeometryVolume(*volume, face->getTEOffset(),  -							vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex()); +						LLVertexBuffer* buff = face->getVertexBuffer(); +						if (buff) +						{ +							face->getGeometryVolume(*volume, face->getTEOffset(),  +								vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex()); + +							if (buff->isLocked()) +							{ +								mapped_buffers.insert(buff); +							} +						}  					}  				} - +				  				drawablep->clearState(LLDrawable::REBUILD_ALL);  			}  		} -		//unmap all the buffers -		for (LLSpatialGroup::buffer_map_t::iterator i = group->mBufferMap.begin(); i != group->mBufferMap.end(); ++i) +		for (std::set<LLVertexBuffer*>::iterator iter = mapped_buffers.begin(); iter != mapped_buffers.end(); ++iter)  		{ -			LLSpatialGroup::buffer_texture_map_t& map = i->second; -			for (LLSpatialGroup::buffer_texture_map_t::iterator j = map.begin(); j != map.end(); ++j) -			{ -				LLSpatialGroup::buffer_list_t& list = j->second; -				for (LLSpatialGroup::buffer_list_t::iterator k = list.begin(); k != list.end(); ++k) -				{ -					LLVertexBuffer* buffer = *k; -					if (buffer->isLocked()) -					{ -						buffer->setBuffer(0); -					} -				} -			} +			(*iter)->setBuffer(0);  		} -		 +  		// don't forget alpha  		if(group != NULL &&   		   !group->mVertexBuffer.isNull() &&  @@ -4713,6 +4716,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  			}  			const LLTextureEntry* te = facep->getTextureEntry(); +			tex = facep->getTexture();  			BOOL is_alpha = (facep->getPoolType() == LLDrawPool::POOL_ALPHA) ? TRUE : FALSE; diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp index 69ebad61ac..e70ac0a2e7 100644 --- a/indra/newview/llvowater.cpp +++ b/indra/newview/llvowater.cpp @@ -282,6 +282,11 @@ void LLVOWater::updateSpatialExtents(LLVector4a &newMin, LLVector4a& newMax)  U32 LLVOWater::getPartitionType() const  {  +	if (mIsEdgePatch) +	{ +		return LLViewerRegion::PARTITION_VOIDWATER; +	} +  	return LLViewerRegion::PARTITION_WATER;   } @@ -300,6 +305,7 @@ LLWaterPartition::LLWaterPartition()  LLVoidWaterPartition::LLVoidWaterPartition()  { +	mOcclusionEnabled = FALSE;  	mDrawableType = LLPipeline::RENDER_TYPE_VOIDWATER;  	mPartitionType = LLViewerRegion::PARTITION_VOIDWATER;  } diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp index 257884d921..bd1d2ed7a7 100644 --- a/indra/newview/llxmlrpctransaction.cpp +++ b/indra/newview/llxmlrpctransaction.cpp @@ -394,16 +394,18 @@ bool LLXMLRPCTransaction::Impl::process()  		}  	} -	const F32 MAX_PROCESSING_TIME = 0.05f; -	LLTimer timer; +	//const F32 MAX_PROCESSING_TIME = 0.05f; +	//LLTimer timer; -	while (mCurlRequest->perform() > 0) +	mCurlRequest->perform(); + +	/*while (mCurlRequest->perform() > 0)  	{  		if (timer.getElapsedTimeF32() >= MAX_PROCESSING_TIME)  		{  			return false;  		} -	} +	}*/  	while(1)  	{ diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index e74bf2a620..dfcc7396ba 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -336,10 +336,10 @@ static const U32 gl_cube_face[] =  void validate_framebuffer_object(); -void addDeferredAttachments(LLRenderTarget& target) +bool addDeferredAttachments(LLRenderTarget& target)  { -	target.addColorAttachment(GL_RGBA); //specular -	target.addColorAttachment(GL_RGBA); //normal+z	 +	return target.addColorAttachment(GL_RGBA) && //specular +			target.addColorAttachment(GL_RGBA); //normal+z	  }  LLPipeline::LLPipeline() : @@ -586,18 +586,61 @@ void LLPipeline::allocatePhysicsBuffer()  void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)  { -	// remember these dimensions -	mScreenWidth = resX; -	mScreenHeight = resY; -	 -	//cap samples at 4 for render targets to avoid out of memory errors  	U32 samples = gGLManager.getNumFBOFSAASamples(gSavedSettings.getU32("RenderFSAASamples"));  	if (gGLManager.mIsATI) -	{ //disable multisampling of render targets where ATI is involved +	{ //ATI doesn't like the way we use multisample texture  		samples = 0;  	} +	//try to allocate screen buffers at requested resolution and samples +	// - on failure, shrink number of samples and try again +	// - if not multisampled, shrink resolution and try again (favor X resolution over Y) +	// Make sure to call "releaseScreenBuffers" after each failure to cleanup the partially loaded state + +	if (!allocateScreenBuffer(resX, resY, samples)) +	{ +		releaseScreenBuffers(); +		//reduce number of samples  +		while (samples > 0) +		{ +			samples /= 2; +			if (allocateScreenBuffer(resX, resY, samples)) +			{ //success +				return; +			} +			releaseScreenBuffers(); +		} + +		//reduce resolution +		while (resY > 0 && resX > 0) +		{ +			resY /= 2; +			if (allocateScreenBuffer(resX, resY, samples)) +			{ +				return; +			} +			releaseScreenBuffers(); + +			resX /= 2; +			if (allocateScreenBuffer(resX, resY, samples)) +			{ +				return; +			} +			releaseScreenBuffers(); +		} + +		llwarns << "Unable to allocate screen buffer at any resolution!" << llendl; +	} +} + + +bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) +{ +	// remember these dimensions +	mScreenWidth = resX; +	mScreenHeight = resY; +	  	U32 res_mod = gSavedSettings.getU32("RenderResolutionDivisor");  	if (res_mod > 1 && res_mod < resX && res_mod < resY) @@ -608,7 +651,10 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)  	if (gSavedSettings.getBOOL("RenderUIBuffer"))  	{ -		mUIScreen.allocate(resX,resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); +		if (!mUIScreen.allocate(resX,resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) +		{ +			return false; +		}  	}	  	if (LLPipeline::sRenderDeferred) @@ -618,22 +664,22 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)  		bool gi = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED);  		//allocate deferred rendering color buffers -		mDeferredScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples); -		mDeferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples); -		addDeferredAttachments(mDeferredScreen); +		if (!mDeferredScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false; +		if (!mDeferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false; +		if (!addDeferredAttachments(mDeferredScreen)) return false; -		mScreen.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples);		 +		if (!mScreen.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;  #if LL_DARWIN  		// As of OS X 10.6.7, Apple doesn't support multiple color formats in a single FBO -		mEdgeMap.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); +		if (!mEdgeMap.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false;  #else -		mEdgeMap.allocate(resX, resY, GL_ALPHA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); +		if (!mEdgeMap.allocate(resX, resY, GL_ALPHA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false;  #endif  		if (shadow_detail > 0 || ssao)  		{ //only need mDeferredLight[0] for shadows OR ssao -			mDeferredLight[0].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); +			if (!mDeferredLight[0].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false;  		}  		else  		{ @@ -642,7 +688,7 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)  		if (ssao)  		{ //only need mDeferredLight[1] for ssao -			mDeferredLight[1].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, false); +			if (!mDeferredLight[1].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, false)) return false;  		}  		else  		{ @@ -651,14 +697,14 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)  		if (gi)  		{ //only need mDeferredLight[2] and mGIMapPost for gi -			mDeferredLight[2].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, false); +			if (!mDeferredLight[2].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, false)) return false;  			for (U32 i = 0; i < 2; i++)  			{  #if LL_DARWIN  				// As of OS X 10.6.7, Apple doesn't support multiple color formats in a single FBO -				mGIMapPost[i].allocate(resX,resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); +				if (!mGIMapPost[i].allocate(resX,resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE)) return false;  #else -				mGIMapPost[i].allocate(resX,resY, GL_RGB, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); +				if (!mGIMapPost[i].allocate(resX,resY, GL_RGB, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE)) return false;  #endif  			}  		} @@ -685,7 +731,7 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)  		{ //allocate 4 sun shadow maps  			for (U32 i = 0; i < 4; i++)  			{ -				mShadow[i].allocate(U32(resX*scale),U32(resY*scale), shadow_fmt, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE); +				if (!mShadow[i].allocate(U32(resX*scale),U32(resY*scale), shadow_fmt, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE)) return false;  			}  		}  		else @@ -703,7 +749,7 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)  		{ //allocate two spot shadow maps  			for (U32 i = 4; i < 6; i++)  			{ -				mShadow[i].allocate(width, height, shadow_fmt, TRUE, FALSE); +				if (!mShadow[i].allocate(width, height, shadow_fmt, TRUE, FALSE)) return false;  			}  		}  		else @@ -716,7 +762,7 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)  		width = nhpo2(resX)/2;  		height = nhpo2(resY)/2; -		mLuminanceMap.allocate(width,height, GL_RGBA, FALSE, FALSE); +		if (!mLuminanceMap.allocate(width,height, GL_RGBA, FALSE, FALSE)) return false;  	}  	else  	{ @@ -738,7 +784,7 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)  		mEdgeMap.release();  		mLuminanceMap.release(); -		mScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE);		 +		if (!mScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false;		  	}  	if (LLPipeline::sRenderDeferred) @@ -750,6 +796,7 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)  	stop_glerror(); +	return true;  }  //static @@ -800,9 +847,23 @@ void LLPipeline::releaseGLBuffers()  	mWaterRef.release();  	mWaterDis.release(); +	 +	for (U32 i = 0; i < 3; i++) +	{ +		mGlow[i].release(); +	} + +	releaseScreenBuffers(); + +	gBumpImageList.destroyGL(); +	LLVOAvatar::resetImpostors(); +} + +void LLPipeline::releaseScreenBuffers() +{ +	mUIScreen.release();  	mScreen.release();  	mPhysicsDisplay.release(); -	mUIScreen.release();  	mDeferredScreen.release();  	mDeferredDepth.release();  	for (U32 i = 0; i < 3; i++) @@ -821,16 +882,9 @@ void LLPipeline::releaseGLBuffers()  	{  		mShadow[i].release();  	} - -	for (U32 i = 0; i < 3; i++) -	{ -		mGlow[i].release(); -	} - -	gBumpImageList.destroyGL(); -	LLVOAvatar::resetImpostors();  } +  void LLPipeline::createGLBuffers()  {  	LLMemType mt_cb(LLMemType::MTYPE_PIPELINE_CREATE_BUFFERS); @@ -1983,6 +2037,14 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl  	LLGLDepthTest depth(GL_TRUE, GL_FALSE); +	bool bound_shader = false; +	if (gPipeline.canUseVertexShaders() && LLGLSLShader::sCurBoundShader == 0) +	{ //if no shader is currently bound, use the occlusion shader instead of fixed function if we can +		// (shadow render uses a special shader that clamps to clip planes) +		bound_shader = true; +		gOcclusionProgram.bind(); +	} +	  	for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();   			iter != LLWorld::getInstance()->getRegionList().end(); ++iter)  	{ @@ -2010,6 +2072,11 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl  		}  	} +	if (bound_shader) +	{ +		gOcclusionProgram.unbind(); +	} +  	camera.disableUserClipPlane();  	if (hasRenderType(LLPipeline::RENDER_TYPE_SKY) &&  @@ -2133,7 +2200,21 @@ void LLPipeline::doOcclusion(LLCamera& camera)  		LLGLDepthTest depth(GL_TRUE, GL_FALSE);  		LLGLDisable cull(GL_CULL_FACE); + +		bool bind_shader = LLGLSLShader::sNoFixedFunction && LLGLSLShader::sCurBoundShader == 0; +		if (bind_shader) +		{ +			if (LLPipeline::sShadowRender) +			{ +				gDeferredShadowProgram.bind(); +			} +			else +			{ +				gOcclusionProgram.bind(); +			} +		} +  		for (LLCullResult::sg_list_t::iterator iter = sCull->beginOcclusionGroups(); iter != sCull->endOcclusionGroups(); ++iter)  		{  			LLSpatialGroup* group = *iter; @@ -2141,6 +2222,18 @@ void LLPipeline::doOcclusion(LLCamera& camera)  			group->clearOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION);  		} +		if (bind_shader) +		{ +			if (LLPipeline::sShadowRender) +			{ +				gDeferredShadowProgram.unbind(); +			} +			else +			{ +				gOcclusionProgram.unbind(); +			} +		} +  		gGL.setColorMask(true, false);  	}  } @@ -3249,6 +3342,11 @@ void render_hud_elements()  	gGL.color4f(1,1,1,1);  	if (!LLPipeline::sReflectionRender && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))  	{ +		if (LLGLSLShader::sNoFixedFunction) +		{ +			gUIProgram.bind(); +		} +  		LLGLEnable multisample(gSavedSettings.getU32("RenderFSAASamples") > 0 ? GL_MULTISAMPLE_ARB : 0);  		gViewerWindow->renderSelections(FALSE, FALSE, FALSE); // For HUD version in render_ui_3d() @@ -3262,6 +3360,10 @@ void render_hud_elements()  		// Render name tags.  		LLHUDObject::renderAll(); +		if (LLGLSLShader::sNoFixedFunction) +		{ +			gUIProgram.unbind(); +		}  	}  	else if (gForceRenderLandFence)  	{ @@ -3599,8 +3701,8 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)  						check_stack_depth(stack_depth);  						std::string msg = llformat("pass %d", i);  						LLGLState::checkStates(msg); -						LLGLState::checkTextureChannels(msg); -						LLGLState::checkClientArrays(msg); +						//LLGLState::checkTextureChannels(msg); +						//LLGLState::checkClientArrays(msg);  					}  				}  			} @@ -3638,16 +3740,6 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)  	LLVertexBuffer::unbind();  	LLGLState::checkStates(); -	LLGLState::checkTextureChannels(); -	LLGLState::checkClientArrays(); - -	 - -	stop_glerror(); -		 -	LLGLState::checkStates(); -	LLGLState::checkTextureChannels(); -	LLGLState::checkClientArrays();  	LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderHighlights"); @@ -3701,8 +3793,8 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)  	LLVertexBuffer::unbind();  	LLGLState::checkStates(); -	LLGLState::checkTextureChannels(); -	LLGLState::checkClientArrays(); +//	LLGLState::checkTextureChannels(); +//	LLGLState::checkClientArrays();  }  void LLPipeline::renderGeomDeferred(LLCamera& camera) @@ -3785,8 +3877,6 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)  						llerrs << "GL matrix stack corrupted!" << llendl;  					}  					LLGLState::checkStates(); -					LLGLState::checkTextureChannels(); -					LLGLState::checkClientArrays();  				}  			}  		} @@ -3879,8 +3969,6 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)  						llerrs << "GL matrix stack corrupted!" << llendl;  					}  					LLGLState::checkStates(); -					LLGLState::checkTextureChannels(); -					LLGLState::checkClientArrays();  				}  			}  		} @@ -3955,8 +4043,6 @@ void LLPipeline::renderGeomShadow(LLCamera& camera)  				LLVertexBuffer::unbind();  				LLGLState::checkStates(); -				LLGLState::checkTextureChannels(); -				LLGLState::checkClientArrays();  			}  		}  		else @@ -6449,30 +6535,39 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)  		LLGLDisable blend(GL_BLEND); -		//tex unit 0 -		gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_COLOR); -	 -		gGL.getTexUnit(0)->bind(&mGlow[1]); -		gGL.getTexUnit(1)->activate(); -		gGL.getTexUnit(1)->enable(LLTexUnit::TT_RECT_TEXTURE); - - -		//tex unit 1 -		gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_ADD, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR); +		if (LLGLSLShader::sNoFixedFunction) +		{ +			gGlowCombineProgram.bind(); +		} +		else +		{ +			//tex unit 0 +			gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_COLOR); +			//tex unit 1 +			gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_ADD, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR); +		} +		gGL.getTexUnit(0)->bind(&mGlow[1]);  		gGL.getTexUnit(1)->bind(&mScreen); -		gGL.getTexUnit(1)->activate();  		LLGLEnable multisample(gSavedSettings.getU32("RenderFSAASamples") > 0 ? GL_MULTISAMPLE_ARB : 0);  		buff->setBuffer(mask);  		buff->drawArrays(LLRender::TRIANGLE_STRIP, 0, 3); -		gGL.getTexUnit(1)->disable(); -		gGL.getTexUnit(1)->setTextureBlendType(LLTexUnit::TB_MULT); +		if (LLGLSLShader::sNoFixedFunction) +		{ +			gGlowCombineProgram.unbind(); +		} +		else +		{ +			gGL.getTexUnit(1)->disable(); +			gGL.getTexUnit(1)->setTextureBlendType(LLTexUnit::TB_MULT); -		gGL.getTexUnit(0)->activate(); -		gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); +			gGL.getTexUnit(0)->activate(); +			gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); +		} +		  	}  	if (LLRenderTarget::sUseFBO) @@ -6485,6 +6580,11 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)  	if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES))  	{ +		if (LLGLSLShader::sNoFixedFunction) +		{ +			gUIProgram.bind(); +		} +  		gGL.setColorMask(true, false);  		LLVector2 tc1(0,0); @@ -6508,6 +6608,12 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)  		gGL.end();  		gGL.flush(); + +		if (LLGLSLShader::sNoFixedFunction) +		{ +			gUIProgram.unbind(); +		} +  	}  	glMatrixMode(GL_PROJECTION); @@ -7923,7 +8029,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)  			static LLCullResult ref_result; -			if (LLDrawPoolWater::sNeedsDistortionUpdate) +			if (LLDrawPoolWater::sNeedsReflectionUpdate)  			{  				//initial sky pass (no user clip plane)  				{ //mask out everything but the sky @@ -8063,8 +8169,6 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)  		LLViewerCamera::getInstance()->setUserClipPlane(npnorm);  		LLGLState::checkStates(); -		LLGLState::checkTextureChannels(); -		LLGLState::checkClientArrays();  		if (!skip_avatar_update)  		{ @@ -8197,6 +8301,10 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera  	LLVertexBuffer::unbind();  	{ +		if (!use_shader) +		{ //occlusion program is general purpose depth-only no-textures +			gOcclusionProgram.bind(); +		}  		LLFastTimer ftm(FTM_SHADOW_SIMPLE);  		LLGLDisable test(GL_ALPHA_TEST);  		gGL.getTexUnit(0)->disable(); @@ -8205,6 +8313,10 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera  			renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE);  		}  		gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); +		if (!use_shader) +		{ +			gOcclusionProgram.unbind(); +		}  	}  	if (use_shader) diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index e9da25e544..28e6526acd 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -113,9 +113,11 @@ public:  	void resetVertexBuffers();  	void resizeScreenTexture();  	void releaseGLBuffers(); +	void releaseScreenBuffers();  	void createGLBuffers();  	void allocateScreenBuffer(U32 resX, U32 resY); +	bool allocateScreenBuffer(U32 resX, U32 resY, U32 samples);  	void allocatePhysicsBuffer();  	void resetVertexBuffers(LLDrawable* drawable); | 
