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
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
00294 if (this->vid.fbdev->initLayer(0, width, height, pixelformat, backbuffer)) {
00295
00296 this->layers[layer_id].width = width;
00297 this->layers[layer_id].height = height;
00298 this->layers[layer_id].pixelformat = pixelformat;
00299
00300
00301 memcpy(this->layers[layer_id].buffers, this->vid.fbdev->layers[0].buffers, sizeof(this->vid.fbdev->layers[0].buffers));
00302
00303
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
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
00328 if (this->osd1.fbdev->initLayer(0, width, height, pixelformat, backbuffer)) {
00329
00330 this->layers[layer_id].width = width;
00331 this->layers[layer_id].height = height;
00332 this->layers[layer_id].pixelformat = pixelformat;
00333
00334
00335 memcpy(this->layers[layer_id].buffers, this->osd1.fbdev->layers[0].buffers, sizeof(this->osd1.fbdev->layers[0].buffers));
00336
00337
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
00358 INITCHECK;
00359
00360 switch (layer_id) {
00361 case 0:
00362
00363 printf("MMSFBDevOmap: layer %d cannot be released\n", layer_id);
00364 return false;
00365 case 1:
00366
00367 if (this->vid.fbdev) {
00368
00369 this->vid.fbdev->initLayer(0, 0, 0, MMSFB_PF_NONE, 0);
00370
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
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
00390 INITCHECK;
00391
00392 switch (layer_id) {
00393 case 0:
00394
00395 printf("MMSFBDevOmap: layer %d cannot be restored\n", layer_id);
00396 return false;
00397 case 1:
00398
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
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
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
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
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