00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "mmscore/mmsperf.h"
00034 #include <stdio.h>
00035 #include <sys/time.h>
00036
00037
00038
00039 bool MMSPerf::initialized = false;
00040 MMSMutex MMSPerf::lockme;
00041 struct timeval MMSPerf::start_time;
00042 MMSFBPERF_MEASURING_LIST MMSPerf::fillrect;
00043 MMSFBPERF_MEASURING_LIST MMSPerf::drawline;
00044 MMSFBPERF_MEASURING_LIST MMSPerf::drawstring;
00045 MMSFBPERF_MEASURING_LIST MMSPerf::blit;
00046 MMSFBPERF_MEASURING_LIST MMSPerf::stretchblit;
00047 MMSFBPERF_MEASURING_LIST MMSPerf::xshmputimage;
00048 MMSFBPERF_MEASURING_LIST MMSPerf::xvshmputimage;
00049 MMSFBPERF_MEASURING_LIST MMSPerf::vsync;
00050 MMSFBPERF_MEASURING_LIST MMSPerf::swapdisplay;
00051 MMSFBPERF_MEASURING_LIST_VKEY MMSPerf::vkey;
00052
00053
00054 MMSPerf::MMSPerf() {
00055 if (!this->initialized) {
00056
00057 reset();
00058 this->initialized = true;
00059 }
00060 }
00061
00062 MMSPerf::~MMSPerf() {
00063 }
00064
00065 void MMSPerf::lock() {
00066 lockme.lock();
00067 }
00068
00069 void MMSPerf::unlock() {
00070 lockme.unlock();
00071 }
00072
00073 void MMSPerf::reset() {
00074
00075 lock();
00076 memset(this->fillrect, 0, sizeof(this->fillrect));
00077 memset(this->drawline, 0, sizeof(this->drawline));
00078 memset(this->drawstring, 0, sizeof(this->drawstring));
00079 memset(this->blit, 0, sizeof(this->blit));
00080 memset(this->stretchblit, 0, sizeof(this->stretchblit));
00081 memset(this->xshmputimage, 0, sizeof(this->xshmputimage));
00082 memset(this->xvshmputimage, 0, sizeof(this->xvshmputimage));
00083 memset(this->vsync, 0, sizeof(this->vsync));
00084 memset(this->swapdisplay, 0, sizeof(this->swapdisplay));
00085 memset(this->vkey, 0, sizeof(this->vkey));
00086 gettimeofday(&this->start_time, NULL);
00087 unlock();
00088 }
00089
00090 unsigned int MMSPerf::getDuration() {
00091 struct timeval end_time;
00092 gettimeofday(&end_time, NULL);
00093
00094 unsigned int ms = (end_time.tv_sec - this->start_time.tv_sec) * 1000;
00095 if (end_time.tv_usec >= this->start_time.tv_usec)
00096 ms+= (end_time.tv_usec - this->start_time.tv_usec) / 1000;
00097 else
00098 ms-= (this->start_time.tv_usec - end_time.tv_usec) / 1000;
00099 if (ms == 0) ms = 1;
00100
00101 return ms;
00102 }
00103
00104 void MMSPerf::addMeasuringVals(MMSFBPERF_MEASURING_VALS *summary, MMSFBPERF_MEASURING_VALS *add_sum) {
00105
00106 summary->calls+= add_sum->calls;
00107 summary->usecs+= add_sum->usecs;
00108
00109 if (add_sum->mpixels > 0 && add_sum->rpixels > 0) {
00110
00111 summary->mpixels+= add_sum->mpixels; lock();
00112
00113 summary->rpixels+= add_sum->rpixels;
00114 summary->mpixels+= summary->rpixels / 1000000;
00115 summary->rpixels%= 1000000;
00116
00117
00118 summary->mpps = summary->mpixels * 1000;
00119 if (summary->usecs > 1000) summary->mpps/= summary->usecs / 1000;
00120 if (summary->usecs > 0) summary->mpps+= summary->rpixels / summary->usecs;
00121 }
00122 }
00123
00124 void MMSPerf::addMeasuringVals(MMSFBPERF_MEASURING_VALS_VKEY *summary, MMSFBPERF_MEASURING_VALS_VKEY *add_sum) {
00125
00126 summary->calls+= add_sum->calls;
00127 summary->usecs+= add_sum->usecs;
00128 }
00129
00130 int MMSPerf::getPerfVals(MMSFBPERF_MEASURING_LIST *mlist, const char *prefix, char *retbuf, int retbuf_size,
00131 MMSFBPERF_MEASURING_VALS *summary) {
00132 char *retbuf_start=retbuf;
00133 char *retbuf_end = retbuf + retbuf_size;
00134
00135 for (unsigned int buftype = 0; buftype < 2; buftype++) {
00136 for (unsigned int pf_cnt = 0; pf_cnt < MMSFB_PF_CNT; pf_cnt++) {
00137 for (unsigned int src_pf_cnt = 0; src_pf_cnt < MMSFB_PF_CNT; src_pf_cnt++) {
00138 for (unsigned int flags_cnt = 0; flags_cnt < MMSFBPERF_MAXFLAGS; flags_cnt++) {
00139
00140 MMSFBPERF_MEASURING_VALS *mv = &(*mlist)[buftype][pf_cnt][src_pf_cnt][flags_cnt];
00141 if (!mv->usecs) {
00142
00143 continue;
00144 }
00145
00146 if (summary) {
00147
00148 addMeasuringVals(summary, mv);
00149 }
00150
00151
00152 char buf[256];
00153 int cnt;
00154 memset(buf, ' ', sizeof(buf));
00155
00156 cnt = sprintf(&buf[0], "%s", prefix);
00157 buf[0 + cnt] = ' ';
00158
00159 cnt = sprintf(&buf[14], "%c", (buftype)?'X':'O');
00160 buf[14 + cnt] = ' ';
00161
00162 cnt = sprintf(&buf[16], "%s", getMMSFBPixelFormatString((MMSFBSurfacePixelFormat)pf_cnt).c_str());
00163 buf[16 + cnt] = ' ';
00164
00165 cnt = sprintf(&buf[25], "%s", getMMSFBPixelFormatString((MMSFBSurfacePixelFormat)src_pf_cnt).c_str());
00166 buf[25 + cnt] = ' ';
00167
00168 cnt = sprintf(&buf[34], "%05x", flags_cnt);
00169 buf[34 + cnt] = ' ';
00170
00171 cnt = sprintf(&buf[40], "%d", mv->calls);
00172 buf[40 + cnt] = ' ';
00173
00174 cnt = sprintf(&buf[47], "%d.%03d", mv->mpixels, mv->rpixels / 1000);
00175 buf[47 + cnt] = ' ';
00176
00177 cnt = sprintf(&buf[57], "%d", mv->usecs);
00178 buf[57 + cnt] = ' ';
00179
00180 cnt = sprintf(&buf[69], "%d", mv->mpps);
00181 cnt+=69;
00182
00183
00184 if (retbuf + cnt + 1 <= retbuf_end) {
00185 memcpy(retbuf, buf, cnt);
00186 retbuf+=cnt;
00187 *retbuf = '\n';
00188 retbuf++;
00189 *retbuf = 0;
00190 }
00191 else {
00192
00193 return -1;
00194 }
00195 }
00196 }
00197 }
00198 }
00199
00200 return (int)(retbuf - retbuf_start);
00201 }
00202
00203 int MMSPerf::getPerfVals(MMSFBPERF_MEASURING_LIST_VKEY *mlist, char *retbuf, int retbuf_size,
00204 MMSFBPERF_MEASURING_VALS_VKEY *summary) {
00205
00206 #if 0
00207 char *retbuf_start=retbuf;
00208 char *retbuf_end = retbuf + retbuf_size;
00209
00210 for (unsigned int vk = 0; vk < MMSFBPERF_MAXVKEYS; vk++) {
00211
00212 MMSFBPERF_MEASURING_VALS_VKEY *mv = &(*mlist)[vk];
00213 if (!mv->usecs) {
00214
00215 continue;
00216 }
00217
00218 if (summary) {
00219
00220 addMeasuringVals(summary, mv);
00221 }
00222
00223
00224 char buf[256];
00225 int cnt;
00226 memset(buf, ' ', sizeof(buf));
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256 if (retbuf + cnt + 1 <= retbuf_end) {
00257 memcpy(retbuf, buf, cnt);
00258 retbuf+=cnt;
00259 *retbuf = '\n';
00260 retbuf++;
00261 *retbuf = 0;
00262 }
00263 else {
00264
00265 return -1;
00266 }
00267 }
00268
00269 return (int)(retbuf - retbuf_start);
00270 #else
00271 return 0;
00272 #endif
00273 }
00274
00275 void MMSPerf::stopMeasuring(struct timeval *perf_stime, MMSFBPERF_MEASURING_VALS *mvals,
00276 int sw, int sh, int dw, int dh) {
00277
00278 struct timeval perf_etime;
00279 gettimeofday(&perf_etime, NULL);
00280
00281 lock();
00282
00283
00284 mvals->calls++;
00285
00286
00287 if (dw <= 0 || dh <= 0)
00288 mvals->rpixels+= sw * sh;
00289 else
00290 mvals->rpixels+= ((sw + dw) / 2) * ((sh + dh) / 2);
00291 if (mvals->rpixels > 1000000) {
00292 mvals->mpixels+= mvals->rpixels / 1000000;
00293 mvals->rpixels%= 1000000;
00294 }
00295
00296
00297 mvals->usecs+= (perf_etime.tv_sec - perf_stime->tv_sec) * 1000000;
00298 if (perf_etime.tv_usec >= perf_stime->tv_usec)
00299 mvals->usecs+= perf_etime.tv_usec - perf_stime->tv_usec;
00300 else
00301 mvals->usecs-= perf_stime->tv_usec - perf_etime.tv_usec;
00302 if (mvals->usecs == 0) mvals->usecs = 1;
00303
00304
00305 mvals->mpps= (mvals->mpixels * 1000000 + mvals->rpixels) / mvals->usecs;
00306
00307 unlock();
00308 }
00309
00310 void MMSPerf::stopMeasuring(struct timeval *perf_stime, MMSFBPERF_MEASURING_VALS_VKEY *mvals) {
00311
00312 struct timeval perf_etime;
00313 gettimeofday(&perf_etime, NULL);
00314
00315 lock();
00316
00317
00318 mvals->calls++;
00319
00320
00321 mvals->usecs+= (perf_etime.tv_sec - perf_stime->tv_sec) * 1000000;
00322 if (perf_etime.tv_usec >= perf_stime->tv_usec)
00323 mvals->usecs+= perf_etime.tv_usec - perf_stime->tv_usec;
00324 else
00325 mvals->usecs-= perf_stime->tv_usec - perf_etime.tv_usec;
00326 if (mvals->usecs == 0) mvals->usecs = 1;
00327
00328 unlock();
00329 }
00330
00331 void MMSPerf::startMeasuring(struct timeval *perf_stime) {
00332
00333 gettimeofday(perf_stime, NULL);
00334 }
00335
00336 void MMSPerf::stopMeasuringFillRectangle(struct timeval *perf_stime,
00337 MMSFBSurface *surface, int w, int h) {
00338
00339
00340 MMSFBSurfacePixelFormat pixelformat = surface->config.surface_buffer->pixelformat;
00341 MMSFBDrawingFlags drawingflags = surface->config.drawingflags;
00342 unsigned int buftype = (!surface->config.surface_buffer->buffers[0].hwbuffer && !surface->config.surface_buffer->external_buffer)?0:1;
00343 if ((pixelformat < MMSFB_PF_CNT) && (drawingflags < MMSFBPERF_MAXFLAGS))
00344 stopMeasuring(perf_stime, &this->fillrect[buftype][pixelformat][MMSFB_PF_NONE][drawingflags], w, h);
00345 }
00346
00347 void MMSPerf::stopMeasuringDrawLine(struct timeval *perf_stime,
00348 MMSFBSurface *surface, int pixels) {
00349
00350
00351 MMSFBSurfacePixelFormat pixelformat = surface->config.surface_buffer->pixelformat;
00352 MMSFBDrawingFlags drawingflags = surface->config.drawingflags;
00353 unsigned int buftype = (!surface->config.surface_buffer->buffers[0].hwbuffer && !surface->config.surface_buffer->external_buffer)?0:1;
00354 if ((pixelformat < MMSFB_PF_CNT) && (drawingflags < MMSFBPERF_MAXFLAGS))
00355 stopMeasuring(perf_stime, &this->drawline[buftype][pixelformat][MMSFB_PF_NONE][drawingflags], pixels, 1);
00356 }
00357
00358 void MMSPerf::stopMeasuringDrawString(struct timeval *perf_stime,
00359 MMSFBSurface *surface, int w, int h) {
00360
00361
00362 MMSFBSurfacePixelFormat pixelformat = surface->config.surface_buffer->pixelformat;
00363 MMSFBDrawingFlags drawingflags = surface->config.drawingflags;
00364 unsigned int buftype = (!surface->config.surface_buffer->buffers[0].hwbuffer && !surface->config.surface_buffer->external_buffer)?0:1;
00365 if ((pixelformat < MMSFB_PF_CNT) && (drawingflags < MMSFBPERF_MAXFLAGS))
00366 stopMeasuring(perf_stime, &this->drawstring[buftype][pixelformat][MMSFB_PF_NONE][drawingflags], w, h);
00367 }
00368
00369 void MMSPerf::stopMeasuringBlit(struct timeval *perf_stime,
00370 MMSFBSurface *surface,
00371 MMSFBSurfacePixelFormat src_pixelformat,
00372 int sw, int sh) {
00373
00374
00375 MMSFBSurfacePixelFormat pixelformat = surface->config.surface_buffer->pixelformat;
00376 MMSFBBlittingFlags blittingflags = surface->config.blittingflags;
00377 unsigned int buftype = (!surface->config.surface_buffer->buffers[0].hwbuffer && !surface->config.surface_buffer->external_buffer)?0:1;
00378 if ((pixelformat < MMSFB_PF_CNT) && (src_pixelformat < MMSFB_PF_CNT) && (blittingflags < MMSFBPERF_MAXFLAGS))
00379 stopMeasuring(perf_stime, &this->blit[buftype][pixelformat][src_pixelformat][blittingflags], sw, sh);
00380 }
00381
00382 void MMSPerf::stopMeasuringStretchBlit(struct timeval *perf_stime,
00383 MMSFBSurface *surface,
00384 MMSFBSurfacePixelFormat src_pixelformat,
00385 int sw, int sh, int dw, int dh) {
00386
00387
00388 MMSFBSurfacePixelFormat pixelformat = surface->config.surface_buffer->pixelformat;
00389 MMSFBBlittingFlags blittingflags = surface->config.blittingflags;
00390 unsigned int buftype = (!surface->config.surface_buffer->buffers[0].hwbuffer && !surface->config.surface_buffer->external_buffer)?0:1;
00391 if ((pixelformat < MMSFB_PF_CNT) && (src_pixelformat < MMSFB_PF_CNT) && (blittingflags < MMSFBPERF_MAXFLAGS))
00392 stopMeasuring(perf_stime, &this->stretchblit[buftype][pixelformat][src_pixelformat][blittingflags], sw, sh, dw, dh);
00393 }
00394
00395 void MMSPerf::stopMeasuringXShmPutImage(struct timeval *perf_stime,
00396 MMSFBSurface *surface,
00397 int sw, int sh) {
00398
00399
00400 MMSFBSurfacePixelFormat pixelformat = surface->config.surface_buffer->pixelformat;
00401 unsigned int buftype = (!surface->config.surface_buffer->buffers[0].hwbuffer && !surface->config.surface_buffer->external_buffer)?0:1;
00402 if (pixelformat < MMSFB_PF_CNT)
00403 stopMeasuring(perf_stime, &this->xshmputimage[buftype][pixelformat][pixelformat][MMSFB_BLIT_NOFX], sw, sh);
00404 }
00405
00406 void MMSPerf::stopMeasuringXvShmPutImage(struct timeval *perf_stime,
00407 MMSFBSurface *surface,
00408 int sw, int sh, int dw, int dh) {
00409
00410
00411 MMSFBSurfacePixelFormat pixelformat = surface->config.surface_buffer->pixelformat;
00412 unsigned int buftype = (!surface->config.surface_buffer->buffers[0].hwbuffer && !surface->config.surface_buffer->external_buffer)?0:1;
00413 if (pixelformat < MMSFB_PF_CNT)
00414 stopMeasuring(perf_stime, &this->xvshmputimage[buftype][pixelformat][pixelformat][MMSFB_BLIT_NOFX], sw, sh, dw, dh);
00415 }
00416
00417 void MMSPerf::stopMeasuringVSync(struct timeval *perf_stime,
00418 MMSFBSurface *surface) {
00419
00420
00421 MMSFBSurfacePixelFormat pixelformat = surface->config.surface_buffer->pixelformat;
00422 unsigned int buftype = (!surface->config.surface_buffer->buffers[0].hwbuffer && !surface->config.surface_buffer->external_buffer)?0:1;
00423 if (pixelformat < MMSFB_PF_CNT)
00424 stopMeasuring(perf_stime, &this->vsync[buftype][pixelformat][MMSFB_PF_NONE][MMSFB_BLIT_NOFX]);
00425 }
00426
00427 void MMSPerf::stopMeasuringSwapDisplay(struct timeval *perf_stime,
00428 MMSFBSurface *surface) {
00429
00430
00431 MMSFBSurfacePixelFormat pixelformat = surface->config.surface_buffer->pixelformat;
00432 unsigned int buftype = (!surface->config.surface_buffer->buffers[0].hwbuffer && !surface->config.surface_buffer->external_buffer)?0:1;
00433 if (pixelformat < MMSFB_PF_CNT)
00434 stopMeasuring(perf_stime, &this->swapdisplay[buftype][pixelformat][MMSFB_PF_NONE][MMSFB_BLIT_NOFX]);
00435 }
00436