diff --git a/indra/llui/llcheckboxctrl.cpp b/indra/llui/llcheckboxctrl.cpp index e8e34e64d..5df4ae675 100644 --- a/indra/llui/llcheckboxctrl.cpp +++ b/indra/llui/llcheckboxctrl.cpp @@ -93,11 +93,13 @@ LLCheckBoxCtrl::LLCheckBoxCtrl(const std::string& name, const LLRect& rect, // *HACK Get rid of this with SL-55508... // this allows blank check boxes and radio boxes for now - std::string local_label = label; + // Singu Note: Don't do this. Slows rendering down dramatically, and also seems to not fix anything? + /*std::string local_label = label; if(local_label.empty()) { - local_label = " "; - } + + //local_label = " "; + }*/ mLabel = new LLTextBox( std::string("CheckboxCtrl Label"), label_rect, local_label, mFont ); mLabel->setFollowsLeft(); diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 4e1531831..7af6313af 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -1403,7 +1403,16 @@ void LLScrollListCtrl::drawItems() { LLLocalClipRect clip(mItemListRect); - S32 cur_y = y; + LLRect clip_rect = LLUI::getRootView()->getRect(); + if (LLGLState::isEnabled()) + { + LLRect scissor = gGL.getScissor(); + scissor.mLeft /= LLUI::getScaleFactor().mV[VX]; + scissor.mTop /= LLUI::getScaleFactor().mV[VY]; + scissor.mRight /= LLUI::getScaleFactor().mV[VX]; + scissor.mBottom /= LLUI::getScaleFactor().mV[VY]; + clip_rect.intersectWith(scissor); + } S32 max_columns = 0; @@ -1418,55 +1427,70 @@ void LLScrollListCtrl::drawItems() { return; } - item_list::iterator iter; - for (S32 line = first_line; line <= last_line; line++) + bool done = false; + for (S32 pass = 0; !done; ++pass) { - LLScrollListItem* item = mItemList[line]; - - item_rect.setOriginAndSize( - x, - cur_y, - mItemListRect.getWidth(), - mLineHeight ); - item->setRect(item_rect); - - //LL_INFOS() << item_rect.getWidth() << LL_ENDL; - - max_columns = llmax(max_columns, item->getNumColumns()); - - LLColor4 fg_color; - LLColor4 bg_color(LLColor4::transparent); - - if( mScrollLines <= line && line < mScrollLines + num_page_lines ) + bool should_continue = false; // False until all passes are done for all row cells. + S32 cur_y = y; + for (S32 line = first_line; line <= last_line; line++) { - fg_color = (item->getEnabled() ? mFgUnselectedColor : mFgDisabledColor); - if( item->getSelected() && mCanSelect) + LLScrollListItem* item = mItemList[line]; + + item_rect.setOriginAndSize( + x, + cur_y, + mItemListRect.getWidth(), + mLineHeight); + item->setRect(item_rect); + + //LL_INFOS() << item_rect.getWidth() << LL_ENDL; + + max_columns = llmax(max_columns, item->getNumColumns()); + + LLColor4 fg_color; + LLColor4 bg_color(LLColor4::transparent); + + if (mScrollLines <= line && line < mScrollLines + num_page_lines) { - bg_color = mBgSelectedColor; - fg_color = (item->getEnabled() ? mFgSelectedColor : mFgDisabledColor); - } - else if (mHighlightedItem == line && mCanSelect) - { - bg_color = mHighlightedColor; - } - else - { - if (mDrawStripes && (line % 2 == 0) && (max_columns > 1)) + cur_y -= mLineHeight; + + // Do not draw if not on screen. + LLRect screen_rect = item_rect; + screen_rect.translate(LLFontGL::sCurOrigin.mX, LLFontGL::sCurOrigin.mY); + if (!clip_rect.overlaps(screen_rect)) { - bg_color = mBgStripeColor; + continue; } + + fg_color = (item->getEnabled() ? mFgUnselectedColor : mFgDisabledColor); + if (item->getSelected() && mCanSelect) + { + bg_color = mBgSelectedColor; + fg_color = (item->getEnabled() ? mFgSelectedColor : mFgDisabledColor); + } + else if (mHighlightedItem == line && mCanSelect) + { + bg_color = mHighlightedColor; + } + else + { + if (mDrawStripes && (line % 2 == 0) && (max_columns > 1)) + { + bg_color = mBgStripeColor; + } + } + + if (!item->getEnabled()) + { + bg_color = mBgReadOnlyColor; + } + + should_continue |= item->draw(pass, item_rect, fg_color, bg_color, highlight_color, mColumnPadding); } - - if (!item->getEnabled()) - { - bg_color = mBgReadOnlyColor; - } - - item->draw(item_rect, fg_color, bg_color, highlight_color, mColumnPadding); - - cur_y -= mLineHeight; } + done = !should_continue; } + } } diff --git a/indra/llui/llscrolllistitem.cpp b/indra/llui/llscrolllistitem.cpp index 3abe322a9..c490a5249 100644 --- a/indra/llui/llscrolllistitem.cpp +++ b/indra/llui/llscrolllistitem.cpp @@ -28,6 +28,7 @@ #include "linden_common.h" #include "llscrolllistitem.h" +#include "llview.h" //--------------------------------------------------------------------------- @@ -116,32 +117,73 @@ std::string LLScrollListItem::getContentsCSV() const } -void LLScrollListItem::draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding) +bool LLScrollListItem::draw(const U32 pass, const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding) { + const U32 num_cols = (U32)getNumColumns(); + // draw background rect - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - LLRect bg_rect = rect; - gl_rect_2d( bg_rect, bg_color ); - - S32 cur_x = rect.mLeft; - S32 num_cols = getNumColumns(); - S32 cur_col = 0; - - for (LLScrollListCell* cell = getColumn(0); cur_col < num_cols; cell = getColumn(++cur_col)) + if (pass == 0) { - // Two ways a cell could be hidden - if (cell->getWidth() < 0 - || !cell->getVisible()) continue; - - LLUI::pushMatrix(); - { - LLUI::translate((F32) cur_x, (F32) rect.mBottom); - - cell->draw( fg_color, highlight_color ); - } - LLUI::popMatrix(); - - cur_x += cell->getWidth() + column_padding; + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gl_rect_2d(rect, bg_color); + return true; } + // Draw column (pass - 1) + else if (pass <= num_cols) + { + LLScrollListCell* cur_cell = getColumn(pass - 1); + if (!cur_cell) + { + return false; + } + // Two ways a cell could be hidden + else if (cur_cell->getWidth() && cur_cell->getVisible()) + { + // Iterate over cells to the left and calculate offset. + S32 offset = rect.mLeft; + for (U32 i = 0; i < (pass - 1); ++i) + { + LLScrollListCell* cell = getColumn(i); + if (!cell) + { + return false; // Shouldn't happen. + } + if (cell->getVisible() && cell->getWidth()) + { + // Only apply padding if cell is visible and has width. + offset += cell->getWidth() + column_padding; + } + } + // Do not draw if not on screen. + // Only care about horizontal bounds. This draw call wont even occur if this row is entirely off screen. + LLRect clip_rect = LLUI::getRootView()->getRect(); + if (LLGLState::isEnabled()) + { + LLRect scissor = gGL.getScissor(); + scissor.mLeft /= LLUI::getScaleFactor().mV[VX]; + scissor.mTop /= LLUI::getScaleFactor().mV[VY]; + scissor.mRight /= LLUI::getScaleFactor().mV[VX]; + scissor.mBottom /= LLUI::getScaleFactor().mV[VY]; + clip_rect.intersectWith(scissor); + } + if (offset + LLFontGL::sCurOrigin.mX >= clip_rect.mRight) + { + // Went off the right edge of the screen. Don't bother with any more columns. + return false; + } + // Draw if not off the left edge of screen. If it is off the left edge, still return true if other colums remain. + if (offset + LLFontGL::sCurOrigin.mX + cur_cell->getWidth() > clip_rect.mLeft) + { + LLUI::pushMatrix(); + { + LLUI::translate((F32)offset, (F32)rect.mBottom); + cur_cell->draw(fg_color, highlight_color); + } + LLUI::popMatrix(); + } + } + return pass != getNumColumns(); + } + return false; } diff --git a/indra/llui/llscrolllistitem.h b/indra/llui/llscrolllistitem.h index 0d87a0fbf..a1229e034 100644 --- a/indra/llui/llscrolllistitem.h +++ b/indra/llui/llscrolllistitem.h @@ -92,7 +92,7 @@ public: std::string getContentsCSV() const; - virtual void draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding); + virtual bool draw(const U32 pass, const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding); protected: LLScrollListItem( const Params& ); diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 8bae13aac..c983d3a84 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -1221,7 +1221,16 @@ void LLView::drawChildren() }*/ if (!mChildList.empty()) { - LLView* rootp = LLUI::getRootView(); + LLRect clip_rect = LLUI::getRootView()->getRect(); + if (LLGLState::isEnabled()) + { + LLRect scissor = gGL.getScissor(); + scissor.mLeft /= LLUI::getScaleFactor().mV[VX]; + scissor.mTop /= LLUI::getScaleFactor().mV[VY]; + scissor.mRight /= LLUI::getScaleFactor().mV[VX]; + scissor.mBottom /= LLUI::getScaleFactor().mV[VY]; + clip_rect.intersectWith(scissor); + } ++sDepth; for (child_list_const_reverse_iter_t child_iter = mChildList.rbegin(); child_iter != mChildList.rend(); ++child_iter) @@ -1235,10 +1244,13 @@ void LLView::drawChildren() if (viewp->getVisible() && /*viewp != focus_view && */viewp->getRect().isValid()) { // Only draw views that are within the root view - LLRect screen_rect = viewp->calcScreenRect(); - if ( rootp->getRect().overlaps(screen_rect) ) + // LLView::calcScreenRect not used due to scrolllist cells containing views that aren't inserted into the view heirarchy. + // Render-time offset is stored in LLFontGL::sCurOrigin, which is valid during the draw call chain (which this method is part of) + // Bonus: Reading LLFontGL::sCurOrigin is way (way way way) faster than calling LLView::calcScreenRect. + LLRect screen_rect = viewp->getRect(); + screen_rect.translate(LLFontGL::sCurOrigin.mX, LLFontGL::sCurOrigin.mY); + if ( clip_rect.overlaps(screen_rect) ) { - //gGL.matrixMode(LLRender::MM_MODELVIEW); LLUI::pushMatrix(); { LLUI::translate((F32)viewp->getRect().mLeft, (F32)viewp->getRect().mBottom, 0.f); @@ -1263,7 +1275,6 @@ void LLView::drawChildren() LLUI::popMatrix(); } } - } --sDepth; }