merging latest viewer-development to mesh merge candidate.

master
Nyx (Neal Orman) 2011-07-25 18:26:14 -04:00
commit c07f55e605
90 changed files with 2163 additions and 338 deletions

View File

@ -153,3 +153,4 @@ e1ed60913230dd64269a7f7fc52cbc6004f6d52c 2.8.0-start
6866d9df6efbd441c66451debd376d21211de39c 2.7.5-release
e1ed60913230dd64269a7f7fc52cbc6004f6d52c DRTVWR-71_2.8.0-beta1
e1ed60913230dd64269a7f7fc52cbc6004f6d52c 2.8.0-beta1
54bc7823ad4e3a436fef79710f685a7372bbf795 2.8.2-start

View File

@ -219,6 +219,7 @@ Boroondas Gupte
VWR-20891
VWR-23455
VWR-24487
VWR-26066
WEB-262
Bulli Schumann
CT-218

View File

@ -317,7 +317,8 @@ if (LL_TESTS)
LL_ADD_INTEGRATION_TEST(lllazy "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llprocessor "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llrand "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llsdserialize "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llsdserialize "" "${test_libs}"
"${PYTHON_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/setpython.py")
LL_ADD_INTEGRATION_TEST(llstring "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lltreeiterators "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lluri "" "${test_libs}")

View File

@ -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

View File

@ -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;

View File

@ -29,7 +29,7 @@
const S32 LL_VERSION_MAJOR = 2;
const S32 LL_VERSION_MINOR = 8;
const S32 LL_VERSION_PATCH = 2;
const S32 LL_VERSION_PATCH = 3;
const S32 LL_VERSION_BUILD = 0;
const char * const LL_CHANNEL = "Project Viewer - Mesh";

View File

