00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
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
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
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
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
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
00106 this->primary = &this->osd1;
00107
00108 this->osd1.fbdev->initLayer(0, 0, 0, MMSFB_PF_NONE, 0);
00109 break;
00110 }
00111 }
00112 else {
00113
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
00126 closeDevice();
00127
00128
00129 this->console = console;
00130 this->isinitialized = true;
00131 return true;
00132 }
00133
00134 void MMSFBDevOmap::closeDevice() {
00135
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
00151 this->isinitialized = false;
00152 }
00153
00154 bool MMSFBDevOmap::waitForVSync() {
00155
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
00167 }
00168
00169 return true;
00170 }
00171
00172 bool MMSFBDevOmap::panDisplay(int buffer_id, void *framebuffer_base) {
00173
00174 INITCHECK;
00175
00176 if (this->osd0.fbdev && framebuffer_base == this->osd0.fbdev->framebuffer_base) {
00177
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
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
00192 if (this->osd1.fbdev)
00193 return this->osd1.fbdev->MMSFBDev::panDisplay(buffer_id);
00194 return false;
00195 }
00196
00197
00198 printf("MMSFBDevOmap: framebuffer base pointer not correct\n");
00199 return false;
00200 }
00201
00202 bool MMSFBDevOmap::testLayer(int layer_id) {
00203
00204 INITCHECK;
00205
00206 switch (layer_id) {
00207 case 0:
00208
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
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
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
00242 INITCHECK;
00243
00244 if (!testLayer(layer_id)) {
00245
00246 return false;
00247 }
00248
00249 switch (layer_id) {
00250 case 0:
00251
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
00261 if (this->osd0.fbdev->initLayer(0, width, height, pixelformat, backbuffer)) {
00262
00263 this->layers[layer_id].width = width;
00264 this->layers[layer_id].height = height;
00265 this->layers[layer_id].pixelformat = pixelformat;
00266
00267
00268 memcpy(this->layers[layer_id].buffers, this->osd0.fbdev->layers[0].buffers, sizeof(this->osd0.fbdev->layers[0].buffers));
00269
00270
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
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
00296 if (this->vid.fbdev->initLayer(0, width, height, pixelformat, backbuffer)) {
00297
00298 this->layers[layer_id].width = width;
00299 this->layers[layer_id].height = height;
00300 this->layers[layer_id].pixelformat = pixelformat;
00301
00302
00303 memcpy(this->layers[layer_id].buffers, this->vid.fbdev->layers[0].buffers, sizeof(this->vid.fbdev->layers[0].buffers));
00304
00305
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
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
00330 if (this->osd1.fbdev->initLayer(0, width, height, pixelformat, backbuffer)) {
00331
00332 this->layers[layer_id].width = width;
00333 this->layers[layer_id].height = height;
00334 this->layers[layer_id].pixelformat = pixelformat;
00335
00336
00337 memcpy(this->layers[layer_id].buffers, this->osd1.fbdev->layers[0].buffers, sizeof(this->osd1.fbdev->layers[0].buffers));
00338
00339
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
00360 INITCHECK;
00361
00362 switch (layer_id) {
00363 case 0:
00364
00365 printf("MMSFBDevOmap: layer %d cannot be released\n", layer_id);
00366 return false;
00367 case 1:
00368
00369 if (this->vid.fbdev) {
00370
00371 this->vid.fbdev->initLayer(0, 0, 0, MMSFB_PF_NONE, 0);
00372
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
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
00392 INITCHECK;
00393
00394 switch (layer_id) {
00395 case 0:
00396
00397 printf("MMSFBDevOmap: layer %d cannot be restored\n", layer_id);
00398 return false;
00399 case 1:
00400
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
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
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
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
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