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-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 <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 #if 0
00287         // Video layer (VID)
00288         if   (pixelformat != MMSFB_PF_I420) {
00289             printf("MMSFBDevOmap: Video Layer %d needs pixelformat I420 (==YUV420) but %s given\n",
00290                         layer_id, getMMSFBPixelFormatString(pixelformat).c_str());
00291             return false;
00292         }
00293 #endif
00294 
00295         // enable VID
00296         if (this->vid.fbdev->initLayer(0, width, height, pixelformat, backbuffer)) {
00297             // set values
00298             this->layers[layer_id].width = width;
00299             this->layers[layer_id].height = height;
00300             this->layers[layer_id].pixelformat = pixelformat;
00301 
00302             // save the buffers
00303             memcpy(this->layers[layer_id].buffers, this->vid.fbdev->layers[0].buffers, sizeof(this->vid.fbdev->layers[0].buffers));
00304 
00305             // layer is initialized
00306             this->layers[layer_id].isinitialized = true;
00307 
00308             printf("MMSFBDevOmap: Video Layer %d initialized with %dx%dx%d, pixelformat %s\n",
00309                         layer_id, width, height, backbuffer+1, getMMSFBPixelFormatString(pixelformat).c_str());
00310 
00311             this->vid.width = width;
00312             this->vid.height = height;
00313             this->vid.pixelformat = pixelformat;
00314             this->vid.backbuffer = backbuffer;
00315 
00316             return true;
00317         }
00318         return false;
00319 
00320     case 2:
00321         // OSD layer (OSD1)
00322         if   ((pixelformat != MMSFB_PF_ARGB)
00323             &&(pixelformat != MMSFB_PF_RGB32)) {
00324             printf("MMSFBDevOmap: OSD Layer %d needs pixelformat ARGB or RGB32, but %s given\n",
00325                         layer_id, getMMSFBPixelFormatString(pixelformat).c_str());
00326             return false;
00327         }
00328 
00329         // enable OSD1
00330         if (this->osd1.fbdev->initLayer(0, width, height, pixelformat, backbuffer)) {
00331             // set values
00332             this->layers[layer_id].width = width;
00333             this->layers[layer_id].height = height;
00334             this->layers[layer_id].pixelformat = pixelformat;
00335 
00336             // save the buffers
00337             memcpy(this->layers[layer_id].buffers, this->osd1.fbdev->layers[0].buffers, sizeof(this->osd1.fbdev->layers[0].buffers));
00338 
00339             // layer is initialized
00340             this->layers[layer_id].isinitialized = true;
00341 
00342             printf("MMSFBDevOmap: OSD Layer %d initialized with %dx%dx%d, pixelformat %s\n",
00343                         layer_id, width, height, backbuffer+1, getMMSFBPixelFormatString(pixelformat).c_str());
00344 
00345             this->osd1.width = width;
00346             this->osd1.height = height;
00347             this->osd1.pixelformat = pixelformat;
00348             this->osd1.backbuffer = backbuffer;
00349 
00350             return true;
00351         }
00352         return false;
00353     }
00354 
00355     return false;
00356 }
00357 
00358 bool MMSFBDevOmap::releaseLayer(int layer_id) {
00359     // is initialized?
00360     INITCHECK;
00361 
00362     switch (layer_id) {
00363     case 0:
00364         // default fbdev primary layer 0 on primary screen 0
00365         printf("MMSFBDevOmap: layer %d cannot be released\n", layer_id);
00366         return false;
00367     case 1:
00368         // Video layer (VID)
00369         if (this->vid.fbdev) {
00370             // disable
00371             this->vid.fbdev->initLayer(0, 0, 0, MMSFB_PF_NONE, 0);
00372             // close
00373             this->vid.fbdev->closeDevice();
00374             return true;
00375         }
00376         printf("MMSFBDevOmap: Video Layer %d not initialized\n", layer_id);
00377         return false;
00378     case 2:
00379         // OSD layer
00380         printf("MMSFBDevOmap: layer %d cannot be released\n", layer_id);
00381         return false;
00382     default:
00383         printf("MMSFBDevOmap: layer %d is not supported\n", layer_id);
00384         break;
00385     }
00386 
00387     return false;
00388 }
00389 
00390 bool MMSFBDevOmap::restoreLayer(int layer_id) {
00391     // is initialized?
00392     INITCHECK;
00393 
00394     switch (layer_id) {
00395     case 0:
00396         // default fbdev primary layer 0 on primary screen 0
00397         printf("MMSFBDevOmap: layer %d cannot be restored\n", layer_id);
00398         return false;
00399     case 1:
00400         // Video layer (VID)
00401         if (this->vid.fbdev) {
00402             if (this->vid.fbdev->openDevice(this->vid.device, -2)) {
00403                 if (!this->vid.width)
00404                     return this->vid.fbdev->initLayer(0, 0, 0, MMSFB_PF_NONE, 0);
00405                 else
00406                 if (this->vid.width > 0)
00407                     return this->vid.fbdev->initLayer(0, this->vid.width, this->vid.height,
00408                                                       this->vid.pixelformat, this->vid.backbuffer);
00409                 return true;
00410             }
00411             return false;
00412         }
00413         printf("MMSFBDevOmap: Video Layer %d not initialized\n", layer_id);
00414         return false;
00415     case 2:
00416         // OSD layer (OSD1)
00417         printf("MMSFBDevOmap: layer %d cannot be restored\n", layer_id);
00418         return false;
00419     default:
00420         printf("MMSFBDevOmap: layer %d is not supported\n", layer_id);
00421         break;
00422     }
00423 
00424     return false;
00425 }
00426 
00427 bool MMSFBDevOmap::vtGetFd(int *fd) {
00428     if ((this->primary)&&(this->primary->fbdev)) {
00429         if (this->primary->fbdev->vt.fd != -1) {
00430             *fd = this->primary->fbdev->vt.fd;
00431             return true;
00432         }
00433     }
00434     return false;
00435 }
00436 
00437 
00438 bool MMSFBDevOmap::onGenFBPixelFormatDev(MMSFBSurfacePixelFormat pf, unsigned int *nonstd_format, MMSFBPixelDef *pixeldef) {
00439 
00440     if (nonstd_format) {
00441         switch (pf) {
00442         case MMSFB_PF_I420:
00443             *nonstd_format = OMAPFB_COLOR_YUV420;
00444             return true;
00445         default:
00446             break;
00447         }
00448     }
00449     return false;
00450 }
00451 
00452 bool MMSFBDevOmap::onDisableDev(int fd, string device_file) {
00453     // setup omap specific plane
00454     struct omapfb_plane_info plane_info;
00455     ioctl(fd, OMAPFB_QUERY_PLANE, &plane_info);
00456     plane_info.enabled = 0;
00457 
00458     printf("MMSFBDevOmap: disable plane, %s\n", device_file.c_str());
00459     if (ioctl(fd, OMAPFB_SETUP_PLANE, &plane_info)) {
00460         printf("MMSFBDevOmap: could not disable plane, %s\n", device_file.c_str());
00461         return false;
00462     }
00463 
00464     return true;
00465 }
00466 
00467 bool MMSFBDevOmap::onActivateDev(int fd, string device_file, struct fb_var_screeninfo *var_screeninfo,
00468                                  int width, int height, MMSFBSurfacePixelFormat pixelformat, bool switch_mode) {
00469     if (switch_mode) {
00470         if (ioctl(fd, FBIOPUT_VSCREENINFO, var_screeninfo) < 0) {
00471             printf("MMSFBDevOmap: could not switch to mode %dx%d, pixelformat %s (%d bits, nonstd %d), %s\n",
00472                     width, height, getMMSFBPixelFormatString(pixelformat).c_str(),
00473                     var_screeninfo->bits_per_pixel, var_screeninfo->nonstd,
00474                     device_file.c_str());
00475             return false;
00476         }
00477     }
00478 
00479     // enable alpha blending
00480     if (var_screeninfo->transp.length) {
00481         printf("MMSFBDevOmap: set alpha blending!\n");
00482         int sysfd;
00483         sysfd = open("/sys/devices/platform/omapdss/manager0/alpha_blending_enabled",O_WRONLY);
00484         if(sysfd == -1) {
00485             printf("MMSFBDevOmap: could not access display manager (/sys/devices/platform/omapdss/manager0/alpha_blending_enabled)!\n");
00486         }
00487         write(sysfd,"1\n",2);
00488         close(sysfd);
00489     }
00490 
00491     // setup omap specific plane
00492     struct omapfb_plane_info plane_info;
00493     ioctl(fd, OMAPFB_QUERY_PLANE, &plane_info);
00494     plane_info.enabled = 1;
00495     plane_info.pos_x = 0;
00496     plane_info.pos_y = 0;
00497     plane_info.out_width = var_screeninfo->xres;
00498     plane_info.out_height = var_screeninfo->yres;
00499 
00500     printf("MMSFBDevOmap: enable plane, %s\n", device_file.c_str());
00501     if (ioctl(fd, OMAPFB_SETUP_PLANE, &plane_info)) {
00502         printf("MMSFBDevOmap: could not enable plane, %s\n", device_file.c_str());
00503         return false;
00504     }
00505 
00506     return true;
00507 }
00508 
00509 #endif

Generated by doxygen