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