summaryrefslogtreecommitdiff
path: root/indra/llrender
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llrender')
-rw-r--r--indra/llrender/llfontbitmapcache.cpp7
-rw-r--r--indra/llrender/llfontbitmapcache.h7
-rw-r--r--indra/llrender/llfontgl.cpp118
-rw-r--r--indra/llrender/llfontgl.h47
-rw-r--r--indra/llrender/llfontregistry.cpp19
-rw-r--r--indra/llrender/llfontregistry.h13
-rw-r--r--indra/llrender/llgl.cpp201
-rw-r--r--indra/llrender/llgl.h9
-rw-r--r--indra/llrender/llglslshader.cpp10
-rw-r--r--indra/llrender/llimagegl.cpp53
-rw-r--r--indra/llrender/llimagegl.h14
-rw-r--r--indra/llrender/llrender.cpp5
-rw-r--r--indra/llrender/llrender.h3
-rw-r--r--indra/llrender/llrendertarget.cpp13
-rw-r--r--indra/llrender/llrendertarget.h4
-rw-r--r--indra/llrender/llvertexbuffer.cpp136
-rw-r--r--indra/llrender/llvertexbuffer.h1
17 files changed, 526 insertions, 134 deletions
diff --git a/indra/llrender/llfontbitmapcache.cpp b/indra/llrender/llfontbitmapcache.cpp
index f6321b0534..052510e6ed 100644
--- a/indra/llrender/llfontbitmapcache.cpp
+++ b/indra/llrender/llfontbitmapcache.cpp
@@ -4,7 +4,7 @@
*
* $LicenseInfo:firstyear=2008&license=viewergpl$
*
- * Copyright (c) 2008, Linden Research, Inc.
+ * Copyright (c) 2008-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
@@ -12,12 +12,13 @@
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlife.com/developers/opensource/gplv2
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
diff --git a/indra/llrender/llfontbitmapcache.h b/indra/llrender/llfontbitmapcache.h
index e5c09f8826..4beea0d026 100644
--- a/indra/llrender/llfontbitmapcache.h
+++ b/indra/llrender/llfontbitmapcache.h
@@ -4,7 +4,7 @@
*
* $LicenseInfo:firstyear=2008&license=viewergpl$
*
- * Copyright (c) 2008, Linden Research, Inc.
+ * Copyright (c) 2008-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
@@ -12,12 +12,13 @@
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlife.com/developers/opensource/gplv2
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp
index beecb6b7c1..048bfe8e0d 100644
--- a/indra/llrender/llfontgl.cpp
+++ b/indra/llrender/llfontgl.cpp
@@ -32,16 +32,20 @@
#include "linden_common.h"
-#include <boost/tokenizer.hpp>
+#include "llfontgl.h"
+// Linden library includes
#include "llfont.h"
-#include "llfontgl.h"
#include "llfontbitmapcache.h"
#include "llfontregistry.h"
#include "llgl.h"
+#include "llimagegl.h"
#include "llrender.h"
-#include "v4color.h"
#include "llstl.h"
+#include "v4color.h"
+
+// Third party library includes
+#include <boost/tokenizer.hpp>
const S32 BOLD_OFFSET = 1;
@@ -102,14 +106,6 @@ U8 LLFontGL::getStyleFromString(const std::string &style)
{
ret |= UNDERLINE;
}
- if (style.find("SHADOW") != style.npos)
- {
- ret |= DROP_SHADOW;
- }
- if (style.find("SOFT_SHADOW") != style.npos)
- {
- ret |= DROP_SHADOW_SOFT;
- }
return ret;
}
@@ -215,11 +211,11 @@ bool findOrCreateFont(LLFontGL*& fontp, const LLFontDescriptor& desc)
}
// static
-BOOL LLFontGL::initDefaultFonts(F32 screen_dpi, F32 x_scale, F32 y_scale,
+void LLFontGL::initClass(F32 screen_dpi, F32 x_scale, F32 y_scale,
const std::string& app_dir,
- const std::vector<std::string>& xui_paths)
+ const std::vector<std::string>& xui_paths,
+ bool create_gl_textures)
{
- bool succ = true;
sVertDPI = (F32)llfloor(screen_dpi * y_scale);
sHorizDPI = (F32)llfloor(screen_dpi * x_scale);
sScaleX = x_scale;
@@ -229,24 +225,30 @@ BOOL LLFontGL::initDefaultFonts(F32 screen_dpi, F32 x_scale, F32 y_scale,
// Font registry init
if (!sFontRegistry)
{
- sFontRegistry = new LLFontRegistry(xui_paths);
+ sFontRegistry = new LLFontRegistry(xui_paths, create_gl_textures);
sFontRegistry->parseFontInfo("fonts.xml");
}
else
{
sFontRegistry->reset();
}
+}
- // Force standard fonts to get generated up front.
- // This is primarily for error detection purposes.
- succ &= (NULL != getFontSansSerifSmall());
- succ &= (NULL != getFontSansSerif());
- succ &= (NULL != getFontSansSerifBig());
- succ &= (NULL != getFontSansSerifHuge());
- succ &= (NULL != getFontSansSerifBold());
- succ &= (NULL != getFontMonospace());
+// Force standard fonts to get generated up front.
+// This is primarily for error detection purposes.
+// Don't do this during initClass because it can be slow and we want to get
+// the viewer window on screen first. JC
+// static
+bool LLFontGL::loadDefaultFonts()
+{
+ bool succ = true;
+ succ &= (NULL != getFontSansSerifSmall());
+ succ &= (NULL != getFontSansSerif());
+ succ &= (NULL != getFontSansSerifBig());
+ succ &= (NULL != getFontSansSerifHuge());
+ succ &= (NULL != getFontSansSerifBold());
+ succ &= (NULL != getFontMonospace());
succ &= (NULL != getFontExtChar());
-
return succ;
}
@@ -341,6 +343,34 @@ LLFontGL* LLFontGL::getFont(const LLFontDescriptor& desc)
return sFontRegistry->getFont(desc);
}
+//static
+LLFontGL* LLFontGL::getFontByName(const std::string& name)
+{
+ // check for most common fonts first
+ if (name == "SANSSERIF")
+ {
+ return getFontSansSerif();
+ }
+ else if (name == "SANSSERIF_SMALL")
+ {
+ return getFontSansSerifSmall();
+ }
+ else if (name == "SANSSERIF_BIG")
+ {
+ return getFontSansSerifBig();
+ }
+ else if (name == "SMALL" || name == "OCRA")
+ {
+ // *BUG: Should this be "MONOSPACE"? Do we use "OCRA" anymore?
+ // Does "SMALL" mean "SERIF"?
+ return getFontMonospace();
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
BOOL LLFontGL::addChar(const llwchar wch) const
{
if (!LLFont::addChar(wch))
@@ -364,12 +394,13 @@ S32 LLFontGL::renderUTF8(const std::string &text, const S32 offset,
const LLColor4 &color,
const HAlign halign, const VAlign valign,
U8 style,
+ ShadowType shadow,
const S32 max_chars, const S32 max_pixels,
F32* right_x,
BOOL use_ellipses) const
{
LLWString wstr = utf8str_to_wstring(text);
- return render(wstr, offset, x, y, color, halign, valign, style, max_chars, max_pixels, right_x, FALSE, use_ellipses);
+ return render(wstr, offset, x, y, color, halign, valign, style, shadow, max_chars, max_pixels, right_x, FALSE, use_ellipses);
}
S32 LLFontGL::render(const LLWString &wstr,
@@ -378,6 +409,7 @@ S32 LLFontGL::render(const LLWString &wstr,
const LLColor4 &color,
const HAlign halign, const VAlign valign,
U8 style,
+ ShadowType shadow,
const S32 max_chars, S32 max_pixels,
F32* right_x,
BOOL use_embedded,
@@ -401,14 +433,14 @@ S32 LLFontGL::render(const LLWString &wstr,
style = style & (~getFontDesc().getStyle());
F32 drop_shadow_strength = 0.f;
- if (style & (DROP_SHADOW | DROP_SHADOW_SOFT))
+ if (shadow != NO_SHADOW)
{
F32 luminance;
color.calcHSL(NULL, NULL, &luminance);
drop_shadow_strength = clamp_rescale(luminance, 0.35f, 0.6f, 0.f, 1.f);
if (luminance < 0.35f)
{
- style = style & ~(DROP_SHADOW | DROP_SHADOW_SOFT);
+ shadow = NO_SHADOW;
}
}
@@ -547,7 +579,7 @@ S32 LLFontGL::render(const LLWString &wstr,
LLRectf uv_rect(0.f, 1.f, 1.f, 0.f);
LLRectf screen_rect(ext_x, ext_y + ext_height, ext_x + ext_width, ext_y);
- drawGlyph(screen_rect, uv_rect, LLColor4::white, style, drop_shadow_strength);
+ drawGlyph(screen_rect, uv_rect, LLColor4::white, style, shadow, drop_shadow_strength);
if (!label.empty())
{
@@ -559,7 +591,7 @@ S32 LLFontGL::render(const LLWString &wstr,
/*llfloor*/((ext_x + (F32)ext_image->getWidth() + EXT_X_BEARING) / sScaleX),
/*llfloor*/(cur_y / sScaleY),
color,
- halign, BASELINE, NORMAL, S32_MAX, S32_MAX, NULL,
+ halign, BASELINE, NORMAL, NO_SHADOW, S32_MAX, S32_MAX, NULL,
TRUE );
gGL.popMatrix();
}
@@ -613,7 +645,7 @@ S32 LLFontGL::render(const LLWString &wstr,
llround(cur_render_x + (F32)fgi->mXBearing) + (F32)fgi->mWidth,
llround(cur_render_y + (F32)fgi->mYBearing) - (F32)fgi->mHeight);
- drawGlyph(screen_rect, uv_rect, color, style, drop_shadow_strength);
+ drawGlyph(screen_rect, uv_rect, color, style, shadow, drop_shadow_strength);
chars_drawn++;
cur_x += fgi->mXAdvance;
@@ -671,6 +703,7 @@ S32 LLFontGL::render(const LLWString &wstr,
color,
LEFT, valign,
style,
+ shadow,
S32_MAX, max_pixels,
right_x,
FALSE);
@@ -838,13 +871,28 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch
{
if (iswspace(wch))
{
- in_word = FALSE;
+ if(wch !=(0x00A0))
+ {
+ in_word = FALSE;
+ }
+ }
+ if (iswindividual(wch))
+ {
+ if (iswpunct(wchars[i+1]))
+ {
+ in_word=TRUE;
+ }
+ else
+ {
+ in_word=FALSE;
+ start_of_last_word = i;
+ }
}
}
else
{
start_of_last_word = i;
- if (!iswspace(wch))
+ if (!iswspace(wch)||!iswindividual(wch))
{
in_word = TRUE;
}
@@ -1108,7 +1156,7 @@ void LLFontGL::renderQuad(const LLRectf& screen_rect, const LLRectf& uv_rect, F3
llfont_round_y(screen_rect.mBottom));
}
-void LLFontGL::drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4& color, U8 style, F32 drop_shadow_strength) const
+void LLFontGL::drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4& color, U8 style, ShadowType shadow, F32 drop_shadow_strength) const
{
F32 slant_offset;
slant_offset = ((style & ITALIC) ? ( -mAscender * 0.2f) : 0.f);
@@ -1128,7 +1176,7 @@ void LLFontGL::drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, con
renderQuad(screen_rect_offset, uv_rect, slant_offset);
}
}
- else if (style & DROP_SHADOW_SOFT)
+ else if (shadow == DROP_SHADOW_SOFT)
{
LLColor4 shadow_color = LLFontGL::sShadowColor;
shadow_color.mV[VALPHA] = color.mV[VALPHA] * drop_shadow_strength * DROP_SHADOW_SOFT_STRENGTH;
@@ -1161,7 +1209,7 @@ void LLFontGL::drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, con
gGL.color4fv(color.mV);
renderQuad(screen_rect, uv_rect, slant_offset);
}
- else if (style & DROP_SHADOW)
+ else if (shadow == DROP_SHADOW)
{
LLColor4 shadow_color = LLFontGL::sShadowColor;
shadow_color.mV[VALPHA] = color.mV[VALPHA] * drop_shadow_strength;
diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h
index 6cb1727ff4..204c6908af 100644
--- a/indra/llrender/llfontgl.h
+++ b/indra/llrender/llfontgl.h
@@ -34,16 +34,15 @@
#ifndef LL_LLFONTGL_H
#define LL_LLFONTGL_H
-#include "llfont.h"
-#include "llimagegl.h"
-#include "v2math.h"
#include "llcoord.h"
-#include "llrect.h"
-
+#include "llfont.h"
#include "llfontregistry.h"
+#include "llpointer.h"
+#include "llrect.h"
+#include "v2math.h"
class LLColor4;
-
+class LLImageGL;
// Key used to request a font.
class LLFontDescriptor;
@@ -73,12 +72,18 @@ public:
enum StyleFlags
{
// text style to render. May be combined (these are bit flags)
+ // TODO:: Maybe change the value to 0x01 << 0 for 1 0x01 << 1 for 2, 0x01 << 2 for 4
NORMAL = 0,
BOLD = 1,
ITALIC = 2,
- UNDERLINE = 4,
- DROP_SHADOW = 8,
- DROP_SHADOW_SOFT = 16
+ UNDERLINE = 4
+ };
+
+ enum ShadowType
+ {
+ NO_SHADOW,
+ DROP_SHADOW,
+ DROP_SHADOW_SOFT
};
// Takes a string with potentially several flags, i.e. "NORMAL|BOLD|ITALIC"
@@ -93,10 +98,14 @@ public:
LLFontGL &operator=(const LLFontGL &source);
- static BOOL initDefaultFonts(F32 screen_dpi, F32 x_scale, F32 y_scale,
+ static void initClass(F32 screen_dpi, F32 x_scale, F32 y_scale,
const std::string& app_dir,
- const std::vector<std::string>& xui_paths);
+ const std::vector<std::string>& xui_paths,
+ bool create_gl_textures = true);
+ // Load sans-serif, sans-serif-small, etc.
+ // Slow, requires multiple seconds to load fonts.
+ static bool loadDefaultFonts();
static void destroyDefaultFonts();
static void destroyAllGL();
void destroyGL();
@@ -111,17 +120,17 @@ public:
const LLColor4 &color) const
{
return renderUTF8(text, begin_offset, (F32)x, (F32)y, color,
- LEFT, BASELINE, NORMAL,
- S32_MAX, S32_MAX, NULL, FALSE);
+ LEFT, BASELINE, NORMAL, NO_SHADOW,
+ S32_MAX, S32_MAX, NULL, FALSE);
}
S32 renderUTF8(const std::string &text, const S32 begin_offset,
S32 x, S32 y,
const LLColor4 &color,
- HAlign halign, VAlign valign, U8 style = NORMAL) const
+ HAlign halign, VAlign valign, U8 style = NORMAL, ShadowType shadow = NO_SHADOW) const
{
return renderUTF8(text, begin_offset, (F32)x, (F32)y, color,
- halign, valign, style,
+ halign, valign, style, shadow,
S32_MAX, S32_MAX, NULL, FALSE);
}
@@ -133,6 +142,7 @@ public:
HAlign halign,
VAlign valign,
U8 style,
+ ShadowType shadow,
S32 max_chars,
S32 max_pixels,
F32* right_x,
@@ -143,7 +153,7 @@ public:
const LLColor4 &color) const
{
return render(text, begin_offset, x, y, color,
- LEFT, BASELINE, NORMAL,
+ LEFT, BASELINE, NORMAL, NO_SHADOW,
S32_MAX, S32_MAX, NULL, FALSE, FALSE);
}
@@ -155,6 +165,7 @@ public:
HAlign halign = LEFT,
VAlign valign = BASELINE,
U8 style = NORMAL,
+ ShadowType shadow = NO_SHADOW,
S32 max_chars = S32_MAX,
S32 max_pixels = S32_MAX,
F32* right_x=NULL,
@@ -220,7 +231,7 @@ protected:
F32 getEmbeddedCharAdvance(const embedded_data_t* ext_data) const;
void clearEmbeddedChars();
void renderQuad(const LLRectf& screen_rect, const LLRectf& uv_rect, F32 slant_amt) const;
- void drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4& color, U8 style, F32 drop_shadow_fade) const;
+ void drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4& color, U8 style, ShadowType shadow, F32 drop_shadow_fade) const;
public:
static F32 sVertDPI;
@@ -238,6 +249,8 @@ public:
static LLFontGL* getFontSansSerifBold();
static LLFontGL* getFontExtChar();
static LLFontGL* getFont(const LLFontDescriptor& desc);
+ // Use with legacy names like "SANSSERIF_SMALL" or "OCRA"
+ static LLFontGL* getFontByName(const std::string& name);
static LLColor4 sShadowColor;
diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp
index 9b5bc5d0af..18e4a6915d 100644
--- a/indra/llrender/llfontregistry.cpp
+++ b/indra/llrender/llfontregistry.cpp
@@ -5,7 +5,7 @@
*
* $LicenseInfo:firstyear=2008&license=viewergpl$
*
- * Copyright (c) 2008, Linden Research, Inc.
+ * Copyright (c) 2008-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
@@ -13,12 +13,13 @@
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlife.com/developers/opensource/gplv2
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
@@ -167,7 +168,9 @@ LLFontDescriptor LLFontDescriptor::normalize() const
return LLFontDescriptor(new_name,new_size,new_style,getFileNames());
}
-LLFontRegistry::LLFontRegistry(const string_vec_t& xui_paths)
+LLFontRegistry::LLFontRegistry(const string_vec_t& xui_paths,
+ bool create_gl_textures)
+: mCreateGLTextures(create_gl_textures)
{
// Propagate this down from LLUICtrlFactory so LLRender doesn't
// need an upstream dependency on LLUI.
@@ -215,8 +218,8 @@ bool LLFontRegistry::parseFontInfo(const std::string& xml_filename)
success = success || init_succ;
}
}
- if (success)
- dump();
+ //if (success)
+ // dump();
return success;
}
@@ -426,7 +429,9 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)
{
LLFontGL *fontp = new LLFontGL;
std::string font_path = local_path + *file_name_it;
- BOOL is_fallback = !is_first_found;
+ // *HACK: Fallback fonts don't render, so we can use that to suppress
+ // creation of OpenGL textures for test apps. JC
+ BOOL is_fallback = !is_first_found || !mCreateGLTextures;
F32 extra_scale = (is_fallback)?fallback_scale:1.0;
if (!fontp->loadFace(font_path, extra_scale * point_size,
LLFontGL::sVertDPI, LLFontGL::sHorizDPI, 2, is_fallback))
diff --git a/indra/llrender/llfontregistry.h b/indra/llrender/llfontregistry.h
index ed775eeed0..198ca0b920 100644
--- a/indra/llrender/llfontregistry.h
+++ b/indra/llrender/llfontregistry.h
@@ -5,7 +5,7 @@
*
* $LicenseInfo:firstyear=2008&license=viewergpl$
*
- * Copyright (c) 2008, Linden Research, Inc.
+ * Copyright (c) 2008-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
@@ -13,12 +13,13 @@
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlife.com/developers/opensource/gplv2
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
@@ -70,7 +71,10 @@ private:
class LLFontRegistry
{
public:
- LLFontRegistry(const string_vec_t& xui_paths);
+ // 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();
// Load standard font info from XML file(s).
@@ -108,6 +112,7 @@ private:
string_vec_t mUltimateFallbackList;
string_vec_t mXUIPaths;
+ bool mCreateGLTextures;
};
#endif // LL_LLFONTREGISTRY_H
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 61194c4ecf..7e1df0e565 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -45,10 +45,13 @@
#include "llrender.h"
#include "llerror.h"
+#include "llerrorcontrol.h"
#include "llquaternion.h"
#include "llmath.h"
#include "m4math.h"
#include "llstring.h"
+#include "llmemtype.h"
+#include "llstacktrace.h"
#include "llglheaders.h"
@@ -56,9 +59,49 @@
//#define GL_STATE_VERIFY
#endif
+
+BOOL gDebugSession = FALSE;
BOOL gDebugGL = FALSE;
BOOL gClothRipple = FALSE;
BOOL gNoRender = FALSE;
+
+std::ofstream gFailLog;
+
+void ll_init_fail_log(std::string filename)
+{
+ gFailLog.open(filename.c_str());
+}
+
+
+void ll_fail(std::string msg)
+{
+
+ if (gDebugSession)
+ {
+ std::vector<std::string> lines;
+
+ gFailLog << LLError::utcTime() << " " << msg << std::endl;
+
+ gFailLog << "Stack Trace:" << std::endl;
+
+ ll_get_stack_trace(lines);
+
+ for(size_t i = 0; i < lines.size(); ++i)
+ {
+ gFailLog << lines[i] << std::endl;
+ }
+
+ gFailLog << "End of Stack Trace." << std::endl << std::endl;
+
+ gFailLog.flush();
+ }
+};
+
+void ll_close_fail_log()
+{
+ gFailLog.close();
+}
+
LLMatrix4 gGLObliqueProjectionInverse;
#define LL_GL_NAME_POOLING 0
@@ -596,6 +639,7 @@ void LLGLManager::initExtensions()
mHasShaderObjects = FALSE;
mHasVertexShader = FALSE;
mHasFragmentShader = FALSE;
+ mHasTextureRectangle = FALSE;
#else // LL_MESA_HEADLESS
mHasMultitexture = glh_init_extensions("GL_ARB_multitexture");
mHasMipMapGeneration = glh_init_extensions("GL_SGIS_generate_mipmap");
@@ -612,6 +656,7 @@ void LLGLManager::initExtensions()
&& ExtensionExists("GL_EXT_packed_depth_stencil", gGLHExts.mSysExts);
mHasFramebufferMultisample = mHasFramebufferObject && ExtensionExists("GL_EXT_framebuffer_multisample", gGLHExts.mSysExts);
mHasDrawBuffers = ExtensionExists("GL_ARB_draw_buffers", gGLHExts.mSysExts);
+ mHasTextureRectangle = ExtensionExists("GL_ARB_texture_rectangle", gGLHExts.mSysExts);
#if !LL_DARWIN
mHasPointParameters = !mIsATI && ExtensionExists("GL_ARB_point_parameters", gGLHExts.mSysExts);
#endif
@@ -685,6 +730,7 @@ void LLGLManager::initExtensions()
if (strchr(blacklist,'q')) mHasFramebufferObject = FALSE;//S
if (strchr(blacklist,'r')) mHasDrawBuffers = FALSE;//S
if (strchr(blacklist,'s')) mHasFramebufferMultisample = FALSE;
+ if (strchr(blacklist,'t')) mHasTextureRectangle = FALSE;
}
#endif // LL_LINUX || LL_SOLARIS
@@ -971,6 +1017,7 @@ void assert_glerror()
{
return;
}
+
if (!gGLManager.mInited)
{
LL_ERRS("RenderInit") << "GL not initialized" << LL_ENDL;
@@ -988,12 +1035,22 @@ void assert_glerror()
{
LL_WARNS("RenderState") << "GL Error:" << error<< LL_ENDL;
LL_WARNS("RenderState") << "GL Error String:" << gl_error_msg << LL_ENDL;
+
+ if (gDebugSession)
+ {
+ gFailLog << "GL Error:" << gl_error_msg << std::endl;
+ }
}
else
{
// gluErrorString returns NULL for some extensions' error codes.
// you'll probably have to grep for the number in glext.h.
LL_WARNS("RenderState") << "GL Error: UNKNOWN 0x" << std::hex << error << std::dec << LL_ENDL;
+
+ if (gDebugSession)
+ {
+ gFailLog << "GL Error: UNKNOWN 0x" << std::hex << error << std::dec << std::endl;
+ }
}
error = glGetError();
#endif
@@ -1001,7 +1058,14 @@ void assert_glerror()
if (quit)
{
- llerrs << "One or more unhandled GL errors." << llendl;
+ if (gDebugSession)
+ {
+ ll_fail("assert_glerror failed");
+ }
+ else
+ {
+ llerrs << "One or more unhandled GL errors." << llendl;
+ }
}
}
@@ -1087,9 +1151,19 @@ void LLGLState::checkStates(const std::string& msg)
glGetIntegerv(GL_BLEND_SRC, &src);
glGetIntegerv(GL_BLEND_DST, &dst);
+ BOOL error = FALSE;
+
if (src != GL_SRC_ALPHA || dst != GL_ONE_MINUS_SRC_ALPHA)
{
- LL_GL_ERRS << "Blend function corrupted: " << std::hex << src << " " << std::hex << dst << " " << msg << std::dec << LL_ENDL;
+ if (gDebugSession)
+ {
+ gFailLog << "Blend function corrupted: " << std::hex << src << " " << std::hex << dst << " " << msg << std::dec << std::endl;
+ error = TRUE;
+ }
+ else
+ {
+ LL_GL_ERRS << "Blend function corrupted: " << std::hex << src << " " << std::hex << dst << " " << msg << std::dec << LL_ENDL;
+ }
}
for (std::map<LLGLenum, LLGLboolean>::iterator iter = sStateMap.begin();
@@ -1101,10 +1175,22 @@ void LLGLState::checkStates(const std::string& msg)
if(cur_state != gl_state)
{
dumpStates();
- LL_GL_ERRS << llformat("LLGLState error. State: 0x%04x",state) << LL_ENDL;
+ if (gDebugSession)
+ {
+ gFailLog << llformat("LLGLState error. State: 0x%04x",state) << std::endl;
+ error = TRUE;
+ }
+ else
+ {
+ LL_GL_ERRS << llformat("LLGLState error. State: 0x%04x",state) << LL_ENDL;
+ }
}
}
+ if (error)
+ {
+ ll_fail("LLGLState::checkStates failed.");
+ }
stop_glerror();
}
@@ -1115,9 +1201,12 @@ void LLGLState::checkTextureChannels(const std::string& msg)
return;
}
+ stop_glerror();
+
GLint activeTexture;
glGetIntegerv(GL_ACTIVE_TEXTURE_ARB, &activeTexture);
-
+ stop_glerror();
+
BOOL error = FALSE;
if (activeTexture == GL_TEXTURE0_ARB)
@@ -1125,15 +1214,22 @@ void LLGLState::checkTextureChannels(const std::string& msg)
GLint tex_env_mode = 0;
glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &tex_env_mode);
+ stop_glerror();
+
if (tex_env_mode != GL_MODULATE)
{
error = TRUE;
LL_WARNS("RenderState") << "GL_TEXTURE_ENV_MODE invalid: " << std::hex << tex_env_mode << std::dec << LL_ENDL;
+ if (gDebugSession)
+ {
+ gFailLog << "GL_TEXTURE_ENV_MODE invalid: " << std::hex << tex_env_mode << std::dec << std::endl;
+ }
}
}
- GLint maxTextureUnits;
+ GLint maxTextureUnits = 0;
glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &maxTextureUnits);
+ stop_glerror();
static const char* label[] =
{
@@ -1169,30 +1265,48 @@ void LLGLState::checkTextureChannels(const std::string& msg)
{
gGL.getTexUnit(i)->activate();
glClientActiveTextureARB(GL_TEXTURE0_ARB+i);
-
+ stop_glerror();
glGetIntegerv(GL_TEXTURE_STACK_DEPTH, &stackDepth);
+ stop_glerror();
if (stackDepth != 1)
{
error = TRUE;
LL_WARNS("RenderState") << "Texture matrix stack corrupted." << LL_ENDL;
+
+ if (gDebugSession)
+ {
+ gFailLog << "Texture matrix stack corrupted." << std::endl;
+ }
}
glGetFloatv(GL_TEXTURE_MATRIX, (GLfloat*) matrix.mMatrix);
+ stop_glerror();
if (matrix != identity)
{
error = TRUE;
LL_WARNS("RenderState") << "Texture matrix in channel " << i << " corrupt." << LL_ENDL;
+ if (gDebugSession)
+ {
+ gFailLog << "Texture matrix in channel " << i << " corrupt." << std::endl;
+ }
}
- for (S32 j = (i == 0 ? 1 : 0); j < 9; j++)
+
+ for (S32 j = (i == 0 ? 1 : 0);
+ j < (gGLManager.mHasTextureRectangle ? 9 : 8); j++)
{
if (glIsEnabled(value[j]))
{
error = TRUE;
LL_WARNS("RenderState") << "Texture channel " << i << " still has " << label[j] << " enabled." << LL_ENDL;
+ if (gDebugSession)
+ {
+ gFailLog << "Texture channel " << i << " still has " << label[j] << " enabled." << std::endl;
+ }
}
+ stop_glerror();
}
glh::matrix4f mat;
@@ -1200,20 +1314,33 @@ void LLGLState::checkTextureChannels(const std::string& msg)
identity.identity();
glGetFloatv(GL_TEXTURE_MATRIX, mat.m);
+ stop_glerror();
if (mat != identity)
{
error = TRUE;
LL_WARNS("RenderState") << "Texture matrix " << i << " is not identity." << LL_ENDL;
+ if (gDebugSession)
+ {
+ gFailLog << "Texture matrix " << i << " is not identity." << std::endl;
+ }
}
}
gGL.getTexUnit(0)->activate();
glClientActiveTextureARB(GL_TEXTURE0_ARB);
+ stop_glerror();
if (error)
{
- LL_GL_ERRS << "GL texture state corruption detected. " << msg << LL_ENDL;
+ if (gDebugSession)
+ {
+ ll_fail("LLGLState::checkTextureChannels failed.");
+ }
+ else
+ {
+ LL_GL_ERRS << "GL texture state corruption detected. " << msg << LL_ENDL;
+ }
}
}
@@ -1233,6 +1360,10 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
if (active_texture != GL_TEXTURE0_ARB)
{
llwarns << "Client active texture corrupted: " << active_texture << llendl;
+ if (gDebugSession)
+ {
+ gFailLog << "Client active texture corrupted: " << active_texture << std::endl;
+ }
error = TRUE;
}
@@ -1240,6 +1371,10 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
if (active_texture != GL_TEXTURE0_ARB)
{
llwarns << "Active texture corrupted: " << active_texture << llendl;
+ if (gDebugSession)
+ {
+ gFailLog << "Active texture corrupted: " << active_texture << std::endl;
+ }
error = TRUE;
}
@@ -1276,6 +1411,10 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
{
error = TRUE;
LL_WARNS("RenderState") << "GL still has " << label[j] << " enabled." << LL_ENDL;
+ if (gDebugSession)
+ {
+ gFailLog << "GL still has " << label[j] << " enabled." << std::endl;
+ }
}
}
else
@@ -1284,6 +1423,10 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
{
error = TRUE;
LL_WARNS("RenderState") << "GL does not have " << label[j] << " enabled." << LL_ENDL;
+ if (gDebugSession)
+ {
+ gFailLog << "GL does not have " << label[j] << " enabled." << std::endl;
+ }
}
}
}
@@ -1296,6 +1439,10 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
{
error = TRUE;
LL_WARNS("RenderState") << "GL still has GL_TEXTURE_COORD_ARRAY enabled on channel 1." << LL_ENDL;
+ if (gDebugSession)
+ {
+ gFailLog << "GL still has GL_TEXTURE_COORD_ARRAY enabled on channel 1." << std::endl;
+ }
}
}
else
@@ -1304,6 +1451,10 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
{
error = TRUE;
LL_WARNS("RenderState") << "GL does not have GL_TEXTURE_COORD_ARRAY enabled on channel 1." << LL_ENDL;
+ if (gDebugSession)
+ {
+ gFailLog << "GL does not have GL_TEXTURE_COORD_ARRAY enabled on channel 1." << std::endl;
+ }
}
}
@@ -1313,6 +1464,10 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
{
error = TRUE;
LL_WARNS("RenderState") << "GL still has GL_TEXTURE_2D enabled on channel 1." << LL_ENDL;
+ if (gDebugSession)
+ {
+ gFailLog << "GL still has GL_TEXTURE_2D enabled on channel 1." << std::endl;
+ }
}
}
else
@@ -1321,6 +1476,10 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
{
error = TRUE;
LL_WARNS("RenderState") << "GL does not have GL_TEXTURE_2D enabled on channel 1." << LL_ENDL;
+ if (gDebugSession)
+ {
+ gFailLog << "GL does not have GL_TEXTURE_2D enabled on channel 1." << std::endl;
+ }
}
}
@@ -1339,13 +1498,24 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
{
error = TRUE;
LL_WARNS("RenderState") << "GL still has vertex attrib array " << i << " enabled." << LL_ENDL;
+ if (gDebugSession)
+ {
+ gFailLog << "GL still has vertex attrib array " << i << " enabled." << std::endl;
+ }
}
}
}
if (error)
{
- LL_GL_ERRS << "GL client array corruption detected. " << msg << LL_ENDL;
+ if (gDebugSession)
+ {
+ ll_fail("LLGLState::checkClientArrays failed.");
+ }
+ else
+ {
+ LL_GL_ERRS << "GL client array corruption detected. " << msg << LL_ENDL;
+ }
}
}
@@ -1396,7 +1566,17 @@ LLGLState::~LLGLState()
{
if (gDebugGL)
{
- llassert_always(sStateMap[mState] == glIsEnabled(mState));
+ if (!gDebugSession)
+ {
+ llassert_always(sStateMap[mState] == glIsEnabled(mState));
+ }
+ else
+ {
+ if (sStateMap[mState] != glIsEnabled(mState))
+ {
+ ll_fail("GL enabled state does not match expected");
+ }
+ }
}
if (mIsEnabled != mWasEnabled)
@@ -1708,6 +1888,7 @@ void LLGLNamePool::release(GLuint name)
//static
void LLGLNamePool::upkeepPools()
{
+ LLMemType mt(LLMemType::MTYPE_UPKEEP_POOLS);
for (pool_list_t::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter)
{
LLGLNamePool* pool = *iter;
diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h
index 00ff1e2f53..34dd982259 100644
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -50,9 +50,17 @@
#include "glh/glh_linear.h"
extern BOOL gDebugGL;
+extern BOOL gDebugSession;
+extern std::ofstream gFailLog;
#define LL_GL_ERRS LL_ERRS("RenderState")
+void ll_init_fail_log(std::string filename);
+
+void ll_fail(std::string msg);
+
+void ll_close_fail_log();
+
class LLSD;
// Manage GL extensions...
@@ -88,6 +96,7 @@ public:
BOOL mHasOcclusionQuery;
BOOL mHasPointParameters;
BOOL mHasDrawBuffers;
+ BOOL mHasTextureRectangle;
// Other extensions.
BOOL mHasAnisotropic;
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 9e34144658..830617063b 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -408,7 +408,15 @@ S32 LLGLSLShader::disableTexture(S32 uniform, LLTexUnit::eTextureType mode)
{
if (gDebugGL && gGL.getTexUnit(index)->getCurrType() != mode)
{
- llerrs << "Texture channel " << index << " texture type corrupted." << llendl;
+ if (gDebugSession)
+ {
+ gFailLog << "Texture channel " << index << " texture type corrupted." << std::endl;
+ ll_fail("LLGLSLShader::disableTexture failed");
+ }
+ else
+ {
+ llerrs << "Texture channel " << index << " texture type corrupted." << llendl;
+ }
}
gGL.getTexUnit(index)->disable();
}
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index cdf626e16f..e1231eeeb4 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -54,8 +54,8 @@ LLGLuint LLImageGL::sCurrentBoundTextures[MAX_GL_TEXTURE_UNITS] = { 0 };
U32 LLImageGL::sUniqueCount = 0;
U32 LLImageGL::sBindCount = 0;
-S32 LLImageGL::sGlobalTextureMemory = 0;
-S32 LLImageGL::sBoundTextureMemory = 0;
+S32 LLImageGL::sGlobalTextureMemoryInBytes = 0;
+S32 LLImageGL::sBoundTextureMemoryInBytes = 0;
S32 LLImageGL::sCurBoundTextureMemory = 0;
S32 LLImageGL::sCount = 0;
@@ -63,6 +63,7 @@ BOOL LLImageGL::sGlobalUseAnisotropic = FALSE;
F32 LLImageGL::sLastFrameTime = 0.f;
std::set<LLImageGL*> LLImageGL::sImageList;
+
//**************************************************************************************
//below are functions for debug use
//do not delete them even though they are not currently being used.
@@ -87,9 +88,18 @@ void LLImageGL::checkTexSize() const
{
GLint texname;
glGetIntegerv(GL_TEXTURE_BINDING_2D, &texname);
+ BOOL error = FALSE;
if (texname != mTexName)
{
- llerrs << "Invalid texture bound!" << llendl;
+ error = TRUE;
+ if (gDebugSession)
+ {
+ gFailLog << "Invalid texture bound!" << std::endl;
+ }
+ else
+ {
+ llerrs << "Invalid texture bound!" << llendl;
+ }
}
stop_glerror() ;
LLGLint x = 0, y = 0 ;
@@ -102,7 +112,20 @@ void LLImageGL::checkTexSize() const
}
if(x != (mWidth >> mCurrentDiscardLevel) || y != (mHeight >> mCurrentDiscardLevel))
{
- llerrs << "wrong texture size and discard level!" << llendl ;
+ error = TRUE;
+ if (gDebugSession)
+ {
+ gFailLog << "wrong texture size and discard level!" << std::endl;
+ }
+ else
+ {
+ llerrs << "wrong texture size and discard level!" << llendl ;
+ }
+ }
+
+ if (error)
+ {
+ ll_fail("LLImageGL::checkTexSize failed.");
}
}
}
@@ -174,7 +197,7 @@ S32 LLImageGL::dataFormatComponents(S32 dataformat)
void LLImageGL::updateStats(F32 current_time)
{
sLastFrameTime = current_time;
- sBoundTextureMemory = sCurBoundTextureMemory;
+ sBoundTextureMemoryInBytes = sCurBoundTextureMemory;
sCurBoundTextureMemory = 0;
}
@@ -453,10 +476,20 @@ void LLImageGL::updateBindStats(void) const
sUniqueCount++;
updateBoundTexMem(mTextureMemory);
mLastBindTime = sLastFrameTime;
+
+ if(LLFastTimer::sMetricLog)
+ {
+ updateTestStats() ;
+ }
}
}
}
+//virtual
+void LLImageGL::updateTestStats(void) const
+{
+}
+
//virtual
bool LLImageGL::bindError(const S32 stage) const
{
@@ -680,7 +713,6 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
}
else
{
-// LLFastTimer t2(LLFastTimer::FTM_TEMP5);
S32 w = getWidth();
S32 h = getHeight();
if (is_compressed)
@@ -1013,13 +1045,13 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
if (old_name != 0)
{
- sGlobalTextureMemory -= mTextureMemory;
+ sGlobalTextureMemoryInBytes -= mTextureMemory;
LLImageGL::deleteTextures(1, &old_name);
stop_glerror();
}
mTextureMemory = getMipBytes(discard_level);
- sGlobalTextureMemory += mTextureMemory;
+ sGlobalTextureMemoryInBytes += mTextureMemory;
setActive() ;
// mark this as bound at this point, so we don't throw it out immediately
@@ -1096,7 +1128,7 @@ BOOL LLImageGL::isValidForSculpt(S32 discard_level, S32 image_width, S32 image_h
return glwidth >= image_width && glheight >= image_height && (GL_RGB8 == glcomponents || GL_RGBA8 == glcomponents) ;
}
-BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok)
+BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) const
{
llpushcallstacks ;
if (discard_level < 0)
@@ -1220,7 +1252,7 @@ void LLImageGL::destroyGLTexture()
}
}
- sGlobalTextureMemory -= mTextureMemory;
+ sGlobalTextureMemoryInBytes -= mTextureMemory;
mTextureMemory = 0;
LLImageGL::deleteTextures(1, &mTexName);
@@ -1377,7 +1409,6 @@ void LLImageGL::analyzeAlpha(const void* data_in, S32 w, S32 h)
stride = 4;
break;
default:
- llwarns << "Cannot analyze alpha of image with primary format " << std::hex << mFormatPrimary << std::dec << llendl;
return;
}
diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h
index 4f737bcaae..1775ae7de9 100644
--- a/indra/llrender/llimagegl.h
+++ b/indra/llrender/llimagegl.h
@@ -37,11 +37,15 @@
#include "llimage.h"
#include "llgltypes.h"
-#include "llmemory.h"
+#include "llpointer.h"
+#include "llrefcount.h"
#include "v2math.h"
#include "llrender.h"
+#define BYTES_TO_MEGA_BYTES(x) ((x) >> 20)
+#define MEGA_BYTES_TO_BYTES(x) ((x) << 20)
+
//============================================================================
class LLImageGL : public LLRefCount
@@ -54,6 +58,7 @@ public:
static S32 dataFormatComponents(S32 dataformat);
void updateBindStats(void) const;
+ virtual void updateTestStats(void) const;
// needs to be called every frame
static void updateStats(F32 current_time);
@@ -107,7 +112,7 @@ public:
BOOL setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos, S32 width, S32 height);
BOOL setDiscardLevel(S32 discard_level);
// Read back a raw image for this discard level, if it exists
- BOOL readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok);
+ BOOL readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) const;
void destroyGLTexture();
void setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, BOOL swap_bytes = FALSE);
@@ -238,12 +243,13 @@ public:
static LLGLuint sCurrentBoundTextures[MAX_GL_TEXTURE_UNITS]; // Currently bound texture ID
// Global memory statistics
- static S32 sGlobalTextureMemory; // Tracks main memory texmem
- static S32 sBoundTextureMemory; // Tracks bound texmem for last completed frame
+ static S32 sGlobalTextureMemoryInBytes; // Tracks main memory texmem
+ static S32 sBoundTextureMemoryInBytes; // Tracks bound texmem for last completed frame
static S32 sCurBoundTextureMemory; // Tracks bound texmem for current frame
static U32 sBindCount; // Tracks number of texture binds for current frame
static U32 sUniqueCount; // Tracks number of unique texture binds for current frame
static BOOL sGlobalUseAnisotropic;
+
#if DEBUG_MISS
BOOL mMissed; // Missed on last bind?
BOOL getMissed() const { return mMissed; };
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index 6bb217a9c2..d3a230b37b 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -189,7 +189,7 @@ bool LLTexUnit::bind(LLImageGL* texture, bool forceBind)
llwarns << "NULL LLTexUnit::bind texture" << llendl;
return false;
}
-
+
if (!texture->getTexName()) //if texture does not exist
{
//if deleted, will re-generate it immediately
@@ -785,6 +785,9 @@ void LLRender::setSceneBlendType(eBlendType type)
case BT_MULT:
glBlendFunc(GL_DST_COLOR, GL_ZERO);
break;
+ case BT_MULT_ALPHA:
+ glBlendFunc(GL_DST_ALPHA, GL_ZERO);
+ break;
case BT_MULT_X2:
glBlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
break;
diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h
index 437c715c2f..31083d8286 100644
--- a/indra/llrender/llrender.h
+++ b/indra/llrender/llrender.h
@@ -44,7 +44,7 @@
#include "v3math.h"
#include "v4coloru.h"
#include "llstrider.h"
-#include "llmemory.h"
+#include "llpointer.h"
#include "llglheaders.h"
class LLVertexBuffer;
@@ -252,6 +252,7 @@ public:
BT_ADD,
BT_ADD_WITH_ALPHA, // Additive blend modulated by the fragment's alpha.
BT_MULT,
+ BT_MULT_ALPHA,
BT_MULT_X2,
BT_REPLACE
} eBlendType;
diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp
index b7f31779ca..dc052851ca 100644
--- a/indra/llrender/llrendertarget.cpp
+++ b/indra/llrender/llrendertarget.cpp
@@ -36,6 +36,9 @@
#include "llrender.h"
#include "llgl.h"
+LLRenderTarget* LLRenderTarget::sBoundTarget = NULL;
+
+
void check_framebuffer_status()
{
@@ -46,11 +49,9 @@ void check_framebuffer_status()
{
case GL_FRAMEBUFFER_COMPLETE_EXT:
break;
- case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
- llerrs << "WTF?" << llendl;
- break;
default:
- llerrs << "WTF?" << llendl;
+ ll_fail("check_framebuffer_status failed");
+ break;
}
}
}
@@ -273,6 +274,7 @@ void LLRenderTarget::release()
}
mSampleBuffer = NULL;
+ sBoundTarget = NULL;
}
void LLRenderTarget::bindTarget()
@@ -311,6 +313,7 @@ void LLRenderTarget::bindTarget()
}
glViewport(0, 0, mResX, mResY);
+ sBoundTarget = this;
}
// static
@@ -320,6 +323,7 @@ void LLRenderTarget::unbindTarget()
{
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}
+ sBoundTarget = NULL;
}
void LLRenderTarget::clear(U32 mask_in)
@@ -532,6 +536,7 @@ void LLMultisampleBuffer::bindTarget(LLRenderTarget* ref)
glViewport(0, 0, mResX, mResY);
+ sBoundTarget = this;
}
void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, BOOL stencil, LLTexUnit::eTextureType usage, BOOL use_fbo )
diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h
index d5d809b791..98b608f834 100644
--- a/indra/llrender/llrendertarget.h
+++ b/indra/llrender/llrendertarget.h
@@ -140,6 +140,8 @@ public:
//one renderable attachment (i.e. color buffer, depth buffer).
BOOL isComplete() const;
+ static LLRenderTarget* getCurrentBoundTarget() { return sBoundTarget; }
+
protected:
friend class LLMultisampleBuffer;
U32 mResX;
@@ -153,6 +155,8 @@ protected:
LLTexUnit::eTextureType mUsage;
U32 mSamples;
LLMultisampleBuffer* mSampleBuffer;
+
+ static LLRenderTarget* sBoundTarget;
};
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 5d88ea464d..db4189dfea 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -37,7 +37,6 @@
#include "llvertexbuffer.h"
// #include "llrender.h"
#include "llglheaders.h"
-#include "llmemory.h"
#include "llmemtype.h"
#include "llrender.h"
@@ -117,6 +116,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
GL_COLOR_ARRAY,
};
+ BOOL error = FALSE;
for (U32 i = 0; i < 4; ++i)
{
if (sLastMask & mask[i])
@@ -129,7 +129,15 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
{ //needs to be enabled, make sure it was (DEBUG TEMPORARY)
if (i > 0 && !glIsEnabled(array[i]))
{
- llerrs << "Bad client state! " << array[i] << " disabled." << llendl;
+ if (gDebugSession)
+ {
+ error = TRUE;
+ gFailLog << "Bad client state! " << array[i] << " disabled." << std::endl;
+ }
+ else
+ {
+ llerrs << "Bad client state! " << array[i] << " disabled." << llendl;
+ }
}
}
}
@@ -141,11 +149,24 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
}
else if (gDebugGL && glIsEnabled(array[i]))
{ //needs to be disabled, make sure it was (DEBUG TEMPORARY)
- llerrs << "Bad client state! " << array[i] << " enabled." << llendl;
+ if (gDebugSession)
+ {
+ error = TRUE;
+ gFailLog << "Bad client state! " << array[i] << " enabled." << std::endl;
+ }
+ else
+ {
+ llerrs << "Bad client state! " << array[i] << " enabled." << llendl;
+ }
}
}
}
+ if (error)
+ {
+ ll_fail("LLVertexBuffer::setupClientArrays failed");
+ }
+
U32 map_tc[] =
{
MAP_TEXCOORD1,
@@ -315,7 +336,7 @@ void LLVertexBuffer::unbind()
//static
void LLVertexBuffer::cleanupClass()
{
- LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
+ LLMemType mt2(LLMemType::MTYPE_VERTEX_CLEANUP_CLASS);
unbind();
clientCopy(); // deletes GL buffers
}
@@ -342,7 +363,7 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
mResized(FALSE),
mDynamicSize(FALSE)
{
- LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
+ LLMemType mt2(LLMemType::MTYPE_VERTEX_CONSTRUCTOR);
if (!sEnableVBOs)
{
mUsage = 0 ;
@@ -379,7 +400,7 @@ S32 LLVertexBuffer::calcStride(const U32& typemask, S32* offsets)
//virtual
LLVertexBuffer::~LLVertexBuffer()
{
- LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
+ LLMemType mt2(LLMemType::MTYPE_VERTEX_DESTRUCTOR);
destroyGLBuffer();
destroyGLIndices();
sCount--;
@@ -459,8 +480,8 @@ void LLVertexBuffer::releaseIndices()
void LLVertexBuffer::createGLBuffer()
{
- LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
-
+ LLMemType mt2(LLMemType::MTYPE_VERTEX_CREATE_VERTICES);
+
U32 size = getSize();
if (mGLBuffer)
{
@@ -491,7 +512,7 @@ void LLVertexBuffer::createGLBuffer()
void LLVertexBuffer::createGLIndices()
{
- LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
+ LLMemType mt2(LLMemType::MTYPE_VERTEX_CREATE_INDICES);
U32 size = getIndicesSize();
if (mGLIndices)
@@ -523,7 +544,7 @@ void LLVertexBuffer::createGLIndices()
void LLVertexBuffer::destroyGLBuffer()
{
- LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
+ LLMemType mt2(LLMemType::MTYPE_VERTEX_DESTROY_BUFFER);
if (mGLBuffer)
{
if (useVBOs())
@@ -550,7 +571,7 @@ void LLVertexBuffer::destroyGLBuffer()
void LLVertexBuffer::destroyGLIndices()
{
- LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
+ LLMemType mt2(LLMemType::MTYPE_VERTEX_DESTROY_INDICES);
if (mGLIndices)
{
if (useVBOs())
@@ -577,7 +598,7 @@ void LLVertexBuffer::destroyGLIndices()
void LLVertexBuffer::updateNumVerts(S32 nverts)
{
- LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
+ LLMemType mt2(LLMemType::MTYPE_VERTEX_UPDATE_VERTS);
if (nverts >= 65535)
{
@@ -606,7 +627,7 @@ void LLVertexBuffer::updateNumVerts(S32 nverts)
void LLVertexBuffer::updateNumIndices(S32 nindices)
{
- LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
+ LLMemType mt2(LLMemType::MTYPE_VERTEX_UPDATE_INDICES);
mRequestedNumIndices = nindices;
if (!mDynamicSize)
{
@@ -627,7 +648,7 @@ void LLVertexBuffer::updateNumIndices(S32 nindices)
void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
{
- LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
+ LLMemType mt2(LLMemType::MTYPE_VERTEX_ALLOCATE_BUFFER);
updateNumVerts(nverts);
updateNumIndices(nindices);
@@ -650,7 +671,7 @@ void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices)
mRequestedNumVerts = newnverts;
mRequestedNumIndices = newnindices;
- LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
+ LLMemType mt2(LLMemType::MTYPE_VERTEX_RESIZE_BUFFER);
mDynamicSize = TRUE;
if (mUsage == GL_STATIC_DRAW_ARB)
{ //always delete/allocate static buffers on resize
@@ -779,7 +800,7 @@ BOOL LLVertexBuffer::useVBOs() const
// Map for data access
U8* LLVertexBuffer::mapBuffer(S32 access)
{
- LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
+ LLMemType mt2(LLMemType::MTYPE_VERTEX_MAP_BUFFER);
if (mFinal)
{
llerrs << "LLVertexBuffer::mapBuffer() called on a finalized buffer." << llendl;
@@ -791,13 +812,19 @@ U8* LLVertexBuffer::mapBuffer(S32 access)
if (!mLocked && useVBOs())
{
- setBuffer(0);
- mLocked = TRUE;
- stop_glerror();
- mMappedData = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
- stop_glerror();
- mMappedIndexData = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
- stop_glerror();
+ {
+ LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_VERTICES);
+ setBuffer(0);
+ mLocked = TRUE;
+ stop_glerror();
+ mMappedData = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+ stop_glerror();
+ }
+ {
+ LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_INDICES);
+ mMappedIndexData = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+ stop_glerror();
+ }
if (!mMappedData)
{
@@ -840,7 +867,7 @@ U8* LLVertexBuffer::mapBuffer(S32 access)
void LLVertexBuffer::unmapBuffer()
{
- LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
+ LLMemType mt2(LLMemType::MTYPE_VERTEX_UNMAP_BUFFER);
if (mMappedData || mMappedIndexData)
{
if (useVBOs() && mLocked)
@@ -962,7 +989,7 @@ bool LLVertexBuffer::getClothWeightStrider(LLStrider<LLVector4>& strider, S32 in
void LLVertexBuffer::setStride(S32 type, S32 new_stride)
{
- LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
+ LLMemType mt2(LLMemType::MTYPE_VERTEX_SET_STRIDE);
if (mNumVerts)
{
llerrs << "LLVertexBuffer::setOffset called with mNumVerts = " << mNumVerts << llendl;
@@ -984,7 +1011,7 @@ void LLVertexBuffer::setStride(S32 type, S32 new_stride)
// Set for rendering
void LLVertexBuffer::setBuffer(U32 data_mask)
{
- LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
+ LLMemType mt2(LLMemType::MTYPE_VERTEX_SET_BUFFER);
//set up pointers if the data mask is different ...
BOOL setup = (sLastMask != data_mask);
@@ -1016,19 +1043,36 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
sIBOActive = TRUE;
}
+ BOOL error = FALSE;
if (gDebugGL)
{
GLint buff;
glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff);
if ((GLuint)buff != mGLBuffer)
{
- llerrs << "Invalid GL vertex buffer bound: " << buff << llendl;
+ if (gDebugSession)
+ {
+ error = TRUE;
+ gFailLog << "Invalid GL vertex buffer bound: " << buff << std::endl;
+ }
+ else
+ {
+ llerrs << "Invalid GL vertex buffer bound: " << buff << llendl;
+ }
}
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
if ((GLuint)buff != mGLIndices)
{
- llerrs << "Invalid GL index buffer bound: " << buff << llendl;
+ if (gDebugSession)
+ {
+ error = TRUE;
+ gFailLog << "Invalid GL index buffer bound: " << buff << std::endl;
+ }
+ else
+ {
+ llerrs << "Invalid GL index buffer bound: " << buff << llendl;
+ }
}
}
@@ -1040,13 +1084,29 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff);
if ((GLuint)buff != mGLBuffer)
{
- llerrs << "Invalid GL vertex buffer bound: " << buff << llendl;
+ if (gDebugSession)
+ {
+ error = TRUE;
+ gFailLog << "Invalid GL vertex buffer bound: " << std::endl;
+ }
+ else
+ {
+ llerrs << "Invalid GL vertex buffer bound: " << buff << llendl;
+ }
}
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
if ((GLuint)buff != mGLIndices)
{
- llerrs << "Invalid GL index buffer bound: " << buff << llendl;
+ if (gDebugSession)
+ {
+ error = TRUE;
+ gFailLog << "Invalid GL index buffer bound: "<< std::endl;
+ }
+ else
+ {
+ llerrs << "Invalid GL index buffer bound: " << buff << llendl;
+ }
}
}
@@ -1068,10 +1128,22 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
if (data_mask != 0)
{
- llerrs << "Buffer set for rendering before being filled after resize." << llendl;
+ if (gDebugSession)
+ {
+ error = TRUE;
+ gFailLog << "Buffer set for rendering before being filled after resize." << std::endl;
+ }
+ else
+ {
+ llerrs << "Buffer set for rendering before being filled after resize." << llendl;
+ }
}
}
+ if (error)
+ {
+ ll_fail("LLVertexBuffer::mapBuffer failed");
+ }
unmapBuffer();
}
else
@@ -1122,7 +1194,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
// virtual (default)
void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const
{
- LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
+ LLMemType mt2(LLMemType::MTYPE_VERTEX_SETUP_VERTEX_BUFFER);
stop_glerror();
U8* base = useVBOs() ? NULL : mMappedData;
S32 stride = mStride;
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index aad948e17f..b785a22976 100644
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -39,7 +39,6 @@
#include "v4math.h"
#include "v4coloru.h"
#include "llstrider.h"
-#include "llmemory.h"
#include "llrender.h"
#include <set>
#include <vector>