llrender and lldir merge. Removed duplicate assets from skins. cleaned up skin textures.xml files to only include changes from default.

This commit is contained in:
Shyotl
2016-04-11 02:51:08 -05:00
parent d40256fb31
commit be5d2f20bc
1280 changed files with 2354 additions and 10692 deletions

View File

@@ -104,7 +104,6 @@ LLFontGlyphInfo::LLFontGlyphInfo(U32 index)
LLFontFreetype::LLFontFreetype()
: mFontBitmapCachep(new LLFontBitmapCache),
mValid(FALSE),
mAscender(0.f),
mDescender(0.f),
mLineHeight(0.f),
@@ -112,6 +111,7 @@ LLFontFreetype::LLFontFreetype()
mFTFace(NULL),
mRenderGlyphCount(0),
mAddGlyphCount(0),
mStyle(0),
mPointSize(0)
{
}
@@ -204,6 +204,19 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, const F32 point_size,
mName = filename;
mPointSize = point_size;
mStyle = LLFontGL::NORMAL;
if(mFTFace->style_flags & FT_STYLE_FLAG_BOLD)
{
mStyle |= LLFontGL::BOLD;
mStyle &= ~LLFontGL::NORMAL;
}
if(mFTFace->style_flags & FT_STYLE_FLAG_ITALIC)
{
mStyle |= LLFontGL::ITALIC;
mStyle &= ~LLFontGL::NORMAL;
}
return TRUE;
}
@@ -536,6 +549,15 @@ const LLPointer<LLFontBitmapCache> LLFontFreetype::getFontBitmapCache() const
return mFontBitmapCachep;
}
void LLFontFreetype::setStyle(U8 style)
{
mStyle = style;
}
U8 LLFontFreetype::getStyle() const
{
return mStyle;
}
void LLFontFreetype::setSubImageLuminanceAlpha(const U32 x, const U32 y, const U32 bitmap_num, const U32 width, const U32 height, const U8 *data, S32 stride) const
{
LLImageRaw *image_raw = mFontBitmapCachep->getImageRaw(bitmap_num);

View File

@@ -93,8 +93,6 @@ public:
void setFallbackFonts(const font_vector_t &font);
const font_vector_t &getFallbackFonts() const;
void setCharToGlyphMap(llwchar wch, U32 glyph_index) const;
// Global font metrics - in units of pixels
F32 getLineHeight() const;
F32 getAscenderHeight() const;
@@ -140,6 +138,9 @@ public:
const std::string& getName() const;
const LLPointer<LLFontBitmapCache> getFontBitmapCache() const;
void setStyle(U8 style);
U8 getStyle() const;
static bool sOpenGLcrashOnRestart;
@@ -154,6 +155,8 @@ private:
std::string mName;
U8 mStyle;
F32 mPointSize;
F32 mAscender;
F32 mDescender;
@@ -164,8 +167,6 @@ private:
BOOL mIsFallback;
font_vector_t mFallbackFonts; // A list of fallback fonts to look for glyphs in (for Unicode chars)
BOOL mValid;
typedef boost::unordered_map<llwchar, LLFontGlyphInfo*> char_glyph_info_map_t;
mutable char_glyph_info_map_t mCharGlyphInfoMap; // Information about glyph location in bitmap

View File

@@ -36,6 +36,7 @@
#include "llfontregistry.h"
#include "llgl.h"
#include "llrender.h"
#include "lltexture.h"
#include "v4color.h"
#include "llstl.h"
#include "llfasttimer.h"
@@ -69,20 +70,6 @@ const F32 PIXEL_CORRECTION_DISTANCE = 0.01f;
const F32 PAD_UVY = 0.5f; // half of vertical padding between glyphs in the glyph texture
const F32 DROP_SHADOW_SOFT_STRENGTH = 0.3f;
F32 llfont_round_x(F32 x)
{
//return llfloor((x-LLFontGL::sCurOrigin.mX)/LLFontGL::sScaleX+0.5f)*LLFontGL::sScaleX+LLFontGL::sCurOrigin.mX;
//return llfloor(x/LLFontGL::sScaleX+0.5f)*LLFontGL::sScaleY;
return x;
}
F32 llfont_round_y(F32 y)
{
//return llfloor((y-LLFontGL::sCurOrigin.mY)/LLFontGL::sScaleY+0.5f)*LLFontGL::sScaleY+LLFontGL::sCurOrigin.mY;
//return llfloor(y+0.5f);
return y;
}
LLFontGL::LLFontGL()
{
clearEmbeddedChars();
@@ -166,8 +153,9 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
S32 scaled_max_pixels = max_pixels == S32_MAX ? S32_MAX : llceil((F32)max_pixels * sScaleX);
// Strip off any style bits that are already accounted for by the font.
style = style & (~getFontDesc().getStyle());
// determine which style flags need to be added programmatically by stripping off the
// style bits that are drawn by the underlying Freetype font
U8 style_to_add = (style | mFontDescriptor.getStyle()) & ~mFontFreetype->getStyle();
F32 drop_shadow_strength = 0.f;
if (shadow != NO_SHADOW)
@@ -412,7 +400,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
glyph_count = 0;
}
drawGlyph(glyph_count, vertices, uvs, colors, screen_rect, uv_rect, text_color, style, shadow, drop_shadow_strength);
drawGlyph(glyph_count, vertices, uvs, colors, screen_rect, uv_rect, text_color, style_to_add, shadow, drop_shadow_strength);
chars_drawn++;
cur_x += fgi->mXAdvance;
@@ -453,7 +441,8 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
*right_x = (cur_x - origin.mV[VX]) / sScaleX;
}
if (style & UNDERLINE)
//FIXME: add underline as glyph?
if (style_to_add & UNDERLINE)
{
F32 descender = (F32)llfloor(mFontFreetype->getDescenderHeight());
@@ -475,7 +464,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
(cur_x - origin.mV[VX]) / sScaleX, (F32)y,
color,
LEFT, valign,
style,
style_to_add,
shadow,
S32_MAX, max_pixels,
right_x,
@@ -940,7 +929,7 @@ void LLFontGL::removeEmbeddedChar( llwchar wc ) const
}
// static
void LLFontGL::initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::string& app_dir, const std::vector<std::string>& xui_paths, bool create_gl_textures)
void LLFontGL::initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::string& app_dir, bool create_gl_textures)
{
sVertDPI = (F32)llfloor(screen_dpi * y_scale);
sHorizDPI = (F32)llfloor(screen_dpi * x_scale);
@@ -951,7 +940,7 @@ void LLFontGL::initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::st
// Font registry init
if (!sFontRegistry)
{
sFontRegistry = new LLFontRegistry(xui_paths,create_gl_textures);
sFontRegistry = new LLFontRegistry(create_gl_textures);
sFontRegistry->parseFontInfo("fonts.xml");
}
else

View File

@@ -30,7 +30,7 @@
#include "llcoord.h"
#include "llfontregistry.h"
#include "lltexture.h"
#include "llimagegl.h"
#include "llpointer.h"
#include "llrect.h"
#include "v2math.h"
@@ -152,7 +152,7 @@ public:
void addEmbeddedChar( llwchar wc, LLTexture* image, const LLWString& label) const;
void removeEmbeddedChar( llwchar wc ) const;
static void initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::string& app_dir, const std::vector<std::string>& xui_paths, bool create_gl_textures = true);
static void initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::string& app_dir, bool create_gl_textures = true);
// Load sans-serif, sans-serif-small, etc.
// Slow, requires multiple seconds to load fonts.

View File

@@ -34,13 +34,15 @@
#include "llcontrol.h"
#include "lldir.h"
#include "llwindow.h"
#include "llxmlnode.h"
extern LLControlGroup gSavedSettings;
using std::string;
using std::map;
bool fontDescInitFromXML(LLXMLNodePtr node, LLFontDescriptor& desc);
bool font_desc_init_from_xml(LLXMLNodePtr node, LLFontDescriptor& desc);
bool init_from_xml(LLFontRegistry* registry, LLXMLNodePtr node);
LLFontDescriptor::LLFontDescriptor():
mStyle(0)
@@ -163,14 +165,9 @@ LLFontDescriptor LLFontDescriptor::normalize() const
return LLFontDescriptor(new_name,new_size,new_style,getFileNames());
}
LLFontRegistry::LLFontRegistry(const string_vec_t& xui_paths,
bool create_gl_textures)
LLFontRegistry::LLFontRegistry(bool create_gl_textures)
: mCreateGLTextures(create_gl_textures)
{
// Propagate this down from LLUICtrlFactory so LLRender doesn't
// need an upstream dependency on LLUI.
mXUIPaths = xui_paths;
// This is potentially a slow directory traversal, so we want to
// cache the result.
mUltimateFallbackList = LLWindow::getDynamicFallbackFontList();
@@ -183,23 +180,27 @@ LLFontRegistry::~LLFontRegistry()
bool LLFontRegistry::parseFontInfo(const std::string& xml_filename)
{
bool success = false; // Succeed if we find at least one XUI file
const string_vec_t& xml_paths = mXUIPaths;
bool success = false; // Succeed if we find and read at least one XUI file
const string_vec_t xml_paths = gDirUtilp->findSkinnedFilenames(LLDir::XUI, xml_filename);
if (xml_paths.empty())
{
// We didn't even find one single XUI file
return false;
}
for (string_vec_t::const_iterator path_it = xml_paths.begin();
path_it != xml_paths.end();
++path_it)
{
LLXMLNodePtr root;
std::string full_filename = gDirUtilp->findSkinnedFilename(*path_it, xml_filename);
bool parsed_file = LLXMLNode::parseFile(full_filename, root, NULL);
bool parsed_file = LLXMLNode::parseFile(*path_it, root, NULL);
if (!parsed_file)
continue;
if ( root.isNull() || ! root->hasName( "fonts" ) )
{
LL_WARNS() << "Bad font info file: "
<< full_filename << LL_ENDL;
LL_WARNS() << "Bad font info file: " << *path_it << LL_ENDL;
continue;
}
@@ -208,12 +209,12 @@ bool LLFontRegistry::parseFontInfo(const std::string& xml_filename)
if (root->hasName("fonts"))
{
// Expect a collection of children consisting of "font" or "font_size" entries
bool init_succ = initFromXML(root);
bool init_succ = init_from_xml(this, root);
success = success || init_succ;
}
}
if (success)
dump();
//if (success)
// dump();
return success;
}
@@ -231,7 +232,7 @@ std::string currentOsName()
#endif
}
bool fontDescInitFromXML(LLXMLNodePtr node, LLFontDescriptor& desc)
bool font_desc_init_from_xml(LLXMLNodePtr node, LLFontDescriptor& desc)
{
if (node->hasName("font"))
{
@@ -264,14 +265,14 @@ bool fontDescInitFromXML(LLXMLNodePtr node, LLFontDescriptor& desc)
{
if (child_name == currentOsName())
{
fontDescInitFromXML(child, desc);
font_desc_init_from_xml(child, desc);
}
}
}
return true;
}
bool LLFontRegistry::initFromXML(LLXMLNodePtr node)
bool init_from_xml(LLFontRegistry* registry, LLXMLNodePtr node)
{
LLXMLNodePtr child;
@@ -282,17 +283,17 @@ bool LLFontRegistry::initFromXML(LLXMLNodePtr node)
if (child->hasName("font"))
{
LLFontDescriptor desc;
bool font_succ = fontDescInitFromXML(child, desc);
bool font_succ = font_desc_init_from_xml(child, desc);
LLFontDescriptor norm_desc = desc.normalize();
if (font_succ)
{
// if this is the first time we've seen this font name,
// create a new template map entry for it.
const LLFontDescriptor *match_desc = getMatchingFontDesc(desc);
const LLFontDescriptor *match_desc = registry->getMatchingFontDesc(desc);
if (match_desc == NULL)
{
// Create a new entry (with no corresponding font).
mFontMap[norm_desc] = NULL;
registry->mFontMap[norm_desc] = NULL;
}
// otherwise, find the existing entry and combine data.
else
@@ -307,8 +308,8 @@ bool LLFontRegistry::initFromXML(LLXMLNodePtr node)
desc.getFileNames().end());
LLFontDescriptor new_desc = *match_desc;
new_desc.getFileNames() = match_file_names;
mFontMap.erase(*match_desc);
mFontMap[new_desc] = NULL;
registry->mFontMap.erase(*match_desc);
registry->mFontMap[new_desc] = NULL;
}
}
}
@@ -319,7 +320,7 @@ bool LLFontRegistry::initFromXML(LLXMLNodePtr node)
if (child->getAttributeString("name",size_name) &&
child->getAttributeF32("size",size_value))
{
mFontSizes[size_name] = size_value;
registry->mFontSizes[size_name] = size_value;
}
}

View File

@@ -28,7 +28,7 @@
#ifndef LL_LLFONTREGISTRY_H
#define LL_LLFONTREGISTRY_H
#include "llxmlnode.h"
#include "llpointer.h"
class LLFontGL;
@@ -65,15 +65,14 @@ private:
class LLFontRegistry
{
public:
friend bool init_from_xml(LLFontRegistry*, LLPointer<class LLXMLNode>);
// create_gl_textures - set to false for test apps with no OpenGL window,
// such as llui_libtest
LLFontRegistry(const string_vec_t& xui_paths,
bool create_gl_textures);
LLFontRegistry(bool create_gl_textures);
~LLFontRegistry();
// Load standard font info from XML file(s).
bool parseFontInfo(const std::string& xml_filename);
bool initFromXML(LLXMLNodePtr node);
// Clear cached glyphs for all fonts.
void reset();
@@ -95,6 +94,7 @@ public:
const string_vec_t& getUltimateFallbackList() const;
private:
LLFontRegistry(const LLFontRegistry& other); // no-copy
LLFontGL *createFont(const LLFontDescriptor& desc);
typedef std::map<LLFontDescriptor,LLFontGL*> font_reg_map_t;
typedef std::map<std::string,F32> font_size_map_t;
@@ -105,7 +105,6 @@ private:
font_size_map_t mFontSizes;
string_vec_t mUltimateFallbackList;
string_vec_t mXUIPaths;
bool mCreateGLTextures;
};

View File

