blob: 38e3ab2051a7d7d79f6288638d623055e3507c53 [file] [log] [blame]
Naseer Ahmed29a26812012-06-14 00:56:20 -07001/*
2* Copyright (c) 2011-2012, Code Aurora Forum. 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 Code Aurora Forum, Inc. 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#include <stdlib.h>
31#include <utils/Log.h>
32#include <linux/msm_mdp.h>
33#include <cutils/properties.h>
34#include "gralloc_priv.h"
35#include "fb_priv.h"
36#include "overlayUtils.h"
37#include "mdpWrapper.h"
38
39// just a helper static thingy
40namespace {
41struct IOFile {
42 IOFile(const char* s, const char* mode) : fp(0) {
43 fp = ::fopen(s, mode);
44 if(!fp) {
45 ALOGE("Failed open %s", s);
46 }
47 }
48 template <class T>
49 size_t read(T& r, size_t elem) {
50 if(fp) {
51 return ::fread(&r, sizeof(T), elem, fp);
52 }
53 return 0;
54 }
55 size_t write(const char* s, uint32_t val) {
56 if(fp) {
57 return ::fprintf(fp, s, val);
58 }
59 return 0;
60 }
61 bool valid() const { return fp != 0; }
62 ~IOFile() {
63 if(fp) ::fclose(fp);
64 fp=0;
65 }
66 FILE* fp;
67};
68}
69
70namespace overlay {
71
72//----------From class Res ------------------------------
73const char* const Res::devTemplate = "/dev/graphics/fb%u";
74const char* const Res::rotPath = "/dev/msm_rotator";
75const char* const Res::format3DFile =
76 "/sys/class/graphics/fb1/format_3d";
77const char* const Res::edid3dInfoFile =
78 "/sys/class/graphics/fb1/3d_present";
79const char* const Res::barrierFile =
80 "/sys/devices/platform/mipi_novatek.0/enable_3d_barrier";
81//--------------------------------------------------------
82
83
84
85namespace utils {
86//--------------------------------------------------------
87FrameBufferInfo::FrameBufferInfo() {
88 mFBWidth = 0;
89 mFBHeight = 0;
90 mBorderFillSupported = false;
91
92 OvFD mFd;
93
94 // Use open defined in overlayFD file to open fd for fb0
95 if(!overlay::open(mFd, 0, Res::devTemplate)) {
96 ALOGE("FrameBufferInfo: failed to open fd");
97 return;
98 }
99
100 if (!mFd.valid()) {
101 ALOGE("FrameBufferInfo: FD not valid");
102 return;
103 }
104
105 fb_var_screeninfo vinfo;
106 if (!mdp_wrapper::getVScreenInfo(mFd.getFD(), vinfo)) {
107 ALOGE("FrameBufferInfo: failed getVScreenInfo on fb0");
108 mFd.close();
109 return;
110 }
111
112 mdp_overlay ov;
113 memset(&ov, 0, sizeof(ov));
114 ov.id = 1;
115 if (!mdp_wrapper::getOverlay(mFd.getFD(), ov)) {
116 ALOGE("FrameBufferInfo: failed getOverlay on fb0");
117 mFd.close();
118 return;
119 }
120
121 mFd.close();
122
123 mFBWidth = vinfo.xres;
124 mFBHeight = vinfo.yres;
125 mBorderFillSupported = (ov.flags & MDP_BORDERFILL_SUPPORTED) ?
126 true : false;
127}
128
129FrameBufferInfo* FrameBufferInfo::getInstance() {
130 if (!sFBInfoInstance) {
131 sFBInfoInstance = new FrameBufferInfo;
132 }
133 return sFBInfoInstance;
134}
135
136int FrameBufferInfo::getWidth() const {
137 return mFBWidth;
138}
139
140int FrameBufferInfo::getHeight() const {
141 return mFBHeight;
142}
143
144bool FrameBufferInfo::supportTrueMirroring() const {
145 return mBorderFillSupported;
146}
147
148//--------------------------------------------------------
149uint32_t getSize(const Whf& whf) {
150 int aligned_height=0, pitch=0;
151
152 uint32_t size = whf.w * whf.h;
153 switch (whf.format) {
154 case MDP_RGBA_8888:
155 case MDP_BGRA_8888:
156 case MDP_RGBX_8888:
157 size *= 4;
158 break;
159 case MDP_RGB_565:
160 case MDP_Y_CBCR_H2V1:
161 size *= 2;
162 break;
163 case MDP_Y_CBCR_H2V2:
164 case MDP_Y_CRCB_H2V2:
165 size = (size * 3) / 2;
166 break;
167 case MDP_Y_CRCB_H2V2_TILE:
168 case MDP_Y_CBCR_H2V2_TILE:
169 aligned_height = align(whf.h , 32);
170 pitch = align(whf.w, 128);
171 size = pitch * aligned_height;
172 size = align(size, 8192);
173
174 aligned_height = align(whf.h >> 1, 32);
175 size += pitch * aligned_height;
176 size = align(size, 8192);
177 break;
178 default:
179 ALOGE("getSize unknown format %d", whf.format);
180 return 0;
181 }
182 return size;
183}
184
185int getMdpFormat(int format) {
186 switch (format) {
187 case HAL_PIXEL_FORMAT_RGBA_8888 :
188 return MDP_RGBA_8888;
189 case HAL_PIXEL_FORMAT_BGRA_8888:
190 return MDP_BGRA_8888;
191 case HAL_PIXEL_FORMAT_RGB_565:
192 return MDP_RGB_565;
193 case HAL_PIXEL_FORMAT_RGBX_8888:
194 return MDP_RGBX_8888;
195 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
196 return MDP_Y_CBCR_H2V1;
197 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
198 return MDP_Y_CRCB_H2V1;
199 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
200 return MDP_Y_CBCR_H2V2;
201 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
202 return MDP_Y_CRCB_H2V2;
203 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
204 return MDP_Y_CBCR_H2V2_TILE;
205 case HAL_PIXEL_FORMAT_YV12:
206 return MDP_Y_CR_CB_H2V2;
207 default:
208 ALOGE("Error getMdpFormat format=%d", format);
209 return -1;
210 }
211 // not reached
212 return -1;
213}
214
215bool isHDMIConnected () {
216 char value[PROPERTY_VALUE_MAX] = {0};
217 property_get("hw.hdmiON", value, "0");
218 int isHDMI = atoi(value);
219 return isHDMI ? true : false;
220}
221
222bool is3DTV() {
223 char is3DTV = '0';
224 IOFile fp(Res::edid3dInfoFile, "r");
225 (void)fp.read(is3DTV, 1);
226 ALOGI("3DTV EDID flag: %d", is3DTV);
227 return (is3DTV == '0') ? false : true;
228}
229
230bool isPanel3D() {
231 OvFD fd;
232 if(!overlay::open(fd, 0 /*fb*/, Res::devTemplate)){
233 ALOGE("isPanel3D Can't open framebuffer 0");
234 return false;
235 }
236 fb_fix_screeninfo finfo;
237 if(!mdp_wrapper::getFScreenInfo(fd.getFD(), finfo)) {
238 ALOGE("isPanel3D read fb0 failed");
239 }
240 fd.close();
241 return (FB_TYPE_3D_PANEL == finfo.type) ? true : false;
242}
243
244bool usePanel3D() {
245 if(!isPanel3D())
246 return false;
247 char value[PROPERTY_VALUE_MAX];
248 property_get("persist.user.panel3D", value, "0");
249 int usePanel3D = atoi(value);
250 return usePanel3D ? true : false;
251}
252
253bool send3DInfoPacket (uint32_t format3D) {
254 IOFile fp(Res::format3DFile, "wb");
255 (void)fp.write("%d", format3D);
256 if(!fp.valid()) {
257 ALOGE("send3DInfoPacket: no sysfs entry for setting 3d mode");
258 return false;
259 }
260 return true;
261}
262
263bool enableBarrier (uint32_t orientation) {
264 IOFile fp(Res::barrierFile, "wb");
265 (void)fp.write("%d", orientation);
266 if(!fp.valid()) {
267 ALOGE("enableBarrier no sysfs entry for "
268 "enabling barriers on 3D panel");
269 return false;
270 }
271 return true;
272}
273
274uint32_t getS3DFormat(uint32_t fmt) {
275 // The S3D is part of the HAL_PIXEL_FORMAT_YV12 value. Add
276 // an explicit check for the format
277 if (fmt == HAL_PIXEL_FORMAT_YV12) {
278 return 0;
279 }
280 uint32_t fmt3D = format3D(fmt);
281 uint32_t fIn3D = format3DInput(fmt3D); // MSB 2 bytes - inp
282 uint32_t fOut3D = format3DOutput(fmt3D); // LSB 2 bytes - out
283 fmt3D = fIn3D | fOut3D;
284 if (!fIn3D) {
285 fmt3D |= fOut3D << SHIFT_TOT_3D; //Set the input format
286 }
287 if (!fOut3D) {
288 switch (fIn3D) {
289 case HAL_3D_IN_SIDE_BY_SIDE_L_R:
290 case HAL_3D_IN_SIDE_BY_SIDE_R_L:
291 // For all side by side formats, set the output
292 // format as Side-by-Side i.e 0x1
293 fmt3D |= HAL_3D_IN_SIDE_BY_SIDE_L_R >> SHIFT_TOT_3D;
294 break;
295 default:
296 fmt3D |= fIn3D >> SHIFT_TOT_3D; //Set the output format
297 }
298 }
299 return fmt3D;
300}
301
302void normalizeCrop(uint32_t& xy, uint32_t& wh) {
303 if (xy & 0x0001) {
304 // x or y is odd, increment it's value
305 xy += 1;
306 // Since we've incremented x(y), we need to decrement
307 // w(h) accordingly
308 if (wh & 0x0001) {
309 // w or h is odd, decrement it by 1, to make it even
310 even_out(wh);
311 } else {
312 // w(h) is already even, hence we decrement by 2
313 wh -=2;
314 }
315 } else {
316 even_out(wh);
317 }
318}
319
320void scale(mdp_overlay& ov)
321{
322 /* Scaling of upto a max of 8 times supported */
323 overlay::utils::Dim dst(overlay::utils::getDstRectDim(ov));
324 overlay::utils::Dim src(overlay::utils::getSrcRectDim(ov));
325 if(dst.w >(src.w * overlay::utils::HW_OV_MAGNIFICATION_LIMIT)) {
326 dst.w = overlay::utils::HW_OV_MAGNIFICATION_LIMIT * src.w;
327 }
328 if(dst.h >(src.h * overlay::utils::HW_OV_MAGNIFICATION_LIMIT)) {
329 dst.h = overlay::utils::HW_OV_MAGNIFICATION_LIMIT * src.h;
330 }
331
332 setDstRectDim(dst, ov);
333}
334
335} // utils
336
337} // overlay