hwc.cpp revision 513ddc2124abf90c63af41999201f0d2031af0c8
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 | ATRACE_TAG_HAL)
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 "external.h"
36#include "hwc_copybit.h"
37#include "profiler.h"
38
39using namespace qhwc;
40using namespace overlay;
41
42#define VSYNC_DEBUG 0
43#define BLANK_DEBUG 1
44
45static int hwc_device_open(const struct hw_module_t* module,
46                           const char* name,
47                           struct hw_device_t** device);
48
49static struct hw_module_methods_t hwc_module_methods = {
50    open: hwc_device_open
51};
52
53hwc_module_t HAL_MODULE_INFO_SYM = {
54    common: {
55        tag: HARDWARE_MODULE_TAG,
56        version_major: 2,
57        version_minor: 0,
58        id: HWC_HARDWARE_MODULE_ID,
59        name: "Qualcomm Hardware Composer Module",
60        author: "CodeAurora Forum",
61        methods: &hwc_module_methods,
62        dso: 0,
63        reserved: {0},
64    }
65};
66
67/*
68 * Save callback functions registered to HWC
69 */
70static void hwc_registerProcs(struct hwc_composer_device_1* dev,
71                              hwc_procs_t const* procs)
72{
73    ALOGI("%s", __FUNCTION__);
74    hwc_context_t* ctx = (hwc_context_t*)(dev);
75    if(!ctx) {
76        ALOGE("%s: Invalid context", __FUNCTION__);
77        return;
78    }
79    ctx->proc = procs;
80
81    // Now that we have the functions needed, kick off
82    // the uevent & vsync threads
83    init_uevent_thread(ctx);
84    init_vsync_thread(ctx);
85}
86
87//Helper
88static void reset(hwc_context_t *ctx, int numDisplays,
89                  hwc_display_contents_1_t** displays) {
90    memset(ctx->listStats, 0, sizeof(ctx->listStats));
91    for(int i = 0; i < MAX_DISPLAYS; i++) {
92        hwc_display_contents_1_t *list = displays[i];
93        // XXX:SurfaceFlinger no longer guarantees that this
94        // value is reset on every prepare. However, for the layer
95        // cache we need to reset it.
96        // We can probably rethink that later on
97        if (LIKELY(list && list->numHwLayers > 1)) {
98            for(uint32_t j = 0; j < list->numHwLayers; j++) {
99                if(list->hwLayers[j].compositionType != HWC_FRAMEBUFFER_TARGET)
100                    list->hwLayers[j].compositionType = HWC_FRAMEBUFFER;
101            }
102        }
103
104        if(ctx->mFBUpdate[i])
105            ctx->mFBUpdate[i]->reset();
106        if(ctx->mCopyBit[i])
107            ctx->mCopyBit[i]->reset();
108        if(ctx->mLayerRotMap[i])
109            ctx->mLayerRotMap[i]->reset();
110    }
111}
112
113//clear prev layer prop flags and realloc for current frame
114static void reset_layer_prop(hwc_context_t* ctx, int dpy, int numAppLayers) {
115    if(ctx->layerProp[dpy]) {
116       delete[] ctx->layerProp[dpy];
117       ctx->layerProp[dpy] = NULL;
118    }
119    ctx->layerProp[dpy] = new LayerProp[numAppLayers];
120}
121
122static int display_commit(hwc_context_t *ctx, int dpy) {
123    int fbFd = ctx->dpyAttr[dpy].fd;
124    if(fbFd == -1) {
125        ALOGE("%s: Invalid FB fd for display: %d", __FUNCTION__, dpy);
126        return -1;
127    }
128
129    struct mdp_display_commit commit_info;
130    memset(&commit_info, 0, sizeof(struct mdp_display_commit));
131    commit_info.flags = MDP_DISPLAY_COMMIT_OVERLAY;
132    if(ioctl(fbFd, MSMFB_DISPLAY_COMMIT, &commit_info) == -1) {
133       ALOGE("%s: MSMFB_DISPLAY_COMMIT for primary failed", __FUNCTION__);
134       return -errno;
135    }
136    return 0;
137}
138
139static int hwc_prepare_primary(hwc_composer_device_1 *dev,
140        hwc_display_contents_1_t *list) {
141    hwc_context_t* ctx = (hwc_context_t*)(dev);
142    const int dpy = HWC_DISPLAY_PRIMARY;
143    if(UNLIKELY(!ctx->mBasePipeSetup))
144        setupBasePipe(ctx);
145    if (LIKELY(list && list->numHwLayers > 1) &&
146            ctx->dpyAttr[dpy].isActive) {
147        reset_layer_prop(ctx, dpy, list->numHwLayers - 1);
148        uint32_t last = list->numHwLayers - 1;
149        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
150        if(fbLayer->handle) {
151            setListStats(ctx, list, dpy);
152            int fbZOrder = ctx->mMDPComp[dpy]->prepare(ctx, list);
153            if(fbZOrder >= 0)
154                ctx->mFBUpdate[dpy]->prepare(ctx, list, fbZOrder);
155
156            if (ctx->mMDP.version < qdutils::MDP_V4_0) {
157                if((fbZOrder >= 0) && ctx->mCopyBit[dpy])
158                    ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
159            }
160        }
161    }
162    return 0;
163}
164
165static int hwc_prepare_external(hwc_composer_device_1 *dev,
166        hwc_display_contents_1_t *list, int dpy) {
167
168    hwc_context_t* ctx = (hwc_context_t*)(dev);
169    Locker::Autolock _l(ctx->mExtLock);
170
171    if (LIKELY(list && list->numHwLayers > 1) &&
172            ctx->dpyAttr[dpy].isActive &&
173            ctx->dpyAttr[dpy].connected) {
174        reset_layer_prop(ctx, dpy, list->numHwLayers - 1);
175        uint32_t last = list->numHwLayers - 1;
176        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
177        if(!ctx->dpyAttr[dpy].isPause) {
178            if(fbLayer->handle) {
179                ctx->mExtDispConfiguring = false;
180                setListStats(ctx, list, dpy);
181                int fbZOrder = ctx->mMDPComp[dpy]->prepare(ctx, list);
182                if(fbZOrder >= 0)
183                    ctx->mFBUpdate[dpy]->prepare(ctx, list, fbZOrder);
184
185                /* Temporarily commenting out C2D until we support partial
186                   copybit composition for mixed mode MDP
187
188                if((fbZOrder >= 0) && ctx->mCopyBit[dpy])
189                    ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
190                */
191            }
192        } else {
193            // External Display is in Pause state.
194            // ToDo:
195            // Mark all application layers as OVERLAY so that
196            // GPU will not compose. This is done for power
197            // optimization
198        }
199    }
200    return 0;
201}
202
203static int hwc_prepare_virtual(hwc_composer_device_1 *dev,
204                               hwc_display_contents_1_t *list, int dpy) {
205    //XXX: Fix when framework support is added
206    return 0;
207}
208
209static int hwc_prepare(hwc_composer_device_1 *dev, size_t numDisplays,
210                       hwc_display_contents_1_t** displays)
211{
212    int ret = 0;
213    hwc_context_t* ctx = (hwc_context_t*)(dev);
214    Locker::Autolock _l(ctx->mBlankLock);
215    reset(ctx, numDisplays, displays);
216
217    ctx->mOverlay->configBegin();
218    ctx->mRotMgr->configBegin();
219    Overlay::setDMAMode(Overlay::DMA_LINE_MODE);
220
221    for (int32_t i = numDisplays - 1; i >= 0; i--) {
222        hwc_display_contents_1_t *list = displays[i];
223        switch(i) {
224            case HWC_DISPLAY_PRIMARY:
225                ret = hwc_prepare_primary(dev, list);
226                break;
227            case HWC_DISPLAY_EXTERNAL:
228                ret = hwc_prepare_external(dev, list, i);
229                break;
230            case HWC_DISPLAY_VIRTUAL:
231                ret = hwc_prepare_virtual(dev, list, i);
232                break;
233            default:
234                ret = -EINVAL;
235        }
236    }
237
238    ctx->mOverlay->configDone();
239    ctx->mRotMgr->configDone();
240
241    return ret;
242}
243
244static int hwc_eventControl(struct hwc_composer_device_1* dev, int dpy,
245                             int event, int enable)
246{
247    int ret = 0;
248    hwc_context_t* ctx = (hwc_context_t*)(dev);
249    Locker::Autolock _l(ctx->mBlankLock);
250    if(!ctx->dpyAttr[dpy].isActive) {
251        ALOGE("Display is blanked - Cannot %s vsync",
252              enable ? "enable" : "disable");
253        return -EINVAL;
254    }
255
256    switch(event) {
257        case HWC_EVENT_VSYNC:
258            if (ctx->vstate.enable == enable)
259                break;
260            ret = hwc_vsync_control(ctx, dpy, enable);
261            if(ret == 0)
262                ctx->vstate.enable = !!enable;
263            ALOGD_IF (VSYNC_DEBUG, "VSYNC state changed to %s",
264                      (enable)?"ENABLED":"DISABLED");
265            break;
266        default:
267            ret = -EINVAL;
268    }
269    return ret;
270}
271
272static int hwc_blank(struct hwc_composer_device_1* dev, int dpy, int blank)
273{
274    ATRACE_CALL();
275    hwc_context_t* ctx = (hwc_context_t*)(dev);
276
277    Locker::Autolock _l(ctx->mBlankLock);
278    int ret = 0;
279    ALOGD_IF(BLANK_DEBUG, "%s: %s display: %d", __FUNCTION__,
280          blank==1 ? "Blanking":"Unblanking", dpy);
281    if(blank) {
282        // free up all the overlay pipes in use
283        // when we get a blank for either display
284        // makes sure that all pipes are freed
285        ctx->mOverlay->configBegin();
286        ctx->mOverlay->configDone();
287        ctx->mRotMgr->clear();
288    }
289    switch(dpy) {
290        case HWC_DISPLAY_PRIMARY:
291            if(blank) {
292                ret = ioctl(ctx->dpyAttr[dpy].fd, FBIOBLANK,
293                            FB_BLANK_POWERDOWN);
294            } else {
295                ret = ioctl(ctx->dpyAttr[dpy].fd, FBIOBLANK,FB_BLANK_UNBLANK);
296            }
297            break;
298        case HWC_DISPLAY_EXTERNAL:
299        case HWC_DISPLAY_VIRTUAL:
300            if(blank) {
301                // call external framebuffer commit on blank,
302                // so that any pipe unsets gets committed
303                if (display_commit(ctx, dpy) < 0) {
304                    ret = -1;
305                    ALOGE("%s:post failed for external display !! ",
306                          __FUNCTION__);
307                }
308            } else {
309            }
310            break;
311        default:
312            return -EINVAL;
313    }
314    // Enable HPD here, as during bootup unblank is called
315    // when SF is completely initialized
316    ctx->mExtDisplay->setHPD(1);
317    if(ret == 0){
318        ctx->dpyAttr[dpy].isActive = !blank;
319    } else {
320        ALOGE("%s: Failed in %s display: %d error:%s", __FUNCTION__,
321              blank==1 ? "blanking":"unblanking", dpy, strerror(errno));
322        return ret;
323    }
324
325    ALOGD_IF(BLANK_DEBUG, "%s: Done %s display: %d", __FUNCTION__,
326          blank==1 ? "blanking":"unblanking", dpy);
327    return 0;
328}
329
330static int hwc_query(struct hwc_composer_device_1* dev,
331                     int param, int* value)
332{
333    hwc_context_t* ctx = (hwc_context_t*)(dev);
334    int supported = HWC_DISPLAY_PRIMARY_BIT;
335
336    switch (param) {
337    case HWC_BACKGROUND_LAYER_SUPPORTED:
338        // Not supported for now
339        value[0] = 0;
340        break;
341    case HWC_DISPLAY_TYPES_SUPPORTED:
342        if(ctx->mMDP.hasOverlay)
343            supported |= HWC_DISPLAY_EXTERNAL_BIT;
344        value[0] = supported;
345        break;
346    default:
347        return -EINVAL;
348    }
349    return 0;
350
351}
352
353
354static int hwc_set_primary(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
355    ATRACE_CALL();
356    int ret = 0;
357    const int dpy = HWC_DISPLAY_PRIMARY;
358
359    if (LIKELY(list) && ctx->dpyAttr[dpy].isActive) {
360        uint32_t last = list->numHwLayers - 1;
361        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
362        int fd = -1; //FenceFD from the Copybit(valid in async mode)
363        bool copybitDone = false;
364        if(ctx->mCopyBit[dpy])
365            copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
366        if(list->numHwLayers > 1)
367            hwc_sync(ctx, list, dpy, fd);
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            ret = -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        if (!ctx->mMDPComp[dpy]->draw(ctx, list)) {
419            ALOGE("%s: MDPComp draw failed", __FUNCTION__);
420            ret = -1;
421        }
422
423        private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
424        if(copybitDone) {
425            hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer();
426        }
427
428        if(hnd) {
429            if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) {
430                ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
431                ret = -1;
432            }
433        }
434
435        if (display_commit(ctx, dpy) < 0) {
436            ALOGE("%s: display commit fail!", __FUNCTION__);
437            ret = -1;
438        }
439    }
440
441    closeAcquireFds(list);
442    return ret;
443}
444
445static int hwc_set_virtual(hwc_context_t *ctx,
446                           hwc_display_contents_1_t* list, int dpy)
447{
448    //XXX: Implement set.
449    closeAcquireFds(list);
450    if (list) {
451        // SF assumes HWC waits for the acquire fence and returns a new fence
452        // that signals when we're done. Since we don't wait, and also don't
453        // touch the buffer, we can just handle the acquire fence back to SF
454        // as the retire fence.
455        list->retireFenceFd = list->outbufAcquireFenceFd;
456    }
457    return 0;
458}
459
460
461static int hwc_set(hwc_composer_device_1 *dev,
462                   size_t numDisplays,
463                   hwc_display_contents_1_t** displays)
464{
465    int ret = 0;
466    hwc_context_t* ctx = (hwc_context_t*)(dev);
467    Locker::Autolock _l(ctx->mBlankLock);
468    for (uint32_t i = 0; i < numDisplays; i++) {
469        hwc_display_contents_1_t* list = displays[i];
470        switch(i) {
471            case HWC_DISPLAY_PRIMARY:
472                ret = hwc_set_primary(ctx, list);
473                break;
474            case HWC_DISPLAY_EXTERNAL:
475                ret = hwc_set_external(ctx, list, i);
476                break;
477            case HWC_DISPLAY_VIRTUAL:
478                ret = hwc_set_virtual(ctx, list, i);
479                break;
480            default:
481                ret = -EINVAL;
482        }
483    }
484    // This is only indicative of how many times SurfaceFlinger posts
485    // frames to the display.
486    CALC_FPS();
487    MDPComp::resetIdleFallBack();
488    return ret;
489}
490
491int hwc_getDisplayConfigs(struct hwc_composer_device_1* dev, int disp,
492        uint32_t* configs, size_t* numConfigs) {
493    int ret = 0;
494    hwc_context_t* ctx = (hwc_context_t*)(dev);
495    //in 1.1 there is no way to choose a config, report as config id # 0
496    //This config is passed to getDisplayAttributes. Ignore for now.
497    switch(disp) {
498        case HWC_DISPLAY_PRIMARY:
499            if(*numConfigs > 0) {
500                configs[0] = 0;
501                *numConfigs = 1;
502            }
503            ret = 0; //NO_ERROR
504            break;
505        case HWC_DISPLAY_EXTERNAL:
506            ret = -1; //Not connected
507            if(ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected) {
508                ret = 0; //NO_ERROR
509                if(*numConfigs > 0) {
510                    configs[0] = 0;
511                    *numConfigs = 1;
512                }
513            }
514            break;
515    }
516    return ret;
517}
518
519int hwc_getDisplayAttributes(struct hwc_composer_device_1* dev, int disp,
520        uint32_t config, const uint32_t* attributes, int32_t* values) {
521
522    hwc_context_t* ctx = (hwc_context_t*)(dev);
523    //If hotpluggable displays are inactive return error
524    if(disp == HWC_DISPLAY_EXTERNAL && !ctx->dpyAttr[disp].connected) {
525        return -1;
526    }
527
528    //From HWComposer
529    static const uint32_t DISPLAY_ATTRIBUTES[] = {
530        HWC_DISPLAY_VSYNC_PERIOD,
531        HWC_DISPLAY_WIDTH,
532        HWC_DISPLAY_HEIGHT,
533        HWC_DISPLAY_DPI_X,
534        HWC_DISPLAY_DPI_Y,
535        HWC_DISPLAY_NO_ATTRIBUTE,
536    };
537
538    const int NUM_DISPLAY_ATTRIBUTES = (sizeof(DISPLAY_ATTRIBUTES) /
539            sizeof(DISPLAY_ATTRIBUTES)[0]);
540
541    for (size_t i = 0; i < NUM_DISPLAY_ATTRIBUTES - 1; i++) {
542        switch (attributes[i]) {
543        case HWC_DISPLAY_VSYNC_PERIOD:
544            values[i] = ctx->dpyAttr[disp].vsync_period;
545            break;
546        case HWC_DISPLAY_WIDTH:
547            values[i] = ctx->dpyAttr[disp].xres;
548            ALOGD("%s disp = %d, width = %d",__FUNCTION__, disp,
549                    ctx->dpyAttr[disp].xres);
550            break;
551        case HWC_DISPLAY_HEIGHT:
552            values[i] = ctx->dpyAttr[disp].yres;
553            ALOGD("%s disp = %d, height = %d",__FUNCTION__, disp,
554                    ctx->dpyAttr[disp].yres);
555            break;
556        case HWC_DISPLAY_DPI_X:
557            values[i] = (int32_t) (ctx->dpyAttr[disp].xdpi*1000.0);
558            break;
559        case HWC_DISPLAY_DPI_Y:
560            values[i] = (int32_t) (ctx->dpyAttr[disp].ydpi*1000.0);
561            break;
562        default:
563            ALOGE("Unknown display attribute %d",
564                    attributes[i]);
565            return -EINVAL;
566        }
567    }
568    return 0;
569}
570
571void hwc_dump(struct hwc_composer_device_1* dev, char *buff, int buff_len)
572{
573    hwc_context_t* ctx = (hwc_context_t*)(dev);
574    android::String8 aBuf("");
575    dumpsys_log(aBuf, "Qualcomm HWC state:\n");
576    dumpsys_log(aBuf, "  MDPVersion=%d\n", ctx->mMDP.version);
577    dumpsys_log(aBuf, "  DisplayPanel=%c\n", ctx->mMDP.panel);
578    for(int dpy = 0; dpy < MAX_DISPLAYS; dpy++) {
579        if(ctx->mMDPComp[dpy])
580            ctx->mMDPComp[dpy]->dump(aBuf);
581    }
582    char ovDump[2048] = {'\0'};
583    ctx->mOverlay->getDump(ovDump, 2048);
584    dumpsys_log(aBuf, ovDump);
585    ovDump[0] = '\0';
586    ctx->mRotMgr->getDump(ovDump, 1024);
587    dumpsys_log(aBuf, ovDump);
588    strlcpy(buff, aBuf.string(), buff_len);
589}
590
591static int hwc_device_close(struct hw_device_t *dev)
592{
593    if(!dev) {
594        ALOGE("%s: NULL device pointer", __FUNCTION__);
595        return -1;
596    }
597    closeContext((hwc_context_t*)dev);
598    free(dev);
599
600    return 0;
601}
602
603static int hwc_device_open(const struct hw_module_t* module, const char* name,
604                           struct hw_device_t** device)
605{
606    int status = -EINVAL;
607
608    if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
609        struct hwc_context_t *dev;
610        dev = (hwc_context_t*)malloc(sizeof(*dev));
611        memset(dev, 0, sizeof(*dev));
612
613        //Initialize hwc context
614        initContext(dev);
615
616        //Setup HWC methods
617        dev->device.common.tag          = HARDWARE_DEVICE_TAG;
618        dev->device.common.version      = HWC_DEVICE_API_VERSION_1_2;
619        dev->device.common.module       = const_cast<hw_module_t*>(module);
620        dev->device.common.close        = hwc_device_close;
621        dev->device.prepare             = hwc_prepare;
622        dev->device.set                 = hwc_set;
623        dev->device.eventControl        = hwc_eventControl;
624        dev->device.blank               = hwc_blank;
625        dev->device.query               = hwc_query;
626        dev->device.registerProcs       = hwc_registerProcs;
627        dev->device.dump                = hwc_dump;
628        dev->device.getDisplayConfigs   = hwc_getDisplayConfigs;
629        dev->device.getDisplayAttributes = hwc_getDisplayAttributes;
630        *device = &dev->device.common;
631        status = 0;
632    }
633    return status;
634}
635