Hwcomposer.cpp revision 5094bbf4cbe9b244d79ce5ec52a9285978fff311
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
21namespace android {
22namespace intel {
23
24Hwcomposer* Hwcomposer::sInstance(0);
25
26Hwcomposer::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
42Hwcomposer::~Hwcomposer()
43{
44    CTRACE();
45    deinitialize();
46}
47
48bool Hwcomposer::initCheck() const
49{
50    return mInitialized;
51}
52
53bool 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
103bool 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
145bool 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
166bool 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
187bool 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
209bool 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
232bool 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
255bool 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
273int 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
291bool 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
309bool 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
321void 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
333void 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
348void 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
358bool Hwcomposer::release()
359{
360    RETURN_FALSE_IF_NOT_INIT();
361
362    return true;
363}
364
365bool 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
391void 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
401bool 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
456void 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
475Drm* Hwcomposer::getDrm()
476{
477    return mDrm;
478}
479
480DisplayPlaneManager* Hwcomposer::getPlaneManager()
481{
482    return mPlaneManager;
483}
484
485BufferManager* Hwcomposer::getBufferManager()
486{
487    return mBufferManager;
488}
489
490IDisplayContext* Hwcomposer::getDisplayContext()
491{
492    return mDisplayContext;
493}
494
495DisplayAnalyzer* Hwcomposer::getDisplayAnalyzer()
496{
497    return mDisplayAnalyzer;
498}
499
500IDisplayDevice* 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
512UeventObserver* Hwcomposer::getUeventObserver()
513{
514    return mUeventObserver;
515}
516
517
518} // namespace intel
519} // namespace android
520