android_mt6572_jiabo/hardware/ti/omap4/hwc/display.c
2025-09-05 16:56:03 +08:00

183 lines
4.7 KiB
C

/*
* 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 <stdlib.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]);
}