hwc_utils.cpp revision 96c4c95d48dc075196c601b30a8798a262df9720
1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 * Copyright (C) 2012, Code Aurora Forum. 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 <overlay.h>
19#include "hwc_utils.h"
20#include "mdp_version.h"
21#include "hwc_video.h"
22#include "hwc_qbuf.h"
23#include "hwc_copybit.h"
24#include "hwc_external.h"
25#include "hwc_mdpcomp.h"
26
27namespace qhwc {
28
29// Opens Framebuffer device
30static void openFramebufferDevice(hwc_context_t *ctx)
31{
32    hw_module_t const *module;
33    if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) {
34        framebuffer_open(module, &(ctx->mFbDev));
35    }
36}
37
38void initContext(hwc_context_t *ctx)
39{
40    openFramebufferDevice(ctx);
41    ctx->mOverlay = overlay::Overlay::getInstance();
42    ctx->qbuf = new QueuedBufferStore();
43    ctx->mMDP.version = qdutils::MDPVersion::getInstance().getMDPVersion();
44    ctx->mMDP.hasOverlay = qdutils::MDPVersion::getInstance().hasOverlay();
45    ctx->mMDP.panel = qdutils::MDPVersion::getInstance().getPanelType();
46    ctx->mCopybitEngine = CopybitEngine::getInstance();
47    ctx->mExtDisplay = new ExternalDisplay(ctx);
48    MDPComp::init(ctx);
49
50    init_uevent_thread(ctx);
51
52    ALOGI("Initializing Qualcomm Hardware Composer");
53    ALOGI("MDP version: %d", ctx->mMDP.version);
54}
55
56void closeContext(hwc_context_t *ctx)
57{
58    if(ctx->mOverlay) {
59        delete ctx->mOverlay;
60        ctx->mOverlay = NULL;
61    }
62
63    if(ctx->mCopybitEngine) {
64        delete ctx->mCopybitEngine;
65        ctx->mCopybitEngine = NULL;
66    }
67
68    if(ctx->mFbDev) {
69        framebuffer_close(ctx->mFbDev);
70        ctx->mFbDev = NULL;
71    }
72
73    if(ctx->qbuf) {
74        delete ctx->qbuf;
75        ctx->qbuf = NULL;
76    }
77
78    if(ctx->mExtDisplay) {
79        delete ctx->mExtDisplay;
80        ctx->mExtDisplay = NULL;
81    }
82
83
84    free(const_cast<hwc_methods_t *>(ctx->device.methods));
85
86}
87
88void dumpLayer(hwc_layer_t const* l)
89{
90    ALOGD("\ttype=%d, flags=%08x, handle=%p, tr=%02x, blend=%04x, {%d,%d,%d,%d}"
91          ", {%d,%d,%d,%d}",
92          l->compositionType, l->flags, l->handle, l->transform, l->blending,
93          l->sourceCrop.left,
94          l->sourceCrop.top,
95          l->sourceCrop.right,
96          l->sourceCrop.bottom,
97          l->displayFrame.left,
98          l->displayFrame.top,
99          l->displayFrame.right,
100          l->displayFrame.bottom);
101}
102
103void getLayerStats(hwc_context_t *ctx, const hwc_layer_list_t *list)
104{
105    //Video specific stats
106    int yuvCount = 0;
107    int yuvLayerIndex = -1;
108    bool isYuvLayerSkip = false;
109    int skipCount = 0;
110
111    for (size_t i = 0; i < list->numHwLayers; i++) {
112        private_handle_t *hnd =
113            (private_handle_t *)list->hwLayers[i].handle;
114
115        if (isYuvBuffer(hnd)) {
116            yuvCount++;
117            yuvLayerIndex = i;
118            //Animating
119            if (isSkipLayer(&list->hwLayers[i])) {
120                isYuvLayerSkip = true;
121            }
122        } else if (isSkipLayer(&list->hwLayers[i])) { //Popups
123            //If video layer is below a skip layer
124            if(yuvLayerIndex != -1 && yuvLayerIndex < (ssize_t)i) {
125                isYuvLayerSkip = true;
126            }
127            skipCount++;
128        }
129    }
130
131    VideoOverlay::setStats(yuvCount, yuvLayerIndex, isYuvLayerSkip);
132    CopyBit::setStats(yuvCount, yuvLayerIndex, isYuvLayerSkip);
133    MDPComp::setStats(skipCount);
134
135    ctx->numHwLayers = list->numHwLayers;
136    return;
137}
138
139//Crops source buffer against destination and FB boundaries
140void calculate_crop_rects(hwc_rect_t& crop, hwc_rect_t& dst,
141        const int fbWidth, const int fbHeight) {
142
143    int& crop_x = crop.left;
144    int& crop_y = crop.top;
145    int& crop_r = crop.right;
146    int& crop_b = crop.bottom;
147    int crop_w = crop.right - crop.left;
148    int crop_h = crop.bottom - crop.top;
149
150    int& dst_x = dst.left;
151    int& dst_y = dst.top;
152    int& dst_r = dst.right;
153    int& dst_b = dst.bottom;
154    int dst_w = dst.right - dst.left;
155    int dst_h = dst.bottom - dst.top;
156
157    if(dst_x < 0) {
158        float scale_x =  crop_w * 1.0f / dst_w;
159        float diff_factor = (scale_x * abs(dst_x));
160        crop_x = crop_x + (int)diff_factor;
161        crop_w = crop_r - crop_x;
162
163        dst_x = 0;
164        dst_w = dst_r - dst_x;;
165    }
166    if(dst_r > fbWidth) {
167        float scale_x = crop_w * 1.0f / dst_w;
168        float diff_factor = scale_x * (dst_r - fbWidth);
169        crop_r = crop_r - diff_factor;
170        crop_w = crop_r - crop_x;
171
172        dst_r = fbWidth;
173        dst_w = dst_r - dst_x;
174    }
175    if(dst_y < 0) {
176        float scale_y = crop_h * 1.0f / dst_h;
177        float diff_factor = scale_y * abs(dst_y);
178        crop_y = crop_y + diff_factor;
179        crop_h = crop_b - crop_y;
180
181        dst_y = 0;
182        dst_h = dst_b - dst_y;
183    }
184    if(dst_b > fbHeight) {
185        float scale_y = crop_h * 1.0f / dst_h;
186        float diff_factor = scale_y * (dst_b - fbHeight);
187        crop_b = crop_b - diff_factor;
188        crop_h = crop_b - crop_y;
189
190        dst_b = fbHeight;
191        dst_h = dst_b - dst_y;
192    }
193}
194
195};//namespace
196