00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034 #include "indra_constants.h"
00035 #include "llmemoryview.h"
00036
00037 #include "llrect.h"
00038 #include "llerror.h"
00039 #include "llgl.h"
00040 #include "llmath.h"
00041 #include "llfontgl.h"
00042 #include "llmemtype.h"
00043
00044 #include "viewer.h"
00045 #include "llui.h"
00046 #include "llviewercontrol.h"
00047 #include "llstat.h"
00048
00049 #include "llfasttimer.h"
00050
00051
00052
00053 LLMemoryView::LLMemoryView(const std::string& name, const LLRect& rect)
00054 : LLView(name, rect, TRUE),
00055 mDelay(120)
00056 {
00057 setVisible(FALSE);
00058 mDumpTimer.reset();
00059
00060 #ifdef MEM_DUMP_DATA
00061
00062 FILE *dump = fopen("memusagedump.txt", "w");
00063 fclose(dump);
00064 #endif
00065 }
00066
00067 LLMemoryView::~LLMemoryView()
00068 {
00069 }
00070
00071 EWidgetType LLMemoryView::getWidgetType() const
00072 {
00073 return WIDGET_TYPE_MEMORY_VIEW;
00074 }
00075
00076 LLString LLMemoryView::getWidgetTag() const
00077 {
00078 return LL_MEMORY_VIEW_TAG;
00079 }
00080
00081 BOOL LLMemoryView::handleMouseDown(S32 x, S32 y, MASK mask)
00082 {
00083 if (mask & MASK_SHIFT)
00084 {
00085 }
00086 else if (mask & MASK_CONTROL)
00087 {
00088 }
00089 else
00090 {
00091 }
00092 return TRUE;
00093 }
00094
00095 BOOL LLMemoryView::handleMouseUp(S32 x, S32 y, MASK mask)
00096 {
00097 return TRUE;
00098 }
00099
00100
00101 BOOL LLMemoryView::handleHover(S32 x, S32 y, MASK mask)
00102 {
00103 return FALSE;
00104 }
00105
00107
00108 struct mtv_display_info {
00109 S32 memtype;
00110 const char *desc;
00111 LLColor4 *color;
00112 };
00113
00114 static LLColor4 red0(0.5f, 0.0f, 0.0f, 1.0f);
00115
00116 static struct mtv_display_info mtv_display_table[] =
00117 {
00118 { LLMemType::MTYPE_INIT, "Init", &LLColor4::white },
00119 { LLMemType::MTYPE_STARTUP, "Startup", &LLColor4::cyan1 },
00120 { LLMemType::MTYPE_MAIN, "Main", &LLColor4::cyan2 },
00121 { LLMemType::MTYPE_IMAGEBASE, "ImageBase", &LLColor4::yellow1 },
00122 { LLMemType::MTYPE_IMAGERAW, "ImageRaw", &LLColor4::yellow2 },
00123 { LLMemType::MTYPE_IMAGEFORMATTED, "ImageFmtd", &LLColor4::yellow3 },
00124 { LLMemType::MTYPE_APPFMTIMAGE, "ViewerImageFmt", &LLColor4::orange1 },
00125 { LLMemType::MTYPE_APPRAWIMAGE, "ViewerImageRaw", &LLColor4::orange2 },
00126 { LLMemType::MTYPE_APPAUXRAWIMAGE, "ViewerImageAux", &LLColor4::orange3 },
00127 { LLMemType::MTYPE_DRAWABLE, "Drawable", &LLColor4::green1 },
00128 { LLMemType::MTYPE_OBJECT, "ViewerObject", &LLColor4::green2 },
00129 { LLMemType::MTYPE_PIPELINE, "Pipeline", &LLColor4::green3 },
00130 { LLMemType::MTYPE_PARTICLES, "Particles", &LLColor4::green4 },
00131 { LLMemType::MTYPE_SPACE_PARTITION, "Space Partition", &LLColor4::blue2 },
00132 { LLMemType::MTYPE_VERTEX_DATA, "Vertex Buffer", &LLColor4::blue3 },
00133 { LLMemType::MTYPE_AVATAR, "Avatar", &LLColor4::purple1 },
00134 { LLMemType::MTYPE_REGIONS, "Regions", &LLColor4::blue1 },
00135 { LLMemType::MTYPE_TEMP1, "Temp1", &LLColor4::red1 },
00136 { LLMemType::MTYPE_TEMP2, "Temp2", &LLColor4::magenta1 },
00137 { LLMemType::MTYPE_TEMP3, "Temp3", &LLColor4::red2 },
00138 { LLMemType::MTYPE_TEMP4, "Temp4", &LLColor4::magenta2 },
00139 { LLMemType::MTYPE_TEMP5, "Temp5", &LLColor4::red3 },
00140 { LLMemType::MTYPE_TEMP6, "Temp6", &LLColor4::magenta3 },
00141 { LLMemType::MTYPE_TEMP7, "Temp7", &LLColor4::red4 },
00142 { LLMemType::MTYPE_TEMP8, "Temp8", &LLColor4::magenta4 },
00143
00144 { LLMemType::MTYPE_OTHER, "Other", &red0 },
00145 };
00146 static const int MTV_DISPLAY_NUM = (sizeof(mtv_display_table)/sizeof(mtv_display_table[0]));
00147
00148 void LLMemoryView::draw()
00149 {
00150 std::string tdesc;
00151 S32 width = mRect.getWidth();
00152 S32 height = mRect.getHeight();
00153
00154 LLGLSUIDefault gls_ui;
00155 LLGLSNoTexture gls_no_tex;
00156 gl_rect_2d(0, height, width, 0, LLColor4(0.f, 0.f, 0.f, 0.25f));
00157
00158 #if MEM_TRACK_TYPE
00159
00160 S32 left, top, right, bottom;
00161 S32 x, y;
00162
00163 S32 margin = 10;
00164 S32 texth = (S32)LLFontGL::sMonospace->getLineHeight();
00165
00166 S32 xleft = margin;
00167 S32 ytop = height - margin;
00168 S32 labelwidth = 0;
00169 S32 maxmaxbytes = 1;
00170
00171
00172
00173 {
00174 S32 display_memtypes[LLMemType::MTYPE_NUM_TYPES];
00175 for (S32 i=0; i < LLMemType::MTYPE_NUM_TYPES; i++)
00176 {
00177 display_memtypes[i] = 0;
00178 }
00179 for (S32 i=0; i < MTV_DISPLAY_NUM; i++)
00180 {
00181 S32 tidx = mtv_display_table[i].memtype;
00182 display_memtypes[tidx]++;
00183 }
00184 LLMemType::sMemCount[LLMemType::MTYPE_OTHER] = 0;
00185 LLMemType::sMaxMemCount[LLMemType::MTYPE_OTHER] = 0;
00186 for (S32 tidx = 0; tidx < LLMemType::MTYPE_NUM_TYPES; tidx++)
00187 {
00188 if (display_memtypes[tidx] == 0)
00189 {
00190 LLMemType::sMemCount[LLMemType::MTYPE_OTHER] += LLMemType::sMemCount[tidx];
00191 LLMemType::sMaxMemCount[LLMemType::MTYPE_OTHER] += LLMemType::sMaxMemCount[tidx];
00192 }
00193 }
00194 }
00195
00196
00197 {
00198 LLGLSTexture gls_texture;
00199 y = ytop;
00200 S32 peak = 0;
00201 for (S32 i=0; i<MTV_DISPLAY_NUM; i++)
00202 {
00203 x = xleft;
00204
00205 int tidx = mtv_display_table[i].memtype;
00206 S32 bytes = LLMemType::sMemCount[tidx];
00207 S32 maxbytes = LLMemType::sMaxMemCount[tidx];
00208 maxmaxbytes = llmax(maxbytes, maxmaxbytes);
00209 peak += maxbytes;
00210 S32 mbytes = bytes >> 20;
00211
00212 tdesc = llformat("%s [%4d MB] in %06d NEWS",mtv_display_table[i].desc,mbytes, LLMemType::sNewCount[tidx]);
00213 LLFontGL::sMonospace->renderUTF8(tdesc, 0, x, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP);
00214
00215 y -= (texth + 2);
00216
00217 S32 textw = LLFontGL::sMonospace->getWidth(tdesc);
00218 if (textw > labelwidth)
00219 labelwidth = textw;
00220 }
00221 x = xleft;
00222 tdesc = llformat("Total Bytes: %d MB Overhead: %d KB",
00223 LLMemType::sTotalMem >> 20, LLMemType::sOverheadMem >> 10);
00224 LLFontGL::sMonospace->renderUTF8(tdesc, 0, x, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP);
00225 }
00226
00227
00228 y = ytop;
00229 labelwidth += 8;
00230 S32 barw = width - labelwidth - xleft - margin;
00231 for (S32 i=0; i<MTV_DISPLAY_NUM; i++)
00232 {
00233 x = xleft + labelwidth;
00234
00235 int tidx = mtv_display_table[i].memtype;
00236 S32 bytes = LLMemType::sMemCount[tidx];
00237 F32 frac = (F32)bytes / (F32)maxmaxbytes;
00238 S32 w = (S32)(frac * (F32)barw);
00239 left = x; right = x + w;
00240 top = y; bottom = y - texth;
00241 gl_rect_2d(left, top, right, bottom, *mtv_display_table[i].color);
00242
00243 S32 maxbytes = LLMemType::sMaxMemCount[tidx];
00244 F32 frac2 = (F32)maxbytes / (F32)maxmaxbytes;
00245 S32 w2 = (S32)(frac2 * (F32)barw);
00246 left = x + w + 1; right = x + w2;
00247 top = y; bottom = y - texth;
00248 LLColor4 tcolor = *mtv_display_table[i].color;
00249 tcolor.setAlpha(.5f);
00250 gl_rect_2d(left, top, right, bottom, tcolor);
00251
00252 y -= (texth + 2);
00253 }
00254
00255 dumpData();
00256
00257 #endif
00258
00259 LLView::draw();
00260 }
00261
00262 void LLMemoryView::setDataDumpInterval(float delay)
00263 {
00264 mDelay = delay;
00265 }
00266
00267 void LLMemoryView::dumpData()
00268 {
00269 #if MEM_TRACK_TYPE && MEM_DUMP_DATA
00270 if (mDelay && (mDumpTimer.getElapsedTimeF32() > mDelay ))
00271 {
00272
00273 mDumpTimer.reset();
00274
00275 FILE *dump = fopen("memusagedump.txt", "a");
00276
00277 if (dump)
00278 {
00279
00280 fprintf (dump, "Total memory in use = %09d (%03d MB)\n", LLMemType::sTotalMem, LLMemType::sTotalMem>>20);
00281 fprintf (dump, "High Water Mark = %09d (%03d MB)\n\n", LLMemType::sMaxTotalMem, LLMemType::sMaxTotalMem>>20);
00282
00283 for (S32 i=0; i<LLMemType::MTYPE_NUM_TYPES; i++)
00284 {
00285 if (LLMemType::sMemCount[i])
00286 {
00287 std::string outData = llformat("MEM: % 20s %09d %03d MB (%09d %03d MB) in %06d News", LLMemType::sTypeDesc[i], LLMemType::sMemCount[i], LLMemType::sMemCount[i]>>20, LLMemType::sMaxMemCount[i], LLMemType::sMaxMemCount[i]>>20, LLMemType::sNewCount[i]);
00288 fprintf (dump, "%s\n", outData.c_str());
00289 }
00290 }
00291 fprintf (dump, "\n\n");
00292
00293 fclose(dump);
00294 }
00295 }
00296 #endif
00297 }