@@ -223,6 +223,7 @@ PFNGLENDQUERYARBPROC glEndQueryARB = NULL;
PFNGLGETQUERYIVARBPROC glGetQueryivARB = NULL;
PFNGLGETQUERYOBJECTIVARBPROC glGetQueryObjectivARB = NULL;
PFNGLGETQUERYOBJECTUIVARBPROC glGetQueryObjectuivARB = NULL;
PFNGLGETQUERYOBJECTUI64VEXTPROC glGetQueryObjectui64vEXT = NULL;
// GL_ARB_point_parameters
PFNGLPOINTPARAMETERFARBPROC glPointParameterfARB = NULL;
@@ -443,6 +444,7 @@ LLGLManager::LLGLManager() :
mHasCubeMap(FALSE),
mHasDebugOutput(FALSE),
mHasGpuShader5(FALSE),
mHasAdaptiveVsync(FALSE),
mHasTextureSwizzle(FALSE),
@@ -938,6 +940,9 @@ void LLGLManager::initExtensions()
mHasVertexShader = FALSE;
mHasFragmentShader = FALSE;
mHasTextureRectangle = FALSE;
#ifdef GL_ARB_gpu_shader5
mHasGpuShader5 = FALSE;
#endif
#else // LL_MESA_HEADLESS //important, gGLHExts.mSysExts is uninitialized until after glh_init_extensions is called
mHasMultitexture = glh_init_extensions("GL_ARB_multitexture");
mHasATIMemInfo = ExtensionExists("GL_ATI_meminfo", gGLHExts.mSysExts);
@@ -982,7 +987,9 @@ void LLGLManager::initExtensions()
&& (LLRender::sGLCoreProfile || ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts));
mHasFragmentShader = ExtensionExists("GL_ARB_fragment_shader", gGLHExts.mSysExts) && (LLRender::sGLCoreProfile || ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts));
#endif
#ifdef GL_ARB_gpu_shader5
mHasGpuShader5 = ExtensionExists("GL_ARB_gpu_shader5", gGLHExts.mSysExts);;
#endif
#if LL_WINDOWS
mHasAdaptiveVsync = ExtensionExists("WGL_EXT_swap_control_tear", gGLHExts.mSysExts);
#elif LL_LINUX
@@ -1262,6 +1269,9 @@ void LLGLManager::initExtensions()
glGetQueryObjectivARB = (PFNGLGETQUERYOBJECTIVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjectivARB");
glGetQueryObjectuivARB = (PFNGLGETQUERYOBJECTUIVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjectuivARB");
}
#if !LL_DARWIN
glGetQueryObjectui64vEXT = (PFNGLGETQUERYOBJECTUI64VEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjectui64vEXT");
#endif
if (mHasPointParameters)
{
LL_INFOS() << "initExtensions() PointParameters-related procs..." << LL_ENDL;

View File

@@ -112,7 +112,7 @@ public:
BOOL mHasARBEnvCombine;
BOOL mHasCubeMap;
BOOL mHasDebugOutput;
BOOL mHasGpuShader5;
BOOL mHasAdaptiveVsync;
BOOL mHasTextureSwizzle;

View File

@@ -620,6 +620,8 @@ extern PFNGLGETQUERYIVARBPROC glGetQueryivARB;
extern PFNGLGETQUERYOBJECTIVARBPROC glGetQueryObjectivARB;
extern PFNGLGETQUERYOBJECTUIVARBPROC glGetQueryObjectuivARB;
extern PFNGLGETQUERYOBJECTUI64VEXTPROC glGetQueryObjectui64vEXT;
// GL_ARB_point_parameters
extern PFNGLPOINTPARAMETERFARBPROC glPointParameterfARB;
extern PFNGLPOINTPARAMETERFVARBPROC glPointParameterfvARB;

View File

@@ -38,6 +38,11 @@
#include "OpenGL/OpenGL.h"
#endif
#ifdef LL_RELEASE_FOR_DOWNLOAD
#define UNIFORM_ERRS LL_WARNS_ONCE("Shader")
#else
#define UNIFORM_ERRS LL_ERRS("Shader")
#endif
// Lots of STL stuff in here, using namespace std to keep things more readable
using std::vector;
using std::pair;
@@ -48,6 +53,12 @@ GLhandleARB LLGLSLShader::sCurBoundShader = 0;
LLGLSLShader* LLGLSLShader::sCurBoundShaderPtr = NULL;
S32 LLGLSLShader::sIndexedTextureChannels = 0;
bool LLGLSLShader::sNoFixedFunction = false;
bool LLGLSLShader::sProfileEnabled = false;
std::set<LLGLSLShader*> LLGLSLShader::sInstances;
U64 LLGLSLShader::sTotalTimeElapsed = 0;
U32 LLGLSLShader::sTotalTrianglesDrawn = 0;
U64 LLGLSLShader::sTotalSamplesDrawn = 0;
U32 LLGLSLShader::sTotalDrawCalls = 0;
//UI shader -- declared here so llui_libtest will link properly
//Singu note: Not using llui_libtest... and LLViewerShaderMgr is a part of newview. So,
@@ -77,13 +88,221 @@ LLShaderFeatures::LLShaderFeatures()
, hasGamma(false)
, mIndexedTextureChannels(0)
, disableTextureIndex(false)
, hasAlphaMask(false)
, hasAlphaMask(false)
, attachNothing(false)
{
}
//===============================
// LLGLSL Shader implementation
//===============================
//static
void LLGLSLShader::initProfile()
{
sProfileEnabled = true;
sTotalTimeElapsed = 0;
sTotalTrianglesDrawn = 0;
sTotalSamplesDrawn = 0;
sTotalDrawCalls = 0;
for (std::set<LLGLSLShader*>::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter)
{
(*iter)->clearStats();
}
}
struct LLGLSLShaderCompareTimeElapsed
{
bool operator()(const LLGLSLShader* const& lhs, const LLGLSLShader* const& rhs)
{
return lhs->mTimeElapsed < rhs->mTimeElapsed;
}
};
//static
void LLGLSLShader::finishProfile(bool emit_report)
{
sProfileEnabled = false;
if (emit_report)
{
std::vector<LLGLSLShader*> sorted;
for (std::set<LLGLSLShader*>::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter)
{
sorted.push_back(*iter);
}
std::sort(sorted.begin(), sorted.end(), LLGLSLShaderCompareTimeElapsed());
for (std::vector<LLGLSLShader*>::iterator iter = sorted.begin(); iter != sorted.end(); ++iter)
{
(*iter)->dumpStats();
}
LL_INFOS() << "-----------------------------------" << LL_ENDL;
LL_INFOS() << "Total rendering time: " << llformat("%.4f ms", sTotalTimeElapsed/1000000.f) << LL_ENDL;
LL_INFOS() << "Total samples drawn: " << llformat("%.4f million", sTotalSamplesDrawn/1000000.f) << LL_ENDL;
LL_INFOS() << "Total triangles drawn: " << llformat("%.3f million", sTotalTrianglesDrawn/1000000.f) << LL_ENDL;
}
}
void LLGLSLShader::clearStats()
{
mTrianglesDrawn = 0;
mTimeElapsed = 0;
mSamplesDrawn = 0;
mDrawCalls = 0;
mTextureStateFetched = false;
mTextureMagFilter.clear();
mTextureMinFilter.clear();
}
void LLGLSLShader::dumpStats()
{
if (mDrawCalls > 0)
{
LL_INFOS() << "=============================================" << LL_ENDL;
LL_INFOS() << mName << LL_ENDL;
for (U32 i = 0; i < mShaderFiles.size(); ++i)
{
LL_INFOS() << mShaderFiles[i].first << LL_ENDL;
}
for (U32 i = 0; i < mTexture.size(); ++i)
{
GLint idx = mTexture[i];
if (idx >= 0)
{
GLint uniform_idx = getUniformLocation(i);
LL_INFOS() << mUniformNameMap[uniform_idx] << " - " << std::hex << mTextureMagFilter[i] << "/" << mTextureMinFilter[i] << std::dec << LL_ENDL;
}
}
LL_INFOS() << "=============================================" << LL_ENDL;
F32 ms = mTimeElapsed/1000000.f;
F32 seconds = ms/1000.f;
F32 pct_tris = (F32) mTrianglesDrawn/(F32)sTotalTrianglesDrawn*100.f;
F32 tris_sec = (F32) (mTrianglesDrawn/1000000.0);
tris_sec /= seconds;
F32 pct_samples = (F32) ((F64)mSamplesDrawn/(F64)sTotalSamplesDrawn)*100.f;
F32 samples_sec = (F32) mSamplesDrawn/1000000000.0;
samples_sec /= seconds;
F32 pct_calls = (F32) mDrawCalls/(F32)sTotalDrawCalls*100.f;
U32 avg_batch = mTrianglesDrawn/mDrawCalls;
LL_INFOS() << "Triangles Drawn: " << mTrianglesDrawn << " " << llformat("(%.2f pct of total, %.3f million/sec)", pct_tris, tris_sec ) << LL_ENDL;
LL_INFOS() << "Draw Calls: " << mDrawCalls << " " << llformat("(%.2f pct of total, avg %d tris/call)", pct_calls, avg_batch) << LL_ENDL;
LL_INFOS() << "SamplesDrawn: " << mSamplesDrawn << " " << llformat("(%.2f pct of total, %.3f billion/sec)", pct_samples, samples_sec) << LL_ENDL;
LL_INFOS() << "Time Elapsed: " << mTimeElapsed << " " << llformat("(%.2f pct of total, %.5f ms)\n", (F32) ((F64)mTimeElapsed/(F64)sTotalTimeElapsed)*100.f, ms) << LL_ENDL;
}
}
//static
void LLGLSLShader::startProfile()
{
if (sProfileEnabled && sCurBoundShaderPtr)
{
sCurBoundShaderPtr->placeProfileQuery();
}
}
//static
void LLGLSLShader::stopProfile(U32 count, U32 mode)
{
if (sProfileEnabled && sCurBoundShaderPtr)
{
sCurBoundShaderPtr->readProfileQuery(count, mode);
}
}
void LLGLSLShader::placeProfileQuery()
{
#if !LL_DARWIN
if (mTimerQuery == 0)
{
glGenQueriesARB(1, &mSamplesQuery);
glGenQueriesARB(1, &mTimerQuery);
}
if (!mTextureStateFetched)
{
mTextureStateFetched = true;
mTextureMagFilter.resize(mTexture.size());
mTextureMinFilter.resize(mTexture.size());
U32 cur_active = gGL.getCurrentTexUnitIndex();
for (U32 i = 0; i < mTexture.size(); ++i)
{
GLint idx = mTexture[i];
if (idx >= 0)
{
gGL.getTexUnit(idx)->activate();
U32 mag = 0xFFFFFFFF;
U32 min = 0xFFFFFFFF;
U32 type = LLTexUnit::getInternalType(gGL.getTexUnit(idx)->getCurrType());
glGetTexParameteriv(type, GL_TEXTURE_MAG_FILTER, (GLint*) &mag);
glGetTexParameteriv(type, GL_TEXTURE_MIN_FILTER, (GLint*) &min);
mTextureMagFilter[i] = mag;
mTextureMinFilter[i] = min;
}
}
gGL.getTexUnit(cur_active)->activate();
}
glBeginQueryARB(GL_SAMPLES_PASSED, mSamplesQuery);
glBeginQueryARB(GL_TIME_ELAPSED, mTimerQuery);
#endif
}
void LLGLSLShader::readProfileQuery(U32 count, U32 mode)
{
#if !LL_DARWIN
glEndQueryARB(GL_TIME_ELAPSED);
glEndQueryARB(GL_SAMPLES_PASSED);
GLuint64 time_elapsed = 0;
glGetQueryObjectui64vEXT(mTimerQuery, GL_QUERY_RESULT, &time_elapsed);
GLuint64 samples_passed = 0;
glGetQueryObjectui64vEXT(mSamplesQuery, GL_QUERY_RESULT, &samples_passed);
sTotalTimeElapsed += time_elapsed;
mTimeElapsed += time_elapsed;
sTotalSamplesDrawn += samples_passed;
mSamplesDrawn += samples_passed;
U32 tri_count = 0;
switch (mode)
{
case LLRender::TRIANGLES: tri_count = count/3; break;
case LLRender::TRIANGLE_FAN: tri_count = count-2; break;
case LLRender::TRIANGLE_STRIP: tri_count = count-2; break;
default: tri_count = count; break; //points lines etc just use primitive count
}
mTrianglesDrawn += tri_count;
sTotalTrianglesDrawn += tri_count;
sTotalDrawCalls++;
mDrawCalls++;
#endif
}
LLGLSLShader::LLGLSLShader(S32 shader_class)
: mProgramObject(0),
mShaderClass(shader_class),
@@ -91,20 +310,25 @@ LLGLSLShader::LLGLSLShader(S32 shader_class)
mTotalUniformSize(0),
mActiveTextureChannels(0),
mShaderLevel(0),
mShaderGroup(SG_DEFAULT),
mUniformsDirty(FALSE)
mShaderGroup(SG_DEFAULT),
mUniformsDirty(FALSE),
mTimerQuery(0),
mSamplesQuery(0)
{
LLShaderMgr::getGlobalShaderList().push_back(this);
}
LLGLSLShader::~LLGLSLShader()
{
{
}
void LLGLSLShader::unload()
{
stop_glerror();
mAttribute.clear();
sInstances.erase(this);
stop_glerror();
mAttribute.clear();
mTexture.clear();
mUniform.clear();
mShaderFiles.clear();
@@ -126,10 +350,22 @@ void LLGLSLShader::unload()
glDeleteObjectARB(mProgramObject);
mProgramObject = 0;
}
//hack to make apple not complain
glGetError();
if (mTimerQuery)
{
glDeleteQueriesARB(1, &mTimerQuery);
mTimerQuery = 0;
}
if (mSamplesQuery)
{
glDeleteQueriesARB(1, &mSamplesQuery);
mSamplesQuery = 0;
}
//hack to make apple not complain
glGetError();
stop_glerror();
}
@@ -138,9 +374,11 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes,
U32 varying_count,
const char** varyings)
{
//reloading, reset matrix hash values
for (U32 i = 0; i < LLRender::NUM_MATRIX_MODES; ++i)
{
sInstances.insert(this);
//reloading, reset matrix hash values
for (U32 i = 0; i < LLRender::NUM_MATRIX_MODES; ++i)
{
mMatHash[i] = 0xFFFFFFFF;
}
mLightHash = 0xFFFFFFFF;
@@ -243,9 +481,18 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes,
}
}
unbind();
}
}
return success;
if (LLShaderMgr::instance()->mProgramObjects.find(mName) == LLShaderMgr::instance()->mProgramObjects.end())
{
LLShaderMgr::instance()->mProgramObjects.emplace(mName, mProgramObject);
}
else
{
LL_WARNS("ShaderLoading") << "Attempting to create shader program with duplicate name: " << mName << LL_ENDL;
}
return success;
}
BOOL LLGLSLShader::attachObject(std::string object)
@@ -425,6 +672,7 @@ void LLGLSLShader::mapUniform(GLint index, const vector<LLStaticHashedString> *
}
LLStaticHashedString hashedName(name);
mUniformNameMap[location] = name;
mUniformMap[hashedName] = location;
LL_DEBUGS("ShaderLoading") << "Uniform " << name << " is at location " << location << LL_ENDL;
@@ -489,6 +737,7 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
mActiveTextureChannels = 0;
mUniform.clear();
mUniformMap.clear();
mUniformNameMap.clear();
mTexture.clear();
mValueVec4.clear();
mValueMat3.clear();

View File

@@ -56,6 +56,7 @@ public:
S32 mIndexedTextureChannels;
bool disableTextureIndex;
bool hasAlphaMask;
bool attachNothing;
// char numLights;
@@ -73,6 +74,9 @@ public:
SG_WATER
};
static std::set<LLGLSLShader*> sInstances;
static bool sProfileEnabled;
LLGLSLShader(S32 shader_class);
~LLGLSLShader();
@@ -81,7 +85,18 @@ public:
static S32 sIndexedTextureChannels;
static bool sNoFixedFunction;
static void initProfile();
static void finishProfile(bool emit_report = true);
static void startProfile();
static void stopProfile(U32 count, U32 mode);
void unload();
void clearStats();
void dumpStats();
void placeProfileQuery();
void readProfileQuery(U32 count, U32 mode);
BOOL createShader(std::vector<LLStaticHashedString> * attributes,
std::vector<LLStaticHashedString> * uniforms,
U32 varying_count = 0,
@@ -379,6 +394,7 @@ public:
U32 mAttributeMask; //mask of which reserved attributes are set (lines up with LLVertexBuffer::getTypeMask())
std::vector<GLint> mUniform; //lookup table of uniform enum to uniform location
LLStaticStringTable<GLint> mUniformMap; //lookup map of uniform name to uniform location
std::map<GLint, std::string> mUniformNameMap; //lookup map of uniform location to uniform name
//There are less naive ways to do this than just having several vectors for the differing types, but this method is of least complexity and has some inherent type-safety.
std::vector<std::pair<GLint, LLVector4> > mValueVec4; //lookup map of uniform location to last known value
std::vector<std::pair<GLint, LLMatrix3> > mValueMat3; //lookup map of uniform location to last known value
@@ -395,6 +411,23 @@ public:
std::vector< std::pair< std::string, GLenum > > mShaderFiles;
std::string mName;
std::map<std::string, std::string> mDefines;
//statistcis for profiling shader performance
U32 mTimerQuery;
U32 mSamplesQuery;
U64 mTimeElapsed;
static U64 sTotalTimeElapsed;
U32 mTrianglesDrawn;
static U32 sTotalTrianglesDrawn;
U64 mSamplesDrawn;
static U64 sTotalSamplesDrawn;
U32 mDrawCalls;
static U32 sTotalDrawCalls;
bool mTextureStateFetched;
std::vector<U32> mTextureMagFilter;
std::vector<U32> mTextureMinFilter;
};
//UI shader (declared here so llui_libtest will link properly)

View File

@@ -2204,26 +2204,10 @@ void LLImageGL::analyzeAlpha(const void* data_in, U32 w, U32 h)
}
//----------------------------------------------------------------------------
void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in)
U32 LLImageGL::createPickMask(S32 pWidth, S32 pHeight)
{
if(!mNeedsAlphaAndPickMask)
{
return ;
}
delete [] mPickMask;
mPickMask = NULL;
mPickMaskWidth = mPickMaskHeight = 0;
if (mFormatType != GL_UNSIGNED_BYTE ||
mFormatPrimary != GL_RGBA)
{
//cannot generate a pick mask for this texture
return;
}
U32 pick_width = width/2 + 1;
U32 pick_height = height/2 + 1;
U32 pick_width = pWidth/2 + 1;
U32 pick_height = pHeight/2 + 1;
U32 size = pick_width * pick_height;
size = (size + 7) / 8; // pixelcount-to-bits
@@ -2233,6 +2217,44 @@ void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in)
memset(mPickMask, 0, sizeof(U8) * size);
return size;
}
//----------------------------------------------------------------------------
void LLImageGL::freePickMask()
{
// pickmask validity depends on old image size, delete it
if (mPickMask != NULL)
{
delete [] mPickMask;
}
mPickMask = NULL;
mPickMaskWidth = mPickMaskHeight = 0;
}
//----------------------------------------------------------------------------
void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in)
{
if(!mNeedsAlphaAndPickMask)
{
return ;
}
freePickMask();
if (mFormatType != GL_UNSIGNED_BYTE ||
mFormatPrimary != GL_RGBA)
{
//cannot generate a pick mask for this texture
return;
}
#ifdef SHOW_ASSERT
const U32 pickSize = createPickMask(width, height);
#else // SHOW_ASSERT
createPickMask(width, height);
#endif // SHOW_ASSERT
U32 pick_bit = 0;
for (S32 y = 0; y < height; y += 2)
@@ -2245,7 +2267,7 @@ void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in)
{
U32 pick_idx = pick_bit/8;
U32 pick_offset = pick_bit%8;
llassert(pick_idx < size);
llassert(pick_idx < pickSize);
mPickMask[pick_idx] |= 1 << pick_offset;
}

View File

@@ -177,6 +177,9 @@ public:
mutable F32 mLastBindTime; // last time this was bound, by discard level
private:
U32 createPickMask(S32 pWidth, S32 pHeight);
void freePickMask();
LLPointer<LLImageRaw> mSaveData; // used for destroyGL/restoreGL
S32 mSaveDiscardLevel;
U8* mPickMask; //downsampled bitmap approximation of alpha channel. NULL if no alpha channel

View File

