summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gralloc_drm_intel.c9
-rw-r--r--gralloc_drm_kms.c80
-rw-r--r--gralloc_drm_nouveau.c10
-rw-r--r--gralloc_drm_pipe.c10
-rw-r--r--gralloc_drm_radeon.c10
5 files changed, 101 insertions, 18 deletions
diff --git a/gralloc_drm_intel.c b/gralloc_drm_intel.c
index 182b2c8..e21947a 100644
--- a/gralloc_drm_intel.c
+++ b/gralloc_drm_intel.c
@@ -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? */
diff --git a/gralloc_drm_kms.c b/gralloc_drm_kms.c
index c1035cd..77115b3 100644
--- a/gralloc_drm_kms.c
+++ b/gralloc_drm_kms.c
@@ -23,11 +23,13 @@
#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);
diff --git a/gralloc_drm_nouveau.c b/gralloc_drm_nouveau.c
index 6f3af45..b76a2c8 100644
--- a/gralloc_drm_nouveau.c
+++ b/gralloc_drm_nouveau.c
@@ -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;
diff --git a/gralloc_drm_pipe.c b/gralloc_drm_pipe.c
index a679701..ff07c0f 100644
--- a/gralloc_drm_pipe.c
+++ b/gralloc_drm_pipe.c
@@ -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;
diff --git a/gralloc_drm_radeon.c b/gralloc_drm_radeon.c
index ef5280d..40fd53e 100644
--- a/gralloc_drm_radeon.c
+++ b/gralloc_drm_radeon.c
@@ -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;