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