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