• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
Create(HWScale ** intf,bool has_qseed3)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 
Destroy(HWScale * intf)43 DisplayError HWScale::Destroy(HWScale *intf) {
44   delete intf;
45 
46   return kErrorNone;
47 }
48 
SetHWScaleData(const HWScaleData & scale_data,uint32_t index,mdp_layer_commit_v1 * mdp_commit,HWSubBlockType sub_block_type)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 
GetScaleDataRef(uint32_t index,HWSubBlockType sub_block_type)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 
DumpScaleData(void * mdp_scale)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 
SetHWScaleData(const HWScaleData & scale_data,uint32_t index,mdp_layer_commit_v1 * mdp_commit,HWSubBlockType sub_block_type)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 
GetScaleDataRef(uint32_t index,HWSubBlockType sub_block_type)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 
GetMDPScalingFilter(ScalingFilterConfig filter_cfg)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 
GetMDPAlphaInterpolation(HWAlphaInterpolation alpha_filter_cfg)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 
DumpScaleData(void * mdp_scale)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