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-2013 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 /* MAH: this doesn't work at all for now */
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         // get access to the infos and check if used
00212         MMSFBPERF_MEASURING_VALS_VKEY *mv = &(*mlist)[vk];
00213         if (!mv->usecs) {
00214             // unused combination
00215             continue;
00216         }
00217 
00218         if (summary) {
00219             // add current measuring values to summary
00220             addMeasuringVals(summary, mv);
00221         }
00222 
00223         // fill the info line
00224         char buf[256];
00225         int cnt;
00226         memset(buf, ' ', sizeof(buf));
00227 /*
00228         cnt = sprintf(&buf[0],   "%s", prefix);
00229         buf[0 + cnt]   = ' ';
00230 
00231         cnt = sprintf(&buf[14],  "%c", (buftype)?'X':'O');
00232         buf[14 + cnt]   = ' ';
00233 
00234         cnt = sprintf(&buf[16],  "%s", getMMSFBPixelFormatString((MMSFBSurfacePixelFormat)pf_cnt).c_str());
00235         buf[16 + cnt]   = ' ';
00236 
00237         cnt = sprintf(&buf[25],  "%s", getMMSFBPixelFormatString((MMSFBSurfacePixelFormat)src_pf_cnt).c_str());
00238         buf[25 + cnt]   = ' ';
00239 
00240         cnt = sprintf(&buf[34],  "%05x", flags_cnt);
00241         buf[34 + cnt]   = ' ';
00242 
00243         cnt = sprintf(&buf[40],  "%d", mv->calls);
00244         buf[40 + cnt]   = ' ';
00245 
00246         cnt = sprintf(&buf[47],  "%d.%03d", mv->mpixels, mv->rpixels / 1000);
00247         buf[47 + cnt]  = ' ';
00248 
00249         cnt = sprintf(&buf[57],  "%d", mv->usecs);
00250         buf[57 + cnt]  = ' ';
00251 
00252         cnt = sprintf(&buf[69],  "%d", mv->mpps);
00253         cnt+=69;
00254 */
00255         // print it to retbuf
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             // retbuf is full
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     // get stop time
00278     struct timeval perf_etime;
00279     gettimeofday(&perf_etime, NULL);
00280 
00281     lock();
00282 
00283     // count calls
00284     mvals->calls++;
00285 
00286     // calculate pixels
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     // calculate time
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     // calculate mpps (mega pixel per second)
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     // get stop time
00312     struct timeval perf_etime;
00313     gettimeofday(&perf_etime, NULL);
00314 
00315     lock();
00316 
00317     // count calls
00318     mvals->calls++;
00319 
00320     // calculate time
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     // get start time
00333     gettimeofday(perf_stime, NULL);
00334 }
00335 
00336 void MMSPerf::stopMeasuringFillRectangle(struct timeval *perf_stime,
00337                                            MMSFBSurface *surface, int w, int h) {
00338 
00339     // stop measuring for specified pixelformat and flags
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     // stop measuring for specified pixelformat and flags
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     // stop measuring for specified pixelformat and flags
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     // stop measuring for specified pixelformat and flags
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     // stop measuring for specified pixelformat and flags
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     // stop measuring for specified pixelformat and flags
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     // stop measuring for specified pixelformat and flags
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     // stop measuring for specified pixelformat and flags
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     // stop measuring for specified pixelformat and flags
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 

Generated by doxygen