hwc.cpp revision 5ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1
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 <overlayWriteback.h>
32#include <mdp_version.h>
33#include "hwc_utils.h"
34#include "hwc_fbupdate.h"
35#include "hwc_mdpcomp.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    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::Writeback::configBegin();
220
221    Overlay::setDMAMode(Overlay::DMA_LINE_MODE);
222
223    for (int32_t i = numDisplays - 1; i >= 0; i--) {
224        hwc_display_contents_1_t *list = displays[i];
225        switch(i) {
226            case HWC_DISPLAY_PRIMARY:
227                ret = hwc_prepare_primary(dev, list);
228                break;
229            case HWC_DISPLAY_EXTERNAL:
230                ret = hwc_prepare_external(dev, list, i);
231                break;
232            case HWC_DISPLAY_VIRTUAL:
233                ret = hwc_prepare_virtual(dev, list, i);
234                break;
235            default:
236                ret = -EINVAL;
237        }
238    }
239
240    ctx->mOverlay->configDone();
241    ctx->mRotMgr->configDone();
242    overlay::Writeback::configDone();
243
244    return ret;
245}
246
247static int hwc_eventControl(struct hwc_composer_device_1* dev, int dpy,
248                             int event, int enable)
249{
250    int ret = 0;
251    hwc_context_t* ctx = (hwc_context_t*)(dev);
252    switch(event) {
253        case HWC_EVENT_VSYNC:
254            if(!ctx->dpyAttr[dpy].isActive) {
255                ALOGE("Display is blanked - Cannot %s vsync",
256                        enable ? "enable" : "disable");
257                return -EINVAL;
258            }
259
260            if (ctx->vstate.enable == enable)
261                break;
262            ret = hwc_vsync_control(ctx, dpy, enable);
263            if(ret == 0)
264                ctx->vstate.enable = !!enable;
265            ALOGD_IF (VSYNC_DEBUG, "VSYNC state changed to %s",
266                      (enable)?"ENABLED":"DISABLED");
267            break;
268        default:
269            ret = -EINVAL;
270    }
271    return ret;
272}
273
274static int hwc_blank(struct hwc_composer_device_1* dev, int dpy, int blank)
275{
276    ATRACE_CALL();
277    hwc_context_t* ctx = (hwc_context_t*)(dev);
278
279    Locker::Autolock _l(ctx->mBlankLock);
280    int ret = 0;
281    ALOGD_IF(BLANK_DEBUG, "%s: %s display: %d", __FUNCTION__,
282          blank==1 ? "Blanking":"Unblanking", dpy);
283    if(blank) {
284        // free up all the overlay pipes in use
285        // when we get a blank for either display
286        // makes sure that all pipes are freed
287        ctx->mOverlay->configBegin();
288        ctx->mOverlay->configDone();
289        ctx->mRotMgr->clear();
290        overlay::Writeback::clear();
291    }
292    switch(dpy) {
293        case HWC_DISPLAY_PRIMARY:
294            if(blank) {
295                ret = ioctl(ctx->dpyAttr[dpy].fd, FBIOBLANK,
296                            FB_BLANK_POWERDOWN);
297            } else {
298                ret = ioctl(ctx->dpyAttr[dpy].fd, FBIOBLANK,FB_BLANK_UNBLANK);
299            }
300            break;
301        case HWC_DISPLAY_EXTERNAL:
302        case HWC_DISPLAY_VIRTUAL:
303            if(blank) {
304                // call external framebuffer commit on blank,
305                // so that any pipe unsets gets committed
306                if (display_commit(ctx, dpy) < 0) {
307                    ret = -1;
308                    ALOGE("%s:post failed for external display !! ",
309                          __FUNCTION__);
310                }
311            } else {
312            }
313            break;
314        default:
315            return -EINVAL;
316    }
317    // Enable HPD here, as during bootup unblank is called
318    // when SF is completely initialized
319    ctx->mExtDisplay->setHPD(1);
320    if(ret == 0){
321        ctx->dpyAttr[dpy].isActive = !blank;
322    } else {
323        ALOGE("%s: Failed in %s display: %d error:%s", __FUNCTION__,
324              blank==1 ? "blanking":"unblanking", dpy, strerror(errno));
325        return ret;
326    }
327
328    ALOGD_IF(BLANK_DEBUG, "%s: Done %s display: %d", __FUNCTION__,
329          blank==1 ? "blanking":"unblanking", dpy);
330    return 0;
331}
332
333static int hwc_query(struct hwc_composer_device_1* dev,
334                     int param, int* value)
335{
336    hwc_context_t* ctx = (hwc_context_t*)(dev);
337    int supported = HWC_DISPLAY_PRIMARY_BIT;
338
339    switch (param) {
340    case HWC_BACKGROUND_LAYER_SUPPORTED:
341        // Not supported for now
342        value[0] = 0;
343        break;
344    case HWC_DISPLAY_TYPES_SUPPORTED:
345        if(ctx->mMDP.hasOverlay)
346            supported |= HWC_DISPLAY_EXTERNAL_BIT;
347        value[0] = supported;
348        break;
349    default:
350        return -EINVAL;
351    }
352    return 0;
353
354}
355
356
357static int hwc_set_primary(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
358    ATRACE_CALL();
359    int ret = 0;
360    const int dpy = HWC_DISPLAY_PRIMARY;
361
362    if (LIKELY(list) && ctx->dpyAttr[dpy].isActive) {
363        uint32_t last = list->numHwLayers - 1;
364        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
365        int fd = -1; //FenceFD from the Copybit(valid in async mode)
366        bool copybitDone = false;
367        if(ctx->mCopyBit[dpy])
368            copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
369        if(list->numHwLayers > 1)
370            hwc_sync(ctx, list, dpy, fd);
371
372        if (!ctx->mMDPComp[dpy]->draw(ctx, list)) {
373            ALOGE("%s: MDPComp draw failed", __FUNCTION__);
374            ret = -1;
375        }
376
377        //TODO We dont check for SKIP flag on this layer because we need PAN
378        //always. Last layer is always FB
379        private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
380        if(copybitDone) {
381            hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer();
382        }
383
384        if(hnd) {
385            if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) {
386                ALOGE("%s: FBUpdate draw failed", __FUNCTION__);
387                ret = -1;
388            }
389        }
390
391        if (display_commit(ctx, dpy) < 0) {
392            ALOGE("%s: display commit fail!", __FUNCTION__);
393            ret = -1;
394        }
395    }
396
397    closeAcquireFds(list);
398    return ret;
399}
400
401static int hwc_set_external(hwc_context_t *ctx,
402                            hwc_display_contents_1_t* list, int dpy)
403{
404    ATRACE_CALL();
405    int ret = 0;
406    Locker::Autolock _l(ctx->mExtLock);
407
408    if (LIKELY(list) && ctx->dpyAttr[dpy].isActive &&
409        !ctx->dpyAttr[dpy].isPause &&
410        ctx->dpyAttr[dpy].connected) {
411        uint32_t last = list->numHwLayers - 1;
412        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
413        int fd = -1; //FenceFD from the Copybit(valid in async mode)
414        bool copybitDone = false;
415        if(ctx->mCopyBit[dpy])
416            copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
417
418        if(list->numHwLayers > 1)
419            hwc_sync(ctx, list, dpy, fd);
420
421        if (!ctx->mMDPComp[dpy]->draw(ctx, list)) {
422            ALOGE("%s: MDPComp draw failed", __FUNCTION__);
423            ret = -1;
424        }
425
426        private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
427        if(copybitDone) {
428            hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer();
429        }
430
431        if(hnd) {
432            if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) {
433                ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
434                ret = -1;
435            }
436        }
437
438        if (display_commit(ctx, dpy) < 0) {
439            ALOGE("%s: display commit fail!", __FUNCTION__);
440            ret = -1;
441        }
442    }
443
444    closeAcquireFds(list);
445    return ret;
446}
447
448static int hwc_set_virtual(hwc_context_t *ctx,
449                           hwc_display_contents_1_t* list, int dpy)
450{
451    //XXX: Implement set.
452    closeAcquireFds(list);
453    if (list) {
454        // SF assumes HWC waits for the acquire fence and returns a new fence
455        // that signals when we're done. Since we don't wait, and also don't
456        // touch the buffer, we can just handle the acquire fence back to SF
457        // as the retire fence.
458        list->retireFenceFd = list->outbufAcquireFenceFd;
459    }
460    return 0;
461}
462
463
464static int hwc_set(hwc_composer_device_1 *dev,
465                   size_t numDisplays,
466                   hwc_display_contents_1_t** displays)
467{
468    int ret = 0;
469    hwc_context_t* ctx = (hwc_context_t*)(dev);
470    Locker::Autolock _l(ctx->mBlankLock);
471    for (uint32_t i = 0; i < numDisplays; i++) {
472        hwc_display_contents_1_t* list = displays[i];
473        switch(i) {
474            case HWC_DISPLAY_PRIMARY:
475                ret = hwc_set_primary(ctx, list);
476                break;
477            case HWC_DISPLAY_EXTERNAL:
478                ret = hwc_set_external(ctx, list, i);
479                break;
480            case HWC_DISPLAY_VIRTUAL:
481                ret = hwc_set_virtual(ctx, list, i);
482                break;
483            default:
484                ret = -EINVAL;
485        }
486    }
487    // This is only indicative of how many times SurfaceFlinger posts
488    // frames to the display.
489    CALC_FPS();
490    MDPComp::resetIdleFallBack();
491    ctx->mVideoTransFlag = false;
492    return ret;
493}
494
495int hwc_getDisplayConfigs(struct hwc_composer_device_1* dev, int disp,
496        uint32_t* configs, size_t* numConfigs) {
497    int ret = 0;
498    hwc_context_t* ctx = (hwc_context_t*)(dev);
499    //in 1.1 there is no way to choose a config, report as config id # 0
500    //This config is passed to getDisplayAttributes. Ignore for now.
501    switch(disp) {
502        case HWC_DISPLAY_PRIMARY:
503            if(*numConfigs > 0) {
504                configs[0] = 0;
505                *numConfigs = 1;
506            }
507            ret = 0; //NO_ERROR
508            break;
509        case HWC_DISPLAY_EXTERNAL:
510            ret = -1; //Not connected
511            if(ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected) {
512                ret = 0; //NO_ERROR
513                if(*numConfigs > 0) {
514                    configs[0] = 0;
515                    *numConfigs = 1;
516                }
517            }
518            break;
519    }
520    return ret;
521}
522
523int hwc_getDisplayAttributes(struct hwc_composer_device_1* dev, int disp,
524        uint32_t config, const uint32_t* attributes, int32_t* values) {
525
526    hwc_context_t* ctx = (hwc_context_t*)(dev);
527    //If hotpluggable displays are inactive return error
528    if(disp == HWC_DISPLAY_EXTERNAL && !ctx->dpyAttr[disp].connected) {
529        return -1;
530    }
531
532    //From HWComposer
533    static const uint32_t DISPLAY_ATTRIBUTES[] = {
534        HWC_DISPLAY_VSYNC_PERIOD,
535        HWC_DISPLAY_WIDTH,
536        HWC_DISPLAY_HEIGHT,
537        HWC_DISPLAY_DPI_X,
538        HWC_DISPLAY_DPI_Y,
539        HWC_DISPLAY_NO_ATTRIBUTE,
540    };
541
542    const int NUM_DISPLAY_ATTRIBUTES = (sizeof(DISPLAY_ATTRIBUTES) /
543            sizeof(DISPLAY_ATTRIBUTES)[0]);
544
545    for (size_t i = 0; i < NUM_DISPLAY_ATTRIBUTES - 1; i++) {
546        switch (attributes[i]) {
547        case HWC_DISPLAY_VSYNC_PERIOD:
548            values[i] = ctx->dpyAttr[disp].vsync_period;
549            break;
550        case HWC_DISPLAY_WIDTH:
551            values[i] = ctx->dpyAttr[disp].xres;
552            ALOGD("%s disp = %d, width = %d",__FUNCTION__, disp,
553                    ctx->dpyAttr[disp].xres);
554            break;
555        case HWC_DISPLAY_HEIGHT:
556            values[i] = ctx->dpyAttr[disp].yres;
557            ALOGD("%s disp = %d, height = %d",__FUNCTION__, disp,
558                    ctx->dpyAttr[disp].yres);
559            break;
560        case HWC_DISPLAY_DPI_X:
561            values[i] = (int32_t) (ctx->dpyAttr[disp].xdpi*1000.0);
562            break;
563        case HWC_DISPLAY_DPI_Y:
564            values[i] = (int32_t) (ctx->dpyAttr[disp].ydpi*1000.0);
565            break;
566        default:
567            ALOGE("Unknown display attribute %d",
568                    attributes[i]);
569            return -EINVAL;
570        }
571    }
572    return 0;
573}
574
575void hwc_dump(struct hwc_composer_device_1* dev, char *buff, int buff_len)
576{
577    hwc_context_t* ctx = (hwc_context_t*)(dev);
578    android::String8 aBuf("");
579    dumpsys_log(aBuf, "Qualcomm HWC state:\n");
580    dumpsys_log(aBuf, "  MDPVersion=%d\n", ctx->mMDP.version);
581    dumpsys_log(aBuf, "  DisplayPanel=%c\n", ctx->mMDP.panel);
582    for(int dpy = 0; dpy < MAX_DISPLAYS; dpy++) {
583        if(ctx->mMDPComp[dpy])
584            ctx->mMDPComp[dpy]->dump(aBuf);
585    }
586    char ovDump[2048] = {'\0'};
587    ctx->mOverlay->getDump(ovDump, 2048);
588    dumpsys_log(aBuf, ovDump);
589    ovDump[0] = '\0';
590    ctx->mRotMgr->getDump(ovDump, 1024);
591    dumpsys_log(aBuf, ovDump);
592    strlcpy(buff, aBuf.string(), buff_len);
593}
594
595static int hwc_device_close(struct hw_device_t *dev)
596{
597    if(!dev) {
598        ALOGE("%s: NULL device pointer", __FUNCTION__);
599        return -1;
600    }
601    closeContext((hwc_context_t*)dev);
602    free(dev);
603
604    return 0;
605}
606
607static int hwc_device_open(const struct hw_module_t* module, const char* name,
608                           struct hw_device_t** device)
609{
610    int status = -EINVAL;
611
612    if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
613        struct hwc_context_t *dev;
614        dev = (hwc_context_t*)malloc(sizeof(*dev));
615        memset(dev, 0, sizeof(*dev));
616
617        //Initialize hwc context
618        initContext(dev);
619
620        //Setup HWC methods
621        dev->device.common.tag          = HARDWARE_DEVICE_TAG;
622        dev->device.common.version      = HWC_DEVICE_API_VERSION_1_2;
623        dev->device.common.module       = const_cast<hw_module_t*>(module);
624        dev->device.common.close        = hwc_device_close;
625        dev->device.prepare             = hwc_prepare;
626        dev->device.set                 = hwc_set;
627        dev->device.eventControl        = hwc_eventControl;
628        dev->device.blank               = hwc_blank;
629        dev->device.query               = hwc_query;
630        dev->device.registerProcs       = hwc_registerProcs;
631        dev->device.dump                = hwc_dump;
632        dev->device.getDisplayConfigs   = hwc_getDisplayConfigs;
633        dev->device.getDisplayAttributes = hwc_getDisplayAttributes;
634        *device = &dev->device.common;
635        status = 0;
636    }
637    return status;
638}
639