blob: 340490ad9b043b30b56e9e5331df20ff3a453e18 [file] [log] [blame]
Naseer Ahmed29a26812012-06-14 00:56:20 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
Saurabh Shah56f610d2012-08-07 15:27:06 -07003 * Copyright (C) 2012, The Linux Foundation All rights reserved.
Naseer Ahmed29a26812012-06-14 00:56:20 -07004 *
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
Naseer Ahmed5b6708a2012-08-02 13:46:08 -070018#include <EGL/egl.h>
Naseer Ahmed72cf9762012-07-21 12:17:13 -070019#include <overlay.h>
Saurabh Shahfc2acbe2012-08-17 19:47:52 -070020#include <cutils/properties.h>
21#include <gralloc_priv.h>
22#include <fb_priv.h>
Naseer Ahmed29a26812012-06-14 00:56:20 -070023#include "hwc_utils.h"
Naseer Ahmeda87da602012-07-01 23:54:19 -070024#include "mdp_version.h"
Naseer Ahmedf48aef62012-07-20 09:05:53 -070025#include "hwc_video.h"
Saurabh Shah56f610d2012-08-07 15:27:06 -070026#include "external.h"
Naseer Ahmed7c958d42012-07-31 18:57:03 -070027#include "hwc_mdpcomp.h"
Saurabh Shah56f610d2012-08-07 15:27:06 -070028#include "QService.h"
Naseer Ahmed72cf9762012-07-21 12:17:13 -070029
Naseer Ahmed29a26812012-06-14 00:56:20 -070030namespace qhwc {
Naseer Ahmed72cf9762012-07-21 12:17:13 -070031
32// Opens Framebuffer device
33static void openFramebufferDevice(hwc_context_t *ctx)
34{
35 hw_module_t const *module;
36 if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) {
37 framebuffer_open(module, &(ctx->mFbDev));
Saurabh Shah3e858eb2012-09-17 16:53:21 -070038 private_module_t* m = reinterpret_cast<private_module_t*>(
39 ctx->mFbDev->common.module);
40 //xres, yres may not be 32 aligned
41 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres = m->info.xres;
42 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres = m->info.yres;
43 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xdpi = ctx->mFbDev->xdpi;
44 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].ydpi = ctx->mFbDev->ydpi;
45 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period =
46 1000000000l / ctx->mFbDev->fps;
47 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd = openFb(HWC_DISPLAY_PRIMARY);
Naseer Ahmed72cf9762012-07-21 12:17:13 -070048 }
49}
50
Saurabh Shahe4f3f722012-10-05 17:48:58 -070051static void onExtDisconnect(const hwc_context_t::Callbacks& priv_proc) {
52 hwc_context_t *ctx = priv_proc.ctx;
53 overlay::Overlay& ov = *(ctx->mOverlay[HWC_DISPLAY_EXTERNAL]);
54 // Set overlay state
55 ov.setState(ovutils::OV_CLOSED);
56}
57
Naseer Ahmed29a26812012-06-14 00:56:20 -070058void initContext(hwc_context_t *ctx)
59{
Naseer Ahmed72cf9762012-07-21 12:17:13 -070060 openFramebufferDevice(ctx);
Saurabh Shahc4d034f2012-09-27 15:55:15 -070061 overlay::Overlay::initOverlay();
62 for(uint32_t i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
63 ctx->mOverlay[i] = overlay::Overlay::getInstance(i);
64 }
Saurabh Shah56f610d2012-08-07 15:27:06 -070065 ctx->mQService = qService::QService::getInstance(ctx);
Naseer Ahmed96c4c952012-07-25 18:27:14 -070066 ctx->mMDP.version = qdutils::MDPVersion::getInstance().getMDPVersion();
67 ctx->mMDP.hasOverlay = qdutils::MDPVersion::getInstance().hasOverlay();
68 ctx->mMDP.panel = qdutils::MDPVersion::getInstance().getPanelType();
Naseer Ahmed72cf9762012-07-21 12:17:13 -070069 ctx->mExtDisplay = new ExternalDisplay(ctx);
Naseer Ahmed7c958d42012-07-31 18:57:03 -070070 MDPComp::init(ctx);
Naseer Ahmed72cf9762012-07-21 12:17:13 -070071
Naseer Ahmedff4f0252012-10-01 13:03:01 -040072 pthread_mutex_init(&(ctx->vstate.lock), NULL);
73 pthread_cond_init(&(ctx->vstate.cond), NULL);
74 ctx->vstate.enable = false;
75
Saurabh Shahe4f3f722012-10-05 17:48:58 -070076 ctx->priv_proc.onExtDisconnect = onExtDisconnect;
77 ctx->priv_proc.ctx = ctx;
78
Naseer Ahmed72cf9762012-07-21 12:17:13 -070079 ALOGI("Initializing Qualcomm Hardware Composer");
Naseer Ahmed96c4c952012-07-25 18:27:14 -070080 ALOGI("MDP version: %d", ctx->mMDP.version);
Naseer Ahmed29a26812012-06-14 00:56:20 -070081}
82
83void closeContext(hwc_context_t *ctx)
84{
Saurabh Shahc4d034f2012-09-27 15:55:15 -070085 for(uint32_t i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
86 if(ctx->mOverlay[i]) {
87 delete ctx->mOverlay[i];
88 ctx->mOverlay[i] = NULL;
89 }
Naseer Ahmed29a26812012-06-14 00:56:20 -070090 }
Naseer Ahmedf48aef62012-07-20 09:05:53 -070091
Naseer Ahmed72cf9762012-07-21 12:17:13 -070092 if(ctx->mFbDev) {
93 framebuffer_close(ctx->mFbDev);
94 ctx->mFbDev = NULL;
Saurabh Shah3e858eb2012-09-17 16:53:21 -070095 close(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd);
96 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd = -1;
Naseer Ahmed29a26812012-06-14 00:56:20 -070097 }
Naseer Ahmed72cf9762012-07-21 12:17:13 -070098
99 if(ctx->mExtDisplay) {
100 delete ctx->mExtDisplay;
101 ctx->mExtDisplay = NULL;
102 }
Naseer Ahmedff4f0252012-10-01 13:03:01 -0400103
104 pthread_mutex_destroy(&(ctx->vstate.lock));
105 pthread_cond_destroy(&(ctx->vstate.cond));
106
Naseer Ahmed29a26812012-06-14 00:56:20 -0700107}
108
Naseer Ahmed5b6708a2012-08-02 13:46:08 -0700109void dumpLayer(hwc_layer_1_t const* l)
Naseer Ahmed29a26812012-06-14 00:56:20 -0700110{
111 ALOGD("\ttype=%d, flags=%08x, handle=%p, tr=%02x, blend=%04x, {%d,%d,%d,%d}"
112 ", {%d,%d,%d,%d}",
113 l->compositionType, l->flags, l->handle, l->transform, l->blending,
114 l->sourceCrop.left,
115 l->sourceCrop.top,
116 l->sourceCrop.right,
117 l->sourceCrop.bottom,
118 l->displayFrame.left,
119 l->displayFrame.top,
120 l->displayFrame.right,
121 l->displayFrame.bottom);
122}
123
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700124void setListStats(hwc_context_t *ctx,
125 const hwc_display_contents_1_t *list, int dpy) {
126
127 ctx->listStats[dpy].numAppLayers = list->numHwLayers - 1;
128 ctx->listStats[dpy].fbLayerIndex = list->numHwLayers - 1;
Saurabh Shahc4d034f2012-09-27 15:55:15 -0700129 ctx->listStats[dpy].yuvCount = 0;
130 ctx->listStats[dpy].yuvIndex = -1;
131 ctx->listStats[dpy].skipCount = 0;
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700132
133 for (size_t i = 0; i < list->numHwLayers; i++) {
134 private_handle_t *hnd =
135 (private_handle_t *)list->hwLayers[i].handle;
136
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700137 if(list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) {
138 continue;
139 //We disregard FB being skip for now! so the else if
Saurabh Shah35712cb2012-09-14 10:28:18 -0700140 } else if (isSkipLayer(&list->hwLayers[i])) {
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700141 ctx->listStats[dpy].skipCount++;
142 }
143
144 if (UNLIKELY(isYuvBuffer(hnd))) {
145 ctx->listStats[dpy].yuvCount++;
146 ctx->listStats[dpy].yuvIndex = i;
Naseer Ahmed29a26812012-06-14 00:56:20 -0700147 }
148 }
Naseer Ahmed29a26812012-06-14 00:56:20 -0700149}
150
Saurabh Shah541b59d2012-10-11 11:08:12 -0700151static inline void calc_cut(float& leftCutRatio, float& topCutRatio,
152 float& rightCutRatio, float& bottomCutRatio, int orient) {
Saurabh Shah27c1d652012-08-14 19:30:28 -0700153 if(orient & HAL_TRANSFORM_FLIP_H) {
Saurabh Shah541b59d2012-10-11 11:08:12 -0700154 swap(leftCutRatio, rightCutRatio);
Saurabh Shah27c1d652012-08-14 19:30:28 -0700155 }
156 if(orient & HAL_TRANSFORM_FLIP_V) {
Saurabh Shah541b59d2012-10-11 11:08:12 -0700157 swap(topCutRatio, bottomCutRatio);
Saurabh Shah27c1d652012-08-14 19:30:28 -0700158 }
159 if(orient & HAL_TRANSFORM_ROT_90) {
160 //Anti clock swapping
Saurabh Shah541b59d2012-10-11 11:08:12 -0700161 float tmpCutRatio = leftCutRatio;
162 leftCutRatio = topCutRatio;
163 topCutRatio = rightCutRatio;
164 rightCutRatio = bottomCutRatio;
165 bottomCutRatio = tmpCutRatio;
Saurabh Shah27c1d652012-08-14 19:30:28 -0700166 }
167}
168
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700169//Crops source buffer against destination and FB boundaries
170void calculate_crop_rects(hwc_rect_t& crop, hwc_rect_t& dst,
Saurabh Shah27c1d652012-08-14 19:30:28 -0700171 const int fbWidth, const int fbHeight, int orient) {
172 int& crop_l = crop.left;
173 int& crop_t = crop.top;
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700174 int& crop_r = crop.right;
175 int& crop_b = crop.bottom;
176 int crop_w = crop.right - crop.left;
177 int crop_h = crop.bottom - crop.top;
178
Saurabh Shah27c1d652012-08-14 19:30:28 -0700179 int& dst_l = dst.left;
180 int& dst_t = dst.top;
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700181 int& dst_r = dst.right;
182 int& dst_b = dst.bottom;
Saurabh Shah27c1d652012-08-14 19:30:28 -0700183 int dst_w = abs(dst.right - dst.left);
184 int dst_h = abs(dst.bottom - dst.top);
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700185
Saurabh Shah541b59d2012-10-11 11:08:12 -0700186 float leftCutRatio = 0.0f, rightCutRatio = 0.0f, topCutRatio = 0.0f,
187 bottomCutRatio = 0.0f;
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700188
Saurabh Shah27c1d652012-08-14 19:30:28 -0700189 if(dst_l < 0) {
Saurabh Shah541b59d2012-10-11 11:08:12 -0700190 leftCutRatio = (float)(0.0f - dst_l) / (float)dst_w;
Saurabh Shah27c1d652012-08-14 19:30:28 -0700191 dst_l = 0;
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700192 }
193 if(dst_r > fbWidth) {
Saurabh Shah541b59d2012-10-11 11:08:12 -0700194 rightCutRatio = (float)(dst_r - fbWidth) / (float)dst_w;
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700195 dst_r = fbWidth;
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700196 }
Saurabh Shah27c1d652012-08-14 19:30:28 -0700197 if(dst_t < 0) {
Saurabh Shah541b59d2012-10-11 11:08:12 -0700198 topCutRatio = (float)(0 - dst_t) / (float)dst_h;
Saurabh Shah27c1d652012-08-14 19:30:28 -0700199 dst_t = 0;
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700200 }
201 if(dst_b > fbHeight) {
Saurabh Shah541b59d2012-10-11 11:08:12 -0700202 bottomCutRatio = (float)(dst_b - fbHeight) / (float)dst_h;
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700203 dst_b = fbHeight;
Naseer Ahmed29a26812012-06-14 00:56:20 -0700204 }
Saurabh Shah27c1d652012-08-14 19:30:28 -0700205
Saurabh Shah541b59d2012-10-11 11:08:12 -0700206 calc_cut(leftCutRatio, topCutRatio, rightCutRatio, bottomCutRatio, orient);
207 crop_l += crop_w * leftCutRatio;
208 crop_t += crop_h * topCutRatio;
209 crop_r -= crop_w * rightCutRatio;
210 crop_b -= crop_h * bottomCutRatio;
Naseer Ahmed29a26812012-06-14 00:56:20 -0700211}
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700212
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700213bool isExternalActive(hwc_context_t* ctx) {
214 return ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive;
Saurabh Shahfc2acbe2012-08-17 19:47:52 -0700215}
216
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700217int hwc_sync(hwc_context_t *ctx, hwc_display_contents_1_t* list, int dpy) {
Kinjal Bhavsar2dd04a82012-09-18 18:27:59 -0700218 int ret = 0;
219#ifdef USE_FENCE_SYNC
220 struct mdp_buf_sync data;
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700221 int acquireFd[4];
Kinjal Bhavsar2dd04a82012-09-18 18:27:59 -0700222 int count = 0;
223 int releaseFd = -1;
224 int fbFd = -1;
Saurabh Shahc4d034f2012-09-27 15:55:15 -0700225 data.flags = MDP_BUF_SYNC_FLAG_WAIT;
Kinjal Bhavsar2dd04a82012-09-18 18:27:59 -0700226 data.acq_fen_fd = acquireFd;
227 data.rel_fen_fd = &releaseFd;
228 //Accumulate acquireFenceFds
229 for(uint32_t i = 0; i < list->numHwLayers; i++) {
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700230 if((list->hwLayers[i].compositionType == HWC_OVERLAY ||
231 list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) &&
Kinjal Bhavsar2dd04a82012-09-18 18:27:59 -0700232 list->hwLayers[i].acquireFenceFd != -1) {
233 acquireFd[count++] = list->hwLayers[i].acquireFenceFd;
234 }
235 }
236
237 if (count) {
238 data.acq_fen_fd_cnt = count;
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700239 fbFd = ctx->dpyAttr[dpy].fd;
Kinjal Bhavsar2dd04a82012-09-18 18:27:59 -0700240
241 //Waits for acquire fences, returns a release fence
242 ret = ioctl(fbFd, MSMFB_BUFFER_SYNC, &data);
243 if(ret < 0) {
244 ALOGE("ioctl MSMFB_BUFFER_SYNC failed, err=%s",
245 strerror(errno));
246 }
Kinjal Bhavsar2dd04a82012-09-18 18:27:59 -0700247
248 for(uint32_t i = 0; i < list->numHwLayers; i++) {
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700249 if((list->hwLayers[i].compositionType == HWC_OVERLAY ||
250 list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET)) {
Kinjal Bhavsar2dd04a82012-09-18 18:27:59 -0700251 //Close the acquireFenceFds
252 if(list->hwLayers[i].acquireFenceFd > 0) {
253 close(list->hwLayers[i].acquireFenceFd);
254 list->hwLayers[i].acquireFenceFd = -1;
255 }
256 //Populate releaseFenceFds.
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700257 list->hwLayers[i].releaseFenceFd = dup(releaseFd);
Kinjal Bhavsar2dd04a82012-09-18 18:27:59 -0700258 }
259 }
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700260 list->retireFenceFd = releaseFd;
Kinjal Bhavsar2dd04a82012-09-18 18:27:59 -0700261 }
262#endif
263 return ret;
264}
265
Naseer Ahmed29a26812012-06-14 00:56:20 -0700266};//namespace