Logo
  • Main Page
  • Related Pages
  • Modules
  • Classes
  • Files

mmsperf.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2005-2007 Stefan Schwarzer, Jens Schneider,             *
00003  *                           Matthias Hardt, Guido Madaus                  *
00004  *                                                                         *
00005  *   Copyright (C) 2007-2008 BerLinux Solutions GbR                        *
00006  *                           Stefan Schwarzer & Guido Madaus               *
00007  *                                                                         *
00008  *   Copyright (C) 2009-2012 BerLinux Solutions GmbH                       *
00009  *                                                                         *
00010  *   Authors:                                                              *
00011  *      Stefan Schwarzer   <stefan.schwarzer@diskohq.org>,                 *
00012  *      Matthias Hardt     <matthias.hardt@diskohq.org>,                   *
00013  *      Jens Schneider     <jens.schneider@diskohq.org>,                   *
00014  *      Guido Madaus       <guido.madaus@diskohq.org>,                     *
00015  *      Patrick Helterhoff <patrick.helterhoff@diskohq.org>,               *
00016  *      René Bählkow       <rene.baehlkow@diskohq.org>                     *
00017  *                                                                         *
00018  *   This library is free software; you can redistribute it and/or         *
00019  *   modify it under the terms of the GNU Lesser General Public            *
00020  *   License version 2.1 as published by the Free Software Foundation.     *
00021  *                                                                         *
00022  *   This library is distributed in the hope that it will be useful,       *
00023  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00024  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00025  *   Lesser General Public License for more details.                       *
00026  *                                                                         *
00027  *   You should have received a copy of the GNU Lesser General Public      *
00028  *   License along with this library; if not, write to the                 *
00029  *   Free Software Foundation, Inc.,                                       *
00030  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
00031  **************************************************************************/
00032 
00033 #include "mmscore/mmsperf.h"
00034 #include <stdio.h>
00035 #include <sys/time.h>
00036 
00037 
00038 // static variables
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         // first initialization
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     // reset statistic infos
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     // add sum
00106     summary->calls+= add_sum->calls;
00107     summary->usecs+= add_sum->usecs;
00108 
00109     if (add_sum->mpixels > 0 && add_sum->rpixels > 0) {
00110         // re-calculate m/r pixels
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         // re-calculate mpps
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     // add sum
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                     // get access to the infos and check if used
00140                     MMSFBPERF_MEASURING_VALS *mv = &(*mlist)[buftype][pf_cnt][src_pf_cnt][flags_cnt];
00141                     if (!mv->usecs) {
00142                         // unused combination
00143                         continue;
00144                     }
00145 
00146                     if (summary) {
00147                         // add current measuring values to summary
00148                         addMeasuringVals(summary, mv);
00149                     }
00150 
00151                     // fill the info line
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                     // print it to retbuf
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                         // retbuf is full
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         // get access to the infos and check if used
00210         MMSFBPERF_MEASURING_VALS_VKEY *mv = &(*mlist)[vk];
00211         if (!mv->usecs) {
00212             // unused combination
00213             continue;
00214         }
00215 
00216         if (summary) {
00217             // add current measuring values to summary
00218             addMeasuringVals(summary, mv);
00219         }
00220 
00221         // fill the info line
00222         char buf[256];
00223         int cnt;
00224         memset(buf, ' ', sizeof(buf));
00225 /*
00226         cnt = sprintf(&buf[0],   "%s", prefix);
00227         buf[0 + cnt]   = ' ';
00228 
00229         cnt = sprintf(&buf[14],  "%c", (buftype)?'X':'O');
00230         buf[14 + cnt]   = ' ';
00231 
00232         cnt = sprintf(&buf[16],  "%s", getMMSFBPixelFormatString((MMSFBSurfacePixelFormat)pf_cnt).c_str());
00233         buf[16 + cnt]   = ' ';
00234 
00235         cnt = sprintf(&buf[25],  "%s", getMMSFBPixelFormatString((MMSFBSurfacePixelFormat)src_pf_cnt).c_str());
00236         buf[25 + cnt]   = ' ';
00237 
00238         cnt = sprintf(&buf[34],  "%05x", flags_cnt);
00239         buf[34 + cnt]   = ' ';
00240 
00241         cnt = sprintf(&buf[40],  "%d", mv->calls);
00242         buf[40 + cnt]   = ' ';
00243 
00244         cnt = sprintf(&buf[47],  "%d.%03d", mv->mpixels, mv->rpixels / 1000);
00245         buf[47 + cnt]  = ' ';
00246 
00247         cnt = sprintf(&buf[57],  "%d", mv->usecs);
00248         buf[57 + cnt]  = ' ';
00249 
00250         cnt = sprintf(&buf[69],  "%d", mv->mpps);
00251         cnt+=69;
00252 */
00253         // print it to retbuf
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             // retbuf is full
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     // get stop time
00273     struct timeval perf_etime;
00274     gettimeofday(&perf_etime, NULL);
00275 
00276     lock();
00277 
00278     // count calls
00279     mvals->calls++;
00280 
00281     // calculate pixels
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     // calculate time
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     // calculate mpps (mega pixel per second)
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     // get stop time
00307     struct timeval perf_etime;
00308     gettimeofday(&perf_etime, NULL);
00309 
00310     lock();
00311 
00312     // count calls
00313     mvals->calls++;
00314 
00315     // calculate time
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     // get start time
00328     gettimeofday(perf_stime, NULL);
00329 }
00330 
00331 void MMSPerf::stopMeasuringFillRectangle(struct timeval *perf_stime,
00332                                            MMSFBSurface *surface, int w, int h) {
00333 
00334     // stop measuring for specified pixelformat and flags
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     // stop measuring for specified pixelformat and flags
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     // stop measuring for specified pixelformat and flags
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     // stop measuring for specified pixelformat and flags
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     // stop measuring for specified pixelformat and flags
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     // stop measuring for specified pixelformat and flags
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     // stop measuring for specified pixelformat and flags
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     // stop measuring for specified pixelformat and flags
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     // stop measuring for specified pixelformat and flags
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 

Generated by doxygen