@ -25,35 +25,293 @@
* $/LicenseInfo$
*/
#if !LL_WINDOWS
#include <netinet/in.h>
#endif
#include "linden_common.h"
#include "../llsd.h"
#include "../llsdserialize.h"
#include "../llformat.h"
#include "../test/lltut.h"
#if LL_WINDOWS
#include <winsock2.h>
typedef U32 uint32_t;
#include <process.h>
#include <io.h>
#else
#include <unistd.h>
#include <netinet/in.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include "llprocesslauncher.h"
#endif
std::vector<U8> string_to_vector(std::string str)
#include <sstream>
/*==========================================================================*|
// Whoops, seems Linden's Boost package and the viewer are built with
// different settings of VC's /Zc:wchar_t switch! Using Boost.Filesystem
// pathname operations produces Windows link errors:
// unresolved external symbol "private: static class std::codecvt<unsigned short,
// char,int> const * & __cdecl boost::filesystem3::path::wchar_t_codecvt_facet()"
// unresolved external symbol "void __cdecl boost::filesystem3::path_traits::convert()"
// See:
// http://boost.2283326.n4.nabble.com/filesystem-v3-unicode-and-std-codecvt-linker-error-td3455549.html
// which points to:
// http://msdn.microsoft.com/en-us/library/dh8che7s%28v=VS.100%29.aspx
// As we're not trying to preserve compatibility with old Boost.Filesystem
// code, but rather writing brand-new code, use the newest available
// Filesystem API.
#define BOOST_FILESYSTEM_VERSION 3
#include "boost/filesystem.hpp"
#include "boost/filesystem/v3/fstream.hpp"
|*==========================================================================*/
#include "boost/range.hpp"
#include "boost/foreach.hpp"
#include "boost/function.hpp"
#include "boost/lambda/lambda.hpp"
#include "boost/lambda/bind.hpp"
namespace lambda = boost::lambda;
/*==========================================================================*|
// Aaaarrgh, Linden's Boost package doesn't even include Boost.Iostreams!
#include "boost/iostreams/stream.hpp"
#include "boost/iostreams/device/file_descriptor.hpp"
|*==========================================================================*/
#include "../llsd.h"
#include "../llsdserialize.h"
#include "llsdutil.h"
#include "../llformat.h"
#include "../test/lltut.h"
#include "stringize.h"
std::vector<U8> string_to_vector(const std::string& str)
{
// bc LLSD can't...
size_t len = (size_t)str.length();
std::vector<U8> v(len);
for (size_t i = 0; i < len ; i++)
{
v[i] = str[i];
}
return v;
return std::vector<U8>(str.begin(), str.end());
}
#if ! LL_WINDOWS
// We want to call strerror_r(), but alarmingly, there are two different
// variants. The one that returns int always populates the passed buffer
// (except in case of error), whereas the other one always returns a valid
// char* but might or might not populate the passed buffer. How do we know
// which one we're getting? Define adapters for each and let the compiler
// select the applicable adapter.
// strerror_r() returns char*
std::string message_from(int /*orig_errno*/, const char* /*buffer*/, const char* strerror_ret)
{
return strerror_ret;
}
// strerror_r() returns int
std::string message_from(int orig_errno, const char* buffer, int strerror_ret)
{
if (strerror_ret == 0)
{
return buffer;
}
// Here strerror_r() has set errno. Since strerror_r() has already failed,
// seems like a poor bet to call it again to diagnose its own error...
int stre_errno = errno;
if (stre_errno == ERANGE)
{
return STRINGIZE("strerror_r() can't explain errno " << orig_errno
<< " (buffer too small)");
}
if (stre_errno == EINVAL)
{
return STRINGIZE("unknown errno " << orig_errno);
}
// Here we don't even understand the errno from strerror_r()!
return STRINGIZE("strerror_r() can't explain errno " << orig_errno
<< " (error " << stre_errno << ')');
}
#endif // ! LL_WINDOWS
// boost::filesystem::temp_directory_path() isn't yet in Boost 1.45! :-(
std::string temp_directory_path()
{
#if LL_WINDOWS
char buffer[4096];
GetTempPathA(sizeof(buffer), buffer);
return buffer;
#else // LL_DARWIN, LL_LINUX
static const char* vars[] = { "TMPDIR", "TMP", "TEMP", "TEMPDIR" };
BOOST_FOREACH(const char* var, vars)
{
const char* found = getenv(var);
if (found)
return found;
}
return "/tmp";
#endif // LL_DARWIN, LL_LINUX
}
// Windows presents a kinda sorta compatibility layer. Code to the yucky
// Windows names because they're less likely than the Posix names to collide
// with any other names in this source.
#if LL_WINDOWS
#define _remove DeleteFileA
#else // ! LL_WINDOWS
#define _open open
#define _write write
#define _close close
#define _remove remove
#endif // ! LL_WINDOWS
// Create a text file with specified content "somewhere in the
// filesystem," cleaning up when it goes out of scope.
class NamedTempFile
{
public:
// Function that accepts an ostream ref and (presumably) writes stuff to
// it, e.g.:
// (lambda::_1 << "the value is " << 17 << '\n')
typedef boost::function<void(std::ostream&)> Streamer;
NamedTempFile(const std::string& ext, const std::string& content):
mPath(temp_directory_path())
{
createFile(ext, lambda::_1 << content);
}
// Disambiguate when passing string literal
NamedTempFile(const std::string& ext, const char* content):
mPath(temp_directory_path())
{
createFile(ext, lambda::_1 << content);
}
NamedTempFile(const std::string& ext, const Streamer& func):
mPath(temp_directory_path())
{
createFile(ext, func);
}
~NamedTempFile()
{
_remove(mPath.c_str());
}
std::string getName() const { return mPath; }
private:
void createFile(const std::string& ext, const Streamer& func)
{
// Silly maybe, but use 'ext' as the name prefix. Strip off a leading
// '.' if present.
int pfx_offset = ((! ext.empty()) && ext[0] == '.')? 1 : 0;
#if ! LL_WINDOWS
// Make sure mPath ends with a directory separator, if it doesn't already.
if (mPath.empty() ||
! (mPath[mPath.length() - 1] == '\\' || mPath[mPath.length() - 1] == '/'))
{
mPath.append("/");
}
// mkstemp() accepts and modifies a char* template string. Generate
// the template string, then copy to modifiable storage.
// mkstemp() requires its template string to end in six X's.
mPath += ext.substr(pfx_offset) + "XXXXXX";
// Copy to vector<char>
std::vector<char> pathtemplate(mPath.begin(), mPath.end());
// append a nul byte for classic-C semantics
pathtemplate.push_back('\0');
// std::vector promises that a pointer to the 0th element is the same
// as a pointer to a contiguous classic-C array
int fd(mkstemp(&pathtemplate[0]));
if (fd == -1)
{
// The documented errno values (http://linux.die.net/man/3/mkstemp)
// are used in a somewhat unusual way, so provide context-specific
// errors.
if (errno == EEXIST)
{
LL_ERRS("NamedTempFile") << "mkstemp(\"" << mPath
<< "\") could not create unique file " << LL_ENDL;
}
if (errno == EINVAL)
{
LL_ERRS("NamedTempFile") << "bad mkstemp() file path template '"
<< mPath << "'" << LL_ENDL;
}
// Shrug, something else
int mkst_errno = errno;
char buffer[256];
LL_ERRS("NamedTempFile") << "mkstemp(\"" << mPath << "\") failed: "
<< message_from(mkst_errno, buffer,
strerror_r(mkst_errno, buffer, sizeof(buffer)))
<< LL_ENDL;
}
// mkstemp() seems to have worked! Capture the modified filename.
// Avoid the nul byte we appended.
mPath.assign(pathtemplate.begin(), (pathtemplate.end()-1));
/*==========================================================================*|
// Define an ostream on the open fd. Tell it to close fd on destruction.
boost::iostreams::stream<boost::iostreams::file_descriptor_sink>
out(fd, boost::iostreams::close_handle);
|*==========================================================================*/
// Write desired content.
std::ostringstream out;
// Stream stuff to it.
func(out);
std::string data(out.str());
int written(_write(fd, data.c_str(), data.length()));
int closed(_close(fd));
llassert_always(written == data.length() && closed == 0);
#else // LL_WINDOWS
// GetTempFileName() is documented to require a MAX_PATH buffer.
char tempname[MAX_PATH];
// Use 'ext' as filename prefix, but skip leading '.' if any.
// The 0 param is very important: requests iterating until we get a
// unique name.
if (0 == GetTempFileNameA(mPath.c_str(), ext.c_str() + pfx_offset, 0, tempname))
{
// I always have to look up this call... :-P
LPSTR msgptr;
FormatMessageA(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
LPSTR(&msgptr), // have to cast (char**) to (char*)
0, NULL );
LL_ERRS("NamedTempFile") << "GetTempFileName(\"" << mPath << "\", \""
<< (ext.c_str() + pfx_offset) << "\") failed: "
<< msgptr << LL_ENDL;
LocalFree(msgptr);
}
// GetTempFileName() appears to have worked! Capture the actual
// filename.
mPath = tempname;
// Open the file and stream content to it. Destructor will close.
std::ofstream out(tempname);
func(out);
#endif // LL_WINDOWS
}
void peep()
{
std::cout << "File '" << mPath << "' contains:\n";
std::ifstream reader(mPath.c_str());
std::string line;
while (std::getline(reader, line))
std::cout << line << '\n';
std::cout << "---\n";
}
std::string mPath;
};
namespace tut
{
struct sd_xml_data
@ -1494,5 +1752,223 @@ namespace tut
ensureBinaryAndNotation("map", test);
ensureBinaryAndXML("map", test);
}
}
struct TestPythonCompatible
{
TestPythonCompatible():
// Note the peculiar insertion of __FILE__ into this string. Since
// this script is being written into a platform-dependent temp
// directory, we can't locate indra/lib/python relative to
// Python's __file__. Use __FILE__ instead, navigating relative
// to this C++ source file. Use Python raw-string syntax so
// Windows pathname backslashes won't mislead Python's string
// scanner.
import_llsd("import os.path\n"
"import sys\n"
"sys.path.insert(0,\n"
" os.path.join(os.path.dirname(r'" __FILE__ "'),\n"
" os.pardir, os.pardir, 'lib', 'python'))\n"
"try:\n"
" from llbase import llsd\n"
"except ImportError:\n"
" from indra.base import llsd\n")
{}
~TestPythonCompatible() {}
std::string import_llsd;
template <typename CONTENT>
void python(const std::string& desc, const CONTENT& script, int expect=0)
{
const char* PYTHON(getenv("PYTHON"));
ensure("Set $PYTHON to the Python interpreter", PYTHON);
NamedTempFile scriptfile(".py", script);
#if LL_WINDOWS
std::string q("\"");
std::string qPYTHON(q + PYTHON + q);
std::string qscript(q + scriptfile.getName() + q);
int rc = _spawnl(_P_WAIT, PYTHON, qPYTHON.c_str(), qscript.c_str(), NULL);
if (rc == -1)
{
char buffer[256];
strerror_s(buffer, errno); // C++ can infer the buffer size! :-O
ensure(STRINGIZE("Couldn't run Python " << desc << "script: " << buffer), false);
}
else
{
ensure_equals(STRINGIZE(desc << " script terminated with rc " << rc), rc, expect);
}
#else // LL_DARWIN, LL_LINUX
LLProcessLauncher py;
py.setExecutable(PYTHON);
py.addArgument(scriptfile.getName());
ensure_equals(STRINGIZE("Couldn't launch " << desc << " script"), py.launch(), 0);
// Implementing timeout would mean messing with alarm() and
// catching SIGALRM... later maybe...
int status(0);
if (waitpid(py.getProcessID(), &status, 0) == -1)
{
int waitpid_errno(errno);
ensure_equals(STRINGIZE("Couldn't retrieve rc from " << desc << " script: "
"waitpid() errno " << waitpid_errno),
waitpid_errno, ECHILD);
}
else
{
if (WIFEXITED(status))
{
int rc(WEXITSTATUS(status));
ensure_equals(STRINGIZE(desc << " script terminated with rc " << rc),
rc, expect);
}
else if (WIFSIGNALED(status))
{
ensure(STRINGIZE(desc << " script terminated by signal " << WTERMSIG(status)),
false);
}
else
{
ensure(STRINGIZE(desc << " script produced impossible status " << status),
false);
}
}
#endif
}
};
typedef tut::test_group<TestPythonCompatible> TestPythonCompatibleGroup;
typedef TestPythonCompatibleGroup::object TestPythonCompatibleObject;
TestPythonCompatibleGroup pycompat("LLSD serialize Python compatibility");
template<> template<>
void TestPythonCompatibleObject::test<1>()
{
set_test_name("verify python()");
python("hello",
"import sys\n"
"sys.exit(17)\n",
17); // expect nonzero rc
}
template<> template<>
void TestPythonCompatibleObject::test<2>()
{
set_test_name("verify NamedTempFile");
python("platform",
"import sys\n"
"print 'Running on', sys.platform\n");
}
template<> template<>
void TestPythonCompatibleObject::test<3>()
{
set_test_name("verify sequence to Python");
LLSD cdata(LLSDArray(17)(3.14)
("This string\n"
"has several\n"
"lines."));
const char pydata[] =
"def verify(iterable):\n"
" it = iter(iterable)\n"
" assert it.next() == 17\n"
" assert abs(it.next() - 3.14) < 0.01\n"
" assert it.next() == '''\\\n"
"This string\n"
"has several\n"
"lines.'''\n"
" try:\n"
" it.next()\n"
" except StopIteration:\n"
" pass\n"
" else:\n"
" assert False, 'Too many data items'\n";
// Create a something.llsd file containing 'data' serialized to
// notation. It's important to separate with newlines because Python's
// llsd module doesn't support parsing from a file stream, only from a
// string, so we have to know how much of the file to read into a
// string.
NamedTempFile file(".llsd",
// NamedTempFile's boost::function constructor
// takes a callable. To this callable it passes the
// std::ostream with which it's writing the
// NamedTempFile. This lambda-based expression
// first calls LLSD::Serialize() with that ostream,
// then streams a newline to it, etc.
(lambda::bind(LLSDSerialize::toNotation, cdata[0], lambda::_1),
lambda::_1 << '\n',
lambda::bind(LLSDSerialize::toNotation, cdata[1], lambda::_1),
lambda::_1 << '\n',
lambda::bind(LLSDSerialize::toNotation, cdata[2], lambda::_1),
lambda::_1 << '\n'));
python("read C++ notation",
lambda::_1 <<
import_llsd <<
"def parse_each(iterable):\n"
" for item in iterable:\n"
" yield llsd.parse(item)\n" <<
pydata <<
// Don't forget raw-string syntax for Windows pathnames.
"verify(parse_each(open(r'" << file.getName() << "')))\n");
}
template<> template<>
void TestPythonCompatibleObject::test<4>()
{
set_test_name("verify sequence from Python");
// Create an empty data file. This is just a placeholder for our
// script to write into. Create it to establish a unique name that
// we know.
NamedTempFile file(".llsd", "");
python("write Python notation",
lambda::_1 <<
"from __future__ import with_statement\n" <<
import_llsd <<
"DATA = [\n"
" 17,\n"
" 3.14,\n"
" '''\\\n"
"This string\n"
"has several\n"
"lines.''',\n"
"]\n"
// Don't forget raw-string syntax for Windows pathnames.
// N.B. Using 'print' implicitly adds newlines.
"with open(r'" << file.getName() << "', 'w') as f:\n"
" for item in DATA:\n"
" print >>f, llsd.format_notation(item)\n");
std::ifstream inf(file.getName().c_str());
LLSD item;
// Notice that we're not doing anything special to parse out the
// newlines: LLSDSerialize::fromNotation ignores them. While it would
// seem they're not strictly necessary, going in this direction, we
// want to ensure that notation-separated-by-newlines works in both
// directions -- since in practice, a given file might be read by
// either language.
ensure_equals("Failed to read LLSD::Integer from Python",
LLSDSerialize::fromNotation(item, inf, LLSDSerialize::SIZE_UNLIMITED),
1);
ensure_equals(item.asInteger(), 17);
ensure_equals("Failed to read LLSD::Real from Python",
LLSDSerialize::fromNotation(item, inf, LLSDSerialize::SIZE_UNLIMITED),
1);
ensure_approximately_equals("Bad LLSD::Real value from Python",
item.asReal(), 3.14, 7); // 7 bits ~= 0.01
ensure_equals("Failed to read LLSD::String from Python",
LLSDSerialize::fromNotation(item, inf, LLSDSerialize::SIZE_UNLIMITED),
1);
ensure_equals(item.asString(),
"This string\n"
"has several\n"
"lines.");
}
}

