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