hwc.cpp revision 0fdae193307fb17bb537598ab62682edd5138b72
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 } 215ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 216ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return 0; 217ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 218ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 219ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_prepare_external(hwc_composer_device_1 *dev, 220ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hwc_display_contents_1_t *list) { 221ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ATRACE_CALL(); 222ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hwc_context_t* ctx = (hwc_context_t*)(dev); 223ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson const int dpy = HWC_DISPLAY_EXTERNAL; 224ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 225ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if (LIKELY(list && list->numHwLayers > 1) && 226ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->dpyAttr[dpy].isActive && 227ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->dpyAttr[dpy].connected) { 228ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson reset_layer_prop(ctx, dpy, list->numHwLayers - 1); 229ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if(!ctx->dpyAttr[dpy].isPause) { 230ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->dpyAttr[dpy].isConfiguring = false; 231ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson setListStats(ctx, list, dpy); 232ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if(ctx->mMDPComp[dpy]->prepare(ctx, list) < 0) { 233ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson const int fbZ = 0; 234a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ctx->mFBUpdate[dpy]->prepareAndValidate(ctx, list, fbZ); 235ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 236ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } else { 237a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson /* External Display is in Pause state. 238a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson * Mark all application layers as OVERLAY so that 239a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson * GPU will not compose. 240a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson */ 241a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson for(size_t i = 0 ;i < (size_t)(list->numHwLayers - 1); i++) { 242a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson hwc_layer_1_t *layer = &list->hwLayers[i]; 243a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson layer->compositionType = HWC_OVERLAY; 244a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson } 245ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 246ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 247ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return 0; 248ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 249ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 250ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_prepare(hwc_composer_device_1 *dev, size_t numDisplays, 251ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hwc_display_contents_1_t** displays) 252ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{ 253ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson int ret = 0; 254ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hwc_context_t* ctx = (hwc_context_t*)(dev); 255a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 256a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if (ctx->mPanelResetStatus) { 257a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ALOGW("%s: panel is in bad state. reset the panel", __FUNCTION__); 258a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson reset_panel(dev); 259a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson } 260a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 261ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson //Will be unlocked at the end of set 262ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->mDrawLock.lock(); 263ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson reset(ctx, numDisplays, displays); 264ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 265ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->mOverlay->configBegin(); 266ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->mRotMgr->configBegin(); 267ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson overlay::Writeback::configBegin(); 268ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 269a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson for (int32_t i = (numDisplays-1); i >= 0; i--) { 270ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hwc_display_contents_1_t *list = displays[i]; 271a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson int dpy = getDpyforExternalDisplay(ctx, i); 272a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson switch(dpy) { 273ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson case HWC_DISPLAY_PRIMARY: 274ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ret = hwc_prepare_primary(dev, list); 275ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson break; 276ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson case HWC_DISPLAY_EXTERNAL: 277ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ret = hwc_prepare_external(dev, list); 278ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson break; 279ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson case HWC_DISPLAY_VIRTUAL: 280a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(ctx->mHWCVirtual) 281a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ret = ctx->mHWCVirtual->prepare(dev, list); 282ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson break; 283ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson default: 284ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ret = -EINVAL; 285ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 286ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 287ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 288ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->mOverlay->configDone(); 289ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->mRotMgr->configDone(); 290ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson overlay::Writeback::configDone(); 291ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 292ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return ret; 293ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 294ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 295ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_eventControl(struct hwc_composer_device_1* dev, int dpy, 296ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson int event, int enable) 297ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{ 298ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ATRACE_CALL(); 299ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson int ret = 0; 300ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hwc_context_t* ctx = (hwc_context_t*)(dev); 301ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson switch(event) { 302ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson case HWC_EVENT_VSYNC: 303ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if (ctx->vstate.enable == enable) 304ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson break; 305ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ret = hwc_vsync_control(ctx, dpy, enable); 306ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if(ret == 0) 307ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->vstate.enable = !!enable; 308ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ALOGD_IF (VSYNC_DEBUG, "VSYNC state changed to %s", 309ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson (enable)?"ENABLED":"DISABLED"); 310ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson break; 311a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson#ifdef QCOM_BSP 312a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson case HWC_EVENT_ORIENTATION: 313a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(dpy == HWC_DISPLAY_PRIMARY) { 314a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson Locker::Autolock _l(ctx->mDrawLock); 315a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson // store the primary display orientation 316a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ctx->deviceOrientation = enable; 317a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson } 318a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson break; 319a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson#endif 320ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson default: 321ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ret = -EINVAL; 322ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 323ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return ret; 324ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 325ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 326ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_blank(struct hwc_composer_device_1* dev, int dpy, int blank) 327ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{ 328ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ATRACE_CALL(); 329ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hwc_context_t* ctx = (hwc_context_t*)(dev); 330ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 331ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson Locker::Autolock _l(ctx->mDrawLock); 332a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson int ret = 0, value = 0; 333a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 334a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson /* In case of non-hybrid WFD session, we are fooling SF by 335a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson * piggybacking on HDMI display ID for virtual. 336a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson * TODO: Not needed once we have WFD client working on top 337a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson * of Google API's. 338a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson */ 339a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson dpy = getDpyforExternalDisplay(ctx,dpy); 340a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 341ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ALOGD_IF(BLANK_DEBUG, "%s: %s display: %d", __FUNCTION__, 342ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson blank==1 ? "Blanking":"Unblanking", dpy); 343ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if(blank) { 344ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson // free up all the overlay pipes in use 345ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson // when we get a blank for either display 346ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson // makes sure that all pipes are freed 347ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->mOverlay->configBegin(); 348ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->mOverlay->configDone(); 349ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->mRotMgr->clear(); 350a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson // If VDS is connected, do not clear WB object as it 351a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson // will end up detaching IOMMU. This is required 352a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson // to send black frame to WFD sink on power suspend. 353a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson // Note: With this change, we keep the WriteBack object 354a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson // alive on power suspend for AD use case. 355ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 356ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson switch(dpy) { 357a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson case HWC_DISPLAY_PRIMARY: 358a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson value = blank ? FB_BLANK_POWERDOWN : FB_BLANK_UNBLANK; 359a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(ioctl(ctx->dpyAttr[dpy].fd, FBIOBLANK, value) < 0 ) { 360a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ALOGE("%s: Failed to handle blank event(%d) for Primary!!", 361a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson __FUNCTION__, blank ); 362a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson return -1; 363a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson } 364a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 365a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(!blank) { 366a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson // Enable HPD here, as during bootup unblank is called 367a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson // when SF is completely initialized 368a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ctx->mExtDisplay->setHPD(1); 369a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson } 370a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 371a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ctx->dpyAttr[dpy].isActive = !blank; 372a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 373a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(ctx->mVirtualonExtActive) { 374a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson /* if mVirtualonExtActive is true, display hal will 375a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson * receive unblank calls for non-hybrid WFD solution 376a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson * since we piggyback on HDMI. 377a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson * TODO: Not needed once we have WFD client working on top 378a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson of Google API's */ 379ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson break; 380a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson } 381a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson case HWC_DISPLAY_VIRTUAL: 382a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson /* There are two ways to reach this block of code. 383a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 384a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson * Display hal has received unblank call on HWC_DISPLAY_EXTERNAL 385a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson and ctx->mVirtualonExtActive is true. In this case, non-hybrid 386a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson WFD is active. If so, getDpyforExternalDisplay will return dpy 387a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson as HWC_DISPLAY_VIRTUAL. 388a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 389a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson * Display hal has received unblank call on HWC_DISPLAY_PRIMARY 390a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson and since SF is not aware of VIRTUAL DISPLAY being handle by HWC, 391a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson it wont send blank / unblank events for it. We piggyback on 392a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson PRIMARY DISPLAY events to release mdp pipes and 393a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson activate/deactivate VIRTUAL DISPLAY. 394a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 395a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson * TODO: This separate case statement is not needed once we have 396a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson WFD client working on top of Google API's. 397a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 398a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson */ 399a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 400a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected) { 401a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(blank and (!ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isPause)) { 402a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson int dpy = HWC_DISPLAY_VIRTUAL; 403a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) { 404a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ALOGE("%s: display commit fail for virtual!", __FUNCTION__); 405ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ret = -1; 406ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 407ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 408a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isActive = !blank; 409a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson } 410a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson break; 411a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson case HWC_DISPLAY_EXTERNAL: 412a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(blank) { 413a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) { 414a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ALOGE("%s: display commit fail for external!", __FUNCTION__); 415a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ret = -1; 416a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson } 417a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson } 418ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->dpyAttr[dpy].isActive = !blank; 419a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson break; 420a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson default: 421a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson return -EINVAL; 422ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 423ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 424ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ALOGD_IF(BLANK_DEBUG, "%s: Done %s display: %d", __FUNCTION__, 425a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson blank ? "blanking":"unblanking", dpy); 426a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson return ret; 427a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson} 428a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 429a653efede03423aa840da24634f1ec6f20796f1eSimon Wilsonstatic void reset_panel(struct hwc_composer_device_1* dev) 430a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson{ 431a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson int ret = 0; 432a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson hwc_context_t* ctx = (hwc_context_t*)(dev); 433a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 434a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if (!ctx->dpyAttr[HWC_DISPLAY_PRIMARY].isActive) { 435a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ALOGD ("%s : Display OFF - Skip BLANK & UNBLANK", __FUNCTION__); 436a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ctx->mPanelResetStatus = false; 437a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson return; 438a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson } 439a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 440a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ALOGD("%s: calling BLANK DISPLAY", __FUNCTION__); 441a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ret = hwc_blank(dev, HWC_DISPLAY_PRIMARY, 1); 442a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if (ret < 0) { 443a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ALOGE("%s: FBIOBLANK failed to BLANK: %s", __FUNCTION__, 444a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson strerror(errno)); 445a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson } 446a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 447a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ALOGD("%s: calling UNBLANK DISPLAY and enabling vsync", __FUNCTION__); 448a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ret = hwc_blank(dev, HWC_DISPLAY_PRIMARY, 0); 449a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if (ret < 0) { 450a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ALOGE("%s: FBIOBLANK failed to UNBLANK : %s", __FUNCTION__, 451a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson strerror(errno)); 452a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson } 453a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson hwc_vsync_control(ctx, HWC_DISPLAY_PRIMARY, 1); 454a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 455a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ctx->mPanelResetStatus = false; 456ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 457ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 458a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 459ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_query(struct hwc_composer_device_1* dev, 460ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson int param, int* value) 461ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{ 462ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hwc_context_t* ctx = (hwc_context_t*)(dev); 463ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson int supported = HWC_DISPLAY_PRIMARY_BIT; 464ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 465ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson switch (param) { 466ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson case HWC_BACKGROUND_LAYER_SUPPORTED: 467ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson // Not supported for now 468ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson value[0] = 0; 469ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson break; 470a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson case HWC_DISPLAY_TYPES_SUPPORTED: 471ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if(ctx->mMDP.hasOverlay) { 472ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson supported |= HWC_DISPLAY_VIRTUAL_BIT; 4730fdae193307fb17bb537598ab62682edd5138b72radhakrishna if(!(qdutils::MDPVersion::getInstance().is8x26() || 4740fdae193307fb17bb537598ab62682edd5138b72radhakrishna qdutils::MDPVersion::getInstance().is8x16())) 475ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson supported |= HWC_DISPLAY_EXTERNAL_BIT; 476ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 477ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson value[0] = supported; 478ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson break; 479a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson case HWC_FORMAT_RB_SWAP: 480a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson value[0] = 1; 481a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson break; 482a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson case HWC_COLOR_FILL: 483a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson value[0] = 1; 484a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson break; 485ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson default: 486ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return -EINVAL; 487ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 488ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return 0; 489ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 490ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 491ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 492ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 493ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_set_primary(hwc_context_t *ctx, hwc_display_contents_1_t* list) { 494ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ATRACE_CALL(); 495ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson int ret = 0; 496ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson const int dpy = HWC_DISPLAY_PRIMARY; 497ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if (LIKELY(list) && ctx->dpyAttr[dpy].isActive) { 498ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson uint32_t last = list->numHwLayers - 1; 499ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hwc_layer_1_t *fbLayer = &list->hwLayers[last]; 500ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson int fd = -1; //FenceFD from the Copybit(valid in async mode) 501ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson bool copybitDone = false; 502ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if(ctx->mCopyBit[dpy]) 503ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd); 504ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if(list->numHwLayers > 1) 505ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hwc_sync(ctx, list, dpy, fd); 506ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 507a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson // Dump the layers for primary 508a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(ctx->mHwcDebug[dpy]) 509a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ctx->mHwcDebug[dpy]->dumpLayers(list); 510a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 511201e4c9a80c1adb32ac8271a95721aa838c4d9feNaseer Ahmed if (!ctx->mMDPComp[dpy]->draw(ctx, list)) { 512ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ALOGE("%s: MDPComp draw failed", __FUNCTION__); 513ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ret = -1; 514ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 515ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 516ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson //TODO We dont check for SKIP flag on this layer because we need PAN 517ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson //always. Last layer is always FB 518ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson private_handle_t *hnd = (private_handle_t *)fbLayer->handle; 519a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(copybitDone && ctx->mMDP.version >= qdutils::MDP_V4_0) { 520ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer(); 521ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 522ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 523ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if(hnd) { 524ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) { 525ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ALOGE("%s: FBUpdate draw failed", __FUNCTION__); 526ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ret = -1; 527ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 528ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 529ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 530a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd, 531a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ctx->listStats[dpy].roi)) { 532a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ALOGE("%s: display commit fail for %d dpy!", __FUNCTION__, dpy); 533ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ret = -1; 534ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 535a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 536ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 537ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 538a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson closeAcquireFds(list); 539ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return ret; 540ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 541ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 542ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_set_external(hwc_context_t *ctx, 543a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson hwc_display_contents_1_t* list) 544ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{ 545ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ATRACE_CALL(); 546ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson int ret = 0; 547a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 548ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson const int dpy = HWC_DISPLAY_EXTERNAL; 549ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 550a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 551ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if (LIKELY(list) && ctx->dpyAttr[dpy].isActive && 552a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ctx->dpyAttr[dpy].connected && 553a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson !ctx->dpyAttr[dpy].isPause) { 554ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson uint32_t last = list->numHwLayers - 1; 555ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hwc_layer_1_t *fbLayer = &list->hwLayers[last]; 556ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson int fd = -1; //FenceFD from the Copybit(valid in async mode) 557ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson bool copybitDone = false; 558ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if(ctx->mCopyBit[dpy]) 559ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd); 560ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 561ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if(list->numHwLayers > 1) 562ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hwc_sync(ctx, list, dpy, fd); 563ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 564a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson // Dump the layers for external 565a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(ctx->mHwcDebug[dpy]) 566a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ctx->mHwcDebug[dpy]->dumpLayers(list); 567a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 568ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if (!ctx->mMDPComp[dpy]->draw(ctx, list)) { 569ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ALOGE("%s: MDPComp draw failed", __FUNCTION__); 570ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ret = -1; 571ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 572ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 573a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson int extOnlyLayerIndex = 574a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ctx->listStats[dpy].extOnlyLayerIndex; 575a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 576ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson private_handle_t *hnd = (private_handle_t *)fbLayer->handle; 577a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(extOnlyLayerIndex!= -1) { 578a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson hwc_layer_1_t *extLayer = &list->hwLayers[extOnlyLayerIndex]; 579a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson hnd = (private_handle_t *)extLayer->handle; 580a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson } else if(copybitDone) { 581ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer(); 582ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 583ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 584a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(hnd && !isYuvBuffer(hnd)) { 585ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) { 586ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__); 587ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ret = -1; 588ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 589ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 590ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 591a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) { 592a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ALOGE("%s: display commit fail for %d dpy!", __FUNCTION__, dpy); 593ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ret = -1; 594ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 595ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 596ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 597a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson closeAcquireFds(list); 598ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return ret; 599ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 600ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 601ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_set(hwc_composer_device_1 *dev, 602ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson size_t numDisplays, 603ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hwc_display_contents_1_t** displays) 604ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{ 605ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson int ret = 0; 606ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hwc_context_t* ctx = (hwc_context_t*)(dev); 607ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson for (uint32_t i = 0; i < numDisplays; i++) { 608ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hwc_display_contents_1_t* list = displays[i]; 609a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson int dpy = getDpyforExternalDisplay(ctx, i); 610a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson switch(dpy) { 611ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson case HWC_DISPLAY_PRIMARY: 612ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ret = hwc_set_primary(ctx, list); 613ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson break; 614ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson case HWC_DISPLAY_EXTERNAL: 615ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ret = hwc_set_external(ctx, list); 616ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson break; 617ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson case HWC_DISPLAY_VIRTUAL: 618a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(ctx->mHWCVirtual) 619a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ret = ctx->mHWCVirtual->set(ctx, list); 620ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson break; 621ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson default: 622ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ret = -EINVAL; 623ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 624ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 625ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson // This is only indicative of how many times SurfaceFlinger posts 626ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson // frames to the display. 627ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson CALC_FPS(); 628ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson MDPComp::resetIdleFallBack(); 629ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->mVideoTransFlag = false; 630a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(ctx->mRotMgr->getNumActiveSessions() == 0) 631a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson Overlay::setDMAMode(Overlay::DMA_LINE_MODE); 632ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson //Was locked at the beginning of prepare 633ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->mDrawLock.unlock(); 634ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return ret; 635ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 636ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 637ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonint hwc_getDisplayConfigs(struct hwc_composer_device_1* dev, int disp, 638ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson uint32_t* configs, size_t* numConfigs) { 639ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson int ret = 0; 640ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hwc_context_t* ctx = (hwc_context_t*)(dev); 641a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson disp = getDpyforExternalDisplay(ctx, disp); 642ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson //in 1.1 there is no way to choose a config, report as config id # 0 643ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson //This config is passed to getDisplayAttributes. Ignore for now. 644ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson switch(disp) { 645ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson case HWC_DISPLAY_PRIMARY: 646ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if(*numConfigs > 0) { 647ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson configs[0] = 0; 648ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson *numConfigs = 1; 649ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 650ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ret = 0; //NO_ERROR 651ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson break; 652ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson case HWC_DISPLAY_EXTERNAL: 653a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson case HWC_DISPLAY_VIRTUAL: 654ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ret = -1; //Not connected 655a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(ctx->dpyAttr[disp].connected) { 656ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ret = 0; //NO_ERROR 657ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if(*numConfigs > 0) { 658ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson configs[0] = 0; 659ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson *numConfigs = 1; 660ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 661ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 662ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson break; 663ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 664ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return ret; 665ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 666ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 667ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonint hwc_getDisplayAttributes(struct hwc_composer_device_1* dev, int disp, 668a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson uint32_t /*config*/, const uint32_t* attributes, int32_t* values) { 669ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 670ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hwc_context_t* ctx = (hwc_context_t*)(dev); 671a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson disp = getDpyforExternalDisplay(ctx, disp); 672a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson //If hotpluggable displays(i.e, HDMI, WFD) are inactive return error 673a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if( (disp != HWC_DISPLAY_PRIMARY) && !ctx->dpyAttr[disp].connected) { 674ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return -1; 675ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 676ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 677ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson //From HWComposer 678ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson static const uint32_t DISPLAY_ATTRIBUTES[] = { 679ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson HWC_DISPLAY_VSYNC_PERIOD, 680ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson HWC_DISPLAY_WIDTH, 681ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson HWC_DISPLAY_HEIGHT, 682ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson HWC_DISPLAY_DPI_X, 683ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson HWC_DISPLAY_DPI_Y, 684ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson HWC_DISPLAY_NO_ATTRIBUTE, 685ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson }; 686ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 687ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson const int NUM_DISPLAY_ATTRIBUTES = (sizeof(DISPLAY_ATTRIBUTES) / 688ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson sizeof(DISPLAY_ATTRIBUTES)[0]); 689ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 690ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson for (size_t i = 0; i < NUM_DISPLAY_ATTRIBUTES - 1; i++) { 691ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson switch (attributes[i]) { 692ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson case HWC_DISPLAY_VSYNC_PERIOD: 693ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson values[i] = ctx->dpyAttr[disp].vsync_period; 694ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson break; 695ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson case HWC_DISPLAY_WIDTH: 696ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson values[i] = ctx->dpyAttr[disp].xres; 697ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ALOGD("%s disp = %d, width = %d",__FUNCTION__, disp, 698ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->dpyAttr[disp].xres); 699ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson break; 700ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson case HWC_DISPLAY_HEIGHT: 701ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson values[i] = ctx->dpyAttr[disp].yres; 702ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ALOGD("%s disp = %d, height = %d",__FUNCTION__, disp, 703ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->dpyAttr[disp].yres); 704ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson break; 705ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson case HWC_DISPLAY_DPI_X: 706ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson values[i] = (int32_t) (ctx->dpyAttr[disp].xdpi*1000.0); 707ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson break; 708ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson case HWC_DISPLAY_DPI_Y: 709ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson values[i] = (int32_t) (ctx->dpyAttr[disp].ydpi*1000.0); 710ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson break; 711ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson default: 712ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ALOGE("Unknown display attribute %d", 713ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson attributes[i]); 714ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return -EINVAL; 715ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 716ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 717ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return 0; 718ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 719ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 720ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonvoid hwc_dump(struct hwc_composer_device_1* dev, char *buff, int buff_len) 721ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{ 722ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson hwc_context_t* ctx = (hwc_context_t*)(dev); 723ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson Locker::Autolock _l(ctx->mDrawLock); 724ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson android::String8 aBuf(""); 725ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson dumpsys_log(aBuf, "Qualcomm HWC state:\n"); 726ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson dumpsys_log(aBuf, " MDPVersion=%d\n", ctx->mMDP.version); 727ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson dumpsys_log(aBuf, " DisplayPanel=%c\n", ctx->mMDP.panel); 728a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson for(int dpy = 0; dpy < HWC_NUM_DISPLAY_TYPES; dpy++) { 729ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if(ctx->mMDPComp[dpy]) 730ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->mMDPComp[dpy]->dump(aBuf); 731ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 732ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson char ovDump[2048] = {'\0'}; 733ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->mOverlay->getDump(ovDump, 2048); 734ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson dumpsys_log(aBuf, ovDump); 735ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ovDump[0] = '\0'; 736ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ctx->mRotMgr->getDump(ovDump, 1024); 737ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson dumpsys_log(aBuf, ovDump); 738ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ovDump[0] = '\0'; 739ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if(Writeback::getDump(ovDump, 1024)) { 740ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson dumpsys_log(aBuf, ovDump); 741ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ovDump[0] = '\0'; 742ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 743ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson strlcpy(buff, aBuf.string(), buff_len); 744ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 745ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 746ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_device_close(struct hw_device_t *dev) 747ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{ 748ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if(!dev) { 749ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson ALOGE("%s: NULL device pointer", __FUNCTION__); 750ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return -1; 751ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 752ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson closeContext((hwc_context_t*)dev); 753ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson free(dev); 754ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 755ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return 0; 756ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 757ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 758ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_device_open(const struct hw_module_t* module, const char* name, 759ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson struct hw_device_t** device) 760ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{ 761ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson int status = -EINVAL; 762ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 763ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson if (!strcmp(name, HWC_HARDWARE_COMPOSER)) { 764ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson struct hwc_context_t *dev; 765ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson dev = (hwc_context_t*)malloc(sizeof(*dev)); 766a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(dev == NULL) 767a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson return status; 768ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson memset(dev, 0, sizeof(*dev)); 769ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 770ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson //Initialize hwc context 771ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson initContext(dev); 772ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson 773ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson //Setup HWC methods 774ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson dev->device.common.tag = HARDWARE_DEVICE_TAG; 775ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson dev->device.common.version = HWC_DEVICE_API_VERSION_1_3; 776ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson dev->device.common.module = const_cast<hw_module_t*>(module); 777ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson dev->device.common.close = hwc_device_close; 778ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson dev->device.prepare = hwc_prepare; 779ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson dev->device.set = hwc_set; 780ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson dev->device.eventControl = hwc_eventControl; 781ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson dev->device.blank = hwc_blank; 782ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson dev->device.query = hwc_query; 783ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson dev->device.registerProcs = hwc_registerProcs; 784ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson dev->device.dump = hwc_dump; 785ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson dev->device.getDisplayConfigs = hwc_getDisplayConfigs; 786ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson dev->device.getDisplayAttributes = hwc_getDisplayAttributes; 787ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson *device = &dev->device.common; 788ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson status = 0; 789ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson } 790ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson return status; 791ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson} 792