1/* 2// Copyright (c) 2014 Intel Corporation 3// 4// Licensed under the Apache License, Version 2.0 (the "License"); 5// you may not use this file except in compliance with the License. 6// You may obtain a copy of the License at 7// 8// http://www.apache.org/licenses/LICENSE-2.0 9// 10// Unless required by applicable law or agreed to in writing, software 11// distributed under the License is distributed on an "AS IS" BASIS, 12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13// See the License for the specific language governing permissions and 14// limitations under the License. 15*/ 16 17#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL) 18 19#include <hardware/hardware.h> 20#include <string.h> 21#include <stdio.h> 22#include <fcntl.h> 23#include <errno.h> 24#include <common/utils/HwcTrace.h> 25#include <Hwcomposer.h> 26#include <utils/Trace.h> 27 28#define GET_HWC_RETURN_X_IF_NULL(X) \ 29 CTRACE(); \ 30 Hwcomposer *hwc = static_cast<Hwcomposer*>(dev); \ 31 do {\ 32 if (!hwc) { \ 33 ELOGTRACE("invalid HWC device."); \ 34 return X; \ 35 } \ 36 } while (0) 37 38 39#define GET_HWC_RETURN_ERROR_IF_NULL() GET_HWC_RETURN_X_IF_NULL(-EINVAL) 40#define GET_HWC_RETURN_VOID_IF_NULL() GET_HWC_RETURN_X_IF_NULL() 41 42 43namespace android { 44namespace intel { 45 46static int hwc_prepare(struct hwc_composer_device_1 *dev, 47 size_t numDisplays, 48 hwc_display_contents_1_t** displays) 49{ 50 ATRACE_CALL(); 51 GET_HWC_RETURN_ERROR_IF_NULL(); 52 if (!hwc->prepare(numDisplays, displays)) { 53 ELOGTRACE("failed to prepare"); 54 return -EINVAL; 55 } 56 return 0; 57} 58 59static int hwc_set(struct hwc_composer_device_1 *dev, 60 size_t numDisplays, 61 hwc_display_contents_1_t **displays) 62{ 63 ATRACE_CALL(); 64 GET_HWC_RETURN_ERROR_IF_NULL(); 65 if (!hwc->commit(numDisplays, displays)) { 66 ELOGTRACE("failed to commit"); 67 return -EINVAL; 68 } 69 return 0; 70} 71 72static void hwc_dump(struct hwc_composer_device_1 *dev, 73 char *buff, 74 int buff_len) 75{ 76 GET_HWC_RETURN_VOID_IF_NULL(); 77 hwc->dump(buff, buff_len, 0); 78} 79 80void hwc_registerProcs(struct hwc_composer_device_1 *dev, 81 hwc_procs_t const *procs) 82{ 83 GET_HWC_RETURN_VOID_IF_NULL(); 84 hwc->registerProcs(procs); 85} 86 87static int hwc_device_close(struct hw_device_t * /* dev */) 88{ 89 CTRACE(); 90 Hwcomposer::releaseInstance(); 91 return 0; 92} 93 94static int hwc_query(struct hwc_composer_device_1 * /* dev */, 95 int what, int* /* value */) 96{ 97 (void) what; 98 ALOGTRACE("what = %d", what); 99 return -EINVAL; 100} 101 102static int hwc_eventControl(struct hwc_composer_device_1 *dev, 103 int disp, 104 int event, 105 int enabled) 106{ 107 bool ret; 108 ATRACE_CALL(); 109 GET_HWC_RETURN_ERROR_IF_NULL(); 110 111 switch (event) { 112 case HWC_EVENT_VSYNC: 113 ret = hwc->vsyncControl(disp, enabled); 114 if (ret == false) { 115 ELOGTRACE("failed to control vsync"); 116 return -EINVAL; 117 } 118 break; 119 default: 120 WLOGTRACE("unsupported event %d", event); 121 break; 122 } 123 124 return 0; 125} 126 127static int hwc_blank(hwc_composer_device_1_t *dev, int disp, int blank) 128{ 129 ATRACE_CALL(); 130 GET_HWC_RETURN_ERROR_IF_NULL(); 131 bool ret = hwc->blank(disp, blank); 132 if (ret == false) { 133 ELOGTRACE("failed to blank disp %d, blank %d", disp, blank); 134 return -EINVAL; 135 } 136 137 return 0; 138} 139 140static int hwc_getDisplayConfigs(hwc_composer_device_1_t *dev, 141 int disp, 142 uint32_t *configs, 143 size_t *numConfigs) 144{ 145 ATRACE_CALL(); 146 GET_HWC_RETURN_ERROR_IF_NULL(); 147 bool ret = hwc->getDisplayConfigs(disp, configs, numConfigs); 148 if (ret == false) { 149 WLOGTRACE("failed to get configs of disp %d", disp); 150 return -EINVAL; 151 } 152 153 return 0; 154} 155 156static int hwc_getDisplayAttributes(hwc_composer_device_1_t *dev, 157 int disp, 158 uint32_t config, 159 const uint32_t *attributes, 160 int32_t *values) 161{ 162 ATRACE_CALL(); 163 GET_HWC_RETURN_ERROR_IF_NULL(); 164 bool ret = hwc->getDisplayAttributes(disp, config, attributes, values); 165 if (ret == false) { 166 WLOGTRACE("failed to get attributes of disp %d", disp); 167 return -EINVAL; 168 } 169 170 return 0; 171} 172 173static int hwc_compositionComplete(hwc_composer_device_1_t *dev, int disp) 174{ 175 ATRACE_CALL(); 176 GET_HWC_RETURN_ERROR_IF_NULL(); 177 bool ret = hwc->compositionComplete(disp); 178 if (ret == false) { 179 ELOGTRACE("failed for disp %d", disp); 180 return -EINVAL; 181 } 182 183 return 0; 184} 185 186static int hwc_setPowerMode(hwc_composer_device_1_t *dev, int disp, int mode) 187{ 188 ATRACE_CALL(); 189 GET_HWC_RETURN_ERROR_IF_NULL(); 190 bool ret = hwc->setPowerMode(disp, mode); 191 if (ret == false) { 192 WLOGTRACE("failed to set power mode of disp %d", disp); 193 return -EINVAL; 194 } 195 196 return 0; 197} 198 199static int hwc_getActiveConfig(hwc_composer_device_1_t *dev, int disp) 200{ 201 ATRACE_CALL(); 202 GET_HWC_RETURN_ERROR_IF_NULL(); 203 int ret = hwc->getActiveConfig(disp); 204 if (ret == -1) { 205 WLOGTRACE("failed to get active config of disp %d", disp); 206 return -EINVAL; 207 } 208 209 return ret; 210} 211 212static int hwc_setActiveConfig(hwc_composer_device_1_t *dev, int disp, int index) 213{ 214 ATRACE_CALL(); 215 GET_HWC_RETURN_ERROR_IF_NULL(); 216 bool ret = hwc->setActiveConfig(disp, index); 217 if (ret == false) { 218 WLOGTRACE("failed to set active config of disp %d", disp); 219 return -EINVAL; 220 } 221 222 return 0; 223} 224 225static int hwc_setCursorPositionAsync(hwc_composer_device_1_t *dev, int disp, int x, int y) 226{ 227 ATRACE_CALL(); 228 GET_HWC_RETURN_ERROR_IF_NULL(); 229 bool ret = hwc->setCursorPositionAsync(disp, x, y); 230 if (ret == false) { 231 WLOGTRACE("failed to set cursor position of disp %d", disp); 232 return -EINVAL; 233 } 234 235 return 0; 236} 237 238//------------------------------------------------------------------------------ 239 240static int hwc_device_open(const struct hw_module_t* module, 241 const char* name, 242 struct hw_device_t** device) 243{ 244 if (!name) { 245 ELOGTRACE("invalid name."); 246 return -EINVAL; 247 } 248 249 ALOGTRACE("open device %s", name); 250 251 if (strcmp(name, HWC_HARDWARE_COMPOSER) != 0) { 252 ELOGTRACE("try to open unknown HWComposer %s", name); 253 return -EINVAL; 254 } 255 256 Hwcomposer& hwc = Hwcomposer::getInstance(); 257 // initialize our state here 258 if (hwc.initialize() == false) { 259 ELOGTRACE("failed to intialize HWComposer"); 260 Hwcomposer::releaseInstance(); 261 return -EINVAL; 262 } 263 264 // initialize the procs 265 hwc.hwc_composer_device_1_t::common.tag = HARDWARE_DEVICE_TAG; 266 hwc.hwc_composer_device_1_t::common.module = 267 const_cast<hw_module_t*>(module); 268 hwc.hwc_composer_device_1_t::common.close = hwc_device_close; 269 270 hwc.hwc_composer_device_1_t::prepare = hwc_prepare; 271 hwc.hwc_composer_device_1_t::set = hwc_set; 272 hwc.hwc_composer_device_1_t::dump = hwc_dump; 273 hwc.hwc_composer_device_1_t::registerProcs = hwc_registerProcs; 274 hwc.hwc_composer_device_1_t::query = hwc_query; 275 276 hwc.hwc_composer_device_1_t::eventControl = hwc_eventControl; 277 hwc.hwc_composer_device_1_t::getDisplayConfigs = hwc_getDisplayConfigs; 278 hwc.hwc_composer_device_1_t::getDisplayAttributes = hwc_getDisplayAttributes; 279 280 // This is used to hack FBO switch flush issue in SurfaceFlinger. 281 hwc.hwc_composer_device_1_t::reserved_proc[0] = (void*)hwc_compositionComplete; 282 hwc.hwc_composer_device_1_t::common.version = HWC_DEVICE_API_VERSION_1_4; 283 hwc.hwc_composer_device_1_t::setPowerMode = hwc_setPowerMode; 284 hwc.hwc_composer_device_1_t::getActiveConfig = hwc_getActiveConfig; 285 hwc.hwc_composer_device_1_t::setActiveConfig = hwc_setActiveConfig; 286 // Todo: add hwc_setCursorPositionAsync after supporting patches 287 hwc.hwc_composer_device_1_t::setCursorPositionAsync = NULL; 288 289 *device = &hwc.hwc_composer_device_1_t::common; 290 291 return 0; 292} 293 294} // namespace intel 295} // namespace android 296 297static struct hw_module_methods_t hwc_module_methods = { 298 open: android::intel::hwc_device_open 299}; 300 301hwc_module_t HAL_MODULE_INFO_SYM = { 302 common: { 303 tag: HARDWARE_MODULE_TAG, 304 version_major: 1, 305 version_minor: 4, 306 id: HWC_HARDWARE_MODULE_ID, 307 name: "Intel Hardware Composer", 308 author: "Intel", 309 methods: &hwc_module_methods, 310 dso: 0, 311 reserved: { 0 }, 312 } 313}; 314