1 /*
2 * Copyright (c) 2014-2016, 2018-2020, 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 <math.h>
26 #include <utils/constants.h>
27 #include <utils/debug.h>
28 #include <utils/rect.h>
29 #include <utils/formats.h>
30 #include <utils/sys.h>
31 #include <dlfcn.h>
32 #include <algorithm>
33 
34 #include "resource_default.h"
35 
36 #define __CLASS__ "ResourceDefault"
37 
38 namespace sdm {
39 
CreateResourceDefault(const HWResourceInfo & hw_resource_info,ResourceInterface ** resource_intf)40 DisplayError ResourceDefault::CreateResourceDefault(const HWResourceInfo &hw_resource_info,
41                                                     ResourceInterface **resource_intf) {
42   DisplayError error = kErrorNone;
43 
44   ResourceDefault *resource_default = new ResourceDefault(hw_resource_info);
45   if (!resource_default) {
46     return kErrorNone;
47   }
48 
49   error = resource_default->Init();
50   if (error != kErrorNone) {
51     delete resource_default;
52   }
53 
54   *resource_intf = resource_default;
55 
56   return kErrorNone;
57 }
58 
DestroyResourceDefault(ResourceInterface * resource_intf)59 DisplayError ResourceDefault::DestroyResourceDefault(ResourceInterface *resource_intf) {
60   ResourceDefault *resource_default = static_cast<ResourceDefault *>(resource_intf);
61 
62   resource_default->Deinit();
63   delete resource_default;
64 
65   return kErrorNone;
66 }
67 
ResourceDefault(const HWResourceInfo & hw_res_info)68 ResourceDefault::ResourceDefault(const HWResourceInfo &hw_res_info)
69   : hw_res_info_(hw_res_info) {
70 }
71 
Init()72 DisplayError ResourceDefault::Init() {
73   DisplayError error = kErrorNone;
74 
75   num_pipe_ = hw_res_info_.num_vig_pipe + hw_res_info_.num_rgb_pipe + hw_res_info_.num_dma_pipe;
76 
77   if (!num_pipe_) {
78     DLOGE("Number of H/W pipes is Zero!");
79     return kErrorParameters;
80   }
81 
82   src_pipes_.resize(num_pipe_);
83 
84   // Priority order of pipes: VIG, RGB, DMA
85   uint32_t vig_index = 0;
86   uint32_t rgb_index = hw_res_info_.num_vig_pipe;
87   uint32_t dma_index = rgb_index + hw_res_info_.num_rgb_pipe;
88 
89   for (uint32_t i = 0; i < num_pipe_; i++) {
90     const HWPipeCaps &pipe_caps = hw_res_info_.hw_pipes.at(i);
91     if (pipe_caps.type == kPipeTypeVIG) {
92       src_pipes_[vig_index].type = kPipeTypeVIG;
93       src_pipes_[vig_index].index = i;
94       src_pipes_[vig_index].mdss_pipe_id = pipe_caps.id;
95       vig_index++;
96     } else if (pipe_caps.type == kPipeTypeRGB) {
97       src_pipes_[rgb_index].type = kPipeTypeRGB;
98       src_pipes_[rgb_index].index = i;
99       src_pipes_[rgb_index].mdss_pipe_id = pipe_caps.id;
100       rgb_index++;
101     } else if (pipe_caps.type == kPipeTypeDMA) {
102       src_pipes_[dma_index].type = kPipeTypeDMA;
103       src_pipes_[dma_index].index = i;
104       src_pipes_[dma_index].mdss_pipe_id = pipe_caps.id;
105       dma_index++;
106     }
107   }
108 
109   for (uint32_t i = 0; i < num_pipe_; i++) {
110     src_pipes_[i].priority = INT(i);
111   }
112 
113   DLOGI("hw_ver=%x, DMA=%d RGB=%d VIG=%d", hw_res_info_.hw_version, hw_res_info_.num_dma_pipe,
114     hw_res_info_.num_rgb_pipe, hw_res_info_.num_vig_pipe);
115 
116   if (hw_res_info_.max_scale_down < 1 || hw_res_info_.max_scale_up < 1) {
117     DLOGE("Max scaling setting is invalid! max_scale_down = %d, max_scale_up = %d",
118           hw_res_info_.max_scale_down, hw_res_info_.max_scale_up);
119     hw_res_info_.max_scale_down = 1;
120     hw_res_info_.max_scale_up = 1;
121   }
122 
123   // TODO(user): clean it up, query from driver for initial pipe status.
124 #ifndef SDM_VIRTUAL_DRIVER
125   rgb_index = hw_res_info_.num_vig_pipe;
126   src_pipes_[rgb_index].owner = kPipeOwnerKernelMode;
127   src_pipes_[rgb_index + 1].owner = kPipeOwnerKernelMode;
128 #endif
129 
130   return error;
131 }
132 
Deinit()133 DisplayError ResourceDefault::Deinit() {
134   return kErrorNone;
135 }
136 
RegisterDisplay(int32_t display_id,DisplayType type,const HWDisplayAttributes & display_attributes,const HWPanelInfo & hw_panel_info,const HWMixerAttributes & mixer_attributes,Handle * display_ctx)137 DisplayError ResourceDefault::RegisterDisplay(int32_t display_id, DisplayType type,
138                                               const HWDisplayAttributes &display_attributes,
139                                               const HWPanelInfo &hw_panel_info,
140                                               const HWMixerAttributes &mixer_attributes,
141                                               Handle *display_ctx) {
142   DisplayError error = kErrorNone;
143 
144   HWBlockType hw_block_type = kHWBlockMax;
145   switch (type) {
146     case kBuiltIn:
147       if (!hw_block_ctx_[kHWBuiltIn].is_in_use) {
148         hw_block_type = kHWBuiltIn;
149       }
150       break;
151 
152     case kPluggable:
153       if (!hw_block_ctx_[kHWPluggable].is_in_use) {
154         hw_block_type = kHWPluggable;
155       }
156       break;
157 
158     default:
159       DLOGW("RegisterDisplay, invalid type %d", type);
160       return kErrorParameters;
161   }
162 
163   if (hw_block_type == kHWBlockMax) {
164     return kErrorResources;
165   }
166 
167   DisplayResourceContext *display_resource_ctx = new DisplayResourceContext();
168   if (!display_resource_ctx) {
169     return kErrorMemory;
170   }
171 
172   hw_block_ctx_[hw_block_type].is_in_use = true;
173 
174   display_resource_ctx->display_attributes = display_attributes;
175   display_resource_ctx->hw_block_type = hw_block_type;
176   display_resource_ctx->mixer_attributes = mixer_attributes;
177 
178   *display_ctx = display_resource_ctx;
179   return error;
180 }
181 
UnregisterDisplay(Handle display_ctx)182 DisplayError ResourceDefault::UnregisterDisplay(Handle display_ctx) {
183   DisplayResourceContext *display_resource_ctx =
184                           reinterpret_cast<DisplayResourceContext *>(display_ctx);
185   Purge(display_ctx);
186 
187   hw_block_ctx_[display_resource_ctx->hw_block_type].is_in_use = false;
188 
189   delete display_resource_ctx;
190 
191   return kErrorNone;
192 }
193 
ReconfigureDisplay(Handle display_ctx,const HWDisplayAttributes & display_attributes,const HWPanelInfo & hw_panel_info,const HWMixerAttributes & mixer_attributes)194 DisplayError ResourceDefault::ReconfigureDisplay(Handle display_ctx,
195                                                  const HWDisplayAttributes &display_attributes,
196                                                  const HWPanelInfo &hw_panel_info,
197                                                  const HWMixerAttributes &mixer_attributes) {
198   DisplayResourceContext *display_resource_ctx =
199                           reinterpret_cast<DisplayResourceContext *>(display_ctx);
200 
201   display_resource_ctx->display_attributes = display_attributes;
202   display_resource_ctx->mixer_attributes = mixer_attributes;
203 
204   return kErrorNone;
205 }
206 
Start(Handle display_ctx)207 DisplayError ResourceDefault::Start(Handle display_ctx) {
208   return kErrorNone;
209 }
210 
Stop(Handle display_ctx,HWLayers * hw_layers)211 DisplayError ResourceDefault::Stop(Handle display_ctx, HWLayers *hw_layers) {
212   return kErrorNone;
213 }
214 
Prepare(Handle display_ctx,HWLayers * hw_layers)215 DisplayError ResourceDefault::Prepare(Handle display_ctx, HWLayers *hw_layers) {
216   DisplayResourceContext *display_resource_ctx =
217                           reinterpret_cast<DisplayResourceContext *>(display_ctx);
218 
219   DisplayError error = kErrorNone;
220   const struct HWLayersInfo &layer_info = hw_layers->info;
221   HWBlockType hw_block_type = display_resource_ctx->hw_block_type;
222 
223   DLOGV_IF(kTagResources, "==== Resource reserving start: hw_block_type = %d ====", hw_block_type);
224 
225   if (layer_info.hw_layers.size() > 1) {
226     DLOGV_IF(kTagResources, "More than one FB layers");
227     return kErrorResources;
228   }
229 
230   const Layer &layer = layer_info.hw_layers.at(0);
231 
232   if (layer.composition != kCompositionGPUTarget) {
233     DLOGV_IF(kTagResources, "Not an FB layer");
234     return kErrorParameters;
235   }
236 
237   error = Config(display_resource_ctx, hw_layers);
238   if (error != kErrorNone) {
239     DLOGV_IF(kTagResources, "Resource config failed");
240     return error;
241   }
242 
243   for (uint32_t i = 0; i < num_pipe_; i++) {
244     if (src_pipes_[i].hw_block_type == hw_block_type && src_pipes_[i].owner == kPipeOwnerUserMode) {
245       src_pipes_[i].ResetState();
246     }
247   }
248 
249   uint32_t left_index = num_pipe_;
250   uint32_t right_index = num_pipe_;
251   bool need_scale = false;
252 
253   struct HWLayerConfig &layer_config = hw_layers->config[0];
254 
255   HWPipeInfo *left_pipe = &layer_config.left_pipe;
256   HWPipeInfo *right_pipe = &layer_config.right_pipe;
257 
258   // left pipe is needed
259   if (left_pipe->valid) {
260     need_scale = IsScalingNeeded(left_pipe);
261     left_index = GetPipe(hw_block_type, need_scale);
262     if (left_index >= num_pipe_) {
263       DLOGV_IF(kTagResources, "Get left pipe failed: hw_block_type = %d, need_scale = %d",
264                hw_block_type, need_scale);
265       ResourceStateLog();
266       goto CleanupOnError;
267     }
268   }
269 
270   error = SetDecimationFactor(left_pipe);
271   if (error != kErrorNone) {
272     goto CleanupOnError;
273   }
274 
275   if (!right_pipe->valid) {
276     // assign single pipe
277     if (left_index < num_pipe_) {
278       left_pipe->pipe_id = src_pipes_[left_index].mdss_pipe_id;
279     }
280     DLOGV_IF(kTagResources, "1 pipe acquired for FB layer, left_pipe = %x", left_pipe->pipe_id);
281     return kErrorNone;
282   }
283 
284   need_scale = IsScalingNeeded(right_pipe);
285 
286   right_index = GetPipe(hw_block_type, need_scale);
287   if (right_index >= num_pipe_) {
288     DLOGV_IF(kTagResources, "Get right pipe failed: hw_block_type = %d, need_scale = %d",
289              hw_block_type, need_scale);
290     ResourceStateLog();
291     goto CleanupOnError;
292   }
293 
294   if (src_pipes_[right_index].priority < src_pipes_[left_index].priority) {
295     // Swap pipe based on priority
296     std::swap(left_index, right_index);
297   }
298 
299   // assign dual pipes
300   left_pipe->pipe_id = src_pipes_[left_index].mdss_pipe_id;
301   right_pipe->pipe_id = src_pipes_[right_index].mdss_pipe_id;
302 
303   error = SetDecimationFactor(right_pipe);
304   if (error != kErrorNone) {
305     goto CleanupOnError;
306   }
307 
308   DLOGV_IF(kTagResources, "2 pipes acquired for FB layer, left_pipe = %x, right_pipe = %x",
309            left_pipe->pipe_id,  right_pipe->pipe_id);
310 
311   return kErrorNone;
312 
313 CleanupOnError:
314   DLOGV_IF(kTagResources, "Resource reserving failed! hw_block_type = %d", hw_block_type);
315 
316   return kErrorResources;
317 }
318 
PostPrepare(Handle display_ctx,HWLayers * hw_layers)319 DisplayError ResourceDefault::PostPrepare(Handle display_ctx, HWLayers *hw_layers) {
320   return kErrorNone;
321 }
322 
Commit(Handle display_ctx,HWLayers * hw_layers)323 DisplayError ResourceDefault::Commit(Handle display_ctx, HWLayers *hw_layers) {
324   return kErrorNone;
325 }
326 
PostCommit(Handle display_ctx,HWLayers * hw_layers)327 DisplayError ResourceDefault::PostCommit(Handle display_ctx, HWLayers *hw_layers) {
328   DisplayResourceContext *display_resource_ctx =
329                           reinterpret_cast<DisplayResourceContext *>(display_ctx);
330   HWBlockType hw_block_type = display_resource_ctx->hw_block_type;
331   uint64_t frame_count = display_resource_ctx->frame_count;
332 
333   DLOGV_IF(kTagResources, "Resource for hw_block = %d, frame_count = %" PRIu64 , hw_block_type,
334            frame_count);
335 
336   // handoff pipes which are used by splash screen
337   if ((frame_count == 0) && (hw_block_type == kHWBuiltIn)) {
338     for (uint32_t i = 0; i < num_pipe_; i++) {
339       if (src_pipes_[i].hw_block_type == hw_block_type &&
340           src_pipes_[i].owner == kPipeOwnerKernelMode) {
341         src_pipes_[i].owner = kPipeOwnerUserMode;
342       }
343     }
344   }
345 
346   display_resource_ctx->frame_count++;
347 
348   return kErrorNone;
349 }
350 
Purge(Handle display_ctx)351 void ResourceDefault::Purge(Handle display_ctx) {
352   DisplayResourceContext *display_resource_ctx =
353                           reinterpret_cast<DisplayResourceContext *>(display_ctx);
354   HWBlockType hw_block_type = display_resource_ctx->hw_block_type;
355 
356   for (uint32_t i = 0; i < num_pipe_; i++) {
357     if (src_pipes_[i].hw_block_type == hw_block_type && src_pipes_[i].owner == kPipeOwnerUserMode) {
358       src_pipes_[i].ResetState();
359     }
360   }
361   DLOGV_IF(kTagResources, "display hw_block_type = %d", display_resource_ctx->hw_block_type);
362 }
363 
SetMaxMixerStages(Handle display_ctx,uint32_t max_mixer_stages)364 DisplayError ResourceDefault::SetMaxMixerStages(Handle display_ctx, uint32_t max_mixer_stages) {
365   return kErrorNone;
366 }
367 
SearchPipe(HWBlockType hw_block_type,SourcePipe * src_pipes,uint32_t num_pipe)368 uint32_t ResourceDefault::SearchPipe(HWBlockType hw_block_type, SourcePipe *src_pipes,
369                                      uint32_t num_pipe) {
370   uint32_t index = num_pipe_;
371   SourcePipe *src_pipe;
372 
373   // search the pipe being used
374   for (uint32_t i = 0; i < num_pipe; i++) {
375     src_pipe = &src_pipes[i];
376     if (src_pipe->owner == kPipeOwnerUserMode && src_pipe->hw_block_type == kHWBlockMax) {
377       index = src_pipe->index;
378       src_pipe->hw_block_type = hw_block_type;
379       break;
380     }
381   }
382 
383   return index;
384 }
385 
NextPipe(PipeType type,HWBlockType hw_block_type)386 uint32_t ResourceDefault::NextPipe(PipeType type, HWBlockType hw_block_type) {
387   uint32_t num_pipe = 0;
388   SourcePipe *src_pipes = NULL;
389 
390   switch (type) {
391   case kPipeTypeVIG:
392     src_pipes = &src_pipes_[0];
393     num_pipe = hw_res_info_.num_vig_pipe;
394     break;
395   case kPipeTypeRGB:
396     src_pipes = &src_pipes_[hw_res_info_.num_vig_pipe];
397     num_pipe = hw_res_info_.num_rgb_pipe;
398     break;
399   case kPipeTypeDMA:
400   default:
401     src_pipes = &src_pipes_[hw_res_info_.num_vig_pipe + hw_res_info_.num_rgb_pipe];
402     num_pipe = hw_res_info_.num_dma_pipe;
403     break;
404   }
405 
406   return SearchPipe(hw_block_type, src_pipes, num_pipe);
407 }
408 
GetPipe(HWBlockType hw_block_type,bool need_scale)409 uint32_t ResourceDefault::GetPipe(HWBlockType hw_block_type, bool need_scale) {
410   uint32_t index = num_pipe_;
411 
412   // The default behavior is to assume RGB and VG pipes have scalars
413   if (!need_scale) {
414     index = NextPipe(kPipeTypeDMA, hw_block_type);
415   }
416 
417   if ((index >= num_pipe_) && (!need_scale || !hw_res_info_.has_non_scalar_rgb)) {
418     index = NextPipe(kPipeTypeRGB, hw_block_type);
419   }
420 
421   if (index >= num_pipe_) {
422     index = NextPipe(kPipeTypeVIG, hw_block_type);
423   }
424 
425   return index;
426 }
427 
IsScalingNeeded(const HWPipeInfo * pipe_info)428 bool ResourceDefault::IsScalingNeeded(const HWPipeInfo *pipe_info) {
429   const LayerRect &src_roi = pipe_info->src_roi;
430   const LayerRect &dst_roi = pipe_info->dst_roi;
431 
432   return ((dst_roi.right - dst_roi.left) != (src_roi.right - src_roi.left)) ||
433           ((dst_roi.bottom - dst_roi.top) != (src_roi.bottom - src_roi.top));
434 }
435 
ResourceStateLog()436 void ResourceDefault::ResourceStateLog() {
437   DLOGV_IF(kTagResources, "==== resource manager pipe state ====");
438   uint32_t i;
439   for (i = 0; i < num_pipe_; i++) {
440     SourcePipe *src_pipe = &src_pipes_[i];
441     DLOGV_IF(kTagResources, "index = %d, id = %x, hw_block_type = %d, owner = %s", src_pipe->index,
442              src_pipe->mdss_pipe_id, src_pipe->hw_block_type,
443              (src_pipe->owner == kPipeOwnerUserMode) ? "user mode" : "kernel mode");
444   }
445 }
446 
SrcSplitConfig(DisplayResourceContext * display_resource_ctx,const LayerRect & src_rect,const LayerRect & dst_rect,HWLayerConfig * layer_config)447 DisplayError ResourceDefault::SrcSplitConfig(DisplayResourceContext *display_resource_ctx,
448                                         const LayerRect &src_rect, const LayerRect &dst_rect,
449                                         HWLayerConfig *layer_config) {
450   HWPipeInfo *left_pipe = &layer_config->left_pipe;
451   HWPipeInfo *right_pipe = &layer_config->right_pipe;
452   uint32_t max_pipe_width = hw_res_info_.max_pipe_width;
453   uint32_t src_width = (uint32_t)(src_rect.right - src_rect.left);
454   uint32_t dst_width = (uint32_t)(dst_rect.right - dst_rect.left);
455 
456   if (src_width != dst_width) {
457     max_pipe_width =  hw_res_info_.max_scaler_pipe_width;
458   }
459 
460   // Layer cannot qualify for SrcSplit if source or destination width exceeds max pipe width.
461   if ((src_width > max_pipe_width) || (dst_width > max_pipe_width)) {
462     SplitRect(src_rect, dst_rect, &left_pipe->src_roi, &left_pipe->dst_roi, &right_pipe->src_roi,
463               &right_pipe->dst_roi);
464     left_pipe->valid = true;
465     right_pipe->valid = true;
466   } else {
467     left_pipe->src_roi = src_rect;
468     left_pipe->dst_roi = dst_rect;
469     left_pipe->valid = true;
470     *right_pipe = {};
471   }
472 
473   return kErrorNone;
474 }
475 
DisplaySplitConfig(DisplayResourceContext * display_resource_ctx,const LayerRect & src_rect,const LayerRect & dst_rect,HWLayerConfig * layer_config)476 DisplayError ResourceDefault::DisplaySplitConfig(DisplayResourceContext *display_resource_ctx,
477                                             const LayerRect &src_rect, const LayerRect &dst_rect,
478                                             HWLayerConfig *layer_config) {
479   HWMixerAttributes &mixer_attributes = display_resource_ctx->mixer_attributes;
480 
481   // for display split case
482   HWPipeInfo *left_pipe = &layer_config->left_pipe;
483   HWPipeInfo *right_pipe = &layer_config->right_pipe;
484   LayerRect scissor_left, scissor_right, dst_left, crop_left, crop_right, dst_right;
485 
486   scissor_left.right = FLOAT(mixer_attributes.split_left);
487   scissor_left.bottom = FLOAT(mixer_attributes.height);
488 
489   scissor_right.left = FLOAT(mixer_attributes.split_left);
490   scissor_right.top = 0.0f;
491   scissor_right.right = FLOAT(mixer_attributes.width);
492   scissor_right.bottom = FLOAT(mixer_attributes.height);
493 
494   crop_left = src_rect;
495   dst_left = dst_rect;
496   crop_right = crop_left;
497   dst_right = dst_left;
498 
499   bool crop_left_valid = CalculateCropRects(scissor_left, &crop_left, &dst_left);
500   bool crop_right_valid = false;
501 
502   if (IsValid(scissor_right)) {
503     crop_right_valid = CalculateCropRects(scissor_right, &crop_right, &dst_right);
504   }
505 
506   // Reset left_pipe and right_pipe to invalid by default
507   *left_pipe = {};
508   *right_pipe = {};
509 
510   if (crop_left_valid) {
511     // assign left pipe
512     left_pipe->src_roi = crop_left;
513     left_pipe->dst_roi = dst_left;
514     left_pipe->valid = true;
515   }
516 
517   // assign right pipe if needed
518   if (crop_right_valid) {
519     right_pipe->src_roi = crop_right;
520     right_pipe->dst_roi = dst_right;
521     right_pipe->valid = true;
522   }
523 
524   return kErrorNone;
525 }
526 
Config(DisplayResourceContext * display_resource_ctx,HWLayers * hw_layers)527 DisplayError ResourceDefault::Config(DisplayResourceContext *display_resource_ctx,
528                                 HWLayers *hw_layers) {
529   HWLayersInfo &layer_info = hw_layers->info;
530   DisplayError error = kErrorNone;
531   const Layer &layer = layer_info.hw_layers.at(0);
532 
533   error = ValidateLayerParams(&layer);
534   if (error != kErrorNone) {
535     return error;
536   }
537 
538   struct HWLayerConfig *layer_config = &hw_layers->config[0];
539   HWPipeInfo &left_pipe = layer_config->left_pipe;
540   HWPipeInfo &right_pipe = layer_config->right_pipe;
541 
542   LayerRect src_rect = layer.src_rect;
543   LayerRect dst_rect = layer.dst_rect;
544 
545   error = ValidateDimensions(src_rect, dst_rect);
546   if (error != kErrorNone) {
547     return error;
548   }
549 
550   BufferLayout layout = GetBufferLayout(layer.input_buffer.format);
551   error = ValidateScaling(src_rect, dst_rect, false /*rotated90 */, layout,
552                           false /* use_rotator_downscale */);
553   if (error != kErrorNone) {
554     return error;
555   }
556 
557   if (hw_res_info_.is_src_split) {
558     error = SrcSplitConfig(display_resource_ctx, src_rect, dst_rect, layer_config);
559   } else {
560     error = DisplaySplitConfig(display_resource_ctx, src_rect, dst_rect, layer_config);
561   }
562 
563   if (error != kErrorNone) {
564     return error;
565   }
566 
567   error = AlignPipeConfig(&layer, &left_pipe, &right_pipe);
568   if (error != kErrorNone) {
569     return error;
570   }
571 
572   // set z_order, left_pipe should always be valid
573   left_pipe.z_order = 0;
574 
575   DLOGV_IF(kTagResources, "==== FB layer Config ====");
576   Log(kTagResources, "input layer src_rect", layer.src_rect);
577   Log(kTagResources, "input layer dst_rect", layer.dst_rect);
578   Log(kTagResources, "cropped src_rect", src_rect);
579   Log(kTagResources, "cropped dst_rect", dst_rect);
580   Log(kTagResources, "left pipe src", layer_config->left_pipe.src_roi);
581   Log(kTagResources, "left pipe dst", layer_config->left_pipe.dst_roi);
582   if (right_pipe.valid) {
583     right_pipe.z_order = 0;
584     Log(kTagResources, "right pipe src", layer_config->right_pipe.src_roi);
585     Log(kTagResources, "right pipe dst", layer_config->right_pipe.dst_roi);
586   }
587 
588   return error;
589 }
590 
CalculateCropRects(const LayerRect & scissor,LayerRect * crop,LayerRect * dst)591 bool ResourceDefault::CalculateCropRects(const LayerRect &scissor, LayerRect *crop,
592                                          LayerRect *dst) {
593   float &crop_left = crop->left;
594   float &crop_top = crop->top;
595   float &crop_right = crop->right;
596   float &crop_bottom = crop->bottom;
597   float crop_width = crop->right - crop->left;
598   float crop_height = crop->bottom - crop->top;
599 
600   float &dst_left = dst->left;
601   float &dst_top = dst->top;
602   float &dst_right = dst->right;
603   float &dst_bottom = dst->bottom;
604   float dst_width = dst->right - dst->left;
605   float dst_height = dst->bottom - dst->top;
606 
607   const float &sci_left = scissor.left;
608   const float &sci_top = scissor.top;
609   const float &sci_right = scissor.right;
610   const float &sci_bottom = scissor.bottom;
611 
612   float left_cut_ratio = 0.0, right_cut_ratio = 0.0, top_cut_ratio = 0.0, bottom_cut_ratio = 0.0;
613   bool need_cut = false;
614 
615   if (dst_left < sci_left) {
616     left_cut_ratio = (sci_left - dst_left) / dst_width;
617     dst_left = sci_left;
618     need_cut = true;
619   }
620 
621   if (dst_right > sci_right) {
622     right_cut_ratio = (dst_right - sci_right) / dst_width;
623     dst_right = sci_right;
624     need_cut = true;
625   }
626 
627   if (dst_top < sci_top) {
628     top_cut_ratio = (sci_top - dst_top) / (dst_height);
629     dst_top = sci_top;
630     need_cut = true;
631   }
632 
633   if (dst_bottom > sci_bottom) {
634     bottom_cut_ratio = (dst_bottom - sci_bottom) / (dst_height);
635     dst_bottom = sci_bottom;
636     need_cut = true;
637   }
638 
639   if (!need_cut)
640     return true;
641 
642   crop_left += crop_width * left_cut_ratio;
643   crop_top += crop_height * top_cut_ratio;
644   crop_right -= crop_width * right_cut_ratio;
645   crop_bottom -= crop_height * bottom_cut_ratio;
646   Normalize(1, 1, crop);
647   Normalize(1, 1, dst);
648   if (IsValid(*crop) && IsValid(*dst))
649     return true;
650   else
651     return false;
652 }
653 
ValidateLayerParams(const Layer * layer)654 DisplayError ResourceDefault::ValidateLayerParams(const Layer *layer) {
655   const LayerRect &src = layer->src_rect;
656   const LayerRect &dst = layer->dst_rect;
657   const LayerBuffer &input_buffer = layer->input_buffer;
658 
659   if (input_buffer.format == kFormatInvalid) {
660     DLOGV_IF(kTagResources, "Invalid input buffer format %d", input_buffer.format);
661     return kErrorNotSupported;
662   }
663 
664   if (!IsValid(src) || !IsValid(dst)) {
665     Log(kTagResources, "input layer src_rect", src);
666     Log(kTagResources, "input layer dst_rect", dst);
667     return kErrorNotSupported;
668   }
669 
670   // Make sure source in integral only if it is a non secure layer.
671   if (!input_buffer.flags.secure &&
672       ((src.left - roundf(src.left) != 0.0f) ||
673        (src.top - roundf(src.top) != 0.0f) ||
674        (src.right - roundf(src.right) != 0.0f) ||
675        (src.bottom - roundf(src.bottom) != 0.0f))) {
676     DLOGV_IF(kTagResources, "Input ROI is not integral");
677     return kErrorNotSupported;
678   }
679 
680   return kErrorNone;
681 }
682 
ValidateDimensions(const LayerRect & crop,const LayerRect & dst)683 DisplayError ResourceDefault::ValidateDimensions(const LayerRect &crop, const LayerRect &dst) {
684   if (!IsValid(crop)) {
685     Log(kTagResources, "Invalid crop rect", crop);
686     return kErrorNotSupported;
687   }
688 
689   if (!IsValid(dst)) {
690     Log(kTagResources, "Invalid dst rect", dst);
691     return kErrorNotSupported;
692   }
693 
694   float crop_width = crop.right - crop.left;
695   float crop_height = crop.bottom - crop.top;
696   float dst_width = dst.right - dst.left;
697   float dst_height = dst.bottom - dst.top;
698 
699   if ((UINT32(crop_width - dst_width) == 1) || (UINT32(crop_height - dst_height) == 1)) {
700     DLOGV_IF(kTagResources, "One pixel downscaling detected crop_w = %.0f, dst_w = %.0f, " \
701              "crop_h = %.0f, dst_h = %.0f", crop_width, dst_width, crop_height, dst_height);
702     return kErrorNotSupported;
703   }
704 
705   return kErrorNone;
706 }
707 
ValidatePipeParams(HWPipeInfo * pipe_info,LayerBufferFormat format)708 DisplayError ResourceDefault::ValidatePipeParams(HWPipeInfo *pipe_info, LayerBufferFormat format) {
709   DisplayError error = kErrorNone;
710 
711   const LayerRect &src_rect = pipe_info->src_roi;
712   const LayerRect &dst_rect = pipe_info->dst_roi;
713 
714   error = ValidateDimensions(src_rect, dst_rect);
715   if (error != kErrorNone) {
716     return error;
717   }
718 
719   BufferLayout layout = GetBufferLayout(format);
720   error = ValidateScaling(src_rect, dst_rect, false /* rotated90 */, layout,
721                           false /* use_rotator_downscale */);
722   if (error != kErrorNone) {
723     return error;
724   }
725 
726   return kErrorNone;
727 }
728 
ValidateScaling(const LayerRect & crop,const LayerRect & dst,bool rotate90,BufferLayout layout,bool use_rotator_downscale)729 DisplayError ResourceDefault::ValidateScaling(const LayerRect &crop, const LayerRect &dst,
730                                               bool rotate90, BufferLayout layout,
731                                               bool use_rotator_downscale) {
732   DisplayError error = kErrorNone;
733 
734   float scale_x = 1.0f;
735   float scale_y = 1.0f;
736 
737   error = GetScaleFactor(crop, dst, &scale_x, &scale_y);
738   if (error != kErrorNone) {
739     return error;
740   }
741 
742   error = ValidateDownScaling(scale_x, scale_y, (layout != kLinear));
743   if (error != kErrorNone) {
744     return error;
745   }
746 
747   error = ValidateUpScaling(scale_x, scale_y);
748   if (error != kErrorNone) {
749     return error;
750   }
751 
752   return kErrorNone;
753 }
754 
ValidateDownScaling(float scale_x,float scale_y,bool ubwc_tiled)755 DisplayError ResourceDefault::ValidateDownScaling(float scale_x, float scale_y, bool ubwc_tiled) {
756   if ((UINT32(scale_x) > 1) || (UINT32(scale_y) > 1)) {
757     float max_scale_down = FLOAT(hw_res_info_.max_scale_down);
758 
759     // MDP H/W cannot apply decimation on UBWC tiled framebuffer
760     if (!ubwc_tiled && hw_res_info_.has_decimation) {
761       max_scale_down *= FLOAT(kMaxDecimationDownScaleRatio);
762     }
763 
764     if (scale_x > max_scale_down || scale_y > max_scale_down) {
765       DLOGV_IF(kTagResources,
766                "Scaling down is over the limit: scale_x = %.0f, scale_y = %.0f, " \
767                "has_deci = %d", scale_x, scale_y, hw_res_info_.has_decimation);
768       return kErrorNotSupported;
769     }
770   }
771 
772   DLOGV_IF(kTagResources, "scale_x = %.4f, scale_y = %.4f", scale_x, scale_y);
773 
774   return kErrorNone;
775 }
776 
ValidateUpScaling(float scale_x,float scale_y)777 DisplayError ResourceDefault::ValidateUpScaling(float scale_x, float scale_y) {
778   float max_scale_up = FLOAT(hw_res_info_.max_scale_up);
779 
780   if (UINT32(scale_x) < 1 && scale_x > 0.0f) {
781     if ((1.0f / scale_x) > max_scale_up) {
782       DLOGV_IF(kTagResources, "Scaling up is over limit scale_x = %f", 1.0f / scale_x);
783       return kErrorNotSupported;
784     }
785   }
786 
787   if (UINT32(scale_y) < 1 && scale_y > 0.0f) {
788     if ((1.0f / scale_y) > max_scale_up) {
789       DLOGV_IF(kTagResources, "Scaling up is over limit scale_y = %f", 1.0f / scale_y);
790       return kErrorNotSupported;
791     }
792   }
793 
794   DLOGV_IF(kTagResources, "scale_x = %.4f, scale_y = %.4f", scale_x, scale_y);
795 
796   return kErrorNone;
797 }
798 
GetScaleFactor(const LayerRect & crop,const LayerRect & dst,float * scale_x,float * scale_y)799 DisplayError ResourceDefault::GetScaleFactor(const LayerRect &crop, const LayerRect &dst,
800                                         float *scale_x, float *scale_y) {
801   float crop_width = crop.right - crop.left;
802   float crop_height = crop.bottom - crop.top;
803   float dst_width = dst.right - dst.left;
804   float dst_height = dst.bottom - dst.top;
805 
806   *scale_x = crop_width / dst_width;
807   *scale_y = crop_height / dst_height;
808 
809   return kErrorNone;
810 }
811 
SetDecimationFactor(HWPipeInfo * pipe)812 DisplayError ResourceDefault::SetDecimationFactor(HWPipeInfo *pipe) {
813   float src_h = pipe->src_roi.bottom - pipe->src_roi.top;
814   float dst_h = pipe->dst_roi.bottom - pipe->dst_roi.top;
815   float down_scale_h = src_h / dst_h;
816 
817   float src_w = pipe->src_roi.right - pipe->src_roi.left;
818   float dst_w = pipe->dst_roi.right - pipe->dst_roi.left;
819   float down_scale_w = src_w / dst_w;
820 
821   pipe->horizontal_decimation = 0;
822   pipe->vertical_decimation = 0;
823 
824   if (CalculateDecimation(down_scale_w, &pipe->horizontal_decimation) != kErrorNone) {
825     return kErrorNotSupported;
826   }
827 
828   if (CalculateDecimation(down_scale_h, &pipe->vertical_decimation) != kErrorNone) {
829     return kErrorNotSupported;
830   }
831 
832   DLOGI_IF(kTagResources, "horizontal_decimation %d, vertical_decimation %d",
833            pipe->horizontal_decimation, pipe->vertical_decimation);
834 
835   return kErrorNone;
836 }
837 
SplitRect(const LayerRect & src_rect,const LayerRect & dst_rect,LayerRect * src_left,LayerRect * dst_left,LayerRect * src_right,LayerRect * dst_right)838 void ResourceDefault::SplitRect(const LayerRect &src_rect, const LayerRect &dst_rect,
839                            LayerRect *src_left, LayerRect *dst_left, LayerRect *src_right,
840                            LayerRect *dst_right) {
841   // Split rectangle horizontally and evenly into two.
842   float src_width = src_rect.right - src_rect.left;
843   float dst_width = dst_rect.right - dst_rect.left;
844   float src_width_ori = src_width;
845   src_width = ROUND_UP_ALIGN_DOWN(src_width / 2, 1);
846   dst_width = ROUND_UP_ALIGN_DOWN(dst_width * src_width / src_width_ori, 1);
847 
848   src_left->left = src_rect.left;
849   src_left->right = src_rect.left + src_width;
850   src_right->left = src_left->right;
851   src_right->right = src_rect.right;
852 
853   src_left->top = src_rect.top;
854   src_left->bottom = src_rect.bottom;
855   src_right->top = src_rect.top;
856   src_right->bottom = src_rect.bottom;
857 
858   dst_left->top = dst_rect.top;
859   dst_left->bottom = dst_rect.bottom;
860   dst_right->top = dst_rect.top;
861   dst_right->bottom = dst_rect.bottom;
862 
863   dst_left->left = dst_rect.left;
864   dst_left->right = dst_rect.left + dst_width;
865   dst_right->left = dst_left->right;
866   dst_right->right = dst_rect.right;
867 }
868 
AlignPipeConfig(const Layer * layer,HWPipeInfo * left_pipe,HWPipeInfo * right_pipe)869 DisplayError ResourceDefault::AlignPipeConfig(const Layer *layer, HWPipeInfo *left_pipe,
870                                               HWPipeInfo *right_pipe) {
871   DisplayError error = kErrorNone;
872   if (!left_pipe->valid) {
873     DLOGE_IF(kTagResources, "left_pipe should not be invalid");
874     return kErrorNotSupported;
875   }
876 
877   error = ValidatePipeParams(left_pipe, layer->input_buffer.format);
878   if (error != kErrorNone) {
879     goto PipeConfigExit;
880   }
881 
882   if (right_pipe->valid) {
883     // Make sure the  left and right ROI are conjunct
884     right_pipe->src_roi.left = left_pipe->src_roi.right;
885     right_pipe->dst_roi.left = left_pipe->dst_roi.right;
886     error = ValidatePipeParams(right_pipe, layer->input_buffer.format);
887   }
888 
889 PipeConfigExit:
890   if (error != kErrorNone) {
891     DLOGV_IF(kTagResources, "AlignPipeConfig failed");
892   }
893   return error;
894 }
895 
CalculateDecimation(float downscale,uint8_t * decimation)896 DisplayError ResourceDefault::CalculateDecimation(float downscale, uint8_t *decimation) {
897   float max_down_scale = FLOAT(hw_res_info_.max_scale_down);
898 
899   if (downscale <= max_down_scale) {
900     *decimation = 0;
901     return kErrorNone;
902   } else if (!hw_res_info_.has_decimation) {
903     DLOGE("Downscaling exceeds the maximum MDP downscale limit but decimation not enabled");
904     return kErrorNotSupported;
905   }
906 
907   // Decimation is the remaining downscale factor after doing max SDE downscale.
908   // In SDE, decimation is supported in powers of 2.
909   // For ex: If a pipe needs downscale of 8 but max_down_scale is 4
910   // So decimation = powf(2.0, ceilf(log2f(8 / 4))) = powf(2.0, 1.0) = 2
911   *decimation = UINT8(ceilf(log2f(downscale / max_down_scale)));
912   return kErrorNone;
913 }
914 
ValidateAndSetCursorPosition(Handle display_ctx,HWLayers * hw_layers,int x,int y,DisplayConfigVariableInfo * fb_config)915 DisplayError ResourceDefault::ValidateAndSetCursorPosition(Handle display_ctx, HWLayers *hw_layers,
916                                                            int x, int y,
917                                                            DisplayConfigVariableInfo *fb_config) {
918   return kErrorNotSupported;
919 }
920 
SetMaxBandwidthMode(HWBwModes mode)921 DisplayError ResourceDefault::SetMaxBandwidthMode(HWBwModes mode) {
922   return kErrorNotSupported;
923 }
924 
GetScaleLutConfig(HWScaleLutInfo * lut_info)925 DisplayError ResourceDefault::GetScaleLutConfig(HWScaleLutInfo *lut_info) {
926   return kErrorNone;
927 }
928 
SetDetailEnhancerData(Handle display_ctx,const DisplayDetailEnhancerData & de_data)929 DisplayError ResourceDefault::SetDetailEnhancerData(Handle display_ctx,
930                                                     const DisplayDetailEnhancerData &de_data) {
931   return kErrorNotSupported;
932 }
933 
UpdateSyncHandle(Handle display_ctx,const shared_ptr<Fence> & sync_handle)934 DisplayError ResourceDefault::UpdateSyncHandle(Handle display_ctx,
935                                                const shared_ptr<Fence> &sync_handle) {
936   return kErrorNotSupported;
937 }
938 
939 }  // namespace sdm
940