1054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin/* 2054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * Copyright (C) 2010 The Android Open Source Project 3054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * Copyright (C) 2012-2015, The Linux Foundation. All rights reserved. 4054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * 5054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * Not a Contribution, Apache license notifications and license are retained 6054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * for attribution purposes only. 7054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * 8054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * Licensed under the Apache License, Version 2.0 (the "License"); 9054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * you may not use this file except in compliance with the License. 10054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * You may obtain a copy of the License at 11054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * 12054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * http://www.apache.org/licenses/LICENSE-2.0 13054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * 14054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * Unless required by applicable law or agreed to in writing, software 15054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * distributed under the License is distributed on an "AS IS" BASIS, 16054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * See the License for the specific language governing permissions and 18054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * limitations under the License. 19054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin */ 20054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL) 21054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include <fcntl.h> 22054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include <errno.h> 23054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 24054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include <cutils/log.h> 25054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include <cutils/atomic.h> 26054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include <EGL/egl.h> 27054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include <utils/Trace.h> 28054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include <sys/ioctl.h> 29054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include <overlay.h> 30054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include <overlayRotator.h> 31054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include <overlayWriteback.h> 32054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include <mdp_version.h> 33054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include "hwc_utils.h" 34054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include "hwc_fbupdate.h" 35054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include "hwc_mdpcomp.h" 36054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include "hwc_dump_layers.h" 37054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include "hdmi.h" 38054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include "hwc_copybit.h" 39054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include "hwc_ad.h" 40054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include "profiler.h" 41054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include "hwc_virtual.h" 42054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 43054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinusing namespace qhwc; 44054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinusing namespace overlay; 45054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 46054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#define VSYNC_DEBUG 0 47054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#define POWER_MODE_DEBUG 1 48054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 49054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinstatic int hwc_device_open(const struct hw_module_t* module, 50054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin const char* name, 51054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin struct hw_device_t** device); 52054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 53054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinstatic struct hw_module_methods_t hwc_module_methods = { 54054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin open: hwc_device_open 55054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}; 56054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 57054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinstatic void reset_panel(struct hwc_composer_device_1* dev); 58054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 59054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinhwc_module_t HAL_MODULE_INFO_SYM = { 60054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin common: { 61054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin tag: HARDWARE_MODULE_TAG, 62054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin version_major: 2, 63054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin version_minor: 0, 64054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin id: HWC_HARDWARE_MODULE_ID, 65054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin name: "Qualcomm Hardware Composer Module", 66054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin author: "CodeAurora Forum", 67054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin methods: &hwc_module_methods, 68054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin dso: 0, 69054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin reserved: {0}, 70054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 71054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}; 72054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 73054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin/* 74054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * Save callback functions registered to HWC 75054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin */ 76054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinstatic void hwc_registerProcs(struct hwc_composer_device_1* dev, 77054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hwc_procs_t const* procs) 78054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin{ 79054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ALOGI("%s", __FUNCTION__); 80054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hwc_context_t* ctx = (hwc_context_t*)(dev); 81054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(!ctx) { 82054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ALOGE("%s: Invalid context", __FUNCTION__); 83054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return; 84054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 85054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->proc = procs; 86054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 87054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin // Now that we have the functions needed, kick off 88054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin // the uevent & vsync threads 89054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin init_uevent_thread(ctx); 90054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin init_vsync_thread(ctx); 91054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 92054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 93054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinstatic void setPaddingRound(hwc_context_t *ctx, int numDisplays, 94054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hwc_display_contents_1_t** displays) { 95054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->isPaddingRound = false; 96054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin for(int i = 0; i < numDisplays; i++) { 97054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hwc_display_contents_1_t *list = displays[i]; 98054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if (LIKELY(list && list->numHwLayers > 0)) { 99054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if((ctx->mPrevHwLayerCount[i] == 1 or 100054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->mPrevHwLayerCount[i] == 0) and 101054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin (list->numHwLayers > 1)) { 102054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin /* If the previous cycle for dpy 'i' has 0 AppLayers and the 103054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * current cycle has atleast 1 AppLayer, padding round needs 104054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * to be invoked in current cycle on all the active displays 105054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * to free up the resources. 106054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin */ 107054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->isPaddingRound = true; 108054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 109054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->mPrevHwLayerCount[i] = (int)list->numHwLayers; 110054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } else { 111054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->mPrevHwLayerCount[i] = 0; 112054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 113054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 114054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 115054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 116054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin/* Based on certain conditions, isDMAStateChanging will be set 117054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * to make this function self-contained */ 118054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinstatic void setDMAState(hwc_context_t *ctx, int numDisplays, 119054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hwc_display_contents_1_t** displays) { 120054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 121054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->isDMAStateChanging = false; 122054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(ctx->mRotMgr->getNumActiveSessions() == 0) 123054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin Overlay::setDMAMode(Overlay::DMA_LINE_MODE); 124054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 125054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin for(int dpy = 0; dpy < numDisplays; dpy++) { 126054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hwc_display_contents_1_t *list = displays[dpy]; 127054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if (LIKELY(list && list->numHwLayers > 0)) { 128054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin for(size_t layerIndex = 0; layerIndex < list->numHwLayers; 129054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin layerIndex++) { 130054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(list->hwLayers[layerIndex].compositionType != 131054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin HWC_FRAMEBUFFER_TARGET) 132054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin { 133054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hwc_layer_1_t const* layer = &list->hwLayers[layerIndex]; 134054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin private_handle_t *hnd = (private_handle_t *)layer->handle; 135054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 136054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin /* If a layer requires rotation, set the DMA state 137054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * to BLOCK_MODE */ 138054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 139054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if (canUseRotator(ctx, dpy) && 140054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin (has90Transform(layer) || getRotDownscale(ctx, layer)) 141054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin && isRotationDoable(ctx, hnd)) { 142054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(not (ctx->mOverlay->isDMAMultiplexingSupported() && 143054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin dpy)) { 144054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(ctx->mOverlay->isPipeTypeAttached( 145054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin overlay::utils::OV_MDP_PIPE_DMA)) 146054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->isDMAStateChanging = true; 147054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 148054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin Overlay::setDMAMode(Overlay::DMA_BLOCK_MODE); 149054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 150054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 151054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 152054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(dpy) { 153054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin /* Uncomment the below code for testing purpose. 154054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin Assuming the orientation value is in terms of HAL_TRANSFORM, 155054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin this needs mapping to HAL, if its in different convention */ 156054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 157054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin /* char value[PROPERTY_VALUE_MAX]; 158054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin property_get("sys.ext_orientation", value, "0"); 159054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->mExtOrientation = atoi(value);*/ 160054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 161054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(ctx->mExtOrientation || ctx->mBufferMirrorMode) { 162054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(ctx->mOverlay->isPipeTypeAttached( 163054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin overlay::utils::OV_MDP_PIPE_DMA)) { 164054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->isDMAStateChanging = true; 165054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 166054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin Overlay::setDMAMode(Overlay::DMA_BLOCK_MODE); 167054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 168054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 169054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 170054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 171054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 172054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 173054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinstatic void setNumActiveDisplays(hwc_context_t *ctx, int numDisplays, 174054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hwc_display_contents_1_t** displays) { 175054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 176054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->numActiveDisplays = 0; 177054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin for(int i = 0; i < numDisplays; i++) { 178054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hwc_display_contents_1_t *list = displays[i]; 179054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if (LIKELY(list && list->numHwLayers > 0)) { 180054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin /* For display devices like SSD and screenrecord, we cannot 181054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * rely on isActive and connected attributes of dpyAttr to 182054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * determine if the displaydevice is active. Hence in case if 183054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * the layer-list is non-null and numHwLayers > 0, we assume 184054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * the display device to be active. 185054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin */ 186054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->numActiveDisplays += 1; 187054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 188054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 189054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 190054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 191054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinstatic bool isHotPluggable(hwc_context_t *ctx, int dpy) { 192054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return ((dpy == HWC_DISPLAY_EXTERNAL) || 193054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ((dpy == HWC_DISPLAY_PRIMARY) && 194054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->mHDMIDisplay->isHDMIPrimaryDisplay())); 195054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 196054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 197054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinstatic void reset(hwc_context_t *ctx, int numDisplays, 198054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hwc_display_contents_1_t** displays) { 199054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 200054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 201054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin for(int i = 0; i < numDisplays; i++) { 202054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hwc_display_contents_1_t *list = displays[i]; 203054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin // XXX:SurfaceFlinger no longer guarantees that this 204054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin // value is reset on every prepare. However, for the layer 205054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin // cache we need to reset it. 206054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin // We can probably rethink that later on 207054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if (LIKELY(list && list->numHwLayers > 0)) { 208054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin for(size_t j = 0; j < list->numHwLayers; j++) { 209054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(list->hwLayers[j].compositionType != HWC_FRAMEBUFFER_TARGET) 210054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin list->hwLayers[j].compositionType = HWC_FRAMEBUFFER; 211054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 212054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 213054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 214054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 215054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(ctx->mMDPComp[i]) 216054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->mMDPComp[i]->reset(); 217054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(ctx->mFBUpdate[i]) 218054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->mFBUpdate[i]->reset(); 219054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(ctx->mCopyBit[i]) 220054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->mCopyBit[i]->reset(); 221054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(ctx->mLayerRotMap[i]) 222054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->mLayerRotMap[i]->reset(); 223054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 224054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 225054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->mAD->reset(); 226054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 227054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 228054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 229054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinstatic void scaleDisplayFrame(hwc_context_t *ctx, int dpy, 230054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hwc_display_contents_1_t *list) { 231054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin uint32_t origXres = ctx->dpyAttr[dpy].xres; 232054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin uint32_t origYres = ctx->dpyAttr[dpy].yres; 233054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin uint32_t newXres = ctx->dpyAttr[dpy].xres_new; 234054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin uint32_t newYres = ctx->dpyAttr[dpy].yres_new; 235054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin float xresRatio = (float)origXres / (float)newXres; 236054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin float yresRatio = (float)origYres / (float)newYres; 237054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin for (size_t i = 0; i < list->numHwLayers; i++) { 238054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hwc_layer_1_t *layer = &list->hwLayers[i]; 239054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hwc_rect_t& displayFrame = layer->displayFrame; 240054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf); 241054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin uint32_t layerWidth = displayFrame.right - displayFrame.left; 242054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin uint32_t layerHeight = displayFrame.bottom - displayFrame.top; 243054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin displayFrame.left = (int)(xresRatio * (float)displayFrame.left); 244054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin displayFrame.top = (int)(yresRatio * (float)displayFrame.top); 245054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin displayFrame.right = (int)((float)displayFrame.left + 246054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin (float)layerWidth * xresRatio); 247054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin displayFrame.bottom = (int)((float)displayFrame.top + 248054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin (float)layerHeight * yresRatio); 249054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 250054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 251054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 252f1812e0b56773537760c9ae8ea45cee5ac902118Steve Pfetschstatic void hwc_configure_color_temp(hwc_composer_device_1* dev) { 253f1812e0b56773537760c9ae8ea45cee5ac902118Steve Pfetsch hwc_context_t* ctx = (hwc_context_t*)(dev); 254f1812e0b56773537760c9ae8ea45cee5ac902118Steve Pfetsch char value[PROPERTY_VALUE_MAX]; 255f1812e0b56773537760c9ae8ea45cee5ac902118Steve Pfetsch bool cool; 256f1812e0b56773537760c9ae8ea45cee5ac902118Steve Pfetsch 257f1812e0b56773537760c9ae8ea45cee5ac902118Steve Pfetsch property_get("persist.sys.debug.color_temp", value, "x"); 258f1812e0b56773537760c9ae8ea45cee5ac902118Steve Pfetsch cool = (value[0] == '1'); 259f1812e0b56773537760c9ae8ea45cee5ac902118Steve Pfetsch 260f1812e0b56773537760c9ae8ea45cee5ac902118Steve Pfetsch if ((value[0] == '0' || value[0] == '1') && 261f1812e0b56773537760c9ae8ea45cee5ac902118Steve Pfetsch cool != ctx->mCoolColorTemperatureEnabled) { 262f1812e0b56773537760c9ae8ea45cee5ac902118Steve Pfetsch ctx->mCoolColorTemperatureEnabled = cool; 263f1812e0b56773537760c9ae8ea45cee5ac902118Steve Pfetsch 264f1812e0b56773537760c9ae8ea45cee5ac902118Steve Pfetsch ALOGI("Color temperature change. Cool = %d", cool ? 1 : 0); 265f1812e0b56773537760c9ae8ea45cee5ac902118Steve Pfetsch 266f1812e0b56773537760c9ae8ea45cee5ac902118Steve Pfetsch int fd = open("/sys/class/graphics/fb0/color_temp", O_WRONLY); 267f1812e0b56773537760c9ae8ea45cee5ac902118Steve Pfetsch if (fd >= 0) { 268f1812e0b56773537760c9ae8ea45cee5ac902118Steve Pfetsch if (cool) 269f1812e0b56773537760c9ae8ea45cee5ac902118Steve Pfetsch write(fd, "1", 2); 270f1812e0b56773537760c9ae8ea45cee5ac902118Steve Pfetsch else 271f1812e0b56773537760c9ae8ea45cee5ac902118Steve Pfetsch write(fd, "0", 2); 272f1812e0b56773537760c9ae8ea45cee5ac902118Steve Pfetsch close(fd); 273f1812e0b56773537760c9ae8ea45cee5ac902118Steve Pfetsch } else { 274f1812e0b56773537760c9ae8ea45cee5ac902118Steve Pfetsch ALOGE("Failed to open color_temp file with result=%d", fd); 275f1812e0b56773537760c9ae8ea45cee5ac902118Steve Pfetsch } 276f1812e0b56773537760c9ae8ea45cee5ac902118Steve Pfetsch } 277f1812e0b56773537760c9ae8ea45cee5ac902118Steve Pfetsch} 278f1812e0b56773537760c9ae8ea45cee5ac902118Steve Pfetsch 279f1812e0b56773537760c9ae8ea45cee5ac902118Steve Pfetsch 280054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinstatic int hwc_prepare_primary(hwc_composer_device_1 *dev, 281054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hwc_display_contents_1_t *list) { 282054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ATRACE_CALL(); 283054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hwc_context_t* ctx = (hwc_context_t*)(dev); 284054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin const int dpy = HWC_DISPLAY_PRIMARY; 285054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin bool fbComp = false; 286831babe5975a052c87de04db7a6acf006b031380Naseer Ahmed if (!ctx->mDefaultModeApplied) 287831babe5975a052c87de04db7a6acf006b031380Naseer Ahmed applyDefaultMode(ctx); 288054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if (LIKELY(list && list->numHwLayers > 1) && ctx->dpyAttr[dpy].connected && 289054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin (ctx->dpyAttr[dpy].isActive || 290054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->mHDMIDisplay->isHDMIPrimaryDisplay()) 291054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin && !ctx->dpyAttr[dpy].isPause) { 292054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 293054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin // When HDMI is primary we should rely on the first valid 294054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin // draw call in order to activate the display 295054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if (!ctx->dpyAttr[dpy].isActive) { 296054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin // If the cable is connected after HWC initialization and before 297054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin // the UEvent thread is initialized then we will miss the ONLINE 298054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin // event. We need to update the display appropriately when we get 299054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin // the first valid frame. 300054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin int cableConnected = ctx->mHDMIDisplay->getConnectedState(); 301054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if ((cableConnected == 1) && !ctx->dpyAttr[dpy].connected) { 302054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin qhwc::handle_online(ctx, dpy); 303054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 304054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->mHDMIDisplay->activateDisplay(); 305054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->dpyAttr[dpy].isActive = true; 306054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 307054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 308054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if (ctx->dpyAttr[dpy].customFBSize && 309054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin list->flags & HWC_GEOMETRY_CHANGED) 310054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin scaleDisplayFrame(ctx, dpy, list); 311054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 312054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin reset_layer_prop(ctx, dpy, (int)list->numHwLayers - 1); 313054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin setListStats(ctx, list, dpy); 314054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 315054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin fbComp = (ctx->mMDPComp[dpy]->prepare(ctx, list) < 0); 316054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 317054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if (fbComp) { 318054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin const int fbZ = 0; 319054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(not ctx->mFBUpdate[dpy]->prepareAndValidate(ctx, list, fbZ)) { 320054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->mOverlay->clear(dpy); 321054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->mLayerRotMap[dpy]->clear(); 322054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 323054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 324054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 325054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if (ctx->mMDP.version < qdutils::MDP_V4_0) { 326054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(ctx->mCopyBit[dpy]) 327054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->mCopyBit[dpy]->prepare(ctx, list, dpy); 328054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 329054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin setGPUHint(ctx, list); 330054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 331054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return 0; 332054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 333054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 334054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinstatic int hwc_prepare_external(hwc_composer_device_1 *dev, 335054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hwc_display_contents_1_t *list) { 336054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ATRACE_CALL(); 337054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hwc_context_t* ctx = (hwc_context_t*)(dev); 338054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin const int dpy = HWC_DISPLAY_EXTERNAL; 339054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 340054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if (LIKELY(list && list->numHwLayers > 1) && 341054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->dpyAttr[dpy].isActive && 342054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->dpyAttr[dpy].connected) { 343054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin reset_layer_prop(ctx, dpy, (int)list->numHwLayers - 1); 344054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(!ctx->dpyAttr[dpy].isPause) { 345054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->dpyAttr[dpy].isConfiguring = false; 346054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin setListStats(ctx, list, dpy); 347054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(ctx->mMDPComp[dpy]->prepare(ctx, list) < 0) { 348054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin const int fbZ = 0; 349054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(not ctx->mFBUpdate[dpy]->prepareAndValidate(ctx, list, fbZ)) 350054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin { 351054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->mOverlay->clear(dpy); 352054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->mLayerRotMap[dpy]->clear(); 353054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 354054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 355054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } else { 356054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin /* External Display is in Pause state. 357054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * Mark all application layers as OVERLAY so that 358054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * GPU will not compose. 359054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin */ 360054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin for(size_t i = 0 ;i < (size_t)(list->numHwLayers - 1); i++) { 361054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hwc_layer_1_t *layer = &list->hwLayers[i]; 362054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin layer->compositionType = HWC_OVERLAY; 363054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 364054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 365054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 366054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return 0; 367054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 368054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 369054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinstatic int hwc_prepare(hwc_composer_device_1 *dev, size_t numDisplays, 370054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hwc_display_contents_1_t** displays) 371054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin{ 372054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin int ret = 0; 373054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hwc_context_t* ctx = (hwc_context_t*)(dev); 374054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 375054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if (ctx->mPanelResetStatus) { 376054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ALOGW("%s: panel is in bad state. reset the panel", __FUNCTION__); 377054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin reset_panel(dev); 378054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 379054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 380054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin //Will be unlocked at the end of set 381054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->mDrawLock.lock(); 382054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin setPaddingRound(ctx, (int)numDisplays, displays); 383054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin setDMAState(ctx, (int)numDisplays, displays); 384054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin setNumActiveDisplays(ctx, (int)numDisplays, displays); 385054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin reset(ctx, (int)numDisplays, displays); 386054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 387054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->mOverlay->configBegin(); 388054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->mRotMgr->configBegin(); 389054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin overlay::Writeback::configBegin(); 390054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 391054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin for (int32_t dpy = ((int32_t)numDisplays-1); dpy >=0 ; dpy--) { 392054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hwc_display_contents_1_t *list = displays[dpy]; 393054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin resetROI(ctx, dpy); 394054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin switch(dpy) { 395054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin case HWC_DISPLAY_PRIMARY: 396054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ret = hwc_prepare_primary(dev, list); 397054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin break; 398054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin case HWC_DISPLAY_EXTERNAL: 399054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ret = hwc_prepare_external(dev, list); 400054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin break; 401054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin case HWC_DISPLAY_VIRTUAL: 402054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(ctx->mHWCVirtual) 403054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ret = ctx->mHWCVirtual->prepare(dev, list); 404054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin break; 405054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin default: 406054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ret = -EINVAL; 407054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 408054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 409054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 410054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->mOverlay->configDone(); 411054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->mRotMgr->configDone(); 412054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin overlay::Writeback::configDone(); 413054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin // If VD list is deleted, mdp overlay pipe objects and writeback object 414054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin // are deleted as part of configDone functions. 415054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin // Proceed with HWCVirtualVDS object deletion. 416054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(ctx->mHWCVirtual) 417054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->mHWCVirtual->destroy(ctx, numDisplays, displays); 418054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 419054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return ret; 420054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 421054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 422054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinstatic int hwc_eventControl(struct hwc_composer_device_1* dev, int dpy, 423054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin int event, int enable) 424054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin{ 425054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ATRACE_CALL(); 426054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin int ret = 0; 427054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hwc_context_t* ctx = (hwc_context_t*)(dev); 428054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin switch(event) { 429054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin case HWC_EVENT_VSYNC: 430054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if (ctx->vstate.enable == enable) 431054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin break; 432054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ret = hwc_vsync_control(ctx, dpy, enable); 433054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(ret == 0) 434054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->vstate.enable = !!enable; 435054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ALOGD_IF (VSYNC_DEBUG, "VSYNC state changed to %s", 436054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin (enable)?"ENABLED":"DISABLED"); 437054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin break; 438054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#ifdef QCOM_BSP 439054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin case HWC_EVENT_ORIENTATION: 440054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(dpy == HWC_DISPLAY_PRIMARY) { 441054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin Locker::Autolock _l(ctx->mDrawLock); 442054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin // store the primary display orientation 443054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->deviceOrientation = enable; 444054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 445054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin break; 446054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#endif 447054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin default: 448054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ret = -EINVAL; 449054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 450054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return ret; 451054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 452054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 453054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinstatic int hwc_setPowerMode(struct hwc_composer_device_1* dev, int dpy, 454054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin int mode) 455054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin{ 456054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ATRACE_CALL(); 457054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hwc_context_t* ctx = (hwc_context_t*)(dev); 458054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin int ret = 0, value = 0; 459054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 460054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin Locker::Autolock _l(ctx->mDrawLock); 461054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ALOGD_IF(POWER_MODE_DEBUG, "%s: Setting mode %d on display: %d", 462054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin __FUNCTION__, mode, dpy); 463054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 464054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin switch(mode) { 465054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin case HWC_POWER_MODE_OFF: 466054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin // free up all the overlay pipes in use 467054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin // when we get a blank for either display 468054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin // makes sure that all pipes are freed 469054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->mOverlay->configBegin(); 470054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->mOverlay->configDone(); 471054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->mRotMgr->clear(); 472054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin // If VDS is connected, do not clear WB object as it 473054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin // will end up detaching IOMMU. This is required 474054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin // to send black frame to WFD sink on power suspend. 475054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin // Note: With this change, we keep the WriteBack object 476054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin // alive on power suspend for AD use case. 477054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin value = FB_BLANK_POWERDOWN; 478054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin break; 479054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin case HWC_POWER_MODE_DOZE: 480054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin case HWC_POWER_MODE_DOZE_SUSPEND: 481054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin value = FB_BLANK_VSYNC_SUSPEND; 482054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin break; 483054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin case HWC_POWER_MODE_NORMAL: 484054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin value = FB_BLANK_UNBLANK; 485054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin break; 486054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 487054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 488054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin switch(dpy) { 489054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin case HWC_DISPLAY_PRIMARY: 490054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(ctx->mHDMIDisplay->isHDMIPrimaryDisplay()) { 491054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(ctx->dpyAttr[dpy].connected) { 492054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin // When HDMI is connected as primary we clean up resources 493054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin // and call commit to generate a black frame on the interface. 494054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin // However, we do not call blank since we need the timing 495054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin // generator and HDMI core to remain turned on. 496054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if((mode == HWC_POWER_MODE_OFF) && 497054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin (!Overlay::displayCommit(ctx->dpyAttr[dpy].fd))) { 498054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ALOGE("%s: display commit fail for %d", __FUNCTION__, dpy); 499054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ret = -1; 500054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 501054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 502054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } else { 503054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(ioctl(ctx->dpyAttr[dpy].fd, FBIOBLANK, value) < 0 ) { 504054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ALOGE("%s: ioctl FBIOBLANK failed for Primary with error %s" 505054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin " value %d", __FUNCTION__, strerror(errno), value); 506054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return -errno; 507054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 508054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 509054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(mode == HWC_POWER_MODE_NORMAL && !ctx->mHPDEnabled) { 510054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin // Enable HPD here, as during bootup POWER_MODE_NORMAL is set 511054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin // when SF is completely initialized 512054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->mHDMIDisplay->setHPD(1); 513054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->mHPDEnabled = true; 514054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 515054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 516054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->dpyAttr[dpy].isActive = not(mode == HWC_POWER_MODE_OFF); 517054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 518054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin //Deliberate fall through since there is no explicit power mode for 519054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin //virtual displays. 520054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin case HWC_DISPLAY_VIRTUAL: 521054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected) { 522054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin const int dpy = HWC_DISPLAY_VIRTUAL; 523054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(mode == HWC_POWER_MODE_OFF and 524054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin (not ctx->dpyAttr[dpy].isPause)) { 525054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) { 526054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ALOGE("%s: displayCommit failed for virtual", __FUNCTION__); 527054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ret = -1; 528054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 529054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 530054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->dpyAttr[dpy].isActive = not(mode == HWC_POWER_MODE_OFF); 531054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 532054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin break; 533054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin case HWC_DISPLAY_EXTERNAL: 534054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(mode == HWC_POWER_MODE_OFF) { 535054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) { 536054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ALOGE("%s: displayCommit failed for external", __FUNCTION__); 537054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ret = -1; 538054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 539054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 540054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->dpyAttr[dpy].isActive = not(mode == HWC_POWER_MODE_OFF); 541054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin break; 542054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin default: 543054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return -EINVAL; 544054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 545054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 546f1812e0b56773537760c9ae8ea45cee5ac902118Steve Pfetsch // Configure the color temperature 547f1812e0b56773537760c9ae8ea45cee5ac902118Steve Pfetsch hwc_configure_color_temp(dev); 548f1812e0b56773537760c9ae8ea45cee5ac902118Steve Pfetsch 549054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ALOGD_IF(POWER_MODE_DEBUG, "%s: Done setting mode %d on display %d", 550054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin __FUNCTION__, mode, dpy); 551054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return ret; 552054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 553054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 554054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinstatic void reset_panel(struct hwc_composer_device_1* dev) 555054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin{ 556054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin int ret = 0; 557054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hwc_context_t* ctx = (hwc_context_t*)(dev); 558054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 559054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if (!ctx->dpyAttr[HWC_DISPLAY_PRIMARY].isActive) { 560054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ALOGD ("%s : Display OFF - Skip BLANK & UNBLANK", __FUNCTION__); 561054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->mPanelResetStatus = false; 562054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return; 563054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 564054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 565054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ALOGD("%s: setting power mode off", __FUNCTION__); 566054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ret = hwc_setPowerMode(dev, HWC_DISPLAY_PRIMARY, HWC_POWER_MODE_OFF); 567054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if (ret < 0) { 568054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ALOGE("%s: FBIOBLANK failed to BLANK: %s", __FUNCTION__, 569054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin strerror(errno)); 570054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 571054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 572054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ALOGD("%s: setting power mode normal and enabling vsync", __FUNCTION__); 573054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ret = hwc_setPowerMode(dev, HWC_DISPLAY_PRIMARY, HWC_POWER_MODE_NORMAL); 574054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if (ret < 0) { 575054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ALOGE("%s: FBIOBLANK failed to UNBLANK : %s", __FUNCTION__, 576054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin strerror(errno)); 577054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 578054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hwc_vsync_control(ctx, HWC_DISPLAY_PRIMARY, 1); 579054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 580054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->mPanelResetStatus = false; 581054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 582054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 583054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 584054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinstatic int hwc_query(struct hwc_composer_device_1* dev, 585054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin int param, int* value) 586054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin{ 587054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hwc_context_t* ctx = (hwc_context_t*)(dev); 588054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin int supported = HWC_DISPLAY_PRIMARY_BIT; 589054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 590054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin switch (param) { 591054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin case HWC_BACKGROUND_LAYER_SUPPORTED: 592054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin // Not supported for now 593054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin value[0] = 0; 594054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin break; 595054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin case HWC_DISPLAY_TYPES_SUPPORTED: 596054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(ctx->mMDP.hasOverlay) { 597054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin supported |= HWC_DISPLAY_VIRTUAL_BIT; 598054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(!(qdutils::MDPVersion::getInstance().is8x26() || 599054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin qdutils::MDPVersion::getInstance().is8x16() || 600054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin qdutils::MDPVersion::getInstance().is8x39())) 601054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin supported |= HWC_DISPLAY_EXTERNAL_BIT; 602054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 603054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin value[0] = supported; 604054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin break; 605054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin case HWC_FORMAT_RB_SWAP: 606054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin value[0] = 1; 607054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin break; 608054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin case HWC_COLOR_FILL: 609054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin value[0] = 1; 610054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin break; 611054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin default: 612054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return -EINVAL; 613054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 614054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return 0; 615054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 616054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 617054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 618054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 619054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinstatic int hwc_set_primary(hwc_context_t *ctx, hwc_display_contents_1_t* list) { 620054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ATRACE_CALL(); 621054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin int ret = 0; 622054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin const int dpy = HWC_DISPLAY_PRIMARY; 623054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if (LIKELY(list) && ctx->dpyAttr[dpy].isActive 624054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin && !ctx->dpyAttr[dpy].isPause) { 625054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin size_t last = list->numHwLayers - 1; 626054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hwc_layer_1_t *fbLayer = &list->hwLayers[last]; 627054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin int fd = -1; //FenceFD from the Copybit(valid in async mode) 628054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin bool copybitDone = false; 629054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 630054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if (ctx->mCopyBit[dpy]) { 631054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if (ctx->mMDP.version < qdutils::MDP_V4_0) 632054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd); 633054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin else 634054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin fd = ctx->mMDPComp[dpy]->drawOverlap(ctx, list); 635054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 636054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 637054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(list->numHwLayers > 1) 638054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hwc_sync(ctx, list, dpy, fd); 639054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 640054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin // Dump the layers for primary 641054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(ctx->mHwcDebug[dpy]) 642054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->mHwcDebug[dpy]->dumpLayers(list); 643054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 644054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if (!ctx->mMDPComp[dpy]->draw(ctx, list)) { 645054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ALOGE("%s: MDPComp draw failed", __FUNCTION__); 646054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ret = -1; 647054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 648054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 649054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin //TODO We dont check for SKIP flag on this layer because we need PAN 650054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin //always. Last layer is always FB 651054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin private_handle_t *hnd = (private_handle_t *)fbLayer->handle; 652054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(copybitDone && ctx->mMDP.version >= qdutils::MDP_V4_0) { 653054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer(); 654054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 655054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 656054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(isAbcInUse(ctx) == true) { 657054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin int index = ctx->listStats[dpy].renderBufIndexforABC; 658054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hwc_layer_1_t *tempLayer = &list->hwLayers[index]; 659054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hnd = (private_handle_t *)tempLayer->handle; 660054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 661054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 662054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(hnd) { 663054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) { 664054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ALOGE("%s: FBUpdate draw failed", __FUNCTION__); 665054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ret = -1; 666054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 667054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 668054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 66907bb927c66c474b9f0aff9677f848d3d8d543b8fArun Kumar K.R /* When source split is enabled, right ROI will always be NULL since the 67007bb927c66c474b9f0aff9677f848d3d8d543b8fArun Kumar K.R * ROI for the whole panel generated in a single coordinate system will 67107bb927c66c474b9f0aff9677f848d3d8d543b8fArun Kumar K.R * be populuated in left ROI. So leave the right ROI untouched */ 672298391fb24e1303c50b9d4172efe2bb9940114faArun Kumar K.R int lSplit = qdutils::MDPVersion::getInstance().isSrcSplit() ? 0 : 673298391fb24e1303c50b9d4172efe2bb9940114faArun Kumar K.R (isDisplaySplit(ctx, dpy) ? getLeftSplit(ctx, dpy) : 0); 674054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin qhwc::ovutils::Dim lRoi = qhwc::ovutils::Dim( 675054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->listStats[dpy].lRoi.left, 676054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->listStats[dpy].lRoi.top, 677054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->listStats[dpy].lRoi.right - ctx->listStats[dpy].lRoi.left, 678054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->listStats[dpy].lRoi.bottom - ctx->listStats[dpy].lRoi.top); 679054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 680054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin qhwc::ovutils::Dim rRoi = qhwc::ovutils::Dim( 681054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->listStats[dpy].rRoi.left - lSplit, 682054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->listStats[dpy].rRoi.top, 683054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->listStats[dpy].rRoi.right - ctx->listStats[dpy].rRoi.left, 684054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->listStats[dpy].rRoi.bottom - ctx->listStats[dpy].rRoi.top); 685054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 686054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd, lRoi, rRoi)) { 687054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ALOGE("%s: display commit fail for %d dpy!", __FUNCTION__, dpy); 688054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ret = -1; 689054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 690054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 691054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 692054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 693054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin closeAcquireFds(list); 694054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return ret; 695054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 696054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 697054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinstatic int hwc_set_external(hwc_context_t *ctx, 698054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hwc_display_contents_1_t* list) 699054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin{ 700054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ATRACE_CALL(); 701054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin int ret = 0; 702054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 703054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin const int dpy = HWC_DISPLAY_EXTERNAL; 704054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 705054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 706054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if (LIKELY(list) && ctx->dpyAttr[dpy].isActive && 707054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->dpyAttr[dpy].connected && 708054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin !ctx->dpyAttr[dpy].isPause) { 709054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin size_t last = list->numHwLayers - 1; 710054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hwc_layer_1_t *fbLayer = &list->hwLayers[last]; 711054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin int fd = -1; //FenceFD from the Copybit(valid in async mode) 712054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin bool copybitDone = false; 713054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(ctx->mCopyBit[dpy]) 714054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd); 715054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 716054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(list->numHwLayers > 1) 717054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hwc_sync(ctx, list, dpy, fd); 718054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 719054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin // Dump the layers for external 720054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(ctx->mHwcDebug[dpy]) 721054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->mHwcDebug[dpy]->dumpLayers(list); 722054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 723054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if (!ctx->mMDPComp[dpy]->draw(ctx, list)) { 724054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ALOGE("%s: MDPComp draw failed", __FUNCTION__); 725054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ret = -1; 726054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 727054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 728054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin private_handle_t *hnd = (private_handle_t *)fbLayer->handle; 729054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(copybitDone) { 730054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer(); 731054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 732054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 733054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(hnd) { 734054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) { 735054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__); 736054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ret = -1; 737054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 738054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 739054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 740054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) { 741054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ALOGE("%s: display commit fail for %d dpy!", __FUNCTION__, dpy); 742054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ret = -1; 743054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 744054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 745054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 746054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin closeAcquireFds(list); 747054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return ret; 748054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 749054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 750054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinstatic int hwc_set(hwc_composer_device_1 *dev, 751054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin size_t numDisplays, 752054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hwc_display_contents_1_t** displays) 753054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin{ 754054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin int ret = 0; 755054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hwc_context_t* ctx = (hwc_context_t*)(dev); 756054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin for (int dpy = 0; dpy < (int)numDisplays; dpy++) { 757054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hwc_display_contents_1_t* list = displays[dpy]; 758054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin switch(dpy) { 759054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin case HWC_DISPLAY_PRIMARY: 760054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ret = hwc_set_primary(ctx, list); 761054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin break; 762054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin case HWC_DISPLAY_EXTERNAL: 763054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ret = hwc_set_external(ctx, list); 764054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin break; 765054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin case HWC_DISPLAY_VIRTUAL: 766054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(ctx->mHWCVirtual) 767054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ret = ctx->mHWCVirtual->set(ctx, list); 768054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin break; 769054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin default: 770054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ret = -EINVAL; 771054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 772054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 773054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin // This is only indicative of how many times SurfaceFlinger posts 774054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin // frames to the display. 775054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin CALC_FPS(); 776054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin MDPComp::resetIdleFallBack(); 777054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->mVideoTransFlag = false; 778054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin //Was locked at the beginning of prepare 779054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->mDrawLock.unlock(); 780054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return ret; 781054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 782054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 783054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinint hwc_getDisplayConfigs(struct hwc_composer_device_1* dev, int disp, 784054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin uint32_t* configs, size_t* numConfigs) { 785054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hwc_context_t* ctx = (hwc_context_t*)(dev); 786054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 787054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin Locker::Autolock _l(ctx->mDrawLock); 788054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin bool hotPluggable = isHotPluggable(ctx, disp); 789054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin bool isVirtualDisplay = (disp == HWC_DISPLAY_VIRTUAL); 790054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin // If hotpluggable or virtual displays are inactive return error 791054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if ((hotPluggable || isVirtualDisplay) && !ctx->dpyAttr[disp].connected) { 792054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ALOGE("%s display (%d) is inactive", __FUNCTION__, disp); 793054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return -EINVAL; 794054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 795054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 796054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if (*numConfigs <= 0) { 797054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ALOGE("%s Invalid number of configs (%d)", __FUNCTION__, *numConfigs); 798054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return -EINVAL; 799054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 800054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 801054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin switch(disp) { 802054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin case HWC_DISPLAY_PRIMARY: 803054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if (hotPluggable) { 804054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->mHDMIDisplay->getDisplayConfigs(configs, numConfigs); 805054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } else { 8066109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed if(ctx->mColorMode->getNumModes() > 0) { 8076109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed *numConfigs = ctx->mColorMode->getNumModes(); 8086109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed for (size_t i = 0; i < *numConfigs; i++) 8096109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed configs[i] = (uint32_t) i; 8106109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed 8116109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed } else { 8126109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed configs[0] = 0; 8136109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed *numConfigs = 1; 8146109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed } 815054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 816054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin break; 817054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin case HWC_DISPLAY_EXTERNAL: 818054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->mHDMIDisplay->getDisplayConfigs(configs, numConfigs); 819054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin break; 820054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin case HWC_DISPLAY_VIRTUAL: 821054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin configs[0] = 0; 822054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin *numConfigs = 1; 823054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin break; 824054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 825054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return 0; 826054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 827054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 828054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinint hwc_getDisplayAttributes(struct hwc_composer_device_1* dev, int disp, 829054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin uint32_t config, const uint32_t* attributes, int32_t* values) { 830054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 831054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hwc_context_t* ctx = (hwc_context_t*)(dev); 832054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 833054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin Locker::Autolock _l(ctx->mDrawLock); 834054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin bool hotPluggable = isHotPluggable(ctx, disp); 835054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin bool isVirtualDisplay = (disp == HWC_DISPLAY_VIRTUAL); 836054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin // If hotpluggable or virtual displays are inactive return error 837054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if ((hotPluggable || isVirtualDisplay) && !ctx->dpyAttr[disp].connected) { 838054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ALOGE("%s display (%d) is inactive", __FUNCTION__, disp); 839054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return -EINVAL; 840054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 841054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 842054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin uint32_t xres = 0, yres = 0, refresh = 0; 843054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin int ret = 0; 844054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if (hotPluggable) { 845054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ret = ctx->mHDMIDisplay->getAttrForConfig(config, xres, yres, refresh); 846054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(ret < 0) { 847054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ALOGE("%s Error getting attributes for config %d", 848054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin __FUNCTION__, config); 849054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return ret; 850054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 851054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 852054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 8536109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed for (size_t i = 0; attributes[i] != HWC_DISPLAY_NO_ATTRIBUTE; i++) { 854054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin switch (attributes[i]) { 855054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin case HWC_DISPLAY_VSYNC_PERIOD: 856054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin values[i] = 857054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hotPluggable ? refresh : ctx->dpyAttr[disp].vsync_period; 858054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin break; 859054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin case HWC_DISPLAY_WIDTH: 860054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if (ctx->dpyAttr[disp].customFBSize) 861054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin values[i] = ctx->dpyAttr[disp].xres_new; 862054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin else 863054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin values[i] = hotPluggable ? xres : ctx->dpyAttr[disp].xres; 864054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 865054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ALOGD("%s disp = %d, width = %d",__FUNCTION__, disp, 866054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin values[i]); 867054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin break; 868054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin case HWC_DISPLAY_HEIGHT: 869054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if (ctx->dpyAttr[disp].customFBSize) 870054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin values[i] = ctx->dpyAttr[disp].yres_new; 871054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin else 872054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin values[i] = hotPluggable ? yres : ctx->dpyAttr[disp].yres; 873054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ALOGD("%s disp = %d, height = %d",__FUNCTION__, disp, 874054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin values[i]); 875054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin break; 876054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin case HWC_DISPLAY_DPI_X: 877054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin values[i] = (int32_t) (ctx->dpyAttr[disp].xdpi*1000.0); 878054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin break; 879054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin case HWC_DISPLAY_DPI_Y: 880054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin values[i] = (int32_t) (ctx->dpyAttr[disp].ydpi*1000.0); 881054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin break; 8826109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed case HWC_DISPLAY_COLOR_TRANSFORM: 8836109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed values[i] = ctx->mColorMode->getModeForIndex(config); 884054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin break; 885054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin default: 886054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ALOGE("Unknown display attribute %d", 887054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin attributes[i]); 888054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return -EINVAL; 889054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 890054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 891054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return 0; 892054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 893054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 894054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid hwc_dump(struct hwc_composer_device_1* dev, char *buff, int buff_len) 895054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin{ 896054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hwc_context_t* ctx = (hwc_context_t*)(dev); 897054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin Locker::Autolock _l(ctx->mDrawLock); 898054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin android::String8 aBuf(""); 899054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin dumpsys_log(aBuf, "Qualcomm HWC state:\n"); 900054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin dumpsys_log(aBuf, " MDPVersion=%d\n", ctx->mMDP.version); 901054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin dumpsys_log(aBuf, " DisplayPanel=%c\n", ctx->mMDP.panel); 902054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin dumpsys_log(aBuf, " DynRefreshRate=%d\n", 903054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->dpyAttr[HWC_DISPLAY_PRIMARY].dynRefreshRate); 904054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin for(int dpy = 0; dpy < HWC_NUM_DISPLAY_TYPES; dpy++) { 905054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(ctx->mMDPComp[dpy]) 906054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->mMDPComp[dpy]->dump(aBuf, ctx); 907054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 908054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin char ovDump[2048] = {'\0'}; 909054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->mOverlay->getDump(ovDump, 2048); 910054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin dumpsys_log(aBuf, ovDump); 911054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ovDump[0] = '\0'; 912054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ctx->mRotMgr->getDump(ovDump, 1024); 913054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin dumpsys_log(aBuf, ovDump); 914054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ovDump[0] = '\0'; 915054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(Writeback::getDump(ovDump, 1024)) { 916054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin dumpsys_log(aBuf, ovDump); 917054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ovDump[0] = '\0'; 918054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 919054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin strlcpy(buff, aBuf.string(), buff_len); 920054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 921054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 922054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinint hwc_getActiveConfig(struct hwc_composer_device_1* dev, int disp) 923054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin{ 924054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hwc_context_t* ctx = (hwc_context_t*)(dev); 925054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 926054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin Locker::Autolock _l(ctx->mDrawLock); 927054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin bool hotPluggable = isHotPluggable(ctx, disp); 928054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin bool isVirtualDisplay = (disp == HWC_DISPLAY_VIRTUAL); 929054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin // If hotpluggable or virtual displays are inactive return error 930054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if ((hotPluggable || isVirtualDisplay) && !ctx->dpyAttr[disp].connected) { 931054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ALOGE("%s display (%d) is inactive", __FUNCTION__, disp); 932054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return -EINVAL; 933054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 934054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 935054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin // For use cases when primary panel is the default interface we only have 936054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin // the default config (0th index) 9373bbf145177e8bccb8cf5f817dfd7751a712cfdfaNaseer Ahmed if (!hotPluggable && disp == HWC_DISPLAY_PRIMARY) { 9386109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed return ctx->mColorMode->getActiveModeIndex(); 9396109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed } else if (isVirtualDisplay) { 940054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return 0; 941054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 942054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 943054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return ctx->mHDMIDisplay->getActiveConfig(); 944054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 945054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 946054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinint hwc_setActiveConfig(struct hwc_composer_device_1* dev, int disp, int index) 947054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin{ 948054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin hwc_context_t* ctx = (hwc_context_t*)(dev); 949054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 950054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin Locker::Autolock _l(ctx->mDrawLock); 951054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin bool hotPluggable = isHotPluggable(ctx, disp); 952054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin bool isVirtualDisplay = (disp == HWC_DISPLAY_VIRTUAL); 953054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin // If hotpluggable or virtual displays are inactive return error 954054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if ((hotPluggable || isVirtualDisplay) && !ctx->dpyAttr[disp].connected) { 955054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ALOGE("%s display (%d) is inactive", __FUNCTION__, disp); 956054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return -EINVAL; 957054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 958054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 9596109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed // For use cases when primary panel is the default interface we only switch 9606109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed // color modes 9616109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed if(!hotPluggable && disp == HWC_DISPLAY_PRIMARY) { 9626109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed return ctx->mColorMode->applyModeByIndex(index); 9636109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed } else if (isVirtualDisplay) { 9646109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed // virtual supports only the default config (0th index) 965054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return (index == 0) ? index : -EINVAL; 966054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 967054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 968054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return ctx->mHDMIDisplay->setActiveConfig(index); 969054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 970054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 971054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinstatic int hwc_device_close(struct hw_device_t *dev) 972054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin{ 973054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(!dev) { 974054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ALOGE("%s: NULL device pointer", __FUNCTION__); 975054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return -1; 976054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 977054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin closeContext((hwc_context_t*)dev); 978054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin free(dev); 979054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 980054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return 0; 981054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 982054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 983054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinstatic int hwc_device_open(const struct hw_module_t* module, const char* name, 984054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin struct hw_device_t** device) 985054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin{ 986054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin int status = -EINVAL; 987054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 988054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if (!strcmp(name, HWC_HARDWARE_COMPOSER)) { 989054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin struct hwc_context_t *dev; 990054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin dev = (hwc_context_t*)malloc(sizeof(*dev)); 991054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(dev == NULL) 992054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return status; 993054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin memset(dev, 0, sizeof(*dev)); 994054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 995054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin //Initialize hwc context 996054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin initContext(dev); 997054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 998054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin //Setup HWC methods 999054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin dev->device.common.tag = HARDWARE_DEVICE_TAG; 100072aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R dev->device.common.version = HWC_DEVICE_API_VERSION_1_5; 1001054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin dev->device.common.module = const_cast<hw_module_t*>(module); 1002054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin dev->device.common.close = hwc_device_close; 1003054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin dev->device.prepare = hwc_prepare; 1004054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin dev->device.set = hwc_set; 1005054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin dev->device.eventControl = hwc_eventControl; 1006054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin dev->device.setPowerMode = hwc_setPowerMode; 1007054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin dev->device.query = hwc_query; 1008054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin dev->device.registerProcs = hwc_registerProcs; 1009054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin dev->device.dump = hwc_dump; 1010054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin dev->device.getDisplayConfigs = hwc_getDisplayConfigs; 1011054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin dev->device.getDisplayAttributes = hwc_getDisplayAttributes; 1012054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin dev->device.getActiveConfig = hwc_getActiveConfig; 1013054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin dev->device.setActiveConfig = hwc_setActiveConfig; 1014054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin *device = &dev->device.common; 1015054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin status = 0; 1016054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 1017054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return status; 1018054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 1019