diff --git a/indra/llmessage/llares.cpp b/indra/llmessage/llares.cpp index 93079f537..0c6a31856 100644 --- a/indra/llmessage/llares.cpp +++ b/indra/llmessage/llares.cpp @@ -33,6 +33,9 @@ */ #include "linden_common.h" +#define CARES_STATICLIB +#include "llares.h" +#include "llscopedvolatileaprpool.h" #include #include @@ -42,9 +45,7 @@ #include "apr_poll.h" #include "llapr.h" -#define CARES_STATICLIB -#include "llares.h" -#include "llscopedvolatileaprpool.h" + #if defined(LL_WINDOWS) # define ns_c_in 1 diff --git a/indra/llmessage/llares.h b/indra/llmessage/llares.h index a8f4f0524..8cca4fe15 100644 --- a/indra/llmessage/llares.h +++ b/indra/llmessage/llares.h @@ -51,7 +51,8 @@ # include #endif -#include "llmemory.h" +#include "llpointer.h" +#include "llrefcount.h" #include "lluri.h" class LLQueryResponder; diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index 16ddce622..1f06135a8 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -52,8 +52,8 @@ #endif #include "llbufferstream.h" -#include "llstl.h" #include "llsdserialize.h" +#include "llstl.h" #include "llthread.h" #include "llsocks5.h" #include "lltimer.h" @@ -81,6 +81,7 @@ static const S32 MULTI_PERFORM_CALL_REPEAT = 5; static const S32 CURL_REQUEST_TIMEOUT = 30; // seconds static const S32 MAX_ACTIVE_REQUEST_COUNT = 100; +static // DEBUG // S32 gCurlEasyCount = 0; S32 gCurlMultiCount = 0; @@ -223,77 +224,10 @@ namespace boost ////////////////////////////////////////////////////////////////////////////// - -class LLCurl::Easy -{ - LOG_CLASS(Easy); - -private: - Easy(); - -public: - static Easy* getEasy(); - ~Easy(); - - CURL* getCurlHandle() const { return mCurlEasyHandle; } - - void setErrorBuffer(); - void setCA(); - - void setopt(CURLoption option, S32 value); - // These assume the setter does not free value! - void setopt(CURLoption option, void* value); - void setopt(CURLoption option, char* value); - // Copies the string so that it is gauranteed to stick around - void setoptString(CURLoption option, const std::string& value); - - void slist_append(const char* str); - void setHeaders(); - - U32 report(CURLcode); - void getTransferInfo(LLCurl::TransferInfo* info); - - void prepRequest(const std::string& url, const std::vector& headers, ResponderPtr, S32 time_out = 0, bool post = false); - - const char* getErrorBuffer(); - - std::stringstream& getInput() { return mInput; } - std::stringstream& getHeaderOutput() { return mHeaderOutput; } - LLIOPipe::buffer_ptr_t& getOutput() { return mOutput; } - const LLChannelDescriptors& getChannels() { return mChannels; } - - void resetState(); - - static CURL* allocEasyHandle(); - static void releaseEasyHandle(CURL* handle); - -private: - friend class LLCurl; - - CURL* mCurlEasyHandle; - struct curl_slist* mHeaders; - - std::stringstream mRequest; - LLChannelDescriptors mChannels; - LLIOPipe::buffer_ptr_t mOutput; - std::stringstream mInput; - std::stringstream mHeaderOutput; - char mErrorBuffer[CURL_ERROR_SIZE]; - - // Note: char*'s not strings since we pass pointers to curl - std::vector mStrings; - - ResponderPtr mResponder; - - static std::set sFreeHandles; - static std::set sActiveHandles; - static LLMutex* sHandleMutex; -}; - std::set LLCurl::Easy::sFreeHandles; std::set LLCurl::Easy::sActiveHandles; LLMutex* LLCurl::Easy::sHandleMutex = NULL; - +LLMutex* LLCurl::Easy::sMultiMutex = NULL; //static CURL* LLCurl::Easy::allocEasyHandle() @@ -558,7 +492,7 @@ void LLCurl::Easy::prepRequest(const std::string& url, if (post) setoptString(CURLOPT_ENCODING, ""); -// setopt(CURLOPT_VERBOSE, 1); // usefull for debugging + //setopt(CURLOPT_VERBOSE, 1); // useful for debugging setopt(CURLOPT_NOSIGNAL, 1); if (LLSocks::getInstance()->isHttpProxyEnabled()) @@ -623,56 +557,6 @@ void LLCurl::Easy::prepRequest(const std::string& url, //////////////////////////////////////////////////////////////////////////// -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(); - - Easy* allocEasy(); - bool addEasy(Easy* easy); - - void removeEasy(Easy* easy); - - S32 process(); - void perform(); - void doPerform(); - - virtual void run(); - - CURLMsg* info_read(S32* msgs_in_queue); - - S32 mQueued; - S32 mErrorCount; - - S32 mPerformState; - - LLCondition* mSignal; - bool mQuitting; - bool mThreaded; - -private: - void easyFree(Easy*); - - CURLM* mCurlMultiHandle; - - typedef std::set easy_active_list_t; - easy_active_list_t mEasyActiveList; - typedef std::map easy_active_map_t; - easy_active_map_t mEasyActiveMap; - typedef std::set easy_free_list_t; - easy_free_list_t mEasyFreeList; -}; - LLCurl::Multi::Multi() : LLThread("Curl Multi"), mQueued(0), @@ -706,6 +590,11 @@ LLCurl::Multi::~Multi() { llassert(isStopped()); + if (LLCurl::sMultiThreaded) + { + LLCurl::Easy::sMultiMutex->lock(); + } + delete mSignal; mSignal = NULL; @@ -726,6 +615,11 @@ LLCurl::Multi::~Multi() check_curl_multi_code(curl_multi_cleanup(mCurlMultiHandle)); --gCurlMultiCount; + + if (LLCurl::sMultiThreaded) + { + LLCurl::Easy::sMultiMutex->unlock(); + } } CURLMsg* LLCurl::Multi::info_read(S32* msgs_in_queue) @@ -762,6 +656,7 @@ void LLCurl::Multi::run() mPerformState = PERFORM_STATE_PERFORMING; if (!mQuitting) { + LLMutexLock lock(LLCurl::Easy::sMultiMutex); doPerform(); } } @@ -1356,6 +1251,7 @@ void LLCurl::initClass(bool multi_threaded) check_curl_code(code); Easy::sHandleMutex = new LLMutex; + Easy::sMultiMutex = new LLMutex; #if SAFE_SSL S32 mutex_count = CRYPTO_num_locks(); @@ -1377,6 +1273,8 @@ void LLCurl::cleanupClass() delete Easy::sHandleMutex; Easy::sHandleMutex = NULL; + delete Easy::sMultiMutex; + Easy::sMultiMutex = NULL; for (std::set::iterator iter = Easy::sFreeHandles.begin(); iter != Easy::sFreeHandles.end(); ++iter) { @@ -1390,3 +1288,13 @@ void LLCurl::cleanupClass() } const unsigned int LLCurl::MAX_REDIRECTS = 5; + +// Provide access to LLCurl free functions outside of llcurl.cpp without polluting the global namespace. +void LLCurlFF::check_easy_code(CURLcode code) +{ + check_curl_code(code); +} +void LLCurlFF::check_multi_code(CURLMcode code) +{ + check_curl_multi_code(code); +} diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h index 73516803f..f91abecd5 100644 --- a/indra/llmessage/llcurl.h +++ b/indra/llmessage/llcurl.h @@ -192,6 +192,124 @@ private: static const unsigned int MAX_REDIRECTS; }; +class LLCurl::Easy +{ + LOG_CLASS(Easy); + +private: + Easy(); + +public: + static Easy* getEasy(); + ~Easy(); + + CURL* getCurlHandle() const { return mCurlEasyHandle; } + + void setErrorBuffer(); + void setCA(); + + void setopt(CURLoption option, S32 value); + // These assume the setter does not free value! + void setopt(CURLoption option, void* value); + void setopt(CURLoption option, char* value); + // Copies the string so that it is gauranteed to stick around + void setoptString(CURLoption option, const std::string& value); + + void slist_append(const char* str); + void setHeaders(); + + U32 report(CURLcode); + void getTransferInfo(LLCurl::TransferInfo* info); + + void prepRequest(const std::string& url, const std::vector& headers, ResponderPtr, S32 time_out = 0, bool post = false); + + const char* getErrorBuffer(); + + std::stringstream& getInput() { return mInput; } + std::stringstream& getHeaderOutput() { return mHeaderOutput; } + LLIOPipe::buffer_ptr_t& getOutput() { return mOutput; } + const LLChannelDescriptors& getChannels() { return mChannels; } + + void resetState(); + + static CURL* allocEasyHandle(); + static void releaseEasyHandle(CURL* handle); + +private: + friend class LLCurl; + friend class LLCurl::Multi; + + CURL* mCurlEasyHandle; + struct curl_slist* mHeaders; + + std::stringstream mRequest; + LLChannelDescriptors mChannels; + LLIOPipe::buffer_ptr_t mOutput; + std::stringstream mInput; + std::stringstream mHeaderOutput; + char mErrorBuffer[CURL_ERROR_SIZE]; + + // Note: char*'s not strings since we pass pointers to curl + std::vector mStrings; + + ResponderPtr mResponder; + + static std::set sFreeHandles; + static std::set sActiveHandles; + static LLMutex* sHandleMutex; + static LLMutex* sMultiMutex; +}; + +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(); + + Easy* allocEasy(); + bool addEasy(Easy* easy); + + void removeEasy(Easy* easy); + + S32 process(); + void perform(); + void doPerform(); + + virtual void run(); + + CURLMsg* info_read(S32* msgs_in_queue); + + S32 mQueued; + S32 mErrorCount; + + S32 mPerformState; + + LLCondition* mSignal; + bool mQuitting; + bool mThreaded; + +private: + void easyFree(Easy*); + + CURLM* mCurlMultiHandle; + + typedef std::set easy_active_list_t; + easy_active_list_t mEasyActiveList; + typedef std::map easy_active_map_t; + easy_active_map_t mEasyActiveMap; + typedef std::set easy_free_list_t; + easy_free_list_t mEasyFreeList; +}; + namespace boost { void intrusive_ptr_add_ref(LLCurl::Responder* p); @@ -248,6 +366,8 @@ public: bool getResult(CURLcode* result, LLCurl::TransferInfo* info = NULL); std::string getErrorString(); + LLCurl::Easy* getEasy() const { return mEasy; } + private: CURLMsg* info_read(S32* queue, LLCurl::TransferInfo* info); @@ -258,4 +378,11 @@ private: bool mResultReturned; }; +// Provide access to LLCurl free functions outside of llcurl.cpp without polluting the global namespace. +namespace LLCurlFF +{ + void check_easy_code(CURLcode code); + void check_multi_code(CURLMcode code); +} + #endif // LL_LLCURL_H diff --git a/indra/llmessage/lliosocket.cpp b/indra/llmessage/lliosocket.cpp index f70d474d7..774950162 100644 --- a/indra/llmessage/lliosocket.cpp +++ b/indra/llmessage/lliosocket.cpp @@ -243,6 +243,7 @@ LLSocket::~LLSocket() { ll_debug_socket("Destroying socket", mSocket); apr_socket_close(mSocket); + mSocket = NULL; } } @@ -604,7 +605,6 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl( { chain.push_back(LLIOPipe::ptr_t(new LLIOSocketWriter(llsocket))); pump->addChain(chain, mResponseTimeout); - status = STATUS_OK; } else { diff --git a/indra/llmessage/llpacketring.cpp b/indra/llmessage/llpacketring.cpp index 74c30406d..60359dfc5 100644 --- a/indra/llmessage/llpacketring.cpp +++ b/indra/llmessage/llpacketring.cpp @@ -34,13 +34,6 @@ #include "llpacketring.h" -// linden library includes -#include "llerror.h" -#include "lltimer.h" -#include "timing.h" -#include "llrand.h" -#include "u64.h" - #include "llsocks5.h" #if LL_WINDOWS @@ -50,9 +43,16 @@ #include #endif +// linden library includes +#include "llerror.h" +#include "lltimer.h" +#include "llrand.h" +#include "message.h" +#include "timing.h" +#include "u64.h" // #include "llmessagelog.h" -#include "message.h" + // diff --git a/indra/llmessage/llpacketring.h b/indra/llmessage/llpacketring.h index 5d2c24640..355113e1a 100644 --- a/indra/llmessage/llpacketring.h +++ b/indra/llmessage/llpacketring.h @@ -36,11 +36,10 @@ #include -#include "llpacketbuffer.h" #include "llhost.h" -#include "net.h" +#include "llpacketbuffer.h" #include "llthrottle.h" - +#include "net.h" class LLPacketRing { diff --git a/indra/llmessage/message.h b/indra/llmessage/message.h index e89ee42fb..759dafca4 100644 --- a/indra/llmessage/message.h +++ b/indra/llmessage/message.h @@ -59,10 +59,10 @@ #include "llhttpclient.h" #include "llhttpnode.h" #include "llpacketack.h" +#include "llsingleton.h" #include "message_prehash.h" #include "llstl.h" #include "llmsgvariabletype.h" -#include "llmsgvariabletype.h" #include "llmessagesenderinterface.h" #include "llstoredmessage.h" diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 37b3d27d1..80a26c0a1 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -1929,10 +1929,66 @@ bool LLModel::loadModel(std::istream& is) } -void LLModel::matchMaterialOrder(LLModel* ref) +bool LLModel::isMaterialListSubset( LLModel* ref ) { - llassert(ref->mMaterialList.size() == mMaterialList.size()); + S32 refCnt = ref->mMaterialList.size(); + S32 modelCnt = mMaterialList.size(); + + for (S32 src = 0; src < modelCnt; ++src) + { + bool foundRef = false; + + for (S32 dst = 0; dst < refCnt; ++dst) + { + //llinfos<mMaterialList[dst]<mMaterialList[dst]; + + if ( foundRef ) + { + break; + } + } + if (!foundRef) + { + return false; + } + } + + return true; +} +bool LLModel::needToAddFaces( LLModel* ref, int& refFaceCnt, int& modelFaceCnt ) +{ + bool changed = false; + if ( refFaceCnt< modelFaceCnt ) + { + refFaceCnt += modelFaceCnt - refFaceCnt; + changed = true; + } + else + if ( modelFaceCnt < refFaceCnt ) + { + modelFaceCnt += refFaceCnt - modelFaceCnt; + changed = true; + } + + return changed; +} + +bool LLModel::matchMaterialOrder(LLModel* ref, int& refFaceCnt, int& modelFaceCnt ) +{ + //Is this a subset? + //LODs cannot currently add new materials, e.g. + //1. ref = a,b,c lod1 = d,e => This is not permitted + //2. ref = a,b,c lod1 = c => This would be permitted + + bool isASubset = isMaterialListSubset( ref ); + if ( !isASubset ) + { + llinfos<<"Material of model is not a subset of reference."< index_map; //build a map of material slot names to face indexes @@ -1978,6 +2034,7 @@ void LLModel::matchMaterialOrder(LLModel* ref) //override material list with reference model ordering mMaterialList = ref->mMaterialList; + return true; } diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index 58975e55b..19c07dd0b 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -180,8 +180,10 @@ public: //reorder face list based on mMaterialList in this and reference so //order matches that of reference (material ordering touchup) - void matchMaterialOrder(LLModel* reference); - + bool matchMaterialOrder(LLModel* ref, int& refFaceCnt, int& modelFaceCnt ); + bool isMaterialListSubset( LLModel* ref ); + bool needToAddFaces( LLModel* ref, int& refFaceCnt, int& modelFaceCnt ); + std::vector mMaterialList; //data used for skin weights diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index e5a782f3f..879a8b690 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -1410,7 +1410,7 @@ void LLImageGL::deleteDeadTextures() { LLTexUnit* tex_unit = gGL.getTexUnit(i); - if (tex_unit->getCurrTexture() == tex) + if (tex_unit && tex_unit->getCurrTexture() == tex) { tex_unit->unbind(tex_unit->getCurrType()); stop_glerror(); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 7115f16b1..9029a8188 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -2842,7 +2842,7 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e bool special_cursor = specialHoverCursor(); for (S32 i = start_face; i < end_face; ++i) { - if (!special_cursor && !pick_transparent && getTE(i)->getColor().mV[3] == 0.f) + if (!special_cursor && !pick_transparent && getTE(i) && getTE(i)->getColor().mV[3] == 0.f) { //don't attempt to pick completely transparent faces unless //pick_transparent is true continue; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 7ed337b59..8f8eab62d 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -3878,6 +3878,7 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera) occlude = FALSE; gGLLastMatrix = NULL; glLoadMatrixd(gGLModelView); + LLGLSLShader::bindNoShader(); doOcclusion(camera); gGLLastMatrix = NULL; glLoadMatrixd(gGLModelView); @@ -9410,7 +9411,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) { //create alpha mask based on depth buffer (grey out if muted) if (LLPipeline::sRenderDeferred) { - GLuint buff = GL_COLOR_ATTACHMENT0_EXT; + GLuint buff = GL_COLOR_ATTACHMENT0; glDrawBuffersARB(1, &buff); }