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