blob: c94a5c6c51d0d0d017b1b9c2d15ff56a417c7007 [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"
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070051
52using namespace android;
53
54namespace qhwc {
55
56#define MAX_SYSFS_FILE_PATH 255
57
58int VirtualDisplay::configure() {
59 if(!openFrameBuffer())
60 return -1;
61
62 if(ioctl(mFd, FBIOGET_VSCREENINFO, &mVInfo) < 0) {
63 ALOGD("%s: FBIOGET_VSCREENINFO failed with %s", __FUNCTION__,
64 strerror(errno));
65 return -1;
66 }
67 setAttributes();
68 return 0;
69}
70
Amara Venkata Mastan Manoj Kumar376d8a82013-03-13 19:18:47 -070071void VirtualDisplay::getAttributes(int& width, int& height) {
72 width = mVInfo.xres;
73 height = mVInfo.yres;
74}
75
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070076int VirtualDisplay::teardown() {
77 closeFrameBuffer();
78 memset(&mVInfo, 0, sizeof(mVInfo));
Tatenda Chipeperekwa3368d082013-08-30 14:03:15 -070079 // Reset the resolution when we close the fb for this device. We need
80 // this to distinguish between an ONLINE and RESUME event.
81 mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].xres = 0;
82 mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].yres = 0;
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070083 return 0;
84}
85
86VirtualDisplay::VirtualDisplay(hwc_context_t* ctx):mFd(-1),
87 mHwcContext(ctx)
88{
89 memset(&mVInfo, 0, sizeof(mVInfo));
90}
91
92VirtualDisplay::~VirtualDisplay()
93{
94 closeFrameBuffer();
95}
96
97void VirtualDisplay::setAttributes() {
Amara Venkata Mastan Manoj Kumar376d8a82013-03-13 19:18:47 -070098 if(mHwcContext) {
Tatenda Chipeperekwa3368d082013-08-30 14:03:15 -070099 unsigned int &w = mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].xres;
100 unsigned int &h = mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].yres;
101
102 // Always set dpyAttr res to mVInfo res, only on an ONLINE event. Keep
103 // the original configuration to cater for DRC initiated RESUME events
104 if(w == 0 || h == 0){
105 w = mVInfo.xres;
106 h = mVInfo.yres;
107 }
Amara Venkata Mastan Manoj Kumar376d8a82013-03-13 19:18:47 -0700108 mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].mDownScaleMode = false;
Tatenda Chipeperekwa3368d082013-08-30 14:03:15 -0700109
Amara Venkata Mastan Manoj Kumar376d8a82013-03-13 19:18:47 -0700110 if(!qdutils::MDPVersion::getInstance().is8x26()) {
111 uint32_t priW = mHwcContext->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
112 uint32_t priH = mHwcContext->dpyAttr[HWC_DISPLAY_PRIMARY].yres;
Tatenda Chipeperekwa3368d082013-08-30 14:03:15 -0700113
114 // Find the maximum resolution between primary and virtual
115 uint32_t maxArea = max((w * h), (priW * priH));
116
117 // If primary resolution is more than the wfd resolution
Amara Venkata Mastan Manoj Kumar376d8a82013-03-13 19:18:47 -0700118 // configure dpy attr to primary resolution and set
Tatenda Chipeperekwa3368d082013-08-30 14:03:15 -0700119 // downscale mode.
120 // DRC is only valid when the original resolution on the WiFi
121 // display is greater than the new resolution in mVInfo.
122 if(maxArea > (mVInfo.xres * mVInfo.yres)) {
123 if(maxArea == (priW * priH)) {
124 // Here we account for the case when primary resolution is
125 // greater than that of the WiFi display
126 w = priW;
127 h = priH;
128 // WFD is always in landscape, so always assign the higher
129 // dimension to wfd's xres
130 if(priH > priW) {
131 w = priH;
132 h = priW;
133 }
Amara Venkata Mastan Manoj Kumar376d8a82013-03-13 19:18:47 -0700134 }
135 // Set External Display MDP Downscale mode indicator
136 mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].mDownScaleMode = true;
137 }
138 }
139 mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].vsync_period =
140 1000000000l /60;
141 ALOGD_IF(DEBUG,"%s: Setting Virtual Attr: res(%d x %d)",__FUNCTION__,
142 mVInfo.xres, mVInfo.yres);
143 }
Jeykumar Sankaran27dee262013-08-01 17:09:54 -0700144}
145
146bool VirtualDisplay::openFrameBuffer()
147{
148 if (mFd == -1) {
149 int fbNum = overlay::Overlay::getInstance()->
150 getFbForDpy(HWC_DISPLAY_VIRTUAL);
151
152 char strDevPath[MAX_SYSFS_FILE_PATH];
153 sprintf(strDevPath,"/dev/graphics/fb%d", fbNum);
154
155 mFd = open(strDevPath, O_RDWR);
156 if(mFd < 0) {
157 ALOGE("%s: Unable to open %s ", __FUNCTION__,strDevPath);
158 return -1;
159 }
160
161 mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].fd = mFd;
162 }
163 return 1;
164}
165
166bool VirtualDisplay::closeFrameBuffer()
167{
168 if(mFd >= 0) {
169 if(close(mFd) < 0 ) {
170 ALOGE("%s: Unable to close FD(%d)", __FUNCTION__, mFd);
171 return -1;
172 }
173 mFd = -1;
174 mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].fd = mFd;
175 }
176 return 1;
177}
178};