@@ -56,7 +56,7 @@ bool LLRender::sGLCoreProfile = false;
static const U32 LL_NUM_TEXTURE_LAYERS = 32;
static const U32 LL_NUM_LIGHT_UNITS = 8;
static GLenum sGLTextureType[] =
static const GLenum sGLTextureType[] =
{
GL_TEXTURE_2D,
GL_TEXTURE_RECTANGLE_ARB,
@@ -64,14 +64,14 @@ static GLenum sGLTextureType[] =
//,GL_TEXTURE_2D_MULTISAMPLE Don't use.
};
static GLint sGLAddressMode[] =
static const GLint sGLAddressMode[] =
{
GL_REPEAT,
GL_MIRRORED_REPEAT,
GL_CLAMP_TO_EDGE
};
static GLenum sGLCompareFunc[] =
static const GLenum sGLCompareFunc[] =
{
GL_NEVER,
GL_ALWAYS,
@@ -85,7 +85,7 @@ static GLenum sGLCompareFunc[] =
const U32 immediate_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXCOORD0;
static GLenum sGLBlendFactor[] =
static const GLenum sGLBlendFactor[] =
{
GL_ONE,
GL_ZERO,
@@ -102,15 +102,15 @@ static GLenum sGLBlendFactor[] =
};
LLTexUnit::LLTexUnit(S32 index)
: mCurrTexType(TT_NONE), mCurrBlendType(TB_MULT),
mCurrColorOp(TBO_MULT), mCurrAlphaOp(TBO_MULT),
mCurrColorSrc1(TBS_TEX_COLOR), mCurrColorSrc2(TBS_PREV_COLOR),
mCurrAlphaSrc1(TBS_TEX_ALPHA), mCurrAlphaSrc2(TBS_PREV_ALPHA),
mCurrColorScale(1), mCurrAlphaScale(1), mCurrTexture(0),
mHasMipMaps(false)
: mCurrTexType(TT_NONE), mCurrBlendType(TB_MULT),
mCurrColorOp(TBO_MULT), mCurrAlphaOp(TBO_MULT),
mCurrColorSrc1(TBS_TEX_COLOR), mCurrColorSrc2(TBS_PREV_COLOR),
mCurrAlphaSrc1(TBS_TEX_ALPHA), mCurrAlphaSrc2(TBS_PREV_ALPHA),
mCurrColorScale(1), mCurrAlphaScale(1), mCurrTexture(0),
mHasMipMaps(false),
mIndex(index)
{
llassert_always(index < (S32)LL_NUM_TEXTURE_LAYERS);
mIndex = index;
}
//static
@@ -228,53 +228,66 @@ void LLTexUnit::disable(void)
bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind)
{
stop_glerror();
if (mIndex < 0) return false;
LLImageGL* gl_tex = NULL ;
if (texture == NULL || !(gl_tex = texture->getGLTexture()))
if (mIndex >= 0)
{
LL_WARNS() << "NULL LLTexUnit::bind texture" << LL_ENDL;
gGL.flush();
LLImageGL* gl_tex = NULL ;
if (texture != NULL && (gl_tex = texture->getGLTexture()))
{
if (gl_tex->getTexName()) //if texture exists
{
//in audit, replace the selected texture by the default one.
if(gAuditTexture && for_rendering && LLImageGL::sCurTexPickSize > 0)
{
if(texture->getWidth() * texture->getHeight() == LLImageGL::sCurTexPickSize)
{
gl_tex->updateBindStats(gl_tex->mTextureMemory);
return bind(LLImageGL::sHighlightTexturep.get());
}
}
if ((mCurrTexture != gl_tex->getTexName()) || forceBind)
{
gGL.flush();
activate();
enable(gl_tex->getTarget());
mCurrTexture = gl_tex->getTexName();
glBindTexture(sGLTextureType[gl_tex->getTarget()], mCurrTexture);
if(gl_tex->updateBindStats(gl_tex->mTextureMemory))
{
texture->setActive() ;
texture->updateBindStatsForTester() ;
}
mHasMipMaps = gl_tex->mHasMipMaps;
if (gl_tex->mTexOptionsDirty)
{
gl_tex->mTexOptionsDirty = false;
setTextureAddressMode(gl_tex->mAddressMode);
setTextureFilteringOption(gl_tex->mFilterOption);
}
}
}
else
{
//if deleted, will re-generate it immediately
texture->forceImmediateUpdate() ;
gl_tex->forceUpdateBindStats() ;
return texture->bindDefaultImage(mIndex);
}
}
else
{
LL_WARNS() << "NULL LLTexUnit::bind texture" << LL_ENDL;
return false;
}
}
else
{ // mIndex < 0
return false;
}
if (!gl_tex->getTexName()) //if texture does not exist
{
//if deleted, will re-generate it immediately
texture->forceImmediateUpdate() ;
gl_tex->forceUpdateBindStats() ;
return texture->bindDefaultImage(mIndex);
}
//in audit, replace the selected texture by the default one.
if(gAuditTexture && for_rendering && LLImageGL::sCurTexPickSize > 0)
{
if(texture->getWidth() * texture->getHeight() == LLImageGL::sCurTexPickSize)
{
gl_tex->updateBindStats(gl_tex->mTextureMemory);
return bind(LLImageGL::sHighlightTexturep.get());
}
}
if ((mCurrTexture != gl_tex->getTexName()) || forceBind)
{
gGL.flush();
activate();
enable(gl_tex->getTarget());
mCurrTexture = gl_tex->getTexName();
glBindTexture(sGLTextureType[gl_tex->getTarget()], mCurrTexture);
if(gl_tex->updateBindStats(gl_tex->mTextureMemory))
{
texture->setActive() ;
texture->updateBindStatsForTester() ;
}
mHasMipMaps = gl_tex->mHasMipMaps;
if (gl_tex->mTexOptionsDirty)
{
gl_tex->mTexOptionsDirty = false;
setTextureAddressMode(gl_tex->mAddressMode);
setTextureFilteringOption(gl_tex->mFilterOption);
}
}
return true;
}
@@ -1763,7 +1776,7 @@ void LLRender::pushUIMatrix()
{
if (mUIOffset.empty())
{
mUIOffset.push_back(LLVector4a(0.f));
mUIOffset.emplace_back(LLVector4a(0.f));
}
else
{
@@ -1772,7 +1785,7 @@ void LLRender::pushUIMatrix()
if (mUIScale.empty())
{
mUIScale.push_back(LLVector4a(1.f));
mUIScale.emplace_back(LLVector4a(1.f));
}
else
{
@@ -1782,9 +1795,9 @@ void LLRender::pushUIMatrix()
void LLRender::popUIMatrix()
{
if (mUIOffset.empty())
if (mUIOffset.empty() || mUIScale.empty())
{
LL_ERRS() << "UI offset stack blown." << LL_ENDL;
LL_ERRS() << "UI offset or scale stack blown." << LL_ENDL;
}
mUIOffset.pop_back();
mUIScale.pop_back();

View File

@@ -38,12 +38,13 @@
#include "v3math.h"
#include "v4coloru.h"
#include "v4math.h"
#include "llmatrix4a.h"
#include "llalignedarray.h"
#include "llstrider.h"
#include "llpointer.h"
#include "llglheaders.h"
#include "llmatrix4a.h"
#include "llrect.h"
#include "llvector4a.h"
#include <boost/align/aligned_allocator.hpp>
class LLVertexBuffer;
class LLCubeMap;
@@ -200,7 +201,7 @@ public:
void setHasMipMaps(bool hasMips) { mHasMipMaps = hasMips; }
protected:
S32 mIndex;
const S32 mIndex;
U32 mCurrTexture;
eTextureType mCurrTexType;
eTextureBlendType mCurrBlendType;
@@ -493,8 +494,8 @@ private:
F32 mMaxAnisotropy;
LLAlignedArray<LLVector4a, 64> mUIOffset;
LLAlignedArray<LLVector4a, 64> mUIScale;
std::vector<LLVector4a, boost::alignment::aligned_allocator<LLVector4a, 64> > mUIOffset;
std::vector<LLVector4a, boost::alignment::aligned_allocator<LLVector4a, 64> > mUIScale;
} LL_ALIGN_POSTFIX(16);

View File

@@ -348,6 +348,11 @@ void gl_draw_image( S32 x, S32 y, LLTexture* image, const LLColor4& color, const
gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), 0.f, image, color, uv_rect );
}
void gl_draw_scaled_target(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* target, const LLColor4& color, const LLRectf& uv_rect)
{
gl_draw_scaled_rotated_image(x, y, width, height, 0.f, NULL, color, uv_rect, target);
}
void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect)
{
if (NULL == image)
@@ -358,7 +363,7 @@ void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image,
gl_draw_scaled_rotated_image( x, y, width, height, 0.f, image, color, uv_rect );
}
void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_rect)
void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_rect, bool scale_inner)
{
if (NULL == image)
{
@@ -371,10 +376,10 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border
F32 border_height_fraction = (F32)border_height / (F32)image->getHeight(0);
LLRectf scale_rect(border_width_fraction, 1.f - border_height_fraction, 1.f - border_width_fraction, border_height_fraction);
gl_draw_scaled_image_with_border(x, y, width, height, image, color, solid_color, uv_rect, scale_rect);
gl_draw_scaled_image_with_border(x, y, width, height, image, color, solid_color, uv_rect, scale_rect, scale_inner);
}
void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_outer_rect, const LLRectf& center_rect)
void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_outer_rect, const LLRectf& center_rect, bool scale_inner)
{
stop_glerror();
@@ -384,56 +389,6 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTex
return;
}
// add in offset of current image to current UI translation
const LLVector3 ui_scale = gGL.getUIScale();
const LLVector3 ui_translation = (gGL.getUITranslation() + LLVector3(x, y, 0.f)).scaledVec(ui_scale);
F32 uv_width = uv_outer_rect.getWidth();
F32 uv_height = uv_outer_rect.getHeight();
// shrink scaling region to be proportional to clipped image region
LLRectf uv_center_rect(
uv_outer_rect.mLeft + (center_rect.mLeft * uv_width),
uv_outer_rect.mBottom + (center_rect.mTop * uv_height),
uv_outer_rect.mLeft + (center_rect.mRight * uv_width),
uv_outer_rect.mBottom + (center_rect.mBottom * uv_height));
F32 image_width = image->getWidth(0);
F32 image_height = image->getHeight(0);
S32 image_natural_width = ll_round(image_width * uv_width);
S32 image_natural_height = ll_round(image_height * uv_height);
LLRectf draw_center_rect( uv_center_rect.mLeft * image_width,
uv_center_rect.mTop * image_height,
uv_center_rect.mRight * image_width,
uv_center_rect.mBottom * image_height);
{ // scale fixed region of image to drawn region
draw_center_rect.mRight += width - image_natural_width;
draw_center_rect.mTop += height - image_natural_height;
F32 border_shrink_width = llmax(0.f, draw_center_rect.mLeft - draw_center_rect.mRight);
F32 border_shrink_height = llmax(0.f, draw_center_rect.mBottom - draw_center_rect.mTop);
F32 shrink_width_ratio = center_rect.getWidth() == 1.f ? 0.f : border_shrink_width / ((F32)image_natural_width * (1.f - center_rect.getWidth()));
F32 shrink_height_ratio = center_rect.getHeight() == 1.f ? 0.f : border_shrink_height / ((F32)image_natural_height * (1.f - center_rect.getHeight()));
F32 shrink_scale = 1.f - llmax(shrink_width_ratio, shrink_height_ratio);
draw_center_rect.mLeft = ll_round(ui_translation.mV[VX] + (F32)draw_center_rect.mLeft * shrink_scale * ui_scale.mV[VX]);
draw_center_rect.mTop = ll_round(ui_translation.mV[VY] + lerp((F32)height, (F32)draw_center_rect.mTop, shrink_scale) * ui_scale.mV[VY]);
draw_center_rect.mRight = ll_round(ui_translation.mV[VX] + lerp((F32)width, (F32)draw_center_rect.mRight, shrink_scale) * ui_scale.mV[VX]);
draw_center_rect.mBottom = ll_round(ui_translation.mV[VY] + (F32)draw_center_rect.mBottom * shrink_scale * ui_scale.mV[VY]);
}
LLRectf draw_outer_rect(ui_translation.mV[VX],
ui_translation.mV[VY] + height * ui_scale.mV[VY],
ui_translation.mV[VX] + width * ui_scale.mV[VX],
ui_translation.mV[VY]);
LLGLSUIDefault gls_ui;
if (solid_color)
{
if (LLGLSLShader::sNoFixedFunction)
@@ -447,7 +402,79 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTex
}
}
gGL.getTexUnit(0)->bind(image, true);
if (center_rect.mLeft == 0.f
&& center_rect.mRight == 1.f
&& center_rect.mBottom == 0.f
&& center_rect.mTop == 1.f)
{
gl_draw_scaled_image(x, y, width, height, image, color, uv_outer_rect);
}
else
{
// add in offset of current image to current UI translation
const LLVector3 ui_scale = gGL.getUIScale();
const LLVector3 ui_translation = (gGL.getUITranslation() + LLVector3(x, y, 0.f)).scaledVec(ui_scale);
F32 uv_width = uv_outer_rect.getWidth();
F32 uv_height = uv_outer_rect.getHeight();
// shrink scaling region to be proportional to clipped image region
LLRectf uv_center_rect( uv_outer_rect.mLeft + (center_rect.mLeft * uv_width),
uv_outer_rect.mBottom + (center_rect.mTop * uv_height),
uv_outer_rect.mLeft + (center_rect.mRight * uv_width),
uv_outer_rect.mBottom + (center_rect.mBottom * uv_height));
F32 image_width = image->getWidth(0);
F32 image_height = image->getHeight(0);
S32 image_natural_width = ll_round(image_width * uv_width);
S32 image_natural_height = ll_round(image_height * uv_height);
LLRectf draw_center_rect( uv_center_rect.mLeft * image_width,
uv_center_rect.mTop * image_height,
uv_center_rect.mRight * image_width,
uv_center_rect.mBottom * image_height);
if (scale_inner)
{
// scale center region of image to drawn region
draw_center_rect.mRight += width - image_natural_width;
draw_center_rect.mTop += height - image_natural_height;
const F32 border_shrink_width = llmax(0.f, draw_center_rect.mLeft - draw_center_rect.mRight);
const F32 border_shrink_height = llmax(0.f, draw_center_rect.mBottom - draw_center_rect.mTop);
const F32 shrink_width_ratio = center_rect.getWidth() == 1.f ? 0.f : border_shrink_width / ((F32)image_natural_width * (1.f - center_rect.getWidth()));
const F32 shrink_height_ratio = center_rect.getHeight() == 1.f ? 0.f : border_shrink_height / ((F32)image_natural_height * (1.f - center_rect.getHeight()));
const F32 border_shrink_scale = 1.f - llmax(shrink_width_ratio, shrink_height_ratio);
draw_center_rect.mLeft *= border_shrink_scale;
draw_center_rect.mTop = lerp((F32)height, (F32)draw_center_rect.mTop, border_shrink_scale);
draw_center_rect.mRight = lerp((F32)width, (F32)draw_center_rect.mRight, border_shrink_scale);
draw_center_rect.mBottom *= border_shrink_scale;
}
else
{
// keep center region of image at fixed scale, but in same relative position
F32 scale_factor = llmin((F32)width / draw_center_rect.getWidth(), (F32)height / draw_center_rect.getHeight(), 1.f);
F32 scaled_width = draw_center_rect.getWidth() * scale_factor;
F32 scaled_height = draw_center_rect.getHeight() * scale_factor;
draw_center_rect.setCenterAndSize(uv_center_rect.getCenterX() * width, uv_center_rect.getCenterY() * height, scaled_width, scaled_height);
}
draw_center_rect.mLeft = ll_round(ui_translation.mV[VX] + (F32)draw_center_rect.mLeft * ui_scale.mV[VX]);
draw_center_rect.mTop = ll_round(ui_translation.mV[VY] + (F32)draw_center_rect.mTop * ui_scale.mV[VY]);
draw_center_rect.mRight = ll_round(ui_translation.mV[VX] + (F32)draw_center_rect.mRight * ui_scale.mV[VX]);
draw_center_rect.mBottom = ll_round(ui_translation.mV[VY] + (F32)draw_center_rect.mBottom * ui_scale.mV[VY]);
LLRectf draw_outer_rect(ui_translation.mV[VX],
ui_translation.mV[VY] + height * ui_scale.mV[VY],
ui_translation.mV[VX] + width * ui_scale.mV[VX],
ui_translation.mV[VY]);
LLGLSUIDefault gls_ui;
gGL.getTexUnit(0)->bind(image, true);
gGL.color4fv(color.mV);
gGL.diffuseColor4fv(color.mV); //workaround: Intel HD 4000
@@ -611,11 +638,12 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTex
uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mTop);
pos[index].set(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f);
index++;
index++;
gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES);
gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES);
}
gGL.end();
}
gGL.end();
if (solid_color)
{
@@ -635,9 +663,9 @@ void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LL
gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), degrees, image, color, uv_rect );
}
void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect)
void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect, LLRenderTarget* target)
{
if (NULL == image)
if (!image && !target)
{
LL_WARNS() << "image == NULL; aborting function" << LL_ENDL;
return;
@@ -645,8 +673,14 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre
LLGLSUIDefault gls_ui;
gGL.getTexUnit(0)->bind(image, true);
if(image != NULL)
{
gGL.getTexUnit(0)->bind(image, true);
}
else
{
gGL.getTexUnit(0)->bind(target);
}
gGL.color4fv(color.mV);
@@ -698,11 +732,18 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre
gGL.translateUI(offset_x, offset_y, 0.f);
LLMatrix3 quat(0.f, 0.f, degrees*DEG_TO_RAD);
gGL.getTexUnit(0)->bind(image, true);
if(image != NULL)
{
gGL.getTexUnit(0)->bind(image, true);
}
else
{
gGL.getTexUnit(0)->bind(target);
}
gGL.color4fv(color.mV);
gGL.begin(LLRender::QUADS);
{
LLVector3 v;
@@ -1202,18 +1243,18 @@ void gl_segmented_rect_2d_tex(const S32 left,
gGL.popUIMatrix();
}
//FIXME: rewrite to use scissor?
void gl_segmented_rect_2d_fragment_tex(const S32 left,
const S32 top,
const S32 right,
const S32 bottom,
const S32 texture_width,
const S32 texture_height,
const S32 border_size,
const F32 start_fragment,
const F32 end_fragment,
const U32 edges)
void gl_segmented_rect_2d_fragment_tex(const LLRect& rect,
const S32 texture_width,
const S32 texture_height,
const S32 border_size,
const F32 start_fragment,
const F32 end_fragment,
const U32 edges)
{
const S32 left = rect.mLeft;
const S32 right = rect.mRight;
const S32 top = rect.mTop;
const S32 bottom = rect.mBottom;
S32 width = llabs(right - left);
S32 height = llabs(top - bottom);
@@ -1343,10 +1384,10 @@ void gl_segmented_rect_2d_fragment_tex(const S32 left,
if (end_fragment > middle_end)
{
u_min = (1.f - llmax(0.f, ((start_fragment - middle_end) / middle_start))) * border_uv_scale.mV[VX];
u_max = (1.f - ((end_fragment - middle_end) / middle_start)) * border_uv_scale.mV[VX];
x_min = width_vec - ((1.f - llmax(0.f, ((start_fragment - middle_end) / middle_start))) * border_width_right);
x_max = width_vec - ((1.f - ((end_fragment - middle_end) / middle_start)) * border_width_right);
u_min = 1.f - ((1.f - llmax(0.f, (start_fragment - middle_end) / middle_start)) * border_uv_scale.mV[VX]);
u_max = 1.f - ((1.f - ((end_fragment - middle_end) / middle_start)) * border_uv_scale.mV[VX]);
x_min = width_vec - ((1.f - llmax(0.f, (start_fragment - middle_end) / middle_start)) * border_width_right);
x_max = width_vec - ((1.f - ((end_fragment - middle_end) / middle_start)) * border_width_right);
// draw bottom right
gGL.texCoord2f(u_min, 0.f);
@@ -1393,145 +1434,132 @@ void gl_segmented_rect_2d_fragment_tex(const S32 left,
gGL.popUIMatrix();
}
void gl_segmented_rect_3d_tex(const LLVector2& border_scale, const LLVector3& border_width,
const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec,
const U32 edges)
void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv_rect, const LLRectf& center_draw_rect,
const LLVector3& width_vec, const LLVector3& height_vec)
{
LLVector3 left_border_width = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? border_width : LLVector3::zero;
LLVector3 right_border_width = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? border_width : LLVector3::zero;
LLVector3 top_border_height = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? border_height : LLVector3::zero;
LLVector3 bottom_border_height = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? border_height : LLVector3::zero;
gGL.begin(LLRender::QUADS);
{
// draw bottom left
gGL.texCoord2f(0.f, 0.f);
gGL.texCoord2f(clip_rect.mLeft, clip_rect.mBottom);
gGL.vertex3f(0.f, 0.f, 0.f);
gGL.texCoord2f(border_scale.mV[VX], 0.f);
gGL.vertex3fv(left_border_width.mV);
gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mBottom);
gGL.vertex3fv((center_draw_rect.mLeft * width_vec).mV);
gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]);
gGL.vertex3fv((left_border_width + bottom_border_height).mV);
gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
gGL.texCoord2f(0.f, border_scale.mV[VY]);
gGL.vertex3fv(bottom_border_height.mV);
gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mBottom);
gGL.vertex3fv((center_draw_rect.mBottom * height_vec).mV);
// draw bottom middle
gGL.texCoord2f(border_scale.mV[VX], 0.f);
gGL.vertex3fv(left_border_width.mV);
gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mBottom);
gGL.vertex3fv((center_draw_rect.mLeft * width_vec).mV);
gGL.texCoord2f(1.f - border_scale.mV[VX], 0.f);
gGL.vertex3fv((width_vec - right_border_width).mV);
gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mBottom);
gGL.vertex3fv((center_draw_rect.mRight * width_vec).mV);
gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]);
gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV);
gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);
gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]);
gGL.vertex3fv((left_border_width + bottom_border_height).mV);
gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
// draw bottom right
gGL.texCoord2f(1.f - border_scale.mV[VX], 0.f);
gGL.vertex3fv((width_vec - right_border_width).mV);
gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mBottom);
gGL.vertex3fv((center_draw_rect.mRight * width_vec).mV);
gGL.texCoord2f(1.f, 0.f);
gGL.texCoord2f(clip_rect.mRight, clip_rect.mBottom);
gGL.vertex3fv(width_vec.mV);
gGL.texCoord2f(1.f, border_scale.mV[VY]);
gGL.vertex3fv((width_vec + bottom_border_height).mV);
gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mBottom);
gGL.vertex3fv((width_vec + center_draw_rect.mBottom * height_vec).mV);
gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]);
gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV);
gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);
// draw left
gGL.texCoord2f(0.f, border_scale.mV[VY]);
gGL.vertex3fv(bottom_border_height.mV);
gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mBottom);
gGL.vertex3fv((center_draw_rect.mBottom * height_vec).mV);
gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]);
gGL.vertex3fv((left_border_width + bottom_border_height).mV);
gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]);
gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV);
gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);
gGL.texCoord2f(0.f, 1.f - border_scale.mV[VY]);
gGL.vertex3fv((height_vec - top_border_height).mV);
gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mTop);
gGL.vertex3fv((center_draw_rect.mTop * height_vec).mV);
// draw middle
gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]);
gGL.vertex3fv((left_border_width + bottom_border_height).mV);
gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]);
gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV);
gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);
gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]);
gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV);
gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);
gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]);
gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV);
gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);
// draw right
gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]);
gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV);
gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);
gGL.texCoord2f(1.f, border_scale.mV[VY]);
gGL.vertex3fv((width_vec + bottom_border_height).mV);
gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mBottom);
gGL.vertex3fv((width_vec + center_draw_rect.mBottom * height_vec).mV);
gGL.texCoord2f(1.f, 1.f - border_scale.mV[VY]);
gGL.vertex3fv((width_vec + height_vec - top_border_height).mV);
gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mTop);
gGL.vertex3fv((width_vec + center_draw_rect.mTop * height_vec).mV);
gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]);
gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV);
gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);
// draw top left
gGL.texCoord2f(0.f, 1.f - border_scale.mV[VY]);
gGL.vertex3fv((height_vec - top_border_height).mV);
gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mTop);
gGL.vertex3fv((center_draw_rect.mTop * height_vec).mV);
gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]);
gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV);
gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);
gGL.texCoord2f(border_scale.mV[VX], 1.f);
gGL.vertex3fv((left_border_width + height_vec).mV);
gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mTop);
gGL.vertex3fv((center_draw_rect.mLeft * width_vec + height_vec).mV);
gGL.texCoord2f(0.f, 1.f);
gGL.texCoord2f(clip_rect.mLeft, clip_rect.mTop);
gGL.vertex3fv((height_vec).mV);
// draw top middle
gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]);
gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV);
gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);
gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]);
gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV);
gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);
gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f);
gGL.vertex3fv((width_vec - right_border_width + height_vec).mV);
gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mTop);
gGL.vertex3fv((center_draw_rect.mRight * width_vec + height_vec).mV);
gGL.texCoord2f(border_scale.mV[VX], 1.f);
gGL.vertex3fv((left_border_width + height_vec).mV);
gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mTop);
gGL.vertex3fv((center_draw_rect.mLeft * width_vec + height_vec).mV);
// draw top right
gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]);
gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV);
gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);
gGL.texCoord2f(1.f, 1.f - border_scale.mV[VY]);
gGL.vertex3fv((width_vec + height_vec - top_border_height).mV);
gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mTop);
gGL.vertex3fv((width_vec + center_draw_rect.mTop * height_vec).mV);
gGL.texCoord2f(1.f, 1.f);
gGL.texCoord2f(clip_rect.mRight, clip_rect.mTop);
gGL.vertex3fv((width_vec + height_vec).mV);
gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f);
gGL.vertex3fv((width_vec - right_border_width + height_vec).mV);
gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mTop);
gGL.vertex3fv((center_draw_rect.mRight * width_vec + height_vec).mV);
}
gGL.end();
}
void gl_segmented_rect_3d_tex_top(const LLVector2& border_scale, const LLVector3& border_width, const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec)
{
gl_segmented_rect_3d_tex(border_scale, border_width, border_height, width_vec, height_vec, ROUNDED_RECT_TOP);
}
// static
void LLRender2D::initClass(LLImageProviderInterface* image_provider,
const LLVector2* scale_factor)

View File

