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

mmskms.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_KMS__
00034 
00035 #include <unistd.h>
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <errno.h>
00039 #include <string.h>
00040 #include <strings.h>
00041 #include <fcntl.h>
00042 #include <sys/ioctl.h>
00043 #include <sys/mman.h>
00044 #include <sys/kd.h>
00045 #include "mmsgui/fb/mmskms.h"
00046 #include "mmsgui/fb/mmsfbconv.h"
00047 #include "mmsgui/fb/fb.h"
00048 
00049 #define INITCHECK  if(!this->isinitialized){MMSFB_SetError(0,"MMSKms is not initialized");return false;}
00050 
00051 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
00052 
00053 static void page_flip_handler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *data)
00054 {
00055     int *waiting_for_flip = (int*)data;
00056     *waiting_for_flip = 0;
00057 }
00058 
00059 MMSKms::MMSKms() {
00060     // init fb vals
00061     this->isinitialized = false;
00062     this->framebuffer_base = NULL;
00063     this->drm.fd = -1;
00064     memset(this->layers, 0, sizeof(this->layers));
00065     this->layers_cnt = 0;
00066     this->active_screen = 0;
00067 
00068     if (MMSFBBase_rotate180) {
00069         this->rotate180 = true;
00070         MMSFBBase_rotate180 = false;
00071     } else {
00072         this->rotate180 = false;
00073     }
00074 
00075 }
00076 
00077 MMSKms::~MMSKms() {
00078     closeDevice();
00079 }
00080 
00081 
00082 void MMSKms::dump_blob(uint32_t blob_id)
00083 {
00084         uint32_t i;
00085         unsigned char *blob_data;
00086         drmModePropertyBlobPtr blob;
00087 
00088         blob = drmModeGetPropertyBlob(this->drm.fd, blob_id);
00089         if (!blob)
00090                 return;
00091 
00092         blob_data = (unsigned char *)blob->data;
00093 
00094         for (i = 0; i < blob->length; i++) {
00095                 if (i % 16 == 0)
00096                         printf("\n\t\t\t");
00097                 printf("%.2hhx", blob_data[i]);
00098         }
00099         printf("\n");
00100 
00101         drmModeFreePropertyBlob(blob);
00102 }
00103 
00104 
00105 void MMSKms::dump_prop(uint32_t prop_id, uint64_t value)
00106 {
00107         int i;
00108         drmModePropertyPtr prop;
00109 
00110         prop = drmModeGetProperty(this->drm.fd, prop_id);
00111 
00112         printf("\t%d", prop_id);
00113         if (!prop) {
00114                 printf("\n");
00115                 return;
00116         }
00117 
00118         printf(" %s:\n", prop->name);
00119 
00120         printf("\t\tflags:");
00121         if (prop->flags & DRM_MODE_PROP_PENDING)
00122                 printf(" pending");
00123         if (prop->flags & DRM_MODE_PROP_RANGE)
00124                 printf(" range");
00125         if (prop->flags & DRM_MODE_PROP_IMMUTABLE)
00126                 printf(" immutable");
00127         if (prop->flags & DRM_MODE_PROP_ENUM)
00128                 printf(" enum");
00129         if (prop->flags & DRM_MODE_PROP_BITMASK)
00130                 printf(" bitmask");
00131         if (prop->flags & DRM_MODE_PROP_BLOB)
00132                 printf(" blob");
00133         printf("\n");
00134 
00135         if (prop->flags & DRM_MODE_PROP_RANGE) {
00136                 printf("\t\tvalues:");
00137                 for (i = 0; i < prop->count_values; i++)
00138                         printf(" %llu", prop->values[i]);
00139                 printf("\n");
00140         }
00141 
00142         if (prop->flags & DRM_MODE_PROP_ENUM) {
00143                 printf("\t\tenums:");
00144                 for (i = 0; i < prop->count_enums; i++)
00145                         printf(" %s=%llu", prop->enums[i].name,
00146                                prop->enums[i].value);
00147                 printf("\n");
00148         } else if (prop->flags & DRM_MODE_PROP_BITMASK) {
00149                 printf("\t\tvalues:");
00150                 for (i = 0; i < prop->count_enums; i++)
00151                         printf(" %s=0x%llx", prop->enums[i].name,
00152                                (1LL << prop->enums[i].value));
00153                 printf("\n");
00154         } else {
00155         }
00156 
00157         if (prop->flags & DRM_MODE_PROP_BLOB) {
00158                 printf("\t\tblobs:\n");
00159                 for (i = 0; i < prop->count_blobs; i++)
00160                         dump_blob(prop->blob_ids[i]);
00161                 printf("\n");
00162         } else {
00163         }
00164 
00165         printf("\t\tvalue:");
00166         if (prop->flags & DRM_MODE_PROP_BLOB)
00167                 dump_blob(value);
00168         else
00169                 printf(" %llu\n", value);
00170 
00171         drmModeFreeProperty(prop);
00172 }
00173 
00174 bool MMSKms::init_drm()
00175 {
00176     static const char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "omapdrm", "exynos" };
00177     drmModeRes *resources;
00178     drmModeConnector *connector = NULL;
00179     drmModeEncoder *encoder = NULL;
00180     int i, area;
00181 
00182     for (i = 0; i < ARRAY_SIZE(modules); i++) {
00183         printf("trying to load module %s...", modules[i]);
00184         this->drm.fd = drmOpen(modules[i], NULL);
00185 
00186         if (this->drm.fd < 0) {
00187             printf("failed.\n");
00188         } else {
00189             printf("success.\n");
00190             break;
00191         }
00192     }
00193 
00194     if (this->drm.fd < 0) {
00195         printf("could not open drm device\n");
00196         return false;
00197     }
00198 
00199     resources = drmModeGetResources(this->drm.fd);
00200     if (!resources) {
00201         printf("drmModeGetResources failed: %s\n", strerror(errno));
00202         drmClose(this->drm.fd);
00203         this->drm.fd = -1;
00204         return false;
00205     }
00206 
00207     /* find a connected connector: */
00208     for (i = 0; i < resources->count_connectors; i++) {
00209         connector = drmModeGetConnector(this->drm.fd, resources->connectors[i]);
00210 
00211         if (connector->connection == DRM_MODE_CONNECTED) {
00212             /* it's connected, let's use this! */
00213             break;
00214         }
00215 
00216         drmModeFreeConnector(connector);
00217         connector = NULL;
00218     }
00219 
00220     if (!connector) {
00221         /* we could be fancy and listen for hotplug events and wait for
00222         * a connector..
00223         */
00224         printf("no connected connector!\n");
00225         drmClose(this->drm.fd);
00226         this->drm.fd = -1;
00227         return false;
00228     }
00229 
00230     /* find highest resolution mode: */
00231     for (i = 0, area = 0; i < connector->count_modes; i++) {
00232         drmModeModeInfo *current_mode = &connector->modes[i];
00233 //      printf("curr mode h: %d, v: %d\n", current_mode->hdisplay, current_mode->vdisplay);
00234         int current_area = current_mode->hdisplay * current_mode->vdisplay;
00235 
00236         if (current_area > area) {
00237             this->drm.mode = current_mode;
00238             area = current_area;
00239         }
00240     }
00241 
00242     if (!this->drm.mode) {
00243         printf("could not find mode!\n");
00244         drmClose(this->drm.fd);
00245         this->drm.fd = -1;
00246         return false;
00247     }
00248 
00249     /* find encoder: */
00250     for (i = 0; i < resources->count_encoders; i++) {
00251         encoder = drmModeGetEncoder(this->drm.fd, resources->encoders[i]);
00252 
00253         if (encoder->encoder_id == connector->encoder_id)
00254             break;
00255 
00256         drmModeFreeEncoder(encoder);
00257         encoder = NULL;
00258     }
00259 
00260     if (!encoder) {
00261         printf("no encoder!\n");
00262         drmClose(this->drm.fd);
00263         this->drm.fd = -1;
00264         return false;
00265     }
00266 
00267     this->drm.crtc_id = encoder->crtc_id;
00268     this->drm.connector_id = connector->connector_id;
00269 
00270     if (this->rotate180) {
00271         drmModeObjectSetProperty(this->drm.fd, encoder->crtc_id, DRM_MODE_OBJECT_CRTC, 8, 4);
00272     }
00273 
00274 //  drmModeObjectPropertiesPtr tmp = drmModeObjectGetProperties(this->drm.fd, this->drm.crtc_id, DRM_MODE_OBJECT_CRTC);
00275 //
00276 //  if (tmp)
00277 //      printf("properties count: %d\n", tmp->count_props);
00278 //
00279 //  printf("  props:\n");
00280 //    int j = 0;
00281 //  if (tmp) {
00282 //          for (j = 0; j < tmp->count_props; j++)
00283 //                  dump_prop(tmp->props[j],
00284 //                          tmp->prop_values[j]);
00285 //          drmModeFreeObjectProperties(tmp);
00286 //  } else {
00287 //          printf("\tcould not get mode properties: %s\n",
00288 //                 strerror(errno));
00289 //  }
00290 
00291 //    drmModeObjectPropertiesPtr props;
00292     drmModePlaneRes *plane_resources;
00293     drmModePlane *ovr;
00294 
00295     plane_resources = drmModeGetPlaneResources(this->drm.fd);
00296     if (!plane_resources) {
00297             fprintf(stderr, "drmModeGetPlaneResources failed: %s\n",
00298                     strerror(errno));
00299             return false;
00300     }
00301 
00302 //  printf("Planes:\n");
00303 //  printf("id\tcrtc\tfb\tCRTC x,y\tx,y\tgamma size\n");
00304     for (i = 0; i < plane_resources->count_planes; i++) {
00305             ovr = drmModeGetPlane(this->drm.fd, plane_resources->planes[i]);
00306             if (!ovr) {
00307                     fprintf(stderr, "drmModeGetPlane failed: %s\n",
00308                             strerror(errno));
00309                     continue;
00310             }
00311 
00312 //          printf("%d\t%d\t%d\t%d,%d\t\t%d,%d\t%d\n",
00313 //                 ovr->plane_id, ovr->crtc_id, ovr->fb_id,
00314 //                 ovr->crtc_x, ovr->crtc_y, ovr->x, ovr->y,
00315 //                 ovr->gamma_size);
00316 //
00317 //          if (!ovr->count_formats)
00318 //                  continue;
00319 //
00320 //          printf("  formats:");
00321 //          for (j = 0; j < ovr->count_formats; j++)
00322 //                  printf(" %4.4s", (char *)&ovr->formats[j]);
00323 //          printf("\n");
00324 //
00325 //          printf("  props:\n");
00326 //          props = drmModeObjectGetProperties(this->drm.fd, ovr->plane_id,
00327 //                                             DRM_MODE_OBJECT_PLANE);
00328 //          if (props) {
00329 //                  for (j = 0; j < props->count_props; j++)
00330 //                          dump_prop(props->props[j],
00331 //                                    props->prop_values[j]);
00332 //                  drmModeFreeObjectProperties(props);
00333 //          } else {
00334 //                  printf("\tcould not get plane properties: %s\n",
00335 //                         strerror(errno));
00336 //          }
00337 
00338             if (ovr->possible_crtcs & this->drm.crtc_id){
00339                     this->drm.plane_id = ovr->plane_id;
00340                     break;
00341             }
00342 
00343 //          drmModeFreePlane(ovr);
00344     }
00345 //  printf("\n");
00346 
00347 
00348     return true;
00349 }
00350 
00351 bool MMSKms::init_gbm()
00352 {
00353     this->drm.dev = gbm_create_device(this->drm.fd);
00354 
00355     if (!init_omap()) {
00356         printf("failed to initialize OMAP\n");
00357         return false;
00358     }
00359 
00360 //  this->bo = gbm_bo_import(this->drm.dev, GBM_BO_IMPORT_WL_BUFFER, this->framebuffer_base, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
00361 
00362     //  this->drm.surface = (struct gbm_surface*) calloc(1, sizeof *this->drm.surface);
00363     //
00364     //  this->drm.surface->gbm_device = gbm_bo_get_device(this->bo);
00365     //  this->drm.surface->width =  gbm_bo_get_width(this->bo);
00366     //  this->drm.surface->height = gbm_bo_get_height(this->bo);
00367     //  this->drm.surface->format = gbm_bo_get_format(this->bo);
00368     //  this->drm.surface->flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING;
00369 
00370     if (outputtype == MMSFB_OT_OGL) {
00371         this->drm.surface = gbm_surface_create(this->drm.dev, this->drm.mode->hdisplay, this->drm.mode->vdisplay,
00372                             GBM_FORMAT_ARGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
00373 
00374         if (!this->drm.surface) {
00375             printf("failed to create gbm surface\n");
00376             drmClose(this->drm.fd);
00377             this->drm.fd = -1;
00378             return false;
00379         }
00380 
00381         this->bo = gbm_surface_lock_front_buffer(this->drm.surface);
00382         this->fb = (DRM_FB*)drm_fb_get_from_bo(this->bo);
00383         gbm_surface_release_buffer(this->drm.surface, this->bo);
00384     }
00385 
00386     return true;
00387 }
00388 
00389 static void
00390 drm_fb_destroy_callback(struct gbm_bo *bo, void *data)
00391 {
00392     DRM_FB *fb = (DRM_FB*)data;
00393     struct gbm_device *gbm = gbm_bo_get_device(bo);
00394     if(gbm) {
00395         int fd = gbm_device_get_fd(gbm);
00396         if (fb->fb_id)
00397             drmModeRmFB(fd, fb->fb_id);
00398     }
00399 
00400     free(fb);
00401 }
00402 
00403 DRM_FB* MMSKms::drm_fb_get_from_bo(struct gbm_bo *bo)
00404 {
00405     DRM_FB *fb = (DRM_FB*)gbm_bo_get_user_data(bo);
00406     uint32_t width, height, stride, handle;
00407     int ret;
00408 
00409     if (fb)
00410         return fb;
00411 
00412     fb = (DRM_FB*)calloc(1, sizeof *fb);
00413     fb->bo = bo;
00414 
00415     width = gbm_bo_get_width(bo);
00416     height = gbm_bo_get_height(bo);
00417     stride = gbm_bo_get_stride(bo);
00418     handle = gbm_bo_get_handle(bo).u32;
00419 
00420     ret = drmModeAddFB(this->drm.fd, width, height, 24, 32, stride, handle, &fb->fb_id);
00421     if (ret) {
00422         printf("failed to create fb: %s\n", strerror(errno));
00423         free(fb);
00424         return NULL;
00425     }
00426 
00427     ret =0;
00428     ret = drmModeSetCrtc(this->drm.fd, this->drm.crtc_id, fb->fb_id, 0, 0,
00429                         &this->drm.connector_id, 1, this->drm.mode);
00430 
00431     if (ret) {
00432         printf("failed to set mode: %s\n", strerror(errno));
00433     }
00434 
00435     if (this->rotate180) {
00436         drmModeObjectSetProperty(this->drm.fd, this->drm.plane_id, DRM_MODE_OBJECT_PLANE, 8, 4);
00437     }
00438 
00439     if ((this->drm.width != this->drm.mode->hdisplay) || (this->drm.height != this->drm.mode->vdisplay)) {
00440         ret = drmModeSetPlane(this->drm.fd, this->drm.plane_id, this->drm.crtc_id,
00441                 fb->fb_id, 0, 0, 0, this->drm.mode->hdisplay, this->drm.mode->vdisplay,
00442                 0, (this->drm.mode->vdisplay-this->drm.height) << 16, this->drm.width << 16, this->drm.height << 16);
00443 
00444         if (ret)
00445             printf("drmModeSetPlane failed\n");
00446     }
00447 
00448     gbm_bo_set_user_data(bo, fb, drm_fb_destroy_callback);
00449 
00450     return fb;
00451 }
00452 
00453 bool MMSKms::init_omap()
00454 {
00455     this->drm.o_dev = omap_device_new(this->drm.fd);
00456 
00457     if (!this->drm.dev) {
00458         printf("ERROR:couldn't create omap device\n");
00459         return false;
00460     }
00461 
00462     uint32_t bo_flags = OMAP_BO_TILED_32 | OMAP_BO_SCANOUT | OMAP_BO_WC;
00463 
00464     if (bo_flags & OMAP_BO_TILED) {
00465         this->o_bo = omap_bo_new_tiled(this->drm.o_dev, this->drm.mode->hdisplay, this->drm.mode->vdisplay, bo_flags);
00466     } else {
00467         this->o_bo = omap_bo_new(this->drm.o_dev, this->drm.mode->hdisplay * this->drm.mode->vdisplay * 32 / 8, bo_flags);
00468     }
00469 
00470     if (!this->o_bo) {
00471         printf("failed to create omap bo\n");
00472         drmClose(this->drm.fd);
00473         this->drm.fd = -1;
00474         return false;
00475     }
00476 
00477 
00478     uint32_t handle;
00479     int ret;
00480 
00481     this->fb = (DRM_FB*)calloc(1, sizeof *this->fb);
00482 
00483     unsigned int alignedWidth;
00484     alignedWidth = (this->drm.mode->hdisplay + (32 - 1)) & ~(32 - 1);
00485     this->stride = ((alignedWidth * 32) + 7) / 8;
00486     if (bo_flags & OMAP_BO_TILED)
00487         this->stride = (stride + (4096 - 1)) & ~(4096 - 1);
00488 
00489     handle = omap_bo_handle(this->o_bo);
00490 
00491     ret = drmModeAddFB(this->drm.fd, this->drm.mode->hdisplay, this->drm.mode->vdisplay, 24, 32, this->stride, handle, &fb->fb_id);
00492     if (ret) {
00493         printf("failed to create fb: %s\n", strerror(errno));
00494         free(this->fb);
00495         return false;
00496     }
00497 
00498 //  omap_bo_cpu_prep(this->o_bo, OMAP_GEM_WRITE);
00499     this->framebuffer_base = omap_bo_map(this->o_bo);
00500 //  omap_bo_cpu_fini(this->o_bo, OMAP_GEM_WRITE);
00501 
00502     return true;
00503 }
00504 
00505 bool MMSKms::openDevice(MMSFBOutputType outputtype) {
00506     // close the device if opened
00507     this->outputtype = outputtype;
00508     closeDevice();
00509 
00510     if (!init_drm()) {
00511         printf("failed to initialize DRM\n");
00512         return false;
00513     }
00514 
00515     if (!init_gbm()) {
00516         printf("failed to initialize GBM\n");
00517         return false;
00518     }
00519 
00520     memset(&this->evctx, 0, sizeof(this->evctx));
00521     this->evctx.version = DRM_EVENT_CONTEXT_VERSION;
00522     this->evctx.page_flip_handler = page_flip_handler;
00523 
00524     // all initialized :)
00525     this->isinitialized = true;
00526 
00527     return true;
00528 }
00529 
00530 void MMSKms::closeDevice() {
00531 
00532     if (this->drm.fd != -1) {
00533         drmClose(this->drm.fd);
00534         this->drm.fd = -1;
00535     }
00536 
00537     // reset all other
00538     this->isinitialized = false;
00539     memset(this->layers, 0, sizeof(this->layers));
00540     this->layers_cnt = 0;
00541     this->active_screen = 0;
00542 }
00543 
00544 bool MMSKms::isInitialized() {
00545     return this->isinitialized;
00546 }
00547 
00548 bool MMSKms::panDisplay(int buffer_id, void *framebuffer_base) {
00549     // is initialized?
00550     INITCHECK;
00551 
00552     // check framebuffer_base pointer
00553     if (framebuffer_base) {
00554         if (framebuffer_base != this->framebuffer_base) {
00555             printf("MMSFBDev: framebuffer base pointer not correct\n");
00556             return false;
00557         }
00558     }
00559 
00560     fd_set fds;
00561     FD_ZERO(&fds);
00562     FD_SET(0, &fds);
00563     FD_SET(this->drm.fd, &fds);
00564 
00565     int waiting_for_flip = 1;
00566     int ret = 0;
00567 
00568     printf("MMSKMS: page flip (pan display)\n");
00569 
00570     ret = drmModePageFlip(this->drm.fd, this->drm.crtc_id, this->fb->fb_id, DRM_MODE_PAGE_FLIP_EVENT, &waiting_for_flip);
00571     if (ret) {
00572         printf("OPENGL_SWAP: failed to queue page flip\n");
00573         return false;
00574     }
00575 
00576     while (waiting_for_flip) {
00577         ret = select(this->drm.fd + 1, &fds, NULL, NULL, NULL);
00578         if (ret < 0) {
00579             printf("OPENGL_SWAP: select err\n");
00580             return false;
00581         } else if (ret == 0) {
00582             printf("OPENGL_SWAP: select timeout!\n");
00583             return false;
00584         } else if (FD_ISSET(0, &fds)) {
00585             printf("OPENGL_SWAP: user interrupted!\n");
00586             break;
00587         }
00588         drmHandleEvent(this->drm.fd, &this->evctx);
00589     }
00590 
00591     return true;
00592 }
00593 
00594 bool MMSKms::testLayer(int layer_id) {
00595     // is initialized?
00596     INITCHECK;
00597 
00598     // default fbdev does support only primary layer 0 on primary screen 0
00599     if (layer_id != 0) {
00600         printf("MMSKms: layer %d is not supported\n", layer_id);
00601         return false;
00602     }
00603 
00604     return true;
00605 }
00606 
00607 bool MMSKms::initLayer(int layer_id, int width, int height, MMSFBSurfacePixelFormat pixelformat, int backbuffer) {
00608     // is initialized?
00609     INITCHECK;
00610 
00611 //  printf("init layer w: %d, h: %d\n", width, height);
00612 
00613     this->drm.width = width;
00614     this->drm.height = height;
00615 
00616     // default fbdev does support only primary layer 0 on primary screen 0
00617     if (layer_id != 0) {
00618         printf("MMSKms: layer %d is not supported\n", layer_id);
00619         return false;
00620     }
00621 
00622     int ret =0;
00623 
00624     /* set mode: */
00625     ret = 0;
00626     ret = drmModeSetCrtc(this->drm.fd, this->drm.crtc_id, this->fb->fb_id, 0, 0,
00627                         &this->drm.connector_id, 1, this->drm.mode);
00628 
00629     if (ret) {
00630         printf("failed to set mode: %s\n", strerror(errno));
00631         return false;
00632     }
00633 
00634     if (this->rotate180) {
00635         drmModeObjectSetProperty(this->drm.fd, this->drm.plane_id, DRM_MODE_OBJECT_PLANE, 8, 4);
00636     }
00637 
00638     if ((this->drm.width != this->drm.mode->hdisplay) || (this->drm.height != this->drm.mode->vdisplay)) {
00639         ret = drmModeSetPlane(this->drm.fd, this->drm.plane_id, this->drm.crtc_id,
00640                 this->fb->fb_id, 0, 0, 0, this->drm.mode->hdisplay, this->drm.mode->vdisplay,
00641                 0, 0, this->drm.width << 16, this->drm.height << 16);
00642 
00643         if (ret)
00644             printf("drmModeSetPlane failed\n");
00645     }
00646 
00647     if (width <= 0 || height <= 0) {
00648         // the layer is disabled now
00649         this->layers[layer_id].isinitialized = false;
00650         return true;
00651     }
00652 
00653     // save dimension of the layer
00654     this->layers[layer_id].width = width;
00655     this->layers[layer_id].height = height;
00656     this->layers[layer_id].pixelformat = pixelformat;
00657 
00658     // save the buffers
00659     memset(&this->layers[layer_id].buffers, 0, sizeof(this->layers[layer_id].buffers));
00660 
00661     this->layers[layer_id].buffers[0].ptr  = this->framebuffer_base;
00662     this->layers[layer_id].buffers[0].pitch= this->stride;
00663     this->layers[layer_id].buffers[0].hwbuffer = true;
00664 
00665     // layer is initialized
00666     this->layers[layer_id].isinitialized = true;
00667 
00668     // this layer is on screen 0 (default)
00669     this->active_screen = 0;
00670 
00671     return true;
00672 }
00673 
00674 bool MMSKms::releaseLayer(int layer_id) {
00675     printf("MMSKms: layer %d cannot be released\n", layer_id);
00676     return false;
00677 }
00678 
00679 bool MMSKms::restoreLayer(int layer_id) {
00680     printf("MMSKms: layer %d cannot be restored\n", layer_id);
00681     return false;
00682 }
00683 
00684 bool MMSKms::getPixelFormat(int layer_id, MMSFBSurfacePixelFormat *pf) {
00685     // is initialized?
00686     INITCHECK;
00687 
00688     // is layer initialized?
00689     if (!this->layers[layer_id].isinitialized)
00690         return false;
00691 
00692     // return pixelformat
00693     *pf = this->layers[layer_id].pixelformat;
00694     return true;
00695 }
00696 
00697 bool MMSKms::getFrameBufferPtr(int layer_id, MMSFBSurfacePlanesBuffer buffers, int *width, int *height) {
00698     // is initialized?
00699     INITCHECK;
00700 
00701     // is layer initialized?
00702     if (!this->layers[layer_id].isinitialized) {
00703         return false;
00704     }
00705 
00706     // return buffer infos
00707     if (buffers)
00708         memcpy(buffers, this->layers[layer_id].buffers, sizeof(this->layers[layer_id].buffers));
00709     *width = this->layers[layer_id].width;
00710     *height = this->layers[layer_id].height;
00711 
00712     return true;
00713 }
00714 
00715 
00716 void MMSKms::genFBPixelFormat(MMSFBSurfacePixelFormat pf, unsigned int *nonstd_format, MMSFBPixelDef *pixeldef) {
00717 
00718     // generate std format
00719     if (nonstd_format) *nonstd_format = 0;
00720     getBitsPerPixel(pf, pixeldef);
00721 
00722     // try to get a fb specific format
00723     this->onGenFBPixelFormat.emit(pf, nonstd_format, pixeldef);
00724 }
00725 
00726 DRM *MMSKms::getDrm() {
00727     return &(this->drm);
00728 }
00729 
00730 void MMSKms::pageFlip() {
00731 
00732     fd_set fds;
00733     FD_ZERO(&fds);
00734     FD_SET(0, &fds);
00735     FD_SET(this->drm.fd, &fds);
00736 
00737     DRM_FB *my_fb;
00738     struct gbm_bo *next_bo;
00739     int waiting_for_flip = 1;
00740 
00741     next_bo = gbm_surface_lock_front_buffer(this->drm.surface);
00742     my_fb = (DRM_FB*)drm_fb_get_from_bo(next_bo);
00743 //  my_fb = (DRM_FB*)drm_fb_get_from_bo(this->bo);
00744 //  my_fb = this->fb;
00745 
00746     int ret =0;
00747 
00748 //  ret = drmModeSetCrtc(this->drm.fd, this->drm.crtc_id, my_fb->fb_id, 0, 0,
00749 //                      &this->drm.connector_id, 1, this->drm.mode);
00750 //
00751 //  if (ret) {
00752 //      printf("failed to set mode: %s\n", strerror(errno));
00753 //      return;
00754 //  }
00755 //
00756 //  drmModeObjectSetProperty(this->drm.fd, this->drm.plane_id, DRM_MODE_OBJECT_PLANE, 8, 4);
00757 //
00758 //  if ((this->drm.width != this->drm.mode->hdisplay) || (this->drm.height != this->drm.mode->vdisplay)) {
00759 //      ret = drmModeSetPlane(this->drm.fd, this->drm.plane_id, this->drm.crtc_id,
00760 //              my_fb->fb_id, 0, 0, 0, this->drm.mode->hdisplay, this->drm.mode->vdisplay,
00761 //              0, (this->drm.mode->vdisplay-this->drm.height) << 16, this->drm.width << 16, this->drm.height << 16);
00762 //
00763 //      if (ret)
00764 //          printf("drmModeSetPlane failed\n");
00765 //  }
00766 
00767     ret = 0;
00768     ret = drmModePageFlip(this->drm.fd, this->drm.crtc_id, my_fb->fb_id,    DRM_MODE_PAGE_FLIP_EVENT, &waiting_for_flip);
00769     if (ret) {
00770         printf("OPENGL_SWAP: failed to queue page flip\n");
00771         return;
00772     }
00773 
00774     while (waiting_for_flip) {
00775         ret = select(this->drm.fd + 1, &fds, NULL, NULL, NULL);
00776         if (ret < 0) {
00777             printf("OPENGL_SWAP: select err\n");
00778             return;
00779         } else if (ret == 0) {
00780             printf("OPENGL_SWAP: select timeout!\n");
00781             return;
00782         } else if (FD_ISSET(0, &fds)) {
00783             printf("OPENGL_SWAP: user interrupted!\n");
00784             break;
00785         }
00786         drmHandleEvent(this->drm.fd, &this->evctx);
00787     }
00788 
00789     gbm_surface_release_buffer(this->drm.surface, next_bo);
00790 //  bo = next_bo;
00791 }
00792 
00793 #endif

Generated by doxygen