View File

@ -0,0 +1,19 @@
#!/usr/bin/python
"""\
@file setpython.py
@author Nat Goodspeed
@date 2011-07-13
@brief Set PYTHON environment variable for tests that care.
$LicenseInfo:firstyear=2011&license=viewerlgpl$
Copyright (c) 2011, Linden Research, Inc.
$/LicenseInfo$
"""
import os
import sys
import subprocess
if __name__ == "__main__":
os.environ["PYTHON"] = sys.executable
sys.exit(subprocess.call(sys.argv[1:]))

View File

@ -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;
}
S32 LLCurl::Multi::perform()
void LLCurl::Multi::perform()
{
S32 q = 0;
for (S32 call_count = 0;
call_count < MULTI_PERFORM_CALL_REPEAT;
call_count += 1)
if (mPerformState == PERFORM_STATE_READY)
{
CURLMcode code = curl_multi_perform(mCurlMultiHandle, &q);
if (CURLM_CALL_MULTI_PERFORM != code || q == 0)
{
check_curl_multi_code(code);
break;
}
mSignal->signal();
}
}
void LLCurl::Multi::run()
{
while (!mQuitting)
{
mSignal->wait();
mPerformState = PERFORM_STATE_PERFORMING;
if (!mQuitting)
{
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)

View File

@ -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();

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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;
}

View File

@ -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))

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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();

