Merge branch 'UICleanup' of git://github.com/Shyotl/SingularityViewer
Conflicts: indra/llappearance/llwearable.h indra/llui/llcombobox.h indra/newview/jcfloaterareasearch.cpp indra/newview/jcfloaterareasearch.h indra/newview/llpanelgrouproles.cpp indra/newview/llpanelgrouproles.h indra/newview/llviewermenu.cpp - Plugged in new MenuFloaterDict for AssetBlacklist and SoundExplorer in menu_viewer.xml and removed the old listeners for them. indra/newview/skins/default/xui/es/floater_inventory.xml Compile Fixes: indra/llcommon/llstl.h - error: expected nested-name-specifier before ‘const’ indra/llui/llmultisliderctrl.cpp:283:12: error: ‘caller’ was not declared in this scope indra/llui/lltexteditor.cpp - error: operands to ?: have different types ‘const LLPointer<LLTextSegment>’ and ‘long int’ - error: passing ‘const LLPointer<LLTextSegment>’ as ‘this’ argument of ‘LLPointer<Type>& LLPointer<Type>::operator=(const LLPointer<Type>&) [with Type = LLTextSegment]’ discards qualifiers indra/newview/llfloaterpermissionsmgr.cpp - Silly Shyotl, boost bind, not std bind. indra/newview/llfloaterproperties.* - error: ‘LLInstanceTracker<LLFloaterProperties, LLUUID>’ is an inaccessible base of ‘LLFloaterProperties’ indra/newview/llgivemoney.cpp - Again, boost::ref, not std::ref indra/newview/llpreviewscript.cpp - no known conversion for argument 1 from ‘std::vector<const LLPointer<LLTextSegment> >’ to ‘std::vector<LLPointer<LLTextSegment> >&
This commit is contained in:
@@ -219,17 +219,15 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
||||
}
|
||||
}
|
||||
|
||||
gGL.pushMatrix();
|
||||
gGL.loadIdentity();
|
||||
gGL.translatef(floorf(sCurOrigin.mX*sScaleX), floorf(sCurOrigin.mY*sScaleY), sCurDepth);
|
||||
gGL.pushUIMatrix();
|
||||
|
||||
// this code snaps the text origin to a pixel grid to start with
|
||||
F32 pixel_offset_x = llround((F32)sCurOrigin.mX) - (sCurOrigin.mX);
|
||||
F32 pixel_offset_y = llround((F32)sCurOrigin.mY) - (sCurOrigin.mY);
|
||||
gGL.translatef(-pixel_offset_x, -pixel_offset_y, 0.f);
|
||||
gGL.loadUIIdentity();
|
||||
|
||||
LLVector2 origin(floorf(sCurOrigin.mX*sScaleX), floorf(sCurOrigin.mY*sScaleY));
|
||||
|
||||
|
||||
gGL.color4fv( color.mV );
|
||||
// Depth translation, so that floating text appears 'in-world'
|
||||
// and is correctly occluded.
|
||||
gGL.translatef(0.f,0.f,sCurDepth);
|
||||
|
||||
S32 chars_drawn = 0;
|
||||
S32 i;
|
||||
@@ -249,20 +247,21 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
||||
// Not guaranteed to be set correctly
|
||||
gGL.setSceneBlendType(LLRender::BT_ALPHA);
|
||||
|
||||
cur_x = ((F32)x * sScaleX);
|
||||
cur_y = ((F32)y * sScaleY);
|
||||
cur_x = ((F32)x * sScaleX) + origin.mV[VX];
|
||||
cur_y = ((F32)y * sScaleY) + origin.mV[VY];
|
||||
|
||||
// Offset y by vertical alignment.
|
||||
// use unscaled font metrics here
|
||||
switch (valign)
|
||||
{
|
||||
case TOP:
|
||||
cur_y -= mAscender;
|
||||
cur_y -= llceil(mAscender);
|
||||
break;
|
||||
case BOTTOM:
|
||||
cur_y += mDescender;
|
||||
cur_y += llceil(mDescender);
|
||||
break;
|
||||
case VCENTER:
|
||||
cur_y -= ((mAscender - mDescender)/2.f);
|
||||
cur_y -= llceil((llceil(mAscender) - llceil(mDescender))/2.f);
|
||||
break;
|
||||
case BASELINE:
|
||||
// Baseline, do nothing.
|
||||
@@ -276,10 +275,10 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
||||
case LEFT:
|
||||
break;
|
||||
case RIGHT:
|
||||
cur_x -= llmin(scaled_max_pixels, llround(getWidthF32(wstr.c_str(), 0, length) * sScaleX));
|
||||
cur_x -= llmin(scaled_max_pixels, llround(getWidthF32(wstr.c_str(), begin_offset, length) * sScaleX));
|
||||
break;
|
||||
case HCENTER:
|
||||
cur_x -= llmin(scaled_max_pixels, llround(getWidthF32(wstr.c_str(), 0, length) * sScaleX)) / 2;
|
||||
cur_x -= llmin(scaled_max_pixels, llround(getWidthF32(wstr.c_str(), begin_offset, length) * sScaleX)) / 2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -288,10 +287,12 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
||||
cur_render_y = cur_y;
|
||||
cur_render_x = cur_x;
|
||||
|
||||
F32 start_x = cur_x;
|
||||
F32 start_x = (F32)llround(cur_x);
|
||||
|
||||
F32 inv_width = 1.f / mFontBitmapCachep->getBitmapWidth();
|
||||
F32 inv_height = 1.f / mFontBitmapCachep->getBitmapHeight();
|
||||
const LLFontBitmapCache* font_bitmap_cache = mFontBitmapCachep;
|
||||
|
||||
F32 inv_width = 1.f / font_bitmap_cache->getBitmapWidth();
|
||||
F32 inv_height = 1.f / font_bitmap_cache->getBitmapHeight();
|
||||
|
||||
const S32 LAST_CHARACTER = LLFontFreetype::LAST_CHAR_FULL;
|
||||
|
||||
@@ -300,7 +301,8 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
||||
if (use_ellipses && halign == LEFT)
|
||||
{
|
||||
// check for too long of a string
|
||||
if (getWidthF32(wstr.c_str(), 0, max_chars) * sScaleX > scaled_max_pixels)
|
||||
S32 string_width = llround(getWidthF32(wstr.c_str(), begin_offset, max_chars) * sScaleX);
|
||||
if (string_width > scaled_max_pixels)
|
||||
{
|
||||
// use four dots for ellipsis width to generate padding
|
||||
const LLWString dots(utf8str_to_wstring(std::string("....")));
|
||||
@@ -358,12 +360,9 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
||||
if (!label.empty())
|
||||
{
|
||||
gGL.pushMatrix();
|
||||
//gGL.loadIdentity();
|
||||
//gGL.translatef(sCurOrigin.mX, sCurOrigin.mY, 0.0f);
|
||||
//gGL.scalef(sScaleX, sScaleY, 1.f);
|
||||
getFontExtChar()->render(label, 0,
|
||||
/*llfloor*/((ext_x + (F32)ext_image->getWidth() + EXT_X_BEARING) / sScaleX),
|
||||
/*llfloor*/(cur_y / sScaleY),
|
||||
/*llfloor*/(ext_x / sScaleX) + ext_image->getWidth() + EXT_X_BEARING - sCurOrigin.mX,
|
||||
/*llfloor*/(cur_render_y / sScaleY) - sCurOrigin.mY,
|
||||
color,
|
||||
halign, BASELINE, NORMAL, NO_SHADOW, S32_MAX, S32_MAX, NULL,
|
||||
TRUE );
|
||||
@@ -412,12 +411,12 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
||||
LLRectf uv_rect((fgi->mXBitmapOffset) * inv_width,
|
||||
(fgi->mYBitmapOffset + fgi->mHeight + PAD_UVY) * inv_height,
|
||||
(fgi->mXBitmapOffset + fgi->mWidth) * inv_width,
|
||||
(fgi->mYBitmapOffset - PAD_UVY) * inv_height);
|
||||
// snap glyph origin to whole screen pixel
|
||||
LLRectf screen_rect(llround(cur_render_x + (F32)fgi->mXBearing),
|
||||
llround(cur_render_y + (F32)fgi->mYBearing),
|
||||
llround(cur_render_x + (F32)fgi->mXBearing) + (F32)fgi->mWidth,
|
||||
llround(cur_render_y + (F32)fgi->mYBearing) - (F32)fgi->mHeight);
|
||||
(fgi->mYBitmapOffset - PAD_UVY) * inv_height);
|
||||
// snap glyph origin to whole screen pixel
|
||||
LLRectf screen_rect((F32)llround(cur_render_x + (F32)fgi->mXBearing),
|
||||
(F32)llround(cur_render_y + (F32)fgi->mYBearing),
|
||||
(F32)llround(cur_render_x + (F32)fgi->mXBearing) + (F32)fgi->mWidth,
|
||||
(F32)llround(cur_render_y + (F32)fgi->mYBearing) - (F32)fgi->mHeight);
|
||||
|
||||
drawGlyph(screen_rect, uv_rect, color, style, shadow, drop_shadow_strength);
|
||||
|
||||
@@ -440,8 +439,8 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
||||
// Must do this to cur_x, not just to cur_render_x, otherwise you
|
||||
// will squish sub-pixel kerned characters too close together.
|
||||
// For example, "CCCCC" looks bad.
|
||||
cur_x = (F32)llfloor(cur_x + 0.5f);
|
||||
//cur_y = (F32)llfloor(cur_y + 0.5f);
|
||||
cur_x = (F32)llround(cur_x);
|
||||
//cur_y = (F32)llround(cur_y);
|
||||
|
||||
cur_render_x = cur_x;
|
||||
cur_render_y = cur_y;
|
||||
@@ -450,41 +449,40 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
||||
|
||||
if (right_x)
|
||||
{
|
||||
*right_x = cur_x / sScaleX;
|
||||
*right_x = (cur_x - origin.mV[VX]) / sScaleX;
|
||||
}
|
||||
|
||||
if (style & UNDERLINE)
|
||||
{
|
||||
F32 descender = (F32)llfloor(mDescender);
|
||||
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
gGL.begin(LLRender::LINES);
|
||||
gGL.vertex2f(start_x, cur_y - (mDescender));
|
||||
gGL.vertex2f(cur_x, cur_y - (mDescender));
|
||||
gGL.vertex2f(start_x, cur_y - descender);
|
||||
gGL.vertex2f(cur_x, cur_y - descender);
|
||||
gGL.end();
|
||||
}
|
||||
|
||||
// *FIX: get this working in all alignment cases, etc.
|
||||
if (draw_ellipses)
|
||||
{
|
||||
|
||||
// recursively render ellipses at end of string
|
||||
// we've already reserved enough room
|
||||
gGL.pushMatrix();
|
||||
//gGL.loadIdentity();
|
||||
//gGL.translatef(sCurOrigin.mX, sCurOrigin.mY, 0.0f);
|
||||
//gGL.scalef(sScaleX, sScaleY, 1.f);
|
||||
gGL.pushUIMatrix();
|
||||
renderUTF8(std::string("..."),
|
||||
0,
|
||||
cur_x / sScaleX, (F32)y,
|
||||
(cur_x - origin.mV[VX]) / sScaleX, (F32)y,
|
||||
color,
|
||||
LEFT, valign,
|
||||
style,
|
||||
LLFontGL::NO_SHADOW,
|
||||
shadow,
|
||||
S32_MAX, max_pixels,
|
||||
right_x,
|
||||
FALSE);
|
||||
gGL.popMatrix();
|
||||
gGL.popUIMatrix();
|
||||
}
|
||||
|
||||
gGL.popMatrix();
|
||||
gGL.popUIMatrix();
|
||||
|
||||
return chars_drawn;
|
||||
}
|
||||
@@ -578,7 +576,7 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, const S32 begin_offset, const S
|
||||
cur_x += getXAdvance(wch);
|
||||
llwchar next_char = wchars[i+1];
|
||||
|
||||
if (((i + 1) < max_chars)
|
||||
if (((i + 1) < begin_offset + max_chars)
|
||||
&& next_char
|
||||
&& (next_char < LAST_CHARACTER))
|
||||
{
|
||||
@@ -587,7 +585,7 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, const S32 begin_offset, const S
|
||||
}
|
||||
}
|
||||
// Round after kerning.
|
||||
cur_x = (F32)llfloor(cur_x + 0.5f);
|
||||
cur_x = (F32)llround(cur_x);
|
||||
}
|
||||
|
||||
return cur_x / sScaleX;
|
||||
@@ -694,7 +692,7 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch
|
||||
}
|
||||
}
|
||||
// Round after kerning.
|
||||
cur_x = (F32)llfloor(cur_x + 0.5f);
|
||||
cur_x = (F32)llround(cur_x);
|
||||
drawn_x = cur_x;
|
||||
}
|
||||
|
||||
@@ -871,7 +869,7 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, const S32 begin_offset,
|
||||
}
|
||||
|
||||
// Round after kerning.
|
||||
cur_x = (F32)llfloor(cur_x + 0.5f);
|
||||
cur_x = (F32)llround(cur_x);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -100,22 +100,21 @@ void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, const LL
|
||||
|
||||
void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixel_offset, BOOL filled)
|
||||
{
|
||||
gGL.pushMatrix();
|
||||
gGL.pushUIMatrix();
|
||||
left += LLFontGL::sCurOrigin.mX;
|
||||
right += LLFontGL::sCurOrigin.mX;
|
||||
bottom += LLFontGL::sCurOrigin.mY;
|
||||
top += LLFontGL::sCurOrigin.mY;
|
||||
|
||||
gGL.loadIdentity();
|
||||
gGL.loadUIIdentity();
|
||||
gl_rect_2d(llfloor((F32)left * LLRender2D::sGLScaleFactor.mV[VX]) - pixel_offset,
|
||||
llfloor((F32)top * LLRender2D::sGLScaleFactor.mV[VY]) + pixel_offset,
|
||||
llfloor((F32)right * LLRender2D::sGLScaleFactor.mV[VX]) + pixel_offset,
|
||||
llfloor((F32)bottom * LLRender2D::sGLScaleFactor.mV[VY]) - pixel_offset,
|
||||
filled);
|
||||
gGL.popMatrix();
|
||||
gGL.popUIMatrix();
|
||||
}
|
||||
|
||||
|
||||
void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, BOOL filled )
|
||||
{
|
||||
stop_glerror();
|
||||
@@ -386,8 +385,8 @@ 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 = LLVector3(1.f,1.f,1.f);//gGL.getUIScale();
|
||||
const LLVector3 ui_translation = LLVector3(x,y,0.f);//(gGL.getUITranslation() + LLVector3(x, y, 0.f)).scaledVec(ui_scale);
|
||||
const LLVector3 ui_scale = gGL.getUIScale();
|
||||
const LLVector3 ui_translation = (gGL.getUITranslation() + LLVector3(x, y, 0.f)).scaledVec(ui_scale);
|
||||
|
||||
F32 uv_width = uv_outer_rect.getWidth();
|
||||
F32 uv_height = uv_outer_rect.getHeight();
|
||||
@@ -659,8 +658,8 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre
|
||||
|
||||
gGL.begin(LLRender::QUADS);
|
||||
{
|
||||
LLVector3 ui_scale = LLVector3(1.f,1.f,1.f);//gGL.getUIScale();
|
||||
LLVector3 ui_translation = LLVector3(0.f,0.f,0.f); //gGL.getUITranslation();
|
||||
LLVector3 ui_scale = gGL.getUIScale();
|
||||
LLVector3 ui_translation = gGL.getUITranslation();
|
||||
ui_translation.mV[VX] += x;
|
||||
ui_translation.mV[VY] += y;
|
||||
ui_translation.scaleVec(ui_scale);
|
||||
@@ -690,13 +689,13 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre
|
||||
}
|
||||
else
|
||||
{
|
||||
gGL.pushMatrix();
|
||||
gGL.translatef((F32)x, (F32)y, 0.f);
|
||||
gGL.pushUIMatrix();
|
||||
gGL.translateUI((F32)x, (F32)y, 0.f);
|
||||
|
||||
F32 offset_x = F32(width/2);
|
||||
F32 offset_y = F32(height/2);
|
||||
|
||||
gGL.translatef(offset_x, offset_y, 0.f);
|
||||
gGL.translateUI(offset_x, offset_y, 0.f);
|
||||
|
||||
LLMatrix3 quat(0.f, 0.f, degrees*DEG_TO_RAD);
|
||||
|
||||
@@ -725,7 +724,7 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre
|
||||
gGL.vertex2f(v.mV[0], v.mV[1] );
|
||||
}
|
||||
gGL.end();
|
||||
gGL.popMatrix();
|
||||
gGL.popUIMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -766,9 +765,9 @@ void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled, F
|
||||
end_angle += F_TWO_PI;
|
||||
}
|
||||
|
||||
gGL.pushMatrix();
|
||||
gGL.pushUIMatrix();
|
||||
{
|
||||
gGL.translatef(center_x, center_y, 0.f);
|
||||
gGL.translateUI(center_x, center_y, 0.f);
|
||||
|
||||
// Inexact, but reasonably fast.
|
||||
F32 delta = (end_angle - start_angle) / steps;
|
||||
@@ -799,15 +798,15 @@ void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled, F
|
||||
}
|
||||
gGL.end();
|
||||
}
|
||||
gGL.popMatrix();
|
||||
gGL.popUIMatrix();
|
||||
}
|
||||
|
||||
void gl_circle_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled)
|
||||
{
|
||||
gGL.pushMatrix();
|
||||
gGL.pushUIMatrix();
|
||||
{
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
gGL.translatef(center_x, center_y, 0.f);
|
||||
gGL.translateUI(center_x, center_y, 0.f);
|
||||
|
||||
// Inexact, but reasonably fast.
|
||||
F32 delta = F_TWO_PI / steps;
|
||||
@@ -838,7 +837,7 @@ void gl_circle_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled
|
||||
}
|
||||
gGL.end();
|
||||
}
|
||||
gGL.popMatrix();
|
||||
gGL.popUIMatrix();
|
||||
}
|
||||
|
||||
// Renders a ring with sides (tube shape)
|
||||
@@ -865,9 +864,9 @@ void gl_deep_circle( F32 radius, F32 depth, S32 steps )
|
||||
|
||||
void gl_ring( F32 radius, F32 width, const LLColor4& center_color, const LLColor4& side_color, S32 steps, BOOL render_center )
|
||||
{
|
||||
gGL.pushMatrix();
|
||||
gGL.pushUIMatrix();
|
||||
{
|
||||
gGL.translatef(0.f, 0.f, -width / 2);
|
||||
gGL.translateUI(0.f, 0.f, -width / 2);
|
||||
if( render_center )
|
||||
{
|
||||
gGL.color4fv(center_color.mV);
|
||||
@@ -878,11 +877,11 @@ void gl_ring( F32 radius, F32 width, const LLColor4& center_color, const LLColor
|
||||
{
|
||||
gGL.diffuseColor4fv(side_color.mV);
|
||||
gl_washer_2d(radius, radius - width, steps, side_color, side_color);
|
||||
gGL.translatef(0.f, 0.f, width);
|
||||
gGL.translateUI(0.f, 0.f, width);
|
||||
gl_washer_2d(radius - width, radius, steps, side_color, side_color);
|
||||
}
|
||||
}
|
||||
gGL.popMatrix();
|
||||
gGL.popUIMatrix();
|
||||
}
|
||||
|
||||
// Draw gray and white checkerboard with black border
|
||||
@@ -1057,9 +1056,9 @@ void gl_segmented_rect_2d_tex(const S32 left,
|
||||
S32 width = llabs(right - left);
|
||||
S32 height = llabs(top - bottom);
|
||||
|
||||
gGL.pushMatrix();
|
||||
gGL.pushUIMatrix();
|
||||
|
||||
gGL.translatef((F32)left, (F32)bottom, 0.f);
|
||||
gGL.translateUI((F32)left, (F32)bottom, 0.f);
|
||||
LLVector2 border_uv_scale((F32)border_size / (F32)texture_width, (F32)border_size / (F32)texture_height);
|
||||
|
||||
if (border_uv_scale.mV[VX] > 0.5f)
|
||||
@@ -1200,7 +1199,7 @@ void gl_segmented_rect_2d_tex(const S32 left,
|
||||
}
|
||||
gGL.end();
|
||||
|
||||
gGL.popMatrix();
|
||||
gGL.popUIMatrix();
|
||||
}
|
||||
|
||||
//FIXME: rewrite to use scissor?
|
||||
@@ -1218,9 +1217,9 @@ void gl_segmented_rect_2d_fragment_tex(const S32 left,
|
||||
S32 width = llabs(right - left);
|
||||
S32 height = llabs(top - bottom);
|
||||
|
||||
gGL.pushMatrix();
|
||||
gGL.pushUIMatrix();
|
||||
|
||||
gGL.translatef((F32)left, (F32)bottom, 0.f);
|
||||
gGL.translateUI((F32)left, (F32)bottom, 0.f);
|
||||
LLVector2 border_uv_scale((F32)border_size / (F32)texture_width, (F32)border_size / (F32)texture_height);
|
||||
|
||||
if (border_uv_scale.mV[VX] > 0.5f)
|
||||
@@ -1391,7 +1390,7 @@ void gl_segmented_rect_2d_fragment_tex(const S32 left,
|
||||
}
|
||||
gGL.end();
|
||||
|
||||
gGL.popMatrix();
|
||||
gGL.popUIMatrix();
|
||||
}
|
||||
|
||||
void gl_segmented_rect_3d_tex(const LLVector2& border_scale, const LLVector3& border_width,
|
||||
@@ -1554,7 +1553,7 @@ void LLRender2D::cleanupClass()
|
||||
//static
|
||||
void LLRender2D::translate(F32 x, F32 y, F32 z)
|
||||
{
|
||||
gGL.translatef(x,y,z);
|
||||
gGL.translateUI(x,y,z);
|
||||
LLFontGL::sCurOrigin.mX += (S32) x;
|
||||
LLFontGL::sCurOrigin.mY += (S32) y;
|
||||
LLFontGL::sCurDepth += z;
|
||||
@@ -1563,14 +1562,14 @@ void LLRender2D::translate(F32 x, F32 y, F32 z)
|
||||
//static
|
||||
void LLRender2D::pushMatrix()
|
||||
{
|
||||
gGL.pushMatrix();
|
||||
gGL.pushUIMatrix();
|
||||
LLFontGL::sOriginStack.push_back(std::make_pair(LLFontGL::sCurOrigin, LLFontGL::sCurDepth));
|
||||
}
|
||||
|
||||
//static
|
||||
void LLRender2D::popMatrix()
|
||||
{
|
||||
gGL.popMatrix();
|
||||
gGL.popUIMatrix();
|
||||
LLFontGL::sCurOrigin = LLFontGL::sOriginStack.back().first;
|
||||
LLFontGL::sCurDepth = LLFontGL::sOriginStack.back().second;
|
||||
LLFontGL::sOriginStack.pop_back();
|
||||
@@ -1579,7 +1578,7 @@ void LLRender2D::popMatrix()
|
||||
//static
|
||||
void LLRender2D::loadIdentity()
|
||||
{
|
||||
gGL.loadIdentity();
|
||||
gGL.loadUIIdentity();
|
||||
LLFontGL::sCurOrigin.mX = 0;
|
||||
LLFontGL::sCurOrigin.mY = 0;
|
||||
LLFontGL::sCurDepth = 0.f;
|
||||
|
||||
@@ -36,9 +36,6 @@
|
||||
#include "llshadermgr.h"
|
||||
#include "llglslshader.h"
|
||||
#include "llmemory.h"
|
||||
#include "llfasttimer.h"
|
||||
|
||||
#define LL_VBO_POOLING 0
|
||||
|
||||
//Next Highest Power Of Two
|
||||
//helper function, returns first number > v that is a power of 2, or v if v is already a power of 2
|
||||
@@ -67,6 +64,7 @@ U32 wpo2(U32 i)
|
||||
|
||||
|
||||
const U32 LL_VBO_BLOCK_SIZE = 2048;
|
||||
const U32 LL_VBO_POOL_MAX_SEED_SIZE = 256*1024;
|
||||
|
||||
U32 vbo_block_size(U32 size)
|
||||
{ //what block size will fit size?
|
||||
@@ -79,6 +77,7 @@ U32 vbo_block_index(U32 size)
|
||||
return vbo_block_size(size)/LL_VBO_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
const U32 LL_VBO_POOL_SEED_COUNT = vbo_block_index(LL_VBO_POOL_MAX_SEED_SIZE);
|
||||
|
||||
|
||||
//============================================================================
|
||||
@@ -91,6 +90,11 @@ LLVBOPool LLVertexBuffer::sDynamicIBOPool(GL_DYNAMIC_DRAW_ARB, GL_ELEMENT_ARRAY_
|
||||
|
||||
U32 LLVBOPool::sBytesPooled = 0;
|
||||
U32 LLVBOPool::sIndexBytesPooled = 0;
|
||||
U32 LLVBOPool::sCurGLName = 1;
|
||||
|
||||
std::list<U32> LLVertexBuffer::sAvailableVAOName;
|
||||
U32 LLVertexBuffer::sCurVAOName = 1;
|
||||
|
||||
U32 LLVertexBuffer::sAllocatedIndexBytes = 0;
|
||||
U32 LLVertexBuffer::sIndexCount = 0;
|
||||
|
||||
@@ -116,14 +120,54 @@ bool LLVertexBuffer::sUseVAO = false;
|
||||
bool LLVertexBuffer::sPreferStreamDraw = false;
|
||||
|
||||
|
||||
volatile U8* LLVBOPool::allocate(U32& name, U32 size)
|
||||
U32 LLVBOPool::genBuffer()
|
||||
{
|
||||
U32 ret = 0;
|
||||
|
||||
if (mGLNamePool.empty())
|
||||
{
|
||||
ret = sCurGLName++;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = mGLNamePool.front();
|
||||
mGLNamePool.pop_front();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void LLVBOPool::deleteBuffer(U32 name)
|
||||
{
|
||||
if (gGLManager.mInited)
|
||||
{
|
||||
LLVertexBuffer::unbind();
|
||||
|
||||
glBindBufferARB(mType, name);
|
||||
glBufferDataARB(mType, 0, NULL, mUsage);
|
||||
|
||||
llassert(std::find(mGLNamePool.begin(), mGLNamePool.end(), name) == mGLNamePool.end());
|
||||
|
||||
mGLNamePool.push_back(name);
|
||||
|
||||
glBindBufferARB(mType, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LLVBOPool::LLVBOPool(U32 vboUsage, U32 vboType)
|
||||
: mUsage(vboUsage), mType(vboType)
|
||||
{
|
||||
mMissCount.resize(LL_VBO_POOL_SEED_COUNT);
|
||||
std::fill(mMissCount.begin(), mMissCount.end(), 0);
|
||||
}
|
||||
|
||||
volatile U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)
|
||||
{
|
||||
llassert(vbo_block_size(size) == size);
|
||||
|
||||
volatile U8* ret = NULL;
|
||||
|
||||
#if LL_VBO_POOLING
|
||||
|
||||
U32 i = vbo_block_index(size);
|
||||
|
||||
if (mFreeList.size() <= i)
|
||||
@@ -131,12 +175,18 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size)
|
||||
mFreeList.resize(i+1);
|
||||
}
|
||||
|
||||
if (mFreeList[i].empty())
|
||||
if (mFreeList[i].empty() || for_seed)
|
||||
{
|
||||
//make a new buffer
|
||||
glGenBuffersARB(1, &name);
|
||||
name = genBuffer();
|
||||
|
||||
glBindBufferARB(mType, name);
|
||||
|
||||
if (!for_seed && i < LL_VBO_POOL_SEED_COUNT)
|
||||
{ //record this miss
|
||||
mMissCount[i]++;
|
||||
}
|
||||
|
||||
if (mType == GL_ARRAY_BUFFER_ARB)
|
||||
{
|
||||
LLVertexBuffer::sAllocatedBytes += size;
|
||||
@@ -157,6 +207,25 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size)
|
||||
}
|
||||
|
||||
glBindBufferARB(mType, 0);
|
||||
|
||||
if (for_seed)
|
||||
{ //put into pool for future use
|
||||
llassert(mFreeList.size() > i);
|
||||
|
||||
Record rec;
|
||||
rec.mGLName = name;
|
||||
rec.mClientData = ret;
|
||||
|
||||
if (mType == GL_ARRAY_BUFFER_ARB)
|
||||
{
|
||||
sBytesPooled += size;
|
||||
}
|
||||
else
|
||||
{
|
||||
sIndexBytesPooled += size;
|
||||
}
|
||||
mFreeList[i].push_back(rec);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -174,33 +243,6 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size)
|
||||
|
||||
mFreeList[i].pop_front();
|
||||
}
|
||||
#else //no pooling
|
||||
|
||||
glGenBuffersARB(1, &name);
|
||||
glBindBufferARB(mType, name);
|
||||
|
||||
if (mType == GL_ARRAY_BUFFER_ARB)
|
||||
{
|
||||
LLVertexBuffer::sAllocatedBytes += size;
|
||||
}
|
||||
else
|
||||
{
|
||||
LLVertexBuffer::sAllocatedIndexBytes += size;
|
||||
}
|
||||
|
||||
if (LLVertexBuffer::sDisableVBOMapping || mUsage != GL_DYNAMIC_DRAW_ARB)
|
||||
{
|
||||
glBufferDataARB(mType, size, 0, mUsage);
|
||||
ret = (U8*) ll_aligned_malloc_16(size);
|
||||
}
|
||||
else
|
||||
{ //always use a true hint of static draw when allocating non-client-backed buffers
|
||||
glBufferDataARB(mType, size, 0, GL_STATIC_DRAW_ARB);
|
||||
}
|
||||
|
||||
glBindBufferARB(mType, 0);
|
||||
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -209,34 +251,7 @@ void LLVBOPool::release(U32 name, volatile U8* buffer, U32 size)
|
||||
{
|
||||
llassert(vbo_block_size(size) == size);
|
||||
|
||||
#if LL_VBO_POOLING
|
||||
|
||||
U32 i = vbo_block_index(size);
|
||||
|
||||
llassert(mFreeList.size() > i);
|
||||
|
||||
Record rec;
|
||||
rec.mGLName = name;
|
||||
rec.mClientData = buffer;
|
||||
|
||||
if (buffer == NULL)
|
||||
{
|
||||
glDeleteBuffersARB(1, &rec.mGLName);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mType == GL_ARRAY_BUFFER_ARB)
|
||||
{
|
||||
sBytesPooled += size;
|
||||
}
|
||||
else
|
||||
{
|
||||
sIndexBytesPooled += size;
|
||||
}
|
||||
mFreeList[i].push_back(rec);
|
||||
}
|
||||
#else //no pooling
|
||||
glDeleteBuffersARB(1, &name);
|
||||
deleteBuffer(name);
|
||||
ll_aligned_free_16((U8*) buffer);
|
||||
|
||||
if (mType == GL_ARRAY_BUFFER_ARB)
|
||||
@@ -247,12 +262,37 @@ void LLVBOPool::release(U32 name, volatile U8* buffer, U32 size)
|
||||
{
|
||||
LLVertexBuffer::sAllocatedIndexBytes -= size;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void LLVBOPool::seedPool()
|
||||
{
|
||||
U32 dummy_name = 0;
|
||||
|
||||
if (mFreeList.size() < LL_VBO_POOL_SEED_COUNT)
|
||||
{
|
||||
mFreeList.resize(LL_VBO_POOL_SEED_COUNT);
|
||||
}
|
||||
|
||||
for (U32 i = 0; i < LL_VBO_POOL_SEED_COUNT; i++)
|
||||
{
|
||||
if (mMissCount[i] > mFreeList[i].size())
|
||||
{
|
||||
U32 size = i*LL_VBO_BLOCK_SIZE;
|
||||
|
||||
S32 count = mMissCount[i] - mFreeList[i].size();
|
||||
for (S32 j = 0; j < count; ++j)
|
||||
{
|
||||
allocate(dummy_name, size, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LLVBOPool::cleanup()
|
||||
{
|
||||
U32 size = 1;
|
||||
U32 size = LL_VBO_BLOCK_SIZE;
|
||||
|
||||
for (U32 i = 0; i < mFreeList.size(); ++i)
|
||||
{
|
||||
@@ -262,8 +302,8 @@ void LLVBOPool::cleanup()
|
||||
{
|
||||
Record& r = l.front();
|
||||
|
||||
glDeleteBuffersARB(1, &r.mGLName);
|
||||
|
||||
deleteBuffer(r.mGLName);
|
||||
|
||||
if (r.mClientData)
|
||||
{
|
||||
ll_aligned_free_16((void*) r.mClientData);
|
||||
@@ -283,8 +323,11 @@ void LLVBOPool::cleanup()
|
||||
}
|
||||
}
|
||||
|
||||
size *= 2;
|
||||
size += LL_VBO_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
//reset miss counts
|
||||
std::fill(mMissCount.begin(), mMissCount.end(), 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -318,6 +361,41 @@ U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] =
|
||||
GL_LINE_LOOP,
|
||||
};
|
||||
|
||||
//static
|
||||
U32 LLVertexBuffer::getVAOName()
|
||||
{
|
||||
U32 ret = 0;
|
||||
|
||||
if (!sAvailableVAOName.empty())
|
||||
{
|
||||
ret = sAvailableVAOName.front();
|
||||
sAvailableVAOName.pop_front();
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef GL_ARB_vertex_array_object
|
||||
glGenVertexArrays(1, &ret);
|
||||
#endif
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//static
|
||||
void LLVertexBuffer::releaseVAOName(U32 name)
|
||||
{
|
||||
sAvailableVAOName.push_back(name);
|
||||
}
|
||||
|
||||
|
||||
//static
|
||||
void LLVertexBuffer::seedPools()
|
||||
{
|
||||
sStreamVBOPool.seedPool();
|
||||
sDynamicVBOPool.seedPool();
|
||||
sStreamIBOPool.seedPool();
|
||||
sDynamicIBOPool.seedPool();
|
||||
}
|
||||
|
||||
//static
|
||||
void LLVertexBuffer::setupClientArrays(U32 data_mask)
|
||||
@@ -473,8 +551,21 @@ void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos, con
|
||||
gGL.syncMatrices();
|
||||
|
||||
U32 count = pos.size();
|
||||
llassert_always(norm.size() >= pos.size());
|
||||
llassert_always(count > 0);
|
||||
|
||||
llassert(norm.size() >= pos.size());
|
||||
llassert(count > 0);
|
||||
|
||||
if( count == 0 )
|
||||
{
|
||||
llwarns << "Called drawArrays with 0 vertices" << llendl;
|
||||
return;
|
||||
}
|
||||
|
||||
if( norm.size() < pos.size() )
|
||||
{
|
||||
llwarns << "Called drawArrays with #" << norm.size() << " normals and #" << pos.size() << " vertices" << llendl;
|
||||
return;
|
||||
}
|
||||
|
||||
unbind();
|
||||
|
||||
@@ -690,6 +781,7 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
|
||||
placeFence();
|
||||
}
|
||||
|
||||
static LLFastTimer::DeclareTimer FTM_GL_DRAW_ARRAYS("GL draw arrays");
|
||||
void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
|
||||
{
|
||||
llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
|
||||
@@ -724,8 +816,11 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
|
||||
return;
|
||||
}
|
||||
|
||||
stop_glerror();
|
||||
glDrawArrays(sGLMode[mode], first, count);
|
||||
{
|
||||
LLFastTimer t2(FTM_GL_DRAW_ARRAYS);
|
||||
stop_glerror();
|
||||
glDrawArrays(sGLMode[mode], first, count);
|
||||
}
|
||||
stop_glerror();
|
||||
placeFence();
|
||||
}
|
||||
@@ -920,7 +1015,7 @@ LLVertexBuffer::~LLVertexBuffer()
|
||||
if (mGLArray)
|
||||
{
|
||||
#if GL_ARB_vertex_array_object
|
||||
glDeleteVertexArrays(1, &mGLArray);
|
||||
releaseVAOName(mGLArray);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1193,7 +1288,7 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
|
||||
if (gGLManager.mHasVertexArrayObject && useVBOs() && (LLRender::sGLCoreProfile || sUseVAO))
|
||||
{
|
||||
#if GL_ARB_vertex_array_object
|
||||
glGenVertexArrays(1, &mGLArray);
|
||||
mGLArray = getVAOName();
|
||||
#endif
|
||||
setupVertexArray();
|
||||
}
|
||||
|
||||
@@ -56,24 +56,29 @@ class LLVBOPool
|
||||
public:
|
||||
static U32 sBytesPooled;
|
||||
static U32 sIndexBytesPooled;
|
||||
|
||||
static U32 sCurGLName;
|
||||
|
||||
LLVBOPool(U32 vboUsage, U32 vboType)
|
||||
: mUsage(vboUsage)
|
||||
, mType(vboType)
|
||||
{}
|
||||
|
||||
LLVBOPool(U32 vboUsage, U32 vboType);
|
||||
|
||||
const U32 mUsage;
|
||||
const U32 mType;
|
||||
|
||||
//size MUST be a power of 2
|
||||
volatile U8* allocate(U32& name, U32 size);
|
||||
volatile U8* allocate(U32& name, U32 size, bool for_seed = false);
|
||||
|
||||
//size MUST be the size provided to allocate that returned the given name
|
||||
void release(U32 name, volatile U8* buffer, U32 size);
|
||||
|
||||
//batch allocate buffers to be provided to the application on demand
|
||||
void seedPool();
|
||||
|
||||
//destroy all records in mFreeList
|
||||
void cleanup();
|
||||
|
||||
U32 genBuffer();
|
||||
void deleteBuffer(U32 name);
|
||||
|
||||
class Record
|
||||
{
|
||||
public:
|
||||
@@ -81,8 +86,12 @@ public:
|
||||
volatile U8* mClientData;
|
||||
};
|
||||
|
||||
std::list<U32> mGLNamePool;
|
||||
|
||||
typedef std::list<Record> record_list_t;
|
||||
std::vector<record_list_t> mFreeList;
|
||||
std::vector<U32> mMissCount;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -119,10 +128,18 @@ public:
|
||||
static LLVBOPool sStreamIBOPool;
|
||||
static LLVBOPool sDynamicIBOPool;
|
||||
|
||||
static std::list<U32> sAvailableVAOName;
|
||||
static U32 sCurVAOName;
|
||||
|
||||
static bool sUseStreamDraw;
|
||||
static bool sUseVAO;
|
||||
static bool sPreferStreamDraw;
|
||||
|
||||
static void seedPools();
|
||||
|
||||
static U32 getVAOName();
|
||||
static void releaseVAOName(U32 name);
|
||||
|
||||
static void initClass(bool use_vbo, bool no_vbo_mapping);
|
||||
static void cleanupClass();
|
||||
static void setupClientArrays(U32 data_mask);
|
||||
|
||||
Reference in New Issue
Block a user