hwc.cpp revision 6e5f4943b740677ec2f124fda808f6fb2d715cde
1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 * Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
4 *
5 * Not a Contribution, Apache license notifications and license are retained
6 * for attribution purposes only.
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 *      http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20#define ATRACE_TAG ATRACE_TAG_GRAPHICS
21#include <fcntl.h>
22#include <errno.h>
23
24#include <cutils/log.h>
25#include <cutils/atomic.h>
26#include <EGL/egl.h>
27#include <utils/Trace.h>
28#include <sys/ioctl.h>
29#include <overlay.h>
30#include <overlayRotator.h>
31#include <mdp_version.h>
32#include "hwc_utils.h"
33#include "hwc_fbupdate.h"
34#include "hwc_mdpcomp.h"
35#include "hwc_dump_layers.h"
36#include "external.h"
37#include "hwc_copybit.h"
38#include "profiler.h"
39
40using namespace qhwc;
41using namespace overlay;
42
43#define VSYNC_DEBUG 0
44#define BLANK_DEBUG 1
45
46static int hwc_device_open(const struct hw_module_t* module,
47                           const char* name,
48                           struct hw_device_t** device);
49
50static struct hw_module_methods_t hwc_module_methods = {
51    open: hwc_device_open
52};
53
54hwc_module_t HAL_MODULE_INFO_SYM = {
55    common: {
56        tag: HARDWARE_MODULE_TAG,
57        version_major: 2,
58        version_minor: 0,
59        id: HWC_HARDWARE_MODULE_ID,
60        name: "Qualcomm Hardware Composer Module",
61        author: "CodeAurora Forum",
62        methods: &hwc_module_methods,
63        dso: 0,
64        reserved: {0},
65    }
66};
67
68/*
69 * Save callback functions registered to HWC
70 */
71static void hwc_registerProcs(struct hwc_composer_device_1* dev,
72                              hwc_procs_t const* procs)
73{
74    ALOGI("%s", __FUNCTION__);
75    hwc_context_t* ctx = (hwc_context_t*)(dev);
76    if(!ctx) {
77        ALOGE("%s: Invalid context", __FUNCTION__);
78        return;
79    }
80    ctx->proc = procs;
81
82    // Now that we have the functions needed, kick off
83    // the uevent & vsync threads
84    init_uevent_thread(ctx);
85    init_vsync_thread(ctx);
86}
87
88//Helper
89static void reset(hwc_context_t *ctx, int numDisplays,
90                  hwc_display_contents_1_t** displays) {
91    memset(ctx->listStats, 0, sizeof(ctx->listStats));
92    for(int i = 0; i < MAX_DISPLAYS; i++) {
93        hwc_display_contents_1_t *list = displays[i];
94        // XXX:SurfaceFlinger no longer guarantees that this
95        // value is reset on every prepare. However, for the layer
96        // cache we need to reset it.
97        // We can probably rethink that later on
98        if (LIKELY(list && list->numHwLayers > 1)) {
99            for(uint32_t j = 0; j < list->numHwLayers; j++) {
100                if(list->hwLayers[j].compositionType != HWC_FRAMEBUFFER_TARGET)
101                    list->hwLayers[j].compositionType = HWC_FRAMEBUFFER;
102            }
103        }
104
105        if(ctx->mFBUpdate[i])
106            ctx->mFBUpdate[i]->reset();
107        if(ctx->mCopyBit[i])
108            ctx->mCopyBit[i]->reset();
109    }
110}
111
112//clear prev layer prop flags and realloc for current frame
113static void reset_layer_prop(hwc_context_t* ctx, int dpy, int numAppLayers) {
114    if(ctx->layerProp[dpy]) {
115       delete[] ctx->layerProp[dpy];
116       ctx->layerProp[dpy] = NULL;
117    }
118    ctx->layerProp[dpy] = new LayerProp[numAppLayers];
119}
120
121static int display_commit(hwc_context_t *ctx, int dpy) {
122    struct mdp_display_commit commit_info;
123    memset(&commit_info, 0, sizeof(struct mdp_display_commit));
124    commit_info.flags = MDP_DISPLAY_COMMIT_OVERLAY;
125    if(ioctl(ctx->dpyAttr[dpy].fd, MSMFB_DISPLAY_COMMIT, &commit_info) == -1) {
126       ALOGE("%s: MSMFB_DISPLAY_COMMIT for primary failed", __FUNCTION__);
127       return -errno;
128    }
129    return 0;
130}
131
132static int hwc_prepare_primary(hwc_composer_device_1 *dev,
133        hwc_display_contents_1_t *list) {
134    hwc_context_t* ctx = (hwc_context_t*)(dev);
135    const int dpy = HWC_DISPLAY_PRIMARY;
136    if (LIKELY(list && list->numHwLayers > 1) &&
137            ctx->dpyAttr[dpy].isActive) {
138        reset_layer_prop(ctx, dpy, list->numHwLayers - 1);
139        uint32_t last = list->numHwLayers - 1;
140        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
141        if(fbLayer->handle) {
142            setListStats(ctx, list, dpy);
143            int fbZOrder = ctx->mMDPComp[dpy]->prepare(ctx, list);
144            if(fbZOrder >= 0)
145                ctx->mFBUpdate[dpy]->prepare(ctx, list, fbZOrder);
146
147            /* Temporarily commenting out C2D until we support partial
148               copybit composition for mixed mode MDP
149
150            // Use Copybit, when MDP comp fails
151            if((fbZOrder >= 0) && ctx->mCopyBit[dpy])
152                ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
153            */
154        }
155    }
156    return 0;
157}
158
159static int hwc_prepare_external(hwc_composer_device_1 *dev,
160        hwc_display_contents_1_t *list, int dpy) {
161
162    hwc_context_t* ctx = (hwc_context_t*)(dev);
163    Locker::Autolock _l(ctx->mExtLock);
164
165    if (LIKELY(list && list->numHwLayers > 1) &&
166            ctx->dpyAttr[dpy].isActive &&
167            ctx->dpyAttr[dpy].connected) {
168        reset_layer_prop(ctx, dpy, list->numHwLayers - 1);
169        uint32_t last = list->numHwLayers - 1;
170        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
171        if(!ctx->dpyAttr[dpy].isPause) {
172            if(fbLayer->handle) {
173                ctx->mExtDispConfiguring = false;
174                setListStats(ctx, list, dpy);
175                int fbZOrder = ctx->mMDPComp[dpy]->prepare(ctx, list);
176                if(fbZOrder >= 0)
177                    ctx->mFBUpdate[dpy]->prepare(ctx, list, fbZOrder);
178
179                /* Temporarily commenting out C2D until we support partial
180                   copybit composition for mixed mode MDP
181
182                if((fbZOrder >= 0) && ctx->mCopyBit[dpy])
183                    ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
184                */
185            }
186        } else {
187            // External Display is in Pause state.
188            // ToDo:
189            // Mark all application layers as OVERLAY so that
190            // GPU will not compose. This is done for power
191            // optimization
192        }
193    }
194    return 0;
195}
196
197static int hwc_prepare(hwc_composer_device_1 *dev, size_t numDisplays,
198                       hwc_display_contents_1_t** displays)
199{
200    int ret = 0;
201    hwc_context_t* ctx = (hwc_context_t*)(dev);
202    Locker::Autolock _l(ctx->mBlankLock);
203    reset(ctx, numDisplays, displays);
204
205    ctx->mOverlay->configBegin();
206    ctx->mRotMgr->configBegin();
207    Overlay::setDMAMode(Overlay::DMA_LINE_MODE);
208
209    for (int32_t i = numDisplays; i >= 0; i--) {
210        hwc_display_contents_1_t *list = displays[i];
211        switch(i) {
212            case HWC_DISPLAY_PRIMARY:
213                ret = hwc_prepare_primary(dev, list);
214                break;
215            case HWC_DISPLAY_EXTERNAL:
216            case HWC_DISPLAY_VIRTUAL:
217                ret = hwc_prepare_external(dev, list, i);
218                break;
219            default:
220                ret = -EINVAL;
221        }
222    }
223
224    ctx->mOverlay->configDone();
225    ctx->mRotMgr->configDone();
226
227    return ret;
228}
229
230static int hwc_eventControl(struct hwc_composer_device_1* dev, int dpy,
231                             int event, int enable)
232{
233    int ret = 0;
234    hwc_context_t* ctx = (hwc_context_t*)(dev);
235    pthread_mutex_lock(&ctx->vstate.lock);
236    switch(event) {
237        case HWC_EVENT_VSYNC:
238            if (ctx->vstate.enable == enable)
239                break;
240            ret = hwc_vsync_control(ctx, dpy, enable);
241            if(ret == 0) {
242                ctx->vstate.enable = !!enable;
243                pthread_cond_signal(&ctx->vstate.cond);
244            }
245            ALOGD_IF (VSYNC_DEBUG, "VSYNC state changed to %s",
246                      (enable)?"ENABLED":"DISABLED");
247            break;
248        default:
249            ret = -EINVAL;
250    }
251    pthread_mutex_unlock(&ctx->vstate.lock);
252    return ret;
253}
254
255static int hwc_blank(struct hwc_composer_device_1* dev, int dpy, int blank)
256{
257    ATRACE_CALL();
258    hwc_context_t* ctx = (hwc_context_t*)(dev);
259
260    Locker::Autolock _l(ctx->mBlankLock);
261    int ret = 0;
262    ALOGD_IF(BLANK_DEBUG, "%s: %s display: %d", __FUNCTION__,
263          blank==1 ? "Blanking":"Unblanking", dpy);
264    if(blank) {
265        // free up all the overlay pipes in use
266        // when we get a blank for either display
267        // makes sure that all pipes are freed
268        ctx->mOverlay->configBegin();
269        ctx->mOverlay->configDone();
270        ctx->mRotMgr->clear();
271    }
272    switch(dpy) {
273        case HWC_DISPLAY_PRIMARY:
274            if(blank) {
275                ret = ioctl(ctx->dpyAttr[dpy].fd, FBIOBLANK,FB_BLANK_POWERDOWN);
276
277                if(ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected == true) {
278                    // Surfaceflinger does not send Blank/unblank event to hwc
279                    // for virtual display, handle it explicitly when blank for
280                    // primary is invoked, so that any pipes unset get committed
281                    if (display_commit(ctx, HWC_DISPLAY_VIRTUAL) < 0) {
282                        ret = -1;
283                        ALOGE("%s:post failed for virtual display !!",
284                                                            __FUNCTION__);
285                    } else {
286                        ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isActive = !blank;
287                    }
288                }
289            } else {
290                ret = ioctl(ctx->dpyAttr[dpy].fd, FBIOBLANK, FB_BLANK_UNBLANK);
291                if(ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected == true) {
292                    ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isActive = !blank;
293                }
294            }
295            break;
296        case HWC_DISPLAY_EXTERNAL:
297            if(blank) {
298                // call external framebuffer commit on blank,
299                // so that any pipe unsets gets committed
300                if (display_commit(ctx, dpy) < 0) {
301                    ret = -1;
302                    ALOGE("%s:post failed for external display !! ",
303                          __FUNCTION__);
304                }
305            } else {
306            }
307            break;
308        default:
309            return -EINVAL;
310    }
311    // Enable HPD here, as during bootup unblank is called
312    // when SF is completely initialized
313    ctx->mExtDisplay->setHPD(1);
314    if(ret == 0){
315        ctx->dpyAttr[dpy].isActive = !blank;
316    } else {
317        ALOGE("%s: Failed in %s display: %d error:%s", __FUNCTION__,
318              blank==1 ? "blanking":"unblanking", dpy, strerror(errno));
319        return ret;
320    }
321
322    ALOGD_IF(BLANK_DEBUG, "%s: Done %s display: %d", __FUNCTION__,
323          blank==1 ? "blanking":"unblanking", dpy);
324    return 0;
325}
326
327static int hwc_query(struct hwc_composer_device_1* dev,
328                     int param, int* value)
329{
330    hwc_context_t* ctx = (hwc_context_t*)(dev);
331    int supported = HWC_DISPLAY_PRIMARY_BIT;
332
333    switch (param) {
334    case HWC_BACKGROUND_LAYER_SUPPORTED:
335        // Not supported for now
336        value[0] = 0;
337        break;
338    case HWC_DISPLAY_TYPES_SUPPORTED:
339        if(ctx->mMDP.hasOverlay)
340            supported |= HWC_DISPLAY_EXTERNAL_BIT;
341        value[0] = supported;
342        break;
343    default:
344        return -EINVAL;
345    }
346    return 0;
347
348}
349
350
351static int hwc_set_primary(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
352    ATRACE_CALL();
353    int ret = 0;
354    const int dpy = HWC_DISPLAY_PRIMARY;
355    if (LIKELY(list) && ctx->dpyAttr[dpy].isActive) {
356        uint32_t last = list->numHwLayers - 1;
357        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
358        int fd = -1; //FenceFD from the Copybit(valid in async mode)
359        bool copybitDone = false;
360        if(ctx->mCopyBit[dpy])
361            copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
362        if(list->numHwLayers > 1)
363            hwc_sync(ctx, list, dpy, fd);
364
365        // Dump the layers for primary
366        if(ctx->mHwcDebug[dpy])
367            ctx->mHwcDebug[dpy]->dumpLayers(list);
368
369        if (!ctx->mMDPComp[dpy]->draw(ctx, list)) {
370            ALOGE("%s: MDPComp draw failed", __FUNCTION__);
371            ret = -1;
372        }
373
374        //TODO We dont check for SKIP flag on this layer because we need PAN
375        //always. Last layer is always FB
376        private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
377        if(copybitDone) {
378            hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer();
379        }
380
381        if(hnd) {
382            if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) {
383                ALOGE("%s: FBUpdate draw failed", __FUNCTION__);
384                ret = -1;
385            }
386        }
387
388        if (display_commit(ctx, dpy) < 0) {
389            ALOGE("%s: display commit fail!", __FUNCTION__);
390            return -1;
391        }
392    }
393
394    closeAcquireFds(list);
395    return ret;
396}
397
398static int hwc_set_external(hwc_context_t *ctx,
399                            hwc_display_contents_1_t* list, int dpy)
400{
401    ATRACE_CALL();
402    int ret = 0;
403    Locker::Autolock _l(ctx->mExtLock);
404
405    if (LIKELY(list) && ctx->dpyAttr[dpy].isActive &&
406        !ctx->dpyAttr[dpy].isPause &&
407        ctx->dpyAttr[dpy].connected) {
408        uint32_t last = list->numHwLayers - 1;
409        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
410        int fd = -1; //FenceFD from the Copybit(valid in async mode)
411        bool copybitDone = false;
412        if(ctx->mCopyBit[dpy])
413            copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
414
415        if(list->numHwLayers > 1)
416            hwc_sync(ctx, list, dpy, fd);
417
418        // Dump the layers for external
419        if(ctx->mHwcDebug[dpy])
420            ctx->mHwcDebug[dpy]->dumpLayers(list);
421
422        if (!ctx->mMDPComp[dpy]->draw(ctx, list)) {
423            ALOGE("%s: MDPComp draw failed", __FUNCTION__);
424            ret = -1;
425        }
426
427        private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
428        if(copybitDone) {
429            hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer();
430        }
431
432        if(hnd) {
433            if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) {
434                ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
435                ret = -1;
436            }
437        }
438
439        if (display_commit(ctx, dpy) < 0) {
440            ALOGE("%s: display commit fail!", __FUNCTION__);
441            ret = -1;
442        }
443    }
444
445    closeAcquireFds(list);
446    return ret;
447}
448
449static int hwc_set(hwc_composer_device_1 *dev,
450                   size_t numDisplays,
451                   hwc_display_contents_1_t** displays)
452{
453    int ret = 0;
454    hwc_context_t* ctx = (hwc_context_t*)(dev);
455    Locker::Autolock _l(ctx->mBlankLock);
456    for (uint32_t i = 0; i <= numDisplays; i++) {
457        hwc_display_contents_1_t* list = displays[i];
458        switch(i) {
459            case HWC_DISPLAY_PRIMARY:
460                ret = hwc_set_primary(ctx, list);
461                break;
462            case HWC_DISPLAY_EXTERNAL:
463            case HWC_DISPLAY_VIRTUAL:
464            /* ToDo: We are using hwc_set_external path for both External and
465                     Virtual displays on HWC1.1. Eventually, we will have
466                     separate functions when we move to HWC1.2
467            */
468                ret = hwc_set_external(ctx, list, i);
469                break;
470            default:
471                ret = -EINVAL;
472        }
473    }
474    // This is only indicative of how many times SurfaceFlinger posts
475    // frames to the display.
476    CALC_FPS();
477    return ret;
478}
479
480int hwc_getDisplayConfigs(struct hwc_composer_device_1* dev, int disp,
481        uint32_t* configs, size_t* numConfigs) {
482    int ret = 0;
483    hwc_context_t* ctx = (hwc_context_t*)(dev);
484    //in 1.1 there is no way to choose a config, report as config id # 0
485    //This config is passed to getDisplayAttributes. Ignore for now.
486    switch(disp) {
487        case HWC_DISPLAY_PRIMARY:
488            if(*numConfigs > 0) {
489                configs[0] = 0;
490                *numConfigs = 1;
491            }
492            ret = 0; //NO_ERROR
493            break;
494        case HWC_DISPLAY_EXTERNAL:
495            ret = -1; //Not connected
496            if(ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected) {
497                ret = 0; //NO_ERROR
498                if(*numConfigs > 0) {
499                    configs[0] = 0;
500                    *numConfigs = 1;
501                }
502            }
503            break;
504    }
505    return ret;
506}
507
508int hwc_getDisplayAttributes(struct hwc_composer_device_1* dev, int disp,
509        uint32_t config, const uint32_t* attributes, int32_t* values) {
510
511    hwc_context_t* ctx = (hwc_context_t*)(dev);
512    //If hotpluggable displays are inactive return error
513    if(disp == HWC_DISPLAY_EXTERNAL && !ctx->dpyAttr[disp].connected) {
514        return -1;
515    }
516
517    //From HWComposer
518    static const uint32_t DISPLAY_ATTRIBUTES[] = {
519        HWC_DISPLAY_VSYNC_PERIOD,
520        HWC_DISPLAY_WIDTH,
521        HWC_DISPLAY_HEIGHT,
522        HWC_DISPLAY_DPI_X,
523        HWC_DISPLAY_DPI_Y,
524        HWC_DISPLAY_NO_ATTRIBUTE,
525    };
526
527    const int NUM_DISPLAY_ATTRIBUTES = (sizeof(DISPLAY_ATTRIBUTES) /
528            sizeof(DISPLAY_ATTRIBUTES)[0]);
529
530    for (size_t i = 0; i < NUM_DISPLAY_ATTRIBUTES - 1; i++) {
531        switch (attributes[i]) {
532        case HWC_DISPLAY_VSYNC_PERIOD:
533            values[i] = ctx->dpyAttr[disp].vsync_period;
534            break;
535        case HWC_DISPLAY_WIDTH:
536            values[i] = ctx->dpyAttr[disp].xres;
537            ALOGD("%s disp = %d, width = %d",__FUNCTION__, disp,
538                    ctx->dpyAttr[disp].xres);
539            break;
540        case HWC_DISPLAY_HEIGHT:
541            values[i] = ctx->dpyAttr[disp].yres;
542            ALOGD("%s disp = %d, height = %d",__FUNCTION__, disp,
543                    ctx->dpyAttr[disp].yres);
544            break;
545        case HWC_DISPLAY_DPI_X:
546            values[i] = (int32_t) (ctx->dpyAttr[disp].xdpi*1000.0);
547            break;
548        case HWC_DISPLAY_DPI_Y:
549            values[i] = (int32_t) (ctx->dpyAttr[disp].ydpi*1000.0);
550            break;
551        default:
552            ALOGE("Unknown display attribute %d",
553                    attributes[i]);
554            return -EINVAL;
555        }
556    }
557    return 0;
558}
559
560void hwc_dump(struct hwc_composer_device_1* dev, char *buff, int buff_len)
561{
562    hwc_context_t* ctx = (hwc_context_t*)(dev);
563    android::String8 aBuf("");
564    dumpsys_log(aBuf, "Qualcomm HWC state:\n");
565    dumpsys_log(aBuf, "  MDPVersion=%d\n", ctx->mMDP.version);
566    dumpsys_log(aBuf, "  DisplayPanel=%c\n", ctx->mMDP.panel);
567    for(int dpy = 0; dpy < MAX_DISPLAYS; dpy++) {
568        if(ctx->mMDPComp[dpy])
569            ctx->mMDPComp[dpy]->dump(aBuf);
570    }
571    char ovDump[2048] = {'\0'};
572    ctx->mOverlay->getDump(ovDump, 2048);
573    dumpsys_log(aBuf, ovDump);
574    ovDump[0] = '\0';
575    ctx->mRotMgr->getDump(ovDump, 1024);
576    dumpsys_log(aBuf, ovDump);
577    strlcpy(buff, aBuf.string(), buff_len);
578}
579
580static int hwc_device_close(struct hw_device_t *dev)
581{
582    if(!dev) {
583        ALOGE("%s: NULL device pointer", __FUNCTION__);
584        return -1;
585    }
586    closeContext((hwc_context_t*)dev);
587    free(dev);
588
589    return 0;
590}
591
592static int hwc_device_open(const struct hw_module_t* module, const char* name,
593                           struct hw_device_t** device)
594{
595    int status = -EINVAL;
596
597    if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
598        struct hwc_context_t *dev;
599        dev = (hwc_context_t*)malloc(sizeof(*dev));
600        memset(dev, 0, sizeof(*dev));
601
602        //Initialize hwc context
603        initContext(dev);
604
605        //Setup HWC methods
606        dev->device.common.tag          = HARDWARE_DEVICE_TAG;
607        dev->device.common.version      = HWC_DEVICE_API_VERSION_1_1;
608        dev->device.common.module       = const_cast<hw_module_t*>(module);
609        dev->device.common.close        = hwc_device_close;
610        dev->device.prepare             = hwc_prepare;
611        dev->device.set                 = hwc_set;
612        dev->device.eventControl        = hwc_eventControl;
613        dev->device.blank               = hwc_blank;
614        dev->device.query               = hwc_query;
615        dev->device.registerProcs       = hwc_registerProcs;
616        dev->device.dump                = hwc_dump;
617        dev->device.getDisplayConfigs   = hwc_getDisplayConfigs;
618        dev->device.getDisplayAttributes = hwc_getDisplayAttributes;
619        *device = &dev->device.common;
620        status = 0;
621    }
622    return status;
623}
624