View File

@ -88,7 +88,9 @@ public:
// ARB Extensions
BOOL mHasVertexBufferObject;
BOOL mHasSync;
BOOL mHasMapBufferRange;
BOOL mHasFlushBufferRange;
BOOL mHasPBuffer;
BOOL mHasShaderObjects;
BOOL mHasVertexShader;

View File

@ -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;

View File

@ -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();

View File

@ -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

View File

@ -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()

View File

@ -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();

View File

@ -52,6 +52,8 @@ class LLTexUnit
{
friend class LLRender;
public:
static U32 sWhiteTexture;
typedef enum
{
TT_TEXTURE = 0, // Standard 2D Texture

View File

@ -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)

View File

@ -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();

View File

@ -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,
@ -310,6 +366,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
@ -341,6 +398,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
@ -366,6 +424,7 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
stop_glerror();
glDrawArrays(sGLMode[mode], first, count);
stop_glerror();
placeFence();
}
//static
@ -445,9 +504,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 ;
@ -528,9 +589,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()
@ -893,17 +985,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;
}
@ -968,8 +1054,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)
{
@ -1009,6 +1094,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)
@ -1019,29 +1105,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;
@ -1083,7 +1190,6 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran
llerrs << "memory allocation for vertex data failed." << llendl ;
}
}
sMappedCount++;
}
}
else
@ -1091,7 +1197,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;
}
@ -1115,7 +1221,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)
{
@ -1153,6 +1259,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
setBuffer(0, TYPE_INDEX);
mIndexLocked = TRUE;
sMappedCount++;
stop_glerror();
if(sDisableVBOMapping)
@ -1163,29 +1270,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
{
src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, sizeof(U16)*mNumIndices, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);
#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*) 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();
@ -1212,15 +1341,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;
}
@ -1269,8 +1396,7 @@ void LLVertexBuffer::unmapBuffer(S32 type)
}
else
{
#ifdef GL_ARB_map_buffer_range
if (gGLManager.mHasMapBufferRange)
if (gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange)
{
if (!mMappedVertexRegions.empty())
{
@ -1280,16 +1406,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();
@ -1327,8 +1459,7 @@ void LLVertexBuffer::unmapBuffer(S32 type)
}
else
{
#ifdef GL_ARB_map_buffer_range
if (gGLManager.mHasMapBufferRange)
if (gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange)
{
if (!mMappedIndexRegions.empty())
{
@ -1337,16 +1468,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();

View File

@ -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;

View File

@ -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);
}
}
}

View File

@ -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

View File

@ -52,8 +52,20 @@ LLDirIterator::Impl::Impl(const std::string &dirname, const std::string &mask)
{
fs::path dir_path(dirname);
// Check if path exists.
if (!fs::exists(dir_path))
bool is_dir = false;
// Check if path is a directory.
try
{
is_dir = fs::is_directory(dir_path);
}
catch (fs::basic_filesystem_error<fs::path>& e)
{
llwarns << e.what() << llendl;
return;
}
if (!is_dir)
{
llwarns << "Invalid path: \"" << dir_path.string() << "\"" << llendl;
return;
@ -66,7 +78,7 @@ LLDirIterator::Impl::Impl(const std::string &dirname, const std::string &mask)
}
catch (fs::basic_filesystem_error<fs::path>& e)
{
llerrs << e.what() << llendl;
llwarns << e.what() << llendl;
return;
}
@ -82,7 +94,7 @@ LLDirIterator::Impl::Impl(const std::string &dirname, const std::string &mask)
}
catch (boost::regex_error& e)
{
llerrs << "\"" << exp << "\" is not a valid regular expression: "
llwarns << "\"" << exp << "\" is not a valid regular expression: "
<< e.what() << llendl;
return;
}

View File

@ -44,7 +44,6 @@
<array>
<!-- sample entry for debugging a specific item -->
<!-- <string>Voice</string> -->
<string>Capabilities</string>
</array>
</map>
</array>

View File

@ -3848,7 +3848,7 @@
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>https://www.xstreetsl.com/modules.php?name=Marketplace&amp;CategoryID=233</string>
<string>https://marketplace.secondlife.com/products/search?search[category_id]=200&amp;search[maturity][]=General&amp;search[page]=1&amp;search[per_page]=12</string>
</map>
<key>GridCrossSections</key>
<map>

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -0,0 +1,11 @@
/**
* @file occlusionF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* $/LicenseInfo$
*/
void main()
{
gl_FragColor = vec4(1,1,1,1);
}

View File

@ -0,0 +1,12 @@
/**
* @file uiV.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* $/LicenseInfo$
*/
void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}

