1/*
2* Copyright (c) 2011, 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#ifndef MDP_WRAPPER_H
31#define MDP_WRAPPER_H
32
33#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
34
35/*
36* In order to make overlay::mdp_wrapper shorter, please do something like:
37* namespace mdpwrap = overlay::mdp_wrapper;
38* */
39
40#include <linux/msm_mdp.h>
41#include <linux/msm_rotator.h>
42#include <sys/ioctl.h>
43#include <utils/Log.h>
44#include <utils/Trace.h>
45#include <errno.h>
46#include "overlayUtils.h"
47
48#define IOCTL_DEBUG 0
49
50namespace overlay{
51
52namespace mdp_wrapper{
53/* FBIOGET_FSCREENINFO */
54bool getFScreenInfo(int fd, fb_fix_screeninfo& finfo);
55
56/* FBIOGET_VSCREENINFO */
57bool getVScreenInfo(int fd, fb_var_screeninfo& vinfo);
58
59/* FBIOPUT_VSCREENINFO */
60bool setVScreenInfo(int fd, fb_var_screeninfo& vinfo);
61
62/* MSM_ROTATOR_IOCTL_START */
63bool startRotator(int fd, msm_rotator_img_info& rot);
64
65/* MSM_ROTATOR_IOCTL_ROTATE */
66bool rotate(int fd, msm_rotator_data_info& rot);
67
68/* MSMFB_OVERLAY_SET */
69bool setOverlay(int fd, mdp_overlay& ov);
70
71/* MSMFB_OVERLAY_PREPARE */
72bool validateAndSet(const int& fd, mdp_overlay_list& list);
73
74/* MSM_ROTATOR_IOCTL_FINISH */
75bool endRotator(int fd, int sessionId);
76
77/* MSMFB_OVERLAY_UNSET */
78bool unsetOverlay(int fd, int ovId);
79
80/* MSMFB_OVERLAY_GET */
81bool getOverlay(int fd, mdp_overlay& ov);
82
83/* MSMFB_OVERLAY_PLAY */
84bool play(int fd, msmfb_overlay_data& od);
85
86/* MSMFB_DISPLAY_COMMIT */
87bool displayCommit(int fd);
88
89/* MSMFB_WRITEBACK_INIT, MSMFB_WRITEBACK_START */
90bool wbInitStart(int fbfd);
91
92/* MSMFB_WRITEBACK_STOP, MSMFB_WRITEBACK_TERMINATE */
93bool wbStopTerminate(int fbfd);
94
95/* MSMFB_WRITEBACK_QUEUE_BUFFER */
96bool wbQueueBuffer(int fbfd, struct msmfb_data& fbData);
97
98/* MSMFB_WRITEBACK_DEQUEUE_BUFFER */
99bool wbDequeueBuffer(int fbfd, struct msmfb_data& fbData);
100
101/* the following are helper functions for dumping
102 * msm_mdp and friends*/
103void dump(const char* const s, const msmfb_overlay_data& ov);
104void dump(const char* const s, const msmfb_data& ov);
105void dump(const char* const s, const mdp_overlay& ov);
106void dump(const char* const s, const msmfb_overlay_3d& ov);
107void dump(const char* const s, const uint32_t u[], uint32_t cnt);
108void dump(const char* const s, const msmfb_img& ov);
109void dump(const char* const s, const mdp_rect& ov);
110
111/* and rotator */
112void dump(const char* const s, const msm_rotator_img_info& rot);
113void dump(const char* const s, const msm_rotator_data_info& rot);
114
115/* info */
116void dump(const char* const s, const fb_fix_screeninfo& finfo);
117void dump(const char* const s, const fb_var_screeninfo& vinfo);
118
119//---------------Inlines -------------------------------------
120
121inline bool getFScreenInfo(int fd, fb_fix_screeninfo& finfo) {
122    ATRACE_CALL();
123    if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) < 0) {
124        ALOGE("Failed to call ioctl FBIOGET_FSCREENINFO err=%s",
125                strerror(errno));
126        return false;
127    }
128    return true;
129}
130
131inline bool getVScreenInfo(int fd, fb_var_screeninfo& vinfo) {
132    ATRACE_CALL();
133    if (ioctl(fd, FBIOGET_VSCREENINFO, &vinfo) < 0) {
134        ALOGE("Failed to call ioctl FBIOGET_VSCREENINFO err=%s",
135                strerror(errno));
136        return false;
137    }
138    return true;
139}
140
141inline bool setVScreenInfo(int fd, fb_var_screeninfo& vinfo) {
142    ATRACE_CALL();
143    if (ioctl(fd, FBIOPUT_VSCREENINFO, &vinfo) < 0) {
144        ALOGE("Failed to call ioctl FBIOPUT_VSCREENINFO err=%s",
145                strerror(errno));
146        return false;
147    }
148    return true;
149}
150
151inline bool startRotator(int fd, msm_rotator_img_info& rot) {
152    ATRACE_CALL();
153    if (ioctl(fd, MSM_ROTATOR_IOCTL_START, &rot) < 0){
154        ALOGE("Failed to call ioctl MSM_ROTATOR_IOCTL_START err=%s",
155                strerror(errno));
156        return false;
157    }
158    return true;
159}
160
161inline bool rotate(int fd, msm_rotator_data_info& rot) {
162    ATRACE_CALL();
163    if (ioctl(fd, MSM_ROTATOR_IOCTL_ROTATE, &rot) < 0) {
164        ALOGE("Failed to call ioctl MSM_ROTATOR_IOCTL_ROTATE err=%s",
165                strerror(errno));
166        return false;
167    }
168    return true;
169}
170
171inline bool setOverlay(int fd, mdp_overlay& ov) {
172    ATRACE_CALL();
173    if (ioctl(fd, MSMFB_OVERLAY_SET, &ov) < 0) {
174        ALOGE("Failed to call ioctl MSMFB_OVERLAY_SET err=%s",
175                strerror(errno));
176        return false;
177    }
178    return true;
179}
180
181inline bool validateAndSet(const int& fd, mdp_overlay_list& list) {
182    ATRACE_CALL();
183    if (ioctl(fd, MSMFB_OVERLAY_PREPARE, &list) < 0) {
184        ALOGD_IF(IOCTL_DEBUG, "Failed to call ioctl MSMFB_OVERLAY_PREPARE "
185                "err=%s", strerror(errno));
186        return false;
187    }
188    return true;
189}
190
191inline bool endRotator(int fd, uint32_t sessionId) {
192    ATRACE_CALL();
193    if (ioctl(fd, MSM_ROTATOR_IOCTL_FINISH, &sessionId) < 0) {
194        ALOGE("Failed to call ioctl MSM_ROTATOR_IOCTL_FINISH err=%s",
195                strerror(errno));
196        return false;
197    }
198    return true;
199}
200
201inline bool unsetOverlay(int fd, int ovId) {
202    ATRACE_CALL();
203    if (ioctl(fd, MSMFB_OVERLAY_UNSET, &ovId) < 0) {
204        ALOGE("Failed to call ioctl MSMFB_OVERLAY_UNSET err=%s",
205                strerror(errno));
206        return false;
207    }
208    return true;
209}
210
211inline bool getOverlay(int fd, mdp_overlay& ov) {
212    ATRACE_CALL();
213    if (ioctl(fd, MSMFB_OVERLAY_GET, &ov) < 0) {
214        ALOGE("Failed to call ioctl MSMFB_OVERLAY_GET err=%s",
215                strerror(errno));
216        return false;
217    }
218    return true;
219}
220
221inline bool play(int fd, msmfb_overlay_data& od) {
222    ATRACE_CALL();
223    if (ioctl(fd, MSMFB_OVERLAY_PLAY, &od) < 0) {
224        ALOGE("Failed to call ioctl MSMFB_OVERLAY_PLAY err=%s",
225                strerror(errno));
226        return false;
227    }
228    return true;
229}
230
231inline bool displayCommit(int fd, mdp_display_commit& info) {
232    ATRACE_CALL();
233    if(ioctl(fd, MSMFB_DISPLAY_COMMIT, &info) == -1) {
234        ALOGE("Failed to call ioctl MSMFB_DISPLAY_COMMIT err=%s",
235                strerror(errno));
236        return false;
237    }
238    return true;
239}
240
241inline bool wbInitStart(int fbfd) {
242    ATRACE_CALL();
243    if(ioctl(fbfd, MSMFB_WRITEBACK_INIT, NULL) < 0) {
244        ALOGE("Failed to call ioctl MSMFB_WRITEBACK_INIT err=%s",
245                strerror(errno));
246        return false;
247    }
248    if(ioctl(fbfd, MSMFB_WRITEBACK_START, NULL) < 0) {
249        ALOGE("Failed to call ioctl MSMFB_WRITEBACK_START err=%s",
250                strerror(errno));
251        return false;
252    }
253    return true;
254}
255
256inline bool wbStopTerminate(int fbfd) {
257    ATRACE_CALL();
258    if(ioctl(fbfd, MSMFB_WRITEBACK_STOP, NULL) < 0) {
259        ALOGE("Failed to call ioctl MSMFB_WRITEBACK_STOP err=%s",
260                strerror(errno));
261        return false;
262    }
263    if(ioctl(fbfd, MSMFB_WRITEBACK_TERMINATE, NULL) < 0) {
264        ALOGE("Failed to call ioctl MSMFB_WRITEBACK_TERMINATE err=%s",
265                strerror(errno));
266        return false;
267    }
268    return true;
269}
270
271inline bool wbQueueBuffer(int fbfd, struct msmfb_data& fbData) {
272    ATRACE_CALL();
273    if(ioctl(fbfd, MSMFB_WRITEBACK_QUEUE_BUFFER, &fbData) < 0) {
274        ALOGE("Failed to call ioctl MSMFB_WRITEBACK_QUEUE_BUFFER err=%s",
275                strerror(errno));
276        return false;
277    }
278    return true;
279}
280
281inline bool wbDequeueBuffer(int fbfd, struct msmfb_data& fbData) {
282    ATRACE_CALL();
283    if(ioctl(fbfd, MSMFB_WRITEBACK_DEQUEUE_BUFFER, &fbData) < 0) {
284        ALOGE("Failed to call ioctl MSMFB_WRITEBACK_DEQUEUE_BUFFER err=%s",
285                strerror(errno));
286        return false;
287    }
288    return true;
289}
290
291/* dump funcs */
292inline void dump(const char* const s, const msmfb_overlay_data& ov) {
293    ALOGE("%s msmfb_overlay_data id=%d",
294            s, ov.id);
295    dump("data", ov.data);
296}
297inline void dump(const char* const s, const msmfb_data& ov) {
298    ALOGE("%s msmfb_data offset=%d memid=%d id=%d flags=0x%x priv=%d",
299            s, ov.offset, ov.memory_id, ov.id, ov.flags, ov.priv);
300}
301inline void dump(const char* const s, const mdp_overlay& ov) {
302    ALOGE("%s mdp_overlay z=%d fg=%d alpha=%d mask=%d flags=0x%x id=%d",
303            s, ov.z_order, ov.is_fg, ov.alpha,
304            ov.transp_mask, ov.flags, ov.id);
305    dump("src", ov.src);
306    dump("src_rect", ov.src_rect);
307    dump("dst_rect", ov.dst_rect);
308    /*
309    Commented off to prevent verbose logging, since user_data could have 8 or so
310    fields which are mostly 0
311    dump("user_data", ov.user_data,
312            sizeof(ov.user_data)/sizeof(ov.user_data[0]));
313    */
314}
315inline void dump(const char* const s, const msmfb_img& ov) {
316    ALOGE("%s msmfb_img w=%d h=%d format=%d %s",
317            s, ov.width, ov.height, ov.format,
318            overlay::utils::getFormatString(ov.format));
319}
320inline void dump(const char* const s, const mdp_rect& ov) {
321    ALOGE("%s mdp_rect x=%d y=%d w=%d h=%d",
322            s, ov.x, ov.y, ov.w, ov.h);
323}
324
325inline void dump(const char* const s, const msmfb_overlay_3d& ov) {
326    ALOGE("%s msmfb_overlay_3d 3d=%d w=%d h=%d",
327            s, ov.is_3d, ov.width, ov.height);
328
329}
330inline void dump(const char* const s, const uint32_t u[], uint32_t cnt) {
331    ALOGE("%s user_data cnt=%d", s, cnt);
332    for(uint32_t i=0; i < cnt; ++i) {
333        ALOGE("i=%d val=%d", i, u[i]);
334    }
335}
336inline void dump(const char* const s, const msm_rotator_img_info& rot) {
337    ALOGE("%s msm_rotator_img_info sessid=%u dstx=%d dsty=%d rot=%d, ena=%d scale=%d",
338            s, rot.session_id, rot.dst_x, rot.dst_y,
339            rot.rotations, rot.enable, rot.downscale_ratio);
340    dump("src", rot.src);
341    dump("dst", rot.dst);
342    dump("src_rect", rot.src_rect);
343}
344inline void dump(const char* const s, const msm_rotator_data_info& rot) {
345    ALOGE("%s msm_rotator_data_info sessid=%u verkey=%d",
346            s, rot.session_id, rot.version_key);
347    dump("src", rot.src);
348    dump("dst", rot.dst);
349    dump("src_chroma", rot.src_chroma);
350    dump("dst_chroma", rot.dst_chroma);
351}
352inline void dump(const char* const s, const fb_fix_screeninfo& finfo) {
353    ALOGE("%s fb_fix_screeninfo type=%d", s, finfo.type);
354}
355inline void dump(const char* const s, const fb_var_screeninfo& vinfo) {
356    ALOGE("%s fb_var_screeninfo xres=%d yres=%d",
357            s, vinfo.xres, vinfo.yres);
358}
359
360} // mdp_wrapper
361
362} // overlay
363
364#endif // MDP_WRAPPER_H
365