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

mmsfb_fillrectangle_yv12.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2005-2007 Stefan Schwarzer, Jens Schneider,             *
00003  *                           Matthias Hardt, Guido Madaus                  *
00004  *                                                                         *
00005  *   Copyright (C) 2007-2008 BerLinux Solutions GbR                        *
00006  *                           Stefan Schwarzer & Guido Madaus               *
00007  *                                                                         *
00008  *   Copyright (C) 2009-2013 BerLinux Solutions GmbH                       *
00009  *                                                                         *
00010  *   Authors:                                                              *
00011  *      Stefan Schwarzer   <stefan.schwarzer@diskohq.org>,                 *
00012  *      Matthias Hardt     <matthias.hardt@diskohq.org>,                   *
00013  *      Jens Schneider     <jens.schneider@diskohq.org>,                   *
00014  *      Guido Madaus       <guido.madaus@diskohq.org>,                     *
00015  *      Patrick Helterhoff <patrick.helterhoff@diskohq.org>,               *
00016  *      René Bählkow       <rene.baehlkow@diskohq.org>                     *
00017  *                                                                         *
00018  *   This library is free software; you can redistribute it and/or         *
00019  *   modify it under the terms of the GNU Lesser General Public            *
00020  *   License version 2.1 as published by the Free Software Foundation.     *
00021  *                                                                         *
00022  *   This library is distributed in the hope that it will be useful,       *
00023  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00024  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00025  *   Lesser General Public License for more details.                       *
00026  *                                                                         *
00027  *   You should have received a copy of the GNU Lesser General Public      *
00028  *   License along with this library; if not, write to the                 *
00029  *   Free Software Foundation, Inc.,                                       *
00030  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
00031  **************************************************************************/
00032 
00033 #include "mmsgui/fb/mmsfbconv.h"
00034 
00035 #ifdef __HAVE_PF_YV12__
00036 
00037 #include <cstring>
00038 #include "mmstools/mmstools.h"
00039 
00040 void mmsfb_fillrectangle_yv12(MMSFBSurfacePlanes *dst_planes, int dst_height,
00041                               int dx, int dy, int dw, int dh, MMSFBColor color) {
00042     // first time?
00043     static bool firsttime = true;
00044     if (firsttime) {
00045         printf("DISKO: Using accelerated fill rectangle to YV12.\n");
00046         firsttime = false;
00047     }
00048 
00049     // get the first destination ptr/pitch
00050     unsigned char *dst = (unsigned char *)dst_planes->ptr;
00051     int dst_pitch = dst_planes->pitch;
00052 
00053     // prepare...
00054 //  int  src_pitch_pix      = src_pitch >> 2;
00055     int dst_pitch_pix       = dst_pitch;
00056     int dst_pitch_pix_half  = dst_pitch_pix >> 1;
00057 
00058 //  src+= sx + sy * src_pitch_pix;
00059 
00060 //  unsigned int OLDSRC  = (*src) + 1;
00061 //  unsigned int old_y;
00062 //  unsigned int old_u;
00063 //  unsigned int old_v;
00064 
00065 //  int  src_pixels = src_pitch_pix * sh;
00066 
00067     // check odd/even
00068     bool odd_left   = (dx & 0x01);
00069     bool odd_top    = (dy & 0x01);
00070     bool odd_right  = ((dx + dw) & 0x01);
00071     bool odd_bottom = ((dy + dh) & 0x01);
00072 
00073     // pointer to the pixel components of the first destination pixel
00074     unsigned char *dst_y = dst + dx + dy * dst_pitch_pix;
00075     unsigned char *dst_u;
00076     unsigned char *dst_v;
00077     if ((dst_planes->ptr2)&&(dst_planes->ptr3)) {
00078         dst_u = (unsigned char *)dst_planes->ptr2 + (dx >> 1) + (dy >> 1) * dst_pitch_pix_half;
00079         dst_v = (unsigned char *)dst_planes->ptr3 + (dx >> 1) + (dy >> 1) * dst_pitch_pix_half;
00080     }
00081     else {
00082         dst_u = dst + dst_pitch_pix * dst_height + dst_pitch_pix_half * (dst_height >> 1) + (dx >> 1) + (dy >> 1) * dst_pitch_pix_half;
00083         dst_v = dst + dst_pitch_pix * dst_height                                          + (dx >> 1) + (dy >> 1) * dst_pitch_pix_half;
00084     }
00085 
00086 
00087     // offsets to the other three pixels
00088 //  unsigned int dst_y2_offs = 1;
00089 //  unsigned int dst_y3_offs = dst_pitch;
00090 //  unsigned int dst_y4_offs = dst_y3_offs + 1;
00091 //  unsigned int src2_offs = 1;
00092 //  unsigned int src3_offs = src_pitch_pix;
00093 //  unsigned int src4_offs = src3_offs + 1;
00094 
00095     // arithmetic mean
00096 //  register unsigned int d_u;
00097 //  register unsigned int d_v;
00098 
00099     // prepare the color
00100     unsigned int SRC_Y = MMSFB_CONV_RGB2Y(color.r, color.g, color.b);
00101     unsigned int SRC_U = MMSFB_CONV_RGB2U(color.r, color.g, color.b);
00102     unsigned int SRC_V = MMSFB_CONV_RGB2V(color.r, color.g, color.b);
00103 
00104     // draw odd pixels around the even rectangle
00105     /*if (odd_top && odd_left) {
00106         // odd top-left pixel
00107         register unsigned int SRC;
00108         register unsigned int A;
00109 
00110         // for arithmetic mean we have to set U and V from pixels outside the current rectangle
00111         d_u = (*dst_u) * 3;
00112         d_v = (*dst_v) * 3;
00113 
00114         // calculate my pixel...
00115         MMSFB_CONV_BLEND_ARGB_TO_YV12_PIXEL(*src, *dst_y, *dst_u, *dst_v, d_u+=, d_v+=);
00116 
00117         // calulate the arithmetic mean
00118         *dst_u = d_u >> 2;
00119         *dst_v = d_v >> 2;
00120     }*/
00121 
00122     /*if (odd_top && odd_right) {
00123         // odd top-right pixel
00124         MMSFB_CONV_BLEND_ARGB_TO_YV12_PUSHPTR;
00125 
00126         // go to the pixel in the current line
00127         src   += sw - 1;
00128         dst_y += sw - 1;
00129         if (odd_left) {
00130             dst_u += sw >> 1;
00131             dst_v += sw >> 1;
00132         }
00133         else {
00134             dst_u += (sw - 1) >> 1;
00135             dst_v += (sw - 1) >> 1;
00136         }
00137 
00138         register unsigned int SRC;
00139         register unsigned int A;
00140 
00141         // for arithmetic mean we have to set U and V from pixels outside the current rectangle
00142         d_u = (*dst_u) * 3;
00143         d_v = (*dst_v) * 3;
00144 
00145         // calculate my pixel...
00146         MMSFB_CONV_BLEND_ARGB_TO_YV12_PIXEL(*src, *dst_y, *dst_u, *dst_v, d_u+=, d_v+=);
00147 
00148         // calulate the arithmetic mean
00149         *dst_u = d_u >> 2;
00150         *dst_v = d_v >> 2;
00151 
00152         // restore the pointers
00153         MMSFB_CONV_BLEND_ARGB_TO_YV12_POPPTR;
00154     }*/
00155 
00156 /*  if (odd_bottom && odd_left) {
00157         // odd bottom-left pixel
00158         MMSFB_CONV_BLEND_ARGB_TO_YV12_PUSHPTR;
00159 
00160         // go to the line
00161         src   += src_pitch_pix * (sh-1);
00162         dst_y += dst_pitch_pix * (sh-1);
00163         if (odd_top) {
00164             dst_u += dst_pitch_pix_half * (sh >> 1);
00165             dst_v += dst_pitch_pix_half * (sh >> 1);
00166         }
00167         else {
00168             dst_u += dst_pitch_pix_half * ((sh-1) >> 1);
00169             dst_v += dst_pitch_pix_half * ((sh-1) >> 1);
00170         }
00171 
00172         register unsigned int SRC;
00173         register unsigned int A;
00174 
00175         // for arithmetic mean we have to set U and V from pixels outside the current rectangle
00176         d_u = (*dst_u) * 3;
00177         d_v = (*dst_v) * 3;
00178 
00179         // calculate my pixel...
00180         MMSFB_CONV_BLEND_ARGB_TO_YV12_PIXEL(*src, *dst_y, *dst_u, *dst_v, d_u+=, d_v+=);
00181 
00182         // calulate the arithmetic mean
00183         *dst_u = d_u >> 2;
00184         *dst_v = d_v >> 2;
00185 
00186         // restore the pointers
00187         MMSFB_CONV_BLEND_ARGB_TO_YV12_POPPTR;
00188     }*/
00189 
00190     /*if (odd_bottom && odd_right) {
00191         // odd bottom-right pixel
00192         MMSFB_CONV_BLEND_ARGB_TO_YV12_PUSHPTR;
00193 
00194         // go to the line
00195         src   += src_pitch_pix * (sh-1);
00196         dst_y += dst_pitch_pix * (sh-1);
00197         if (odd_top) {
00198             dst_u += dst_pitch_pix_half * (sh >> 1);
00199             dst_v += dst_pitch_pix_half * (sh >> 1);
00200         }
00201         else {
00202             dst_u += dst_pitch_pix_half * ((sh-1) >> 1);
00203             dst_v += dst_pitch_pix_half * ((sh-1) >> 1);
00204         }
00205 
00206         // go to the pixel in the current line
00207         src   += sw - 1;
00208         dst_y += sw - 1;
00209         if (odd_left) {
00210             dst_u += sw >> 1;
00211             dst_v += sw >> 1;
00212         }
00213         else {
00214             dst_u += (sw - 1) >> 1;
00215             dst_v += (sw - 1) >> 1;
00216         }
00217 
00218         register unsigned int SRC;
00219         register unsigned int A;
00220 
00221         // for arithmetic mean we have to set U and V from pixels outside the current rectangle
00222         d_u = (*dst_u) * 3;
00223         d_v = (*dst_v) * 3;
00224 
00225         // calculate my pixel...
00226         MMSFB_CONV_BLEND_ARGB_TO_YV12_PIXEL(*src, *dst_y, *dst_u, *dst_v, d_u+=, d_v+=);
00227 
00228         // calulate the arithmetic mean
00229         *dst_u = d_u >> 2;
00230         *dst_v = d_v >> 2;
00231 
00232         // restore the pointers
00233         MMSFB_CONV_BLEND_ARGB_TO_YV12_POPPTR;
00234     }*/
00235 
00236     /*if (odd_top) {
00237         // odd top line
00238         MMSFB_CONV_BLEND_ARGB_TO_YV12_PUSHPTR;
00239 
00240         // calculate start and end
00241         unsigned int *line_end = src + sw;
00242         if (odd_left) {
00243             src++;
00244             dst_y++;
00245             dst_u++;
00246             dst_v++;
00247             line_end--;
00248         }
00249         if (odd_right)
00250             line_end--;
00251 
00252         // through the line
00253         while (src < line_end) {
00254             register unsigned int SRC;
00255             register unsigned int A;
00256 
00257             // for arithmetic mean we have to set U and V from pixels outside the current rectangle
00258             d_u = (*dst_u) << 1;
00259             d_v = (*dst_v) << 1;
00260 
00261             // calculate my two pixels...
00262             MMSFB_CONV_BLEND_ARGB_TO_YV12_PIXEL(*src, *dst_y, *dst_u, *dst_v, d_u+=, d_v+=);
00263             MMSFB_CONV_BLEND_ARGB_TO_YV12_PIXEL(src[src2_offs], dst_y[dst_y2_offs], *dst_u, *dst_v, d_u+=, d_v+=);
00264 
00265             // calulate the arithmetic mean
00266             *dst_u = d_u >> 2;
00267             *dst_v = d_v >> 2;
00268 
00269             // go to the next two pixels
00270             src+=2;
00271             dst_y+=2;
00272             dst_u++;
00273             dst_v++;
00274         }
00275 
00276         // restore the pointers
00277         MMSFB_CONV_BLEND_ARGB_TO_YV12_POPPTR;
00278     }*/
00279 
00280     /*if (odd_bottom) {
00281         // odd bottom line
00282         MMSFB_CONV_BLEND_ARGB_TO_YV12_PUSHPTR;
00283 
00284         // calculate start and end
00285         src   += src_pitch_pix * (sh-1);
00286         dst_y += dst_pitch_pix * (sh-1);
00287         if (odd_top) {
00288             dst_u += dst_pitch_pix_half * (sh >> 1);
00289             dst_v += dst_pitch_pix_half * (sh >> 1);
00290         }
00291         else {
00292             dst_u += dst_pitch_pix_half * ((sh-1) >> 1);
00293             dst_v += dst_pitch_pix_half * ((sh-1) >> 1);
00294         }
00295 
00296         unsigned int *line_end = src + sw;
00297         if (odd_left) {
00298             src++;
00299             dst_y++;
00300             dst_u++;
00301             dst_v++;
00302             line_end--;
00303         }
00304         if (odd_right)
00305             line_end--;
00306 
00307         // through the line
00308         while (src < line_end) {
00309             register unsigned int SRC;
00310             register unsigned int A;
00311 
00312             // for arithmetic mean we have to set U and V from pixels outside the current rectangle
00313             d_u = (*dst_u) << 1;
00314             d_v = (*dst_v) << 1;
00315 
00316             // calculate my two pixels...
00317             MMSFB_CONV_BLEND_ARGB_TO_YV12_PIXEL(*src, *dst_y, *dst_u, *dst_v, d_u+=, d_v+=);
00318             MMSFB_CONV_BLEND_ARGB_TO_YV12_PIXEL(src[src2_offs], dst_y[dst_y2_offs], *dst_u, *dst_v, d_u+=, d_v+=);
00319 
00320             // calulate the arithmetic mean
00321             *dst_u = d_u >> 2;
00322             *dst_v = d_v >> 2;
00323 
00324             // go to the next two pixels
00325             src+=2;
00326             dst_y+=2;
00327             dst_u++;
00328             dst_v++;
00329         }
00330 
00331         // restore the pointers
00332         MMSFB_CONV_BLEND_ARGB_TO_YV12_POPPTR;
00333     }*/
00334 
00335     /*if (odd_left) {
00336         // odd left line
00337         MMSFB_CONV_BLEND_ARGB_TO_YV12_PUSHPTR;
00338 
00339         // calculate start and end
00340         unsigned int *src_end = src + src_pixels;
00341         int src_pitch_diff    = src_pitch_pix << 1;
00342         int dst_pitch_diff    = dst_pitch_pix << 1;
00343         int dst_pitch_uvdiff  = dst_pitch_pix_half;
00344         if (odd_top) {
00345             src     += src_pitch_pix;
00346             src_end -= src_pitch_pix;
00347             dst_y   += dst_pitch_pix;
00348             dst_u   += dst_pitch_pix_half;
00349             dst_v   += dst_pitch_pix_half;
00350         }
00351         if (odd_bottom)
00352             src_end -= src_pitch_pix;
00353 
00354         // through all lines
00355         while (src < src_end) {
00356             // for the first pixel in the line
00357             register unsigned int SRC;
00358             register unsigned int A;
00359 
00360             // for arithmetic mean we have to set U and V from pixels outside the current rectangle
00361             d_u = (*dst_u) << 1;
00362             d_v = (*dst_v) << 1;
00363 
00364             // calculate my two pixels...
00365             MMSFB_CONV_BLEND_ARGB_TO_YV12_PIXEL(*src, *dst_y, *dst_u, *dst_v, d_u+=, d_v+=);
00366             MMSFB_CONV_BLEND_ARGB_TO_YV12_PIXEL(src[src3_offs], dst_y[dst_y3_offs], *dst_u, *dst_v, d_u+=, d_v+=);
00367 
00368             // calulate the arithmetic mean
00369             *dst_u = d_u >> 2;
00370             *dst_v = d_v >> 2;
00371 
00372             // go to the next two lines
00373             src   += src_pitch_diff;
00374             dst_y += dst_pitch_diff;
00375             dst_u += dst_pitch_uvdiff;
00376             dst_v += dst_pitch_uvdiff;
00377         }
00378 
00379         // restore the pointers
00380         MMSFB_CONV_BLEND_ARGB_TO_YV12_POPPTR;
00381     }*/
00382 
00383     /*if (odd_right) {
00384         // odd right line
00385         MMSFB_CONV_BLEND_ARGB_TO_YV12_PUSHPTR;
00386 
00387         // calculate start and end
00388         unsigned int *src_end = src + src_pixels;
00389         int src_pitch_diff    = src_pitch_pix << 1;
00390         int dst_pitch_diff    = dst_pitch_pix << 1;
00391         int dst_pitch_uvdiff  = dst_pitch_pix_half;
00392         src   += sw - 1;
00393         dst_y += sw - 1;
00394         if (odd_left) {
00395             dst_u += sw >> 1;
00396             dst_v += sw >> 1;
00397         }
00398         else {
00399             dst_u += (sw - 1) >> 1;
00400             dst_v += (sw - 1) >> 1;
00401         }
00402         if (odd_top) {
00403             src     += src_pitch_pix;
00404             src_end -= src_pitch_pix;
00405             dst_y   += dst_pitch_pix;
00406             dst_u   += dst_pitch_pix_half;
00407             dst_v   += dst_pitch_pix_half;
00408         }
00409         if (odd_bottom)
00410             src_end -= src_pitch_pix;
00411 
00412         // through all lines
00413         while (src < src_end) {
00414             // for the first pixel in the line
00415             register unsigned int SRC;
00416             register unsigned int A;
00417 
00418             // for arithmetic mean we have to set U and V from pixels outside the current rectangle
00419             d_u = (*dst_u) << 1;
00420             d_v = (*dst_v) << 1;
00421 
00422             // calculate my two pixels...
00423             MMSFB_CONV_BLEND_ARGB_TO_YV12_PIXEL(*src, *dst_y, *dst_u, *dst_v, d_u+=, d_v+=);
00424             MMSFB_CONV_BLEND_ARGB_TO_YV12_PIXEL(src[src3_offs], dst_y[dst_y3_offs], *dst_u, *dst_v, d_u+=, d_v+=);
00425 
00426             // calulate the arithmetic mean
00427             *dst_u = d_u >> 2;
00428             *dst_v = d_v >> 2;
00429 
00430             // go to the next two lines
00431             src   += src_pitch_diff;
00432             dst_y += dst_pitch_diff;
00433             dst_u += dst_pitch_uvdiff;
00434             dst_v += dst_pitch_uvdiff;
00435         }
00436 
00437         // restore the pointers
00438         MMSFB_CONV_BLEND_ARGB_TO_YV12_POPPTR;
00439     }*/
00440 
00441     // calc even positions...
00442     if (odd_top) {
00443         // odd top
00444         dy++;
00445         dh--;
00446         dst_y+=dst_pitch;
00447         dst_u+=dst_pitch >> 1;
00448         dst_v+=dst_pitch >> 1;
00449     }
00450 
00451     if (odd_bottom) {
00452         // odd bottom
00453         dh--;
00454     }
00455 
00456     if (odd_left) {
00457         // odd left
00458         dx++;
00459         dw--;
00460         dst_y++;
00461         dst_u++;
00462         dst_v++;
00463     }
00464 
00465     if (odd_right) {
00466         // odd right
00467         dw--;
00468     }
00469 
00470 
00471     // now we are even aligned and can go through a optimized loop
00472     ////////////////////////////////////////////////////////////////////////
00473     // clear Y
00474     unsigned char *dst_end = dst_y + dst_pitch_pix * dh;
00475     int dw_half = dw >> 1;
00476     while (dst_y < dst_end) {
00477         memset(dst_y, SRC_Y, dw);
00478         dst_y+= dst_pitch_pix;
00479     }
00480     // clear U
00481     dst_end = dst_u + dst_pitch_pix_half * (dh >> 1);
00482     while (dst_u < dst_end) {
00483         memset(dst_u, SRC_U, dw_half);
00484         dst_u+= dst_pitch_pix_half;
00485     }
00486     // clear V
00487     dst_end = dst_v + dst_pitch_pix_half * (dh >> 1);
00488     while (dst_v < dst_end) {
00489         memset(dst_v, SRC_V, dw_half);
00490         dst_v+= dst_pitch_pix_half;
00491     }
00492 }
00493 
00494 #endif

Generated by doxygen