View File

@ -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);
}

View File

@ -0,0 +1,16 @@
/**
* @file solidcolorV.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* $/LicenseInfo$
*/
void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_FrontColor = gl_Color;
gl_TexCoord[0] = gl_MultiTexCoord0;
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -1,6 +1,6 @@
version 30
version 32
// NOTE: This is mostly identical to featuretable_mac.txt with a few differences
// 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
//

View File

@ -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

View File

@ -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
//
@ -243,13 +243,6 @@ RenderDeferred 0 0
RenderDeferredSSAO 0 0
RenderShadowDetail 0 0
//
// No GL_ARB_map_buffer_range
//
list NoMapBufferRange
RenderVBOMappingDisable 1 0
//
// "Default" setups for safe, low, medium, high
//

View File

@ -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
//

View File

@ -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();
}
}
//

View File

@ -27,10 +27,16 @@
#include "lldateutil.h"
#include <boost/date_time/gregorian/gregorian.hpp>
#include <boost/date_time/posix_time/ptime.hpp>
// Linden libraries
#include "lltrans.h"
#include "llui.h"
using namespace boost::gregorian;
using namespace boost::posix_time;
static S32 DAYS_PER_MONTH_NOLEAP[] =
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
static S32 DAYS_PER_MONTH_LEAP[] =
@ -186,3 +192,24 @@ std::string LLDateUtil::ageFromDate(const std::string& date_string)
//{
// return ageFromDateISO(date_string, LLDate::now());
//}
S32 LLDateUtil::secondsSinceEpochFromString(const std::string& format, const std::string& str)
{
date_input_facet *facet = new date_input_facet(format);
std::stringstream ss;
ss << str;
ss.imbue(std::locale(ss.getloc(), facet));
date d;
ss >> d;
ptime time_t_date(d);
ptime time_t_epoch(date(1970,1,1));
// We assume that the date defined by str is in UTC, so the difference
// is calculated with no time zone corrections.
time_duration diff = time_t_date - time_t_epoch;
return diff.total_seconds();
}

