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

mmsfbsurface.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 "mmsgui/fb/mmsfbsurface.h"
00034 #include "mmsgui/fb/mmsfb.h"
00035 #include "mmsgui/fb/mmsfbsurfacemanager.h"
00036 
00037 //#define DEBUG_LOCK_OUTPUT
00038 #ifdef DEBUG_LOCK_OUTPUT
00039 #include <sys/syscall.h>
00040 #endif
00041 
00042 #ifdef __ENABLE_ACTMON__
00043 #include "mmscore/mmsperf.h"
00044 #endif
00045 
00046 #include <math.h>
00047 #include <string.h>
00048 #include <stdlib.h>
00049 
00050 #ifdef __HAVE_XLIB__
00051 #include <ft2build.h>
00052 #include FT_GLYPH_H
00053 #endif
00054 
00055 
00056 #ifdef  __HAVE_DIRECTFB__
00057 D_DEBUG_DOMAIN( MMS_Surface, "MMS/Surface", "MMS FB Surface" );
00058 #endif
00059 
00060 // static variables
00061 bool MMSFBSurface::extendedaccel                                = false;
00062 MMSFBSurfaceAllocMethod MMSFBSurface::allocmethod               = MMSFBSurfaceAllocMethod_malloc;
00063 
00064 #define INITCHECK  if((!mmsfb->isInitialized())||(!this->initialized)){MMSFB_SetError(0,"MMSFBSurface is not initialized");return false;}
00065 
00066 #define CLIPSUBSURFACE \
00067     MMSFBRegion reg, tmp; \
00068     bool tmpset; \
00069     if (clipSubSurface(&reg, false, &tmp, &tmpset)) {
00070 
00071 #define UNCLIPSUBSURFACE \
00072     clipSubSurface(NULL, false, &tmp, &tmpset); }
00073 
00074 #define SETSUBSURFACE_DRAWINGFLAGS \
00075     MMSFBColor ccc = this->config.color; \
00076     this->dfb_surface->SetColor(this->dfb_surface, ccc.r, ccc.g, ccc.b, ccc.a); \
00077     this->dfb_surface->SetDrawingFlags(this->dfb_surface, getDFBSurfaceDrawingFlagsFromMMSFBDrawingFlags(this->config.drawingflags));
00078 
00079 #define RESETSUBSURFACE_DRAWINGFLAGS \
00080     ccc = this->root_parent->config.color; \
00081     this->dfb_surface->SetColor(this->dfb_surface, ccc.r, ccc.g, ccc.b, ccc.a); \
00082     this->dfb_surface->SetDrawingFlags(this->dfb_surface, getDFBSurfaceDrawingFlagsFromMMSFBDrawingFlags(this->root_parent->config.drawingflags));
00083 
00084 #define SETSUBSURFACE_BLITTINGFLAGS \
00085     MMSFBColor ccc = this->config.color; \
00086     this->dfb_surface->SetColor(this->dfb_surface, ccc.r, ccc.g, ccc.b, ccc.a); \
00087     this->dfb_surface->SetBlittingFlags(this->dfb_surface, getDFBSurfaceBlittingFlagsFromMMSFBBlittingFlags(this->config.blittingflags));
00088 
00089 #define RESETSUBSURFACE_BLITTINGFLAGS \
00090     ccc = this->root_parent->config.color; \
00091     this->dfb_surface->SetColor(this->dfb_surface, ccc.r, ccc.g, ccc.b, ccc.a); \
00092     this->dfb_surface->SetBlittingFlags(this->dfb_surface, getDFBSurfaceBlittingFlagsFromMMSFBBlittingFlags(this->root_parent->config.blittingflags));
00093 
00094 
00095 
00096 MMSFBSurface::MMSFBSurface(int w, int h, MMSFBSurfacePixelFormat pixelformat, int backbuffer, bool systemonly) {
00097     // init me
00098     this->initialized = false;
00099 #ifdef  __HAVE_DIRECTFB__
00100     this->dfb_surface = NULL;
00101 #endif
00102     this->surface_read_locked = false;
00103     this->surface_read_lock_cnt = 0;
00104     this->surface_write_locked = false;
00105     this->surface_write_lock_cnt = 0;
00106     this->surface_invert_lock = false;
00107 #ifdef __HAVE_XLIB__
00108     this->scaler = NULL;
00109 #endif
00110 
00111     // create the surfacebuffer where additional infos are stored
00112     createSurfaceBuffer();
00113 
00114     if (this->allocmethod == MMSFBSurfaceAllocMethod_dfb) {
00115 #ifdef  __HAVE_DIRECTFB__
00116         // create surface description
00117         DFBSurfaceDescription   surface_desc;
00118         surface_desc.flags = (DFBSurfaceDescriptionFlags)(DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT);
00119         surface_desc.width = w;
00120         surface_desc.height = h;
00121         surface_desc.pixelformat = getDFBPixelFormatFromMMSFBPixelFormat(pixelformat);
00122 
00123         if (surface_desc.pixelformat==DSPF_UNKNOWN)
00124             surface_desc.flags = (DFBSurfaceDescriptionFlags)(surface_desc.flags & ~DSDESC_PIXELFORMAT);
00125 
00126         // we use premultiplied surfaces because of alphachannel blitting with better performance
00127         surface_desc.flags = (DFBSurfaceDescriptionFlags)(surface_desc.flags | DSDESC_CAPS);
00128         surface_desc.caps = DSCAPS_PREMULTIPLIED;
00129 
00130         switch (backbuffer) {
00131             case 1: // front + one back buffer (double)
00132                 surface_desc.caps = (DFBSurfaceCapabilities)(surface_desc.caps | DSCAPS_DOUBLE);
00133                 break;
00134             case 2: // front + two back buffer (triple)
00135                 surface_desc.caps = (DFBSurfaceCapabilities)(surface_desc.caps | DSCAPS_TRIPLE);
00136                 break;
00137         }
00138 
00139         // surface should stored in system memory only?
00140         if (systemonly)
00141             surface_desc.caps = (DFBSurfaceCapabilities)(surface_desc.caps | DSCAPS_SYSTEMONLY);
00142 
00143         // create the surface
00144         DFBResult dfbres;
00145         if ((dfbres=mmsfb->dfb->CreateSurface(mmsfb->dfb, &surface_desc, &this->dfb_surface)) != DFB_OK) {
00146             this->dfb_surface = NULL;
00147             DEBUGMSG("MMSGUI", "ERROR");
00148             MMSFB_SetError(dfbres, "IDirectFB::CreateSurface(" + iToStr(w) + "x" + iToStr(h) + ") failed");
00149             return;
00150         }
00151 
00152         init(MMSFBSurfaceAllocatedBy_dfb, NULL, NULL);
00153 #endif
00154     }
00155     else
00156     if (this->allocmethod == MMSFBSurfaceAllocMethod_ogl) {
00157 #ifdef  __HAVE_OPENGL__
00158         // setup surface attributes
00159         // if we allocate an fbo, backbuffers are not supported
00160         MMSFBSurfaceBuffer *sb = this->config.surface_buffer;
00161         this->config.w = sb->sbw = w;
00162         this->config.h = sb->sbh = h;
00163         sb->pixelformat = MMSFB_PF_ABGR;
00164         sb->alphachannel = true;
00165         sb->premultiplied = false;
00166         sb->backbuffer = 0;
00167         sb->numbuffers = 1;
00168         sb->systemonly = false;
00169 
00170         // setup plane buffer
00171         sb->currbuffer_read = 0;
00172         sb->currbuffer_write = 0;
00173         sb->buffers[0].hwbuffer = true;
00174         sb->buffers[0].opaque = false;
00175         sb->buffers[0].transparent = false;
00176 
00177         mmsfb->bei->alloc(this);
00178 
00179         init(MMSFBSurfaceAllocatedBy_ogl, NULL, NULL);
00180 #endif
00181     }
00182     else {
00183         // setup surface attributes
00184         MMSFBSurfaceBuffer *sb = this->config.surface_buffer;
00185         this->config.w = sb->sbw = w;
00186         this->config.h = sb->sbh = h;
00187         sb->pixelformat = pixelformat;
00188         sb->alphachannel = isAlphaPixelFormat(sb->pixelformat);
00189         sb->premultiplied = true;
00190         sb->backbuffer = backbuffer;
00191         sb->systemonly = systemonly;
00192 
00193         // allocate my surface buffers
00194         sb->numbuffers = backbuffer + 1;
00195         if (sb->numbuffers > MMSFBSurfaceMaxBuffers) {
00196             sb->numbuffers = MMSFBSurfaceMaxBuffers;
00197             sb->backbuffer = sb->numbuffers - 1;
00198         }
00199         sb->currbuffer_read = 0;
00200         if (sb->numbuffers > 1)
00201             // using backbuffer(s)
00202             sb->currbuffer_write = 1;
00203         else
00204             // using only a single buffer for read/write
00205             sb->currbuffer_write = 0;
00206         DEBUGMSG("MMSGUI", "start allocating surface buffer");
00207         memset(sb->buffers, 0, sizeof(sb->buffers));
00208         for (int i = 0; i < sb->numbuffers; i++) {
00209             sb->buffers[i].pitch = calcPitch(w);
00210             int size = calcSize(sb->buffers[i].pitch, sb->sbh);
00211             DEBUGMSG("MMSGUI", ">allocating surface buffer #%d, %d bytes (pitch=%d, h=%d)", i, size, sb->buffers[i].pitch, sb->sbh);
00212             sb->buffers[i].ptr = malloc(size);
00213             sb->buffers[i].hwbuffer = false;
00214 
00215             // few internally pixelformats supports planes and therefore we must init the pointers
00216             initPlanePointers(&sb->buffers[i], sb->sbh);
00217         }
00218         DEBUGMSG("MMSGUI", "allocating surface buffer finished");
00219 
00220         init(MMSFBSurfaceAllocatedBy_malloc, NULL, NULL);
00221     }
00222 }
00223 
00224 
00225 #ifdef  __HAVE_DIRECTFB__
00226 
00227 MMSFBSurface::MMSFBSurface(IDirectFBSurface *dfb_surface, MMSFBSurface *parent,
00228                            MMSFBRectangle *sub_surface_rect) {
00229     // init me
00230     this->initialized = false;
00231 #ifdef  __HAVE_DIRECTFB__
00232     this->dfb_surface = dfb_surface;
00233 #endif
00234 #ifdef __HAVE_XLIB__
00235     this->scaler = NULL;
00236 #endif
00237 
00238     // create the surfacebuffer where additional infos are stored
00239     createSurfaceBuffer();
00240 
00241     init(MMSFBSurfaceAllocatedBy_dfb, parent, sub_surface_rect);
00242 }
00243 
00244 #endif
00245 
00246 
00247 MMSFBSurface::MMSFBSurface(MMSFBSurface *parent, MMSFBRectangle *sub_surface_rect) {
00248     // init me
00249     this->initialized = false;
00250 #ifdef  __HAVE_DIRECTFB__
00251     this->dfb_surface = NULL;
00252 #endif
00253 #ifdef __HAVE_XLIB__
00254     this->scaler = NULL;
00255 #endif
00256 
00257     if ((!parent)||(this->allocmethod == MMSFBSurfaceAllocMethod_dfb)) {
00258         // create the surfacebuffer where additional infos are stored
00259         createSurfaceBuffer();
00260     }
00261     else {
00262         // != DFB and parent set
00263         this->config.surface_buffer = NULL;
00264     }
00265 
00266     this->layer = NULL;
00267 
00268     init(parent->allocated_by, parent, sub_surface_rect);
00269 }
00270 
00271 
00272 
00273 MMSFBSurface::MMSFBSurface(int w, int h, MMSFBSurfacePixelFormat pixelformat, int backbuffer, MMSFBSurfacePlanes *planes) {
00274     // init me
00275     this->initialized = false;
00276 #ifdef  __HAVE_DIRECTFB__
00277     this->dfb_surface = NULL;
00278 #endif
00279     this->surface_read_locked = false;
00280     this->surface_read_lock_cnt = 0;
00281     this->surface_write_locked = false;
00282     this->surface_write_lock_cnt = 0;
00283     this->surface_invert_lock = false;
00284 #ifdef __HAVE_XLIB__
00285     this->scaler = NULL;
00286 #endif
00287 
00288     // create the surfacebuffer where additional infos are stored
00289     createSurfaceBuffer();
00290 
00291     // setup surface attributes
00292     MMSFBSurfaceBuffer *sb = this->config.surface_buffer;
00293     this->config.w = sb->sbw = w;
00294     this->config.h = sb->sbh = h;
00295     sb->pixelformat = pixelformat;
00296     sb->alphachannel = isAlphaPixelFormat(sb->pixelformat);
00297     sb->premultiplied = true;
00298     sb->backbuffer = backbuffer;
00299     sb->systemonly = true;
00300 
00301     // set the surface buffer
00302     memset(sb->buffers, 0, sizeof(sb->buffers));
00303     sb->numbuffers = backbuffer+1;
00304     if (sb->numbuffers > MMSFBSurfaceMaxBuffers) sb->numbuffers = MMSFBSurfaceMaxBuffers;
00305     sb->buffers[0] = *planes;
00306     if (sb->numbuffers >= 2) {
00307         if (planes[1].ptr)
00308             sb->buffers[1] = planes[1];
00309         else
00310             sb->numbuffers = 1;
00311     }
00312     if (sb->numbuffers >= 3) {
00313         if (planes[2].ptr)
00314             sb->buffers[2] = planes[2];
00315         else
00316             sb->numbuffers = 2;
00317     }
00318     sb->backbuffer = sb->numbuffers - 1;
00319     sb->currbuffer_read = 0;
00320     if (sb->numbuffers <= 1)
00321         sb->currbuffer_write = 0;
00322     else
00323         sb->currbuffer_write = 1;
00324     sb->external_buffer = true;
00325 
00326     init(MMSFBSurfaceAllocatedBy_malloc, NULL, NULL);
00327 }
00328 
00329 MMSFBSurface::MMSFBSurface(int w, int h, MMSFBSurfacePixelFormat pixelformat, MMSFBSurfacePlanes *planes) {
00330     MMSFBSurface(w, h, pixelformat, 0, planes);
00331 }
00332 
00333 
00334 #ifdef __HAVE_XV__
00335 MMSFBSurface::MMSFBSurface(int w, int h, MMSFBSurfacePixelFormat pixelformat, XvImage *xv_image1, XvImage *xv_image2) {
00336     // init me
00337     this->initialized = false;
00338 #ifdef  __HAVE_DIRECTFB__
00339     this->dfb_surface = NULL;
00340 #endif
00341     this->surface_read_locked = false;
00342     this->surface_read_lock_cnt = 0;
00343     this->surface_write_locked = false;
00344     this->surface_write_lock_cnt = 0;
00345     this->surface_invert_lock = false;
00346     this->scaler = NULL;
00347 
00348     // create the surfacebuffer where additional infos are stored
00349     createSurfaceBuffer();
00350 
00351     // setup surface attributes
00352     MMSFBSurfaceBuffer *sb = this->config.surface_buffer;
00353     this->config.w = sb->sbw = w;
00354     this->config.h = sb->sbh = h;
00355     sb->pixelformat = pixelformat;
00356     sb->alphachannel = isAlphaPixelFormat(sb->pixelformat);
00357     sb->premultiplied = true;
00358     sb->backbuffer = 1;
00359     sb->systemonly = true;
00360 
00361     // set the surface buffer
00362     memset(sb->buffers, 0, sizeof(sb->buffers));
00363     sb->numbuffers = 2;
00364     sb->xv_image[0] = xv_image1;
00365     sb->buffers[0].ptr = sb->xv_image[0]->data;
00366     sb->buffers[0].pitch = *(sb->xv_image[0]->pitches);
00367     sb->buffers[0].hwbuffer = false;
00368     sb->xv_image[1] = xv_image2;
00369     sb->buffers[1].ptr = sb->xv_image[1]->data;
00370     sb->buffers[1].pitch = *(sb->xv_image[1]->pitches);
00371     sb->buffers[1].hwbuffer = false;
00372     sb->currbuffer_read = 0;
00373     sb->currbuffer_write = 1;
00374     sb->external_buffer = true;
00375 
00376     init(MMSFBSurfaceAllocatedBy_xvimage, NULL, NULL);
00377 }
00378 #endif
00379 
00380 #ifdef __HAVE_XLIB__
00381 MMSFBSurface::MMSFBSurface(int w, int h, MMSFBSurfacePixelFormat pixelformat, XImage *x_image1, XImage *x_image2, MMSFBSurface *scaler) {
00382     // init me
00383     this->initialized = false;
00384 #ifdef  __HAVE_DIRECTFB__
00385     this->dfb_surface = NULL;
00386 #endif
00387     this->surface_read_locked = false;
00388     this->surface_read_lock_cnt = 0;
00389     this->surface_write_locked = false;
00390     this->surface_write_lock_cnt = 0;
00391     this->surface_invert_lock = false;
00392     this->scaler = scaler;
00393 
00394     // create the surfacebuffer where additional infos are stored
00395     createSurfaceBuffer();
00396 
00397     // setup surface attributes
00398     MMSFBSurfaceBuffer *sb = this->config.surface_buffer;
00399     this->config.w = sb->sbw = w;
00400     this->config.h = sb->sbh = h;
00401     sb->pixelformat = pixelformat;
00402     sb->alphachannel = isAlphaPixelFormat(sb->pixelformat);
00403     sb->premultiplied = true;
00404     sb->backbuffer = 0;
00405     sb->systemonly = true;
00406 
00407     // set the surface buffer
00408     memset(sb->buffers, 0, sizeof(sb->buffers));
00409     if (x_image2) {
00410         // two ximages
00411         sb->backbuffer = 1;
00412         sb->numbuffers = 2;
00413         sb->x_image[0] = x_image1;
00414         sb->buffers[0].ptr = sb->x_image[0]->data;
00415         sb->buffers[0].pitch = sb->x_image[0]->bytes_per_line;
00416         sb->buffers[0].hwbuffer = false;
00417         sb->x_image[1] = x_image2;
00418         sb->buffers[1].ptr = sb->x_image[1]->data;
00419         sb->buffers[1].pitch = sb->x_image[1]->bytes_per_line;
00420         sb->buffers[1].hwbuffer = false;
00421         sb->currbuffer_read = 0;
00422         sb->currbuffer_write = 1;
00423         sb->external_buffer = true;
00424     }
00425     else {
00426         // only one buffer
00427         sb->backbuffer = 0;
00428         sb->numbuffers = 1;
00429         sb->x_image[0] = x_image1;
00430         sb->buffers[0].ptr = sb->x_image[0]->data;
00431         sb->buffers[0].pitch = sb->x_image[0]->bytes_per_line;
00432         sb->buffers[0].hwbuffer = false;
00433         sb->x_image[1] = NULL;
00434         sb->buffers[1].ptr = NULL;
00435         sb->buffers[1].hwbuffer = false;
00436         sb->currbuffer_read = 0;
00437         sb->currbuffer_write = 0;
00438         sb->external_buffer = true;
00439     }
00440 
00441     init(MMSFBSurfaceAllocatedBy_ximage, NULL, NULL);
00442 }
00443 #endif
00444 
00445 
00446 
00447 #ifdef __HAVE_OPENGL__
00448 MMSFBSurface::MMSFBSurface(int w, int h, MMSFBSurfaceAllocatedBy allocated_by) {
00449     // init me
00450     this->initialized = false;
00451 #ifdef  __HAVE_DIRECTFB__
00452     this->dfb_surface = NULL;
00453 #endif
00454 #ifdef __HAVE_XLIB__
00455     this->scaler = NULL;
00456 #endif
00457 
00458     // currently only for ogl
00459     if (allocated_by != MMSFBSurfaceAllocatedBy_ogl)
00460         return;
00461 
00462     // create the surfacebuffer where additional infos are stored
00463     createSurfaceBuffer();
00464 
00465     // setup surface attributes
00466     this->config.w = this->config.surface_buffer->sbw = w;
00467     this->config.h = this->config.surface_buffer->sbh = h;
00468 
00469     if (this->config.surface_buffer) {
00470         MMSFBSurfaceBuffer *sb = this->config.surface_buffer;
00471         memset(sb->buffers, 0, sizeof(sb->buffers));
00472         sb->numbuffers = 0;
00473         sb->external_buffer = false;
00474 
00475         // setup plane buffer
00476         sb->currbuffer_read = 0;
00477         sb->currbuffer_write = 0;
00478         sb->buffers[0].hwbuffer = true;
00479         sb->buffers[0].opaque = false;
00480         sb->buffers[0].transparent = false;
00481 
00482         // this surface is the primary opengl framebuffer
00483         sb->ogl_fbo = 0;
00484         sb->ogl_fbo_initialized = true;
00485     }
00486 
00487     init(MMSFBSurfaceAllocatedBy_ogl, NULL, NULL);
00488 }
00489 #endif
00490 
00491 
00492 
00493 MMSFBSurface::~MMSFBSurface() {
00494 
00495 #ifdef __ENABLE_ACTMON__
00496     if (this->mmsperf)
00497         delete this->mmsperf;
00498 #endif
00499 
00500     if (!mmsfb->isInitialized()) return;
00501 
00502     // release memory - only if not the layer surface
00503     if (this->initialized) {
00504         if (!this->is_sub_surface) {
00505 #ifndef USE_DFB_SUBSURFACE
00506             // delete all sub surfaces
00507             deleteSubSurface(NULL);
00508 #endif
00509             mmsfbsurfacemanager->releaseSurface(this);
00510         }
00511         else {
00512 #ifdef USE_DFB_SUBSURFACE
00513             if (this->dfb_surface) {
00514                 this->dfb_surface->Release(this->dfb_surface);
00515             }
00516 #endif
00517 
00518             if (this->parent)
00519                 this->parent->deleteSubSurface(this);
00520         }
00521     }
00522 }
00523 
00524 
00525 
00526 void MMSFBSurface::init(MMSFBSurfaceAllocatedBy allocated_by,
00527                         MMSFBSurface *parent,
00528                         MMSFBRectangle *sub_surface_rect) {
00529     // init me
00530 #ifdef __ENABLE_ACTMON__
00531     this->mmsperf = new MMSPerf();
00532 #endif
00533 
00534 #if defined(__HAVE_FBDEV__) || defined(__HAVE_KMS__)
00535     this->fbdev_ts = NULL;
00536 #endif
00537 
00538     this->allocated_by = allocated_by;
00539     this->initialized = true;
00540 
00541     this->surface_read_locked = false;
00542     this->surface_read_lock_cnt = 0;
00543     this->surface_write_locked = false;
00544     this->surface_write_lock_cnt = 0;
00545     this->surface_invert_lock = false;
00546     this->flipflags = MMSFB_FLIP_NONE;
00547     this->TID = 0;
00548     this->Lock_cnt = 0;
00549 
00550     this->clear_request.set = false;
00551 
00552     // init subsurface
00553     this->parent = parent;
00554     this->root_parent =  NULL;
00555     this->sub_surface_xoff = 0;
00556     this->sub_surface_yoff = 0;
00557     if (this->parent) {
00558         if (!this->parent->is_sub_surface)
00559             this->root_parent = this->parent;
00560         else
00561             this->root_parent = this->parent->root_parent;
00562 
00563         this->is_sub_surface = true;
00564 
00565         this->sub_surface_rect = *sub_surface_rect;
00566 
00567         this->config.surface_buffer = this->root_parent->config.surface_buffer;
00568 
00569         this->layer = parent->layer;
00570 
00571 #ifndef USE_DFB_SUBSURFACE
00572 
00573 #ifdef __HAVE_DIRECTFB__
00574         this->dfb_surface = this->root_parent->dfb_surface;
00575 #endif
00576 
00577         getRealSubSurfacePos();
00578 #endif
00579 
00580     }
00581     else {
00582         this->is_sub_surface = false;
00583         this->sub_surface_rect.x = 0;
00584         this->sub_surface_rect.y = 0;
00585         this->sub_surface_rect.w = 0;
00586         this->sub_surface_rect.h = 0;
00587     }
00588 
00589 
00590     // get current config
00591     if (this->initialized) {
00592         getConfiguration();
00593 
00594         // init color
00595         this->config.color.r = 0;
00596         this->config.color.g = 0;
00597         this->config.color.b = 0;
00598         this->config.color.a = 0;
00599         this->config.shadow_top_color = this->config.color;
00600         this->config.shadow_bottom_color = this->config.color;
00601         this->config.shadow_left_color = this->config.color;
00602         this->config.shadow_right_color = this->config.color;
00603         this->config.shadow_top_left_color = this->config.color;
00604         this->config.shadow_top_right_color = this->config.color;
00605         this->config.shadow_bottom_left_color = this->config.color;
00606         this->config.shadow_bottom_right_color = this->config.color;
00607         this->config.clipped = false;
00608         this->config.iswinsurface = false;
00609         this->config.islayersurface = (this->parent && this->parent->isLayerSurface());
00610         this->config.drawingflags = MMSFB_DRAW_NOFX;
00611         this->config.blittingflags = MMSFB_BLIT_NOFX;
00612         this->config.font = NULL;
00613     }
00614 }
00615 
00616 
00617 
00618 bool MMSFBSurface::isInitialized() {
00619     return this->initialized;
00620 }
00621 
00622 
00623 void MMSFBSurface::createSurfaceBuffer() {
00624 
00625     // create the surfacebuffer where additional infos are stored
00626     this->config.surface_buffer = new MMSFBSurfaceBuffer;
00627     MMSFBSurfaceBuffer *sb = this->config.surface_buffer;
00628     if (!sb) return;
00629 
00630     memset(sb->buffers, 0, sizeof(sb->buffers));
00631     sb->numbuffers = 0;
00632     sb->external_buffer = false;
00633 #if defined(__HAVE_FBDEV__) || defined(__HAVE_KMS__)
00634     sb->mmsfbdev_surface = NULL;
00635 #endif
00636 #ifdef __HAVE_XLIB__
00637     sb->x_image[0] = NULL;
00638 #endif
00639 #ifdef __HAVE_XV__
00640     sb->xv_image[0] = NULL;
00641 #endif
00642 #ifdef __HAVE_OPENGL__
00643     sb->ogl_fbo = 0;
00644     sb->ogl_tex = 0;
00645     sb->ogl_rbo = 0;
00646     sb->ogl_fbo_initialized = false;
00647     sb->ogl_tex_initialized = false;
00648     sb->ogl_rbo_initialized = false;
00649     sb->ogl_unchanged_depth_buffer = false;
00650 #endif
00651 }
00652 
00653 
00654 void MMSFBSurface::freeSurfaceBuffer() {
00655 
00656     if (!this->initialized)
00657         return;
00658 
00659     if (this->allocated_by == MMSFBSurfaceAllocatedBy_dfb) {
00660 #ifdef  __HAVE_DIRECTFB__
00661         if (this->dfb_surface) {
00662             this->dfb_surface->Release(this->dfb_surface);
00663             this->dfb_surface = NULL;
00664         }
00665 #endif
00666     }
00667     if (this->allocated_by == MMSFBSurfaceAllocatedBy_ogl) {
00668 #ifdef  __HAVE_OPENGL__
00669         //free my surface buffers
00670         MMSFBSurfaceBuffer *sb = this->config.surface_buffer;
00671         if (!sb->external_buffer) {
00672             // buffer which is internally allocated
00673             if (!this->is_sub_surface) {
00674                 // no subsurface
00675                 // free all buffers (front and back buffers)
00676                 mmsfb->bei->free(this);
00677                 delete sb;
00678                 sb=NULL;
00679             }
00680         }
00681 
00682         if(sb) {
00683             sb->numbuffers = 0;
00684         }
00685 #endif
00686     }
00687     else {
00688         //free my surface buffers
00689         MMSFBSurfaceBuffer *sb = this->config.surface_buffer;
00690         if (!sb->external_buffer) {
00691             // buffer which is internally allocated
00692             if (!this->is_sub_surface) {
00693                 // no subsurface
00694                 // free all buffers (front and back buffers)
00695                 for (int i = 0; i < sb->numbuffers; i++) {
00696                     // free only first plane of each buffer, because it points to memory for all used planes
00697                     if (sb->buffers[i].ptr) {
00698                         free(sb->buffers[i].ptr);
00699                         sb->buffers[i].ptr = NULL;
00700                     }
00701                 }
00702                 delete sb;
00703                 sb=NULL;
00704             }
00705         }
00706         if(sb) {
00707             sb->numbuffers = 0;
00708         }
00709     }
00710 
00711     this->initialized = false;
00712 }
00713 
00714 void MMSFBSurface::deleteSubSurface(MMSFBSurface *surface) {
00715     if (surface) {
00716         // remove a sub surface from the list
00717         for (unsigned int i = 0; i < this->children.size(); i++)
00718             if (this->children.at(i) == surface) {
00719                 this->children.erase(this->children.begin()+i);
00720                 break;
00721             }
00722     }
00723     else {
00724         // delete all sub surfaces
00725         for (unsigned int i = 0; i < this->children.size(); i++) {
00726             this->children.at(i)->deleteSubSurface(NULL);
00727             delete this->children.at(i);
00728         }
00729     }
00730 }
00731 
00732 int MMSFBSurface::calcPitch(int width) {
00733 
00734     MMSFBSurfacePixelFormat pf = this->config.surface_buffer->pixelformat;
00735     int    pitch = width;
00736 
00737     switch (pf) {
00738     case MMSFB_PF_ARGB1555:
00739         pitch = width * 2;
00740         break;
00741     case MMSFB_PF_RGB16:
00742         pitch = width * 2;
00743         break;
00744     case MMSFB_PF_RGB24:
00745         pitch = width * 3;
00746         break;
00747     case MMSFB_PF_RGB32:
00748         pitch = width * 4;
00749         break;
00750     case MMSFB_PF_ARGB:
00751         pitch = width * 4;
00752         break;
00753     case MMSFB_PF_A8:
00754         pitch = width;
00755         break;
00756     case MMSFB_PF_YUY2:
00757         pitch = width * 2;
00758         break;
00759     case MMSFB_PF_RGB332:
00760         pitch = width;
00761         break;
00762     case MMSFB_PF_UYVY:
00763         pitch = width * 2;
00764         break;
00765     case MMSFB_PF_I420:
00766         pitch = width;
00767         break;
00768     case MMSFB_PF_YV12:
00769         pitch = width;
00770         break;
00771     case MMSFB_PF_LUT8:
00772         pitch = width;
00773         break;
00774     case MMSFB_PF_ALUT44:
00775         pitch = width;
00776         break;
00777     case MMSFB_PF_AiRGB:
00778         pitch = width * 4;
00779         break;
00780     case MMSFB_PF_A1:
00781         pitch = width / 8;
00782         break;
00783     case MMSFB_PF_NV12:
00784         pitch = width;
00785         break;
00786     case MMSFB_PF_NV16:
00787         pitch = width;
00788         break;
00789     case MMSFB_PF_ARGB2554:
00790         pitch = width * 2;
00791         break;
00792     case MMSFB_PF_ARGB4444:
00793         pitch = width * 2;
00794         break;
00795     case MMSFB_PF_NV21:
00796         pitch = width;
00797         break;
00798     case MMSFB_PF_AYUV:
00799         pitch = width * 4;
00800         break;
00801     case MMSFB_PF_ARGB3565:
00802         pitch = width * 2;
00803         break;
00804     case MMSFB_PF_BGR24:
00805         pitch = width * 3;
00806         break;
00807     case MMSFB_PF_BGR555:
00808         pitch = width * 2;
00809         break;
00810     case MMSFB_PF_ABGR:
00811         pitch = width * 4;
00812         break;
00813     default:
00814         break;
00815     }
00816 
00817     if (pitch <= 0) pitch = 1;
00818     if (pitch % 4)
00819         pitch += 4 - pitch % 4;
00820 
00821     return pitch;
00822 }
00823 
00824 int MMSFBSurface::calcSize(int pitch, int height) {
00825 
00826     MMSFBSurfacePixelFormat pf = this->config.surface_buffer->pixelformat;
00827     int size = pitch * height;
00828     int diff;
00829 
00830     if (pf == MMSFB_PF_I420) {
00831         // increase size for U/V planes
00832         size += size / 2;
00833         if ((diff = size % pitch))
00834             size += pitch - diff;
00835     }
00836     else
00837     if (pf == MMSFB_PF_YV12) {
00838         // increase size for U/V planes
00839         size += size / 2;
00840         if ((diff = size % pitch))
00841             size += pitch - diff;
00842     }
00843     else
00844     if (pf == MMSFB_PF_ARGB3565) {
00845         // increase size for alpha plane (4 bit for each pixel)
00846         size += size / 4;
00847         if ((diff = size % pitch))
00848             size += pitch - diff;
00849     }
00850 
00851     return size;
00852 }
00853 
00854 void MMSFBSurface::initPlanePointers(MMSFBSurfacePlanes *planes, int height) {
00855 
00856     MMSFBSurfacePixelFormat pf = this->config.surface_buffer->pixelformat;
00857 
00858     switch (pf) {
00859     case MMSFB_PF_YV12:
00860         planes->ptr3 = ((unsigned char *)planes->ptr) + planes->pitch * height;
00861         planes->pitch3 = planes->pitch / 4;
00862         planes->ptr2 = ((unsigned char *)planes->ptr3) + planes->pitch3 * height;
00863         planes->pitch2 = planes->pitch3;
00864         break;
00865     case MMSFB_PF_ARGB3565:
00866         planes->ptr2 = ((unsigned char *)planes->ptr) + planes->pitch * height;
00867         planes->pitch2 = planes->pitch / 4;
00868         planes->ptr3 = NULL;
00869         planes->pitch3 = 0;
00870         break;
00871     default:
00872         break;
00873     }
00874 }
00875 
00876 void MMSFBSurface::getRealSubSurfacePos(MMSFBSurface *surface, bool refreshChilds) {
00877     if (this->is_sub_surface) {
00878         this->sub_surface_xoff = this->sub_surface_rect.x + this->parent->sub_surface_xoff;
00879         this->sub_surface_yoff = this->sub_surface_rect.y + this->parent->sub_surface_yoff;
00880 
00881         if (refreshChilds)
00882             for (unsigned int i = 0; i < this->children.size(); i++)
00883                 this->children.at(i)->getRealSubSurfacePos(NULL, refreshChilds);
00884     }
00885     else {
00886         this->sub_surface_xoff = 0;
00887         this->sub_surface_yoff = 0;
00888     }
00889 }
00890 
00891 
00892 bool MMSFBSurface::clipSubSurface(MMSFBRegion *region, bool regionset, MMSFBRegion *tmp, bool *tmpset) {
00893     MMSFBRegion myregion;
00894 
00895     if (!region) {
00896         if (*tmpset)
00897             this->root_parent->setClip(tmp);
00898         else
00899             this->root_parent->setClip(NULL);
00900 //      this->root_parent->unlock();
00901         return true;
00902     }
00903 
00904     /* get my region */
00905     getClip(&myregion);
00906 
00907     if (this->is_sub_surface) {
00908         myregion.x1+=sub_surface_xoff;
00909         myregion.y1+=sub_surface_yoff;
00910         myregion.x2+=sub_surface_xoff;
00911         myregion.y2+=sub_surface_yoff;
00912     }
00913 
00914     if (!regionset) {
00915         /* init region */
00916         *region = myregion;
00917         if(this->parent)
00918             return this->parent->clipSubSurface(region, true, tmp, tmpset);
00919     }
00920 
00921     /* check if input region is within my region */
00922     if (region->x1 < myregion.x1)
00923         region->x1 = myregion.x1;
00924     else
00925     if (region->x1 > myregion.x2)
00926         return false;
00927 
00928     if (region->y1 < myregion.y1)
00929         region->y1 = myregion.y1;
00930     else
00931     if (region->y1 > myregion.y2)
00932         return false;
00933 
00934     if (region->x2 > myregion.x2)
00935         region->x2 = myregion.x2;
00936     else
00937     if (region->x2 < myregion.x1)
00938         return false;
00939 
00940     if (region->y2 > myregion.y2)
00941         region->y2 = myregion.y2;
00942     else
00943     if (region->y2 < myregion.y1)
00944         return false;
00945 
00946     /* have a parent, call recursive */
00947     if (this->is_sub_surface)
00948         return this->parent->clipSubSurface(region, true, tmp, tmpset);
00949 
00950     /* i am the root, set clip now */
00951 //  lock();
00952     if (this->config.clipped) {
00953         getClip(tmp);
00954         *tmpset=true;
00955     }
00956     else
00957         *tmpset=false;
00958     setClip(region);
00959     return true;
00960 }
00961 
00962 void *MMSFBSurface::getDFBSurface() {
00963     if (!initialized)
00964         return NULL;
00965 
00966 #ifdef  __HAVE_DIRECTFB__
00967     return this->dfb_surface;
00968 #endif
00969 
00970     return NULL;
00971 }
00972 
00973 bool MMSFBSurface::getConfiguration(MMSFBSurfaceConfig *config) {
00974 
00975     /* check if initialized */
00976     INITCHECK;
00977 
00978     if (this->allocated_by == MMSFBSurfaceAllocatedBy_dfb) {
00979 #ifdef  __HAVE_DIRECTFB__
00980         DFBSurfaceCapabilities  caps;
00981         DFBResult               dfbres;
00982         DFBSurfacePixelFormat   mypf;
00983 
00984         /* get size */
00985         if (!this->is_sub_surface) {
00986             if ((dfbres=this->dfb_surface->GetSize(this->dfb_surface, &(this->config.w), &(this->config.h))) != DFB_OK) {
00987                 MMSFB_SetError(dfbres, "IDirectFBSurface::GetSize() failed");
00988                 return false;
00989             }
00990             this->config.surface_buffer->sbw = this->config.w;
00991             this->config.surface_buffer->sbh = this->config.h;
00992         }
00993         else {
00994 #ifdef USE_DFB_SUBSURFACE
00995             if ((dfbres=this->dfb_surface->GetSize(this->dfb_surface, &(this->config.w), &(this->config.h))) != DFB_OK) {
00996                 MMSFB_SetError(dfbres, "IDirectFBSurface::GetSize() failed");
00997                 return false;
00998             }
00999 #else
01000             this->config.w = this->sub_surface_rect.w;
01001             this->config.h = this->sub_surface_rect.h;
01002 #endif
01003         }
01004 
01005         // get the surface pitch
01006         void *ptr;
01007         if (this->dfb_surface->Lock(this->dfb_surface, DSLF_READ, &ptr, &this->config.surface_buffer->buffers[0].pitch) == DFB_OK) {
01008             this->dfb_surface->Unlock(this->dfb_surface);
01009         }
01010 
01011         /* get pixelformat */
01012         if ((dfbres=this->dfb_surface->GetPixelFormat(this->dfb_surface, &mypf)) != DFB_OK) {
01013             MMSFB_SetError(dfbres, "IDirectFBSurface::GetPixelFormat() failed");
01014             return false;
01015         }
01016 
01017         /* build a format string */
01018         this->config.surface_buffer->pixelformat = getMMSFBPixelFormatFromDFBPixelFormat(mypf);
01019         this->config.surface_buffer->alphachannel = isAlphaPixelFormat(this->config.surface_buffer->pixelformat);
01020 
01021         /* get capabilities */
01022         if ((dfbres=this->dfb_surface->GetCapabilities(this->dfb_surface, &caps)) != DFB_OK) {
01023             MMSFB_SetError(dfbres, "IDirectFBSurface::GetCapabilities() failed");
01024             return false;
01025         }
01026 
01027         /* is it a premultiplied surface? */
01028         this->config.surface_buffer->premultiplied = caps & DSCAPS_PREMULTIPLIED;
01029 
01030         /* get the buffer mode */
01031         this->config.surface_buffer->backbuffer = 0;
01032         if (caps & DSCAPS_DOUBLE)
01033             this->config.surface_buffer->backbuffer = 1;
01034         else
01035         if (caps & DSCAPS_TRIPLE)
01036             this->config.surface_buffer->backbuffer = 2;
01037 
01038         /* system only? */
01039         this->config.surface_buffer->systemonly = false;
01040         if (caps & DSCAPS_SYSTEMONLY)
01041             this->config.surface_buffer->systemonly = true;
01042 
01043         /* fill return config */
01044         if (config)
01045             *config = this->config;
01046 
01047         /* log some infos */
01048         if ((!config)&&(!this->is_sub_surface)) {
01049             DEBUGMSG("MMSGUI", "Surface properties:");
01050 
01051             DEBUGMSG("MMSGUI", " type:         DFB");
01052             DEBUGMSG("MMSGUI", " size:         " + iToStr(this->config.w) + "x" + iToStr(this->config.h));
01053             DEBUGMSG("MMSGUI", " pitch:        " + iToStr(this->config.surface_buffer->buffers[0].pitch));
01054 
01055             if (this->config.surface_buffer->alphachannel)
01056                 DEBUGMSG("MMSGUI", " pixelformat:  " + getMMSFBPixelFormatString(this->config.surface_buffer->pixelformat) + ",ALPHACHANNEL");
01057             else
01058                 DEBUGMSG("MMSGUI", " pixelformat:  " + getMMSFBPixelFormatString(this->config.surface_buffer->pixelformat));
01059 
01060             DEBUGMSG("MMSGUI", " capabilities:");
01061 
01062             if (caps & DSCAPS_PRIMARY)
01063                 DEBUGMSG("MMSGUI", "  PRIMARY");
01064             if (caps & DSCAPS_SYSTEMONLY)
01065                 DEBUGMSG("MMSGUI", "  SYSTEMONLY");
01066             if (caps & DSCAPS_VIDEOONLY)
01067                 DEBUGMSG("MMSGUI", "  VIDEOONLY");
01068             if (caps & DSCAPS_DOUBLE)
01069                 DEBUGMSG("MMSGUI", "  DOUBLE");
01070             if (caps & DSCAPS_TRIPLE)
01071                 DEBUGMSG("MMSGUI", "  TRIPLE");
01072             if (caps & DSCAPS_PREMULTIPLIED)
01073                 DEBUGMSG("MMSGUI", "  PREMULTIPLIED");
01074         }
01075 
01076         return true;
01077 #endif
01078     }
01079     else
01080     if (this->allocated_by == MMSFBSurfaceAllocatedBy_ogl) {
01081 #ifdef  __HAVE_OPENGL__
01082         if (this->config.surface_buffer->ogl_fbo == 0) {
01083             // this surface is the primary display buffer connected to the x-window
01084             int val;
01085 
01086             // get size
01087             if (this->is_sub_surface) {
01088                 this->config.w = this->sub_surface_rect.w;
01089                 this->config.h = this->sub_surface_rect.h;
01090             }
01091             this->config.surface_buffer->buffers[0].pitch = this->config.w * 4;
01092 
01093             this->config.surface_buffer->pixelformat = MMSFB_PF_ABGR;
01094             this->config.surface_buffer->alphachannel = true;
01095             this->config.surface_buffer->premultiplied = false;
01096 
01097             // get double buffering status
01098 /*printf("getconfig\n");fflush(stdout);
01099             LOCK_OGL(0);
01100 printf("getconfig2\n");fflush(stdout);
01101             int glxres;
01102             if ((glxres = glXGetConfig(this->x_display, this->xvi, GLX_DOUBLEBUFFER, &val))) {
01103                 MMSFB_SetError(glxres, "glXGetConfig() failed");
01104                 UNLOCK_OGL;
01105                 return false;
01106             }
01107             UNLOCK_OGL;*/
01108 // TODO
01109             val = 1;
01110             this->config.surface_buffer->backbuffer = (val)?1:0;
01111             this->config.surface_buffer->numbuffers = this->config.surface_buffer->backbuffer + 1;
01112 
01113             this->config.surface_buffer->systemonly = false;
01114         }
01115         else {
01116             // get size
01117             if (this->is_sub_surface) {
01118                 this->config.w = this->sub_surface_rect.w;
01119                 this->config.h = this->sub_surface_rect.h;
01120             }
01121             this->config.surface_buffer->buffers[0].pitch = this->config.w * 4;
01122 
01123             this->config.surface_buffer->pixelformat = MMSFB_PF_ABGR;
01124             this->config.surface_buffer->alphachannel = true;
01125             this->config.surface_buffer->premultiplied = false;
01126 
01127             this->config.surface_buffer->backbuffer = 0;
01128             this->config.surface_buffer->numbuffers = this->config.surface_buffer->backbuffer + 1;
01129 
01130             this->config.surface_buffer->systemonly = false;
01131         }
01132 
01133         // fill return config
01134         if (config)
01135             *config = this->config;
01136 
01137         // log some infos
01138         if ((!config)&&(!this->is_sub_surface)) {
01139             DEBUGMSG("MMSGUI", "Surface properties:");
01140 
01141             DEBUGMSG("MMSGUI", " type:         OGL");
01142             DEBUGMSG("MMSGUI", " size:         " + iToStr(this->config.w) + "x" + iToStr(this->config.h));
01143             DEBUGMSG("MMSGUI", " pitch:        " + iToStr(this->config.surface_buffer->buffers[0].pitch));
01144 
01145             if (this->config.surface_buffer->alphachannel)
01146                 DEBUGMSG("MMSGUI", " pixelformat:  " + getMMSFBPixelFormatString(this->config.surface_buffer->pixelformat) + ",ALPHACHANNEL");
01147             else
01148                 DEBUGMSG("MMSGUI", " pixelformat:  " + getMMSFBPixelFormatString(this->config.surface_buffer->pixelformat));
01149 
01150             DEBUGMSG("MMSGUI", " capabilities:");
01151 
01152             if (this->config.surface_buffer->ogl_fbo == 0)
01153                 DEBUGMSG("MMSGUI", "  PRIMARY");
01154             if (this->config.surface_buffer->backbuffer == 1)
01155                 DEBUGMSG("MMSGUI", "  DOUBLE");
01156         }
01157         return true;
01158 #endif
01159     }
01160     else {
01161         // get size
01162         if (this->is_sub_surface) {
01163             this->config.w = this->sub_surface_rect.w;
01164             this->config.h = this->sub_surface_rect.h;
01165         }
01166 
01167         // fill return config
01168         if (config)
01169             *config = this->config;
01170 
01171         // log some infos
01172         if ((!config)&&(!this->is_sub_surface)) {
01173             DEBUGMSG("MMSGUI", "Surface properties:");
01174 
01175             DEBUGMSG("MMSGUI", " type:         MMS");
01176             DEBUGMSG("MMSGUI", " size:         " + iToStr(this->config.w) + "x" + iToStr(this->config.h));
01177             DEBUGMSG("MMSGUI", " pitch:        " + iToStr(this->config.surface_buffer->buffers[0].pitch));
01178 
01179             if (this->config.surface_buffer->alphachannel)
01180                 DEBUGMSG("MMSGUI", " pixelformat:  " + getMMSFBPixelFormatString(this->config.surface_buffer->pixelformat) + ",ALPHACHANNEL");
01181             else
01182                 DEBUGMSG("MMSGUI", " pixelformat:  " + getMMSFBPixelFormatString(this->config.surface_buffer->pixelformat));
01183 
01184             DEBUGMSG("MMSGUI", " capabilities:");
01185 
01186             if (this->config.surface_buffer->systemonly)
01187                 DEBUGMSG("MMSGUI", "  SYSTEMONLY");
01188             if (this->config.surface_buffer->backbuffer == 1)
01189                 DEBUGMSG("MMSGUI", "  DOUBLE");
01190             if (this->config.surface_buffer->backbuffer == 2)
01191                 DEBUGMSG("MMSGUI", "  TRIPLE");
01192             if (this->config.surface_buffer->premultiplied)
01193                 DEBUGMSG("MMSGUI", "  PREMULTIPLIED");
01194         }
01195         return true;
01196     }
01197     return false;
01198 }
01199 
01200 void MMSFBSurface::setExtendedAcceleration(bool extendedaccel) {
01201     this->extendedaccel = extendedaccel;
01202 }
01203 
01204 bool MMSFBSurface::getExtendedAcceleration() {
01205     return this->extendedaccel;
01206 }
01207 
01208 void MMSFBSurface::setAllocMethod(MMSFBSurfaceAllocMethod allocmethod) {
01209     this->allocmethod = allocmethod;
01210     if (this->allocmethod == MMSFBSurfaceAllocMethod_malloc)
01211         printf("DISKO: Using own surface memory management.\n");
01212 }
01213 
01214 MMSFBSurfaceAllocMethod MMSFBSurface::getAllocMethod() {
01215     return this->allocmethod;
01216 }
01217 
01218 bool MMSFBSurface::isWinSurface() {
01219     return this->config.iswinsurface;
01220 }
01221 
01222 bool MMSFBSurface::isLayerSurface() {
01223     return this->config.islayersurface;
01224 }
01225 
01226 bool MMSFBSurface::isSubSurface() {
01227     return this->is_sub_surface;
01228 }
01229 
01230 MMSFBSurface *MMSFBSurface::getParent() {
01231     return this->parent;
01232 }
01233 
01234 MMSFBSurface *MMSFBSurface::getRootParent() {
01235     return this->root_parent;
01236 }
01237 
01238 bool MMSFBSurface::setWinSurface(bool iswinsurface) {
01239 
01240     /* check if initialized */
01241     INITCHECK;
01242 
01243     /* set the flag */
01244     this->config.iswinsurface = iswinsurface;
01245 
01246     return true;
01247 }
01248 
01249 bool MMSFBSurface::setLayerSurface(bool islayersurface) {
01250 
01251     /* check if initialized */
01252     INITCHECK;
01253 
01254     /* set the flag */
01255     this->config.islayersurface = islayersurface;
01256 
01257     return true;
01258 }
01259 
01260 
01261 bool MMSFBSurface::isOpaque() {
01262     if (MMSFBSURFACE_READ_BUFFER(this).opaque) {
01263         return true;
01264     }
01265     else {
01266         return (!isAlphaPixelFormat(this->config.surface_buffer->pixelformat));
01267     }
01268 }
01269 
01270 
01271 bool MMSFBSurface::getPixelFormat(MMSFBSurfacePixelFormat *pixelformat) {
01272 
01273     /* check if initialized */
01274     INITCHECK;
01275 
01276     /* return the pixelformat */
01277     *pixelformat = this->config.surface_buffer->pixelformat;
01278 
01279     return true;
01280 }
01281 
01282 bool MMSFBSurface::getSize(int *w, int *h) {
01283 
01284     /* check if initialized */
01285     INITCHECK;
01286 
01287     /* return values */
01288     *w = this->config.w;
01289     *h = this->config.h;
01290 
01291     return true;
01292 }
01293 
01294 bool MMSFBSurface::getNumberOfBuffers(int *num) {
01295 
01296     // check if initialized
01297     INITCHECK;
01298 
01299     // return value
01300     *num = this->config.surface_buffer->backbuffer + 1;
01301 
01302     return true;
01303 }
01304 
01305 bool MMSFBSurface::getMemSize(int *size) {
01306 
01307     /* check if initialized */
01308     INITCHECK;
01309 
01310     /* init size */
01311     if (!size)
01312         return false;
01313     *size = 0;
01314 
01315     *size = calcSize(this->config.surface_buffer->buffers[0].pitch, this->config.h);
01316 
01317     return true;
01318 }
01319 
01320 
01321 bool MMSFBSurface::setFlipFlags(MMSFBFlipFlags flags) {
01322     this->flipflags = flags;
01323     return true;
01324 }
01325 
01326 
01327 
01328 bool MMSFBSurface::calcClip(int x, int y, int w, int h, MMSFBRectangle *crect) {
01329     MMSFBRegion clipreg;
01330 
01331 #ifndef USE_DFB_SUBSURFACE
01332     if (!this->is_sub_surface) {
01333 #endif
01334         // normal surface or dfb subsurface
01335         if (!this->config.clipped) {
01336             clipreg.x1 = 0;
01337             clipreg.y1 = 0;
01338             clipreg.x2 = this->config.w - 1;
01339             clipreg.y2 = this->config.h - 1;
01340         }
01341         else {
01342             clipreg = this->config.clip;
01343         }
01344 #ifndef USE_DFB_SUBSURFACE
01345     }
01346     else {
01347         // subsurface
01348         if (!this->root_parent->config.clipped) {
01349             clipreg.x1 = 0;
01350             clipreg.y1 = 0;
01351             clipreg.x2 = this->root_parent->config.w - 1;
01352             clipreg.y2 = this->root_parent->config.h - 1;
01353         }
01354         else {
01355             clipreg = this->root_parent->config.clip;
01356         }
01357     }
01358 #endif
01359 
01360     if (x < clipreg.x1) {
01361         // left outside
01362         w-= clipreg.x1 - x;
01363         if (w <= 0) {
01364             return false;
01365         }
01366         x = clipreg.x1;
01367     }
01368     else
01369     if (x > clipreg.x2) {
01370         // right outside
01371         return false;
01372     }
01373 
01374     if (y < clipreg.y1) {
01375         // top outside
01376         h-= clipreg.y1 - y;
01377         if (h <= 0) {
01378             return false;
01379         }
01380         y = clipreg.y1;
01381     }
01382     else
01383     if (y > clipreg.y2) {
01384         // bottom outside
01385         return false;
01386     }
01387 
01388     if (x + w - 1 > clipreg.x2) {
01389         // to width
01390         w = clipreg.x2 - x + 1;
01391     }
01392 
01393     if (y + h - 1 > clipreg.y2) {
01394         // to height
01395         h = clipreg.y2 - y + 1;
01396     }
01397 
01398     // set crect and return
01399     if (crect) {
01400         crect->x = x;
01401         crect->y = y;
01402         crect->w = w;
01403         crect->h = h;
01404     }
01405     return true;
01406 }
01407 
01408 bool MMSFBSurface::doClear(unsigned char r, unsigned char g,
01409                            unsigned char b, unsigned char a) {
01410     bool ret = false;
01411 
01412     // check if initialized
01413     INITCHECK;
01414 /*
01415 MMSFBRegion clip;
01416 getClip(&clip);
01417 printf("doClear with clip %d,%d,%d,%d (%d,%d,%d,%d)\n", clip.x1, clip.y1, clip.x2, clip.y2, r,g,b,a);
01418 */
01419 
01420     if (this->allocated_by == MMSFBSurfaceAllocatedBy_dfb) {
01421 #ifdef  __HAVE_DIRECTFB__
01422 
01423         MMSFBSURFACE_WRITE_BUFFER(this).opaque      = false;
01424         MMSFBSURFACE_WRITE_BUFFER(this).transparent = false;
01425 
01426         DFBResult   dfbres;
01427         D_DEBUG_AT( MMS_Surface, "clear( argb %02x %02x %02x %02x ) <- %dx%d\n",
01428                     a, r, g, b, this->config.surface_buffer->sbw, this->config.surface_buffer->sbh );
01429         MMSFB_TRACE();
01430 
01431         if ((a < 0xff)&&(this->config.surface_buffer->premultiplied)) {
01432             // premultiplied surface, have to premultiply the color
01433             register int aa = a + 1;
01434             r = (aa * r) >> 8;
01435             g = (aa * g) >> 8;
01436             b = (aa * b) >> 8;
01437         }
01438 
01439         if (!this->is_sub_surface) {
01440             // clear surface
01441             if ((dfbres=this->dfb_surface->Clear(this->dfb_surface, r, g, b, a)) != DFB_OK) {
01442                 MMSFB_SetError(dfbres, "IDirectFBSurface::Clear() failed");
01443                 return false;
01444             }
01445             ret = true;
01446         }
01447         else {
01448 
01449 #ifndef USE_DFB_SUBSURFACE
01450             CLIPSUBSURFACE
01451 #endif
01452 
01453             // clear surface
01454             if (this->dfb_surface->Clear(this->dfb_surface, r, g, b, a) == DFB_OK)
01455                 ret = true;
01456 
01457 #ifndef USE_DFB_SUBSURFACE
01458             UNCLIPSUBSURFACE
01459 #endif
01460         }
01461 #endif
01462     }
01463     else {
01464 
01465         // save opaque/transparent status
01466         bool opaque_saved       = MMSFBSURFACE_WRITE_BUFFER(this).opaque;
01467         bool transparent_saved  = MMSFBSURFACE_WRITE_BUFFER(this).transparent;
01468 
01469         // get final rectangle and new opaque/transparent status
01470         MMSFBRectangle crect;
01471         MMSFBDrawingFlags drawingflags;
01472         MMSFBColor color = MMSFBColor(r, g, b, a);
01473         if (!checkDrawingStatus(0, 0, this->config.w, this->config.h, crect, drawingflags, &color, true)) {
01474             // nothing to draw
01475             ret = true;
01476         }
01477         else {
01478             if (this->allocated_by == MMSFBSurfaceAllocatedBy_ogl) {
01479 #ifdef  __HAVE_OPENGL__
01480                 MMSFBSURFACE_WRITE_BUFFER(this).opaque      = false;
01481                 MMSFBSURFACE_WRITE_BUFFER(this).transparent = false;
01482 
01483                 if (!this->is_sub_surface) {
01484 
01485                     mmsfb->bei->clear(this, color);
01486 
01487                     ret = true;
01488                 }
01489                 else {
01490                     CLIPSUBSURFACE
01491 
01492                     mmsfb->bei->clear(this, color);
01493 
01494                     UNCLIPSUBSURFACE
01495 
01496                     ret = true;
01497                 }
01498 #endif
01499             }
01500             else {
01501                 ret = extendedAccelFillRectangle(crect.x, crect.y, crect.w, crect.h, drawingflags, &color);
01502             }
01503         }
01504 
01505         if (!ret) {
01506             // restore opaque/transparent status
01507             MMSFBSURFACE_WRITE_BUFFER(this).opaque      = opaque_saved;
01508             MMSFBSURFACE_WRITE_BUFFER(this).transparent = transparent_saved;
01509         }
01510 
01511     }
01512 
01513     return ret;
01514 }
01515 
01516 
01517 bool MMSFBSurface::finClear(MMSFBRectangle *check_rect, bool test) {
01518 
01519     // block other threads
01520 //  lock();
01521 
01522     CLEAR_REQUEST *clear_req = &this->clear_request;
01523     if (this->is_sub_surface) clear_req = &this->root_parent->clear_request;
01524 
01525     if (!clear_req->set) {
01526 //      unlock();
01527         return false;
01528     }
01529 
01530     if (!test) {
01531         // NOT in test mode: reset the clear flag
01532         clear_req->set = false;
01533     }
01534 
01535 //printf("finClear\n");
01536 
01537 
01538     if (check_rect) {
01539         // we have to check if clear request can be skipped
01540 //printf(">>>>>finClear rect %d,%d,%d,%d\n", check_rect->x, check_rect->y, check_rect->w, check_rect->h);
01541         if (this->is_sub_surface) {
01542 //          check_rect->x+=sub_surface_xoff;
01543 //          check_rect->y+=sub_surface_yoff;
01544         }
01545 //printf(">>X>>finClear rect %d,%d,%d,%d\n", check_rect->x, check_rect->y, check_rect->w, check_rect->h);
01546 
01547         if (check_rect->x <= clear_req->real_region.x1 &&
01548             check_rect->y <= clear_req->real_region.y1 &&
01549             check_rect->x + check_rect->w - 1 >= clear_req->real_region.x2 &&
01550             check_rect->y + check_rect->h - 1 >= clear_req->real_region.y2) {
01551             // skip clear request
01552 //printf(">>>>>finClear rect %d,%d,%d,%d  >>> skipped\n", check_rect->x, check_rect->y, check_rect->w, check_rect->h);
01553 
01554 //          unlock();
01555             return false;
01556         }
01557     }
01558 
01559     if (test) {
01560         // test mode: return true if we have to clear
01561 //      unlock();
01562         return true;
01563     }
01564 
01565     // we have to clear, set clip
01566     MMSFBRegion clip;
01567     bool clipped = clear_req->surface->config.clipped;
01568     if (clipped) {
01569         clear_req->surface->getClip(&clip);
01570         if (clear_req->clipped)
01571             clear_req->surface->setClip(&clear_req->clip);
01572         else
01573             clear_req->surface->setClip(NULL);
01574     }
01575     else {
01576         if (clear_req->clipped)
01577             clear_req->surface->setClip(&clear_req->clip);
01578     }
01579 
01580     // do it
01581     clear_req->surface->doClear(clear_req->color.r,
01582                                 clear_req->color.g,
01583                                 clear_req->color.b,
01584                                 clear_req->color.a);
01585 
01586     // reset clip
01587     if (clipped) {
01588         clear_req->surface->setClip(&clip);
01589     }
01590     else {
01591         if (clear_req->clipped)
01592             clear_req->surface->setClip(NULL);
01593     }
01594 
01595 //  unlock();
01596     return true;
01597 }
01598 
01599 bool MMSFBSurface::clear(unsigned char r, unsigned char g,
01600                          unsigned char b, unsigned char a) {
01601 
01602     // check if initialized
01603     INITCHECK;
01604 /*
01605 MMSFBRegion clip;
01606 getClip(&clip);
01607 printf("clear with clip %d,%d,%d,%d (%d,%d,%d,%d)  dest opaque = %d\n", clip.x1, clip.y1, clip.x2, clip.y2, r,g,b,a,MMSFBSURFACE_WRITE_BUFFER(this).opaque);
01608 printf("------real %d,%d,%d,%d\n",clip.x1+sub_surface_xoff, clip.y1+sub_surface_yoff, clip.x2+sub_surface_xoff, clip.y2+sub_surface_yoff);
01609 */
01610 
01611     // block other threads
01612 //    lock();
01613 
01614     // get access to previous clear request
01615     CLEAR_REQUEST *clear_req = &this->clear_request;
01616     if (this->is_sub_surface) clear_req = &this->root_parent->clear_request;
01617 
01618     // checking for previous clear...
01619     // it can be possible to skip previous clear
01620     // so we have to put affected rectangle to finClear() method, preparing the decision
01621     MMSFBRegion clip;
01622     getClip(&clip);
01623     MMSFBRectangle rect = MMSFBRectangle(clip.x1, clip.y1, clip.x1 + clip.x2 + 1, clip.y1 + clip.y2 + 1);
01624 
01625     if (finClear(&rect, true)) {
01626         // there is a previous clear which we have to finalize
01627         finClear();
01628     }
01629     else {
01630         // there is no previous clear OR new clear command will full overlap previous clear
01631         // so we can skip previous clear
01632     }
01633 
01634     // save clear request
01635     clear_req->set = true;
01636     clear_req->surface = this;
01637     clear_req->clipped = this->config.clipped;
01638     if (clear_req->clipped)
01639         getClip(&clear_req->clip);
01640     clear_req->color = MMSFBColor(r, g, b, a);
01641 
01642     // get affected region on the real existing surface buffer
01643     clear_req->real_region = (clear_req->clipped) ? clear_req->clip : MMSFBRegion(0, 0, this->config.w-1, this->config.h-1);
01644     if (this->is_sub_surface) {
01645         clear_req->real_region.x1+= this->sub_surface_xoff;
01646         clear_req->real_region.y1+= this->sub_surface_yoff;
01647         clear_req->real_region.x2+= this->sub_surface_xoff;
01648         clear_req->real_region.y2+= this->sub_surface_yoff;
01649     }
01650 
01651     // all right
01652 //  unlock();
01653     return true;
01654 }
01655 
01656 bool MMSFBSurface::setColor(unsigned char r, unsigned char g,
01657                             unsigned char b, unsigned char a) {
01658 
01659     // check if initialized
01660     INITCHECK;
01661 
01662     if (this->allocated_by == MMSFBSurfaceAllocatedBy_dfb) {
01663 #ifdef  __HAVE_DIRECTFB__
01664         DFBResult   dfbres;
01665 
01666         // set color
01667 #ifdef USE_DFB_SUBSURFACE
01668         if ((dfbres=this->dfb_surface->SetColor(this->dfb_surface, r, g, b, a)) != DFB_OK) {
01669             MMSFB_SetError(dfbres, "IDirectFBSurface::SetColor() failed");
01670             return false;
01671         }
01672 #else
01673         if (!this->is_sub_surface) {
01674             if ((dfbres=this->dfb_surface->SetColor(this->dfb_surface, r, g, b, a)) != DFB_OK) {
01675                 MMSFB_SetError(dfbres, "IDirectFBSurface::SetColor() failed");
01676                 return false;
01677             }
01678         }
01679 #endif
01680 #endif
01681     }
01682 
01683     // save the color
01684     MMSFBColor *col = &this->config.color;
01685     col->r = r;
01686     col->g = g;
01687     col->b = b;
01688     col->a = a;
01689 
01690     // set the default drawing flags
01691     // reason a): if it is an PREMULTIPLIED surface, the given color has to
01692     //            premultiplied internally before using it
01693     // reason b): if an alpha value is specified, the next draw function
01694     //            should blend over the surface
01695     this->setDrawingFlagsByAlpha(a);
01696 
01697     return true;
01698 }
01699 
01700 bool MMSFBSurface::setColor(MMSFBColor &color) {
01701     return setColor(color.r, color.g, color.b, color.a);
01702 }
01703 
01704 bool MMSFBSurface::getColor(MMSFBColor *color) {
01705 
01706     // check if initialized
01707     INITCHECK;
01708 
01709     // return the color
01710     *color = this->config.color;
01711 
01712     return true;
01713 }
01714 
01715 bool MMSFBSurface::setShadowColor(MMSFBColor &shadow_top_color, MMSFBColor &shadow_bottom_color,
01716                                   MMSFBColor &shadow_left_color, MMSFBColor &shadow_right_color,
01717                                   MMSFBColor &shadow_top_left_color, MMSFBColor &shadow_top_right_color,
01718                                   MMSFBColor &shadow_bottom_left_color, MMSFBColor &shadow_bottom_right_color) {
01719 
01720     // check if initialized
01721     INITCHECK;
01722 
01723     // save the new shadow colors
01724     // note: if the alphachannel of a color is 0, the respective shadow is disabled
01725     this->config.shadow_top_color = shadow_top_color;
01726     this->config.shadow_bottom_color = shadow_bottom_color;
01727     this->config.shadow_left_color = shadow_left_color;
01728     this->config.shadow_right_color = shadow_right_color;
01729     this->config.shadow_top_left_color = shadow_top_left_color;
01730     this->config.shadow_top_right_color = shadow_top_right_color;
01731     this->config.shadow_bottom_left_color = shadow_bottom_left_color;
01732     this->config.shadow_bottom_right_color = shadow_bottom_right_color;
01733 
01734     return true;
01735 }
01736 
01737 bool MMSFBSurface::setClip(MMSFBRegion *clip) {
01738 
01739     // check if initialized
01740     INITCHECK;
01741 
01742     if (this->allocated_by == MMSFBSurfaceAllocatedBy_dfb) {
01743 #ifdef  __HAVE_DIRECTFB__
01744         DFBResult   dfbres;
01745 
01746         // set clip
01747 #ifdef USE_DFB_SUBSURFACE
01748         if ((dfbres=this->dfb_surface->SetClip(this->dfb_surface, (DFBRegion*)clip)) != DFB_OK) {
01749             MMSFB_SetError(dfbres, "IDirectFBSurface::SetClip() failed");
01750             return false;
01751         }
01752 #else
01753         if (!this->is_sub_surface) {
01754             if ((dfbres=this->dfb_surface->SetClip(this->dfb_surface, (DFBRegion*)clip)) != DFB_OK) {
01755                 MMSFB_SetError(dfbres, "IDirectFBSurface::SetClip() failed");
01756                 return false;
01757             }
01758         }
01759 #endif
01760 #endif
01761     }
01762 
01763     // save the region
01764     if (clip) {
01765         this->config.clipped = true;
01766         this->config.clip = *clip;
01767     }
01768     else {
01769         this->config.clipped = false;
01770     }
01771 
01772     return true;
01773 }
01774 
01775 bool MMSFBSurface::setClip(int x1, int y1, int x2, int y2) {
01776     MMSFBRegion clip;
01777     clip.x1=x1;
01778     clip.y1=y1;
01779     clip.x2=x2;
01780     clip.y2=y2;
01781     return setClip(&clip);
01782 }
01783 
01784 bool MMSFBSurface::getClip(MMSFBRegion *clip) {
01785 
01786     /* check if initialized */
01787     INITCHECK;
01788 
01789     /* return the clip region */
01790     if (this->config.clipped) {
01791         *clip = this->config.clip;
01792     }
01793     else {
01794         clip->x1 = 0;
01795         clip->y1 = 0;
01796         clip->x2 = this->config.w - 1;
01797         clip->y2 = this->config.h - 1;
01798     }
01799 
01800     return true;
01801 }
01802 
01803 
01804 bool MMSFBSurface::setDrawingFlags(MMSFBDrawingFlags flags) {
01805 
01806     /* check if initialized */
01807     INITCHECK;
01808 
01809     if (this->allocated_by == MMSFBSurfaceAllocatedBy_dfb) {
01810 #ifdef  __HAVE_DIRECTFB__
01811         DFBResult   dfbres;
01812 
01813         /* set the drawing flags */
01814 #ifdef USE_DFB_SUBSURFACE
01815         if ((dfbres=this->dfb_surface->SetDrawingFlags(this->dfb_surface, getDFBSurfaceDrawingFlagsFromMMSFBDrawingFlags(flags))) != DFB_OK) {
01816             MMSFB_SetError(dfbres, "IDirectFBSurface::SetDrawingFlags() failed");
01817             return false;
01818         }
01819 #else
01820         if (!this->is_sub_surface) {
01821             if ((dfbres=this->dfb_surface->SetDrawingFlags(this->dfb_surface, getDFBSurfaceDrawingFlagsFromMMSFBDrawingFlags(flags))) != DFB_OK) {
01822                 MMSFB_SetError(dfbres, "IDirectFBSurface::SetDrawingFlags() failed");
01823                 return false;
01824             }
01825         }
01826 #endif
01827 #endif
01828     }
01829 
01830     /* save the flags */
01831     this->config.drawingflags = flags;
01832 
01833     return true;
01834 }
01835 
01836 
01837 
01838 bool MMSFBSurface::drawLine(int x1, int y1, int x2, int y2) {
01839     bool ret = false;
01840 
01841     // check if initialized
01842     INITCHECK;
01843 
01844     // check if we can use fill rectangle
01845     if (x1 == x2) {
01846         if (y1 <= y2) {
01847             return fillRectangle(x1, y1, 1, y2-y1+1);
01848         }
01849         else {
01850             return fillRectangle(x1, y2, 1, y1-y2+1);
01851         }
01852     }
01853     else
01854     if (y1 == y2) {
01855         if (x1 <= x2) {
01856             return fillRectangle(x1, y1, x2-x1+1, 1);
01857         }
01858         else {
01859             return fillRectangle(x2, y1, x1-x2+1, 1);
01860         }
01861     }
01862 
01863     MMSFBSURFACE_WRITE_BUFFER(this).opaque      = false;
01864     MMSFBSURFACE_WRITE_BUFFER(this).transparent = false;
01865 
01866     // finalize previous clear
01867     finClear();
01868 
01869     if (this->allocated_by == MMSFBSurfaceAllocatedBy_dfb) {
01870 #ifdef  __HAVE_DIRECTFB__
01871         DFBResult   dfbres;
01872         MMSFB_BREAK();
01873 
01874         // draw a line
01875         if (!this->is_sub_surface) {
01876             if (!extendedAccelDrawLine(x1, y1, x2, y2))
01877                 if ((dfbres=this->dfb_surface->DrawLine(this->dfb_surface, x1, y1, x2, y2)) != DFB_OK) {
01878                     MMSFB_SetError(dfbres, "IDirectFBSurface::DrawLine() failed");
01879                     return false;
01880                 }
01881             ret = true;
01882         }
01883         else {
01884 
01885 #ifndef USE_DFB_SUBSURFACE
01886             CLIPSUBSURFACE
01887 
01888             x1+=this->sub_surface_xoff;
01889             y1+=this->sub_surface_yoff;
01890             x2+=this->sub_surface_xoff;
01891             y2+=this->sub_surface_yoff;
01892 
01893             SETSUBSURFACE_DRAWINGFLAGS;
01894 #endif
01895 
01896             if (extendedAccelDrawLine(x1, y1, x2, y2))
01897                 ret = true;
01898             else
01899                 if (this->dfb_surface->DrawLine(this->dfb_surface, x1, y1, x2, y2) == DFB_OK)
01900                     ret = true;
01901 
01902 #ifndef USE_DFB_SUBSURFACE
01903             RESETSUBSURFACE_DRAWINGFLAGS;
01904 
01905             UNCLIPSUBSURFACE
01906 #endif
01907         }
01908 
01909 #endif
01910     }
01911     else
01912     if (this->allocated_by == MMSFBSurfaceAllocatedBy_ogl) {
01913 #ifdef  __HAVE_OPENGL__
01914         if (!this->is_sub_surface) {
01915 
01916             mmsfb->bei->drawLine(this, x1, y1, x2, y2);
01917 
01918             ret = true;
01919         }
01920         else {
01921             CLIPSUBSURFACE
01922 
01923             mmsfb->bei->drawLine(this, x1, y1, x2, y2);
01924 
01925             UNCLIPSUBSURFACE
01926 
01927             ret = true;
01928         }
01929 #endif
01930     }
01931     else {
01932 
01933         if (!this->is_sub_surface) {
01934             ret = extendedAccelDrawLine(x1, y1, x2, y2);
01935         }
01936         else {
01937             CLIPSUBSURFACE
01938 
01939             x1+=this->sub_surface_xoff;
01940             y1+=this->sub_surface_yoff;
01941             x2+=this->sub_surface_xoff;
01942             y2+=this->sub_surface_yoff;
01943 
01944             ret = extendedAccelDrawLine(x1, y1, x2, y2);
01945 
01946             UNCLIPSUBSURFACE
01947         }
01948 
01949     }
01950 
01951     return ret;
01952 }
01953 
01954 bool MMSFBSurface::drawRectangle(int x, int y, int w, int h) {
01955     bool ret = false;
01956 
01957     // check if initialized
01958     INITCHECK;
01959     if (w < 1 || h < 1)
01960         return false;
01961 
01962     MMSFBSURFACE_WRITE_BUFFER(this).opaque      = false;
01963     MMSFBSURFACE_WRITE_BUFFER(this).transparent = false;
01964 
01965     // finalize previous clear
01966     finClear();
01967 
01968     if (this->allocated_by == MMSFBSurfaceAllocatedBy_ogl) {
01969 #ifdef  __HAVE_OPENGL__
01970         if (!this->is_sub_surface) {
01971 
01972             MMSFBRectangle rect = MMSFBRectangle(x, y, w, h);
01973             mmsfb->bei->drawRectangle(this, rect);
01974 
01975             ret = true;
01976         }
01977         else {
01978             CLIPSUBSURFACE
01979 
01980             MMSFBRectangle rect = MMSFBRectangle(x, y, w, h);
01981             mmsfb->bei->drawRectangle(this, rect);
01982 
01983             UNCLIPSUBSURFACE
01984 
01985             ret = true;
01986         }
01987 #endif
01988     }
01989     else {
01990         // draw lines...
01991         if (w==1)
01992             ret = drawLine(x, y, x, y+h-1);
01993         else
01994         if (h==1)
01995             ret = drawLine(x, y, x+w-1, y);
01996         else {
01997             ret = drawLine(x, y, x+w-1, y);
01998             ret = drawLine(x, y+h-1, x+w-1, y+h-1);
01999             if (h>2) {
02000                 ret = drawLine(x, y+1, x, y+h-2);
02001                 ret = drawLine(x+w-1, y+1, x+w-1, y+h-2);
02002             }
02003         }
02004     }
02005 
02006     return ret;
02007 }
02008 
02009 bool MMSFBSurface::checkDrawingStatus(int x, int y, int w, int h,
02010                                       MMSFBRectangle &crect, MMSFBDrawingFlags &drawingflags,
02011                                       MMSFBColor *color, bool force_cleaning) {
02012     if (!color) {
02013         color = &this->config.color;
02014     }
02015 
02016     if (!force_cleaning) {
02017         if (color->a == 0x00) {
02018             // fill color is full transparent
02019             if (this->config.drawingflags & MMSFB_DRAW_BLEND) {
02020                 // nothing to draw
02021                 return false;
02022             }
02023         }
02024     }
02025     else {
02026         // if force_cleaning is set by the caller, we do not check for alpha == 0x00
02027         // note: doClear() will need this to force cleaning the surface
02028     }
02029 
02030 
02031     // check clipping region and calculate final rectangle
02032     if (!this->is_sub_surface) {
02033         if (!calcClip(x, y, w, h, &crect)) {
02034             // rectangle described with x, y, w, h is outside of the surface or clipping rectangle
02035             return false;
02036         }
02037     }
02038     else {
02039         bool outside = false;
02040         CLIPSUBSURFACE
02041         if (!calcClip(x + this->sub_surface_xoff, y + this->sub_surface_yoff, w, h, &crect)) {
02042             // rectangle described with x, y, w, h is outside of the surface or clipping rectangle
02043             outside = true;
02044         }
02045         UNCLIPSUBSURFACE
02046         if (outside) return false;
02047     }
02048 
02049     // set new opaque/transparent status and get drawing flags for it
02050     if (!force_cleaning) {
02051         // starting with drawingflags from config
02052         drawingflags = this->config.drawingflags;
02053     }
02054     else {
02055         // starting with special drawing flags for cleaning surface
02056         drawingflags = MMSFB_DRAW_SRC_PREMULTIPLY;
02057     }
02058     switch (color->a) {
02059     case 0x00:
02060         // fill color is full transparent
02061         switch (drawingflags) {
02062         case MMSFB_DRAW_NOFX:
02063         case MMSFB_DRAW_SRC_PREMULTIPLY:
02064             // note: we use this->config.surface_buffer->sbw and this->config.surface_buffer->sbh
02065             //       because this is the dimension of the real existing buffer
02066             if    ((crect.x <= 0) && (crect.y <= 0)
02067                 && (crect.x + crect.w >= this->config.surface_buffer->sbw)
02068                 && (crect.y + crect.h >= this->config.surface_buffer->sbh)) {
02069                 // fill writes the whole destination surface
02070                 MMSFBSURFACE_WRITE_BUFFER(this).opaque      = false;
02071                 MMSFBSURFACE_WRITE_BUFFER(this).transparent = true;
02072             }
02073             else {
02074                 // let transparent status unchanged
02075                 MMSFBSURFACE_WRITE_BUFFER(this).opaque = false;
02076             }
02077             break;
02078         default:
02079             // after drawing surface is not opaque and not transparent
02080             MMSFBSURFACE_WRITE_BUFFER(this).opaque      = false;
02081             MMSFBSURFACE_WRITE_BUFFER(this).transparent = false;
02082             break;
02083         }
02084         break;
02085 
02086     case 0xff:
02087         // fill color is opaque
02088         // so remove the DRAW_BLEND flag if set
02089         drawingflags = drawingflags & ~MMSFB_DRAW_BLEND;
02090         switch (drawingflags) {
02091         case MMSFB_DRAW_NOFX:
02092         case MMSFB_DRAW_SRC_PREMULTIPLY:
02093             // note: we use this->config.surface_buffer->sbw and this->config.surface_buffer->sbh
02094             //       because this is the dimension of the real existing buffer
02095             if    ((crect.x <= 0) && (crect.y <= 0)
02096                 && (crect.x + crect.w >= this->config.surface_buffer->sbw)
02097                 && (crect.y + crect.h >= this->config.surface_buffer->sbh)) {
02098                 // fill writes the whole destination surface
02099                 MMSFBSURFACE_WRITE_BUFFER(this).opaque      = true;
02100                 MMSFBSURFACE_WRITE_BUFFER(this).transparent = false;
02101             }
02102             else {
02103                 // let opaque status unchanged
02104                 MMSFBSURFACE_WRITE_BUFFER(this).transparent = false;
02105             }
02106             break;
02107         default:
02108             // after drawing surface is not opaque and not transparent
02109             MMSFBSURFACE_WRITE_BUFFER(this).opaque      = false;
02110             MMSFBSURFACE_WRITE_BUFFER(this).transparent = false;
02111             break;
02112         }
02113         break;
02114 
02115     default:
02116         // fill color is semi-transparent
02117         if (!(drawingflags & MMSFB_DRAW_BLEND)) {
02118             // after drawing surface is not opaque
02119             MMSFBSURFACE_WRITE_BUFFER(this).opaque = false;
02120         }
02121 
02122         // after drawing surface is not transparent
02123         MMSFBSURFACE_WRITE_BUFFER(this).transparent = false;
02124         break;
02125     }
02126 
02127     return true;
02128 }
02129 
02130 bool MMSFBSurface::fillRectangle(int x, int y, int w, int h) {
02131     bool        ret = false;
02132 
02133     // check if initialized
02134     INITCHECK;
02135 
02136     if ((this->config.drawingflags & MMSFB_DRAW_BLEND) && this->config.color.a == 0x00) {
02137         // nothing to draw
02138         return true;
02139     }
02140 
02141     if ((((this->config.drawingflags & MMSFB_DRAW_BLEND) == 0) || this->config.color.a == 0xff) && !this->is_sub_surface) {
02142         // we can write color directly to destination without blending
02143         // so we can use clear method instead of fill rectangle
02144         MMSFBRegion clip;
02145         if (getClip(&clip)) {
02146             if (x <= clip.x1 && y <= clip.y1 && x + w - 1 >= clip.x2 && y + h - 1 >= clip.y2) {
02147                 // clear clipped region
02148                 return clear(this->config.color.r, this->config.color.g, this->config.color.b, this->config.color.a);
02149             }
02150         }
02151     }
02152 
02153     if ((w <= 0) || (h <= 0)) {
02154         // use full surface
02155         x = 0;
02156         y = 0;
02157         w = this->config.w;
02158         h = this->config.h;
02159     }
02160 
02161     // save opaque/transparent status
02162     bool opaque_saved       = MMSFBSURFACE_WRITE_BUFFER(this).opaque;
02163     bool transparent_saved  = MMSFBSURFACE_WRITE_BUFFER(this).transparent;
02164 
02165     // get final rectangle and new opaque/transparent status
02166     MMSFBRectangle crect;
02167     MMSFBDrawingFlags drawingflags;
02168     if (!checkDrawingStatus(x, y, w, h, crect, drawingflags)) {
02169         // nothing to draw
02170         return true;
02171     }
02172 
02173     // finalize previous clear
02174     finClear();
02175 
02176     if (this->allocated_by == MMSFBSurfaceAllocatedBy_dfb) {
02177 #ifdef  __HAVE_DIRECTFB__
02178         DFBResult   dfbres;
02179         D_DEBUG_AT( MMS_Surface, "fill( %d,%d - %dx%d ) <- %dx%d, %02x %02x %02x %02x\n",
02180                     x, y, w, h, this->config.surface_buffer->sbw, this->config.surface_buffer->sbh,
02181                     this->config.color.a, this->config.color.r, this->config.color.g, this->config.color.b );
02182         MMSFB_TRACE();
02183 
02184         /* fill rectangle */
02185         if (!this->is_sub_surface) {
02186             if (!extendedAccelFillRectangle(crect.x, crect.y, crect.w, crect.h, this->config.drawingflags))
02187                 if ((dfbres=this->dfb_surface->FillRectangle(this->dfb_surface, x, y, w, h)) != DFB_OK) {
02188                     MMSFB_SetError(dfbres, "IDirectFBSurface::FillRectangle() failed");
02189                     return false;
02190                 }
02191             ret = true;
02192         }
02193         else {
02194 
02195 #ifndef USE_DFB_SUBSURFACE
02196             CLIPSUBSURFACE
02197 
02198             SETSUBSURFACE_DRAWINGFLAGS;
02199 #endif
02200 
02201             if (extendedAccelFillRectangle(crect.x, crect.y, crect.w, crect.h, this->config.drawingflags))
02202                 ret = true;
02203             else
02204                 if (this->dfb_surface->FillRectangle(this->dfb_surface, x, y, w, h) == DFB_OK)
02205                     ret = true;
02206 
02207 #ifndef USE_DFB_SUBSURFACE
02208             RESETSUBSURFACE_DRAWINGFLAGS;
02209 
02210             UNCLIPSUBSURFACE
02211 #endif
02212         }
02213 #endif
02214     }
02215     if (this->allocated_by == MMSFBSurfaceAllocatedBy_ogl) {
02216 #ifdef  __HAVE_OPENGL__
02217         mmsfb->bei->fillRectangle(this, crect, drawingflags);
02218         ret = true;
02219 #endif
02220     }
02221     else {
02222         ret = extendedAccelFillRectangle(crect.x, crect.y, crect.w, crect.h, drawingflags);
02223     }
02224 
02225     if (!ret) {
02226         // restore opaque/transparent status
02227         MMSFBSURFACE_WRITE_BUFFER(this).opaque      = opaque_saved;
02228         MMSFBSURFACE_WRITE_BUFFER(this).transparent = transparent_saved;
02229     }
02230 
02231     return ret;
02232 }
02233 
02234 bool MMSFBSurface::drawTriangle(int x1, int y1, int x2, int y2, int x3, int y3) {
02235     MMSFB_BREAK();
02236 
02237     bool ret = false;
02238 
02239     // check if initialized
02240     INITCHECK;
02241 
02242     MMSFBSURFACE_WRITE_BUFFER(this).opaque      = false;
02243     MMSFBSURFACE_WRITE_BUFFER(this).transparent = false;
02244 
02245     // finalize previous clear
02246     finClear();
02247 
02248     if (this->allocated_by == MMSFBSurfaceAllocatedBy_ogl) {
02249 #ifdef  __HAVE_OPENGL__
02250         if (!this->is_sub_surface) {
02251 
02252             MMSFBTriangle triangle = MMSFBTriangle(x1, y1, x2, y2, x3, y3);
02253             mmsfb->bei->drawTriangle(this, triangle);
02254 
02255             ret = true;
02256         }
02257         else {
02258             CLIPSUBSURFACE
02259 
02260             MMSFBTriangle triangle = MMSFBTriangle(x1, y1, x2, y2, x3, y3);
02261             mmsfb->bei->drawTriangle(this, triangle);
02262 
02263             UNCLIPSUBSURFACE
02264 
02265             ret = true;
02266         }
02267 #endif
02268     }
02269     else {
02270         // draw triangle
02271         drawLine(x1, y1, x2, y2);
02272         drawLine(x1, y1, x3, y3);
02273         drawLine(x2, y2, x3, y3);
02274         ret = true;
02275     }
02276 
02277     return ret;
02278 }
02279 
02280 bool MMSFBSurface::fillTriangle(int x1, int y1, int x2, int y2, int x3, int y3) {
02281     bool ret = false;
02282 
02283     // check if initialized
02284     INITCHECK;
02285 
02286     MMSFBSURFACE_WRITE_BUFFER(this).opaque      = false;
02287     MMSFBSURFACE_WRITE_BUFFER(this).transparent = false;
02288 
02289     // finalize previous clear
02290     finClear();
02291 
02292     if (this->allocated_by == MMSFBSurfaceAllocatedBy_dfb) {
02293 #ifdef  __HAVE_DIRECTFB__
02294         DFBResult   dfbres;
02295         MMSFB_BREAK();
02296 
02297         // fill triangle
02298         if (!this->is_sub_surface) {
02299             if ((dfbres=this->dfb_surface->FillTriangle(this->dfb_surface, x1, y1, x2, y2, x3, y3)) != DFB_OK) {
02300                 MMSFB_SetError(dfbres, "IDirectFBSurface::FillTriangle() failed");
02301                 return false;
02302             }
02303         }
02304         else {
02305 
02306 #ifndef USE_DFB_SUBSURFACE
02307             CLIPSUBSURFACE
02308 
02309             x1+=this->sub_surface_xoff;
02310             y1+=this->sub_surface_yoff;
02311             x2+=this->sub_surface_xoff;
02312             y2+=this->sub_surface_yoff;
02313             x3+=this->sub_surface_xoff;
02314             y3+=this->sub_surface_yoff;
02315 
02316             SETSUBSURFACE_DRAWINGFLAGS;
02317 #endif
02318 
02319             this->dfb_surface->FillTriangle(this->dfb_surface, x1, y1, x2, y2, x3, y3);
02320 
02321 #ifndef USE_DFB_SUBSURFACE
02322             RESETSUBSURFACE_DRAWINGFLAGS;
02323 
02324             UNCLIPSUBSURFACE
02325 #endif
02326 
02327         }
02328 
02329         ret = true;
02330 #endif
02331     }
02332     else
02333     if (this->allocated_by == MMSFBSurfaceAllocatedBy_ogl) {
02334 #ifdef  __HAVE_OPENGL__
02335         if (!this->is_sub_surface) {
02336 
02337             MMSFBTriangle triangle = MMSFBTriangle(x1, y1, x2, y2, x3, y3);
02338             mmsfb->bei->fillTriangle(this, triangle);
02339 
02340             ret = true;
02341         }
02342         else {
02343             CLIPSUBSURFACE
02344 
02345             MMSFBTriangle triangle = MMSFBTriangle(x1, y1, x2, y2, x3, y3);
02346             mmsfb->bei->fillTriangle(this, triangle);
02347 
02348             UNCLIPSUBSURFACE
02349 
02350             ret = true;
02351         }
02352 #endif
02353     }
02354     else {
02355         //TODO
02356         ret = true;
02357     }
02358 
02359     return ret;
02360 }
02361 
02362 bool MMSFBSurface::drawCircle(int x, int y, int radius, int start_octant, int end_octant) {
02363 
02364     MMSFB_BREAK();
02365 
02366     /* check if initialized */
02367     INITCHECK;
02368 
02369     MMSFBSURFACE_WRITE_BUFFER(this).opaque      = false;
02370     MMSFBSURFACE_WRITE_BUFFER(this).transparent = false;
02371 
02372     // finalize previous clear
02373     finClear();
02374 
02375     /* draw circle */
02376     if (end_octant < start_octant) end_octant = start_octant;
02377     if ((start_octant<=4)&&(end_octant>=3))
02378         drawLine(x, y + radius, x, y + radius);
02379     if ((start_octant==0)||(end_octant==7))
02380         drawLine(x, y - radius, x, y - radius);
02381     if ((start_octant<=2)&&(end_octant>=1))
02382         drawLine(x + radius, y, x + radius, y);
02383     if ((start_octant<=6)&&(end_octant>=5))
02384         drawLine(x - radius, y, x - radius, y);
02385     int mr = radius * radius;
02386     int mx = 1;
02387     int my = (int) (sqrt(mr - 1) + 0.5);
02388 
02389     while (mx < my) {
02390         if ((start_octant<=0)&&(end_octant>=0))
02391             drawLine(x + mx, y - my, x + mx, y - my); /* octant 0 */
02392         if ((start_octant<=1)&&(end_octant>=1))
02393             drawLine(x + my, y - mx, x + my, y - mx); /* octant 1 */
02394         if ((start_octant<=2)&&(end_octant>=2))
02395             drawLine(x + my, y + mx, x + my, y + mx); /* octant 2 */
02396         if ((start_octant<=3)&&(end_octant>=3))
02397             drawLine(x + mx, y + my, x + mx, y + my); /* octant 3 */
02398         if ((start_octant<=4)&&(end_octant>=4))
02399             drawLine(x - mx, y + my, x - mx, y + my); /* octant 4 */
02400         if ((start_octant<=5)&&(end_octant>=5))
02401             drawLine(x - my, y + mx, x - my, y + mx); /* octant 5 */
02402         if ((start_octant<=6)&&(end_octant>=6))
02403             drawLine(x - my, y - mx, x - my, y - mx); /* octant 6 */
02404         if ((start_octant<=7)&&(end_octant>=7))
02405             drawLine(x - mx, y - my, x - mx, y - my); /* octant 7 */
02406 
02407         mx++;
02408         my = (int) (sqrt(mr - mx*mx) + 0.5);
02409     }
02410 
02411     if (mx == my) {
02412         if ((start_octant<=3)&&(end_octant>=2))
02413             drawLine(x + mx, y + my, x + mx, y + my);
02414         if ((start_octant<=1)&&(end_octant>=0))
02415             drawLine(x + mx, y - my, x + mx, y - my);
02416         if ((start_octant<=5)&&(end_octant>=4))
02417             drawLine(x - mx, y + my, x - mx, y + my);
02418         if ((start_octant<=7)&&(end_octant>=6))
02419             drawLine(x - mx, y - my, x - mx, y - my);
02420     }
02421 
02422     return true;
02423 }
02424 
02425 
02426 
02427 bool MMSFBSurface::setBlittingFlags(MMSFBBlittingFlags flags) {
02428 
02429     // check if initialized
02430     INITCHECK;
02431 
02432     if (this->allocated_by == MMSFBSurfaceAllocatedBy_dfb) {
02433 #ifdef  __HAVE_DIRECTFB__
02434         DFBResult   dfbres;
02435 
02436         if ((flags & MMSFB_BLIT_BLEND_ALPHACHANNEL)||(flags & MMSFB_BLIT_BLEND_COLORALPHA)) {
02437             // if we do alpha channel blitting, we have to change the default settings to become correct results
02438             if (this->config.surface_buffer->alphachannel)
02439                 dfb_surface->SetSrcBlendFunction(dfb_surface,(DFBSurfaceBlendFunction)DSBF_ONE);
02440             else
02441                 dfb_surface->SetSrcBlendFunction(dfb_surface,(DFBSurfaceBlendFunction)DSBF_SRCALPHA);
02442             dfb_surface->SetDstBlendFunction(dfb_surface,(DFBSurfaceBlendFunction)(DSBF_INVSRCALPHA));
02443 
02444             if (flags & MMSFB_BLIT_BLEND_COLORALPHA)
02445                  flags = (MMSFBBlittingFlags)(flags | MMSFB_BLIT_SRC_PREMULTCOLOR);
02446         }
02447 
02448         // set the blitting flags
02449         if ((dfbres=this->dfb_surface->SetBlittingFlags(this->dfb_surface, getDFBSurfaceBlittingFlagsFromMMSFBBlittingFlags(flags))) != DFB_OK) {
02450             MMSFB_SetError(dfbres, "IDirectFBSurface::SetBlittingFlags() failed");
02451 
02452             return false;
02453         }
02454 #endif
02455     }
02456 
02457     // save the flags
02458     this->config.blittingflags = flags;
02459 
02460     return true;
02461 }
02462 
02463 bool MMSFBSurface::getBlittingFlags(MMSFBBlittingFlags *flags) {
02464 
02465     // check if initialized
02466     INITCHECK;
02467 
02468     // parameter given?
02469     if (!flags)
02470         return false;
02471 
02472     // save the flags
02473     *flags = this->config.blittingflags;
02474 
02475     return true;
02476 }
02477 
02478 bool MMSFBSurface::extendedLock(MMSFBSurface *src, MMSFBSurfacePlanes *src_planes,
02479                                 MMSFBSurface *dst, MMSFBSurfacePlanes *dst_planes) {
02480 
02481     if (src) {
02482         memset(src_planes, 0, sizeof(MMSFBSurfacePlanes));
02483         src->lock(MMSFB_LOCK_READ, src_planes, false);
02484         if (!src_planes->ptr) {
02485             return false;
02486         }
02487     }
02488     if (dst) {
02489         memset(dst_planes, 0, sizeof(MMSFBSurfacePlanes));
02490         dst->lock(MMSFB_LOCK_WRITE, dst_planes, false);
02491         if (!dst_planes->ptr) {
02492             if (src)
02493                 src->unlock(false);
02494             return false;
02495         }
02496     }
02497 
02498     if (this->surface_invert_lock) {
02499         if (src_planes && dst_planes) {
02500             MMSFBSurfacePlanes t_planes;
02501             t_planes = *src_planes;
02502             *src_planes = *dst_planes;
02503             *dst_planes = t_planes;
02504         }
02505     }
02506 
02507     return true;
02508 }
02509 
02510 void MMSFBSurface::extendedUnlock(MMSFBSurface *src, MMSFBSurface *dst, MMSFBSurfacePlanes *dst_planes) {
02511     if (dst) {
02512         if (dst_planes) {
02513             // save the given dst_planes to the surface buffers array
02514             MMSFBSurfaceBuffer *sb = this->config.surface_buffer;
02515             sb->buffers[sb->currbuffer_write] = *dst_planes;
02516         }
02517         else {
02518             // dst_planes not given, reset the special flags
02519 //          MMSFBSURFACE_WRITE_BUFFER(this).opaque      = false;
02520             MMSFBSURFACE_WRITE_BUFFER(this).transparent = false;
02521         }
02522         dst->unlock(false);
02523     }
02524     if (src) {
02525         src->unlock(false);
02526     }
02527 }
02528 
02529 
02530 bool MMSFBSurface::printMissingCombination(string method, MMSFBSurface *source, MMSFBSurfacePlanes *src_planes,
02531                                            MMSFBSurfacePixelFormat src_pixelformat, int src_width, int src_height,
02532                                            MMSFBBlittingFlags blittingflags) {
02533 #ifdef  __HAVE_DIRECTFB__
02534     // failed, check if it must not
02535     if ((this->allocated_by == MMSFBSurfaceAllocatedBy_dfb) && (!source || (source->allocated_by == MMSFBSurfaceAllocatedBy_dfb)))
02536         return false;
02537 #endif
02538 
02539     // fatal error!!!
02540     // we use our own surface buffer handling, but we have not found a matching routine!!!
02541     // so print the missing combination and return true
02542     printf("DISKO: Missing following combination in method %s\n", method.c_str());
02543     if (source) {
02544         printf("  source type:               %s\n", (source->is_sub_surface)?"subsurface":"surface");
02545         switch (source->allocated_by) {
02546         case MMSFBSurfaceAllocatedBy_dfb:
02547             printf("  source memory:             managed by dfb\n");
02548             break;
02549         case MMSFBSurfaceAllocatedBy_malloc:
02550             printf("  source memory:             managed by disko\n");
02551             break;
02552         case MMSFBSurfaceAllocatedBy_xvimage:
02553             printf("  source memory:             managed by x11 (xvimage)\n");
02554             break;
02555         case MMSFBSurfaceAllocatedBy_ximage:
02556             printf("  source memory:             managed by x11 (ximage)\n");
02557             break;
02558         case MMSFBSurfaceAllocatedBy_ogl:
02559             printf("  source memory:             managed by opengl\n");
02560             break;
02561         }
02562         printf("  source pixelformat:        %s\n", getMMSFBPixelFormatString(source->config.surface_buffer->pixelformat).c_str());
02563         printf("  source premultiplied:      %s\n", (source->config.surface_buffer->premultiplied)?"yes":"no");
02564     }
02565     if (src_planes) {
02566         printf("  source type:               surface\n");
02567         printf("  source memory:             extern (0x%08lx, pitch=%d)\n", (unsigned long)src_planes->ptr, src_planes->pitch);
02568         if (src_planes->ptr2) {
02569             printf("                                    (0x%08lx, pitch=%d)\n",  (unsigned long)src_planes->ptr2, src_planes->pitch2);
02570             if (src_planes->ptr3)
02571                 printf("                                    (0x%08lx, pitch=%d)\n",  (unsigned long)src_planes->ptr3, src_planes->pitch3);
02572         }
02573         printf("  source pixelformat:        %s\n", getMMSFBPixelFormatString(src_pixelformat).c_str());
02574     }
02575     printf("  destination type:          %s\n", (this->is_sub_surface)?"subsurface":"surface");
02576     switch (this->allocated_by) {
02577     case MMSFBSurfaceAllocatedBy_dfb:
02578         printf("  destination memory:        managed by dfb\n");
02579         break;
02580     case MMSFBSurfaceAllocatedBy_malloc:
02581         printf("  destination memory:        managed by disko\n");
02582         break;
02583     case MMSFBSurfaceAllocatedBy_xvimage:
02584         printf("  destination memory:        managed by x11 (xvimage)\n");
02585         break;
02586     case MMSFBSurfaceAllocatedBy_ximage:
02587         printf("  destination memory:        managed by x11 (ximage)\n");
02588         break;
02589     case MMSFBSurfaceAllocatedBy_ogl:
02590         printf("  destination memory:        managed by opengl\n");
02591         break;
02592     }
02593     printf("  destination pixelformat:   %s\n", getMMSFBPixelFormatString(this->config.surface_buffer->pixelformat).c_str());
02594     printf("  destination premultiplied: %s\n", (this->config.surface_buffer->premultiplied)?"yes":"no");
02595     printf("  destination color:         r=%d, g=%d, b=%d, a=%d\n", this->config.color.r, this->config.color.g, this->config.color.b, this->config.color.a);
02596     if ((source)||(src_planes)) {
02597         printf("  blitting flags (%06x):  ", blittingflags);
02598         if (blittingflags == MMSFB_BLIT_NOFX)
02599             printf(" NOFX");
02600         if (blittingflags & MMSFB_BLIT_BLEND_ALPHACHANNEL)
02601             printf(" BLEND_ALPHACHANNEL");
02602         if (blittingflags & MMSFB_BLIT_BLEND_COLORALPHA)
02603             printf(" BLEND_COLORALPHA");
02604         if (blittingflags & MMSFB_BLIT_COLORIZE)
02605             printf(" COLORIZE");
02606         if (blittingflags & MMSFB_BLIT_SRC_PREMULTIPLY)
02607             printf(" SRC_PREMULTIPLY");
02608         if (blittingflags & MMSFB_BLIT_ANTIALIASING)
02609             printf(" ANTIALIASING");
02610         printf("\n");
02611     }
02612     else {
02613         printf("  drawing flags (%06x):   ", this->config.drawingflags);
02614         if (this->config.drawingflags == MMSFB_DRAW_NOFX)
02615             printf(" NOFX");
02616         if (this->config.drawingflags & MMSFB_DRAW_BLEND)
02617             printf(" BLEND");
02618         if (this->config.drawingflags & MMSFB_DRAW_SRC_PREMULTIPLY)
02619             printf(" SRC_PREMULTIPLY");
02620         printf("\n");
02621     }
02622     printf("*****\n");
02623     return true;
02624 }
02625 
02626 
02627 
02628 
02629 bool MMSFBSurface::extendedAccelBlitEx(MMSFBSurface *source,
02630                                        MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat, int src_width, int src_height,
02631                                        MMSFBRectangle *src_rect, int x, int y, MMSFBBlittingFlags blittingflags) {
02632 
02633     MMSFBSurfacePlanes my_src_planes;
02634     if (source) {
02635         // premultiplied surface?
02636         if (!source->config.surface_buffer->premultiplied)
02637             return false;
02638 
02639         src_pixelformat = source->config.surface_buffer->pixelformat;
02640         src_width = (!source->root_parent)?source->config.w:source->root_parent->config.w;
02641         src_height = (!source->root_parent)?source->config.h:source->root_parent->config.h;
02642 
02643         // empty source planes
02644         memset(&my_src_planes, 0, sizeof(MMSFBSurfacePlanes));
02645         src_planes = &my_src_planes;
02646     }
02647 
02648     // a few help and clipping values
02649     MMSFBSurfacePlanes dst_planes;
02650     int sx = src_rect->x;
02651     int sy = src_rect->y;
02652     int sw = src_rect->w;
02653     int sh = src_rect->h;
02654     MMSFBRegion clipreg;
02655 #ifndef USE_DFB_SUBSURFACE
02656     if (!this->is_sub_surface) {
02657 #endif
02658         // normal surface or dfb subsurface
02659         if (!this->config.clipped) {
02660             clipreg.x1 = 0;
02661             clipreg.y1 = 0;
02662             clipreg.x2 = this->config.w - 1;
02663             clipreg.y2 = this->config.h - 1;
02664         }
02665         else
02666             clipreg = this->config.clip;
02667 #ifndef USE_DFB_SUBSURFACE
02668     }
02669     else {
02670         // subsurface
02671         if (!this->root_parent->config.clipped) {
02672             clipreg.x1 = 0;
02673             clipreg.y1 = 0;
02674             clipreg.x2 = this->root_parent->config.w - 1;
02675             clipreg.y2 = this->root_parent->config.h - 1;
02676         }
02677         else
02678             clipreg = this->root_parent->config.clip;
02679     }
02680 #endif
02681 
02682     if (x < clipreg.x1) {
02683         // left outside
02684         sx+= clipreg.x1 - x;
02685         sw-= clipreg.x1 - x;
02686         if (sw <= 0)
02687             return true;
02688         x = clipreg.x1;
02689     }
02690     else
02691     if (x > clipreg.x2)
02692         // right outside
02693         return true;
02694     if (y < clipreg.y1) {
02695         // top outside
02696         sy+= clipreg.y1 - y;
02697         sh-= clipreg.y1 - y;
02698         if (sh <= 0)
02699             return true;
02700         y = clipreg.y1;
02701     }
02702     else
02703     if (y > clipreg.y2)
02704         // bottom outside
02705         return true;
02706     if (x + sw - 1 > clipreg.x2)
02707         // to width
02708         sw = clipreg.x2 - x + 1;
02709     if (y + sh - 1 > clipreg.y2)
02710         // to height
02711         sh = clipreg.y2 - y + 1;
02712 
02713     // adjust x/y
02714     if (x < 0) {
02715         sx -= x;
02716         sw += x;
02717         x = 0;
02718     }
02719     if (y < 0) {
02720         sy -= y;
02721         sh += y;
02722         y = 0;
02723     }
02724     if ((sw <= 0)||(sh <= 0))
02725         return true;
02726 
02727     // extract antialiasing flag from blittingflags
02728 //  bool antialiasing = (this->config.blittingflags & MMSFB_BLIT_ANTIALIASING);
02729 //  MMSFBBlittingFlags blittingflags = this->config.blittingflags & ~MMSFB_BLIT_ANTIALIASING;
02730 
02731     // checking pixelformats...
02732     switch (src_pixelformat) {
02733 #ifdef __HAVE_PF_ARGB__
02734     case MMSFB_PF_ARGB:
02735         // source is ARGB
02736         if (this->config.surface_buffer->pixelformat == MMSFB_PF_ARGB) {
02737             // destination is ARGB
02738             if (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_NOFX) {
02739                 // convert without alpha channel
02740                 return blitARGBtoARGB(source, src_planes, src_pixelformat,
02741                                         src_width, src_height, sx, sy, sw, sh,
02742                                         x, y);
02743             }
02744             else
02745             if (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_BLEND_ALPHACHANNEL) {
02746                 // blitting with alpha channel
02747                 return blitARGBtoARGB_BLEND(source, src_planes, src_pixelformat,
02748                                         src_width, src_height, sx, sy, sw, sh,
02749                                         x, y);
02750             }
02751             else
02752             if   ((blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_BLEND_COLORALPHA)
02753                 ||(blittingflags == (MMSFBBlittingFlags)(MMSFB_BLIT_BLEND_ALPHACHANNEL|MMSFB_BLIT_BLEND_COLORALPHA))
02754                 ||(blittingflags == (MMSFBBlittingFlags)(MMSFB_BLIT_BLEND_ALPHACHANNEL|MMSFB_BLIT_BLEND_COLORALPHA|MMSFB_BLIT_SRC_PREMULTCOLOR))) {
02755                 // blitting with alpha channel and coloralpha
02756                 return blitARGBtoARGB_BLEND_COLORALPHA(source, src_planes, src_pixelformat,
02757                                         src_width, src_height, sx, sy, sw, sh,
02758                                         x, y);
02759             }
02760             // does not match
02761             return false;
02762         }
02763         else
02764         if (this->config.surface_buffer->pixelformat == MMSFB_PF_AiRGB) {
02765             // destination is AiRGB
02766             if (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_BLEND_ALPHACHANNEL) {
02767                 // blitting with alpha channel
02768                 return blitARGBtoAiRGB_BLEND(source, src_planes, src_pixelformat,
02769                                         src_width, src_height, sx, sy, sw, sh,
02770                                         x, y);
02771             }
02772 
02773             // does not match
02774             return false;
02775         }
02776         else
02777         if (this->config.surface_buffer->pixelformat == MMSFB_PF_RGB32) {
02778             // destination is RGB32
02779             if (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_NOFX) {
02780                 // convert without alpha channel
02781                 return blitARGBtoRGB32(source, src_planes, src_pixelformat,
02782                                         src_width, src_height, sx, sy, sw, sh,
02783                                         x, y);
02784             }
02785             else
02786             if (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_BLEND_ALPHACHANNEL) {
02787                 // blitting with alpha channel
02788                 return blitARGBtoRGB32_BLEND(source, src_planes, src_pixelformat,
02789                                         src_width, src_height, sx, sy, sw, sh,
02790                                         x, y);
02791             }
02792             else
02793             if   ((blittingflags == (MMSFBBlittingFlags)(MMSFB_BLIT_BLEND_ALPHACHANNEL|MMSFB_BLIT_BLEND_COLORALPHA))
02794                 ||(blittingflags == (MMSFBBlittingFlags)(MMSFB_BLIT_BLEND_ALPHACHANNEL|MMSFB_BLIT_BLEND_COLORALPHA|MMSFB_BLIT_SRC_PREMULTCOLOR))) {
02795                 // blitting with alpha channel and coloralpha
02796                 return blitARGBtoRGB32_BLEND_COLORALPHA(source, src_planes, src_pixelformat,
02797                                         src_width, src_height, sx, sy, sw, sh,
02798                                         x, y);
02799             }
02800             else
02801             if   ((blittingflags == (MMSFBBlittingFlags)(MMSFB_BLIT_BLEND_COLORALPHA))
02802                 ||(blittingflags == (MMSFBBlittingFlags)(MMSFB_BLIT_BLEND_COLORALPHA|MMSFB_BLIT_SRC_PREMULTCOLOR))) {
02803                 // blitting with coloralpha
02804                 return blitARGBtoRGB32_COLORALPHA(source, src_planes, src_pixelformat,
02805                                         src_width, src_height, sx, sy, sw, sh,
02806                                         x, y);
02807             }
02808 
02809             // does not match
02810             return false;
02811         }
02812         else
02813         if (this->config.surface_buffer->pixelformat == MMSFB_PF_RGB16) {
02814             // destination is RGB16 (RGB565)
02815             if (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_NOFX) {
02816                 // convert without alpha channel
02817                 return blitARGBtoRGB16(source, src_planes, src_pixelformat,
02818                                         src_width, src_height, sx, sy, sw, sh,
02819                                         x, y);
02820             }
02821             else
02822             if (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_BLEND_ALPHACHANNEL) {
02823                 // blitting with alpha channel
02824                 return blitARGBtoRGB16_BLEND(source, src_planes, src_pixelformat,
02825                                         src_width, src_height, sx, sy, sw, sh,
02826                                         x, y);
02827             }
02828 
02829             // does not match
02830             return false;
02831         }
02832         else
02833         if (this->config.surface_buffer->pixelformat == MMSFB_PF_ARGB3565) {
02834             // destination is ARGB3565
02835             switch (blittingflags) {
02836             case MMSFB_BLIT_NOFX:
02837                 // convert without alpha channel
02838                 return blitARGBtoARGB3565(source, src_planes, src_pixelformat,
02839                                         src_width, src_height, sx, sy, sw, sh,
02840                                         x, y);
02841 
02842             case MMSFB_BLIT_BLEND_ALPHACHANNEL:
02843                 // blitting with alpha channel
02844                 return blitARGBtoARGB3565_BLEND(source, src_planes, src_pixelformat,
02845                                         src_width, src_height, sx, sy, sw, sh,
02846                                         x, y);
02847             }
02848 
02849             // does not match
02850             return false;
02851         }
02852         else
02853         if (this->config.surface_buffer->pixelformat == MMSFB_PF_YV12) {
02854             // destination is YV12
02855             if (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_NOFX) {
02856                 // blitting without alpha channel
02857                 return blitARGBtoYV12(source, src_planes, src_pixelformat,
02858                                         src_width, src_height, sx, sy, sw, sh,
02859                                         x, y);
02860             }
02861             else
02862             if (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_BLEND_ALPHACHANNEL) {
02863                 // blitting with alpha channel
02864                 return blitARGBtoYV12_BLEND(source, src_planes, src_pixelformat,
02865                                         src_width, src_height, sx, sy, sw, sh,
02866                                         x, y);
02867             }
02868             else
02869             if   ((blittingflags == (MMSFBBlittingFlags)(MMSFB_BLIT_BLEND_ALPHACHANNEL|MMSFB_BLIT_BLEND_COLORALPHA))
02870                 ||(blittingflags == (MMSFBBlittingFlags)(MMSFB_BLIT_BLEND_ALPHACHANNEL|MMSFB_BLIT_BLEND_COLORALPHA|MMSFB_BLIT_SRC_PREMULTCOLOR))) {
02871                 // blitting with alpha channel and coloralpha
02872                 return blitARGBtoYV12_BLEND_COLORALPHA(source, src_planes, src_pixelformat,
02873                                         src_width, src_height, sx, sy, sw, sh,
02874                                         x, y);
02875             }
02876 
02877             // does not match
02878             return false;
02879         }
02880         else
02881         if (this->config.surface_buffer->pixelformat == MMSFB_PF_RGB24) {
02882             // destination is RGB24
02883             if (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_NOFX) {
02884                 // blitting without alpha channel
02885                 return blitARGBtoRGB24(source, src_planes, src_pixelformat,
02886                                         src_width, src_height, sx, sy, sw, sh,
02887                                         x, y);
02888             }
02889             else
02890             if (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_BLEND_ALPHACHANNEL) {
02891                 // blitting with alpha channel
02892                 return blitARGBtoRGB24_BLEND(source, src_planes, src_pixelformat,
02893                                         src_width, src_height, sx, sy, sw, sh,
02894                                         x, y);
02895             }
02896 
02897             // does not match
02898             return false;
02899         }
02900         else
02901         if (this->config.surface_buffer->pixelformat == MMSFB_PF_BGR24) {
02902             // destination is BGR24
02903             if (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_BLEND_ALPHACHANNEL) {
02904                 // blitting with alpha channel
02905                 return blitARGBtoBGR24_BLEND(source, src_planes, src_pixelformat,
02906                                         src_width, src_height, sx, sy, sw, sh,
02907                                         x, y);
02908             }
02909             else
02910             if   ((blittingflags == (MMSFBBlittingFlags)(MMSFB_BLIT_BLEND_ALPHACHANNEL|MMSFB_BLIT_BLEND_COLORALPHA))
02911                 ||(blittingflags == (MMSFBBlittingFlags)(MMSFB_BLIT_BLEND_ALPHACHANNEL|MMSFB_BLIT_BLEND_COLORALPHA|MMSFB_BLIT_SRC_PREMULTCOLOR))) {
02912                 // blitting with alpha channel and coloralpha
02913                 return blitARGBtoBGR24_BLEND_COLORALPHA(source, src_planes, src_pixelformat,
02914                                         src_width, src_height, sx, sy, sw, sh,
02915                                         x, y);
02916             }
02917 
02918             // does not match
02919             return false;
02920         }
02921         else
02922         if (this->config.surface_buffer->pixelformat == MMSFB_PF_BGR555) {
02923             // destination is BGR555
02924             if (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_BLEND_ALPHACHANNEL) {
02925                 // blitting with alpha channel
02926                 return blitARGBtoBGR555_BLEND(source, src_planes, src_pixelformat,
02927                                         src_width, src_height, sx, sy, sw, sh,
02928                                         x, y);
02929             }
02930 
02931             // does not match
02932             return false;
02933         }
02934 
02935         // does not match
02936         return false;
02937 #endif
02938 
02939 #ifdef __HAVE_PF_RGB32__
02940     case MMSFB_PF_RGB32:
02941         // source is RGB32
02942         if (this->config.surface_buffer->pixelformat == MMSFB_PF_RGB32) {
02943             // destination is RGB32
02944             if    ((blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_NOFX)
02945                 || (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_BLEND_ALPHACHANNEL)) {
02946                 // blitting without alpha channel
02947                 return blitRGB32toRGB32(source, src_planes, src_pixelformat,
02948                                         src_width, src_height, sx, sy, sw, sh,
02949                                         x, y);
02950             }
02951             else
02952             if (blittingflags == (MMSFBBlittingFlags)(MMSFB_BLIT_BLEND_COLORALPHA)) {
02953                 // blitting with coloralpha
02954                 return blitRGB32toRGB32_COLORALPHA(source, src_planes, src_pixelformat,
02955                                         src_width, src_height, sx, sy, sw, sh,
02956                                         x, y);
02957             }
02958 
02959             // does not match
02960             return false;
02961         }
02962         // source is RGB32
02963         if (this->config.surface_buffer->pixelformat == MMSFB_PF_ARGB) {
02964             // destination is RGB32
02965             if    ((blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_NOFX)
02966                 || (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_BLEND_ALPHACHANNEL)) {
02967                 // blitting without alpha channel
02968                 return blitRGB32toARGB(source, src_planes, src_pixelformat,
02969                                         src_width, src_height, sx, sy, sw, sh,
02970                                         x, y);
02971             }
02972 
02973             // does not match
02974             return false;
02975         }
02976 
02977         // does not match
02978         return false;
02979 #endif
02980 
02981 #ifdef __HAVE_PF_RGB16__
02982     case MMSFB_PF_RGB16:
02983         // source is RGB16 (RGB565)
02984         if (this->config.surface_buffer->pixelformat == MMSFB_PF_RGB16) {
02985             // destination is RGB16 (RGB565)
02986             if    ((blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_NOFX)
02987                 || (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_BLEND_ALPHACHANNEL)) {
02988                 // blitting without alpha channel
02989                 return blitRGB16toRGB16(source, src_planes, src_pixelformat,
02990                                         src_width, src_height, sx, sy, sw, sh,
02991                                         x, y);
02992             }
02993 
02994             // does not match
02995             return false;
02996         }
02997         else
02998         if (this->config.surface_buffer->pixelformat == MMSFB_PF_ARGB) {
02999             // destination is ARGB
03000             if    ((blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_NOFX)
03001                 || (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_BLEND_ALPHACHANNEL)) {
03002                 // blitting without alpha channel
03003                 return blitRGB16toARGB(source, src_planes, src_pixelformat,
03004                                         src_width, src_height, sx, sy, sw, sh,
03005                                         x, y);
03006             }
03007 
03008             // does not match
03009             return false;
03010         }
03011         else
03012         if (this->config.surface_buffer->pixelformat == MMSFB_PF_RGB32) {
03013             // destination is RGB32
03014             if (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_NOFX) {
03015                 // blitting without alpha channel
03016                 return blitRGB16toRGB32(source, src_planes, src_pixelformat,
03017                                         src_width, src_height, sx, sy, sw, sh,
03018                                         x, y);
03019             }
03020 
03021             // does not match
03022             return false;
03023         }
03024 
03025         // does not match
03026         return false;
03027 #endif
03028 
03029 #ifdef __HAVE_PF_AiRGB__
03030     case MMSFB_PF_AiRGB:
03031         // source is AiRGB
03032         if (this->config.surface_buffer->pixelformat == MMSFB_PF_AiRGB) {
03033             // destination is AiRGB
03034             if (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_NOFX) {
03035                 // convert without alpha channel
03036                 return blitAiRGBtoAiRGB(source, src_planes, src_pixelformat,
03037                                         src_width, src_height, sx, sy, sw, sh,
03038                                         x, y);
03039             }
03040             else
03041             if (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_BLEND_ALPHACHANNEL) {
03042                 // blitting with alpha channel
03043                 return blitAiRGBtoAiRGB_BLEND(source, src_planes, src_pixelformat,
03044                                         src_width, src_height, sx, sy, sw, sh,
03045                                         x, y);
03046             }
03047             else
03048             if   ((blittingflags == (MMSFBBlittingFlags)(MMSFB_BLIT_BLEND_ALPHACHANNEL|MMSFB_BLIT_BLEND_COLORALPHA))
03049                 ||(blittingflags == (MMSFBBlittingFlags)(MMSFB_BLIT_BLEND_ALPHACHANNEL|MMSFB_BLIT_BLEND_COLORALPHA|MMSFB_BLIT_SRC_PREMULTCOLOR))) {
03050                 // blitting with alpha channel and coloralpha
03051                 return blitAiRGBtoAiRGB_BLEND_COLORALPHA(source, src_planes, src_pixelformat,
03052                                         src_width, src_height, sx, sy, sw, sh,
03053                                         x, y);
03054             }
03055 
03056             // does not match
03057             return false;
03058         }
03059         else
03060         if (this->config.surface_buffer->pixelformat == MMSFB_PF_ARGB) {
03061             if (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_NOFX) {
03062                 // convert without alpha channel
03063                 return blitAiRGBtoARGB(source, src_planes, src_pixelformat,
03064                                         src_width, src_height, sx, sy, sw, sh,
03065                                         x, y);
03066             } else
03067             if (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_BLEND_ALPHACHANNEL) {
03068                 // blitting with alpha channel
03069                 return blitAiRGBtoARGB_BLEND(source, src_planes, src_pixelformat,
03070                                         src_width, src_height, sx, sy, sw, sh,
03071                                         x, y);
03072             }
03073         }
03074         else if (this->config.surface_buffer->pixelformat == MMSFB_PF_RGB16) {
03075             // destination is RGB16 (RGB565)
03076             if (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_NOFX) {
03077                 // convert without alpha channel
03078                 return blitAiRGBtoRGB16(source, src_planes, src_pixelformat,
03079                                         src_width, src_height, sx, sy, sw, sh,
03080                                         x, y);
03081             }
03082             else
03083             if (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_BLEND_ALPHACHANNEL) {
03084                 // blitting with alpha channel
03085                 return blitAiRGBtoRGB16_BLEND(source, src_planes, src_pixelformat,
03086                                         src_width, src_height, sx, sy, sw, sh,
03087                                         x, y);
03088             }
03089 
03090             // does not match
03091             return false;
03092         }
03093 
03094         // does not match
03095         return false;
03096 #endif
03097 
03098 #ifdef __HAVE_PF_AYUV__
03099     case MMSFB_PF_AYUV:
03100         // source is AYUV
03101         if (this->config.surface_buffer->pixelformat == MMSFB_PF_AYUV) {
03102             // destination is AYUV
03103             if (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_NOFX) {
03104                 // convert without alpha channel
03105                 return blitAYUVtoAYUV(source, src_planes, src_pixelformat,
03106                                         src_width, src_height, sx, sy, sw, sh,
03107                                         x, y);
03108             }
03109             else
03110             if (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_BLEND_ALPHACHANNEL) {
03111                 // blitting with alpha channel
03112                 return blitAYUVtoAYUV_BLEND(source, src_planes, src_pixelformat,
03113                                         src_width, src_height, sx, sy, sw, sh,
03114                                         x, y);
03115             }
03116             else
03117             if   ((blittingflags == (MMSFBBlittingFlags)(MMSFB_BLIT_BLEND_ALPHACHANNEL|MMSFB_BLIT_BLEND_COLORALPHA))
03118                 ||(blittingflags == (MMSFBBlittingFlags)(MMSFB_BLIT_BLEND_ALPHACHANNEL|MMSFB_BLIT_BLEND_COLORALPHA|MMSFB_BLIT_SRC_PREMULTCOLOR))) {
03119                 // blitting with alpha channel and coloralpha
03120                 return blitAYUVtoAYUV_BLEND_COLORALPHA(source, src_planes, src_pixelformat,
03121                                         src_width, src_height, sx, sy, sw, sh,
03122                                         x, y);
03123             }
03124 
03125             // does not match
03126             return false;
03127         }
03128         else
03129         if (this->config.surface_buffer->pixelformat == MMSFB_PF_RGB16) {
03130             // destination is RGB16 (RGB565)
03131             if (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_NOFX) {
03132                 // convert without alpha channel
03133                 return blitAYUVtoRGB16(source, src_planes, src_pixelformat,
03134                                         src_width, src_height, sx, sy, sw, sh,
03135                                         x, y);
03136             }
03137             else
03138             if (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_BLEND_ALPHACHANNEL) {
03139                 // blitting with alpha channel
03140                 return blitAYUVtoRGB16_BLEND(source, src_planes, src_pixelformat,
03141                                         src_width, src_height, sx, sy, sw, sh,
03142                                         x, y);
03143             }
03144 
03145             // does not match
03146             return false;
03147         }
03148         else
03149         if (this->config.surface_buffer->pixelformat == MMSFB_PF_YV12) {
03150             // destination is YV12
03151             if (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_BLEND_ALPHACHANNEL) {
03152                 // blitting with alpha channel
03153                 return blitAYUVtoYV12_BLEND(source, src_planes, src_pixelformat,
03154                                         src_width, src_height, sx, sy, sw, sh,
03155                                         x, y);
03156             }
03157             else
03158             if   ((blittingflags == (MMSFBBlittingFlags)(MMSFB_BLIT_BLEND_ALPHACHANNEL|MMSFB_BLIT_BLEND_COLORALPHA))
03159                 ||(blittingflags == (MMSFBBlittingFlags)(MMSFB_BLIT_BLEND_ALPHACHANNEL|MMSFB_BLIT_BLEND_COLORALPHA|MMSFB_BLIT_SRC_PREMULTCOLOR))) {
03160                 // blitting with alpha channel and coloralpha
03161                 return blitAYUVtoYV12_BLEND_COLORALPHA(source, src_planes, src_pixelformat,
03162                                         src_width, src_height, sx, sy, sw, sh,
03163                                         x, y);
03164             }
03165 
03166             // does not match
03167             return false;
03168         }
03169 
03170         // does not match
03171         return false;
03172 #endif
03173 
03174 #ifdef __HAVE_PF_YV12__
03175     case MMSFB_PF_YV12:
03176         // source is YV12
03177         if (this->config.surface_buffer->pixelformat == MMSFB_PF_YV12) {
03178             // destination is YV12
03179             if   ((blittingflags == MMSFB_BLIT_NOFX)
03180                 ||(blittingflags == MMSFB_BLIT_BLEND_ALPHACHANNEL)) {
03181                 // blitting without alpha channel
03182                 return blitYV12toYV12(source, src_planes, src_pixelformat,
03183                                         src_width, src_height, sx, sy, sw, sh,
03184                                         x, y);
03185             }
03186 
03187             // does not match
03188             return false;
03189         }
03190         else
03191         if (this->config.surface_buffer->pixelformat == MMSFB_PF_RGB32) {
03192             // destination is RGB32
03193             if   ((blittingflags == MMSFB_BLIT_NOFX)
03194                 ||(blittingflags == MMSFB_BLIT_BLEND_ALPHACHANNEL)) {
03195                 // convert without alpha channel
03196                 return blitYV12toRGB32(source, src_planes, src_pixelformat,
03197                                         src_width, src_height, sx, sy, sw, sh,
03198                                         x, y);
03199             }
03200 
03201             // does not match
03202             return false;
03203         }
03204 
03205         // does not match
03206         return false;
03207 #endif
03208 
03209 #ifdef __HAVE_PF_I420__
03210     case MMSFB_PF_I420:
03211         // source is I420
03212         if (this->config.surface_buffer->pixelformat == MMSFB_PF_I420) {
03213             // destination is I420
03214             if   ((blittingflags == MMSFB_BLIT_NOFX)
03215                 ||(blittingflags == MMSFB_BLIT_BLEND_ALPHACHANNEL)) {
03216                 // blitting without alpha channel
03217                 return blitI420toI420(source, src_planes, src_pixelformat,
03218                                         src_width, src_height, sx, sy, sw, sh,
03219                                         x, y);
03220             }
03221 
03222             // does not match
03223             return false;
03224         }
03225         else
03226         if (this->config.surface_buffer->pixelformat == MMSFB_PF_YV12) {
03227             // destination is YV12
03228             if   ((blittingflags == MMSFB_BLIT_NOFX)
03229                 ||(blittingflags == MMSFB_BLIT_BLEND_ALPHACHANNEL)) {
03230                 // convert without alpha channel
03231                 return blitI420toYV12(source, src_planes, src_pixelformat,
03232                                         src_width, src_height, sx, sy, sw, sh,
03233                                         x, y);
03234             }
03235 
03236             // does not match
03237             return false;
03238         }
03239 
03240         // does not match
03241         return false;
03242 #endif
03243 
03244 #ifdef __HAVE_PF_YUY2__
03245     case MMSFB_PF_YUY2:
03246         // source is YUY2
03247         if (this->config.surface_buffer->pixelformat == MMSFB_PF_YUY2) {
03248             // destination is YV12
03249             if   ((blittingflags == MMSFB_BLIT_NOFX)
03250                 ||(blittingflags == MMSFB_BLIT_BLEND_ALPHACHANNEL)) {
03251                 // blitting without alpha channel
03252                 return blitYUY2toYUY2(source, src_planes, src_pixelformat,
03253                                         src_width, src_height, sx, sy, sw, sh,
03254                                         x, y);
03255             }
03256 
03257             // does not match
03258             return false;
03259         }
03260         else
03261         if (this->config.surface_buffer->pixelformat == MMSFB_PF_YV12) {
03262             // destination is YV12
03263             if   ((blittingflags == MMSFB_BLIT_NOFX)
03264                 ||(blittingflags == MMSFB_BLIT_BLEND_ALPHACHANNEL)) {
03265                 // convert without alpha channel
03266                 return blitYUY2toYV12(source, src_planes, src_pixelformat,
03267                                         src_width, src_height, sx, sy, sw, sh,
03268                                         x, y);
03269             }
03270 
03271             // does not match
03272             return false;
03273         }
03274 
03275         // does not match
03276         return false;
03277 #endif
03278 
03279 #ifdef __HAVE_PF_RGB24__
03280     case MMSFB_PF_RGB24:
03281         // source is RGB24
03282         if (this->config.surface_buffer->pixelformat == MMSFB_PF_RGB24) {
03283             // destination is RGB24
03284             if    ((blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_NOFX)
03285                 || (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_BLEND_ALPHACHANNEL)) {
03286                 // blitting without alpha channel
03287                 return blitRGB24toRGB24(source, src_planes, src_pixelformat,
03288                                         src_width, src_height, sx, sy, sw, sh,
03289                                         x, y);
03290             }
03291 
03292             // does not match
03293             return false;
03294         }
03295         else
03296         if (this->config.surface_buffer->pixelformat == MMSFB_PF_ARGB) {
03297             // destination is ARGB
03298             if (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_NOFX) {
03299                 // convert without alpha channel
03300                 return blitRGB24toARGB(source, src_planes, src_pixelformat,
03301                                         src_width, src_height, sx, sy, sw, sh,
03302                                         x, y);
03303             }
03304 
03305             // does not match
03306             return false;
03307         }
03308         else
03309         if (this->config.surface_buffer->pixelformat == MMSFB_PF_RGB32) {
03310             // destination is RGB32
03311             if    ((blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_NOFX)
03312                 || (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_BLEND_ALPHACHANNEL)) {
03313                 // convert without alpha channel
03314                 return blitRGB24toRGB32(source, src_planes, src_pixelformat,
03315                                         src_width, src_height, sx, sy, sw, sh,
03316                                         x, y);
03317             }
03318 
03319             // does not match
03320             return false;
03321         }
03322         else
03323         if (this->config.surface_buffer->pixelformat == MMSFB_PF_YV12) {
03324             // destination is YV12
03325             if    ((blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_NOFX)
03326                 || (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_BLEND_ALPHACHANNEL)) {
03327                 // convert without alpha channel
03328                 return blitRGB24toYV12(source, src_planes, src_pixelformat,
03329                                         src_width, src_height, sx, sy, sw, sh,
03330                                         x, y);
03331             }
03332 
03333             // does not match
03334             return false;
03335         }
03336 
03337         // does not match
03338         return false;
03339 #endif
03340 
03341 #ifdef __HAVE_PF_BGR24__
03342     case MMSFB_PF_BGR24:
03343         // source is BGR24
03344         if (this->config.surface_buffer->pixelformat == MMSFB_PF_BGR24) {
03345             // destination is BGR24
03346             if    ((blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_NOFX)
03347                 || (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_BLEND_ALPHACHANNEL)) {
03348                 // blitting without alpha channel
03349                 return blitBGR24toBGR24(source, src_planes, src_pixelformat,
03350                                         src_width, src_height, sx, sy, sw, sh,
03351                                         x, y);
03352             }
03353             else
03354             if (blittingflags == (MMSFBBlittingFlags)(MMSFB_BLIT_BLEND_COLORALPHA)) {
03355                 // blitting with coloralpha
03356                 return blitBGR24toBGR24_COLORALPHA(source, src_planes, src_pixelformat,
03357                                         src_width, src_height, sx, sy, sw, sh,
03358                                         x, y);
03359             }
03360 
03361             // does not match
03362             return false;
03363         }
03364 
03365         // does not match
03366         return false;
03367 #endif
03368 
03369 #ifdef __HAVE_PF_ARGB3565__
03370     case MMSFB_PF_ARGB3565:
03371         // source is ARGB3565
03372         if (this->config.surface_buffer->pixelformat == MMSFB_PF_ARGB3565) {
03373             // destination is ARGB3565
03374             if (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_NOFX) {
03375                 // blitting with alpha channel
03376                 return blitARGB3565toARGB3565(source, src_planes, src_pixelformat,
03377                                         src_width, src_height, sx, sy, sw, sh,
03378                                         x, y);
03379             }
03380 
03381             // does not match
03382             return false;
03383         }
03384 
03385         // does not match
03386         return false;
03387 #endif
03388 
03389 #ifdef __HAVE_PF_ARGB4444__
03390     case MMSFB_PF_ARGB4444:
03391         // source is ARGB4444
03392         if (this->config.surface_buffer->pixelformat == MMSFB_PF_ARGB4444) {
03393             // destination is ARGB4444
03394             if (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_NOFX) {
03395                 // blitting with alpha channel
03396                 return blitARGB4444toARGB4444(source, src_planes, src_pixelformat,
03397                                         src_width, src_height, sx, sy, sw, sh,
03398                                         x, y);
03399             }
03400             else
03401             if (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_BLEND_ALPHACHANNEL) {
03402                 // blitting with alpha channel
03403                 return blitARGB4444toARGB4444_BLEND(source, src_planes, src_pixelformat,
03404                                         src_width, src_height, sx, sy, sw, sh,
03405                                         x, y);
03406             }
03407             else
03408             if   ((blittingflags == (MMSFBBlittingFlags)(MMSFB_BLIT_BLEND_ALPHACHANNEL|MMSFB_BLIT_BLEND_COLORALPHA))
03409                 ||(blittingflags == (MMSFBBlittingFlags)(MMSFB_BLIT_BLEND_ALPHACHANNEL|MMSFB_BLIT_BLEND_COLORALPHA|MMSFB_BLIT_SRC_PREMULTCOLOR))) {
03410                 // blitting with alpha channel and coloralpha
03411                 return blitARGB4444toARGB4444_BLEND_COLORALPHA(source, src_planes, src_pixelformat,
03412                                         src_width, src_height, sx, sy, sw, sh,
03413                                         x, y);
03414             }
03415 
03416             // does not match
03417             return false;
03418         }
03419         else
03420         if (this->config.surface_buffer->pixelformat == MMSFB_PF_RGB32) {
03421             // destination is RGB32
03422             if (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_BLEND_ALPHACHANNEL) {
03423                 // blitting with alpha channel
03424                 return blitARGB4444toRGB32_BLEND(source, src_planes, src_pixelformat,
03425                                         src_width, src_height, sx, sy, sw, sh,
03426                                         x, y);
03427             }
03428             else
03429             if   ((blittingflags == (MMSFBBlittingFlags)(MMSFB_BLIT_BLEND_ALPHACHANNEL|MMSFB_BLIT_BLEND_COLORALPHA))
03430                 ||(blittingflags == (MMSFBBlittingFlags)(MMSFB_BLIT_BLEND_ALPHACHANNEL|MMSFB_BLIT_BLEND_COLORALPHA|MMSFB_BLIT_SRC_PREMULTCOLOR))) {
03431                 // blitting with alpha channel and coloralpha
03432                 return blitARGB4444toRGB32_BLEND_COLORALPHA(source, src_planes, src_pixelformat,
03433                                         src_width, src_height, sx, sy, sw, sh,
03434                                         x, y);
03435             }
03436 
03437             // does not match
03438             return false;
03439         }
03440 
03441         // does not match
03442         return false;
03443 #endif
03444 
03445 #ifdef __HAVE_PF_BGR555__
03446     case MMSFB_PF_BGR555:
03447         // source is BGR555
03448         if (this->config.surface_buffer->pixelformat == MMSFB_PF_BGR555) {
03449             // destination is BGR555
03450             if    ((blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_NOFX)
03451                 || (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_BLEND_ALPHACHANNEL)) {
03452                 // blitting without alpha channel
03453                 return blitBGR555toBGR555(source, src_planes, src_pixelformat,
03454                                         src_width, src_height, sx, sy, sw, sh,
03455                                         x, y);
03456             }
03457 
03458             // does not match
03459             return false;
03460         }
03461 
03462         // does not match
03463         return false;
03464 #endif
03465 
03466     default:
03467         // does not match
03468         break;
03469     }
03470 
03471 
03472     // does not match
03473     return false;
03474 }
03475 
03476 bool MMSFBSurface::extendedAccelBlit(MMSFBSurface *source, MMSFBRectangle *src_rect,
03477                                            int x, int y, MMSFBBlittingFlags blittingflags) {
03478     // extended acceleration on?
03479     if (!this->extendedaccel)
03480         return false;
03481 
03482     if (!extendedAccelBlitEx(source,
03483                              NULL, MMSFB_PF_NONE, 0, 0,
03484                              src_rect, x, y, blittingflags))
03485         return printMissingCombination("extendedAccelBlit()", source, NULL, MMSFB_PF_NONE, 0, 0, blittingflags);
03486     else
03487         return true;
03488 }
03489 
03490 bool MMSFBSurface::extendedAccelBlitBuffer(MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat, int src_width, int src_height,
03491                                            MMSFBRectangle *src_rect, int x, int y, MMSFBBlittingFlags blittingflags) {
03492     // extended acceleration on?
03493     if (!this->extendedaccel)
03494         return false;
03495 
03496     if (!extendedAccelBlitEx(NULL,
03497                              src_planes, src_pixelformat, src_width, src_height,
03498                              src_rect, x, y, blittingflags))
03499         return printMissingCombination("extendedAccelBlitBuffer()", NULL,
03500                             src_planes, src_pixelformat, src_width, src_height, blittingflags);
03501     else
03502         return true;
03503 }
03504 
03505 
03506 
03507 
03508 bool MMSFBSurface::extendedAccelStretchBlitEx(MMSFBSurface *source,
03509                                               MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat, int src_width, int src_height,
03510                                               MMSFBRectangle *src_rect, MMSFBRectangle *dest_rect,
03511                                               MMSFBRectangle *real_dest_rect, bool calc_dest_rect) {
03512     MMSFBSurfacePlanes my_src_planes;
03513     if (source) {
03514         // premultiplied surface?
03515         if (!source->config.surface_buffer->premultiplied)
03516             return false;
03517 
03518         src_pixelformat = source->config.surface_buffer->pixelformat;
03519         src_width = (!source->root_parent)?source->config.w:source->root_parent->config.w;
03520         src_height = (!source->root_parent)?source->config.h:source->root_parent->config.h;
03521 
03522         // empty source planes
03523         memset(&my_src_planes, 0, sizeof(MMSFBSurfacePlanes));
03524         src_planes = &my_src_planes;
03525     }
03526 
03527     // a few help and clipping values
03528     MMSFBSurfacePlanes dst_planes;
03529     int sx = src_rect->x;
03530     int sy = src_rect->y;
03531     int sw = src_rect->w;
03532     int sh = src_rect->h;
03533     int dx = dest_rect->x;
03534     int dy = dest_rect->y;
03535     int dw = dest_rect->w;
03536     int dh = dest_rect->h;
03537     int wf;
03538     int hf;
03539     if (!calc_dest_rect) {
03540         // calc factor
03541         wf = (dw<<16)/sw;
03542         hf = (dh<<16)/sh;
03543     }
03544     else {
03545         // have to calculate accurate factor based on surface dimensions
03546         wf = (this->config.w<<16)/src_width;
03547         hf = (this->config.h<<16)/src_height;
03548     }
03549 
03550 //printf("sx=%d,sy=%d,sw=%d,sh=%d,dx=%d,dy=%d,dw=%d,dh=%d\n", sx,sy,sw,sh,dx,dy,dw,dh);
03551 
03552 
03553     MMSFBRegion clipreg;
03554 #ifndef USE_DFB_SUBSURFACE
03555     if (!this->is_sub_surface) {
03556 #endif
03557         // normal surface or dfb subsurface
03558         if (!this->config.clipped) {
03559             clipreg.x1 = 0;
03560             clipreg.y1 = 0;
03561             clipreg.x2 = this->config.w - 1;
03562             clipreg.y2 = this->config.h - 1;
03563         }
03564         else
03565             clipreg = this->config.clip;
03566 #ifndef USE_DFB_SUBSURFACE
03567     }
03568     else {
03569         // subsurface
03570         if (!this->root_parent->config.clipped) {
03571             clipreg.x1 = 0;
03572             clipreg.y1 = 0;
03573             clipreg.x2 = this->root_parent->config.w - 1;
03574             clipreg.y2 = this->root_parent->config.h - 1;
03575         }
03576         else
03577             clipreg = this->root_parent->config.clip;
03578     }
03579 #endif
03580 
03581 //printf("cx1=%d,cy1=%d,cx2=%d,cy2=%d\n", clipreg.x1,clipreg.y1,clipreg.x2,clipreg.y2);
03582 
03583 
03584     if (dx < clipreg.x1) {
03585         // left outside
03586         sx+= ((clipreg.x1 - dx)<<16) / wf;
03587 /*      sw-= (clipreg.x1 - dx) / wf;
03588         if (sw <= 0)
03589             return true;*/
03590         dw-= clipreg.x1 - dx;
03591         if (dw <= 0)
03592             return true;
03593         sw = (dw<<16) / wf;
03594         dx = clipreg.x1;
03595     }
03596     else
03597     if (dx > clipreg.x2)
03598         // right outside
03599         return true;
03600     if (dy < clipreg.y1) {
03601         // top outside
03602         sy+= ((clipreg.y1 - dy)<<16) / hf;
03603 /*      sh-= (clipreg.y1 - dy) / hf;
03604         if (sh <= 0)
03605             return true;*/
03606         dh-= clipreg.y1 - dy;
03607         if (dh <= 0)
03608             return true;
03609         sh = (dh<<16) / hf;
03610         dy = clipreg.y1;
03611     }
03612     else
03613     if (dy > clipreg.y2)
03614         // bottom outside
03615         return true;
03616     if (dx + dw - 1 > clipreg.x2) {
03617         // to width
03618         dw = clipreg.x2 - dx + 1;
03619         sw = (dw<<16) / wf;
03620     }
03621     if (dy + dh - 1 > clipreg.y2) {
03622         // to height
03623         dh = clipreg.y2 - dy + 1;
03624         sh = (dh<<16) / hf;
03625     }
03626     if (sw<=0) sw = 1;
03627     if (sh<=0) sh = 1;
03628     if (dw<=0) dw = 1;
03629     if (dh<=0) dh = 1;
03630 
03631     if (calc_dest_rect) {
03632         // signal the following routines, that stretch factors have to based on surface dimensions
03633         dw=0;
03634         dh=0;
03635     }
03636 
03637 //printf(">sx=%d,sy=%d,sw=%d,sh=%d,dx=%d,dy=%d,dw=%d,dh=%d\n", sx,sy,sw,sh,dx,dy,dw,dh);
03638 
03639 //if (source->is_sub_surface) {
03640 //  sx+=source->sub_surface_xoff;
03641 //  sy+=source->sub_surface_yoff;
03642 //}
03643 
03644 //printf("!sx=%d,sy=%d,sw=%d,sh=%d,dx=%d,dy=%d,dw=%d,dh=%d\n", sx,sy,sw,sh,dx,dy,dw,dh);
03645 
03646 //dy-=10;
03647 
03648 
03649     // extract antialiasing flag from blittingflags
03650     bool antialiasing = (this->config.blittingflags & MMSFB_BLIT_ANTIALIASING);
03651     MMSFBBlittingFlags blittingflags = this->config.blittingflags & ~MMSFB_BLIT_ANTIALIASING;
03652 
03653 
03654     // checking pixelformats...
03655     switch (src_pixelformat) {
03656 #ifdef __HAVE_PF_ARGB__
03657     case MMSFB_PF_ARGB:
03658         // source is ARGB
03659         if (this->config.surface_buffer->pixelformat == MMSFB_PF_ARGB) {
03660             // destination is ARGB
03661             if (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_NOFX) {
03662                 // blitting without alpha channel
03663                 return stretchBlitARGBtoARGB(source, src_planes, src_pixelformat,
03664                                         src_width, src_height, sx, sy, sw, sh,
03665                                         dx, dy, dw, dh,
03666                                         antialiasing);
03667             }
03668             else
03669             if (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_BLEND_ALPHACHANNEL) {
03670                 // blitting with alpha channel
03671                 return stretchBlitARGBtoARGB_BLEND(source, src_planes, src_pixelformat,
03672                                         src_width, src_height, sx, sy, sw, sh,
03673                                         dx, dy, dw, dh,
03674                                         antialiasing);
03675             }
03676             else
03677             if   ((blittingflags == (MMSFBBlittingFlags)(MMSFB_BLIT_BLEND_ALPHACHANNEL|MMSFB_BLIT_BLEND_COLORALPHA))
03678                 ||(blittingflags == (MMSFBBlittingFlags)(MMSFB_BLIT_BLEND_ALPHACHANNEL|MMSFB_BLIT_BLEND_COLORALPHA|MMSFB_BLIT_SRC_PREMULTCOLOR))) {
03679                 // blitting with alpha channel and coloralpha
03680                 return stretchBlitARGBtoARGB_BLEND_COLORALPHA(source, src_planes, src_pixelformat,
03681                                         src_width, src_height, sx, sy, sw, sh,
03682                                         dx, dy, dw, dh,
03683                                         antialiasing);
03684             }
03685 
03686             // does not match
03687             return false;
03688         }
03689         else
03690         if (this->config.surface_buffer->pixelformat == MMSFB_PF_RGB32) {
03691             // destination is RGB32
03692             if (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_BLEND_ALPHACHANNEL) {
03693                 // blitting with alpha channel
03694                 return stretchBlitARGBtoRGB32_BLEND(source, src_planes, src_pixelformat,
03695                                         src_width, src_height, sx, sy, sw, sh,
03696                                         dx, dy, dw, dh,
03697                                         antialiasing);
03698             }
03699 
03700             // does not match
03701             return false;
03702         }
03703 
03704         // does not match
03705         return false;
03706 #endif
03707 
03708 #ifdef __HAVE_PF_RGB32__
03709     case MMSFB_PF_RGB32:
03710         // source is RGB32
03711         if (this->config.surface_buffer->pixelformat == MMSFB_PF_RGB32) {
03712             // destination is RGB32
03713             if (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_NOFX) {
03714                 // blitting without alpha channel
03715                 return stretchBlitRGB32toRGB32(source, src_planes, src_pixelformat,
03716                                         src_width, src_height, sx, sy, sw, sh,
03717                                         dx, dy, dw, dh,
03718                                         antialiasing);
03719             }
03720 
03721             // does not match
03722             return false;
03723         }
03724 
03725         // does not match
03726         return false;
03727 #endif
03728 
03729 #ifdef __HAVE_PF_RGB24__
03730     case MMSFB_PF_RGB24:
03731         // source is RGB24
03732         if (this->config.surface_buffer->pixelformat == MMSFB_PF_ARGB) {
03733             // destination is ARGB
03734             if (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_NOFX) {
03735                 // blitting without alpha channel
03736                 return stretchBlitRGB24toARGB(source, src_planes, src_pixelformat,
03737                                         src_width, src_height, sx, sy, sw, sh,
03738                                         dx, dy, dw, dh,
03739                                         antialiasing);
03740             }
03741 
03742             // does not match
03743             return false;
03744         }
03745         else
03746         if (this->config.surface_buffer->pixelformat == MMSFB_PF_RGB32) {
03747             // destination is RGB32
03748             if (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_NOFX) {
03749                 // blitting without alpha channel
03750                 return stretchBlitRGB24toRGB32(source, src_planes, src_pixelformat,
03751                                         src_width, src_height, sx, sy, sw, sh,
03752                                         dx, dy, dw, dh,
03753                                         antialiasing);
03754             }
03755 
03756             // does not match
03757             return false;
03758         }
03759 
03760         // does not match
03761         return false;
03762 #endif
03763 
03764 #ifdef __HAVE_PF_AiRGB__
03765     case MMSFB_PF_AiRGB:
03766         // source is AiRGB
03767         if (this->config.surface_buffer->pixelformat == MMSFB_PF_AiRGB) {
03768             // destination is AiRGB
03769             if (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_NOFX) {
03770                 // blitting without alpha channel
03771                 return stretchBlitAiRGBtoAiRGB(source, src_planes, src_pixelformat,
03772                                         src_width, src_height, sx, sy, sw, sh,
03773                                         dx, dy, dw, dh,
03774                                         antialiasing);
03775             }
03776             else
03777             if (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_BLEND_ALPHACHANNEL) {
03778                 // blitting with alpha channel
03779                 return stretchBlitAiRGBtoAiRGB_BLEND(source, src_planes, src_pixelformat,
03780                                         src_width, src_height, sx, sy, sw, sh,
03781                                         dx, dy, dw, dh,
03782                                         antialiasing);
03783             }
03784             else
03785             if   ((blittingflags == (MMSFBBlittingFlags)(MMSFB_BLIT_BLEND_ALPHACHANNEL|MMSFB_BLIT_BLEND_COLORALPHA))
03786                 ||(blittingflags == (MMSFBBlittingFlags)(MMSFB_BLIT_BLEND_ALPHACHANNEL|MMSFB_BLIT_BLEND_COLORALPHA|MMSFB_BLIT_SRC_PREMULTCOLOR))) {
03787                 // blitting with alpha channel and coloralpha
03788                 return stretchBlitAiRGBtoAiRGB_BLEND_COLORALPHA(source, src_planes, src_pixelformat,
03789                                         src_width, src_height, sx, sy, sw, sh,
03790                                         dx, dy, dw, dh,
03791                                         antialiasing);
03792             }
03793 
03794             // does not match
03795             return false;
03796         }
03797 
03798         // does not match
03799         return false;
03800 #endif
03801 
03802 #ifdef __HAVE_PF_AYUV__
03803     case MMSFB_PF_AYUV:
03804         // source is AYUV
03805         if (this->config.surface_buffer->pixelformat == MMSFB_PF_AYUV) {
03806             // destination is AYUV
03807             if (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_NOFX) {
03808                 // blitting without alpha channel
03809                 return stretchBlitAYUVtoAYUV(source, src_planes, src_pixelformat,
03810                                         src_width, src_height, sx, sy, sw, sh,
03811                                         dx, dy, dw, dh,
03812                                         antialiasing);
03813             }
03814             else
03815             if (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_BLEND_ALPHACHANNEL) {
03816                 // blitting with alpha channel
03817                 return stretchBlitAYUVtoAYUV_BLEND(source, src_planes, src_pixelformat,
03818                                         src_width, src_height, sx, sy, sw, sh,
03819                                         dx, dy, dw, dh,
03820                                         antialiasing);
03821             }
03822             else
03823             if   ((blittingflags == (MMSFBBlittingFlags)(MMSFB_BLIT_BLEND_ALPHACHANNEL|MMSFB_BLIT_BLEND_COLORALPHA))
03824                 ||(blittingflags == (MMSFBBlittingFlags)(MMSFB_BLIT_BLEND_ALPHACHANNEL|MMSFB_BLIT_BLEND_COLORALPHA|MMSFB_BLIT_SRC_PREMULTCOLOR))) {
03825                 // blitting with alpha channel and coloralpha
03826                 return stretchBlitAYUVtoAYUV_BLEND_COLORALPHA(source, src_planes, src_pixelformat,
03827                                         src_width, src_height, sx, sy, sw, sh,
03828                                         dx, dy, dw, dh,
03829                                         antialiasing);
03830             }
03831 
03832             // does not match
03833             return false;
03834         }
03835 
03836         // does not match
03837         return false;
03838 #endif
03839 
03840 #ifdef __HAVE_PF_YV12__
03841     case MMSFB_PF_YV12:
03842         // source is YV12
03843         if (this->config.surface_buffer->pixelformat == MMSFB_PF_YV12) {
03844             // destination is YV12
03845             if   ((blittingflags == MMSFB_BLIT_NOFX)
03846                 ||(blittingflags == MMSFB_BLIT_BLEND_ALPHACHANNEL)) {
03847                 // stretch without alpha channel
03848                 return stretchBlitYV12toYV12(source, src_planes, src_pixelformat,
03849                                         src_width, src_height, sx, sy, sw, sh,
03850                                         dx, dy, dw, dh,
03851                                         antialiasing);
03852             }
03853 
03854             // does not match
03855             return false;
03856         }
03857 
03858         // does not match
03859         return false;
03860 #endif
03861 
03862 #ifdef __HAVE_PF_I420__
03863     case MMSFB_PF_I420:
03864         // source is I420
03865         if (this->config.surface_buffer->pixelformat == MMSFB_PF_YV12) {
03866             // destination is YV12
03867             if   ((blittingflags == MMSFB_BLIT_NOFX)
03868                 ||(blittingflags == MMSFB_BLIT_BLEND_ALPHACHANNEL)) {
03869                 // stretch without alpha channel
03870                 return stretchBlitI420toYV12(source, src_planes, src_pixelformat,
03871                                         src_width, src_height, sx, sy, sw, sh,
03872                                         dx, dy, dw, dh,
03873                                         antialiasing);
03874             }
03875 
03876             // does not match
03877             return false;
03878         }
03879 
03880         // does not match
03881         return false;
03882 #endif
03883 
03884 #ifdef __HAVE_PF_YUY2__
03885     case MMSFB_PF_YUY2:
03886         // source is YUY2
03887         if (this->config.surface_buffer->pixelformat == MMSFB_PF_YV12) {
03888             // destination is YV12
03889             if   ((blittingflags == MMSFB_BLIT_NOFX)
03890                 ||(blittingflags == MMSFB_BLIT_BLEND_ALPHACHANNEL)) {
03891                 // stretch without alpha channel
03892                 return stretchBlitYUY2toYV12(source, src_planes, src_pixelformat,
03893                                         src_width, src_height, sx, sy, sw, sh,
03894                                         dx, dy, dw, dh,
03895                                         antialiasing);
03896             }
03897 
03898             // does not match
03899             return false;
03900         }
03901 
03902         // does not match
03903         return false;
03904 #endif
03905 
03906 #ifdef __HAVE_PF_ARGB4444__
03907     case MMSFB_PF_ARGB4444:
03908         // source is ARGB4444
03909         if (this->config.surface_buffer->pixelformat == MMSFB_PF_ARGB4444) {
03910             // destination is ARGB4444
03911             if (blittingflags == (MMSFBBlittingFlags)MMSFB_BLIT_BLEND_ALPHACHANNEL) {
03912                 // blitting with alpha channel
03913                 return stretchBlitARGB4444toARGB4444_BLEND(source, src_planes, src_pixelformat,
03914                                         src_width, src_height, sx, sy, sw, sh,
03915                                         dx, dy, dw, dh,
03916                                         antialiasing);
03917             }
03918             else
03919             if   ((blittingflags == (MMSFBBlittingFlags)(MMSFB_BLIT_BLEND_ALPHACHANNEL|MMSFB_BLIT_BLEND_COLORALPHA))
03920                 ||(blittingflags == (MMSFBBlittingFlags)(MMSFB_BLIT_BLEND_ALPHACHANNEL|MMSFB_BLIT_BLEND_COLORALPHA|MMSFB_BLIT_SRC_PREMULTCOLOR))) {
03921                 // blitting with alpha channel and coloralpha
03922                 return stretchBlitARGB4444toARGB4444_BLEND_COLORALPHA(source, src_planes, src_pixelformat,
03923                                         src_width, src_height, sx, sy, sw, sh,
03924                                         dx, dy, dw, dh,
03925                                         antialiasing);
03926             }
03927 
03928             // does not match
03929             return false;
03930         }
03931 
03932         // does not match
03933         return false;
03934 #endif
03935 
03936 #ifdef __HAVE_PF_RGB16__
03937     case MMSFB_PF_RGB16:
03938         // source is RGB16
03939         if (this->config.surface_buffer->pixelformat == MMSFB_PF_RGB16) {
03940             // destination is RGB16
03941             if   ((blittingflags == (MMSFBBlittingFlags)(MMSFB_BLIT_NOFX))
03942                 ||(blittingflags == (MMSFBBlittingFlags)(MMSFB_BLIT_BLEND_ALPHACHANNEL))) {
03943                 // blitting without alpha channel
03944                 return stretchBlitRGB16toRGB16(source, src_planes, src_pixelformat,
03945                                         src_width, src_height, sx, sy, sw, sh,
03946                                         dx, dy, dw, dh,
03947                                         antialiasing);
03948             }
03949 
03950             // does not match
03951             return false;
03952         }
03953 
03954         // does not match
03955         return false;
03956 #endif
03957 
03958     default:
03959         break;
03960     }
03961 
03962     // does not match
03963     return false;
03964 }
03965 
03966 
03967 bool MMSFBSurface::extendedAccelStretchBlit(MMSFBSurface *source, MMSFBRectangle *src_rect, MMSFBRectangle *dest_rect,
03968                                             MMSFBRectangle *real_dest_rect, bool calc_dest_rect) {
03969     // extended acceleration on?
03970     if (!this->extendedaccel)
03971         return false;
03972 
03973     if (!extendedAccelStretchBlitEx(source,
03974                                     NULL, MMSFB_PF_NONE, 0, 0,
03975                                     src_rect, dest_rect,
03976                                     real_dest_rect, calc_dest_rect))
03977         return printMissingCombination("extendedAccelStretchBlit()", source,
03978                 NULL, MMSFB_PF_NONE, 0, 0, this->config.blittingflags & ~MMSFB_BLIT_ANTIALIASING);
03979     else
03980         return true;
03981 }
03982 
03983 bool MMSFBSurface::extendedAccelStretchBlitBuffer(MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat, int src_width, int src_height,
03984                                                   MMSFBRectangle *src_rect, MMSFBRectangle *dest_rect,
03985                                                   MMSFBRectangle *real_dest_rect, bool calc_dest_rect) {
03986     // extended acceleration on?
03987     if (!this->extendedaccel)
03988         return false;
03989 
03990     if (!extendedAccelStretchBlitEx(NULL,
03991                                     src_planes, src_pixelformat, src_width, src_height,
03992                                     src_rect, dest_rect,
03993                                     real_dest_rect, calc_dest_rect))
03994         return printMissingCombination("extendedAccelStretchBlitBuffer()", NULL, src_planes,
03995                                 src_pixelformat, src_width, src_height, this->config.blittingflags & ~MMSFB_BLIT_ANTIALIASING);
03996     else
03997         return true;
03998 }
03999 
04000 
04001 
04002 
04003 bool MMSFBSurface::extendedAccelFillRectangleEx(int x, int y, int w, int h,
04004                                                 MMSFBDrawingFlags drawingflags, MMSFBColor *col) {
04005 
04006     // a few help and clipping values
04007     MMSFBSurfacePlanes dst_planes;
04008     int sx = x;
04009     int sy = y;
04010     int sw = w;
04011     int sh = h;
04012     int dst_height = (!this->root_parent)?this->config.h:this->root_parent->config.h;
04013 
04014     // calculate the color
04015     MMSFBColor color = (!col) ? this->config.color : *col;
04016     if (drawingflags & (MMSFBDrawingFlags)MMSFB_DRAW_SRC_PREMULTIPLY) {
04017         // pre-multiplication needed
04018         if (color.a != 0xff) {
04019             color.r = ((color.a+1) * color.r) >> 8;
04020             color.g = ((color.a+1) * color.g) >> 8;
04021             color.b = ((color.a+1) * color.b) >> 8;
04022         }
04023     }
04024 
04025     // checking pixelformats...
04026     switch (this->config.surface_buffer->pixelformat) {
04027 #ifdef __HAVE_PF_ARGB__
04028     case MMSFB_PF_ARGB:
04029         // destination is ARGB
04030         if   ((drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_NOFX))
04031             | (drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_NOFX|MMSFB_DRAW_SRC_PREMULTIPLY))) {
04032             // drawing without alpha channel
04033             return fillRectangleARGB(dst_height, sx, sy, sw, sh, color);
04034         }
04035         else
04036         if   ((drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_BLEND))
04037             | (drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_BLEND|MMSFB_DRAW_SRC_PREMULTIPLY))) {
04038             // drawing with alpha channel
04039             return fillRectangleARGB_BLEND(dst_height, sx, sy, sw, sh, color);
04040         }
04041 
04042         // does not match
04043         return false;
04044 #endif
04045 
04046 #ifdef __HAVE_PF_AYUV__
04047     case MMSFB_PF_AYUV:
04048         // destination is AYUV
04049         if   ((drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_NOFX))
04050             | (drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_NOFX|MMSFB_DRAW_SRC_PREMULTIPLY))) {
04051             // drawing without alpha channel
04052             return fillRectangleAYUV(dst_height, sx, sy, sw, sh, color);
04053         }
04054         else
04055         if   ((drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_BLEND))
04056             | (drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_BLEND|MMSFB_DRAW_SRC_PREMULTIPLY))) {
04057             // drawing with alpha channel
04058             return fillRectangleAYUV_BLEND(dst_height, sx, sy, sw, sh, color);
04059         }
04060 
04061         // does not match
04062         return false;
04063 #endif
04064 
04065 #ifdef __HAVE_PF_RGB32__
04066     case MMSFB_PF_RGB32:
04067         // destination is RGB32
04068         if   ((drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_NOFX))
04069             | (drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_NOFX|MMSFB_DRAW_SRC_PREMULTIPLY))) {
04070             // drawing without alpha channel
04071             return fillRectangleRGB32(dst_height, sx, sy, sw, sh, color);
04072         }
04073 
04074         // does not match
04075         return false;
04076 #endif
04077 
04078 #ifdef __HAVE_PF_RGB24__
04079     case MMSFB_PF_RGB24:
04080         // destination is RGB24
04081         if   ((drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_NOFX))
04082             | (drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_NOFX|MMSFB_DRAW_SRC_PREMULTIPLY))) {
04083             // drawing without alpha channel
04084             return fillRectangleRGB24(dst_height, sx, sy, sw, sh, color);
04085         }
04086 
04087         // does not match
04088         return false;
04089 #endif
04090 
04091 #ifdef __HAVE_PF_RGB16__
04092     case MMSFB_PF_RGB16:
04093         // destination is RGB16 (RGB565)
04094         if   ((drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_NOFX))
04095             | (drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_NOFX|MMSFB_DRAW_SRC_PREMULTIPLY))) {
04096             // drawing without alpha channel
04097             return fillRectangleRGB16(dst_height, sx, sy, sw, sh, color);
04098         }
04099         else
04100         if   ((drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_BLEND))
04101             | (drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_BLEND|MMSFB_DRAW_SRC_PREMULTIPLY))) {
04102             // drawing with alpha channel
04103             return fillRectangleRGB16_BLEND(dst_height, sx, sy, sw, sh, color);
04104         }
04105 
04106         // does not match
04107         return false;
04108 #endif
04109 
04110 #ifdef __HAVE_PF_YV12__
04111     case MMSFB_PF_YV12:
04112         // destination is YV12
04113         if   ((drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_NOFX))
04114             | (drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_NOFX|MMSFB_DRAW_SRC_PREMULTIPLY))) {
04115             // drawing without alpha channel
04116             return fillRectangleYV12(dst_height, sx, sy, sw, sh, color);
04117         }
04118 
04119         // does not match
04120         return false;
04121 #endif
04122 
04123 #ifdef __HAVE_PF_I420__
04124     case MMSFB_PF_I420:
04125         // destination is I420
04126         if   ((drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_NOFX))
04127             | (drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_NOFX|MMSFB_DRAW_SRC_PREMULTIPLY))) {
04128             // drawing without alpha channel
04129             return fillRectangleI420(dst_height, sx, sy, sw, sh, color);
04130         }
04131 
04132         // does not match
04133         return false;
04134 #endif
04135 
04136 #ifdef __HAVE_PF_YUY2__
04137     case MMSFB_PF_YUY2:
04138         // destination is YUY2
04139         if   ((drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_NOFX))
04140             | (drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_NOFX|MMSFB_DRAW_SRC_PREMULTIPLY))) {
04141             // drawing without alpha channel
04142             return fillRectangleYUY2(dst_height, sx, sy, sw, sh, color);
04143         }
04144 
04145         // does not match
04146         return false;
04147 #endif
04148 
04149 #ifdef __HAVE_PF_ARGB3565__
04150     case MMSFB_PF_ARGB3565:
04151         // destination is ARGB3565
04152         if   ((drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_NOFX))
04153             | (drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_NOFX|MMSFB_DRAW_SRC_PREMULTIPLY))) {
04154             // drawing without alpha channel
04155             return fillRectangleARGB3565(dst_height, sx, sy, sw, sh, color);
04156         }
04157 
04158         // does not match
04159         return false;
04160 #endif
04161 
04162 #ifdef __HAVE_PF_ARGB4444__
04163     case MMSFB_PF_ARGB4444:
04164         // destination is ARGB4444
04165         if   ((drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_NOFX))
04166             | (drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_NOFX|MMSFB_DRAW_SRC_PREMULTIPLY))) {
04167             // drawing without alpha channel
04168             return fillRectangleARGB4444(dst_height, sx, sy, sw, sh, color);
04169         }
04170         else
04171         if   ((drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_BLEND))
04172             | (drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_BLEND|MMSFB_DRAW_SRC_PREMULTIPLY))) {
04173             // drawing with alpha channel
04174             return fillRectangleARGB4444_BLEND(dst_height, sx, sy, sw, sh, color);
04175         }
04176 
04177         // does not match
04178         return false;
04179 #endif
04180 
04181 #ifdef __HAVE_PF_BGR24__
04182     case MMSFB_PF_BGR24:
04183         // destination is BGR24
04184         if   ((drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_NOFX))
04185             | (drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_NOFX|MMSFB_DRAW_SRC_PREMULTIPLY))) {
04186             // drawing without alpha channel
04187             return fillRectangleBGR24(dst_height, sx, sy, sw, sh, color);
04188         }
04189 
04190         // does not match
04191         return false;
04192 #endif
04193 
04194 #ifdef __HAVE_PF_BGR555__
04195     case MMSFB_PF_BGR555:
04196         // destination is BGR555
04197         if   ((drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_NOFX))
04198             | (drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_NOFX|MMSFB_DRAW_SRC_PREMULTIPLY))) {
04199             // drawing without alpha channel
04200             return fillRectangleBGR555(dst_height, sx, sy, sw, sh, color);
04201         }
04202 
04203         // does not match
04204         return false;
04205 #endif
04206 
04207     default:
04208         // does not match
04209         break;
04210     }
04211 
04212     // does not match
04213     return false;
04214 }
04215 
04216 
04217 bool MMSFBSurface::extendedAccelFillRectangle(int x, int y, int w, int h,
04218                                               MMSFBDrawingFlags drawingflags, MMSFBColor *color) {
04219 
04220     // extended acceleration on?
04221     if (!this->extendedaccel)
04222         return false;
04223 
04224     if (!extendedAccelFillRectangleEx(x, y, w, h, drawingflags, color))
04225         return printMissingCombination("extendedAccelFillRectangle()");
04226     else
04227         return true;
04228 }
04229 
04230 
04231 
04232 
04233 bool MMSFBSurface::extendedAccelDrawLineEx(int x1, int y1, int x2, int y2) {
04234 
04235     // a few help and clipping values
04236     MMSFBSurfacePlanes dst_planes;
04237     MMSFBRegion clipreg;
04238     int dst_height = (!this->root_parent)?this->config.h:this->root_parent->config.h;
04239 
04240 #ifndef USE_DFB_SUBSURFACE
04241     if (!this->is_sub_surface) {
04242 #endif
04243         // normal surface or dfb subsurface
04244         if (!this->config.clipped) {
04245             clipreg.x1 = 0;
04246             clipreg.y1 = 0;
04247             clipreg.x2 = this->config.w - 1;
04248             clipreg.y2 = this->config.h - 1;
04249         }
04250         else
04251             clipreg = this->config.clip;
04252 #ifndef USE_DFB_SUBSURFACE
04253     }
04254     else {
04255         // subsurface
04256         if (!this->root_parent->config.clipped) {
04257             clipreg.x1 = 0;
04258             clipreg.y1 = 0;
04259             clipreg.x2 = this->root_parent->config.w - 1;
04260             clipreg.y2 = this->root_parent->config.h - 1;
04261         }
04262         else
04263             clipreg = this->root_parent->config.clip;
04264     }
04265 #endif
04266 
04267     // calculate the color
04268     MMSFBColor color = this->config.color;
04269     if (this->config.drawingflags & (MMSFBDrawingFlags)MMSFB_DRAW_SRC_PREMULTIPLY) {
04270         // pre-multiplication needed
04271         if (color.a != 0xff) {
04272             color.r = ((color.a+1) * color.r) >> 8;
04273             color.g = ((color.a+1) * color.g) >> 8;
04274             color.b = ((color.a+1) * color.b) >> 8;
04275         }
04276     }
04277 
04278     // checking pixelformats...
04279     switch (this->config.surface_buffer->pixelformat) {
04280     case MMSFB_PF_ARGB:
04281         // destination is ARGB
04282         if   ((this->config.drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_NOFX))
04283             | (this->config.drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_NOFX|MMSFB_DRAW_SRC_PREMULTIPLY))) {
04284             // drawing without alpha channel
04285             if (extendedLock(NULL, NULL, this, &dst_planes)) {
04286                 MMSFB_ROTATE_180_REGION(this, clipreg.x1, clipreg.y1, clipreg.x2, clipreg.y2);
04287                 MMSFB_ROTATE_180_REGION(this, x1, y1, x2, y2);
04288                 MMSFBPERF_START_MEASURING;
04289                     mmsfb_drawline_argb(&dst_planes, dst_height, clipreg, x1, y1, x2, y2, color);
04290                 MMSFBPERF_STOP_MEASURING_DRAWLINE(this, x1, y1, x2, y2);
04291                 MMSFB_ROTATE_180_REGION(this, clipreg.x1, clipreg.y1, clipreg.x2, clipreg.y2);
04292                 MMSFB_ROTATE_180_REGION(this, x1, y1, x2, y2);
04293                 extendedUnlock(NULL, this);
04294                 return true;
04295             }
04296 
04297             return false;
04298         }
04299         else
04300         if   ((this->config.drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_BLEND))
04301             | (this->config.drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_BLEND|MMSFB_DRAW_SRC_PREMULTIPLY))) {
04302             if (extendedLock(NULL, NULL, this, &dst_planes)) {
04303                 // drawing with alpha channel
04304                 MMSFB_ROTATE_180_REGION(this, clipreg.x1, clipreg.y1, clipreg.x2, clipreg.y2);
04305                 MMSFB_ROTATE_180_REGION(this, x1, y1, x2, y2);
04306                 MMSFBPERF_START_MEASURING;
04307                     mmsfb_drawline_blend_argb(&dst_planes, dst_height, clipreg, x1, y1, x2, y2, color);
04308                 MMSFBPERF_STOP_MEASURING_DRAWLINE(this, x1, y1, x2, y2);
04309                 MMSFB_ROTATE_180_REGION(this, clipreg.x1, clipreg.y1, clipreg.x2, clipreg.y2);
04310                 MMSFB_ROTATE_180_REGION(this, x1, y1, x2, y2);
04311                 extendedUnlock(NULL, this);
04312                 return true;
04313             }
04314         }
04315 
04316         // does not match
04317         return false;
04318 
04319     case MMSFB_PF_ARGB4444:
04320         // destination is ARGB4444
04321         if   ((this->config.drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_NOFX))
04322             | (this->config.drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_NOFX|MMSFB_DRAW_SRC_PREMULTIPLY))) {
04323             // drawing without alpha channel
04324             if (extendedLock(NULL, NULL, this, &dst_planes)) {
04325                 MMSFB_ROTATE_180_REGION(this, clipreg.x1, clipreg.y1, clipreg.x2, clipreg.y2);
04326                 MMSFB_ROTATE_180_REGION(this, x1, y1, x2, y2);
04327                 MMSFBPERF_START_MEASURING;
04328                     mmsfb_drawline_argb4444(&dst_planes, dst_height, clipreg, x1, y1, x2, y2, color);
04329                 MMSFBPERF_STOP_MEASURING_DRAWLINE(this, x1, y1, x2, y2);
04330                 MMSFB_ROTATE_180_REGION(this, clipreg.x1, clipreg.y1, clipreg.x2, clipreg.y2);
04331                 MMSFB_ROTATE_180_REGION(this, x1, y1, x2, y2);
04332                 extendedUnlock(NULL, this);
04333                 return true;
04334             }
04335 
04336             return false;
04337         }
04338 
04339         // does not match
04340         return false;
04341 
04342     default:
04343         // does not match
04344         break;
04345     }
04346 
04347     // does not match
04348     return false;
04349 }
04350 
04351 
04352 bool MMSFBSurface::extendedAccelDrawLine(int x1, int y1, int x2, int y2) {
04353 
04354     // extended acceleration on?
04355     if (!this->extendedaccel)
04356         return false;
04357 
04358     if (!extendedAccelDrawLineEx(x1, y1, x2, y2))
04359         return printMissingCombination("extendedAccelDrawLine()");
04360     else
04361         return true;
04362 }
04363 
04364 
04365 
04366 
04367 bool MMSFBSurface::renderScene(MMS_VERTEX_ARRAY **varrays,
04368                                MMS_INDEX_ARRAY  **iarrays,
04369                                MMS3D_MATERIAL       *materials,
04370                                MMSFBSurface         **textures,
04371                                MMS3D_OBJECT         **objects) {
04372 
04373     bool         ret = false;
04374 
04375     if (this->allocated_by == MMSFBSurfaceAllocatedBy_ogl) {
04376 #ifdef  __HAVE_OPENGL__
04377 
04378         if (!this->is_sub_surface) {
04379 
04380             mmsfb->bei->renderScene(this, varrays, iarrays, materials, textures, objects);
04381 
04382             ret = true;
04383         }
04384         else {
04385             CLIPSUBSURFACE
04386 
04387             mmsfb->bei->renderScene(this, varrays, iarrays, materials, textures, objects);
04388 
04389             UNCLIPSUBSURFACE
04390 
04391             ret = true;
04392         }
04393 #endif
04394     }
04395 
04396     return ret;
04397 }
04398 
04399 
04400 bool MMSFBSurface::merge(MMSFBSurface *source1, MMSFBSurface *source2, MMSFBMergingMode mergingmode) {
04401 
04402     bool         ret = false;
04403 
04404     if (this->allocated_by == MMSFBSurfaceAllocatedBy_ogl) {
04405 #ifdef  __HAVE_OPENGL__
04406 
04407         if (!this->is_sub_surface) {
04408 
04409             mmsfb->bei->merge(this, source1, source2, mergingmode);
04410 
04411             ret = true;
04412         }
04413         else {
04414             CLIPSUBSURFACE
04415 
04416             mmsfb->bei->merge(this, source1, source2, mergingmode);
04417 
04418             UNCLIPSUBSURFACE
04419 
04420             ret = true;
04421         }
04422 #endif
04423     }
04424 
04425     return ret;
04426 }
04427 
04428 
04429 
04430 bool MMSFBSurface::checkBlittingStatus(bool src_opaque, bool src_transparent, int x, int y, int w, int h,
04431                                        MMSFBRectangle &crect, MMSFBBlittingFlags &blittingflags) {
04432 
04433     if (src_transparent) {
04434         // source is full transparent
04435         if (this->config.blittingflags & MMSFB_BLIT_BLEND_ALPHACHANNEL) {
04436             // nothing to draw
04437             return false;
04438         }
04439     }
04440 
04441     // check clipping region and calculate final rectangle
04442     if (!this->is_sub_surface) {
04443         if (!calcClip(x, y, w, h, &crect)) {
04444             // rectangle described with x, y, w, h is outside of the surface or clipping rectangle
04445             return false;
04446         }
04447     }
04448     else {
04449         bool outside = false;
04450         CLIPSUBSURFACE
04451         if (!calcClip(x + this->sub_surface_xoff, y + this->sub_surface_yoff, w, h, &crect)) {
04452             // rectangle described with x, y, w, h is outside of the surface or clipping rectangle
04453             outside = true;
04454         }
04455         UNCLIPSUBSURFACE
04456         if (outside) return false;
04457     }
04458 
04459     // set new opaque/transparent status and get blitting flags for it
04460     blittingflags = this->config.blittingflags;
04461     if (src_opaque) {
04462         // source is an opaque buffer
04463         // so remove the BLEND_ALPHACHANNEL flag if set
04464         blittingflags = blittingflags & ~MMSFB_BLIT_BLEND_ALPHACHANNEL;
04465         switch (blittingflags) {
04466         case MMSFB_BLIT_NOFX:
04467         case MMSFB_BLIT_COLORIZE:
04468             // note: we use this->config.surface_buffer->sbw and this->config.surface_buffer->sbh
04469             //       because this is the dimension of the real existing buffer
04470             if    ((crect.x <= 0) && (crect.y <= 0)
04471                 && (crect.x + crect.w >= this->config.surface_buffer->sbw)
04472                 && (crect.y + crect.h >= this->config.surface_buffer->sbh)) {
04473                 // blit writes the whole destination surface
04474                 MMSFBSURFACE_WRITE_BUFFER(this).opaque      = true;
04475                 MMSFBSURFACE_WRITE_BUFFER(this).transparent = false;
04476             }
04477             else {
04478                 // let opaque status unchanged
04479                 MMSFBSURFACE_WRITE_BUFFER(this).transparent = false;
04480             }
04481             break;
04482         default:
04483             // after blitting surface is not opaque and not transparent
04484             MMSFBSURFACE_WRITE_BUFFER(this).opaque      = false;
04485             MMSFBSURFACE_WRITE_BUFFER(this).transparent = false;
04486             break;
04487         }
04488     }
04489     else {
04490         // source is semi-transparent
04491         if (!(blittingflags & MMSFB_BLIT_BLEND_ALPHACHANNEL)) {
04492             // after the blitting surface is not opaque
04493             MMSFBSURFACE_WRITE_BUFFER(this).opaque = false;
04494         }
04495 
04496         // after blitting surface is not transparent
04497         MMSFBSURFACE_WRITE_BUFFER(this).transparent = false;
04498     }
04499 
04500     return true;
04501 }
04502 
04503 bool MMSFBSurface::checkBlittingStatus(MMSFBSurface *source, int x, int y, int w, int h,
04504                                        MMSFBRectangle &crect, MMSFBBlittingFlags &blittingflags) {
04505     return checkBlittingStatus(MMSFBSURFACE_READ_BUFFER(source).opaque, MMSFBSURFACE_READ_BUFFER(source).transparent,
04506                                 x, y, w, h, crect, blittingflags);
04507 }
04508 
04509 
04510 bool MMSFBSurface::blit(MMSFBSurface *source, MMSFBRectangle *src_rect, int x, int y) {
04511     MMSFBRectangle src;
04512     bool         ret = false;
04513 
04514     // check if initialized
04515     INITCHECK;
04516 
04517     if (src_rect) {
04518          src = *src_rect;
04519     }
04520     else {
04521          src.x = 0;
04522          src.y = 0;
04523          src.w = source->config.w;
04524          src.h = source->config.h;
04525     }
04526 
04527     // finalize previous clear for source surface
04528     source->finClear();
04529 
04530     // save opaque/transparent status
04531     bool opaque_saved       = MMSFBSURFACE_WRITE_BUFFER(this).opaque;
04532     bool transparent_saved  = MMSFBSURFACE_WRITE_BUFFER(this).transparent;
04533 
04534     // get final rectangle and new opaque/transparent status
04535     MMSFBRectangle crect;
04536     MMSFBBlittingFlags blittingflags;
04537     if (!checkBlittingStatus(source, x, y, src.w, src.h, crect, blittingflags)) {
04538         // nothing to draw
04539         return true;
04540     }
04541 
04542 //printf(" blit to %d,%d,%d,%d    dest opaque = %d, %d\n", crect.x, crect.y, crect.w, crect.h,MMSFBSURFACE_WRITE_BUFFER(this).opaque,opaque_saved);
04543 
04544     // finalize previous clear
04545     finClear((MMSFBSURFACE_WRITE_BUFFER(this).opaque) ? &crect: NULL);
04546 
04547     if (this->allocated_by != MMSFBSurfaceAllocatedBy_dfb){
04548 //    &&this->allocated_by != MMSFBSurfaceAllocatedBy_ogl) {
04549         //TODO: implement changes for dfb too
04550         //TODO: building lot for ogl too
04551 
04552         // prepare source rectangle
04553         if (source->is_sub_surface) {
04554             src.x+=source->sub_surface_xoff;
04555             src.y+=source->sub_surface_yoff;
04556         }
04557         if (this->is_sub_surface) {
04558             src.x+= crect.x - this->sub_surface_xoff - x;
04559             src.y+= crect.y - this->sub_surface_yoff - y;
04560         }
04561         else {
04562             src.x+= crect.x - x;
04563             src.y+= crect.y - y;
04564         }
04565         src.w = crect.w;
04566         src.h = crect.h;
04567     }
04568 
04569     if (this->allocated_by == MMSFBSurfaceAllocatedBy_dfb) {
04570 #ifdef  __HAVE_DIRECTFB__
04571         DFBResult    dfbres;
04572         D_DEBUG_AT( MMS_Surface, "blit( %d,%d - %dx%d -> %d,%d ) <- %dx%d\n",
04573                     DFB_RECTANGLE_VALS(&src), x, y, this->config.w, this->config.h );
04574         MMSFB_TRACE();
04575 
04576 #ifndef USE_DFB_SUBSURFACE
04577         // prepare source rectangle
04578         if (source->is_sub_surface) {
04579             src.x+=source->sub_surface_xoff;
04580             src.y+=source->sub_surface_yoff;
04581         }
04582 #endif
04583 
04584         // blit
04585         if (!this->is_sub_surface) {
04586             if (!extendedAccelBlit(source, &src, x, y, this->config.blittingflags))
04587                 if ((dfbres=this->dfb_surface->Blit(this->dfb_surface, (IDirectFBSurface *)source->getDFBSurface(), (DFBRectangle*)&src, x, y)) != DFB_OK) {
04588 #ifndef USE_DFB_SUBSURFACE
04589                     // reset source rectangle
04590                     if (source->is_sub_surface) {
04591                         src.x-=source->sub_surface_xoff;
04592                         src.y-=source->sub_surface_yoff;
04593                     }
04594 #endif
04595                     MMSFB_SetError(dfbres, "IDirectFBSurface::Blit() failed, src rect="
04596                                            +iToStr(src.x)+","+iToStr(src.y)+","+iToStr(src.w)+","+iToStr(src.h)
04597                                            +", dst="+iToStr(x)+","+iToStr(y));
04598                     return false;
04599                 }
04600             ret = true;
04601         }
04602         else {
04603 
04604 #ifndef USE_DFB_SUBSURFACE
04605             CLIPSUBSURFACE
04606 
04607             x+=this->sub_surface_xoff;
04608             y+=this->sub_surface_yoff;
04609 
04610             SETSUBSURFACE_BLITTINGFLAGS;
04611 #endif
04612 
04613             if (extendedAccelBlit(source, &src, x, y, this->config.blittingflags))
04614                 ret = true;
04615             else
04616                 if (this->dfb_surface->Blit(this->dfb_surface, (IDirectFBSurface *)source->getDFBSurface(), (DFBRectangle*)&src, x, y) == DFB_OK)
04617                     ret = true;
04618 
04619 #ifndef USE_DFB_SUBSURFACE
04620             RESETSUBSURFACE_BLITTINGFLAGS;
04621 
04622             UNCLIPSUBSURFACE
04623 #endif
04624 
04625         }
04626 #endif
04627     }
04628     else
04629     if (this->allocated_by == MMSFBSurfaceAllocatedBy_ogl) {
04630 #ifdef  __HAVE_OPENGL__
04631         mmsfb->bei->blit(this, source, src, crect.x, crect.y, blittingflags);
04632         ret = true;
04633 #endif
04634     }
04635     else {
04636         ret = extendedAccelBlit(source, &src, crect.x, crect.y, blittingflags);
04637     }
04638 
04639     if (!ret) {
04640         // restore opaque/transparent status
04641         MMSFBSURFACE_WRITE_BUFFER(this).opaque      = opaque_saved;
04642         MMSFBSURFACE_WRITE_BUFFER(this).transparent = transparent_saved;
04643     }
04644 
04645     return ret;
04646 }
04647 
04648 
04649 
04650 bool MMSFBSurface::blitBuffer(MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat, int src_width, int src_height,
04651                               MMSFBRectangle *src_rect, int x, int y, bool opaque) {
04652     MMSFBRectangle src;
04653     bool         ret = false;
04654 
04655     if (src_rect) {
04656          src = *src_rect;
04657     }
04658     else {
04659          src.x = 0;
04660          src.y = 0;
04661          src.w = src_width;
04662          src.h = src_height;
04663     }
04664 
04665     // check if initialized
04666     INITCHECK;
04667 
04668     // save opaque/transparent status
04669     bool opaque_saved       = MMSFBSURFACE_WRITE_BUFFER(this).opaque;
04670     bool transparent_saved  = MMSFBSURFACE_WRITE_BUFFER(this).transparent;
04671 
04672     // get final rectangle and new opaque/transparent status
04673     MMSFBRectangle crect;
04674     MMSFBBlittingFlags blittingflags;
04675     if (!checkBlittingStatus(opaque, false, x, y, src.w, src.h, crect, blittingflags)) {
04676         // nothing to draw
04677         return true;
04678     }
04679 
04680     // finalize previous clear
04681     finClear((MMSFBSURFACE_WRITE_BUFFER(this).opaque) ? &crect: NULL);
04682 
04683     if (this->allocated_by == MMSFBSurfaceAllocatedBy_dfb) {
04684 #ifdef  __HAVE_DIRECTFB__
04685 #endif
04686     }
04687     else
04688     if (this->allocated_by == MMSFBSurfaceAllocatedBy_ogl) {
04689 #ifdef  __HAVE_OPENGL__
04690 
04691         if (!this->is_sub_surface) {
04692 
04693             mmsfb->bei->blitBuffer(this, src_planes, src_pixelformat, src_width, src_height, src, x, y,
04694                                     blittingflags);
04695 
04696             ret = true;
04697         }
04698         else {
04699             CLIPSUBSURFACE
04700 
04701             mmsfb->bei->blitBuffer(this, src_planes, src_pixelformat, src_width, src_height, src, x, y,
04702                                     blittingflags);
04703 
04704             UNCLIPSUBSURFACE
04705 
04706             ret = true;
04707         }
04708 
04709 #endif
04710     }
04711     else {
04712         // blit buffer
04713         if (!this->is_sub_surface) {
04714             ret = extendedAccelBlitBuffer(src_planes, src_pixelformat, src_width, src_height, &src,
04715                                           x, y, blittingflags);
04716         }
04717         else {
04718             CLIPSUBSURFACE
04719 
04720             x+=this->sub_surface_xoff;
04721             y+=this->sub_surface_yoff;
04722 
04723             ret = extendedAccelBlitBuffer(src_planes, src_pixelformat, src_width, src_height, &src,
04724                                           x, y, blittingflags);
04725 
04726             UNCLIPSUBSURFACE
04727 
04728         }
04729     }
04730 
04731 
04732     if (!ret) {
04733         // restore opaque/transparent status
04734         MMSFBSURFACE_WRITE_BUFFER(this).opaque      = opaque_saved;
04735         MMSFBSURFACE_WRITE_BUFFER(this).transparent = transparent_saved;
04736     }
04737 
04738 
04739     return ret;
04740 }
04741 
04742 bool MMSFBSurface::blitBuffer(void *src_ptr, int src_pitch, MMSFBSurfacePixelFormat src_pixelformat, int src_width, int src_height,
04743                               MMSFBRectangle *src_rect, int x, int y, bool opaque) {
04744     MMSFBSurfacePlanes src_planes = MMSFBSurfacePlanes(src_ptr, src_pitch);
04745     return blitBuffer(&src_planes, src_pixelformat, src_width, src_height, src_rect, x, y, opaque);
04746 }
04747 
04748 bool MMSFBSurface::stretchBlit(MMSFBSurface *source, MMSFBRectangle *src_rect, MMSFBRectangle *dest_rect,
04749                                MMSFBRectangle *real_dest_rect, bool calc_dest_rect) {
04750     MMSFBRectangle src;
04751     MMSFBRectangle dst;
04752     bool         ret = false;
04753 
04754     // use whole source surface if src_rect is not given
04755     if (src_rect) {
04756          src = *src_rect;
04757     }
04758     else {
04759          src.x = 0;
04760          src.y = 0;
04761          src.w = source->config.w;
04762          src.h = source->config.h;
04763     }
04764 
04765 
04766     // use whole destination surface if dest_rect is not given and calc_dest_rect is not set
04767     if ((dest_rect)&&(!calc_dest_rect)) {
04768          dst = *dest_rect;
04769     }
04770     else {
04771         if (!calc_dest_rect) {
04772             dst.x = 0;
04773             dst.y = 0;
04774             dst.w = this->config.w;
04775             dst.h = this->config.h;
04776         }
04777         else {
04778             // calc dest_rect from src_rect based on src/dst surface dimension
04779             dst.x = (src.x * this->config.w) / source->config.w;
04780             dst.y = (src.y * this->config.h) / source->config.h;
04781             dst.w = src.x + src.w - 1;
04782             dst.h = src.y + src.h - 1;
04783             dst.w = (dst.w * this->config.w) / source->config.w;
04784             dst.h = (dst.h * this->config.h) / source->config.h;
04785             dst.w = dst.w - dst.x + 1;
04786             dst.h = dst.h - dst.y + 1;
04787         }
04788     }
04789 
04790     // return the used destination rectangle
04791     if (real_dest_rect)
04792         *real_dest_rect = dst;
04793 
04794     // check if i can blit without stretching
04795     if (src.w == dst.w && src.h == dst.h) {
04796         return blit(source, &src, dst.x, dst.y);
04797     }
04798 
04799     // check if initialized
04800     INITCHECK;
04801 
04802     // finalize previous clear for source surface
04803 
04804     source->finClear();
04805 
04806     // save opaque/transparent status
04807     bool opaque_saved       = MMSFBSURFACE_WRITE_BUFFER(this).opaque;
04808     bool transparent_saved  = MMSFBSURFACE_WRITE_BUFFER(this).transparent;
04809 
04810     // get final rectangle and new opaque/transparent status
04811     MMSFBRectangle crect;
04812     MMSFBBlittingFlags blittingflags;
04813     if (!checkBlittingStatus(source, dst.x, dst.y, dst.w, dst.h, crect, blittingflags)) {
04814         // nothing to draw
04815         return true;
04816     }
04817 
04818 //printf(" stretch to %d,%d,%d,%d\n", crect.x, crect.y, crect.w, crect.h);
04819 
04820 
04821     // finalize previous clear
04822     finClear((MMSFBSURFACE_WRITE_BUFFER(this).opaque) ? &crect: NULL);
04823 
04824     //TODO: use crect for the following code...
04825     //...
04826 
04827     if (this->allocated_by == MMSFBSurfaceAllocatedBy_dfb) {
04828 #ifdef  __HAVE_DIRECTFB__
04829         DFBResult    dfbres;
04830         bool         blit_done = false;
04831         D_DEBUG_AT( MMS_Surface, "stretchBlit( %d,%d - %dx%d  ->  %d,%d - %dx%d ) <- %dx%d\n",
04832                     DFB_RECTANGLE_VALS(&src), DFB_RECTANGLE_VALS(&dst), this->config.w, this->config.h);
04833         MMSFB_BREAK();
04834 
04835 #ifndef USE_DFB_SUBSURFACE
04836         // prepare source rectangle
04837         if (source->is_sub_surface) {
04838             src.x+=source->sub_surface_xoff;
04839             src.y+=source->sub_surface_yoff;
04840         }
04841 #endif
04842 
04843         if (this->config.blittingflags != MMSFB_BLIT_NOFX) {
04844             /* stretch blit with blitting flags */
04845 
04846             if (!this->is_sub_surface) {
04847                 if (extendedAccelStretchBlit(source, &src, &dst, real_dest_rect, calc_dest_rect)) {
04848                     blit_done = true;
04849                     ret = true;
04850                 }
04851             }
04852             else {
04853 
04854 #ifndef USE_DFB_SUBSURFACE
04855                 CLIPSUBSURFACE
04856 
04857                 dst.x+=this->sub_surface_xoff;
04858                 dst.y+=this->sub_surface_yoff;
04859 
04860                 SETSUBSURFACE_BLITTINGFLAGS;
04861 #endif
04862 
04863                 if (extendedAccelStretchBlit(source, &src, &dst, real_dest_rect, calc_dest_rect)) {
04864                     blit_done = true;
04865                     ret = true;
04866                 }
04867 
04868 
04869 #ifndef USE_DFB_SUBSURFACE
04870                 RESETSUBSURFACE_BLITTINGFLAGS;
04871 
04872                 dst.x-=this->sub_surface_xoff;
04873                 dst.y-=this->sub_surface_yoff;
04874 
04875                 UNCLIPSUBSURFACE
04876 #endif
04877             }
04878 
04879             if (!blit_done) {
04880                 /* we use a temporary surface to separate the stretchblit from the extra blitting functions */
04881                 MMSFBSurface *tempsuf = mmsfbsurfacemanager->getTemporarySurface(dst.w, dst.h);
04882 
04883                 if (tempsuf) {
04884                     MMSFBRectangle temp;
04885                     temp.x=0;
04886                     temp.y=0;
04887                     temp.w=dst.w;
04888                     temp.h=dst.h;
04889 
04890                     dfbres = DFB_OK;
04891                     dfbres=((IDirectFBSurface *)tempsuf->getDFBSurface())->StretchBlit((IDirectFBSurface *)tempsuf->getDFBSurface(), (IDirectFBSurface *)source->getDFBSurface(), (DFBRectangle*)&src, (DFBRectangle*)&temp);
04892                     if (dfbres == DFB_OK) {
04893                         if (!this->is_sub_surface) {
04894                             if (extendedAccelBlit(tempsuf, &temp, dst.x, dst.y, this->config.blittingflags)) {
04895                                 blit_done = true;
04896                                 ret = true;
04897                             }
04898                             else
04899                             if ((dfbres=this->dfb_surface->Blit(this->dfb_surface, (IDirectFBSurface *)tempsuf->getDFBSurface(), (DFBRectangle*)&temp, dst.x, dst.y)) == DFB_OK) {
04900                                 blit_done = true;
04901                                 ret = true;
04902                             }
04903                         }
04904                         else {
04905 
04906 #ifndef USE_DFB_SUBSURFACE
04907                             CLIPSUBSURFACE
04908 
04909                             dst.x+=this->sub_surface_xoff;
04910                             dst.y+=this->sub_surface_yoff;
04911 
04912                             SETSUBSURFACE_BLITTINGFLAGS;
04913 #endif
04914 
04915                             if (!extendedAccelBlit(tempsuf, &temp, dst.x, dst.y, this->config.blittingflags))
04916                                 this->dfb_surface->Blit(this->dfb_surface, (IDirectFBSurface *)tempsuf->getDFBSurface(), (DFBRectangle*)&temp, dst.x, dst.y);
04917 
04918 #ifndef USE_DFB_SUBSURFACE
04919                             RESETSUBSURFACE_BLITTINGFLAGS;
04920 
04921                             dst.x-=this->sub_surface_xoff;
04922                             dst.y-=this->sub_surface_yoff;
04923 
04924                             UNCLIPSUBSURFACE
04925 #endif
04926 
04927                             blit_done = true;
04928                             ret = true;
04929 
04930                         }
04931                     }
04932 
04933                     mmsfbsurfacemanager->releaseTemporarySurface(tempsuf);
04934                 }
04935             }
04936         }
04937 
04938         if (!blit_done) {
04939             // normal stretch blit
04940             if (!this->is_sub_surface) {
04941                 dfbres = DFB_OK;
04942                 if (!extendedAccelStretchBlit(source, &src, &dst, real_dest_rect, calc_dest_rect))
04943                     dfbres=this->dfb_surface->StretchBlit(this->dfb_surface, (IDirectFBSurface *)source->getDFBSurface(), (DFBRectangle*)&src, (DFBRectangle*)&dst);
04944                 if (dfbres != DFB_OK) {
04945 #ifndef USE_DFB_SUBSURFACE
04946                     // reset source rectangle
04947                     if (source->is_sub_surface) {
04948                         src.x-=source->sub_surface_xoff;
04949                         src.y-=source->sub_surface_yoff;
04950                     }
04951 #endif
04952                     MMSFB_SetError(dfbres, "IDirectFBSurface::StretchBlit() failed");
04953                     return false;
04954                 }
04955                 ret = true;
04956             }
04957             else {
04958 
04959 #ifndef USE_DFB_SUBSURFACE
04960                 CLIPSUBSURFACE
04961 
04962                 dst.x+=this->sub_surface_xoff;
04963                 dst.y+=this->sub_surface_yoff;
04964 
04965                 SETSUBSURFACE_BLITTINGFLAGS;
04966 #endif
04967 
04968                 if (!extendedAccelStretchBlit(source, &src, &dst, real_dest_rect, calc_dest_rect))
04969                     this->dfb_surface->StretchBlit(this->dfb_surface, (IDirectFBSurface *)source->getDFBSurface(), (DFBRectangle*)&src, (DFBRectangle*)&dst);
04970                 ret = true;
04971 
04972 #ifndef USE_DFB_SUBSURFACE
04973                 RESETSUBSURFACE_BLITTINGFLAGS;
04974 
04975                 dst.x-=this->sub_surface_xoff;
04976                 dst.y-=this->sub_surface_yoff;
04977 
04978                 UNCLIPSUBSURFACE
04979 #endif
04980             }
04981         }
04982 
04983 #ifndef USE_DFB_SUBSURFACE
04984         // reset source rectangle
04985         if (source->is_sub_surface) {
04986             src.x-=source->sub_surface_xoff;
04987             src.y-=source->sub_surface_yoff;
04988         }
04989 #endif
04990 
04991 #endif
04992     }
04993     else
04994     if (this->allocated_by == MMSFBSurfaceAllocatedBy_ogl) {
04995 #ifdef  __HAVE_OPENGL__
04996 
04997         if (!this->is_sub_surface) {
04998 
04999             mmsfb->bei->stretchBlit(this, source, src, dst, blittingflags);
05000 
05001             ret = true;
05002         }
05003         else {
05004             CLIPSUBSURFACE
05005 
05006             mmsfb->bei->stretchBlit(this, source, src, dst, blittingflags);
05007 
05008             UNCLIPSUBSURFACE
05009 
05010             ret = true;
05011         }
05012 
05013 #endif
05014     }
05015     else {
05016 
05017         // prepare source rectangle
05018         if (source->is_sub_surface) {
05019             src.x+=source->sub_surface_xoff;
05020             src.y+=source->sub_surface_yoff;
05021         }
05022 
05023         // normal stretch blit
05024         if (!this->is_sub_surface) {
05025             ret = extendedAccelStretchBlit(source, &src, &dst, real_dest_rect, calc_dest_rect);
05026         }
05027         else {
05028             CLIPSUBSURFACE
05029 
05030             dst.x+=this->sub_surface_xoff;
05031             dst.y+=this->sub_surface_yoff;
05032 
05033             ret = extendedAccelStretchBlit(source, &src, &dst, real_dest_rect, calc_dest_rect);
05034 
05035             dst.x-=this->sub_surface_xoff;
05036             dst.y-=this->sub_surface_yoff;
05037 
05038             UNCLIPSUBSURFACE
05039         }
05040 
05041         // reset source rectangle
05042         if (source->is_sub_surface) {
05043             src.x-=source->sub_surface_xoff;
05044             src.y-=source->sub_surface_yoff;
05045         }
05046     }
05047 
05048     if (!ret) {
05049         // restore opaque/transparent status
05050         MMSFBSURFACE_WRITE_BUFFER(this).opaque      = opaque_saved;
05051         MMSFBSURFACE_WRITE_BUFFER(this).transparent = transparent_saved;
05052     }
05053 
05054     return ret;
05055 }
05056 
05057 bool MMSFBSurface::stretchBlitBuffer(MMSFBExternalSurfaceBuffer *extbuf, MMSFBSurfacePixelFormat src_pixelformat, int src_width, int src_height,
05058                                      MMSFBRectangle *src_rect, MMSFBRectangle *dest_rect,
05059                                      MMSFBRectangle *real_dest_rect, bool calc_dest_rect) {
05060     MMSFBRectangle src;
05061     MMSFBRectangle dst;
05062     bool ret = false;
05063 
05064     // use whole source surface if src_rect is not given
05065     if (src_rect) {
05066          src = *src_rect;
05067     }
05068     else {
05069          src.x = 0;
05070          src.y = 0;
05071          src.w = src_width;
05072          src.h = src_height;
05073     }
05074 
05075 
05076 
05077     // use whole destination surface if dest_rect is not given and calc_dest_rect is not set
05078     if ((dest_rect)&&(!calc_dest_rect)) {
05079          dst = *dest_rect;
05080     }
05081     else {
05082         if (!calc_dest_rect) {
05083             dst.x = 0;
05084             dst.y = 0;
05085             dst.w = this->config.w;
05086             dst.h = this->config.h;
05087         }
05088         else {
05089             // calc dest_rect from src_rect based on src/dst surface dimension
05090             dst.x = (src.x * this->config.w) / src_width;
05091             dst.y = (src.y * this->config.h) / src_height;
05092             dst.w = src.x + src.w - 1;
05093             dst.h = src.y + src.h - 1;
05094             dst.w = (dst.w * this->config.w) / src_width;
05095             dst.h = (dst.h * this->config.h) / src_height;
05096             dst.w = dst.w - dst.x + 1;
05097             dst.h = dst.h - dst.y + 1;
05098         }
05099     }
05100 
05101     // return the used dest_rect
05102     if (real_dest_rect)
05103         *real_dest_rect = dst;
05104 
05105     // check if i can blit without stretching
05106     if (src.w == dst.w && src.h == dst.h) {
05107         return blitBuffer(extbuf->ptr, extbuf->pitch, src_pixelformat, src_width, src_height, &src, dst.x, dst.y);
05108     }
05109 
05110     // check if initialized
05111     INITCHECK;
05112 
05113 
05114     //TODO: this reset is to be improved...
05115     MMSFBSURFACE_WRITE_BUFFER(this).opaque      = false;
05116     MMSFBSURFACE_WRITE_BUFFER(this).transparent = false;
05117 
05118     // finalize previous clear
05119     finClear();
05120 
05121     if (this->allocated_by == MMSFBSurfaceAllocatedBy_dfb) {
05122 #ifdef  __HAVE_DIRECTFB__
05123 #endif
05124     }
05125     else
05126     if (this->allocated_by == MMSFBSurfaceAllocatedBy_ogl) {
05127 #ifdef  __HAVE_OPENGL__
05128 
05129         if (!this->is_sub_surface) {
05130 
05131             mmsfb->bei->stretchBlitBuffer(this, extbuf, src_pixelformat, src_width, src_height,
05132                                             src, dst, this->config.blittingflags);
05133 
05134             ret = true;
05135         }
05136         else {
05137             CLIPSUBSURFACE
05138 
05139             mmsfb->bei->stretchBlitBuffer(this, extbuf, src_pixelformat, src_width, src_height,
05140                                             src, dst, this->config.blittingflags);
05141 
05142             UNCLIPSUBSURFACE
05143 
05144             ret = true;
05145         }
05146 
05147 #endif
05148     }
05149     else {
05150         /* normal stretch blit */
05151         if (!this->is_sub_surface) {
05152             ret = extendedAccelStretchBlitBuffer(extbuf, src_pixelformat, src_width, src_height, &src, &dst,
05153                                                  real_dest_rect, calc_dest_rect);
05154         }
05155         else {
05156             CLIPSUBSURFACE
05157 
05158             dst.x+=this->sub_surface_xoff;
05159             dst.y+=this->sub_surface_yoff;
05160 
05161             ret = extendedAccelStretchBlitBuffer(extbuf, src_pixelformat, src_width, src_height, &src, &dst,
05162                                                  real_dest_rect, calc_dest_rect);
05163 
05164             dst.x-=this->sub_surface_xoff;
05165             dst.y-=this->sub_surface_yoff;
05166 
05167             UNCLIPSUBSURFACE
05168         }
05169 
05170     }
05171 
05172     return ret;
05173 }
05174 
05175 bool MMSFBSurface::stretchBlitBuffer(void *src_ptr, int src_pitch, MMSFBSurfacePixelFormat src_pixelformat, int src_width, int src_height,
05176                                      MMSFBRectangle *src_rect, MMSFBRectangle *dest_rect,
05177                                      MMSFBRectangle *real_dest_rect, bool calc_dest_rect) {
05178     MMSFBExternalSurfaceBuffer extbuf;
05179     memset(&extbuf, 0, sizeof(extbuf));
05180     extbuf.ptr = src_ptr;
05181     extbuf.pitch = src_pitch;
05182     return stretchBlitBuffer(&extbuf, src_pixelformat, src_width, src_height, src_rect, dest_rect,
05183                              real_dest_rect, calc_dest_rect);
05184 }
05185 
05186 
05187 void MMSFBSurface::processSwapDisplay(void *in_data, int in_data_len, void **out_data, int *out_data_len) {
05188 #if defined(__HAVE_FBDEV__) || defined(__HAVE_KMS__)
05189     MMSFBSurfaceBuffer *sb = this->config.surface_buffer;
05190 
05191     if (in_data_len >> 8) {
05192         MMSFBPERF_START_MEASURING;
05193 
05194 #ifdef __HAVE_FBDEV__
05195         // vsync
05196         mmsfb->mmsfbdev->waitForVSync();
05197 #else
05198 //      mmsfb->mmskms->waitForVSync();
05199 #endif
05200 
05201         MMSFBPERF_STOP_MEASURING_VSYNC(sb->mmsfbdev_surface);
05202     }
05203 
05204     MMSFBPERF_START_MEASURING;
05205 
05206 #ifdef __HAVE_FBDEV__
05207     // swap display
05208     mmsfb->mmsfbdev->panDisplay(in_data_len & 0xff, sb->buffers[0].ptr);
05209 #else
05210     // swap display
05211     mmsfb->mmskms->panDisplay(in_data_len & 0xff, sb->buffers[0].ptr);
05212 #endif
05213 
05214     MMSFBPERF_STOP_MEASURING_SWAPDISPLAY(sb->mmsfbdev_surface);
05215 #endif
05216 }
05217 
05218 void MMSFBSurface::swapDisplay(bool vsync) {
05219 #if defined(__HAVE_FBDEV__) || defined(__HAVE_KMS__)
05220     MMSFBSurfaceBuffer *sb = this->config.surface_buffer;
05221 
05222     if (sb->mmsfbdev_surface != this)
05223         return;
05224 
05225     // surface is the fb layer surface
05226     if (sb->numbuffers > 2) {
05227         // more than two buffers (e.g. TRIPLE buffering), so we should use non-blocked panning
05228         if (!this->fbdev_ts) {
05229             // init thread server for display panning
05230             this->fbdev_ts = new MMSThreadServer(100, "MMSThreadServer4MMSFBSurface", false);
05231             this->fbdev_ts->onProcessData.connect(sigc::mem_fun(this,&MMSFBSurface::processSwapDisplay));
05232             this->fbdev_ts->start();
05233         }
05234 
05235         // hard disable vsync
05236         // reason: difference between current and next buffer is minimal and both buffers are not the next write buffer
05237         // TODO: this can be hw dependent, then we have to change the code
05238         vsync = false;
05239 
05240         // trigger panning and return immediately
05241         this->fbdev_ts->trigger(NULL, sb->currbuffer_read | ((vsync)?0x100:0));
05242     }
05243     else
05244     if (sb->numbuffers == 2) {
05245         // two buffers (BACKVIDEO)
05246         if (vsync) {
05247             MMSFBPERF_START_MEASURING;
05248 
05249 #ifdef __HAVE_FBDEV__
05250             // vsync
05251             mmsfb->mmsfbdev->waitForVSync();
05252 #else
05253 //          mmsfb->mmskms->waitForVSync();
05254 #endif
05255 
05256             MMSFBPERF_STOP_MEASURING_VSYNC(sb->mmsfbdev_surface);
05257         }
05258 
05259         MMSFBPERF_START_MEASURING;
05260 
05261 #ifdef __HAVE_FBDEV__
05262         // swap display
05263         mmsfb->mmsfbdev->panDisplay(sb->currbuffer_read, sb->buffers[0].ptr);
05264 #else
05265         mmsfb->mmskms->panDisplay(sb->currbuffer_read, sb->buffers[0].ptr);
05266 #endif
05267 
05268         MMSFBPERF_STOP_MEASURING_SWAPDISPLAY(sb->mmsfbdev_surface);
05269     }
05270 #endif
05271 }
05272 
05273 
05274 bool MMSFBSurface::flip(MMSFBRegion *region) {
05275 
05276     // check if initialized
05277     INITCHECK;
05278 
05279     // finalize previous clear
05280     finClear();
05281 
05282     if (this->allocated_by == MMSFBSurfaceAllocatedBy_dfb) {
05283 #ifdef  __HAVE_DIRECTFB__
05284         if (region)
05285              D_DEBUG_AT( MMS_Surface, "flip( %d,%d - %dx%d ) <- %dx%d\n",
05286                          DFB_RECTANGLE_VALS_FROM_REGION(region), this->config.w, this->config.h );
05287         else
05288              D_DEBUG_AT( MMS_Surface, "flip( %d,%d - %dx%d ) <- %dx%d\n",
05289                          0, 0, this->config.w, this->config.h, this->config.w, this->config.h );
05290 
05291         MMSFB_TRACE();
05292 
05293         DFBResult   dfbres;
05294 
05295 #ifdef USE_DFB_WINMAN
05296 
05297         // flip
05298         if ((dfbres=this->dfb_surface->Flip(this->dfb_surface, region, this->flipflags)) != DFB_OK) {
05299             MMSFB_SetError(dfbres, "IDirectFBSurface::Flip() failed");
05300 
05301             return false;
05302         }
05303 
05304 #endif
05305 
05306 #ifdef USE_MMSFB_WINMAN
05307 
05308         // flip
05309         if (!this->is_sub_surface) {
05310             if ((dfbres=this->dfb_surface->Flip(this->dfb_surface, (DFBRegion*)region, getDFBSurfaceFlipFlagsFromMMSFBFlipFlags(this->flipflags))) != DFB_OK) {
05311                 MMSFB_SetError(dfbres, "IDirectFBSurface::Flip() failed");
05312 
05313                 return false;
05314             }
05315         }
05316         else {
05317 #ifndef USE_DFB_SUBSURFACE
05318             CLIPSUBSURFACE
05319 
05320             MMSFBRegion myregion;
05321             if (!region) {
05322                 myregion.x1 = 0;
05323                 myregion.y1 = 0;
05324                 myregion.x2 = this->config.w - 1;
05325                 myregion.y2 = this->config.h - 1;
05326             }
05327             else
05328                 myregion = *region;
05329 
05330             myregion.x1+=this->sub_surface_xoff;
05331             myregion.y1+=this->sub_surface_yoff;
05332             myregion.x2+=this->sub_surface_xoff;
05333             myregion.y2+=this->sub_surface_yoff;
05334 
05335             this->dfb_surface->Flip(this->dfb_surface, (DFBRegion*)&myregion, getDFBSurfaceFlipFlagsFromMMSFBFlipFlags(this->flipflags));
05336 
05337 #else
05338             this->dfb_surface->Flip(this->dfb_surface, region, getDFBSurfaceFlipFlagsFromMMSFBFlipFlags(this->flipflags));
05339 #endif
05340 
05341 #ifndef USE_DFB_SUBSURFACE
05342             UNCLIPSUBSURFACE
05343 #endif
05344         }
05345 
05346         if (this->config.iswinsurface) {
05347             // inform the window manager
05348             mmsfbwindowmanager->flipSurface(this, region);
05349         }
05350         else {
05351             if (this->is_sub_surface) {
05352                 // sub surface, use the root parent surface
05353                 if (this->root_parent->config.iswinsurface) {
05354                     // inform the window manager, use the correct region
05355                     MMSFBRegion reg;
05356                     if (region)
05357                         reg = *region;
05358                     else {
05359                         reg.x1=0;
05360                         reg.y1=0;
05361                         reg.x2=sub_surface_rect.w-1;
05362                         reg.y2=sub_surface_rect.h-1;
05363                     }
05364                     reg.x1+=this->sub_surface_xoff;
05365                     reg.y1+=this->sub_surface_yoff;
05366                     reg.x2+=this->sub_surface_xoff;
05367                     reg.y2+=this->sub_surface_yoff;
05368                     mmsfbwindowmanager->flipSurface(this->root_parent, &reg);
05369                 }
05370             }
05371         }
05372 
05373 #endif
05374 
05375         return true;
05376 #else
05377         return false;
05378 #endif
05379     }
05380     else
05381     if (this->allocated_by == MMSFBSurfaceAllocatedBy_ogl) {
05382 #ifdef  __HAVE_OPENGL__
05383         if (this->config.surface_buffer->numbuffers > 1) {
05384             // currently we work with fbo frontbuffers only, ogl flips will only supported via glXSwapBuffers()
05385 
05386             //TODO...
05387         }
05388 
05389         if (!this->config.surface_buffer->ogl_fbo) {
05390             // this is the primary fbo, flip it to the xwindow
05391             // note: there is no chance to flip a region with glXSwapBuffers!!!
05392             mmsfb->bei->swap();
05393         }
05394 
05395         if (this->config.iswinsurface) {
05396             // inform the window manager
05397 #ifdef  __HAVE_GLX__
05398             mmsfbwindowmanager->flipSurface(NULL);
05399 #else
05400             mmsfbwindowmanager->flipSurface(this, region);
05401 #endif
05402         }
05403         else {
05404             if (this->is_sub_surface) {
05405                 // sub surface, use the root parent surface
05406                 if (this->root_parent->config.iswinsurface) {
05407 
05408                     // inform the window manager, use the correct region
05409 #ifdef  __HAVE_GLX__
05410                     mmsfbwindowmanager->flipSurface(NULL);
05411 #else
05412                     MMSFBRegion reg;
05413                     if (region)
05414                         reg = *region;
05415                     else {
05416                         reg.x1=0;
05417                         reg.y1=0;
05418                         reg.x2=sub_surface_rect.w-1;
05419                         reg.y2=sub_surface_rect.h-1;
05420                     }
05421                     reg.x1+=this->sub_surface_xoff;
05422                     reg.y1+=this->sub_surface_yoff;
05423                     reg.x2+=this->sub_surface_xoff;
05424                     reg.y2+=this->sub_surface_yoff;
05425                     mmsfbwindowmanager->flipSurface(this->root_parent, &reg);
05426 #endif
05427                 }
05428             }
05429         }
05430 
05431 
05432 
05433 
05434         return true;
05435 #else
05436         return false;
05437 #endif
05438     }
05439     else {
05440         // flip my own surfaces
05441         MMSFBSurfaceBuffer *sb = this->config.surface_buffer;
05442         if (sb->numbuffers > 1) {
05443             // flip is only needed, if we have at least one backbuffer
05444             if (!this->is_sub_surface) {
05445                 // not a subsurface
05446                 if (!region) {
05447                     // flip my buffers without blitting
05448                     sb->currbuffer_read++;
05449                     if (sb->currbuffer_read >= sb->numbuffers)
05450                         sb->currbuffer_read = 0;
05451                     sb->currbuffer_write++;
05452                     if (sb->currbuffer_write >= sb->numbuffers)
05453                         sb->currbuffer_write = 0;
05454 
05455 #if defined(__HAVE_FBDEV__) || defined(__HAVE_KMS__)
05456                     if (sb->mmsfbdev_surface == this) {
05457                         // surface is the fb layer surface, so we have to swap the display
05458                         swapDisplay(true);
05459                     }
05460 #endif
05461                 }
05462                 else {
05463                     MMSFBRectangle src_rect;
05464                     src_rect.x = region->x1;
05465                     src_rect.y = region->y1;
05466                     src_rect.w = region->x2 - region->x1 + 1;
05467                     src_rect.h = region->y2 - region->y1 + 1;
05468 
05469                     // check if region is equal to the whole surface
05470                     if   ((src_rect.x == 0) && (src_rect.y == 0)
05471                         &&(src_rect.w == this->config.w) && (src_rect.h == this->config.h)) {
05472                         // yes, flip my buffers without blitting
05473                         sb->currbuffer_read++;
05474                         if (sb->currbuffer_read >= sb->numbuffers)
05475                             sb->currbuffer_read = 0;
05476                         sb->currbuffer_write++;
05477                         if (sb->currbuffer_write >= sb->numbuffers)
05478                             sb->currbuffer_write = 0;
05479 
05480 #if defined(__HAVE_FBDEV__) || defined(__HAVE_KMS__)
05481                         if (sb->mmsfbdev_surface == this) {
05482                             // surface is the fb layer surface, so we have to swap the display
05483                             swapDisplay(true);
05484                         }
05485 #endif
05486                     }
05487                     else {
05488                         // blit region from write to read buffer of the same MMSFBSurface
05489                         MMSFBBlittingFlags savedbf = this->config.blittingflags;
05490                         this->config.blittingflags = (MMSFBBlittingFlags)MMSFB_BLIT_NOFX;
05491 
05492                         this->surface_invert_lock = true;
05493 
05494                         if (MMSFBSURFACE_READ_BUFFER(this).opaque)
05495                             MMSFBSURFACE_READ_BUFFER(this).opaque = MMSFBSURFACE_WRITE_BUFFER(this).opaque;
05496                         if (MMSFBSURFACE_READ_BUFFER(this).transparent)
05497                             MMSFBSURFACE_READ_BUFFER(this).transparent = MMSFBSURFACE_WRITE_BUFFER(this).transparent;
05498 
05499                         this->extendedAccelBlit(this, &src_rect, src_rect.x, src_rect.y, MMSFB_BLIT_NOFX);
05500 
05501                         this->surface_invert_lock = false;
05502 
05503                         this->config.blittingflags = savedbf;
05504 
05505 #if defined(__HAVE_FBDEV__) || defined(__HAVE_KMS__)
05506                         if (sb->mmsfbdev_surface == this) {
05507                             // surface is the fb layer surface
05508                             // there is no need to swapDisplay() because current read buffer (currbuffer_read) has NOT changed
05509                             if (this->flipflags & MMSFB_FLIP_FLUSH) {
05510                                 // BUT: MMSFB_FLIP_FLUSH tells us, that we have to trigger an pan event to frame buffer driver
05511                                 swapDisplay(true);
05512                             }
05513                         }
05514 #endif
05515                     }
05516                 }
05517             }
05518             else {
05519                 CLIPSUBSURFACE
05520 
05521                 MMSFBRectangle src_rect;
05522                 if (!region) {
05523                     src_rect.x = 0;
05524                     src_rect.y = 0;
05525                     src_rect.w = this->config.w;
05526                     src_rect.h = this->config.h;
05527                 }
05528                 else {
05529                     src_rect.x = region->x1;
05530                     src_rect.y = region->y1;
05531                     src_rect.w = region->x2 - region->x1 + 1;
05532                     src_rect.h = region->y2 - region->y1 + 1;
05533                 }
05534 
05535                 src_rect.x+=this->sub_surface_xoff;
05536                 src_rect.y+=this->sub_surface_yoff;
05537 
05538                 // blit region from write to read buffer of the same MMSFBSurface
05539                 MMSFBBlittingFlags savedbf = this->config.blittingflags;
05540                 this->config.blittingflags = (MMSFBBlittingFlags)MMSFB_BLIT_NOFX;
05541 
05542                 this->surface_invert_lock = true;
05543 
05544                 if (MMSFBSURFACE_READ_BUFFER(this).opaque)
05545                     MMSFBSURFACE_READ_BUFFER(this).opaque = MMSFBSURFACE_WRITE_BUFFER(this).opaque;
05546                 if (MMSFBSURFACE_READ_BUFFER(this).transparent)
05547                     MMSFBSURFACE_READ_BUFFER(this).transparent = MMSFBSURFACE_WRITE_BUFFER(this).transparent;
05548 
05549                 this->extendedAccelBlit(this, &src_rect, src_rect.x, src_rect.y, MMSFB_BLIT_NOFX);
05550 
05551                 this->surface_invert_lock = false;
05552 
05553                 this->config.blittingflags = savedbf;
05554 
05555                 UNCLIPSUBSURFACE
05556             }
05557         }
05558 
05559 #if defined(__HAVE_FBDEV__) || defined(__HAVE_KMS__)
05560         if (sb->mmsfbdev_surface) {
05561             if (sb->mmsfbdev_surface != this) {
05562                 // this surface is the backbuffer in system memory of the layer (BACKSYSTEM buffer mode)
05563 
05564                 MMSFBPERF_START_MEASURING;
05565 
05566 #ifdef __HAVE_FBDEV__
05567                 // sync
05568                 mmsfb->mmsfbdev->waitForVSync();
05569 #else
05570 //              mmsfb->mmskms->waitForVSync();
05571 #endif
05572 
05573                 MMSFBPERF_STOP_MEASURING_VSYNC(sb->mmsfbdev_surface);
05574 
05575                 // put the image to the framebuffer
05576                 if (!region) {
05577                     // full
05578                     sb->mmsfbdev_surface->blit(this, NULL, 0, 0);
05579                 }
05580                 else {
05581                     // a few lines
05582                     MMSFBRectangle rect;
05583                     rect.x = 0;
05584                     rect.y = region->y1;
05585                     rect.w = this->config.w;
05586                     rect.h = region->y2 - region->y1 + 1;
05587                     sb->mmsfbdev_surface->blit(this, &rect, rect.x, rect.y);
05588                 }
05589             }
05590         }
05591         else {
05592 #endif
05593 
05594 #ifdef __HAVE_XLIB__
05595         if (sb->x_image[0]) {
05596             // XSHM, put the image to the x-server
05597             if (!this->scaler) {
05598                 // no scaler defined
05599                 mmsfb->xlock.lock();
05600                 XLockDisplay(mmsfb->x_display);
05601                 if (!region) {
05602                     // put whole image
05603                     int dx = 0;
05604                     int dy = 0;
05605                     if (mmsfb->fullscreen == MMSFB_FSM_ASPECT_RATIO) {
05606                         dx = (mmsfb->display_w - this->config.w) >> 1;
05607                         dy = (mmsfb->display_h - this->config.h) >> 1;
05608                     }
05609                     if(this->layer) {
05610                         //printf("before putimage window %d\n layerid %d\n this->config.w: %d\n this->config.h: %d\n", layer->x_window, layer->config.id, layer->config.w, layer->config.h);
05611 
05612                         if ((mmsfb->fullscreen == MMSFB_FSM_TRUE || mmsfb->fullscreen == MMSFB_FSM_ASPECT_RATIO)) {
05613 //TODO: change the ifdef, what to do if XRenderComposite not available?
05614 #ifdef __HAVE_XV__
05615 
05616                             MMSFBPERF_START_MEASURING;
05617 
05618                             //put image to layer pixmap
05619                             XShmPutImage(mmsfb->x_display, layer->pixmap, layer->x_gc, sb->x_image[sb->currbuffer_read],
05620                                           0, 0, dx, dy,
05621                                           layer->config.w, layer->config.h, False);
05622 
05623                             double scale = (double)layer->x_window_w / layer->config.w;
05624 
05625                             // Scaling matrix
05626                             XTransform xform = {{
05627                                 { XDoubleToFixed( 1 ), XDoubleToFixed( 0 ), XDoubleToFixed(     0 ) },
05628                                 { XDoubleToFixed( 0 ), XDoubleToFixed( 1 ), XDoubleToFixed(     0 ) },
05629                                 { XDoubleToFixed( 0 ), XDoubleToFixed( 0 ), XDoubleToFixed( scale ) }
05630                             }};
05631 
05632                             XRenderSetPictureTransform( mmsfb->x_display, layer->x_pixmap_pict, &xform );
05633                             XRenderSetPictureFilter( mmsfb->x_display, layer->x_pixmap_pict, FilterBilinear, 0, 0 );
05634 
05635 
05636                             //put render image
05637                               /* copy the pixmap content using XRender */
05638                             XRenderComposite(mmsfb->x_display,
05639                                    PictOpSrc,
05640                                    layer->x_pixmap_pict,
05641                                    None,
05642                                    layer->x_window_pict,
05643                                    0, 0,
05644                                    0, 0,
05645                                    0, 0,
05646                                    layer->x_window_w, layer->x_window_h);
05647 
05648                             //XFlush(mmsfb->x_display);
05649                             XSync(mmsfb->x_display, False);
05650 
05651                             MMSFBPERF_STOP_MEASURING_XSHMPUTIMAGE(this, layer->config.w, layer->config.h);
05652 
05653 #endif
05654                         } else {
05655 
05656                             MMSFBPERF_START_MEASURING;
05657 
05658                             XShmPutImage(mmsfb->x_display, layer->x_window, layer->x_gc, sb->x_image[sb->currbuffer_read],
05659                                           0, 0, dx, dy,
05660                                           this->config.w, this->config.h, False);
05661 
05662                             //XFlush(mmsfb->x_display);
05663                             XSync(mmsfb->x_display, False);
05664 
05665                             MMSFBPERF_STOP_MEASURING_XSHMPUTIMAGE(this, this->config.w, this->config.h);
05666                         }
05667                     }
05668                 }
05669                 else {
05670                     // put only a region
05671                     MMSFBRegion myreg = *region;
05672                     if (myreg.x1 < 0) myreg.x1 = 0;
05673                     if (myreg.y1 < 0) myreg.y1 = 0;
05674                     if (myreg.x2 >= this->config.w) myreg.x2 = this->config.w - 1;
05675                     if (myreg.y2 >= this->config.h) myreg.y2 = this->config.h - 1;
05676                     if ((myreg.x2 >= myreg.x1)&&(myreg.y2 >= myreg.y1)) {
05677                         int dx = 0;
05678                         int dy = 0;
05679                         if (mmsfb->fullscreen == MMSFB_FSM_ASPECT_RATIO) {
05680                             dx = (mmsfb->display_w - this->config.w) >> 1;
05681                             dy = (mmsfb->display_h - this->config.h) >> 1;
05682                         }
05683                         if(this->layer) {
05684                             //printf("before putimage region %d\n layerid %d\n this->config.w: %d\n this->config.h: %d\n", layer->x_window, layer->config.id, layer->config.w, layer->config.h);
05685 
05686                             if ((mmsfb->fullscreen == MMSFB_FSM_TRUE || mmsfb->fullscreen == MMSFB_FSM_ASPECT_RATIO)) {
05687 //TODO: change the ifdef, what to do if XRenderComposite not available?
05688 #ifdef __HAVE_XV__
05689 
05690                                 MMSFBPERF_START_MEASURING;
05691 
05692                                 int ww = myreg.x2 - myreg.x1 + 1;
05693                                 int hh = myreg.y2 - myreg.y1 + 1;
05694 
05695                                 //put image to layer pixmap
05696                                 XShmPutImage(mmsfb->x_display, layer->pixmap, layer->x_gc, sb->x_image[sb->currbuffer_read],
05697                                              myreg.x1, myreg.y1, myreg.x1 + dx, myreg.y1 + dy,
05698                                              ww, hh, False);
05699 
05700                                 double scale = (double)layer->x_window_w / layer->config.w; // We'll scale the window to 50% of its original size
05701 
05702                                 // Scaling matrix
05703                                 XTransform xform = {{
05704                                     { XDoubleToFixed( 1 ), XDoubleToFixed( 0 ), XDoubleToFixed(     0 ) },
05705                                     { XDoubleToFixed( 0 ), XDoubleToFixed( 1 ), XDoubleToFixed(     0 ) },
05706                                     { XDoubleToFixed( 0 ), XDoubleToFixed( 0 ), XDoubleToFixed( scale ) }
05707                                 }};
05708 
05709                                 XRenderSetPictureTransform( mmsfb->x_display, layer->x_pixmap_pict, &xform );
05710                                 XRenderSetPictureFilter( mmsfb->x_display, layer->x_pixmap_pict, FilterBilinear, 0, 0 );
05711 
05712                                 //put render image
05713                                 /* copy the pixmap content using XRender */
05714                                 XRenderComposite(mmsfb->x_display,
05715                                        PictOpSrc,
05716                                        layer->x_pixmap_pict,
05717                                        None,
05718                                        layer->x_window_pict,
05719                                        0, 0,
05720                                        0, 0,
05721                                        0, 0,
05722                                        layer->x_window_w, layer->x_window_h);
05723 
05724 
05725                                 //XFlush(mmsfb->x_display);
05726                                 XSync(mmsfb->x_display, False);
05727 
05728                                 MMSFBPERF_STOP_MEASURING_XSHMPUTIMAGE(this, ww, hh);
05729 
05730 #endif
05731                             } else {
05732 
05733                                 MMSFBPERF_START_MEASURING;
05734 
05735                                 XShmPutImage(mmsfb->x_display, layer->x_window, layer->x_gc, sb->x_image[sb->currbuffer_read],
05736                                           0, 0, dx, dy,
05737                                           this->config.w, this->config.h, False);
05738 
05739                                 //XFlush(mmsfb->x_display);
05740                                 XSync(mmsfb->x_display, False);
05741 
05742                                 MMSFBPERF_STOP_MEASURING_XSHMPUTIMAGE(this, this->config.w, this->config.h);
05743                             }
05744                         }
05745                     }
05746                 }
05747                 XUnlockDisplay(mmsfb->x_display);
05748                 mmsfb->xlock.unlock();
05749             } else {
05750                 //printf("do scaler....\n");
05751 
05752                 // scale to scaler
05753                 if (!region) {
05754                     // scale whole image
05755                     this->scaler->stretchBlit(this, NULL, NULL);
05756                     this->scaler->flip();
05757                 }
05758                 else {
05759                     // scale only a region
05760                     MMSFBRegion myreg = *region;
05761 
05762                     // enlarge the region because of little calulation errors while stretching
05763                     myreg.x1--;
05764                     myreg.y1--;
05765                     myreg.x2++;
05766                     myreg.y2++;
05767 
05768                     // check region
05769                     if (myreg.x1 < 0) myreg.x1 = 0;
05770                     if (myreg.y1 < 0) myreg.y1 = 0;
05771                     if (myreg.x2 >= this->config.w) myreg.x2 = this->config.w - 1;
05772                     if (myreg.y2 >= this->config.h) myreg.y2 = this->config.h - 1;
05773                     if ((myreg.x2 >= myreg.x1)&&(myreg.y2 >= myreg.y1)) {
05774                         // stretch & flip to make it visible on the screen
05775                         MMSFBRectangle src_rect;
05776                         src_rect.x = myreg.x1;
05777                         src_rect.y = myreg.y1;
05778                         src_rect.w = myreg.x2 - myreg.x1 + 1;
05779                         src_rect.h = myreg.y2 - myreg.y1 + 1;
05780                         MMSFBRectangle dst_rect;
05781                         this->scaler->stretchBlit(this, &src_rect, NULL, &dst_rect, true);
05782                         myreg.x1 = dst_rect.x;
05783                         myreg.y1 = dst_rect.y;
05784                         myreg.x2 = dst_rect.x + dst_rect.w - 1;
05785                         myreg.y2 = dst_rect.y + dst_rect.h - 1;
05786                         this->scaler->flip(&myreg);
05787                     }
05788                 }
05789             }
05790         }
05791 #ifdef __HAVE_XV__
05792         else
05793         if (sb->xv_image[0]) {
05794             // XVSHM, put the image to the x-server
05795             mmsfb->xlock.lock();
05796             XLockDisplay(mmsfb->x_display);
05797             if (mmsfb->fullscreen == MMSFB_FSM_TRUE || mmsfb->fullscreen == MMSFB_FSM_ASPECT_RATIO) {
05798                 // calc ratio
05799                 MMSFBRectangle dest;
05800                 calcAspectRatio(mmsfb->x11_win_rect.w, mmsfb->x11_win_rect.h, mmsfb->display_w, mmsfb->display_h, dest,
05801                                 (mmsfb->fullscreen == MMSFB_FSM_ASPECT_RATIO), true);
05802 
05803                 MMSFBPERF_START_MEASURING;
05804 
05805                 //printf("do vputimage\n");
05806                 // put image
05807                 XvShmPutImage(mmsfb->x_display, mmsfb->xv_port, layer->x_window, layer->x_gc, sb->xv_image[sb->currbuffer_read],
05808                               0, 0, mmsfb->x11_win_rect.w, mmsfb->x11_win_rect.h,
05809                               dest.x, dest.y, dest.w, dest.h, False);
05810 
05811                 //XFlush(mmsfb->x_display);
05812                 XSync(mmsfb->x_display, False);
05813 
05814                 MMSFBPERF_STOP_MEASURING_XVSHMPUTIMAGE(this, mmsfb->x11_win_rect.w, mmsfb->x11_win_rect.h, dest.w, dest.h);
05815             }
05816             else if (mmsfb->resized) {
05817 
05818                 MMSFBPERF_START_MEASURING;
05819 
05820                 //printf("stretch to %d:%d\n",mmsfb->target_window_w, mmsfb->target_window_h);
05821                 XvShmPutImage(mmsfb->x_display, mmsfb->xv_port, layer->x_window, layer->x_gc, sb->xv_image[sb->currbuffer_read],
05822                               0, 0, mmsfb->x11_win_rect.w, mmsfb->x11_win_rect.h,
05823                               0, 0, mmsfb->target_window_w, mmsfb->target_window_h, False);
05824 
05825                 //XFlush(mmsfb->x_display);
05826                 XSync(mmsfb->x_display, False);
05827 
05828                 MMSFBPERF_STOP_MEASURING_XVSHMPUTIMAGE(this, mmsfb->x11_win_rect.w, mmsfb->x11_win_rect.h, mmsfb->target_window_w, mmsfb->target_window_h);
05829             }
05830             else {
05831                 /*printf("do vputimage2\n");
05832                 printf("layer: %x, this: %x\n", layer, this);
05833                 printf("sb->xv_image: %x\n", sb->xv_image[sb->currbuffer_read]);
05834 */
05835 
05836                 MMSFBPERF_START_MEASURING;
05837 
05838                 XvShmPutImage(mmsfb->x_display, mmsfb->xv_port, layer->x_window, layer->x_gc, sb->xv_image[sb->currbuffer_read],
05839                               0, 0, mmsfb->x11_win_rect.w, mmsfb->x11_win_rect.h,
05840                               0, 0, mmsfb->x11_win_rect.w, mmsfb->x11_win_rect.h, False);
05841 
05842                 //XFlush(mmsfb->x_display);
05843                 XSync(mmsfb->x_display, False);
05844 
05845                 MMSFBPERF_STOP_MEASURING_XVSHMPUTIMAGE(this, mmsfb->x11_win_rect.w, mmsfb->x11_win_rect.h, mmsfb->x11_win_rect.w, mmsfb->x11_win_rect.h);
05846             }
05847 
05848             XUnlockDisplay(mmsfb->x_display);
05849             mmsfb->xlock.unlock();
05850         }
05851 #endif
05852 #endif
05853 
05854 #if defined(__HAVE_FBDEV__) || defined(__HAVE_KMS__)
05855         }
05856 #endif
05857 
05858         if (this->config.iswinsurface) {
05859             // inform the window manager
05860             mmsfbwindowmanager->flipSurface(this, region);
05861         }
05862         else {
05863             if (this->is_sub_surface) {
05864                 // sub surface, use the root parent surface
05865                 if (this->root_parent->config.iswinsurface) {
05866                     // inform the window manager, use the correct region
05867                     MMSFBRegion reg;
05868                     if (region)
05869                         reg = *region;
05870                     else {
05871                         reg.x1=0;
05872                         reg.y1=0;
05873                         reg.x2=sub_surface_rect.w-1;
05874                         reg.y2=sub_surface_rect.h-1;
05875                     }
05876                     reg.x1+=this->sub_surface_xoff;
05877                     reg.y1+=this->sub_surface_yoff;
05878                     reg.x2+=this->sub_surface_xoff;
05879                     reg.y2+=this->sub_surface_yoff;
05880                     mmsfbwindowmanager->flipSurface(this->root_parent, &reg);
05881                 }
05882             }
05883         }
05884 
05885         return true;
05886     }
05887 }
05888 
05889 
05890 bool MMSFBSurface::flip(int x1, int y1, int x2, int y2) {
05891     MMSFBRegion region(x1, y1, x2, y2);
05892     return flip(&region);
05893 }
05894 
05895 
05896 bool MMSFBSurface::refresh() {
05897     // check if initialized
05898     INITCHECK;
05899 
05900     // finalize previous clear
05901     finClear();
05902 
05903     if (this->allocated_by == MMSFBSurfaceAllocatedBy_dfb) {
05904 #ifdef  __HAVE_DIRECTFB__
05905 #endif
05906     }
05907     else {
05908 #ifdef __HAVE_XLIB__
05909         MMSFBSurfaceBuffer *sb = this->config.surface_buffer;
05910         if (sb->x_image[0]) {
05911             // XSHM, put the image to the x-server
05912             if (!this->scaler) {
05913                 // no scaler defined
05914                 mmsfb->xlock.lock();
05915                 XLockDisplay(mmsfb->x_display);
05916                 int dx = 0;
05917                 int dy = 0;
05918 /*              if (mmsfb->fullscreen == MMSFB_FSM_ASPECT_RATIO) {
05919                     dx = (mmsfb->display_w - this->config.w) >> 1;
05920                     dy = (mmsfb->display_h - this->config.h) >> 1;
05921                 }
05922 
05923                 XShmPutImage(mmsfb->x_display, layer->x_window, layer->x_gc, sb->x_image[sb->currbuffer_read],
05924                               0, 0, dx, dy,
05925                               this->config.w, this->config.h, False);
05926 */
05927 
05928                 if (mmsfb->fullscreen == MMSFB_FSM_TRUE) {
05929                         // put image to layer pixmap
05930                         XShmPutImage(mmsfb->x_display, layer->pixmap, layer->x_gc, sb->x_image[sb->currbuffer_read],
05931                                                   0, 0, dx, dy,
05932                                                   layer->config.w, layer->config.h, False);
05933 
05934                         double scale = (double)layer->x_window_w / layer->config.w;
05935 
05936                         // Scaling matrix
05937                         XTransform xform = {{
05938                                 { XDoubleToFixed( 1 ), XDoubleToFixed( 0 ), XDoubleToFixed(     0 ) },
05939                                 { XDoubleToFixed( 0 ), XDoubleToFixed( 1 ), XDoubleToFixed(     0 ) },
05940                                 { XDoubleToFixed( 0 ), XDoubleToFixed( 0 ), XDoubleToFixed( scale ) }
05941                         }};
05942 
05943                         XRenderSetPictureTransform( mmsfb->x_display, layer->x_pixmap_pict, &xform );
05944                         XRenderSetPictureFilter( mmsfb->x_display, layer->x_pixmap_pict, FilterBilinear, 0, 0 );
05945 
05946                         //put render image, copy the pixmap content using XRender
05947                         XRenderComposite(mmsfb->x_display,
05948                                    PictOpSrc,
05949                                    layer->x_pixmap_pict,
05950                                    None,
05951                                    layer->x_window_pict,
05952                                    0, 0,
05953                                    0, 0,
05954                                    0, 0,
05955                                    layer->x_window_w, layer->x_window_h);
05956 
05957                 } else {
05958                         if (mmsfb->fullscreen == MMSFB_FSM_ASPECT_RATIO) {
05959                                 dx = (mmsfb->display_w - this->config.w) >> 1;
05960                                 dy = (mmsfb->display_h - this->config.h) >> 1;
05961                         }
05962 
05963                         XShmPutImage(mmsfb->x_display, layer->x_window, layer->x_gc, sb->x_image[sb->currbuffer_read],
05964                                                   0, 0, dx, dy,
05965                                                   this->config.w, this->config.h, False);
05966                 }
05967 
05968                 //XFlush(mmsfb->x_display);
05969                 XSync(mmsfb->x_display, False);
05970                 XUnlockDisplay(mmsfb->x_display);
05971                 mmsfb->xlock.unlock();
05972             }
05973             else {
05974                 // scale to scaler
05975                 this->scaler->stretchBlit(this, NULL, NULL);
05976                 this->scaler->flip();
05977             }
05978         }
05979 #ifdef __HAVE_XV__
05980         else
05981         if (sb->xv_image[0]) {
05982             // XVSHM, put the image to the x-server
05983             this->lock();
05984             mmsfb->xlock.lock();
05985             XLockDisplay(mmsfb->x_display);
05986             if (mmsfb->fullscreen == MMSFB_FSM_TRUE || mmsfb->fullscreen == MMSFB_FSM_ASPECT_RATIO) {
05987                 // calc ratio
05988                 MMSFBRectangle dest;
05989                 calcAspectRatio(mmsfb->x11_win_rect.w, mmsfb->x11_win_rect.h, mmsfb->display_w, mmsfb->display_h, dest,
05990                                 (mmsfb->fullscreen == MMSFB_FSM_ASPECT_RATIO), true);
05991 
05992                 // put image
05993                 XvShmPutImage(mmsfb->x_display, mmsfb->xv_port, layer->x_window, layer->x_gc, sb->xv_image[sb->currbuffer_read],
05994                               0, 0, mmsfb->x11_win_rect.w, mmsfb->x11_win_rect.h,
05995                               dest.x, dest.y, dest.w, dest.h, False);
05996             } else if(mmsfb->resized) {
05997                 XvShmPutImage(mmsfb->x_display, mmsfb->xv_port, layer->x_window, layer->x_gc, sb->xv_image[sb->currbuffer_read],
05998                               0, 0, mmsfb->x11_win_rect.w, mmsfb->x11_win_rect.h,
05999                               0, 0, mmsfb->target_window_w, mmsfb->target_window_h, False);
06000             }else{
06001                 XvShmPutImage(mmsfb->x_display, mmsfb->xv_port, layer->x_window, layer->x_gc, sb->xv_image[sb->currbuffer_read],
06002                               0, 0, mmsfb->x11_win_rect.w, mmsfb->x11_win_rect.h,
06003                               0, 0, mmsfb->x11_win_rect.w, mmsfb->x11_win_rect.h, False);
06004             }
06005             //XFlush(mmsfb->x_display);
06006             XSync(mmsfb->x_display, False);
06007             XUnlockDisplay(mmsfb->x_display);
06008             mmsfb->xlock.unlock();
06009             this->unlock();
06010         }
06011 #endif
06012 #endif
06013     }
06014 
06015     return true;
06016 }
06017 
06018 bool MMSFBSurface::createCopy(MMSFBSurface **dstsurface, int w, int h,
06019                               bool copycontent, bool withbackbuffer, MMSFBSurfacePixelFormat pixelformat) {
06020 
06021     // check if initialized
06022     INITCHECK;
06023 
06024     // finalize previous clear
06025     finClear();
06026 
06027     if (this->is_sub_surface)
06028         return false;
06029 
06030     *dstsurface = NULL;
06031 
06032     if (!w) w = config.w;
06033     if (!h) h = config.h;
06034 
06035     // create new surface
06036     if (!mmsfb->createSurface(dstsurface, w, h, (pixelformat==MMSFB_PF_NONE)?this->config.surface_buffer->pixelformat:pixelformat,
06037                              (withbackbuffer)?this->config.surface_buffer->backbuffer:0,this->config.surface_buffer->systemonly)) {
06038         if (*dstsurface)
06039             delete *dstsurface;
06040         *dstsurface = NULL;
06041         return false;
06042     }
06043 
06044     if (copycontent) {
06045         // copy the content
06046         MMSFBRectangle dstrect;
06047         dstrect.x = 0;
06048         dstrect.y = 0;
06049         dstrect.w = w;
06050         dstrect.h = h;
06051         (*dstsurface)->setDrawingFlags((MMSFBDrawingFlags) MMSFB_DRAW_NOFX);
06052         (*dstsurface)->setBlittingFlags((MMSFBBlittingFlags) MMSFB_BLIT_NOFX);
06053         (*dstsurface)->stretchBlit(this, NULL, &dstrect);
06054         if (withbackbuffer) {
06055             (*dstsurface)->flip();
06056         }
06057     }
06058 
06059     return true;
06060 }
06061 
06062 bool MMSFBSurface::resize(int w, int h) {
06063 
06064     // check old size, resize only if size changed
06065     int old_w, old_h;
06066     if (!getSize(&old_w, &old_h)) return false;
06067     if ((old_w == w) && (old_h == h)) return true;
06068 
06069     // finalize previous clear
06070     finClear();
06071 
06072     if (!this->is_sub_surface) {
06073         // normal surface
06074         // create a copy
06075         MMSFBSurface *dstsurface;
06076         createCopy(&dstsurface, w, h, true, true);
06077 
06078         if (this->allocated_by == MMSFBSurfaceAllocatedBy_dfb) {
06079 #ifdef  __HAVE_DIRECTFB__
06080             D_DEBUG_AT( MMS_Surface, "resize( %dx%d -> %dx%d )\n",
06081                         this->config.w, this->config.h, w, h );
06082 
06083             MMSFB_TRACE();
06084 
06085             // move the dfb pointers
06086             IDirectFBSurface *s = this->dfb_surface;
06087             this->dfb_surface = dstsurface->dfb_surface;
06088             dstsurface->dfb_surface = s;
06089 
06090             // load the new configuration
06091             this->getConfiguration();
06092             dstsurface->getConfiguration();
06093 #endif
06094         }
06095         else {
06096             // move the surface buffer data
06097             MMSFBSurfaceBuffer *sb = this->config.surface_buffer;
06098             this->config.surface_buffer = dstsurface->config.surface_buffer;
06099             dstsurface->config.surface_buffer = sb;
06100 
06101             // set size to new size
06102             this->config.w = w;
06103             this->config.h = h;
06104 
06105             // load the new configuration
06106             this->getConfiguration();
06107         }
06108 
06109         // free dstsurface
06110         delete dstsurface;
06111 
06112         return true;
06113     }
06114     else  {
06115         // sub surface
06116         MMSFBRectangle rect = this->sub_surface_rect;
06117         rect.w = w;
06118         rect.h = h;
06119         return setSubSurface(&rect);
06120 
06121     }
06122 }
06123 
06124 
06125 
06126 void MMSFBSurface::modulateBrightness(MMSFBColor *color, unsigned char brightness) {
06127 
06128     /* full brightness? */
06129     if (brightness == 255) return;
06130 
06131     /* full darkness? */
06132     if (brightness == 0) {
06133         color->r = 0;
06134         color->g = 0;
06135         color->b = 0;
06136         return;
06137     }
06138 
06139     /* modulate the color */
06140     unsigned int bn = 100000 * (255-brightness);
06141     if (color->r > 0) {
06142         unsigned int i = (10000 * 255) / (unsigned int)color->r;
06143         color->r = (5+((10 * (unsigned int)color->r) - (bn / i))) / 10;
06144     }
06145     if (color->g > 0) {
06146         unsigned int i = (10000 * 255) / (unsigned int)color->g;
06147         color->g = (5+((10 * (unsigned int)color->g) - (bn / i))) / 10;
06148     }
06149     if (color->b > 0) {
06150         unsigned int i = (10000 * 255) / (unsigned int)color->b;
06151         color->b = (5+((10 * (unsigned int)color->b) - (bn / i))) / 10;
06152     }
06153 }
06154 
06155 void MMSFBSurface::modulateOpacity(MMSFBColor *color, unsigned char opacity) {
06156 
06157     /* full opacity? */
06158     if (opacity == 255) return;
06159 
06160     /* complete transparent? */
06161     if (opacity == 0) {
06162         color->a = 0;
06163         return;
06164     }
06165 
06166     /* modulate the alpha value */
06167     unsigned int bn = 100000 * (255-opacity);
06168     if (color->a > 0) {
06169         unsigned int i = (10000 * 255) / (unsigned int)color->a;
06170         color->a = (5+((10 * (unsigned int)color->a) - (bn / i))) / 10;
06171     }
06172 }
06173 
06174 
06175 bool MMSFBSurface::setBlittingFlagsByBrightnessAlphaAndOpacity(
06176                     unsigned char brightness, unsigned char alpha, unsigned char opacity) {
06177     MMSFBColor color;
06178 
06179     /* check if initialized */
06180     INITCHECK;
06181 
06182     /* modulate the opacity into the color */
06183     color.a = alpha;
06184     modulateOpacity(&color, opacity);
06185 
06186     /* set color for blitting */
06187     setColor(brightness, brightness, brightness, color.a);
06188 
06189     /* set blitting flags */
06190     if (brightness != 255) {
06191         if (color.a == 255)
06192             setBlittingFlags((MMSFBBlittingFlags)(MMSFB_BLIT_COLORIZE|MMSFB_BLIT_BLEND_ALPHACHANNEL));
06193         else
06194             setBlittingFlags((MMSFBBlittingFlags)(MMSFB_BLIT_COLORIZE|MMSFB_BLIT_BLEND_ALPHACHANNEL|MMSFB_BLIT_BLEND_COLORALPHA));
06195     }
06196     else {
06197         if (color.a == 255)
06198             setBlittingFlags((MMSFBBlittingFlags)(MMSFB_BLIT_BLEND_ALPHACHANNEL));
06199         else
06200             setBlittingFlags((MMSFBBlittingFlags)(MMSFB_BLIT_BLEND_ALPHACHANNEL|MMSFB_BLIT_BLEND_COLORALPHA));
06201     }
06202 
06203     return true;
06204 }
06205 
06206 
06207 bool MMSFBSurface::setBlittingFlagsByBrightnessAlphaAndOpacityAndSource(
06208                     unsigned char brightness, unsigned char alpha, unsigned char opacity,
06209                     MMSFBSurface *source) {
06210     MMSFBColor color;
06211 
06212     // check if initialized
06213     INITCHECK;
06214 
06215     // modulate the opacity into the color
06216     color.a = alpha;
06217     modulateOpacity(&color, opacity);
06218 
06219     // set color for blitting
06220     setColor(brightness, brightness, brightness, color.a);
06221 
06222     // set blitting flags
06223     if (!MMSFBSURFACE_READ_BUFFER(source).opaque) {
06224         // source is not opaque
06225         if (brightness != 255) {
06226             if (color.a == 255)
06227                 setBlittingFlags((MMSFBBlittingFlags)(MMSFB_BLIT_COLORIZE|MMSFB_BLIT_BLEND_ALPHACHANNEL));
06228             else
06229                 setBlittingFlags((MMSFBBlittingFlags)(MMSFB_BLIT_COLORIZE|MMSFB_BLIT_BLEND_ALPHACHANNEL|MMSFB_BLIT_BLEND_COLORALPHA));
06230         }
06231         else {
06232             if (color.a == 255)
06233                 setBlittingFlags((MMSFBBlittingFlags)(MMSFB_BLIT_BLEND_ALPHACHANNEL));
06234             else
06235                 setBlittingFlags((MMSFBBlittingFlags)(MMSFB_BLIT_BLEND_ALPHACHANNEL|MMSFB_BLIT_BLEND_COLORALPHA));
06236         }
06237     }
06238     else {
06239         // source is opaque, so we do not need MMSFB_BLIT_BLEND_ALPHACHANNEL
06240         if (brightness != 255) {
06241             if (color.a == 255)
06242                 setBlittingFlags((MMSFBBlittingFlags)(MMSFB_BLIT_COLORIZE));
06243             else
06244                 setBlittingFlags((MMSFBBlittingFlags)(MMSFB_BLIT_COLORIZE|MMSFB_BLIT_BLEND_COLORALPHA));
06245         }
06246         else {
06247             if (color.a == 255)
06248                 setBlittingFlags((MMSFBBlittingFlags)(MMSFB_BLIT_NOFX));
06249             else
06250                 setBlittingFlags((MMSFBBlittingFlags)(MMSFB_BLIT_BLEND_COLORALPHA));
06251         }
06252     }
06253 
06254     return true;
06255 }
06256 
06257 
06258 
06259 bool MMSFBSurface::setDrawingFlagsByAlpha(unsigned char alpha) {
06260 
06261     // check if initialized
06262     INITCHECK;
06263 
06264     // set the drawing flags
06265     if (this->config.surface_buffer->premultiplied) {
06266         // premultiplied surface, have to premultiply the color
06267         if (alpha == 255)
06268             setDrawingFlags((MMSFBDrawingFlags)(MMSFB_DRAW_NOFX|MMSFB_DRAW_SRC_PREMULTIPLY));
06269         else
06270             setDrawingFlags((MMSFBDrawingFlags)(MMSFB_DRAW_BLEND|MMSFB_DRAW_SRC_PREMULTIPLY));
06271     }
06272     else {
06273         if (alpha == 255)
06274             setDrawingFlags((MMSFBDrawingFlags)MMSFB_DRAW_NOFX);
06275         else
06276             setDrawingFlags((MMSFBDrawingFlags)MMSFB_DRAW_BLEND);
06277     }
06278 
06279     return true;
06280 }
06281 
06282 
06283 bool MMSFBSurface::setDrawingColorAndFlagsByBrightnessAndOpacity(
06284                         MMSFBColor color, unsigned char brightness, unsigned char opacity) {
06285 
06286     // check if initialized
06287     INITCHECK;
06288 
06289     // modulate the brightness into the color
06290     modulateBrightness(&color, brightness);
06291 
06292     // modulate the opacity into the color
06293     modulateOpacity(&color, opacity);
06294 
06295     // set the color for drawing
06296     setColor(color.r, color.g, color.b, color.a);
06297 
06298     // set the drawing flags
06299     setDrawingFlagsByAlpha(color.a);
06300 
06301     return true;
06302 }
06303 
06304 
06305 bool MMSFBSurface::setDrawingColorAndFlagsByBrightnessAndOpacity(
06306                         MMSFBColor color,
06307                         MMSFBColor shadow_top_color, MMSFBColor shadow_bottom_color,
06308                         MMSFBColor shadow_left_color, MMSFBColor shadow_right_color,
06309                         MMSFBColor shadow_top_left_color, MMSFBColor shadow_top_right_color,
06310                         MMSFBColor shadow_bottom_left_color, MMSFBColor shadow_bottom_right_color,
06311                         unsigned char brightness, unsigned char opacity) {
06312 
06313     if (!setDrawingColorAndFlagsByBrightnessAndOpacity(color, brightness, opacity))
06314         return false;
06315 
06316     // modulate the brightness/opacity into the shadow colors
06317     modulateBrightness(&shadow_top_color, brightness);
06318     modulateOpacity(&shadow_top_color, opacity);
06319     modulateBrightness(&shadow_bottom_color, brightness);
06320     modulateOpacity(&shadow_bottom_color, opacity);
06321     modulateBrightness(&shadow_left_color, brightness);
06322     modulateOpacity(&shadow_left_color, opacity);
06323     modulateBrightness(&shadow_right_color, brightness);
06324     modulateOpacity(&shadow_right_color, opacity);
06325     modulateBrightness(&shadow_top_left_color, brightness);
06326     modulateOpacity(&shadow_top_left_color, opacity);
06327     modulateBrightness(&shadow_top_right_color, brightness);
06328     modulateOpacity(&shadow_top_right_color, opacity);
06329     modulateBrightness(&shadow_bottom_left_color, brightness);
06330     modulateOpacity(&shadow_bottom_left_color, opacity);
06331     modulateBrightness(&shadow_bottom_right_color, brightness);
06332     modulateOpacity(&shadow_bottom_right_color, opacity);
06333 
06334     // set the shadow colors
06335     return setShadowColor(shadow_top_color, shadow_bottom_color, shadow_left_color, shadow_right_color,
06336                           shadow_top_left_color, shadow_top_right_color, shadow_bottom_left_color, shadow_bottom_right_color);
06337 }
06338 
06339 
06340 bool MMSFBSurface::setFont(MMSFBFont *font) {
06341 
06342     /* check if initialized */
06343     INITCHECK;
06344 
06345     if (this->allocated_by == MMSFBSurfaceAllocatedBy_dfb) {
06346 #ifdef  __HAVE_DIRECTFB__
06347         DFBResult   dfbres;
06348 
06349         /* set font */
06350         if ((dfbres=this->dfb_surface->SetFont(this->dfb_surface, (IDirectFBFont*)font->dfbfont)) != DFB_OK) {
06351             MMSFB_SetError(dfbres, "IDirectFBSurface::SetFont() failed");
06352             return false;
06353         }
06354 #endif
06355     }
06356     else {
06357         //TODO
06358     }
06359 
06360     /* save the font */
06361     this->config.font = font;
06362 
06363     return true;
06364 }
06365 
06366 
06367 
06368 bool MMSFBSurface::blit_text(string &text, int len, int x, int y) {
06369     MMSFBRegion clipreg;
06370     MMSFBSurfacePlanes dst_planes;
06371 
06372 #ifndef USE_DFB_SUBSURFACE
06373     if (!this->is_sub_surface) {
06374 #endif
06375         // normal surface or dfb subsurface
06376         if (!this->config.clipped) {
06377             clipreg.x1 = 0;
06378             clipreg.y1 = 0;
06379             clipreg.x2 = this->config.w - 1;
06380             clipreg.y2 = this->config.h - 1;
06381         }
06382         else
06383             clipreg = this->config.clip;
06384 #ifndef USE_DFB_SUBSURFACE
06385     }
06386     else {
06387         // subsurface
06388         if (!this->root_parent->config.clipped) {
06389             clipreg.x1 = 0;
06390             clipreg.y1 = 0;
06391             clipreg.x2 = this->root_parent->config.w - 1;
06392             clipreg.y2 = this->root_parent->config.h - 1;
06393         }
06394         else
06395             clipreg = this->root_parent->config.clip;
06396     }
06397 #endif
06398 
06399     // calculate the color
06400     MMSFBColor color = this->config.color;
06401     if (this->config.drawingflags & (MMSFBDrawingFlags)MMSFB_DRAW_SRC_PREMULTIPLY) {
06402         // pre-multiplication needed
06403         if (color.a != 0xff) {
06404             color.r = ((color.a+1) * color.r) >> 8;
06405             color.g = ((color.a+1) * color.g) >> 8;
06406             color.b = ((color.a+1) * color.b) >> 8;
06407         }
06408     }
06409 
06410     // checking pixelformats...
06411     switch (this->config.surface_buffer->pixelformat) {
06412     case MMSFB_PF_ARGB:
06413         // destination is ARGB
06414         if   ((this->config.drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_NOFX))
06415             ||(this->config.drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_NOFX|MMSFB_DRAW_SRC_PREMULTIPLY))) {
06416             if (extendedLock(NULL, NULL, this, &dst_planes)) {
06417                 MMSFB_ROTATE_180_REGION(this, clipreg.x1, clipreg.y1, clipreg.x2, clipreg.y2);
06418                 MMSFB_ROTATE_180_RECT(this, x, y, 1, 1);
06419                 MMSFBPERF_START_MEASURING;
06420                     mmsfb_drawstring_blend_argb(
06421                             &dst_planes, this->config.font, clipreg,
06422                             text, len, x, y, color);
06423                 MMSFBPERF_STOP_MEASURING_DRAWSTRING(this, clipreg, text, len, x, y);
06424                 MMSFB_ROTATE_180_REGION(this, clipreg.x1, clipreg.y1, clipreg.x2, clipreg.y2);
06425                 MMSFB_ROTATE_180_RECT(this, x, y, 1, 1);
06426                 extendedUnlock(NULL, this);
06427                 return true;
06428             }
06429             return false;
06430         }
06431         else
06432         if   ((this->config.drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_BLEND))
06433             ||(this->config.drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_BLEND|MMSFB_DRAW_SRC_PREMULTIPLY))) {
06434             if (extendedLock(NULL, NULL, this, &dst_planes)) {
06435                 MMSFB_ROTATE_180_REGION(this, clipreg.x1, clipreg.y1, clipreg.x2, clipreg.y2);
06436                 MMSFB_ROTATE_180_RECT(this, x, y, 1, 1);
06437                 MMSFBPERF_START_MEASURING;
06438                     mmsfb_drawstring_blend_coloralpha_argb(
06439                             &dst_planes, this->config.font, clipreg,
06440                             text, len, x, y, color);
06441                 MMSFBPERF_STOP_MEASURING_DRAWSTRING(this, clipreg, text, len, x, y);
06442                 MMSFB_ROTATE_180_REGION(this, clipreg.x1, clipreg.y1, clipreg.x2, clipreg.y2);
06443                 MMSFB_ROTATE_180_RECT(this, x, y, 1, 1);
06444                 extendedUnlock(NULL, this);
06445                 return true;
06446             }
06447             return false;
06448         }
06449         break;
06450 
06451     case MMSFB_PF_RGB32:
06452         // destination is RGB32
06453         if   ((this->config.drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_NOFX))
06454             ||(this->config.drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_NOFX|MMSFB_DRAW_SRC_PREMULTIPLY))) {
06455             if (extendedLock(NULL, NULL, this, &dst_planes)) {
06456                 MMSFB_ROTATE_180_REGION(this, clipreg.x1, clipreg.y1, clipreg.x2, clipreg.y2);
06457                 MMSFB_ROTATE_180_RECT(this, x, y, 1, 1);
06458                 MMSFBPERF_START_MEASURING;
06459                     mmsfb_drawstring_blend_rgb32(
06460                             &dst_planes, this->config.font, clipreg,
06461                             text, len, x, y, color);
06462                 MMSFBPERF_STOP_MEASURING_DRAWSTRING(this, clipreg, text, len, x, y);
06463                 MMSFB_ROTATE_180_REGION(this, clipreg.x1, clipreg.y1, clipreg.x2, clipreg.y2);
06464                 MMSFB_ROTATE_180_RECT(this, x, y, 1, 1);
06465                 extendedUnlock(NULL, this);
06466                 return true;
06467             }
06468             return false;
06469         }
06470         else
06471         if   ((this->config.drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_BLEND))
06472             ||(this->config.drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_BLEND|MMSFB_DRAW_SRC_PREMULTIPLY))) {
06473             if (extendedLock(NULL, NULL, this, &dst_planes)) {
06474                 MMSFB_ROTATE_180_REGION(this, clipreg.x1, clipreg.y1, clipreg.x2, clipreg.y2);
06475                 MMSFB_ROTATE_180_RECT(this, x, y, 1, 1);
06476                 MMSFBPERF_START_MEASURING;
06477                     mmsfb_drawstring_blend_coloralpha_rgb32(
06478                             &dst_planes, this->config.font, clipreg,
06479                             text, len, x, y, color);
06480                 MMSFBPERF_STOP_MEASURING_DRAWSTRING(this, clipreg, text, len, x, y);
06481                 MMSFB_ROTATE_180_REGION(this, clipreg.x1, clipreg.y1, clipreg.x2, clipreg.y2);
06482                 MMSFB_ROTATE_180_RECT(this, x, y, 1, 1);
06483                 extendedUnlock(NULL, this);
06484                 return true;
06485             }
06486             return false;
06487         }
06488         break;
06489 
06490     case MMSFB_PF_ARGB4444:
06491         // destination is ARGB4444
06492         if   ((this->config.drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_NOFX))
06493             ||(this->config.drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_NOFX|MMSFB_DRAW_SRC_PREMULTIPLY))) {
06494             if (extendedLock(NULL, NULL, this, &dst_planes)) {
06495                 MMSFB_ROTATE_180_REGION(this, clipreg.x1, clipreg.y1, clipreg.x2, clipreg.y2);
06496                 MMSFB_ROTATE_180_RECT(this, x, y, 1, 1);
06497                 MMSFBPERF_START_MEASURING;
06498                     mmsfb_drawstring_blend_argb4444(
06499                             &dst_planes, this->config.font, clipreg,
06500                             text, len, x, y, color);
06501                 MMSFBPERF_STOP_MEASURING_DRAWSTRING(this, clipreg, text, len, x, y);
06502                 MMSFB_ROTATE_180_REGION(this, clipreg.x1, clipreg.y1, clipreg.x2, clipreg.y2);
06503                 MMSFB_ROTATE_180_RECT(this, x, y, 1, 1);
06504                 extendedUnlock(NULL, this);
06505                 return true;
06506             }
06507             return false;
06508         }
06509         break;
06510 
06511     case MMSFB_PF_RGB16:
06512         // destination is RGB16
06513         if   ((this->config.drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_NOFX))
06514             ||(this->config.drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_NOFX|MMSFB_DRAW_SRC_PREMULTIPLY))) {
06515             if (extendedLock(NULL, NULL, this, &dst_planes)) {
06516                 MMSFB_ROTATE_180_REGION(this, clipreg.x1, clipreg.y1, clipreg.x2, clipreg.y2);
06517                 MMSFB_ROTATE_180_RECT(this, x, y, 1, 1);
06518                 MMSFBPERF_START_MEASURING;
06519                     mmsfb_drawstring_blend_rgb16(
06520                             &dst_planes, this->config.font, clipreg,
06521                             text, len, x, y, color);
06522                 MMSFBPERF_STOP_MEASURING_DRAWSTRING(this, clipreg, text, len, x, y);
06523                 MMSFB_ROTATE_180_REGION(this, clipreg.x1, clipreg.y1, clipreg.x2, clipreg.y2);
06524                 MMSFB_ROTATE_180_RECT(this, x, y, 1, 1);
06525                 extendedUnlock(NULL, this);
06526                 return true;
06527             }
06528             return false;
06529         }
06530         else
06531         if   ((this->config.drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_BLEND))
06532             ||(this->config.drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_BLEND|MMSFB_DRAW_SRC_PREMULTIPLY))) {
06533             if (extendedLock(NULL, NULL, this, &dst_planes)) {
06534                 MMSFB_ROTATE_180_REGION(this, clipreg.x1, clipreg.y1, clipreg.x2, clipreg.y2);
06535                 MMSFB_ROTATE_180_RECT(this, x, y, 1, 1);
06536                 MMSFBPERF_START_MEASURING;
06537                     mmsfb_drawstring_blend_coloralpha_rgb16(
06538                             &dst_planes, this->config.font, clipreg,
06539                             text, len, x, y, color);
06540                 MMSFBPERF_STOP_MEASURING_DRAWSTRING(this, clipreg, text, len, x, y);
06541                 MMSFB_ROTATE_180_REGION(this, clipreg.x1, clipreg.y1, clipreg.x2, clipreg.y2);
06542                 MMSFB_ROTATE_180_RECT(this, x, y, 1, 1);
06543                 extendedUnlock(NULL, this);
06544                 return true;
06545             }
06546             return false;
06547         }
06548         break;
06549 
06550     default:
06551         // does not match
06552         break;
06553     }
06554 
06555     return printMissingCombination("blit_text()", NULL, NULL, MMSFB_PF_NONE, 0, 0);
06556 }
06557 
06558 
06559 bool MMSFBSurface::blit_text_with_shadow(string &text, int len, int x, int y) {
06560 
06561     bool top            = (this->config.shadow_top_color.a);
06562     bool bottom         = (this->config.shadow_bottom_color.a);
06563     bool left           = (this->config.shadow_left_color.a);
06564     bool right          = (this->config.shadow_right_color.a);
06565     bool top_left       = (this->config.shadow_top_left_color.a);
06566     bool top_right      = (this->config.shadow_top_right_color.a);
06567     bool bottom_left    = (this->config.shadow_bottom_left_color.a);
06568     bool bottom_right   = (this->config.shadow_bottom_right_color.a);
06569     bool shadow = (top || bottom || left || right || top_left || top_right || bottom_left || bottom_right);
06570 
06571     if (!shadow) {
06572         // normal text output without shadow
06573 #ifdef __HAVE_OPENGL__
06574         if (mmsfb->bei) {
06575             mmsfb->bei->drawString(this, text, len, x, y);
06576             return true;
06577         }
06578 #endif
06579         return blit_text(text, len, x, y);
06580     }
06581     else {
06582         // draw text with shadow
06583         // drawing color and flags will be temporary changed during the shadow blits
06584         MMSFBColor savedcol = this->config.color;
06585         MMSFBDrawingFlags saveddf = this->config.drawingflags;
06586 
06587 
06588         //TODO: for now we assume that this->config.color.a is 0xff!!!
06589         //      else we have to blit text and shadow in an temporary buffer with (text with a=0xff)
06590         //      and finally blend the result with coloralpha to this destination surface
06591 
06592 
06593         if (top) {
06594             // draw shadow on the top
06595             this->config.color = this->config.shadow_top_color;
06596             this->setDrawingFlagsByAlpha(this->config.color.a);
06597 #ifdef __HAVE_OPENGL__
06598             if (mmsfb->bei) {
06599                 mmsfb->bei->drawString(this, text, len, x, y-1);
06600             }
06601             else
06602 #endif
06603             blit_text(text, len, x, y-1);
06604         }
06605         if (bottom) {
06606             // draw shadow on the bottom
06607             this->config.color = this->config.shadow_bottom_color;
06608             this->setDrawingFlagsByAlpha(this->config.color.a);
06609 #ifdef __HAVE_OPENGL__
06610             if (mmsfb->bei) {
06611                 mmsfb->bei->drawString(this, text, len, x, y+1);
06612             }
06613             else
06614 #endif
06615             blit_text(text, len, x, y+1);
06616         }
06617         if (left) {
06618             // draw shadow on the left
06619             this->config.color = this->config.shadow_left_color;
06620             this->setDrawingFlagsByAlpha(this->config.color.a);
06621 #ifdef __HAVE_OPENGL__
06622             if (mmsfb->bei) {
06623                 mmsfb->bei->drawString(this, text, len, x-1, y);
06624             }
06625             else
06626 #endif
06627             blit_text(text, len, x-1, y);
06628         }
06629         if (right) {
06630             // draw shadow on the right
06631             this->config.color = this->config.shadow_right_color;
06632             this->setDrawingFlagsByAlpha(this->config.color.a);
06633 #ifdef __HAVE_OPENGL__
06634             if (mmsfb->bei) {
06635                 mmsfb->bei->drawString(this, text, len, x+1, y);
06636             }
06637             else
06638 #endif
06639             blit_text(text, len, x+1, y);
06640         }
06641         if (top_left) {
06642             // draw shadow on the top-left
06643             this->config.color = this->config.shadow_top_left_color;
06644             this->setDrawingFlagsByAlpha(this->config.color.a);
06645 #ifdef __HAVE_OPENGL__
06646             if (mmsfb->bei) {
06647                 mmsfb->bei->drawString(this, text, len, x-1, y-1);
06648             }
06649             else
06650 #endif
06651             blit_text(text, len, x-1, y-1);
06652         }
06653         if (top_right) {
06654             // draw shadow on the top-right
06655             this->config.color = this->config.shadow_top_right_color;
06656             this->setDrawingFlagsByAlpha(this->config.color.a);
06657 #ifdef __HAVE_OPENGL__
06658             if (mmsfb->bei) {
06659                 mmsfb->bei->drawString(this, text, len, x+1, y-1);
06660             }
06661             else
06662 #endif
06663             blit_text(text, len, x+1, y-1);
06664         }
06665         if (bottom_left) {
06666             // draw shadow on the bottom-left
06667             this->config.color = this->config.shadow_bottom_left_color;
06668             this->setDrawingFlagsByAlpha(this->config.color.a);
06669 #ifdef __HAVE_OPENGL__
06670             if (mmsfb->bei) {
06671                 mmsfb->bei->drawString(this, text, len, x-1, y+1);
06672             }
06673             else
06674 #endif
06675             blit_text(text, len, x-1, y+1);
06676         }
06677         if (bottom_right) {
06678             // draw shadow on the bottom-right
06679             this->config.color = this->config.shadow_bottom_right_color;
06680             this->setDrawingFlagsByAlpha(this->config.color.a);
06681 #ifdef __HAVE_OPENGL__
06682             if (mmsfb->bei) {
06683                 mmsfb->bei->drawString(this, text, len, x+1, y+1);
06684             }
06685             else
06686 #endif
06687             blit_text(text, len, x+1, y+1);
06688         }
06689 
06690         // restore drawing color and flags
06691         this->config.color = savedcol;
06692         this->config.drawingflags = saveddf;
06693 
06694         // for now we set this->config.color.a to 0xff!!!
06695         this->config.color.a = 0xff;
06696         this->setDrawingFlagsByAlpha(this->config.color.a);
06697 
06698         // final draw
06699         bool ret = false;
06700 #ifdef __HAVE_OPENGL__
06701         if (mmsfb->bei) {
06702             mmsfb->bei->drawString(this, text, len, x, y);
06703             ret = true;
06704         }
06705         else
06706 #endif
06707         ret = blit_text(text, len, x, y);
06708 
06709         // restore drawing color and flags
06710         this->config.color = savedcol;
06711         this->config.drawingflags = saveddf;
06712 
06713         return ret;
06714     }
06715 }
06716 
06717 
06718 bool MMSFBSurface::drawString(string text, int len, int x, int y) {
06719 
06720     // check if initialized
06721     INITCHECK;
06722 
06723     // finalize previous clear
06724     finClear();
06725 
06726     if (!this->config.font)
06727         return false;
06728 
06729     // get the length of the string
06730     if (len < 0) len = text.size();
06731     if (!len) return true;
06732 
06733     if (this->allocated_by == MMSFBSurfaceAllocatedBy_dfb) {
06734 #ifdef  __HAVE_DIRECTFB__
06735         D_DEBUG_AT( MMS_Surface, "drawString( '%s', %d, %d,%d ) <- %dx%d\n",
06736                     text.c_str(), len, x, y, this->config.w, this->config.h );
06737         MMSFB_TRACE();
06738 
06739         // draw a string
06740         DFBResult dfbres;
06741         if (!this->is_sub_surface) {
06742             if ((dfbres=this->dfb_surface->DrawString(this->dfb_surface, text.c_str(), len, x, y, DSTF_TOPLEFT)) != DFB_OK) {
06743                 MMSFB_SetError(dfbres, "IDirectFBSurface::DrawString() failed");
06744 
06745                 return false;
06746             }
06747         }
06748         else {
06749 #ifndef USE_DFB_SUBSURFACE
06750             CLIPSUBSURFACE
06751 
06752             x+=this->sub_surface_xoff;
06753             y+=this->sub_surface_yoff;
06754 
06755             SETSUBSURFACE_DRAWINGFLAGS;
06756 #endif
06757 
06758             this->dfb_surface->DrawString(this->dfb_surface, text.c_str(), len, x, y, DSTF_TOPLEFT);
06759 
06760 #ifndef USE_DFB_SUBSURFACE
06761             RESETSUBSURFACE_DRAWINGFLAGS;
06762 
06763             UNCLIPSUBSURFACE
06764 #endif
06765         }
06766 #endif
06767     }
06768     else
06769     if (this->allocated_by == MMSFBSurfaceAllocatedBy_ogl) {
06770 #ifdef  __HAVE_OPENGL__
06771         if (!this->is_sub_surface) {
06772 //          mmsfb->bei->drawString(this, text, len, x, y);
06773             blit_text_with_shadow(text, len, x, y);
06774         }
06775         else {
06776             CLIPSUBSURFACE
06777 
06778 //          mmsfb->bei->drawString(this, text, len, x, y);
06779             blit_text_with_shadow(text, len, x, y);
06780 
06781             UNCLIPSUBSURFACE
06782         }
06783 #endif
06784     }
06785     else {
06786         // draw a string
06787         if (!this->is_sub_surface) {
06788             blit_text_with_shadow(text, len, x, y);
06789         }
06790         else {
06791             CLIPSUBSURFACE
06792 
06793             x+=this->sub_surface_xoff;
06794             y+=this->sub_surface_yoff;
06795 
06796             blit_text_with_shadow(text, len, x, y);
06797 
06798             UNCLIPSUBSURFACE
06799         }
06800     }
06801 
06802     return true;
06803 }
06804 
06805 void MMSFBSurface::lock(MMSFBLockFlags flags, MMSFBSurfacePlanes *planes, bool pthread_lock) {
06806     if (!pthread_lock) {
06807         // no pthread lock needed
06808         if (this->allocated_by == MMSFBSurfaceAllocatedBy_dfb) {
06809 #ifdef  __HAVE_DIRECTFB__
06810             if (flags && planes) {
06811                 // get the access to the surface buffer
06812                 memset(planes, 0, sizeof(MMSFBSurfacePlanes));
06813                 if (flags == MMSFB_LOCK_READ) {
06814                     if (this->dfb_surface->Lock(this->dfb_surface, DSLF_READ, &planes->ptr, &planes->pitch) != DFB_OK) {
06815                         planes->ptr = NULL;
06816                         planes->pitch = 0;
06817                     }
06818                 }
06819                 else
06820                 if (flags == MMSFB_LOCK_WRITE) {
06821                     if (this->dfb_surface->Lock(this->dfb_surface, DSLF_WRITE, &planes->ptr, &planes->pitch) != DFB_OK) {
06822                         planes->ptr = NULL;
06823                         planes->pitch = 0;
06824                     }
06825                 }
06826             }
06827 #endif
06828         }
06829         else {
06830             if (flags && planes) {
06831                 // get the access to the surface buffer
06832                 memset(planes, 0, sizeof(MMSFBSurfacePlanes));
06833                 MMSFBSurfaceBuffer *sb = this->config.surface_buffer;
06834                 if (flags == MMSFB_LOCK_READ) {
06835                     *planes = sb->buffers[sb->currbuffer_read];
06836                 }
06837                 else
06838                 if (flags == MMSFB_LOCK_WRITE) {
06839                     *planes = sb->buffers[sb->currbuffer_write];
06840                 }
06841             }
06842         }
06843         return;
06844     }
06845 
06846     // which surface is to lock?
06847     MMSFBSurface *tolock = this;
06848     if (this->root_parent)
06849         tolock = this->root_parent;
06850     else
06851     if (this->parent)
06852         tolock = this->parent;
06853 
06854     if (tolock->Lock.trylock() == 0) {
06855         // I have got the lock the first time
06856         tolock->TID = pthread_self();
06857         tolock->Lock_cnt = 1;
06858     }
06859     else {
06860         if ((tolock->TID == pthread_self())&&(tolock->Lock_cnt > 0)) {
06861             // I am the thread which has already locked this surface
06862             tolock->Lock_cnt++;
06863         }
06864         else {
06865             // another thread has already locked this surface, waiting for...
06866 #ifdef DEBUG_LOCK_OUTPUT
06867             printf("surface try lock - (%lu), cnt: %d surf: %p\n", (pid_t) syscall (SYS_gettid), tolock->Lock_cnt, tolock);
06868 #endif
06869             tolock->Lock.lock();
06870             tolock->TID = pthread_self();
06871             tolock->Lock_cnt = 1;
06872         }
06873     }
06874 
06875     if (this->allocated_by == MMSFBSurfaceAllocatedBy_dfb) {
06876 #ifdef  __HAVE_DIRECTFB__
06877         if (flags && planes) {
06878             // get the access to the surface buffer
06879             memset(planes, 0, sizeof(MMSFBSurfacePlanes));
06880             if (flags == MMSFB_LOCK_READ) {
06881                 if (!tolock->surface_read_locked) {
06882                     if (this->dfb_surface->Lock(this->dfb_surface, DSLF_READ, &planes->ptr, &planes->pitch) != DFB_OK) {
06883                         planes->ptr = NULL;
06884                         planes->pitch = 0;
06885                     }
06886                     else {
06887                         tolock->surface_read_locked = true;
06888                         tolock->surface_read_lock_cnt = tolock->Lock_cnt;
06889                     }
06890                 }
06891             }
06892             else
06893             if (flags == MMSFB_LOCK_WRITE) {
06894                 if (!tolock->surface_write_locked) {
06895                     if (this->dfb_surface->Lock(this->dfb_surface, DSLF_WRITE, &planes->ptr, &planes->pitch) != DFB_OK) {
06896                         planes->ptr = NULL;
06897                         planes->pitch = 0;
06898                     }
06899                     else {
06900                         tolock->surface_write_locked = true;
06901                         tolock->surface_write_lock_cnt = tolock->Lock_cnt;
06902                     }
06903                 }
06904             }
06905         }
06906 #endif
06907     }
06908     else {
06909         if (flags && planes) {
06910             // get the access to the surface buffer
06911             memset(planes, 0, sizeof(MMSFBSurfacePlanes));
06912             MMSFBSurfaceBuffer *sb = this->config.surface_buffer;
06913             if (flags == MMSFB_LOCK_READ) {
06914                 if (!tolock->surface_read_locked) {
06915                     *planes = sb->buffers[sb->currbuffer_read];
06916                     tolock->surface_read_locked = true;
06917                     tolock->surface_read_lock_cnt = tolock->Lock_cnt;
06918                 }
06919             }
06920             else
06921             if (flags == MMSFB_LOCK_WRITE) {
06922                 if (!tolock->surface_write_locked) {
06923                     *planes = sb->buffers[sb->currbuffer_write];
06924                     tolock->surface_write_locked = true;
06925                     tolock->surface_write_lock_cnt = tolock->Lock_cnt;
06926                 }
06927             }
06928         }
06929     }
06930 }
06931 
06932 void MMSFBSurface::lock(MMSFBLockFlags flags, void **ptr, int *pitch) {
06933     if (!ptr || !pitch) {
06934         // nothing to return
06935         lock(flags, NULL, true);
06936     }
06937     else {
06938         // get the planes an return the first one
06939         MMSFBSurfacePlanes planes;
06940         lock(flags, &planes, true);
06941         *ptr = planes.ptr;
06942         *pitch = planes.pitch;
06943     }
06944 }
06945 
06946 void MMSFBSurface::lock(MMSFBLockFlags flags, MMSFBSurfacePlanes *planes) {
06947     lock(flags, planes, true);
06948 }
06949 
06950 bool MMSFBSurface::tryToLock() {
06951 
06952     // which surface is to lock?
06953     MMSFBSurface *tolock = this;
06954     if (this->root_parent)
06955         tolock = this->root_parent;
06956     else
06957     if (this->parent)
06958         tolock = this->parent;
06959 
06960     if (tolock->Lock.trylock() == 0) {
06961         // I have got the lock the first time
06962         tolock->TID = pthread_self();
06963         tolock->Lock_cnt = 1;
06964     }
06965     else {
06966         if ((tolock->TID == pthread_self())&&(tolock->Lock_cnt > 0)) {
06967             // I am the thread which has already locked this surface
06968             tolock->Lock_cnt++;
06969         }
06970         else {
06971             // another thread has already locked this surface, waiting for...
06972 #ifdef DEBUG_LOCK_OUTPUT
06973             printf("surface locked from other thread - (%lu), cnt: %d surf: %p\n", (pid_t) syscall (SYS_gettid), tolock->Lock_cnt, tolock);
06974 #endif
06975             return false;
06976 //          tolock->Lock.lock();
06977 //          tolock->TID = pthread_self();
06978 //          tolock->Lock_cnt = 1;
06979         }
06980     }
06981 
06982     return true;
06983 }
06984 
06985 void MMSFBSurface::unlock(bool pthread_unlock) {
06986     if (!pthread_unlock) {
06987         // no pthread unlock needed
06988         if (this->allocated_by == MMSFBSurfaceAllocatedBy_dfb) {
06989 #ifdef  __HAVE_DIRECTFB__
06990             this->dfb_surface->Unlock(this->dfb_surface);
06991 #endif
06992         }
06993         return;
06994     }
06995 
06996     // which surface is to lock?
06997     MMSFBSurface *tolock = this;
06998     if (this->root_parent)
06999         tolock = this->root_parent;
07000     else
07001     if (this->parent)
07002         tolock = this->parent;
07003 
07004     if (tolock->TID != pthread_self())
07005         return;
07006 
07007     if (tolock->Lock_cnt==0)
07008         return;
07009 
07010     // unlock dfb surface?
07011     if ((tolock->surface_read_locked)&&(tolock->surface_read_lock_cnt == tolock->Lock_cnt)) {
07012         if (this->allocated_by == MMSFBSurfaceAllocatedBy_dfb) {
07013 #ifdef  __HAVE_DIRECTFB__
07014             this->dfb_surface->Unlock(this->dfb_surface);
07015 #endif
07016         }
07017         tolock->surface_read_locked = false;
07018         tolock->surface_read_lock_cnt = 0;
07019     }
07020     else
07021     if ((tolock->surface_write_locked)&&(tolock->surface_write_lock_cnt == tolock->Lock_cnt)) {
07022         if (this->allocated_by == MMSFBSurfaceAllocatedBy_dfb) {
07023 #ifdef  __HAVE_DIRECTFB__
07024             this->dfb_surface->Unlock(this->dfb_surface);
07025 #endif
07026         }
07027         tolock->surface_write_locked = false;
07028         tolock->surface_write_lock_cnt = 0;
07029     }
07030 
07031     tolock->Lock_cnt--;
07032 
07033     if (tolock->Lock_cnt == 0)
07034         tolock->Lock.unlock();
07035 }
07036 
07037 void MMSFBSurface::unlock() {
07038     unlock(true);
07039 }
07040 
07041 unsigned int MMSFBSurface::getNumberOfSubSurfaces() {
07042     return this->children.size();
07043 }
07044 
07045 MMSFBSurface *MMSFBSurface::getSubSurface(MMSFBRectangle *rect) {
07046 #ifdef  __HAVE_DIRECTFB__
07047     IDirectFBSurface *subsuf = NULL;
07048 #endif
07049     MMSFBSurface    *surface;
07050 
07051     // check if initialized
07052     if((!mmsfb->isInitialized())||(!this->initialized)){MMSFB_SetError(0,"MMSFBSurface is not initialized");return NULL;}
07053 
07054     // finalize previous clear
07055     finClear();
07056 
07057 #ifdef USE_DFB_SUBSURFACE
07058     // get a sub surface
07059     DFBResult dfbres;
07060     if ((dfbres=this->dfb_surface->GetSubSurface(this->dfb_surface, rect, &subsuf)) != DFB_OK) {
07061         MMSFB_SetError(dfbres, "IDirectFBSurface::GetSubSurface() failed");
07062         return false;
07063     }
07064 
07065     // create a new surface instance
07066     surface = new MMSFBSurface(subsuf, this, rect);
07067 #else
07068     // create a new surface instance
07069     surface = new MMSFBSurface(this, rect);
07070 #endif
07071 
07072     if (!surface) {
07073 #ifdef USE_DFB_SUBSURFACE
07074         if (subsuf)
07075             subsuf->Release(subsuf);
07076 #endif
07077         MMSFB_SetError(0, "cannot create new instance of MMSFBSurface");
07078         return NULL;
07079     }
07080 
07081     // add to my list
07082     this->children.push_back(surface);
07083 
07084     return surface;
07085 }
07086 
07087 bool MMSFBSurface::setSubSurface(MMSFBRectangle *rect) {
07088 
07089     // check if initialized
07090     INITCHECK;
07091 
07092     // finalize previous clear
07093     finClear();
07094 
07095     // only sub surfaces can be moved
07096     if (!this->is_sub_surface)
07097         return false;
07098 
07099 //    lock();
07100 
07101     if (memcmp(rect, &(this->sub_surface_rect), sizeof(this->sub_surface_rect)) == 0) {
07102         /* nothing changed */
07103 //      unlock();
07104         return false;
07105     }
07106 
07107 #ifdef USE_DFB_SUBSURFACE
07108     /* because dfb has no IDirectFBSurface::setSubSurface(), allocate a new and release the old one */
07109     DFBResult dfbres;
07110     IDirectFBSurface *subsuf = NULL;
07111     if ((dfbres=this->parent->dfb_surface->GetSubSurface(this->parent->dfb_surface, rect, &subsuf)) != DFB_OK) {
07112         MMSFB_SetError(dfbres, "IDirectFBSurface::GetSubSurface() failed");
07113 //        unlock();
07114         return false;
07115     }
07116 
07117     if (this->dfb_surface)
07118         this->dfb_surface->Release(this->dfb_surface);
07119 
07120     this->dfb_surface = subsuf;
07121 
07122 #endif
07123 
07124     this->sub_surface_rect = *rect;
07125 
07126 #ifndef USE_DFB_SUBSURFACE
07127 
07128     getRealSubSurfacePos(NULL, true);
07129 
07130 #endif
07131 
07132 //    unlock();
07133 
07134     return true;
07135 }
07136 
07137 bool MMSFBSurface::setSubSurface(MMSFBRegion *region) {
07138     MMSFBRectangle rect;
07139 
07140     if (!region)
07141         return false;
07142 
07143     rect.x = region->x1;
07144     rect.y = region->y1;
07145     rect.w = region->x2 - region->x1 + 1;
07146     rect.h = region->y2 - region->y1 + 1;
07147 
07148     return setSubSurface(&rect);
07149 }
07150 
07151 bool MMSFBSurface::moveTo(int x, int y) {
07152     MMSFBRectangle rect;
07153 
07154     rect = this->sub_surface_rect;
07155     rect.x = x;
07156     rect.y = y;
07157 
07158     return setSubSurface(&rect);
07159 }
07160 
07161 bool MMSFBSurface::move(int x, int y) {
07162     MMSFBRectangle rect;
07163 
07164     rect = this->sub_surface_rect;
07165     rect.x += x;
07166     rect.y += y;
07167 
07168     return setSubSurface(&rect);
07169 }
07170 
07171 
07172 bool MMSFBSurface::dump2fcb(bool (*fcb)(char *, int, void *, int *), void *argp, int *argi,
07173                            int x, int y, int w, int h, MMSFBSurfaceDumpMode dumpmode) {
07174 #define D2FCB_ADDSTR1(f) {int l=sprintf(ob,f);if(!fcb(ob,l,argp,argi)){this->unlock();return false;}}
07175 #define D2FCB_ADDSTR2(f,v) {int l=sprintf(ob,f,v);if(!fcb(ob,l,argp,argi)){this->unlock();return false;}}
07176     // check inputs
07177     if (!fcb)
07178         return false;
07179     if ((x < 0)||(y < 0)||(w < 0)||(h < 0))
07180         return false;
07181     if (w == 0)
07182         w = this->config.w - x;
07183     if (h == 0)
07184         h = this->config.h - y;
07185     if ((x + w > this->config.w)||(y + h > this->config.h))
07186         return false;
07187 
07188     // finalize previous clear
07189     finClear();
07190 
07191     // set buffer
07192     char ob[65536];
07193 
07194     // get access to the surface memory
07195     unsigned char   *sbuf;
07196     int             pitch;
07197     this->lock(MMSFB_LOCK_READ, (void**)&sbuf, &pitch);
07198     if (!sbuf)
07199         return false;
07200 
07201     // print format
07202     sprintf(ob, "* %s: x=%d, y=%d, w=%d, h=%d",
07203                 getMMSFBPixelFormatString(this->config.surface_buffer->pixelformat).c_str(),
07204                 x, y, w, h);
07205     fcb(ob, strlen(ob), argp, argi);
07206 
07207     bool dumpok = false;
07208     if (dumpmode == MMSFBSURFACE_DUMPMODE_BYTE) {
07209         // dump byte-by-byte
07210         switch (this->config.surface_buffer->pixelformat) {
07211         case MMSFB_PF_I420:
07212         case MMSFB_PF_YV12:
07213         case MMSFB_PF_NV12:
07214         case MMSFB_PF_NV16:
07215         case MMSFB_PF_NV21:
07216         case MMSFB_PF_ARGB3565:
07217             // do not dump plane formats here
07218             break;
07219         default: {
07220                 // all other formats
07221                 MMSFBPixelDef pixeldef;
07222                 getBitsPerPixel(this->config.surface_buffer->pixelformat, &pixeldef);
07223                 int bits_pp = pixeldef.bits;
07224                 int bytes_pp = bits_pp / 8;
07225                 unsigned char *buf = sbuf + x * bytes_pp + y * pitch;
07226                 D2FCB_ADDSTR1("\n* byte-by-byte ****************************************************************");
07227                 for (int j = 0; j < h-y; j++) {
07228                     int i = j * pitch;
07229                     D2FCB_ADDSTR2("\n%02x", buf[i++]);
07230                     while (i < (w-x) * bytes_pp + j * pitch) {
07231                         D2FCB_ADDSTR2(",%02x", buf[i]);
07232                         i++;
07233                     }
07234                 }
07235                 dumpok = true;
07236             }
07237             break;
07238         }
07239     }
07240 
07241     if (!dumpok) {
07242         // dump pixels
07243         switch (this->config.surface_buffer->pixelformat) {
07244         case MMSFB_PF_ARGB:
07245         case MMSFB_PF_RGB32: {
07246                 int pitch_pix = pitch >> 2;
07247                 unsigned int *buf = (unsigned int*)sbuf + x + y * pitch_pix;
07248                 switch (this->config.surface_buffer->pixelformat) {
07249                 case MMSFB_PF_ARGB:
07250                     D2FCB_ADDSTR1("\n* aarrggbb hex (4-byte integer) ***********************************************");
07251                     break;
07252                 case MMSFB_PF_RGB32:
07253                     D2FCB_ADDSTR1("\n* --rrggbb hex (4-byte integer) ***********************************************");
07254                     break;
07255                 default:
07256                     break;
07257                 }
07258                 for (int j = 0; j < h-y; j++) {
07259                     int i = j * pitch_pix;
07260                     D2FCB_ADDSTR2("\n%08x", (int)buf[i++]);
07261                     while (i < (w-x) + j * pitch_pix) {
07262                         D2FCB_ADDSTR2(",%08x", (int)buf[i]);
07263                         i++;
07264                     }
07265                 }
07266                 D2FCB_ADDSTR1("\n*******************************************************************************");
07267             }
07268             break;
07269         case MMSFB_PF_BGR24: {
07270                 D2FCB_ADDSTR1("\n* bbggrr hex (3-byte) *********************************************************");
07271                 D2FCB_ADDSTR1("\nn/a");
07272                 D2FCB_ADDSTR1("\n*******************************************************************************");
07273             }
07274             break;
07275         case MMSFB_PF_RGB16:
07276         case MMSFB_PF_BGR555: {
07277                 int pitch_pix = pitch >> 1;
07278                 unsigned short int *buf = (unsigned short int*)sbuf + x + y * pitch_pix;
07279                 switch (this->config.surface_buffer->pixelformat) {
07280                 case MMSFB_PF_RGB16:
07281                     D2FCB_ADDSTR1("\n* rrrrrggggggbbbbb bin (2-byte integer) ***************************************");
07282                     break;
07283                 case MMSFB_PF_BGR555:
07284                     D2FCB_ADDSTR1("\n* 0bbbbbgggggrrrrr bin (2-byte integer) ***************************************");
07285                     break;
07286                 default:
07287                     break;
07288                 }
07289                 for (int j = 0; j < h-y; j++) {
07290                     int i = j * pitch_pix;
07291                     D2FCB_ADDSTR2("\n%04x", buf[i++]);
07292                     while (i < (w-x) + j * pitch_pix) {
07293                         D2FCB_ADDSTR2(",%04x", buf[i]);
07294                         i++;
07295                     }
07296                 }
07297                 D2FCB_ADDSTR1("\n*******************************************************************************");
07298             }
07299             break;
07300         case MMSFB_PF_I420:
07301         case MMSFB_PF_YV12: {
07302                 int pitch_pix = pitch;
07303                 unsigned char *buf_y;
07304                 unsigned char *buf_u = sbuf + pitch_pix * this->config.h + (x >> 1) + (y >> 1) * (pitch_pix >> 1);
07305                 unsigned char *buf_v = sbuf + pitch_pix * (this->config.h + (this->config.h >> 2)) + (x >> 1) + (y >> 1) * (pitch_pix >> 1);
07306                 if (this->config.surface_buffer->pixelformat == MMSFB_PF_YV12) {
07307                     buf_y = buf_u;
07308                     buf_u = buf_v;
07309                     buf_v = buf_y;
07310                 }
07311                 buf_y = sbuf + x + y * pitch_pix;
07312                 D2FCB_ADDSTR1("\n* Y plane *********************************************************************");
07313                 for (int j = 0; j < h-y; j++) {
07314                     int i = j * pitch_pix;
07315                     D2FCB_ADDSTR2("\n%02x", buf_y[i++]);
07316                     while (i < (w-x) + j * pitch_pix) {
07317                         D2FCB_ADDSTR2(",%02x", buf_y[i]);
07318                         i++;
07319                     }
07320                 }
07321                 D2FCB_ADDSTR1("\n* U plane *********************************************************************");
07322                 x = x >> 1;
07323                 y = y >> 1;
07324                 w = w >> 1;
07325                 h = h >> 1;
07326                 for (int j = 0; j < h-y; j++) {
07327                     int i = j * (pitch_pix >> 1);
07328                     D2FCB_ADDSTR2("\n%02x", buf_u[i++]);
07329                     while (i < (w-x) + j * (pitch_pix >> 1)) {
07330                         D2FCB_ADDSTR2(",%02x", buf_u[i]);
07331                         i++;
07332                     }
07333                 }
07334                 D2FCB_ADDSTR1("\n* V plane *********************************************************************");
07335                 for (int j = 0; j < h-y; j++) {
07336                     int i = j * (pitch_pix >> 1);
07337                     D2FCB_ADDSTR2("\n%02x", buf_v[i++]);
07338                     while (i < (w-x) + j * (pitch_pix >> 1)) {
07339                         D2FCB_ADDSTR2(",%02x", buf_v[i]);
07340                         i++;
07341                     }
07342                 }
07343                 D2FCB_ADDSTR1("\n*******************************************************************************");
07344             }
07345             break;
07346         default:
07347             // no dump routine for this pixelformat
07348             this->unlock();
07349             return false;
07350         }
07351     }
07352 
07353     // finalize
07354     this->unlock();
07355     D2FCB_ADDSTR1("\n");
07356     return true;
07357 }
07358 
07359 bool dump2buffer_fcb(char *buf, int len, void *argp, int *argi) {
07360     if (len >= *argi) return false;
07361     char *ap = *((char**)argp);
07362     memcpy(ap, buf, len);
07363     ap+= len;
07364     *((void**)argp) = ap;
07365     *argi = *argi - len;
07366     return true;
07367 }
07368 
07369 int MMSFBSurface::dump2buffer(char *out_buffer, int out_buffer_len, int x, int y, int w, int h,
07370                               MMSFBSurfaceDumpMode dumpmode) {
07371     int obl = out_buffer_len;
07372     if (dump2fcb(dump2buffer_fcb, (void*)(&out_buffer), &obl, x, y, w, h, dumpmode)) {
07373         out_buffer[out_buffer_len - obl] = 0;
07374         return out_buffer_len - obl;
07375     }
07376     return 0;
07377 }
07378 
07379 bool dump2file_fcb(char *buf, int len, void *argp, int *argi) {
07380     size_t ritems;
07381     ((MMSFile *)argp)->writeBuffer(buf, &ritems, 1, len);
07382     return true;
07383 }
07384 
07385 bool MMSFBSurface::dump2file(string filename, int x, int y, int w, int h,
07386                              MMSFBSurfaceDumpMode dumpmode) {
07387     MMSFile *mmsfile = new MMSFile(filename, MMSFM_WRITE);
07388     if (mmsfile) {
07389         if (dump2fcb(dump2file_fcb, mmsfile, NULL, x, y, w, h, dumpmode)) {
07390             delete mmsfile;
07391             return true;
07392         }
07393         delete mmsfile;
07394     }
07395     return false;
07396 }
07397 
07398 bool MMSFBSurface::dump2file(string filename, MMSFBSurfaceDumpMode dumpmode) {
07399     return dump2file(filename, 0, 0, 0, 0, dumpmode);
07400 }
07401 
07402 bool dump_fcb(char *buf, int len, void *argp, int *argi) {
07403     buf[len] = 0;
07404     printf("%s", buf);
07405     return true;
07406 }
07407 
07408 bool MMSFBSurface::dump(int x, int y, int w, int h,
07409                         MMSFBSurfaceDumpMode dumpmode) {
07410     if (dump2fcb(dump_fcb, NULL, NULL, x, y, w, h, dumpmode)) {
07411         printf("\n");
07412         return true;
07413     }
07414     return false;
07415 }
07416 
07417 bool MMSFBSurface::dump(MMSFBSurfaceDumpMode dumpmode) {
07418     return dump(0, 0, 0, 0, dumpmode);
07419 }
07420 
07421 bool mmsfb_create_cached_surface(MMSFBSurface **cs, int width, int height,
07422                                  MMSFBSurfacePixelFormat pixelformat) {
07423     if (!cs) return false;
07424 
07425     // check the properties of the existing surface
07426     if (*cs) {
07427         // check if old surface has the same dimension
07428         int w = 0, h = 0;
07429         (*cs)->getSize(&w, &h);
07430         if ((w != width) || (h != height)) {
07431             delete *cs;
07432             *cs = NULL;
07433         }
07434     }
07435 
07436     if (*cs) {
07437         // check if old surface has the same pixelformat
07438         MMSFBSurfacePixelFormat pf = MMSFB_PF_NONE;
07439         (*cs)->getPixelFormat(&pf);
07440         if (pf != pixelformat) {
07441             delete *cs;
07442             *cs = NULL;
07443         }
07444     }
07445 
07446     if (!*cs) {
07447         // create new surface
07448         *cs = new MMSFBSurface(width, height, pixelformat);
07449     }
07450 
07451     return (*cs);
07452 }
07453 
07454 
07455 
07456 
07457 
07458 bool MMSFBSurface::blitARGBtoARGB(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
07459                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
07460                                     int x, int y) {
07461 #ifdef __HAVE_PF_ARGB__
07462     MMSFBSurfacePlanes dst_planes;
07463 
07464     if (extendedLock(source, src_planes, this, &dst_planes)) {
07465         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07466         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07467         MMSFBPERF_START_MEASURING;
07468             mmsfb_blit_argb_to_argb(
07469                     src_planes, src_height,
07470                     sx, sy, sw, sh,
07471                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
07472                     x, y);
07473         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
07474         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07475         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07476         extendedUnlock(source, this);
07477         return true;
07478     }
07479 #endif
07480 
07481     return false;
07482 }
07483 
07484 bool MMSFBSurface::blitARGBtoARGB_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
07485                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
07486                                     int x, int y) {
07487 #ifdef __HAVE_PF_ARGB__
07488     MMSFBSurfacePlanes dst_planes;
07489 
07490     if (extendedLock(source, src_planes, this, &dst_planes)) {
07491         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07492         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07493         MMSFBPERF_START_MEASURING;
07494             mmsfb_blit_blend_argb_to_argb(
07495                     src_planes, src_height,
07496                     sx, sy, sw, sh,
07497                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
07498                     x, y);
07499         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
07500         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07501         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07502         extendedUnlock(source, this);
07503         return true;
07504     }
07505 #endif
07506 
07507     return false;
07508 }
07509 
07510 bool MMSFBSurface::blitARGBtoARGB_BLEND_COLORALPHA(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
07511                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
07512                                     int x, int y) {
07513 #ifdef __HAVE_PF_ARGB__
07514     MMSFBSurfacePlanes dst_planes;
07515 
07516     if (extendedLock(source, src_planes, this, &dst_planes)) {
07517         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07518         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07519         MMSFBPERF_START_MEASURING;
07520             mmsfb_blit_blend_coloralpha_argb_to_argb(
07521                     src_planes, src_height,
07522                     sx, sy, sw, sh,
07523                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
07524                     x, y,
07525                     this->config.color.a);
07526         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
07527         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07528         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07529         extendedUnlock(source, this);
07530         return true;
07531     }
07532 #endif
07533 
07534     return false;
07535 }
07536 
07537 
07538 bool MMSFBSurface::blitARGBtoAiRGB_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
07539                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
07540                                     int x, int y) {
07541 #ifdef __HAVE_PF_ARGB__
07542 #ifdef __HAVE_PF_AiRGB__
07543     MMSFBSurfacePlanes dst_planes;
07544 
07545     if (extendedLock(source, src_planes, this, &dst_planes)) {
07546         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07547         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07548         MMSFBPERF_START_MEASURING;
07549             mmsfb_blit_blend_argb_to_airgb(
07550                     src_planes, src_height,
07551                     sx, sy, sw, sh,
07552                     (unsigned int *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
07553                     x, y);
07554         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
07555         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07556         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07557         extendedUnlock(source, this);
07558         return true;
07559     }
07560 #endif
07561 #endif
07562 
07563     return false;
07564 }
07565 
07566 
07567 bool MMSFBSurface::blitARGBtoRGB32(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
07568                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
07569                                     int x, int y) {
07570 #ifdef __HAVE_PF_ARGB__
07571 #ifdef __HAVE_PF_RGB32__
07572     MMSFBSurfacePlanes dst_planes;
07573 
07574     if (extendedLock(source, src_planes, this, &dst_planes)) {
07575         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07576         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07577         MMSFBPERF_START_MEASURING;
07578             mmsfb_blit_argb_to_rgb32(
07579                     src_planes, src_height,
07580                     sx, sy, sw, sh,
07581                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
07582                     x, y);
07583         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
07584         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07585         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07586         extendedUnlock(source, this);
07587         return true;
07588     }
07589 #endif
07590 #endif
07591 
07592     return false;
07593 }
07594 
07595 bool MMSFBSurface::blitARGBtoRGB32_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
07596                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
07597                                     int x, int y) {
07598 #ifdef __HAVE_PF_ARGB__
07599 #ifdef __HAVE_PF_RGB32__
07600     MMSFBSurfacePlanes dst_planes;
07601 
07602     if (extendedLock(source, src_planes, this, &dst_planes)) {
07603         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07604         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07605         MMSFBPERF_START_MEASURING;
07606             mmsfb_blit_blend_argb_to_rgb32(
07607                     src_planes, src_height,
07608                     sx, sy, sw, sh,
07609                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
07610                     x, y);
07611         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
07612         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07613         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07614         extendedUnlock(source, this);
07615         return true;
07616     }
07617 #endif
07618 #endif
07619 
07620     return false;
07621 }
07622 
07623 bool MMSFBSurface::blitARGBtoRGB32_BLEND_COLORALPHA(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
07624                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
07625                                     int x, int y) {
07626 #ifdef __HAVE_PF_ARGB__
07627 #ifdef __HAVE_PF_RGB32__
07628     MMSFBSurfacePlanes dst_planes;
07629 
07630     if (extendedLock(source, src_planes, this, &dst_planes)) {
07631         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07632         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07633         MMSFBPERF_START_MEASURING;
07634             mmsfb_blit_blend_coloralpha_argb_to_rgb32(
07635                     src_planes, src_height,
07636                     sx, sy, sw, sh,
07637                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
07638                     x, y,
07639                     this->config.color.a);
07640         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
07641         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07642         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07643         extendedUnlock(source, this);
07644         return true;
07645     }
07646 #endif
07647 #endif
07648 
07649     return false;
07650 }
07651 
07652 bool MMSFBSurface::blitARGBtoRGB32_COLORALPHA(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
07653                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
07654                                     int x, int y) {
07655 #ifdef __HAVE_PF_ARGB__
07656 #ifdef __HAVE_PF_RGB32__
07657     MMSFBSurfacePlanes dst_planes;
07658 
07659     if (extendedLock(source, src_planes, this, &dst_planes)) {
07660         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07661         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07662         MMSFBPERF_START_MEASURING;
07663             mmsfb_blit_coloralpha_argb_to_rgb32(
07664                     src_planes, src_height,
07665                     sx, sy, sw, sh,
07666                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
07667                     x, y,
07668                     this->config.color.a);
07669         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
07670         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07671         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07672         extendedUnlock(source, this);
07673         return true;
07674     }
07675 #endif
07676 #endif
07677 
07678     return false;
07679 }
07680 
07681 bool MMSFBSurface::blitARGBtoRGB16(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
07682                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
07683                                     int x, int y) {
07684 #ifdef __HAVE_PF_ARGB__
07685 #ifdef __HAVE_PF_RGB16__
07686     MMSFBSurfacePlanes dst_planes;
07687 
07688     if (extendedLock(source, src_planes, this, &dst_planes)) {
07689         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07690         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07691         MMSFBPERF_START_MEASURING;
07692             mmsfb_blit_argb_to_rgb16(src_planes, src_height,
07693                                      sx, sy, sw, sh,
07694                                      (unsigned short int *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
07695                                      x, y);
07696         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
07697         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07698         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07699         extendedUnlock(source, this);
07700         return true;
07701     }
07702 #endif
07703 #endif
07704 
07705     return false;
07706 }
07707 
07708 bool MMSFBSurface::blitARGBtoRGB16_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
07709                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
07710                                     int x, int y) {
07711 #ifdef __HAVE_PF_ARGB__
07712 #ifdef __HAVE_PF_RGB16__
07713     MMSFBSurfacePlanes dst_planes;
07714 
07715     if (extendedLock(source, src_planes, this, &dst_planes)) {
07716         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07717         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07718         MMSFBPERF_START_MEASURING;
07719             mmsfb_blit_blend_argb_to_rgb16(src_planes, src_height,
07720                                            sx, sy, sw, sh,
07721                                            &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
07722                                            x, y);
07723         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
07724         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07725         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07726         extendedUnlock(source, this);
07727         return true;
07728     }
07729 #endif
07730 #endif
07731 
07732     return false;
07733 }
07734 
07735 bool MMSFBSurface::blitARGBtoARGB3565(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
07736                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
07737                                     int x, int y) {
07738 #ifdef __HAVE_PF_ARGB__
07739 #ifdef __HAVE_PF_ARGB3565__
07740     MMSFBSurfacePlanes dst_planes;
07741 
07742     if (extendedLock(source, src_planes, this, &dst_planes)) {
07743         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07744         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07745         MMSFBPERF_START_MEASURING;
07746             mmsfb_blit_argb_to_argb3565(
07747                     src_planes, src_height,
07748                     sx, sy, sw, sh,
07749                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
07750                     x, y);
07751         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
07752         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07753         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07754         extendedUnlock(source, this);
07755         return true;
07756     }
07757 #endif
07758 #endif
07759 
07760     return false;
07761 }
07762 
07763 bool MMSFBSurface::blitARGBtoARGB3565_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
07764                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
07765                                     int x, int y) {
07766 #ifdef __HAVE_PF_ARGB__
07767 #ifdef __HAVE_PF_ARGB3565__
07768     MMSFBSurfacePlanes dst_planes;
07769 
07770     if (extendedLock(source, src_planes, this, &dst_planes)) {
07771         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07772         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07773         MMSFBPERF_START_MEASURING;
07774             mmsfb_blit_blend_argb_to_argb3565(
07775                     src_planes, src_height,
07776                     sx, sy, sw, sh,
07777                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
07778                     x, y);
07779         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
07780         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07781         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07782         extendedUnlock(source, this);
07783         return true;
07784     }
07785 #endif
07786 #endif
07787 
07788     return false;
07789 }
07790 
07791 
07792 bool MMSFBSurface::blitARGBtoYV12(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
07793                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
07794                                     int x, int y) {
07795 #ifdef __HAVE_PF_ARGB__
07796 #ifdef __HAVE_PF_YV12__
07797     MMSFBSurfacePlanes dst_planes;
07798 
07799     if (extendedLock(source, src_planes, this, &dst_planes)) {
07800         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07801         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07802         MMSFBPERF_START_MEASURING;
07803             mmsfb_blit_argb_to_yv12(
07804                     src_planes, src_height,
07805                     sx, sy, sw, sh,
07806                     (unsigned char *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
07807                     x, y);
07808         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
07809         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07810         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07811         extendedUnlock(source, this);
07812         return true;
07813     }
07814 #endif
07815 #endif
07816 
07817     return false;
07818 }
07819 
07820 bool MMSFBSurface::blitARGBtoYV12_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
07821                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
07822                                     int x, int y) {
07823 #ifdef __HAVE_PF_ARGB__
07824 #ifdef __HAVE_PF_YV12__
07825     MMSFBSurfacePlanes dst_planes;
07826 
07827     if (extendedLock(source, src_planes, this, &dst_planes)) {
07828         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07829         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07830         MMSFBPERF_START_MEASURING;
07831             mmsfb_blit_blend_argb_to_yv12(
07832                     src_planes, src_height,
07833                     sx, sy, sw, sh,
07834                     (unsigned char *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
07835                     x, y);
07836         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
07837         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07838         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07839         extendedUnlock(source, this);
07840         return true;
07841     }
07842 #endif
07843 #endif
07844 
07845     return false;
07846 }
07847 
07848 bool MMSFBSurface::blitARGBtoYV12_BLEND_COLORALPHA(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
07849                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
07850                                     int x, int y) {
07851 #ifdef __HAVE_PF_ARGB__
07852 #ifdef __HAVE_PF_YV12__
07853     MMSFBSurfacePlanes dst_planes;
07854 
07855     if (extendedLock(source, src_planes, this, &dst_planes)) {
07856         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07857         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07858         MMSFBPERF_START_MEASURING;
07859             mmsfb_blit_blend_coloralpha_argb_to_yv12(
07860                     src_planes, src_height,
07861                     sx, sy, sw, sh,
07862                     (unsigned char *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
07863                     x, y,
07864                     this->config.color.a);
07865         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
07866         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07867         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07868         extendedUnlock(source, this);
07869         return true;
07870     }
07871 #endif
07872 #endif
07873 
07874     return false;
07875 }
07876 
07877 bool MMSFBSurface::blitARGBtoRGB24(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
07878                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
07879                                     int x, int y) {
07880 #ifdef __HAVE_PF_ARGB__
07881 #ifdef __HAVE_PF_RGB24__
07882     MMSFBSurfacePlanes dst_planes;
07883 
07884     if (extendedLock(source, src_planes, this, &dst_planes)) {
07885         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07886         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07887         MMSFBPERF_START_MEASURING;
07888             mmsfb_blit_argb_to_rgb24(
07889                     src_planes, src_height,
07890                     sx, sy, sw, sh,
07891                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
07892                     x, y);
07893         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
07894         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07895         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07896         extendedUnlock(source, this);
07897         return true;
07898     }
07899 #endif
07900 #endif
07901 
07902     return false;
07903 }
07904 
07905 bool MMSFBSurface::blitARGBtoRGB24_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
07906                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
07907                                     int x, int y) {
07908 #ifdef __HAVE_PF_ARGB__
07909 #ifdef __HAVE_PF_RGB24__
07910     MMSFBSurfacePlanes dst_planes;
07911 
07912     if (extendedLock(source, src_planes, this, &dst_planes)) {
07913         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07914         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07915         MMSFBPERF_START_MEASURING;
07916             mmsfb_blit_blend_argb_to_rgb24(
07917                     src_planes, src_height,
07918                     sx, sy, sw, sh,
07919                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
07920                     x, y);
07921         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
07922         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07923         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07924         extendedUnlock(source, this);
07925         return true;
07926     }
07927 #endif
07928 #endif
07929 
07930     return false;
07931 }
07932 
07933 bool MMSFBSurface::blitARGBtoBGR24_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
07934                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
07935                                     int x, int y) {
07936 #ifdef __HAVE_PF_ARGB__
07937 #ifdef __HAVE_PF_BGR24__
07938     MMSFBSurfacePlanes dst_planes;
07939 
07940     if (extendedLock(source, src_planes, this, &dst_planes)) {
07941         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07942         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07943         MMSFBPERF_START_MEASURING;
07944             mmsfb_blit_blend_argb_to_bgr24(
07945                     src_planes, src_height,
07946                     sx, sy, sw, sh,
07947                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
07948                     x, y);
07949         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
07950         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07951         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07952         extendedUnlock(source, this);
07953         return true;
07954     }
07955 #endif
07956 #endif
07957 
07958     return false;
07959 }
07960 
07961 bool MMSFBSurface::blitARGBtoBGR24_BLEND_COLORALPHA(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
07962                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
07963                                     int x, int y) {
07964 #ifdef __HAVE_PF_ARGB__
07965 #ifdef __HAVE_PF_BGR24__
07966     MMSFBSurfacePlanes dst_planes;
07967 
07968     if (extendedLock(source, src_planes, this, &dst_planes)) {
07969         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07970         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07971         MMSFBPERF_START_MEASURING;
07972             mmsfb_blit_blend_coloralpha_argb_to_bgr24(
07973                     src_planes, src_height,
07974                     sx, sy, sw, sh,
07975                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
07976                     x, y,
07977                     this->config.color.a);
07978         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
07979         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07980         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07981         extendedUnlock(source, this);
07982         return true;
07983     }
07984 #endif
07985 #endif
07986 
07987     return false;
07988 }
07989 
07990 bool MMSFBSurface::blitARGBtoBGR555_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
07991                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
07992                                     int x, int y) {
07993 #ifdef __HAVE_PF_ARGB__
07994 #ifdef __HAVE_PF_BGR555__
07995     MMSFBSurfacePlanes dst_planes;
07996 
07997     if (extendedLock(source, src_planes, this, &dst_planes)) {
07998         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07999         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08000         MMSFBPERF_START_MEASURING;
08001             mmsfb_blit_blend_argb_to_bgr555(
08002                     src_planes, src_height,
08003                     sx, sy, sw, sh,
08004                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08005                     x, y);
08006         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08007         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08008         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08009         extendedUnlock(source, this);
08010         return true;
08011     }
08012 #endif
08013 #endif
08014 
08015     return false;
08016 }
08017 
08018 bool MMSFBSurface::blitRGB32toRGB32(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08019                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08020                                     int x, int y) {
08021 #ifdef __HAVE_PF_RGB32__
08022     MMSFBSurfacePlanes dst_planes;
08023 
08024     if (extendedLock(source, src_planes, this, &dst_planes)) {
08025         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08026         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08027         MMSFBPERF_START_MEASURING;
08028             mmsfb_blit_rgb32_to_rgb32(
08029                     src_planes, src_height,
08030                     sx, sy, sw, sh,
08031                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08032                     x, y);
08033         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08034         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08035         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08036         extendedUnlock(source, this);
08037         return true;
08038     }
08039 #endif
08040 
08041     return false;
08042 }
08043 
08044 bool MMSFBSurface::blitRGB32toARGB(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08045                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08046                                     int x, int y) {
08047 #ifdef __HAVE_PF_RGB32__
08048     MMSFBSurfacePlanes dst_planes;
08049 
08050     if (extendedLock(source, src_planes, this, &dst_planes)) {
08051         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08052         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08053         MMSFBPERF_START_MEASURING;
08054             mmsfb_blit_rgb32_to_argb(
08055                     src_planes, src_height,
08056                     sx, sy, sw, sh,
08057                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08058                     x, y);
08059         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08060         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08061         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08062         extendedUnlock(source, this);
08063         return true;
08064     }
08065 #endif
08066 
08067     return false;
08068 }
08069 
08070 bool MMSFBSurface::blitRGB32toRGB32_COLORALPHA(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08071                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08072                                     int x, int y) {
08073 #ifdef __HAVE_PF_RGB32__
08074     MMSFBSurfacePlanes dst_planes;
08075 
08076     if (extendedLock(source, src_planes, this, &dst_planes)) {
08077         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08078         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08079         MMSFBPERF_START_MEASURING;
08080             mmsfb_blit_coloralpha_rgb32_to_rgb32(
08081                     src_planes, src_height,
08082                     sx, sy, sw, sh,
08083                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08084                     x, y,
08085                     this->config.color.a);
08086         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08087         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08088         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08089         extendedUnlock(source, this);
08090         return true;
08091     }
08092 #endif
08093 
08094     return false;
08095 }
08096 
08097 bool MMSFBSurface::blitRGB16toRGB16(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08098                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08099                                     int x, int y) {
08100 #ifdef __HAVE_PF_RGB16__
08101     MMSFBSurfacePlanes dst_planes;
08102 
08103     if (extendedLock(source, src_planes, this, &dst_planes)) {
08104         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08105         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08106         MMSFBPERF_START_MEASURING;
08107             mmsfb_blit_rgb16_to_rgb16(
08108                     src_planes, src_height,
08109                     sx, sy, sw, sh,
08110                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08111                     x, y);
08112         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08113         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08114         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08115         extendedUnlock(source, this);
08116         return true;
08117     }
08118 #endif
08119 
08120     return false;
08121 }
08122 
08123 bool MMSFBSurface::blitRGB16toARGB(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08124                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08125                                     int x, int y) {
08126 #ifdef __HAVE_PF_RGB16__
08127 #ifdef __HAVE_PF_ARGB__
08128     MMSFBSurfacePlanes dst_planes;
08129 
08130     if (extendedLock(source, src_planes, this, &dst_planes)) {
08131         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08132         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08133         MMSFBPERF_START_MEASURING;
08134             mmsfb_blit_rgb16_to_argb(
08135                     src_planes, src_height,
08136                     sx, sy, sw, sh,
08137                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08138                     x, y);
08139         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08140         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08141         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08142         extendedUnlock(source, this);
08143         return true;
08144     }
08145 #endif
08146 #endif
08147 
08148     return false;
08149 }
08150 
08151 bool MMSFBSurface::blitRGB16toRGB32(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08152                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08153                                     int x, int y) {
08154 #ifdef __HAVE_PF_RGB16__
08155 #ifdef __HAVE_PF_RGB32__
08156     MMSFBSurfacePlanes dst_planes;
08157 
08158     if (extendedLock(source, src_planes, this, &dst_planes)) {
08159         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08160         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08161         MMSFBPERF_START_MEASURING;
08162             mmsfb_blit_rgb16_to_rgb32(
08163                     src_planes, src_height,
08164                     sx, sy, sw, sh,
08165                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08166                     x, y);
08167         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08168         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08169         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08170         extendedUnlock(source, this);
08171         return true;
08172     }
08173 #endif
08174 #endif
08175 
08176     return false;
08177 }
08178 
08179 bool MMSFBSurface::blitAiRGBtoAiRGB(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08180                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08181                                     int x, int y) {
08182 #ifdef __HAVE_PF_AiRGB__
08183     MMSFBSurfacePlanes dst_planes;
08184 
08185     if (extendedLock(source, src_planes, this, &dst_planes)) {
08186         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08187         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08188         MMSFBPERF_START_MEASURING;
08189             mmsfb_blit_airgb_to_airgb(src_planes, src_height,
08190                                       sx, sy, sw, sh,
08191                                       &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08192                                       x, y);
08193         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08194         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08195         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08196         extendedUnlock(source, this);
08197         return true;
08198     }
08199 #endif
08200 
08201     return false;
08202 }
08203 
08204 bool MMSFBSurface::blitAiRGBtoAiRGB_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08205                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08206                                     int x, int y) {
08207 #ifdef __HAVE_PF_AiRGB__
08208     MMSFBSurfacePlanes dst_planes;
08209 
08210     if (extendedLock(source, src_planes, this, &dst_planes)) {
08211         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08212         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08213         MMSFBPERF_START_MEASURING;
08214             mmsfb_blit_blend_airgb_to_airgb(src_planes, src_height,
08215                                             sx, sy, sw, sh,
08216                                             (unsigned int *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08217                                             x, y);
08218         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08219         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08220         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08221         extendedUnlock(source, this);
08222         return true;
08223     }
08224 #endif
08225 
08226     return false;
08227 }
08228 
08229 bool MMSFBSurface::blitAiRGBtoAiRGB_BLEND_COLORALPHA(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08230                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08231                                     int x, int y) {
08232 #ifdef __HAVE_PF_AiRGB__
08233     MMSFBSurfacePlanes dst_planes;
08234 
08235     if (extendedLock(source, src_planes, this, &dst_planes)) {
08236         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08237         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08238         MMSFBPERF_START_MEASURING;
08239             mmsfb_blit_blend_coloralpha_airgb_to_airgb(src_planes, src_height,
08240                                                        sx, sy, sw, sh,
08241                                                        (unsigned int *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08242                                                        x, y,
08243                                                        this->config.color.a);
08244         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08245         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08246         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08247         extendedUnlock(source, this);
08248         return true;
08249     }
08250 #endif
08251 
08252     return false;
08253 }
08254 
08255 bool MMSFBSurface::blitAiRGBtoARGB(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08256                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08257                                     int x, int y) {
08258 #ifdef __HAVE_PF_ARGB__
08259 #ifdef __HAVE_PF_AiRGB__
08260     MMSFBSurfacePlanes dst_planes;
08261 
08262     if (extendedLock(source, src_planes, this, &dst_planes)) {
08263         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08264         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08265         MMSFBPERF_START_MEASURING;
08266             mmsfb_blit_airgb_to_argb(
08267                     src_planes, src_height,
08268                     sx, sy, sw, sh,
08269                     (unsigned int *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08270                     x, y);
08271         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08272         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08273         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08274         extendedUnlock(source, this);
08275         return true;
08276     }
08277 #endif
08278 #endif
08279 
08280     return false;
08281 }
08282 
08283 bool MMSFBSurface::blitAiRGBtoARGB_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08284                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08285                                     int x, int y) {
08286 #ifdef __HAVE_PF_ARGB__
08287 #ifdef __HAVE_PF_AiRGB__
08288     MMSFBSurfacePlanes dst_planes;
08289 
08290     if (extendedLock(source, src_planes, this, &dst_planes)) {
08291         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08292         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08293         MMSFBPERF_START_MEASURING;
08294             mmsfb_blit_blend_airgb_to_argb(
08295                     src_planes, src_height,
08296                     sx, sy, sw, sh,
08297                     (unsigned int *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08298                     x, y);
08299         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08300         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08301         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08302         extendedUnlock(source, this);
08303         return true;
08304     }
08305 #endif
08306 #endif
08307 
08308     return false;
08309 }
08310 
08311 bool MMSFBSurface::blitAiRGBtoRGB16(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08312                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08313                                     int x, int y) {
08314 #ifdef __HAVE_PF_AiRGB__
08315 #ifdef __HAVE_PF_RGB16__
08316     MMSFBSurfacePlanes dst_planes;
08317 
08318     if (extendedLock(source, src_planes, this, &dst_planes)) {
08319         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08320         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08321         MMSFBPERF_START_MEASURING;
08322             mmsfb_blit_airgb_to_rgb16(src_planes, src_height,
08323                                       sx, sy, sw, sh,
08324                                       (unsigned short int *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08325                                       x, y);
08326         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08327         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08328         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08329         extendedUnlock(source, this);
08330         return true;
08331     }
08332 #endif
08333 #endif
08334 
08335     return false;
08336 }
08337 
08338 bool MMSFBSurface::blitAiRGBtoRGB16_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08339                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08340                                     int x, int y) {
08341 #ifdef __HAVE_PF_AiRGB__
08342 #ifdef __HAVE_PF_RGB16__
08343     MMSFBSurfacePlanes dst_planes;
08344 
08345     if (extendedLock(source, src_planes, this, &dst_planes)) {
08346         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08347         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08348         MMSFBPERF_START_MEASURING;
08349             mmsfb_blit_blend_airgb_to_rgb16(src_planes, src_height,
08350                                             sx, sy, sw, sh,
08351                                             (unsigned short int *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08352                                             x, y);
08353         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08354         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08355         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08356         extendedUnlock(source, this);
08357         return true;
08358     }
08359 #endif
08360 #endif
08361 
08362     return false;
08363 }
08364 
08365 bool MMSFBSurface::blitAYUVtoAYUV(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08366                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08367                                     int x, int y) {
08368 #ifdef __HAVE_PF_AYUV__
08369     MMSFBSurfacePlanes dst_planes;
08370 
08371     if (extendedLock(source, src_planes, this, &dst_planes)) {
08372         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08373         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08374         MMSFBPERF_START_MEASURING;
08375             mmsfb_blit_ayuv_to_ayuv(src_planes, src_height,
08376                                     sx, sy, sw, sh,
08377                                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08378                                     x, y);
08379         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08380         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08381         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08382         extendedUnlock(source, this);
08383         return true;
08384     }
08385 #endif
08386 
08387     return false;
08388 }
08389 
08390 bool MMSFBSurface::blitAYUVtoAYUV_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08391                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08392                                     int x, int y) {
08393 #ifdef __HAVE_PF_AYUV__
08394     MMSFBSurfacePlanes dst_planes;
08395 
08396     if (extendedLock(source, src_planes, this, &dst_planes)) {
08397         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08398         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08399         MMSFBPERF_START_MEASURING;
08400             mmsfb_blit_blend_ayuv_to_ayuv(src_planes, src_height,
08401                                           sx, sy, sw, sh,
08402                                           (unsigned int *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08403                                           x, y);
08404         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08405         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08406         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08407         extendedUnlock(source, this);
08408         return true;
08409     }
08410 #endif
08411 
08412     return false;
08413 }
08414 
08415 bool MMSFBSurface::blitAYUVtoAYUV_BLEND_COLORALPHA(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08416                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08417                                     int x, int y) {
08418 #ifdef __HAVE_PF_AYUV__
08419     MMSFBSurfacePlanes dst_planes;
08420 
08421     if (extendedLock(source, src_planes, this, &dst_planes)) {
08422         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08423         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08424         MMSFBPERF_START_MEASURING;
08425             mmsfb_blit_blend_coloralpha_ayuv_to_ayuv(src_planes, src_height,
08426                                                      sx, sy, sw, sh,
08427                                                      (unsigned int *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08428                                                      x, y,
08429                                                      this->config.color.a);
08430         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08431         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08432         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08433         extendedUnlock(source, this);
08434         return true;
08435     }
08436 #endif
08437 
08438     return false;
08439 }
08440 
08441 bool MMSFBSurface::blitAYUVtoRGB16(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08442                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08443                                     int x, int y) {
08444 #ifdef __HAVE_PF_AYUV__
08445 #ifdef __HAVE_PF_RGB16__
08446     MMSFBSurfacePlanes dst_planes;
08447 
08448     if (extendedLock(source, src_planes, this, &dst_planes)) {
08449         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08450         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08451         MMSFBPERF_START_MEASURING;
08452             mmsfb_blit_ayuv_to_rgb16(src_planes, src_height,
08453                                      sx, sy, sw, sh,
08454                                      (unsigned short int *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08455                                      x, y);
08456         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08457         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08458         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08459         extendedUnlock(source, this);
08460         return true;
08461     }
08462 #endif
08463 #endif
08464 
08465     return false;
08466 }
08467 
08468 bool MMSFBSurface::blitAYUVtoRGB16_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08469                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08470                                     int x, int y) {
08471 #ifdef __HAVE_PF_AYUV__
08472 #ifdef __HAVE_PF_RGB16__
08473     MMSFBSurfacePlanes dst_planes;
08474 
08475     if (extendedLock(source, src_planes, this, &dst_planes)) {
08476         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08477         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08478         MMSFBPERF_START_MEASURING;
08479             mmsfb_blit_blend_ayuv_to_rgb16(src_planes, src_height,
08480                                            sx, sy, sw, sh,
08481                                            (unsigned short int *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08482                                            x, y);
08483         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08484         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08485         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08486         extendedUnlock(source, this);
08487         return true;
08488     }
08489 #endif
08490 #endif
08491 
08492     return false;
08493 }
08494 
08495 bool MMSFBSurface::blitAYUVtoYV12_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08496                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08497                                     int x, int y) {
08498 #ifdef __HAVE_PF_AYUV__
08499 #ifdef __HAVE_PF_YV12__
08500     MMSFBSurfacePlanes dst_planes;
08501 
08502     if (extendedLock(source, src_planes, this, &dst_planes)) {
08503         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08504         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08505         MMSFBPERF_START_MEASURING;
08506             mmsfb_blit_blend_ayuv_to_yv12(src_planes, src_height,
08507                                           sx, sy, sw, sh,
08508                                           (unsigned char *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08509                                           x, y);
08510         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08511         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08512         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08513         extendedUnlock(source, this);
08514         return true;
08515     }
08516 #endif
08517 #endif
08518 
08519     return false;
08520 }
08521 
08522 bool MMSFBSurface::blitAYUVtoYV12_BLEND_COLORALPHA(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08523                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08524                                     int x, int y) {
08525 #ifdef __HAVE_PF_AYUV__
08526 #ifdef __HAVE_PF_YV12__
08527     MMSFBSurfacePlanes dst_planes;
08528 
08529     if (extendedLock(source, src_planes, this, &dst_planes)) {
08530         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08531         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08532         MMSFBPERF_START_MEASURING;
08533             mmsfb_blit_blend_coloralpha_ayuv_to_yv12(src_planes, src_height,
08534                                                      sx, sy, sw, sh,
08535                                                      (unsigned char *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08536                                                      x, y,
08537                                                      this->config.color.a);
08538         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08539         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08540         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08541         extendedUnlock(source, this);
08542         return true;
08543     }
08544 #endif
08545 #endif
08546 
08547     return false;
08548 }
08549 
08550 bool MMSFBSurface::blitYV12toYV12(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08551                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08552                                     int x, int y) {
08553 #ifdef __HAVE_PF_YV12__
08554     MMSFBSurfacePlanes dst_planes;
08555 
08556     if (extendedLock(source, src_planes, this, &dst_planes)) {
08557         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08558         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08559         MMSFBPERF_START_MEASURING;
08560             mmsfb_blit_yv12_to_yv12(src_planes, src_height,
08561                                     sx, sy, sw, sh,
08562                                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08563                                     x, y);
08564         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08565         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08566         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08567         extendedUnlock(source, this);
08568         return true;
08569     }
08570 #endif
08571 
08572     return false;
08573 }
08574 
08575 bool MMSFBSurface::blitYV12toRGB32(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08576                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08577                                     int x, int y) {
08578 #ifdef __HAVE_PF_YV12__
08579 #ifdef __HAVE_PF_RGB32__
08580     MMSFBSurfacePlanes dst_planes;
08581 
08582     if (extendedLock(source, src_planes, this, &dst_planes)) {
08583         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08584         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08585         MMSFBPERF_START_MEASURING;
08586             mmsfb_blit_yv12_to_rgb32(src_planes, src_height,
08587                                      sx, sy, sw, sh,
08588                                      (unsigned int *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08589                                      x, y);
08590         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08591         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08592         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08593         extendedUnlock(source, this);
08594         return true;
08595     }
08596 #endif
08597 #endif
08598 
08599     return false;
08600 }
08601 
08602 bool MMSFBSurface::blitI420toI420(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08603                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08604                                     int x, int y) {
08605 #ifdef __HAVE_PF_I420__
08606     MMSFBSurfacePlanes dst_planes;
08607 
08608     if (extendedLock(source, src_planes, this, &dst_planes)) {
08609         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08610         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08611         MMSFBPERF_START_MEASURING;
08612             mmsfb_blit_i420_to_i420(src_planes, src_height,
08613                                     sx, sy, sw, sh,
08614                                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08615                                     x, y);
08616         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08617         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08618         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08619         extendedUnlock(source, this);
08620         return true;
08621     }
08622 #endif
08623 
08624     return false;
08625 }
08626 
08627 bool MMSFBSurface::blitI420toYV12(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08628                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08629                                     int x, int y) {
08630 #ifdef __HAVE_PF_I420__
08631 #ifdef __HAVE_PF_YV12__
08632     MMSFBSurfacePlanes dst_planes;
08633 
08634     if (extendedLock(source, src_planes, this, &dst_planes)) {
08635         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08636         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08637         MMSFBPERF_START_MEASURING;
08638             mmsfb_blit_i420_to_yv12(
08639                     src_planes, src_height,
08640                     sx, sy, sw, sh,
08641                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08642                     x, y);
08643         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08644         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08645         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08646         extendedUnlock(source, this);
08647         return true;
08648     }
08649 #endif
08650 #endif
08651 
08652     return false;
08653 }
08654 
08655 bool MMSFBSurface::blitYUY2toYUY2(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08656                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08657                                     int x, int y) {
08658 #ifdef __HAVE_PF_YUY2__
08659     MMSFBSurfacePlanes dst_planes;
08660 
08661     if (extendedLock(source, src_planes, this, &dst_planes)) {
08662         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08663         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08664         MMSFBPERF_START_MEASURING;
08665             mmsfb_blit_yuy2_to_yuy2(
08666                     src_planes, src_height,
08667                     sx, sy, sw, sh,
08668                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08669                     x, y);
08670         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08671         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08672         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08673         extendedUnlock(source, this);
08674         return true;
08675     }
08676 #endif
08677 
08678     return false;
08679 }
08680 
08681 bool MMSFBSurface::blitYUY2toYV12(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08682                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08683                                     int x, int y) {
08684 #ifdef __HAVE_PF_YUY2__
08685 #ifdef __HAVE_PF_YV12__
08686     MMSFBSurfacePlanes dst_planes;
08687 
08688     if (extendedLock(source, src_planes, this, &dst_planes)) {
08689         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08690         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08691         MMSFBPERF_START_MEASURING;
08692             mmsfb_blit_yuy2_to_yv12(
08693                     src_planes, src_height,
08694                     sx, sy, sw, sh,
08695                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08696                     x, y);
08697         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08698         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08699         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08700         extendedUnlock(source, this);
08701         return true;
08702     }
08703 #endif
08704 #endif
08705 
08706     return false;
08707 }
08708 
08709 bool MMSFBSurface::blitRGB24toRGB24(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08710                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08711                                     int x, int y) {
08712 #ifdef __HAVE_PF_RGB24__
08713     MMSFBSurfacePlanes dst_planes;
08714 
08715     if (extendedLock(source, src_planes, this, &dst_planes)) {
08716         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08717         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08718         MMSFBPERF_START_MEASURING;
08719             mmsfb_blit_rgb24_to_rgb24(src_planes, src_height,
08720                                       sx, sy, sw, sh,
08721                                       &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08722                                       x, y);
08723         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08724         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08725         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08726         extendedUnlock(source, this);
08727         return true;
08728     }
08729 #endif
08730 
08731     return false;
08732 }
08733 
08734 bool MMSFBSurface::blitRGB24toARGB(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08735                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08736                                     int x, int y) {
08737 #ifdef __HAVE_PF_RGB24__
08738 #ifdef __HAVE_PF_ARGB__
08739     MMSFBSurfacePlanes dst_planes;
08740 
08741     if (extendedLock(source, src_planes, this, &dst_planes)) {
08742         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08743         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08744         MMSFBPERF_START_MEASURING;
08745             mmsfb_blit_rgb24_to_argb(src_planes, src_height,
08746                                     sx, sy, sw, sh,
08747                                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08748                                     x, y);
08749         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08750         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08751         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08752         extendedUnlock(source, this);
08753         return true;
08754     }
08755 #endif
08756 #endif
08757 
08758     return false;
08759 }
08760 
08761 bool MMSFBSurface::blitRGB24toRGB32(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08762                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08763                                     int x, int y) {
08764 #ifdef __HAVE_PF_RGB24__
08765 #ifdef __HAVE_PF_RGB32__
08766     MMSFBSurfacePlanes dst_planes;
08767 
08768     if (extendedLock(source, src_planes, this, &dst_planes)) {
08769         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08770         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08771         MMSFBPERF_START_MEASURING;
08772             mmsfb_blit_rgb24_to_rgb32(src_planes, src_height,
08773                                       sx, sy, sw, sh,
08774                                       &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08775                                       x, y);
08776         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08777         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08778         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08779         extendedUnlock(source, this);
08780         return true;
08781     }
08782 #endif
08783 #endif
08784 
08785     return false;
08786 }
08787 
08788 bool MMSFBSurface::blitRGB24toYV12(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08789                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08790                                     int x, int y) {
08791 #ifdef __HAVE_PF_RGB24__
08792 #ifdef __HAVE_PF_YV12__
08793     MMSFBSurfacePlanes dst_planes;
08794 
08795     if (extendedLock(source, src_planes, this, &dst_planes)) {
08796         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08797         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08798         MMSFBPERF_START_MEASURING;
08799             mmsfb_blit_rgb24_to_yv12(
08800                     src_planes, src_height,
08801                     sx, sy, sw, sh,
08802                     (unsigned char *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08803                     x, y);
08804         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08805         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08806         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08807         extendedUnlock(source, this);
08808         return true;
08809     }
08810 #endif
08811 #endif
08812 
08813     return false;
08814 }
08815 
08816 bool MMSFBSurface::blitBGR24toBGR24(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08817                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08818                                     int x, int y) {
08819 #ifdef __HAVE_PF_BGR24__
08820     MMSFBSurfacePlanes dst_planes;
08821 
08822     if (extendedLock(source, src_planes, this, &dst_planes)) {
08823         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08824         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08825         MMSFBPERF_START_MEASURING;
08826             mmsfb_blit_bgr24_to_bgr24(
08827                     src_planes, src_height,
08828                     sx, sy, sw, sh,
08829                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08830                     x, y);
08831         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08832         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08833         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08834         extendedUnlock(source, this);
08835         return true;
08836     }
08837 #endif
08838 
08839     return false;
08840 }
08841 
08842 bool MMSFBSurface::blitBGR24toBGR24_COLORALPHA(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08843                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08844                                     int x, int y) {
08845 #ifdef __HAVE_PF_BGR24__
08846     MMSFBSurfacePlanes dst_planes;
08847 
08848     if (extendedLock(source, src_planes, this, &dst_planes)) {
08849         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08850         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08851         MMSFBPERF_START_MEASURING;
08852             mmsfb_blit_coloralpha_bgr24_to_bgr24(
08853                     src_planes, src_height,
08854                     sx, sy, sw, sh,
08855                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08856                     x, y,
08857                     this->config.color.a);
08858         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08859         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08860         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08861         extendedUnlock(source, this);
08862         return true;
08863     }
08864 #endif
08865 
08866     return false;
08867 }
08868 
08869 bool MMSFBSurface::blitARGB3565toARGB3565(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08870                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08871                                     int x, int y) {
08872 #ifdef __HAVE_PF_ARGB3565__
08873     MMSFBSurfacePlanes dst_planes;
08874 
08875     if (extendedLock(source, src_planes, this, &dst_planes)) {
08876         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08877         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08878         MMSFBPERF_START_MEASURING;
08879             mmsfb_blit_argb3565_to_argb3565(src_planes, src_height,
08880                                             sx, sy, sw, sh,
08881                                             &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08882                                             x, y);
08883         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08884         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08885         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08886         extendedUnlock(source, this);
08887         return true;
08888     }
08889 #endif
08890 
08891     return false;
08892 }
08893 
08894 bool MMSFBSurface::blitARGB4444toARGB4444(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08895                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08896                                     int x, int y) {
08897 #ifdef __HAVE_PF_ARGB4444__
08898     MMSFBSurfacePlanes dst_planes;
08899 
08900     if (extendedLock(source, src_planes, this, &dst_planes)) {
08901         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08902         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08903         MMSFBPERF_START_MEASURING;
08904             mmsfb_blit_argb4444_to_argb4444(
08905                     src_planes, src_height,
08906                     sx, sy, sw, sh,
08907                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08908                     x, y);
08909         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08910         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08911         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08912         extendedUnlock(source, this);
08913         return true;
08914     }
08915 #endif
08916 
08917     return false;
08918 }
08919 
08920 bool MMSFBSurface::blitARGB4444toARGB4444_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08921                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08922                                     int x, int y) {
08923 #ifdef __HAVE_PF_ARGB4444__
08924     MMSFBSurfacePlanes dst_planes;
08925 
08926     if (extendedLock(source, src_planes, this, &dst_planes)) {
08927         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08928         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08929         MMSFBPERF_START_MEASURING;
08930             mmsfb_blit_blend_argb4444_to_argb4444(
08931                     src_planes, src_height,
08932                     sx, sy, sw, sh,
08933                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08934                     x, y);
08935         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08936         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08937         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08938         extendedUnlock(source, this);
08939         return true;
08940     }
08941 #endif
08942 
08943     return false;
08944 }
08945 
08946 bool MMSFBSurface::blitARGB4444toARGB4444_BLEND_COLORALPHA(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08947                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08948                                     int x, int y) {
08949 #ifdef __HAVE_PF_ARGB4444__
08950     MMSFBSurfacePlanes dst_planes;
08951 
08952     if (extendedLock(source, src_planes, this, &dst_planes)) {
08953         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08954         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08955         MMSFBPERF_START_MEASURING;
08956             mmsfb_blit_blend_coloralpha_argb4444_to_argb4444(
08957                     src_planes, src_height,
08958                     sx, sy, sw, sh,
08959                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08960                     x, y,
08961                     this->config.color.a);
08962         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08963         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08964         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08965         extendedUnlock(source, this);
08966         return true;
08967     }
08968 #endif
08969 
08970     return false;
08971 }
08972 
08973 bool MMSFBSurface::blitARGB4444toRGB32_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08974                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08975                                     int x, int y) {
08976 #ifdef __HAVE_PF_ARGB4444__
08977 #ifdef __HAVE_PF_RGB32__
08978     MMSFBSurfacePlanes dst_planes;
08979 
08980     if (extendedLock(source, src_planes, this, &dst_planes)) {
08981         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08982         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08983         MMSFBPERF_START_MEASURING;
08984             mmsfb_blit_blend_argb4444_to_rgb32(
08985                     src_planes, src_height,
08986                     sx, sy, sw, sh,
08987                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08988                     x, y);
08989         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08990         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08991         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08992         extendedUnlock(source, this);
08993         return true;
08994     }
08995 #endif
08996 #endif
08997 
08998     return false;
08999 }
09000 
09001 bool MMSFBSurface::blitARGB4444toRGB32_BLEND_COLORALPHA(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
09002                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
09003                                     int x, int y) {
09004 #ifdef __HAVE_PF_ARGB4444__
09005 #ifdef __HAVE_PF_RGB32__
09006     MMSFBSurfacePlanes dst_planes;
09007 
09008     if (extendedLock(source, src_planes, this, &dst_planes)) {
09009         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09010         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
09011         MMSFBPERF_START_MEASURING;
09012             mmsfb_blit_blend_coloralpha_argb4444_to_rgb32(
09013                     src_planes, src_height,
09014                     sx, sy, sw, sh,
09015                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
09016                     x, y,
09017                     this->config.color.a);
09018         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
09019         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09020         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
09021         extendedUnlock(source, this);
09022         return true;
09023     }
09024 #endif
09025 #endif
09026 
09027     return false;
09028 }
09029 
09030 bool MMSFBSurface::blitBGR555toBGR555(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
09031                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
09032                                     int x, int y) {
09033 #ifdef __HAVE_PF_BGR555__
09034     MMSFBSurfacePlanes dst_planes;
09035 
09036     if (extendedLock(source, src_planes, this, &dst_planes)) {
09037         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09038         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
09039         MMSFBPERF_START_MEASURING;
09040             mmsfb_blit_bgr555_to_bgr555(
09041                     src_planes, src_height,
09042                     sx, sy, sw, sh,
09043                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
09044                     x, y);
09045         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
09046         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09047         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
09048         extendedUnlock(source, this);
09049         return true;
09050     }
09051 #endif
09052 
09053     return false;
09054 }
09055 
09056 
09057 
09058 bool MMSFBSurface::stretchBlitARGBtoARGB(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
09059                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
09060                                     int dx, int dy, int dw, int dh,
09061                                     bool antialiasing) {
09062 #ifdef __HAVE_PF_ARGB__
09063     MMSFBSurfacePlanes dst_planes;
09064 
09065     if (extendedLock(source, src_planes, this, &dst_planes)) {
09066         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09067         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09068         MMSFBPERF_START_MEASURING;
09069             mmsfb_stretchblit_argb_to_argb(
09070                     src_planes, src_height,
09071                     sx, sy, sw, sh,
09072                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
09073                     dx, dy, dw, dh,
09074                     antialiasing);
09075         MMSFBPERF_STOP_MEASURING_STRETCHBLIT(this, src_pixelformat, sw, sh, dw, dh);
09076         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09077         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09078         extendedUnlock(source, this);
09079 
09080         return true;
09081     }
09082 #endif
09083 
09084     return false;
09085 }
09086 
09087 
09088 bool MMSFBSurface::stretchBlitARGBtoARGB_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
09089                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
09090                                     int dx, int dy, int dw, int dh,
09091                                     bool antialiasing) {
09092 #ifdef __HAVE_PF_ARGB__
09093     MMSFBSurfacePlanes dst_planes;
09094 
09095     if (extendedLock(source, src_planes, this, &dst_planes)) {
09096         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09097         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09098         MMSFBPERF_START_MEASURING;
09099             mmsfb_stretchblit_blend_argb_to_argb(
09100                     src_planes, src_height,
09101                     sx, sy, sw, sh,
09102                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
09103                     dx, dy, dw, dh);
09104         MMSFBPERF_STOP_MEASURING_STRETCHBLIT(this, src_pixelformat, sw, sh, dw, dh);
09105         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09106         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09107         extendedUnlock(source, this);
09108 
09109         return true;
09110     }
09111 #endif
09112 
09113     return false;
09114 }
09115 
09116 bool MMSFBSurface::stretchBlitARGBtoARGB_BLEND_COLORALPHA(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
09117                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
09118                                     int dx, int dy, int dw, int dh,
09119                                     bool antialiasing) {
09120 #ifdef __HAVE_PF_ARGB__
09121     MMSFBSurfacePlanes dst_planes;
09122 
09123     if (extendedLock(source, src_planes, this, &dst_planes)) {
09124         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09125         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09126         MMSFBPERF_START_MEASURING;
09127             mmsfb_stretchblit_blend_coloralpha_argb_to_argb(
09128                     src_planes, src_height,
09129                     sx, sy, sw, sh,
09130                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
09131                     dx, dy, dw, dh,
09132                     this->config.color.a);
09133         MMSFBPERF_STOP_MEASURING_STRETCHBLIT(this, src_pixelformat, sw, sh, dw, dh);
09134         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09135         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09136         extendedUnlock(source, this);
09137 
09138         return true;
09139     }
09140 #endif
09141 
09142     return false;
09143 }
09144 
09145 bool MMSFBSurface::stretchBlitARGBtoRGB32_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
09146                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
09147                                     int dx, int dy, int dw, int dh,
09148                                     bool antialiasing) {
09149 #ifdef __HAVE_PF_ARGB__
09150 #ifdef __HAVE_PF_RGB32__
09151     MMSFBSurfacePlanes dst_planes;
09152 
09153     if (extendedLock(source, src_planes, this, &dst_planes)) {
09154         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09155         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09156         MMSFBPERF_START_MEASURING;
09157             mmsfb_stretchblit_blend_argb_to_rgb32(
09158                     src_planes, src_height,
09159                     sx, sy, sw, sh,
09160                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
09161                     dx, dy, dw, dh);
09162         MMSFBPERF_STOP_MEASURING_STRETCHBLIT(this, src_pixelformat, sw, sh, dw, dh);
09163         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09164         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09165         extendedUnlock(source, this);
09166 
09167         return true;
09168     }
09169 #endif
09170 #endif
09171 
09172     return false;
09173 }
09174 
09175 bool MMSFBSurface::stretchBlitRGB32toRGB32(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
09176                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
09177                                     int dx, int dy, int dw, int dh,
09178                                     bool antialiasing) {
09179 #ifdef __HAVE_PF_RGB32__
09180     MMSFBSurfacePlanes dst_planes;
09181 
09182     if (extendedLock(source, src_planes, this, &dst_planes)) {
09183         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09184         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09185         MMSFBPERF_START_MEASURING;
09186             mmsfb_stretchblit_rgb32_to_rgb32(
09187                     src_planes, src_height,
09188                     sx, sy, sw, sh,
09189                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
09190                     dx, dy, dw, dh,
09191                     antialiasing);
09192         MMSFBPERF_STOP_MEASURING_STRETCHBLIT(this, src_pixelformat, sw, sh, dw, dh);
09193         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09194         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09195         extendedUnlock(source, this);
09196 
09197         return true;
09198     }
09199 #endif
09200 
09201     return false;
09202 }
09203 
09204 bool MMSFBSurface::stretchBlitRGB24toARGB(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
09205                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
09206                                     int dx, int dy, int dw, int dh,
09207                                     bool antialiasing) {
09208 #ifdef __HAVE_PF_RGB24__
09209 #ifdef __HAVE_PF_ARGB__
09210     MMSFBSurfacePlanes dst_planes;
09211 
09212     if (extendedLock(source, src_planes, this, &dst_planes)) {
09213         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09214         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09215         MMSFBPERF_START_MEASURING;
09216             mmsfb_stretchblit_rgb24_to_argb(
09217                     src_planes, src_height,
09218                     sx, sy, sw, sh,
09219                     (unsigned int *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
09220                     dx, dy, dw, dh,
09221                     antialiasing);
09222         MMSFBPERF_STOP_MEASURING_STRETCHBLIT(this, src_pixelformat, sw, sh, dw, dh);
09223         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09224         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09225         extendedUnlock(source, this);
09226 
09227         return true;
09228     }
09229 #endif
09230 #endif
09231 
09232     return false;
09233 }
09234 
09235 bool MMSFBSurface::stretchBlitRGB24toRGB32(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
09236                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
09237                                     int dx, int dy, int dw, int dh,
09238                                     bool antialiasing) {
09239 #ifdef __HAVE_PF_RGB24__
09240 #ifdef __HAVE_PF_RGB32__
09241     MMSFBSurfacePlanes dst_planes;
09242 
09243     if (extendedLock(source, src_planes, this, &dst_planes)) {
09244         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09245         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09246         MMSFBPERF_START_MEASURING;
09247             mmsfb_stretchblit_rgb24_to_rgb32(
09248                     src_planes, src_height,
09249                     sx, sy, sw, sh,
09250                     (unsigned int *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
09251                     dx, dy, dw, dh,
09252                     antialiasing);
09253         MMSFBPERF_STOP_MEASURING_STRETCHBLIT(this, src_pixelformat, sw, sh, dw, dh);
09254         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09255         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09256         extendedUnlock(source, this);
09257 
09258         return true;
09259     }
09260 #endif
09261 #endif
09262 
09263     return false;
09264 }
09265 
09266 
09267 bool MMSFBSurface::stretchBlitAiRGBtoAiRGB(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
09268                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
09269                                     int dx, int dy, int dw, int dh,
09270                                     bool antialiasing) {
09271 #ifdef __HAVE_PF_AiRGB__
09272     MMSFBSurfacePlanes dst_planes;
09273 
09274     if (extendedLock(source, src_planes, this, &dst_planes)) {
09275         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09276         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09277         MMSFBPERF_START_MEASURING;
09278             mmsfb_stretchblit_airgb_to_airgb(
09279                     src_planes, src_height,
09280                     sx, sy, sw, sh,
09281                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
09282                     dx, dy, dw, dh,
09283                     antialiasing);
09284         MMSFBPERF_STOP_MEASURING_STRETCHBLIT(this, src_pixelformat, sw, sh, dw, dh);
09285         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09286         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09287         extendedUnlock(source, this);
09288 
09289         return true;
09290     }
09291 #endif
09292 
09293     return false;
09294 }
09295 
09296 bool MMSFBSurface::stretchBlitAiRGBtoAiRGB_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
09297                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
09298                                     int dx, int dy, int dw, int dh,
09299                                     bool antialiasing) {
09300 #ifdef __HAVE_PF_AiRGB__
09301     MMSFBSurfacePlanes dst_planes;
09302 
09303     if (extendedLock(source, src_planes, this, &dst_planes)) {
09304         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09305         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09306         MMSFBPERF_START_MEASURING;
09307             mmsfb_stretchblit_blend_airgb_to_airgb(
09308                     src_planes, src_height,
09309                     sx, sy, sw, sh,
09310                     (unsigned int *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
09311                     dx, dy, dw, dh);
09312         MMSFBPERF_STOP_MEASURING_STRETCHBLIT(this, src_pixelformat, sw, sh, dw, dh);
09313         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09314         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09315         extendedUnlock(source, this);
09316 
09317         return true;
09318     }
09319 #endif
09320 
09321     return false;
09322 }
09323 
09324 bool MMSFBSurface::stretchBlitAiRGBtoAiRGB_BLEND_COLORALPHA(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
09325                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
09326                                     int dx, int dy, int dw, int dh,
09327                                     bool antialiasing) {
09328 #ifdef __HAVE_PF_AiRGB__
09329     MMSFBSurfacePlanes dst_planes;
09330 
09331     if (extendedLock(source, src_planes, this, &dst_planes)) {
09332         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09333         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09334         MMSFBPERF_START_MEASURING;
09335             mmsfb_stretchblit_blend_coloralpha_airgb_to_airgb(
09336                     src_planes, src_height,
09337                     sx, sy, sw, sh,
09338                     (unsigned int *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
09339                     dx, dy, dw, dh,
09340                     this->config.color.a);
09341         MMSFBPERF_STOP_MEASURING_STRETCHBLIT(this, src_pixelformat, sw, sh, dw, dh);
09342         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09343         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09344         extendedUnlock(source, this);
09345 
09346         return true;
09347     }
09348 #endif
09349 
09350     return false;
09351 }
09352 
09353 bool MMSFBSurface::stretchBlitAYUVtoAYUV(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
09354                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
09355                                     int dx, int dy, int dw, int dh,
09356                                     bool antialiasing) {
09357 #ifdef __HAVE_PF_AYUV__
09358     MMSFBSurfacePlanes dst_planes;
09359 
09360     if (extendedLock(source, src_planes, this, &dst_planes)) {
09361         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09362         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09363         MMSFBPERF_START_MEASURING;
09364             mmsfb_stretchblit_ayuv_to_ayuv(
09365                     src_planes, src_height,
09366                     sx, sy, sw, sh,
09367                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
09368                     dx, dy, dw, dh,
09369                     antialiasing);
09370         MMSFBPERF_STOP_MEASURING_STRETCHBLIT(this, src_pixelformat, sw, sh, dw, dh);
09371         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09372         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09373         extendedUnlock(source, this);
09374 
09375         return true;
09376     }
09377 #endif
09378 
09379     return false;
09380 }
09381 
09382 bool MMSFBSurface::stretchBlitAYUVtoAYUV_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
09383                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
09384                                     int dx, int dy, int dw, int dh,
09385                                     bool antialiasing) {
09386 #ifdef __HAVE_PF_AYUV__
09387     MMSFBSurfacePlanes dst_planes;
09388 
09389     if (extendedLock(source, src_planes, this, &dst_planes)) {
09390         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09391         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09392         MMSFBPERF_START_MEASURING;
09393             mmsfb_stretchblit_blend_ayuv_to_ayuv(
09394                     src_planes, src_height,
09395                     sx, sy, sw, sh,
09396                     (unsigned int *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
09397                     dx, dy, dw, dh);
09398         MMSFBPERF_STOP_MEASURING_STRETCHBLIT(this, src_pixelformat, sw, sh, dw, dh);
09399         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09400         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09401         extendedUnlock(source, this);
09402 
09403         return true;
09404     }
09405 #endif
09406 
09407     return false;
09408 }
09409 
09410 bool MMSFBSurface::stretchBlitAYUVtoAYUV_BLEND_COLORALPHA(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
09411                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
09412                                     int dx, int dy, int dw, int dh,
09413                                     bool antialiasing) {
09414 #ifdef __HAVE_PF_AYUV__
09415     MMSFBSurfacePlanes dst_planes;
09416 
09417     if (extendedLock(source, src_planes, this, &dst_planes)) {
09418         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09419         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09420         MMSFBPERF_START_MEASURING;
09421             mmsfb_stretchblit_blend_coloralpha_ayuv_to_ayuv(
09422                     src_planes, src_height,
09423                     sx, sy, sw, sh,
09424                     (unsigned int *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
09425                     dx, dy, dw, dh,
09426                     this->config.color.a);
09427         MMSFBPERF_STOP_MEASURING_STRETCHBLIT(this, src_pixelformat, sw, sh, dw, dh);
09428         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09429         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09430         extendedUnlock(source, this);
09431 
09432         return true;
09433     }
09434 #endif
09435 
09436     return false;
09437 }
09438 
09439 bool MMSFBSurface::stretchBlitYV12toYV12(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
09440                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
09441                                     int dx, int dy, int dw, int dh,
09442                                     bool antialiasing) {
09443 #ifdef __HAVE_PF_YV12__
09444     MMSFBSurfacePlanes dst_planes;
09445 
09446     if (extendedLock(source, src_planes, this, &dst_planes)) {
09447         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09448         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09449         MMSFBPERF_START_MEASURING;
09450             mmsfb_stretchblit_yv12_to_yv12(
09451                     src_planes, src_height,
09452                     sx, sy, sw, sh,
09453                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
09454                     dx, dy, dw, dh,
09455                     antialiasing);
09456         MMSFBPERF_STOP_MEASURING_STRETCHBLIT(this, src_pixelformat, sw, sh, dw, dh);
09457         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09458         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09459         extendedUnlock(source, this);
09460         return true;
09461     }
09462 #endif
09463 
09464     return false;
09465 }
09466 
09467 bool MMSFBSurface::stretchBlitI420toYV12(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
09468                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
09469                                     int dx, int dy, int dw, int dh,
09470                                     bool antialiasing) {
09471 #ifdef __HAVE_PF_I420__
09472 #ifdef __HAVE_PF_YV12__
09473     MMSFBSurfacePlanes dst_planes;
09474 
09475     if (extendedLock(source, src_planes, this, &dst_planes)) {
09476         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09477         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09478         MMSFBPERF_START_MEASURING;
09479             mmsfb_stretchblit_i420_to_yv12(
09480                     src_planes, src_height,
09481                     sx, sy, sw, sh,
09482                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
09483                     dx, dy, dw, dh,
09484                     antialiasing);
09485         MMSFBPERF_STOP_MEASURING_STRETCHBLIT(this, src_pixelformat, sw, sh, dw, dh);
09486         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09487         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09488         extendedUnlock(source, this);
09489         return true;
09490     }
09491 #endif
09492 #endif
09493 
09494     return false;
09495 }
09496 
09497 bool MMSFBSurface::stretchBlitYUY2toYV12(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
09498                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
09499                                     int dx, int dy, int dw, int dh,
09500                                     bool antialiasing) {
09501 #ifdef __HAVE_PF_YUY2__
09502 #ifdef __HAVE_PF_YV12__
09503     MMSFBSurfacePlanes dst_planes;
09504 
09505     if (extendedLock(source, src_planes, this, &dst_planes)) {
09506         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09507         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09508         MMSFBPERF_START_MEASURING;
09509             mmsfb_stretchblit_yuy2_to_yv12(
09510                     src_planes, src_height,
09511                     sx, sy, sw, sh,
09512                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
09513                     dx, dy, dw, dh,
09514                     antialiasing);
09515         MMSFBPERF_STOP_MEASURING_STRETCHBLIT(this, src_pixelformat, sw, sh, dw, dh);
09516         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09517         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09518         extendedUnlock(source, this);
09519         return true;
09520     }
09521 #endif
09522 #endif
09523 
09524     return false;
09525 }
09526 
09527 
09528 bool MMSFBSurface::stretchBlitARGB4444toARGB4444_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
09529                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
09530                                     int dx, int dy, int dw, int dh,
09531                                     bool antialiasing) {
09532 #ifdef __HAVE_PF_ARGB4444__
09533     MMSFBSurfacePlanes dst_planes;
09534 
09535     if (extendedLock(source, src_planes, this, &dst_planes)) {
09536         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09537         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09538         MMSFBPERF_START_MEASURING;
09539             mmsfb_stretchblit_blend_argb4444_to_argb4444(
09540                     src_planes, src_height,
09541                     sx, sy, sw, sh,
09542                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
09543                     dx, dy, dw, dh);
09544         MMSFBPERF_STOP_MEASURING_STRETCHBLIT(this, src_pixelformat, sw, sh, dw, dh);
09545         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09546         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09547         extendedUnlock(source, this);
09548 
09549         return true;
09550     }
09551 #endif
09552 
09553     return false;
09554 }
09555 
09556 
09557 bool MMSFBSurface::stretchBlitARGB4444toARGB4444_BLEND_COLORALPHA(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
09558                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
09559                                     int dx, int dy, int dw, int dh,
09560                                     bool antialiasing) {
09561 #ifdef __HAVE_PF_ARGB4444__
09562     MMSFBSurfacePlanes dst_planes;
09563 
09564     if (extendedLock(source, src_planes, this, &dst_planes)) {
09565         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09566         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09567         MMSFBPERF_START_MEASURING;
09568             mmsfb_stretchblit_blend_coloralpha_argb4444_to_argb4444(
09569                     src_planes, src_height,
09570                     sx, sy, sw, sh,
09571                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
09572                     dx, dy, dw, dh,
09573                     this->config.color.a);
09574         MMSFBPERF_STOP_MEASURING_STRETCHBLIT(this, src_pixelformat, sw, sh, dw, dh);
09575         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09576         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09577         extendedUnlock(source, this);
09578 
09579         return true;
09580     }
09581 #endif
09582 
09583     return false;
09584 }
09585 
09586 bool MMSFBSurface::stretchBlitRGB16toRGB16(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
09587                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
09588                                     int dx, int dy, int dw, int dh,
09589                                     bool antialiasing) {
09590 #ifdef __HAVE_PF_RGB16__
09591     MMSFBSurfacePlanes dst_planes;
09592 
09593     if (extendedLock(source, src_planes, this, &dst_planes)) {
09594         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09595         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09596         MMSFBPERF_START_MEASURING;
09597             mmsfb_stretchblit_rgb16_to_rgb16(
09598                     src_planes, src_height,
09599                     sx, sy, sw, sh,
09600                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
09601                     dx, dy, dw, dh,
09602                     antialiasing);
09603         MMSFBPERF_STOP_MEASURING_STRETCHBLIT(this, src_pixelformat, sw, sh, dw, dh);
09604         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09605         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09606         extendedUnlock(source, this);
09607 
09608         return true;
09609     }
09610 #endif
09611 
09612     return false;
09613 }
09614 
09615 
09616 bool MMSFBSurface::fillRectangleARGB(int dst_height, int dx, int dy, int dw, int dh, MMSFBColor &color) {
09617 #ifdef __HAVE_PF_ARGB__
09618     MMSFBSurfacePlanes dst_planes;
09619 
09620     if (extendedLock(NULL, NULL, this, &dst_planes)) {
09621         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09622         MMSFBPERF_START_MEASURING;
09623             mmsfb_fillrectangle_argb(&dst_planes, dst_height,
09624                                      dx, dy, dw, dh, color);
09625         MMSFBPERF_STOP_MEASURING_FILLRECT(this, dw, dh);
09626         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09627         extendedUnlock(NULL, this, &dst_planes);
09628         return true;
09629     }
09630 #endif
09631 
09632     return false;
09633 }
09634 
09635 bool MMSFBSurface::fillRectangleARGB_BLEND(int dst_height, int dx, int dy, int dw, int dh, MMSFBColor &color) {
09636 #ifdef __HAVE_PF_ARGB__
09637     MMSFBSurfacePlanes dst_planes;
09638 
09639     if (extendedLock(NULL, NULL, this, &dst_planes)) {
09640         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09641         MMSFBPERF_START_MEASURING;
09642             mmsfb_fillrectangle_blend_argb(&dst_planes, dst_height,
09643                                            dx, dy, dw, dh, color);
09644         MMSFBPERF_STOP_MEASURING_FILLRECT(this, dw, dh);
09645         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09646         extendedUnlock(NULL, this, &dst_planes);
09647         return true;
09648     }
09649 #endif
09650 
09651     return false;
09652 }
09653 
09654 bool MMSFBSurface::fillRectangleAYUV(int dst_height, int dx, int dy, int dw, int dh, MMSFBColor &color) {
09655 #ifdef __HAVE_PF_AYUV__
09656     MMSFBSurfacePlanes dst_planes;
09657 
09658     if (extendedLock(NULL, NULL, this, &dst_planes)) {
09659         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09660         MMSFBPERF_START_MEASURING;
09661             mmsfb_fillrectangle_ayuv(&dst_planes, dst_height,
09662                                      dx, dy, dw, dh, color);
09663         MMSFBPERF_STOP_MEASURING_FILLRECT(this, dw, dh);
09664         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09665         extendedUnlock(NULL, this);
09666         return true;
09667     }
09668 #endif
09669 
09670     return false;
09671 }
09672 
09673 bool MMSFBSurface::fillRectangleAYUV_BLEND(int dst_height, int dx, int dy, int dw, int dh, MMSFBColor &color) {
09674 #ifdef __HAVE_PF_AYUV__
09675     MMSFBSurfacePlanes dst_planes;
09676 
09677     if (extendedLock(NULL, NULL, this, &dst_planes)) {
09678         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09679         MMSFBPERF_START_MEASURING;
09680             mmsfb_fillrectangle_blend_ayuv(&dst_planes, dst_height,
09681                                            dx, dy, dw, dh, color);
09682         MMSFBPERF_STOP_MEASURING_FILLRECT(this, dw, dh);
09683         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09684         extendedUnlock(NULL, this);
09685         return true;
09686     }
09687 #endif
09688 
09689     return false;
09690 }
09691 
09692 bool MMSFBSurface::fillRectangleRGB32(int dst_height, int dx, int dy, int dw, int dh, MMSFBColor &color) {
09693 #ifdef __HAVE_PF_RGB32__
09694     MMSFBSurfacePlanes dst_planes;
09695 
09696     if (extendedLock(NULL, NULL, this, &dst_planes)) {
09697         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09698         MMSFBPERF_START_MEASURING;
09699             mmsfb_fillrectangle_rgb32(&dst_planes, dst_height,
09700                                       dx, dy, dw, dh, color);
09701         MMSFBPERF_STOP_MEASURING_FILLRECT(this, dw, dh);
09702         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09703         extendedUnlock(NULL, this);
09704         return true;
09705     }
09706 #endif
09707 
09708     return false;
09709 }
09710 
09711 bool MMSFBSurface::fillRectangleRGB24(int dst_height, int dx, int dy, int dw, int dh, MMSFBColor &color) {
09712 #ifdef __HAVE_PF_RGB24__
09713     MMSFBSurfacePlanes dst_planes;
09714 
09715     if (extendedLock(NULL, NULL, this, &dst_planes)) {
09716         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09717         MMSFBPERF_START_MEASURING;
09718             mmsfb_fillrectangle_rgb24(&dst_planes, dst_height,
09719                                       dx, dy, dw, dh, color);
09720         MMSFBPERF_STOP_MEASURING_FILLRECT(this, dw, dh);
09721         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09722         extendedUnlock(NULL, this);
09723         return true;
09724     }
09725 #endif
09726 
09727     return false;
09728 }
09729 
09730 bool MMSFBSurface::fillRectangleRGB16(int dst_height, int dx, int dy, int dw, int dh, MMSFBColor &color) {
09731 #ifdef __HAVE_PF_RGB16__
09732     MMSFBSurfacePlanes dst_planes;
09733 
09734     if (extendedLock(NULL, NULL, this, &dst_planes)) {
09735         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09736         MMSFBPERF_START_MEASURING;
09737             mmsfb_fillrectangle_rgb16(&dst_planes, dst_height,
09738                                      dx, dy, dw, dh, color);
09739         MMSFBPERF_STOP_MEASURING_FILLRECT(this, dw, dh);
09740         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09741         extendedUnlock(NULL, this, &dst_planes);
09742         return true;
09743     }
09744 #endif
09745 
09746     return false;
09747 }
09748 
09749 bool MMSFBSurface::fillRectangleRGB16_BLEND(int dst_height, int dx, int dy, int dw, int dh, MMSFBColor &color) {
09750 #ifdef __HAVE_PF_RGB16__
09751     MMSFBSurfacePlanes dst_planes;
09752 
09753     if (extendedLock(NULL, NULL, this, &dst_planes)) {
09754         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09755         MMSFBPERF_START_MEASURING;
09756             mmsfb_fillrectangle_blend_rgb16(&dst_planes, dst_height,
09757                                            dx, dy, dw, dh, color);
09758         MMSFBPERF_STOP_MEASURING_FILLRECT(this, dw, dh);
09759         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09760         extendedUnlock(NULL, this, &dst_planes);
09761         return true;
09762     }
09763 #endif
09764 
09765     return false;
09766 }
09767 
09768 bool MMSFBSurface::fillRectangleYV12(int dst_height, int dx, int dy, int dw, int dh, MMSFBColor &color) {
09769 #ifdef __HAVE_PF_YV12__
09770     MMSFBSurfacePlanes dst_planes;
09771 
09772     if (extendedLock(NULL, NULL, this, &dst_planes)) {
09773         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09774         MMSFBPERF_START_MEASURING;
09775             mmsfb_fillrectangle_yv12(&dst_planes, dst_height,
09776                                      dx, dy, dw, dh, color);
09777         MMSFBPERF_STOP_MEASURING_FILLRECT(this, dw, dh);
09778         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09779         extendedUnlock(NULL, this);
09780         return true;
09781     }
09782 #endif
09783 
09784     return false;
09785 }
09786 
09787 bool MMSFBSurface::fillRectangleI420(int dst_height, int dx, int dy, int dw, int dh, MMSFBColor &color) {
09788 #ifdef __HAVE_PF_I420__
09789     MMSFBSurfacePlanes dst_planes;
09790 
09791     if (extendedLock(NULL, NULL, this, &dst_planes)) {
09792         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09793         MMSFBPERF_START_MEASURING;
09794             mmsfb_fillrectangle_i420(&dst_planes, dst_height,
09795                                      dx, dy, dw, dh, color);
09796         MMSFBPERF_STOP_MEASURING_FILLRECT(this, dw, dh);
09797         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09798         extendedUnlock(NULL, this);
09799         return true;
09800     }
09801 #endif
09802 
09803     return false;
09804 }
09805 
09806 bool MMSFBSurface::fillRectangleYUY2(int dst_height, int dx, int dy, int dw, int dh, MMSFBColor &color) {
09807 #ifdef __HAVE_PF_YUY2__
09808     MMSFBSurfacePlanes dst_planes;
09809 
09810     if (extendedLock(NULL, NULL, this, &dst_planes)) {
09811         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09812         MMSFBPERF_START_MEASURING;
09813             mmsfb_fillrectangle_yuy2(&dst_planes, dst_height,
09814                                      dx, dy, dw, dh, color);
09815         MMSFBPERF_STOP_MEASURING_FILLRECT(this, dw, dh);
09816         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09817         extendedUnlock(NULL, this);
09818         return true;
09819     }
09820 #endif
09821 
09822     return false;
09823 }
09824 
09825 bool MMSFBSurface::fillRectangleARGB3565(int dst_height, int dx, int dy, int dw, int dh, MMSFBColor &color) {
09826 #ifdef __HAVE_PF_ARGB3565__
09827     MMSFBSurfacePlanes dst_planes;
09828 
09829     if (extendedLock(NULL, NULL, this, &dst_planes)) {
09830         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09831         MMSFBPERF_START_MEASURING;
09832             mmsfb_fillrectangle_argb3565(&dst_planes, dst_height,
09833                                      dx, dy, dw, dh, color);
09834         MMSFBPERF_STOP_MEASURING_FILLRECT(this, dw, dh);
09835         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09836         extendedUnlock(NULL, this);
09837         return true;
09838     }
09839 #endif
09840 
09841     return false;
09842 }
09843 
09844 bool MMSFBSurface::fillRectangleARGB4444(int dst_height, int dx, int dy, int dw, int dh, MMSFBColor &color) {
09845 #ifdef __HAVE_PF_ARGB4444__
09846     MMSFBSurfacePlanes dst_planes;
09847 
09848     if (extendedLock(NULL, NULL, this, &dst_planes)) {
09849         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09850         MMSFBPERF_START_MEASURING;
09851             mmsfb_fillrectangle_argb4444(&dst_planes, dst_height,
09852                                      dx, dy, dw, dh, color);
09853         MMSFBPERF_STOP_MEASURING_FILLRECT(this, dw, dh);
09854         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09855         extendedUnlock(NULL, this);
09856         return true;
09857     }
09858 #endif
09859 
09860     return false;
09861 }
09862 
09863 bool MMSFBSurface::fillRectangleARGB4444_BLEND(int dst_height, int dx, int dy, int dw, int dh, MMSFBColor &color) {
09864 #ifdef __HAVE_PF_ARGB4444__
09865     MMSFBSurfacePlanes dst_planes;
09866 
09867     if (extendedLock(NULL, NULL, this, &dst_planes)) {
09868         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09869         MMSFBPERF_START_MEASURING;
09870             mmsfb_fillrectangle_blend_argb4444(&dst_planes, dst_height,
09871                                      dx, dy, dw, dh, color);
09872         MMSFBPERF_STOP_MEASURING_FILLRECT(this, dw, dh);
09873         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09874         extendedUnlock(NULL, this);
09875         return true;
09876     }
09877 #endif
09878 
09879     return false;
09880 }
09881 
09882 bool MMSFBSurface::fillRectangleBGR24(int dst_height, int dx, int dy, int dw, int dh, MMSFBColor &color) {
09883 #ifdef __HAVE_PF_BGR24__
09884     MMSFBSurfacePlanes dst_planes;
09885 
09886     if (extendedLock(NULL, NULL, this, &dst_planes)) {
09887         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09888         MMSFBPERF_START_MEASURING;
09889             mmsfb_fillrectangle_bgr24(&dst_planes, dst_height,
09890                                      dx, dy, dw, dh, color);
09891         MMSFBPERF_STOP_MEASURING_FILLRECT(this, dw, dh);
09892         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09893         extendedUnlock(NULL, this);
09894         return true;
09895     }
09896 #endif
09897 
09898     return false;
09899 }
09900 
09901 bool MMSFBSurface::fillRectangleBGR555(int dst_height, int dx, int dy, int dw, int dh, MMSFBColor &color) {
09902 #ifdef __HAVE_PF_BGR555__
09903     MMSFBSurfacePlanes dst_planes;
09904 
09905     if (extendedLock(NULL, NULL, this, &dst_planes)) {
09906         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09907         MMSFBPERF_START_MEASURING;
09908             mmsfb_fillrectangle_bgr555(&dst_planes, dst_height,
09909                                      dx, dy, dw, dh, color);
09910         MMSFBPERF_STOP_MEASURING_FILLRECT(this, dw, dh);
09911         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09912         extendedUnlock(NULL, this);
09913         return true;
09914     }
09915 #endif
09916 
09917     return false;
09918 }
09919 
09920 
09921 
09922 
09923 
09924 
09925 
09926 
09927 

Generated by doxygen