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