View File

@ -69,6 +69,20 @@ namespace LLDateUtil
//std::string ageFromDateISO(const std::string& date_string);
//std::string ageFromDate(S32 born_year, S32 born_month, S32 born_day, const LLDate& now);
/**
* Convert a string of a specified date format into seconds since the Epoch.
*
* Many of the format flags are those used by strftime(...), but not all.
* For the full list of supported time format specifiers
* see http://www.boost.org/doc/libs/1_47_0/doc/html/date_time/date_time_io.html#date_time.format_flags
*
* @param format Format characters string. Example: "%A %b %d, %Y"
* @param str Date string containing the time in specified format.
*
* @return Number of seconds since 01/01/1970 UTC.
*/
S32 secondsSinceEpochFromString(const std::string& format, const std::string& str);
}
#endif

View File

@ -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();
}

View File

@ -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
{

View File

@ -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)
// 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);
}
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);

View File

@ -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()

View File

@ -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

View File

@ -73,7 +73,7 @@ void LLDrawPoolTree::beginRenderPass(S32 pass)
shader = &gObjectSimpleNonIndexedProgram;
}
if (gPipeline.canUseWindLightShadersOnObjects())
if (gPipeline.canUseVertexShaders())
{
shader->bind();
}

View File

@ -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();
}
}
}

View File

@ -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)

View File

@ -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

View File

@ -70,7 +70,7 @@
#include "llappviewer.h"
#include "llmapimagetype.h"
#include "llweb.h"
#include "llslider.h"
#include "llsliderctrl.h"
#include "message.h"
#include "llwindow.h" // copyTextToClipboard()
#include <algorithm>
@ -1029,7 +1029,7 @@ void LLFloaterWorldMap::adjustZoomSliderBounds()
F32 min_power = log(pixels_per_region/256.f)/log(2.f);
getChild<LLSlider>("zoom slider")->setMinValue(min_power);
getChild<LLSliderCtrl>("zoom slider")->setMinValue(min_power);
}

View File

@ -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 )

View File

