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 char *retbuf_start=retbuf;
00206 char *retbuf_end = retbuf + retbuf_size;
00207
00208 for (unsigned int vk = 0; vk < MMSFBPERF_MAXVKEYS; vk++) {
00209
00210 MMSFBPERF_MEASURING_VALS_VKEY *mv = &(*mlist)[vk];
00211 if (!mv->usecs) {
00212
00213 continue;
00214 }
00215
00216 if (summary) {
00217
00218 addMeasuringVals(summary, mv);
00219 }
00220
00221
00222 char buf[256];
00223 int cnt;
00224 memset(buf, ' ', sizeof(buf));
00225
00226
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 if (retbuf + cnt + 1 <= retbuf_end) {
00255 memcpy(retbuf, buf, cnt);
00256 retbuf+=cnt;
00257 *retbuf = '\n';
00258 retbuf++;
00259 *retbuf = 0;
00260 }
00261 else {
00262
00263 return -1;
00264 }
00265 }
00266
00267 return (int)(retbuf - retbuf_start);
00268 }
00269
00270 void MMSPerf::stopMeasuring(struct timeval *perf_stime, MMSFBPERF_MEASURING_VALS *mvals,
00271 int sw, int sh, int dw, int dh) {
00272
00273 struct timeval perf_etime;
00274 gettimeofday(&perf_etime, NULL);
00275
00276 lock();
00277
00278
00279 mvals->calls++;
00280
00281
00282 if (dw <= 0 || dh <= 0)
00283 mvals->rpixels+= sw * sh;
00284 else
00285 mvals->rpixels+= ((sw + dw) / 2) * ((sh + dh) / 2);
00286 if (mvals->rpixels > 1000000) {
00287 mvals->mpixels+= mvals->rpixels / 1000000;
00288 mvals->rpixels%= 1000000;
00289 }
00290
00291
00292 mvals->usecs+= (perf_etime.tv_sec - perf_stime->tv_sec) * 1000000;
00293 if (perf_etime.tv_usec >= perf_stime->tv_usec)
00294 mvals->usecs+= perf_etime.tv_usec - perf_stime->tv_usec;
00295 else
00296 mvals->usecs-= perf_stime->tv_usec - perf_etime.tv_usec;
00297 if (mvals->usecs == 0) mvals->usecs = 1;
00298
00299
00300 mvals->mpps= (mvals->mpixels * 1000000 + mvals->rpixels) / mvals->usecs;
00301
00302 unlock();
00303 }
00304
00305 void MMSPerf::stopMeasuring(struct timeval *perf_stime, MMSFBPERF_MEASURING_VALS_VKEY *mvals) {
00306
00307 struct timeval perf_etime;
00308 gettimeofday(&perf_etime, NULL);
00309
00310 lock();
00311
00312
00313 mvals->calls++;
00314
00315
00316 mvals->usecs+= (perf_etime.tv_sec - perf_stime->tv_sec) * 1000000;
00317 if (perf_etime.tv_usec >= perf_stime->tv_usec)
00318 mvals->usecs+= perf_etime.tv_usec - perf_stime->tv_usec;
00319 else
00320 mvals->usecs-= perf_stime->tv_usec - perf_etime.tv_usec;
00321 if (mvals->usecs == 0) mvals->usecs = 1;
00322
00323 unlock();
00324 }
00325
00326 void MMSPerf::startMeasuring(struct timeval *perf_stime) {
00327
00328 gettimeofday(perf_stime, NULL);
00329 }
00330
00331 void MMSPerf::stopMeasuringFillRectangle(struct timeval *perf_stime,
00332 MMSFBSurface *surface, int w, int h) {
00333
00334
00335 MMSFBSurfacePixelFormat pixelformat = surface->config.surface_buffer->pixelformat;
00336 MMSFBDrawingFlags drawingflags = surface->config.drawingflags;
00337 unsigned int buftype = (!surface->config.surface_buffer->buffers[0].hwbuffer && !surface->config.surface_buffer->external_buffer)?0:1;
00338 if ((pixelformat < MMSFB_PF_CNT) && (drawingflags < MMSFBPERF_MAXFLAGS))
00339 stopMeasuring(perf_stime, &this->fillrect[buftype][pixelformat][MMSFB_PF_NONE][drawingflags], w, h);
00340 }
00341
00342 void MMSPerf::stopMeasuringDrawLine(struct timeval *perf_stime,
00343 MMSFBSurface *surface, int pixels) {
00344
00345
00346 MMSFBSurfacePixelFormat pixelformat = surface->config.surface_buffer->pixelformat;
00347 MMSFBDrawingFlags drawingflags = surface->config.drawingflags;
00348 unsigned int buftype = (!surface->config.surface_buffer->buffers[0].hwbuffer && !surface->config.surface_buffer->external_buffer)?0:1;
00349 if ((pixelformat < MMSFB_PF_CNT) && (drawingflags < MMSFBPERF_MAXFLAGS))
00350 stopMeasuring(perf_stime, &this->drawline[buftype][pixelformat][MMSFB_PF_NONE][drawingflags], pixels, 1);
00351 }
00352
00353 void MMSPerf::stopMeasuringDrawString(struct timeval *perf_stime,
00354 MMSFBSurface *surface, int w, int h) {
00355
00356
00357 MMSFBSurfacePixelFormat pixelformat = surface->config.surface_buffer->pixelformat;
00358 MMSFBDrawingFlags drawingflags = surface->config.drawingflags;
00359 unsigned int buftype = (!surface->config.surface_buffer->buffers[0].hwbuffer && !surface->config.surface_buffer->external_buffer)?0:1;
00360 if ((pixelformat < MMSFB_PF_CNT) && (drawingflags < MMSFBPERF_MAXFLAGS))
00361 stopMeasuring(perf_stime, &this->drawstring[buftype][pixelformat][MMSFB_PF_NONE][drawingflags], w, h);
00362 }
00363
00364 void MMSPerf::stopMeasuringBlit(struct timeval *perf_stime,
00365 MMSFBSurface *surface,
00366 MMSFBSurfacePixelFormat src_pixelformat,
00367 int sw, int sh) {
00368
00369
00370 MMSFBSurfacePixelFormat pixelformat = surface->config.surface_buffer->pixelformat;
00371 MMSFBBlittingFlags blittingflags = surface->config.blittingflags;
00372 unsigned int buftype = (!surface->config.surface_buffer->buffers[0].hwbuffer && !surface->config.surface_buffer->external_buffer)?0:1;
00373 if ((pixelformat < MMSFB_PF_CNT) && (src_pixelformat < MMSFB_PF_CNT) && (blittingflags < MMSFBPERF_MAXFLAGS))
00374 stopMeasuring(perf_stime, &this->blit[buftype][pixelformat][src_pixelformat][blittingflags], sw, sh);
00375 }
00376
00377 void MMSPerf::stopMeasuringStretchBlit(struct timeval *perf_stime,
00378 MMSFBSurface *surface,
00379 MMSFBSurfacePixelFormat src_pixelformat,
00380 int sw, int sh, int dw, int dh) {
00381
00382
00383 MMSFBSurfacePixelFormat pixelformat = surface->config.surface_buffer->pixelformat;
00384 MMSFBBlittingFlags blittingflags = surface->config.blittingflags;
00385 unsigned int buftype = (!surface->config.surface_buffer->buffers[0].hwbuffer && !surface->config.surface_buffer->external_buffer)?0:1;
00386 if ((pixelformat < MMSFB_PF_CNT) && (src_pixelformat < MMSFB_PF_CNT) && (blittingflags < MMSFBPERF_MAXFLAGS))
00387 stopMeasuring(perf_stime, &this->stretchblit[buftype][pixelformat][src_pixelformat][blittingflags], sw, sh, dw, dh);
00388 }
00389
00390 void MMSPerf::stopMeasuringXShmPutImage(struct timeval *perf_stime,
00391 MMSFBSurface *surface,
00392 int sw, int sh) {
00393
00394
00395 MMSFBSurfacePixelFormat pixelformat = surface->config.surface_buffer->pixelformat;
00396 unsigned int buftype = (!surface->config.surface_buffer->buffers[0].hwbuffer && !surface->config.surface_buffer->external_buffer)?0:1;
00397 if (pixelformat < MMSFB_PF_CNT)
00398 stopMeasuring(perf_stime, &this->xshmputimage[buftype][pixelformat][pixelformat][MMSFB_BLIT_NOFX], sw, sh);
00399 }
00400
00401 void MMSPerf::stopMeasuringXvShmPutImage(struct timeval *perf_stime,
00402 MMSFBSurface *surface,
00403 int sw, int sh, int dw, int dh) {
00404
00405
00406 MMSFBSurfacePixelFormat pixelformat = surface->config.surface_buffer->pixelformat;
00407 unsigned int buftype = (!surface->config.surface_buffer->buffers[0].hwbuffer && !surface->config.surface_buffer->external_buffer)?0:1;
00408 if (pixelformat < MMSFB_PF_CNT)
00409 stopMeasuring(perf_stime, &this->xvshmputimage[buftype][pixelformat][pixelformat][MMSFB_BLIT_NOFX], sw, sh, dw, dh);
00410 }
00411
00412 void MMSPerf::stopMeasuringVSync(struct timeval *perf_stime,
00413 MMSFBSurface *surface) {
00414
00415
00416 MMSFBSurfacePixelFormat pixelformat = surface->config.surface_buffer->pixelformat;
00417 unsigned int buftype = (!surface->config.surface_buffer->buffers[0].hwbuffer && !surface->config.surface_buffer->external_buffer)?0:1;
00418 if (pixelformat < MMSFB_PF_CNT)
00419 stopMeasuring(perf_stime, &this->vsync[buftype][pixelformat][MMSFB_PF_NONE][MMSFB_BLIT_NOFX]);
00420 }
00421
00422 void MMSPerf::stopMeasuringSwapDisplay(struct timeval *perf_stime,
00423 MMSFBSurface *surface) {
00424
00425
00426 MMSFBSurfacePixelFormat pixelformat = surface->config.surface_buffer->pixelformat;
00427 unsigned int buftype = (!surface->config.surface_buffer->buffers[0].hwbuffer && !surface->config.surface_buffer->external_buffer)?0:1;
00428 if (pixelformat < MMSFB_PF_CNT)
00429 stopMeasuring(perf_stime, &this->swapdisplay[buftype][pixelformat][MMSFB_PF_NONE][MMSFB_BLIT_NOFX]);
00430 }
00431