1 /* 2 // Copyright(c)2014 IntelCorporation 3 // 4 // LicensedundertheApacheLicense,Version2.0(the"License"); 5 // youmaynotusethisfileexceptincompliancewiththeLicense. 6 // YoumayobtainacopyoftheLicenseat 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unlessrequiredbyapplicablelaworagreedtoinwriting,software 11 // distributedundertheLicenseisdistributedonan"ASIS"BASIS, 12 // WITHOUTWARRANTIESORCONDITIONSOFANYKIND,eitherexpressorimplied. 13 // SeetheLicenseforthespecificlanguagegoverningpermissionsand 14 // limitationsundertheLicense. 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 39 namespace android { 40 namespace intel { 41 42 static 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 54 static 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 66 static 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 74 void 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 81 static int hwc_device_close(struct hw_device_t *dev) 82 { 83 CTRACE(); 84 Hwcomposer::releaseInstance(); 85 return 0; 86 } 87 88 static 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 96 static 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 120 static 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 132 static 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 147 static 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 163 static 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 175 static 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 187 static 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 199 static 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 211 static 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 225 static 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 283 static struct hw_module_methods_t hwc_module_methods = { 284 open: android::intel::hwc_device_open 285 }; 286 287 hwc_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