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