@ -2514,6 +2514,11 @@ void LLFolderBridge::folderOptionsMenu()
}
}
if (!isItemRemovable())
{
disabled_items.push_back(std::string("Delete"));
}
#ifndef LL_RELEASE_FOR_DOWNLOAD
if (LLFolderType::lookupIsProtectedType(type))
{

View File

@ -35,6 +35,7 @@
#include "llqueryflags.h"
#include "llagent.h"
#include "lldateutil.h"
#include "lliconctrl.h"
#include "llfloaterreg.h"
#include "lllineeditor.h"
@ -1056,6 +1057,14 @@ void LLGroupMoneyDetailsTabEventHandler::processReply(LLMessageSystem* msg,
msg->getS32Fast(_PREHASH_MoneyData, _PREHASH_CurrentInterval, current_interval );
msg->getStringFast(_PREHASH_MoneyData, _PREHASH_StartDate, start_date);
std::string time_str = LLTrans::getString("GroupMoneyDate");
LLSD substitution;
// We don't do time zone corrections of the calculated number of seconds
// because we don't have a full time stamp, only a date.
substitution["datetime"] = LLDateUtil::secondsSinceEpochFromString("%A %b %d, %Y", start_date);
LLStringUtil::format (time_str, substitution);
if ( interval_days != mImplementationp->mIntervalLength ||
current_interval != mImplementationp->mCurrentInterval )
{
@ -1064,7 +1073,7 @@ void LLGroupMoneyDetailsTabEventHandler::processReply(LLMessageSystem* msg,
return;
}
std::string text = start_date;
std::string text = time_str;
text.append("\n\n");
S32 total_amount = 0;
@ -1203,7 +1212,15 @@ void LLGroupMoneySalesTabEventHandler::processReply(LLMessageSystem* msg,
// Start with the date.
if (text == mImplementationp->mLoadingText)
{
text = start_date + "\n\n";
std::string time_str = LLTrans::getString("GroupMoneyDate");
LLSD substitution;
// We don't do time zone corrections of the calculated number of seconds
// because we don't have a full time stamp, only a date.
substitution["datetime"] = LLDateUtil::secondsSinceEpochFromString("%A %b %d, %Y", start_date);
LLStringUtil::format (time_str, substitution);
text = time_str + "\n\n";
}
S32 transactions = msg->getNumberOfBlocksFast(_PREHASH_HistoryData);
@ -1408,12 +1425,26 @@ void LLGroupMoneyPlanningTabEventHandler::processReply(LLMessageSystem* msg,
}
text.append(LLTrans::getString("SummaryForTheWeek"));
text.append(start_date);
std::string date_format_str = LLTrans::getString("GroupPlanningDate");
std::string time_str = date_format_str;
LLSD substitution;
// We don't do time zone corrections of the calculated number of seconds
// because we don't have a full time stamp, only a date.
substitution["datetime"] = LLDateUtil::secondsSinceEpochFromString("%m/%d/%Y", start_date);
LLStringUtil::format (time_str, substitution);
text.append(time_str);
if (current_interval == 0)
{
text.append(LLTrans::getString("NextStipendDay"));
text.append(next_stipend_date);
time_str = date_format_str;
substitution["datetime"] = LLDateUtil::secondsSinceEpochFromString("%m/%d/%Y", next_stipend_date);
LLStringUtil::format (time_str, substitution);
text.append(time_str);
text.append("\n\n");
text.append(llformat("%-24sL$%6d\n", LLTrans::getString("GroupMoneyBalance").c_str(), balance ));
text.append(1, '\n');

View File

@ -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);

View File

@ -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)

View File

@ -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)

View File

@ -44,6 +44,7 @@
#include "llbottomtray.h"
#include "llcompilequeue.h"
#include "llconsole.h"
#include "lldaycyclemanager.h"
#include "lldebugview.h"
#include "llenvmanager.h"
#include "llfilepicker.h"
@ -101,6 +102,7 @@
#include "llworldmap.h"
#include "pipeline.h"
#include "llviewerjoystick.h"
#include "llwaterparammanager.h"
#include "llwlanimator.h"
#include "llwlparammanager.h"
#include "llfloatercamera.h"
@ -7670,6 +7672,40 @@ class LLWorldEnvPreset : public view_listener_t
}
};
class LLWorldEnableEnvPreset : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
std::string item = userdata.asString();
if (item == "delete_water")
{
LLWaterParamManager::preset_name_list_t user_waters;
LLWaterParamManager::instance().getUserPresetNames(user_waters);
return !user_waters.empty();
}
else if (item == "delete_sky")
{
LLWLParamManager::preset_name_list_t user_skies;
LLWLParamManager::instance().getUserPresetNames(user_skies);
return !user_skies.empty();
}
else if (item == "delete_day_cycle")
{
LLDayCycleManager::preset_name_list_t user_days;
LLDayCycleManager::instance().getUserPresetNames(user_days);
return !user_days.empty();
}
else
{
llwarns << "Unknown item" << llendl;
}
return false;
}
};
/// Post-Process callbacks
class LLWorldPostProcess : public view_listener_t
{
@ -7909,6 +7945,7 @@ void initialize_menus()
view_listener_t::addMenu(new LLWorldEnvSettings(), "World.EnvSettings");
view_listener_t::addMenu(new LLWorldEnvPreset(), "World.EnvPreset");
view_listener_t::addMenu(new LLWorldEnableEnvPreset(), "World.EnableEnvPreset");
view_listener_t::addMenu(new LLWorldPostProcess(), "World.PostProcess");
view_listener_t::addMenu(new LLWorldToggleMovementControls(), "World.Toggle.MovementControls");

View File

@ -1343,18 +1343,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;
}
}
@ -1364,6 +1375,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();

View File

@ -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();
@ -1751,6 +1784,22 @@ BOOL LLViewerShaderMgr::loadShadersObject()
success = gObjectSimpleProgram.createShader(NULL, NULL);
}
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";
@ -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;

View File

@ -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;

View File

@ -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)
{

View File

@ -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();

View File

@ -2287,6 +2287,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();
{
@ -2361,6 +2366,11 @@ void LLViewerWindow::draw()
LLUI::popMatrix();
gGL.popMatrix();
if (LLGLSLShader::sNoFixedFunction)
{
gUIProgram.unbind();
}
//#if LL_DEBUG
LLView::sIsDrawing = FALSE;
//#endif

View File

@ -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())

View File

@ -51,6 +51,7 @@
#include "llspatialpartition.h"
#include "llnotificationsutil.h"
#include "raytrace.h"
#include "llglslshader.h"
extern LLPipeline gPipeline;

View File

@ -3746,6 +3746,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;
@ -4364,6 +4369,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);
@ -4378,35 +4385,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() &&
@ -4716,6 +4719,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;

