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