OSDN Git Service

add support for debug.drm.mode
authorChia-I Wu <olvaffe@gmail.com>
Sat, 30 Jul 2011 08:06:31 +0000 (17:06 +0900)
committerChia-I Wu <olvaffe@gmail.com>
Sat, 30 Jul 2011 08:17:27 +0000 (17:17 +0900)
The mode string is "<xres>x<yres>[@<bpp>]".

gralloc_drm_intel.c
gralloc_drm_kms.c
gralloc_drm_nouveau.c
gralloc_drm_pipe.c
gralloc_drm_radeon.c

index 182b2c8..e21947a 100644 (file)
@@ -496,7 +496,14 @@ static void intel_init_kms_features(struct gralloc_drm_drv_t *drv,
        struct drm_i915_getparam gp;
        int pageflipping, id;
 
-       drm->fb_format = HAL_PIXEL_FORMAT_BGRA_8888;
+       switch (drm->fb_format) {
+       case HAL_PIXEL_FORMAT_BGRA_8888:
+       case HAL_PIXEL_FORMAT_RGB_565:
+               break;
+       default:
+               drm->fb_format = HAL_PIXEL_FORMAT_BGRA_8888;
+               break;
+       }
 
        drm->mode_dirty_fb = 0;
        /* why? */
index c1035cd..77115b3 100644 (file)
 
 #define LOG_TAG "GRALLOC-KMS"
 
+#include <cutils/properties.h>
 #include <cutils/log.h>
 #include <errno.h>
 #include <unistd.h>
 #include <signal.h>
 #include <stdlib.h>
+#include <stdio.h>
 #include "gralloc_drm.h"
 #include "gralloc_drm_priv.h"
 
@@ -356,6 +358,59 @@ static void drm_kms_init_features(struct gralloc_drm_t *drm)
        LOGD("will use %s for fb posting", swap_mode);
 }
 
+static drmModeModeInfoPtr find_mode(drmModeConnectorPtr connector, int *bpp)
+{
+       char value[PROPERTY_VALUE_MAX];
+       drmModeModeInfoPtr mode;
+       int dist, i;
+       int xres = 0, yres = 0;
+
+       if (property_get("debug.drm.mode", value, NULL)) {
+               char *p = value, *end;
+
+               /* parse <xres>x<yres>[@<bpp>] */
+               if (sscanf(value, "%dx%d@%d", &xres, &yres, bpp) != 3) {
+                       *bpp = 0;
+                       if (sscanf(value, "%dx%d", &xres, &yres) != 2)
+                               xres = yres = 0;
+               }
+       }
+       else {
+               *bpp = 0;
+       }
+
+       mode = NULL;
+       dist = INT_MAX;
+       for (i = 0; i < connector->count_modes; i++) {
+               drmModeModeInfoPtr m = &connector->modes[i];
+               int tmp;
+
+               if (xres && yres) {
+                       tmp = (m->hdisplay - xres) * (m->hdisplay - xres) +
+                               (m->vdisplay - yres) * (m->vdisplay - yres);
+               }
+               else {
+                       /* use the first preferred mode */
+                       tmp = (m->type & DRM_MODE_TYPE_PREFERRED) ? 0 : dist;
+               }
+
+               if (tmp < dist) {
+                       mode = m;
+                       dist = tmp;
+                       if (!dist)
+                               break;
+               }
+       }
+
+       /* fallback to the first mode */
+       if (!mode)
+               mode = &connector->modes[0];
+
+       *bpp /= 8;
+
+       return mode;
+}
+
 /*
  * Initialize KMS with a connector.
  */
@@ -364,7 +419,7 @@ static int drm_kms_init_with_connector(struct gralloc_drm_t *drm,
 {
        drmModeEncoderPtr encoder;
        drmModeModeInfoPtr mode;
-       int i;
+       int bpp, i;
 
        if (!connector->count_modes)
                return -EINVAL;
@@ -384,20 +439,17 @@ static int drm_kms_init_with_connector(struct gralloc_drm_t *drm,
        drm->crtc_id = drm->resources->crtcs[i];
        drm->connector_id = connector->connector_id;
 
-       /* find the first preferred mode */
-       mode = NULL;
-       for (i = 0; i < connector->count_modes; i++) {
-               drmModeModeInfoPtr m = &connector->modes[i];
-               if (m->type & DRM_MODE_TYPE_PREFERRED) {
-                       mode = m;
-                       break;
-               }
-       }
-       /* no preference; use the first */
-       if (!mode)
-               mode = &connector->modes[0];
-
+       mode = find_mode(connector, &bpp);
        drm->mode = *mode;
+       switch (bpp) {
+       case 2:
+               drm->fb_format = HAL_PIXEL_FORMAT_RGB_565;
+               break;
+       case 4:
+       default:
+               drm->fb_format = HAL_PIXEL_FORMAT_BGRA_8888;
+               break;
+       }
 
        if (connector->mmWidth && connector->mmHeight) {
                drm->xdpi = (drm->mode.hdisplay * 25.4 / connector->mmWidth);
index 6f3af45..b76a2c8 100644 (file)
@@ -269,7 +269,15 @@ static void nouveau_init_kms_features(struct gralloc_drm_drv_t *drv,
 {
        struct nouveau_info *info = (struct nouveau_info *) drv;
 
-       drm->fb_format = HAL_PIXEL_FORMAT_BGRA_8888;
+       switch (drm->fb_format) {
+       case HAL_PIXEL_FORMAT_BGRA_8888:
+       case HAL_PIXEL_FORMAT_RGB_565:
+               break;
+       default:
+               drm->fb_format = HAL_PIXEL_FORMAT_BGRA_8888;
+               break;
+       }
+
        drm->mode_dirty_fb = 0;
        drm->swap_mode = (info->chan) ? DRM_SWAP_FLIP : DRM_SWAP_SETCRTC;
        drm->mode_sync_flip = 1;
index a679701..ff07c0f 100644 (file)
@@ -337,7 +337,15 @@ static void pipe_init_kms_features(struct gralloc_drm_drv_t *drv, struct gralloc
 {
        struct pipe_manager *pm = (struct pipe_manager *) drv;
 
-       drm->fb_format = HAL_PIXEL_FORMAT_BGRA_8888;
+       switch (drm->fb_format) {
+       case HAL_PIXEL_FORMAT_BGRA_8888:
+       case HAL_PIXEL_FORMAT_RGB_565:
+               break;
+       default:
+               drm->fb_format = HAL_PIXEL_FORMAT_BGRA_8888;
+               break;
+       }
+
        drm->mode_dirty_fb = (strcmp(pm->driver, "vmwgfx") == 0);
        drm->swap_mode = DRM_SWAP_FLIP;
        drm->mode_sync_flip = 1;
index ef5280d..40fd53e 100644 (file)
@@ -325,7 +325,15 @@ static void drm_gem_radeon_unmap(struct gralloc_drm_drv_t *drv,
 static void drm_gem_radeon_init_kms_features(struct gralloc_drm_drv_t *drv,
                struct gralloc_drm_t *drm)
 {
-       drm->fb_format = HAL_PIXEL_FORMAT_BGRA_8888;
+       switch (drm->fb_format) {
+       case HAL_PIXEL_FORMAT_BGRA_8888:
+       case HAL_PIXEL_FORMAT_RGB_565:
+               break;
+       default:
+               drm->fb_format = HAL_PIXEL_FORMAT_BGRA_8888;
+               break;
+       }
+
        drm->mode_dirty_fb = 0;
        drm->swap_mode = DRM_SWAP_FLIP;
        drm->mode_sync_flip = 1;