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 <common/utils/HwcTrace.h>
17 #include <Hwcomposer.h>
18 #include <common/utils/Dump.h>
19 #include <UeventObserver.h>
20
21 namespace android {
22 namespace intel {
23
24 Hwcomposer* Hwcomposer::sInstance(0);
25
Hwcomposer()26 Hwcomposer::Hwcomposer()
27 : mProcs(0),
28 mDrm(0),
29 mPlaneManager(0),
30 mBufferManager(0),
31 mDisplayAnalyzer(0),
32 mDisplayContext(0),
33 mUeventObserver(0),
34 mInitialized(false)
35 {
36 CTRACE();
37
38 mDisplayDevices.setCapacity(IDisplayDevice::DEVICE_COUNT);
39 mDisplayDevices.clear();
40 }
41
~Hwcomposer()42 Hwcomposer::~Hwcomposer()
43 {
44 CTRACE();
45 deinitialize();
46 }
47
initCheck() const48 bool Hwcomposer::initCheck() const
49 {
50 return mInitialized;
51 }
52
prepare(size_t numDisplays,hwc_display_contents_1_t ** displays)53 bool Hwcomposer::prepare(size_t numDisplays,
54 hwc_display_contents_1_t** displays)
55 {
56 bool ret = true;
57
58 RETURN_FALSE_IF_NOT_INIT();
59 ALOGTRACE("display count = %d", numDisplays);
60
61 if (!numDisplays || !displays) {
62 ELOGTRACE("invalid parameters");
63 return false;
64 }
65
66 mDisplayAnalyzer->analyzeContents(numDisplays, displays);
67
68 // disable reclaimed planes
69 mPlaneManager->disableReclaimedPlanes();
70
71 // reclaim all allocated planes if possible
72 for (size_t i = 0; i < numDisplays; i++) {
73 if (i >= mDisplayDevices.size()) {
74 continue;
75 }
76 IDisplayDevice *device = mDisplayDevices.itemAt(i);
77 if (!device) {
78 VLOGTRACE("device %d doesn't exist", i);
79 continue;
80 }
81 device->prePrepare(displays[i]);
82 }
83
84 for (size_t i = 0; i < numDisplays; i++) {
85 if (i >= mDisplayDevices.size()) {
86 continue;
87 }
88 IDisplayDevice *device = mDisplayDevices.itemAt(i);
89 if (!device) {
90 VLOGTRACE("device %d doesn't exist", i);
91 continue;
92 }
93 ret = device->prepare(displays[i]);
94 if (ret == false) {
95 ELOGTRACE("failed to do prepare for device %d", i);
96 continue;
97 }
98 }
99
100 return ret;
101 }
102
commit(size_t numDisplays,hwc_display_contents_1_t ** displays)103 bool Hwcomposer::commit(size_t numDisplays,
104 hwc_display_contents_1_t **displays)
105 {
106 bool ret = true;
107
108 RETURN_FALSE_IF_NOT_INIT();
109 ALOGTRACE("display count = %d", numDisplays);
110
111 if (!numDisplays || !displays) {
112 ELOGTRACE("invalid parameters");
113 return false;
114 }
115
116 mDisplayContext->commitBegin(numDisplays, displays);
117
118 for (size_t i = 0; i < numDisplays; i++) {
119 if (i >= mDisplayDevices.size()) {
120 continue;
121 }
122 IDisplayDevice *device = mDisplayDevices.itemAt(i);
123 if (!device) {
124 VLOGTRACE("device %d doesn't exist", i);
125 continue;
126 }
127
128 if (!device->isConnected()) {
129 VLOGTRACE("device %d is disconnected", i);
130 continue;
131 }
132
133 ret = device->commit(displays[i], mDisplayContext);
134 if (ret == false) {
135 ELOGTRACE("failed to do commit for device %d", i);
136 continue;
137 }
138 }
139
140 mDisplayContext->commitEnd(numDisplays, displays);
141 // return true always
142 return true;
143 }
144
vsyncControl(int disp,int enabled)145 bool Hwcomposer::vsyncControl(int disp, int enabled)
146 {
147 RETURN_FALSE_IF_NOT_INIT();
148 ALOGTRACE("disp = %d, enabled = %d", disp, enabled);
149
150 if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) {
151 ELOGTRACE("invalid disp %d", disp);
152 return false;
153 }
154 if (disp >= (int) mDisplayDevices.size()) {
155 return false;
156 }
157 IDisplayDevice *device = mDisplayDevices.itemAt(disp);
158 if (!device) {
159 ELOGTRACE("no device found");
160 return false;
161 }
162
163 return device->vsyncControl(enabled ? true : false);
164 }
165
blank(int disp,int blank)166 bool Hwcomposer::blank(int disp, int blank)
167 {
168 RETURN_FALSE_IF_NOT_INIT();
169 ALOGTRACE("disp = %d, blank = %d", disp, blank);
170
171 if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) {
172 ELOGTRACE("invalid disp %d", disp);
173 return false;
174 }
175 if (disp >= (int) mDisplayDevices.size()) {
176 return false;
177 }
178 IDisplayDevice *device = mDisplayDevices.itemAt(disp);
179 if (!device) {
180 ELOGTRACE("no device found");
181 return false;
182 }
183
184 return device->blank(blank ? true : false);
185 }
186
getDisplayConfigs(int disp,uint32_t * configs,size_t * numConfigs)187 bool Hwcomposer::getDisplayConfigs(int disp,
188 uint32_t *configs,
189 size_t *numConfigs)
190 {
191 RETURN_FALSE_IF_NOT_INIT();
192
193 if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) {
194 ELOGTRACE("invalid disp %d", disp);
195 return false;
196 }
197 if (disp >= (int) mDisplayDevices.size()) {
198 return false;
199 }
200 IDisplayDevice *device = mDisplayDevices.itemAt(disp);
201 if (!device) {
202 ELOGTRACE("no device %d found", disp);
203 return false;
204 }
205
206 return device->getDisplayConfigs(configs, numConfigs);
207 }
208
getDisplayAttributes(int disp,uint32_t config,const uint32_t * attributes,int32_t * values)209 bool Hwcomposer::getDisplayAttributes(int disp,
210 uint32_t config,
211 const uint32_t *attributes,
212 int32_t *values)
213 {
214 RETURN_FALSE_IF_NOT_INIT();
215
216 if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) {
217 ELOGTRACE("invalid disp %d", disp);
218 return false;
219 }
220 if (disp >= (int) mDisplayDevices.size()) {
221 return false;
222 }
223 IDisplayDevice *device = mDisplayDevices.itemAt(disp);
224 if (!device) {
225 ELOGTRACE("no device found");
226 return false;
227 }
228
229 return device->getDisplayAttributes(config, attributes, values);
230 }
231
compositionComplete(int disp)232 bool Hwcomposer::compositionComplete(int disp)
233 {
234 RETURN_FALSE_IF_NOT_INIT();
235
236 if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) {
237 ELOGTRACE("invalid disp %d", disp);
238 return false;
239 }
240
241 mDisplayContext->compositionComplete();
242 if (disp >= (int) mDisplayDevices.size()) {
243 return false;
244 }
245
246 IDisplayDevice *device = mDisplayDevices.itemAt(disp);
247 if (!device) {
248 ELOGTRACE("no device found");
249 return false;
250 }
251
252 return device->compositionComplete();
253 }
254
setPowerMode(int disp,int mode)255 bool Hwcomposer::setPowerMode(int disp, int mode)
256 {
257 RETURN_FALSE_IF_NOT_INIT();
258
259 if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) {
260 ELOGTRACE("invalid disp %d", disp);
261 return false;
262 }
263
264 IDisplayDevice *device = mDisplayDevices.itemAt(disp);
265 if (!device) {
266 ELOGTRACE("no device found");
267 return false;
268 }
269
270 return device->setPowerMode(mode);
271 }
272
getActiveConfig(int disp)273 int Hwcomposer::getActiveConfig(int disp)
274 {
275 RETURN_NULL_IF_NOT_INIT();
276
277 if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) {
278 ELOGTRACE("invalid disp %d", disp);
279 return -1;
280 }
281
282 IDisplayDevice *device = mDisplayDevices.itemAt(disp);
283 if (!device) {
284 ELOGTRACE("no device found");
285 return -1;
286 }
287
288 return device->getActiveConfig();
289 }
290
setActiveConfig(int disp,int index)291 bool Hwcomposer::setActiveConfig(int disp, int index)
292 {
293 RETURN_FALSE_IF_NOT_INIT();
294
295 if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) {
296 ELOGTRACE("invalid disp %d", disp);
297 return false;
298 }
299
300 IDisplayDevice *device = mDisplayDevices.itemAt(disp);
301 if (!device) {
302 ELOGTRACE("no device found");
303 return false;
304 }
305
306 return device->setActiveConfig(index);
307 }
308
setCursorPositionAsync(int disp,int x,int y)309 bool Hwcomposer::setCursorPositionAsync(int disp, int x, int y)
310 {
311 RETURN_FALSE_IF_NOT_INIT();
312
313 if (disp != HWC_DISPLAY_PRIMARY && disp != HWC_DISPLAY_EXTERNAL) {
314 ELOGTRACE("invalid disp %d", disp);
315 return false;
316 }
317
318 return mDisplayContext->setCursorPosition(disp, x, y);
319 }
320
vsync(int disp,int64_t timestamp)321 void Hwcomposer::vsync(int disp, int64_t timestamp)
322 {
323 RETURN_VOID_IF_NOT_INIT();
324
325 if (mProcs && mProcs->vsync) {
326 VLOGTRACE("report vsync on disp %d, timestamp %llu", disp, timestamp);
327 // workaround to pretend vsync is from primary display
328 // Display will freeze if vsync is from external display.
329 mProcs->vsync(const_cast<hwc_procs_t*>(mProcs), IDisplayDevice::DEVICE_PRIMARY, timestamp);
330 }
331 }
332
hotplug(int disp,bool connected)333 void Hwcomposer::hotplug(__attribute__((unused))int disp, bool connected)
334 {
335 RETURN_VOID_IF_NOT_INIT();
336
337 if (mProcs && mProcs->hotplug) {
338 DLOGTRACE("report hotplug on disp %d, connected %d", disp, connected);
339 mProcs->hotplug(const_cast<hwc_procs_t*>(mProcs), disp, connected);
340 DLOGTRACE("hotplug callback processed and returned!");
341 }
342
343 mDisplayAnalyzer->postHotplugEvent(connected);
344 }
345
invalidate()346 void Hwcomposer::invalidate()
347 {
348 RETURN_VOID_IF_NOT_INIT();
349
350 if (mProcs && mProcs->invalidate) {
351 DLOGTRACE("invalidating screen...");
352 mProcs->invalidate(const_cast<hwc_procs_t*>(mProcs));
353 }
354 }
355
release()356 bool Hwcomposer::release()
357 {
358 RETURN_FALSE_IF_NOT_INIT();
359
360 return true;
361 }
362
dump(char * buff,int buff_len,int *)363 bool Hwcomposer::dump(char *buff, int buff_len, int * /* cur_len */)
364 {
365 RETURN_FALSE_IF_NOT_INIT();
366
367 Dump d(buff, buff_len);
368
369 // dump composer status
370 d.append("Hardware Composer state:");
371 // dump device status
372 for (size_t i= 0; i < mDisplayDevices.size(); i++) {
373 IDisplayDevice *device = mDisplayDevices.itemAt(i);
374 if (device)
375 device->dump(d);
376 }
377
378 // dump plane manager status
379 if (mPlaneManager)
380 mPlaneManager->dump(d);
381
382 // dump buffer manager status
383 if (mBufferManager)
384 mBufferManager->dump(d);
385
386 return true;
387 }
388
registerProcs(hwc_procs_t const * procs)389 void Hwcomposer::registerProcs(hwc_procs_t const *procs)
390 {
391 CTRACE();
392
393 if (!procs) {
394 WLOGTRACE("procs is NULL");
395 }
396 mProcs = procs;
397 }
398
initialize()399 bool Hwcomposer::initialize()
400 {
401 CTRACE();
402
403 // create drm
404 mDrm = new Drm();
405 if (!mDrm || !mDrm->initialize()) {
406 DEINIT_AND_RETURN_FALSE("failed to create DRM");
407 }
408
409 // create buffer manager
410 mBufferManager = createBufferManager();
411 if (!mBufferManager || !mBufferManager->initialize()) {
412 DEINIT_AND_RETURN_FALSE("failed to create buffer manager");
413 }
414
415 // create display plane manager
416 mPlaneManager = createDisplayPlaneManager();
417 if (!mPlaneManager || !mPlaneManager->initialize()) {
418 DEINIT_AND_RETURN_FALSE("failed to create display plane manager");
419 }
420
421 mDisplayContext = createDisplayContext();
422 if (!mDisplayContext || !mDisplayContext->initialize()) {
423 DEINIT_AND_RETURN_FALSE("failed to create display context");
424 }
425
426 mUeventObserver = new UeventObserver();
427 if (!mUeventObserver || !mUeventObserver->initialize()) {
428 DEINIT_AND_RETURN_FALSE("failed to initialize uevent observer");
429 }
430
431 // create display device
432 for (int i = 0; i < IDisplayDevice::DEVICE_COUNT; i++) {
433 IDisplayDevice *device = createDisplayDevice(i, *mPlaneManager);
434 if (!device || !device->initialize()) {
435 DEINIT_AND_DELETE_OBJ(device);
436 DEINIT_AND_RETURN_FALSE("failed to create device %d", i);
437 }
438 // add this device
439 mDisplayDevices.insertAt(device, i, 1);
440 }
441
442 mDisplayAnalyzer = new DisplayAnalyzer();
443 if (!mDisplayAnalyzer || !mDisplayAnalyzer->initialize()) {
444 DEINIT_AND_RETURN_FALSE("failed to initialize display analyzer");
445 }
446
447 // all initialized, starting uevent observer
448 mUeventObserver->start();
449
450 mInitialized = true;
451 return true;
452 }
453
deinitialize()454 void Hwcomposer::deinitialize()
455 {
456 DEINIT_AND_DELETE_OBJ(mDisplayAnalyzer);
457
458 DEINIT_AND_DELETE_OBJ(mUeventObserver);
459 // destroy display devices
460 for (size_t i = 0; i < mDisplayDevices.size(); i++) {
461 IDisplayDevice *device = mDisplayDevices.itemAt(i);
462 DEINIT_AND_DELETE_OBJ(device);
463 }
464 mDisplayDevices.clear();
465
466 DEINIT_AND_DELETE_OBJ(mDisplayContext);
467 DEINIT_AND_DELETE_OBJ(mPlaneManager);
468 DEINIT_AND_DELETE_OBJ(mBufferManager);
469 DEINIT_AND_DELETE_OBJ(mDrm);
470 mInitialized = false;
471 }
472
getDrm()473 Drm* Hwcomposer::getDrm()
474 {
475 return mDrm;
476 }
477
getPlaneManager()478 DisplayPlaneManager* Hwcomposer::getPlaneManager()
479 {
480 return mPlaneManager;
481 }
482
getBufferManager()483 BufferManager* Hwcomposer::getBufferManager()
484 {
485 return mBufferManager;
486 }
487
getDisplayContext()488 IDisplayContext* Hwcomposer::getDisplayContext()
489 {
490 return mDisplayContext;
491 }
492
getDisplayAnalyzer()493 DisplayAnalyzer* Hwcomposer::getDisplayAnalyzer()
494 {
495 return mDisplayAnalyzer;
496 }
497
getDisplayDevice(int disp)498 IDisplayDevice* Hwcomposer::getDisplayDevice(int disp)
499 {
500 if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) {
501 ELOGTRACE("invalid disp %d", disp);
502 return NULL;
503 }
504 if (disp >= (int) mDisplayDevices.size()) {
505 return NULL;
506 }
507 return mDisplayDevices.itemAt(disp);
508 }
509
getUeventObserver()510 UeventObserver* Hwcomposer::getUeventObserver()
511 {
512 return mUeventObserver;
513 }
514
515
516 } // namespace intel
517 } // namespace android
518