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