@@ -71,11 +71,12 @@ void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4&
void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians, F32 end_radians, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color);
void gl_washer_spokes_2d(F32 outer_radius, F32 inner_radius, S32 count, const LLColor4& inner_color, const LLColor4& outer_color);
void gl_draw_image(S32 x, S32 y, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
void gl_draw_scaled_target(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* target, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees,LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), const LLRectf& scale_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), LLRenderTarget* target = NULL);
void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), bool scale_inner = true);
void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), const LLRectf& scale_rect = LLRectf(0.f, 1.f, 1.f, 0.f), bool scale_inner = true);
void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase = 0.f );
@@ -105,9 +106,8 @@ typedef enum e_rounded_edge
void gl_segmented_rect_2d_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const U32 edges = ROUNDED_RECT_ALL);
void gl_segmented_rect_2d_fragment_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const F32 start_fragment, const F32 end_fragment, const U32 edges = ROUNDED_RECT_ALL);
void gl_segmented_rect_3d_tex(const LLVector2& border_scale, const LLVector3& border_width, const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec, U32 edges = ROUNDED_RECT_ALL);
void gl_segmented_rect_3d_tex_top(const LLVector2& border_scale, const LLVector3& border_width, const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec);
void gl_segmented_rect_2d_fragment_tex(const LLRect& rect, const S32 texture_width, const S32 texture_height, const S32 border_size, const F32 start_fragment, const F32 end_fragment, const U32 edges = ROUNDED_RECT_ALL);
void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv_rect, const LLRectf& center_draw_rect, const LLVector3& width_vec, const LLVector3& height_vec);
inline void gl_rect_2d( const LLRect& rect, BOOL filled )
{

View File

@@ -80,7 +80,11 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{
llassert_always(shader != NULL);
LLShaderFeatures *features = & shader->mFeatures;
if (features->attachNothing)
{
return TRUE;
}
//////////////////////////////////////
// Attach Vertex Shader Features First
//////////////////////////////////////
@@ -640,11 +644,14 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
// before any non-preprocessor directives (per spec)
text[count++] = strdup("#extension GL_ARB_texture_rectangle : enable\n");
text[count++] = strdup("#extension GL_ARB_shader_texture_lod : enable\n");
if (minor_version == 50 && gGLManager.mHasGpuShader5)
{
text[count++] = strdup("#extension GL_ARB_gpu_shader5 : enable\n");
}
//some implementations of GLSL 1.30 require integer precision be explicitly declared
text[count++] = strdup("precision mediump int;\n");
text[count++] = strdup("precision highp float;\n");
text[count++] = strdup("#define FXAA_GLSL_130 1\n");
}
else
{ //set version to 400
@@ -653,11 +660,11 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
// before any non-preprocessor directives (per spec)
text[count++] = strdup("#extension GL_ARB_texture_rectangle : enable\n");
text[count++] = strdup("#extension GL_ARB_shader_texture_lod : enable\n");
text[count++] = strdup("#define FXAA_GLSL_400 1\n");
}
text[count++] = strdup("#define DEFINE_GL_FRAGCOLOR 1\n");
text[count++] = strdup("#define FXAA_GLSL_130 1\n");
text[count++] = strdup("#define ATTRIBUTE in\n");
@@ -875,8 +882,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
{ //dump every 128 lines
LL_WARNS("ShaderLoading") << "\n" << ostr.str() << LL_ENDL;
ostr.clear();
ostr.str(LLStringUtil::null);
ostr = std::stringstream();
}
}
@@ -943,6 +949,63 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
return ret;
}
void LLShaderMgr::unloadShaders()
{
//Instead of manually unloading, shaders are now automatically accumulated in a list.
//Simply iterate and unload.
std::vector<LLGLSLShader *> &shader_list = LLShaderMgr::getGlobalShaderList();
for (std::vector<LLGLSLShader *>::iterator it = shader_list.begin(); it != shader_list.end(); ++it)
(*it)->unload();
mShaderObjects.clear();
mProgramObjects.clear();
}
void LLShaderMgr::unloadShaderObjects()
{
std::multimap<std::string, LLShaderMgr::CachedObjectInfo >::iterator it = mShaderObjects.begin();
for (; it != mShaderObjects.end(); ++it)
if (it->second.mHandle)
glDeleteObjectARB(it->second.mHandle);
mShaderObjects.clear();
cleanupShaderSources();
}
void LLShaderMgr::cleanupShaderSources()
{
if (!mProgramObjects.empty())
{
for (auto iter = mProgramObjects.cbegin(),
iter_end = mProgramObjects.cend(); iter != iter_end; ++iter)
{
GLuint program = iter->second;
if (program > 0)
{
GLhandleARB shaders[1024] = {};
GLsizei count = -1;
glGetAttachedObjectsARB(program, 1024, &count, shaders);
if (count > 0)
{
for (GLsizei i = 0; i < count; ++i)
{
std::multimap<std::string, LLShaderMgr::CachedObjectInfo>::iterator it = mShaderObjects.begin();
for (; it != LLShaderMgr::instance()->mShaderObjects.end(); it++)
{
if ((*it).second.mHandle == shaders[i])
{
glDetachObjectARB(program, shaders[i]);
break;
}
}
}
}
}
}
// Clear the linked program list as its no longer needed
mProgramObjects.clear();
}
}
BOOL LLShaderMgr::linkProgramObject(GLhandleARB obj, BOOL suppress_errors)
{
//check for errors

View File

@@ -232,6 +232,8 @@ DISPLAY_GAMMA,
BOOL linkProgramObject(GLhandleARB obj, BOOL suppress_errors = FALSE);
BOOL validateProgramObject(GLhandleARB obj);
GLhandleARB loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, std::map<std::string, std::string>* defines = NULL, S32 texture_index_channels = -1);
void unloadShaders();
void unloadShaderObjects();
// Implemented in the application to actually point to the shader directory.
virtual std::string getShaderDirPrefix(void) = 0; // Pure Virtual
@@ -252,6 +254,9 @@ public:
// Map of shader names to compiled
std::multimap<std::string, CachedObjectInfo > mShaderObjects; //Singu Note: Packing more info here. Doing such provides capability to skip unneeded duplicate loading..
// Map of program names linked
std::map<std::string, GLuint> mProgramObjects;
//global (reserved slot) shader parameters
std::vector<std::string> mReservedAttribs;
@@ -261,6 +266,7 @@ public:
std::map<std::string, std::string> mDefinitions;
protected:
void cleanupShaderSources();
// our parameter manager singleton instance
static LLShaderMgr * sInstance;

View File

@@ -38,11 +38,9 @@ LLUIImage::LLUIImage(const std::string& name, LLPointer<LLTexture> image)
mImage(image),
mScaleRegion(0.f, 1.f, 1.f, 0.f),
mClipRegion(0.f, 1.f, 1.f, 0.f),
mUniformScaling(TRUE),
mNoClip(TRUE),
mImageLoaded(NULL)
{
}
mImageLoaded(NULL),
mScaleStyle(SCALE_INNER)
{}
LLUIImage::~LLUIImage()
{
@@ -52,44 +50,35 @@ LLUIImage::~LLUIImage()
void LLUIImage::setClipRegion(const LLRectf& region)
{
mClipRegion = region;
mNoClip = mClipRegion.mLeft == 0.f
&& mClipRegion.mRight == 1.f
&& mClipRegion.mBottom == 0.f
&& mClipRegion.mTop == 1.f;
}
void LLUIImage::setScaleRegion(const LLRectf& region)
{
mScaleRegion = region;
mUniformScaling = mScaleRegion.mLeft == 0.f
&& mScaleRegion.mRight == 1.f
&& mScaleRegion.mBottom == 0.f
&& mScaleRegion.mTop == 1.f;
}
void LLUIImage::setScaleStyle(LLUIImage::EScaleStyle style)
{
mScaleStyle = style;
}
//TODO: move drawing implementation inside class
void LLUIImage::draw(S32 x, S32 y, const LLColor4& color) const
{
gl_draw_scaled_image(x, y, getWidth(), getHeight(), mImage, color, mClipRegion);
draw(x, y, getWidth(), getHeight(), color);
}
void LLUIImage::draw(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) const
{
if (mUniformScaling)
{
gl_draw_scaled_image(x, y, width, height, mImage, color, mClipRegion);
}
else
{
gl_draw_scaled_image_with_border(
x, y,
width, height,
mImage,
color,
FALSE,
mClipRegion,
mScaleRegion);
}
gl_draw_scaled_image_with_border(
x, y,
width, height,
mImage,
color,
FALSE,
mClipRegion,
mScaleRegion,
mScaleStyle == SCALE_INNER);
}
void LLUIImage::drawSolid(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) const
@@ -101,7 +90,8 @@ void LLUIImage::drawSolid(S32 x, S32 y, S32 width, S32 height, const LLColor4& c
color,
TRUE,
mClipRegion,
mScaleRegion);
mScaleRegion,
mScaleStyle == SCALE_INNER);
}
void LLUIImage::drawBorder(S32 x, S32 y, S32 width, S32 height, const LLColor4& color, S32 border_width) const
@@ -112,6 +102,50 @@ void LLUIImage::drawBorder(S32 x, S32 y, S32 width, S32 height, const LLColor4&
drawSolid(border_rect, color);
}
void LLUIImage::draw3D(const LLVector3& origin_agent, const LLVector3& x_axis, const LLVector3& y_axis,
const LLRect& rect, const LLColor4& color)
{
F32 border_scale = 1.f;
F32 border_height = (1.f - mScaleRegion.getHeight()) * getHeight();
F32 border_width = (1.f - mScaleRegion.getWidth()) * getWidth();
if (rect.getHeight() < border_height || rect.getWidth() < border_width)
{
if(border_height - rect.getHeight() > border_width - rect.getWidth())
{
border_scale = (F32)rect.getHeight() / border_height;
}
else
{
border_scale = (F32)rect.getWidth() / border_width;
}
}
LLRender2D::pushMatrix();
{
LLVector3 rect_origin = origin_agent + (rect.mLeft * x_axis) + (rect.mBottom * y_axis);
LLRender2D::translate(rect_origin.mV[VX],
rect_origin.mV[VY],
rect_origin.mV[VZ]);
gGL.getTexUnit(0)->bind(getImage());
gGL.color4fv(color.mV);
LLRectf center_uv_rect(mClipRegion.mLeft + mScaleRegion.mLeft * mClipRegion.getWidth(),
mClipRegion.mBottom + mScaleRegion.mTop * mClipRegion.getHeight(),
mClipRegion.mLeft + mScaleRegion.mRight * mClipRegion.getWidth(),
mClipRegion.mBottom + mScaleRegion.mBottom * mClipRegion.getHeight());
gl_segmented_rect_3d_tex(mClipRegion,
center_uv_rect,
LLRectf(border_width * border_scale * 0.5f / (F32)rect.getWidth(),
(rect.getHeight() - (border_height * border_scale * 0.5f)) / (F32)rect.getHeight(),
(rect.getWidth() - (border_width * border_scale * 0.5f)) / (F32)rect.getWidth(),
(border_height * border_scale * 0.5f) / (F32)rect.getHeight()),
rect.getWidth() * x_axis,
rect.getHeight() * y_axis);
} LLRender2D::popMatrix();
}
S32 LLUIImage::getWidth() const
{
// return clipped dimensions of actual image area

View File

@@ -45,6 +45,12 @@ extern const LLColor4 UI_VERTEX_COLOR;
class LLUIImage : public LLRefCount
{
public:
enum EScaleStyle
{
SCALE_INNER,
SCALE_OUTER
};
typedef boost::signals2::signal<void (void)> image_loaded_signal_t;
LLUIImage(const std::string& name, LLPointer<LLTexture> image);
@@ -52,6 +58,7 @@ public:
void setClipRegion(const LLRectf& region);
void setScaleRegion(const LLRectf& region);
void setScaleStyle(EScaleStyle style);
LLPointer<LLTexture> getImage() { return mImage; }
const LLPointer<LLTexture>& getImage() const { return mImage; }
@@ -67,7 +74,9 @@ public:
void drawBorder(S32 x, S32 y, S32 width, S32 height, const LLColor4& color, S32 border_width) const;
void drawBorder(const LLRect& rect, const LLColor4& color, S32 border_width) const { drawBorder(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), color, border_width); }
void drawBorder(S32 x, S32 y, const LLColor4& color, S32 border_width) const { drawBorder(x, y, getWidth(), getHeight(), color, border_width); }
void draw3D(const LLVector3& origin_agent, const LLVector3& x_axis, const LLVector3& y_axis, const LLRect& rect, const LLColor4& color);
const std::string& getName() const { return mName; }
virtual S32 getWidth() const;
@@ -84,12 +93,11 @@ public:
protected:
image_loaded_signal_t* mImageLoaded;
std::string mName;
LLRectf mScaleRegion;
LLRectf mClipRegion;
LLPointer<LLTexture> mImage;
BOOL mUniformScaling;
BOOL mNoClip;
std::string mName;
LLRectf mScaleRegion;
LLRectf mClipRegion;
LLPointer<LLTexture> mImage;
EScaleStyle mScaleStyle;
};
namespace LLInitParam

View File

@@ -466,7 +466,7 @@ void LLMultiSlider::draw()
F32 opacity = getEnabled() ? 1.f : 0.3f;
// Track
LLUIImagePtr thumb_imagep = LLUI::getUIImage("rounded_square.tga");
LLUIImagePtr thumb_imagep = LLUI::getUIImage("Rounded_Square");
S32 height_offset = (getRect().getHeight() - MULTI_TRACK_HEIGHT) / 2;
LLRect track_rect(0, getRect().getHeight() - height_offset, getRect().getWidth(), height_offset );

View File

@@ -1297,14 +1297,20 @@ LLXMLNodePtr LLNotificationTemplates::checkForXMLTemplate(LLXMLNodePtr item)
bool LLNotificationTemplates::loadTemplates()
{
const std::string xml_filename = "notifications.xml";
LL_INFOS() << "Reading notifications template" << LL_ENDL;
// Passing findSkinnedFilenames(constraint=LLDir::ALL_SKINS) makes it
// output all relevant pathnames instead of just the ones from the most
// specific skin.
std::vector<std::string> search_paths =
gDirUtilp->findSkinnedFilenames(LLDir::XUI, "notifications.xml", LLDir::ALL_SKINS);
std::string base_filename = search_paths.front();
LLXMLNodePtr root;
BOOL success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root);
BOOL success = LLXMLNode::getLayeredXMLNode(root, search_paths);
if (!success || root.isNull() || !root->hasName( "notifications" ))
{
LL_ERRS() << "Problem reading UI Notifications file: " << xml_filename << LL_ENDL;
LL_ERRS() << "Problem reading XML from UI Notifications file: " << base_filename << LL_ENDL;
return false;
}
@@ -1337,7 +1343,7 @@ bool LLNotificationTemplates::loadTemplates()
if (!item->hasName("notification"))
{
LL_WARNS() << "Unexpected entity " << item->getName()->mString <<
" found in " << xml_filename << LL_ENDL;
" found in notifications.xml [language=]" << LLUI::getLanguage() << LL_ENDL;
continue;
}
}
@@ -1347,14 +1353,20 @@ bool LLNotificationTemplates::loadTemplates()
bool LLNotifications::loadNotifications()
{
const std::string xml_filename = "notifications.xml";
LL_INFOS() << "Reading notifications template" << LL_ENDL;
// Passing findSkinnedFilenames(constraint=LLDir::ALL_SKINS) makes it
// output all relevant pathnames instead of just the ones from the most
// specific skin.
std::vector<std::string> search_paths =
gDirUtilp->findSkinnedFilenames(LLDir::XUI, "notifications.xml", LLDir::ALL_SKINS);
std::string base_filename = search_paths.front();
LLXMLNodePtr root;
BOOL success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root);
BOOL success = LLXMLNode::getLayeredXMLNode(root, search_paths);
if (!success || root.isNull() || !root->hasName( "notifications" ))
{
LL_ERRS() << "Problem reading UI Notifications file: " << xml_filename << LL_ENDL;
LL_ERRS() << "Problem reading XML from UI Notifications file: " << base_filename << LL_ENDL;
return false;
}

View File

@@ -92,8 +92,9 @@
#include <boost/utility.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/type_traits.hpp>
#include <boost/signals2.hpp>
#include <boost/range.hpp>
// we want to minimize external dependencies, but this one is important
#include "llsd.h"
#include "llinstancetracker.h"
@@ -102,6 +103,7 @@
#include "llavatarname.h"
#include "llevents.h"
#include "llfunctorregistry.h"
#include "llinitparam.h"
#include "llui.h"
#include "llxmlnode.h"
#include "llnotificationptr.h"
@@ -131,6 +133,70 @@ class LLNotificationForm
LOG_CLASS(LLNotificationForm);
public:
struct FormElementBase : public LLInitParam::Block<FormElementBase>
{
Optional<std::string> name;
Optional<bool> enabled;
FormElementBase();
};
struct FormIgnore : public LLInitParam::Block<FormIgnore, FormElementBase>
{
Optional<std::string> text;
Optional<bool> save_option;
Optional<std::string> control;
Optional<bool> invert_control;
FormIgnore();
};
struct FormButton : public LLInitParam::Block<FormButton, FormElementBase>
{
Mandatory<S32> index;
Mandatory<std::string> text;
Optional<std::string> ignore;
Optional<bool> is_default;
Mandatory<std::string> type;
FormButton();
};
struct FormInput : public LLInitParam::Block<FormInput, FormElementBase>
{
Mandatory<std::string> type;
Optional<S32> width;
Optional<S32> max_length_chars;
Optional<std::string> text;
Optional<std::string> value;
FormInput();
};
struct FormElement : public LLInitParam::ChoiceBlock<FormElement>
{
Alternative<FormButton> button;
Alternative<FormInput> input;
FormElement();
};
struct FormElements : public LLInitParam::Block<FormElements>
{
Multiple<FormElement> elements;
FormElements();
};
struct Params : public LLInitParam::Block<Params>
{
Optional<std::string> name;
Optional<FormIgnore> ignore;
Optional<FormElements> form_elements;
Params();
};
typedef enum e_ignore_type
{
IGNORE_NO,

View File

@@ -48,16 +48,16 @@
static LLRegisterWidget<LLProgressBar> r("progress_bar");
LLProgressBar::LLProgressBar(const std::string& name, const LLRect &rect)
: LLView(name, rect, FALSE),
mImageBar( NULL ),
mImageShadow( NULL )
: LLView(name, rect, FALSE)
//mImageBar( NULL ),
// mImageShadow( NULL )
{
mPercentDone = 0.f;
// Defaults:
setImageBar("rounded_square.tga");
setImageShadow("rounded_square_soft.tga");
setImageBar("Rounded_Square");
setImageShadow("Rounded_Square_Soft");
mColorBackground = LLColor4(0.3254f, 0.4000f, 0.5058f, 1.0f);
mColorBar = LLColor4(0.5764f, 0.6627f, 0.8352f, 1.0f);
@@ -75,10 +75,8 @@ void LLProgressBar::draw()
static LLTimer timer;
F32 alpha = getDrawContext().mAlpha;
//LLUIImagePtr shadow_imagep = LLUI::getUIImage("rounded_square_soft.tga");
LLUIImagePtr bar_fg_imagep = LLUI::getUIImage("progressbar_fill.tga");
LLUIImagePtr bar_bg_imagep = LLUI::getUIImage("progressbar_track.tga");
//LLUIImagePtr bar_imagep = LLUI::getUIImage("rounded_square.tga");
LLUIImagePtr bar_fg_imagep = LLUI::getUIImage("ProgressBar");
LLUIImagePtr bar_bg_imagep = LLUI::getUIImage("ProgressTrack");
LLColor4 background_color = LLUI::sColorsGroup->getColor("LoginProgressBarBgColor");
bar_bg_imagep->draw(getLocalRect(), background_color % alpha);
@@ -95,12 +93,12 @@ void LLProgressBar::setPercent(const F32 percent)
void LLProgressBar::setImageBar( const std::string &bar_name )
{
mImageBar = LLUI::getUIImage(bar_name)->getImage();
//mImageBar = LLUI::getUIImage(bar_name)->getImage();
}
void LLProgressBar::setImageShadow(const std::string &shadow_name)
{
mImageShadow = LLUI::getUIImage(shadow_name)->getImage();
//mImageShadow = LLUI::getUIImage(shadow_name)->getImage();
}
void LLProgressBar::setColorBar(const LLColor4 &c)
@@ -140,14 +138,14 @@ LLView* LLProgressBar::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactor
LLProgressBar *progress = new LLProgressBar(name, LLRect());
std::string image_bar;
/*std::string image_bar;
if (node->hasAttribute("image_bar")) node->getAttributeString("image_bar",image_bar);
if (image_bar != LLStringUtil::null) progress->setImageBar(image_bar);
std::string image_shadow;
if (node->hasAttribute("image_shadow")) node->getAttributeString("image_shadow",image_shadow);
if (image_shadow != LLStringUtil::null) progress->setImageShadow(image_shadow);
if (image_shadow != LLStringUtil::null) progress->setImageShadow(image_shadow);*/
LLColor4 color_bar;

View File

@@ -62,13 +62,13 @@ public:
protected:
F32 mPercentDone;
LLPointer<LLTexture> mImageBar;
//<LLTexture> mImageBar;
//LLUUID mImageBarID;
//LLString mImageBarName;
LLColor4 mColorBar;
LLColor4 mColorBar2;
LLPointer<LLTexture> mImageShadow;
//LLPointer<LLTexture> mImageShadow;
//LLUUID mImageShadowID;
//LLString mImageShadowName;
LLColor4 mColorShadow;

View File

@@ -511,7 +511,7 @@ void LLScrollbar::draw()
// Draw background and thumb.
LLUIImage* rounded_rect_imagep = LLUI::getUIImage("rounded_square.tga");
LLUIImage* rounded_rect_imagep = LLUI::getUIImage("Rounded_Square");
if (!rounded_rect_imagep)
{

View File

@@ -203,7 +203,7 @@ LLScrollListText::LLScrollListText(const LLScrollListCell::Params& p)
// initialize rounded rect image
if (!mRoundedRectImage)
{
mRoundedRectImage = LLUI::getUIImage("rounded_square.tga");
mRoundedRectImage = LLUI::getUIImage("Rounded_Square");
}
}

View File

@@ -72,9 +72,9 @@ LLSlider::LLSlider(
mMouseDownSignal( NULL ),
mMouseUpSignal( NULL )
{
mThumbImage = LLUI::getUIImage("icn_slide-thumb_dark.tga");
mTrackImage = LLUI::getUIImage("icn_slide-groove_dark.tga");
mTrackHighlightImage = LLUI::getUIImage("icn_slide-highlight.tga");
mThumbImage = LLUI::getUIImage("SliderThumb_Off");
mTrackImage = LLUI::getUIImage("SliderTrack_Horiz");
mTrackHighlightImage = LLUI::getUIImage("SliderTrack_Horiz_Highlight");
// properly handle setting the starting thumb rect
// do it this way to handle both the operating-on-settings

View File

@@ -223,32 +223,33 @@ std::string LLUI::getLanguage()
//static
std::string LLUI::locateSkin(const std::string& filename)
{
std::string slash = gDirUtilp->getDirDelimiter();
std::string found_file = filename;
if (!gDirUtilp->fileExists(found_file))
if (gDirUtilp->fileExists(found_file))
{
found_file = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename); // Should be CUSTOM_SKINS?
return found_file;
}
if (sConfigGroup && sConfigGroup->controlExists("Language"))
found_file = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename); // Should be CUSTOM_SKINS?
if (gDirUtilp->fileExists(found_file))
{
if (!gDirUtilp->fileExists(found_file))
{
std::string localization = getLanguage();
std::string local_skin = "xui" + slash + localization + slash + filename;
found_file = gDirUtilp->findSkinnedFilename(local_skin);
}
return found_file;
}
if (!gDirUtilp->fileExists(found_file))
found_file = gDirUtilp->findSkinnedFilename(LLDir::XUI, filename);
if (! found_file.empty())
{
std::string local_skin = "xui" + slash + "en-us" + slash + filename;
found_file = gDirUtilp->findSkinnedFilename(local_skin);
return found_file;
}
if (!gDirUtilp->fileExists(found_file))
found_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, filename);
if (gDirUtilp->fileExists(found_file))
{
found_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, filename);
return found_file;
}
return found_file;
}
LL_WARNS("LLUI") << "Can't find '" << filename
<< "' in user settings, any skin directory or app_settings" << LL_ENDL;
return "";
}
//static
LLVector2 LLUI::getWindowSize()

