Merge changes I66d4fc71,I686dce91,I31325c76
* changes: libadfhwc: Fix adf_hwc_close libadfhwc: add adf_set_active_config_hwc2 support libadfhwc: support hwc2 display attributes
This commit is contained in:
commit
497cb085c7
2 changed files with 106 additions and 13 deletions
|
|
@ -166,6 +166,71 @@ int adf_getDisplayAttributes(struct adf_hwc_helper *dev, int disp,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t adf_display_attribute_hwc2(const adf_interface_data &data,
|
||||||
|
const drm_mode_modeinfo &mode, const uint32_t attribute)
|
||||||
|
{
|
||||||
|
switch (attribute) {
|
||||||
|
case HWC2_ATTRIBUTE_VSYNC_PERIOD:
|
||||||
|
if (mode.vrefresh)
|
||||||
|
return 1000000000 / mode.vrefresh;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case HWC2_ATTRIBUTE_WIDTH:
|
||||||
|
return mode.hdisplay;
|
||||||
|
|
||||||
|
case HWC2_ATTRIBUTE_HEIGHT:
|
||||||
|
return mode.vdisplay;
|
||||||
|
|
||||||
|
case HWC2_ATTRIBUTE_DPI_X:
|
||||||
|
return dpi(mode.hdisplay, data.width_mm);
|
||||||
|
|
||||||
|
case HWC2_ATTRIBUTE_DPI_Y:
|
||||||
|
return dpi(mode.vdisplay, data.height_mm);
|
||||||
|
|
||||||
|
default:
|
||||||
|
ALOGE("unknown display attribute %u", attribute);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int adf_getDisplayAttributes_hwc2(struct adf_hwc_helper *dev, int disp,
|
||||||
|
uint32_t config, const uint32_t *attributes, int32_t *values)
|
||||||
|
{
|
||||||
|
if ((size_t)disp >= dev->intf_fds.size())
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (config >= dev->display_configs.size())
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
adf_interface_data data;
|
||||||
|
int err = adf_get_interface_data(dev->intf_fds[disp], &data);
|
||||||
|
if (err < 0) {
|
||||||
|
ALOGE("failed to get ADF interface data: %s", strerror(err));
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; attributes[i] != HWC2_ATTRIBUTE_INVALID; i++)
|
||||||
|
values[i] = adf_display_attribute_hwc2(data,
|
||||||
|
dev->display_configs[config], attributes[i]);
|
||||||
|
|
||||||
|
adf_free_interface_data(&data);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int adf_set_active_config_hwc2(struct adf_hwc_helper *dev, int disp,
|
||||||
|
uint32_t config)
|
||||||
|
{
|
||||||
|
if ((size_t)disp >= dev->intf_fds.size())
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (config >= dev->display_configs.size())
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
struct drm_mode_modeinfo mode = dev->display_configs[config];
|
||||||
|
|
||||||
|
return adf_interface_set_mode(dev->intf_fds[disp], &mode);
|
||||||
|
}
|
||||||
|
|
||||||
static void handle_adf_event(struct adf_hwc_helper *dev, int disp)
|
static void handle_adf_event(struct adf_hwc_helper *dev, int disp)
|
||||||
{
|
{
|
||||||
adf_event *event;
|
adf_event *event;
|
||||||
|
|
@ -208,28 +273,39 @@ static void *adf_event_thread(void *data)
|
||||||
|
|
||||||
setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
|
setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
|
||||||
|
|
||||||
pollfd *fds = new pollfd[dev->intf_fds.size()];
|
struct sigaction action = { };
|
||||||
|
sigemptyset(&action.sa_mask);
|
||||||
|
action.sa_flags = 0;
|
||||||
|
action.sa_handler = [](int) { pthread_exit(0); };
|
||||||
|
|
||||||
|
if (sigaction(SIGUSR2, &action, NULL) < 0) {
|
||||||
|
ALOGE("failed to set thread exit action %s", strerror(errno));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
sigset_t signal_set;
|
||||||
|
sigemptyset(&signal_set);
|
||||||
|
sigaddset(&signal_set, SIGUSR2);
|
||||||
|
|
||||||
|
pthread_sigmask(SIG_UNBLOCK, &signal_set, NULL);
|
||||||
|
|
||||||
|
pollfd fds[dev->intf_fds.size()];
|
||||||
for (size_t i = 0; i < dev->intf_fds.size(); i++) {
|
for (size_t i = 0; i < dev->intf_fds.size(); i++) {
|
||||||
fds[i].fd = dev->intf_fds[i];
|
fds[i].fd = dev->intf_fds[i];
|
||||||
fds[i].events = POLLIN | POLLPRI;
|
fds[i].events = POLLIN | POLLPRI;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
int err = poll(fds, dev->intf_fds.size(), -1);
|
if (TEMP_FAILURE_RETRY(poll(fds, dev->intf_fds.size(), -1)) < 0) {
|
||||||
|
|
||||||
if (err > 0) {
|
|
||||||
for (size_t i = 0; i < dev->intf_fds.size(); i++)
|
|
||||||
if (fds[i].revents & (POLLIN | POLLPRI))
|
|
||||||
handle_adf_event(dev, i);
|
|
||||||
}
|
|
||||||
else if (err == -1) {
|
|
||||||
if (errno == EINTR)
|
|
||||||
break;
|
|
||||||
ALOGE("error in event thread: %s", strerror(errno));
|
ALOGE("error in event thread: %s", strerror(errno));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < dev->intf_fds.size(); i++)
|
||||||
|
if (fds[i].revents & (POLLIN | POLLPRI))
|
||||||
|
handle_adf_event(dev, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete [] fds;
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -264,6 +340,12 @@ int adf_hwc_open(int *intf_fds, size_t n_intfs,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sigset_t signal_set;
|
||||||
|
sigemptyset(&signal_set);
|
||||||
|
sigaddset(&signal_set, SIGUSR2);
|
||||||
|
|
||||||
|
pthread_sigmask(SIG_BLOCK, &signal_set, NULL);
|
||||||
|
|
||||||
ret = pthread_create(&dev_ret->event_thread, NULL, adf_event_thread,
|
ret = pthread_create(&dev_ret->event_thread, NULL, adf_event_thread,
|
||||||
dev_ret);
|
dev_ret);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
|
@ -284,7 +366,7 @@ err:
|
||||||
|
|
||||||
void adf_hwc_close(struct adf_hwc_helper *dev)
|
void adf_hwc_close(struct adf_hwc_helper *dev)
|
||||||
{
|
{
|
||||||
pthread_kill(dev->event_thread, SIGTERM);
|
pthread_kill(dev->event_thread, SIGUSR2);
|
||||||
pthread_join(dev->event_thread, NULL);
|
pthread_join(dev->event_thread, NULL);
|
||||||
|
|
||||||
for (size_t i = 0; i < dev->intf_fds.size(); i++)
|
for (size_t i = 0; i < dev->intf_fds.size(); i++)
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
#include <video/adf.h>
|
#include <video/adf.h>
|
||||||
|
|
||||||
#include <hardware/hwcomposer.h>
|
#include <hardware/hwcomposer.h>
|
||||||
|
#include <hardware/hwcomposer2.h>
|
||||||
|
|
||||||
struct adf_hwc_helper;
|
struct adf_hwc_helper;
|
||||||
|
|
||||||
|
|
@ -123,6 +124,16 @@ int adf_getDisplayConfigs(struct adf_hwc_helper *dev, int disp,
|
||||||
uint32_t *configs, size_t *numConfigs);
|
uint32_t *configs, size_t *numConfigs);
|
||||||
int adf_getDisplayAttributes(struct adf_hwc_helper *dev, int disp,
|
int adf_getDisplayAttributes(struct adf_hwc_helper *dev, int disp,
|
||||||
uint32_t config, const uint32_t *attributes, int32_t *values);
|
uint32_t config, const uint32_t *attributes, int32_t *values);
|
||||||
|
/**
|
||||||
|
* Generic implementation of common HWC2 functions.
|
||||||
|
*
|
||||||
|
* The HWC2 should not return these functions directly through getFunction.
|
||||||
|
* Instead, the HWC2 should return stub functions which call these helpers.
|
||||||
|
*/
|
||||||
|
int adf_getDisplayAttributes_hwc2(struct adf_hwc_helper *dev, int disp,
|
||||||
|
uint32_t config, const uint32_t *attributes, int32_t *values);
|
||||||
|
int adf_set_active_config_hwc2(struct adf_hwc_helper *dev, int disp,
|
||||||
|
uint32_t config);
|
||||||
|
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue