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

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

Generated by doxygen