1a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson/* 2a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson* Copyright (c) 2013 The Linux Foundation. All rights reserved. 3a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson* 4a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson* Redistribution and use in source and binary forms, with or without 5a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson* modification, are permitted provided that the following conditions are 6a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson* met: 7a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson* * Redistributions of source code must retain the above copyright 8a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson* notice, this list of conditions and the following disclaimer. 9a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson* * Redistributions in binary form must reproduce the above 10a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson* copyright notice, this list of conditions and the following 11a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson* disclaimer in the documentation and/or other materials provided 12a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson* with the distribution. 13a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson* * Neither the name of The Linux Foundation. nor the names of its 14a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson* contributors may be used to endorse or promote products derived 15a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson* from this software without specific prior written permission. 16a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson* 17a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson*/ 29a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 30a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 31a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson#define DEBUG 0 32a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson#include <ctype.h> 33a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson#include <fcntl.h> 34a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson#include <media/IAudioPolicyService.h> 35a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson#include <media/AudioSystem.h> 36a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson#include <utils/threads.h> 37a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson#include <utils/Errors.h> 38a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson#include <utils/Log.h> 39a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 40a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson#include <linux/msm_mdp.h> 41a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson#include <linux/fb.h> 42a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson#include <sys/ioctl.h> 43a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson#include <sys/poll.h> 44a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson#include <sys/resource.h> 45a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson#include <cutils/properties.h> 46a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson#include "hwc_utils.h" 47a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson#include "virtual.h" 48a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson#include "overlayUtils.h" 49a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson#include "overlay.h" 50a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson#include "mdp_version.h" 5131f8c0d6a416c0c2a685cac101430d2a47840356Tatenda Chipeperekwa#include "qd_utils.h" 52a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 53a653efede03423aa840da24634f1ec6f20796f1eSimon Wilsonusing namespace android; 54a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 55a653efede03423aa840da24634f1ec6f20796f1eSimon Wilsonnamespace qhwc { 56a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 57a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson#define MAX_SYSFS_FILE_PATH 255 58a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 59a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson/* Max. resolution assignable to virtual display. */ 60a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson#define SUPPORTED_VIRTUAL_AREA (1920*1080) 61a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 62a653efede03423aa840da24634f1ec6f20796f1eSimon Wilsonint VirtualDisplay::configure() { 63a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(!openFrameBuffer()) 64a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson return -1; 65a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 66a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(ioctl(mFd, FBIOGET_VSCREENINFO, &mVInfo) < 0) { 67a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ALOGD("%s: FBIOGET_VSCREENINFO failed with %s", __FUNCTION__, 68a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson strerror(errno)); 69a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson return -1; 70a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson } 71a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson setAttributes(); 72a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson return 0; 73a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson} 74a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 75a653efede03423aa840da24634f1ec6f20796f1eSimon Wilsonvoid VirtualDisplay::getAttributes(int& width, int& height) { 76a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson width = mVInfo.xres; 77a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson height = mVInfo.yres; 78a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson} 79a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 80a653efede03423aa840da24634f1ec6f20796f1eSimon Wilsonint VirtualDisplay::teardown() { 81a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson closeFrameBuffer(); 82a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson memset(&mVInfo, 0, sizeof(mVInfo)); 83a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson // Reset the resolution when we close the fb for this device. We need 84a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson // this to distinguish between an ONLINE and RESUME event. 85a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].xres = 0; 86a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].yres = 0; 87a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson return 0; 88a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson} 89a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 90a653efede03423aa840da24634f1ec6f20796f1eSimon WilsonVirtualDisplay::VirtualDisplay(hwc_context_t* ctx):mFd(-1), 91a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson mHwcContext(ctx) 92a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson{ 93a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson memset(&mVInfo, 0, sizeof(mVInfo)); 94a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson} 95a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 96a653efede03423aa840da24634f1ec6f20796f1eSimon WilsonVirtualDisplay::~VirtualDisplay() 97a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson{ 98a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson closeFrameBuffer(); 99a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson} 100a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 101a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson/* Initializes the resolution attributes of the virtual display 102a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson that are reported to SurfaceFlinger. 103a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson Cases: 104a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 1. ONLINE event - initialize to frame buffer resolution 105a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 2. RESUME event - retain original resolution 106a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson*/ 107a653efede03423aa840da24634f1ec6f20796f1eSimon Wilsonvoid VirtualDisplay::initResolution(uint32_t &extW, uint32_t &extH) { 108a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson // On ONLINE event, display resolution attributes are 0. 109a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(extW == 0 || extH == 0){ 110a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson extW = mVInfo.xres; 111a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson extH = mVInfo.yres; 112a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson } 113a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson} 114a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 115a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson/* Sets the virtual resolution to match that of the primary 116a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson display in the event that the virtual display currently 117a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson connected has a lower resolution. NB: we always report the 118a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson highest available resolution to SurfaceFlinger. 119a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson*/ 120a653efede03423aa840da24634f1ec6f20796f1eSimon Wilsonvoid VirtualDisplay::setToPrimary(uint32_t maxArea, 121a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson uint32_t priW, 122a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson uint32_t priH, 123a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson uint32_t &extW, 124a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson uint32_t &extH) { 125a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson // for eg., primary in 1600p and WFD in 1080p 126a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson // we wont use downscale feature because MAX MDP 127a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson // writeback resolution supported is 1080p (tracked 128a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson // by SUPPORTED_VIRTUAL_AREA). 129a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if((maxArea == (priW * priH)) 130a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson && (maxArea <= SUPPORTED_VIRTUAL_AREA)) { 13131f8c0d6a416c0c2a685cac101430d2a47840356Tatenda Chipeperekwa // tmpW and tmpH will hold the primary dimensions before we 13231f8c0d6a416c0c2a685cac101430d2a47840356Tatenda Chipeperekwa // update the aspect ratio if necessary. 13331f8c0d6a416c0c2a685cac101430d2a47840356Tatenda Chipeperekwa uint32_t tmpW = priW; 13431f8c0d6a416c0c2a685cac101430d2a47840356Tatenda Chipeperekwa uint32_t tmpH = priH; 135a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson // If WFD is in landscape, assign the higher dimension 136a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson // to WFD's xres. 137a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(priH > priW) { 13831f8c0d6a416c0c2a685cac101430d2a47840356Tatenda Chipeperekwa tmpW = priH; 13931f8c0d6a416c0c2a685cac101430d2a47840356Tatenda Chipeperekwa tmpH = priW; 140a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson } 14131f8c0d6a416c0c2a685cac101430d2a47840356Tatenda Chipeperekwa // The aspect ratios of the external and primary displays 14231f8c0d6a416c0c2a685cac101430d2a47840356Tatenda Chipeperekwa // can be different. As a result, directly assigning primary 14331f8c0d6a416c0c2a685cac101430d2a47840356Tatenda Chipeperekwa // resolution could lead to an incorrect final image. 14431f8c0d6a416c0c2a685cac101430d2a47840356Tatenda Chipeperekwa // We get around this by calculating a new resolution by 14531f8c0d6a416c0c2a685cac101430d2a47840356Tatenda Chipeperekwa // keeping aspect ratio intact. 14631f8c0d6a416c0c2a685cac101430d2a47840356Tatenda Chipeperekwa hwc_rect r = {0, 0, 0, 0}; 14731f8c0d6a416c0c2a685cac101430d2a47840356Tatenda Chipeperekwa getAspectRatioPosition(tmpW, tmpH, extW, extH, r); 14831f8c0d6a416c0c2a685cac101430d2a47840356Tatenda Chipeperekwa extW = r.right - r.left; 14931f8c0d6a416c0c2a685cac101430d2a47840356Tatenda Chipeperekwa extH = r.bottom - r.top; 150a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson } 151a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson} 152a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 153a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson/* Set External Display MDP Downscale mode indicator. Only set to 154a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson TRUE for the following scenarios: 155a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 1. Valid DRC scenarios i.e. when the original WFD resolution 156a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson is greater than the new/requested resolution in mVInfo. 157a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 2. WFD down scale path i.e. when WFD resolution is lower than 158a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson primary resolution. 159a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson Furthermore, downscale mode is only valid when downscaling from 160a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson SUPPORTED_VIRTUAL_AREA to a lower resolution. 161a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson (SUPPORTED_VIRTUAL_AREA represents the maximum resolution that 162a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson we can configure to the virtual display) 163a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson*/ 164a653efede03423aa840da24634f1ec6f20796f1eSimon Wilsonvoid VirtualDisplay::setDownScaleMode(uint32_t maxArea) { 165a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if((maxArea > (mVInfo.xres * mVInfo.yres)) 166a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson && (maxArea <= SUPPORTED_VIRTUAL_AREA)) { 167a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].mDownScaleMode = true; 168a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson }else { 169a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].mDownScaleMode = false; 170a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson } 171a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson} 172a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 173a653efede03423aa840da24634f1ec6f20796f1eSimon Wilsonvoid VirtualDisplay::setAttributes() { 174a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(mHwcContext) { 175a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson uint32_t &extW = mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].xres; 176a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson uint32_t &extH = mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].yres; 177a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson uint32_t priW = mHwcContext->dpyAttr[HWC_DISPLAY_PRIMARY].xres; 178a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson uint32_t priH = mHwcContext->dpyAttr[HWC_DISPLAY_PRIMARY].yres; 179a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 180a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson initResolution(extW, extH); 181a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 18257ca59ccafa0efa6fb8f5684e90777bbeb6f92c7Tatenda Chipeperekwa // Dynamic Resolution Change depends on MDP downscaling. 18357ca59ccafa0efa6fb8f5684e90777bbeb6f92c7Tatenda Chipeperekwa // MDP downscale property will be ignored to exercise DRC use case. 18457ca59ccafa0efa6fb8f5684e90777bbeb6f92c7Tatenda Chipeperekwa // If DRC is in progress, ext WxH will have non-zero values. 18557ca59ccafa0efa6fb8f5684e90777bbeb6f92c7Tatenda Chipeperekwa bool isDRC = (extW > 0) && (extH > 0); 18657ca59ccafa0efa6fb8f5684e90777bbeb6f92c7Tatenda Chipeperekwa 18757ca59ccafa0efa6fb8f5684e90777bbeb6f92c7Tatenda Chipeperekwa if(!qdutils::MDPVersion::getInstance().is8x26() 18857ca59ccafa0efa6fb8f5684e90777bbeb6f92c7Tatenda Chipeperekwa && (mHwcContext->mMDPDownscaleEnabled || isDRC)) { 189a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 190a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson // maxArea represents the maximum resolution between 191a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson // primary and virtual display. 192a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson uint32_t maxArea = max((extW * extH), (priW * priH)); 193a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 194a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson setToPrimary(maxArea, priW, priH, extW, extH); 195a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 196a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson setDownScaleMode(maxArea); 197a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson } 198a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].vsync_period = 199a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 1000000000l /60; 200a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ALOGD_IF(DEBUG,"%s: Setting Virtual Attr: res(%d x %d)",__FUNCTION__, 201a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson mVInfo.xres, mVInfo.yres); 202a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson } 203a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson} 204a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 205a653efede03423aa840da24634f1ec6f20796f1eSimon Wilsonbool VirtualDisplay::openFrameBuffer() 206a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson{ 207a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if (mFd == -1) { 208a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson int fbNum = overlay::Overlay::getInstance()-> 209a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson getFbForDpy(HWC_DISPLAY_VIRTUAL); 210a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 211a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson char strDevPath[MAX_SYSFS_FILE_PATH]; 212a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson snprintf(strDevPath,sizeof(strDevPath), "/dev/graphics/fb%d", fbNum); 213a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 214a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson mFd = open(strDevPath, O_RDWR); 215a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(mFd < 0) { 216a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ALOGE("%s: Unable to open %s ", __FUNCTION__,strDevPath); 217a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson return -1; 218a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson } 219a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 220a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].fd = mFd; 221a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson } 222a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson return 1; 223a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson} 224a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson 225a653efede03423aa840da24634f1ec6f20796f1eSimon Wilsonbool VirtualDisplay::closeFrameBuffer() 226a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson{ 227a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(mFd >= 0) { 228a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson if(close(mFd) < 0 ) { 229a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson ALOGE("%s: Unable to close FD(%d)", __FUNCTION__, mFd); 230a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson return -1; 231a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson } 232a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson mFd = -1; 233a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].fd = mFd; 234a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson } 235a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson return 1; 236a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson} 237a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson}; 238