|
|
/* |
|
|
// Copyright (c) 2014 Intel Corporation |
|
|
// |
|
|
// 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 <hardware/hardware.h> |
|
|
#include <string.h> |
|
|
#include <stdio.h> |
|
|
#include <fcntl.h> |
|
|
#include <errno.h> |
|
|
#include <HwcTrace.h> |
|
|
#include <Hwcomposer.h> |
|
|
|
|
|
#define GET_HWC_RETURN_X_IF_NULL(X) \ |
|
|
CTRACE(); \ |
|
|
Hwcomposer *hwc = static_cast<Hwcomposer*>(dev); \ |
|
|
do {\ |
|
|
if (!hwc) { \ |
|
|
ETRACE("invalid HWC device."); \ |
|
|
return X; \ |
|
|
} \ |
|
|
} while (0) |
|
|
|
|
|
|
|
|
#define GET_HWC_RETURN_ERROR_IF_NULL() GET_HWC_RETURN_X_IF_NULL(-EINVAL) |
|
|
#define GET_HWC_RETURN_VOID_IF_NULL() GET_HWC_RETURN_X_IF_NULL() |
|
|
|
|
|
|
|
|
namespace android { |
|
|
namespace intel { |
|
|
|
|
|
static int hwc_prepare(struct hwc_composer_device_1 *dev, |
|
|
size_t numDisplays, |
|
|
hwc_display_contents_1_t** displays) |
|
|
{ |
|
|
GET_HWC_RETURN_ERROR_IF_NULL(); |
|
|
if (!hwc->prepare(numDisplays, displays)) { |
|
|
ETRACE("failed to prepare"); |
|
|
return -EINVAL; |
|
|
} |
|
|
return 0; |
|
|
} |
|
|
|
|
|
static int hwc_set(struct hwc_composer_device_1 *dev, |
|
|
size_t numDisplays, |
|
|
hwc_display_contents_1_t **displays) |
|
|
{ |
|
|
GET_HWC_RETURN_ERROR_IF_NULL(); |
|
|
if (!hwc->commit(numDisplays, displays)) { |
|
|
ETRACE("failed to commit"); |
|
|
return -EINVAL; |
|
|
} |
|
|
return 0; |
|
|
} |
|
|
|
|
|
static void hwc_dump(struct hwc_composer_device_1 *dev, |
|
|
char *buff, |
|
|
int buff_len) |
|
|
{ |
|
|
GET_HWC_RETURN_VOID_IF_NULL(); |
|
|
hwc->dump(buff, buff_len, 0); |
|
|
} |
|
|
|
|
|
void hwc_registerProcs(struct hwc_composer_device_1 *dev, |
|
|
hwc_procs_t const *procs) |
|
|
{ |
|
|
GET_HWC_RETURN_VOID_IF_NULL(); |
|
|
hwc->registerProcs(procs); |
|
|
} |
|
|
|
|
|
static int hwc_device_close(struct hw_device_t *dev) |
|
|
{ |
|
|
CTRACE(); |
|
|
Hwcomposer::releaseInstance(); |
|
|
return 0; |
|
|
} |
|
|
|
|
|
static int hwc_query(struct hwc_composer_device_1 *dev, |
|
|
int what, |
|
|
int* value) |
|
|
{ |
|
|
ATRACE("what = %d", what); |
|
|
return -EINVAL; |
|
|
} |
|
|
|
|
|
static int hwc_eventControl(struct hwc_composer_device_1 *dev, |
|
|
int disp, |
|
|
int event, |
|
|
int enabled) |
|
|
{ |
|
|
bool ret; |
|
|
GET_HWC_RETURN_ERROR_IF_NULL(); |
|
|
|
|
|
switch (event) { |
|
|
case HWC_EVENT_VSYNC: |
|
|
ret = hwc->vsyncControl(disp, enabled); |
|
|
if (ret == false) { |
|
|
ETRACE("failed to control vsync"); |
|
|
return -EINVAL; |
|
|
} |
|
|
break; |
|
|
default: |
|
|
WTRACE("unsupported event %d", event); |
|
|
break; |
|
|
} |
|
|
|
|
|
return 0; |
|
|
} |
|
|
|
|
|
static int hwc_blank(hwc_composer_device_1_t *dev, int disp, int blank) |
|
|
{ |
|
|
GET_HWC_RETURN_ERROR_IF_NULL(); |
|
|
bool ret = hwc->blank(disp, blank); |
|
|
if (ret == false) { |
|
|
ETRACE("failed to blank disp %d, blank %d", disp, blank); |
|
|
return -EINVAL; |
|
|
} |
|
|
|
|
|
return 0; |
|
|
} |
|
|
|
|
|
static int hwc_getDisplayConfigs(hwc_composer_device_1_t *dev, |
|
|
int disp, |
|
|
uint32_t *configs, |
|
|
size_t *numConfigs) |
|
|
{ |
|
|
GET_HWC_RETURN_ERROR_IF_NULL(); |
|
|
bool ret = hwc->getDisplayConfigs(disp, configs, numConfigs); |
|
|
if (ret == false) { |
|
|
WTRACE("failed to get configs of disp %d", disp); |
|
|
return -EINVAL; |
|
|
} |
|
|
|
|
|
return 0; |
|
|
} |
|
|
|
|
|
static int hwc_getDisplayAttributes(hwc_composer_device_1_t *dev, |
|
|
int disp, |
|
|
uint32_t config, |
|
|
const uint32_t *attributes, |
|
|
int32_t *values) |
|
|
{ |
|
|
GET_HWC_RETURN_ERROR_IF_NULL(); |
|
|
bool ret = hwc->getDisplayAttributes(disp, config, attributes, values); |
|
|
if (ret == false) { |
|
|
WTRACE("failed to get attributes of disp %d", disp); |
|
|
return -EINVAL; |
|
|
} |
|
|
|
|
|
return 0; |
|
|
} |
|
|
|
|
|
static int hwc_compositionComplete(hwc_composer_device_1_t *dev, int disp) |
|
|
{ |
|
|
GET_HWC_RETURN_ERROR_IF_NULL(); |
|
|
bool ret = hwc->compositionComplete(disp); |
|
|
if (ret == false) { |
|
|
ETRACE("failed for disp %d", disp); |
|
|
return -EINVAL; |
|
|
} |
|
|
|
|
|
return 0; |
|
|
} |
|
|
|
|
|
static int hwc_setPowerMode(hwc_composer_device_1_t *dev, int disp, int mode) |
|
|
{ |
|
|
GET_HWC_RETURN_ERROR_IF_NULL(); |
|
|
bool ret = hwc->setPowerMode(disp, mode); |
|
|
if (ret == false) { |
|
|
WTRACE("failed to set power mode of disp %d", disp); |
|
|
return -EINVAL; |
|
|
} |
|
|
|
|
|
return 0; |
|
|
} |
|
|
|
|
|
static int hwc_getActiveConfig(hwc_composer_device_1_t *dev, int disp) |
|
|
{ |
|
|
GET_HWC_RETURN_ERROR_IF_NULL(); |
|
|
int ret = hwc->getActiveConfig(disp); |
|
|
if (ret == -1) { |
|
|
WTRACE("failed to get active config of disp %d", disp); |
|
|
return -EINVAL; |
|
|
} |
|
|
|
|
|
return ret; |
|
|
} |
|
|
|
|
|
static int hwc_setActiveConfig(hwc_composer_device_1_t *dev, int disp, int index) |
|
|
{ |
|
|
GET_HWC_RETURN_ERROR_IF_NULL(); |
|
|
bool ret = hwc->setActiveConfig(disp, index); |
|
|
if (ret == false) { |
|
|
WTRACE("failed to set active config of disp %d", disp); |
|
|
return -EINVAL; |
|
|
} |
|
|
|
|
|
return 0; |
|
|
} |
|
|
|
|
|
static int hwc_setCursorPositionAsync(hwc_composer_device_1_t *dev, int disp, int x, int y) |
|
|
{ |
|
|
GET_HWC_RETURN_ERROR_IF_NULL(); |
|
|
bool ret = hwc->setCursorPositionAsync(disp, x, y); |
|
|
if (ret == false) { |
|
|
WTRACE("failed to set cursor position of disp %d", disp); |
|
|
return -EINVAL; |
|
|
} |
|
|
|
|
|
return 0; |
|
|
} |
|
|
|
|
|
//------------------------------------------------------------------------------ |
|
|
|
|
|
static int hwc_device_open(const struct hw_module_t* module, |
|
|
const char* name, |
|
|
struct hw_device_t** device) |
|
|
{ |
|
|
if (!name) { |
|
|
ETRACE("invalid name."); |
|
|
return -EINVAL; |
|
|
} |
|
|
|
|
|
ATRACE("open device %s", name); |
|
|
|
|
|
if (strcmp(name, HWC_HARDWARE_COMPOSER) != 0) { |
|
|
ETRACE("try to open unknown HWComposer %s", name); |
|
|
return -EINVAL; |
|
|
} |
|
|
|
|
|
Hwcomposer& hwc = Hwcomposer::getInstance(); |
|
|
// initialize our state here |
|
|
if (hwc.initialize() == false) { |
|
|
ETRACE("failed to intialize HWComposer"); |
|
|
Hwcomposer::releaseInstance(); |
|
|
return -EINVAL; |
|
|
} |
|
|
|
|
|
// initialize the procs |
|
|
hwc.hwc_composer_device_1_t::common.tag = HARDWARE_DEVICE_TAG; |
|
|
hwc.hwc_composer_device_1_t::common.module = |
|
|
const_cast<hw_module_t*>(module); |
|
|
hwc.hwc_composer_device_1_t::common.close = hwc_device_close; |
|
|
|
|
|
hwc.hwc_composer_device_1_t::prepare = hwc_prepare; |
|
|
hwc.hwc_composer_device_1_t::set = hwc_set; |
|
|
hwc.hwc_composer_device_1_t::dump = hwc_dump; |
|
|
hwc.hwc_composer_device_1_t::registerProcs = hwc_registerProcs; |
|
|
hwc.hwc_composer_device_1_t::query = hwc_query; |
|
|
|
|
|
hwc.hwc_composer_device_1_t::blank = hwc_blank; |
|
|
hwc.hwc_composer_device_1_t::eventControl = hwc_eventControl; |
|
|
hwc.hwc_composer_device_1_t::getDisplayConfigs = hwc_getDisplayConfigs; |
|
|
hwc.hwc_composer_device_1_t::getDisplayAttributes = hwc_getDisplayAttributes; |
|
|
|
|
|
// This is used to hack FBO switch flush issue in SurfaceFlinger. |
|
|
hwc.hwc_composer_device_1_t::reserved_proc[0] = (void*)hwc_compositionComplete; |
|
|
hwc.hwc_composer_device_1_t::common.version = HWC_DEVICE_API_VERSION_1_4; |
|
|
hwc.hwc_composer_device_1_t::setPowerMode = hwc_setPowerMode; |
|
|
hwc.hwc_composer_device_1_t::getActiveConfig = hwc_getActiveConfig; |
|
|
hwc.hwc_composer_device_1_t::setActiveConfig = hwc_setActiveConfig; |
|
|
// Todo: add hwc_setCursorPositionAsync after supporting patches |
|
|
hwc.hwc_composer_device_1_t::setCursorPositionAsync = NULL; |
|
|
|
|
|
*device = &hwc.hwc_composer_device_1_t::common; |
|
|
|
|
|
return 0; |
|
|
} |
|
|
|
|
|
} // namespace intel |
|
|
} // namespace android |
|
|
|
|
|
static struct hw_module_methods_t hwc_module_methods = { |
|
|
open: android::intel::hwc_device_open |
|
|
}; |
|
|
|
|
|
hwc_module_t HAL_MODULE_INFO_SYM = { |
|
|
common: { |
|
|
tag: HARDWARE_MODULE_TAG, |
|
|
version_major: 1, |
|
|
version_minor: 4, |
|
|
id: HWC_HARDWARE_MODULE_ID, |
|
|
name: "Intel Hardware Composer", |
|
|
author: "Intel", |
|
|
methods: &hwc_module_methods, |
|
|
dso: NULL, |
|
|
reserved: {0}, |
|
|
} |
|
|
};
|
|
|
|