Home | History | Annotate | Download | only in fb
      1 /*
      2 * Copyright (c) 2016, The Linux Foundation. All rights reserved.
      3 *
      4 * Redistribution and use in source and binary forms, with or without modification, are permitted
      5 * provided that the following conditions are met:
      6 *    * Redistributions of source code must retain the above copyright notice, this list of
      7 *      conditions and the following disclaimer.
      8 *    * Redistributions in binary form must reproduce the above copyright notice, this list of
      9 *      conditions and the following disclaimer in the documentation and/or other materials provided
     10 *      with the distribution.
     11 *    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
     12 *      endorse or promote products derived from this software without specific prior written
     13 *      permission.
     14 *
     15 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     16 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     17 * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
     18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     19 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     20 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     21 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     22 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     23 */
     24 
     25 #include <stdio.h>
     26 #include <utils/debug.h>
     27 #include "hw_scale.h"
     28 
     29 #define __CLASS__ "HWScale"
     30 
     31 namespace sdm {
     32 
     33 DisplayError HWScale::Create(HWScale **intf, bool has_qseed3) {
     34   if (has_qseed3) {
     35     *intf = new HWScaleV2();
     36   } else {
     37     *intf = new HWScaleV1();
     38   }
     39 
     40   return kErrorNone;
     41 }
     42 
     43 DisplayError HWScale::Destroy(HWScale *intf) {
     44   delete intf;
     45 
     46   return kErrorNone;
     47 }
     48 
     49 void HWScaleV1::SetHWScaleData(const HWScaleData &scale_data, uint32_t index,
     50                                mdp_layer_commit_v1 *mdp_commit, HWSubBlockType sub_block_type) {
     51   if (!scale_data.enable.scale) {
     52     return;
     53   }
     54 
     55   if (sub_block_type == kHWDestinationScalar) {
     56     return;
     57   }
     58 
     59   mdp_input_layer *mdp_layer = &mdp_commit->input_layers[index];
     60   mdp_layer->flags |= MDP_LAYER_ENABLE_PIXEL_EXT;
     61   mdp_scale_data *mdp_scale = &scale_data_v1_.at(index);
     62   mdp_scale->enable_pxl_ext = scale_data.enable.scale;
     63   for (int i = 0; i < MAX_PLANES; i++) {
     64     const HWPlane &plane = scale_data.plane[i];
     65     mdp_scale->init_phase_x[i] = plane.init_phase_x;
     66     mdp_scale->phase_step_x[i] = plane.phase_step_x;
     67     mdp_scale->init_phase_y[i] = plane.init_phase_y;
     68     mdp_scale->phase_step_y[i] = plane.phase_step_y;
     69 
     70     mdp_scale->num_ext_pxls_left[i] = plane.left.extension;
     71     mdp_scale->left_ftch[i] = plane.left.overfetch;
     72     mdp_scale->left_rpt[i] = plane.left.repeat;
     73 
     74     mdp_scale->num_ext_pxls_top[i] = plane.top.extension;
     75     mdp_scale->top_ftch[i] = plane.top.overfetch;
     76     mdp_scale->top_rpt[i] = plane.top.repeat;
     77 
     78     mdp_scale->num_ext_pxls_right[i] = plane.right.extension;
     79     mdp_scale->right_ftch[i] = plane.right.overfetch;
     80     mdp_scale->right_rpt[i] = plane.right.repeat;
     81 
     82     mdp_scale->num_ext_pxls_btm[i] = plane.bottom.extension;
     83     mdp_scale->btm_ftch[i] = plane.bottom.overfetch;
     84     mdp_scale->btm_rpt[i] = plane.bottom.repeat;
     85 
     86     mdp_scale->roi_w[i] = plane.roi_width;
     87   }
     88 
     89   return;
     90 }
     91 
     92 void* HWScaleV1::GetScaleDataRef(uint32_t index, HWSubBlockType sub_block_type) {
     93   if (sub_block_type != kHWDestinationScalar) {
     94     return &scale_data_v1_.at(index);
     95   }
     96 
     97   return NULL;
     98 }
     99 
    100 void HWScaleV1::DumpScaleData(void *mdp_scale) {
    101   if (!mdp_scale) {
    102     return;
    103   }
    104 
    105   mdp_scale_data *scale = reinterpret_cast<mdp_scale_data *>(mdp_scale);
    106   if (scale->enable_pxl_ext) {
    107     DLOGV_IF(kTagDriverConfig, "Scale Enable = %d", scale->enable_pxl_ext);
    108     for (int j = 0; j < MAX_PLANES; j++) {
    109       DLOGV_IF(kTagDriverConfig, "Scale Data[%d] : Phase=[%x %x %x %x] Pixel_Ext=[%d %d %d %d]",
    110                j, scale->init_phase_x[j], scale->phase_step_x[j], scale->init_phase_y[j],
    111                scale->phase_step_y[j], scale->num_ext_pxls_left[j], scale->num_ext_pxls_top[j],
    112                scale->num_ext_pxls_right[j], scale->num_ext_pxls_btm[j]);
    113       DLOGV_IF(kTagDriverConfig, "Fetch=[%d %d %d %d]  Repeat=[%d %d %d %d]  roi_width = %d",
    114                scale->left_ftch[j], scale->top_ftch[j], scale->right_ftch[j], scale->btm_ftch[j],
    115                scale->left_rpt[j], scale->top_rpt[j], scale->right_rpt[j], scale->btm_rpt[j],
    116                scale->roi_w[j]);
    117     }
    118   }
    119 
    120   return;
    121 }
    122 
    123 void HWScaleV2::SetHWScaleData(const HWScaleData &scale_data, uint32_t index,
    124                                mdp_layer_commit_v1 *mdp_commit, HWSubBlockType sub_block_type) {
    125   if (!scale_data.enable.scale && !scale_data.enable.direction_detection &&
    126       !scale_data.enable.detail_enhance ) {
    127     return;
    128   }
    129 
    130   mdp_scale_data_v2 *mdp_scale;
    131   if (sub_block_type != kHWDestinationScalar) {
    132     mdp_input_layer *mdp_layer = &mdp_commit->input_layers[index];
    133     mdp_layer->flags |= MDP_LAYER_ENABLE_QSEED3_SCALE;
    134     mdp_scale = &scale_data_v2_.at(index);
    135   } else {
    136     mdp_scale_data_v2 mdp_dest_scale;
    137     mdp_destination_scaler_data *dest_scalar =
    138       reinterpret_cast<mdp_destination_scaler_data *>(mdp_commit->dest_scaler);
    139 
    140     dest_scalar[index].flags = MDP_DESTSCALER_ENABLE;
    141 
    142     if (scale_data.enable.detail_enhance) {
    143       dest_scalar[index].flags |= MDP_DESTSCALER_ENHANCER_UPDATE;
    144     }
    145 
    146     dest_scale_data_v2_.insert(std::make_pair(index, mdp_dest_scale));
    147     mdp_scale = &dest_scale_data_v2_[index];
    148   }
    149 
    150   mdp_scale->enable = (scale_data.enable.scale ? ENABLE_SCALE : 0) |
    151                       (scale_data.enable.direction_detection ? ENABLE_DIRECTION_DETECTION : 0) |
    152                       (scale_data.enable.detail_enhance ? ENABLE_DETAIL_ENHANCE : 0);
    153 
    154   for (int i = 0; i < MAX_PLANES; i++) {
    155     const HWPlane &plane = scale_data.plane[i];
    156     mdp_scale->init_phase_x[i] = plane.init_phase_x;
    157     mdp_scale->phase_step_x[i] = plane.phase_step_x;
    158     mdp_scale->init_phase_y[i] = plane.init_phase_y;
    159     mdp_scale->phase_step_y[i] = plane.phase_step_y;
    160 
    161     mdp_scale->num_ext_pxls_left[i] = UINT32(plane.left.extension);
    162     mdp_scale->left_ftch[i] = plane.left.overfetch;
    163     mdp_scale->left_rpt[i] = plane.left.repeat;
    164 
    165     mdp_scale->num_ext_pxls_top[i] = UINT32(plane.top.extension);
    166     mdp_scale->top_ftch[i] = UINT32(plane.top.overfetch);
    167     mdp_scale->top_rpt[i] = UINT32(plane.top.repeat);
    168 
    169     mdp_scale->num_ext_pxls_right[i] = UINT32(plane.right.extension);
    170     mdp_scale->right_ftch[i] = plane.right.overfetch;
    171     mdp_scale->right_rpt[i] = plane.right.repeat;
    172 
    173     mdp_scale->num_ext_pxls_btm[i] = UINT32(plane.bottom.extension);
    174     mdp_scale->btm_ftch[i] = UINT32(plane.bottom.overfetch);
    175     mdp_scale->btm_rpt[i] = UINT32(plane.bottom.repeat);
    176 
    177     mdp_scale->roi_w[i] = plane.roi_width;
    178 
    179     mdp_scale->preload_x[i] = UINT32(plane.preload_x);
    180     mdp_scale->preload_y[i] = UINT32(plane.preload_y);
    181 
    182     mdp_scale->src_width[i] = plane.src_width;
    183     mdp_scale->src_height[i] = plane.src_height;
    184   }
    185 
    186   mdp_scale->dst_width = scale_data.dst_width;
    187   mdp_scale->dst_height = scale_data.dst_height;
    188 
    189   mdp_scale->y_rgb_filter_cfg = GetMDPScalingFilter(scale_data.y_rgb_filter_cfg);
    190   mdp_scale->uv_filter_cfg = GetMDPScalingFilter(scale_data.uv_filter_cfg);
    191   mdp_scale->alpha_filter_cfg = GetMDPAlphaInterpolation(scale_data.alpha_filter_cfg);
    192   mdp_scale->blend_cfg = scale_data.blend_cfg;
    193 
    194   mdp_scale->lut_flag = (scale_data.lut_flag.lut_swap ? SCALER_LUT_SWAP : 0) |
    195                         (scale_data.lut_flag.lut_dir_wr ? SCALER_LUT_DIR_WR : 0) |
    196                         (scale_data.lut_flag.lut_y_cir_wr ? SCALER_LUT_Y_CIR_WR : 0) |
    197                         (scale_data.lut_flag.lut_uv_cir_wr ? SCALER_LUT_UV_CIR_WR : 0) |
    198                         (scale_data.lut_flag.lut_y_sep_wr ? SCALER_LUT_Y_SEP_WR : 0) |
    199                         (scale_data.lut_flag.lut_uv_sep_wr ? SCALER_LUT_UV_SEP_WR : 0);
    200 
    201   // lut indicies - index starts from 0, hence subtract by 1 when > 0
    202   mdp_scale->dir_lut_idx = (scale_data.dir_lut_idx > 0) ? scale_data.dir_lut_idx - 1 :
    203                                                           scale_data.dir_lut_idx;
    204   mdp_scale->y_rgb_cir_lut_idx = (scale_data.y_rgb_cir_lut_idx  > 0) ?
    205                                   scale_data.y_rgb_cir_lut_idx - 1 : scale_data.y_rgb_cir_lut_idx;
    206   mdp_scale->uv_cir_lut_idx = (scale_data.uv_cir_lut_idx > 0) ? scale_data.uv_cir_lut_idx - 1 :
    207                                scale_data.uv_cir_lut_idx;
    208   mdp_scale->y_rgb_sep_lut_idx = (scale_data.y_rgb_sep_lut_idx  > 0) ?
    209                                   scale_data.y_rgb_sep_lut_idx - 1 : scale_data.y_rgb_sep_lut_idx;
    210   mdp_scale->uv_sep_lut_idx = (scale_data.uv_sep_lut_idx  > 0) ? scale_data.uv_sep_lut_idx - 1 :
    211                                scale_data.uv_sep_lut_idx;
    212 
    213   if (mdp_scale->enable & ENABLE_DETAIL_ENHANCE) {
    214     mdp_det_enhance_data *mdp_det_enhance = &mdp_scale->detail_enhance;
    215     mdp_det_enhance->enable = scale_data.detail_enhance.enable;
    216     mdp_det_enhance->sharpen_level1 = scale_data.detail_enhance.sharpen_level1;
    217     mdp_det_enhance->sharpen_level2 = scale_data.detail_enhance.sharpen_level2;
    218     mdp_det_enhance->clip = scale_data.detail_enhance.clip;
    219     mdp_det_enhance->limit = scale_data.detail_enhance.limit;
    220     mdp_det_enhance->thr_quiet = scale_data.detail_enhance.thr_quiet;
    221     mdp_det_enhance->thr_dieout = scale_data.detail_enhance.thr_dieout;
    222     mdp_det_enhance->thr_low = scale_data.detail_enhance.thr_low;
    223     mdp_det_enhance->thr_high = scale_data.detail_enhance.thr_high;
    224     mdp_det_enhance->prec_shift = scale_data.detail_enhance.prec_shift;
    225 
    226     for (int i = 0; i < MAX_DET_CURVES; i++) {
    227       mdp_det_enhance->adjust_a[i] = scale_data.detail_enhance.adjust_a[i];
    228       mdp_det_enhance->adjust_b[i] = scale_data.detail_enhance.adjust_b[i];
    229       mdp_det_enhance->adjust_c[i] = scale_data.detail_enhance.adjust_c[i];
    230     }
    231   }
    232 
    233   return;
    234 }
    235 
    236 void* HWScaleV2::GetScaleDataRef(uint32_t index, HWSubBlockType sub_block_type) {
    237   if (sub_block_type != kHWDestinationScalar) {
    238     return &scale_data_v2_.at(index);
    239   } else {
    240     return &dest_scale_data_v2_[index];
    241   }
    242 }
    243 
    244 uint32_t HWScaleV2::GetMDPScalingFilter(ScalingFilterConfig filter_cfg) {
    245   switch (filter_cfg) {
    246   case kFilterEdgeDirected:
    247     return FILTER_EDGE_DIRECTED_2D;
    248   case kFilterCircular:
    249     return FILTER_CIRCULAR_2D;
    250   case kFilterSeparable:
    251     return FILTER_SEPARABLE_1D;
    252   case kFilterBilinear:
    253     return FILTER_BILINEAR;
    254   default:
    255     DLOGE("Invalid Scaling Filter");
    256     return kFilterMax;
    257   }
    258 }
    259 
    260 uint32_t HWScaleV2::GetMDPAlphaInterpolation(HWAlphaInterpolation alpha_filter_cfg) {
    261   switch (alpha_filter_cfg) {
    262   case kInterpolationPixelRepeat:
    263     return FILTER_ALPHA_DROP_REPEAT;
    264   case kInterpolationBilinear:
    265     return FILTER_ALPHA_BILINEAR;
    266   default:
    267     DLOGE("Invalid Alpha Interpolation");
    268     return kInterpolationMax;
    269   }
    270 }
    271 
    272 void HWScaleV2::DumpScaleData(void *mdp_scale) {
    273   if (!mdp_scale) {
    274     return;
    275   }
    276 
    277   mdp_scale_data_v2 *scale = reinterpret_cast<mdp_scale_data_v2 *>(mdp_scale);
    278   if (scale->enable) {
    279     DLOGV_IF(kTagDriverConfig, "Scale Enable = %d", scale->enable);
    280     for (int j = 0; j < MAX_PLANES; j++) {
    281       DLOGV_IF(kTagDriverConfig, "Scale Data[%d]: Phase_init[x y]=[%x %x] Phase_step:[x y]=[%x %x]",
    282         j, scale->init_phase_x[j], scale->init_phase_y[j], scale->phase_step_x[j],
    283         scale->phase_step_y[j]);
    284       DLOGV_IF(kTagDriverConfig, "Preload[x y]=[%x %x], Pixel Ext=[%d %d] Ovfetch=[%d %d %d %d]",
    285         scale->preload_x[j], scale->preload_y[j], scale->num_ext_pxls_left[j],
    286         scale->num_ext_pxls_top[j], scale->left_ftch[j], scale->top_ftch[j], scale->right_ftch[j],
    287         scale->btm_ftch[j]);
    288       DLOGV_IF(kTagDriverConfig, "Repeat=[%d %d %d %d] Src[w x h]=[%d %d] roi_width = %d",
    289         scale->left_rpt[j], scale->top_rpt[j], scale->right_rpt[j], scale->btm_rpt[j],
    290         scale->src_width[j], scale->src_height[j], scale->roi_w[j]);
    291     }
    292 
    293     DLOGV_IF(kTagDriverConfig, "LUT flags = %d", scale->lut_flag);
    294     DLOGV_IF(kTagDriverConfig, "y_rgb_filter=%d, uv_filter=%d, alpha_filter=%d, blend_cfg=%d",
    295       scale->y_rgb_filter_cfg, scale->uv_filter_cfg, scale->alpha_filter_cfg, scale->blend_cfg);
    296     DLOGV_IF(kTagDriverConfig, "dir_lut=%d, y_rgb_cir=%d, uv_cir=%d, y_rgb_sep=%d, uv_sep=%d",
    297       scale->dir_lut_idx, scale->y_rgb_cir_lut_idx, scale->uv_cir_lut_idx,
    298       scale->y_rgb_sep_lut_idx, scale->uv_sep_lut_idx);
    299     if (scale->enable & ENABLE_DETAIL_ENHANCE) {
    300       mdp_det_enhance_data *de = &scale->detail_enhance;
    301       DLOGV_IF(kTagDriverConfig, "Detail Enhance: enable: %d sharpen_level1: %d sharpen_level2: %d",
    302         de->enable, de->sharpen_level1, de->sharpen_level2);
    303       DLOGV_IF(kTagDriverConfig, "clip: %d limit:%d thr_quiet: %d thr_dieout: %d",
    304         de->clip, de->limit, de->thr_quiet, de->thr_dieout);
    305       DLOGV_IF(kTagDriverConfig, "thr_low: %d thr_high: %d prec_shift: %d", de->thr_low,
    306         de->thr_high, de->prec_shift);
    307       for (uint32_t i = 0; i < MAX_DET_CURVES; i++) {
    308         DLOGV_IF(kTagDriverConfig, "adjust_a[%d]: %d adjust_b[%d]: %d adjust_c[%d]: %d", i,
    309           de->adjust_a[i], i, de->adjust_b[i], i, de->adjust_c[i]);
    310       }
    311     }
    312   }
    313 
    314   return;
    315 }
    316 
    317 }  // namespace sdm
    318