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 #ifndef INTEL_SUPPORT_HDMI_PRIMARY
338     if (mProcs && mProcs->hotplug) {
339         DLOGTRACE("report hotplug on disp %d, connected %d", disp, connected);
340         mProcs->hotplug(const_cast<hwc_procs_t*>(mProcs), disp, connected);
341         DLOGTRACE("hotplug callback processed and returned!");
342     }
343 #endif
344 
345     mDisplayAnalyzer->postHotplugEvent(connected);
346 }
347 
invalidate()348 void Hwcomposer::invalidate()
349 {
350     RETURN_VOID_IF_NOT_INIT();
351 
352     if (mProcs && mProcs->invalidate) {
353         DLOGTRACE("invalidating screen...");
354         mProcs->invalidate(const_cast<hwc_procs_t*>(mProcs));
355     }
356 }
357 
release()358 bool Hwcomposer::release()
359 {
360     RETURN_FALSE_IF_NOT_INIT();
361 
362     return true;
363 }
364 
dump(char * buff,int buff_len,int *)365 bool Hwcomposer::dump(char *buff, int buff_len, int * /* cur_len */)
366 {
367     RETURN_FALSE_IF_NOT_INIT();
368 
369     Dump d(buff, buff_len);
370 
371     // dump composer status
372     d.append("Hardware Composer state:");
373     // dump device status
374     for (size_t i= 0; i < mDisplayDevices.size(); i++) {
375         IDisplayDevice *device = mDisplayDevices.itemAt(i);
376         if (device)
377             device->dump(d);
378     }
379 
380     // dump plane manager status
381     if (mPlaneManager)
382         mPlaneManager->dump(d);
383 
384     // dump buffer manager status
385     if (mBufferManager)
386         mBufferManager->dump(d);
387 
388     return true;
389 }
390 
registerProcs(hwc_procs_t const * procs)391 void Hwcomposer::registerProcs(hwc_procs_t const *procs)
392 {
393     CTRACE();
394 
395     if (!procs) {
396         WLOGTRACE("procs is NULL");
397     }
398     mProcs = procs;
399 }
400 
initialize()401 bool Hwcomposer::initialize()
402 {
403     CTRACE();
404 
405     // create drm
406     mDrm = new Drm();
407     if (!mDrm || !mDrm->initialize()) {
408         DEINIT_AND_RETURN_FALSE("failed to create DRM");
409     }
410 
411     // create buffer manager
412     mBufferManager = createBufferManager();
413     if (!mBufferManager || !mBufferManager->initialize()) {
414         DEINIT_AND_RETURN_FALSE("failed to create buffer manager");
415     }
416 
417     // create display plane manager
418     mPlaneManager = createDisplayPlaneManager();
419     if (!mPlaneManager || !mPlaneManager->initialize()) {
420         DEINIT_AND_RETURN_FALSE("failed to create display plane manager");
421     }
422 
423     mDisplayContext = createDisplayContext();
424     if (!mDisplayContext || !mDisplayContext->initialize()) {
425         DEINIT_AND_RETURN_FALSE("failed to create display context");
426     }
427 
428     mUeventObserver = new UeventObserver();
429     if (!mUeventObserver || !mUeventObserver->initialize()) {
430         DEINIT_AND_RETURN_FALSE("failed to initialize uevent observer");
431     }
432 
433     // create display device
434     for (int i = 0; i < IDisplayDevice::DEVICE_COUNT; i++) {
435         IDisplayDevice *device = createDisplayDevice(i, *mPlaneManager);
436         if (!device || !device->initialize()) {
437             DEINIT_AND_DELETE_OBJ(device);
438             DEINIT_AND_RETURN_FALSE("failed to create device %d", i);
439         }
440         // add this device
441         mDisplayDevices.insertAt(device, i, 1);
442     }
443 
444     mDisplayAnalyzer = new DisplayAnalyzer();
445     if (!mDisplayAnalyzer || !mDisplayAnalyzer->initialize()) {
446         DEINIT_AND_RETURN_FALSE("failed to initialize display analyzer");
447     }
448 
449     // all initialized, starting uevent observer
450     mUeventObserver->start();
451 
452     mInitialized = true;
453     return true;
454 }
455 
deinitialize()456 void Hwcomposer::deinitialize()
457 {
458     DEINIT_AND_DELETE_OBJ(mDisplayAnalyzer);
459 
460     DEINIT_AND_DELETE_OBJ(mUeventObserver);
461     // destroy display devices
462     for (size_t i = 0; i < mDisplayDevices.size(); i++) {
463         IDisplayDevice *device = mDisplayDevices.itemAt(i);
464         DEINIT_AND_DELETE_OBJ(device);
465     }
466     mDisplayDevices.clear();
467 
468     DEINIT_AND_DELETE_OBJ(mDisplayContext);
469     DEINIT_AND_DELETE_OBJ(mPlaneManager);
470     DEINIT_AND_DELETE_OBJ(mBufferManager);
471     DEINIT_AND_DELETE_OBJ(mDrm);
472     mInitialized = false;
473 }
474 
getDrm()475 Drm* Hwcomposer::getDrm()
476 {
477     return mDrm;
478 }
479 
getPlaneManager()480 DisplayPlaneManager* Hwcomposer::getPlaneManager()
481 {
482     return mPlaneManager;
483 }
484 
getBufferManager()485 BufferManager* Hwcomposer::getBufferManager()
486 {
487     return mBufferManager;
488 }
489 
getDisplayContext()490 IDisplayContext* Hwcomposer::getDisplayContext()
491 {
492     return mDisplayContext;
493 }
494 
getDisplayAnalyzer()495 DisplayAnalyzer* Hwcomposer::getDisplayAnalyzer()
496 {
497     return mDisplayAnalyzer;
498 }
499 
getDisplayDevice(int disp)500 IDisplayDevice* Hwcomposer::getDisplayDevice(int disp)
501 {
502     if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) {
503         ELOGTRACE("invalid disp %d", disp);
504         return NULL;
505     }
506     if (disp >= (int) mDisplayDevices.size()) {
507         return NULL;
508     }
509     return mDisplayDevices.itemAt(disp);
510 }
511 
getUeventObserver()512 UeventObserver* Hwcomposer::getUeventObserver()
513 {
514     return mUeventObserver;
515 }
516 
517 
518 } // namespace intel
519 } // namespace android
520