blob: 8cc9cc0632ab69be39010ace7019d22de65eb42d [file] [log] [blame]
Naseer Ahmed29a26812012-06-14 00:56:20 -07001/*
Naseer Ahmed758bfc52012-11-28 17:02:08 -05002* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
Naseer Ahmed29a26812012-06-14 00:56:20 -07003*
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.
Naseer Ahmed758bfc52012-11-28 17:02:08 -050013* * Neither the name of The Linux Foundation nor the names of its
Naseer Ahmed29a26812012-06-14 00:56:20 -070014* 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"
Naseer Ahmed29a26812012-06-14 00:56:20 -070035#include "overlayUtils.h"
36#include "mdpWrapper.h"
Saurabh Shah94822ee2012-08-17 16:48:43 -070037#include "mdp_version.h"
Naseer Ahmed29a26812012-06-14 00:56:20 -070038
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 ------------------------------
Naseer Ahmedf48aef62012-07-20 09:05:53 -070073const char* const Res::fbPath = "/dev/graphics/fb%u";
Naseer Ahmed29a26812012-06-14 00:56:20 -070074const 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 {
Ajay Dudanicb3da0a2012-09-07 13:37:49 -070086
Naseer Ahmed29a26812012-06-14 00:56:20 -070087//--------------------------------------------------------
Naseer Ahmedaf49e212012-07-31 19:13:41 -070088//Refer to graphics.h, gralloc_priv.h, msm_mdp.h
Naseer Ahmed29a26812012-06-14 00:56:20 -070089int getMdpFormat(int format) {
90 switch (format) {
Naseer Ahmedaf49e212012-07-31 19:13:41 -070091 //From graphics.h
Naseer Ahmed29a26812012-06-14 00:56:20 -070092 case HAL_PIXEL_FORMAT_RGBA_8888 :
93 return MDP_RGBA_8888;
Naseer Ahmed29a26812012-06-14 00:56:20 -070094 case HAL_PIXEL_FORMAT_RGBX_8888:
95 return MDP_RGBX_8888;
Naseer Ahmedaf49e212012-07-31 19:13:41 -070096 case HAL_PIXEL_FORMAT_RGB_888:
97 return MDP_RGB_888;
98 case HAL_PIXEL_FORMAT_RGB_565:
99 return MDP_RGB_565;
100 case HAL_PIXEL_FORMAT_BGRA_8888:
101 return MDP_BGRA_8888;
Naseer Ahmed29a26812012-06-14 00:56:20 -0700102 case HAL_PIXEL_FORMAT_YV12:
Saurabh Shahae1044e2012-08-21 16:03:32 -0700103 return MDP_Y_CR_CB_GH2V2;
Naseer Ahmedaf49e212012-07-31 19:13:41 -0700104 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
105 return MDP_Y_CBCR_H2V1;
106 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
107 return MDP_Y_CRCB_H2V2;
108
109 //From gralloc_priv.h
110 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
111 return MDP_Y_CBCR_H2V2_TILE;
112 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
113 return MDP_Y_CBCR_H2V2;
114 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
115 return MDP_Y_CRCB_H2V1;
116 case HAL_PIXEL_FORMAT_YCbCr_444_SP:
117 return MDP_Y_CBCR_H1V1;
118 case HAL_PIXEL_FORMAT_YCrCb_444_SP:
119 return MDP_Y_CRCB_H1V1;
Sushil Chauhanc5e61482012-08-22 17:13:32 -0700120 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
121 return MDP_Y_CBCR_H2V2_VENUS;
Naseer Ahmed29a26812012-06-14 00:56:20 -0700122 default:
Naseer Ahmedaf49e212012-07-31 19:13:41 -0700123 //Unsupported by MDP
124 //---graphics.h--------
125 //HAL_PIXEL_FORMAT_RGBA_5551
126 //HAL_PIXEL_FORMAT_RGBA_4444
127 //HAL_PIXEL_FORMAT_YCbCr_422_I
128 //---gralloc_priv.h-----
129 //HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO = 0x7FA30C01
130 //HAL_PIXEL_FORMAT_R_8 = 0x10D
131 //HAL_PIXEL_FORMAT_RG_88 = 0x10E
Saurabh Shahfc3652f2013-02-15 13:15:45 -0800132 ALOGE("%s: Unsupported HAL format = 0x%x", __func__, format);
133 return -1;
134 }
135 // not reached
136 return -1;
137}
138
139//Takes mdp format as input and translates to equivalent HAL format
140//Refer to graphics.h, gralloc_priv.h, msm_mdp.h for formats.
141int getHALFormat(int mdpFormat) {
142 switch (mdpFormat) {
143 //From graphics.h
144 case MDP_RGBA_8888:
145 return HAL_PIXEL_FORMAT_RGBA_8888;
146 case MDP_RGBX_8888:
147 return HAL_PIXEL_FORMAT_RGBX_8888;
148 case MDP_RGB_888:
149 return HAL_PIXEL_FORMAT_RGB_888;
150 case MDP_RGB_565:
151 return HAL_PIXEL_FORMAT_RGB_565;
152 case MDP_BGRA_8888:
153 return HAL_PIXEL_FORMAT_BGRA_8888;
154 case MDP_Y_CR_CB_GH2V2:
155 return HAL_PIXEL_FORMAT_YV12;
156 case MDP_Y_CBCR_H2V1:
157 return HAL_PIXEL_FORMAT_YCbCr_422_SP;
158 case MDP_Y_CRCB_H2V2:
159 return HAL_PIXEL_FORMAT_YCrCb_420_SP;
160
161 //From gralloc_priv.h
162 case MDP_Y_CBCR_H2V2_TILE:
163 return HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED;
164 case MDP_Y_CBCR_H2V2:
165 return HAL_PIXEL_FORMAT_YCbCr_420_SP;
166 case MDP_Y_CRCB_H2V1:
167 return HAL_PIXEL_FORMAT_YCrCb_422_SP;
168 case MDP_Y_CBCR_H1V1:
169 return HAL_PIXEL_FORMAT_YCbCr_444_SP;
170 case MDP_Y_CRCB_H1V1:
171 return HAL_PIXEL_FORMAT_YCrCb_444_SP;
172 case MDP_Y_CBCR_H2V2_VENUS:
173 return HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS;
174 default:
175 ALOGE("%s: Unsupported MDP format = 0x%x", __func__, mdpFormat);
Naseer Ahmed29a26812012-06-14 00:56:20 -0700176 return -1;
177 }
178 // not reached
179 return -1;
180}
181
Saurabh Shahacf10202013-02-26 10:15:15 -0800182int getDownscaleFactor(const int& src_w, const int& src_h,
183 const int& dst_w, const int& dst_h) {
184 int dscale_factor = utils::ROT_DS_NONE;
185 // We need this check to engage the rotator whenever possible to assist MDP
186 // in performing video downscale.
187 // This saves bandwidth and avoids causing the driver to make too many panel
188 // -mode switches between BLT (writeback) and non-BLT (Direct) modes.
189 // Use-case: Video playback [with downscaling and rotation].
190 if (dst_w && dst_h)
191 {
192 uint32_t dscale = (src_w * src_h) / (dst_w * dst_h);
193 if(dscale < 2) {
194 // Down-scale to > 50% of orig.
195 dscale_factor = utils::ROT_DS_NONE;
196 } else if(dscale < 4) {
197 // Down-scale to between > 25% to <= 50% of orig.
198 dscale_factor = utils::ROT_DS_HALF;
199 } else if(dscale < 8) {
200 // Down-scale to between > 12.5% to <= 25% of orig.
201 dscale_factor = utils::ROT_DS_FOURTH;
202 } else {
203 // Down-scale to <= 12.5% of orig.
204 dscale_factor = utils::ROT_DS_EIGHTH;
205 }
206 }
207 return dscale_factor;
208}
209
210static inline int compute(const uint32_t& x, const uint32_t& y,
211 const uint32_t& z) {
212 return x - ( y + z );
213}
214
Saurabh Shah76fd6552013-03-14 14:45:38 -0700215//Expects transform to be adjusted for clients of Android.
216//i.e flips switched if 90 component present.
217//See getMdpOrient()
218void preRotateSource(const eTransform& tr, Whf& whf, Dim& srcCrop) {
Saurabh Shahacf10202013-02-26 10:15:15 -0800219 if(tr & OVERLAY_TRANSFORM_FLIP_H) {
220 srcCrop.x = compute(whf.w, srcCrop.x, srcCrop.w);
221 }
222 if(tr & OVERLAY_TRANSFORM_FLIP_V) {
223 srcCrop.y = compute(whf.h, srcCrop.y, srcCrop.h);
224 }
225 if(tr & OVERLAY_TRANSFORM_ROT_90) {
226 int tmp = srcCrop.x;
227 srcCrop.x = compute(whf.h,
228 srcCrop.y,
229 srcCrop.h);
230 srcCrop.y = tmp;
231 swap(whf.w, whf.h);
232 swap(srcCrop.w, srcCrop.h);
233 }
Saurabh Shahacf10202013-02-26 10:15:15 -0800234}
235
Naseer Ahmed29a26812012-06-14 00:56:20 -0700236bool is3DTV() {
237 char is3DTV = '0';
238 IOFile fp(Res::edid3dInfoFile, "r");
239 (void)fp.read(is3DTV, 1);
240 ALOGI("3DTV EDID flag: %d", is3DTV);
241 return (is3DTV == '0') ? false : true;
242}
243
244bool isPanel3D() {
245 OvFD fd;
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700246 if(!overlay::open(fd, 0 /*fb*/, Res::fbPath)){
Naseer Ahmed29a26812012-06-14 00:56:20 -0700247 ALOGE("isPanel3D Can't open framebuffer 0");
248 return false;
249 }
250 fb_fix_screeninfo finfo;
251 if(!mdp_wrapper::getFScreenInfo(fd.getFD(), finfo)) {
252 ALOGE("isPanel3D read fb0 failed");
253 }
254 fd.close();
255 return (FB_TYPE_3D_PANEL == finfo.type) ? true : false;
256}
257
258bool usePanel3D() {
259 if(!isPanel3D())
260 return false;
261 char value[PROPERTY_VALUE_MAX];
262 property_get("persist.user.panel3D", value, "0");
263 int usePanel3D = atoi(value);
264 return usePanel3D ? true : false;
265}
266
267bool send3DInfoPacket (uint32_t format3D) {
268 IOFile fp(Res::format3DFile, "wb");
269 (void)fp.write("%d", format3D);
270 if(!fp.valid()) {
271 ALOGE("send3DInfoPacket: no sysfs entry for setting 3d mode");
272 return false;
273 }
274 return true;
275}
276
277bool enableBarrier (uint32_t orientation) {
278 IOFile fp(Res::barrierFile, "wb");
279 (void)fp.write("%d", orientation);
280 if(!fp.valid()) {
281 ALOGE("enableBarrier no sysfs entry for "
282 "enabling barriers on 3D panel");
283 return false;
284 }
285 return true;
286}
287
288uint32_t getS3DFormat(uint32_t fmt) {
289 // The S3D is part of the HAL_PIXEL_FORMAT_YV12 value. Add
290 // an explicit check for the format
291 if (fmt == HAL_PIXEL_FORMAT_YV12) {
292 return 0;
293 }
294 uint32_t fmt3D = format3D(fmt);
295 uint32_t fIn3D = format3DInput(fmt3D); // MSB 2 bytes - inp
296 uint32_t fOut3D = format3DOutput(fmt3D); // LSB 2 bytes - out
297 fmt3D = fIn3D | fOut3D;
298 if (!fIn3D) {
299 fmt3D |= fOut3D << SHIFT_TOT_3D; //Set the input format
300 }
301 if (!fOut3D) {
302 switch (fIn3D) {
303 case HAL_3D_IN_SIDE_BY_SIDE_L_R:
304 case HAL_3D_IN_SIDE_BY_SIDE_R_L:
305 // For all side by side formats, set the output
306 // format as Side-by-Side i.e 0x1
307 fmt3D |= HAL_3D_IN_SIDE_BY_SIDE_L_R >> SHIFT_TOT_3D;
308 break;
309 default:
310 fmt3D |= fIn3D >> SHIFT_TOT_3D; //Set the output format
311 }
312 }
313 return fmt3D;
314}
315
Sushil Chauhanb4d184f2013-02-11 16:13:10 -0800316bool isMdssRotator() {
317 int mdpVersion = qdutils::MDPVersion::getInstance().getMDPVersion();
318 return (mdpVersion >= qdutils::MDSS_V5);
319}
320
Saurabh Shah0d0a7cb2013-02-12 17:58:19 -0800321void getDump(char *buf, size_t len, const char *prefix,
322 const mdp_overlay& ov) {
323 char str[256] = {'\0'};
324 snprintf(str, 256,
325 "%s id=%d z=%d fg=%d alpha=%d mask=%d flags=0x%x\n",
326 prefix, ov.id, ov.z_order, ov.is_fg, ov.alpha,
327 ov.transp_mask, ov.flags);
328 strncat(buf, str, strlen(str));
329 getDump(buf, len, "\tsrc(msmfb_img)", ov.src);
330 getDump(buf, len, "\tsrc_rect(mdp_rect)", ov.src_rect);
331 getDump(buf, len, "\tdst_rect(mdp_rect)", ov.dst_rect);
332}
333
334void getDump(char *buf, size_t len, const char *prefix,
335 const msmfb_img& ov) {
336 char str_src[256] = {'\0'};
337 snprintf(str_src, 256,
338 "%s w=%d h=%d format=%d %s\n",
339 prefix, ov.width, ov.height, ov.format,
340 overlay::utils::getFormatString(ov.format));
341 strncat(buf, str_src, strlen(str_src));
342}
343
344void getDump(char *buf, size_t len, const char *prefix,
345 const mdp_rect& ov) {
346 char str_rect[256] = {'\0'};
347 snprintf(str_rect, 256,
348 "%s x=%d y=%d w=%d h=%d\n",
349 prefix, ov.x, ov.y, ov.w, ov.h);
350 strncat(buf, str_rect, strlen(str_rect));
351}
352
353void getDump(char *buf, size_t len, const char *prefix,
354 const msmfb_overlay_data& ov) {
355 char str[256] = {'\0'};
356 snprintf(str, 256,
357 "%s id=%d\n",
358 prefix, ov.id);
359 strncat(buf, str, strlen(str));
360 getDump(buf, len, "\tdata(msmfb_data)", ov.data);
361}
362
363void getDump(char *buf, size_t len, const char *prefix,
364 const msmfb_data& ov) {
365 char str_data[256] = {'\0'};
366 snprintf(str_data, 256,
367 "%s offset=%d memid=%d id=%d flags=0x%x priv=%d\n",
368 prefix, ov.offset, ov.memory_id, ov.id, ov.flags,
369 ov.priv);
370 strncat(buf, str_data, strlen(str_data));
371}
372
373void getDump(char *buf, size_t len, const char *prefix,
374 const msm_rotator_img_info& rot) {
375 char str[256] = {'\0'};
376 snprintf(str, 256, "%s sessid=%u rot=%d, enable=%d downscale=%d\n",
377 prefix, rot.session_id, rot.rotations, rot.enable,
378 rot.downscale_ratio);
379 strncat(buf, str, strlen(str));
380 getDump(buf, len, "\tsrc", rot.src);
381 getDump(buf, len, "\tdst", rot.dst);
382 getDump(buf, len, "\tsrc_rect", rot.src_rect);
383}
384
385void getDump(char *buf, size_t len, const char *prefix,
386 const msm_rotator_data_info& rot) {
387 char str[256] = {'\0'};
388 snprintf(str, 256,
389 "%s sessid=%u verkey=%d\n",
390 prefix, rot.session_id, rot.version_key);
391 strncat(buf, str, strlen(str));
392 getDump(buf, len, "\tsrc", rot.src);
393 getDump(buf, len, "\tdst", rot.dst);
394 getDump(buf, len, "\tsrc_chroma", rot.src_chroma);
395 getDump(buf, len, "\tdst_chroma", rot.dst_chroma);
396}
397
Naseer Ahmed29a26812012-06-14 00:56:20 -0700398} // utils
399
400} // overlay