summaryrefslogtreecommitdiffstats
path: root/hwc
diff options
context:
space:
mode:
Diffstat (limited to 'hwc')
-rw-r--r--hwc/Android.mk2
-rw-r--r--hwc/display.c182
-rw-r--r--hwc/display.h48
-rw-r--r--hwc/hwc.c25
-rw-r--r--hwc/hwc_dev.h2
5 files changed, 252 insertions, 7 deletions
diff --git a/hwc/Android.mk b/hwc/Android.mk
index dd83714..e8e59f0 100644
--- a/hwc/Android.mk
+++ b/hwc/Android.mk
@@ -8,7 +8,7 @@ LOCAL_ARM_MODE := arm
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/../vendor/lib/hw
LOCAL_SHARED_LIBRARIES := liblog libEGL libcutils libutils libhardware libhardware_legacy libz \
libion_ti
-LOCAL_SRC_FILES := hwc.c rgz_2d.c dock_image.c sw_vsync.c
+LOCAL_SRC_FILES := hwc.c rgz_2d.c dock_image.c sw_vsync.c display.c
LOCAL_STATIC_LIBRARIES := libpng
LOCAL_MODULE_TAGS := optional
diff --git a/hwc/display.c b/hwc/display.c
new file mode 100644
index 0000000..bd59813
--- /dev/null
+++ b/hwc/display.c
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) Texas Instruments - http://www.ti.com/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <errno.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <sys/ioctl.h>
+
+#include <cutils/log.h>
+
+#include <video/dsscomp.h>
+
+#include "hwc_dev.h"
+#include "display.h"
+
+#define PRIMARY_DISPLAY_CONFIGS 1
+#define PRIMARY_DISPLAY_FPS 60
+#define PRIMARY_DISPLAY_DEFAULT_DPI 150
+#define MAX_DISPLAY_ID (MAX_DISPLAYS - 1)
+#define INCH_TO_MM 25.4f
+
+static void free_display(display_t *display)
+{
+ if (display) {
+ if (display->configs)
+ free(display->configs);
+
+ free(display);
+ }
+}
+
+static int allocate_display(uint32_t max_configs, display_t **new_display)
+{
+ int err = 0;
+
+ display_t *display = (display_t *)malloc(sizeof(*display));
+ if (display == NULL) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+
+ memset(display, 0, sizeof(*display));
+
+ display->num_configs = max_configs;
+ size_t config_data_size = sizeof(*display->configs) * display->num_configs;
+ display->configs = (display_config_t *)malloc(config_data_size);
+ if (display->configs == NULL) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+
+ memset(display->configs, 0, config_data_size);
+
+err_out:
+
+ if (err) {
+ ALOGE("Failed to allocate display (configs = %d)", max_configs);
+ free_display(display);
+ } else {
+ *new_display = display;
+ }
+
+ return err;
+}
+
+int init_primary_display(omap_hwc_device_t *hwc_dev)
+{
+ int ret = ioctl(hwc_dev->dsscomp_fd, DSSCIOC_QUERY_DISPLAY, &hwc_dev->fb_dis);
+ if (ret) {
+ ALOGE("failed to get display info (%d): %m", errno);
+ return -errno;
+ }
+
+ int err = allocate_display(PRIMARY_DISPLAY_CONFIGS, &hwc_dev->displays[HWC_DISPLAY_PRIMARY]);
+ if (err)
+ return err;
+
+ display_config_t *config = &hwc_dev->displays[HWC_DISPLAY_PRIMARY]->configs[0];
+
+ config->xres = hwc_dev->fb_dis.timings.x_res;
+ config->yres = hwc_dev->fb_dis.timings.y_res;
+ config->fps = PRIMARY_DISPLAY_FPS;
+
+ if (hwc_dev->fb_dis.width_in_mm && hwc_dev->fb_dis.height_in_mm) {
+ config->xdpi = (int)(config->xres * INCH_TO_MM) / hwc_dev->fb_dis.width_in_mm;
+ config->ydpi = (int)(config->yres * INCH_TO_MM) / hwc_dev->fb_dis.height_in_mm;
+ } else {
+ config->xdpi = PRIMARY_DISPLAY_DEFAULT_DPI;
+ config->ydpi = PRIMARY_DISPLAY_DEFAULT_DPI;
+ }
+
+ return 0;
+}
+
+int get_display_configs(omap_hwc_device_t *hwc_dev, int disp, uint32_t *configs, size_t *numConfigs)
+{
+ if (!numConfigs)
+ return -EINVAL;
+
+ if (*numConfigs == 0)
+ return 0;
+
+ if (!configs || disp < 0 || disp > MAX_DISPLAY_ID || !hwc_dev->displays[disp])
+ return -EINVAL;
+
+ display_t *display = hwc_dev->displays[disp];
+ size_t num = display->num_configs;
+ uint32_t c;
+
+ if (num > *numConfigs)
+ num = *numConfigs;
+
+ for (c = 0; c < num; c++)
+ configs[c] = c;
+
+ *numConfigs = num;
+
+ return 0;
+}
+
+int get_display_attributes(omap_hwc_device_t *hwc_dev, int disp, uint32_t cfg, const uint32_t *attributes, int32_t *values)
+{
+ if (!attributes || !values)
+ return 0;
+
+ if (disp < 0 || disp > MAX_DISPLAY_ID || !hwc_dev->displays[disp])
+ return -EINVAL;
+
+ display_t *display = hwc_dev->displays[disp];
+
+ if (cfg >= display->num_configs)
+ return -EINVAL;
+
+ const uint32_t* attribute = attributes;
+ int32_t* value = values;
+ display_config_t *config = &display->configs[cfg];
+
+ while (*attribute != HWC_DISPLAY_NO_ATTRIBUTE) {
+ switch (*attribute) {
+ case HWC_DISPLAY_VSYNC_PERIOD:
+ *value = 1000000000 / config->fps;
+ break;
+ case HWC_DISPLAY_WIDTH:
+ *value = config->xres;
+ break;
+ case HWC_DISPLAY_HEIGHT:
+ *value = config->yres;
+ break;
+ case HWC_DISPLAY_DPI_X:
+ *value = 1000 * config->xdpi;
+ break;
+ case HWC_DISPLAY_DPI_Y:
+ *value = 1000 * config->ydpi;
+ break;
+ }
+
+ attribute++;
+ value++;
+ }
+
+ return 0;
+}
+
+void free_displays(omap_hwc_device_t *hwc_dev)
+{
+ int i;
+ for (i = 0; i < MAX_DISPLAYS; i++)
+ free_display(hwc_dev->displays[i]);
+}
diff --git a/hwc/display.h b/hwc/display.h
new file mode 100644
index 0000000..f24fc41
--- /dev/null
+++ b/hwc/display.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) Texas Instruments - http://www.ti.com/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __DISPLAY__
+#define __DISPLAY__
+
+#include <stdint.h>
+
+#define MAX_DISPLAYS 3
+#define MAX_DISPLAY_CONFIGS 32
+
+struct display_config {
+ int xres;
+ int yres;
+ int fps;
+ int xdpi;
+ int ydpi;
+};
+typedef struct display_config display_config_t;
+
+struct display {
+ uint32_t num_configs;
+ display_config_t *configs;
+ uint32_t active_config_ix;
+};
+typedef struct display display_t;
+
+typedef struct omap_hwc_device omap_hwc_device_t;
+
+int init_primary_display(omap_hwc_device_t *hwc_dev);
+int get_display_configs(omap_hwc_device_t *hwc_dev, int disp, uint32_t *configs, size_t *numConfigs);
+int get_display_attributes(omap_hwc_device_t *hwc_dev, int disp, uint32_t config, const uint32_t *attributes, int32_t *values);
+void free_displays(omap_hwc_device_t *hwc_dev);
+
+#endif
diff --git a/hwc/hwc.c b/hwc/hwc.c
index 3ba7e98..e155d28 100644
--- a/hwc/hwc.c
+++ b/hwc/hwc.c
@@ -44,6 +44,7 @@
#include <ion_ti/ion.h>
#include "hwc_dev.h"
+#include "display.h"
#include "dock_image.h"
#include "sw_vsync.h"
@@ -844,7 +845,7 @@ static int set_best_hdmi_mode(omap_hwc_device_t *hwc_dev, uint32_t xres, uint32_
int dis_ix = hwc_dev->on_tv ? 0 : 1;
struct _qdis {
struct dsscomp_display_info dis;
- struct dsscomp_videomode modedb[32];
+ struct dsscomp_videomode modedb[MAX_DISPLAY_CONFIGS];
} d = { .dis = { .ix = dis_ix } };
omap_hwc_ext_t *ext = &hwc_dev->ext;
@@ -2096,6 +2097,7 @@ static int hwc_device_close(hw_device_t* device)
/* pthread will get killed when parent process exits */
pthread_mutex_destroy(&hwc_dev->lock);
+ free_displays(hwc_dev);
free(hwc_dev);
}
@@ -2473,6 +2475,17 @@ static int hwc_blank(struct hwc_composer_device_1 *dev, int dpy, int blank)
return 0;
}
+static int hwc_getDisplayConfigs(struct hwc_composer_device_1* dev, int disp, uint32_t* configs, size_t* numConfigs)
+{
+ return get_display_configs((omap_hwc_device_t *)dev, disp, configs, numConfigs);
+}
+
+static int hwc_getDisplayAttributes(struct hwc_composer_device_1* dev, int disp,
+ uint32_t config, const uint32_t* attributes, int32_t* values)
+{
+ return get_display_attributes((omap_hwc_device_t *)dev, disp, config, attributes, values);
+}
+
static int hwc_device_open(const hw_module_t* module, const char* name, hw_device_t** device)
{
omap_hwc_module_t *hwc_mod = (omap_hwc_module_t *)module;
@@ -2517,6 +2530,8 @@ static int hwc_device_open(const hw_module_t* module, const char* name, hw_devic
hwc_dev->base.blank = hwc_blank;
hwc_dev->base.dump = hwc_dump;
hwc_dev->base.registerProcs = hwc_registerProcs;
+ hwc_dev->base.getDisplayConfigs = hwc_getDisplayConfigs;
+ hwc_dev->base.getDisplayAttributes = hwc_getDisplayAttributes;
hwc_dev->base.query = hwc_query;
hwc_dev->fb_dev = hwc_mod->fb_dev;
@@ -2554,12 +2569,9 @@ static int hwc_device_open(const hw_module_t* module, const char* name, hw_devic
goto done;
}
- ret = ioctl(hwc_dev->dsscomp_fd, DSSCIOC_QUERY_DISPLAY, &hwc_dev->fb_dis);
- if (ret) {
- ALOGE("failed to get display info (%d): %m", errno);
- err = -errno;
+ err = init_primary_display(hwc_dev);
+ if (err)
goto done;
- }
hwc_dev->ion_fd = ion_open();
if (hwc_dev->ion_fd < 0) {
@@ -2693,6 +2705,7 @@ done:
close(hwc_dev->fb_fd);
pthread_mutex_destroy(&hwc_dev->lock);
free(hwc_dev->buffers);
+ free_displays(hwc_dev);
free(hwc_dev);
}
diff --git a/hwc/hwc_dev.h b/hwc/hwc_dev.h
index 9acc9aa..471a577 100644
--- a/hwc/hwc_dev.h
+++ b/hwc/hwc_dev.h
@@ -31,6 +31,7 @@
#include "hal_public.h"
#include "rgz_2d.h"
+#include "display.h"
struct ext_transform {
uint8_t rotation : 3; /* 90-degree clockwise rotations */
@@ -172,6 +173,7 @@ struct omap_hwc_device {
struct ion_handle *ion_handles[2];
bool use_sw_vsync;
+ display_t *displays[MAX_DISPLAYS];
};
typedef struct omap_hwc_device omap_hwc_device_t;