summaryrefslogtreecommitdiff
path: root/indra/llrender
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llrender')
-rw-r--r--indra/llrender/llcubemap.cpp13
-rw-r--r--indra/llrender/llcubemaparray.cpp8
-rw-r--r--indra/llrender/llcubemaparray.h4
-rw-r--r--indra/llrender/llfontbitmapcache.cpp10
-rw-r--r--indra/llrender/llfontbitmapcache.h4
-rw-r--r--indra/llrender/llfontfreetype.cpp17
-rw-r--r--indra/llrender/llfontfreetype.h6
-rw-r--r--indra/llrender/llfontfreetypesvg.cpp20
-rw-r--r--indra/llrender/llfontfreetypesvg.h2
-rw-r--r--indra/llrender/llfontgl.cpp52
-rw-r--r--indra/llrender/llfontgl.h22
-rw-r--r--indra/llrender/llfontregistry.cpp8
-rw-r--r--indra/llrender/llgl.cpp67
-rw-r--r--indra/llrender/llgl.h70
-rw-r--r--indra/llrender/llglslshader.cpp260
-rw-r--r--indra/llrender/llglslshader.h58
-rw-r--r--indra/llrender/llgltexture.cpp67
-rw-r--r--indra/llrender/llgltexture.h42
-rw-r--r--indra/llrender/llimagegl.cpp538
-rw-r--r--indra/llrender/llimagegl.h132
-rw-r--r--indra/llrender/llpostprocess.cpp8
-rw-r--r--indra/llrender/llrender.cpp16
-rw-r--r--indra/llrender/llrender.h7
-rw-r--r--indra/llrender/llrender2dutils.cpp44
-rw-r--r--indra/llrender/llrender2dutils.h30
-rw-r--r--indra/llrender/llrendertarget.cpp84
-rw-r--r--indra/llrender/llrendertarget.h6
-rw-r--r--indra/llrender/llshadermgr.cpp127
-rw-r--r--indra/llrender/llshadermgr.h25
-rw-r--r--indra/llrender/lltexturemanagerbridge.h4
-rw-r--r--indra/llrender/lluiimage.cpp6
-rw-r--r--indra/llrender/lluiimage.inl4
-rw-r--r--indra/llrender/llvertexbuffer.cpp296
-rw-r--r--indra/llrender/llvertexbuffer.h26
34 files changed, 1197 insertions, 886 deletions
diff --git a/indra/llrender/llcubemap.cpp b/indra/llrender/llcubemap.cpp
index f16d5b6e53..26e4aaad52 100644
--- a/indra/llrender/llcubemap.cpp
+++ b/indra/llrender/llcubemap.cpp
@@ -78,7 +78,7 @@ void LLCubeMap::initGL()
for (int i = 0; i < 6; i++)
{
- mImages[i] = new LLImageGL(RESOLUTION, RESOLUTION, 4, FALSE);
+ mImages[i] = new LLImageGL(RESOLUTION, RESOLUTION, 4, false);
#if USE_SRGB_DECODE
if (mIssRGB) {
mImages[i]->setExplicitFormat(GL_SRGB8_ALPHA8, GL_RGBA);
@@ -111,6 +111,9 @@ void LLCubeMap::initRawData(const std::vector<LLPointer<LLImageRaw> >& rawimages
// Yes, I know that this is inefficient! - djs 08/08/02
for (int i = 0; i < 6; i++)
{
+ LLImageDataSharedLock lockIn(rawimages[i]);
+ LLImageDataLock lockOut(mRawImages[i]);
+
const U8 *sd = rawimages[i]->getData();
U8 *td = mRawImages[i]->getData();
@@ -173,7 +176,7 @@ void LLCubeMap::initReflectionMap(U32 resolution, U32 components)
LLImageGL::generateTextures(1, &texname);
- mImages[0] = new LLImageGL(resolution, resolution, components, TRUE);
+ mImages[0] = new LLImageGL(resolution, resolution, components, true);
mImages[0]->setTexName(texname);
mImages[0]->setTarget(mTargets[0], LLTexUnit::TT_CUBE_MAP);
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_CUBE_MAP, texname);
@@ -197,7 +200,7 @@ void LLCubeMap::initEnvironmentMap(const std::vector<LLPointer<LLImageRaw> >& ra
llassert(rawimages[i]->getHeight() == resolution);
llassert(rawimages[i]->getComponents() == components);
- mImages[i] = new LLImageGL(resolution, resolution, components, TRUE);
+ mImages[i] = new LLImageGL(resolution, resolution, components, true);
mImages[i]->setTarget(mTargets[i], LLTexUnit::TT_CUBE_MAP);
mRawImages[i] = rawimages[i];
mImages[i]->createGLTexture(0, mRawImages[i], texname);
@@ -221,8 +224,8 @@ void LLCubeMap::generateMipMaps()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- mImages[0]->setUseMipMaps(TRUE);
- mImages[0]->setHasMipMaps(TRUE);
+ mImages[0]->setUseMipMaps(true);
+ mImages[0]->setHasMipMaps(true);
enableTexture(0);
bind();
mImages[0]->setFilteringOption(LLTexUnit::TFO_BILINEAR);
diff --git a/indra/llrender/llcubemaparray.cpp b/indra/llrender/llcubemaparray.cpp
index 03fbb90bf6..be69b997da 100644
--- a/indra/llrender/llcubemaparray.cpp
+++ b/indra/llrender/llcubemaparray.cpp
@@ -42,6 +42,8 @@
//#pragma optimize("", off)
+using namespace LLImageGLMemory;
+
// MUST match order of OpenGL face-layers
GLenum LLCubeMapArray::sTargets[6] =
{
@@ -107,7 +109,7 @@ LLCubeMapArray::~LLCubeMapArray()
{
}
-void LLCubeMapArray::allocate(U32 resolution, U32 components, U32 count, BOOL use_mips)
+void LLCubeMapArray::allocate(U32 resolution, U32 components, U32 count, bool use_mips)
{
U32 texname = 0;
mWidth = resolution;
@@ -128,6 +130,8 @@ void LLCubeMapArray::allocate(U32 resolution, U32 components, U32 count, BOOL us
U32 mip = 0;
+ free_cur_tex_image();
+
while (resolution >= 1)
{
glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, format, resolution, resolution, count * 6, 0,
@@ -141,6 +145,8 @@ void LLCubeMapArray::allocate(U32 resolution, U32 components, U32 count, BOOL us
++mip;
}
+ alloc_tex_image(resolution * 6, resolution, format);
+
mImage->setAddressMode(LLTexUnit::TAM_CLAMP);
if (use_mips)
diff --git a/indra/llrender/llcubemaparray.h b/indra/llrender/llcubemaparray.h
index 9d78c5b0d4..675aaaf07c 100644
--- a/indra/llrender/llcubemaparray.h
+++ b/indra/llrender/llcubemaparray.h
@@ -51,8 +51,8 @@ public:
// res - resolution of each cube face
// components - number of components per pixel
// count - number of cube maps in the array
- // use_mips - if TRUE, mipmaps will be allocated for this cube map array and anisotropic filtering will be used
- void allocate(U32 res, U32 components, U32 count, BOOL use_mips = TRUE);
+ // use_mips - if true, mipmaps will be allocated for this cube map array and anisotropic filtering will be used
+ void allocate(U32 res, U32 components, U32 count, bool use_mips = true);
void bind(S32 stage);
void unbind();
diff --git a/indra/llrender/llfontbitmapcache.cpp b/indra/llrender/llfontbitmapcache.cpp
index 243041945a..46c2e89797 100644
--- a/indra/llrender/llfontbitmapcache.cpp
+++ b/indra/llrender/llfontbitmapcache.cpp
@@ -78,11 +78,11 @@ LLImageGL *LLFontBitmapCache::getImageGL(EFontGlyphType bitmap_type, U32 bitmap_
}
-BOOL LLFontBitmapCache::nextOpenPos(S32 width, S32& pos_x, S32& pos_y, EFontGlyphType bitmap_type, U32& bitmap_num)
+bool LLFontBitmapCache::nextOpenPos(S32 width, S32& pos_x, S32& pos_y, EFontGlyphType bitmap_type, U32& bitmap_num)
{
if (bitmap_type >= EFontGlyphType::Count)
{
- return FALSE;
+ return false;
}
const U32 bitmap_idx = static_cast<U32>(bitmap_type);
@@ -108,7 +108,7 @@ BOOL LLFontBitmapCache::nextOpenPos(S32 width, S32& pos_x, S32& pos_y, EFontGlyp
S32 num_components = getNumComponents(bitmap_type);
mImageRawVec[bitmap_idx].push_back(new LLImageRaw(mBitmapWidth, mBitmapHeight, num_components));
- bitmap_num = mImageRawVec[bitmap_idx].size() - 1;
+ bitmap_num = static_cast<U32>(mImageRawVec[bitmap_idx].size()) - 1;
LLImageRaw* image_raw = getImageRaw(bitmap_type, bitmap_num);
if (EFontGlyphType::Grayscale == bitmap_type)
@@ -126,7 +126,7 @@ BOOL LLFontBitmapCache::nextOpenPos(S32 width, S32& pos_x, S32& pos_y, EFontGlyp
// Attach corresponding GL texture. (*TODO: is this needed?)
gGL.getTexUnit(0)->bind(image_gl);
- image_gl->setFilteringOption(LLTexUnit::TFO_POINT); // was setMipFilterNearest(TRUE, TRUE);
+ image_gl->setFilteringOption(LLTexUnit::TFO_POINT); // was setMipFilterNearest(true, true);
}
else
{
@@ -142,7 +142,7 @@ BOOL LLFontBitmapCache::nextOpenPos(S32 width, S32& pos_x, S32& pos_y, EFontGlyp
mCurrentOffsetX[bitmap_idx] += width + 1;
- return TRUE;
+ return true;
}
void LLFontBitmapCache::destroyGL()
diff --git a/indra/llrender/llfontbitmapcache.h b/indra/llrender/llfontbitmapcache.h
index 8f704df44f..f2dfd87877 100644
--- a/indra/llrender/llfontbitmapcache.h
+++ b/indra/llrender/llfontbitmapcache.h
@@ -52,7 +52,7 @@ public:
void reset();
- BOOL nextOpenPos(S32 width, S32& posX, S32& posY, EFontGlyphType bitmapType, U32& bitmapNum);
+ bool nextOpenPos(S32 width, S32& posX, S32& posY, EFontGlyphType bitmapType, U32& bitmapNum);
void destroyGL();
@@ -60,7 +60,7 @@ public:
LLImageGL* getImageGL(EFontGlyphType bitmapType, U32 bitmapNum) const;
S32 getMaxCharWidth() const { return mMaxCharWidth; }
- U32 getNumBitmaps(EFontGlyphType bitmapType) const { return (bitmapType < EFontGlyphType::Count) ? mImageRawVec[static_cast<U32>(bitmapType)].size() : 0; }
+ U32 getNumBitmaps(EFontGlyphType bitmapType) const { return (bitmapType < EFontGlyphType::Count) ? static_cast<U32>(mImageRawVec[static_cast<U32>(bitmapType)].size()) : 0U; }
S32 getBitmapWidth() const { return mBitmapWidth; }
S32 getBitmapHeight() const { return mBitmapHeight; }
diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp
index 554e70d6a7..fa76669258 100644
--- a/indra/llrender/llfontfreetype.cpp
+++ b/indra/llrender/llfontfreetype.cpp
@@ -145,7 +145,7 @@ LLFontFreetype::LLFontFreetype()
pFileStream(NULL),
pFtStream(NULL),
#endif
- mIsFallback(FALSE),
+ mIsFallback(false),
mFTFace(NULL),
mRenderGlyphCount(0),
mAddGlyphCount(0),
@@ -180,7 +180,7 @@ unsigned long ft_read_cb(FT_Stream stream, unsigned long offset, unsigned char *
llifstream *file_stream = static_cast<llifstream *>(stream->descriptor.pointer);
file_stream->seekg(offset, std::ios::beg);
file_stream->read((char*)buffer, count);
- return file_stream->gcount();
+ return (unsigned long)file_stream->gcount();
}
void ft_close_cb(FT_Stream stream) {
@@ -189,7 +189,7 @@ void ft_close_cb(FT_Stream stream) {
}
#endif
-BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, bool is_fallback, S32 face_n)
+bool LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, bool is_fallback, S32 face_n)
{
// Don't leak face objects. This is also needed to deal with
// changed font file names.
@@ -214,7 +214,7 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v
#ifdef LL_WINDOWS
clearFontStreams();
#endif
- return FALSE;
+ return false;
}
mIsFallback = is_fallback;
@@ -234,7 +234,7 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v
clearFontStreams();
#endif
mFTFace = NULL;
- return FALSE;
+ return false;
}
F32 y_max, y_min, x_max, x_min;
@@ -281,7 +281,7 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v
mStyle |= LLFontGL::ITALIC;
}
- return TRUE;
+ return true;
}
S32 LLFontFreetype::getNumFaces(const std::string& filename)
@@ -330,7 +330,7 @@ S32 LLFontFreetype::ftOpenFace(const std::string& filename, S32 face_n)
pFtStream = new LLFT_Stream();
pFtStream->base = 0;
pFtStream->pos = 0;
- pFtStream->size = file_size;
+ pFtStream->size = static_cast<unsigned long>(file_size);
pFtStream->descriptor.pointer = pFileStream;
pFtStream->read = ft_read_cb;
pFtStream->close = ft_close_cb;
@@ -443,7 +443,7 @@ F32 LLFontFreetype::getXKerning(const LLFontGlyphInfo* left_glyph_info, const LL
return delta.x*(1.f/64.f);
}
-BOOL LLFontFreetype::hasGlyph(llwchar wch) const
+bool LLFontFreetype::hasGlyph(llwchar wch) const
{
llassert(!mIsFallback);
return(mCharGlyphInfoMap.find(wch) != mCharGlyphInfoMap.end());
@@ -853,6 +853,7 @@ bool LLFontFreetype::setSubImageBGRA(U32 x, U32 y, U32 bitmap_num, U16 width, U1
void LLFontFreetype::setSubImageLuminanceAlpha(U32 x, U32 y, U32 bitmap_num, U32 width, U32 height, U8 *data, S32 stride) const
{
LLImageRaw *image_raw = mFontBitmapCachep->getImageRaw(EFontGlyphType::Grayscale, bitmap_num);
+ LLImageDataLock lock(image_raw);
llassert(!mIsFallback);
llassert(image_raw && (image_raw->getComponents() == 2));
diff --git a/indra/llrender/llfontfreetype.h b/indra/llrender/llfontfreetype.h
index 19112830a4..eba89f5def 100644
--- a/indra/llrender/llfontfreetype.h
+++ b/indra/llrender/llfontfreetype.h
@@ -86,7 +86,7 @@ public:
// is_fallback should be true for fallback fonts that aren't used
// to render directly (Unicode backup, primarily)
- BOOL loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, bool is_fallback, S32 face_n);
+ bool loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, bool is_fallback, S32 face_n);
S32 getNumFaces(const std::string& filename);
@@ -153,7 +153,7 @@ private:
void resetBitmapCache();
void setSubImageLuminanceAlpha(U32 x, U32 y, U32 bitmap_num, U32 width, U32 height, U8 *data, S32 stride = 0) const;
bool setSubImageBGRA(U32 x, U32 y, U32 bitmap_num, U16 width, U16 height, const U8* data, U32 stride) const;
- BOOL hasGlyph(llwchar wch) const; // Has a glyph for this character
+ bool hasGlyph(llwchar wch) const; // Has a glyph for this character
LLFontGlyphInfo* addGlyph(llwchar wch, EFontGlyphType glyph_type) const; // Add a new character to the font if necessary
LLFontGlyphInfo* addGlyphFromFont(const LLFontFreetype *fontp, llwchar wch, U32 glyph_index, EFontGlyphType bitmap_type) const; // Add a glyph from this font to the other (returns the glyph_index, 0 if not found)
void renderGlyph(EFontGlyphType bitmap_type, U32 glyph_index) const;
@@ -175,7 +175,7 @@ private:
LLFT_Stream *pFtStream;
#endif
- BOOL mIsFallback;
+ bool mIsFallback;
typedef std::pair<LLPointer<LLFontFreetype>, char_functor_t> fallback_font_t;
typedef std::vector<fallback_font_t> fallback_font_vector_t;
fallback_font_vector_t mFallbackFonts; // A list of fallback fonts to look for glyphs in (for Unicode chars)
diff --git a/indra/llrender/llfontfreetypesvg.cpp b/indra/llrender/llfontfreetypesvg.cpp
index e33da7cf86..15251fe1b1 100644
--- a/indra/llrender/llfontfreetypesvg.cpp
+++ b/indra/llrender/llfontfreetypesvg.cpp
@@ -137,18 +137,18 @@ FT_Error LLFontFreeTypeSvgRenderer::OnPresetGlypthSlot(FT_GlyphSlot glyph_slot,
float svg_scale = llmin(svg_x_scale, svg_y_scale);
datap->Scale = svg_scale;
- glyph_slot->bitmap.width = floorf(svg_width) * svg_scale;
- glyph_slot->bitmap.rows = floorf(svg_height) * svg_scale;
+ glyph_slot->bitmap.width = (unsigned int)(floorf(svg_width) * svg_scale);
+ glyph_slot->bitmap.rows = (unsigned int)(floorf(svg_height) * svg_scale);
glyph_slot->bitmap_left = (document->metrics.x_ppem - glyph_slot->bitmap.width) / 2;
- glyph_slot->bitmap_top = glyph_slot->face->size->metrics.ascender / 64.f;
+ glyph_slot->bitmap_top = (FT_Int)(glyph_slot->face->size->metrics.ascender / 64.f);
glyph_slot->bitmap.pitch = glyph_slot->bitmap.width * 4;
glyph_slot->bitmap.pixel_mode = FT_PIXEL_MODE_BGRA;
/* Copied as-is from fcft (MIT license) */
// Compute all the bearings and set them correctly. The outline is scaled already, we just need to use the bounding box.
- float horiBearingX = 0.;
- float horiBearingY = -glyph_slot->bitmap_top;
+ float horiBearingX = 0.f;
+ float horiBearingY = -(float)glyph_slot->bitmap_top;
// XXX parentheses correct?
float vertBearingX = glyph_slot->metrics.horiBearingX / 64.0f - glyph_slot->metrics.horiAdvance / 64.0f / 2;
@@ -157,13 +157,13 @@ FT_Error LLFontFreeTypeSvgRenderer::OnPresetGlypthSlot(FT_GlyphSlot glyph_slot,
// Do conversion in two steps to avoid 'bad function cast' warning
glyph_slot->metrics.width = glyph_slot->bitmap.width * 64;
glyph_slot->metrics.height = glyph_slot->bitmap.rows * 64;
- glyph_slot->metrics.horiBearingX = horiBearingX * 64;
- glyph_slot->metrics.horiBearingY = horiBearingY * 64;
- glyph_slot->metrics.vertBearingX = vertBearingX * 64;
- glyph_slot->metrics.vertBearingY = vertBearingY * 64;
+ glyph_slot->metrics.horiBearingX = (FT_Pos)(horiBearingX * 64);
+ glyph_slot->metrics.horiBearingY = (FT_Pos)(horiBearingY * 64);
+ glyph_slot->metrics.vertBearingX = (FT_Pos)(vertBearingX * 64);
+ glyph_slot->metrics.vertBearingY = (FT_Pos)(vertBearingY * 64);
if (glyph_slot->metrics.vertAdvance == 0)
{
- glyph_slot->metrics.vertAdvance = glyph_slot->bitmap.rows * 1.2f * 64;
+ glyph_slot->metrics.vertAdvance = (FT_Pos)(glyph_slot->bitmap.rows * 1.2f * 64);
}
return FT_Err_Ok;
diff --git a/indra/llrender/llfontfreetypesvg.h b/indra/llrender/llfontfreetypesvg.h
index 62aefd10b5..94b83d5fff 100644
--- a/indra/llrender/llfontfreetypesvg.h
+++ b/indra/llrender/llfontfreetypesvg.h
@@ -50,7 +50,7 @@ public:
// - right before the svg module calls the render callback hook. (with cache == true)
static FT_Error OnPresetGlypthSlot(FT_GlyphSlot glyph_slot, FT_Bool cache, FT_Pointer* state);
- // Called to render an OT-SVG glyph (right after the preset hook OnPresetGlypthSlot was called with cache set to TRUE)
+ // Called to render an OT-SVG glyph (right after the preset hook OnPresetGlypthSlot was called with cache set to true)
static FT_Error OnRender(FT_GlyphSlot glyph_slot, FT_Pointer* state);
// Called to deallocate our per glyph slot data
diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp
index 3714bb1883..b9a4235a4e 100644
--- a/indra/llrender/llfontgl.cpp
+++ b/indra/llrender/llfontgl.cpp
@@ -58,7 +58,7 @@ F32 LLFontGL::sVertDPI = 96.f;
F32 LLFontGL::sHorizDPI = 96.f;
F32 LLFontGL::sScaleX = 1.f;
F32 LLFontGL::sScaleY = 1.f;
-BOOL LLFontGL::sDisplayFont = TRUE ;
+bool LLFontGL::sDisplayFont = true ;
std::string LLFontGL::sAppDir;
LLColor4 LLFontGL::sShadowColor(0.f, 0.f, 0.f, 1.f);
@@ -89,7 +89,7 @@ void LLFontGL::destroyGL()
mFontFreetype->destroyGL();
}
-BOOL LLFontGL::loadFace(const std::string& filename, F32 point_size, const F32 vert_dpi, const F32 horz_dpi, bool is_fallback, S32 face_n)
+bool LLFontGL::loadFace(const std::string& filename, F32 point_size, const F32 vert_dpi, const F32 horz_dpi, bool is_fallback, S32 face_n)
{
if(mFontFreetype == reinterpret_cast<LLFontFreetype*>(NULL))
{
@@ -110,14 +110,14 @@ S32 LLFontGL::getNumFaces(const std::string& filename)
}
S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, const LLRect& rect, const LLColor4 &color, HAlign halign, VAlign valign, U8 style,
- ShadowType shadow, S32 max_chars, F32* right_x, BOOL use_ellipses, BOOL use_color) const
+ ShadowType shadow, S32 max_chars, F32* right_x, bool use_ellipses, bool use_color) const
{
- LLRectf rect_float(rect.mLeft, rect.mTop, rect.mRight, rect.mBottom);
+ LLRectf rect_float((F32)rect.mLeft, (F32)rect.mTop, (F32)rect.mRight, (F32)rect.mBottom);
return render(wstr, begin_offset, rect_float, color, halign, valign, style, shadow, max_chars, right_x, use_ellipses, use_color);
}
S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, const LLRectf& rect, const LLColor4 &color, HAlign halign, VAlign valign, U8 style,
- ShadowType shadow, S32 max_chars, F32* right_x, BOOL use_ellipses, BOOL use_color) const
+ ShadowType shadow, S32 max_chars, F32* right_x, bool use_ellipses, bool use_color) const
{
F32 x = rect.mLeft;
F32 y = 0.f;
@@ -138,18 +138,18 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, const LLRectf& rec
y = rect.mBottom;
break;
}
- return render(wstr, begin_offset, x, y, color, halign, valign, style, shadow, max_chars, rect.getWidth(), right_x, use_ellipses, use_color);
+ return render(wstr, begin_offset, x, y, color, halign, valign, style, shadow, max_chars, (S32)rect.getWidth(), right_x, use_ellipses, use_color);
}
S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style,
- ShadowType shadow, S32 max_chars, S32 max_pixels, F32* right_x, BOOL use_ellipses, BOOL use_color) const
+ ShadowType shadow, S32 max_chars, S32 max_pixels, F32* right_x, bool use_ellipses, bool use_color) const
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
if(!sDisplayFont) //do not display texts
{
- return wstr.length() ;
+ return static_cast<S32>(wstr.length());
}
if (wstr.empty())
@@ -254,7 +254,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
const S32 LAST_CHARACTER = LLFontFreetype::LAST_CHAR_FULL;
- BOOL draw_ellipses = FALSE;
+ bool draw_ellipses = false;
if (use_ellipses)
{
// check for too long of a string
@@ -264,7 +264,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
// use four dots for ellipsis width to generate padding
const LLWString dots(utf8str_to_wstring(std::string("....")));
scaled_max_pixels = llmax(0, scaled_max_pixels - ll_round(getWidthF32(dots.c_str())));
- draw_ellipses = TRUE;
+ draw_ellipses = true;
}
}
@@ -278,7 +278,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
LLColor4U text_color(color);
// Preserve the transparency to render fading emojis in fading text (e.g.
// for the chat console)... HB
- LLColor4U emoji_color(255, 255, 255, text_color.mV[VW]);
+ LLColor4U emoji_color(255, 255, 255, text_color.mV[VALPHA]);
std::pair<EFontGlyphType, S32> bitmap_entry = std::make_pair(EFontGlyphType::Grayscale, -1);
S32 glyph_count = 0;
@@ -415,7 +415,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
shadow,
S32_MAX, max_pixels,
right_x,
- FALSE,
+ false,
use_color);
gGL.popUIMatrix();
}
@@ -430,7 +430,7 @@ S32 LLFontGL::render(const LLWString &text, S32 begin_offset, F32 x, F32 y, cons
return render(text, begin_offset, x, y, color, LEFT, BASELINE, NORMAL, NO_SHADOW);
}
-S32 LLFontGL::renderUTF8(const std::string &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, ShadowType shadow, S32 max_chars, S32 max_pixels, F32* right_x, BOOL use_ellipses, BOOL use_color) const
+S32 LLFontGL::renderUTF8(const std::string &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, ShadowType shadow, S32 max_chars, S32 max_pixels, F32* right_x, bool use_ellipses, bool use_color) const
{
return render(utf8str_to_wstring(text), begin_offset, x, y, color, halign, valign, style, shadow, max_chars, max_pixels, right_x, use_ellipses, use_color);
}
@@ -560,7 +560,7 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, S32 begin_offset, S32 max_chars
void LLFontGL::generateASCIIglyphs()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_UI
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
for (U32 i = 32; (i < 127); i++)
{
mFontFreetype->getGlyphInfo(i, EFontGlyphType::Grayscale);
@@ -570,7 +570,7 @@ void LLFontGL::generateASCIIglyphs()
// Returns the max number of complete characters from text (up to max_chars) that can be drawn in max_pixels
S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars, EWordWrapStyle end_on_word_boundary) const
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_UI
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
if (!wchars || !wchars[0] || max_chars == 0)
{
return 0;
@@ -579,11 +579,11 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch
llassert(max_pixels >= 0.f);
llassert(max_chars >= 0);
- BOOL clip = FALSE;
+ bool clip = false;
F32 cur_x = 0;
S32 start_of_last_word = 0;
- BOOL in_word = FALSE;
+ bool in_word = false;
// avoid S32 overflow when max_pixels == S32_MAX by staying in floating point
F32 scaled_max_pixels = max_pixels * sScaleX;
@@ -608,18 +608,18 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch
{
if(wch !=(0x00A0))
{
- in_word = FALSE;
+ in_word = false;
}
}
if (iswindividual(wch))
{
if (iswpunct(wchars[i+1]))
{
- in_word=TRUE;
+ in_word=true;
}
else
{
- in_word=FALSE;
+ in_word=false;
start_of_last_word = i;
}
}
@@ -629,7 +629,7 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch
start_of_last_word = i;
if (!iswspace(wch)||!iswindividual(wch))
{
- in_word = TRUE;
+ in_word = true;
}
}
@@ -655,7 +655,7 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch
// clip if current character runs past scaled_max_pixels (using width_padding)
if (scaled_max_pixels < cur_x + width_padding)
{
- clip = TRUE;
+ clip = true;
break;
}
@@ -753,7 +753,7 @@ S32 LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_
}
-S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, S32 begin_offset, F32 target_x, F32 max_pixels, S32 max_chars, BOOL round) const
+S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, S32 begin_offset, F32 target_x, F32 max_pixels, S32 max_chars, bool round) const
{
if (!wchars || !wchars[0] || max_chars == 0)
{
@@ -881,7 +881,7 @@ void LLFontGL::dumpFontTextures()
// static
bool LLFontGL::loadDefaultFonts()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_UI
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
bool succ = true;
succ &= (NULL != getFontSansSerifSmall());
succ &= (NULL != getFontSansSerif());
@@ -894,7 +894,7 @@ bool LLFontGL::loadDefaultFonts()
void LLFontGL::loadCommonFonts()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_UI
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
getFont(LLFontDescriptor("SansSerif", "Small", BOLD));
getFont(LLFontDescriptor("SansSerif", "Large", BOLD));
getFont(LLFontDescriptor("SansSerif", "Huge", BOLD));
@@ -1165,7 +1165,7 @@ LLFontGL* LLFontGL::getFontDefault()
std::string LLFontGL::getFontPathSystem()
{
#if LL_DARWIN
- // HACK for Mac OS X
+ // HACK for macOS
return "/System/Library/Fonts/";
#elif LL_WINDOWS
diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h
index 65f0a8cbfd..de7529a583 100644
--- a/indra/llrender/llfontgl.h
+++ b/indra/llrender/llfontgl.h
@@ -87,7 +87,7 @@ public:
void destroyGL();
- BOOL loadFace(const std::string& filename, F32 point_size, const F32 vert_dpi, const F32 horz_dpi, bool is_fallback, S32 face_n);
+ bool loadFace(const std::string& filename, F32 point_size, const F32 vert_dpi, const F32 horz_dpi, bool is_fallback, S32 face_n);
S32 getNumFaces(const std::string& filename);
@@ -98,8 +98,8 @@ public:
U8 style = NORMAL, ShadowType shadow = NO_SHADOW,
S32 max_chars = S32_MAX,
F32* right_x=NULL,
- BOOL use_ellipses = FALSE,
- BOOL use_color = TRUE) const;
+ bool use_ellipses = false,
+ bool use_color = true) const;
S32 render(const LLWString &text, S32 begin_offset,
const LLRectf& rect,
@@ -108,8 +108,8 @@ public:
U8 style = NORMAL, ShadowType shadow = NO_SHADOW,
S32 max_chars = S32_MAX,
F32* right_x=NULL,
- BOOL use_ellipses = FALSE,
- BOOL use_color = TRUE) const;
+ bool use_ellipses = false,
+ bool use_color = true) const;
S32 render(const LLWString &text, S32 begin_offset,
F32 x, F32 y,
@@ -118,13 +118,13 @@ public:
U8 style = NORMAL, ShadowType shadow = NO_SHADOW,
S32 max_chars = S32_MAX, S32 max_pixels = S32_MAX,
F32* right_x=NULL,
- BOOL use_ellipses = FALSE,
- BOOL use_color = TRUE) const;
+ bool use_ellipses = false,
+ bool use_color = true) const;
S32 render(const LLWString &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color) const;
// renderUTF8 does a conversion, so is slower!
- S32 renderUTF8(const std::string &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, ShadowType shadow, S32 max_chars = S32_MAX, S32 max_pixels = S32_MAX, F32* right_x = NULL, BOOL use_ellipses = FALSE, BOOL use_color = TRUE) const;
+ S32 renderUTF8(const std::string &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, ShadowType shadow, S32 max_chars = S32_MAX, S32 max_pixels = S32_MAX, F32* right_x = NULL, bool use_ellipses = false, bool use_color = true) const;
S32 renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color) const;
S32 renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style = NORMAL, ShadowType shadow = NO_SHADOW) const;
@@ -159,7 +159,7 @@ public:
S32 firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_len, S32 start_pos=S32_MAX, S32 max_chars = S32_MAX) const;
// Returns the index of the character closest to pixel position x (ignoring text to the right of max_pixels and max_chars)
- S32 charFromPixelOffset(const llwchar* wchars, S32 char_offset, F32 x, F32 max_pixels=F32_MAX, S32 max_chars = S32_MAX, BOOL round = TRUE) const;
+ S32 charFromPixelOffset(const llwchar* wchars, S32 char_offset, F32 x, F32 max_pixels=F32_MAX, S32 max_chars = S32_MAX, bool round = true) const;
const LLFontDescriptor& getFontDesc() const;
@@ -192,7 +192,7 @@ public:
static std::string nameFromVAlign(LLFontGL::VAlign align);
static LLFontGL::VAlign vAlignFromName(const std::string& name);
- static void setFontDisplay(BOOL flag) { sDisplayFont = flag; }
+ static void setFontDisplay(bool flag) { sDisplayFont = flag; }
static LLFontGL* getFontEmojiSmall();
static LLFontGL* getFontEmojiMedium();
@@ -224,7 +224,7 @@ public:
static F32 sHorizDPI;
static F32 sScaleX;
static F32 sScaleY;
- static BOOL sDisplayFont ;
+ static bool sDisplayFont ;
static std::string sAppDir; // For loading fonts
private:
diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp
index 546211aac8..c48a389f6a 100644
--- a/indra/llrender/llfontregistry.cpp
+++ b/indra/llrender/llfontregistry.cpp
@@ -297,7 +297,7 @@ bool font_desc_init_from_xml(LLXMLNodePtr node, LLFontDescriptor& desc)
if (child->hasAttribute("load_collection"))
{
- BOOL col = FALSE;
+ bool col = false;
child->getAttributeBOOL("load_collection", col);
if (col)
{
@@ -475,7 +475,7 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)
// The first font will get pulled will be the "head" font, set to non-fallback.
// Rest will consitute the fallback list.
- BOOL is_first_found = TRUE;
+ bool is_first_found = true;
string_vec_t font_search_paths;
font_search_paths.push_back(LLFontGL::getFontPathLocal());
@@ -499,8 +499,8 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)
// *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;
+ bool is_fallback = !is_first_found || !mCreateGLTextures;
+ F32 extra_scale = (is_fallback) ? fallback_scale : 1.0f;
F32 point_size_scale = extra_scale * point_size;
bool is_font_loaded = false;
for(string_vec_t::iterator font_search_path_it = font_search_paths.begin();
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index a34efe24d3..556b7b0e35 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -59,12 +59,12 @@
#endif
-BOOL gDebugSession = FALSE;
-BOOL gDebugGLSession = FALSE;
-BOOL gClothRipple = FALSE;
-BOOL gHeadlessClient = FALSE;
-BOOL gNonInteractive = FALSE;
-BOOL gGLActive = FALSE;
+bool gDebugSession = false;
+bool gDebugGLSession = false;
+bool gClothRipple = false;
+bool gHeadlessClient = false;
+bool gNonInteractive = false;
+bool gGLActive = false;
static const std::string HEADLESS_VENDOR_STRING("Linden Lab");
static const std::string HEADLESS_RENDERER_STRING("Headless");
@@ -979,21 +979,21 @@ PFNGLPOLYGONOFFSETCLAMPPROC glPolygonOffsetClamp = nullptr;
LLGLManager gGLManager;
LLGLManager::LLGLManager() :
- mInited(FALSE),
- mIsDisabled(FALSE),
+ mInited(false),
+ mIsDisabled(false),
mMaxSamples(0),
mNumTextureImageUnits(1),
mMaxSampleMaskWords(0),
mMaxColorTextureSamples(0),
mMaxDepthTextureSamples(0),
mMaxIntegerSamples(0),
- mIsAMD(FALSE),
- mIsNVIDIA(FALSE),
- mIsIntel(FALSE),
+ mIsAMD(false),
+ mIsNVIDIA(false),
+ mIsIntel(false),
#if LL_DARWIN
- mIsMobileGF(FALSE),
+ mIsMobileGF(false),
#endif
- mHasRequirements(TRUE),
+ mHasRequirements(true),
mDriverVersionMajor(1),
mDriverVersionMinor(0),
mDriverVersionRelease(0),
@@ -1143,12 +1143,12 @@ bool LLGLManager::initGL()
{
mGLVendorShort = "AMD";
// *TODO: Fix this?
- mIsAMD = TRUE;
+ mIsAMD = true;
}
else if (mGLVendor.find("NVIDIA ") != std::string::npos)
{
mGLVendorShort = "NVIDIA";
- mIsNVIDIA = TRUE;
+ mIsNVIDIA = true;
}
else if (mGLVendor.find("INTEL") != std::string::npos
#if LL_LINUX
@@ -1159,7 +1159,7 @@ bool LLGLManager::initGL()
)
{
mGLVendorShort = "INTEL";
- mIsIntel = TRUE;
+ mIsIntel = true;
}
else
{
@@ -1169,7 +1169,7 @@ bool LLGLManager::initGL()
// This is called here because it depends on the setting of mIsGF2or4MX, and sets up mHasMultitexture.
initExtensions();
- S32 old_vram = mVRAM;
+ U32 old_vram = mVRAM;
mVRAM = 0;
#if LL_WINDOWS
@@ -1211,7 +1211,7 @@ bool LLGLManager::initGL()
// Function will check all GPUs WMI knows of and will pick up the one with most
// memory. We need to check all GPUs because system can switch active GPU to
// weaker one, to preserve power when not under load.
- S32 mem = LLDXHardware::getMBVideoMemoryViaWMI();
+ U32 mem = LLDXHardware::getMBVideoMemoryViaWMI();
if (mem != 0)
{
mVRAM = mem;
@@ -1234,6 +1234,11 @@ bool LLGLManager::initGL()
glGetIntegerv(GL_MAX_INTEGER_SAMPLES, &mMaxIntegerSamples);
glGetIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &mMaxSampleMaskWords);
glGetIntegerv(GL_MAX_SAMPLES, &mMaxSamples);
+ glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &mMaxUniformBlockSize);
+
+ // sanity clamp max uniform block size to 64k just in case
+ // there's some implementation that reports a crazy value
+ mMaxUniformBlockSize = llmin(mMaxUniformBlockSize, 65536);
if (mGLVersion >= 4.59f)
{
@@ -1341,7 +1346,7 @@ void LLGLManager::asLLSD(LLSD& info)
info["gpu_version"] = mDriverVersionVendorString;
info["opengl_version"] = mGLVersionString;
- info["vram"] = mVRAM;
+ info["vram"] = LLSD::Integer(mVRAM);
// OpenGL limits
info["max_samples"] = mMaxSamples;
@@ -1368,12 +1373,12 @@ void LLGLManager::shutdownGL()
{
glFinish();
stop_glerror();
- mInited = FALSE;
+ mInited = false;
}
}
// these are used to turn software blending on. They appear in the Debug/Avatar menu
-// presence of vertex skinning/blending or vertex programs will set these to FALSE by default.
+// presence of vertex skinning/blending or vertex programs will set these to false by default.
void LLGLManager::initExtensions()
{
@@ -1408,7 +1413,7 @@ void LLGLManager::initExtensions()
glGetIntegerv(GL_MAX_ELEMENTS_INDICES, (GLint*) &mGLMaxIndexRange);
glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint*) &mGLMaxTextureSize);
- mInited = TRUE;
+ mInited = true;
#if LL_WINDOWS
LL_DEBUGS("RenderInit") << "GL Probe: Getting symbols" << LL_ENDL;
@@ -2293,10 +2298,10 @@ void do_assert_glerror()
// Create or update texture to be used with this data
GLenum error;
error = glGetError();
- BOOL quit = FALSE;
+ bool quit = false;
if (LL_UNLIKELY(error))
{
- quit = TRUE;
+ quit = true;
GLubyte const * gl_error_msg = gluErrorString(error);
if (NULL != gl_error_msg)
{
@@ -2416,7 +2421,7 @@ void LLGLState::dumpStates()
for (boost::unordered_map<LLGLenum, LLGLboolean>::iterator iter = sStateMap.begin();
iter != sStateMap.end(); ++iter)
{
- LL_INFOS("RenderState") << llformat(" 0x%04x : %s",(S32)iter->first,iter->second?"TRUE":"FALSE") << LL_ENDL;
+ LL_INFOS("RenderState") << llformat(" 0x%04x : %s",(S32)iter->first,iter->second?"true":"false") << LL_ENDL;
}
}
@@ -2459,7 +2464,7 @@ void LLGLState::checkStates(GLboolean writeAlpha)
///////////////////////////////////////////////////////////////////////
LLGLState::LLGLState(LLGLenum state, S32 enabled) :
- mState(state), mWasEnabled(FALSE), mIsEnabled(FALSE)
+ mState(state), mWasEnabled(false), mIsEnabled(false)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
@@ -2478,15 +2483,15 @@ void LLGLState::setEnabled(S32 enabled)
}
if (enabled == CURRENT_STATE)
{
- enabled = sStateMap[mState] == GL_TRUE ? TRUE : FALSE;
+ enabled = sStateMap[mState] == GL_TRUE ? ENABLED_STATE : DISABLED_STATE;
}
- else if (enabled == TRUE && sStateMap[mState] != GL_TRUE)
+ else if (enabled == ENABLED_STATE && sStateMap[mState] != GL_TRUE)
{
gGL.flush();
glEnable(mState);
sStateMap[mState] = GL_TRUE;
}
- else if (enabled == FALSE && sStateMap[mState] != GL_FALSE)
+ else if (enabled == DISABLED_STATE && sStateMap[mState] != GL_FALSE)
{
gGL.flush();
glDisable(mState);
@@ -2741,7 +2746,7 @@ LLGLDepthTest::LLGLDepthTest(GLboolean depth_enabled, GLboolean write_enabled, G
{ // always disable depth writes if depth testing is disabled
// GL spec defines this as a requirement, but some implementations allow depth writes with testing disabled
// The proper way to write to depth buffer with testing disabled is to enable testing and use a depth_func of GL_ALWAYS
- write_enabled = FALSE;
+ write_enabled = GL_FALSE;
}
if (depth_enabled != sDepthEnabled)
@@ -2794,7 +2799,7 @@ void LLGLDepthTest::checkState()
if (gDebugGL)
{
GLint func = 0;
- GLboolean mask = FALSE;
+ GLboolean mask = GL_FALSE;
glGetIntegerv(GL_DEPTH_FUNC, &func);
glGetBooleanv(GL_DEPTH_WRITEMASK, &mask);
diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h
index 5a7ad943df..be1c0a532a 100644
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -45,9 +45,9 @@
#include "llglheaders.h"
#include "glh/glh_linear.h"
-extern BOOL gDebugGL;
-extern BOOL gDebugSession;
-extern BOOL gDebugGLSession;
+extern bool gDebugGL;
+extern bool gDebugSession;
+extern bool gDebugGLSession;
extern llofstream gFailLog;
#define LL_GL_ERRS LL_ERRS("RenderState")
@@ -73,8 +73,8 @@ public:
std::string getRawGLString(); // For sending to simulator
- BOOL mInited;
- BOOL mIsDisabled;
+ bool mInited;
+ bool mIsDisabled;
// OpenGL limits
S32 mMaxSamples;
@@ -87,6 +87,7 @@ public:
S32 mGLMaxIndexRange;
S32 mGLMaxTextureSize;
F32 mMaxAnisotropy = 0.f;
+ S32 mMaxUniformBlockSize = 0;
// GL 4.x capabilities
bool mHasCubeMapArray = false;
@@ -97,17 +98,20 @@ public:
// Vendor-specific extensions
bool mHasAMDAssociations = false;
- BOOL mIsAMD;
- BOOL mIsNVIDIA;
- BOOL mIsIntel;
+ bool mIsAMD;
+ bool mIsNVIDIA;
+ bool mIsIntel;
+
+ // hints to the render pipe
+ U32 mDownScaleMethod = 0; // see settings.xml RenderDownScaleMethod
#if LL_DARWIN
// Needed to distinguish problem cards on older Macs that break with Materials
- BOOL mIsMobileGF;
+ bool mIsMobileGF;
#endif
// Whether this version of GL is good enough for SL to use
- BOOL mHasRequirements;
+ bool mHasRequirements;
S32 mDriverVersionMajor;
S32 mDriverVersionMinor;
@@ -118,9 +122,7 @@ public:
std::string mDriverVersionVendorString;
std::string mGLVersionString;
- S32 mVRAM; // VRAM in MB
-
- void getPixelFormat(); // Get the best pixel format
+ U32 mVRAM; // VRAM in MB
std::string getGLInfoString();
void printGLInfoString();
@@ -138,7 +140,6 @@ public:
private:
void initExtensions();
void initGLStates();
- void initGLImages();
};
extern LLGLManager gGLManager;
@@ -155,13 +156,18 @@ void assert_glerror();
void clear_glerror();
-//#if LL_DEBUG
+
# define stop_glerror() assert_glerror()
# define llglassertok() assert_glerror()
-//#else
-//# define stop_glerror()
-//# define llglassertok()
-//#endif
+
+// stop_glerror is still needed on OS X but has performance implications
+// use macro below to conditionally add stop_glerror to non-release builds
+// on OS X
+#if LL_DARWIN && !LL_RELEASE_FOR_DOWNLOAD
+#define STOP_GLERROR stop_glerror()
+#else
+#define STOP_GLERROR
+#endif
#define llglassertok_always() assert_glerror()
@@ -241,16 +247,16 @@ protected:
static boost::unordered_map<LLGLenum, LLGLboolean> sStateMap;
public:
- enum { CURRENT_STATE = -2 };
+ enum { CURRENT_STATE = -2, DISABLED_STATE = 0, ENABLED_STATE = 1 };
LLGLState(LLGLenum state, S32 enabled = CURRENT_STATE);
~LLGLState();
void setEnabled(S32 enabled);
- void enable() { setEnabled(TRUE); }
- void disable() { setEnabled(FALSE); }
+ void enable() { setEnabled(ENABLED_STATE); }
+ void disable() { setEnabled(DISABLED_STATE); }
protected:
LLGLenum mState;
- BOOL mWasEnabled;
- BOOL mIsEnabled;
+ bool mWasEnabled;
+ bool mIsEnabled;
};
// New LLGLState class wrappers that don't depend on actual GL flags.
@@ -284,14 +290,14 @@ public:
class LLGLEnable : public LLGLState
{
public:
- LLGLEnable(LLGLenum state) : LLGLState(state, TRUE) {}
+ LLGLEnable(LLGLenum state) : LLGLState(state, ENABLED_STATE) {}
};
/// TODO: Being deprecated.
class LLGLDisable : public LLGLState
{
public:
- LLGLDisable(LLGLenum state) : LLGLState(state, FALSE) {}
+ LLGLDisable(LLGLenum state) : LLGLState(state, DISABLED_STATE) {}
};
/*
@@ -351,9 +357,9 @@ public:
static std::list<LLGLUpdate*> sGLQ;
- BOOL mInQ;
+ bool mInQ;
LLGLUpdate()
- : mInQ(FALSE)
+ : mInQ(false)
{
}
virtual ~LLGLUpdate()
@@ -405,10 +411,10 @@ void init_glstates();
void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor_specific, std::string* version_string );
-extern BOOL gClothRipple;
-extern BOOL gHeadlessClient;
-extern BOOL gNonInteractive;
-extern BOOL gGLActive;
+extern bool gClothRipple;
+extern bool gHeadlessClient;
+extern bool gNonInteractive;
+extern bool gGLActive;
// Deal with changing glext.h definitions for newer SDK versions, specifically
// with MAC OSX 10.5 -> 10.6
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 3cc26b14bd..e76a30a954 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -54,6 +54,8 @@ using std::string;
GLuint LLGLSLShader::sCurBoundShader = 0;
LLGLSLShader* LLGLSLShader::sCurBoundShaderPtr = NULL;
S32 LLGLSLShader::sIndexedTextureChannels = 0;
+U32 LLGLSLShader::sMaxGLTFMaterials = 0;
+U32 LLGLSLShader::sMaxGLTFNodes = 0;
bool LLGLSLShader::sProfileEnabled = false;
std::set<LLGLSLShader*> LLGLSLShader::sInstances;
LLGLSLShader::defines_map_t LLGLSLShader::sGlobalDefines;
@@ -81,7 +83,7 @@ const std::string gShaderConstsVal[LLGLSLShader::NUM_SHADER_CONSTS] =
};
-BOOL shouldChange(const LLVector4& v1, const LLVector4& v2)
+bool shouldChange(const LLVector4& v1, const LLVector4& v2)
{
return v1 != v2;
}
@@ -188,7 +190,7 @@ void LLGLSLShader::dumpStats()
tris_sec /= seconds;
F32 pct_samples = (F32)((F64)mSamplesDrawn / (F64)sTotalSamplesDrawn) * 100.f;
- F32 samples_sec = (F32)mSamplesDrawn / 1000000000.0;
+ F32 samples_sec = (F32)(mSamplesDrawn / 1000000000.0);
samples_sec /= seconds;
F32 pct_binds = (F32)mBinds / (F32)sTotalBinds * 100.f;
@@ -309,7 +311,7 @@ LLGLSLShader::LLGLSLShader()
mShaderLevel(0),
mShaderGroup(SG_DEFAULT),
mFeatures(),
- mUniformsDirty(FALSE),
+ mUniformsDirty(false),
mTimerQuery(0),
mSamplesQuery(0),
mPrimitivesQuery(0)
@@ -381,10 +383,7 @@ void LLGLSLShader::unloadInternal()
stop_glerror();
}
-BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString>* attributes,
- std::vector<LLStaticHashedString>* uniforms,
- U32 varying_count,
- const char** varyings)
+bool LLGLSLShader::createShader()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
@@ -415,10 +414,10 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString>* attributes,
// Shouldn't happen if shader related extensions, like ARB_vertex_shader, exist.
LL_SHADER_LOADING_WARNS() << "Failed to create handle for shader: " << mName << LL_ENDL;
unloadInternal();
- return FALSE;
+ return false;
}
- BOOL success = TRUE;
+ bool success = true;
mUsingBinaryProgram = LLShaderMgr::instance()->loadCachedProgramBinary(this);
@@ -440,7 +439,7 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString>* attributes,
}
else
{
- success = FALSE;
+ success = false;
}
}
}
@@ -449,16 +448,16 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString>* attributes,
if (!LLShaderMgr::instance()->attachShaderFeatures(this))
{
unloadInternal();
- return FALSE;
+ return false;
}
// Map attributes and uniforms
if (success)
{
- success = mapAttributes(attributes);
+ success = mapAttributes();
}
if (success)
{
- success = mapUniforms(uniforms);
+ success = mapUniforms();
}
if (!success)
{
@@ -469,7 +468,7 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString>* attributes,
{
LL_SHADER_LOADING_WARNS() << "Failed to link using shader level " << mShaderLevel << " trying again using shader level " << (mShaderLevel - 1) << LL_ENDL;
mShaderLevel--;
- return createShader(attributes, uniforms);
+ return createShader();
}
else
{
@@ -479,6 +478,7 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString>* attributes,
}
else if (mFeatures.mIndexedTextureChannels > 0)
{ //override texture channels for indexed texture rendering
+ llassert(mFeatures.mIndexedTextureChannels == LLGLSLShader::sIndexedTextureChannels); // these numbers must always match
bind();
S32 channel_count = mFeatures.mIndexedTextureChannels;
@@ -488,19 +488,41 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString>* attributes,
uniform1i(uniName, i);
}
- S32 cur_tex = channel_count; //adjust any texture channels that might have been overwritten
+ //adjust any texture channels that might have been overwritten
for (U32 i = 0; i < mTexture.size(); i++)
{
- if (mTexture[i] > -1 && mTexture[i] < channel_count)
+ if (mTexture[i] > -1)
{
- llassert(cur_tex < gGLManager.mNumTextureImageUnits);
- uniform1i(i, cur_tex);
- mTexture[i] = cur_tex++;
+ S32 new_tex = mTexture[i] + channel_count;
+ uniform1i(i, new_tex);
+ mTexture[i] = new_tex;
}
}
+
+ // get the true number of active texture channels
+ mActiveTextureChannels = channel_count;
+ for (auto& tex : mTexture)
+ {
+ mActiveTextureChannels = llmax(mActiveTextureChannels, tex + 1);
+ }
+
+ // when indexed texture channels are used, enforce an upper limit of 16
+ // this should act as a canary in the coal mine for adding textures
+ // and breaking machines that are limited to 16 texture channels
+ llassert(mActiveTextureChannels <= 16);
unbind();
}
+ LL_DEBUGS("GLSLTextureChannels") << mName << " has " << mActiveTextureChannels << " active texture channels" << LL_ENDL;
+
+ for (U32 i = 0; i < mTexture.size(); i++)
+ {
+ if (mTexture[i] > -1)
+ {
+ LL_DEBUGS("GLSLTextureChannels") << "Texture " << LLShaderMgr::instance()->mReservedUniforms[i] << " assigned to channel " << mTexture[i] << LL_ENDL;
+ }
+ }
+
#ifdef LL_PROFILER_ENABLE_RENDER_DOC
setLabel(mName.c_str());
#endif
@@ -529,7 +551,7 @@ void dumpAttachObject(const char* func_name, GLuint program_object, const std::s
}
#endif // DEBUG_SHADER_INCLUDES
-BOOL LLGLSLShader::attachVertexObject(std::string object_path)
+bool LLGLSLShader::attachVertexObject(std::string object_path)
{
if (LLShaderMgr::instance()->mVertexShaderObjects.count(object_path) > 0)
{
@@ -539,19 +561,19 @@ BOOL LLGLSLShader::attachVertexObject(std::string object_path)
dumpAttachObject("attachVertexObject", mProgramObject, object_path);
#endif // DEBUG_SHADER_INCLUDES
stop_glerror();
- return TRUE;
+ return true;
}
else
{
LL_SHADER_LOADING_WARNS() << "Attempting to attach shader object: '" << object_path << "' that hasn't been compiled." << LL_ENDL;
- return FALSE;
+ return false;
}
}
-BOOL LLGLSLShader::attachFragmentObject(std::string object_path)
+bool LLGLSLShader::attachFragmentObject(std::string object_path)
{
if(mUsingBinaryProgram)
- return TRUE;
+ return true;
if (LLShaderMgr::instance()->mFragmentShaderObjects.count(object_path) > 0)
{
@@ -561,12 +583,12 @@ BOOL LLGLSLShader::attachFragmentObject(std::string object_path)
dumpAttachObject("attachFragmentObject", mProgramObject, object_path);
#endif // DEBUG_SHADER_INCLUDES
stop_glerror();
- return TRUE;
+ return true;
}
else
{
LL_SHADER_LOADING_WARNS() << "Attempting to attach shader object: '" << object_path << "' that hasn't been compiled." << LL_ENDL;
- return FALSE;
+ return false;
}
}
@@ -602,11 +624,11 @@ void LLGLSLShader::attachObjects(GLuint* objects, S32 count)
}
}
-BOOL LLGLSLShader::mapAttributes(const std::vector<LLStaticHashedString>* attributes)
+bool LLGLSLShader::mapAttributes()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
- BOOL res = TRUE;
+ bool res = true;
if (!mUsingBinaryProgram)
{
//before linking, make sure reserved attributes always have consistent locations
@@ -621,11 +643,10 @@ BOOL LLGLSLShader::mapAttributes(const std::vector<LLStaticHashedString>* attrib
}
mAttribute.clear();
- U32 numAttributes = (attributes == NULL) ? 0 : attributes->size();
#if LL_RELEASE_WITH_DEBUG_INFO
- mAttribute.resize(LLShaderMgr::instance()->mReservedAttribs.size() + numAttributes, { -1, NULL });
+ mAttribute.resize(LLShaderMgr::instance()->mReservedAttribs.size(), { -1, NULL });
#else
- mAttribute.resize(LLShaderMgr::instance()->mReservedAttribs.size() + numAttributes, -1);
+ mAttribute.resize(LLShaderMgr::instance()->mReservedAttribs.size(), -1);
#endif
if (res)
@@ -649,27 +670,14 @@ BOOL LLGLSLShader::mapAttributes(const std::vector<LLStaticHashedString>* attrib
LL_DEBUGS("ShaderUniform") << "Attribute " << name << " assigned to channel " << index << LL_ENDL;
}
}
- if (attributes != NULL)
- {
- for (U32 i = 0; i < numAttributes; i++)
- {
- const char* name = (*attributes)[i].String().c_str();
- S32 index = glGetAttribLocation(mProgramObject, name);
- if (index != -1)
- {
- mAttribute[LLShaderMgr::instance()->mReservedAttribs.size() + i] = index;
- LL_DEBUGS("ShaderUniform") << "Attribute " << name << " assigned to channel " << index << LL_ENDL;
- }
- }
- }
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
-void LLGLSLShader::mapUniform(GLint index, const vector<LLStaticHashedString>* uniforms)
+void LLGLSLShader::mapUniform(GLint index)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
@@ -753,22 +761,11 @@ void LLGLSLShader::mapUniform(GLint index, const vector<LLStaticHashedString>* u
//found it
mUniform[i] = location;
mTexture[i] = mapUniformTextureChannel(location, type, size);
- return;
- }
- }
-
- if (uniforms != NULL)
- {
- for (U32 i = 0; i < uniforms->size(); i++)
- {
- if ((mUniform[i + LLShaderMgr::instance()->mReservedUniforms.size()] == -1)
- && ((*uniforms)[i].String() == name))
+ if (mTexture[i] != -1)
{
- //found it
- mUniform[i + LLShaderMgr::instance()->mReservedUniforms.size()] = location;
- mTexture[i + LLShaderMgr::instance()->mReservedUniforms.size()] = mapUniformTextureChannel(location, type, size);
- return;
+ LL_DEBUGS("GLSLTextureChannels") << name << " assigned to texture channel " << mTexture[i] << LL_ENDL;
}
+ return;
}
}
}
@@ -806,35 +803,31 @@ GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type, GLint
if (size == 1)
{
glUniform1i(location, mActiveTextureChannels);
- LL_DEBUGS("ShaderUniform") << "Assigned to texture channel " << mActiveTextureChannels << LL_ENDL;
mActiveTextureChannels++;
}
else
{
//is array of textures, make sequential after this texture
- GLint channel[32]; // <=== only support up to 32 texture channels
- llassert(size <= 32);
- size = llmin(size, 32);
+ GLint channel[16]; // <=== only support up to 16 texture channels
+ llassert(size <= 16);
+ size = llmin(size, 16);
for (int i = 0; i < size; ++i)
{
channel[i] = mActiveTextureChannels++;
}
glUniform1iv(location, size, channel);
- LL_DEBUGS("ShaderUniform") << "Assigned to texture channel " <<
- (mActiveTextureChannels - size) << " through " << (mActiveTextureChannels - 1) << LL_ENDL;
}
- llassert(mActiveTextureChannels <= 32); // too many textures (probably)
return ret;
}
return -1;
}
-BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString>* uniforms)
+bool LLGLSLShader::mapUniforms()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
- BOOL res = TRUE;
+ bool res = true;
mTotalUniformSize = 0;
mActiveTextureChannels = 0;
@@ -843,9 +836,8 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString>* uniforms)
mTexture.clear();
mValue.clear();
//initialize arrays
- U32 numUniforms = (uniforms == NULL) ? 0 : uniforms->size();
- mUniform.resize(numUniforms + LLShaderMgr::instance()->mReservedUniforms.size(), -1);
- mTexture.resize(numUniforms + LLShaderMgr::instance()->mReservedUniforms.size(), -1);
+ mUniform.resize(LLShaderMgr::instance()->mReservedUniforms.size(), -1);
+ mTexture.resize(LLShaderMgr::instance()->mReservedUniforms.size(), -1);
bind();
@@ -946,26 +938,26 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString>* uniforms)
if (specularDiff || bumpLessDiff || envLessDiff || refLessDiff)
{
- mapUniform(diffuseMap, uniforms);
+ mapUniform(diffuseMap);
skip_index.insert(diffuseMap);
if (-1 != specularMap) {
- mapUniform(specularMap, uniforms);
+ mapUniform(specularMap);
skip_index.insert(specularMap);
}
if (-1 != bumpMap) {
- mapUniform(bumpMap, uniforms);
+ mapUniform(bumpMap);
skip_index.insert(bumpMap);
}
if (-1 != environmentMap) {
- mapUniform(environmentMap, uniforms);
+ mapUniform(environmentMap);
skip_index.insert(environmentMap);
}
if (-1 != reflectionMap) {
- mapUniform(reflectionMap, uniforms);
+ mapUniform(reflectionMap);
skip_index.insert(reflectionMap);
}
}
@@ -979,21 +971,31 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString>* uniforms)
if (skip_index.end() != skip_index.find(i)) continue;
//........................................................................................
- mapUniform(i, uniforms);
+ mapUniform(i);
}
//........................................................................................................................................
- if (mFeatures.hasReflectionProbes) // Set up block binding, in a way supported by Apple (rather than binding = 1 in .glsl).
- { // See slide 35 and more of https://docs.huihoo.com/apple/wwdc/2011/session_420__advances_in_opengl_for_mac_os_x_lion.pdf
- static const GLuint BLOCKBINDING = 1; //picked by us
- //Get the index, similar to a uniform location
- GLuint UBOBlockIndex = glGetUniformBlockIndex(mProgramObject, "ReflectionProbes");
+ // Set up block binding, in a way supported by Apple (rather than binding = 1 in .glsl).
+ // See slide 35 and more of https://docs.huihoo.com/apple/wwdc/2011/session_420__advances_in_opengl_for_mac_os_x_lion.pdf
+ const char* ubo_names[] =
+ {
+ "ReflectionProbes", // UB_REFLECTION_PROBES
+ "GLTFJoints", // UB_GLTF_JOINTS
+ "GLTFNodes", // UB_GLTF_NODES
+ "GLTFMaterials", // UB_GLTF_MATERIALS
+ };
+
+ llassert(LL_ARRAY_SIZE(ubo_names) == NUM_UNIFORM_BLOCKS);
+
+ for (U32 i = 0; i < NUM_UNIFORM_BLOCKS; ++i)
+ {
+ GLuint UBOBlockIndex = glGetUniformBlockIndex(mProgramObject, ubo_names[i]);
if (UBOBlockIndex != GL_INVALID_INDEX)
{
- //Set this index to a binding index
- glUniformBlockBinding(mProgramObject, UBOBlockIndex, BLOCKBINDING);
+ glUniformBlockBinding(mProgramObject, UBOBlockIndex, i);
}
}
+
unbind();
LL_DEBUGS("ShaderUniform") << "Total Uniform Size: " << mTotalUniformSize << LL_ENDL;
@@ -1001,11 +1003,11 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString>* uniforms)
}
-BOOL LLGLSLShader::link(BOOL suppress_errors)
+bool LLGLSLShader::link(bool suppress_errors)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
- BOOL success = LLShaderMgr::instance()->linkProgramObject(mProgramObject, suppress_errors);
+ bool success = LLShaderMgr::instance()->linkProgramObject(mProgramObject, suppress_errors);
if (!success && !suppress_errors)
{
@@ -1045,10 +1047,17 @@ void LLGLSLShader::bind()
if (mUniformsDirty)
{
LLShaderMgr::instance()->updateShaderUniforms(this);
- mUniformsDirty = FALSE;
+ mUniformsDirty = false;
}
}
+void LLGLSLShader::bind(U8 variant)
+{
+ llassert(mGLTFVariants.size() == LLGLSLShader::NUM_GLTF_VARIANTS);
+ llassert(variant < LLGLSLShader::NUM_GLTF_VARIANTS);
+ mGLTFVariants[variant].bind();
+}
+
void LLGLSLShader::bind(bool rigged)
{
if (rigged)
@@ -1094,7 +1103,8 @@ S32 LLGLSLShader::bindTexture(S32 uniform, LLTexture* texture, LLTexUnit::eTextu
if (uniform < 0 || uniform >= (S32)mTexture.size())
{
- LL_SHADER_UNIFORM_ERRS() << "Uniform out of range: " << uniform << LL_ENDL;
+ LL_WARNS_ONCE("Shader") << "Uniform index out of bounds. Size: " << (S32)mUniform.size() << " index: " << uniform << LL_ENDL;
+ llassert(false);
return -1;
}
@@ -1115,6 +1125,8 @@ S32 LLGLSLShader::bindTexture(S32 uniform, LLRenderTarget* texture, bool depth,
if (uniform < 0 || uniform >= (S32)mTexture.size())
{
+ LL_WARNS_ONCE("Shader") << "Uniform index out of bounds. Size: " << (S32)mUniform.size() << " index: " << uniform << LL_ENDL;
+ llassert(false);
return -1;
}
@@ -1162,7 +1174,8 @@ S32 LLGLSLShader::unbindTexture(S32 uniform, LLTexUnit::eTextureType mode)
if (uniform < 0 || uniform >= (S32)mTexture.size())
{
- LL_SHADER_UNIFORM_ERRS() << "Uniform out of range: " << uniform << LL_ENDL;
+ LL_WARNS_ONCE("Shader") << "Uniform index out of bounds. Size: " << (S32)mUniform.size() << " index: " << uniform << LL_ENDL;
+ llassert(false);
return -1;
}
@@ -1187,7 +1200,8 @@ S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode, LLTex
if (uniform < 0 || uniform >= (S32)mTexture.size())
{
- LL_SHADER_UNIFORM_ERRS() << "Uniform out of range: " << uniform << LL_ENDL;
+ LL_WARNS_ONCE("Shader") << "Uniform index out of bounds. Size: " << (S32)mUniform.size() << " index: " << uniform << LL_ENDL;
+ llassert(false);
return -1;
}
@@ -1208,7 +1222,8 @@ S32 LLGLSLShader::disableTexture(S32 uniform, LLTexUnit::eTextureType mode, LLTe
if (uniform < 0 || uniform >= (S32)mTexture.size())
{
- LL_SHADER_UNIFORM_ERRS() << "Uniform out of range: " << uniform << LL_ENDL;
+ LL_WARNS_ONCE("Shader") << "Uniform index out of bounds. Size: " << (S32)mUniform.size() << " index: " << uniform << LL_ENDL;
+ llassert(false);
return -1;
}
S32 index = mTexture[uniform];
@@ -1239,7 +1254,8 @@ void LLGLSLShader::uniform1i(U32 index, GLint x)
{
if (mUniform.size() <= index)
{
- LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
+ LL_WARNS_ONCE("Shader") << "Uniform index out of bounds. Size: " << (S32)mUniform.size() << " index: " << index << LL_ENDL;
+ llassert(false);
return;
}
@@ -1249,7 +1265,7 @@ void LLGLSLShader::uniform1i(U32 index, GLint x)
if (iter == mValue.end() || iter->second.mV[0] != x)
{
glUniform1i(mUniform[index], x);
- mValue[mUniform[index]] = LLVector4(x, 0.f, 0.f, 0.f);
+ mValue[mUniform[index]] = LLVector4((F32)x, 0.f, 0.f, 0.f);
}
}
}
@@ -1264,7 +1280,8 @@ void LLGLSLShader::uniform1f(U32 index, GLfloat x)
{
if (mUniform.size() <= index)
{
- LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
+ LL_WARNS_ONCE("Shader") << "Uniform index out of bounds. Size: " << (S32)mUniform.size() << " index: " << index << LL_ENDL;
+ llassert(false);
return;
}
@@ -1299,7 +1316,8 @@ void LLGLSLShader::uniform2f(U32 index, GLfloat x, GLfloat y)
{
if (mUniform.size() <= index)
{
- LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
+ LL_WARNS_ONCE("Shader") << "Uniform index out of bounds. Size: " << (S32)mUniform.size() << " index: " << index << LL_ENDL;
+ llassert(false);
return;
}
@@ -1325,7 +1343,8 @@ void LLGLSLShader::uniform3f(U32 index, GLfloat x, GLfloat y, GLfloat z)
{
if (mUniform.size() <= index)
{
- LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
+ LL_WARNS_ONCE("Shader") << "Uniform index out of bounds. Size: " << (S32)mUniform.size() << " index: " << index << LL_ENDL;
+ llassert(false);
return;
}
@@ -1351,7 +1370,8 @@ void LLGLSLShader::uniform4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat
{
if (mUniform.size() <= index)
{
- LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
+ LL_WARNS_ONCE("Shader") << "Uniform index out of bounds. Size: " << (S32)mUniform.size() << " index: " << index << LL_ENDL;
+ llassert(false);
return;
}
@@ -1377,14 +1397,15 @@ void LLGLSLShader::uniform1iv(U32 index, U32 count, const GLint* v)
{
if (mUniform.size() <= index)
{
- LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
+ LL_WARNS_ONCE("Shader") << "Uniform index out of bounds. Size: " << (S32)mUniform.size() << " index: " << index << LL_ENDL;
+ llassert(false);
return;
}
if (mUniform[index] >= 0)
{
const auto& iter = mValue.find(mUniform[index]);
- LLVector4 vec(v[0], 0.f, 0.f, 0.f);
+ LLVector4 vec((F32)v[0], 0.f, 0.f, 0.f);
if (iter == mValue.end() || shouldChange(iter->second, vec) || count != 1)
{
glUniform1iv(mUniform[index], count, v);
@@ -1403,14 +1424,15 @@ void LLGLSLShader::uniform4iv(U32 index, U32 count, const GLint* v)
{
if (mUniform.size() <= index)
{
- LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
+ LL_WARNS_ONCE("Shader") << "Uniform index out of bounds. Size: " << (S32)mUniform.size() << " index: " << index << LL_ENDL;
+ llassert(false);
return;
}
if (mUniform[index] >= 0)
{
const auto& iter = mValue.find(mUniform[index]);
- LLVector4 vec(v[0], v[1], v[2], v[3]);
+ LLVector4 vec((F32)v[0], (F32)v[1], (F32)v[2], (F32)v[3]);
if (iter == mValue.end() || shouldChange(iter->second, vec) || count != 1)
{
glUniform1iv(mUniform[index], count, v);
@@ -1430,7 +1452,8 @@ void LLGLSLShader::uniform1fv(U32 index, U32 count, const GLfloat* v)
{
if (mUniform.size() <= index)
{
- LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
+ LL_WARNS_ONCE("Shader") << "Uniform index out of bounds. Size: " << (S32)mUniform.size() << " index: " << index << LL_ENDL;
+ llassert(false);
return;
}
@@ -1456,7 +1479,8 @@ void LLGLSLShader::uniform2fv(U32 index, U32 count, const GLfloat* v)
{
if (mUniform.size() <= index)
{
- LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
+ LL_WARNS_ONCE("Shader") << "Uniform index out of bounds. Size: " << (S32)mUniform.size() << " index: " << index << LL_ENDL;
+ llassert(false);
return;
}
@@ -1482,7 +1506,8 @@ void LLGLSLShader::uniform3fv(U32 index, U32 count, const GLfloat* v)
{
if (mUniform.size() <= index)
{
- LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
+ LL_WARNS_ONCE("Shader") << "Uniform index out of bounds. Size: " << (S32)mUniform.size() << " index: " << index << LL_ENDL;
+ llassert(false);
return;
}
@@ -1508,7 +1533,8 @@ void LLGLSLShader::uniform4fv(U32 index, U32 count, const GLfloat* v)
{
if (mUniform.size() <= index)
{
- LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
+ LL_WARNS_ONCE("Shader") << "Uniform index out of bounds. Size: " << (S32)mUniform.size() << " index: " << index << LL_ENDL;
+ llassert(false);
return;
}
@@ -1535,7 +1561,8 @@ void LLGLSLShader::uniformMatrix2fv(U32 index, U32 count, GLboolean transpose, c
{
if (mUniform.size() <= index)
{
- LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
+ LL_WARNS_ONCE("Shader") << "Uniform index out of bounds. Size: " << (S32)mUniform.size() << " index: " << index << LL_ENDL;
+ llassert(false);
return;
}
@@ -1555,7 +1582,8 @@ void LLGLSLShader::uniformMatrix3fv(U32 index, U32 count, GLboolean transpose, c
{
if (mUniform.size() <= index)
{
- LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
+ LL_WARNS_ONCE("Shader") << "Uniform index out of bounds. Size: " << (S32)mUniform.size() << " index: " << index << LL_ENDL;
+ llassert(false);
return;
}
@@ -1575,7 +1603,8 @@ void LLGLSLShader::uniformMatrix3x4fv(U32 index, U32 count, GLboolean transpose,
{
if (mUniform.size() <= index)
{
- LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
+ LL_WARNS_ONCE("Shader") << "Uniform index out of bounds. Size: " << (S32)mUniform.size() << " index: " << index << LL_ENDL;
+ llassert(false);
return;
}
@@ -1595,7 +1624,8 @@ void LLGLSLShader::uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, c
{
if (mUniform.size() <= index)
{
- LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
+ LL_WARNS_ONCE("Shader") << "Uniform index out of bounds. Size: " << (S32)mUniform.size() << " index: " << index << LL_ENDL;
+ llassert(false);
return;
}
@@ -1672,7 +1702,7 @@ void LLGLSLShader::uniform1i(const LLStaticHashedString& uniform, GLint v)
if (location >= 0)
{
const auto& iter = mValue.find(location);
- LLVector4 vec(v, 0.f, 0.f, 0.f);
+ LLVector4 vec((F32)v, 0.f, 0.f, 0.f);
if (iter == mValue.end() || shouldChange(iter->second, vec))
{
glUniform1i(location, v);
@@ -1688,7 +1718,7 @@ void LLGLSLShader::uniform1iv(const LLStaticHashedString& uniform, U32 count, co
if (location >= 0)
{
- LLVector4 vec(v[0], 0, 0, 0);
+ LLVector4 vec((F32)v[0], 0.f, 0.f, 0.f);
const auto& iter = mValue.find(location);
if (iter == mValue.end() || shouldChange(iter->second, vec) || count != 1)
{
@@ -1706,7 +1736,7 @@ void LLGLSLShader::uniform4iv(const LLStaticHashedString& uniform, U32 count, co
if (location >= 0)
{
- LLVector4 vec(v[0], v[1], v[2], v[3]);
+ LLVector4 vec((F32)v[0], (F32)v[1], (F32)v[2], (F32)v[3]);
const auto& iter = mValue.find(location);
if (iter == mValue.end() || shouldChange(iter->second, vec) || count != 1)
{
@@ -1725,7 +1755,7 @@ void LLGLSLShader::uniform2i(const LLStaticHashedString& uniform, GLint i, GLint
if (location >= 0)
{
const auto& iter = mValue.find(location);
- LLVector4 vec(i, j, 0.f, 0.f);
+ LLVector4 vec((F32)i, (F32)j, 0.f, 0.f);
if (iter == mValue.end() || shouldChange(iter->second, vec))
{
glUniform2i(location, i, j);
diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h
index d7741c51bb..86e5625dca 100644
--- a/indra/llrender/llglslshader.h
+++ b/indra/llrender/llglslshader.h
@@ -44,6 +44,7 @@ public:
bool hasTransport = false; // implies no lighting (it's possible to have neither though)
bool hasSkinning = false;
bool hasObjectSkinning = false;
+ bool mGLTF = false;
bool hasAtmospherics = false;
bool hasGamma = false;
bool hasShadows = false;
@@ -51,7 +52,6 @@ public:
bool hasSrgb = false;
bool isDeferred = false;
bool hasScreenSpaceReflections = false;
- bool disableTextureIndex = false;
bool hasAlphaMask = false;
bool hasReflectionProbes = false;
bool attachNothing = false;
@@ -69,8 +69,8 @@ public:
template<typename T>
struct UniformSetting
{
- S32 mUniform;
- T mValue;
+ S32 mUniform{ 0 };
+ T mValue{};
};
typedef UniformSetting<S32> IntSetting;
@@ -145,6 +145,16 @@ public:
SG_COUNT
} eGroup;
+ enum UniformBlock : GLuint
+ {
+ UB_REFLECTION_PROBES, // "ReflectionProbes"
+ UB_GLTF_JOINTS, // "GLTFJoints"
+ UB_GLTF_NODES, // "GLTFNodes"
+ UB_GLTF_MATERIALS, // "GLTFMaterials"
+ NUM_UNIFORM_BLOCKS
+ };
+
+
static std::set<LLGLSLShader*> sInstances;
static bool sProfileEnabled;
@@ -155,6 +165,9 @@ public:
static LLGLSLShader* sCurBoundShaderPtr;
static S32 sIndexedTextureChannels;
+ static U32 sMaxGLTFMaterials;
+ static U32 sMaxGLTFNodes;
+
static void initProfile();
static void finishProfile(bool emit_report = true);
@@ -175,17 +188,14 @@ public:
// If force_read is true, will force an immediate readback (severe performance penalty)
bool readProfileQuery(bool for_runtime = false, bool force_read = false);
- BOOL createShader(std::vector<LLStaticHashedString>* attributes,
- std::vector<LLStaticHashedString>* uniforms,
- U32 varying_count = 0,
- const char** varyings = NULL);
- BOOL attachFragmentObject(std::string object);
- BOOL attachVertexObject(std::string object);
+ bool createShader();
+ bool attachFragmentObject(std::string object);
+ bool attachVertexObject(std::string object);
void attachObject(GLuint object);
void attachObjects(GLuint* objects = NULL, S32 count = 0);
- BOOL mapAttributes(const std::vector<LLStaticHashedString>* attributes);
- BOOL mapUniforms(const std::vector<LLStaticHashedString>*);
- void mapUniform(GLint index, const std::vector<LLStaticHashedString>*);
+ bool mapAttributes();
+ bool mapUniforms();
+ void mapUniform(GLint index);
void uniform1i(U32 index, GLint i);
void uniform1f(U32 index, GLfloat v);
void fastUniform1f(U32 index, GLfloat v);
@@ -252,7 +262,7 @@ public:
S32 unbindTexture(const std::string& uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
S32 unbindTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
- BOOL link(BOOL suppress_errors = FALSE);
+ bool link(bool suppress_errors = false);
void bind();
//helper to conditionally bind mRiggedVariant instead of this
void bind(bool rigged);
@@ -290,7 +300,7 @@ public:
S32 mActiveTextureChannels;
S32 mShaderLevel;
S32 mShaderGroup; // see LLGLSLShader::eGroup
- BOOL mUniformsDirty;
+ bool mUniformsDirty;
LLShaderFeatures mFeatures;
std::vector< std::pair< std::string, GLenum > > mShaderFiles;
std::string mName;
@@ -318,6 +328,26 @@ public:
// this pointer should be set to whichever shader represents this shader's rigged variant
LLGLSLShader* mRiggedVariant = nullptr;
+ // variants for use by GLTF renderer
+ // bit 0 = alpha mode blend (1) or opaque (0)
+ // bit 1 = rigged (1) or static (0)
+ // bit 2 = unlit (1) or lit (0)
+ // bit 3 = single (0) or multi (1) uv coordinates
+ struct GLTFVariant
+ {
+ constexpr static U8 ALPHA_BLEND = 1;
+ constexpr static U8 RIGGED = 2;
+ constexpr static U8 UNLIT = 4;
+ constexpr static U8 MULTI_UV = 8;
+ };
+
+ constexpr static U8 NUM_GLTF_VARIANTS = 16;
+
+ std::vector<LLGLSLShader> mGLTFVariants;
+
+ //helper to bind GLTF variant
+ void bind(U8 variant);
+
// hacky flag used for optimization in LLDrawPoolAlpha
bool mCanBindFast = false;
diff --git a/indra/llrender/llgltexture.cpp b/indra/llrender/llgltexture.cpp
index 104976fcc6..4dcca5a726 100644
--- a/indra/llrender/llgltexture.cpp
+++ b/indra/llrender/llgltexture.cpp
@@ -27,13 +27,13 @@
#include "llgltexture.h"
-LLGLTexture::LLGLTexture(BOOL usemipmaps)
+LLGLTexture::LLGLTexture(bool usemipmaps)
{
init();
mUseMipMaps = usemipmaps;
}
-LLGLTexture::LLGLTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps)
+LLGLTexture::LLGLTexture(const U32 width, const U32 height, const U8 components, bool usemipmaps)
{
init();
mFullWidth = width ;
@@ -43,14 +43,14 @@ LLGLTexture::LLGLTexture(const U32 width, const U32 height, const U8 components,
setTexelsPerImage();
}
-LLGLTexture::LLGLTexture(const LLImageRaw* raw, BOOL usemipmaps)
+LLGLTexture::LLGLTexture(const LLImageRaw* raw, bool usemipmaps)
{
init();
mUseMipMaps = usemipmaps ;
// Create an empty image of the specified size and width
mGLTexturep = new LLImageGL(raw, usemipmaps) ;
- mFullWidth = mGLTexturep->getCurrentWidth();
- mFullHeight = mGLTexturep->getCurrentHeight();
+ mFullWidth = mGLTexturep->getWidth();
+ mFullHeight = mGLTexturep->getHeight();
mComponents = mGLTexturep->getComponents();
setTexelsPerImage();
}
@@ -67,12 +67,12 @@ void LLGLTexture::init()
mFullWidth = 0;
mFullHeight = 0;
mTexelsPerImage = 0 ;
- mUseMipMaps = FALSE ;
+ mUseMipMaps = false ;
mComponents = 0 ;
mTextureState = NO_DELETE ;
- mDontDiscard = FALSE;
- mNeedsGLTexture = FALSE ;
+ mDontDiscard = false;
+ mNeedsGLTexture = false ;
}
void LLGLTexture::cleanup()
@@ -141,7 +141,7 @@ LLImageGL* LLGLTexture::getGLTexture() const
return mGLTexturep ;
}
-BOOL LLGLTexture::createGLTexture()
+bool LLGLTexture::createGLTexture()
{
if(mGLTexturep.isNull())
{
@@ -151,11 +151,11 @@ BOOL LLGLTexture::createGLTexture()
return mGLTexturep->createGLTexture() ;
}
-BOOL LLGLTexture::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename, BOOL to_create, S32 category, bool defer_copy, LLGLuint* tex_name)
+bool LLGLTexture::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename, bool to_create, S32 category, bool defer_copy, LLGLuint* tex_name)
{
llassert(mGLTexturep.notNull());
- BOOL ret = mGLTexturep->createGLTexture(discard_level, imageraw, usename, to_create, category, defer_copy, tex_name) ;
+ bool ret = mGLTexturep->createGLTexture(discard_level, imageraw, usename, to_create, category, defer_copy, tex_name) ;
if(ret)
{
@@ -168,7 +168,7 @@ BOOL LLGLTexture::createGLTexture(S32 discard_level, const LLImageRaw* imageraw,
return ret ;
}
-void LLGLTexture::setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes)
+void LLGLTexture::setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, bool swap_bytes)
{
llassert(mGLTexturep.notNull()) ;
@@ -223,22 +223,22 @@ LLGLuint LLGLTexture::getTexName() const
return mGLTexturep->getTexName() ;
}
-BOOL LLGLTexture::hasGLTexture() const
+bool LLGLTexture::hasGLTexture() const
{
if(mGLTexturep.notNull())
{
return mGLTexturep->getHasGLTexture() ;
}
- return FALSE ;
+ return false ;
}
-BOOL LLGLTexture::getBoundRecently() const
+bool LLGLTexture::getBoundRecently() const
{
if(mGLTexturep.notNull())
{
return mGLTexturep->getBoundRecently() ;
}
- return FALSE ;
+ return false ;
}
LLTexUnit::eTextureType LLGLTexture::getTarget(void) const
@@ -247,7 +247,7 @@ LLTexUnit::eTextureType LLGLTexture::getTarget(void) const
return mGLTexturep->getTarget() ;
}
-BOOL LLGLTexture::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, LLGLuint use_name)
+bool LLGLTexture::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, LLGLuint use_name)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
llassert(mGLTexturep.notNull()) ;
@@ -255,7 +255,7 @@ BOOL LLGLTexture::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos,
return mGLTexturep->setSubImage(imageraw, x_pos, y_pos, width, height, 0, use_name) ;
}
-BOOL LLGLTexture::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, LLGLuint use_name)
+bool LLGLTexture::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, LLGLuint use_name)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
llassert(mGLTexturep.notNull()) ;
@@ -310,14 +310,14 @@ LLGLenum LLGLTexture::getPrimaryFormat() const
return mGLTexturep->getPrimaryFormat() ;
}
-BOOL LLGLTexture::getIsAlphaMask() const
+bool LLGLTexture::getIsAlphaMask() const
{
llassert(mGLTexturep.notNull()) ;
return mGLTexturep->getIsAlphaMask() ;
}
-BOOL LLGLTexture::getMask(const LLVector2 &tc)
+bool LLGLTexture::getMask(const LLVector2 &tc)
{
llassert(mGLTexturep.notNull()) ;
@@ -330,14 +330,14 @@ F32 LLGLTexture::getTimePassedSinceLastBound()
return mGLTexturep->getTimePassedSinceLastBound() ;
}
-BOOL LLGLTexture::getMissed() const
+bool LLGLTexture::getMissed() const
{
llassert(mGLTexturep.notNull()) ;
return mGLTexturep->getMissed() ;
}
-BOOL LLGLTexture::isJustBound() const
+bool LLGLTexture::isJustBound() const
{
llassert(mGLTexturep.notNull()) ;
@@ -351,34 +351,13 @@ void LLGLTexture::forceUpdateBindStats(void) const
return mGLTexturep->forceUpdateBindStats() ;
}
-U32 LLGLTexture::getTexelsInAtlas() const
-{
- llassert(mGLTexturep.notNull()) ;
-
- return mGLTexturep->getTexelsInAtlas() ;
-}
-
-U32 LLGLTexture::getTexelsInGLTexture() const
-{
- llassert(mGLTexturep.notNull()) ;
-
- return mGLTexturep->getTexelsInGLTexture() ;
-}
-
-BOOL LLGLTexture::isGLTextureCreated() const
+bool LLGLTexture::isGLTextureCreated() const
{
llassert(mGLTexturep.notNull()) ;
return mGLTexturep->isGLTextureCreated() ;
}
-S32 LLGLTexture::getDiscardLevelInAtlas() const
-{
- llassert(mGLTexturep.notNull()) ;
-
- return mGLTexturep->getDiscardLevelInAtlas() ;
-}
-
void LLGLTexture::destroyGLTexture()
{
if(mGLTexturep.notNull() && mGLTexturep->getHasGLTexture())
diff --git a/indra/llrender/llgltexture.h b/indra/llrender/llgltexture.h
index f5bef0e291..a7de20dc5c 100644
--- a/indra/llrender/llgltexture.h
+++ b/indra/llrender/llgltexture.h
@@ -51,10 +51,10 @@ public:
BOOST_NONE = 0,
BOOST_AVATAR ,
BOOST_AVATAR_BAKED ,
- BOOST_SCULPTED ,
BOOST_TERRAIN , // Needed for minimap generation for now. Lower than BOOST_HIGH so the texture stats don't get forced, i.e. texture stats are manually managed by minimap/terrain instead.
BOOST_HIGH = 10,
+ BOOST_SCULPTED ,
BOOST_BUMP ,
BOOST_UNUSED_1 , // Placeholder to avoid disrupting habits around texture debug
BOOST_SELECTED ,
@@ -75,7 +75,6 @@ public:
AVATAR_SCRATCH_TEX,
DYNAMIC_TEX,
MEDIA,
- ATLAS,
OTHER,
MAX_GL_IMAGE_CATEGORY
};
@@ -94,9 +93,9 @@ protected:
LOG_CLASS(LLGLTexture);
public:
- LLGLTexture(BOOL usemipmaps = TRUE);
- LLGLTexture(const LLImageRaw* raw, BOOL usemipmaps) ;
- LLGLTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps) ;
+ LLGLTexture(bool usemipmaps = true);
+ LLGLTexture(const LLImageRaw* raw, bool usemipmaps) ;
+ LLGLTexture(const U32 width, const U32 height, const U8 components, bool usemipmaps) ;
virtual void dump(); // debug info to LL_INFOS()
@@ -117,25 +116,25 @@ public:
/*virtual*/S32 getWidth(S32 discard_level = -1) const;
/*virtual*/S32 getHeight(S32 discard_level = -1) const;
- BOOL hasGLTexture() const ;
+ bool hasGLTexture() const ;
LLGLuint getTexName() const ;
- BOOL createGLTexture() ;
+ bool createGLTexture() ;
// Create a GL Texture from an image raw
// discard_level - mip level, 0 for highest resultion mip
// imageraw - the image to copy from
// usename - explicit GL name override
- // to_create - set to FALSE to force gl texture to not be created
+ // to_create - set to false to force gl texture to not be created
// category - LLGLTexture category for this LLGLTexture
// defer_copy - set to true to allocate GL texture but NOT initialize with imageraw data
// tex_name - if not null, will be set to the GL name of the texture created
- BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE, S32 category = LLGLTexture::OTHER, bool defer_copy = false, LLGLuint* tex_name = nullptr);
+ bool createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, bool to_create = true, S32 category = LLGLTexture::OTHER, bool defer_copy = false, LLGLuint* tex_name = nullptr);
void setFilteringOption(LLTexUnit::eTextureFilterOptions option);
- void setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, BOOL swap_bytes = FALSE);
+ void setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, bool swap_bytes = false);
void setAddressMode(LLTexUnit::eTextureAddressMode mode);
- BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, LLGLuint use_name = 0);
- BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, LLGLuint use_name = 0);
+ bool setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, LLGLuint use_name = 0);
+ bool setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, LLGLuint use_name = 0);
void setGLTextureCreated (bool initialized);
void setCategory(S32 category) ;
void setTexName(LLGLuint); // for forcing w/ externally created textures only
@@ -145,21 +144,18 @@ public:
S32 getMaxDiscardLevel() const;
S32 getDiscardLevel() const;
S8 getComponents() const;
- BOOL getBoundRecently() const;
+ bool getBoundRecently() const;
S32Bytes getTextureMemory() const ;
LLGLenum getPrimaryFormat() const;
- BOOL getIsAlphaMask() const ;
+ bool getIsAlphaMask() const ;
LLTexUnit::eTextureType getTarget(void) const ;
- BOOL getMask(const LLVector2 &tc);
+ bool getMask(const LLVector2 &tc);
F32 getTimePassedSinceLastBound();
- BOOL getMissed() const ;
- BOOL isJustBound()const ;
+ bool getMissed() const ;
+ bool isJustBound()const ;
void forceUpdateBindStats(void) const;
- U32 getTexelsInAtlas() const ;
- U32 getTexelsInGLTexture() const ;
- BOOL isGLTextureCreated() const ;
- S32 getDiscardLevelInAtlas() const ;
+ bool isGLTextureCreated() const ;
LLGLTextureState getTextureState() const { return mTextureState; }
//---------------------------------------------------------------------------------------------
@@ -171,7 +167,7 @@ public:
void forceActive() ;
void setNoDelete() ;
void dontDiscard() { mDontDiscard = 1; mTextureState = NO_DELETE; }
- BOOL getDontDiscard() const { return mDontDiscard; }
+ bool getDontDiscard() const { return mDontDiscard; }
//-----------------
private:
@@ -188,7 +184,7 @@ protected:
S32 mBoostLevel; // enum describing priority level
U32 mFullWidth;
U32 mFullHeight;
- BOOL mUseMipMaps;
+ bool mUseMipMaps;
S8 mComponents;
U32 mTexelsPerImage; // Texels per image.
mutable S8 mNeedsGLTexture;
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 1609afb7ef..058afa0cf2 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -41,6 +41,7 @@
#include "llrender.h"
#include "llwindow.h"
#include "llframetimer.h"
+#include <unordered_set>
extern LL_COMMON_API bool on_main_thread();
@@ -56,14 +57,17 @@ const F32 MIN_TEXTURE_LIFETIME = 10.f;
U32 wpo2(U32 i);
-// texture memory accounting (for OS X)
+U32 LLImageGL::sFrameCount = 0;
+
+
+// texture memory accounting (for macOS)
static LLMutex sTexMemMutex;
static std::unordered_map<U32, U64> sTextureAllocs;
static U64 sTextureBytes = 0;
// track a texture alloc on the currently bound texture.
// asserts that no currently tracked alloc exists
-static void alloc_tex_image(U32 width, U32 height, U32 pixformat)
+void LLImageGLMemory::alloc_tex_image(U32 width, U32 height, U32 pixformat)
{
U32 texUnit = gGL.getCurrentTexUnitIndex();
U32 texName = gGL.getTexUnit(texUnit)->getCurrTexture();
@@ -81,7 +85,7 @@ static void alloc_tex_image(U32 width, U32 height, U32 pixformat)
}
// track texture free on given texName
-static void free_tex_image(U32 texName)
+void LLImageGLMemory::free_tex_image(U32 texName)
{
sTexMemMutex.lock();
auto iter = sTextureAllocs.find(texName);
@@ -98,22 +102,24 @@ static void free_tex_image(U32 texName)
}
// track texture free on given texNames
-static void free_tex_images(U32 count, const U32* texNames)
+void LLImageGLMemory::free_tex_images(U32 count, const U32* texNames)
{
- for (int i = 0; i < count; ++i)
+ for (U32 i = 0; i < count; ++i)
{
free_tex_image(texNames[i]);
}
}
// track texture free on currently bound texture
-static void free_cur_tex_image()
+void LLImageGLMemory::free_cur_tex_image()
{
U32 texUnit = gGL.getCurrentTexUnitIndex();
U32 texName = gGL.getTexUnit(texUnit)->getCurrTexture();
free_tex_image(texName);
}
+using namespace LLImageGLMemory;
+
// static
U64 LLImageGL::getTextureBytesAllocated()
{
@@ -126,12 +132,11 @@ U32 LLImageGL::sUniqueCount = 0;
U32 LLImageGL::sBindCount = 0;
S32 LLImageGL::sCount = 0;
-BOOL LLImageGL::sGlobalUseAnisotropic = FALSE;
+bool LLImageGL::sGlobalUseAnisotropic = false;
F32 LLImageGL::sLastFrameTime = 0.f;
-BOOL LLImageGL::sAllowReadBackRaw = FALSE ;
LLImageGL* LLImageGL::sDefaultGLTexture = NULL ;
bool LLImageGL::sCompressTextures = false;
-std::set<LLImageGL*> LLImageGL::sImageList;
+std::unordered_set<LLImageGL*> LLImageGL::sImageList;
bool LLImageGLThread::sEnabledTextures = false;
@@ -147,7 +152,10 @@ S32 LLImageGL::sCurTexPickSize = -1 ;
S32 LLImageGL::sMaxCategories = 1 ;
//optimization for when we don't need to calculate mIsMask
-BOOL LLImageGL::sSkipAnalyzeAlpha;
+bool LLImageGL::sSkipAnalyzeAlpha;
+U32 LLImageGL::sScratchPBO = 0;
+U32 LLImageGL::sScratchPBOSize = 0;
+
//------------------------
//****************************************************************************************************
@@ -157,20 +165,6 @@ BOOL LLImageGL::sSkipAnalyzeAlpha;
//**************************************************************************************
//below are functions for debug use
//do not delete them even though they are not currently being used.
-void check_all_images()
-{
- for (std::set<LLImageGL*>::iterator iter = LLImageGL::sImageList.begin();
- iter != LLImageGL::sImageList.end(); iter++)
- {
- LLImageGL* glimage = *iter;
- if (glimage->getTexName() && glimage->isGLTextureCreated())
- {
- gGL.getTexUnit(0)->bind(glimage) ;
- glimage->checkTexSize() ;
- gGL.getTexUnit(0)->unbind(glimage->getTarget()) ;
- }
- }
-}
void LLImageGL::checkTexSize(bool forced) const
{
@@ -185,12 +179,12 @@ void LLImageGL::checkTexSize(bool forced) const
GLint texname;
glGetIntegerv(GL_TEXTURE_BINDING_2D, &texname);
- BOOL error = FALSE;
+ bool error = false;
if (texname != mTexName)
{
LL_INFOS() << "Bound: " << texname << " Should bind: " << mTexName << " Default: " << LLImageGL::sDefaultGLTexture->getTexName() << LL_ENDL;
- error = TRUE;
+ error = true;
if (gDebugSession)
{
gFailLog << "Invalid texture bound!" << std::endl;
@@ -213,7 +207,7 @@ void LLImageGL::checkTexSize(bool forced) const
}
if(x != (mWidth >> mCurrentDiscardLevel) || y != (mHeight >> mCurrentDiscardLevel))
{
- error = TRUE;
+ error = true;
if (gDebugSession)
{
gFailLog << "wrong texture size and discard level!" <<
@@ -236,7 +230,7 @@ void LLImageGL::checkTexSize(bool forced) const
//**************************************************************************************
//----------------------------------------------------------------------------
-BOOL is_little_endian()
+bool is_little_endian()
{
S32 a = 0x12345678;
U8 *c = (U8*)(&a);
@@ -245,11 +239,16 @@ BOOL is_little_endian()
}
//static
-void LLImageGL::initClass(LLWindow* window, S32 num_catagories, BOOL skip_analyze_alpha /* = false */, bool thread_texture_loads /* = false */, bool thread_media_updates /* = false */)
+void LLImageGL::initClass(LLWindow* window, S32 num_catagories, bool skip_analyze_alpha /* = false */, bool thread_texture_loads /* = false */, bool thread_media_updates /* = false */)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
sSkipAnalyzeAlpha = skip_analyze_alpha;
+ if (sScratchPBO == 0)
+ {
+ glGenBuffers(1, &sScratchPBO);
+ }
+
if (thread_texture_loads || thread_media_updates)
{
LLImageGLThread::createInstance(window);
@@ -263,6 +262,12 @@ void LLImageGL::cleanupClass()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
LLImageGLThread::deleteSingleton();
+ if (sScratchPBO != 0)
+ {
+ glDeleteBuffers(1, &sScratchPBO);
+ sScratchPBO = 0;
+ sScratchPBOSize = 0;
+ }
}
@@ -289,6 +294,8 @@ S32 LLImageGL::dataFormatBits(S32 dataformat)
case GL_SRGB_ALPHA: return 32;
case GL_BGRA: return 32; // Used for QuickTime media textures on the Mac
case GL_DEPTH_COMPONENT: return 24;
+ case GL_RGB16F: return 48;
+ case GL_RGBA16F: return 64;
default:
LL_ERRS() << "LLImageGL::Unknown format: " << dataformat << LL_ENDL;
return 0;
@@ -356,66 +363,19 @@ void LLImageGL::updateStats(F32 current_time)
//----------------------------------------------------------------------------
//static
-void LLImageGL::destroyGL(BOOL save_state)
+void LLImageGL::destroyGL()
{
for (S32 stage = 0; stage < gGLManager.mNumTextureImageUnits; stage++)
{
gGL.getTexUnit(stage)->unbind(LLTexUnit::TT_TEXTURE);
}
-
- sAllowReadBackRaw = true ;
- for (std::set<LLImageGL*>::iterator iter = sImageList.begin();
- iter != sImageList.end(); iter++)
- {
- LLImageGL* glimage = *iter;
- if (glimage->mTexName)
- {
- if (save_state && glimage->isGLTextureCreated() && glimage->mComponents)
- {
- glimage->mSaveData = new LLImageRaw;
- if(!glimage->readBackRaw(glimage->mCurrentDiscardLevel, glimage->mSaveData, false)) //necessary, keep it.
- {
- glimage->mSaveData = NULL ;
- }
- }
-
- glimage->destroyGLTexture();
- stop_glerror();
- }
- }
- sAllowReadBackRaw = false ;
-}
-
-//static
-void LLImageGL::restoreGL()
-{
- for (std::set<LLImageGL*>::iterator iter = sImageList.begin();
- iter != sImageList.end(); iter++)
- {
- LLImageGL* glimage = *iter;
- if(glimage->getTexName())
- {
- LL_ERRS() << "tex name is not 0." << LL_ENDL ;
- }
- if (glimage->mSaveData.notNull())
- {
- if (glimage->getComponents() && glimage->mSaveData->getComponents())
- {
- glimage->createGLTexture(glimage->mCurrentDiscardLevel, glimage->mSaveData, 0, TRUE, glimage->getCategory());
- stop_glerror();
- }
- glimage->mSaveData = NULL; // deletes data
- }
- }
}
//static
void LLImageGL::dirtyTexOptions()
{
- for (std::set<LLImageGL*>::iterator iter = sImageList.begin();
- iter != sImageList.end(); iter++)
+ for (auto& glimage : sImageList)
{
- LLImageGL* glimage = *iter;
glimage->mTexOptionsDirty = true;
stop_glerror();
}
@@ -425,30 +385,30 @@ void LLImageGL::dirtyTexOptions()
//for server side use only.
//static
-BOOL LLImageGL::create(LLPointer<LLImageGL>& dest, BOOL usemipmaps)
+bool LLImageGL::create(LLPointer<LLImageGL>& dest, bool usemipmaps)
{
dest = new LLImageGL(usemipmaps);
- return TRUE;
+ return true;
}
//for server side use only.
-BOOL LLImageGL::create(LLPointer<LLImageGL>& dest, U32 width, U32 height, U8 components, BOOL usemipmaps)
+bool LLImageGL::create(LLPointer<LLImageGL>& dest, U32 width, U32 height, U8 components, bool usemipmaps)
{
dest = new LLImageGL(width, height, components, usemipmaps);
- return TRUE;
+ return true;
}
//for server side use only.
-BOOL LLImageGL::create(LLPointer<LLImageGL>& dest, const LLImageRaw* imageraw, BOOL usemipmaps)
+bool LLImageGL::create(LLPointer<LLImageGL>& dest, const LLImageRaw* imageraw, bool usemipmaps)
{
dest = new LLImageGL(imageraw, usemipmaps);
- return TRUE;
+ return true;
}
//----------------------------------------------------------------------------
-LLImageGL::LLImageGL(BOOL usemipmaps)
-: mSaveData(0), mExternalTexture(FALSE)
+LLImageGL::LLImageGL(bool usemipmaps)
+: mSaveData(0), mExternalTexture(false)
{
init(usemipmaps);
setSize(0, 0, 0);
@@ -456,8 +416,8 @@ LLImageGL::LLImageGL(BOOL usemipmaps)
sCount++;
}
-LLImageGL::LLImageGL(U32 width, U32 height, U8 components, BOOL usemipmaps)
-: mSaveData(0), mExternalTexture(FALSE)
+LLImageGL::LLImageGL(U32 width, U32 height, U8 components, bool usemipmaps)
+: mSaveData(0), mExternalTexture(false)
{
llassert( components <= 4 );
init(usemipmaps);
@@ -466,8 +426,8 @@ LLImageGL::LLImageGL(U32 width, U32 height, U8 components, BOOL usemipmaps)
sCount++;
}
-LLImageGL::LLImageGL(const LLImageRaw* imageraw, BOOL usemipmaps)
-: mSaveData(0), mExternalTexture(FALSE)
+LLImageGL::LLImageGL(const LLImageRaw* imageraw, bool usemipmaps)
+: mSaveData(0), mExternalTexture(false)
{
init(usemipmaps);
setSize(0, 0, 0);
@@ -508,7 +468,7 @@ LLImageGL::~LLImageGL()
}
}
-void LLImageGL::init(BOOL usemipmaps)
+void LLImageGL::init(bool usemipmaps)
{
#if LL_IMAGEGL_THREAD_CHECK
mActiveThread = LLThread::currentID();
@@ -525,23 +485,19 @@ void LLImageGL::init(BOOL usemipmaps)
mPickMaskWidth = 0;
mPickMaskHeight = 0;
mUseMipMaps = usemipmaps;
- mHasExplicitFormat = FALSE;
+ mHasExplicitFormat = false;
- mIsMask = FALSE;
- mNeedsAlphaAndPickMask = TRUE ;
+ mIsMask = false;
+ mNeedsAlphaAndPickMask = true ;
mAlphaStride = 0 ;
mAlphaOffset = 0 ;
- mGLTextureCreated = FALSE ;
+ mGLTextureCreated = false ;
mTexName = 0;
mWidth = 0;
mHeight = 0;
mCurrentDiscardLevel = -1;
- mDiscardLevelInAtlas = -1 ;
- mTexelsInAtlas = 0 ;
- mTexelsInGLTexture = 0 ;
-
mAllowCompression = true;
mTarget = GL_TEXTURE_2D;
@@ -561,10 +517,10 @@ void LLImageGL::init(BOOL usemipmaps)
mFormatInternal = -1;
mFormatPrimary = (LLGLenum) 0;
mFormatType = GL_UNSIGNED_BYTE;
- mFormatSwapBytes = FALSE;
+ mFormatSwapBytes = false;
#ifdef DEBUG_MISS
- mMissed = FALSE;
+ mMissed = false;
#endif
mCategory = -1;
@@ -618,9 +574,6 @@ bool LLImageGL::setSize(S32 width, S32 height, S32 ncomponents, S32 discard_leve
return false;
}
- // pickmask validity depends on old image size, delete it
- freePickMask();
-
mWidth = width;
mHeight = height;
mComponents = ncomponents;
@@ -682,12 +635,12 @@ void LLImageGL::forceUpdateBindStats(void) const
mLastBindTime = sLastFrameTime;
}
-BOOL LLImageGL::updateBindStats() const
+bool LLImageGL::updateBindStats() const
{
if (mTexName != 0)
{
#ifdef DEBUG_MISS
- mMissed = ! getIsResident(TRUE);
+ mMissed = ! getIsResident(true);
#endif
sBindCount++;
if (mLastBindTime != sLastFrameTime)
@@ -696,10 +649,10 @@ BOOL LLImageGL::updateBindStats() const
sUniqueCount++;
mLastBindTime = sLastFrameTime;
- return TRUE ;
+ return true ;
}
}
- return FALSE ;
+ return false ;
}
F32 LLImageGL::getTimePassedSinceLastBound()
@@ -707,11 +660,11 @@ F32 LLImageGL::getTimePassedSinceLastBound()
return sLastFrameTime - mLastBindTime ;
}
-void LLImageGL::setExplicitFormat( LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes )
+void LLImageGL::setExplicitFormat( LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, bool swap_bytes )
{
// Note: must be called before createTexture()
// Note: it's up to the caller to ensure that the format matches the number of components.
- mHasExplicitFormat = TRUE;
+ mHasExplicitFormat = true;
mFormatInternal = internal_format;
mFormatPrimary = primary_format;
if(type_format == 0)
@@ -732,10 +685,10 @@ void LLImageGL::setImage(const LLImageRaw* imageraw)
(imageraw->getHeight() == getHeight(mCurrentDiscardLevel)) &&
(imageraw->getComponents() == getComponents()));
const U8* rawdata = imageraw->getData();
- setImage(rawdata, FALSE);
+ setImage(rawdata, false);
}
-BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips /* = FALSE */, S32 usename /* = 0 */)
+bool LLImageGL::setImage(const U8* data_in, bool data_hasmips /* = false */, S32 usename /* = 0 */)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
@@ -785,7 +738,7 @@ BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips /* = FALSE */, S32
}
if (is_compressed)
{
- S32 tex_size = dataFormatBytes(mFormatPrimary, w, h);
+ GLsizei tex_size = (GLsizei)dataFormatBytes(mFormatPrimary, w, h);
glCompressedTexImage2D(mTarget, gl_level, mFormatPrimary, w, h, 0, tex_size, (GLvoid *)data_in);
stop_glerror();
}
@@ -917,7 +870,7 @@ BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips /* = FALSE */, S32
}
mGLTextureCreated = false;
- return FALSE;
+ return false;
}
else
{
@@ -988,7 +941,7 @@ BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips /* = FALSE */, S32
S32 h = getHeight();
if (is_compressed)
{
- S32 tex_size = dataFormatBytes(mFormatPrimary, w, h);
+ GLsizei tex_size = (GLsizei)dataFormatBytes(mFormatPrimary, w, h);
glCompressedTexImage2D(mTarget, 0, mFormatPrimary, w, h, 0, tex_size, (GLvoid *)data_in);
stop_glerror();
}
@@ -1018,99 +971,7 @@ BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips /* = FALSE */, S32
}
stop_glerror();
mGLTextureCreated = true;
- return TRUE;
-}
-
-BOOL LLImageGL::preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image)
-{
- //not compatible with core GL profile
- llassert(!LLRender::sGLCoreProfile);
-
- if (gGLManager.mIsDisabled)
- {
- LL_WARNS() << "Trying to create a texture while GL is disabled!" << LL_ENDL;
- return FALSE;
- }
- llassert(gGLManager.mInited);
- stop_glerror();
-
- if (discard_level < 0)
- {
- llassert(mCurrentDiscardLevel >= 0);
- discard_level = mCurrentDiscardLevel;
- }
-
- // Actual image width/height = raw image width/height * 2^discard_level
- S32 w = raw_image->getWidth() << discard_level;
- S32 h = raw_image->getHeight() << discard_level;
-
- // setSize may call destroyGLTexture if the size does not match
- if (!setSize(w, h, raw_image->getComponents(), discard_level))
- {
- LL_WARNS() << "Trying to create a texture with incorrect dimensions!" << LL_ENDL;
- return FALSE;
- }
-
- if (!mHasExplicitFormat)
- {
- switch (mComponents)
- {
- case 1:
- // Use luminance alpha (for fonts)
- mFormatInternal = GL_LUMINANCE8;
- mFormatPrimary = GL_LUMINANCE;
- mFormatType = GL_UNSIGNED_BYTE;
- break;
- case 2:
- // Use luminance alpha (for fonts)
- mFormatInternal = GL_LUMINANCE8_ALPHA8;
- mFormatPrimary = GL_LUMINANCE_ALPHA;
- mFormatType = GL_UNSIGNED_BYTE;
- break;
- case 3:
- mFormatInternal = GL_RGB8;
- mFormatPrimary = GL_RGB;
- mFormatType = GL_UNSIGNED_BYTE;
- break;
- case 4:
- mFormatInternal = GL_RGBA8;
- mFormatPrimary = GL_RGBA;
- mFormatType = GL_UNSIGNED_BYTE;
- break;
- default:
- LL_ERRS() << "Bad number of components for texture: " << (U32) getComponents() << LL_ENDL;
- }
- }
-
- mCurrentDiscardLevel = discard_level;
- mDiscardLevelInAtlas = discard_level;
- mTexelsInAtlas = raw_image->getWidth() * raw_image->getHeight() ;
- mLastBindTime = sLastFrameTime;
- mGLTextureCreated = false ;
-
- glPixelStorei(GL_UNPACK_ROW_LENGTH, raw_image->getWidth());
- stop_glerror();
-
- if(mFormatSwapBytes)
- {
- glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
- stop_glerror();
- }
-
- return TRUE ;
-}
-
-void LLImageGL::postAddToAtlas()
-{
- if(mFormatSwapBytes)
- {
- glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
- stop_glerror();
- }
-
- glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- gGL.getTexUnit(0)->setTextureFilteringOption(mFilterOption);
- stop_glerror();
+ return true;
}
U32 type_width_from_pixtype(U32 pixtype)
@@ -1145,7 +1006,7 @@ bool should_stagger_image_set(bool compressed)
#else
// glTexSubImage2D doesn't work with compressed textures on select tested Nvidia GPUs on Windows 10 -Cosmic,2023-03-08
// Setting media textures off-thread seems faster when not using sub_image_lines (Nvidia/Windows 10) -Cosmic,2023-03-31
- return !compressed && on_main_thread();
+ return !compressed && on_main_thread() && !gGLManager.mIsIntel;
#endif
}
@@ -1167,31 +1028,31 @@ void sub_image_lines(U32 target, S32 miplevel, S32 x_offset, S32 y_offset, S32 w
}
}
-BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update /* = FALSE */, LLGLuint use_name)
+bool LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, bool force_fast_update /* = false */, LLGLuint use_name)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
if (!width || !height)
{
- return TRUE;
+ return true;
}
LLGLuint tex_name = use_name != 0 ? use_name : mTexName;
if (0 == tex_name)
{
// *TODO: Re-enable warning? Ran into thread locking issues? DK 2011-02-18
//LL_WARNS() << "Setting subimage on image without GL texture" << LL_ENDL;
- return FALSE;
+ return false;
}
if (datap == NULL)
{
// *TODO: Re-enable warning? Ran into thread locking issues? DK 2011-02-18
//LL_WARNS() << "Setting subimage on image with NULL datap" << LL_ENDL;
- return FALSE;
+ return false;
}
// HACK: allow the caller to explicitly force the fast path (i.e. using glTexSubImage2D here instead of calling setImage) even when updating the full texture.
if (!force_fast_update && x_pos == 0 && y_pos == 0 && width == getWidth() && height == getHeight() && data_width == width && data_height == height)
{
- setImage(datap, FALSE, tex_name);
+ setImage(datap, false, tex_name);
}
else
{
@@ -1243,7 +1104,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
const U8* sub_datap = datap + (y_pos * data_width + x_pos) * getComponents();
// Update the GL texture
- BOOL res = gGL.getTexUnit(0)->bindManual(mBindTarget, tex_name);
+ bool res = gGL.getTexUnit(0)->bindManual(mBindTarget, tex_name);
if (!res) LL_ERRS() << "LLImageGL::setSubImage(): bindTexture failed" << LL_ENDL;
stop_glerror();
@@ -1273,28 +1134,28 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
stop_glerror();
mGLTextureCreated = true;
}
- return TRUE;
+ return true;
}
-BOOL LLImageGL::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update /* = FALSE */, LLGLuint use_name)
+bool LLImageGL::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, bool force_fast_update /* = false */, LLGLuint use_name)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
return setSubImage(imageraw->getData(), imageraw->getWidth(), imageraw->getHeight(), x_pos, y_pos, width, height, force_fast_update, use_name);
}
// Copy sub image from frame buffer
-BOOL LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos, S32 width, S32 height)
+bool LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos, S32 width, S32 height)
{
if (gGL.getTexUnit(0)->bind(this, false, true))
{
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, fb_x, fb_y, x_pos, y_pos, width, height);
mGLTextureCreated = true;
stop_glerror();
- return TRUE;
+ return true;
}
else
{
- return FALSE;
+ return false;
}
}
@@ -1314,7 +1175,7 @@ void LLImageGL::generateTextures(S32 numTextures, U32 *textures)
name_count = pool_size;
}
- if (numTextures <= name_count)
+ if ((U32)numTextures <= name_count)
{
//copy teture names off the end of the pool
memcpy(textures, name_pool + name_count - numTextures, sizeof(U32) * numTextures);
@@ -1328,12 +1189,36 @@ void LLImageGL::generateTextures(S32 numTextures, U32 *textures)
}
// static
+void LLImageGL::updateClass()
+{
+ sFrameCount++;
+}
+
+// static
void LLImageGL::deleteTextures(S32 numTextures, const U32 *textures)
{
+ // wait a few frames before actually deleting the textures to avoid
+ // synchronization issues with the GPU
+ static std::vector<U32> sFreeList[4];
+
if (gGLManager.mInited)
{
- free_tex_images(numTextures, textures);
- glDeleteTextures(numTextures, textures);
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
+ U32 idx = sFrameCount % 4;
+
+ for (S32 i = 0; i < numTextures; ++i)
+ {
+ sFreeList[idx].push_back(textures[i]);
+ }
+
+ idx = (sFrameCount + 3) % 4;
+
+ if (!sFreeList[idx].empty())
+ {
+ glDeleteTextures((GLsizei) sFreeList[idx].size(), sFreeList[idx].data());
+ free_tex_images((GLsizei) sFreeList[idx].size(), sFreeList[idx].data());
+ sFreeList[idx].resize(0);
+ }
}
}
@@ -1511,7 +1396,7 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
//create an empty GL texture: just create a texture name
//the texture is assiciate with some image by calling glTexImage outside LLImageGL
-BOOL LLImageGL::createGLTexture()
+bool LLImageGL::createGLTexture()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
checkActiveThread();
@@ -1519,7 +1404,7 @@ BOOL LLImageGL::createGLTexture()
if (gGLManager.mIsDisabled)
{
LL_WARNS() << "Trying to create a texture while GL is disabled!" << LL_ENDL;
- return FALSE;
+ return false;
}
mGLTextureCreated = false ; //do not save this texture when gl is destroyed.
@@ -1539,13 +1424,13 @@ BOOL LLImageGL::createGLTexture()
if (!mTexName)
{
LL_WARNS() << "LLImageGL::createGLTexture failed to make an empty texture" << LL_ENDL;
- return FALSE;
+ return false;
}
- return TRUE ;
+ return true ;
}
-BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename/*=0*/, BOOL to_create, S32 category, bool defer_copy, LLGLuint* tex_name)
+bool LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename/*=0*/, bool to_create, S32 category, bool defer_copy, LLGLuint* tex_name)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
checkActiveThread();
@@ -1553,7 +1438,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
if (gGLManager.mIsDisabled)
{
LL_WARNS() << "Trying to create a texture while GL is disabled!" << LL_ENDL;
- return FALSE;
+ return false;
}
llassert(gGLManager.mInited);
@@ -1563,7 +1448,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
{
LL_WARNS() << "Trying to create a texture from invalid image data" << LL_ENDL;
mGLTextureCreated = false;
- return FALSE;
+ return false;
}
if (discard_level < 0)
@@ -1584,7 +1469,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
{
LL_WARNS() << "Trying to create a texture with incorrect dimensions!" << LL_ENDL;
mGLTextureCreated = false;
- return FALSE;
+ return false;
}
if (mHasExplicitFormat &&
@@ -1593,7 +1478,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
{
LL_WARNS() << "Incorrect format: " << std::hex << mFormatPrimary << " components: " << (U32)mComponents << LL_ENDL;
- mHasExplicitFormat = FALSE;
+ mHasExplicitFormat = false;
}
if( !mHasExplicitFormat )
@@ -1635,15 +1520,15 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
mCurrentDiscardLevel = discard_level;
mLastBindTime = sLastFrameTime;
mGLTextureCreated = false;
- return TRUE ;
+ return true ;
}
setCategory(category);
const U8* rawdata = imageraw->getData();
- return createGLTexture(discard_level, rawdata, FALSE, usename, defer_copy, tex_name);
+ return createGLTexture(discard_level, rawdata, false, usename, defer_copy, tex_name);
}
-BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_hasmips, S32 usename, bool defer_copy, LLGLuint* tex_name)
+bool LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, bool data_hasmips, S32 usename, bool defer_copy, LLGLuint* tex_name)
// Call with void data, vmem is allocated but unitialized
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
@@ -1716,7 +1601,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
LL_PROFILE_ZONE_NAMED("cglt - late setImage");
if (!setImage(data_in, data_hasmips, new_texname))
{
- return FALSE;
+ return false;
}
}
@@ -1748,13 +1633,12 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
mTextureMemory = (S64Bytes)getMipBytes(mCurrentDiscardLevel);
- mTexelsInGLTexture = getWidth() * getHeight();
// mark this as bound at this point, so we don't throw it out immediately
mLastBindTime = sLastFrameTime;
checkActiveThread();
- return TRUE;
+ return true;
}
void LLImageGL::syncToMainThread(LLGLuint new_tex_name)
@@ -1824,10 +1708,9 @@ void LLImageGL::syncTexName(LLGLuint texname)
}
}
-BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) const
+bool LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) const
{
- llassert_always(sAllowReadBackRaw) ;
- //LL_ERRS() << "should not call this function!" << LL_ENDL ;
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
if (discard_level < 0)
{
@@ -1836,7 +1719,7 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre
if (mTexName == 0 || discard_level < mCurrentDiscardLevel || discard_level > mMaxDiscardLevel )
{
- return FALSE;
+ return false;
}
S32 gl_discard = discard_level - mCurrentDiscardLevel;
@@ -1853,7 +1736,7 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre
if (glwidth == 0)
{
// No mip data smaller than current discard level
- return FALSE;
+ return false;
}
S32 width = getWidth(discard_level);
@@ -1861,14 +1744,14 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre
S32 ncomponents = getComponents();
if (ncomponents == 0)
{
- return FALSE;
+ return false;
}
if(width < glwidth)
{
LL_WARNS() << "texture size is smaller than it should be." << LL_ENDL ;
LL_WARNS() << "width: " << width << " glwidth: " << glwidth << " mWidth: " << mWidth <<
" mCurrentDiscardLevel: " << (S32)mCurrentDiscardLevel << " discard_level: " << (S32)discard_level << LL_ENDL ;
- return FALSE ;
+ return false ;
}
if (width <= 0 || width > 2048 || height <= 0 || height > 2048 || ncomponents < 1 || ncomponents > 4)
@@ -1890,6 +1773,8 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre
}
//-----------------------------------------------------------------------------------------------
+ LLImageDataLock lock(imageraw);
+
if (is_compressed)
{
LLGLint glbytes;
@@ -1898,7 +1783,7 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre
{
LL_WARNS() << "Memory allocation failed for reading back texture. Size is: " << glbytes << LL_ENDL ;
LL_WARNS() << "width: " << width << "height: " << height << "components: " << ncomponents << LL_ENDL ;
- return FALSE ;
+ return false ;
}
glGetCompressedTexImage(mTarget, gl_discard, (GLvoid*)(imageraw->getData()));
@@ -1910,7 +1795,7 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre
{
LL_WARNS() << "Memory allocation failed for reading back texture." << LL_ENDL ;
LL_WARNS() << "width: " << width << "height: " << height << "components: " << ncomponents << LL_ENDL ;
- return FALSE ;
+ return false ;
}
glGetTexImage(GL_TEXTURE_2D, gl_discard, mFormatPrimary, mFormatType, (GLvoid*)(imageraw->getData()));
@@ -1928,11 +1813,11 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre
LL_WARNS() << "GL Error happens after reading back texture. Error code: " << error << LL_ENDL ;
}
- return FALSE ;
+ return false ;
}
//-----------------------------------------------------------------------------------------------
- return TRUE ;
+ return true ;
}
void LLImageGL::destroyGLTexture()
@@ -1949,7 +1834,7 @@ void LLImageGL::destroyGLTexture()
LLImageGL::deleteTextures(1, &mTexName);
mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel.
mTexName = 0;
- mGLTextureCreated = FALSE ;
+ mGLTextureCreated = false ;
}
}
@@ -2000,7 +1885,7 @@ void LLImageGL::setFilteringOption(LLTexUnit::eTextureFilterOptions option)
}
}
-BOOL LLImageGL::getIsResident(BOOL test_now)
+bool LLImageGL::getIsResident(bool test_now)
{
if (test_now)
{
@@ -2010,7 +1895,7 @@ BOOL LLImageGL::getIsResident(BOOL test_now)
}
else
{
- mIsResident = FALSE;
+ mIsResident = false;
}
}
@@ -2073,17 +1958,17 @@ S64 LLImageGL::getMipBytes(S32 discard_level) const
return res;
}
-BOOL LLImageGL::isJustBound() const
+bool LLImageGL::isJustBound() const
{
- return (BOOL)(sLastFrameTime - mLastBindTime < 0.5f);
+ return sLastFrameTime - mLastBindTime < 0.5f;
}
-BOOL LLImageGL::getBoundRecently() const
+bool LLImageGL::getBoundRecently() const
{
- return (BOOL)(sLastFrameTime - mLastBindTime < MIN_TEXTURE_LIFETIME);
+ return (bool)(sLastFrameTime - mLastBindTime < MIN_TEXTURE_LIFETIME);
}
-BOOL LLImageGL::getIsAlphaMask() const
+bool LLImageGL::getIsAlphaMask() const
{
llassert_always(!sSkipAnalyzeAlpha);
return mIsMask;
@@ -2096,7 +1981,7 @@ void LLImageGL::setTarget(const LLGLenum target, const LLTexUnit::eTextureType b
}
const S8 INVALID_OFFSET = -99 ;
-void LLImageGL::setNeedsAlphaAndPickMask(BOOL need_mask)
+void LLImageGL::setNeedsAlphaAndPickMask(bool need_mask)
{
if(mNeedsAlphaAndPickMask != need_mask)
{
@@ -2109,7 +1994,7 @@ void LLImageGL::setNeedsAlphaAndPickMask(BOOL need_mask)
else //do not need alpha mask
{
mAlphaOffset = INVALID_OFFSET ;
- mIsMask = FALSE;
+ mIsMask = false;
}
}
}
@@ -2134,8 +2019,8 @@ void LLImageGL::calcAlphaChannelOffsetAndStride()
case GL_RED:
case GL_RGB:
case GL_SRGB:
- mNeedsAlphaAndPickMask = FALSE;
- mIsMask = FALSE;
+ mNeedsAlphaAndPickMask = false;
+ mIsMask = false;
return; //no alpha channel.
case GL_RGBA:
case GL_SRGB_ALPHA:
@@ -2182,8 +2067,8 @@ void LLImageGL::calcAlphaChannelOffsetAndStride()
{
LL_WARNS() << "Cannot analyze alpha for image with format type " << std::hex << mFormatType << std::dec << LL_ENDL;
- mNeedsAlphaAndPickMask = FALSE ;
- mIsMask = FALSE;
+ mNeedsAlphaAndPickMask = false ;
+ mIsMask = false;
}
}
@@ -2280,17 +2165,19 @@ void LLImageGL::analyzeAlpha(const void* data_in, U32 w, U32 h)
(lowerhalftotal == length && alphatotal != 0) || // all close to transparent but not all totally transparent, or
(upperhalftotal == length && alphatotal != 255*length)) // all close to opaque but not all totally opaque
{
- mIsMask = FALSE; // not suitable for masking
+ mIsMask = false; // not suitable for masking
}
else
{
- mIsMask = TRUE;
+ mIsMask = true;
}
}
//----------------------------------------------------------------------------
U32 LLImageGL::createPickMask(S32 pWidth, S32 pHeight)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
+ freePickMask();
U32 pick_width = pWidth/2 + 1;
U32 pick_height = pHeight/2 + 1;
@@ -2308,7 +2195,6 @@ U32 LLImageGL::createPickMask(S32 pWidth, S32 pHeight)
//----------------------------------------------------------------------------
void LLImageGL::freePickMask()
{
- // pickmask validity depends on old image size, delete it
if (mPickMask != NULL)
{
delete [] mPickMask;
@@ -2346,16 +2232,16 @@ void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in)
return ;
}
- freePickMask();
-
if (mFormatType != GL_UNSIGNED_BYTE ||
((mFormatPrimary != GL_RGBA)
&& (mFormatPrimary != GL_SRGB_ALPHA)))
{
//cannot generate a pick mask for this texture
+ freePickMask();
return;
}
+
#ifdef SHOW_ASSERT
const U32 pickSize = createPickMask(width, height);
#else // SHOW_ASSERT
@@ -2384,9 +2270,9 @@ void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in)
}
}
-BOOL LLImageGL::getMask(const LLVector2 &tc)
+bool LLImageGL::getMask(const LLVector2 &tc)
{
- BOOL res = TRUE;
+ bool res = true;
if (mPickMask)
{
@@ -2430,13 +2316,13 @@ BOOL LLImageGL::getMask(const LLVector2 &tc)
S32 idx = y*mPickMaskWidth+x;
S32 offset = idx%8;
- res = mPickMask[idx/8] & (1 << offset) ? TRUE : FALSE;
+ res = (mPickMask[idx/8] & (1 << offset)) != 0;
}
return res;
}
-void LLImageGL::setCurTexSizebar(S32 index, BOOL set_pick_size)
+void LLImageGL::setCurTexSizebar(S32 index, bool set_pick_size)
{
sCurTexSizeBar = index ;
@@ -2454,6 +2340,114 @@ void LLImageGL::resetCurTexSizebar()
sCurTexSizeBar = -1 ;
sCurTexPickSize = -1 ;
}
+
+bool LLImageGL::scaleDown(S32 desired_discard)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
+
+ if (mTarget != GL_TEXTURE_2D)
+ {
+ return false;
+ }
+
+ desired_discard = llmin(desired_discard, mMaxDiscardLevel);
+
+ if (desired_discard <= mCurrentDiscardLevel)
+ {
+ return false;
+ }
+
+ S32 mip = desired_discard - mCurrentDiscardLevel;
+
+ S32 desired_width = getWidth(desired_discard);
+ S32 desired_height = getHeight(desired_discard);
+
+ if (gGLManager.mDownScaleMethod == 0)
+ { // use an FBO to downscale the texture
+ // allocate new texture
+ U32 temp_texname = 0;
+ generateTextures(1, &temp_texname);
+ gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, temp_texname, true);
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("scaleDown - glTexImage2D");
+ glTexImage2D(mTarget, 0, mFormatPrimary, desired_width, desired_height, 0, mFormatPrimary, mFormatType, NULL);
+ }
+
+ // account for new texture getting created
+ alloc_tex_image(desired_width, desired_height, mFormatPrimary);
+
+ // Use render-to-texture to scale down the texture
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("scaleDown - glFramebufferTexture2D");
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTarget, temp_texname, 0);
+ }
+
+ glViewport(0, 0, desired_width, desired_height);
+
+ // draw a full screen triangle
+ gGL.getTexUnit(0)->bind(this);
+ glDrawArrays(GL_TRIANGLES, 0, 3);
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ // delete old texture and assign new texture name
+ deleteTextures(1, &mTexName);
+ mTexName = temp_texname;
+
+ if (mHasMipMaps)
+ { // generate mipmaps if needed
+ LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("scaleDown - glGenerateMipmap");
+ gGL.getTexUnit(0)->bind(this);
+ glGenerateMipmap(mTarget);
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ }
+ }
+ else
+ { // use a PBO to downscale the texture
+ U64 size = getBytes(desired_discard);
+ llassert(size <= 2048 * 2048 * 4); // we shouldn't be using this method to downscale huge textures, but it'll work
+ gGL.getTexUnit(0)->bind(this);
+
+ if (sScratchPBO == 0)
+ {
+ glGenBuffers(1, &sScratchPBO);
+ sScratchPBOSize = 0;
+ }
+
+ glBindBuffer(GL_PIXEL_PACK_BUFFER, sScratchPBO);
+
+ if (size > sScratchPBOSize)
+ {
+ glBufferData(GL_PIXEL_PACK_BUFFER, size, NULL, GL_STREAM_COPY);
+ sScratchPBOSize = (U32)size;
+ }
+
+ glGetTexImage(mTarget, mip, mFormatPrimary, mFormatType, nullptr);
+
+ free_tex_image(mTexName);
+
+ glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
+
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, sScratchPBO);
+ glTexImage2D(mTarget, 0, mFormatPrimary, desired_width, desired_height, 0, mFormatPrimary, mFormatType, nullptr);
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+
+ alloc_tex_image(desired_width, desired_height, mFormatPrimary);
+
+ if (mHasMipMaps)
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("scaleDown - glGenerateMipmap");
+ glGenerateMipmap(mTarget);
+ }
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ }
+
+ mCurrentDiscardLevel = desired_discard;
+
+ return true;
+}
+
+
//----------------------------------------------------------------------------
#if LL_IMAGEGL_THREAD_CHECK
void LLImageGL::checkActiveThread()
diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h
index 89e35d2226..5073701c30 100644
--- a/indra/llrender/llimagegl.h
+++ b/indra/llrender/llimagegl.h
@@ -39,6 +39,7 @@
#include "llrender.h"
#include "threadpool.h"
#include "workqueue.h"
+#include <unordered_set>
#define LL_IMAGEGL_THREAD_CHECK 0 //set to 1 to enable thread debugging for ImageGL
@@ -47,12 +48,23 @@ class LLWindow;
#define BYTES_TO_MEGA_BYTES(x) ((x) >> 20)
#define MEGA_BYTES_TO_BYTES(x) ((x) << 20)
+namespace LLImageGLMemory
+{
+ void alloc_tex_image(U32 width, U32 height, U32 pixformat);
+ void free_tex_image(U32 texName);
+ void free_tex_images(U32 count, const U32* texNames);
+ void free_cur_tex_image();
+}
+
//============================================================================
class LLImageGL : public LLRefCount
{
friend class LLTexUnit;
public:
+ // call once per frame
+ static void updateClass();
+
// Get an estimate of how many bytes have been allocated in vram for textures.
// Does not include mipmaps.
// NOTE: multiplying this number by two gives a good estimate for total
@@ -68,16 +80,15 @@ public:
static S64 dataFormatBytes(S32 dataformat, S32 width, S32 height);
static S32 dataFormatComponents(S32 dataformat);
- BOOL updateBindStats() const ;
+ bool updateBindStats() const ;
F32 getTimePassedSinceLastBound();
void forceUpdateBindStats(void) const;
// needs to be called every frame
static void updateStats(F32 current_time);
- // Save off / restore GL textures
- static void destroyGL(BOOL save_state = TRUE);
- static void restoreGL();
+ // cleanup GL state
+ static void destroyGL();
static void dirtyTexOptions();
static bool checkSize(S32 width, S32 height);
@@ -85,14 +96,14 @@ public:
//for server side use only.
// Not currently necessary for LLImageGL, but required in some derived classes,
// so include for compatability
- static BOOL create(LLPointer<LLImageGL>& dest, BOOL usemipmaps = TRUE);
- static BOOL create(LLPointer<LLImageGL>& dest, U32 width, U32 height, U8 components, BOOL usemipmaps = TRUE);
- static BOOL create(LLPointer<LLImageGL>& dest, const LLImageRaw* imageraw, BOOL usemipmaps = TRUE);
+ static bool create(LLPointer<LLImageGL>& dest, bool usemipmaps = true);
+ static bool create(LLPointer<LLImageGL>& dest, U32 width, U32 height, U8 components, bool usemipmaps = true);
+ static bool create(LLPointer<LLImageGL>& dest, const LLImageRaw* imageraw, bool usemipmaps = true);
public:
- LLImageGL(BOOL usemipmaps = TRUE);
- LLImageGL(U32 width, U32 height, U8 components, BOOL usemipmaps = TRUE);
- LLImageGL(const LLImageRaw* imageraw, BOOL usemipmaps = TRUE);
+ LLImageGL(bool usemipmaps = true);
+ LLImageGL(U32 width, U32 height, U8 components, bool usemipmaps = true);
+ LLImageGL(const LLImageRaw* imageraw, bool usemipmaps = true);
// For wrapping textures created via GL elsewhere with our API only. Use with caution.
LLImageGL(LLGLuint mTexName, U32 components, LLGLenum target, LLGLint formatInternal, LLGLenum formatPrimary, LLGLenum formatType, LLTexUnit::eTextureAddressMode addressMode);
@@ -112,34 +123,38 @@ public:
static void setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels, bool allow_compression = true);
- BOOL createGLTexture() ;
- BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE,
+ bool createGLTexture() ;
+ bool createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, bool to_create = true,
S32 category = sMaxCategories-1, bool defer_copy = false, LLGLuint* tex_name = nullptr);
- BOOL createGLTexture(S32 discard_level, const U8* data, BOOL data_hasmips = FALSE, S32 usename = 0, bool defer_copy = false, LLGLuint* tex_name = nullptr);
+ bool createGLTexture(S32 discard_level, const U8* data, bool data_hasmips = false, S32 usename = 0, bool defer_copy = false, LLGLuint* tex_name = nullptr);
void setImage(const LLImageRaw* imageraw);
- BOOL setImage(const U8* data_in, BOOL data_hasmips = FALSE, S32 usename = 0);
+ bool setImage(const U8* data_in, bool data_hasmips = false, S32 usename = 0);
// *TODO: This function may not work if the textures is compressed (i.e.
// RenderCompressTextures is 0). Partial image updates do not work on
// compressed textures.
- BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE, LLGLuint use_name = 0);
- BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE, LLGLuint use_name = 0);
- BOOL setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos, S32 width, S32 height);
+ bool setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, bool force_fast_update = false, LLGLuint use_name = 0);
+ bool setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, bool force_fast_update = false, LLGLuint use_name = 0);
+ bool setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos, S32 width, S32 height);
// wait for gl commands to finish on current thread and push
// a lambda to main thread to swap mNewTexName and mTexName
void syncToMainThread(LLGLuint new_tex_name);
// Read back a raw image for this discard level, if it exists
- BOOL readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) const;
+ bool readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) const;
void destroyGLTexture();
void forceToInvalidateGLTexture();
- void setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, BOOL swap_bytes = FALSE);
+ void setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, bool swap_bytes = false);
void setComponents(S8 ncomponents) { mComponents = ncomponents; }
S32 getDiscardLevel() const { return mCurrentDiscardLevel; }
S32 getMaxDiscardLevel() const { return mMaxDiscardLevel; }
+ // override the current discard level
+ // should only be used for local textures where you know exactly what you're doing
+ void setDiscardLevel(S32 level) { mCurrentDiscardLevel = level; }
+
S32 getCurrentWidth() const { return mWidth ;}
S32 getCurrentHeight() const { return mHeight ;}
S32 getWidth(S32 discard_level = -1) const;
@@ -147,18 +162,18 @@ public:
U8 getComponents() const { return mComponents; }
S64 getBytes(S32 discard_level = -1) const;
S64 getMipBytes(S32 discard_level = -1) const;
- BOOL getBoundRecently() const;
- BOOL isJustBound() const;
- BOOL getHasExplicitFormat() const { return mHasExplicitFormat; }
+ bool getBoundRecently() const;
+ bool isJustBound() const;
+ bool getHasExplicitFormat() const { return mHasExplicitFormat; }
LLGLenum getPrimaryFormat() const { return mFormatPrimary; }
LLGLenum getFormatType() const { return mFormatType; }
- BOOL getHasGLTexture() const { return mTexName != 0; }
+ bool getHasGLTexture() const { return mTexName != 0; }
LLGLuint getTexName() const { return mTexName; }
- BOOL getIsAlphaMask() const;
+ bool getIsAlphaMask() const;
- BOOL getIsResident(BOOL test_now = FALSE); // not const
+ bool getIsResident(bool test_now = false); // not const
void setTarget(const LLGLenum target, const LLTexUnit::eTextureType bind_target);
@@ -166,11 +181,11 @@ public:
bool isGLTextureCreated(void) const { return mGLTextureCreated ; }
void setGLTextureCreated (bool initialized) { mGLTextureCreated = initialized; }
- BOOL getUseMipMaps() const { return mUseMipMaps; }
- void setUseMipMaps(BOOL usemips) { mUseMipMaps = usemips; }
- void setHasMipMaps(BOOL hasmips) { mHasMipMaps = hasmips; }
+ bool getUseMipMaps() const { return mUseMipMaps; }
+ void setUseMipMaps(bool usemips) { mUseMipMaps = usemips; }
+ void setHasMipMaps(bool hasmips) { mHasMipMaps = hasmips; }
void updatePickMask(S32 width, S32 height, const U8* data_in);
- BOOL getMask(const LLVector2 &tc);
+ bool getMask(const LLVector2 &tc);
void checkTexSize(bool forced = false) const ;
@@ -186,19 +201,12 @@ public:
void setFilteringOption(LLTexUnit::eTextureFilterOptions option);
LLTexUnit::eTextureFilterOptions getFilteringOption(void) const { return mFilterOption; }
- LLGLenum getTexTarget()const { return mTarget ;}
- S8 getDiscardLevelInAtlas()const {return mDiscardLevelInAtlas;}
- U32 getTexelsInAtlas()const { return mTexelsInAtlas ;}
- U32 getTexelsInGLTexture()const {return mTexelsInGLTexture;}
-
+ LLGLenum getTexTarget()const { return mTarget; }
- void init(BOOL usemipmaps);
+ void init(bool usemipmaps);
virtual void cleanup(); // Clean up the LLImageGL so it can be reinitialized. Be careful when using this in derived class destructors
- void setNeedsAlphaAndPickMask(BOOL need_mask);
-
- BOOL preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image);
- void postAddToAtlas() ;
+ void setNeedsAlphaAndPickMask(bool need_mask);
#if LL_IMAGEGL_THREAD_CHECK
// thread debugging
@@ -206,6 +214,13 @@ public:
void checkActiveThread();
#endif
+ // scale down to the desired discard level using GPU
+ // returns true if texture was scaled down
+ // desired discard will be clamped to max discard
+ // if desired discard is less than or equal to current discard, no scaling will occur
+ // only works for GL_TEXTURE_2D target
+ bool scaleDown(S32 desired_discard);
+
public:
// Various GL/Rendering options
S64Bytes mTextureMemory;
@@ -222,25 +237,20 @@ private:
U16 mPickMaskWidth;
U16 mPickMaskHeight;
S8 mUseMipMaps;
- BOOL mHasExplicitFormat; // If false (default), GL format is f(mComponents)
+ bool mHasExplicitFormat; // If false (default), GL format is f(mComponents)
bool mAutoGenMips = false;
- BOOL mIsMask;
- BOOL mNeedsAlphaAndPickMask;
+ bool mIsMask;
+ bool mNeedsAlphaAndPickMask;
S8 mAlphaStride ;
S8 mAlphaOffset ;
bool mGLTextureCreated ;
LLGLuint mTexName;
- //LLGLuint mNewTexName = 0; // tex name set by background thread to be applied in main thread
U16 mWidth;
U16 mHeight;
S8 mCurrentDiscardLevel;
- S8 mDiscardLevelInAtlas;
- U32 mTexelsInAtlas ;
- U32 mTexelsInGLTexture;
-
bool mAllowCompression;
protected:
@@ -261,42 +271,44 @@ protected:
LLGLint mFormatInternal; // = GL internalformat
LLGLenum mFormatPrimary; // = GL format (pixel data format)
LLGLenum mFormatType;
- BOOL mFormatSwapBytes;// if true, use glPixelStorei(GL_UNPACK_SWAP_BYTES, 1)
+ bool mFormatSwapBytes;// if true, use glPixelStorei(GL_UNPACK_SWAP_BYTES, 1)
- BOOL mExternalTexture;
+ bool mExternalTexture;
// STATICS
public:
- static std::set<LLImageGL*> sImageList;
+ static std::unordered_set<LLImageGL*> sImageList;
static S32 sCount;
-
+ static U32 sFrameCount;
static F32 sLastFrameTime;
// Global memory statistics
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;
+ static bool sGlobalUseAnisotropic;
static LLImageGL* sDefaultGLTexture ;
- static BOOL sAutomatedTest;
+ static bool sAutomatedTest;
static bool sCompressTextures; //use GL texture compression
#if DEBUG_MISS
- BOOL mMissed; // Missed on last bind?
- BOOL getMissed() const { return mMissed; };
+ bool mMissed; // Missed on last bind?
+ bool getMissed() const { return mMissed; };
#else
- BOOL getMissed() const { return FALSE; };
+ bool getMissed() const { return false; };
#endif
public:
- static void initClass(LLWindow* window, S32 num_catagories, BOOL skip_analyze_alpha = false, bool thread_texture_loads = false, bool thread_media_updates = false);
+ static void initClass(LLWindow* window, S32 num_catagories, bool skip_analyze_alpha = false, bool thread_texture_loads = false, bool thread_media_updates = false);
static void cleanupClass() ;
private:
static S32 sMaxCategories;
- static BOOL sSkipAnalyzeAlpha;
+ static bool sSkipAnalyzeAlpha;
+ static U32 sScratchPBO;
+ static U32 sScratchPBOSize;
//the flag to allow to call readBackRaw(...).
//can be removed if we do not use that function at all.
- static BOOL sAllowReadBackRaw ;
+ static bool sAllowReadBackRaw ;
//
//****************************************************************************************************
//The below for texture auditing use only
@@ -317,7 +329,7 @@ public:
static S32 sCurTexSizeBar ;
static S32 sCurTexPickSize ;
- static void setCurTexSizebar(S32 index, BOOL set_pick_size = TRUE) ;
+ static void setCurTexSizebar(S32 index, bool set_pick_size = true) ;
static void resetCurTexSizebar();
//****************************************************************************************************
diff --git a/indra/llrender/llpostprocess.cpp b/indra/llrender/llpostprocess.cpp
index 4242e330f4..eef7193c92 100644
--- a/indra/llrender/llpostprocess.cpp
+++ b/indra/llrender/llpostprocess.cpp
@@ -165,7 +165,7 @@ void LLPostProcess::invalidate()
mSceneRenderTexture = NULL ;
mNoiseTexture = NULL ;
mTempBloomTexture = NULL ;
- initialized = FALSE ;
+ initialized = false ;
}
void LLPostProcess::apply(unsigned int width, unsigned int height)
@@ -343,7 +343,7 @@ void LLPostProcess::viewOrthogonal(unsigned int width, unsigned int height)
gGL.matrixMode(LLRender::MM_PROJECTION);
gGL.pushMatrix();
gGL.loadIdentity();
- gGL.ortho( 0.f, (GLdouble) width , (GLdouble) height , 0.f, -1.f, 1.f );
+ gGL.ortho( 0.f, (GLfloat) width , (GLfloat) height , 0.f, -1.f, 1.f );
gGL.matrixMode(LLRender::MM_MODELVIEW);
gGL.pushMatrix();
gGL.loadIdentity();
@@ -367,7 +367,7 @@ void LLPostProcess::createTexture(LLPointer<LLImageGL>& texture, unsigned int wi
{
std::vector<GLubyte> data(width * height * 4, 0) ;
- texture = new LLImageGL(FALSE) ;
+ texture = new LLImageGL(false) ;
if(texture->createGLTexture())
{
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, texture->getTexName());
@@ -387,7 +387,7 @@ void LLPostProcess::createNoiseTexture(LLPointer<LLImageGL>& texture)
}
}
- texture = new LLImageGL(FALSE) ;
+ texture = new LLImageGL(false) ;
if(texture->createGLTexture())
{
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, texture->getTexName());
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index b92c9363fc..1301d325a0 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -990,6 +990,9 @@ void LLRender::syncLightState()
void LLRender::syncMatrices()
{
+ STOP_GLERROR;
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
+
static const U32 name[] =
{
LLShaderMgr::MODELVIEW_MATRIX,
@@ -1012,8 +1015,6 @@ void LLRender::syncMatrices()
if (shader)
{
- //llassert(shader);
-
bool mvp_done = false;
U32 i = MM_MODELVIEW;
@@ -1087,7 +1088,7 @@ void LLRender::syncMatrices()
if (shader->getUniformLocation(LLShaderMgr::INVERSE_PROJECTION_MATRIX))
{
glh::matrix4f inv_proj = mat.inverse();
- shader->uniformMatrix4fv(LLShaderMgr::INVERSE_PROJECTION_MATRIX, 1, FALSE, inv_proj.m);
+ shader->uniformMatrix4fv(LLShaderMgr::INVERSE_PROJECTION_MATRIX, 1, false, inv_proj.m);
}
// Used by some full screen effects - such as full screen lights, glow, etc.
@@ -1134,6 +1135,7 @@ void LLRender::syncMatrices()
syncLightState();
}
}
+ STOP_GLERROR;
}
void LLRender::translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z)
@@ -1512,7 +1514,7 @@ LLLightState* LLRender::getLight(U32 index)
void LLRender::setAmbientLightColor(const LLColor4& color)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
if (color != mAmbientLightColor)
{
++mLightHash;
@@ -1585,6 +1587,7 @@ void LLRender::end()
}
void LLRender::flush()
{
+ STOP_GLERROR;
if (mCount > 0)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
@@ -1685,7 +1688,7 @@ void LLRender::flush()
if (attribute_mask & LLVertexBuffer::MAP_TEXCOORD0)
{
- vb->setTexCoordData(mTexcoordsp.get());
+ vb->setTexCoord0Data(mTexcoordsp.get());
}
if (attribute_mask & LLVertexBuffer::MAP_COLOR)
@@ -1693,6 +1696,9 @@ void LLRender::flush()
vb->setColorData(mColorsp.get());
}
+#if LL_DARWIN
+ vb->unmapBuffer();
+#endif
vb->unbind();
sVBCache[vhash] = { vb , std::chrono::steady_clock::now() };
diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h
index ebdc9e751d..e6b4118beb 100644
--- a/indra/llrender/llrender.h
+++ b/indra/llrender/llrender.h
@@ -297,7 +297,11 @@ public:
ALTERNATE_DIFFUSE_MAP = 1,
NORMAL_MAP = 1,
SPECULAR_MAP = 2,
- NUM_TEXTURE_CHANNELS = 3,
+ BASECOLOR_MAP = 3,
+ METALLIC_ROUGHNESS_MAP = 4,
+ GLTF_NORMAL_MAP = 5,
+ EMISSIVE_MAP = 6,
+ NUM_TEXTURE_CHANNELS = 7,
};
enum eVolumeTexIndex : U8
@@ -548,6 +552,5 @@ glh::matrix4f gl_perspective(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloa
glh::matrix4f gl_lookat(LLVector3 eye, LLVector3 center, LLVector3 up);
#define LL_SHADER_LOADING_WARNS(...) LL_WARNS()
-#define LL_SHADER_UNIFORM_ERRS(...) LL_ERRS("Shader")
#endif
diff --git a/indra/llrender/llrender2dutils.cpp b/indra/llrender/llrender2dutils.cpp
index e1742f84a1..176c7a5d2c 100644
--- a/indra/llrender/llrender2dutils.cpp
+++ b/indra/llrender/llrender2dutils.cpp
@@ -51,11 +51,11 @@ const LLColor4 UI_VERTEX_COLOR(1.f, 1.f, 1.f, 1.f);
// Functions
//
-BOOL ui_point_in_rect(S32 x, S32 y, S32 left, S32 top, S32 right, S32 bottom)
+bool ui_point_in_rect(S32 x, S32 y, S32 left, S32 top, S32 right, S32 bottom)
{
- if (x < left || right < x) return FALSE;
- if (y < bottom || top < y) return FALSE;
- return TRUE;
+ if (x < left || right < x) return false;
+ if (y < bottom || top < y) return false;
+ return true;
}
@@ -91,13 +91,13 @@ void gl_draw_x(const LLRect& rect, const LLColor4& color)
}
-void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, S32 pixel_offset, BOOL filled)
+void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, S32 pixel_offset, bool filled)
{
gGL.color4fv(color.mV);
gl_rect_2d_offset_local(left, top, right, bottom, pixel_offset, filled);
}
-void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixel_offset, BOOL filled)
+void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixel_offset, bool filled)
{
gGL.pushUIMatrix();
left += LLFontGL::sCurOrigin.mX;
@@ -115,7 +115,7 @@ void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixe
}
-void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, BOOL filled )
+void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, bool filled )
{
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
@@ -143,14 +143,14 @@ void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, BOOL filled )
}
}
-void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, BOOL filled )
+void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, bool filled )
{
gGL.color4fv( color.mV );
gl_rect_2d( left, top, right, bottom, filled );
}
-void gl_rect_2d( const LLRect& rect, const LLColor4& color, BOOL filled )
+void gl_rect_2d( const LLRect& rect, const LLColor4& color, bool filled )
{
gGL.color4fv( color.mV );
gl_rect_2d( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, filled );
@@ -243,7 +243,7 @@ void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2, const LLColor4 &color )
gGL.end();
}
-void gl_triangle_2d(S32 x1, S32 y1, S32 x2, S32 y2, S32 x3, S32 y3, const LLColor4& color, BOOL filled)
+void gl_triangle_2d(S32 x1, S32 y1, S32 x2, S32 y2, S32 x3, S32 y3, const LLColor4& color, bool filled)
{
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
@@ -322,7 +322,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, bool scale_inner)
+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)
{
@@ -338,7 +338,7 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border
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, bool 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, bool scale_inner)
{
stop_glerror();
@@ -364,7 +364,7 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTex
{
// 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);
+ const LLVector3 ui_translation = (gGL.getUITranslation() + LLVector3((F32)x, (F32)y, 0.f)).scaledVec(ui_scale);
F32 uv_width = uv_outer_rect.getWidth();
F32 uv_height = uv_outer_rect.getHeight();
@@ -375,8 +375,8 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTex
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);
+ F32 image_width = (F32)image->getWidth(0);
+ F32 image_height = (F32)image->getHeight(0);
S32 image_natural_width = ll_round(image_width * uv_width);
S32 image_natural_height = ll_round(image_height * uv_height);
@@ -413,10 +413,10 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTex
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]);
+ draw_center_rect.mLeft = (F32)ll_round(ui_translation.mV[VX] + (F32)draw_center_rect.mLeft * ui_scale.mV[VX]);
+ draw_center_rect.mTop = (F32)ll_round(ui_translation.mV[VY] + (F32)draw_center_rect.mTop * ui_scale.mV[VY]);
+ draw_center_rect.mRight = (F32)ll_round(ui_translation.mV[VX] + (F32)draw_center_rect.mRight * ui_scale.mV[VX]);
+ draw_center_rect.mBottom = (F32)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],
@@ -729,7 +729,7 @@ void gl_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& c
LLRender2D::getInstance()->setLineWidth(1.f);
}
-void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled, F32 start_angle, F32 end_angle)
+void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, bool filled, F32 start_angle, F32 end_angle)
{
if (end_angle < start_angle)
{
@@ -772,7 +772,7 @@ void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled, F
gGL.popUIMatrix();
}
-void gl_circle_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled)
+void gl_circle_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, bool filled)
{
gGL.pushUIMatrix();
{
@@ -833,7 +833,7 @@ void gl_deep_circle( F32 radius, F32 depth, S32 steps )
gGL.end();
}
-void gl_ring( F32 radius, F32 width, const LLColor4& center_color, const LLColor4& side_color, S32 steps, BOOL render_center )
+void gl_ring( F32 radius, F32 width, const LLColor4& center_color, const LLColor4& side_color, S32 steps, bool render_center )
{
gGL.pushUIMatrix();
{
diff --git a/indra/llrender/llrender2dutils.h b/indra/llrender/llrender2dutils.h
index c3c6d66b8e..0d3efc38d6 100644
--- a/indra/llrender/llrender2dutils.h
+++ b/indra/llrender/llrender2dutils.h
@@ -43,30 +43,30 @@ class LLUUID;
extern const LLColor4 UI_VERTEX_COLOR;
-BOOL ui_point_in_rect(S32 x, S32 y, S32 left, S32 top, S32 right, S32 bottom);
+bool ui_point_in_rect(S32 x, S32 y, S32 left, S32 top, S32 right, S32 bottom);
void gl_state_for_2d(S32 width, S32 height);
void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2);
void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2, const LLColor4 &color );
-void gl_triangle_2d(S32 x1, S32 y1, S32 x2, S32 y2, S32 x3, S32 y3, const LLColor4& color, BOOL filled);
+void gl_triangle_2d(S32 x1, S32 y1, S32 x2, S32 y2, S32 x3, S32 y3, const LLColor4& color, bool filled);
void gl_rect_2d_simple( S32 width, S32 height );
void gl_draw_x(const LLRect& rect, const LLColor4& color);
-void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, BOOL filled = TRUE );
-void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, BOOL filled = TRUE );
-void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, S32 pixel_offset = 0, BOOL filled = TRUE );
-void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixel_offset = 0, BOOL filled = TRUE );
-void gl_rect_2d(const LLRect& rect, BOOL filled = TRUE );
-void gl_rect_2d(const LLRect& rect, const LLColor4& color, BOOL filled = TRUE );
+void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, bool filled = true );
+void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, bool filled = true );
+void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, S32 pixel_offset = 0, bool filled = true );
+void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixel_offset = 0, bool filled = true );
+void gl_rect_2d(const LLRect& rect, bool filled = true );
+void gl_rect_2d(const LLRect& rect, const LLColor4& color, bool filled = true );
void gl_rect_2d_checkerboard(const LLRect& rect, GLfloat alpha = 1.0f);
void gl_drop_shadow(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &start_color, S32 lines);
-void gl_circle_2d(F32 x, F32 y, F32 radius, S32 steps, BOOL filled);
-void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled, F32 start_angle, F32 end_angle);
+void gl_circle_2d(F32 x, F32 y, F32 radius, S32 steps, bool filled);
+void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, bool filled, F32 start_angle, F32 end_angle);
void gl_deep_circle( F32 radius, F32 depth );
-void gl_ring( F32 radius, F32 width, const LLColor4& center_color, const LLColor4& side_color, S32 steps, BOOL render_center );
+void gl_ring( F32 radius, F32 width, const LLColor4& center_color, const LLColor4& side_color, S32 steps, bool render_center );
void gl_corners_2d(S32 left, S32 top, S32 right, S32 bottom, S32 length, F32 max_frac);
void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color);
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);
@@ -76,8 +76,8 @@ void gl_draw_scaled_target(S32 x, S32 y, S32 width, S32 height, LLRenderTarget*
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), 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_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_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color);
@@ -110,12 +110,12 @@ void gl_segmented_rect_2d_tex(const S32 left, const S32 top, const S32 right, co
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 )
+inline void gl_rect_2d( const LLRect& rect, bool filled )
{
gl_rect_2d( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, filled );
}
-inline void gl_rect_2d_offset_local( const LLRect& rect, S32 pixel_offset, BOOL filled)
+inline void gl_rect_2d_offset_local( const LLRect& rect, S32 pixel_offset, bool filled)
{
gl_rect_2d_offset_local( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, pixel_offset, filled );
}
diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp
index 9cd7527d3e..f700201ace 100644
--- a/indra/llrender/llrendertarget.cpp
+++ b/indra/llrender/llrendertarget.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llrendertarget.cpp
* @brief LLRenderTarget implementation
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -44,7 +44,7 @@ void check_framebuffer_status()
break;
default:
LL_WARNS() << "check_framebuffer_status failed -- " << std::hex << status << LL_ENDL;
- ll_fail("check_framebuffer_status failed");
+ ll_fail("check_framebuffer_status failed");
break;
}
}
@@ -75,10 +75,10 @@ LLRenderTarget::~LLRenderTarget()
}
void LLRenderTarget::resize(U32 resx, U32 resy)
-{
+{
//for accounting, get the number of pixels added/subtracted
S32 pix_diff = (resx*resy)-(mResX*mResY);
-
+
mResX = resx;
mResY = resy;
@@ -92,7 +92,7 @@ void LLRenderTarget::resize(U32 resx, U32 resy)
}
if (mDepth)
- {
+ {
gGL.getTexUnit(0)->bindManual(mUsage, mDepth);
U32 internal_type = LLTexUnit::getInternalType(mUsage);
LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT24, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL, false);
@@ -100,7 +100,7 @@ void LLRenderTarget::resize(U32 resx, U32 resy)
sBytesAllocated += pix_diff*4;
}
}
-
+
bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, LLTexUnit::eTextureType usage, LLTexUnit::eTextureMipGeneration generateMipMaps)
{
@@ -112,7 +112,7 @@ bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, LLT
resy = llmin(resy, (U32) gGLManager.mGLMaxTextureSize);
release();
-
+
mResX = resx;
mResY = resy;
@@ -123,9 +123,9 @@ bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, LLT
if (mGenerateMipMaps != LLTexUnit::TMG_NONE) {
// Calculate the number of mip levels based upon resolution that we should have.
- mMipLevels = 1 + floor(log10((float)llmax(mResX, mResY))/log10(2.0));
+ mMipLevels = 1 + (U32)floor(log10((float)llmax(mResX, mResY)) / log10(2.0));
}
-
+
if (depth)
{
if (!allocateDepth())
@@ -140,12 +140,12 @@ bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, LLT
if (mDepth)
{
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
-
+
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), mDepth, 0);
glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
}
-
+
return addColorAttachment(color_fmt);
}
@@ -190,7 +190,7 @@ void LLRenderTarget::releaseColorAttachment()
llassert(!isBoundInStack());
llassert(mTex.size() == 1); //cannot use releaseColorAttachment with LLRenderTarget managed color targets
llassert(mFBO != 0); // mFBO must be valid
-
+
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, LLTexUnit::getInternalType(mUsage), 0, 0);
glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
@@ -208,7 +208,7 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
return true;
}
- U32 offset = mTex.size();
+ U32 offset = static_cast<U32>(mTex.size());
if( offset >= 4 )
{
@@ -238,12 +238,12 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
return false;
}
}
-
+
sBytesAllocated += mResX*mResY*4;
stop_glerror();
-
+
if (offset == 0)
{ //use bilinear filtering on single texture render targets that aren't multisampled
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
@@ -266,15 +266,15 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
stop_glerror();
}
-
+
if (mFBO)
{
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+offset,
LLTexUnit::getInternalType(mUsage), tex, 0);
-
+
check_framebuffer_status();
-
+
glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
}
@@ -286,8 +286,8 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
bindTarget();
flush();
}
-
-
+
+
return true;
}
@@ -296,7 +296,7 @@ bool LLRenderTarget::allocateDepth()
LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
LLImageGL::generateTextures(1, &mDepth);
gGL.getTexUnit(0)->bindManual(mUsage, mDepth);
-
+
U32 internal_type = LLTexUnit::getInternalType(mUsage);
stop_glerror();
clear_glerror();
@@ -336,7 +336,7 @@ void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target)
if (mDepth)
{
glBindFramebuffer(GL_FRAMEBUFFER, target.mFBO);
-
+
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), mDepth, 0);
check_framebuffer_status();
@@ -355,7 +355,7 @@ void LLRenderTarget::release()
if (mDepth)
{
LLImageGL::deleteTextures(1, &mDepth);
-
+
mDepth = 0;
sBytesAllocated -= mResX*mResY*4;
@@ -378,11 +378,11 @@ void LLRenderTarget::release()
if (mFBO && (mTex.size() > 1))
{
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
- S32 z;
+ size_t z;
for (z = mTex.size() - 1; z >= 1; z--)
{
sBytesAllocated -= mResX*mResY*4;
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+z, LLTexUnit::getInternalType(mUsage), 0, 0);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, static_cast<GLenum>(GL_COLOR_ATTACHMENT0+z), LLTexUnit::getInternalType(mUsage), 0, 0);
LLImageGL::deleteTextures(1, &mTex[z]);
}
glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
@@ -408,7 +408,7 @@ void LLRenderTarget::release()
mTex.clear();
mInternalFormat.clear();
-
+
mResX = mResY = 0;
}
@@ -417,7 +417,7 @@ void LLRenderTarget::bindTarget()
LL_PROFILE_GPU_ZONE("bindTarget");
llassert(mFBO);
llassert(!isBoundInStack());
-
+
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
sCurFBO = mFBO;
@@ -426,14 +426,17 @@ void LLRenderTarget::bindTarget()
GL_COLOR_ATTACHMENT1,
GL_COLOR_ATTACHMENT2,
GL_COLOR_ATTACHMENT3};
- glDrawBuffers(mTex.size(), drawbuffers);
-
+
if (mTex.empty())
{ //no color buffer to draw to
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
}
-
+ else
+ {
+ glDrawBuffers(static_cast<GLsizei>(mTex.size()), drawbuffers);
+ glReadBuffer(GL_COLOR_ATTACHMENT0);
+ }
check_framebuffer_status();
glViewport(0, 0, mResX, mResY);
@@ -452,7 +455,7 @@ void LLRenderTarget::clear(U32 mask_in)
if (mUseDepth)
{
mask |= GL_DEPTH_BUFFER_BIT;
-
+
}
if (mFBO)
{
@@ -485,7 +488,7 @@ U32 LLRenderTarget::getTexture(U32 attachment) const
U32 LLRenderTarget::getNumTextures() const
{
- return mTex.size();
+ return static_cast<U32>(mTex.size());
}
void LLRenderTarget::bindTexture(U32 index, S32 channel, LLTexUnit::eTextureFilterOptions filter_options)
@@ -519,7 +522,8 @@ void LLRenderTarget::flush()
llassert(sCurFBO == mFBO);
llassert(sBoundTarget == this);
- if (mGenerateMipMaps == LLTexUnit::TMG_AUTO) {
+ if (mGenerateMipMaps == LLTexUnit::TMG_AUTO)
+ {
LL_PROFILE_GPU_ZONE("rt generate mipmaps");
bindTexture(0, 0, LLTexUnit::TFO_TRILINEAR);
glGenerateMipmap(GL_TEXTURE_2D);
@@ -540,12 +544,14 @@ void LLRenderTarget::flush()
glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
sCurResX = gGLViewport[2];
sCurResY = gGLViewport[3];
+ glReadBuffer(GL_BACK);
+ glDrawBuffer(GL_BACK);
}
}
bool LLRenderTarget::isComplete() const
{
- return (!mTex.empty() || mDepth) ? true : false;
+ return !mTex.empty() || mDepth;
}
void LLRenderTarget::getViewport(S32* viewport)
@@ -560,7 +566,7 @@ bool LLRenderTarget::isBoundInStack() const
{
LLRenderTarget* cur = sBoundTarget;
while (cur && cur != this)
- {
+ {
cur = cur->mPreviousRT;
}
diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h
index 340276a752..cd3290cf66 100644
--- a/indra/llrender/llrendertarget.h
+++ b/indra/llrender/llrendertarget.h
@@ -61,7 +61,7 @@
class LLRenderTarget
{
public:
- //whether or not to use FBO implementation
+ // Whether or not to use FBO implementation
static bool sUseFBO;
static U32 sBytesAllocated;
static U32 sCurFBO;
@@ -172,6 +172,8 @@ public:
// *HACK
void swapFBORefs(LLRenderTarget& other);
+ static LLRenderTarget* sBoundTarget;
+
protected:
U32 mResX;
U32 mResY;
@@ -186,8 +188,6 @@ protected:
U32 mMipLevels;
LLTexUnit::eTextureType mUsage;
-
- static LLRenderTarget* sBoundTarget;
};
#endif
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index 0f3716bc18..bc542d325e 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -44,7 +44,6 @@ using std::make_pair;
using std::string;
LLShaderMgr * LLShaderMgr::sInstance = NULL;
-bool LLShaderMgr::sMirrorsEnabled = false;
LLShaderMgr::LLShaderMgr()
{
@@ -66,14 +65,14 @@ LLShaderMgr * LLShaderMgr::instance()
return sInstance;
}
-BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
+bool LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{
llassert_always(shader != NULL);
LLShaderFeatures *features = & shader->mFeatures;
if (features->attachNothing)
{
- return TRUE;
+ return true;
}
//////////////////////////////////////
// Attach Vertex Shader Features First
@@ -84,7 +83,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{
if (!shader->attachVertexObject("windlight/atmosphericsVarsV.glsl"))
{
- return FALSE;
+ return false;
}
}
@@ -92,7 +91,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{
if (!shader->attachVertexObject("windlight/atmosphericsHelpersV.glsl"))
{
- return FALSE;
+ return false;
}
}
@@ -102,40 +101,40 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{
if (!shader->attachVertexObject("lighting/lightFuncSpecularV.glsl"))
{
- return FALSE;
+ return false;
}
if (!features->isAlphaLighting)
{
if (!shader->attachVertexObject("lighting/sumLightsSpecularV.glsl"))
{
- return FALSE;
+ return false;
}
}
if (!shader->attachVertexObject("lighting/lightSpecularV.glsl"))
{
- return FALSE;
+ return false;
}
}
else
{
if (!shader->attachVertexObject("lighting/lightFuncV.glsl"))
{
- return FALSE;
+ return false;
}
if (!features->isAlphaLighting)
{
if (!shader->attachVertexObject("lighting/sumLightsV.glsl"))
{
- return FALSE;
+ return false;
}
}
if (!shader->attachVertexObject("lighting/lightV.glsl"))
{
- return FALSE;
+ return false;
}
}
}
@@ -145,16 +144,16 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{
if (!shader->attachVertexObject("environment/srgbF.glsl")) // NOTE -- "F" suffix is superfluous here, there is nothing fragment specific in srgbF
{
- return FALSE;
+ return false;
}
if (!shader->attachVertexObject("windlight/atmosphericsFuncs.glsl")) {
- return FALSE;
+ return false;
}
if (!shader->attachVertexObject("windlight/atmosphericsV.glsl"))
{
- return FALSE;
+ return false;
}
}
@@ -162,7 +161,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{
if (!shader->attachVertexObject("avatar/avatarSkinV.glsl"))
{
- return FALSE;
+ return false;
}
}
@@ -171,13 +170,13 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
shader->mRiggedVariant = shader;
if (!shader->attachVertexObject("avatar/objectSkinV.glsl"))
{
- return FALSE;
+ return false;
}
}
if (!shader->attachVertexObject("deferred/textureUtilV.glsl"))
{
- return FALSE;
+ return false;
}
///////////////////////////////////////
@@ -188,14 +187,14 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
if (!shader->attachFragmentObject("deferred/globalF.glsl"))
{
- return FALSE;
+ return false;
}
if (features->hasSrgb || features->hasAtmospherics || features->calculatesAtmospherics || features->isDeferred)
{
if (!shader->attachFragmentObject("environment/srgbF.glsl"))
{
- return FALSE;
+ return false;
}
}
@@ -203,7 +202,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{
if (!shader->attachFragmentObject("windlight/atmosphericsVarsF.glsl"))
{
- return FALSE;
+ return false;
}
}
@@ -211,7 +210,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{
if (!shader->attachFragmentObject("windlight/atmosphericsHelpersF.glsl"))
{
- return FALSE;
+ return false;
}
}
@@ -220,7 +219,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{
if (!shader->attachFragmentObject("deferred/deferredUtil.glsl"))
{
- return FALSE;
+ return false;
}
}
@@ -228,7 +227,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{
if (!shader->attachFragmentObject("deferred/screenSpaceReflUtil.glsl"))
{
- return FALSE;
+ return false;
}
}
@@ -236,7 +235,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{
if (!shader->attachFragmentObject("deferred/shadowUtil.glsl"))
{
- return FALSE;
+ return false;
}
}
@@ -244,7 +243,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{
if (!shader->attachFragmentObject("deferred/reflectionProbeF.glsl"))
{
- return FALSE;
+ return false;
}
}
@@ -252,7 +251,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{
if (!shader->attachFragmentObject("deferred/aoUtil.glsl"))
{
- return FALSE;
+ return false;
}
}
@@ -260,19 +259,19 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{
if (!shader->attachFragmentObject("windlight/gammaF.glsl"))
{
- return FALSE;
+ return false;
}
}
if (features->hasAtmospherics || features->isDeferred)
{
if (!shader->attachFragmentObject("windlight/atmosphericsFuncs.glsl")) {
- return FALSE;
+ return false;
}
if (!shader->attachFragmentObject("windlight/atmosphericsF.glsl"))
{
- return FALSE;
+ return false;
}
}
@@ -280,7 +279,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{
if (!shader->attachFragmentObject("deferred/pbrterrainUtilF.glsl"))
{
- return FALSE;
+ return false;
}
}
@@ -289,26 +288,26 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{
if (!shader->attachFragmentObject("environment/waterFogF.glsl"))
{
- return FALSE;
+ return false;
}
}
if (features->hasLighting)
{
- if (features->disableTextureIndex)
+ if (features->mIndexedTextureChannels <= 1)
{
if (features->hasAlphaMask)
{
if (!shader->attachFragmentObject("lighting/lightAlphaMaskNonIndexedF.glsl"))
{
- return FALSE;
+ return false;
}
}
else
{
if (!shader->attachFragmentObject("lighting/lightNonIndexedF.glsl"))
{
- return FALSE;
+ return false;
}
}
}
@@ -318,14 +317,14 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{
if (!shader->attachFragmentObject("lighting/lightAlphaMaskF.glsl"))
{
- return FALSE;
+ return false;
}
}
else
{
if (!shader->attachFragmentObject("lighting/lightF.glsl"))
{
- return FALSE;
+ return false;
}
}
shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels, 1);
@@ -336,18 +335,18 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{
if (!shader->attachVertexObject("objects/nonindexedTextureV.glsl"))
{
- return FALSE;
+ return false;
}
}
else
{
if (!shader->attachVertexObject("objects/indexedTextureV.glsl"))
{
- return FALSE;
+ return false;
}
}
- return TRUE;
+ return true;
}
//============================================================================
@@ -421,7 +420,7 @@ void LLShaderMgr::dumpShaderSource(U32 shader_code_count, GLchar** shader_code_t
LL_CONT << LL_ENDL;
}
-void LLShaderMgr::dumpObjectLog(GLuint ret, BOOL warns, const std::string& filename)
+void LLShaderMgr::dumpObjectLog(GLuint ret, bool warns, const std::string& filename)
{
std::string log;
log = get_object_log(ret);
@@ -600,11 +599,6 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev
extra_code_text[extra_code_count++] = strdup("#define FXAA_GLSL_130 1\n");
}
- if (sMirrorsEnabled)
- {
- extra_code_text[extra_code_count++] = strdup("#define HERO_PROBES 1\n");
- }
-
// Use alpha float to store bit flags
// See: C++: addDeferredAttachment(), shader: frag_data[2]
extra_code_text[extra_code_count++] = strdup("#define GBUFFER_FLAG_SKIP_ATMOS 0.0 \n"); // atmo kill
@@ -689,7 +683,7 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev
{ //switches are supported in GLSL 1.30 and later
if (gGLManager.mIsNVIDIA)
{ //switches are unreliable on some NVIDIA drivers
- for (U32 i = 0; i < texture_index_channels; ++i)
+ for (S32 i = 0; i < texture_index_channels; ++i)
{
std::string if_string = llformat("\t%sif (vary_texture_index == %d) { return texture(tex%d, texcoord); }\n", i > 0 ? "else " : "", i, i);
extra_code_text[extra_code_count++] = strdup(if_string.c_str());
@@ -877,7 +871,7 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev
{
//an error occured, print log
LL_WARNS("ShaderLoading") << "GLSL Compilation Error:" << LL_ENDL;
- dumpObjectLog(ret, TRUE, open_file_name);
+ dumpObjectLog(ret, true, open_file_name);
dumpShaderSource(shader_code_count, shader_code_text);
glDeleteShader(ret); //no longer need handle
ret = 0;
@@ -919,7 +913,7 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev
return ret;
}
-BOOL LLShaderMgr::linkProgramObject(GLuint obj, BOOL suppress_errors)
+bool LLShaderMgr::linkProgramObject(GLuint obj, bool suppress_errors)
{
//check for errors
{
@@ -936,7 +930,7 @@ BOOL LLShaderMgr::linkProgramObject(GLuint obj, BOOL suppress_errors)
{
//an error occured, print log
LL_SHADER_LOADING_WARNS() << "GLSL Linker Error:" << LL_ENDL;
- dumpObjectLog(obj, TRUE, "linker");
+ dumpObjectLog(obj, true, "linker");
return success;
}
}
@@ -947,12 +941,12 @@ BOOL LLShaderMgr::linkProgramObject(GLuint obj, BOOL suppress_errors)
{
LL_SHADER_LOADING_WARNS() << "GLSL Linker: Running in Software:" << LL_ENDL;
success = GL_FALSE;
- suppress_errors = FALSE;
+ suppress_errors = false;
}
return success;
}
-BOOL LLShaderMgr::validateProgramObject(GLuint obj)
+bool LLShaderMgr::validateProgramObject(GLuint obj)
{
//check program validity against current GL
glValidateProgram(obj);
@@ -965,7 +959,7 @@ BOOL LLShaderMgr::validateProgramObject(GLuint obj)
}
else
{
- dumpObjectLog(obj, FALSE);
+ dumpObjectLog(obj, false);
}
return success;
@@ -1003,7 +997,7 @@ void LLShaderMgr::initShaderCache(bool enabled, const LLUUID& old_cache_version,
ProgramBinaryData binary_info = ProgramBinaryData();
binary_info.mBinaryFormat = data_pair.second["binary_format"].asInteger();
binary_info.mBinaryLength = data_pair.second["binary_size"].asInteger();
- binary_info.mLastUsedTime = data_pair.second["last_used"].asReal();
+ binary_info.mLastUsedTime = (F32)data_pair.second["last_used"].asReal();
mShaderBinaryCache.insert_or_assign(LLUUID(data_pair.first), binary_info);
}
}
@@ -1034,7 +1028,7 @@ void LLShaderMgr::persistShaderCacheMetadata()
LLSD out = LLSD::emptyMap();
static const F32 LRU_TIME = (60.f * 60.f) * 24.f * 7.f; // 14 days
- const F32 current_time = LLTimer::getTotalSeconds();
+ const F32 current_time = (F32)LLTimer::getTotalSeconds();
for (auto it = mShaderBinaryCache.begin(); it != mShaderBinaryCache.end();)
{
const ProgramBinaryData& shader_metadata = it->second;
@@ -1093,7 +1087,7 @@ bool LLShaderMgr::loadCachedProgramBinary(LLGLSLShader* shader)
glGetProgramiv(shader->mProgramObject, GL_LINK_STATUS, &success);
if (error == GL_NO_ERROR && success == GL_TRUE)
{
- binary_iter->second.mLastUsedTime = LLTimer::getTotalSeconds();
+ binary_iter->second.mLastUsedTime = (F32)LLTimer::getTotalSeconds();
LL_INFOS() << "Loaded cached binary for shader: " << shader->mName << LL_ENDL;
return true;
}
@@ -1120,7 +1114,7 @@ bool LLShaderMgr::saveCachedProgramBinary(LLGLSLShader* shader)
program_binary.resize(binary_info.mBinaryLength);
GLenum error = glGetError(); // Clear current error
- glGetProgramBinary(shader->mProgramObject, program_binary.size() * sizeof(U8), nullptr, &binary_info.mBinaryFormat, program_binary.data());
+ glGetProgramBinary(shader->mProgramObject, static_cast<GLsizei>(program_binary.size() * sizeof(U8)), nullptr, &binary_info.mBinaryFormat, program_binary.data());
error = glGetError();
if (error == GL_NO_ERROR)
{
@@ -1131,7 +1125,7 @@ bool LLShaderMgr::saveCachedProgramBinary(LLGLSLShader* shader)
fwrite(program_binary.data(), sizeof(U8), program_binary.size(), outfile);
outfile.close();
- binary_info.mLastUsedTime = LLTimer::getTotalSeconds();
+ binary_info.mLastUsedTime = (F32)LLTimer::getTotalSeconds();
mShaderBinaryCache.insert_or_assign(shader->mShaderHash, binary_info);
return true;
@@ -1157,6 +1151,7 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedAttribs.push_back("weight");
mReservedAttribs.push_back("weight4");
mReservedAttribs.push_back("clothing");
+ mReservedAttribs.push_back("joint");
mReservedAttribs.push_back("texture_index");
//matrix state
@@ -1177,9 +1172,19 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("texture_base_color_transform"); // (GLTF)
mReservedUniforms.push_back("texture_normal_transform"); // (GLTF)
mReservedUniforms.push_back("texture_metallic_roughness_transform"); // (GLTF)
+ mReservedUniforms.push_back("texture_occlusion_transform"); // (GLTF)
mReservedUniforms.push_back("texture_emissive_transform"); // (GLTF)
+ mReservedUniforms.push_back("base_color_texcoord"); // (GLTF)
+ mReservedUniforms.push_back("emissive_texcoord"); // (GLTF)
+ mReservedUniforms.push_back("normal_texcoord"); // (GLTF)
+ mReservedUniforms.push_back("metallic_roughness_texcoord"); // (GLTF)
+ mReservedUniforms.push_back("occlusion_texcoord"); // (GLTF)
+ mReservedUniforms.push_back("gltf_node_id"); // (GLTF)
+ mReservedUniforms.push_back("gltf_material_id"); // (GLTF)
- llassert(mReservedUniforms.size() == LLShaderMgr::TEXTURE_EMISSIVE_TRANSFORM+1);
+ mReservedUniforms.push_back("terrain_texture_transforms"); // (GLTF)
+
+ llassert(mReservedUniforms.size() == LLShaderMgr::TERRAIN_TEXTURE_TRANSFORMS +1);
mReservedUniforms.push_back("viewport");
@@ -1223,6 +1228,9 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("diffuseMap");
mReservedUniforms.push_back("altDiffuseMap");
mReservedUniforms.push_back("specularMap");
+ mReservedUniforms.push_back("metallicRoughnessMap");
+ mReservedUniforms.push_back("normalMap");
+ mReservedUniforms.push_back("occlusionMap");
mReservedUniforms.push_back("emissiveMap");
mReservedUniforms.push_back("bumpMap");
mReservedUniforms.push_back("bumpMap2");
@@ -1234,7 +1242,6 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("heroProbes");
mReservedUniforms.push_back("cloud_noise_texture");
mReservedUniforms.push_back("cloud_noise_texture_next");
- mReservedUniforms.push_back("fullbright");
mReservedUniforms.push_back("lightnorm");
mReservedUniforms.push_back("sunlight_color");
mReservedUniforms.push_back("ambient_color");
@@ -1346,7 +1353,6 @@ void LLShaderMgr::initAttribsAndUniforms()
llassert(mReservedUniforms.size() == LLShaderMgr::DEFERRED_SHADOW5+1);
- mReservedUniforms.push_back("normalMap");
mReservedUniforms.push_back("positionMap");
mReservedUniforms.push_back("diffuseRect");
mReservedUniforms.push_back("specularRect");
@@ -1359,7 +1365,6 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("bloomMap");
mReservedUniforms.push_back("projectionMap");
mReservedUniforms.push_back("norm_mat");
- mReservedUniforms.push_back("texture_gamma");
mReservedUniforms.push_back("specular_color");
mReservedUniforms.push_back("env_intensity");
diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h
index 8b13e822d5..921ef20997 100644
--- a/indra/llrender/llshadermgr.h
+++ b/indra/llrender/llshadermgr.h
@@ -56,7 +56,17 @@ public:
TEXTURE_BASE_COLOR_TRANSFORM, // "texture_base_color_transform" (GLTF)
TEXTURE_NORMAL_TRANSFORM, // "texture_normal_transform" (GLTF)
TEXTURE_METALLIC_ROUGHNESS_TRANSFORM, // "texture_metallic_roughness_transform" (GLTF)
+ TEXTURE_OCCLUSION_TRANSFORM, // "texture_occlusion_transform" (GLTF)
TEXTURE_EMISSIVE_TRANSFORM, // "texture_emissive_transform" (GLTF)
+ BASE_COLOR_TEXCOORD, // "base_color_texcoord" (GLTF)
+ EMISSIVE_TEXCOORD, // "emissive_texcoord" (GLTF)
+ NORMAL_TEXCOORD, // "normal_texcoord" (GLTF)
+ METALLIC_ROUGHNESS_TEXCOORD, // "metallic_roughness_texcoord" (GLTF)
+ OCCLUSION_TEXCOORD, // "occlusion_texcoord" (GLTF)
+ GLTF_NODE_ID, // "gltf_node_id" (GLTF)
+ GLTF_MATERIAL_ID, // "gltf_material_id" (GLTF)
+
+ TERRAIN_TEXTURE_TRANSFORMS, // "terrain_texture_transforms" (GLTF)
VIEWPORT, // "viewport"
LIGHT_POSITION, // "light_position"
@@ -91,6 +101,9 @@ public:
DIFFUSE_MAP, // "diffuseMap"
ALTERNATE_DIFFUSE_MAP, // "altDiffuseMap"
SPECULAR_MAP, // "specularMap"
+ METALLIC_ROUGHNESS_MAP, // "metallicRoughnessMap"
+ NORMAL_MAP, // "normalMap"
+ OCCLUSION_MAP, // "occlusionMap"
EMISSIVE_MAP, // "emissiveMap"
BUMP_MAP, // "bumpMap"
BUMP_MAP2, // "bumpMap2"
@@ -102,7 +115,6 @@ public:
HERO_PROBE, // "heroProbes"
CLOUD_NOISE_MAP, // "cloud_noise_texture"
CLOUD_NOISE_MAP_NEXT, // "cloud_noise_texture_next"
- FULLBRIGHT, // "fullbright"
LIGHTNORM, // "lightnorm"
SUNLIGHT_COLOR, // "sunlight_color"
AMBIENT, // "ambient_color"
@@ -200,7 +212,6 @@ public:
DEFERRED_SHADOW3, // "shadowMap3"
DEFERRED_SHADOW4, // "shadowMap4"
DEFERRED_SHADOW5, // "shadowMap5"
- DEFERRED_NORMAL, // "normalMap"
DEFERRED_POSITION, // "positionMap"
DEFERRED_DIFFUSE, // "diffuseRect"
DEFERRED_SPECULAR, // "specularRect"
@@ -213,7 +224,6 @@ public:
DEFERRED_BLOOM, // "bloomMap"
DEFERRED_PROJECTION, // "projectionMap"
DEFERRED_NORM_MATRIX, // "norm_mat"
- TEXTURE_GAMMA, // "texture_gamma"
SPECULAR_COLOR, // "specular_color"
ENVIRONMENT_INTENSITY, // "env_intensity"
@@ -328,11 +338,11 @@ public:
virtual void initAttribsAndUniforms(void);
- BOOL attachShaderFeatures(LLGLSLShader * shader);
- void dumpObjectLog(GLuint ret, BOOL warns = TRUE, const std::string& filename = "");
+ bool attachShaderFeatures(LLGLSLShader * shader);
+ void dumpObjectLog(GLuint ret, bool warns = true, const std::string& filename = "");
void dumpShaderSource(U32 shader_code_count, GLchar** shader_code_text);
- BOOL linkProgramObject(GLuint obj, BOOL suppress_errors = FALSE);
- BOOL validateProgramObject(GLuint obj);
+ bool linkProgramObject(GLuint obj, bool suppress_errors = false);
+ bool validateProgramObject(GLuint obj);
GLuint loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, std::map<std::string, std::string>* defines = NULL, S32 texture_index_channels = -1);
// Implemented in the application to actually point to the shader directory.
@@ -368,7 +378,6 @@ public:
bool mShaderCacheInitialized = false;
bool mShaderCacheEnabled = false;
std::string mShaderCacheDir;
- static bool sMirrorsEnabled;
protected:
diff --git a/indra/llrender/lltexturemanagerbridge.h b/indra/llrender/lltexturemanagerbridge.h
index 0b76ee4de8..e742324e4a 100644
--- a/indra/llrender/lltexturemanagerbridge.h
+++ b/indra/llrender/lltexturemanagerbridge.h
@@ -36,8 +36,8 @@ class LLTextureManagerBridge
public:
virtual ~LLTextureManagerBridge() {}
- virtual LLPointer<LLGLTexture> getLocalTexture(BOOL usemipmaps = TRUE, BOOL generate_gl_tex = TRUE) = 0;
- virtual LLPointer<LLGLTexture> getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) = 0;
+ virtual LLPointer<LLGLTexture> getLocalTexture(bool usemipmaps = true, bool generate_gl_tex = true) = 0;
+ virtual LLPointer<LLGLTexture> getLocalTexture(const U32 width, const U32 height, const U8 components, bool usemipmaps, bool generate_gl_tex = true) = 0;
virtual LLGLTexture* getFetchedTexture(const LLUUID &image_id) = 0;
};
diff --git a/indra/llrender/lluiimage.cpp b/indra/llrender/lluiimage.cpp
index bcf665ca18..d31a91e2af 100644
--- a/indra/llrender/lluiimage.cpp
+++ b/indra/llrender/lluiimage.cpp
@@ -83,7 +83,7 @@ void LLUIImage::draw3D(const LLVector3& origin_agent, const LLVector3& x_axis, c
LLRender2D::getInstance()->pushMatrix();
{
- LLVector3 rect_origin = origin_agent + (rect.mLeft * x_axis) + (rect.mBottom * y_axis);
+ LLVector3 rect_origin = origin_agent + ((F32)rect.mLeft * x_axis) + ((F32)rect.mBottom * y_axis);
LLRender2D::getInstance()->translate(rect_origin.mV[VX],
rect_origin.mV[VY],
rect_origin.mV[VZ]);
@@ -100,8 +100,8 @@ void LLUIImage::draw3D(const LLVector3& origin_agent, const LLVector3& x_axis, c
(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);
+ (F32)rect.getWidth() * x_axis,
+ (F32)rect.getHeight() * y_axis);
} LLRender2D::getInstance()->popMatrix();
}
diff --git a/indra/llrender/lluiimage.inl b/indra/llrender/lluiimage.inl
index a69616c0c1..dff1fcdfcc 100644
--- a/indra/llrender/lluiimage.inl
+++ b/indra/llrender/lluiimage.inl
@@ -36,7 +36,7 @@ void LLUIImage::draw(S32 x, S32 y, S32 width, S32 height, const LLColor4& color)
width, height,
mImage,
color,
- FALSE,
+ false,
mClipRegion,
mScaleRegion,
mScaleStyle == SCALE_INNER);
@@ -49,7 +49,7 @@ void LLUIImage::drawSolid(S32 x, S32 y, S32 width, S32 height, const LLColor4& c
width, height,
mImage,
color,
- TRUE,
+ true,
mClipRegion,
mScaleRegion,
mScaleStyle == SCALE_INNER);
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 7caf20f40b..2eb7c21f77 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -290,6 +290,62 @@ static GLuint gen_buffer()
#define ANALYZE_VBO_POOL 0
+#if LL_DARWIN
+
+// experimental -- disable VBO pooling on OS X and use glMapBuffer
+class LLVBOPool
+{
+public:
+ U64 mAllocated = 0;
+
+ U64 getVramBytesUsed()
+ {
+ return mAllocated;
+ }
+
+ void allocate(GLenum type, U32 size, GLuint& name, U8*& data)
+ {
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX;
+ STOP_GLERROR;
+ llassert(type == GL_ARRAY_BUFFER || type == GL_ELEMENT_ARRAY_BUFFER);
+ llassert(name == 0); // non zero name indicates a gl name that wasn't freed
+ llassert(data == nullptr); // non null data indicates a buffer that wasn't freed
+ llassert(size >= 2); // any buffer size smaller than a single index is nonsensical
+
+ mAllocated += size;
+
+ { //allocate a new buffer
+ LL_PROFILE_GPU_ZONE("vbo alloc");
+ // ON OS X, we don't allocate a VBO until the last possible moment
+ // in unmapBuffer
+ data = (U8*) ll_aligned_malloc_16(size);
+ STOP_GLERROR;
+ }
+ }
+
+ void free(GLenum type, U32 size, GLuint name, U8* data)
+ {
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX;
+ llassert(type == GL_ARRAY_BUFFER || type == GL_ELEMENT_ARRAY_BUFFER);
+ llassert(size >= 2);
+
+ if (data)
+ {
+ ll_aligned_free_16(data);
+ }
+
+ mAllocated -= size;
+ STOP_GLERROR;
+ if (name)
+ {
+ glDeleteBuffers(1, &name);
+ }
+ STOP_GLERROR;
+ }
+};
+
+#else
+
class LLVBOPool
{
public:
@@ -509,9 +565,8 @@ public:
mIBOPool.clear();
mVBOPool.clear();
}
-
-
};
+#endif
static LLVBOPool* sVBOPool = nullptr;
@@ -545,6 +600,7 @@ const U32 LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_MAX] =
sizeof(F32), // TYPE_WEIGHT,
sizeof(LLVector4), // TYPE_WEIGHT4,
sizeof(LLVector4), // TYPE_CLOTHWEIGHT,
+ sizeof(U64), // TYPE_JOINT,
sizeof(LLVector4), // TYPE_TEXTURE_INDEX (actually exists as position.w), no extra data, but stride is 16 bytes
};
@@ -562,6 +618,7 @@ static const std::string vb_type_name[] =
"TYPE_WEIGHT",
"TYPE_WEIGHT4",
"TYPE_CLOTHWEIGHT",
+ "TYPE_JOINT"
"TYPE_TEXTURE_INDEX",
"TYPE_MAX",
"TYPE_INDEX",
@@ -629,6 +686,8 @@ void LLVertexBuffer::drawElements(U32 mode, const LLVector4a* pos, const LLVecto
LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX;
llassert(LLGLSLShader::sCurBoundShaderPtr != NULL);
+ STOP_GLERROR;
+
gGL.syncMatrices();
U32 mask = LLVertexBuffer::MAP_VERTEX;
@@ -643,7 +702,7 @@ void LLVertexBuffer::drawElements(U32 mode, const LLVector4a* pos, const LLVecto
if (tc != nullptr)
{
- for (int i = 0; i < num_indices; ++i)
+ for (U32 i = 0; i < num_indices; ++i)
{
U16 idx = indicesp[i];
gGL.texCoord2fv(tc[idx].mV);
@@ -652,7 +711,7 @@ void LLVertexBuffer::drawElements(U32 mode, const LLVector4a* pos, const LLVecto
}
else
{
- for (int i = 0; i < num_indices; ++i)
+ for (U32 i = 0; i < num_indices; ++i)
{
U16 idx = indicesp[i];
gGL.vertex3fv(pos[idx].getF32ptr());
@@ -669,24 +728,23 @@ bool LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_of
return true;
}
- llassert(start < (U32)mNumVerts);
- llassert(end < (U32)mNumVerts);
+ llassert(start < mNumVerts);
+ llassert(end < mNumVerts);
- if (start >= (U32) mNumVerts ||
- end >= (U32) mNumVerts)
+ if (start >= mNumVerts ||
+ end >= mNumVerts)
{
LL_ERRS() << "Bad vertex buffer draw range: [" << start << ", " << end << "] vs " << mNumVerts << LL_ENDL;
}
- llassert(mNumIndices >= 0);
-
- if (indices_offset >= (U32) mNumIndices ||
- indices_offset + count > (U32) mNumIndices)
+ if (indices_offset >= mNumIndices ||
+ indices_offset + count > mNumIndices)
{
LL_ERRS() << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << LL_ENDL;
}
{
+#if 0 // not a reliable test for VBOs that are not backed by a CPU buffer
U16* idx = (U16*) mMappedIndexData+indices_offset;
for (U32 i = 0; i < count; ++i)
{
@@ -718,12 +776,13 @@ bool LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_of
for (U32 i = start; i < end; i++)
{
U32 idx = (U32) (v[i][3]+0.25f);
- if (idx >= shader->mFeatures.mIndexedTextureChannels)
+ if (idx >= (U32)shader->mFeatures.mIndexedTextureChannels)
{
LL_ERRS() << "Bad texture index found in vertex data stream." << LL_ENDL;
}
}
}
+#endif
}
return true;
@@ -741,10 +800,19 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
llassert(mGLBuffer == sGLRenderBuffer);
llassert(mGLIndices == sGLRenderIndices);
gGL.syncMatrices();
+ STOP_GLERROR;
glDrawRangeElements(sGLMode[mode], start, end, count, mIndicesType,
(GLvoid*) (indices_offset * (size_t) mIndicesStride));
+ STOP_GLERROR;
}
+void LLVertexBuffer::drawRangeFast(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const
+{
+ glDrawRangeElements(sGLMode[mode], start, end, count, mIndicesType,
+ (GLvoid*)(indices_offset * (size_t)mIndicesStride));
+}
+
+
void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
{
drawRange(mode, 0, mNumVerts-1, count, indices_offset);
@@ -758,7 +826,9 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
llassert(mGLIndices == sGLRenderIndices);
gGL.syncMatrices();
+ STOP_GLERROR;
glDrawArrays(sGLMode[mode], first, count);
+ STOP_GLERROR;
}
//static
@@ -781,9 +851,10 @@ void LLVertexBuffer::initClass(LLWindow* window)
//static
void LLVertexBuffer::unbind()
{
+ STOP_GLERROR;
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-
+ STOP_GLERROR;
sGLRenderBuffer = 0;
sGLRenderIndices = 0;
}
@@ -998,12 +1069,6 @@ bool LLVertexBuffer::updateNumVerts(U32 nverts)
bool success = true;
- if (nverts > 65536)
- {
- LL_WARNS() << "Vertex buffer overflow!" << LL_ENDL;
- nverts = 65536;
- }
-
U32 needed_size = calcOffsets(mTypeMask, mOffsets, nverts);
if (needed_size != mSize)
@@ -1036,8 +1101,7 @@ bool LLVertexBuffer::updateNumIndices(U32 nindices)
bool LLVertexBuffer::allocateBuffer(U32 nverts, U32 nindices)
{
- if (nverts < 0 || nindices < 0 ||
- nverts > 65536)
+ if (nverts < 0 || nindices < 0)
{
LL_ERRS() << "Bad vertex buffer allocation: " << nverts << " : " << nindices << LL_ENDL;
}
@@ -1080,6 +1144,7 @@ U8* LLVertexBuffer::mapVertexBuffer(LLVertexBuffer::AttributeType type, U32 inde
count = mNumVerts - index;
}
+#if !LL_DARWIN
U32 start = mOffsets[type] + sTypeSize[type] * index;
U32 end = start + sTypeSize[type] * count-1;
@@ -1100,7 +1165,7 @@ U8* LLVertexBuffer::mapVertexBuffer(LLVertexBuffer::AttributeType type, U32 inde
//didn't expand an existing region, make a new one
mMappedVertexRegions.push_back({ start, end });
}
-
+#endif
return mMappedData+mOffsets[type]+sTypeSize[type]*index;
}
@@ -1114,6 +1179,7 @@ U8* LLVertexBuffer::mapIndexBuffer(U32 index, S32 count)
count = mNumIndices-index;
}
+#if !LL_DARWIN
U32 start = sizeof(U16) * index;
U32 end = start + sizeof(U16) * count-1;
@@ -1134,6 +1200,7 @@ U8* LLVertexBuffer::mapIndexBuffer(U32 index, S32 count)
//didn't expand an existing region, make a new one
mMappedIndexRegions.push_back({ start, end });
}
+#endif
return mMappedIndexData + sizeof(U16)*index;
}
@@ -1142,9 +1209,19 @@ U8* LLVertexBuffer::mapIndexBuffer(U32 index, S32 count)
// target -- "target" parameter for glBufferSubData
// start -- first byte to copy
// end -- last byte to copy (NOT last byte + 1)
-// data -- mMappedData or mMappedIndexData
-static void flush_vbo(GLenum target, U32 start, U32 end, void* data)
-{
+// data -- data to be flushed
+// dst -- mMappedData or mMappedIndexData
+void LLVertexBuffer::flush_vbo(GLenum target, U32 start, U32 end, void* data, U8* dst)
+{
+#if LL_DARWIN
+ LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vb memcpy");
+ STOP_GLERROR;
+ // copy into mapped buffer
+ memcpy(dst+start, data, end-start+1);
+#else
+ llassert(target == GL_ARRAY_BUFFER ? sGLRenderBuffer == mGLBuffer : sGLRenderIndices == mGLIndices);
+
+ // skip mapped data and stream to GPU via glBufferSubData
if (end != 0)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("glBufferSubData");
@@ -1163,10 +1240,12 @@ static void flush_vbo(GLenum target, U32 start, U32 end, void* data)
glBufferSubData(target, i, size, (U8*) data + (i-start));
}
}
+#endif
}
void LLVertexBuffer::unmapBuffer()
{
+ STOP_GLERROR;
struct SortMappedRegion
{
bool operator()(const MappedRegion& lhs, const MappedRegion& rhs)
@@ -1175,9 +1254,51 @@ void LLVertexBuffer::unmapBuffer()
}
};
+#if LL_DARWIN
+ STOP_GLERROR;
+ if (mMappedData)
+ {
+ if (mGLBuffer)
+ {
+ glDeleteBuffers(1, &mGLBuffer);
+ }
+ mGLBuffer = gen_buffer();
+ glBindBuffer(GL_ARRAY_BUFFER, mGLBuffer);
+ sGLRenderBuffer = mGLBuffer;
+ glBufferData(GL_ARRAY_BUFFER, mSize, mMappedData, GL_STATIC_DRAW);
+ }
+ else if (mGLBuffer != sGLRenderBuffer)
+ {
+ glBindBuffer(GL_ARRAY_BUFFER, mGLBuffer);
+ sGLRenderBuffer = mGLBuffer;
+ }
+ STOP_GLERROR;
+
+ if (mMappedIndexData)
+ {
+ if (mGLIndices)
+ {
+ glDeleteBuffers(1, &mGLIndices);
+ }
+
+ mGLIndices = gen_buffer();
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mGLIndices);
+ sGLRenderIndices = mGLIndices;
+
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, mIndicesSize, mMappedIndexData, GL_STATIC_DRAW);
+ }
+ else if (mGLIndices != sGLRenderIndices)
+ {
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mGLIndices);
+ sGLRenderIndices = mGLIndices;
+ }
+ STOP_GLERROR;
+#else
+
if (!mMappedVertexRegions.empty())
{
LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("unmapBuffer - vertex");
+
if (sGLRenderBuffer != mGLBuffer)
{
glBindBuffer(GL_ARRAY_BUFFER, mGLBuffer);
@@ -1198,14 +1319,13 @@ void LLVertexBuffer::unmapBuffer()
}
else
{
- flush_vbo(GL_ARRAY_BUFFER, start, end, (U8*)mMappedData + start);
+ flush_vbo(GL_ARRAY_BUFFER, start, end, (U8*)mMappedData + start, mMappedData);
start = region.mStart;
end = region.mEnd;
}
}
- flush_vbo(GL_ARRAY_BUFFER, start, end, (U8*)mMappedData + start);
-
+ flush_vbo(GL_ARRAY_BUFFER, start, end, (U8*)mMappedData + start, mMappedData);
mMappedVertexRegions.clear();
}
@@ -1232,16 +1352,16 @@ void LLVertexBuffer::unmapBuffer()
}
else
{
- flush_vbo(GL_ELEMENT_ARRAY_BUFFER, start, end, (U8*)mMappedIndexData + start);
+ flush_vbo(GL_ELEMENT_ARRAY_BUFFER, start, end, (U8*)mMappedIndexData + start, mMappedIndexData);
start = region.mStart;
end = region.mEnd;
}
}
- flush_vbo(GL_ELEMENT_ARRAY_BUFFER, start, end, (U8*)mMappedIndexData + start);
-
+ flush_vbo(GL_ELEMENT_ARRAY_BUFFER, start, end, (U8*)mMappedIndexData + start, mMappedIndexData);
mMappedIndexRegions.clear();
}
+#endif
}
//----------------------------------------------------------------------------
@@ -1362,6 +1482,13 @@ bool LLVertexBuffer::getClothWeightStrider(LLStrider<LLVector4>& strider, U32 in
// Set for rendering
void LLVertexBuffer::setBuffer()
{
+ STOP_GLERROR;
+#if LL_DARWIN
+ if (!mGLBuffer)
+ { // OS X doesn't allocate a buffer until we call unmapBuffer
+ return;
+ }
+#endif
// no data may be pending
llassert(mMappedVertexRegions.empty());
llassert(mMappedIndexRegions.empty());
@@ -1394,12 +1521,15 @@ void LLVertexBuffer::setBuffer()
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mGLIndices);
sGLRenderIndices = mGLIndices;
}
+
+ STOP_GLERROR;
}
// virtual (default)
void LLVertexBuffer::setupVertexBuffer()
{
+ STOP_GLERROR;
U8* base = nullptr;
U32 data_mask = LLGLSLShader::sCurBoundShaderPtr->mAttributeMask;
@@ -1471,6 +1601,12 @@ void LLVertexBuffer::setupVertexBuffer()
void* ptr = (void*)(base + mOffsets[TYPE_WEIGHT4]);
glVertexAttribPointer(loc, 4, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], ptr);
}
+ if (data_mask & MAP_JOINT)
+ {
+ AttributeType loc = TYPE_JOINT;
+ void* ptr = (void*)(base + mOffsets[TYPE_JOINT]);
+ glVertexAttribIPointer(loc, 4, GL_UNSIGNED_SHORT, LLVertexBuffer::sTypeSize[TYPE_JOINT], ptr);
+ }
if (data_mask & MAP_CLOTHWEIGHT)
{
AttributeType loc = TYPE_CLOTHWEIGHT;
@@ -1489,59 +1625,121 @@ void LLVertexBuffer::setupVertexBuffer()
void* ptr = (void*)(base + mOffsets[TYPE_VERTEX]);
glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr);
}
+ STOP_GLERROR;
}
void LLVertexBuffer::setPositionData(const LLVector4a* data)
{
- llassert(sGLRenderBuffer == mGLBuffer);
- flush_vbo(GL_ARRAY_BUFFER, 0, sizeof(LLVector4a) * getNumVerts()-1, (U8*) data);
+ flush_vbo(GL_ARRAY_BUFFER, 0, sizeof(LLVector4a) * getNumVerts()-1, (U8*) data, mMappedData);
}
-void LLVertexBuffer::setTexCoordData(const LLVector2* data)
+void LLVertexBuffer::setTexCoord0Data(const LLVector2* data)
{
- llassert(sGLRenderBuffer == mGLBuffer);
- flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_TEXCOORD0], mOffsets[TYPE_TEXCOORD0] + sTypeSize[TYPE_TEXCOORD0] * getNumVerts() - 1, (U8*)data);
+ flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_TEXCOORD0], mOffsets[TYPE_TEXCOORD0] + sTypeSize[TYPE_TEXCOORD0] * getNumVerts() - 1, (U8*)data, mMappedData);
+}
+
+void LLVertexBuffer::setTexCoord1Data(const LLVector2* data)
+{
+ flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_TEXCOORD1], mOffsets[TYPE_TEXCOORD1] + sTypeSize[TYPE_TEXCOORD1] * getNumVerts() - 1, (U8*)data, mMappedData);
}
void LLVertexBuffer::setColorData(const LLColor4U* data)
{
- llassert(sGLRenderBuffer == mGLBuffer);
- flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_COLOR], mOffsets[TYPE_COLOR] + sTypeSize[TYPE_COLOR] * getNumVerts() - 1, (U8*) data);
+ flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_COLOR], mOffsets[TYPE_COLOR] + sTypeSize[TYPE_COLOR] * getNumVerts() - 1, (U8*) data, mMappedData);
}
void LLVertexBuffer::setNormalData(const LLVector4a* data)
{
- llassert(sGLRenderBuffer == mGLBuffer);
- flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_NORMAL], mOffsets[TYPE_NORMAL] + sTypeSize[TYPE_NORMAL] * getNumVerts() - 1, (U8*) data);
+ flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_NORMAL], mOffsets[TYPE_NORMAL] + sTypeSize[TYPE_NORMAL] * getNumVerts() - 1, (U8*) data, mMappedData);
}
void LLVertexBuffer::setTangentData(const LLVector4a* data)
{
- llassert(sGLRenderBuffer == mGLBuffer);
- flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_TANGENT], mOffsets[TYPE_TANGENT] + sTypeSize[TYPE_TANGENT] * getNumVerts() - 1, (U8*) data);
+ flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_TANGENT], mOffsets[TYPE_TANGENT] + sTypeSize[TYPE_TANGENT] * getNumVerts() - 1, (U8*) data, mMappedData);
}
void LLVertexBuffer::setWeight4Data(const LLVector4a* data)
{
- llassert(sGLRenderBuffer == mGLBuffer);
- flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_WEIGHT4], mOffsets[TYPE_WEIGHT4] + sTypeSize[TYPE_WEIGHT4] * getNumVerts() - 1, (U8*) data);
+ flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_WEIGHT4], mOffsets[TYPE_WEIGHT4] + sTypeSize[TYPE_WEIGHT4] * getNumVerts() - 1, (U8*) data, mMappedData);
+}
+
+void LLVertexBuffer::setJointData(const U64* data)
+{
+ flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_JOINT], mOffsets[TYPE_JOINT] + sTypeSize[TYPE_JOINT] * getNumVerts() - 1, (U8*) data, mMappedData);
}
void LLVertexBuffer::setIndexData(const U16* data)
{
- llassert(sGLRenderIndices == mGLIndices);
- flush_vbo(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(U16) * getNumIndices() - 1, (U8*) data);
+ flush_vbo(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(U16) * getNumIndices() - 1, (U8*) data, mMappedIndexData);
}
void LLVertexBuffer::setIndexData(const U32* data)
{
- llassert(sGLRenderIndices == mGLIndices);
if (mIndicesType != GL_UNSIGNED_INT)
{ // HACK -- vertex buffers are initialized as 16-bit indices, but can be switched to 32-bit indices
mIndicesType = GL_UNSIGNED_INT;
mIndicesStride = 4;
mNumIndices /= 2;
}
- flush_vbo(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(U32) * getNumIndices() - 1, (U8*)data);
+ flush_vbo(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(U32) * getNumIndices() - 1, (U8*)data, mMappedIndexData);
+}
+
+void LLVertexBuffer::setPositionData(const LLVector4a* data, U32 offset, U32 count)
+{
+ flush_vbo(GL_ARRAY_BUFFER, offset * sizeof(LLVector4a), (offset + count) * sizeof(LLVector4a) - 1, (U8*)data, mMappedData);
+}
+
+void LLVertexBuffer::setNormalData(const LLVector4a* data, U32 offset, U32 count)
+{
+ flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_NORMAL] + offset * sTypeSize[TYPE_NORMAL], mOffsets[TYPE_NORMAL] + (offset + count) * sTypeSize[TYPE_NORMAL] - 1, (U8*)data, mMappedData);
+}
+
+void LLVertexBuffer::setTexCoord0Data(const LLVector2* data, U32 offset, U32 count)
+{
+ flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_TEXCOORD0] + offset * sTypeSize[TYPE_TEXCOORD0], mOffsets[TYPE_TEXCOORD0] + (offset + count) * sTypeSize[TYPE_TEXCOORD0] - 1, (U8*)data, mMappedData);
+}
+
+void LLVertexBuffer::setTexCoord1Data(const LLVector2* data, U32 offset, U32 count)
+{
+ flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_TEXCOORD1] + offset * sTypeSize[TYPE_TEXCOORD1], mOffsets[TYPE_TEXCOORD1] + (offset + count) * sTypeSize[TYPE_TEXCOORD1] - 1, (U8*)data, mMappedData);
+}
+
+void LLVertexBuffer::setColorData(const LLColor4U* data, U32 offset, U32 count)
+{
+ flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_COLOR] + offset * sTypeSize[TYPE_COLOR], mOffsets[TYPE_COLOR] + (offset + count) * sTypeSize[TYPE_COLOR] - 1, (U8*)data, mMappedData);
+}
+
+void LLVertexBuffer::setTangentData(const LLVector4a* data, U32 offset, U32 count)
+{
+ flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_TANGENT] + offset * sTypeSize[TYPE_TANGENT], mOffsets[TYPE_TANGENT] + (offset + count) * sTypeSize[TYPE_TANGENT] - 1, (U8*)data, mMappedData);
+}
+
+void LLVertexBuffer::setWeight4Data(const LLVector4a* data, U32 offset, U32 count)
+{
+ flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_WEIGHT4] + offset * sTypeSize[TYPE_WEIGHT4], mOffsets[TYPE_WEIGHT4] + (offset + count) * sTypeSize[TYPE_WEIGHT4] - 1, (U8*)data, mMappedData);
+}
+
+void LLVertexBuffer::setJointData(const U64* data, U32 offset, U32 count)
+{
+ flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_JOINT] + offset * sTypeSize[TYPE_JOINT], mOffsets[TYPE_JOINT] + (offset + count) * sTypeSize[TYPE_JOINT] - 1, (U8*)data, mMappedData);
+}
+
+void LLVertexBuffer::setIndexData(const U16* data, U32 offset, U32 count)
+{
+ flush_vbo(GL_ELEMENT_ARRAY_BUFFER, offset * sizeof(U16), (offset + count) * sizeof(U16) - 1, (U8*)data, mMappedIndexData);
+}
+
+void LLVertexBuffer::setIndexData(const U32* data, U32 offset, U32 count)
+{
+ if (mIndicesType != GL_UNSIGNED_INT)
+ { // HACK -- vertex buffers are initialized as 16-bit indices, but can be switched to 32-bit indices
+ mIndicesType = GL_UNSIGNED_INT;
+ mIndicesStride = 4;
+ mNumIndices /= 2;
+ }
+ flush_vbo(GL_ELEMENT_ARRAY_BUFFER, offset * sizeof(U32), (offset + count) * sizeof(U32) - 1, (U8*)data, mMappedIndexData);
}
+
+
+
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index b634609929..49500e28ce 100644
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -110,6 +110,7 @@ public:
TYPE_WEIGHT, // "weight"
TYPE_WEIGHT4, // "weight4"
TYPE_CLOTHWEIGHT, // "clothing"
+ TYPE_JOINT, // "joint"
TYPE_TEXTURE_INDEX, // "texture_index"
TYPE_MAX, // TYPE_MAX is the size/boundary marker for attributes that go in the vertex buffer
TYPE_INDEX, // TYPE_INDEX is beyond _MAX because it lives in a separate (index) buffer
@@ -129,6 +130,7 @@ public:
MAP_WEIGHT = (1<<TYPE_WEIGHT),
MAP_WEIGHT4 = (1<<TYPE_WEIGHT4),
MAP_CLOTHWEIGHT = (1<<TYPE_CLOTHWEIGHT),
+ MAP_JOINT = (1<<TYPE_JOINT),
MAP_TEXTURE_INDEX = (1<<TYPE_TEXTURE_INDEX),
};
@@ -193,11 +195,25 @@ public:
void setNormalData(const LLVector4a* data);
void setTangentData(const LLVector4a* data);
void setWeight4Data(const LLVector4a* data);
- void setTexCoordData(const LLVector2* data);
+ void setJointData(const U64* data);
+ void setTexCoord0Data(const LLVector2* data);
+ void setTexCoord1Data(const LLVector2* data);
void setColorData(const LLColor4U* data);
void setIndexData(const U16* data);
void setIndexData(const U32* data);
+ void setPositionData(const LLVector4a* data, U32 offset, U32 count);
+ void setNormalData(const LLVector4a* data, U32 offset, U32 count);
+ void setTangentData(const LLVector4a* data, U32 offset, U32 count);
+ void setWeight4Data(const LLVector4a* data, U32 offset, U32 count);
+ void setJointData(const U64* data, U32 offset, U32 count);
+ void setTexCoord0Data(const LLVector2* data, U32 offset, U32 count);
+ void setTexCoord1Data(const LLVector2* data, U32 offset, U32 count);
+ void setColorData(const LLColor4U* data, U32 offset, U32 count);
+ void setIndexData(const U16* data, U32 offset, U32 count);
+ void setIndexData(const U32* data, U32 offset, U32 count);
+
+
U32 getNumVerts() const { return mNumVerts; }
U32 getNumIndices() const { return mNumIndices; }
@@ -215,6 +231,10 @@ public:
void drawArrays(U32 mode, U32 offset, U32 count) const;
void drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const;
+ // draw without syncing matrices. If you're positive there have been no matrix
+ // since the last call to syncMatrices, this is much faster than drawRange
+ void drawRangeFast(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const;
+
//for debugging, validate data in given range is valid
bool validateRange(U32 start, U32 end, U32 count, U32 offset) const;
@@ -252,11 +272,13 @@ private:
friend class LLNavShapeVBOManager;
friend class LLNavMeshVBOManager;
+ void flush_vbo(GLenum target, U32 start, U32 end, void* data, U8* dst);
+
LLVertexBuffer(U32 typemask, U32 usage)
: LLVertexBuffer(typemask)
{}
- bool allocateBuffer(S32 nverts, S32 nindices, BOOL create) { return allocateBuffer(nverts, nindices); }
+ bool allocateBuffer(S32 nverts, S32 nindices, bool create) { return allocateBuffer(nverts, nindices); }
public: