diff options
Diffstat (limited to 'hwc/display.c')
-rw-r--r-- | hwc/display.c | 182 |
1 files changed, 182 insertions, 0 deletions
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]); +} |