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-2012 BerLinux Solutions GmbH                       *
00009  *                                                                         *
00010  *   Authors:                                                              *
00011  *      Stefan Schwarzer   <stefan.schwarzer@diskohq.org>,                 *
00012  *      Matthias Hardt     <matthias.hardt@diskohq.org>,                   *
00013  *      Jens Schneider     <jens.schneider@diskohq.org>,                   *
00014  *      Guido Madaus       <guido.madaus@diskohq.org>,                     *
00015  *      Patrick Helterhoff <patrick.helterhoff@diskohq.org>,               *
00016  *      René Bählkow       <rene.baehlkow@diskohq.org>                     *
00017  *                                                                         *
00018  *   This library is free software; you can redistribute it and/or         *
00019  *   modify it under the terms of the GNU Lesser General Public            *
00020  *   License version 2.1 as published by the Free Software Foundation.     *
00021  *                                                                         *
00022  *   This library is distributed in the hope that it will be useful,       *
00023  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00024  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00025  *   Lesser General Public License for more details.                       *
00026  *                                                                         *
00027  *   You should have received a copy of the GNU Lesser General Public      *
00028  *   License along with this library; if not, write to the                 *
00029  *   Free Software Foundation, Inc.,                                       *
00030  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
00031  **************************************************************************/
00032 
00033 #include "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 #ifdef __HAVE_FBDEV__
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 #ifdef __HAVE_FBDEV__
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) {
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 #ifdef __HAVE_FBDEV__
05189     MMSFBSurfaceBuffer *sb = this->config.surface_buffer;
05190 
05191     if (in_data_len >> 8) {
05192         MMSFBPERF_START_MEASURING;
05193 
05194         // vsync
05195         mmsfb->mmsfbdev->waitForVSync();
05196 
05197         MMSFBPERF_STOP_MEASURING_VSYNC(sb->mmsfbdev_surface);
05198     }
05199 
05200     MMSFBPERF_START_MEASURING;
05201 
05202     // swap display
05203     mmsfb->mmsfbdev->panDisplay(in_data_len & 0xff, sb->buffers[0].ptr);
05204 
05205     MMSFBPERF_STOP_MEASURING_SWAPDISPLAY(sb->mmsfbdev_surface);
05206 #endif
05207 }
05208 
05209 void MMSFBSurface::swapDisplay(bool vsync) {
05210 #ifdef __HAVE_FBDEV__
05211     MMSFBSurfaceBuffer *sb = this->config.surface_buffer;
05212 
05213     if (sb->mmsfbdev_surface != this)
05214         return;
05215 
05216     // surface is the fb layer surface
05217     if (sb->numbuffers > 2) {
05218         // more than two buffers (e.g. TRIPLE buffering), so we should use non-blocked panning
05219         if (!this->fbdev_ts) {
05220             // init thread server for display panning
05221             this->fbdev_ts = new MMSThreadServer(100, "MMSThreadServer4MMSFBSurface", false);
05222             this->fbdev_ts->onProcessData.connect(sigc::mem_fun(this,&MMSFBSurface::processSwapDisplay));
05223             this->fbdev_ts->start();
05224         }
05225 
05226         // hard disable vsync
05227         // reason: difference between current and next buffer is minimal and both buffers are not the next write buffer
05228         // TODO: this can be hw dependent, then we have to change the code
05229         vsync = false;
05230 
05231         // trigger panning and return immediately
05232         this->fbdev_ts->trigger(NULL, sb->currbuffer_read | ((vsync)?0x100:0));
05233     }
05234     else
05235     if (sb->numbuffers == 2) {
05236         // two buffers (BACKVIDEO)
05237         if (vsync) {
05238             MMSFBPERF_START_MEASURING;
05239 
05240             // vsync
05241             mmsfb->mmsfbdev->waitForVSync();
05242 
05243             MMSFBPERF_STOP_MEASURING_VSYNC(sb->mmsfbdev_surface);
05244         }
05245 
05246         MMSFBPERF_START_MEASURING;
05247 
05248         // swap display
05249         mmsfb->mmsfbdev->panDisplay(sb->currbuffer_read, sb->buffers[0].ptr);
05250 
05251         MMSFBPERF_STOP_MEASURING_SWAPDISPLAY(sb->mmsfbdev_surface);
05252     }
05253 #endif
05254 }
05255 
05256 
05257 bool MMSFBSurface::flip(MMSFBRegion *region) {
05258 
05259     // check if initialized
05260     INITCHECK;
05261 
05262     // finalize previous clear
05263     finClear();
05264 
05265     if (this->allocated_by == MMSFBSurfaceAllocatedBy_dfb) {
05266 #ifdef  __HAVE_DIRECTFB__
05267         if (region)
05268              D_DEBUG_AT( MMS_Surface, "flip( %d,%d - %dx%d ) <- %dx%d\n",
05269                          DFB_RECTANGLE_VALS_FROM_REGION(region), this->config.w, this->config.h );
05270         else
05271              D_DEBUG_AT( MMS_Surface, "flip( %d,%d - %dx%d ) <- %dx%d\n",
05272                          0, 0, this->config.w, this->config.h, this->config.w, this->config.h );
05273 
05274         MMSFB_TRACE();
05275 
05276         DFBResult   dfbres;
05277 
05278 #ifdef USE_DFB_WINMAN
05279 
05280         // flip
05281         if ((dfbres=this->dfb_surface->Flip(this->dfb_surface, region, this->flipflags)) != DFB_OK) {
05282             MMSFB_SetError(dfbres, "IDirectFBSurface::Flip() failed");
05283 
05284             return false;
05285         }
05286 
05287 #endif
05288 
05289 #ifdef USE_MMSFB_WINMAN
05290 
05291         // flip
05292         if (!this->is_sub_surface) {
05293             if ((dfbres=this->dfb_surface->Flip(this->dfb_surface, (DFBRegion*)region, getDFBSurfaceFlipFlagsFromMMSFBFlipFlags(this->flipflags))) != DFB_OK) {
05294                 MMSFB_SetError(dfbres, "IDirectFBSurface::Flip() failed");
05295 
05296                 return false;
05297             }
05298         }
05299         else {
05300 #ifndef USE_DFB_SUBSURFACE
05301             CLIPSUBSURFACE
05302 
05303             MMSFBRegion myregion;
05304             if (!region) {
05305                 myregion.x1 = 0;
05306                 myregion.y1 = 0;
05307                 myregion.x2 = this->config.w - 1;
05308                 myregion.y2 = this->config.h - 1;
05309             }
05310             else
05311                 myregion = *region;
05312 
05313             myregion.x1+=this->sub_surface_xoff;
05314             myregion.y1+=this->sub_surface_yoff;
05315             myregion.x2+=this->sub_surface_xoff;
05316             myregion.y2+=this->sub_surface_yoff;
05317 
05318             this->dfb_surface->Flip(this->dfb_surface, (DFBRegion*)&myregion, getDFBSurfaceFlipFlagsFromMMSFBFlipFlags(this->flipflags));
05319 
05320 #else
05321             this->dfb_surface->Flip(this->dfb_surface, region, getDFBSurfaceFlipFlagsFromMMSFBFlipFlags(this->flipflags));
05322 #endif
05323 
05324 #ifndef USE_DFB_SUBSURFACE
05325             UNCLIPSUBSURFACE
05326 #endif
05327         }
05328 
05329         if (this->config.iswinsurface) {
05330             // inform the window manager
05331             mmsfbwindowmanager->flipSurface(this, region);
05332         }
05333         else {
05334             if (this->is_sub_surface) {
05335                 // sub surface, use the root parent surface
05336                 if (this->root_parent->config.iswinsurface) {
05337                     // inform the window manager, use the correct region
05338                     MMSFBRegion reg;
05339                     if (region)
05340                         reg = *region;
05341                     else {
05342                         reg.x1=0;
05343                         reg.y1=0;
05344                         reg.x2=sub_surface_rect.w-1;
05345                         reg.y2=sub_surface_rect.h-1;
05346                     }
05347                     reg.x1+=this->sub_surface_xoff;
05348                     reg.y1+=this->sub_surface_yoff;
05349                     reg.x2+=this->sub_surface_xoff;
05350                     reg.y2+=this->sub_surface_yoff;
05351                     mmsfbwindowmanager->flipSurface(this->root_parent, &reg);
05352                 }
05353             }
05354         }
05355 
05356 #endif
05357 
05358         return true;
05359 #else
05360         return false;
05361 #endif
05362     }
05363     else
05364     if (this->allocated_by == MMSFBSurfaceAllocatedBy_ogl) {
05365 #ifdef  __HAVE_OPENGL__
05366         if (this->config.surface_buffer->numbuffers > 1) {
05367             // currently we work with fbo frontbuffers only, ogl flips will only supported via glXSwapBuffers()
05368 
05369             //TODO...
05370         }
05371 
05372         if (!this->config.surface_buffer->ogl_fbo) {
05373             // this is the primary fbo, flip it to the xwindow
05374             // note: there is no chance to flip a region with glXSwapBuffers!!!
05375             mmsfb->bei->swap();
05376         }
05377 
05378         if (this->config.iswinsurface) {
05379             // inform the window manager
05380 #ifdef  __HAVE_GLX__
05381             mmsfbwindowmanager->flipSurface(NULL);
05382 #else
05383             mmsfbwindowmanager->flipSurface(this, region);
05384 #endif
05385         }
05386         else {
05387             if (this->is_sub_surface) {
05388                 // sub surface, use the root parent surface
05389                 if (this->root_parent->config.iswinsurface) {
05390 
05391                     // inform the window manager, use the correct region
05392 #ifdef  __HAVE_GLX__
05393                     mmsfbwindowmanager->flipSurface(NULL);
05394 #else
05395                     MMSFBRegion reg;
05396                     if (region)
05397                         reg = *region;
05398                     else {
05399                         reg.x1=0;
05400                         reg.y1=0;
05401                         reg.x2=sub_surface_rect.w-1;
05402                         reg.y2=sub_surface_rect.h-1;
05403                     }
05404                     reg.x1+=this->sub_surface_xoff;
05405                     reg.y1+=this->sub_surface_yoff;
05406                     reg.x2+=this->sub_surface_xoff;
05407                     reg.y2+=this->sub_surface_yoff;
05408                     mmsfbwindowmanager->flipSurface(this->root_parent, &reg);
05409 #endif
05410                 }
05411             }
05412         }
05413 
05414 
05415 
05416 
05417         return true;
05418 #else
05419         return false;
05420 #endif
05421     }
05422     else {
05423         // flip my own surfaces
05424         MMSFBSurfaceBuffer *sb = this->config.surface_buffer;
05425         if (sb->numbuffers > 1) {
05426             // flip is only needed, if we have at least one backbuffer
05427             if (!this->is_sub_surface) {
05428                 // not a subsurface
05429                 if (!region) {
05430                     // flip my buffers without blitting
05431                     sb->currbuffer_read++;
05432                     if (sb->currbuffer_read >= sb->numbuffers)
05433                         sb->currbuffer_read = 0;
05434                     sb->currbuffer_write++;
05435                     if (sb->currbuffer_write >= sb->numbuffers)
05436                         sb->currbuffer_write = 0;
05437 
05438 #ifdef __HAVE_FBDEV__
05439                     if (sb->mmsfbdev_surface == this) {
05440                         // surface is the fb layer surface, so we have to swap the display
05441                         swapDisplay(true);
05442                     }
05443 #endif
05444                 }
05445                 else {
05446                     MMSFBRectangle src_rect;
05447                     src_rect.x = region->x1;
05448                     src_rect.y = region->y1;
05449                     src_rect.w = region->x2 - region->x1 + 1;
05450                     src_rect.h = region->y2 - region->y1 + 1;
05451 
05452                     // check if region is equal to the whole surface
05453                     if   ((src_rect.x == 0) && (src_rect.y == 0)
05454                         &&(src_rect.w == this->config.w) && (src_rect.h == this->config.h)) {
05455                         // yes, flip my buffers without blitting
05456                         sb->currbuffer_read++;
05457                         if (sb->currbuffer_read >= sb->numbuffers)
05458                             sb->currbuffer_read = 0;
05459                         sb->currbuffer_write++;
05460                         if (sb->currbuffer_write >= sb->numbuffers)
05461                             sb->currbuffer_write = 0;
05462 
05463 #ifdef __HAVE_FBDEV__
05464                         if (sb->mmsfbdev_surface == this) {
05465                             // surface is the fb layer surface, so we have to swap the display
05466                             swapDisplay(true);
05467                         }
05468 #endif
05469                     }
05470                     else {
05471                         // blit region from write to read buffer of the same MMSFBSurface
05472                         MMSFBBlittingFlags savedbf = this->config.blittingflags;
05473                         this->config.blittingflags = (MMSFBBlittingFlags)MMSFB_BLIT_NOFX;
05474 
05475                         this->surface_invert_lock = true;
05476 
05477                         if (MMSFBSURFACE_READ_BUFFER(this).opaque)
05478                             MMSFBSURFACE_READ_BUFFER(this).opaque = MMSFBSURFACE_WRITE_BUFFER(this).opaque;
05479                         if (MMSFBSURFACE_READ_BUFFER(this).transparent)
05480                             MMSFBSURFACE_READ_BUFFER(this).transparent = MMSFBSURFACE_WRITE_BUFFER(this).transparent;
05481 
05482                         this->extendedAccelBlit(this, &src_rect, src_rect.x, src_rect.y, MMSFB_BLIT_NOFX);
05483 
05484                         this->surface_invert_lock = false;
05485 
05486                         this->config.blittingflags = savedbf;
05487 
05488 #ifdef __HAVE_FBDEV__
05489                         if (sb->mmsfbdev_surface == this) {
05490                             // surface is the fb layer surface
05491                             // there is no need to swapDisplay() because current read buffer (currbuffer_read) has NOT changed
05492                             if (this->flipflags & MMSFB_FLIP_FLUSH) {
05493                                 // BUT: MMSFB_FLIP_FLUSH tells us, that we have to trigger an pan event to frame buffer driver
05494                                 swapDisplay(true);
05495                             }
05496                         }
05497 #endif
05498                     }
05499                 }
05500             }
05501             else {
05502                 CLIPSUBSURFACE
05503 
05504                 MMSFBRectangle src_rect;
05505                 if (!region) {
05506                     src_rect.x = 0;
05507                     src_rect.y = 0;
05508                     src_rect.w = this->config.w;
05509                     src_rect.h = this->config.h;
05510                 }
05511                 else {
05512                     src_rect.x = region->x1;
05513                     src_rect.y = region->y1;
05514                     src_rect.w = region->x2 - region->x1 + 1;
05515                     src_rect.h = region->y2 - region->y1 + 1;
05516                 }
05517 
05518                 src_rect.x+=this->sub_surface_xoff;
05519                 src_rect.y+=this->sub_surface_yoff;
05520 
05521                 // blit region from write to read buffer of the same MMSFBSurface
05522                 MMSFBBlittingFlags savedbf = this->config.blittingflags;
05523                 this->config.blittingflags = (MMSFBBlittingFlags)MMSFB_BLIT_NOFX;
05524 
05525                 this->surface_invert_lock = true;
05526 
05527                 if (MMSFBSURFACE_READ_BUFFER(this).opaque)
05528                     MMSFBSURFACE_READ_BUFFER(this).opaque = MMSFBSURFACE_WRITE_BUFFER(this).opaque;
05529                 if (MMSFBSURFACE_READ_BUFFER(this).transparent)
05530                     MMSFBSURFACE_READ_BUFFER(this).transparent = MMSFBSURFACE_WRITE_BUFFER(this).transparent;
05531 
05532                 this->extendedAccelBlit(this, &src_rect, src_rect.x, src_rect.y, MMSFB_BLIT_NOFX);
05533 
05534                 this->surface_invert_lock = false;
05535 
05536                 this->config.blittingflags = savedbf;
05537 
05538                 UNCLIPSUBSURFACE
05539             }
05540         }
05541 
05542 #ifdef __HAVE_FBDEV__
05543         if (sb->mmsfbdev_surface) {
05544             if (sb->mmsfbdev_surface != this) {
05545                 // this surface is the backbuffer in system memory of the layer (BACKSYSTEM buffer mode)
05546 
05547                 MMSFBPERF_START_MEASURING;
05548 
05549                 // sync
05550                 mmsfb->mmsfbdev->waitForVSync();
05551 
05552                 MMSFBPERF_STOP_MEASURING_VSYNC(sb->mmsfbdev_surface);
05553 
05554                 // put the image to the framebuffer
05555                 if (!region) {
05556                     // full
05557                     sb->mmsfbdev_surface->blit(this, NULL, 0, 0);
05558                 }
05559                 else {
05560                     // a few lines
05561                     MMSFBRectangle rect;
05562                     rect.x = 0;
05563                     rect.y = region->y1;
05564                     rect.w = this->config.w;
05565                     rect.h = region->y2 - region->y1 + 1;
05566                     sb->mmsfbdev_surface->blit(this, &rect, rect.x, rect.y);
05567                 }
05568             }
05569         }
05570         else {
05571 #endif
05572 
05573 #ifdef __HAVE_XLIB__
05574         if (sb->x_image[0]) {
05575             // XSHM, put the image to the x-server
05576             if (!this->scaler) {
05577                 // no scaler defined
05578                 mmsfb->xlock.lock();
05579                 XLockDisplay(mmsfb->x_display);
05580                 if (!region) {
05581                     // put whole image
05582                     int dx = 0;
05583                     int dy = 0;
05584                     if (mmsfb->fullscreen == MMSFB_FSM_ASPECT_RATIO) {
05585                         dx = (mmsfb->display_w - this->config.w) >> 1;
05586                         dy = (mmsfb->display_h - this->config.h) >> 1;
05587                     }
05588                     if(this->layer) {
05589                         //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);
05590 
05591                         if ((mmsfb->fullscreen == MMSFB_FSM_TRUE || mmsfb->fullscreen == MMSFB_FSM_ASPECT_RATIO)) {
05592 //TODO: change the ifdef, what to do if XRenderComposite not available?
05593 #ifdef __HAVE_XV__
05594 
05595                             MMSFBPERF_START_MEASURING;
05596 
05597                             //put image to layer pixmap
05598                             XShmPutImage(mmsfb->x_display, layer->pixmap, layer->x_gc, sb->x_image[sb->currbuffer_read],
05599                                           0, 0, dx, dy,
05600                                           layer->config.w, layer->config.h, False);
05601 
05602                             double scale = (double)layer->x_window_w / layer->config.w;
05603 
05604                             // Scaling matrix
05605                             XTransform xform = {{
05606                                 { XDoubleToFixed( 1 ), XDoubleToFixed( 0 ), XDoubleToFixed(     0 ) },
05607                                 { XDoubleToFixed( 0 ), XDoubleToFixed( 1 ), XDoubleToFixed(     0 ) },
05608                                 { XDoubleToFixed( 0 ), XDoubleToFixed( 0 ), XDoubleToFixed( scale ) }
05609                             }};
05610 
05611                             XRenderSetPictureTransform( mmsfb->x_display, layer->x_pixmap_pict, &xform );
05612                             XRenderSetPictureFilter( mmsfb->x_display, layer->x_pixmap_pict, FilterBilinear, 0, 0 );
05613 
05614 
05615                             //put render image
05616                               /* copy the pixmap content using XRender */
05617                             XRenderComposite(mmsfb->x_display,
05618                                    PictOpSrc,
05619                                    layer->x_pixmap_pict,
05620                                    None,
05621                                    layer->x_window_pict,
05622                                    0, 0,
05623                                    0, 0,
05624                                    0, 0,
05625                                    layer->x_window_w, layer->x_window_h);
05626 
05627                             //XFlush(mmsfb->x_display);
05628                             XSync(mmsfb->x_display, False);
05629 
05630                             MMSFBPERF_STOP_MEASURING_XSHMPUTIMAGE(this, layer->config.w, layer->config.h);
05631 
05632 #endif
05633                         } else {
05634 
05635                             MMSFBPERF_START_MEASURING;
05636 
05637                             XShmPutImage(mmsfb->x_display, layer->x_window, layer->x_gc, sb->x_image[sb->currbuffer_read],
05638                                           0, 0, dx, dy,
05639                                           this->config.w, this->config.h, False);
05640 
05641                             //XFlush(mmsfb->x_display);
05642                             XSync(mmsfb->x_display, False);
05643 
05644                             MMSFBPERF_STOP_MEASURING_XSHMPUTIMAGE(this, this->config.w, this->config.h);
05645                         }
05646                     }
05647                 }
05648                 else {
05649                     // put only a region
05650                     MMSFBRegion myreg = *region;
05651                     if (myreg.x1 < 0) myreg.x1 = 0;
05652                     if (myreg.y1 < 0) myreg.y1 = 0;
05653                     if (myreg.x2 >= this->config.w) myreg.x2 = this->config.w - 1;
05654                     if (myreg.y2 >= this->config.h) myreg.y2 = this->config.h - 1;
05655                     if ((myreg.x2 >= myreg.x1)&&(myreg.y2 >= myreg.y1)) {
05656                         int dx = 0;
05657                         int dy = 0;
05658                         if (mmsfb->fullscreen == MMSFB_FSM_ASPECT_RATIO) {
05659                             dx = (mmsfb->display_w - this->config.w) >> 1;
05660                             dy = (mmsfb->display_h - this->config.h) >> 1;
05661                         }
05662                         if(this->layer) {
05663                             //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);
05664 
05665                             if ((mmsfb->fullscreen == MMSFB_FSM_TRUE || mmsfb->fullscreen == MMSFB_FSM_ASPECT_RATIO)) {
05666 //TODO: change the ifdef, what to do if XRenderComposite not available?
05667 #ifdef __HAVE_XV__
05668 
05669                                 MMSFBPERF_START_MEASURING;
05670 
05671                                 int ww = myreg.x2 - myreg.x1 + 1;
05672                                 int hh = myreg.y2 - myreg.y1 + 1;
05673 
05674                                 //put image to layer pixmap
05675                                 XShmPutImage(mmsfb->x_display, layer->pixmap, layer->x_gc, sb->x_image[sb->currbuffer_read],
05676                                              myreg.x1, myreg.y1, myreg.x1 + dx, myreg.y1 + dy,
05677                                              ww, hh, False);
05678 
05679                                 double scale = (double)layer->x_window_w / layer->config.w; // We'll scale the window to 50% of its original size
05680 
05681                                 // Scaling matrix
05682                                 XTransform xform = {{
05683                                     { XDoubleToFixed( 1 ), XDoubleToFixed( 0 ), XDoubleToFixed(     0 ) },
05684                                     { XDoubleToFixed( 0 ), XDoubleToFixed( 1 ), XDoubleToFixed(     0 ) },
05685                                     { XDoubleToFixed( 0 ), XDoubleToFixed( 0 ), XDoubleToFixed( scale ) }
05686                                 }};
05687 
05688                                 XRenderSetPictureTransform( mmsfb->x_display, layer->x_pixmap_pict, &xform );
05689                                 XRenderSetPictureFilter( mmsfb->x_display, layer->x_pixmap_pict, FilterBilinear, 0, 0 );
05690 
05691                                 //put render image
05692                                 /* copy the pixmap content using XRender */
05693                                 XRenderComposite(mmsfb->x_display,
05694                                        PictOpSrc,
05695                                        layer->x_pixmap_pict,
05696                                        None,
05697                                        layer->x_window_pict,
05698                                        0, 0,
05699                                        0, 0,
05700                                        0, 0,
05701                                        layer->x_window_w, layer->x_window_h);
05702 
05703 
05704                                 //XFlush(mmsfb->x_display);
05705                                 XSync(mmsfb->x_display, False);
05706 
05707                                 MMSFBPERF_STOP_MEASURING_XSHMPUTIMAGE(this, ww, hh);
05708 
05709 #endif
05710                             } else {
05711 
05712                                 MMSFBPERF_START_MEASURING;
05713 
05714                                 XShmPutImage(mmsfb->x_display, layer->x_window, layer->x_gc, sb->x_image[sb->currbuffer_read],
05715                                           0, 0, dx, dy,
05716                                           this->config.w, this->config.h, False);
05717 
05718                                 //XFlush(mmsfb->x_display);
05719                                 XSync(mmsfb->x_display, False);
05720 
05721                                 MMSFBPERF_STOP_MEASURING_XSHMPUTIMAGE(this, this->config.w, this->config.h);
05722                             }
05723                         }
05724                     }
05725                 }
05726                 XUnlockDisplay(mmsfb->x_display);
05727                 mmsfb->xlock.unlock();
05728             } else {
05729                 //printf("do scaler....\n");
05730 
05731                 // scale to scaler
05732                 if (!region) {
05733                     // scale whole image
05734                     this->scaler->stretchBlit(this, NULL, NULL);
05735                     this->scaler->flip();
05736                 }
05737                 else {
05738                     // scale only a region
05739                     MMSFBRegion myreg = *region;
05740 
05741                     // enlarge the region because of little calulation errors while stretching
05742                     myreg.x1--;
05743                     myreg.y1--;
05744                     myreg.x2++;
05745                     myreg.y2++;
05746 
05747                     // check region
05748                     if (myreg.x1 < 0) myreg.x1 = 0;
05749                     if (myreg.y1 < 0) myreg.y1 = 0;
05750                     if (myreg.x2 >= this->config.w) myreg.x2 = this->config.w - 1;
05751                     if (myreg.y2 >= this->config.h) myreg.y2 = this->config.h - 1;
05752                     if ((myreg.x2 >= myreg.x1)&&(myreg.y2 >= myreg.y1)) {
05753                         // stretch & flip to make it visible on the screen
05754                         MMSFBRectangle src_rect;
05755                         src_rect.x = myreg.x1;
05756                         src_rect.y = myreg.y1;
05757                         src_rect.w = myreg.x2 - myreg.x1 + 1;
05758                         src_rect.h = myreg.y2 - myreg.y1 + 1;
05759                         MMSFBRectangle dst_rect;
05760                         this->scaler->stretchBlit(this, &src_rect, NULL, &dst_rect, true);
05761                         myreg.x1 = dst_rect.x;
05762                         myreg.y1 = dst_rect.y;
05763                         myreg.x2 = dst_rect.x + dst_rect.w - 1;
05764                         myreg.y2 = dst_rect.y + dst_rect.h - 1;
05765                         this->scaler->flip(&myreg);
05766                     }
05767                 }
05768             }
05769         }
05770 #ifdef __HAVE_XV__
05771         else
05772         if (sb->xv_image[0]) {
05773             // XVSHM, put the image to the x-server
05774             mmsfb->xlock.lock();
05775             XLockDisplay(mmsfb->x_display);
05776             if (mmsfb->fullscreen == MMSFB_FSM_TRUE || mmsfb->fullscreen == MMSFB_FSM_ASPECT_RATIO) {
05777                 // calc ratio
05778                 MMSFBRectangle dest;
05779                 calcAspectRatio(mmsfb->x11_win_rect.w, mmsfb->x11_win_rect.h, mmsfb->display_w, mmsfb->display_h, dest,
05780                                 (mmsfb->fullscreen == MMSFB_FSM_ASPECT_RATIO), true);
05781 
05782                 MMSFBPERF_START_MEASURING;
05783 
05784                 //printf("do vputimage\n");
05785                 // put image
05786                 XvShmPutImage(mmsfb->x_display, mmsfb->xv_port, layer->x_window, layer->x_gc, sb->xv_image[sb->currbuffer_read],
05787                               0, 0, mmsfb->x11_win_rect.w, mmsfb->x11_win_rect.h,
05788                               dest.x, dest.y, dest.w, dest.h, False);
05789 
05790                 //XFlush(mmsfb->x_display);
05791                 XSync(mmsfb->x_display, False);
05792 
05793                 MMSFBPERF_STOP_MEASURING_XVSHMPUTIMAGE(this, mmsfb->x11_win_rect.w, mmsfb->x11_win_rect.h, dest.w, dest.h);
05794             }
05795             else if (mmsfb->resized) {
05796 
05797                 MMSFBPERF_START_MEASURING;
05798 
05799                 //printf("stretch to %d:%d\n",mmsfb->target_window_w, mmsfb->target_window_h);
05800                 XvShmPutImage(mmsfb->x_display, mmsfb->xv_port, layer->x_window, layer->x_gc, sb->xv_image[sb->currbuffer_read],
05801                               0, 0, mmsfb->x11_win_rect.w, mmsfb->x11_win_rect.h,
05802                               0, 0, mmsfb->target_window_w, mmsfb->target_window_h, False);
05803 
05804                 //XFlush(mmsfb->x_display);
05805                 XSync(mmsfb->x_display, False);
05806 
05807                 MMSFBPERF_STOP_MEASURING_XVSHMPUTIMAGE(this, mmsfb->x11_win_rect.w, mmsfb->x11_win_rect.h, mmsfb->target_window_w, mmsfb->target_window_h);
05808             }
05809             else {
05810                 /*printf("do vputimage2\n");
05811                 printf("layer: %x, this: %x\n", layer, this);
05812                 printf("sb->xv_image: %x\n", sb->xv_image[sb->currbuffer_read]);
05813 */
05814 
05815                 MMSFBPERF_START_MEASURING;
05816 
05817                 XvShmPutImage(mmsfb->x_display, mmsfb->xv_port, layer->x_window, layer->x_gc, sb->xv_image[sb->currbuffer_read],
05818                               0, 0, mmsfb->x11_win_rect.w, mmsfb->x11_win_rect.h,
05819                               0, 0, mmsfb->x11_win_rect.w, mmsfb->x11_win_rect.h, False);
05820 
05821                 //XFlush(mmsfb->x_display);
05822                 XSync(mmsfb->x_display, False);
05823 
05824                 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);
05825             }
05826 
05827             XUnlockDisplay(mmsfb->x_display);
05828             mmsfb->xlock.unlock();
05829         }
05830 #endif
05831 #endif
05832 
05833 #ifdef __HAVE_FBDEV__
05834         }
05835 #endif
05836 
05837         if (this->config.iswinsurface) {
05838             // inform the window manager
05839             mmsfbwindowmanager->flipSurface(this, region);
05840         }
05841         else {
05842             if (this->is_sub_surface) {
05843                 // sub surface, use the root parent surface
05844                 if (this->root_parent->config.iswinsurface) {
05845                     // inform the window manager, use the correct region
05846                     MMSFBRegion reg;
05847                     if (region)
05848                         reg = *region;
05849                     else {
05850                         reg.x1=0;
05851                         reg.y1=0;
05852                         reg.x2=sub_surface_rect.w-1;
05853                         reg.y2=sub_surface_rect.h-1;
05854                     }
05855                     reg.x1+=this->sub_surface_xoff;
05856                     reg.y1+=this->sub_surface_yoff;
05857                     reg.x2+=this->sub_surface_xoff;
05858                     reg.y2+=this->sub_surface_yoff;
05859                     mmsfbwindowmanager->flipSurface(this->root_parent, &reg);
05860                 }
05861             }
05862         }
05863 
05864         return true;
05865     }
05866 }
05867 
05868 
05869 bool MMSFBSurface::flip(int x1, int y1, int x2, int y2) {
05870     MMSFBRegion region(x1, y1, x2, y2);
05871     return flip(&region);
05872 }
05873 
05874 
05875 bool MMSFBSurface::refresh() {
05876     // check if initialized
05877     INITCHECK;
05878 
05879     // finalize previous clear
05880     finClear();
05881 
05882     if (this->allocated_by == MMSFBSurfaceAllocatedBy_dfb) {
05883 #ifdef  __HAVE_DIRECTFB__
05884 #endif
05885     }
05886     else {
05887 #ifdef __HAVE_XLIB__
05888         MMSFBSurfaceBuffer *sb = this->config.surface_buffer;
05889         if (sb->x_image[0]) {
05890             // XSHM, put the image to the x-server
05891             if (!this->scaler) {
05892                 // no scaler defined
05893                 mmsfb->xlock.lock();
05894                 XLockDisplay(mmsfb->x_display);
05895                 int dx = 0;
05896                 int dy = 0;
05897 /*              if (mmsfb->fullscreen == MMSFB_FSM_ASPECT_RATIO) {
05898                     dx = (mmsfb->display_w - this->config.w) >> 1;
05899                     dy = (mmsfb->display_h - this->config.h) >> 1;
05900                 }
05901 
05902                 XShmPutImage(mmsfb->x_display, layer->x_window, layer->x_gc, sb->x_image[sb->currbuffer_read],
05903                               0, 0, dx, dy,
05904                               this->config.w, this->config.h, False);
05905 */
05906 
05907                 if (mmsfb->fullscreen == MMSFB_FSM_TRUE) {
05908                         // put image to layer pixmap
05909                         XShmPutImage(mmsfb->x_display, layer->pixmap, layer->x_gc, sb->x_image[sb->currbuffer_read],
05910                                                   0, 0, dx, dy,
05911                                                   layer->config.w, layer->config.h, False);
05912 
05913                         double scale = (double)layer->x_window_w / layer->config.w;
05914 
05915                         // Scaling matrix
05916                         XTransform xform = {{
05917                                 { XDoubleToFixed( 1 ), XDoubleToFixed( 0 ), XDoubleToFixed(     0 ) },
05918                                 { XDoubleToFixed( 0 ), XDoubleToFixed( 1 ), XDoubleToFixed(     0 ) },
05919                                 { XDoubleToFixed( 0 ), XDoubleToFixed( 0 ), XDoubleToFixed( scale ) }
05920                         }};
05921 
05922                         XRenderSetPictureTransform( mmsfb->x_display, layer->x_pixmap_pict, &xform );
05923                         XRenderSetPictureFilter( mmsfb->x_display, layer->x_pixmap_pict, FilterBilinear, 0, 0 );
05924 
05925                         //put render image, copy the pixmap content using XRender
05926                         XRenderComposite(mmsfb->x_display,
05927                                    PictOpSrc,
05928                                    layer->x_pixmap_pict,
05929                                    None,
05930                                    layer->x_window_pict,
05931                                    0, 0,
05932                                    0, 0,
05933                                    0, 0,
05934                                    layer->x_window_w, layer->x_window_h);
05935 
05936                 } else {
05937                         if (mmsfb->fullscreen == MMSFB_FSM_ASPECT_RATIO) {
05938                                 dx = (mmsfb->display_w - this->config.w) >> 1;
05939                                 dy = (mmsfb->display_h - this->config.h) >> 1;
05940                         }
05941 
05942                         XShmPutImage(mmsfb->x_display, layer->x_window, layer->x_gc, sb->x_image[sb->currbuffer_read],
05943                                                   0, 0, dx, dy,
05944                                                   this->config.w, this->config.h, False);
05945                 }
05946 
05947                 //XFlush(mmsfb->x_display);
05948                 XSync(mmsfb->x_display, False);
05949                 XUnlockDisplay(mmsfb->x_display);
05950                 mmsfb->xlock.unlock();
05951             }
05952             else {
05953                 // scale to scaler
05954                 this->scaler->stretchBlit(this, NULL, NULL);
05955                 this->scaler->flip();
05956             }
05957         }
05958 #ifdef __HAVE_XV__
05959         else
05960         if (sb->xv_image[0]) {
05961             // XVSHM, put the image to the x-server
05962             this->lock();
05963             mmsfb->xlock.lock();
05964             XLockDisplay(mmsfb->x_display);
05965             if (mmsfb->fullscreen == MMSFB_FSM_TRUE || mmsfb->fullscreen == MMSFB_FSM_ASPECT_RATIO) {
05966                 // calc ratio
05967                 MMSFBRectangle dest;
05968                 calcAspectRatio(mmsfb->x11_win_rect.w, mmsfb->x11_win_rect.h, mmsfb->display_w, mmsfb->display_h, dest,
05969                                 (mmsfb->fullscreen == MMSFB_FSM_ASPECT_RATIO), true);
05970 
05971                 // put image
05972                 XvShmPutImage(mmsfb->x_display, mmsfb->xv_port, layer->x_window, layer->x_gc, sb->xv_image[sb->currbuffer_read],
05973                               0, 0, mmsfb->x11_win_rect.w, mmsfb->x11_win_rect.h,
05974                               dest.x, dest.y, dest.w, dest.h, False);
05975             } else if(mmsfb->resized) {
05976                 XvShmPutImage(mmsfb->x_display, mmsfb->xv_port, layer->x_window, layer->x_gc, sb->xv_image[sb->currbuffer_read],
05977                               0, 0, mmsfb->x11_win_rect.w, mmsfb->x11_win_rect.h,
05978                               0, 0, mmsfb->target_window_w, mmsfb->target_window_h, False);
05979             }else{
05980                 XvShmPutImage(mmsfb->x_display, mmsfb->xv_port, layer->x_window, layer->x_gc, sb->xv_image[sb->currbuffer_read],
05981                               0, 0, mmsfb->x11_win_rect.w, mmsfb->x11_win_rect.h,
05982                               0, 0, mmsfb->x11_win_rect.w, mmsfb->x11_win_rect.h, False);
05983             }
05984             //XFlush(mmsfb->x_display);
05985             XSync(mmsfb->x_display, False);
05986             XUnlockDisplay(mmsfb->x_display);
05987             mmsfb->xlock.unlock();
05988             this->unlock();
05989         }
05990 #endif
05991 #endif
05992     }
05993 
05994     return true;
05995 }
05996 
05997 bool MMSFBSurface::createCopy(MMSFBSurface **dstsurface, int w, int h,
05998                               bool copycontent, bool withbackbuffer, MMSFBSurfacePixelFormat pixelformat) {
05999 
06000     // check if initialized
06001     INITCHECK;
06002 
06003     // finalize previous clear
06004     finClear();
06005 
06006     if (this->is_sub_surface)
06007         return false;
06008 
06009     *dstsurface = NULL;
06010 
06011     if (!w) w = config.w;
06012     if (!h) h = config.h;
06013 
06014     // create new surface
06015     if (!mmsfb->createSurface(dstsurface, w, h, (pixelformat==MMSFB_PF_NONE)?this->config.surface_buffer->pixelformat:pixelformat,
06016                              (withbackbuffer)?this->config.surface_buffer->backbuffer:0,this->config.surface_buffer->systemonly)) {
06017         if (*dstsurface)
06018             delete *dstsurface;
06019         *dstsurface = NULL;
06020         return false;
06021     }
06022 
06023     if (copycontent) {
06024         // copy the content
06025         MMSFBRectangle dstrect;
06026         dstrect.x = 0;
06027         dstrect.y = 0;
06028         dstrect.w = w;
06029         dstrect.h = h;
06030         (*dstsurface)->setDrawingFlags((MMSFBDrawingFlags) MMSFB_DRAW_NOFX);
06031         (*dstsurface)->setBlittingFlags((MMSFBBlittingFlags) MMSFB_BLIT_NOFX);
06032         (*dstsurface)->stretchBlit(this, NULL, &dstrect);
06033         if (withbackbuffer) {
06034             (*dstsurface)->flip();
06035         }
06036     }
06037 
06038     return true;
06039 }
06040 
06041 bool MMSFBSurface::resize(int w, int h) {
06042 
06043     // check old size, resize only if size changed
06044     int old_w, old_h;
06045     if (!getSize(&old_w, &old_h)) return false;
06046     if ((old_w == w) && (old_h == h)) return true;
06047 
06048     // finalize previous clear
06049     finClear();
06050 
06051     if (!this->is_sub_surface) {
06052         // normal surface
06053         // create a copy
06054         MMSFBSurface *dstsurface;
06055         createCopy(&dstsurface, w, h, true, true);
06056 
06057         if (this->allocated_by == MMSFBSurfaceAllocatedBy_dfb) {
06058 #ifdef  __HAVE_DIRECTFB__
06059             D_DEBUG_AT( MMS_Surface, "resize( %dx%d -> %dx%d )\n",
06060                         this->config.w, this->config.h, w, h );
06061 
06062             MMSFB_TRACE();
06063 
06064             // move the dfb pointers
06065             IDirectFBSurface *s = this->dfb_surface;
06066             this->dfb_surface = dstsurface->dfb_surface;
06067             dstsurface->dfb_surface = s;
06068 
06069             // load the new configuration
06070             this->getConfiguration();
06071             dstsurface->getConfiguration();
06072 #endif
06073         }
06074         else {
06075             // move the surface buffer data
06076             MMSFBSurfaceBuffer *sb = this->config.surface_buffer;
06077             this->config.surface_buffer = dstsurface->config.surface_buffer;
06078             dstsurface->config.surface_buffer = sb;
06079 
06080             // set size to new size
06081             this->config.w = w;
06082             this->config.h = h;
06083 
06084             // load the new configuration
06085             this->getConfiguration();
06086         }
06087 
06088         // free dstsurface
06089         delete dstsurface;
06090 
06091         return true;
06092     }
06093     else  {
06094         // sub surface
06095         MMSFBRectangle rect = this->sub_surface_rect;
06096         rect.w = w;
06097         rect.h = h;
06098         return setSubSurface(&rect);
06099 
06100     }
06101 }
06102 
06103 
06104 
06105 void MMSFBSurface::modulateBrightness(MMSFBColor *color, unsigned char brightness) {
06106 
06107     /* full brightness? */
06108     if (brightness == 255) return;
06109 
06110     /* full darkness? */
06111     if (brightness == 0) {
06112         color->r = 0;
06113         color->g = 0;
06114         color->b = 0;
06115         return;
06116     }
06117 
06118     /* modulate the color */
06119     unsigned int bn = 100000 * (255-brightness);
06120     if (color->r > 0) {
06121         unsigned int i = (10000 * 255) / (unsigned int)color->r;
06122         color->r = (5+((10 * (unsigned int)color->r) - (bn / i))) / 10;
06123     }
06124     if (color->g > 0) {
06125         unsigned int i = (10000 * 255) / (unsigned int)color->g;
06126         color->g = (5+((10 * (unsigned int)color->g) - (bn / i))) / 10;
06127     }
06128     if (color->b > 0) {
06129         unsigned int i = (10000 * 255) / (unsigned int)color->b;
06130         color->b = (5+((10 * (unsigned int)color->b) - (bn / i))) / 10;
06131     }
06132 }
06133 
06134 void MMSFBSurface::modulateOpacity(MMSFBColor *color, unsigned char opacity) {
06135 
06136     /* full opacity? */
06137     if (opacity == 255) return;
06138 
06139     /* complete transparent? */
06140     if (opacity == 0) {
06141         color->a = 0;
06142         return;
06143     }
06144 
06145     /* modulate the alpha value */
06146     unsigned int bn = 100000 * (255-opacity);
06147     if (color->a > 0) {
06148         unsigned int i = (10000 * 255) / (unsigned int)color->a;
06149         color->a = (5+((10 * (unsigned int)color->a) - (bn / i))) / 10;
06150     }
06151 }
06152 
06153 
06154 bool MMSFBSurface::setBlittingFlagsByBrightnessAlphaAndOpacity(
06155                     unsigned char brightness, unsigned char alpha, unsigned char opacity) {
06156     MMSFBColor color;
06157 
06158     /* check if initialized */
06159     INITCHECK;
06160 
06161     /* modulate the opacity into the color */
06162     color.a = alpha;
06163     modulateOpacity(&color, opacity);
06164 
06165     /* set color for blitting */
06166     setColor(brightness, brightness, brightness, color.a);
06167 
06168     /* set blitting flags */
06169     if (brightness != 255) {
06170         if (color.a == 255)
06171             setBlittingFlags((MMSFBBlittingFlags)(MMSFB_BLIT_COLORIZE|MMSFB_BLIT_BLEND_ALPHACHANNEL));
06172         else
06173             setBlittingFlags((MMSFBBlittingFlags)(MMSFB_BLIT_COLORIZE|MMSFB_BLIT_BLEND_ALPHACHANNEL|MMSFB_BLIT_BLEND_COLORALPHA));
06174     }
06175     else {
06176         if (color.a == 255)
06177             setBlittingFlags((MMSFBBlittingFlags)(MMSFB_BLIT_BLEND_ALPHACHANNEL));
06178         else
06179             setBlittingFlags((MMSFBBlittingFlags)(MMSFB_BLIT_BLEND_ALPHACHANNEL|MMSFB_BLIT_BLEND_COLORALPHA));
06180     }
06181 
06182     return true;
06183 }
06184 
06185 
06186 bool MMSFBSurface::setBlittingFlagsByBrightnessAlphaAndOpacityAndSource(
06187                     unsigned char brightness, unsigned char alpha, unsigned char opacity,
06188                     MMSFBSurface *source) {
06189     MMSFBColor color;
06190 
06191     // check if initialized
06192     INITCHECK;
06193 
06194     // modulate the opacity into the color
06195     color.a = alpha;
06196     modulateOpacity(&color, opacity);
06197 
06198     // set color for blitting
06199     setColor(brightness, brightness, brightness, color.a);
06200 
06201     // set blitting flags
06202     if (!MMSFBSURFACE_READ_BUFFER(source).opaque) {
06203         // source is not opaque
06204         if (brightness != 255) {
06205             if (color.a == 255)
06206                 setBlittingFlags((MMSFBBlittingFlags)(MMSFB_BLIT_COLORIZE|MMSFB_BLIT_BLEND_ALPHACHANNEL));
06207             else
06208                 setBlittingFlags((MMSFBBlittingFlags)(MMSFB_BLIT_COLORIZE|MMSFB_BLIT_BLEND_ALPHACHANNEL|MMSFB_BLIT_BLEND_COLORALPHA));
06209         }
06210         else {
06211             if (color.a == 255)
06212                 setBlittingFlags((MMSFBBlittingFlags)(MMSFB_BLIT_BLEND_ALPHACHANNEL));
06213             else
06214                 setBlittingFlags((MMSFBBlittingFlags)(MMSFB_BLIT_BLEND_ALPHACHANNEL|MMSFB_BLIT_BLEND_COLORALPHA));
06215         }
06216     }
06217     else {
06218         // source is opaque, so we do not need MMSFB_BLIT_BLEND_ALPHACHANNEL
06219         if (brightness != 255) {
06220             if (color.a == 255)
06221                 setBlittingFlags((MMSFBBlittingFlags)(MMSFB_BLIT_COLORIZE));
06222             else
06223                 setBlittingFlags((MMSFBBlittingFlags)(MMSFB_BLIT_COLORIZE|MMSFB_BLIT_BLEND_COLORALPHA));
06224         }
06225         else {
06226             if (color.a == 255)
06227                 setBlittingFlags((MMSFBBlittingFlags)(MMSFB_BLIT_NOFX));
06228             else
06229                 setBlittingFlags((MMSFBBlittingFlags)(MMSFB_BLIT_BLEND_COLORALPHA));
06230         }
06231     }
06232 
06233     return true;
06234 }
06235 
06236 
06237 
06238 bool MMSFBSurface::setDrawingFlagsByAlpha(unsigned char alpha) {
06239 
06240     // check if initialized
06241     INITCHECK;
06242 
06243     // set the drawing flags
06244     if (this->config.surface_buffer->premultiplied) {
06245         // premultiplied surface, have to premultiply the color
06246         if (alpha == 255)
06247             setDrawingFlags((MMSFBDrawingFlags)(MMSFB_DRAW_NOFX|MMSFB_DRAW_SRC_PREMULTIPLY));
06248         else
06249             setDrawingFlags((MMSFBDrawingFlags)(MMSFB_DRAW_BLEND|MMSFB_DRAW_SRC_PREMULTIPLY));
06250     }
06251     else {
06252         if (alpha == 255)
06253             setDrawingFlags((MMSFBDrawingFlags)MMSFB_DRAW_NOFX);
06254         else
06255             setDrawingFlags((MMSFBDrawingFlags)MMSFB_DRAW_BLEND);
06256     }
06257 
06258     return true;
06259 }
06260 
06261 
06262 bool MMSFBSurface::setDrawingColorAndFlagsByBrightnessAndOpacity(
06263                         MMSFBColor color, unsigned char brightness, unsigned char opacity) {
06264 
06265     // check if initialized
06266     INITCHECK;
06267 
06268     // modulate the brightness into the color
06269     modulateBrightness(&color, brightness);
06270 
06271     // modulate the opacity into the color
06272     modulateOpacity(&color, opacity);
06273 
06274     // set the color for drawing
06275     setColor(color.r, color.g, color.b, color.a);
06276 
06277     // set the drawing flags
06278     setDrawingFlagsByAlpha(color.a);
06279 
06280     return true;
06281 }
06282 
06283 
06284 bool MMSFBSurface::setDrawingColorAndFlagsByBrightnessAndOpacity(
06285                         MMSFBColor color,
06286                         MMSFBColor shadow_top_color, MMSFBColor shadow_bottom_color,
06287                         MMSFBColor shadow_left_color, MMSFBColor shadow_right_color,
06288                         MMSFBColor shadow_top_left_color, MMSFBColor shadow_top_right_color,
06289                         MMSFBColor shadow_bottom_left_color, MMSFBColor shadow_bottom_right_color,
06290                         unsigned char brightness, unsigned char opacity) {
06291 
06292     if (!setDrawingColorAndFlagsByBrightnessAndOpacity(color, brightness, opacity))
06293         return false;
06294 
06295     // modulate the brightness/opacity into the shadow colors
06296     modulateBrightness(&shadow_top_color, brightness);
06297     modulateOpacity(&shadow_top_color, opacity);
06298     modulateBrightness(&shadow_bottom_color, brightness);
06299     modulateOpacity(&shadow_bottom_color, opacity);
06300     modulateBrightness(&shadow_left_color, brightness);
06301     modulateOpacity(&shadow_left_color, opacity);
06302     modulateBrightness(&shadow_right_color, brightness);
06303     modulateOpacity(&shadow_right_color, opacity);
06304     modulateBrightness(&shadow_top_left_color, brightness);
06305     modulateOpacity(&shadow_top_left_color, opacity);
06306     modulateBrightness(&shadow_top_right_color, brightness);
06307     modulateOpacity(&shadow_top_right_color, opacity);
06308     modulateBrightness(&shadow_bottom_left_color, brightness);
06309     modulateOpacity(&shadow_bottom_left_color, opacity);
06310     modulateBrightness(&shadow_bottom_right_color, brightness);
06311     modulateOpacity(&shadow_bottom_right_color, opacity);
06312 
06313     // set the shadow colors
06314     return setShadowColor(shadow_top_color, shadow_bottom_color, shadow_left_color, shadow_right_color,
06315                           shadow_top_left_color, shadow_top_right_color, shadow_bottom_left_color, shadow_bottom_right_color);
06316 }
06317 
06318 
06319 bool MMSFBSurface::setFont(MMSFBFont *font) {
06320 
06321     /* check if initialized */
06322     INITCHECK;
06323 
06324     if (this->allocated_by == MMSFBSurfaceAllocatedBy_dfb) {
06325 #ifdef  __HAVE_DIRECTFB__
06326         DFBResult   dfbres;
06327 
06328         /* set font */
06329         if ((dfbres=this->dfb_surface->SetFont(this->dfb_surface, (IDirectFBFont*)font->dfbfont)) != DFB_OK) {
06330             MMSFB_SetError(dfbres, "IDirectFBSurface::SetFont() failed");
06331             return false;
06332         }
06333 #endif
06334     }
06335     else {
06336         //TODO
06337     }
06338 
06339     /* save the font */
06340     this->config.font = font;
06341 
06342     return true;
06343 }
06344 
06345 
06346 
06347 bool MMSFBSurface::blit_text(string &text, int len, int x, int y) {
06348     MMSFBRegion clipreg;
06349     MMSFBSurfacePlanes dst_planes;
06350 
06351 #ifndef USE_DFB_SUBSURFACE
06352     if (!this->is_sub_surface) {
06353 #endif
06354         // normal surface or dfb subsurface
06355         if (!this->config.clipped) {
06356             clipreg.x1 = 0;
06357             clipreg.y1 = 0;
06358             clipreg.x2 = this->config.w - 1;
06359             clipreg.y2 = this->config.h - 1;
06360         }
06361         else
06362             clipreg = this->config.clip;
06363 #ifndef USE_DFB_SUBSURFACE
06364     }
06365     else {
06366         // subsurface
06367         if (!this->root_parent->config.clipped) {
06368             clipreg.x1 = 0;
06369             clipreg.y1 = 0;
06370             clipreg.x2 = this->root_parent->config.w - 1;
06371             clipreg.y2 = this->root_parent->config.h - 1;
06372         }
06373         else
06374             clipreg = this->root_parent->config.clip;
06375     }
06376 #endif
06377 
06378     // calculate the color
06379     MMSFBColor color = this->config.color;
06380     if (this->config.drawingflags & (MMSFBDrawingFlags)MMSFB_DRAW_SRC_PREMULTIPLY) {
06381         // pre-multiplication needed
06382         if (color.a != 0xff) {
06383             color.r = ((color.a+1) * color.r) >> 8;
06384             color.g = ((color.a+1) * color.g) >> 8;
06385             color.b = ((color.a+1) * color.b) >> 8;
06386         }
06387     }
06388 
06389     // checking pixelformats...
06390     switch (this->config.surface_buffer->pixelformat) {
06391     case MMSFB_PF_ARGB:
06392         // destination is ARGB
06393         if   ((this->config.drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_NOFX))
06394             ||(this->config.drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_NOFX|MMSFB_DRAW_SRC_PREMULTIPLY))) {
06395             if (extendedLock(NULL, NULL, this, &dst_planes)) {
06396                 MMSFB_ROTATE_180_REGION(this, clipreg.x1, clipreg.y1, clipreg.x2, clipreg.y2);
06397                 MMSFB_ROTATE_180_RECT(this, x, y, 1, 1);
06398                 MMSFBPERF_START_MEASURING;
06399                     mmsfb_drawstring_blend_argb(
06400                             &dst_planes, this->config.font, clipreg,
06401                             text, len, x, y, color);
06402                 MMSFBPERF_STOP_MEASURING_DRAWSTRING(this, clipreg, text, len, x, y);
06403                 MMSFB_ROTATE_180_REGION(this, clipreg.x1, clipreg.y1, clipreg.x2, clipreg.y2);
06404                 MMSFB_ROTATE_180_RECT(this, x, y, 1, 1);
06405                 extendedUnlock(NULL, this);
06406                 return true;
06407             }
06408             return false;
06409         }
06410         else
06411         if   ((this->config.drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_BLEND))
06412             ||(this->config.drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_BLEND|MMSFB_DRAW_SRC_PREMULTIPLY))) {
06413             if (extendedLock(NULL, NULL, this, &dst_planes)) {
06414                 MMSFB_ROTATE_180_REGION(this, clipreg.x1, clipreg.y1, clipreg.x2, clipreg.y2);
06415                 MMSFB_ROTATE_180_RECT(this, x, y, 1, 1);
06416                 MMSFBPERF_START_MEASURING;
06417                     mmsfb_drawstring_blend_coloralpha_argb(
06418                             &dst_planes, this->config.font, clipreg,
06419                             text, len, x, y, color);
06420                 MMSFBPERF_STOP_MEASURING_DRAWSTRING(this, clipreg, text, len, x, y);
06421                 MMSFB_ROTATE_180_REGION(this, clipreg.x1, clipreg.y1, clipreg.x2, clipreg.y2);
06422                 MMSFB_ROTATE_180_RECT(this, x, y, 1, 1);
06423                 extendedUnlock(NULL, this);
06424                 return true;
06425             }
06426             return false;
06427         }
06428         break;
06429 
06430     case MMSFB_PF_RGB32:
06431         // destination is RGB32
06432         if   ((this->config.drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_NOFX))
06433             ||(this->config.drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_NOFX|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_rgb32(
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         else
06450         if   ((this->config.drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_BLEND))
06451             ||(this->config.drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_BLEND|MMSFB_DRAW_SRC_PREMULTIPLY))) {
06452             if (extendedLock(NULL, NULL, this, &dst_planes)) {
06453                 MMSFB_ROTATE_180_REGION(this, clipreg.x1, clipreg.y1, clipreg.x2, clipreg.y2);
06454                 MMSFB_ROTATE_180_RECT(this, x, y, 1, 1);
06455                 MMSFBPERF_START_MEASURING;
06456                     mmsfb_drawstring_blend_coloralpha_rgb32(
06457                             &dst_planes, this->config.font, clipreg,
06458                             text, len, x, y, color);
06459                 MMSFBPERF_STOP_MEASURING_DRAWSTRING(this, clipreg, text, len, x, y);
06460                 MMSFB_ROTATE_180_REGION(this, clipreg.x1, clipreg.y1, clipreg.x2, clipreg.y2);
06461                 MMSFB_ROTATE_180_RECT(this, x, y, 1, 1);
06462                 extendedUnlock(NULL, this);
06463                 return true;
06464             }
06465             return false;
06466         }
06467         break;
06468 
06469     case MMSFB_PF_ARGB4444:
06470         // destination is ARGB4444
06471         if   ((this->config.drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_NOFX))
06472             ||(this->config.drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_NOFX|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_argb4444(
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_RGB16:
06491         // destination is RGB16
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_rgb16(
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         else
06510         if   ((this->config.drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_BLEND))
06511             ||(this->config.drawingflags == (MMSFBDrawingFlags)(MMSFB_DRAW_BLEND|MMSFB_DRAW_SRC_PREMULTIPLY))) {
06512             if (extendedLock(NULL, NULL, this, &dst_planes)) {
06513                 MMSFB_ROTATE_180_REGION(this, clipreg.x1, clipreg.y1, clipreg.x2, clipreg.y2);
06514                 MMSFB_ROTATE_180_RECT(this, x, y, 1, 1);
06515                 MMSFBPERF_START_MEASURING;
06516                     mmsfb_drawstring_blend_coloralpha_rgb16(
06517                             &dst_planes, this->config.font, clipreg,
06518                             text, len, x, y, color);
06519                 MMSFBPERF_STOP_MEASURING_DRAWSTRING(this, clipreg, text, len, x, y);
06520                 MMSFB_ROTATE_180_REGION(this, clipreg.x1, clipreg.y1, clipreg.x2, clipreg.y2);
06521                 MMSFB_ROTATE_180_RECT(this, x, y, 1, 1);
06522                 extendedUnlock(NULL, this);
06523                 return true;
06524             }
06525             return false;
06526         }
06527         break;
06528 
06529     default:
06530         // does not match
06531         break;
06532     }
06533 
06534     return printMissingCombination("blit_text()", NULL, NULL, MMSFB_PF_NONE, 0, 0);
06535 }
06536 
06537 
06538 bool MMSFBSurface::blit_text_with_shadow(string &text, int len, int x, int y) {
06539 
06540     bool top            = (this->config.shadow_top_color.a);
06541     bool bottom         = (this->config.shadow_bottom_color.a);
06542     bool left           = (this->config.shadow_left_color.a);
06543     bool right          = (this->config.shadow_right_color.a);
06544     bool top_left       = (this->config.shadow_top_left_color.a);
06545     bool top_right      = (this->config.shadow_top_right_color.a);
06546     bool bottom_left    = (this->config.shadow_bottom_left_color.a);
06547     bool bottom_right   = (this->config.shadow_bottom_right_color.a);
06548     bool shadow = (top || bottom || left || right || top_left || top_right || bottom_left || bottom_right);
06549 
06550     if (!shadow) {
06551         // normal text output without shadow
06552 #ifdef __HAVE_OPENGL__
06553         if (mmsfb->bei) {
06554             mmsfb->bei->drawString(this, text, len, x, y);
06555             return true;
06556         }
06557 #endif
06558         return blit_text(text, len, x, y);
06559     }
06560     else {
06561         // draw text with shadow
06562         // drawing color and flags will be temporary changed during the shadow blits
06563         MMSFBColor savedcol = this->config.color;
06564         MMSFBDrawingFlags saveddf = this->config.drawingflags;
06565 
06566 
06567         //TODO: for now we assume that this->config.color.a is 0xff!!!
06568         //      else we have to blit text and shadow in an temporary buffer with (text with a=0xff)
06569         //      and finally blend the result with coloralpha to this destination surface
06570 
06571 
06572         if (top) {
06573             // draw shadow on the top
06574             this->config.color = this->config.shadow_top_color;
06575             this->setDrawingFlagsByAlpha(this->config.color.a);
06576 #ifdef __HAVE_OPENGL__
06577             if (mmsfb->bei) {
06578                 mmsfb->bei->drawString(this, text, len, x, y-1);
06579             }
06580             else
06581 #endif
06582             blit_text(text, len, x, y-1);
06583         }
06584         if (bottom) {
06585             // draw shadow on the bottom
06586             this->config.color = this->config.shadow_bottom_color;
06587             this->setDrawingFlagsByAlpha(this->config.color.a);
06588 #ifdef __HAVE_OPENGL__
06589             if (mmsfb->bei) {
06590                 mmsfb->bei->drawString(this, text, len, x, y+1);
06591             }
06592             else
06593 #endif
06594             blit_text(text, len, x, y+1);
06595         }
06596         if (left) {
06597             // draw shadow on the left
06598             this->config.color = this->config.shadow_left_color;
06599             this->setDrawingFlagsByAlpha(this->config.color.a);
06600 #ifdef __HAVE_OPENGL__
06601             if (mmsfb->bei) {
06602                 mmsfb->bei->drawString(this, text, len, x-1, y);
06603             }
06604             else
06605 #endif
06606             blit_text(text, len, x-1, y);
06607         }
06608         if (right) {
06609             // draw shadow on the right
06610             this->config.color = this->config.shadow_right_color;
06611             this->setDrawingFlagsByAlpha(this->config.color.a);
06612 #ifdef __HAVE_OPENGL__
06613             if (mmsfb->bei) {
06614                 mmsfb->bei->drawString(this, text, len, x+1, y);
06615             }
06616             else
06617 #endif
06618             blit_text(text, len, x+1, y);
06619         }
06620         if (top_left) {
06621             // draw shadow on the top-left
06622             this->config.color = this->config.shadow_top_left_color;
06623             this->setDrawingFlagsByAlpha(this->config.color.a);
06624 #ifdef __HAVE_OPENGL__
06625             if (mmsfb->bei) {
06626                 mmsfb->bei->drawString(this, text, len, x-1, y-1);
06627             }
06628             else
06629 #endif
06630             blit_text(text, len, x-1, y-1);
06631         }
06632         if (top_right) {
06633             // draw shadow on the top-right
06634             this->config.color = this->config.shadow_top_right_color;
06635             this->setDrawingFlagsByAlpha(this->config.color.a);
06636 #ifdef __HAVE_OPENGL__
06637             if (mmsfb->bei) {
06638                 mmsfb->bei->drawString(this, text, len, x+1, y-1);
06639             }
06640             else
06641 #endif
06642             blit_text(text, len, x+1, y-1);
06643         }
06644         if (bottom_left) {
06645             // draw shadow on the bottom-left
06646             this->config.color = this->config.shadow_bottom_left_color;
06647             this->setDrawingFlagsByAlpha(this->config.color.a);
06648 #ifdef __HAVE_OPENGL__
06649             if (mmsfb->bei) {
06650                 mmsfb->bei->drawString(this, text, len, x-1, y+1);
06651             }
06652             else
06653 #endif
06654             blit_text(text, len, x-1, y+1);
06655         }
06656         if (bottom_right) {
06657             // draw shadow on the bottom-right
06658             this->config.color = this->config.shadow_bottom_right_color;
06659             this->setDrawingFlagsByAlpha(this->config.color.a);
06660 #ifdef __HAVE_OPENGL__
06661             if (mmsfb->bei) {
06662                 mmsfb->bei->drawString(this, text, len, x+1, y+1);
06663             }
06664             else
06665 #endif
06666             blit_text(text, len, x+1, y+1);
06667         }
06668 
06669         // restore drawing color and flags
06670         this->config.color = savedcol;
06671         this->config.drawingflags = saveddf;
06672 
06673         // for now we set this->config.color.a to 0xff!!!
06674         this->config.color.a = 0xff;
06675         this->setDrawingFlagsByAlpha(this->config.color.a);
06676 
06677         // final draw
06678         bool ret = false;
06679 #ifdef __HAVE_OPENGL__
06680         if (mmsfb->bei) {
06681             mmsfb->bei->drawString(this, text, len, x, y);
06682             ret = true;
06683         }
06684         else
06685 #endif
06686         ret = blit_text(text, len, x, y);
06687 
06688         // restore drawing color and flags
06689         this->config.color = savedcol;
06690         this->config.drawingflags = saveddf;
06691 
06692         return ret;
06693     }
06694 }
06695 
06696 
06697 bool MMSFBSurface::drawString(string text, int len, int x, int y) {
06698 
06699     // check if initialized
06700     INITCHECK;
06701 
06702     // finalize previous clear
06703     finClear();
06704 
06705     if (!this->config.font)
06706         return false;
06707 
06708     // get the length of the string
06709     if (len < 0) len = text.size();
06710     if (!len) return true;
06711 
06712     if (this->allocated_by == MMSFBSurfaceAllocatedBy_dfb) {
06713 #ifdef  __HAVE_DIRECTFB__
06714         D_DEBUG_AT( MMS_Surface, "drawString( '%s', %d, %d,%d ) <- %dx%d\n",
06715                     text.c_str(), len, x, y, this->config.w, this->config.h );
06716         MMSFB_TRACE();
06717 
06718         // draw a string
06719         DFBResult dfbres;
06720         if (!this->is_sub_surface) {
06721             if ((dfbres=this->dfb_surface->DrawString(this->dfb_surface, text.c_str(), len, x, y, DSTF_TOPLEFT)) != DFB_OK) {
06722                 MMSFB_SetError(dfbres, "IDirectFBSurface::DrawString() failed");
06723 
06724                 return false;
06725             }
06726         }
06727         else {
06728 #ifndef USE_DFB_SUBSURFACE
06729             CLIPSUBSURFACE
06730 
06731             x+=this->sub_surface_xoff;
06732             y+=this->sub_surface_yoff;
06733 
06734             SETSUBSURFACE_DRAWINGFLAGS;
06735 #endif
06736 
06737             this->dfb_surface->DrawString(this->dfb_surface, text.c_str(), len, x, y, DSTF_TOPLEFT);
06738 
06739 #ifndef USE_DFB_SUBSURFACE
06740             RESETSUBSURFACE_DRAWINGFLAGS;
06741 
06742             UNCLIPSUBSURFACE
06743 #endif
06744         }
06745 #endif
06746     }
06747     else
06748     if (this->allocated_by == MMSFBSurfaceAllocatedBy_ogl) {
06749 #ifdef  __HAVE_OPENGL__
06750         if (!this->is_sub_surface) {
06751 //          mmsfb->bei->drawString(this, text, len, x, y);
06752             blit_text_with_shadow(text, len, x, y);
06753         }
06754         else {
06755             CLIPSUBSURFACE
06756 
06757 //          mmsfb->bei->drawString(this, text, len, x, y);
06758             blit_text_with_shadow(text, len, x, y);
06759 
06760             UNCLIPSUBSURFACE
06761         }
06762 #endif
06763     }
06764     else {
06765         // draw a string
06766         if (!this->is_sub_surface) {
06767             blit_text_with_shadow(text, len, x, y);
06768         }
06769         else {
06770             CLIPSUBSURFACE
06771 
06772             x+=this->sub_surface_xoff;
06773             y+=this->sub_surface_yoff;
06774 
06775             blit_text_with_shadow(text, len, x, y);
06776 
06777             UNCLIPSUBSURFACE
06778         }
06779     }
06780 
06781     return true;
06782 }
06783 
06784 void MMSFBSurface::lock(MMSFBLockFlags flags, MMSFBSurfacePlanes *planes, bool pthread_lock) {
06785     if (!pthread_lock) {
06786         // no pthread lock needed
06787         if (this->allocated_by == MMSFBSurfaceAllocatedBy_dfb) {
06788 #ifdef  __HAVE_DIRECTFB__
06789             if (flags && planes) {
06790                 // get the access to the surface buffer
06791                 memset(planes, 0, sizeof(MMSFBSurfacePlanes));
06792                 if (flags == MMSFB_LOCK_READ) {
06793                     if (this->dfb_surface->Lock(this->dfb_surface, DSLF_READ, &planes->ptr, &planes->pitch) != DFB_OK) {
06794                         planes->ptr = NULL;
06795                         planes->pitch = 0;
06796                     }
06797                 }
06798                 else
06799                 if (flags == MMSFB_LOCK_WRITE) {
06800                     if (this->dfb_surface->Lock(this->dfb_surface, DSLF_WRITE, &planes->ptr, &planes->pitch) != DFB_OK) {
06801                         planes->ptr = NULL;
06802                         planes->pitch = 0;
06803                     }
06804                 }
06805             }
06806 #endif
06807         }
06808         else {
06809             if (flags && planes) {
06810                 // get the access to the surface buffer
06811                 memset(planes, 0, sizeof(MMSFBSurfacePlanes));
06812                 MMSFBSurfaceBuffer *sb = this->config.surface_buffer;
06813                 if (flags == MMSFB_LOCK_READ) {
06814                     *planes = sb->buffers[sb->currbuffer_read];
06815                 }
06816                 else
06817                 if (flags == MMSFB_LOCK_WRITE) {
06818                     *planes = sb->buffers[sb->currbuffer_write];
06819                 }
06820             }
06821         }
06822         return;
06823     }
06824 
06825     // which surface is to lock?
06826     MMSFBSurface *tolock = this;
06827     if (this->root_parent)
06828         tolock = this->root_parent;
06829     else
06830     if (this->parent)
06831         tolock = this->parent;
06832 
06833     if (tolock->Lock.trylock() == 0) {
06834         // I have got the lock the first time
06835         tolock->TID = pthread_self();
06836         tolock->Lock_cnt = 1;
06837     }
06838     else {
06839         if ((tolock->TID == pthread_self())&&(tolock->Lock_cnt > 0)) {
06840             // I am the thread which has already locked this surface
06841             tolock->Lock_cnt++;
06842         }
06843         else {
06844             // another thread has already locked this surface, waiting for...
06845 #ifdef DEBUG_LOCK_OUTPUT
06846             printf("surface try lock - (%lu), cnt: %d surf: %p\n", (pid_t) syscall (SYS_gettid), tolock->Lock_cnt, tolock);
06847 #endif
06848             tolock->Lock.lock();
06849             tolock->TID = pthread_self();
06850             tolock->Lock_cnt = 1;
06851         }
06852     }
06853 
06854     if (this->allocated_by == MMSFBSurfaceAllocatedBy_dfb) {
06855 #ifdef  __HAVE_DIRECTFB__
06856         if (flags && planes) {
06857             // get the access to the surface buffer
06858             memset(planes, 0, sizeof(MMSFBSurfacePlanes));
06859             if (flags == MMSFB_LOCK_READ) {
06860                 if (!tolock->surface_read_locked) {
06861                     if (this->dfb_surface->Lock(this->dfb_surface, DSLF_READ, &planes->ptr, &planes->pitch) != DFB_OK) {
06862                         planes->ptr = NULL;
06863                         planes->pitch = 0;
06864                     }
06865                     else {
06866                         tolock->surface_read_locked = true;
06867                         tolock->surface_read_lock_cnt = tolock->Lock_cnt;
06868                     }
06869                 }
06870             }
06871             else
06872             if (flags == MMSFB_LOCK_WRITE) {
06873                 if (!tolock->surface_write_locked) {
06874                     if (this->dfb_surface->Lock(this->dfb_surface, DSLF_WRITE, &planes->ptr, &planes->pitch) != DFB_OK) {
06875                         planes->ptr = NULL;
06876                         planes->pitch = 0;
06877                     }
06878                     else {
06879                         tolock->surface_write_locked = true;
06880                         tolock->surface_write_lock_cnt = tolock->Lock_cnt;
06881                     }
06882                 }
06883             }
06884         }
06885 #endif
06886     }
06887     else {
06888         if (flags && planes) {
06889             // get the access to the surface buffer
06890             memset(planes, 0, sizeof(MMSFBSurfacePlanes));
06891             MMSFBSurfaceBuffer *sb = this->config.surface_buffer;
06892             if (flags == MMSFB_LOCK_READ) {
06893                 if (!tolock->surface_read_locked) {
06894                     *planes = sb->buffers[sb->currbuffer_read];
06895                     tolock->surface_read_locked = true;
06896                     tolock->surface_read_lock_cnt = tolock->Lock_cnt;
06897                 }
06898             }
06899             else
06900             if (flags == MMSFB_LOCK_WRITE) {
06901                 if (!tolock->surface_write_locked) {
06902                     *planes = sb->buffers[sb->currbuffer_write];
06903                     tolock->surface_write_locked = true;
06904                     tolock->surface_write_lock_cnt = tolock->Lock_cnt;
06905                 }
06906             }
06907         }
06908     }
06909 }
06910 
06911 void MMSFBSurface::lock(MMSFBLockFlags flags, void **ptr, int *pitch) {
06912     if (!ptr || !pitch) {
06913         // nothing to return
06914         lock(flags, NULL, true);
06915     }
06916     else {
06917         // get the planes an return the first one
06918         MMSFBSurfacePlanes planes;
06919         lock(flags, &planes, true);
06920         *ptr = planes.ptr;
06921         *pitch = planes.pitch;
06922     }
06923 }
06924 
06925 void MMSFBSurface::lock(MMSFBLockFlags flags, MMSFBSurfacePlanes *planes) {
06926     lock(flags, planes, true);
06927 }
06928 
06929 bool MMSFBSurface::tryToLock() {
06930 
06931     // which surface is to lock?
06932     MMSFBSurface *tolock = this;
06933     if (this->root_parent)
06934         tolock = this->root_parent;
06935     else
06936     if (this->parent)
06937         tolock = this->parent;
06938 
06939     if (tolock->Lock.trylock() == 0) {
06940         // I have got the lock the first time
06941         tolock->TID = pthread_self();
06942         tolock->Lock_cnt = 1;
06943     }
06944     else {
06945         if ((tolock->TID == pthread_self())&&(tolock->Lock_cnt > 0)) {
06946             // I am the thread which has already locked this surface
06947             tolock->Lock_cnt++;
06948         }
06949         else {
06950             // another thread has already locked this surface, waiting for...
06951 #ifdef DEBUG_LOCK_OUTPUT
06952             printf("surface locked from other thread - (%lu), cnt: %d surf: %p\n", (pid_t) syscall (SYS_gettid), tolock->Lock_cnt, tolock);
06953 #endif
06954             return false;
06955 //          tolock->Lock.lock();
06956 //          tolock->TID = pthread_self();
06957 //          tolock->Lock_cnt = 1;
06958         }
06959     }
06960 
06961     return true;
06962 }
06963 
06964 void MMSFBSurface::unlock(bool pthread_unlock) {
06965     if (!pthread_unlock) {
06966         // no pthread unlock needed
06967         if (this->allocated_by == MMSFBSurfaceAllocatedBy_dfb) {
06968 #ifdef  __HAVE_DIRECTFB__
06969             this->dfb_surface->Unlock(this->dfb_surface);
06970 #endif
06971         }
06972         return;
06973     }
06974 
06975     // which surface is to lock?
06976     MMSFBSurface *tolock = this;
06977     if (this->root_parent)
06978         tolock = this->root_parent;
06979     else
06980     if (this->parent)
06981         tolock = this->parent;
06982 
06983     if (tolock->TID != pthread_self())
06984         return;
06985 
06986     if (tolock->Lock_cnt==0)
06987         return;
06988 
06989     // unlock dfb surface?
06990     if ((tolock->surface_read_locked)&&(tolock->surface_read_lock_cnt == tolock->Lock_cnt)) {
06991         if (this->allocated_by == MMSFBSurfaceAllocatedBy_dfb) {
06992 #ifdef  __HAVE_DIRECTFB__
06993             this->dfb_surface->Unlock(this->dfb_surface);
06994 #endif
06995         }
06996         tolock->surface_read_locked = false;
06997         tolock->surface_read_lock_cnt = 0;
06998     }
06999     else
07000     if ((tolock->surface_write_locked)&&(tolock->surface_write_lock_cnt == tolock->Lock_cnt)) {
07001         if (this->allocated_by == MMSFBSurfaceAllocatedBy_dfb) {
07002 #ifdef  __HAVE_DIRECTFB__
07003             this->dfb_surface->Unlock(this->dfb_surface);
07004 #endif
07005         }
07006         tolock->surface_write_locked = false;
07007         tolock->surface_write_lock_cnt = 0;
07008     }
07009 
07010     tolock->Lock_cnt--;
07011 
07012     if (tolock->Lock_cnt == 0)
07013         tolock->Lock.unlock();
07014 }
07015 
07016 void MMSFBSurface::unlock() {
07017     unlock(true);
07018 }
07019 
07020 unsigned int MMSFBSurface::getNumberOfSubSurfaces() {
07021     return this->children.size();
07022 }
07023 
07024 MMSFBSurface *MMSFBSurface::getSubSurface(MMSFBRectangle *rect) {
07025 #ifdef  __HAVE_DIRECTFB__
07026     IDirectFBSurface *subsuf = NULL;
07027 #endif
07028     MMSFBSurface    *surface;
07029 
07030     // check if initialized
07031     INITCHECK;
07032 
07033     // finalize previous clear
07034     finClear();
07035 
07036 #ifdef USE_DFB_SUBSURFACE
07037     // get a sub surface
07038     DFBResult dfbres;
07039     if ((dfbres=this->dfb_surface->GetSubSurface(this->dfb_surface, rect, &subsuf)) != DFB_OK) {
07040         MMSFB_SetError(dfbres, "IDirectFBSurface::GetSubSurface() failed");
07041         return false;
07042     }
07043 
07044     // create a new surface instance
07045     surface = new MMSFBSurface(subsuf, this, rect);
07046 #else
07047     // create a new surface instance
07048     surface = new MMSFBSurface(this, rect);
07049 #endif
07050 
07051     if (!surface) {
07052 #ifdef USE_DFB_SUBSURFACE
07053         if (subsuf)
07054             subsuf->Release(subsuf);
07055 #endif
07056         MMSFB_SetError(0, "cannot create new instance of MMSFBSurface");
07057         return NULL;
07058     }
07059 
07060     // add to my list
07061     this->children.push_back(surface);
07062 
07063     return surface;
07064 }
07065 
07066 bool MMSFBSurface::setSubSurface(MMSFBRectangle *rect) {
07067 
07068     // check if initialized
07069     INITCHECK;
07070 
07071     // finalize previous clear
07072     finClear();
07073 
07074     // only sub surfaces can be moved
07075     if (!this->is_sub_surface)
07076         return false;
07077 
07078 //    lock();
07079 
07080     if (memcmp(rect, &(this->sub_surface_rect), sizeof(this->sub_surface_rect)) == 0) {
07081         /* nothing changed */
07082 //      unlock();
07083         return false;
07084     }
07085 
07086 #ifdef USE_DFB_SUBSURFACE
07087     /* because dfb has no IDirectFBSurface::setSubSurface(), allocate a new and release the old one */
07088     DFBResult dfbres;
07089     IDirectFBSurface *subsuf = NULL;
07090     if ((dfbres=this->parent->dfb_surface->GetSubSurface(this->parent->dfb_surface, rect, &subsuf)) != DFB_OK) {
07091         MMSFB_SetError(dfbres, "IDirectFBSurface::GetSubSurface() failed");
07092 //        unlock();
07093         return false;
07094     }
07095 
07096     if (this->dfb_surface)
07097         this->dfb_surface->Release(this->dfb_surface);
07098 
07099     this->dfb_surface = subsuf;
07100 
07101 #endif
07102 
07103     this->sub_surface_rect = *rect;
07104 
07105 #ifndef USE_DFB_SUBSURFACE
07106 
07107     getRealSubSurfacePos(NULL, true);
07108 
07109 #endif
07110 
07111 //    unlock();
07112 
07113     return true;
07114 }
07115 
07116 bool MMSFBSurface::setSubSurface(MMSFBRegion *region) {
07117     MMSFBRectangle rect;
07118 
07119     if (!region)
07120         return false;
07121 
07122     rect.x = region->x1;
07123     rect.y = region->y1;
07124     rect.w = region->x2 - region->x1 + 1;
07125     rect.h = region->y2 - region->y1 + 1;
07126 
07127     return setSubSurface(&rect);
07128 }
07129 
07130 bool MMSFBSurface::moveTo(int x, int y) {
07131     MMSFBRectangle rect;
07132 
07133     rect = this->sub_surface_rect;
07134     rect.x = x;
07135     rect.y = y;
07136 
07137     return setSubSurface(&rect);
07138 }
07139 
07140 bool MMSFBSurface::move(int x, int y) {
07141     MMSFBRectangle rect;
07142 
07143     rect = this->sub_surface_rect;
07144     rect.x += x;
07145     rect.y += y;
07146 
07147     return setSubSurface(&rect);
07148 }
07149 
07150 
07151 bool MMSFBSurface::dump2fcb(bool (*fcb)(char *, int, void *, int *), void *argp, int *argi,
07152                            int x, int y, int w, int h, MMSFBSurfaceDumpMode dumpmode) {
07153 #define D2FCB_ADDSTR1(f) {int l=sprintf(ob,f);if(!fcb(ob,l,argp,argi)){this->unlock();return false;}}
07154 #define D2FCB_ADDSTR2(f,v) {int l=sprintf(ob,f,v);if(!fcb(ob,l,argp,argi)){this->unlock();return false;}}
07155     // check inputs
07156     if (!fcb)
07157         return false;
07158     if ((x < 0)||(y < 0)||(w < 0)||(h < 0))
07159         return false;
07160     if (w == 0)
07161         w = this->config.w - x;
07162     if (h == 0)
07163         h = this->config.h - y;
07164     if ((x + w > this->config.w)||(y + h > this->config.h))
07165         return false;
07166 
07167     // finalize previous clear
07168     finClear();
07169 
07170     // set buffer
07171     char ob[65536];
07172 
07173     // get access to the surface memory
07174     unsigned char   *sbuf;
07175     int             pitch;
07176     this->lock(MMSFB_LOCK_READ, (void**)&sbuf, &pitch);
07177     if (!sbuf)
07178         return false;
07179 
07180     // print format
07181     sprintf(ob, "* %s: x=%d, y=%d, w=%d, h=%d",
07182                 getMMSFBPixelFormatString(this->config.surface_buffer->pixelformat).c_str(),
07183                 x, y, w, h);
07184     fcb(ob, strlen(ob), argp, argi);
07185 
07186     bool dumpok = false;
07187     if (dumpmode == MMSFBSURFACE_DUMPMODE_BYTE) {
07188         // dump byte-by-byte
07189         switch (this->config.surface_buffer->pixelformat) {
07190         case MMSFB_PF_I420:
07191         case MMSFB_PF_YV12:
07192         case MMSFB_PF_NV12:
07193         case MMSFB_PF_NV16:
07194         case MMSFB_PF_NV21:
07195         case MMSFB_PF_ARGB3565:
07196             // do not dump plane formats here
07197             break;
07198         default: {
07199                 // all other formats
07200                 MMSFBPixelDef pixeldef;
07201                 getBitsPerPixel(this->config.surface_buffer->pixelformat, &pixeldef);
07202                 int bits_pp = pixeldef.bits;
07203                 int bytes_pp = bits_pp / 8;
07204                 unsigned char *buf = sbuf + x * bytes_pp + y * pitch;
07205                 D2FCB_ADDSTR1("\n* byte-by-byte ****************************************************************");
07206                 for (int j = 0; j < h-y; j++) {
07207                     int i = j * pitch;
07208                     D2FCB_ADDSTR2("\n%02x", buf[i++]);
07209                     while (i < (w-x) * bytes_pp + j * pitch) {
07210                         D2FCB_ADDSTR2(",%02x", buf[i]);
07211                         i++;
07212                     }
07213                 }
07214                 dumpok = true;
07215             }
07216             break;
07217         }
07218     }
07219 
07220     if (!dumpok) {
07221         // dump pixels
07222         switch (this->config.surface_buffer->pixelformat) {
07223         case MMSFB_PF_ARGB:
07224         case MMSFB_PF_RGB32: {
07225                 int pitch_pix = pitch >> 2;
07226                 unsigned int *buf = (unsigned int*)sbuf + x + y * pitch_pix;
07227                 switch (this->config.surface_buffer->pixelformat) {
07228                 case MMSFB_PF_ARGB:
07229                     D2FCB_ADDSTR1("\n* aarrggbb hex (4-byte integer) ***********************************************");
07230                     break;
07231                 case MMSFB_PF_RGB32:
07232                     D2FCB_ADDSTR1("\n* --rrggbb hex (4-byte integer) ***********************************************");
07233                     break;
07234                 default:
07235                     break;
07236                 }
07237                 for (int j = 0; j < h-y; j++) {
07238                     int i = j * pitch_pix;
07239                     D2FCB_ADDSTR2("\n%08x", (int)buf[i++]);
07240                     while (i < (w-x) + j * pitch_pix) {
07241                         D2FCB_ADDSTR2(",%08x", (int)buf[i]);
07242                         i++;
07243                     }
07244                 }
07245                 D2FCB_ADDSTR1("\n*******************************************************************************");
07246             }
07247             break;
07248         case MMSFB_PF_BGR24: {
07249                 D2FCB_ADDSTR1("\n* bbggrr hex (3-byte) *********************************************************");
07250                 D2FCB_ADDSTR1("\nn/a");
07251                 D2FCB_ADDSTR1("\n*******************************************************************************");
07252             }
07253             break;
07254         case MMSFB_PF_RGB16:
07255         case MMSFB_PF_BGR555: {
07256                 int pitch_pix = pitch >> 1;
07257                 unsigned short int *buf = (unsigned short int*)sbuf + x + y * pitch_pix;
07258                 switch (this->config.surface_buffer->pixelformat) {
07259                 case MMSFB_PF_RGB16:
07260                     D2FCB_ADDSTR1("\n* rrrrrggggggbbbbb bin (2-byte integer) ***************************************");
07261                     break;
07262                 case MMSFB_PF_BGR555:
07263                     D2FCB_ADDSTR1("\n* 0bbbbbgggggrrrrr bin (2-byte integer) ***************************************");
07264                     break;
07265                 default:
07266                     break;
07267                 }
07268                 for (int j = 0; j < h-y; j++) {
07269                     int i = j * pitch_pix;
07270                     D2FCB_ADDSTR2("\n%04x", buf[i++]);
07271                     while (i < (w-x) + j * pitch_pix) {
07272                         D2FCB_ADDSTR2(",%04x", buf[i]);
07273                         i++;
07274                     }
07275                 }
07276                 D2FCB_ADDSTR1("\n*******************************************************************************");
07277             }
07278             break;
07279         case MMSFB_PF_I420:
07280         case MMSFB_PF_YV12: {
07281                 int pitch_pix = pitch;
07282                 unsigned char *buf_y;
07283                 unsigned char *buf_u = sbuf + pitch_pix * this->config.h + (x >> 1) + (y >> 1) * (pitch_pix >> 1);
07284                 unsigned char *buf_v = sbuf + pitch_pix * (this->config.h + (this->config.h >> 2)) + (x >> 1) + (y >> 1) * (pitch_pix >> 1);
07285                 if (this->config.surface_buffer->pixelformat == MMSFB_PF_YV12) {
07286                     buf_y = buf_u;
07287                     buf_u = buf_v;
07288                     buf_v = buf_y;
07289                 }
07290                 buf_y = sbuf + x + y * pitch_pix;
07291                 D2FCB_ADDSTR1("\n* Y plane *********************************************************************");
07292                 for (int j = 0; j < h-y; j++) {
07293                     int i = j * pitch_pix;
07294                     D2FCB_ADDSTR2("\n%02x", buf_y[i++]);
07295                     while (i < (w-x) + j * pitch_pix) {
07296                         D2FCB_ADDSTR2(",%02x", buf_y[i]);
07297                         i++;
07298                     }
07299                 }
07300                 D2FCB_ADDSTR1("\n* U plane *********************************************************************");
07301                 x = x >> 1;
07302                 y = y >> 1;
07303                 w = w >> 1;
07304                 h = h >> 1;
07305                 for (int j = 0; j < h-y; j++) {
07306                     int i = j * (pitch_pix >> 1);
07307                     D2FCB_ADDSTR2("\n%02x", buf_u[i++]);
07308                     while (i < (w-x) + j * (pitch_pix >> 1)) {
07309                         D2FCB_ADDSTR2(",%02x", buf_u[i]);
07310                         i++;
07311                     }
07312                 }
07313                 D2FCB_ADDSTR1("\n* V plane *********************************************************************");
07314                 for (int j = 0; j < h-y; j++) {
07315                     int i = j * (pitch_pix >> 1);
07316                     D2FCB_ADDSTR2("\n%02x", buf_v[i++]);
07317                     while (i < (w-x) + j * (pitch_pix >> 1)) {
07318                         D2FCB_ADDSTR2(",%02x", buf_v[i]);
07319                         i++;
07320                     }
07321                 }
07322                 D2FCB_ADDSTR1("\n*******************************************************************************");
07323             }
07324             break;
07325         default:
07326             // no dump routine for this pixelformat
07327             this->unlock();
07328             return false;
07329         }
07330     }
07331 
07332     // finalize
07333     this->unlock();
07334     D2FCB_ADDSTR1("\n");
07335     return true;
07336 }
07337 
07338 bool dump2buffer_fcb(char *buf, int len, void *argp, int *argi) {
07339     if (len >= *argi) return false;
07340     char *ap = *((char**)argp);
07341     memcpy(ap, buf, len);
07342     ap+= len;
07343     *((void**)argp) = ap;
07344     *argi = *argi - len;
07345     return true;
07346 }
07347 
07348 int MMSFBSurface::dump2buffer(char *out_buffer, int out_buffer_len, int x, int y, int w, int h,
07349                               MMSFBSurfaceDumpMode dumpmode) {
07350     int obl = out_buffer_len;
07351     if (dump2fcb(dump2buffer_fcb, (void*)(&out_buffer), &obl, x, y, w, h, dumpmode)) {
07352         out_buffer[out_buffer_len - obl] = 0;
07353         return out_buffer_len - obl;
07354     }
07355     return 0;
07356 }
07357 
07358 bool dump2file_fcb(char *buf, int len, void *argp, int *argi) {
07359     size_t ritems;
07360     ((MMSFile *)argp)->writeBuffer(buf, &ritems, 1, len);
07361     return true;
07362 }
07363 
07364 bool MMSFBSurface::dump2file(string filename, int x, int y, int w, int h,
07365                              MMSFBSurfaceDumpMode dumpmode) {
07366     MMSFile *mmsfile = new MMSFile(filename, MMSFM_WRITE);
07367     if (mmsfile) {
07368         if (dump2fcb(dump2file_fcb, mmsfile, NULL, x, y, w, h, dumpmode)) {
07369             delete mmsfile;
07370             return true;
07371         }
07372         delete mmsfile;
07373     }
07374     return false;
07375 }
07376 
07377 bool MMSFBSurface::dump2file(string filename, MMSFBSurfaceDumpMode dumpmode) {
07378     return dump2file(filename, 0, 0, 0, 0, dumpmode);
07379 }
07380 
07381 bool dump_fcb(char *buf, int len, void *argp, int *argi) {
07382     buf[len] = 0;
07383     printf("%s", buf);
07384     return true;
07385 }
07386 
07387 bool MMSFBSurface::dump(int x, int y, int w, int h,
07388                         MMSFBSurfaceDumpMode dumpmode) {
07389     if (dump2fcb(dump_fcb, NULL, NULL, x, y, w, h, dumpmode)) {
07390         printf("\n");
07391         return true;
07392     }
07393     return false;
07394 }
07395 
07396 bool MMSFBSurface::dump(MMSFBSurfaceDumpMode dumpmode) {
07397     return dump(0, 0, 0, 0, dumpmode);
07398 }
07399 
07400 bool mmsfb_create_cached_surface(MMSFBSurface **cs, int width, int height,
07401                                  MMSFBSurfacePixelFormat pixelformat) {
07402     if (!cs) return false;
07403 
07404     // check the properties of the existing surface
07405     if (*cs) {
07406         // check if old surface has the same dimension
07407         int w, h;
07408         (*cs)->getSize(&w, &h);
07409         if ((w != width) || (h != height)) {
07410             delete *cs;
07411             *cs = NULL;
07412         }
07413     }
07414 
07415     if (*cs) {
07416         // check if old surface has the same pixelformat
07417         MMSFBSurfacePixelFormat pf;
07418         (*cs)->getPixelFormat(&pf);
07419         if (pf != pixelformat) {
07420             delete *cs;
07421             *cs = NULL;
07422         }
07423     }
07424 
07425     if (!*cs) {
07426         // create new surface
07427         *cs = new MMSFBSurface(width, height, pixelformat);
07428     }
07429 
07430     return (*cs);
07431 }
07432 
07433 
07434 
07435 
07436 
07437 bool MMSFBSurface::blitARGBtoARGB(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
07438                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
07439                                     int x, int y) {
07440 #ifdef __HAVE_PF_ARGB__
07441     MMSFBSurfacePlanes dst_planes;
07442 
07443     if (extendedLock(source, src_planes, this, &dst_planes)) {
07444         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07445         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07446         MMSFBPERF_START_MEASURING;
07447             mmsfb_blit_argb_to_argb(
07448                     src_planes, src_height,
07449                     sx, sy, sw, sh,
07450                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
07451                     x, y);
07452         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
07453         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07454         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07455         extendedUnlock(source, this);
07456         return true;
07457     }
07458 #endif
07459 
07460     return false;
07461 }
07462 
07463 bool MMSFBSurface::blitARGBtoARGB_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
07464                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
07465                                     int x, int y) {
07466 #ifdef __HAVE_PF_ARGB__
07467     MMSFBSurfacePlanes dst_planes;
07468 
07469     if (extendedLock(source, src_planes, this, &dst_planes)) {
07470         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07471         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07472         MMSFBPERF_START_MEASURING;
07473             mmsfb_blit_blend_argb_to_argb(
07474                     src_planes, src_height,
07475                     sx, sy, sw, sh,
07476                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
07477                     x, y);
07478         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
07479         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07480         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07481         extendedUnlock(source, this);
07482         return true;
07483     }
07484 #endif
07485 
07486     return false;
07487 }
07488 
07489 bool MMSFBSurface::blitARGBtoARGB_BLEND_COLORALPHA(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
07490                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
07491                                     int x, int y) {
07492 #ifdef __HAVE_PF_ARGB__
07493     MMSFBSurfacePlanes dst_planes;
07494 
07495     if (extendedLock(source, src_planes, this, &dst_planes)) {
07496         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07497         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07498         MMSFBPERF_START_MEASURING;
07499             mmsfb_blit_blend_coloralpha_argb_to_argb(
07500                     src_planes, src_height,
07501                     sx, sy, sw, sh,
07502                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
07503                     x, y,
07504                     this->config.color.a);
07505         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
07506         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07507         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07508         extendedUnlock(source, this);
07509         return true;
07510     }
07511 #endif
07512 
07513     return false;
07514 }
07515 
07516 
07517 bool MMSFBSurface::blitARGBtoAiRGB_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
07518                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
07519                                     int x, int y) {
07520 #ifdef __HAVE_PF_ARGB__
07521 #ifdef __HAVE_PF_AiRGB__
07522     MMSFBSurfacePlanes dst_planes;
07523 
07524     if (extendedLock(source, src_planes, this, &dst_planes)) {
07525         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07526         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07527         MMSFBPERF_START_MEASURING;
07528             mmsfb_blit_blend_argb_to_airgb(
07529                     src_planes, src_height,
07530                     sx, sy, sw, sh,
07531                     (unsigned int *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
07532                     x, y);
07533         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
07534         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07535         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07536         extendedUnlock(source, this);
07537         return true;
07538     }
07539 #endif
07540 #endif
07541 
07542     return false;
07543 }
07544 
07545 
07546 bool MMSFBSurface::blitARGBtoRGB32(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
07547                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
07548                                     int x, int y) {
07549 #ifdef __HAVE_PF_ARGB__
07550 #ifdef __HAVE_PF_RGB32__
07551     MMSFBSurfacePlanes dst_planes;
07552 
07553     if (extendedLock(source, src_planes, this, &dst_planes)) {
07554         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07555         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07556         MMSFBPERF_START_MEASURING;
07557             mmsfb_blit_argb_to_rgb32(
07558                     src_planes, src_height,
07559                     sx, sy, sw, sh,
07560                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
07561                     x, y);
07562         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
07563         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07564         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07565         extendedUnlock(source, this);
07566         return true;
07567     }
07568 #endif
07569 #endif
07570 
07571     return false;
07572 }
07573 
07574 bool MMSFBSurface::blitARGBtoRGB32_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
07575                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
07576                                     int x, int y) {
07577 #ifdef __HAVE_PF_ARGB__
07578 #ifdef __HAVE_PF_RGB32__
07579     MMSFBSurfacePlanes dst_planes;
07580 
07581     if (extendedLock(source, src_planes, this, &dst_planes)) {
07582         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07583         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07584         MMSFBPERF_START_MEASURING;
07585             mmsfb_blit_blend_argb_to_rgb32(
07586                     src_planes, src_height,
07587                     sx, sy, sw, sh,
07588                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
07589                     x, y);
07590         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
07591         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07592         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07593         extendedUnlock(source, this);
07594         return true;
07595     }
07596 #endif
07597 #endif
07598 
07599     return false;
07600 }
07601 
07602 bool MMSFBSurface::blitARGBtoRGB32_BLEND_COLORALPHA(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
07603                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
07604                                     int x, int y) {
07605 #ifdef __HAVE_PF_ARGB__
07606 #ifdef __HAVE_PF_RGB32__
07607     MMSFBSurfacePlanes dst_planes;
07608 
07609     if (extendedLock(source, src_planes, this, &dst_planes)) {
07610         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07611         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07612         MMSFBPERF_START_MEASURING;
07613             mmsfb_blit_blend_coloralpha_argb_to_rgb32(
07614                     src_planes, src_height,
07615                     sx, sy, sw, sh,
07616                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
07617                     x, y,
07618                     this->config.color.a);
07619         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
07620         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07621         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07622         extendedUnlock(source, this);
07623         return true;
07624     }
07625 #endif
07626 #endif
07627 
07628     return false;
07629 }
07630 
07631 bool MMSFBSurface::blitARGBtoRGB32_COLORALPHA(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
07632                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
07633                                     int x, int y) {
07634 #ifdef __HAVE_PF_ARGB__
07635 #ifdef __HAVE_PF_RGB32__
07636     MMSFBSurfacePlanes dst_planes;
07637 
07638     if (extendedLock(source, src_planes, this, &dst_planes)) {
07639         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07640         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07641         MMSFBPERF_START_MEASURING;
07642             mmsfb_blit_coloralpha_argb_to_rgb32(
07643                     src_planes, src_height,
07644                     sx, sy, sw, sh,
07645                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
07646                     x, y,
07647                     this->config.color.a);
07648         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
07649         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07650         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07651         extendedUnlock(source, this);
07652         return true;
07653     }
07654 #endif
07655 #endif
07656 
07657     return false;
07658 }
07659 
07660 bool MMSFBSurface::blitARGBtoRGB16(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
07661                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
07662                                     int x, int y) {
07663 #ifdef __HAVE_PF_ARGB__
07664 #ifdef __HAVE_PF_RGB16__
07665     MMSFBSurfacePlanes dst_planes;
07666 
07667     if (extendedLock(source, src_planes, this, &dst_planes)) {
07668         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07669         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07670         MMSFBPERF_START_MEASURING;
07671             mmsfb_blit_argb_to_rgb16(src_planes, src_height,
07672                                      sx, sy, sw, sh,
07673                                      (unsigned short int *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
07674                                      x, y);
07675         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
07676         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07677         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07678         extendedUnlock(source, this);
07679         return true;
07680     }
07681 #endif
07682 #endif
07683 
07684     return false;
07685 }
07686 
07687 bool MMSFBSurface::blitARGBtoRGB16_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
07688                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
07689                                     int x, int y) {
07690 #ifdef __HAVE_PF_ARGB__
07691 #ifdef __HAVE_PF_RGB16__
07692     MMSFBSurfacePlanes dst_planes;
07693 
07694     if (extendedLock(source, src_planes, this, &dst_planes)) {
07695         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07696         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07697         MMSFBPERF_START_MEASURING;
07698             mmsfb_blit_blend_argb_to_rgb16(src_planes, src_height,
07699                                            sx, sy, sw, sh,
07700                                            &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
07701                                            x, y);
07702         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
07703         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07704         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07705         extendedUnlock(source, this);
07706         return true;
07707     }
07708 #endif
07709 #endif
07710 
07711     return false;
07712 }
07713 
07714 bool MMSFBSurface::blitARGBtoARGB3565(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
07715                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
07716                                     int x, int y) {
07717 #ifdef __HAVE_PF_ARGB__
07718 #ifdef __HAVE_PF_ARGB3565__
07719     MMSFBSurfacePlanes dst_planes;
07720 
07721     if (extendedLock(source, src_planes, this, &dst_planes)) {
07722         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07723         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07724         MMSFBPERF_START_MEASURING;
07725             mmsfb_blit_argb_to_argb3565(
07726                     src_planes, src_height,
07727                     sx, sy, sw, sh,
07728                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
07729                     x, y);
07730         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
07731         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07732         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07733         extendedUnlock(source, this);
07734         return true;
07735     }
07736 #endif
07737 #endif
07738 
07739     return false;
07740 }
07741 
07742 bool MMSFBSurface::blitARGBtoARGB3565_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
07743                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
07744                                     int x, int y) {
07745 #ifdef __HAVE_PF_ARGB__
07746 #ifdef __HAVE_PF_ARGB3565__
07747     MMSFBSurfacePlanes dst_planes;
07748 
07749     if (extendedLock(source, src_planes, this, &dst_planes)) {
07750         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07751         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07752         MMSFBPERF_START_MEASURING;
07753             mmsfb_blit_blend_argb_to_argb3565(
07754                     src_planes, src_height,
07755                     sx, sy, sw, sh,
07756                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
07757                     x, y);
07758         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
07759         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07760         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07761         extendedUnlock(source, this);
07762         return true;
07763     }
07764 #endif
07765 #endif
07766 
07767     return false;
07768 }
07769 
07770 
07771 bool MMSFBSurface::blitARGBtoYV12(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
07772                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
07773                                     int x, int y) {
07774 #ifdef __HAVE_PF_ARGB__
07775 #ifdef __HAVE_PF_YV12__
07776     MMSFBSurfacePlanes dst_planes;
07777 
07778     if (extendedLock(source, src_planes, this, &dst_planes)) {
07779         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07780         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07781         MMSFBPERF_START_MEASURING;
07782             mmsfb_blit_argb_to_yv12(
07783                     src_planes, src_height,
07784                     sx, sy, sw, sh,
07785                     (unsigned char *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
07786                     x, y);
07787         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
07788         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07789         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07790         extendedUnlock(source, this);
07791         return true;
07792     }
07793 #endif
07794 #endif
07795 
07796     return false;
07797 }
07798 
07799 bool MMSFBSurface::blitARGBtoYV12_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
07800                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
07801                                     int x, int y) {
07802 #ifdef __HAVE_PF_ARGB__
07803 #ifdef __HAVE_PF_YV12__
07804     MMSFBSurfacePlanes dst_planes;
07805 
07806     if (extendedLock(source, src_planes, this, &dst_planes)) {
07807         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07808         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07809         MMSFBPERF_START_MEASURING;
07810             mmsfb_blit_blend_argb_to_yv12(
07811                     src_planes, src_height,
07812                     sx, sy, sw, sh,
07813                     (unsigned char *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
07814                     x, y);
07815         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
07816         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07817         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07818         extendedUnlock(source, this);
07819         return true;
07820     }
07821 #endif
07822 #endif
07823 
07824     return false;
07825 }
07826 
07827 bool MMSFBSurface::blitARGBtoYV12_BLEND_COLORALPHA(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
07828                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
07829                                     int x, int y) {
07830 #ifdef __HAVE_PF_ARGB__
07831 #ifdef __HAVE_PF_YV12__
07832     MMSFBSurfacePlanes dst_planes;
07833 
07834     if (extendedLock(source, src_planes, this, &dst_planes)) {
07835         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07836         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07837         MMSFBPERF_START_MEASURING;
07838             mmsfb_blit_blend_coloralpha_argb_to_yv12(
07839                     src_planes, src_height,
07840                     sx, sy, sw, sh,
07841                     (unsigned char *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
07842                     x, y,
07843                     this->config.color.a);
07844         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
07845         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07846         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07847         extendedUnlock(source, this);
07848         return true;
07849     }
07850 #endif
07851 #endif
07852 
07853     return false;
07854 }
07855 
07856 bool MMSFBSurface::blitARGBtoRGB24(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
07857                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
07858                                     int x, int y) {
07859 #ifdef __HAVE_PF_ARGB__
07860 #ifdef __HAVE_PF_RGB24__
07861     MMSFBSurfacePlanes dst_planes;
07862 
07863     if (extendedLock(source, src_planes, this, &dst_planes)) {
07864         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07865         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07866         MMSFBPERF_START_MEASURING;
07867             mmsfb_blit_argb_to_rgb24(
07868                     src_planes, src_height,
07869                     sx, sy, sw, sh,
07870                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
07871                     x, y);
07872         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
07873         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07874         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07875         extendedUnlock(source, this);
07876         return true;
07877     }
07878 #endif
07879 #endif
07880 
07881     return false;
07882 }
07883 
07884 bool MMSFBSurface::blitARGBtoRGB24_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
07885                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
07886                                     int x, int y) {
07887 #ifdef __HAVE_PF_ARGB__
07888 #ifdef __HAVE_PF_RGB24__
07889     MMSFBSurfacePlanes dst_planes;
07890 
07891     if (extendedLock(source, src_planes, this, &dst_planes)) {
07892         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07893         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07894         MMSFBPERF_START_MEASURING;
07895             mmsfb_blit_blend_argb_to_rgb24(
07896                     src_planes, src_height,
07897                     sx, sy, sw, sh,
07898                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
07899                     x, y);
07900         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
07901         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07902         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07903         extendedUnlock(source, this);
07904         return true;
07905     }
07906 #endif
07907 #endif
07908 
07909     return false;
07910 }
07911 
07912 bool MMSFBSurface::blitARGBtoBGR24_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
07913                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
07914                                     int x, int y) {
07915 #ifdef __HAVE_PF_ARGB__
07916 #ifdef __HAVE_PF_BGR24__
07917     MMSFBSurfacePlanes dst_planes;
07918 
07919     if (extendedLock(source, src_planes, this, &dst_planes)) {
07920         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07921         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07922         MMSFBPERF_START_MEASURING;
07923             mmsfb_blit_blend_argb_to_bgr24(
07924                     src_planes, src_height,
07925                     sx, sy, sw, sh,
07926                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
07927                     x, y);
07928         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
07929         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07930         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07931         extendedUnlock(source, this);
07932         return true;
07933     }
07934 #endif
07935 #endif
07936 
07937     return false;
07938 }
07939 
07940 bool MMSFBSurface::blitARGBtoBGR24_BLEND_COLORALPHA(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
07941                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
07942                                     int x, int y) {
07943 #ifdef __HAVE_PF_ARGB__
07944 #ifdef __HAVE_PF_BGR24__
07945     MMSFBSurfacePlanes dst_planes;
07946 
07947     if (extendedLock(source, src_planes, this, &dst_planes)) {
07948         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07949         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07950         MMSFBPERF_START_MEASURING;
07951             mmsfb_blit_blend_coloralpha_argb_to_bgr24(
07952                     src_planes, src_height,
07953                     sx, sy, sw, sh,
07954                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
07955                     x, y,
07956                     this->config.color.a);
07957         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
07958         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07959         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07960         extendedUnlock(source, this);
07961         return true;
07962     }
07963 #endif
07964 #endif
07965 
07966     return false;
07967 }
07968 
07969 bool MMSFBSurface::blitARGBtoBGR555_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
07970                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
07971                                     int x, int y) {
07972 #ifdef __HAVE_PF_ARGB__
07973 #ifdef __HAVE_PF_BGR555__
07974     MMSFBSurfacePlanes dst_planes;
07975 
07976     if (extendedLock(source, src_planes, this, &dst_planes)) {
07977         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07978         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07979         MMSFBPERF_START_MEASURING;
07980             mmsfb_blit_blend_argb_to_bgr555(
07981                     src_planes, src_height,
07982                     sx, sy, sw, sh,
07983                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
07984                     x, y);
07985         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
07986         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
07987         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
07988         extendedUnlock(source, this);
07989         return true;
07990     }
07991 #endif
07992 #endif
07993 
07994     return false;
07995 }
07996 
07997 bool MMSFBSurface::blitRGB32toRGB32(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
07998                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
07999                                     int x, int y) {
08000 #ifdef __HAVE_PF_RGB32__
08001     MMSFBSurfacePlanes dst_planes;
08002 
08003     if (extendedLock(source, src_planes, this, &dst_planes)) {
08004         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08005         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08006         MMSFBPERF_START_MEASURING;
08007             mmsfb_blit_rgb32_to_rgb32(
08008                     src_planes, src_height,
08009                     sx, sy, sw, sh,
08010                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08011                     x, y);
08012         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08013         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08014         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08015         extendedUnlock(source, this);
08016         return true;
08017     }
08018 #endif
08019 
08020     return false;
08021 }
08022 
08023 bool MMSFBSurface::blitRGB32toARGB(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08024                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08025                                     int x, int y) {
08026 #ifdef __HAVE_PF_RGB32__
08027     MMSFBSurfacePlanes dst_planes;
08028 
08029     if (extendedLock(source, src_planes, this, &dst_planes)) {
08030         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08031         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08032         MMSFBPERF_START_MEASURING;
08033             mmsfb_blit_rgb32_to_argb(
08034                     src_planes, src_height,
08035                     sx, sy, sw, sh,
08036                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08037                     x, y);
08038         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08039         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08040         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08041         extendedUnlock(source, this);
08042         return true;
08043     }
08044 #endif
08045 
08046     return false;
08047 }
08048 
08049 bool MMSFBSurface::blitRGB32toRGB32_COLORALPHA(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08050                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08051                                     int x, int y) {
08052 #ifdef __HAVE_PF_RGB32__
08053     MMSFBSurfacePlanes dst_planes;
08054 
08055     if (extendedLock(source, src_planes, this, &dst_planes)) {
08056         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08057         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08058         MMSFBPERF_START_MEASURING;
08059             mmsfb_blit_coloralpha_rgb32_to_rgb32(
08060                     src_planes, src_height,
08061                     sx, sy, sw, sh,
08062                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08063                     x, y,
08064                     this->config.color.a);
08065         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08066         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08067         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08068         extendedUnlock(source, this);
08069         return true;
08070     }
08071 #endif
08072 
08073     return false;
08074 }
08075 
08076 bool MMSFBSurface::blitRGB16toRGB16(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08077                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08078                                     int x, int y) {
08079 #ifdef __HAVE_PF_RGB16__
08080     MMSFBSurfacePlanes dst_planes;
08081 
08082     if (extendedLock(source, src_planes, this, &dst_planes)) {
08083         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08084         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08085         MMSFBPERF_START_MEASURING;
08086             mmsfb_blit_rgb16_to_rgb16(
08087                     src_planes, src_height,
08088                     sx, sy, sw, sh,
08089                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08090                     x, y);
08091         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08092         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08093         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08094         extendedUnlock(source, this);
08095         return true;
08096     }
08097 #endif
08098 
08099     return false;
08100 }
08101 
08102 bool MMSFBSurface::blitRGB16toARGB(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08103                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08104                                     int x, int y) {
08105 #ifdef __HAVE_PF_RGB16__
08106 #ifdef __HAVE_PF_ARGB__
08107     MMSFBSurfacePlanes dst_planes;
08108 
08109     if (extendedLock(source, src_planes, this, &dst_planes)) {
08110         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08111         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08112         MMSFBPERF_START_MEASURING;
08113             mmsfb_blit_rgb16_to_argb(
08114                     src_planes, src_height,
08115                     sx, sy, sw, sh,
08116                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08117                     x, y);
08118         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08119         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08120         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08121         extendedUnlock(source, this);
08122         return true;
08123     }
08124 #endif
08125 #endif
08126 
08127     return false;
08128 }
08129 
08130 bool MMSFBSurface::blitRGB16toRGB32(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08131                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08132                                     int x, int y) {
08133 #ifdef __HAVE_PF_RGB16__
08134 #ifdef __HAVE_PF_RGB32__
08135     MMSFBSurfacePlanes dst_planes;
08136 
08137     if (extendedLock(source, src_planes, this, &dst_planes)) {
08138         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08139         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08140         MMSFBPERF_START_MEASURING;
08141             mmsfb_blit_rgb16_to_rgb32(
08142                     src_planes, src_height,
08143                     sx, sy, sw, sh,
08144                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08145                     x, y);
08146         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08147         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08148         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08149         extendedUnlock(source, this);
08150         return true;
08151     }
08152 #endif
08153 #endif
08154 
08155     return false;
08156 }
08157 
08158 bool MMSFBSurface::blitAiRGBtoAiRGB(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08159                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08160                                     int x, int y) {
08161 #ifdef __HAVE_PF_AiRGB__
08162     MMSFBSurfacePlanes dst_planes;
08163 
08164     if (extendedLock(source, src_planes, this, &dst_planes)) {
08165         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08166         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08167         MMSFBPERF_START_MEASURING;
08168             mmsfb_blit_airgb_to_airgb(src_planes, src_height,
08169                                       sx, sy, sw, sh,
08170                                       &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08171                                       x, y);
08172         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08173         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08174         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08175         extendedUnlock(source, this);
08176         return true;
08177     }
08178 #endif
08179 
08180     return false;
08181 }
08182 
08183 bool MMSFBSurface::blitAiRGBtoAiRGB_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08184                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08185                                     int x, int y) {
08186 #ifdef __HAVE_PF_AiRGB__
08187     MMSFBSurfacePlanes dst_planes;
08188 
08189     if (extendedLock(source, src_planes, this, &dst_planes)) {
08190         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08191         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08192         MMSFBPERF_START_MEASURING;
08193             mmsfb_blit_blend_airgb_to_airgb(src_planes, src_height,
08194                                             sx, sy, sw, sh,
08195                                             (unsigned int *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08196                                             x, y);
08197         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08198         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08199         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08200         extendedUnlock(source, this);
08201         return true;
08202     }
08203 #endif
08204 
08205     return false;
08206 }
08207 
08208 bool MMSFBSurface::blitAiRGBtoAiRGB_BLEND_COLORALPHA(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08209                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08210                                     int x, int y) {
08211 #ifdef __HAVE_PF_AiRGB__
08212     MMSFBSurfacePlanes dst_planes;
08213 
08214     if (extendedLock(source, src_planes, this, &dst_planes)) {
08215         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08216         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08217         MMSFBPERF_START_MEASURING;
08218             mmsfb_blit_blend_coloralpha_airgb_to_airgb(src_planes, src_height,
08219                                                        sx, sy, sw, sh,
08220                                                        (unsigned int *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08221                                                        x, y,
08222                                                        this->config.color.a);
08223         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08224         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08225         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08226         extendedUnlock(source, this);
08227         return true;
08228     }
08229 #endif
08230 
08231     return false;
08232 }
08233 
08234 bool MMSFBSurface::blitAiRGBtoARGB(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08235                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08236                                     int x, int y) {
08237 #ifdef __HAVE_PF_ARGB__
08238 #ifdef __HAVE_PF_AiRGB__
08239     MMSFBSurfacePlanes dst_planes;
08240 
08241     if (extendedLock(source, src_planes, this, &dst_planes)) {
08242         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08243         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08244         MMSFBPERF_START_MEASURING;
08245             mmsfb_blit_airgb_to_argb(
08246                     src_planes, src_height,
08247                     sx, sy, sw, sh,
08248                     (unsigned int *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08249                     x, y);
08250         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08251         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08252         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08253         extendedUnlock(source, this);
08254         return true;
08255     }
08256 #endif
08257 #endif
08258 
08259     return false;
08260 }
08261 
08262 bool MMSFBSurface::blitAiRGBtoARGB_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08263                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08264                                     int x, int y) {
08265 #ifdef __HAVE_PF_ARGB__
08266 #ifdef __HAVE_PF_AiRGB__
08267     MMSFBSurfacePlanes dst_planes;
08268 
08269     if (extendedLock(source, src_planes, this, &dst_planes)) {
08270         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08271         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08272         MMSFBPERF_START_MEASURING;
08273             mmsfb_blit_blend_airgb_to_argb(
08274                     src_planes, src_height,
08275                     sx, sy, sw, sh,
08276                     (unsigned int *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08277                     x, y);
08278         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08279         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08280         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08281         extendedUnlock(source, this);
08282         return true;
08283     }
08284 #endif
08285 #endif
08286 
08287     return false;
08288 }
08289 
08290 bool MMSFBSurface::blitAiRGBtoRGB16(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08291                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08292                                     int x, int y) {
08293 #ifdef __HAVE_PF_AiRGB__
08294 #ifdef __HAVE_PF_RGB16__
08295     MMSFBSurfacePlanes dst_planes;
08296 
08297     if (extendedLock(source, src_planes, this, &dst_planes)) {
08298         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08299         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08300         MMSFBPERF_START_MEASURING;
08301             mmsfb_blit_airgb_to_rgb16(src_planes, src_height,
08302                                       sx, sy, sw, sh,
08303                                       (unsigned short int *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08304                                       x, y);
08305         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08306         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08307         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08308         extendedUnlock(source, this);
08309         return true;
08310     }
08311 #endif
08312 #endif
08313 
08314     return false;
08315 }
08316 
08317 bool MMSFBSurface::blitAiRGBtoRGB16_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08318                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08319                                     int x, int y) {
08320 #ifdef __HAVE_PF_AiRGB__
08321 #ifdef __HAVE_PF_RGB16__
08322     MMSFBSurfacePlanes dst_planes;
08323 
08324     if (extendedLock(source, src_planes, this, &dst_planes)) {
08325         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08326         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08327         MMSFBPERF_START_MEASURING;
08328             mmsfb_blit_blend_airgb_to_rgb16(src_planes, src_height,
08329                                             sx, sy, sw, sh,
08330                                             (unsigned short int *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08331                                             x, y);
08332         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08333         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08334         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08335         extendedUnlock(source, this);
08336         return true;
08337     }
08338 #endif
08339 #endif
08340 
08341     return false;
08342 }
08343 
08344 bool MMSFBSurface::blitAYUVtoAYUV(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08345                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08346                                     int x, int y) {
08347 #ifdef __HAVE_PF_AYUV__
08348     MMSFBSurfacePlanes dst_planes;
08349 
08350     if (extendedLock(source, src_planes, this, &dst_planes)) {
08351         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08352         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08353         MMSFBPERF_START_MEASURING;
08354             mmsfb_blit_ayuv_to_ayuv(src_planes, src_height,
08355                                     sx, sy, sw, sh,
08356                                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08357                                     x, y);
08358         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08359         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08360         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08361         extendedUnlock(source, this);
08362         return true;
08363     }
08364 #endif
08365 
08366     return false;
08367 }
08368 
08369 bool MMSFBSurface::blitAYUVtoAYUV_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08370                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08371                                     int x, int y) {
08372 #ifdef __HAVE_PF_AYUV__
08373     MMSFBSurfacePlanes dst_planes;
08374 
08375     if (extendedLock(source, src_planes, this, &dst_planes)) {
08376         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08377         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08378         MMSFBPERF_START_MEASURING;
08379             mmsfb_blit_blend_ayuv_to_ayuv(src_planes, src_height,
08380                                           sx, sy, sw, sh,
08381                                           (unsigned int *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08382                                           x, y);
08383         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08384         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08385         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08386         extendedUnlock(source, this);
08387         return true;
08388     }
08389 #endif
08390 
08391     return false;
08392 }
08393 
08394 bool MMSFBSurface::blitAYUVtoAYUV_BLEND_COLORALPHA(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08395                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08396                                     int x, int y) {
08397 #ifdef __HAVE_PF_AYUV__
08398     MMSFBSurfacePlanes dst_planes;
08399 
08400     if (extendedLock(source, src_planes, this, &dst_planes)) {
08401         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08402         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08403         MMSFBPERF_START_MEASURING;
08404             mmsfb_blit_blend_coloralpha_ayuv_to_ayuv(src_planes, src_height,
08405                                                      sx, sy, sw, sh,
08406                                                      (unsigned int *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08407                                                      x, y,
08408                                                      this->config.color.a);
08409         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08410         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08411         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08412         extendedUnlock(source, this);
08413         return true;
08414     }
08415 #endif
08416 
08417     return false;
08418 }
08419 
08420 bool MMSFBSurface::blitAYUVtoRGB16(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08421                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08422                                     int x, int y) {
08423 #ifdef __HAVE_PF_AYUV__
08424 #ifdef __HAVE_PF_RGB16__
08425     MMSFBSurfacePlanes dst_planes;
08426 
08427     if (extendedLock(source, src_planes, this, &dst_planes)) {
08428         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08429         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08430         MMSFBPERF_START_MEASURING;
08431             mmsfb_blit_ayuv_to_rgb16(src_planes, src_height,
08432                                      sx, sy, sw, sh,
08433                                      (unsigned short int *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08434                                      x, y);
08435         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08436         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08437         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08438         extendedUnlock(source, this);
08439         return true;
08440     }
08441 #endif
08442 #endif
08443 
08444     return false;
08445 }
08446 
08447 bool MMSFBSurface::blitAYUVtoRGB16_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08448                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08449                                     int x, int y) {
08450 #ifdef __HAVE_PF_AYUV__
08451 #ifdef __HAVE_PF_RGB16__
08452     MMSFBSurfacePlanes dst_planes;
08453 
08454     if (extendedLock(source, src_planes, this, &dst_planes)) {
08455         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08456         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08457         MMSFBPERF_START_MEASURING;
08458             mmsfb_blit_blend_ayuv_to_rgb16(src_planes, src_height,
08459                                            sx, sy, sw, sh,
08460                                            (unsigned short int *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08461                                            x, y);
08462         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08463         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08464         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08465         extendedUnlock(source, this);
08466         return true;
08467     }
08468 #endif
08469 #endif
08470 
08471     return false;
08472 }
08473 
08474 bool MMSFBSurface::blitAYUVtoYV12_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08475                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08476                                     int x, int y) {
08477 #ifdef __HAVE_PF_AYUV__
08478 #ifdef __HAVE_PF_YV12__
08479     MMSFBSurfacePlanes dst_planes;
08480 
08481     if (extendedLock(source, src_planes, this, &dst_planes)) {
08482         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08483         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08484         MMSFBPERF_START_MEASURING;
08485             mmsfb_blit_blend_ayuv_to_yv12(src_planes, src_height,
08486                                           sx, sy, sw, sh,
08487                                           (unsigned char *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08488                                           x, y);
08489         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08490         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08491         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08492         extendedUnlock(source, this);
08493         return true;
08494     }
08495 #endif
08496 #endif
08497 
08498     return false;
08499 }
08500 
08501 bool MMSFBSurface::blitAYUVtoYV12_BLEND_COLORALPHA(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08502                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08503                                     int x, int y) {
08504 #ifdef __HAVE_PF_AYUV__
08505 #ifdef __HAVE_PF_YV12__
08506     MMSFBSurfacePlanes dst_planes;
08507 
08508     if (extendedLock(source, src_planes, this, &dst_planes)) {
08509         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08510         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08511         MMSFBPERF_START_MEASURING;
08512             mmsfb_blit_blend_coloralpha_ayuv_to_yv12(src_planes, src_height,
08513                                                      sx, sy, sw, sh,
08514                                                      (unsigned char *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08515                                                      x, y,
08516                                                      this->config.color.a);
08517         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08518         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08519         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08520         extendedUnlock(source, this);
08521         return true;
08522     }
08523 #endif
08524 #endif
08525 
08526     return false;
08527 }
08528 
08529 bool MMSFBSurface::blitYV12toYV12(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08530                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08531                                     int x, int y) {
08532 #ifdef __HAVE_PF_YV12__
08533     MMSFBSurfacePlanes dst_planes;
08534 
08535     if (extendedLock(source, src_planes, this, &dst_planes)) {
08536         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08537         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08538         MMSFBPERF_START_MEASURING;
08539             mmsfb_blit_yv12_to_yv12(src_planes, src_height,
08540                                     sx, sy, sw, sh,
08541                                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08542                                     x, y);
08543         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08544         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08545         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08546         extendedUnlock(source, this);
08547         return true;
08548     }
08549 #endif
08550 
08551     return false;
08552 }
08553 
08554 bool MMSFBSurface::blitYV12toRGB32(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08555                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08556                                     int x, int y) {
08557 #ifdef __HAVE_PF_YV12__
08558 #ifdef __HAVE_PF_RGB32__
08559     MMSFBSurfacePlanes dst_planes;
08560 
08561     if (extendedLock(source, src_planes, this, &dst_planes)) {
08562         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08563         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08564         MMSFBPERF_START_MEASURING;
08565             mmsfb_blit_yv12_to_rgb32(src_planes, src_height,
08566                                      sx, sy, sw, sh,
08567                                      (unsigned int *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08568                                      x, y);
08569         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08570         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08571         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08572         extendedUnlock(source, this);
08573         return true;
08574     }
08575 #endif
08576 #endif
08577 
08578     return false;
08579 }
08580 
08581 bool MMSFBSurface::blitI420toI420(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08582                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08583                                     int x, int y) {
08584 #ifdef __HAVE_PF_I420__
08585     MMSFBSurfacePlanes dst_planes;
08586 
08587     if (extendedLock(source, src_planes, this, &dst_planes)) {
08588         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08589         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08590         MMSFBPERF_START_MEASURING;
08591             mmsfb_blit_i420_to_i420(src_planes, src_height,
08592                                     sx, sy, sw, sh,
08593                                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08594                                     x, y);
08595         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08596         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08597         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08598         extendedUnlock(source, this);
08599         return true;
08600     }
08601 #endif
08602 
08603     return false;
08604 }
08605 
08606 bool MMSFBSurface::blitI420toYV12(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08607                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08608                                     int x, int y) {
08609 #ifdef __HAVE_PF_I420__
08610 #ifdef __HAVE_PF_YV12__
08611     MMSFBSurfacePlanes dst_planes;
08612 
08613     if (extendedLock(source, src_planes, this, &dst_planes)) {
08614         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08615         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08616         MMSFBPERF_START_MEASURING;
08617             mmsfb_blit_i420_to_yv12(
08618                     src_planes, src_height,
08619                     sx, sy, sw, sh,
08620                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08621                     x, y);
08622         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08623         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08624         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08625         extendedUnlock(source, this);
08626         return true;
08627     }
08628 #endif
08629 #endif
08630 
08631     return false;
08632 }
08633 
08634 bool MMSFBSurface::blitYUY2toYUY2(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08635                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08636                                     int x, int y) {
08637 #ifdef __HAVE_PF_YUY2__
08638     MMSFBSurfacePlanes dst_planes;
08639 
08640     if (extendedLock(source, src_planes, this, &dst_planes)) {
08641         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08642         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08643         MMSFBPERF_START_MEASURING;
08644             mmsfb_blit_yuy2_to_yuy2(
08645                     src_planes, src_height,
08646                     sx, sy, sw, sh,
08647                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08648                     x, y);
08649         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08650         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08651         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08652         extendedUnlock(source, this);
08653         return true;
08654     }
08655 #endif
08656 
08657     return false;
08658 }
08659 
08660 bool MMSFBSurface::blitYUY2toYV12(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08661                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08662                                     int x, int y) {
08663 #ifdef __HAVE_PF_YUY2__
08664 #ifdef __HAVE_PF_YV12__
08665     MMSFBSurfacePlanes dst_planes;
08666 
08667     if (extendedLock(source, src_planes, this, &dst_planes)) {
08668         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08669         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08670         MMSFBPERF_START_MEASURING;
08671             mmsfb_blit_yuy2_to_yv12(
08672                     src_planes, src_height,
08673                     sx, sy, sw, sh,
08674                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08675                     x, y);
08676         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08677         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08678         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08679         extendedUnlock(source, this);
08680         return true;
08681     }
08682 #endif
08683 #endif
08684 
08685     return false;
08686 }
08687 
08688 bool MMSFBSurface::blitRGB24toRGB24(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08689                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08690                                     int x, int y) {
08691 #ifdef __HAVE_PF_RGB24__
08692     MMSFBSurfacePlanes dst_planes;
08693 
08694     if (extendedLock(source, src_planes, this, &dst_planes)) {
08695         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08696         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08697         MMSFBPERF_START_MEASURING;
08698             mmsfb_blit_rgb24_to_rgb24(src_planes, src_height,
08699                                       sx, sy, sw, sh,
08700                                       &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08701                                       x, y);
08702         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08703         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08704         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08705         extendedUnlock(source, this);
08706         return true;
08707     }
08708 #endif
08709 
08710     return false;
08711 }
08712 
08713 bool MMSFBSurface::blitRGB24toARGB(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08714                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08715                                     int x, int y) {
08716 #ifdef __HAVE_PF_RGB24__
08717 #ifdef __HAVE_PF_ARGB__
08718     MMSFBSurfacePlanes dst_planes;
08719 
08720     if (extendedLock(source, src_planes, this, &dst_planes)) {
08721         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08722         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08723         MMSFBPERF_START_MEASURING;
08724             mmsfb_blit_rgb24_to_argb(src_planes, src_height,
08725                                     sx, sy, sw, sh,
08726                                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08727                                     x, y);
08728         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08729         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08730         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08731         extendedUnlock(source, this);
08732         return true;
08733     }
08734 #endif
08735 #endif
08736 
08737     return false;
08738 }
08739 
08740 bool MMSFBSurface::blitRGB24toRGB32(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08741                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08742                                     int x, int y) {
08743 #ifdef __HAVE_PF_RGB24__
08744 #ifdef __HAVE_PF_RGB32__
08745     MMSFBSurfacePlanes dst_planes;
08746 
08747     if (extendedLock(source, src_planes, this, &dst_planes)) {
08748         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08749         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08750         MMSFBPERF_START_MEASURING;
08751             mmsfb_blit_rgb24_to_rgb32(src_planes, src_height,
08752                                       sx, sy, sw, sh,
08753                                       &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08754                                       x, y);
08755         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08756         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08757         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08758         extendedUnlock(source, this);
08759         return true;
08760     }
08761 #endif
08762 #endif
08763 
08764     return false;
08765 }
08766 
08767 bool MMSFBSurface::blitRGB24toYV12(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08768                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08769                                     int x, int y) {
08770 #ifdef __HAVE_PF_RGB24__
08771 #ifdef __HAVE_PF_YV12__
08772     MMSFBSurfacePlanes dst_planes;
08773 
08774     if (extendedLock(source, src_planes, this, &dst_planes)) {
08775         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08776         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08777         MMSFBPERF_START_MEASURING;
08778             mmsfb_blit_rgb24_to_yv12(
08779                     src_planes, src_height,
08780                     sx, sy, sw, sh,
08781                     (unsigned char *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08782                     x, y);
08783         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08784         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08785         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08786         extendedUnlock(source, this);
08787         return true;
08788     }
08789 #endif
08790 #endif
08791 
08792     return false;
08793 }
08794 
08795 bool MMSFBSurface::blitBGR24toBGR24(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08796                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08797                                     int x, int y) {
08798 #ifdef __HAVE_PF_BGR24__
08799     MMSFBSurfacePlanes dst_planes;
08800 
08801     if (extendedLock(source, src_planes, this, &dst_planes)) {
08802         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08803         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08804         MMSFBPERF_START_MEASURING;
08805             mmsfb_blit_bgr24_to_bgr24(
08806                     src_planes, src_height,
08807                     sx, sy, sw, sh,
08808                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08809                     x, y);
08810         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08811         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08812         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08813         extendedUnlock(source, this);
08814         return true;
08815     }
08816 #endif
08817 
08818     return false;
08819 }
08820 
08821 bool MMSFBSurface::blitBGR24toBGR24_COLORALPHA(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08822                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08823                                     int x, int y) {
08824 #ifdef __HAVE_PF_BGR24__
08825     MMSFBSurfacePlanes dst_planes;
08826 
08827     if (extendedLock(source, src_planes, this, &dst_planes)) {
08828         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08829         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08830         MMSFBPERF_START_MEASURING;
08831             mmsfb_blit_coloralpha_bgr24_to_bgr24(
08832                     src_planes, src_height,
08833                     sx, sy, sw, sh,
08834                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08835                     x, y,
08836                     this->config.color.a);
08837         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08838         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08839         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08840         extendedUnlock(source, this);
08841         return true;
08842     }
08843 #endif
08844 
08845     return false;
08846 }
08847 
08848 bool MMSFBSurface::blitARGB3565toARGB3565(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08849                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08850                                     int x, int y) {
08851 #ifdef __HAVE_PF_ARGB3565__
08852     MMSFBSurfacePlanes dst_planes;
08853 
08854     if (extendedLock(source, src_planes, this, &dst_planes)) {
08855         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08856         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08857         MMSFBPERF_START_MEASURING;
08858             mmsfb_blit_argb3565_to_argb3565(src_planes, src_height,
08859                                             sx, sy, sw, sh,
08860                                             &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08861                                             x, y);
08862         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08863         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08864         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08865         extendedUnlock(source, this);
08866         return true;
08867     }
08868 #endif
08869 
08870     return false;
08871 }
08872 
08873 bool MMSFBSurface::blitARGB4444toARGB4444(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08874                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08875                                     int x, int y) {
08876 #ifdef __HAVE_PF_ARGB4444__
08877     MMSFBSurfacePlanes dst_planes;
08878 
08879     if (extendedLock(source, src_planes, this, &dst_planes)) {
08880         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08881         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08882         MMSFBPERF_START_MEASURING;
08883             mmsfb_blit_argb4444_to_argb4444(
08884                     src_planes, src_height,
08885                     sx, sy, sw, sh,
08886                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08887                     x, y);
08888         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08889         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08890         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08891         extendedUnlock(source, this);
08892         return true;
08893     }
08894 #endif
08895 
08896     return false;
08897 }
08898 
08899 bool MMSFBSurface::blitARGB4444toARGB4444_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08900                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08901                                     int x, int y) {
08902 #ifdef __HAVE_PF_ARGB4444__
08903     MMSFBSurfacePlanes dst_planes;
08904 
08905     if (extendedLock(source, src_planes, this, &dst_planes)) {
08906         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08907         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08908         MMSFBPERF_START_MEASURING;
08909             mmsfb_blit_blend_argb4444_to_argb4444(
08910                     src_planes, src_height,
08911                     sx, sy, sw, sh,
08912                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08913                     x, y);
08914         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08915         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08916         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08917         extendedUnlock(source, this);
08918         return true;
08919     }
08920 #endif
08921 
08922     return false;
08923 }
08924 
08925 bool MMSFBSurface::blitARGB4444toARGB4444_BLEND_COLORALPHA(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08926                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08927                                     int x, int y) {
08928 #ifdef __HAVE_PF_ARGB4444__
08929     MMSFBSurfacePlanes dst_planes;
08930 
08931     if (extendedLock(source, src_planes, this, &dst_planes)) {
08932         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08933         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08934         MMSFBPERF_START_MEASURING;
08935             mmsfb_blit_blend_coloralpha_argb4444_to_argb4444(
08936                     src_planes, src_height,
08937                     sx, sy, sw, sh,
08938                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08939                     x, y,
08940                     this->config.color.a);
08941         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08942         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08943         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08944         extendedUnlock(source, this);
08945         return true;
08946     }
08947 #endif
08948 
08949     return false;
08950 }
08951 
08952 bool MMSFBSurface::blitARGB4444toRGB32_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08953                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08954                                     int x, int y) {
08955 #ifdef __HAVE_PF_ARGB4444__
08956 #ifdef __HAVE_PF_RGB32__
08957     MMSFBSurfacePlanes dst_planes;
08958 
08959     if (extendedLock(source, src_planes, this, &dst_planes)) {
08960         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08961         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08962         MMSFBPERF_START_MEASURING;
08963             mmsfb_blit_blend_argb4444_to_rgb32(
08964                     src_planes, src_height,
08965                     sx, sy, sw, sh,
08966                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08967                     x, y);
08968         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08969         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08970         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08971         extendedUnlock(source, this);
08972         return true;
08973     }
08974 #endif
08975 #endif
08976 
08977     return false;
08978 }
08979 
08980 bool MMSFBSurface::blitARGB4444toRGB32_BLEND_COLORALPHA(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
08981                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
08982                                     int x, int y) {
08983 #ifdef __HAVE_PF_ARGB4444__
08984 #ifdef __HAVE_PF_RGB32__
08985     MMSFBSurfacePlanes dst_planes;
08986 
08987     if (extendedLock(source, src_planes, this, &dst_planes)) {
08988         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08989         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
08990         MMSFBPERF_START_MEASURING;
08991             mmsfb_blit_blend_coloralpha_argb4444_to_rgb32(
08992                     src_planes, src_height,
08993                     sx, sy, sw, sh,
08994                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
08995                     x, y,
08996                     this->config.color.a);
08997         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
08998         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
08999         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
09000         extendedUnlock(source, this);
09001         return true;
09002     }
09003 #endif
09004 #endif
09005 
09006     return false;
09007 }
09008 
09009 bool MMSFBSurface::blitBGR555toBGR555(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
09010                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
09011                                     int x, int y) {
09012 #ifdef __HAVE_PF_BGR555__
09013     MMSFBSurfacePlanes dst_planes;
09014 
09015     if (extendedLock(source, src_planes, this, &dst_planes)) {
09016         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09017         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
09018         MMSFBPERF_START_MEASURING;
09019             mmsfb_blit_bgr555_to_bgr555(
09020                     src_planes, src_height,
09021                     sx, sy, sw, sh,
09022                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
09023                     x, y);
09024         MMSFBPERF_STOP_MEASURING_BLIT(this, src_pixelformat, sw, sh);
09025         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09026         MMSFB_ROTATE_180_RECT(this, x, y, sw, sh);
09027         extendedUnlock(source, this);
09028         return true;
09029     }
09030 #endif
09031 
09032     return false;
09033 }
09034 
09035 
09036 
09037 bool MMSFBSurface::stretchBlitARGBtoARGB(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
09038                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
09039                                     int dx, int dy, int dw, int dh,
09040                                     bool antialiasing) {
09041 #ifdef __HAVE_PF_ARGB__
09042     MMSFBSurfacePlanes dst_planes;
09043 
09044     if (extendedLock(source, src_planes, this, &dst_planes)) {
09045         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09046         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09047         MMSFBPERF_START_MEASURING;
09048             mmsfb_stretchblit_argb_to_argb(
09049                     src_planes, src_height,
09050                     sx, sy, sw, sh,
09051                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
09052                     dx, dy, dw, dh,
09053                     antialiasing);
09054         MMSFBPERF_STOP_MEASURING_STRETCHBLIT(this, src_pixelformat, sw, sh, dw, dh);
09055         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09056         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09057         extendedUnlock(source, this);
09058 
09059         return true;
09060     }
09061 #endif
09062 
09063     return false;
09064 }
09065 
09066 
09067 bool MMSFBSurface::stretchBlitARGBtoARGB_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
09068                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
09069                                     int dx, int dy, int dw, int dh,
09070                                     bool antialiasing) {
09071 #ifdef __HAVE_PF_ARGB__
09072     MMSFBSurfacePlanes dst_planes;
09073 
09074     if (extendedLock(source, src_planes, this, &dst_planes)) {
09075         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09076         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09077         MMSFBPERF_START_MEASURING;
09078             mmsfb_stretchblit_blend_argb_to_argb(
09079                     src_planes, src_height,
09080                     sx, sy, sw, sh,
09081                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
09082                     dx, dy, dw, dh);
09083         MMSFBPERF_STOP_MEASURING_STRETCHBLIT(this, src_pixelformat, sw, sh, dw, dh);
09084         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09085         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09086         extendedUnlock(source, this);
09087 
09088         return true;
09089     }
09090 #endif
09091 
09092     return false;
09093 }
09094 
09095 bool MMSFBSurface::stretchBlitARGBtoARGB_BLEND_COLORALPHA(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
09096                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
09097                                     int dx, int dy, int dw, int dh,
09098                                     bool antialiasing) {
09099 #ifdef __HAVE_PF_ARGB__
09100     MMSFBSurfacePlanes dst_planes;
09101 
09102     if (extendedLock(source, src_planes, this, &dst_planes)) {
09103         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09104         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09105         MMSFBPERF_START_MEASURING;
09106             mmsfb_stretchblit_blend_coloralpha_argb_to_argb(
09107                     src_planes, src_height,
09108                     sx, sy, sw, sh,
09109                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
09110                     dx, dy, dw, dh,
09111                     this->config.color.a);
09112         MMSFBPERF_STOP_MEASURING_STRETCHBLIT(this, src_pixelformat, sw, sh, dw, dh);
09113         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09114         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09115         extendedUnlock(source, this);
09116 
09117         return true;
09118     }
09119 #endif
09120 
09121     return false;
09122 }
09123 
09124 bool MMSFBSurface::stretchBlitARGBtoRGB32_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
09125                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
09126                                     int dx, int dy, int dw, int dh,
09127                                     bool antialiasing) {
09128 #ifdef __HAVE_PF_ARGB__
09129 #ifdef __HAVE_PF_RGB32__
09130     MMSFBSurfacePlanes dst_planes;
09131 
09132     if (extendedLock(source, src_planes, this, &dst_planes)) {
09133         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09134         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09135         MMSFBPERF_START_MEASURING;
09136             mmsfb_stretchblit_blend_argb_to_rgb32(
09137                     src_planes, src_height,
09138                     sx, sy, sw, sh,
09139                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
09140                     dx, dy, dw, dh);
09141         MMSFBPERF_STOP_MEASURING_STRETCHBLIT(this, src_pixelformat, sw, sh, dw, dh);
09142         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09143         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09144         extendedUnlock(source, this);
09145 
09146         return true;
09147     }
09148 #endif
09149 #endif
09150 
09151     return false;
09152 }
09153 
09154 bool MMSFBSurface::stretchBlitRGB32toRGB32(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
09155                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
09156                                     int dx, int dy, int dw, int dh,
09157                                     bool antialiasing) {
09158 #ifdef __HAVE_PF_RGB32__
09159     MMSFBSurfacePlanes dst_planes;
09160 
09161     if (extendedLock(source, src_planes, this, &dst_planes)) {
09162         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09163         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09164         MMSFBPERF_START_MEASURING;
09165             mmsfb_stretchblit_rgb32_to_rgb32(
09166                     src_planes, src_height,
09167                     sx, sy, sw, sh,
09168                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
09169                     dx, dy, dw, dh,
09170                     antialiasing);
09171         MMSFBPERF_STOP_MEASURING_STRETCHBLIT(this, src_pixelformat, sw, sh, dw, dh);
09172         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09173         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09174         extendedUnlock(source, this);
09175 
09176         return true;
09177     }
09178 #endif
09179 
09180     return false;
09181 }
09182 
09183 bool MMSFBSurface::stretchBlitRGB24toARGB(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
09184                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
09185                                     int dx, int dy, int dw, int dh,
09186                                     bool antialiasing) {
09187 #ifdef __HAVE_PF_RGB24__
09188 #ifdef __HAVE_PF_ARGB__
09189     MMSFBSurfacePlanes dst_planes;
09190 
09191     if (extendedLock(source, src_planes, this, &dst_planes)) {
09192         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09193         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09194         MMSFBPERF_START_MEASURING;
09195             mmsfb_stretchblit_rgb24_to_argb(
09196                     src_planes, src_height,
09197                     sx, sy, sw, sh,
09198                     (unsigned int *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
09199                     dx, dy, dw, dh,
09200                     antialiasing);
09201         MMSFBPERF_STOP_MEASURING_STRETCHBLIT(this, src_pixelformat, sw, sh, dw, dh);
09202         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09203         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09204         extendedUnlock(source, this);
09205 
09206         return true;
09207     }
09208 #endif
09209 #endif
09210 
09211     return false;
09212 }
09213 
09214 bool MMSFBSurface::stretchBlitRGB24toRGB32(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
09215                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
09216                                     int dx, int dy, int dw, int dh,
09217                                     bool antialiasing) {
09218 #ifdef __HAVE_PF_RGB24__
09219 #ifdef __HAVE_PF_RGB32__
09220     MMSFBSurfacePlanes dst_planes;
09221 
09222     if (extendedLock(source, src_planes, this, &dst_planes)) {
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         MMSFBPERF_START_MEASURING;
09226             mmsfb_stretchblit_rgb24_to_rgb32(
09227                     src_planes, src_height,
09228                     sx, sy, sw, sh,
09229                     (unsigned int *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
09230                     dx, dy, dw, dh,
09231                     antialiasing);
09232         MMSFBPERF_STOP_MEASURING_STRETCHBLIT(this, src_pixelformat, sw, sh, dw, dh);
09233         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09234         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09235         extendedUnlock(source, this);
09236 
09237         return true;
09238     }
09239 #endif
09240 #endif
09241 
09242     return false;
09243 }
09244 
09245 
09246 bool MMSFBSurface::stretchBlitAiRGBtoAiRGB(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
09247                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
09248                                     int dx, int dy, int dw, int dh,
09249                                     bool antialiasing) {
09250 #ifdef __HAVE_PF_AiRGB__
09251     MMSFBSurfacePlanes dst_planes;
09252 
09253     if (extendedLock(source, src_planes, this, &dst_planes)) {
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         MMSFBPERF_START_MEASURING;
09257             mmsfb_stretchblit_airgb_to_airgb(
09258                     src_planes, src_height,
09259                     sx, sy, sw, sh,
09260                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
09261                     dx, dy, dw, dh,
09262                     antialiasing);
09263         MMSFBPERF_STOP_MEASURING_STRETCHBLIT(this, src_pixelformat, sw, sh, dw, dh);
09264         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09265         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09266         extendedUnlock(source, this);
09267 
09268         return true;
09269     }
09270 #endif
09271 
09272     return false;
09273 }
09274 
09275 bool MMSFBSurface::stretchBlitAiRGBtoAiRGB_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
09276                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
09277                                     int dx, int dy, int dw, int dh,
09278                                     bool antialiasing) {
09279 #ifdef __HAVE_PF_AiRGB__
09280     MMSFBSurfacePlanes dst_planes;
09281 
09282     if (extendedLock(source, src_planes, this, &dst_planes)) {
09283         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09284         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09285         MMSFBPERF_START_MEASURING;
09286             mmsfb_stretchblit_blend_airgb_to_airgb(
09287                     src_planes, src_height,
09288                     sx, sy, sw, sh,
09289                     (unsigned int *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
09290                     dx, dy, dw, dh);
09291         MMSFBPERF_STOP_MEASURING_STRETCHBLIT(this, src_pixelformat, sw, sh, dw, dh);
09292         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09293         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09294         extendedUnlock(source, this);
09295 
09296         return true;
09297     }
09298 #endif
09299 
09300     return false;
09301 }
09302 
09303 bool MMSFBSurface::stretchBlitAiRGBtoAiRGB_BLEND_COLORALPHA(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
09304                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
09305                                     int dx, int dy, int dw, int dh,
09306                                     bool antialiasing) {
09307 #ifdef __HAVE_PF_AiRGB__
09308     MMSFBSurfacePlanes dst_planes;
09309 
09310     if (extendedLock(source, src_planes, this, &dst_planes)) {
09311         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09312         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09313         MMSFBPERF_START_MEASURING;
09314             mmsfb_stretchblit_blend_coloralpha_airgb_to_airgb(
09315                     src_planes, src_height,
09316                     sx, sy, sw, sh,
09317                     (unsigned int *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
09318                     dx, dy, dw, dh,
09319                     this->config.color.a);
09320         MMSFBPERF_STOP_MEASURING_STRETCHBLIT(this, src_pixelformat, sw, sh, dw, dh);
09321         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09322         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09323         extendedUnlock(source, this);
09324 
09325         return true;
09326     }
09327 #endif
09328 
09329     return false;
09330 }
09331 
09332 bool MMSFBSurface::stretchBlitAYUVtoAYUV(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
09333                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
09334                                     int dx, int dy, int dw, int dh,
09335                                     bool antialiasing) {
09336 #ifdef __HAVE_PF_AYUV__
09337     MMSFBSurfacePlanes dst_planes;
09338 
09339     if (extendedLock(source, src_planes, this, &dst_planes)) {
09340         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09341         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09342         MMSFBPERF_START_MEASURING;
09343             mmsfb_stretchblit_ayuv_to_ayuv(
09344                     src_planes, src_height,
09345                     sx, sy, sw, sh,
09346                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
09347                     dx, dy, dw, dh,
09348                     antialiasing);
09349         MMSFBPERF_STOP_MEASURING_STRETCHBLIT(this, src_pixelformat, sw, sh, dw, dh);
09350         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09351         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09352         extendedUnlock(source, this);
09353 
09354         return true;
09355     }
09356 #endif
09357 
09358     return false;
09359 }
09360 
09361 bool MMSFBSurface::stretchBlitAYUVtoAYUV_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
09362                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
09363                                     int dx, int dy, int dw, int dh,
09364                                     bool antialiasing) {
09365 #ifdef __HAVE_PF_AYUV__
09366     MMSFBSurfacePlanes dst_planes;
09367 
09368     if (extendedLock(source, src_planes, this, &dst_planes)) {
09369         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09370         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09371         MMSFBPERF_START_MEASURING;
09372             mmsfb_stretchblit_blend_ayuv_to_ayuv(
09373                     src_planes, src_height,
09374                     sx, sy, sw, sh,
09375                     (unsigned int *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
09376                     dx, dy, dw, dh);
09377         MMSFBPERF_STOP_MEASURING_STRETCHBLIT(this, src_pixelformat, sw, sh, dw, dh);
09378         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09379         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09380         extendedUnlock(source, this);
09381 
09382         return true;
09383     }
09384 #endif
09385 
09386     return false;
09387 }
09388 
09389 bool MMSFBSurface::stretchBlitAYUVtoAYUV_BLEND_COLORALPHA(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
09390                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
09391                                     int dx, int dy, int dw, int dh,
09392                                     bool antialiasing) {
09393 #ifdef __HAVE_PF_AYUV__
09394     MMSFBSurfacePlanes dst_planes;
09395 
09396     if (extendedLock(source, src_planes, this, &dst_planes)) {
09397         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09398         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09399         MMSFBPERF_START_MEASURING;
09400             mmsfb_stretchblit_blend_coloralpha_ayuv_to_ayuv(
09401                     src_planes, src_height,
09402                     sx, sy, sw, sh,
09403                     (unsigned int *)dst_planes.ptr, dst_planes.pitch, (!this->root_parent)?this->config.h:this->root_parent->config.h,
09404                     dx, dy, dw, dh,
09405                     this->config.color.a);
09406         MMSFBPERF_STOP_MEASURING_STRETCHBLIT(this, src_pixelformat, sw, sh, dw, dh);
09407         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09408         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09409         extendedUnlock(source, this);
09410 
09411         return true;
09412     }
09413 #endif
09414 
09415     return false;
09416 }
09417 
09418 bool MMSFBSurface::stretchBlitYV12toYV12(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
09419                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
09420                                     int dx, int dy, int dw, int dh,
09421                                     bool antialiasing) {
09422 #ifdef __HAVE_PF_YV12__
09423     MMSFBSurfacePlanes dst_planes;
09424 
09425     if (extendedLock(source, src_planes, this, &dst_planes)) {
09426         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09427         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09428         MMSFBPERF_START_MEASURING;
09429             mmsfb_stretchblit_yv12_to_yv12(
09430                     src_planes, src_height,
09431                     sx, sy, sw, sh,
09432                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
09433                     dx, dy, dw, dh,
09434                     antialiasing);
09435         MMSFBPERF_STOP_MEASURING_STRETCHBLIT(this, src_pixelformat, sw, sh, dw, dh);
09436         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09437         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09438         extendedUnlock(source, this);
09439         return true;
09440     }
09441 #endif
09442 
09443     return false;
09444 }
09445 
09446 bool MMSFBSurface::stretchBlitI420toYV12(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
09447                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
09448                                     int dx, int dy, int dw, int dh,
09449                                     bool antialiasing) {
09450 #ifdef __HAVE_PF_I420__
09451 #ifdef __HAVE_PF_YV12__
09452     MMSFBSurfacePlanes dst_planes;
09453 
09454     if (extendedLock(source, src_planes, this, &dst_planes)) {
09455         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09456         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09457         MMSFBPERF_START_MEASURING;
09458             mmsfb_stretchblit_i420_to_yv12(
09459                     src_planes, src_height,
09460                     sx, sy, sw, sh,
09461                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
09462                     dx, dy, dw, dh,
09463                     antialiasing);
09464         MMSFBPERF_STOP_MEASURING_STRETCHBLIT(this, src_pixelformat, sw, sh, dw, dh);
09465         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09466         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09467         extendedUnlock(source, this);
09468         return true;
09469     }
09470 #endif
09471 #endif
09472 
09473     return false;
09474 }
09475 
09476 bool MMSFBSurface::stretchBlitYUY2toYV12(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
09477                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
09478                                     int dx, int dy, int dw, int dh,
09479                                     bool antialiasing) {
09480 #ifdef __HAVE_PF_YUY2__
09481 #ifdef __HAVE_PF_YV12__
09482     MMSFBSurfacePlanes dst_planes;
09483 
09484     if (extendedLock(source, src_planes, this, &dst_planes)) {
09485         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09486         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09487         MMSFBPERF_START_MEASURING;
09488             mmsfb_stretchblit_yuy2_to_yv12(
09489                     src_planes, src_height,
09490                     sx, sy, sw, sh,
09491                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
09492                     dx, dy, dw, dh,
09493                     antialiasing);
09494         MMSFBPERF_STOP_MEASURING_STRETCHBLIT(this, src_pixelformat, sw, sh, dw, dh);
09495         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09496         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09497         extendedUnlock(source, this);
09498         return true;
09499     }
09500 #endif
09501 #endif
09502 
09503     return false;
09504 }
09505 
09506 
09507 bool MMSFBSurface::stretchBlitARGB4444toARGB4444_BLEND(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
09508                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
09509                                     int dx, int dy, int dw, int dh,
09510                                     bool antialiasing) {
09511 #ifdef __HAVE_PF_ARGB4444__
09512     MMSFBSurfacePlanes dst_planes;
09513 
09514     if (extendedLock(source, src_planes, this, &dst_planes)) {
09515         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09516         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09517         MMSFBPERF_START_MEASURING;
09518             mmsfb_stretchblit_blend_argb4444_to_argb4444(
09519                     src_planes, src_height,
09520                     sx, sy, sw, sh,
09521                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
09522                     dx, dy, dw, dh);
09523         MMSFBPERF_STOP_MEASURING_STRETCHBLIT(this, src_pixelformat, sw, sh, dw, dh);
09524         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09525         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09526         extendedUnlock(source, this);
09527 
09528         return true;
09529     }
09530 #endif
09531 
09532     return false;
09533 }
09534 
09535 
09536 bool MMSFBSurface::stretchBlitARGB4444toARGB4444_BLEND_COLORALPHA(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
09537                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
09538                                     int dx, int dy, int dw, int dh,
09539                                     bool antialiasing) {
09540 #ifdef __HAVE_PF_ARGB4444__
09541     MMSFBSurfacePlanes dst_planes;
09542 
09543     if (extendedLock(source, src_planes, this, &dst_planes)) {
09544         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09545         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09546         MMSFBPERF_START_MEASURING;
09547             mmsfb_stretchblit_blend_coloralpha_argb4444_to_argb4444(
09548                     src_planes, src_height,
09549                     sx, sy, sw, sh,
09550                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
09551                     dx, dy, dw, dh,
09552                     this->config.color.a);
09553         MMSFBPERF_STOP_MEASURING_STRETCHBLIT(this, src_pixelformat, sw, sh, dw, dh);
09554         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09555         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09556         extendedUnlock(source, this);
09557 
09558         return true;
09559     }
09560 #endif
09561 
09562     return false;
09563 }
09564 
09565 bool MMSFBSurface::stretchBlitRGB16toRGB16(MMSFBSurface *source, MMSFBSurfacePlanes *src_planes, MMSFBSurfacePixelFormat src_pixelformat,
09566                                     int src_width, int src_height, int sx, int sy, int sw, int sh,
09567                                     int dx, int dy, int dw, int dh,
09568                                     bool antialiasing) {
09569 #ifdef __HAVE_PF_RGB16__
09570     MMSFBSurfacePlanes dst_planes;
09571 
09572     if (extendedLock(source, src_planes, this, &dst_planes)) {
09573         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09574         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09575         MMSFBPERF_START_MEASURING;
09576             mmsfb_stretchblit_rgb16_to_rgb16(
09577                     src_planes, src_height,
09578                     sx, sy, sw, sh,
09579                     &dst_planes, (!this->root_parent)?this->config.h:this->root_parent->config.h,
09580                     dx, dy, dw, dh,
09581                     antialiasing);
09582         MMSFBPERF_STOP_MEASURING_STRETCHBLIT(this, src_pixelformat, sw, sh, dw, dh);
09583         MMSFB_ROTATE_180_RECT_WH(src_width, src_height, sx, sy, sw, sh);
09584         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09585         extendedUnlock(source, this);
09586 
09587         return true;
09588     }
09589 #endif
09590 
09591     return false;
09592 }
09593 
09594 
09595 bool MMSFBSurface::fillRectangleARGB(int dst_height, int dx, int dy, int dw, int dh, MMSFBColor &color) {
09596 #ifdef __HAVE_PF_ARGB__
09597     MMSFBSurfacePlanes dst_planes;
09598 
09599     if (extendedLock(NULL, NULL, this, &dst_planes)) {
09600         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09601         MMSFBPERF_START_MEASURING;
09602             mmsfb_fillrectangle_argb(&dst_planes, dst_height,
09603                                      dx, dy, dw, dh, color);
09604         MMSFBPERF_STOP_MEASURING_FILLRECT(this, dw, dh);
09605         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09606         extendedUnlock(NULL, this, &dst_planes);
09607         return true;
09608     }
09609 #endif
09610 
09611     return false;
09612 }
09613 
09614 bool MMSFBSurface::fillRectangleARGB_BLEND(int dst_height, int dx, int dy, int dw, int dh, MMSFBColor &color) {
09615 #ifdef __HAVE_PF_ARGB__
09616     MMSFBSurfacePlanes dst_planes;
09617 
09618     if (extendedLock(NULL, NULL, this, &dst_planes)) {
09619         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09620         MMSFBPERF_START_MEASURING;
09621             mmsfb_fillrectangle_blend_argb(&dst_planes, dst_height,
09622                                            dx, dy, dw, dh, color);
09623         MMSFBPERF_STOP_MEASURING_FILLRECT(this, dw, dh);
09624         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09625         extendedUnlock(NULL, this, &dst_planes);
09626         return true;
09627     }
09628 #endif
09629 
09630     return false;
09631 }
09632 
09633 bool MMSFBSurface::fillRectangleAYUV(int dst_height, int dx, int dy, int dw, int dh, MMSFBColor &color) {
09634 #ifdef __HAVE_PF_AYUV__
09635     MMSFBSurfacePlanes dst_planes;
09636 
09637     if (extendedLock(NULL, NULL, this, &dst_planes)) {
09638         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09639         MMSFBPERF_START_MEASURING;
09640             mmsfb_fillrectangle_ayuv(&dst_planes, dst_height,
09641                                      dx, dy, dw, dh, color);
09642         MMSFBPERF_STOP_MEASURING_FILLRECT(this, dw, dh);
09643         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09644         extendedUnlock(NULL, this);
09645         return true;
09646     }
09647 #endif
09648 
09649     return false;
09650 }
09651 
09652 bool MMSFBSurface::fillRectangleAYUV_BLEND(int dst_height, int dx, int dy, int dw, int dh, MMSFBColor &color) {
09653 #ifdef __HAVE_PF_AYUV__
09654     MMSFBSurfacePlanes dst_planes;
09655 
09656     if (extendedLock(NULL, NULL, this, &dst_planes)) {
09657         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09658         MMSFBPERF_START_MEASURING;
09659             mmsfb_fillrectangle_blend_ayuv(&dst_planes, dst_height,
09660                                            dx, dy, dw, dh, color);
09661         MMSFBPERF_STOP_MEASURING_FILLRECT(this, dw, dh);
09662         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09663         extendedUnlock(NULL, this);
09664         return true;
09665     }
09666 #endif
09667 
09668     return false;
09669 }
09670 
09671 bool MMSFBSurface::fillRectangleRGB32(int dst_height, int dx, int dy, int dw, int dh, MMSFBColor &color) {
09672 #ifdef __HAVE_PF_RGB32__
09673     MMSFBSurfacePlanes dst_planes;
09674 
09675     if (extendedLock(NULL, NULL, this, &dst_planes)) {
09676         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09677         MMSFBPERF_START_MEASURING;
09678             mmsfb_fillrectangle_rgb32(&dst_planes, dst_height,
09679                                       dx, dy, dw, dh, color);
09680         MMSFBPERF_STOP_MEASURING_FILLRECT(this, dw, dh);
09681         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09682         extendedUnlock(NULL, this);
09683         return true;
09684     }
09685 #endif
09686 
09687     return false;
09688 }
09689 
09690 bool MMSFBSurface::fillRectangleRGB24(int dst_height, int dx, int dy, int dw, int dh, MMSFBColor &color) {
09691 #ifdef __HAVE_PF_RGB24__
09692     MMSFBSurfacePlanes dst_planes;
09693 
09694     if (extendedLock(NULL, NULL, this, &dst_planes)) {
09695         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09696         MMSFBPERF_START_MEASURING;
09697             mmsfb_fillrectangle_rgb24(&dst_planes, dst_height,
09698                                       dx, dy, dw, dh, color);
09699         MMSFBPERF_STOP_MEASURING_FILLRECT(this, dw, dh);
09700         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09701         extendedUnlock(NULL, this);
09702         return true;
09703     }
09704 #endif
09705 
09706     return false;
09707 }
09708 
09709 bool MMSFBSurface::fillRectangleRGB16(int dst_height, int dx, int dy, int dw, int dh, MMSFBColor &color) {
09710 #ifdef __HAVE_PF_RGB16__
09711     MMSFBSurfacePlanes dst_planes;
09712 
09713     if (extendedLock(NULL, NULL, this, &dst_planes)) {
09714         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09715         MMSFBPERF_START_MEASURING;
09716             mmsfb_fillrectangle_rgb16(&dst_planes, dst_height,
09717                                      dx, dy, dw, dh, color);
09718         MMSFBPERF_STOP_MEASURING_FILLRECT(this, dw, dh);
09719         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09720         extendedUnlock(NULL, this, &dst_planes);
09721         return true;
09722     }
09723 #endif
09724 
09725     return false;
09726 }
09727 
09728 bool MMSFBSurface::fillRectangleRGB16_BLEND(int dst_height, int dx, int dy, int dw, int dh, MMSFBColor &color) {
09729 #ifdef __HAVE_PF_RGB16__
09730     MMSFBSurfacePlanes dst_planes;
09731 
09732     if (extendedLock(NULL, NULL, this, &dst_planes)) {
09733         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09734         MMSFBPERF_START_MEASURING;
09735             mmsfb_fillrectangle_blend_rgb16(&dst_planes, dst_height,
09736                                            dx, dy, dw, dh, color);
09737         MMSFBPERF_STOP_MEASURING_FILLRECT(this, dw, dh);
09738         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09739         extendedUnlock(NULL, this, &dst_planes);
09740         return true;
09741     }
09742 #endif
09743 
09744     return false;
09745 }
09746 
09747 bool MMSFBSurface::fillRectangleYV12(int dst_height, int dx, int dy, int dw, int dh, MMSFBColor &color) {
09748 #ifdef __HAVE_PF_YV12__
09749     MMSFBSurfacePlanes dst_planes;
09750 
09751     if (extendedLock(NULL, NULL, this, &dst_planes)) {
09752         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09753         MMSFBPERF_START_MEASURING;
09754             mmsfb_fillrectangle_yv12(&dst_planes, dst_height,
09755                                      dx, dy, dw, dh, color);
09756         MMSFBPERF_STOP_MEASURING_FILLRECT(this, dw, dh);
09757         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09758         extendedUnlock(NULL, this);
09759         return true;
09760     }
09761 #endif
09762 
09763     return false;
09764 }
09765 
09766 bool MMSFBSurface::fillRectangleI420(int dst_height, int dx, int dy, int dw, int dh, MMSFBColor &color) {
09767 #ifdef __HAVE_PF_I420__
09768     MMSFBSurfacePlanes dst_planes;
09769 
09770     if (extendedLock(NULL, NULL, this, &dst_planes)) {
09771         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09772         MMSFBPERF_START_MEASURING;
09773             mmsfb_fillrectangle_i420(&dst_planes, dst_height,
09774                                      dx, dy, dw, dh, color);
09775         MMSFBPERF_STOP_MEASURING_FILLRECT(this, dw, dh);
09776         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09777         extendedUnlock(NULL, this);
09778         return true;
09779     }
09780 #endif
09781 
09782     return false;
09783 }
09784 
09785 bool MMSFBSurface::fillRectangleYUY2(int dst_height, int dx, int dy, int dw, int dh, MMSFBColor &color) {
09786 #ifdef __HAVE_PF_YUY2__
09787     MMSFBSurfacePlanes dst_planes;
09788 
09789     if (extendedLock(NULL, NULL, this, &dst_planes)) {
09790         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09791         MMSFBPERF_START_MEASURING;
09792             mmsfb_fillrectangle_yuy2(&dst_planes, dst_height,
09793                                      dx, dy, dw, dh, color);
09794         MMSFBPERF_STOP_MEASURING_FILLRECT(this, dw, dh);
09795         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09796         extendedUnlock(NULL, this);
09797         return true;
09798     }
09799 #endif
09800 
09801     return false;
09802 }
09803 
09804 bool MMSFBSurface::fillRectangleARGB3565(int dst_height, int dx, int dy, int dw, int dh, MMSFBColor &color) {
09805 #ifdef __HAVE_PF_ARGB3565__
09806     MMSFBSurfacePlanes dst_planes;
09807 
09808     if (extendedLock(NULL, NULL, this, &dst_planes)) {
09809         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09810         MMSFBPERF_START_MEASURING;
09811             mmsfb_fillrectangle_argb3565(&dst_planes, dst_height,
09812                                      dx, dy, dw, dh, color);
09813         MMSFBPERF_STOP_MEASURING_FILLRECT(this, dw, dh);
09814         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09815         extendedUnlock(NULL, this);
09816         return true;
09817     }
09818 #endif
09819 
09820     return false;
09821 }
09822 
09823 bool MMSFBSurface::fillRectangleARGB4444(int dst_height, int dx, int dy, int dw, int dh, MMSFBColor &color) {
09824 #ifdef __HAVE_PF_ARGB4444__
09825     MMSFBSurfacePlanes dst_planes;
09826 
09827     if (extendedLock(NULL, NULL, this, &dst_planes)) {
09828         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09829         MMSFBPERF_START_MEASURING;
09830             mmsfb_fillrectangle_argb4444(&dst_planes, dst_height,
09831                                      dx, dy, dw, dh, color);
09832         MMSFBPERF_STOP_MEASURING_FILLRECT(this, dw, dh);
09833         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09834         extendedUnlock(NULL, this);
09835         return true;
09836     }
09837 #endif
09838 
09839     return false;
09840 }
09841 
09842 bool MMSFBSurface::fillRectangleARGB4444_BLEND(int dst_height, int dx, int dy, int dw, int dh, MMSFBColor &color) {
09843 #ifdef __HAVE_PF_ARGB4444__
09844     MMSFBSurfacePlanes dst_planes;
09845 
09846     if (extendedLock(NULL, NULL, this, &dst_planes)) {
09847         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09848         MMSFBPERF_START_MEASURING;
09849             mmsfb_fillrectangle_blend_argb4444(&dst_planes, dst_height,
09850                                      dx, dy, dw, dh, color);
09851         MMSFBPERF_STOP_MEASURING_FILLRECT(this, dw, dh);
09852         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09853         extendedUnlock(NULL, this);
09854         return true;
09855     }
09856 #endif
09857 
09858     return false;
09859 }
09860 
09861 bool MMSFBSurface::fillRectangleBGR24(int dst_height, int dx, int dy, int dw, int dh, MMSFBColor &color) {
09862 #ifdef __HAVE_PF_BGR24__
09863     MMSFBSurfacePlanes dst_planes;
09864 
09865     if (extendedLock(NULL, NULL, this, &dst_planes)) {
09866         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09867         MMSFBPERF_START_MEASURING;
09868             mmsfb_fillrectangle_bgr24(&dst_planes, dst_height,
09869                                      dx, dy, dw, dh, color);
09870         MMSFBPERF_STOP_MEASURING_FILLRECT(this, dw, dh);
09871         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09872         extendedUnlock(NULL, this);
09873         return true;
09874     }
09875 #endif
09876 
09877     return false;
09878 }
09879 
09880 bool MMSFBSurface::fillRectangleBGR555(int dst_height, int dx, int dy, int dw, int dh, MMSFBColor &color) {
09881 #ifdef __HAVE_PF_BGR555__
09882     MMSFBSurfacePlanes dst_planes;
09883 
09884     if (extendedLock(NULL, NULL, this, &dst_planes)) {
09885         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09886         MMSFBPERF_START_MEASURING;
09887             mmsfb_fillrectangle_bgr555(&dst_planes, dst_height,
09888                                      dx, dy, dw, dh, color);
09889         MMSFBPERF_STOP_MEASURING_FILLRECT(this, dw, dh);
09890         MMSFB_ROTATE_180_RECT(this, dx, dy, dw, dh);
09891         extendedUnlock(NULL, this);
09892         return true;
09893     }
09894 #endif
09895 
09896     return false;
09897 }
09898 
09899 
09900 
09901 
09902 
09903 
09904 
09905 
09906 

Generated by doxygen