hwc_fbupdate.cpp revision 3e858ebde3f2b4e762af8f7f2808d45ba59b890d
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * Copyright (C) 2012, The Linux Foundation. All rights reserved. 4 * 5 * Not a Contribution, Apache license notifications and license are 6 * retained 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 21#define HWC_UI_MIRROR 0 22#include <gralloc_priv.h> 23#include <fb_priv.h> 24#include "hwc_uimirror.h" 25#include "external.h" 26 27namespace qhwc { 28 29 30// Function to get the orientation of UI on primary. 31// When external display is connected, the primary UI is 32// fixed to landscape by the phone window manager. 33// Return the landscape orientation based on w and hw of primary 34int getDeviceOrientation() { 35 int orientation = 0; 36 //Calculate the rect for primary based on whether the supplied 37 //position 38 //is within or outside bounds. 39 const int fbWidth = 40 ovutils::FrameBufferInfo::getInstance()->getWidth(); 41 const int fbHeight = 42 ovutils::FrameBufferInfo::getInstance()->getHeight(); 43 if(fbWidth >= fbHeight) { 44 // landscape panel 45 orientation = overlay::utils::OVERLAY_TRANSFORM_0; 46 } else { 47 // portrait panel 48 orientation = overlay::utils::OVERLAY_TRANSFORM_ROT_90; 49 } 50 return orientation; 51} 52 53//Static Members 54ovutils::eOverlayState UIMirrorOverlay::sState = ovutils::OV_CLOSED; 55bool UIMirrorOverlay::sIsUiMirroringOn = false; 56 57void UIMirrorOverlay::reset() { 58 sIsUiMirroringOn = false; 59 sState = ovutils::OV_CLOSED; 60} 61 62//Prepare the overlay for the UI mirroring 63bool UIMirrorOverlay::prepare(hwc_context_t *ctx, hwc_layer_1_t *fblayer) { 64 sState = ovutils::OV_CLOSED; 65 sIsUiMirroringOn = false; 66 67 if(!ctx->mMDP.hasOverlay) { 68 ALOGD_IF(HWC_UI_MIRROR, "%s, this hw doesnt support mirroring", 69 __FUNCTION__); 70 return false; 71 } 72 // If external display is active 73 if(isExternalActive(ctx)) { 74 sState = ovutils::OV_UI_MIRROR; 75 configure(ctx, fblayer); 76 } 77 return sIsUiMirroringOn; 78} 79 80// Configure 81bool UIMirrorOverlay::configure(hwc_context_t *ctx, hwc_layer_1_t *layer) 82{ 83 if (LIKELY(ctx->mOverlay)) { 84 overlay::Overlay& ov = *(ctx->mOverlay); 85 // Set overlay state 86 ov.setState(sState); 87 framebuffer_device_t *fbDev = ctx->mFbDev; 88 if(fbDev) { 89 private_handle_t *hnd = (private_handle_t *)layer->handle; 90 ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size); 91 // Determine the RGB pipe for UI depending on the state 92 ovutils::eDest dest = ovutils::OV_PIPE_ALL; 93 if (sState == ovutils::OV_2D_TRUE_UI_MIRROR) { 94 // True UI mirroring state: external RGB pipe is OV_PIPE2 95 dest = ovutils::OV_PIPE2; 96 } else if (sState == ovutils::OV_UI_MIRROR) { 97 // UI-only mirroring state: external RGB pipe is OV_PIPE0 98 dest = ovutils::OV_PIPE0; 99 } 100 101 ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE; 102 if(ctx->mSecureMode) { 103 ovutils::setMdpFlags(mdpFlags, 104 ovutils::OV_MDP_SECURE_OVERLAY_SESSION); 105 } 106 107 ovutils::PipeArgs parg(mdpFlags, 108 info, 109 ovutils::ZORDER_0, 110 ovutils::IS_FG_OFF, 111 ovutils::ROT_FLAG_ENABLED); 112 ovutils::PipeArgs pargs[ovutils::MAX_PIPES] = { parg, parg, parg }; 113 ov.setSource(pargs, dest); 114 115 hwc_rect_t sourceCrop = layer->sourceCrop; 116 // x,y,w,h 117 ovutils::Dim dcrop(sourceCrop.left, sourceCrop.top, 118 sourceCrop.right - sourceCrop.left, 119 sourceCrop.bottom - sourceCrop.top); 120 ov.setCrop(dcrop, dest); 121 122 //Get the current orientation on primary panel 123 int transform = getDeviceOrientation(); 124 ovutils::eTransform orient = 125 static_cast<ovutils::eTransform>(transform); 126 ov.setTransform(orient, dest); 127 128 hwc_rect_t displayFrame = layer->displayFrame; 129 ovutils::Dim dpos(displayFrame.left, 130 displayFrame.top, 131 displayFrame.right - displayFrame.left, 132 displayFrame.bottom - displayFrame.top); 133 ov.setPosition(dpos, dest); 134 135 if (!ov.commit(dest)) { 136 ALOGE("%s: commit fails", __FUNCTION__); 137 return false; 138 } 139 sIsUiMirroringOn = true; 140 } 141 } 142 return sIsUiMirroringOn; 143} 144 145bool UIMirrorOverlay::draw(hwc_context_t *ctx, hwc_layer_1_t *layer) 146{ 147 if(!sIsUiMirroringOn) { 148 return true; 149 } 150 bool ret = true; 151 overlay::Overlay& ov = *(ctx->mOverlay); 152 ovutils::eOverlayState state = ov.getState(); 153 ovutils::eDest dest = ovutils::OV_PIPE_ALL; 154 framebuffer_device_t *fbDev = ctx->mFbDev; 155 if(fbDev) { 156 private_module_t* m = reinterpret_cast<private_module_t*>( 157 fbDev->common.module); 158 private_handle_t *hnd = (private_handle_t *)layer->handle; 159 switch (state) { 160 case ovutils::OV_UI_MIRROR: 161 //TODO why is this primary fd 162 if (!ov.queueBuffer(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd, 163 hnd->offset, //div by line_length like in PAN? 164 ovutils::OV_PIPE0)) { 165 ALOGE("%s: queueBuffer failed for external", __FUNCTION__); 166 ret = false; 167 } 168 break; 169 case ovutils::OV_2D_TRUE_UI_MIRROR: 170 if (!ov.queueBuffer(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd, 171 hnd->offset, 172 ovutils::OV_PIPE2)) { 173 ALOGE("%s: queueBuffer failed for external", __FUNCTION__); 174 ret = false; 175 } 176 break; 177 178 default: 179 break; 180 } 181 } 182 return ret; 183} 184 185//--------------------------------------------------------------------- 186}; //namespace qhwc 187