View File

@@ -174,7 +174,7 @@ const std::vector<std::string>& LLUICtrlFactory::getXUIPaths()
//-----------------------------------------------------------------------------
bool LLUICtrlFactory::getLayeredXMLNode(const std::string &xui_filename, LLXMLNodePtr& root)
{
std::string full_filename = gDirUtilp->findSkinnedFilename(sXUIPaths.front(), xui_filename);
std::string full_filename = gDirUtilp->findSkinnedFilenameBaseLang(LLDir::XUI, xui_filename);
if (full_filename.empty())
{
// try filename as passed in since sometimes we load an xml file from a user-supplied path
@@ -194,29 +194,21 @@ bool LLUICtrlFactory::getLayeredXMLNode(const std::string &xui_filename, LLXMLNo
LL_WARNS() << "Problem reading UI description file: " << full_filename << LL_ENDL;
return false;
}
std::vector<std::string> paths =
gDirUtilp->findSkinnedFilenames(LLDir::XUI, xui_filename);
LLXMLNodePtr updateRoot;
std::vector<std::string>::const_iterator itor;
for (itor = sXUIPaths.begin(), ++itor; itor != sXUIPaths.end(); ++itor)
for ( auto& layer_filename : paths )
{
std::string nodeName;
std::string updateName;
std::string layer_filename = gDirUtilp->findSkinnedFilename((*itor), xui_filename);
if(layer_filename.empty())
{
// no localized version of this file, that's ok, keep looking
continue;
}
LLXMLNodePtr updateRoot;
if (!LLXMLNode::parseFile(layer_filename, updateRoot, NULL))
{
LL_WARNS() << "Problem reading localized UI description file: " << (*itor) + gDirUtilp->getDirDelimiter() + xui_filename << LL_ENDL;
LL_WARNS() << "Problem reading localized UI description file: " << layer_filename << LL_ENDL;
return false;
}
std::string updateName;
std::string nodeName;
updateRoot->getAttributeString("name", updateName);
root->getAttributeString("name", nodeName);

View File

@@ -71,8 +71,15 @@ LLDir_Linux gDirUtil;
LLDir *gDirUtilp = (LLDir *)&gDirUtil;
/// Values for findSkinnedFilenames(subdir) parameter
const char
*LLDir::XUI = "xui",
*LLDir::TEXTURES = "textures",
*LLDir::SKINBASE = "";
static const char* const empty = "";
std::string LLDir::sDumpDir = "";
LLDir::LLDir()
: mAppName(""),
mExecutablePathAndName(""),
@@ -85,7 +92,9 @@ LLDir::LLDir()
mOSCacheDir(""),
mCAFile(""),
mTempDir(""),
mDirDelimiter("/") // fallback to forward slash if not overridden
mDirDelimiter("/"), // fallback to forward slash if not overridden
mLanguage("en"),
mUserName("undefined")
{
}
@@ -97,7 +106,11 @@ std::vector<std::string> LLDir::getFilesInDir(const std::string &dirname)
{
//Returns a vector of fullpath filenames.
#if LL_WINDOWS
boost::filesystem::path p (utf8str_to_utf16str(dirname).c_str());
#else
boost::filesystem::path p (dirname);
#endif
std::vector<std::string> v;
if (exists(p))
@@ -188,19 +201,33 @@ S32 LLDir::deleteFilesInDir(const std::string &dirname, const std::string &mask)
U32 LLDir::deleteDirAndContents(const std::string& dir_name)
{
//Removes the directory and its contents. Returns number of files removed.
// Singu Note: boost::filesystem throws exceptions
S32 res = 0;
U32 num_deleted = 0;
try
try
{
res = boost::filesystem::remove_all(dir_name);
#if LL_WINDOWS
boost::filesystem::path dir_path(utf8str_to_utf16str(dir_name).c_str());
#else
boost::filesystem::path dir_path(dir_name);
#endif
if (boost::filesystem::exists (dir_path))
{
if (!boost::filesystem::is_empty (dir_path))
{ // Directory has content
num_deleted = boost::filesystem::remove_all (dir_path);
}
else
{ // Directory is empty
boost::filesystem::remove (dir_path);
}
}
}
catch(const boost::filesystem::filesystem_error& e)
{
LL_WARNS() << "boost::filesystem::remove_all(\"" + dir_name + "\") failed: '" + e.code().message() + "'" << LL_ENDL;
}
return res;
catch (boost::filesystem::filesystem_error &er)
{
LL_WARNS() << "Failed to delete " << dir_name << " with error " << er.code().message() << LL_ENDL;
}
return num_deleted;
}
const std::string LLDir::findFile(const std::string &filename,
@@ -346,6 +373,12 @@ const std::string LLDir::getCacheDir(bool get_default) const
}
}
#if (defined(_WIN64) || defined(__amd64__) || defined(__x86_64__))
#define OS_CACHE_DIR "SingularityViewer64"
#else
#define OS_CACHE_DIR "Obsidian"
#endif
// Return the default cache directory
std::string LLDir::buildSLOSCacheDir() const
{
@@ -363,11 +396,7 @@ std::string LLDir::buildSLOSCacheDir() const
}
else
{
#if defined(_WIN64)
res = add(getOSCacheDir(), "SingularityViewer64");
#else
res = add(getOSCacheDir(), "SingularityViewer");
#endif
res = add(getOSCacheDir(), OS_CACHE_DIR);
}
return res;
}
@@ -390,20 +419,26 @@ const std::string &LLDir::getDirDelimiter() const
return mDirDelimiter;
}
const std::string& LLDir::getDefaultSkinDir() const
{
return mDefaultSkinDir;
}
const std::string &LLDir::getSkinDir() const
{
return mSkinDir;
}
const std::string& LLDir::getUserDefaultSkinDir() const
{
return mUserDefaultSkinDir;
}
const std::string &LLDir::getUserSkinDir() const
{
return mUserSkinDir;
}
const std::string& LLDir::getDefaultSkinDir() const
{
return mDefaultSkinDir;
}
const std::string LLDir::getSkinBaseDir() const
{
@@ -415,6 +450,11 @@ const std::string &LLDir::getLLPluginDir() const
return mLLPluginDir;
}
const std::string &LLDir::getUserName() const
{
return mUserName;
}
static std::string ELLPathToString(ELLPath location)
{
typedef std::map<ELLPath, const char*> ELLPathMap;
@@ -602,7 +642,7 @@ std::string LLDir::getBaseFileName(const std::string& filepath, bool strip_exten
std::string LLDir::getDirName(const std::string& filepath) const
{
std::size_t offset = filepath.find_last_of(getDirDelimiter());
S32 len = (offset == std::string::npos) ? 0 : offset;
size_t len = (offset == std::string::npos) ? 0 : offset;
std::string dirname = filepath.substr(0, len);
return dirname;
}
@@ -618,31 +658,207 @@ std::string LLDir::getExtension(const std::string& filepath) const
return exten;
}
std::string LLDir::findSkinnedFilename(const std::string &filename) const
std::string LLDir::findSkinnedFilenameBaseLang(const std::string &subdir,
const std::string &filename,
ESkinConstraint constraint) const
{
return findSkinnedFilename("", "", filename);
// This implementation is basically just as described in the declaration comments.
std::vector<std::string> found(findSkinnedFilenames(subdir, filename, constraint));
if (found.empty())
{
return "";
}
return found.front();
}
std::string LLDir::findSkinnedFilename(const std::string &subdir, const std::string &filename) const
std::string LLDir::findSkinnedFilename(const std::string &subdir,
const std::string &filename,
ESkinConstraint constraint) const
{
return findSkinnedFilename("", subdir, filename);
// This implementation is basically just as described in the declaration comments.
std::vector<std::string> found(findSkinnedFilenames(subdir, filename, constraint));
if (found.empty())
{
return "";
}
return found.back();
}
std::string LLDir::findSkinnedFilename(const std::string &subdir1, const std::string &subdir2, const std::string &filename) const
// This method exists because the two code paths for
// findSkinnedFilenames(ALL_SKINS) and findSkinnedFilenames(CURRENT_SKIN) must
// generate the list of candidate pathnames in identical ways. The only
// difference is in the body of the inner loop.
template <typename FUNCTION>
void LLDir::walkSearchSkinDirs(const std::string& subdir,
const std::vector<std::string>& subsubdirs,
const std::string& filename,
const FUNCTION& function) const
{
// generate subdirectory path fragment, e.g. "/foo/bar", "/foo", ""
std::string subdirs = ((subdir1.empty() ? "" : mDirDelimiter) + subdir1)
+ ((subdir2.empty() ? "" : mDirDelimiter) + subdir2);
BOOST_FOREACH(std::string skindir, mSearchSkinDirs)
{
std::string subdir_path(add(skindir, subdir));
BOOST_FOREACH(std::string subsubdir, subsubdirs)
{
std::string full_path(add(add(subdir_path, subsubdir), filename));
if (fileExists(full_path))
{
function(subsubdir, full_path);
}
}
}
}
std::vector<std::string> search_paths;
search_paths.push_back(getUserSkinDir() + subdirs); // first look in user skin override
search_paths.push_back(getSkinDir() + subdirs); // then in current skin
search_paths.push_back(getDefaultSkinDir() + subdirs); // then default skin
search_paths.push_back(getCacheDir() + subdirs); // and last in preload directory
// ridiculous little helper function that should go away when we can use lambda
inline void push_back(std::vector<std::string>& vector, const std::string& value)
{
vector.push_back(value);
}
std::string found_file = findFile(filename, search_paths);
return found_file;
typedef std::map<std::string, std::string> StringMap;
// ridiculous little helper function that should go away when we can use lambda
inline void store_in_map(StringMap& map, const std::string& key, const std::string& value)
{
map[key] = value;
}
std::vector<std::string> LLDir::findSkinnedFilenames(const std::string& subdir,
const std::string& filename,
ESkinConstraint constraint) const
{
// Recognize subdirs that have no localization.
static const std::set<std::string> sUnlocalized = list_of
("") // top-level directory not localized
("textures") // textures not localized
;
LL_DEBUGS("LLDir") << "subdir '" << subdir << "', filename '" << filename
<< "', constraint "
<< ((constraint == CURRENT_SKIN)? "CURRENT_SKIN" : "ALL_SKINS")
<< LL_ENDL;
// Cache the default language directory for each subdir we've encountered.
// A cache entry whose value is the empty string means "not localized,
// don't bother checking again."
static StringMap sLocalized;
// Check whether we've already discovered if this subdir is localized.
StringMap::const_iterator found = sLocalized.find(subdir);
if (found == sLocalized.end())
{
// We have not yet determined that. Is it one of the subdirs "known"
// to be unlocalized?
if (sUnlocalized.find(subdir) != sUnlocalized.end())
{
// This subdir is known to be unlocalized. Remember that.
found = sLocalized.insert(StringMap::value_type(subdir, "")).first;
}
else
{
// We do not recognize this subdir. Investigate.
std::string subdir_path(add(getDefaultSkinDir(), subdir));
if (fileExists(add(subdir_path, "en")))
{
// defaultSkinDir/subdir contains subdir "en". That's our
// default language; this subdir is localized.
found = sLocalized.insert(StringMap::value_type(subdir, "en")).first;
}
else if (fileExists(add(subdir_path, "en-us")))
{
// defaultSkinDir/subdir contains subdir "en-us" but not "en".
// Set as default language; this subdir is localized.
found = sLocalized.insert(StringMap::value_type(subdir, "en-us")).first;
}
else
{
// defaultSkinDir/subdir contains neither "en" nor "en-us".
// Assume it's not localized. Remember that assumption.
found = sLocalized.insert(StringMap::value_type(subdir, "")).first;
}
}
}
// Every code path above should have resulted in 'found' becoming a valid
// iterator to an entry in sLocalized.
llassert(found != sLocalized.end());
// Now -- is this subdir localized, or not? The answer determines what
// subdirectories we check (under subdir) for the requested filename.
std::vector<std::string> subsubdirs;
if (found->second.empty())
{
// subdir is not localized. filename should be located directly within it.
subsubdirs.push_back("");
}
else
{
// subdir is localized, and found->second is the default language
// directory within it. Check both the default language and the
// current language -- if it differs from the default, of course.
subsubdirs.push_back(found->second);
if (mLanguage != found->second)
{
subsubdirs.push_back(mLanguage);
}
}
// Build results vector.
std::vector<std::string> results;
// The process we use depends on 'constraint'.
if (constraint != CURRENT_SKIN) // meaning ALL_SKINS
{
// ALL_SKINS is simpler: just return every pathname generated by
// walkSearchSkinDirs(). Tricky bit: walkSearchSkinDirs() passes its
// FUNCTION the subsubdir as well as the full pathname. We just want
// the full pathname.
walkSearchSkinDirs(subdir, subsubdirs, filename,
boost::bind(push_back, boost::ref(results), _2));
}
else // CURRENT_SKIN
{
// CURRENT_SKIN turns out to be a bit of a misnomer because we might
// still return files from two different skins. In any case, this
// value of 'constraint' means we will return at most two paths: one
// for the default language, one for the current language (supposing
// those differ).
// It is important to allow a user to override only the localization
// for a particular file, for all viewer installs, without also
// overriding the default-language file.
// It is important to allow a user to override only the default-
// language file, for all viewer installs, without also overriding the
// applicable localization of that file.
// Therefore, treat the default language and the current language as
// two separate cases. For each, capture the most-specialized file
// that exists.
// Use a map keyed by subsubdir (i.e. language code). This allows us
// to handle the case of a single subsubdirs entry with the same logic
// that handles two. For every real file path generated by
// walkSearchSkinDirs(), update the map entry for its subsubdir.
StringMap path_for;
walkSearchSkinDirs(subdir, subsubdirs, filename,
boost::bind(store_in_map, boost::ref(path_for), _1, _2));
// Now that we have a path for each of the default language and the
// current language, copy them -- in proper order -- into results.
// Don't drive this by walking the map itself: it matters that we
// generate results in the same order as subsubdirs.
BOOST_FOREACH(std::string subsubdir, subsubdirs)
{
StringMap::const_iterator found(path_for.find(subsubdir));
if (found != path_for.end())
{
results.push_back(found->second);
}
}
}
LL_DEBUGS("LLDir") << empty;
const char* comma = "";
BOOST_FOREACH(std::string path, results)
{
LL_CONT << comma << "'" << path << "'";
comma = ", ";
}
LL_CONT << LL_ENDL;
return results;
}
std::string LLDir::getTempFilename() const
@@ -657,7 +873,7 @@ std::string LLDir::getTempFilename() const
}
// static
std::string LLDir::getScrubbedFileName(const std::string uncleanFileName)
std::string LLDir::getScrubbedFileName(const std::string& uncleanFileName)
{
std::string name(uncleanFileName);
std::string illegalChars(getForbiddenFileChars());
@@ -668,8 +884,8 @@ std::string LLDir::getScrubbedFileName(const std::string uncleanFileName)
// replace any illegal file chars with and underscore '_'
for( unsigned int i = 0; i < illegalChars.length(); i++ )
{
int j = -1;
while((j = name.find(illegalChars[i])) > -1)
size_t j = std::string::npos;
while ((j = name.find(illegalChars[i])) != std::string::npos)
{
name[j] = '_';
}
@@ -683,6 +899,19 @@ std::string LLDir::getForbiddenFileChars()
return "\\/:*?\"<>|";
}
// static
std::string LLDir::getGridSpecificDir( const std::string& in, const std::string& grid )
{
std::string ret;
if (!grid.empty())
{
std::string gridlower(grid);
LLStringUtil::toLower(gridlower);
ret = in + "@" + gridlower;
}
return ret;
}
void LLDir::setLindenUserDir(const std::string &grid, const std::string &first, const std::string &last)
{
// if both first and last aren't set, assume we're grabbing the cached dir
@@ -692,15 +921,7 @@ void LLDir::setLindenUserDir(const std::string &grid, const std::string &first,
// utterly consistent with our firstname/lastname case.
std::string userlower(first+"_"+last);
LLStringUtil::toLower(userlower);
mLindenUserDir = add(getOSUserAppDir(), userlower);
if (!grid.empty())
{
std::string gridlower(grid);
LLStringUtil::toLower(gridlower);
mLindenUserDir += "@";
mLindenUserDir += gridlower;
}
mLindenUserDir = getGridSpecificDir(grid, add(getOSUserAppDir(), userlower));
}
else
{
@@ -737,7 +958,7 @@ void LLDir::makePortable()
initAppDirs(mAppName); // This is kinda lazy, but it's probably the quickest, most uniform way.
}
void LLDir::setChatLogsDir(const std::string &path)
void LLDir::setChatLogsDir( const std::string& path)
{
if (!path.empty() )
{
@@ -749,6 +970,11 @@ void LLDir::setChatLogsDir(const std::string &path)
}
}
void LLDir::updatePerAccountChatLogsDir(const std::string &grid)
{
mPerAccountChatLogsDir = getGridSpecificDir(grid, add(getChatLogsDir(), mUserName));
}
void LLDir::setPerAccountChatLogsDir(const std::string &grid, const std::string &first, const std::string &last)
{
// if both first and last aren't set, assume we're grabbing the cached dir
@@ -758,14 +984,9 @@ void LLDir::setPerAccountChatLogsDir(const std::string &grid, const std::string
// utterly consistent with our firstname/lastname case.
std::string userlower(first+"_"+last);
LLStringUtil::toLower(userlower);
mPerAccountChatLogsDir = add(getChatLogsDir(), userlower);
if (!grid.empty())
{
std::string gridlower(grid);
LLStringUtil::toLower(gridlower);
mPerAccountChatLogsDir += "@";
mPerAccountChatLogsDir += gridlower;
}
mUserName = userlower;
updatePerAccountChatLogsDir(grid);
}
else
{
@@ -773,21 +994,59 @@ void LLDir::setPerAccountChatLogsDir(const std::string &grid, const std::string
}
}
void LLDir::setSkinFolder(const std::string &skin_folder)
void LLDir::setSkinFolder(const std::string &skin_folder, const std::string& language)
{
mSkinDir = getSkinBaseDir();
append(mSkinDir, skin_folder);
LL_DEBUGS("LLDir") << "Setting skin '" << skin_folder << "', language '" << language << "'"
<< LL_ENDL;
mSkinName = skin_folder;
mLanguage = language;
// user modifications to current skin
// e.g. c:\documents and settings\users\username\application data\second life\skins\dazzle
mUserSkinDir = getOSUserAppDir();
append(mUserSkinDir, "skins_sg1");
append(mUserSkinDir, skin_folder);
// This method is called multiple times during viewer initialization. Each
// time it's called, reset mSearchSkinDirs.
mSearchSkinDirs.clear();
// base skin which is used as fallback for all skinned files
// e.g. c:\program files\secondlife\skins\default
mDefaultSkinDir = getSkinBaseDir();
append(mDefaultSkinDir, "default");
// This is always the most general of the search skin directories.
addSearchSkinDir(mDefaultSkinDir);
mSkinDir = getSkinBaseDir();
append(mSkinDir, skin_folder);
// Next level of generality is a skin installed with the viewer.
addSearchSkinDir(mSkinDir);
// user modifications to skins, current and default
// e.g. c:\documents and settings\users\username\application data\second life\skins\dazzle
mUserSkinDir = getOSUserAppDir();
append(mUserSkinDir, "skins_sg1");
mUserDefaultSkinDir = mUserSkinDir;
append(mUserDefaultSkinDir, "default");
append(mUserSkinDir, skin_folder);
// Next level of generality is user modifications to default skin...
addSearchSkinDir(mUserDefaultSkinDir);
// then user-defined skins.
addSearchSkinDir(mUserSkinDir);
}
void LLDir::addSearchSkinDir(const std::string& skindir)
{
if (std::find(mSearchSkinDirs.begin(), mSearchSkinDirs.end(), skindir) == mSearchSkinDirs.end())
{
LL_DEBUGS("LLDir") << "search skin: '" << skindir << "'" << LL_ENDL;
mSearchSkinDirs.push_back(skindir);
}
}
std::string LLDir::getSkinFolder() const
{
return mSkinName;
}
std::string LLDir::getLanguage() const
{
return mLanguage;
}
bool LLDir::setCacheDir(const std::string &path)

View File

@@ -78,7 +78,7 @@ class LLDir
virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask) = 0;
virtual std::string getCurPath() = 0;
virtual BOOL fileExists(const std::string &filename) const = 0;
virtual bool fileExists(const std::string &filename) const = 0;
const std::string findFile(const std::string& filename, const std::vector<std::string> filenames) const;
const std::string findFile(const std::string& filename, const std::string& searchPath1 = "", const std::string& searchPath2 = "", const std::string& searchPath3 = "") const;
@@ -103,11 +103,13 @@ class LLDir
const std::string &getOSCacheDir() const; // location of OS-specific cache folder (may be empty string)
const std::string &getCAFile() const; // File containing TLS certificate authorities
const std::string &getDirDelimiter() const; // directory separator for platform (ie. '\' or '/' or ':')
const std::string &getSkinDir() const; // User-specified skin folder.
const std::string &getUserSkinDir() const; // User-specified skin folder with user modifications. e.g. c:\documents and settings\username\application data\second life\skins\curskin
const std::string &getDefaultSkinDir() const; // folder for default skin. e.g. c:\program files\second life\skins\default
const std::string &getSkinDir() const; // User-specified skin folder.
const std::string &getUserDefaultSkinDir() const; // dir with user modifications to default skin
const std::string &getUserSkinDir() const; // User-specified skin folder with user modifications. e.g. c:\documents and settings\username\application data\second life\skins\curskin
const std::string getSkinBaseDir() const; // folder that contains all installed skins (not user modifications). e.g. c:\program files\second life\skins
const std::string &getLLPluginDir() const; // Directory containing plugins and plugin shell
const std::string &getUserName() const;
// Expanded filename
std::string getExpandedFilename(ELLPath location, const std::string &filename) const;
@@ -120,25 +122,80 @@ class LLDir
std::string getExtension(const std::string& filepath) const; // Excludes '.', e.g getExtension("foo.wav") == "wav"
// these methods search the various skin paths for the specified file in the following order:
// getUserSkinDir(), getSkinDir(), getDefaultSkinDir()
std::string findSkinnedFilename(const std::string &filename) const;
std::string findSkinnedFilename(const std::string &subdir, const std::string &filename) const;
std::string findSkinnedFilename(const std::string &subdir1, const std::string &subdir2, const std::string &filename) const;
// getUserSkinDir(), getUserDefaultSkinDir(), getSkinDir(), getDefaultSkinDir()
/// param value for findSkinnedFilenames(), explained below
enum ESkinConstraint { CURRENT_SKIN, ALL_SKINS };
/**
* Given a filename within skin, return an ordered sequence of paths to
* search. Nonexistent files will be filtered out -- which means that the
* vector might be empty.
*
* @param subdir Identify top-level skin subdirectory by passing one of
* LLDir::XUI (file lives under "xui" subtree), LLDir::TEXTURES (file
* lives under "textures" subtree), LLDir::SKINBASE (file lives at top
* level of skin subdirectory).
* @param filename Desired filename within subdir within skin, e.g.
* "panel_login.xml". DO NOT prepend (e.g.) "xui" or the desired language.
* @param constraint Callers perform two different kinds of processing.
* When fetching a XUI file, for instance, the existence of @a filename in
* the specified skin completely supercedes any @a filename in the default
* skin. For that case, leave the default @a constraint=CURRENT_SKIN. The
* returned vector will contain only
* ".../<i>current_skin</i>/xui/en/<i>filename</i>",
* ".../<i>current_skin</i>/xui/<i>current_language</i>/<i>filename</i>".
* But for (e.g.) "strings.xml", we want a given skin to be able to
* override only specific entries from the default skin. Any string not
* defined in the specified skin will be sought in the default skin. For
* that case, pass @a constraint=ALL_SKINS. The returned vector will
* contain at least ".../default/xui/en/strings.xml",
* ".../default/xui/<i>current_language</i>/strings.xml",
* ".../<i>current_skin</i>/xui/en/strings.xml",
* ".../<i>current_skin</i>/xui/<i>current_language</i>/strings.xml".
*/
std::vector<std::string> findSkinnedFilenames(const std::string& subdir,
const std::string& filename,
ESkinConstraint constraint=CURRENT_SKIN) const;
/// Values for findSkinnedFilenames(subdir) parameter
static const char *XUI, *TEXTURES, *SKINBASE;
/**
* Return the base-language pathname from findSkinnedFilenames(), or
* the empty string if no such file exists. Parameters are identical to
* findSkinnedFilenames(). This is shorthand for capturing the vector
* returned by findSkinnedFilenames(), checking for empty() and then
* returning front().
*/
std::string findSkinnedFilenameBaseLang(const std::string &subdir,
const std::string &filename,
ESkinConstraint constraint=CURRENT_SKIN) const;
/**
* Return the "most localized" pathname from findSkinnedFilenames(), or
* the empty string if no such file exists. Parameters are identical to
* findSkinnedFilenames(). This is shorthand for capturing the vector
* returned by findSkinnedFilenames(), checking for empty() and then
* returning back().
*/
std::string findSkinnedFilename(const std::string &subdir,
const std::string &filename,
ESkinConstraint constraint=CURRENT_SKIN) const;
// random filename in common temporary directory
std::string getTempFilename() const;
// For producing safe download file names from potentially unsafe ones
static std::string getScrubbedFileName(const std::string uncleanFileName);
static std::string getScrubbedFileName(const std::string& uncleanFileName);
static std::string getForbiddenFileChars();
static std::string getGridSpecificDir( const std::string& in, const std::string& grid );
void setDumpDir( const std::string& path );
void makePortable();
virtual void setChatLogsDir(const std::string &path); // Set the chat logs dir to this user's dir
virtual void setPerAccountChatLogsDir(const std::string &grid, const std::string &first, const std::string &last); // Set the per user chat log directory.
virtual void setPerAccountChatLogsDir(const std::string &grid, const std::string &first, const std::string& last); // Set the per user chat log directory.
virtual void setLindenUserDir(const std::string& grid, const std::string& first, const std::string& last); // Set the linden user dir to this user's dir
virtual void setSkinFolder(const std::string &skin_folder);
virtual void setSkinFolder(const std::string &skin_folder, const std::string& language);
virtual std::string getSkinFolder() const;
virtual std::string getLanguage() const;
virtual bool setCacheDir(const std::string &path);
virtual void updatePerAccountChatLogsDir(const std::string &grid);
virtual void dumpCurrentDirectories();
@@ -156,6 +213,16 @@ protected:
// Does an add() or append() call need a directory delimiter?
typedef std::pair<bool, unsigned short> SepOff;
SepOff needSep(const std::string& path, const std::string& name) const;
// build mSearchSkinDirs without adding duplicates
void addSearchSkinDir(const std::string& skindir);
// Internal to findSkinnedFilenames()
template <typename FUNCTION>
void walkSearchSkinDirs(const std::string& subdir,
const std::vector<std::string>& subsubdirs,
const std::string& filename,
const FUNCTION& function) const;
std::string mAppName; // install directory under progams/ ie "SecondLife"
std::string mExecutablePathAndName; // full path + Filename of .exe
std::string mExecutableFilename; // Filename of .exe
@@ -173,12 +240,21 @@ protected:
std::string mDefaultCacheDir; // default cache diretory
std::string mOSCacheDir; // operating system cache dir
std::string mDirDelimiter;
std::string mSkinName; // caller-specified skin name
std::string mSkinBaseDir; // Base for skins paths.
std::string mSkinDir; // Location for current skin info.
std::string mDefaultSkinDir; // Location for default skin info.
std::string mSkinDir; // Location for current skin info.
std::string mUserDefaultSkinDir; // Location for default skin info.
std::string mUserSkinDir; // Location for user-modified skin info.
// Skin directories to search, most general to most specific. This order
// works well for composing fine-grained files, in which an individual item
// in a specific file overrides the corresponding item in more general
// files. Of course, for a file-level search, iterate backwards.
std::vector<std::string> mSearchSkinDirs;
std::string mLanguage; // Current viewer language
std::string mLLPluginDir; // Location for plugins and plugin shell
static std::string sDumpDir; // Per-run crash report subdir of log directory.
std::string mUserName; // Current user name
};
void dir_exists_or_crash(const std::string &dir_name);

View File

@@ -257,7 +257,7 @@ std::string LLDir_Linux::getCurPath()
}
BOOL LLDir_Linux::fileExists(const std::string &filename) const
bool LLDir_Linux::fileExists(const std::string &filename) const
{
struct stat stat_data;
// Check the age of the file

View File

@@ -53,7 +53,7 @@ public:
virtual std::string getCurPath();
virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask);
/*virtual*/ BOOL fileExists(const std::string &filename) const;
/*virtual*/ bool fileExists(const std::string &filename) const;
/*virtual*/ std::string getLLPluginLauncher();
/*virtual*/ std::string getLLPluginFilename(std::string base_name);

View File

@@ -267,7 +267,7 @@ std::string LLDir_Mac::getCurPath()
BOOL LLDir_Mac::fileExists(const std::string &filename) const
bool LLDir_Mac::fileExists(const std::string &filename) const
{
struct stat stat_data;
// Check the age of the file

View File

@@ -52,7 +52,7 @@ public:
virtual std::string getCurPath();
virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask);
virtual BOOL fileExists(const std::string &filename) const;
virtual bool fileExists(const std::string &filename) const;
/*virtual*/ std::string getLLPluginLauncher();
/*virtual*/ std::string getLLPluginFilename(std::string base_name);

View File

@@ -278,7 +278,7 @@ std::string LLDir_Solaris::getCurPath()
}
BOOL LLDir_Solaris::fileExists(const std::string &filename) const
bool LLDir_Solaris::fileExists(const std::string &filename) const
{
struct stat stat_data;
// Check the age of the file

View File

@@ -53,7 +53,7 @@ public:
virtual std::string getCurPath();
virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask);
/*virtual*/ BOOL fileExists(const std::string &filename) const;
/*virtual*/ bool fileExists(const std::string &filename) const;
private:
DIR *mDirp;