View File

@ -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;
}

View File

@ -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)
{

View File

@ -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() :
@ -585,19 +585,62 @@ void LLPipeline::allocatePhysicsBuffer()
}
void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
{
U32 samples = gGLManager.getNumFBOFSAASamples(gSavedSettings.getU32("RenderFSAASamples"));
if (gGLManager.mIsATI)
{ //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;
//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
samples = 0;
}
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
@ -6392,30 +6478,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)
@ -6428,6 +6523,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);
@ -6451,6 +6551,12 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
gGL.end();
gGL.flush();
if (LLGLSLShader::sNoFixedFunction)
{
gUIProgram.unbind();
}
}
glMatrixMode(GL_PROJECTION);
@ -7866,7 +7972,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
@ -8006,8 +8112,6 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
LLViewerCamera::getInstance()->setUserClipPlane(npnorm);
LLGLState::checkStates();
LLGLState::checkTextureChannels();
LLGLState::checkClientArrays();
if (!skip_avatar_update)
{
@ -8140,6 +8244,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();
@ -8148,6 +8256,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)

View File

@ -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);

View File

@ -38,6 +38,7 @@
user_resize="false"
width="630">
<web_browser
tab_stop="true"
trusted_content="true"
follows="left|right|top|bottom"
layout="topleft"

View File

@ -557,6 +557,9 @@
<menu_item_call.on_click
function="World.EnvPreset"
parameter="delete_water"/>
<menu_item_call.on_enable
function="World.EnableEnvPreset"
parameter="delete_water"/>
</menu_item_call>
</menu>
@ -583,6 +586,9 @@
<menu_item_call.on_click
function="World.EnvPreset"
parameter="delete_sky"/>
<menu_item_call.on_enable
function="World.EnableEnvPreset"
parameter="delete_sky"/>
</menu_item_call>
</menu>
@ -609,6 +615,9 @@
<menu_item_call.on_click
function="World.EnvPreset"
parameter="delete_day_cycle"/>
<menu_item_call.on_enable
function="World.EnableEnvPreset"
parameter="delete_day_cycle"/>
</menu_item_call>
</menu>
</menu>

View File

@ -2240,6 +2240,7 @@ Returns a string with the requested data about the region
<string name="Unknown">(Unknown)</string>
<string name="SummaryForTheWeek" value="Summary for this week, beginning on " />
<string name="NextStipendDay" value="The next stipend day is " />
<string name="GroupPlanningDate">[mthnum,datetime,utc]/[day,datetime,utc]/[year,datetime,utc]</string>
<string name="GroupIndividualShare" value=" Group Individual Share" />
<string name="GroupColumn" value=" Group" />
<string name="Balance">Balance</string>
@ -2396,6 +2397,7 @@ Returns a string with the requested data about the region
<string name="GroupMoneyBalance">Balance</string>
<string name="GroupMoneyCredits">Credits</string>
<string name="GroupMoneyDebits">Debits</string>
<string name="GroupMoneyDate">[weekday,datetime,utc] [mth,datetime,utc] [day,datetime,utc], [year,datetime,utc]</string>
<!-- viewer object -->
<string name="ViewerObjectContents">Contents</string>

View File

@ -0,0 +1,41 @@
# HG changeset patch
# User Dave Parks <davep@lindenlab.com>
# Date 1308673064 18000
# Node ID 95c5639a3f80920e8dc54703d894517dd7694edf
# Parent 6af10678de4736222b2c3f7e010e984fb5b327de
SH-208 Disable VBO on all intel graphics chips (stability improvement).
diff -r 6af10678de47 -r 95c5639a3f80 indra/newview/featuretable.txt
--- a/indra/newview/featuretable.txt Mon Jun 20 16:42:31 2011 -0700
+++ b/indra/newview/featuretable.txt Tue Jun 21 11:17:44 2011 -0500
@@ -1,4 +1,4 @@
-version 29
+version 30
// NOTE: This is mostly identical to featuretable_mac.txt with a few differences
// Should be combined into one table
@@ -297,6 +297,7 @@
list Intel
RenderAnisotropic 1 0
+RenderVBOEnable 1 0
list GeForce2
RenderAnisotropic 1 0
diff -r 6af10678de47 -r 95c5639a3f80 indra/newview/featuretable_xp.txt
--- a/indra/newview/featuretable_xp.txt Mon Jun 20 16:42:31 2011 -0700
+++ b/indra/newview/featuretable_xp.txt Tue Jun 21 11:17:44 2011 -0500
@@ -1,4 +1,4 @@
-version 29
+version 30
// NOTE: This is mostly identical to featuretable_mac.txt with a few differences
// Should be combined into one table
@@ -295,6 +295,7 @@
list Intel
RenderAnisotropic 1 0
+RenderVBOEnable 1 0
list GeForce2
RenderAnisotropic 1 0