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
39 namespace android {
40 namespace intel {
41
hwc_prepare(struct hwc_composer_device_1 * dev,size_t numDisplays,hwc_display_contents_1_t ** displays)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
hwc_set(struct hwc_composer_device_1 * dev,size_t numDisplays,hwc_display_contents_1_t ** displays)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
hwc_dump(struct hwc_composer_device_1 * dev,char * buff,int buff_len)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
hwc_registerProcs(struct hwc_composer_device_1 * dev,hwc_procs_t const * procs)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
hwc_device_close(struct hw_device_t * dev)81 static int hwc_device_close(struct hw_device_t *dev)
82 {
83 CTRACE();
84 Hwcomposer::releaseInstance();
85 return 0;
86 }
87
hwc_query(struct hwc_composer_device_1 * dev,int what,int * value)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
hwc_eventControl(struct hwc_composer_device_1 * dev,int disp,int event,int enabled)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
hwc_blank(hwc_composer_device_1_t * dev,int disp,int blank)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
hwc_getDisplayConfigs(hwc_composer_device_1_t * dev,int disp,uint32_t * configs,size_t * numConfigs)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
hwc_getDisplayAttributes(hwc_composer_device_1_t * dev,int disp,uint32_t config,const uint32_t * attributes,int32_t * values)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
hwc_compositionComplete(hwc_composer_device_1_t * dev,int disp)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
hwc_setPowerMode(hwc_composer_device_1_t * dev,int disp,int mode)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
hwc_getActiveConfig(hwc_composer_device_1_t * dev,int disp)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
hwc_setActiveConfig(hwc_composer_device_1_t * dev,int disp,int index)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
hwc_setCursorPositionAsync(hwc_composer_device_1_t * dev,int disp,int x,int y)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
hwc_device_open(const struct hw_module_t * module,const char * name,struct hw_device_t ** device)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