View File

@@ -48,60 +48,28 @@ LLDir_Win32::LLDir_Win32()
WCHAR w_str[MAX_PATH];
HRESULT (WINAPI* pSHGetKnownFolderPath)(REFKNOWNFOLDERID rfid, DWORD dwFlags, HANDLE hToken, PWSTR *ppszPath) = NULL;
HMODULE shell = LoadLibrary(L"shell32");
if(shell) //SHGetSpecialFolderPath is deprecated from Vista an onwards. Try to use SHGetKnownFolderPath if it's available
{
pSHGetKnownFolderPath = (HRESULT (WINAPI *)(REFKNOWNFOLDERID, DWORD, HANDLE, PWSTR *))GetProcAddress(shell, "SHGetKnownFolderPath");
}
WCHAR* pPath = NULL;
if(SHGetKnownFolderPath(FOLDERID_RoamingAppData, 0, NULL, &pPath) == S_OK)
wcscpy_s(w_str, pPath);
// Application Data is where user settings go
if(pSHGetKnownFolderPath)
{
WCHAR* pPath = NULL;
if((*pSHGetKnownFolderPath)(FOLDERID_RoamingAppData, 0, NULL, &pPath) == S_OK)
wcscpy_s(w_str,pPath);
else
SHGetFolderPath(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_DEFAULT, w_str );
if(pPath)
CoTaskMemFree(pPath);
}
else //XP doesn't support SHGetKnownFolderPath
{
SHGetFolderPath(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_DEFAULT, w_str );
}
CoTaskMemFree(pPath);
pPath = NULL;
mOSUserDir = utf16str_to_utf8str(llutf16string(w_str));
// We want cache files to go on the local disk, even if the
// user is on a network with a "roaming profile".
//
// On XP this is:
// C:\Docments and Settings\James\Local Settings\Application Data
// On Vista this is:
// C:\Users\James\AppData\Local
// On Vista and above this is:
// C:\Users\<USERNAME>\AppData\Local
//
// We used to store the cache in AppData\Roaming, and the installer
// cleans up that version on upgrade. JC
if(SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &pPath) == S_OK)
wcscpy_s(w_str, pPath);
if(pSHGetKnownFolderPath)
{
WCHAR* pPath = NULL;
if((*pSHGetKnownFolderPath)(FOLDERID_LocalAppData, 0, NULL, &pPath) == S_OK)
wcscpy_s(w_str,pPath);
else
SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA | CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_DEFAULT, w_str );
if(pPath)
CoTaskMemFree(pPath);
}
else //XP doesn't support SHGetKnownFolderPath
{
SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA | CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_DEFAULT, w_str );
}
if(shell)
FreeLibrary(shell);
CoTaskMemFree(pPath);
pPath = NULL;
mOSCacheDir = utf16str_to_utf8str(llutf16string(w_str));
@@ -288,7 +256,7 @@ std::string LLDir_Win32::getCurPath()
}
BOOL LLDir_Win32::fileExists(const std::string &filename) const
bool LLDir_Win32::fileExists(const std::string &filename) const
{
llstat stat_data;
// Check the age of the file

View File

@@ -50,7 +50,7 @@ public:
/*virtual*/ std::string getCurPath();
/*virtual*/ U32 countFilesInDir(const std::string &dirname, const std::string &mask);
/*virtual*/ BOOL fileExists(const std::string &filename) const;
/*virtual*/ bool fileExists(const std::string &filename) const;
/*virtual*/ std::string getLLPluginLauncher();
/*virtual*/ std::string getLLPluginFilename(std::string base_name);

View File

@@ -49,7 +49,11 @@ private:
LLDirIterator::Impl::Impl(const std::string &dirname, const std::string &mask)
: mIsValid(false)
{
#if LL_WINDOWS
fs::path dir_path(utf8str_to_utf16str(dirname).c_str());
#else
fs::path dir_path(dirname);
#endif
bool is_dir = false;
@@ -58,11 +62,7 @@ LLDirIterator::Impl::Impl(const std::string &dirname, const std::string &mask)
{
is_dir = fs::is_directory(dir_path);
}
#if BOOST_FILESYSTEM_VERSION >= 3
catch (fs::filesystem_error& e)
#else
catch (fs::basic_filesystem_error<fs::path>& e)
#endif
catch (const fs::filesystem_error& e)
{
LL_WARNS() << e.what() << LL_ENDL;
return;
@@ -79,13 +79,9 @@ LLDirIterator::Impl::Impl(const std::string &dirname, const std::string &mask)
{
mIter = fs::directory_iterator(dir_path);
}
#if BOOST_FILESYSTEM_VERSION >= 3
catch (fs::filesystem_error& e)
#else
catch (fs::basic_filesystem_error<fs::path>& e)
#endif
catch (const fs::filesystem_error& e)
{
LL_ERRS() << e.what() << LL_ENDL;
LL_WARNS() << e.what() << LL_ENDL;
return;
}
@@ -101,7 +97,7 @@ LLDirIterator::Impl::Impl(const std::string &dirname, const std::string &mask)
}
catch (boost::regex_error& e)
{
LL_ERRS() << "\"" << exp << "\" is not a valid regular expression: "
LL_WARNS() << "\"" << exp << "\" is not a valid regular expression: "
<< e.what() << LL_ENDL;
return;
}
@@ -125,20 +121,26 @@ bool LLDirIterator::Impl::next(std::string &fname)
fs::directory_iterator end_itr; // default construction yields past-the-end
bool found = false;
while (mIter != end_itr && !found)
{
boost::smatch match;
#if BOOST_FILESYSTEM_VERSION >= 3
std::string name = mIter->path().filename().string();
#else
std::string name = mIter->path().filename();
#endif
if ((found = boost::regex_match(name, match, mFilterExp)))
{
fname = name;
}
++mIter;
// Check if path is a directory.
try
{
while (mIter != end_itr && !found)
{
boost::smatch match;
std::string name = mIter->path().filename().string();
found = boost::regex_match(name, match, mFilterExp);
if (found)
{
fname = name;
}
++mIter;
}
}
catch (const fs::filesystem_error& e)
{
LL_WARNS() << e.what() << LL_ENDL;
}
return found;

View File

@@ -258,6 +258,10 @@ A. Or use FXAA_GREEN_AS_LUMA.
#define FXAA_GLSL_130 0
#endif
/*--------------------------------------------------------------------------*/
#ifndef FXAA_GLSL_400
#define FXAA_GLSL_400 0
#endif
/*--------------------------------------------------------------------------*/
#ifndef FXAA_HLSL_3
#define FXAA_HLSL_3 0
#endif
@@ -344,8 +348,8 @@ A. Or use FXAA_GREEN_AS_LUMA.
// 1 = API supports gather4 on alpha channel.
// 0 = API does not support gather4 on alpha channel.
//
#if (FXAA_GLSL_130 == 0)
#define FXAA_GATHER4_ALPHA 0
#if (FXAA_GLSL_400 == 1)
#define FXAA_GATHER4_ALPHA 1
#endif
#if (FXAA_HLSL_5 == 1)
#define FXAA_GATHER4_ALPHA 1
@@ -654,7 +658,7 @@ NOTE the other tuning knobs are now in the shader function inputs!
API PORTING
============================================================================*/
#if (FXAA_GLSL_120 == 1) || (FXAA_GLSL_130 == 1)
#if (FXAA_GLSL_120 == 1) || (FXAA_GLSL_130 == 1) || (FXAA_GLSL_400 == 1)
#define FxaaBool bool
#define FxaaDiscard discard
#define FxaaFloat float
@@ -716,6 +720,16 @@ NOTE the other tuning knobs are now in the shader function inputs!
#endif
#endif
/*--------------------------------------------------------------------------*/
#if (FXAA_GLSL_400 == 1)
// Requires "#version 400" or better
#define FxaaTexTop(t, p) textureLod(t, p, 0.0)
#define FxaaTexOff(t, p, o, r) textureLodOffset(t, p, 0.0, o)
#define FxaaTexAlpha4(t, p) textureGather(t, p, 3)
#define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3)
#define FxaaTexGreen4(t, p) textureGather(t, p, 1)
#define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1)
#endif
/*--------------------------------------------------------------------------*/
#if (FXAA_HLSL_3 == 1) || (FXAA_360 == 1) || (FXAA_PS3 == 1)
#define FxaaInt2 float2
#define FxaaTex sampler2D

View File

@@ -652,7 +652,7 @@ bool LLAppViewer::init()
// set skin search path to default, will be overridden later
// this allows simple skinned file lookups to work
gDirUtilp->setSkinFolder("default");
gDirUtilp->setSkinFolder("default", "en-us");
initLogging();
@@ -725,16 +725,20 @@ bool LLAppViewer::init()
LL_INFOS("InitInfo") << "Threads initialized." << LL_ENDL ;
// Load art UUID information, don't require these strings to be declared in code.
std::string colors_base_filename = gDirUtilp->findSkinnedFilename("colors_base.xml");
LL_DEBUGS("InitInfo") << "Loading base colors from " << colors_base_filename << LL_ENDL;
gColors.loadFromFileLegacy(colors_base_filename, FALSE, TYPE_COL4U);
// Load overrides from user colors file
std::string user_colors_filename = gDirUtilp->findSkinnedFilename("colors.xml");
LL_DEBUGS("InitInfo") << "Loading user colors from " << user_colors_filename << LL_ENDL;
if (gColors.loadFromFileLegacy(user_colors_filename, FALSE, TYPE_COL4U) == 0)
for(auto& colors_base_filename : gDirUtilp->findSkinnedFilenames(LLDir::SKINBASE, "colors_base.xml", LLDir::ALL_SKINS))
{
LL_DEBUGS("InitInfo") << "Cannot load user colors from " << user_colors_filename << LL_ENDL;
LL_DEBUGS("InitInfo") << "Loading colors from " << colors_base_filename << LL_ENDL;
gColors.loadFromFileLegacy(colors_base_filename, FALSE, TYPE_COL4U);
}
// Load overrides from user colors file
for (auto& colors_base_filename : gDirUtilp->findSkinnedFilenames(LLDir::SKINBASE, "colors.xml", LLDir::ALL_SKINS))
{
gColors.loadFromFileLegacy(colors_base_filename, FALSE, TYPE_COL4U);
LL_DEBUGS("InitInfo") << "Loading user colors from " << colors_base_filename << LL_ENDL;
if (gColors.loadFromFileLegacy(colors_base_filename, FALSE, TYPE_COL4U) == 0)
{
LL_DEBUGS("InitInfo") << "Cannot load user colors from " << colors_base_filename << LL_ENDL;
}
}
// Widget construction depends on LLUI being initialized
@@ -747,6 +751,11 @@ bool LLAppViewer::init()
&LLUI::getScaleFactor());
LL_INFOS("InitInfo") << "UI initialized." << LL_ENDL ;
// NOW LLUI::getLanguage() should work. gDirUtilp must know the language
// for this session ASAP so all the file-loading commands that follow,
// that use findSkinnedFilenames(), will include the localized files.
gDirUtilp->setSkinFolder(gDirUtilp->getSkinFolder(), LLUI::getLanguage());
LLUICtrlFactory::getInstance()->setupPaths(); // update paths with correct language set
// Setup LLTrans after LLUI::initClass has been called.
@@ -2411,7 +2420,11 @@ bool LLAppViewer::initConfiguration()
const LLControlVariable* skinfolder = gSavedSettings.getControl("SkinCurrent");
if(skinfolder && LLStringUtil::null != skinfolder->getValue().asString())
{
gDirUtilp->setSkinFolder(skinfolder->getValue().asString());
// Examining "Language" may not suffice -- see LLUI::getLanguage()
// logic. Unfortunately LLUI::getLanguage() doesn't yet do us much
// good because we haven't yet called LLUI::initClass().
gDirUtilp->setSkinFolder(skinfolder->getValue().asString(),
gSavedSettings.getString("Language"));
}
// XUI:translate

View File

@@ -194,7 +194,7 @@ void LLConsole::draw()
// draw remaining lines
F32 y_pos = 0.f;
LLUIImagePtr imagep = LLUI::getUIImage("rounded_square.tga");
LLUIImagePtr imagep = LLUI::getUIImage("Rounded_Square");
static const LLCachedControl<F32> console_background_opacity("ConsoleBackgroundOpacity");
F32 console_opacity = llclamp(console_background_opacity.get(), 0.f, 1.f);

View File

@@ -421,7 +421,7 @@ void LLFastTimerView::draw()
S32 left, top, right, bottom;
S32 x, y, barw, barh, dx, dy;
S32 texth;
LLPointer<LLUIImage> box_imagep = LLUI::getUIImage("rounded_square.tga");
LLPointer<LLUIImage> box_imagep = LLUI::getUIImage("Rounded_Square");
// Draw the window background
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
@@ -884,7 +884,8 @@ void LLFastTimerView::draw()
gGL.color4fv(color.mV);
F32 start_fragment = llclamp((F32)(left - sublevel_left[level]) / (F32)sublevel_dx[level], 0.f, 1.f);
F32 end_fragment = llclamp((F32)(right - sublevel_left[level]) / (F32)sublevel_dx[level], 0.f, 1.f);
gl_segmented_rect_2d_fragment_tex(sublevel_left[level], top - level + scale_offset, sublevel_right[level], bottom + level - scale_offset, box_imagep->getTextureWidth(), box_imagep->getTextureHeight(), 16, start_fragment, end_fragment);
LLRect rect(sublevel_left[level], top - level + scale_offset, sublevel_right[level], bottom + level - scale_offset);
gl_segmented_rect_2d_fragment_tex(rect, box_imagep->getTextureWidth(), box_imagep->getTextureHeight(), 16, start_fragment, end_fragment);
}

View File

@@ -75,7 +75,7 @@ LLFontGL* LLFolderViewItem::getLabelFontForStyle(U8 style)
void LLFolderViewItem::initClass()
{
sArrowImage = LLUI::getUIImage("folder_arrow.tga");
sBoxImage = LLUI::getUIImage("rounded_square.tga");
sBoxImage = LLUI::getUIImage("Rounded_Square");
}
//static

View File

@@ -803,8 +803,8 @@ void LLHoverView::draw()
return;
}
LLUIImagePtr box_imagep = LLUI::getUIImage("rounded_square.tga");
LLUIImagePtr shadow_imagep = LLUI::getUIImage("rounded_square_soft.tga");
LLUIImagePtr box_imagep = LLUI::getUIImage("Rounded_Square");
LLUIImagePtr shadow_imagep = LLUI::getUIImage("Rounded_Square_Soft");
const LLFontGL* fontp = LLResMgr::getInstance()->getRes(LLFONT_SANSSERIF_SMALL);

