hwc.cpp revision ced6b79c3e1b60b05e2e054e709b1f9a2b6b304c
1ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson/* 2ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * Copyright (C) 2010 The Android Open Source Project 3a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved. 4ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * 5ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * Not a Contribution, Apache license notifications and license are retained 6ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * for attribution purposes only. 7ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * 8ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * Licensed under the Apache License, Version 2.0 (the "License"); 9ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * you may not use this file except in compliance with the License. 10ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * You may obtain a copy of the License at 11ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * 12ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * http://www.apache.org/licenses/LICENSE-2.0 13ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * 14ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * Unless required by applicable law or agreed to in writing, software 15ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * distributed under the License is distributed on an "AS IS" BASIS, 16ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * See the License for the specific language governing permissions and 18ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * limitations under the License. 19ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson */ 20ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL) 21ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include <fcntl.h> 22ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include <errno.h> 23ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 24ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include <cutils/log.h> 25ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include <cutils/atomic.h> 26ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include <EGL/egl.h> 27ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include <utils/Trace.h> 28ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include <sys/ioctl.h> 29ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include <overlay.h> 30ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include <overlayRotator.h> 31ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include <overlayWriteback.h> 32ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include <mdp_version.h> 33ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include "hwc_utils.h" 34ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include "hwc_fbupdate.h" 35ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include "hwc_mdpcomp.h" 36a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson#include "hwc_dump_layers.h" 37ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include "external.h" 38ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include "hwc_copybit.h" 39ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include "hwc_ad.h" 40ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include "profiler.h" 41a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson#include "hwc_virtual.h" 42ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 43ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonusing namespace qhwc; 44ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonusing namespace overlay; 45ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 46ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#define VSYNC_DEBUG 0 47ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#define BLANK_DEBUG 1 48ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 49ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_device_open(const struct hw_module_t* module, 50ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson const char* name, 51ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson struct hw_device_t** device); 52ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 53ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic struct hw_module_methods_t hwc_module_methods = { 54ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson open: hwc_device_open 55ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}; 56ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 57a653efede03423aa840da24634f1ec6f20796f1eSimon Wilsonstatic void reset_panel(struct hwc_composer_device_1* dev); 58a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 59ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonhwc_module_t HAL_MODULE_INFO_SYM = { 60ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson common: { 61ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson tag: HARDWARE_MODULE_TAG, 62ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson version_major: 2, 63ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson version_minor: 0, 64ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson id: HWC_HARDWARE_MODULE_ID, 65ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson name: "Qualcomm Hardware Composer Module", 66ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson author: "CodeAurora Forum", 67ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson methods: &hwc_module_methods, 68ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson dso: 0, 69ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson reserved: {0}, 70ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 71ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}; 72ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 73a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson/* In case of non-hybrid WFD session, we are fooling SF by piggybacking on 74a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson * HDMI display ID for virtual. This helper is needed to differentiate their 75a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson * paths in HAL. 76a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson * TODO: Not needed once we have WFD client working on top of Google API's */ 77a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 78a653efede03423aa840da24634f1ec6f20796f1eSimon Wilsonstatic int getDpyforExternalDisplay(hwc_context_t *ctx, int dpy) { 79a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(dpy == HWC_DISPLAY_EXTERNAL && ctx->mVirtualonExtActive) 80a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson return HWC_DISPLAY_VIRTUAL; 81a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson return dpy; 82a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson} 83a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 84ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson/* 85ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * Save callback functions registered to HWC 86ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson */ 87ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic void hwc_registerProcs(struct hwc_composer_device_1* dev, 88ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hwc_procs_t const* procs) 89ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{ 90ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ALOGI("%s", __FUNCTION__); 91ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hwc_context_t* ctx = (hwc_context_t*)(dev); 92ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if(!ctx) { 93ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ALOGE("%s: Invalid context", __FUNCTION__); 94ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return; 95ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 96ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->proc = procs; 97ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 98ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson // Now that we have the functions needed, kick off 99ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson // the uevent & vsync threads 100ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson init_uevent_thread(ctx); 101ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson init_vsync_thread(ctx); 102ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 103ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 104ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson//Helper 105ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic void reset(hwc_context_t *ctx, int numDisplays, 106ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hwc_display_contents_1_t** displays) { 107a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 108a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ctx->numActiveDisplays = 0; 109a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ctx->isPaddingRound = false; 110a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 111a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson for(int i = 0; i < numDisplays; i++) { 112ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hwc_display_contents_1_t *list = displays[i]; 113ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson // XXX:SurfaceFlinger no longer guarantees that this 114ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson // value is reset on every prepare. However, for the layer 115ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson // cache we need to reset it. 116ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson // We can probably rethink that later on 117a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if (LIKELY(list && list->numHwLayers > 0)) { 118ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson for(uint32_t j = 0; j < list->numHwLayers; j++) { 119ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if(list->hwLayers[j].compositionType != HWC_FRAMEBUFFER_TARGET) 120ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson list->hwLayers[j].compositionType = HWC_FRAMEBUFFER; 121ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 122a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 123a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson /* For display devices like SSD and screenrecord, we cannot 124a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson * rely on isActive and connected attributes of dpyAttr to 125a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson * determine if the displaydevice is active. Hence in case if 126a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson * the layer-list is non-null and numHwLayers > 0, we assume 127a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson * the display device to be active. 128a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson */ 129a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ctx->numActiveDisplays += 1; 130a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 131a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if((ctx->mPrevHwLayerCount[i] == 1) and (list->numHwLayers > 1)) { 132a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson /* If the previous cycle for dpy 'i' has 0 AppLayers and the 133a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson * current cycle has atleast 1 AppLayer, padding round needs 134a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson * to be invoked on current cycle to free up the resources. 135a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson */ 136a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ctx->isPaddingRound = true; 137a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson } 138a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ctx->mPrevHwLayerCount[i] = list->numHwLayers; 139a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson } else { 140a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ctx->mPrevHwLayerCount[i] = 0; 141ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 142ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 143ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if(ctx->mFBUpdate[i]) 144ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->mFBUpdate[i]->reset(); 145ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if(ctx->mCopyBit[i]) 146ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->mCopyBit[i]->reset(); 147ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if(ctx->mLayerRotMap[i]) 148ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->mLayerRotMap[i]->reset(); 149ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 150ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 151ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->mAD->reset(); 152a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson MDPComp::reset(); 153a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(ctx->mHWCVirtual) 154a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ctx->mHWCVirtual->destroy(ctx, numDisplays, displays); 155ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 156ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 157a653efede03423aa840da24634f1ec6f20796f1eSimon Wilsonbool isEqual(float f1, float f2) { 158a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson return ((int)(f1*100) == (int)(f2*100)) ? true : false; 159ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 160ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 161a653efede03423aa840da24634f1ec6f20796f1eSimon Wilsonstatic void scaleDisplayFrame(hwc_context_t *ctx, int dpy, 162a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson hwc_display_contents_1_t *list) { 163a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson float origXres = ctx->dpyAttr[dpy].xres_orig; 164a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson float origYres = ctx->dpyAttr[dpy].yres_orig; 165a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson float fakeXres = ctx->dpyAttr[dpy].xres; 166a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson float fakeYres = ctx->dpyAttr[dpy].yres; 167a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson float xresRatio = origXres / fakeXres; 168a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson float yresRatio = origYres / fakeYres; 169a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson for (size_t i = 0; i < list->numHwLayers; i++) { 170a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson hwc_layer_1_t *layer = &list->hwLayers[i]; 171a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson hwc_rect_t& displayFrame = layer->displayFrame; 172a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf); 173a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson float layerWidth = displayFrame.right - displayFrame.left; 174a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson float layerHeight = displayFrame.bottom - displayFrame.top; 175a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson float sourceWidth = sourceCrop.right - sourceCrop.left; 176a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson float sourceHeight = sourceCrop.bottom - sourceCrop.top; 177a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 178a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if (isEqual(layerWidth / sourceWidth, xresRatio) && 179a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson isEqual(layerHeight / sourceHeight, yresRatio)) 180a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson break; 181ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 182a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson displayFrame.left = xresRatio * displayFrame.left; 183a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson displayFrame.top = yresRatio * displayFrame.top; 184a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson displayFrame.right = displayFrame.left + layerWidth * xresRatio; 185a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson displayFrame.bottom = displayFrame.top + layerHeight * yresRatio; 186ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 187ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 188ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 189ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_prepare_primary(hwc_composer_device_1 *dev, 190ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hwc_display_contents_1_t *list) { 191ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ATRACE_CALL(); 192ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hwc_context_t* ctx = (hwc_context_t*)(dev); 193ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson const int dpy = HWC_DISPLAY_PRIMARY; 194a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson bool fbComp = false; 195ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if (LIKELY(list && list->numHwLayers > 1) && 196ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->dpyAttr[dpy].isActive) { 197a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 198a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if (ctx->dpyAttr[dpy].customFBSize) 199a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson scaleDisplayFrame(ctx, dpy, list); 200a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 201ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson reset_layer_prop(ctx, dpy, list->numHwLayers - 1); 202ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson setListStats(ctx, list, dpy); 203a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 204201e4c9a80c1adb32ac8271a95721aa838c4d9feNaseer Ahmed fbComp = (ctx->mMDPComp[dpy]->prepare(ctx, list) < 0); 205a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 206a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if (fbComp) { 207ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson const int fbZ = 0; 208a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ctx->mFBUpdate[dpy]->prepareAndValidate(ctx, list, fbZ); 209ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 210a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 211ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if (ctx->mMDP.version < qdutils::MDP_V4_0) { 212ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if(ctx->mCopyBit[dpy]) 213ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->mCopyBit[dpy]->prepare(ctx, list, dpy); 214ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 2151b0c2f1b1c7201502f75c12131e3bc54f92d60eaRamkumar Radhakrishnan setGPUHint(ctx, list); 216ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 217ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return 0; 218ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 219ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 220ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_prepare_external(hwc_composer_device_1 *dev, 221ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hwc_display_contents_1_t *list) { 222ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ATRACE_CALL(); 223ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hwc_context_t* ctx = (hwc_context_t*)(dev); 224ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson const int dpy = HWC_DISPLAY_EXTERNAL; 225ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 226ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if (LIKELY(list && list->numHwLayers > 1) && 227ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->dpyAttr[dpy].isActive && 228ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->dpyAttr[dpy].connected) { 229ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson reset_layer_prop(ctx, dpy, list->numHwLayers - 1); 230ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if(!ctx->dpyAttr[dpy].isPause) { 231ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->dpyAttr[dpy].isConfiguring = false; 232ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson setListStats(ctx, list, dpy); 233ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if(ctx->mMDPComp[dpy]->prepare(ctx, list) < 0) { 234ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson const int fbZ = 0; 235a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ctx->mFBUpdate[dpy]->prepareAndValidate(ctx, list, fbZ); 236ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 237ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } else { 238a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson /* External Display is in Pause state. 239a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson * Mark all application layers as OVERLAY so that 240a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson * GPU will not compose. 241a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson */ 242a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson for(size_t i = 0 ;i < (size_t)(list->numHwLayers - 1); i++) { 243a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson hwc_layer_1_t *layer = &list->hwLayers[i]; 244a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson layer->compositionType = HWC_OVERLAY; 245a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson } 246ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 247ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 248ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return 0; 249ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 250ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 251ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_prepare(hwc_composer_device_1 *dev, size_t numDisplays, 252ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hwc_display_contents_1_t** displays) 253ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{ 254ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson int ret = 0; 255ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hwc_context_t* ctx = (hwc_context_t*)(dev); 256a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 257a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if (ctx->mPanelResetStatus) { 258a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ALOGW("%s: panel is in bad state. reset the panel", __FUNCTION__); 259a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson reset_panel(dev); 260a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson } 261a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 262ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson //Will be unlocked at the end of set 263ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->mDrawLock.lock(); 264ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson reset(ctx, numDisplays, displays); 265ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 266ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->mOverlay->configBegin(); 267ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->mRotMgr->configBegin(); 268ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson overlay::Writeback::configBegin(); 269ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 270a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson for (int32_t i = (numDisplays-1); i >= 0; i--) { 271ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hwc_display_contents_1_t *list = displays[i]; 272a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson int dpy = getDpyforExternalDisplay(ctx, i); 273a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson switch(dpy) { 274ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson case HWC_DISPLAY_PRIMARY: 275ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ret = hwc_prepare_primary(dev, list); 276ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson break; 277ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson case HWC_DISPLAY_EXTERNAL: 278ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ret = hwc_prepare_external(dev, list); 279ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson break; 280ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson case HWC_DISPLAY_VIRTUAL: 281a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(ctx->mHWCVirtual) 282a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ret = ctx->mHWCVirtual->prepare(dev, list); 283ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson break; 284ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson default: 285ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ret = -EINVAL; 286ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 287ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 288ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 289ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->mOverlay->configDone(); 290ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->mRotMgr->configDone(); 291ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson overlay::Writeback::configDone(); 292ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 293ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return ret; 294ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 295ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 296ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_eventControl(struct hwc_composer_device_1* dev, int dpy, 297ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson int event, int enable) 298ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{ 299ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ATRACE_CALL(); 300ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson int ret = 0; 301ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hwc_context_t* ctx = (hwc_context_t*)(dev); 302ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson switch(event) { 303ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson case HWC_EVENT_VSYNC: 304ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if (ctx->vstate.enable == enable) 305ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson break; 306ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ret = hwc_vsync_control(ctx, dpy, enable); 307ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if(ret == 0) 308ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->vstate.enable = !!enable; 309ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ALOGD_IF (VSYNC_DEBUG, "VSYNC state changed to %s", 310ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson (enable)?"ENABLED":"DISABLED"); 311ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson break; 312a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson#ifdef QCOM_BSP 313a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson case HWC_EVENT_ORIENTATION: 314a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(dpy == HWC_DISPLAY_PRIMARY) { 315a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson Locker::Autolock _l(ctx->mDrawLock); 316a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson // store the primary display orientation 317a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ctx->deviceOrientation = enable; 318a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson } 319a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson break; 320a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson#endif 321ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson default: 322ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ret = -EINVAL; 323ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 324ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return ret; 325ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 326ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 327ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_blank(struct hwc_composer_device_1* dev, int dpy, int blank) 328ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{ 329ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ATRACE_CALL(); 330ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hwc_context_t* ctx = (hwc_context_t*)(dev); 331ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 332ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson Locker::Autolock _l(ctx->mDrawLock); 333a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson int ret = 0, value = 0; 334a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 335a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson /* In case of non-hybrid WFD session, we are fooling SF by 336a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson * piggybacking on HDMI display ID for virtual. 337a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson * TODO: Not needed once we have WFD client working on top 338a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson * of Google API's. 339a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson */ 340a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson dpy = getDpyforExternalDisplay(ctx,dpy); 341a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 342ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ALOGD_IF(BLANK_DEBUG, "%s: %s display: %d", __FUNCTION__, 343ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson blank==1 ? "Blanking":"Unblanking", dpy); 344ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if(blank) { 345ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson // free up all the overlay pipes in use 346ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson // when we get a blank for either display 347ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson // makes sure that all pipes are freed 348ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->mOverlay->configBegin(); 349ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->mOverlay->configDone(); 350ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->mRotMgr->clear(); 351a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson // If VDS is connected, do not clear WB object as it 352a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson // will end up detaching IOMMU. This is required 353a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson // to send black frame to WFD sink on power suspend. 354a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson // Note: With this change, we keep the WriteBack object 355a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson // alive on power suspend for AD use case. 356ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 357ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson switch(dpy) { 358a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson case HWC_DISPLAY_PRIMARY: 359a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson value = blank ? FB_BLANK_POWERDOWN : FB_BLANK_UNBLANK; 360a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(ioctl(ctx->dpyAttr[dpy].fd, FBIOBLANK, value) < 0 ) { 361a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ALOGE("%s: Failed to handle blank event(%d) for Primary!!", 362a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson __FUNCTION__, blank ); 363a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson return -1; 364a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson } 365a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 366a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(!blank) { 367a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson // Enable HPD here, as during bootup unblank is called 368a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson // when SF is completely initialized 369a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ctx->mExtDisplay->setHPD(1); 370a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson } 371a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 372a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ctx->dpyAttr[dpy].isActive = !blank; 373a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 374a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(ctx->mVirtualonExtActive) { 375a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson /* if mVirtualonExtActive is true, display hal will 376a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson * receive unblank calls for non-hybrid WFD solution 377a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson * since we piggyback on HDMI. 378a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson * TODO: Not needed once we have WFD client working on top 379a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson of Google API's */ 380ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson break; 381a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson } 382a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson case HWC_DISPLAY_VIRTUAL: 383a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson /* There are two ways to reach this block of code. 384a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 385a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson * Display hal has received unblank call on HWC_DISPLAY_EXTERNAL 386a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson and ctx->mVirtualonExtActive is true. In this case, non-hybrid 387a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson WFD is active. If so, getDpyforExternalDisplay will return dpy 388a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson as HWC_DISPLAY_VIRTUAL. 389a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 390a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson * Display hal has received unblank call on HWC_DISPLAY_PRIMARY 391a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson and since SF is not aware of VIRTUAL DISPLAY being handle by HWC, 392a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson it wont send blank / unblank events for it. We piggyback on 393a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson PRIMARY DISPLAY events to release mdp pipes and 394a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson activate/deactivate VIRTUAL DISPLAY. 395a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 396a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson * TODO: This separate case statement is not needed once we have 397a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson WFD client working on top of Google API's. 398a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 399a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson */ 400a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 401a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected) { 402a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(blank and (!ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isPause)) { 403a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson int dpy = HWC_DISPLAY_VIRTUAL; 404a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) { 405a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ALOGE("%s: display commit fail for virtual!", __FUNCTION__); 406ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ret = -1; 407ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 408ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 409a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isActive = !blank; 410a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson } 411a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson break; 412a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson case HWC_DISPLAY_EXTERNAL: 413a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(blank) { 414a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) { 415a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ALOGE("%s: display commit fail for external!", __FUNCTION__); 416a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ret = -1; 417a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson } 418a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson } 419ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->dpyAttr[dpy].isActive = !blank; 420a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson break; 421a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson default: 422a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson return -EINVAL; 423ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 424ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 425ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ALOGD_IF(BLANK_DEBUG, "%s: Done %s display: %d", __FUNCTION__, 426a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson blank ? "blanking":"unblanking", dpy); 427a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson return ret; 428a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson} 429a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 430a653efede03423aa840da24634f1ec6f20796f1eSimon Wilsonstatic void reset_panel(struct hwc_composer_device_1* dev) 431a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson{ 432a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson int ret = 0; 433a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson hwc_context_t* ctx = (hwc_context_t*)(dev); 434a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 435a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if (!ctx->dpyAttr[HWC_DISPLAY_PRIMARY].isActive) { 436a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ALOGD ("%s : Display OFF - Skip BLANK & UNBLANK", __FUNCTION__); 437a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ctx->mPanelResetStatus = false; 438a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson return; 439a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson } 440a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 441a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ALOGD("%s: calling BLANK DISPLAY", __FUNCTION__); 442a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ret = hwc_blank(dev, HWC_DISPLAY_PRIMARY, 1); 443a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if (ret < 0) { 444a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ALOGE("%s: FBIOBLANK failed to BLANK: %s", __FUNCTION__, 445a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson strerror(errno)); 446a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson } 447a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 448a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ALOGD("%s: calling UNBLANK DISPLAY and enabling vsync", __FUNCTION__); 449a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ret = hwc_blank(dev, HWC_DISPLAY_PRIMARY, 0); 450a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if (ret < 0) { 451a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ALOGE("%s: FBIOBLANK failed to UNBLANK : %s", __FUNCTION__, 452a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson strerror(errno)); 453a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson } 454a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson hwc_vsync_control(ctx, HWC_DISPLAY_PRIMARY, 1); 455a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 456a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ctx->mPanelResetStatus = false; 457ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 458ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 459a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 460ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_query(struct hwc_composer_device_1* dev, 461ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson int param, int* value) 462ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{ 463ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hwc_context_t* ctx = (hwc_context_t*)(dev); 464ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson int supported = HWC_DISPLAY_PRIMARY_BIT; 465ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 466ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson switch (param) { 467ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson case HWC_BACKGROUND_LAYER_SUPPORTED: 468ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson // Not supported for now 469ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson value[0] = 0; 470ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson break; 471a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson case HWC_DISPLAY_TYPES_SUPPORTED: 472ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if(ctx->mMDP.hasOverlay) { 473ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson supported |= HWC_DISPLAY_VIRTUAL_BIT; 4740fdae193307fb17bb537598ab62682edd5138b72radhakrishna if(!(qdutils::MDPVersion::getInstance().is8x26() || 4750fdae193307fb17bb537598ab62682edd5138b72radhakrishna qdutils::MDPVersion::getInstance().is8x16())) 476ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson supported |= HWC_DISPLAY_EXTERNAL_BIT; 477ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 478ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson value[0] = supported; 479ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson break; 480a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson case HWC_FORMAT_RB_SWAP: 481a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson value[0] = 1; 482a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson break; 483a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson case HWC_COLOR_FILL: 484a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson value[0] = 1; 485a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson break; 486ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson default: 487ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return -EINVAL; 488ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 489ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return 0; 490ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 491ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 492ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 493ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 494ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_set_primary(hwc_context_t *ctx, hwc_display_contents_1_t* list) { 495ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ATRACE_CALL(); 496ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson int ret = 0; 497ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson const int dpy = HWC_DISPLAY_PRIMARY; 498ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if (LIKELY(list) && ctx->dpyAttr[dpy].isActive) { 499ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson uint32_t last = list->numHwLayers - 1; 500ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hwc_layer_1_t *fbLayer = &list->hwLayers[last]; 501ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson int fd = -1; //FenceFD from the Copybit(valid in async mode) 502ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson bool copybitDone = false; 503ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if(ctx->mCopyBit[dpy]) 504ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd); 505ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if(list->numHwLayers > 1) 506ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hwc_sync(ctx, list, dpy, fd); 507ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 508a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson // Dump the layers for primary 509a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(ctx->mHwcDebug[dpy]) 510a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ctx->mHwcDebug[dpy]->dumpLayers(list); 511a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 512201e4c9a80c1adb32ac8271a95721aa838c4d9feNaseer Ahmed if (!ctx->mMDPComp[dpy]->draw(ctx, list)) { 513ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ALOGE("%s: MDPComp draw failed", __FUNCTION__); 514ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ret = -1; 515ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 516ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 517ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson //TODO We dont check for SKIP flag on this layer because we need PAN 518ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson //always. Last layer is always FB 519ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson private_handle_t *hnd = (private_handle_t *)fbLayer->handle; 520a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(copybitDone && ctx->mMDP.version >= qdutils::MDP_V4_0) { 521ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer(); 522ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 523ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 524ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if(hnd) { 525ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) { 526ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ALOGE("%s: FBUpdate draw failed", __FUNCTION__); 527ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ret = -1; 528ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 529ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 530ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 531a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd, 532a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ctx->listStats[dpy].roi)) { 533a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ALOGE("%s: display commit fail for %d dpy!", __FUNCTION__, dpy); 534ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ret = -1; 535ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 536a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 537ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 538ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 539a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson closeAcquireFds(list); 540ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return ret; 541ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 542ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 543ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_set_external(hwc_context_t *ctx, 544a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson hwc_display_contents_1_t* list) 545ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{ 546ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ATRACE_CALL(); 547ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson int ret = 0; 548a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 549ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson const int dpy = HWC_DISPLAY_EXTERNAL; 550ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 551a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 552ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if (LIKELY(list) && ctx->dpyAttr[dpy].isActive && 553a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ctx->dpyAttr[dpy].connected && 554a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson !ctx->dpyAttr[dpy].isPause) { 555ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson uint32_t last = list->numHwLayers - 1; 556ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hwc_layer_1_t *fbLayer = &list->hwLayers[last]; 557ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson int fd = -1; //FenceFD from the Copybit(valid in async mode) 558ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson bool copybitDone = false; 559ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if(ctx->mCopyBit[dpy]) 560ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd); 561ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 562ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if(list->numHwLayers > 1) 563ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hwc_sync(ctx, list, dpy, fd); 564ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 565a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson // Dump the layers for external 566a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(ctx->mHwcDebug[dpy]) 567a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ctx->mHwcDebug[dpy]->dumpLayers(list); 568a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 569ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if (!ctx->mMDPComp[dpy]->draw(ctx, list)) { 570ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ALOGE("%s: MDPComp draw failed", __FUNCTION__); 571ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ret = -1; 572ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 573ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 574a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson int extOnlyLayerIndex = 575a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ctx->listStats[dpy].extOnlyLayerIndex; 576a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 577ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson private_handle_t *hnd = (private_handle_t *)fbLayer->handle; 578a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(extOnlyLayerIndex!= -1) { 579a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson hwc_layer_1_t *extLayer = &list->hwLayers[extOnlyLayerIndex]; 580a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson hnd = (private_handle_t *)extLayer->handle; 581a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson } else if(copybitDone) { 582ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer(); 583ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 584ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 585a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(hnd && !isYuvBuffer(hnd)) { 586ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) { 587ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__); 588ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ret = -1; 589ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 590ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 591ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 592a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) { 593a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ALOGE("%s: display commit fail for %d dpy!", __FUNCTION__, dpy); 594ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ret = -1; 595ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 596ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 597ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 598a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson closeAcquireFds(list); 599ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return ret; 600ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 601ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 602ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_set(hwc_composer_device_1 *dev, 603ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson size_t numDisplays, 604ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hwc_display_contents_1_t** displays) 605ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{ 606ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson int ret = 0; 607ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hwc_context_t* ctx = (hwc_context_t*)(dev); 608ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson for (uint32_t i = 0; i < numDisplays; i++) { 609ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hwc_display_contents_1_t* list = displays[i]; 610a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson int dpy = getDpyforExternalDisplay(ctx, i); 611a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson switch(dpy) { 612ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson case HWC_DISPLAY_PRIMARY: 613ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ret = hwc_set_primary(ctx, list); 614ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson break; 615ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson case HWC_DISPLAY_EXTERNAL: 616ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ret = hwc_set_external(ctx, list); 617ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson break; 618ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson case HWC_DISPLAY_VIRTUAL: 619a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(ctx->mHWCVirtual) 620a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ret = ctx->mHWCVirtual->set(ctx, list); 621ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson break; 622ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson default: 623ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ret = -EINVAL; 624ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 625ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 626ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson // This is only indicative of how many times SurfaceFlinger posts 627ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson // frames to the display. 628ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson CALC_FPS(); 629ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson MDPComp::resetIdleFallBack(); 630ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->mVideoTransFlag = false; 631a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(ctx->mRotMgr->getNumActiveSessions() == 0) 632a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson Overlay::setDMAMode(Overlay::DMA_LINE_MODE); 633ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson //Was locked at the beginning of prepare 634ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->mDrawLock.unlock(); 635ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return ret; 636ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 637ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 638ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonint hwc_getDisplayConfigs(struct hwc_composer_device_1* dev, int disp, 639ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson uint32_t* configs, size_t* numConfigs) { 640ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson int ret = 0; 641ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hwc_context_t* ctx = (hwc_context_t*)(dev); 642a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson disp = getDpyforExternalDisplay(ctx, disp); 643ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson //in 1.1 there is no way to choose a config, report as config id # 0 644ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson //This config is passed to getDisplayAttributes. Ignore for now. 645ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson switch(disp) { 646ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson case HWC_DISPLAY_PRIMARY: 647ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if(*numConfigs > 0) { 648ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson configs[0] = 0; 649ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson *numConfigs = 1; 650ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 651ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ret = 0; //NO_ERROR 652ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson break; 653ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson case HWC_DISPLAY_EXTERNAL: 654a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson case HWC_DISPLAY_VIRTUAL: 655ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ret = -1; //Not connected 656a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(ctx->dpyAttr[disp].connected) { 657ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ret = 0; //NO_ERROR 658ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if(*numConfigs > 0) { 659ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson configs[0] = 0; 660ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson *numConfigs = 1; 661ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 662ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 663ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson break; 664ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 665ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return ret; 666ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 667ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 668ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonint hwc_getDisplayAttributes(struct hwc_composer_device_1* dev, int disp, 669a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson uint32_t /*config*/, const uint32_t* attributes, int32_t* values) { 670ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 671ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hwc_context_t* ctx = (hwc_context_t*)(dev); 672a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson disp = getDpyforExternalDisplay(ctx, disp); 673a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson //If hotpluggable displays(i.e, HDMI, WFD) are inactive return error 674a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if( (disp != HWC_DISPLAY_PRIMARY) && !ctx->dpyAttr[disp].connected) { 675ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return -1; 676ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 677ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 678ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson //From HWComposer 679ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson static const uint32_t DISPLAY_ATTRIBUTES[] = { 680ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson HWC_DISPLAY_VSYNC_PERIOD, 681ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson HWC_DISPLAY_WIDTH, 682ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson HWC_DISPLAY_HEIGHT, 683ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson HWC_DISPLAY_DPI_X, 684ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson HWC_DISPLAY_DPI_Y, 685ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson HWC_DISPLAY_NO_ATTRIBUTE, 686ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson }; 687ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 688ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson const int NUM_DISPLAY_ATTRIBUTES = (sizeof(DISPLAY_ATTRIBUTES) / 689ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson sizeof(DISPLAY_ATTRIBUTES)[0]); 690ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 691ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson for (size_t i = 0; i < NUM_DISPLAY_ATTRIBUTES - 1; i++) { 692ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson switch (attributes[i]) { 693ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson case HWC_DISPLAY_VSYNC_PERIOD: 694ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson values[i] = ctx->dpyAttr[disp].vsync_period; 695ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson break; 696ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson case HWC_DISPLAY_WIDTH: 697ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson values[i] = ctx->dpyAttr[disp].xres; 698ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ALOGD("%s disp = %d, width = %d",__FUNCTION__, disp, 699ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->dpyAttr[disp].xres); 700ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson break; 701ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson case HWC_DISPLAY_HEIGHT: 702ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson values[i] = ctx->dpyAttr[disp].yres; 703ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ALOGD("%s disp = %d, height = %d",__FUNCTION__, disp, 704ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->dpyAttr[disp].yres); 705ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson break; 706ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson case HWC_DISPLAY_DPI_X: 707ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson values[i] = (int32_t) (ctx->dpyAttr[disp].xdpi*1000.0); 708ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson break; 709ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson case HWC_DISPLAY_DPI_Y: 710ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson values[i] = (int32_t) (ctx->dpyAttr[disp].ydpi*1000.0); 711ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson break; 712ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson default: 713ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ALOGE("Unknown display attribute %d", 714ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson attributes[i]); 715ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return -EINVAL; 716ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 717ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 718ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return 0; 719ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 720ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 721ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonvoid hwc_dump(struct hwc_composer_device_1* dev, char *buff, int buff_len) 722ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{ 723ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hwc_context_t* ctx = (hwc_context_t*)(dev); 724ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson Locker::Autolock _l(ctx->mDrawLock); 725ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson android::String8 aBuf(""); 726ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson dumpsys_log(aBuf, "Qualcomm HWC state:\n"); 727ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson dumpsys_log(aBuf, " MDPVersion=%d\n", ctx->mMDP.version); 728ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson dumpsys_log(aBuf, " DisplayPanel=%c\n", ctx->mMDP.panel); 729ced6b79c3e1b60b05e2e054e709b1f9a2b6b304cNaseer Ahmed if(ctx->vstate.fakevsync) 730ced6b79c3e1b60b05e2e054e709b1f9a2b6b304cNaseer Ahmed dumpsys_log(aBuf, " Vsync is being faked!!\n"); 731a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson for(int dpy = 0; dpy < HWC_NUM_DISPLAY_TYPES; dpy++) { 732ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if(ctx->mMDPComp[dpy]) 733ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->mMDPComp[dpy]->dump(aBuf); 734ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 735ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson char ovDump[2048] = {'\0'}; 736ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->mOverlay->getDump(ovDump, 2048); 737ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson dumpsys_log(aBuf, ovDump); 738ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ovDump[0] = '\0'; 739ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->mRotMgr->getDump(ovDump, 1024); 740ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson dumpsys_log(aBuf, ovDump); 741ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ovDump[0] = '\0'; 742ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if(Writeback::getDump(ovDump, 1024)) { 743ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson dumpsys_log(aBuf, ovDump); 744ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ovDump[0] = '\0'; 745ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 746ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson strlcpy(buff, aBuf.string(), buff_len); 747ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 748ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 749ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_device_close(struct hw_device_t *dev) 750ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{ 751ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if(!dev) { 752ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ALOGE("%s: NULL device pointer", __FUNCTION__); 753ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return -1; 754ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 755ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson closeContext((hwc_context_t*)dev); 756ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson free(dev); 757ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 758ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return 0; 759ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 760ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 761ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_device_open(const struct hw_module_t* module, const char* name, 762ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson struct hw_device_t** device) 763ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{ 764ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson int status = -EINVAL; 765ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 766ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if (!strcmp(name, HWC_HARDWARE_COMPOSER)) { 767ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson struct hwc_context_t *dev; 768ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson dev = (hwc_context_t*)malloc(sizeof(*dev)); 769a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(dev == NULL) 770a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson return status; 771ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson memset(dev, 0, sizeof(*dev)); 772ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 773ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson //Initialize hwc context 774ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson initContext(dev); 775ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 776ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson //Setup HWC methods 777ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson dev->device.common.tag = HARDWARE_DEVICE_TAG; 778ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson dev->device.common.version = HWC_DEVICE_API_VERSION_1_3; 779ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson dev->device.common.module = const_cast<hw_module_t*>(module); 780ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson dev->device.common.close = hwc_device_close; 781ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson dev->device.prepare = hwc_prepare; 782ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson dev->device.set = hwc_set; 783ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson dev->device.eventControl = hwc_eventControl; 784ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson dev->device.blank = hwc_blank; 785ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson dev->device.query = hwc_query; 786ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson dev->device.registerProcs = hwc_registerProcs; 787ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson dev->device.dump = hwc_dump; 788ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson dev->device.getDisplayConfigs = hwc_getDisplayConfigs; 789ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson dev->device.getDisplayAttributes = hwc_getDisplayAttributes; 790ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson *device = &dev->device.common; 791ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson status = 0; 792ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 793ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return status; 794ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 795