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

mmsfbdevdavinci.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 #ifdef __HAVE_FBDEV__
00034 
00035 #include "mmsgui/fb/mmsfbdevdavinci.h"
00036 #include <sys/ioctl.h>
00037 #include <cstring>
00038 
00039 #define INITCHECK  if(!this->isinitialized){MMSFB_SetError(0,"MMSFBDevDavinci is not initialized");return false;}
00040 
00041 MMSFBDevDavinci::MMSFBDevDavinci() {
00042     this->osd0.fbdev = NULL;
00043     this->osd1.fbdev = NULL;
00044     this->vid0.fbdev = NULL;
00045     this->vid1.fbdev = NULL;
00046 }
00047 
00048 MMSFBDevDavinci::~MMSFBDevDavinci() {
00049     closeDevice();
00050 }
00051 
00052 bool MMSFBDevDavinci::openDevice(char *device_file, int console) {
00053     // close the device if opened
00054     closeDevice();
00055 
00056     // open davinci frame buffers
00057     for (int i = 0; i < 4; i++) {
00058         MMSFBDev *fbdev;
00059         char      dev[100];
00060         sprintf(dev, "/dev/fb%d", i);
00061         fbdev = new MMSFBDev();
00062         if (!fbdev->openDevice(dev, (!i)?-1:-2)) {
00063             delete fbdev;
00064             closeDevice();
00065             return false;
00066         }
00067 
00068         if (memcmp(fbdev->fix_screeninfo.id, "dm_osd0_fb", 10) == 0) {
00069             this->osd0.fbdev = fbdev;
00070             strcpy(this->osd0.device, dev);
00071             this->osd0.width = -1;
00072         }
00073         else
00074         if (memcmp(fbdev->fix_screeninfo.id, "dm_vid0_fb", 10) == 0) {
00075             this->vid0.fbdev = fbdev;
00076             strcpy(this->vid0.device, dev);
00077             this->vid0.width = 0;
00078             // disable device
00079             this->vid0.fbdev->initLayer(0, 0, 0, MMSFB_PF_NONE, 0);
00080         }
00081         else
00082         if (memcmp(fbdev->fix_screeninfo.id, "dm_osd1_fb", 10) == 0) {
00083             this->osd1.fbdev = fbdev;
00084             strcpy(this->osd1.device, dev);
00085             this->osd1.width = -1;
00086         }
00087         else
00088         if (memcmp(fbdev->fix_screeninfo.id, "dm_vid1_fb", 10) == 0) {
00089             this->vid1.fbdev = fbdev;
00090             strcpy(this->vid1.device, dev);
00091             this->vid1.width = 0;
00092             // disable device
00093             this->vid1.fbdev->initLayer(0, 0, 0, MMSFB_PF_NONE, 0);
00094         }
00095         else {
00096             // not supported
00097             printf("MMSFBDevDavinci: unsupported accelerator %d (%.16s)\n", fbdev->fix_screeninfo.accel, fbdev->fix_screeninfo.id);
00098             delete fbdev;
00099             closeDevice();
00100             return false;
00101         }
00102 
00103         if (!i && !this->osd0.fbdev) {
00104             // osd0 must be at /dev/fb0
00105             printf("MMSFBDevDavinci: /dev/fb0 is not osd0\n");
00106             closeDevice();
00107             return false;
00108         }
00109     }
00110 
00111     // all initialized :)
00112     this->isinitialized = true;
00113 
00114     return true;
00115 }
00116 
00117 void MMSFBDevDavinci::closeDevice() {
00118     // close frame buffers
00119     if (this->vid1.fbdev) {
00120         delete this->vid1.fbdev;
00121         this->vid1.fbdev = NULL;
00122     }
00123     if (this->vid0.fbdev) {
00124         delete this->vid0.fbdev;
00125         this->vid0.fbdev = NULL;
00126     }
00127     if (this->osd1.fbdev) {
00128         delete this->osd1.fbdev;
00129         this->osd1.fbdev = NULL;
00130     }
00131     if (this->osd0.fbdev) {
00132         delete this->osd0.fbdev;
00133         this->osd0.fbdev = NULL;
00134     }
00135 
00136     // reset all other
00137     this->isinitialized = false;
00138 }
00139 
00140 bool MMSFBDevDavinci::waitForVSync() {
00141     // is initialized?
00142     INITCHECK;
00143 
00144     if (!this->osd0.fbdev)
00145         return false;
00146 
00147     static const int s = 0;
00148     if (ioctl(this->osd0.fbdev->fd, FBIO_WAITFORVSYNC, &s)) {
00149         // failed, well then???
00150     }
00151 
00152     return true;
00153 }
00154 
00155 bool MMSFBDevDavinci::panDisplay(int buffer_id, void *framebuffer_base) {
00156     // is initialized?
00157     INITCHECK;
00158 
00159     if   ((framebuffer_base == this->osd0.fbdev->framebuffer_base)
00160         ||(framebuffer_base == this->osd1.fbdev->framebuffer_base)) {
00161         // Graphic layer (OSD0 and OSD1)
00162         if (this->osd0.fbdev)
00163             this->osd0.fbdev->panDisplay(buffer_id);
00164         if (this->osd1.fbdev)
00165             this->osd1.fbdev->panDisplay(buffer_id);
00166         return true;
00167     }
00168     else
00169     if (framebuffer_base == this->vid0.fbdev->framebuffer_base) {
00170         // Video layer (VID0)
00171         if (this->vid0.fbdev)
00172             return this->vid0.fbdev->panDisplay(buffer_id);
00173         return false;
00174     }
00175     else
00176     if (framebuffer_base == this->vid1.fbdev->framebuffer_base) {
00177         // Video layer (VID1)
00178         if (this->vid1.fbdev)
00179             return this->vid1.fbdev->panDisplay(buffer_id);
00180         return false;
00181     }
00182 
00183     // check framebuffer_base pointer
00184     printf("MMSFBDevDavinci: framebuffer base pointer not correct\n");
00185     return false;
00186 }
00187 
00188 bool MMSFBDevDavinci::testLayer(int layer_id) {
00189     // is initialized?
00190     INITCHECK;
00191 
00192     switch (layer_id) {
00193     case 0:
00194         // default fbdev primary layer 0 on primary screen 0
00195         return true;
00196     case 1:
00197         // Video layer (VID0)
00198         return true;
00199     case 2:
00200         // Video layer (VID1)
00201         return true;
00202     default:
00203         printf("MMSFBDevDavinci: layer %d is not supported\n", layer_id);
00204         break;
00205     }
00206 
00207     return false;
00208 }
00209 
00210 
00211 bool MMSFBDevDavinci::initLayer(int layer_id, int width, int height, MMSFBSurfacePixelFormat pixelformat, int backbuffer) {
00212     // is initialized?
00213     INITCHECK;
00214 
00215     switch (layer_id) {
00216     case 0:
00217         // default fbdev primary layer 0 on primary screen 0
00218         if ((!this->osd0.fbdev) || (!this->osd1.fbdev)) {
00219             printf("MMSFBDevDavinci: OSD Layer %d not initialized\n", layer_id);
00220             return false;
00221         }
00222 
00223         if   ((pixelformat != MMSFB_PF_ARGB3565)
00224             &&(pixelformat != MMSFB_PF_RGB16)) {
00225             printf("MMSFBDevDavinci: OSD Layer %d needs pixelformat ARGB3565 or RGB16, but %s given\n",
00226                         layer_id, getMMSFBPixelFormatString(pixelformat).c_str());
00227             return false;
00228         }
00229 
00230         if (backbuffer) {
00231             printf("MMSFBDevDavinci: OSD Layer %d does not support backbuffer handling\n", layer_id);
00232             return false;
00233         }
00234 
00235         // init the two davinci osd "windows"
00236         if (this->osd0.fbdev->initLayer(0, width, height, MMSFB_PF_RGB16, backbuffer)) {
00237             // init osd1 attribute plane
00238             if (this->osd1.fbdev->initLayer(0, width, height, MMSFB_PF_A4, backbuffer)) {
00239                 // set values
00240                 this->layers[layer_id].width = width;
00241                 this->layers[layer_id].height = height;
00242                 this->layers[layer_id].pixelformat = pixelformat;
00243 
00244                 // save the buffers
00245                 memcpy(this->layers[layer_id].buffers, this->osd0.fbdev->layers[0].buffers, sizeof(this->osd0.fbdev->layers[0].buffers));
00246 
00247                 // merge OSD0 with OSD1
00248                 if (pixelformat == MMSFB_PF_ARGB3565) {
00249                     // set the alpha plane
00250                     switch (backbuffer) {
00251                     case 2:
00252                         this->layers[layer_id].buffers[2].ptr2 = this->osd1.fbdev->layers[0].buffers[2].ptr;
00253                         this->layers[layer_id].buffers[2].pitch2 = this->osd1.fbdev->layers[0].buffers[2].pitch;
00254                     case 1:
00255                         this->layers[layer_id].buffers[1].ptr2 = this->osd1.fbdev->layers[0].buffers[1].ptr;
00256                         this->layers[layer_id].buffers[1].pitch2 = this->osd1.fbdev->layers[0].buffers[1].pitch;
00257                     case 0:
00258                         this->layers[layer_id].buffers[0].ptr2 = this->osd1.fbdev->layers[0].buffers[0].ptr;
00259                         this->layers[layer_id].buffers[0].pitch2 = this->osd1.fbdev->layers[0].buffers[0].pitch;
00260                         break;
00261                     default:
00262                         return false;
00263                     }
00264                 }
00265 
00266                 // clear layer
00267                 if (pixelformat == MMSFB_PF_ARGB3565) {
00268                     MMSFBColor color(0x00, 0x00, 0x00, 0x00);
00269                     mmsfb_fillrectangle_argb3565(&(this->layers[layer_id].buffers[0]), this->layers[layer_id].height,
00270                                                  0, 0, this->layers[layer_id].width, this->layers[layer_id].height, color);
00271                 }
00272                 else {
00273                     MMSFBColor color(0x00, 0x00, 0x00, 0xff);
00274                     mmsfb_fillrectangle_rgb16(&(this->layers[layer_id].buffers[0]), this->layers[layer_id].height,
00275                                               0, 0, this->layers[layer_id].width, this->layers[layer_id].height, color);
00276                 }
00277 
00278                 // layer is initialized
00279                 this->layers[layer_id].isinitialized = true;
00280 
00281                 printf("MMSFBDevDavinci: OSD Layer %d initialized with %dx%dx%d, pixelformat %s\n",
00282                             layer_id, width, height, backbuffer+1, getMMSFBPixelFormatString(pixelformat).c_str());
00283 
00284                 this->osd0.width = this->osd1.width = width;
00285                 this->osd0.height = this->osd1.height = height;
00286                 this->osd0.pixelformat = this->osd1.pixelformat = pixelformat;
00287                 this->osd0.backbuffer = this->osd1.backbuffer = backbuffer;
00288                 return true;
00289             }
00290         }
00291         return false;
00292 
00293     case 1:
00294         // Video layer (VID0)
00295         if (!this->vid0.fbdev) {
00296             printf("MMSFBDevDavinci: Video Layer %d not initialized\n", layer_id);
00297             return false;
00298         }
00299 
00300         if (pixelformat != MMSFB_PF_YUY2) {
00301             printf("MMSFBDevDavinci: Video Layer %d needs pixelformat YUY2, but %s given\n",
00302                         layer_id, getMMSFBPixelFormatString(pixelformat).c_str());
00303             return false;
00304         }
00305 
00306         // disable VID1
00307         if (this->vid1.fbdev) {
00308             this->vid1.fbdev->initLayer(0, 0, 0, MMSFB_PF_NONE, 0);
00309             this->vid1.width = 0;
00310         }
00311 
00312         // enable VID0
00313         if (this->vid0.fbdev->initLayer(0, width, height, MMSFB_PF_YUY2, backbuffer)) {
00314             // set values
00315             this->layers[layer_id].width = width;
00316             this->layers[layer_id].height = height;
00317             this->layers[layer_id].pixelformat = pixelformat;
00318 
00319             // save the buffers
00320             memcpy(this->layers[layer_id].buffers, this->vid0.fbdev->layers[0].buffers, sizeof(this->vid0.fbdev->layers[0].buffers));
00321 
00322             // clear layer
00323             MMSFBColor color(0x00, 0x00, 0x00, 0xff);
00324             mmsfb_fillrectangle_yuy2(&(this->layers[layer_id].buffers[0]), this->layers[layer_id].height,
00325                                      0, 0, this->layers[layer_id].width, this->layers[layer_id].height, color);
00326 
00327             // layer is initialized
00328             this->layers[layer_id].isinitialized = true;
00329 
00330             printf("MMSFBDevDavinci: Video Layer %d initialized with %dx%dx%d, pixelformat %s\n",
00331                         layer_id, width, height, backbuffer+1, getMMSFBPixelFormatString(pixelformat).c_str());
00332 
00333             this->vid0.width = width;
00334             this->vid0.height = height;
00335             this->vid0.pixelformat = pixelformat;
00336             this->vid0.backbuffer = backbuffer;
00337 
00338             return true;
00339         }
00340         return false;
00341 
00342     case 2:
00343         // Video layer (VID1)
00344         if (!this->vid1.fbdev) {
00345             printf("MMSFBDevDavinci: Video Layer %d not initialized\n", layer_id);
00346             return false;
00347         }
00348 
00349         if (pixelformat != MMSFB_PF_YUY2) {
00350             printf("MMSFBDevDavinci: Video Layer %d needs pixelformat YUY2, but %s given\n",
00351                         layer_id, getMMSFBPixelFormatString(pixelformat).c_str());
00352             return false;
00353         }
00354 
00355         // disable VID0
00356         if (this->vid0.fbdev) {
00357             this->vid0.fbdev->initLayer(0, 0, 0, MMSFB_PF_NONE, 0);
00358             this->vid0.width = 0;
00359         }
00360 
00361         // enable VID1
00362         if (this->vid1.fbdev->initLayer(0, width, height, MMSFB_PF_YUY2, backbuffer)) {
00363             // set values
00364             this->layers[layer_id].width = width;
00365             this->layers[layer_id].height = height;
00366             this->layers[layer_id].pixelformat = pixelformat;
00367 
00368             // save the buffers
00369             memcpy(this->layers[layer_id].buffers, this->vid1.fbdev->layers[0].buffers, sizeof(this->vid1.fbdev->layers[0].buffers));
00370 
00371             // clear layer
00372             MMSFBColor color(0x00, 0x00, 0x00, 0xff);
00373             mmsfb_fillrectangle_yuy2(&(this->layers[layer_id].buffers[0]), this->layers[layer_id].height,
00374                                      0, 0, this->layers[layer_id].width, this->layers[layer_id].height, color);
00375 
00376             // layer is initialized
00377             this->layers[layer_id].isinitialized = true;
00378 
00379             printf("MMSFBDevDavinci: Video Layer %d initialized with %dx%dx%d, pixelformat %s\n",
00380                         layer_id, width, height, backbuffer+1, getMMSFBPixelFormatString(pixelformat).c_str());
00381 
00382             this->vid1.width = width;
00383             this->vid1.height = height;
00384             this->vid1.pixelformat = pixelformat;
00385             this->vid1.backbuffer = backbuffer;
00386 
00387             return true;
00388         }
00389         return false;
00390     default:
00391         printf("MMSFBDevDavinci: layer %d is not supported\n", layer_id);
00392         break;
00393     }
00394 
00395     return false;
00396 }
00397 
00398 bool MMSFBDevDavinci::releaseLayer(int layer_id) {
00399     // is initialized?
00400     INITCHECK;
00401 
00402     switch (layer_id) {
00403     case 0:
00404         // default fbdev primary layer 0 on primary screen 0
00405         printf("MMSFBDevDavinci: layer %d cannot be released\n", layer_id);
00406         return false;
00407     case 1:
00408         // Video layer (VID0)
00409         if (this->vid0.fbdev) {
00410             // disable
00411             this->vid0.fbdev->initLayer(0, 0, 0, MMSFB_PF_NONE, 0);
00412             // close
00413             this->vid0.fbdev->closeDevice();
00414             return true;
00415         }
00416         printf("MMSFBDevDavinci: Video Layer %d not initialized\n", layer_id);
00417         return false;
00418     case 2:
00419         // Video layer (VID1)
00420         if (this->vid1.fbdev) {
00421             // disable
00422             this->vid1.fbdev->initLayer(0, 0, 0, MMSFB_PF_NONE, 0);
00423             // close
00424             this->vid1.fbdev->closeDevice();
00425             return true;
00426         }
00427         printf("MMSFBDevDavinci: Video Layer %d not initialized\n", layer_id);
00428         return false;
00429     default:
00430         printf("MMSFBDevDavinci: layer %d is not supported\n", layer_id);
00431         break;
00432     }
00433 
00434     return false;
00435 }
00436 
00437 bool MMSFBDevDavinci::restoreLayer(int layer_id) {
00438     // is initialized?
00439     INITCHECK;
00440 
00441     switch (layer_id) {
00442     case 0:
00443         // default fbdev primary layer 0 on primary screen 0
00444         printf("MMSFBDevDavinci: layer %d cannot be restored\n", layer_id);
00445         return false;
00446     case 1:
00447         // Video layer (VID0)
00448         if (this->vid0.fbdev) {
00449             if (this->vid0.fbdev->openDevice(this->vid0.device, -2)) {
00450                 if (!this->vid0.width)
00451                     return this->vid0.fbdev->initLayer(0, 0, 0, MMSFB_PF_NONE, 0);
00452                 else
00453                 if (this->vid0.width > 0)
00454                     return this->vid0.fbdev->initLayer(0, this->vid0.width, this->vid0.height,
00455                                                        this->vid0.pixelformat, this->vid0.backbuffer);
00456                 return true;
00457             }
00458             return false;
00459         }
00460         printf("MMSFBDevDavinci: Video Layer %d not initialized\n", layer_id);
00461         return false;
00462     case 2:
00463         // Video layer (VID1)
00464         if (this->vid1.fbdev) {
00465             if (this->vid1.fbdev->openDevice(this->vid1.device, -2)) {
00466                 if (!this->vid1.width)
00467                     return this->vid1.fbdev->initLayer(0, 0, 0, MMSFB_PF_NONE, 0);
00468                 else
00469                 if (this->vid1.width > 0)
00470                     return this->vid1.fbdev->initLayer(0, this->vid1.width, this->vid1.height,
00471                                                        this->vid1.pixelformat, this->vid1.backbuffer);
00472                 return true;
00473             }
00474             return false;
00475         }
00476         printf("MMSFBDevDavinci: Video Layer %d not initialized\n", layer_id);
00477         return false;
00478     default:
00479         printf("MMSFBDevDavinci: layer %d is not supported\n", layer_id);
00480         break;
00481     }
00482 
00483     return false;
00484 }
00485 
00486 bool MMSFBDevDavinci::vtGetFd(int *fd) {
00487     if (this->osd0.fbdev) {
00488         if (this->osd0.fbdev->vt.fd != -1) {
00489             *fd = this->osd0.fbdev->vt.fd;
00490             return true;
00491         }
00492     }
00493     return false;
00494 }
00495 
00496 #endif

Generated by doxygen