hwc_utils.cpp revision 35712cb6398dc0f7442fe8951ce1e6eec4647f5c
1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 * Copyright (C) 2012, The Linux Foundation All rights reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *      http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18#include <EGL/egl.h>
19#include <overlay.h>
20#include <cutils/properties.h>
21#include <gralloc_priv.h>
22#include <fb_priv.h>
23#include "hwc_utils.h"
24#include "mdp_version.h"
25#include "hwc_video.h"
26#include "hwc_qbuf.h"
27#include "hwc_copybit.h"
28#include "external.h"
29#include "hwc_mdpcomp.h"
30#include "hwc_extonly.h"
31#include "QService.h"
32
33namespace qhwc {
34
35// Opens Framebuffer device
36static void openFramebufferDevice(hwc_context_t *ctx)
37{
38    hw_module_t const *module;
39    if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) {
40        framebuffer_open(module, &(ctx->mFbDev));
41    }
42}
43
44void initContext(hwc_context_t *ctx)
45{
46    openFramebufferDevice(ctx);
47    ctx->mOverlay = overlay::Overlay::getInstance();
48    ctx->mQService = qService::QService::getInstance(ctx);
49    ctx->qbuf = new QueuedBufferStore();
50    ctx->mMDP.version = qdutils::MDPVersion::getInstance().getMDPVersion();
51    ctx->mMDP.hasOverlay = qdutils::MDPVersion::getInstance().hasOverlay();
52    ctx->mMDP.panel = qdutils::MDPVersion::getInstance().getPanelType();
53    ctx->mExtDisplay = new ExternalDisplay(ctx);
54    memset(ctx->dpys,(int)EGL_NO_DISPLAY, MAX_NUM_DISPLAYS);
55    MDPComp::init(ctx);
56
57    ALOGI("Initializing Qualcomm Hardware Composer");
58    ALOGI("MDP version: %d", ctx->mMDP.version);
59}
60
61void closeContext(hwc_context_t *ctx)
62{
63    if(ctx->mOverlay) {
64        delete ctx->mOverlay;
65        ctx->mOverlay = NULL;
66    }
67
68    if(ctx->mCopybitEngine) {
69        delete ctx->mCopybitEngine;
70        ctx->mCopybitEngine = NULL;
71    }
72
73    if(ctx->mFbDev) {
74        framebuffer_close(ctx->mFbDev);
75        ctx->mFbDev = NULL;
76    }
77
78    if(ctx->qbuf) {
79        delete ctx->qbuf;
80        ctx->qbuf = NULL;
81    }
82
83    if(ctx->mExtDisplay) {
84        delete ctx->mExtDisplay;
85        ctx->mExtDisplay = NULL;
86    }
87}
88
89void dumpLayer(hwc_layer_1_t const* l)
90{
91    ALOGD("\ttype=%d, flags=%08x, handle=%p, tr=%02x, blend=%04x, {%d,%d,%d,%d}"
92          ", {%d,%d,%d,%d}",
93          l->compositionType, l->flags, l->handle, l->transform, l->blending,
94          l->sourceCrop.left,
95          l->sourceCrop.top,
96          l->sourceCrop.right,
97          l->sourceCrop.bottom,
98          l->displayFrame.left,
99          l->displayFrame.top,
100          l->displayFrame.right,
101          l->displayFrame.bottom);
102}
103
104void getLayerStats(hwc_context_t *ctx, const hwc_display_contents_1_t *list)
105{
106    //Video specific stats
107    int yuvCount = 0;
108    int yuvLayerIndex = -1;
109    bool isYuvLayerSkip = false;
110    int skipCount = 0;
111    int ccLayerIndex = -1; //closed caption
112    int extLayerIndex = -1; //ext-only or block except closed caption
113    int extCount = 0; //ext-only except closed caption
114    bool isExtBlockPresent = false; //is BLOCK layer present
115    bool yuvSecure = false;
116
117    for (size_t i = 0; i < list->numHwLayers; i++) {
118        private_handle_t *hnd =
119            (private_handle_t *)list->hwLayers[i].handle;
120
121        if (UNLIKELY(isYuvBuffer(hnd))) {
122            yuvCount++;
123            yuvLayerIndex = i;
124            yuvSecure = isSecureBuffer(hnd);
125            //Animating
126            //Do not mark as SKIP if it is secure buffer
127            if (isSkipLayer(&list->hwLayers[i]) && !yuvSecure) {
128                isYuvLayerSkip = true;
129                skipCount++;
130            }
131        } else if(UNLIKELY(isExtCC(hnd))) {
132            ccLayerIndex = i;
133        } else if(UNLIKELY(isExtBlock(hnd))) {
134            extCount++;
135            extLayerIndex = i;
136            isExtBlockPresent = true;
137        } else if(UNLIKELY(isExtOnly(hnd))) {
138            extCount++;
139            //If BLOCK layer present, dont cache index, display BLOCK only.
140            if(isExtBlockPresent == false) extLayerIndex = i;
141        } else if (isSkipLayer(&list->hwLayers[i])) {
142            skipCount++;
143        }
144    }
145
146    VideoOverlay::setStats(yuvCount, yuvLayerIndex, isYuvLayerSkip,
147            ccLayerIndex);
148    ExtOnly::setStats(extCount, extLayerIndex, isExtBlockPresent);
149    CopyBit::setStats(yuvCount, yuvLayerIndex, isYuvLayerSkip);
150    MDPComp::setStats(skipCount);
151
152    ctx->numHwLayers = list->numHwLayers;
153    return;
154}
155
156//Crops source buffer against destination and FB boundaries
157void calculate_crop_rects(hwc_rect_t& crop, hwc_rect_t& dst,
158        const int fbWidth, const int fbHeight) {
159
160    int& crop_x = crop.left;
161    int& crop_y = crop.top;
162    int& crop_r = crop.right;
163    int& crop_b = crop.bottom;
164    int crop_w = crop.right - crop.left;
165    int crop_h = crop.bottom - crop.top;
166
167    int& dst_x = dst.left;
168    int& dst_y = dst.top;
169    int& dst_r = dst.right;
170    int& dst_b = dst.bottom;
171    int dst_w = dst.right - dst.left;
172    int dst_h = dst.bottom - dst.top;
173
174    if(dst_x < 0) {
175        float scale_x =  crop_w * 1.0f / dst_w;
176        float diff_factor = (scale_x * abs(dst_x));
177        crop_x = crop_x + (int)diff_factor;
178        crop_w = crop_r - crop_x;
179
180        dst_x = 0;
181        dst_w = dst_r - dst_x;;
182    }
183    if(dst_r > fbWidth) {
184        float scale_x = crop_w * 1.0f / dst_w;
185        float diff_factor = scale_x * (dst_r - fbWidth);
186        crop_r = crop_r - diff_factor;
187        crop_w = crop_r - crop_x;
188
189        dst_r = fbWidth;
190        dst_w = dst_r - dst_x;
191    }
192    if(dst_y < 0) {
193        float scale_y = crop_h * 1.0f / dst_h;
194        float diff_factor = scale_y * abs(dst_y);
195        crop_y = crop_y + diff_factor;
196        crop_h = crop_b - crop_y;
197
198        dst_y = 0;
199        dst_h = dst_b - dst_y;
200    }
201    if(dst_b > fbHeight) {
202        float scale_y = crop_h * 1.0f / dst_h;
203        float diff_factor = scale_y * (dst_b - fbHeight);
204        crop_b = crop_b - diff_factor;
205        crop_h = crop_b - crop_y;
206
207        dst_b = fbHeight;
208        dst_h = dst_b - dst_y;
209    }
210}
211
212void wait4fbPost(hwc_context_t* ctx) {
213    framebuffer_device_t *fbDev = ctx->mFbDev;
214    if(fbDev) {
215        private_module_t* m = reinterpret_cast<private_module_t*>(
216                              fbDev->common.module);
217        //wait for the fb_post to be called
218        pthread_mutex_lock(&m->fbPostLock);
219        while(m->fbPostDone == false) {
220            pthread_cond_wait(&(m->fbPostCond), &(m->fbPostLock));
221        }
222        m->fbPostDone = false;
223        pthread_mutex_unlock(&m->fbPostLock);
224    }
225}
226
227void wait4Pan(hwc_context_t* ctx) {
228    framebuffer_device_t *fbDev = ctx->mFbDev;
229    if(fbDev) {
230        private_module_t* m = reinterpret_cast<private_module_t*>(
231                              fbDev->common.module);
232        //wait for the fb_post's PAN to finish
233        pthread_mutex_lock(&m->fbPanLock);
234        while(m->fbPanDone == false) {
235            pthread_cond_wait(&(m->fbPanCond), &(m->fbPanLock));
236        }
237        m->fbPanDone = false;
238        pthread_mutex_unlock(&m->fbPanLock);
239    }
240}
241};//namespace
242