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