View File

@@ -112,7 +112,7 @@ LLHUDNameTag::LLHUDNameTag(const U8 type)
{
LLPointer<LLHUDNameTag> ptr(this);
sTextObjects.insert(ptr);
mBubbleImage = LLUI::getUIImage("Rounded_Rect.png");
mBubbleImage = LLUI::getUIImage("Rounded_Rect");
}
LLHUDNameTag::~LLHUDNameTag()
@@ -304,29 +304,14 @@ void LLHUDNameTag::renderText(BOOL for_select)
mOffsetY = lltrunc(mHeight * ((mVertAlignment == ALIGN_VERT_CENTER) ? 0.5f : 1.f));
LLUIImagePtr imagep = mBubbleImage;
// *TODO: make this a per-text setting
static const LLCachedControl<LLColor4> background_chat_color("BackgroundChatColor", LLColor4(0,0,0,1.f));
static const LLCachedControl<F32> chat_bubble_opacity("ChatBubbleOpacity", .5);
LLColor4 bg_color = background_chat_color;
bg_color.setAlpha(chat_bubble_opacity.get() * alpha_factor);
// maybe a no-op?
//const S32 border_height = 16;
//const S32 border_width = 16;
const S32 border_height = 8;
const S32 border_width = 8;
// *TODO move this into helper function
F32 border_scale = 1.f;
if (border_height * 2 > mHeight)
{
border_scale = (F32)mHeight / ((F32)border_height * 2.f);
}
if (border_width * 2 > mWidth)
{
border_scale = llmin(border_scale, (F32)mWidth / ((F32)border_width * 2.f));
}
// scale screen size of borders down
//RN: for now, text on hud objects is never occluded
@@ -336,34 +321,42 @@ void LLHUDNameTag::renderText(BOOL for_select)
LLViewerCamera::getInstance()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec);
LLVector2 border_scale_vec((F32)border_width / (F32)mBubbleImage->getTextureWidth(), (F32)border_height / (F32)mBubbleImage->getTextureHeight());
LLVector3 width_vec = mWidth * x_pixel_vec;
LLVector3 height_vec = mHeight * y_pixel_vec;
LLVector3 scaled_border_width = (F32)llfloor(border_scale * (F32)border_width) * x_pixel_vec;
LLVector3 scaled_border_height = (F32)llfloor(border_scale * (F32)border_height) * y_pixel_vec;
mRadius = (width_vec + height_vec).magVec() * 0.5f;
LLCoordGL screen_pos;
LLViewerCamera::getInstance()->projectPosAgentToScreen(mPositionAgent, screen_pos, FALSE);
LLVector2 screen_offset;
// if (!mUseBubble)
// {
// screen_offset = mPositionOffset;
// }
// else
// {
screen_offset = updateScreenPos(mPositionOffset);
// }
LLVector2 screen_offset = updateScreenPos(mPositionOffset);
LLVector3 render_position = mPositionAgent
+ (x_pixel_vec * screen_offset.mV[VX])
+ (y_pixel_vec * screen_offset.mV[VY]);
// if (mUseBubble)
LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
LLRect screen_rect;
screen_rect.setCenterAndSize(0, static_cast<S32>(lltrunc(-mHeight / 2 + mOffsetY)), static_cast<S32>(lltrunc(mWidth)), static_cast<S32>(lltrunc(mHeight)));
imagep->draw3D(render_position, x_pixel_vec, y_pixel_vec, screen_rect, bg_color);
if (mLabelSegments.size())
{
LLUIImagePtr rect_top_image = LLUI::getUIImage("Rounded_Rect_Top");
LLRect label_top_rect = screen_rect;
const S32 label_height = ll_round((mFontp->getLineHeight() * (F32)mLabelSegments.size() + (VERTICAL_PADDING / 3.f)));
label_top_rect.mBottom = label_top_rect.mTop - label_height;
LLColor4 label_top_color = text_color;
label_top_color.mV[VALPHA] = chat_bubble_opacity * alpha_factor;
rect_top_image->draw3D(render_position, x_pixel_vec, y_pixel_vec, label_top_rect, label_top_color);
}
BOOL outside_width = llabs(mPositionOffset.mV[VX]) > mWidth * 0.5f;
BOOL outside_height = llabs(mPositionOffset.mV[VY] + (mVertAlignment == ALIGN_VERT_TOP ? mHeight * 0.5f : 0.f)) > mHeight * (mVertAlignment == ALIGN_VERT_TOP ? mHeight * 0.75f : 0.5f);
// draw line segments pointing to parent object
if (!mOffscreen && (outside_width || outside_height))
{
LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
LLUI::pushMatrix();
{
LLVector3 bg_pos = render_position
@@ -371,46 +364,9 @@ void LLHUDNameTag::renderText(BOOL for_select)
- (width_vec / 2.f)
- (height_vec);
LLUI::translate(bg_pos.mV[VX], bg_pos.mV[VY], bg_pos.mV[VZ]);
if (for_select)
/*LLUI::pushMatrix();
{
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
S32 name = mSourceObject->mGLName;
LLColor4U coloru((U8)(name >> 16), (U8)(name >> 8), (U8)name);
gGL.color4ubv(coloru.mV);
gl_segmented_rect_3d_tex(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, height_vec);
LLUI::popMatrix();
return;
}
else
{
gGL.getTexUnit(0)->bind(mBubbleImage->getImage());
gGL.color4fv(bg_color.mV);
gl_segmented_rect_3d_tex(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, height_vec);
if ( mLabelSegments.size())
{
LLUI::pushMatrix();
{
gGL.color4f(text_color.mV[VX], text_color.mV[VY], text_color.mV[VZ], chat_bubble_opacity * alpha_factor);
LLVector3 label_height = (mFontp->getLineHeight() * mLabelSegments.size() + (VERTICAL_PADDING / 3.f)) * y_pixel_vec;
LLVector3 label_offset = height_vec - label_height;
LLUI::translate(label_offset.mV[VX], label_offset.mV[VY], label_offset.mV[VZ]);
gl_segmented_rect_3d_tex_top(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, label_height);
}
LLUI::popMatrix();
}
}
BOOL outside_width = llabs(mPositionOffset.mV[VX]) > mWidth * 0.5f;
BOOL outside_height = llabs(mPositionOffset.mV[VY] + (mVertAlignment == ALIGN_VERT_TOP ? mHeight * 0.5f : 0.f)) > mHeight * (mVertAlignment == ALIGN_VERT_TOP ? mHeight * 0.75f : 0.5f);
// draw line segments pointing to parent object
if (!mOffscreen && (outside_width || outside_height))
{
LLUI::pushMatrix();
{
gGL.color4fv(bg_color.mV);
LLVector3 target_pos = -1.f * (mPositionOffset.mV[VX] * x_pixel_vec + mPositionOffset.mV[VY] * y_pixel_vec);
target_pos += (width_vec / 2.f);
@@ -419,67 +375,65 @@ void LLHUDNameTag::renderText(BOOL for_select)
target_pos -= 6.f * y_pixel_vec;
LLUI::translate(target_pos.mV[VX], target_pos.mV[VY], target_pos.mV[VZ]);
gl_segmented_rect_3d_tex(border_scale_vec, 3.f * x_pixel_vec, 3.f * y_pixel_vec, 6.f * x_pixel_vec, 6.f * y_pixel_vec);
}
LLUI::popMatrix();
}
LLUI::popMatrix();*/
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
LLGLDepthTest gls_depth(mZCompare ? GL_TRUE : GL_FALSE, GL_FALSE);
LLVector3 box_center_offset;
box_center_offset = (width_vec * 0.5f) + (height_vec * 0.5f);
LLUI::translate(box_center_offset.mV[VX], box_center_offset.mV[VY], box_center_offset.mV[VZ]);
gGL.color4fv(bg_color.mV);
LLUI::setLineWidth(2.0);
gGL.begin(LLRender::LINES);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
LLGLDepthTest gls_depth(mZCompare ? GL_TRUE : GL_FALSE, GL_FALSE);
LLVector3 box_center_offset;
box_center_offset = (width_vec * 0.5f) + (height_vec * 0.5f);
LLUI::translate(box_center_offset.mV[VX], box_center_offset.mV[VY], box_center_offset.mV[VZ]);
gGL.color4fv(bg_color.mV);
LLUI::setLineWidth(2.0);
gGL.begin(LLRender::LINES);
{
if (outside_width)
{
if (outside_width)
LLVector3 vert;
// draw line in x then y
if (mPositionOffset.mV[VX] < 0.f)
{
LLVector3 vert;
// draw line in x then y
if (mPositionOffset.mV[VX] < 0.f)
{
// start at right edge
vert = width_vec * 0.5f;
gGL.vertex3fv(vert.mV);
}
else
{
// start at left edge
vert = width_vec * -0.5f;
gGL.vertex3fv(vert.mV);
}
vert = -mPositionOffset.mV[VX] * x_pixel_vec;
gGL.vertex3fv(vert.mV);
gGL.vertex3fv(vert.mV);
vert -= mPositionOffset.mV[VY] * y_pixel_vec;
vert -= ((mVertAlignment == ALIGN_VERT_TOP) ? (height_vec * 0.5f) : LLVector3::zero);
// start at right edge
vert = width_vec * 0.5f;
gGL.vertex3fv(vert.mV);
}
else
{
LLVector3 vert;
// draw line in y then x
if (mPositionOffset.mV[VY] < 0.f)
{
// start at top edge
vert = (height_vec * 0.5f) - (mPositionOffset.mV[VX] * x_pixel_vec);
gGL.vertex3fv(vert.mV);
}
else
{
// start at bottom edge
vert = (height_vec * -0.5f) - (mPositionOffset.mV[VX] * x_pixel_vec);
gGL.vertex3fv(vert.mV);
}
vert = -mPositionOffset.mV[VY] * y_pixel_vec - mPositionOffset.mV[VX] * x_pixel_vec;
vert -= ((mVertAlignment == ALIGN_VERT_TOP) ? (height_vec * 0.5f) : LLVector3::zero);
// start at left edge
vert = width_vec * -0.5f;
gGL.vertex3fv(vert.mV);
}
vert = -mPositionOffset.mV[VX] * x_pixel_vec;
gGL.vertex3fv(vert.mV);
gGL.vertex3fv(vert.mV);
vert -= mPositionOffset.mV[VY] * y_pixel_vec;
vert -= ((mVertAlignment == ALIGN_VERT_TOP) ? (height_vec * 0.5f) : LLVector3::zero);
gGL.vertex3fv(vert.mV);
}
else
{
LLVector3 vert;
// draw line in y then x
if (mPositionOffset.mV[VY] < 0.f)
{
// start at top edge
vert = (height_vec * 0.5f) - (mPositionOffset.mV[VX] * x_pixel_vec);
gGL.vertex3fv(vert.mV);
}
else
{
// start at bottom edge
vert = (height_vec * -0.5f) - (mPositionOffset.mV[VX] * x_pixel_vec);
gGL.vertex3fv(vert.mV);
}
vert = -mPositionOffset.mV[VY] * y_pixel_vec - mPositionOffset.mV[VX] * x_pixel_vec;
vert -= ((mVertAlignment == ALIGN_VERT_TOP) ? (height_vec * 0.5f) : LLVector3::zero);
gGL.vertex3fv(vert.mV);
}
gGL.end();
LLUI::setLineWidth(1.0);
}
gGL.end();
LLUI::setLineWidth(1.0);
}
LLUI::popMatrix();
}

View File

@@ -158,7 +158,7 @@ void LLHUDText::renderText()
mOffsetY = lltrunc(mHeight * ((mVertAlignment == ALIGN_VERT_CENTER) ? 0.5f : 1.f));
// *TODO: cache this image
LLUIImagePtr imagep = LLUI::getUIImage("rounded_square.tga");
LLUIImagePtr imagep = LLUI::getUIImage("Rounded_Square");
// *TODO: make this a per-text setting
static const LLCachedControl<LLColor4> background_chat_color("BackgroundChatColor", LLColor4(0,0,0,1.f));

View File

@@ -456,7 +456,7 @@ void LLManip::renderXYZ(const LLVector3 &vec)
gGL.pushMatrix();
{
LLUIImagePtr imagep = LLUI::getUIImage("rounded_square.tga");
LLUIImagePtr imagep = LLUI::getUIImage("Rounded_Square");
gViewerWindow->setup2DRender();
const LLVector2& display_scale = gViewerWindow->getDisplayScale();
gGL.scalef(display_scale.mV[VX], display_scale.mV[VY], 1.f);

View File

@@ -595,15 +595,9 @@ void LLMediaCtrl::navigateTo( std::string url_in, std::string mime_type)
//
void LLMediaCtrl::navigateToLocalPage( const std::string& subdir, const std::string& filename_in )
{
std::string language = LLUI::getLanguage();
std::string filename(gDirUtilp->add(subdir, filename_in));
std::string expanded_filename = gDirUtilp->findSkinnedFilename("html", filename);
std::string expanded_filename = gDirUtilp->findSkinnedFilename("html", language, filename);
if (expanded_filename.empty() && language != "en-us")
{
expanded_filename = gDirUtilp->findSkinnedFilename("html", "en-us", filename);
}
if(expanded_filename.empty())
{
LL_WARNS() << "File " << filename << "not found" << LL_ENDL;

View File

@@ -497,7 +497,7 @@ void LLNotifyBox::draw()
void LLNotifyBox::drawBackground() const
{
if (LLUIImagePtr imagep = LLUI::getUIImage("rounded_square.tga"))
if (LLUIImagePtr imagep = LLUI::getUIImage("Rounded_Square"))
{
gGL.getTexUnit(0)->bind(imagep->getImage());
// set proper background color depending on whether notify box is a caution or not

View File

@@ -495,6 +495,7 @@ void LLViewerShaderMgr::setShaders()
//Flag base shader objects for deletion
//Don't worry-- they won't be deleted until no programs refrence them.
unloadShaderObjects();
cleanupShaderSources();
}
if (gViewerWindow)
@@ -513,11 +514,7 @@ void LLViewerShaderMgr::setShaders()
void LLViewerShaderMgr::unloadShaders()
{
//Instead of manually unloading, shaders are now automatically accumulated in a list.
//Simply iterate and unload.
std::vector<LLGLSLShader *> &shader_list = LLShaderMgr::getGlobalShaderList();
for(std::vector<LLGLSLShader *>::iterator it=shader_list.begin();it!=shader_list.end();++it)
(*it)->unload();
LLShaderMgr::unloadShaders();
for (S32 i = 0; i < SHADER_COUNT; i++)
mVertexShaderLevel[i] = 0;
@@ -530,15 +527,6 @@ void LLViewerShaderMgr::unloadShaders()
LLPipeline::sRenderGlow = FALSE;
}
void LLViewerShaderMgr::unloadShaderObjects()
{
std::multimap<std::string, LLShaderMgr::CachedObjectInfo >::iterator it = mShaderObjects.begin();
for (; it != mShaderObjects.end(); ++it)
if (it->second.mHandle)
glDeleteObjectARB(it->second.mHandle);
mShaderObjects.clear();
}
BOOL LLViewerShaderMgr::loadBasicShaders()
{
// Load basic dependency shaders first

View File

@@ -57,7 +57,6 @@ public:
void initAttribsAndUniforms(void);
void setShaders();
void unloadShaders();
void unloadShaderObjects();
S32 getVertexShaderLevel(S32 type);
BOOL loadBasicShaders();
BOOL loadShadersEffects();

View File

@@ -64,6 +64,7 @@
#include "llviewerstats.h"
#include "pipeline.h"
#include "llappviewer.h"
#include "llxuiparser.h"
#include "llagent.h"
#include "llviewerdisplay.h"
#include "llflexibleobject.h"
@@ -200,7 +201,7 @@ void LLViewerTextureList::doPreloadImages()
static std::string get_texture_list_name()
{
return std::string("texture_list_") + gSavedSettings.getString("LoginLocation") + ".xml";
return gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "texture_list_" + gSavedSettings.getString("LoginLocation") + ".xml");
}
void LLViewerTextureList::doPrefetchImages()
@@ -213,13 +214,22 @@ void LLViewerTextureList::doPrefetchImages()
// Pre-fetch textures from last logout
LLSD imagelist;
std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, get_texture_list_name());
std::string filename = get_texture_list_name();
llifstream file;
file.open(filename);
file.open(filename.c_str());
if (file.is_open())
{
LLSDSerialize::fromXML(imagelist, file);
if ( ! LLSDSerialize::fromXML(imagelist, file) )
{
file.close();
LL_WARNS() << "XML parse error reading texture list '" << filename << "'" << LL_ENDL;
LL_WARNS() << "Removing invalid texture list '" << filename << "'" << LL_ENDL;
LLFile::remove(filename);
return;
}
file.close();
}
S32 texture_count = 0;
for (LLSD::array_iterator iter = imagelist.beginArray();
iter != imagelist.endArray(); ++iter)
{
@@ -233,10 +243,12 @@ void LLViewerTextureList::doPrefetchImages()
LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture(uuid, MIPMAP_TRUE, LLGLTexture::BOOST_NONE, texture_type);
if (image)
{
texture_count += 1;
image->addTextureStats((F32)pixel_area);
}
}
}
LL_DEBUGS() << "fetched " << texture_count << " images from " << filename << LL_ENDL;
}
///////////////////////////////////////////////////////////////////////////////
@@ -597,22 +609,44 @@ void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image)
assert_main_thread();
llassert_always(mInitialized) ;
llassert(image);
if (!image->isInImageList())
{
LL_INFOS() << "RefCount: " << image->getNumRefs() << LL_ENDL ;
uuid_map_t::iterator iter = mUUIDMap.find(image->getID());
if(iter == mUUIDMap.end() || iter->second != image)
{
LL_INFOS() << "Image is not in mUUIDMap!" << LL_ENDL ;
}
LL_ERRS() << "LLViewerTextureList::removeImageFromList - Image not in list" << LL_ENDL;
}
S32 count = mImageList.erase(image) ;
if(count != 1)
S32 count = 0;
if (image->isInImageList())
{
LL_INFOS() << image->getID() << LL_ENDL ;
LL_ERRS() << "Error happens when remove image from mImageList: " << count << LL_ENDL ;
count = mImageList.erase(image) ;
if(count != 1)
{
LL_INFOS() << "Image " << image->getID()
<< " had mInImageList set but mImageList.erase() returned " << count
<< LL_ENDL;
}
}
else
{ // Something is wrong, image is expected in list or callers should check first
LL_INFOS() << "Calling removeImageFromList() for " << image->getID()
<< " but doesn't have mInImageList set"
<< " ref count is " << image->getNumRefs()
<< LL_ENDL;
uuid_map_t::iterator iter = mUUIDMap.find(image->getID());
if(iter == mUUIDMap.end())
{
LL_INFOS() << "Image " << image->getID() << " is also not in mUUIDMap!" << LL_ENDL ;
}
else if (iter->second != image)
{
LL_INFOS() << "Image " << image->getID() << " was in mUUIDMap but with different pointer" << LL_ENDL ;
}
else
{
LL_INFOS() << "Image " << image->getID() << " was in mUUIDMap with same pointer" << LL_ENDL ;
}
count = mImageList.erase(image) ;
if(count != 0)
{ // it was in the list already?
LL_WARNS() << "Image " << image->getID()
<< " had mInImageList false but mImageList.erase() returned " << count
<< LL_ENDL;
}
}
image->setInImageList(FALSE) ;
@@ -1540,28 +1574,31 @@ LLUIImagePtr LLUIImageList::getUIImage(const std::string& image_name, S32 priori
}
LLUIImagePtr LLUIImageList::loadUIImageByName(const std::string& name, const std::string& filename,
BOOL use_mips, const LLRect& scale_rect, const LLRect& clip_rect, LLViewerTexture::EBoostLevel boost_priority )
BOOL use_mips, const LLRect& scale_rect, const LLRect& clip_rect, LLViewerTexture::EBoostLevel boost_priority,
LLUIImage::EScaleStyle scale_style)
{
if (boost_priority == LLGLTexture::BOOST_NONE)
{
boost_priority = LLGLTexture::BOOST_UI;
}
LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTextureFromFile(filename, MIPMAP_NO, boost_priority);
return loadUIImage(imagep, name, use_mips, scale_rect, clip_rect);
return loadUIImage(imagep, name, use_mips, scale_rect, clip_rect, scale_style);
}
LLUIImagePtr LLUIImageList::loadUIImageByID(const LLUUID& id,
BOOL use_mips, const LLRect& scale_rect, const LLRect& clip_rect, LLViewerTexture::EBoostLevel boost_priority)
BOOL use_mips, const LLRect& scale_rect, const LLRect& clip_rect, LLViewerTexture::EBoostLevel boost_priority,
LLUIImage::EScaleStyle scale_style)
{
if (boost_priority == LLGLTexture::BOOST_NONE)
{
boost_priority = LLGLTexture::BOOST_UI;
}
LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(id, MIPMAP_NO, boost_priority);
return loadUIImage(imagep, id.asString(), use_mips, scale_rect, clip_rect);
return loadUIImage(imagep, id.asString(), use_mips, scale_rect, clip_rect, scale_style);
}
LLUIImagePtr LLUIImageList::loadUIImage(LLViewerFetchedTexture* imagep, const std::string& name, BOOL use_mips, const LLRect& scale_rect, const LLRect& clip_rect)
LLUIImagePtr LLUIImageList::loadUIImage(LLViewerFetchedTexture* imagep, const std::string& name, BOOL use_mips, const LLRect& scale_rect, const LLRect& clip_rect,
LLUIImage::EScaleStyle scale_style)
{
if (!imagep) return NULL;
@@ -1574,6 +1611,7 @@ LLUIImagePtr LLUIImageList::loadUIImage(LLViewerFetchedTexture* imagep, const st
imagep->setNoDelete();
LLUIImagePtr new_imagep = new LLUIImage(name, imagep);
new_imagep->setScaleStyle(scale_style);
mUIImages.insert(std::make_pair(name, new_imagep));
mUITextureList.push_back(imagep);
@@ -1592,7 +1630,7 @@ LLUIImagePtr LLUIImageList::loadUIImage(LLViewerFetchedTexture* imagep, const st
return new_imagep;
}
LLUIImagePtr LLUIImageList::preloadUIImage(const std::string& name, const std::string& filename, BOOL use_mips, const LLRect& scale_rect, const LLRect& clip_rect)
LLUIImagePtr LLUIImageList::preloadUIImage(const std::string& name, const std::string& filename, BOOL use_mips, const LLRect& scale_rect, const LLRect& clip_rect, LLUIImage::EScaleStyle scale_style)
{
// look for existing image
uuid_ui_image_map_t::iterator found_it = mUIImages.find(name);
@@ -1602,7 +1640,7 @@ LLUIImagePtr LLUIImageList::preloadUIImage(const std::string& name, const std::s
LL_ERRS() << "UI Image " << name << " already loaded." << LL_ENDL;
}
return loadUIImageByName(name, filename, use_mips, scale_rect, clip_rect);
return loadUIImageByName(name, filename, use_mips, scale_rect, clip_rect, LLGLTexture::BOOST_UI, scale_style);
}
//static
@@ -1662,20 +1700,37 @@ void LLUIImageList::onUIImageLoaded( BOOL success, LLViewerFetchedTexture *src_v
}
}
/*struct UIImageDeclaration : public LLInitParam::Block<UIImageDeclaration>
namespace LLInitParam
{
Mandatory<std::string> name;
Optional<std::string> file_name;
Optional<bool> preload;
Optional<LLRect> scale;
Optional<bool> use_mips;
template<>
struct TypeValues<LLUIImage::EScaleStyle> : public TypeValuesHelper<LLUIImage::EScaleStyle>
{
static void declareValues()
{
declare("scale_inner", LLUIImage::SCALE_INNER);
declare("scale_outer", LLUIImage::SCALE_OUTER);
}
};
}
struct UIImageDeclaration : public LLInitParam::Block<UIImageDeclaration>
{
Mandatory<std::string> name;
Optional<std::string> file_name;
Optional<bool> preload;
Optional<LLRect> scale;
Optional<LLRect> clip;
Optional<bool> use_mips;
Optional<LLUIImage::EScaleStyle> scale_type;
UIImageDeclaration()
: name("name"),
file_name("file_name"),
preload("preload", false),
scale("scale"),
use_mips("use_mips", false)
clip("clip"),
use_mips("use_mips", false),
scale_type("scale_type", LLUIImage::SCALE_INNER)
{}
};
@@ -1692,49 +1747,43 @@ struct UIImageDeclarations : public LLInitParam::Block<UIImageDeclarations>
bool LLUIImageList::initFromFile()
{
// construct path to canonical textures.xml in default skin dir
std::string base_file_path = gDirUtilp->getExpandedFilename(LL_PATH_SKINS, "default", "textures", "textures.xml");
LLXMLNodePtr root;
if (!LLXMLNode::parseFile(base_file_path, root, NULL))
// Look for textures.xml in all the right places. Pass
// constraint=LLDir::ALL_SKINS because we want to overlay textures.xml
// from all the skins directories.
std::vector<std::string> textures_paths =
gDirUtilp->findSkinnedFilenames(LLDir::TEXTURES, "textures.xml", LLDir::ALL_SKINS);
std::vector<std::string>::const_iterator pi(textures_paths.begin()), pend(textures_paths.end());
if (pi == pend)
{
LL_WARNS() << "Unable to parse UI image list file " << base_file_path << LL_ENDL;
LL_WARNS() << "No textures.xml found in skins directories" << LL_ENDL;
return false;
}
// The first (most generic) file gets special validations
LLXMLNodePtr root;
if (!LLXMLNode::parseFile(*pi, root, NULL))
{
LL_WARNS() << "Unable to parse UI image list file " << *pi << LL_ENDL;
return false;
}
if (!root->hasAttribute("version"))
{
LL_WARNS() << "No valid version number in UI image list file " << base_file_path << LL_ENDL;
LL_WARNS() << "No valid version number in UI image list file " << *pi << LL_ENDL;
return false;
}
UIImageDeclarations images;
LLXUIParser parser;
parser.readXUI(root, images, base_file_path);
parser.readXUI(root, images, *pi);
// add components defined in current skin
std::string skin_update_path = gDirUtilp->getSkinDir()
+ gDirUtilp->getDirDelimiter()
+ "textures"
+ gDirUtilp->getDirDelimiter()
+ "textures.xml";
LLXMLNodePtr update_root;
if (skin_update_path != base_file_path
&& LLXMLNode::parseFile(skin_update_path, update_root, NULL))
// add components defined in the rest of the skin paths
while (++pi != pend)
{
parser.readXUI(update_root, images, skin_update_path);
}
// add components defined in user override of current skin
skin_update_path = gDirUtilp->getUserSkinDir()
+ gDirUtilp->getDirDelimiter()
+ "textures"
+ gDirUtilp->getDirDelimiter()
+ "textures.xml";
if (skin_update_path != base_file_path
&& LLXMLNode::parseFile(skin_update_path, update_root, NULL))
{
parser.readXUI(update_root, images, skin_update_path);
LLXMLNodePtr update_root;
if (LLXMLNode::parseFile(*pi, update_root, NULL))
{
parser.readXUI(update_root, images, *pi);
}
}
if (!images.validateBlock()) return false;
@@ -1769,7 +1818,7 @@ bool LLUIImageList::initFromFile()
{
continue;
}
preloadUIImage(image.name, file_name, image.use_mips, image.scale);
preloadUIImage(image.name, file_name, image.use_mips, image.scale, image.clip, image.scale_type);
}
if (cur_pass == PASS_DECODE_NOW && !gSavedSettings.getBOOL("NoPreload"))
@@ -1778,115 +1827,6 @@ bool LLUIImageList::initFromFile()
}
}
return true;
}*/
bool LLUIImageList::initFromFile()
{
// construct path to canonical textures.xml in default skin dir
std::string base_file_path = gDirUtilp->getExpandedFilename(LL_PATH_SKINS, "default", "textures", "textures.xml");
LLXMLNodePtr root;
if (!LLXMLNode::parseFile(base_file_path, root, NULL))
{
LL_WARNS() << "Unable to parse UI image list file " << base_file_path << LL_ENDL;
return false;
}
if (!root->hasAttribute("version"))
{
LL_WARNS() << "No valid version number in UI image list file " << base_file_path << LL_ENDL;
return false;
}
std::vector<std::string> paths;
// path to current selected skin
paths.push_back(gDirUtilp->getSkinDir()
+ gDirUtilp->getDirDelimiter()
+ "textures"
+ gDirUtilp->getDirDelimiter()
+ "textures.xml");
// path to user overrides on current skin
paths.push_back(gDirUtilp->getUserSkinDir()
+ gDirUtilp->getDirDelimiter()
+ "textures"
+ gDirUtilp->getDirDelimiter()
+ "textures.xml");
// apply skinned xml files incrementally
for(std::vector<std::string>::iterator path_it = paths.begin();
path_it != paths.end();
++path_it)
{
// don't reapply base file to itself
if (!path_it->empty() && (*path_it) != base_file_path)
{
LLXMLNodePtr update_root;
if (LLXMLNode::parseFile(*path_it, update_root, NULL))
{
LLXMLNode::updateNode(root, update_root);
}
}
}
enum
{
PASS_DECODE_NOW,
PASS_DECODE_LATER,
NUM_PASSES
};
for (S32 pass = PASS_DECODE_NOW; pass < NUM_PASSES; pass++)
{
LLXMLNodePtr child_nodep = root->getFirstChild();
while(child_nodep.notNull())
{
std::string image_name;
child_nodep->getAttributeString("name", image_name);
std::string file_name = image_name;
LLRect scale_rect;
BOOL use_mip_maps = FALSE;
BOOL preload = FALSE;
child_nodep->getAttributeBOOL("preload", preload);
// load high priority textures on first pass (to kick off decode)
if (preload)
{
if (pass == PASS_DECODE_LATER)
{
child_nodep = child_nodep->getNextSibling();
continue;
}
}
else
{
if (pass == PASS_DECODE_NOW)
{
child_nodep = child_nodep->getNextSibling();
continue;
}
}
child_nodep->getAttributeString("file_name", file_name);
child_nodep->getAttributeBOOL("use_mips", use_mip_maps);
child_nodep->getAttributeS32("scale_left", scale_rect.mLeft);
child_nodep->getAttributeS32("scale_right", scale_rect.mRight);
child_nodep->getAttributeS32("scale_bottom", scale_rect.mBottom);
child_nodep->getAttributeS32("scale_top", scale_rect.mTop);
preloadUIImage(image_name, file_name, use_mip_maps, scale_rect, LLRectBase<S32>::null);
child_nodep = child_nodep->getNextSibling();
}
if (pass == PASS_DECODE_NOW && !gSavedSettings.getBOOL("NoPreload"))
{
gTextureList.decodeAllImages(10.f); // decode preloaded images
}
}
return true;
}

View File

@@ -217,20 +217,22 @@ public:
bool initFromFile();
LLPointer<LLUIImage> preloadUIImage(const std::string& name, const std::string& filename, BOOL use_mips, const LLRect& scale_rect, const LLRect& clip_rect);
LLPointer<LLUIImage> preloadUIImage(const std::string& name, const std::string& filename, BOOL use_mips, const LLRect& scale_rect, const LLRect& clip_rect, LLUIImage::EScaleStyle stype);
static void onUIImageLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata );
private:
LLPointer<LLUIImage> loadUIImageByName(const std::string& name, const std::string& filename,
BOOL use_mips = FALSE, const LLRect& scale_rect = LLRect::null,
const LLRect& clip_rect = LLRect::null,
LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_UI);
LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_UI,
LLUIImage::EScaleStyle = LLUIImage::SCALE_INNER);
LLPointer<LLUIImage> loadUIImageByID(const LLUUID& id,
BOOL use_mips = FALSE, const LLRect& scale_rect = LLRect::null,
const LLRect& clip_rect = LLRect::null,
LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_UI);
LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_UI,
LLUIImage::EScaleStyle = LLUIImage::SCALE_INNER);
LLPointer<LLUIImage> loadUIImage(LLViewerFetchedTexture* imagep, const std::string& name, BOOL use_mips = FALSE, const LLRect& scale_rect = LLRect::null, const LLRect& clip_rect = LLRect::null);
LLPointer<LLUIImage> loadUIImage(LLViewerFetchedTexture* imagep, const std::string& name, BOOL use_mips = FALSE, const LLRect& scale_rect = LLRect::null, const LLRect& clip_rect = LLRect::null, LLUIImage::EScaleStyle = LLUIImage::SCALE_INNER);
struct LLUIImageLoadData

View File

@@ -1777,8 +1777,7 @@ LLViewerWindow::LLViewerWindow(
LLFontGL::initClass( gSavedSettings.getF32("FontScreenDPI"),
mDisplayScale.mV[VX],
mDisplayScale.mV[VY],
gDirUtilp->getAppRODataDir(),
LLUICtrlFactory::getXUIPaths());
gDirUtilp->getAppRODataDir());
}
// Create container for all sub-views
LLView::Params rvp;
@@ -5425,8 +5424,7 @@ void LLViewerWindow::initFonts(F32 zoom_factor)
LLFontGL::initClass( gSavedSettings.getF32("FontScreenDPI"),
mDisplayScale.mV[VX] * zoom_factor,
mDisplayScale.mV[VY] * zoom_factor,
gDirUtilp->getAppRODataDir(),
LLUICtrlFactory::getXUIPaths());
gDirUtilp->getAppRODataDir());
LLFontGL::loadDefaultFonts();
}
void LLViewerWindow::toggleFullscreen(BOOL show_progress)

View File

@@ -149,10 +149,10 @@ void LLWorldMapView::initClass()
sHomeImage = LLUI::getUIImage("map_home.tga");
sTelehubImage = LLUI::getUIImage("map_telehub.tga");
sInfohubImage = LLUI::getUIImage("map_infohub.tga");
sEventImage = LLUI::getUIImage("map_event.tga");
sEventMatureImage = LLUI::getUIImage("map_event_mature.tga");
sEventImage = LLUI::getUIImage("Parcel_PG_Light");
sEventMatureImage = LLUI::getUIImage("Parcel_M_Light");
// To Do: update the image resource for adult events.
sEventAdultImage = LLUI::getUIImage("map_event_adult.tga");
sEventAdultImage = LLUI::getUIImage("Parcel_R_Light");
sTrackCircleImage = LLUI::getUIImage("map_track_16.tga");
sTrackArrowImage = LLUI::getUIImage("direction_arrow.tga");

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 343 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 300 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 268 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 812 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Some files were not shown because too many files have changed in this diff Show More