1 /*
2 * Copyright (c) 2014 - 2019, 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 <core/buffer_allocator.h>
26 #include <utils/constants.h>
27 #include <utils/debug.h>
28 #include <set>
29 #include <string>
30 #include <vector>
31 
32 #include "comp_manager.h"
33 #include "strategy.h"
34 
35 #define __CLASS__ "CompManager"
36 
37 namespace sdm {
38 
Init(const HWResourceInfo & hw_res_info,ExtensionInterface * extension_intf,BufferAllocator * buffer_allocator,BufferSyncHandler * buffer_sync_handler,SocketHandler * socket_handler)39 DisplayError CompManager::Init(const HWResourceInfo &hw_res_info,
40                                ExtensionInterface *extension_intf,
41                                BufferAllocator *buffer_allocator,
42                                BufferSyncHandler *buffer_sync_handler,
43                                SocketHandler *socket_handler) {
44   SCOPE_LOCK(locker_);
45 
46   DisplayError error = kErrorNone;
47 
48   if (extension_intf) {
49     error = extension_intf->CreateResourceExtn(hw_res_info, buffer_allocator, buffer_sync_handler,
50                                                &resource_intf_);
51     extension_intf->CreateDppsControlExtn(&dpps_ctrl_intf_, socket_handler);
52   } else {
53     error = ResourceDefault::CreateResourceDefault(hw_res_info, &resource_intf_);
54   }
55 
56   if (error != kErrorNone) {
57     if (extension_intf) {
58       extension_intf->DestroyDppsControlExtn(dpps_ctrl_intf_);
59     }
60     return error;
61   }
62 
63   hw_res_info_ = hw_res_info;
64   buffer_allocator_ = buffer_allocator;
65   extension_intf_ = extension_intf;
66 
67   return error;
68 }
69 
Deinit()70 DisplayError CompManager::Deinit() {
71   SCOPE_LOCK(locker_);
72 
73   if (extension_intf_) {
74     extension_intf_->DestroyResourceExtn(resource_intf_);
75     extension_intf_->DestroyDppsControlExtn(dpps_ctrl_intf_);
76   } else {
77     ResourceDefault::DestroyResourceDefault(resource_intf_);
78   }
79 
80   return kErrorNone;
81 }
82 
RegisterDisplay(int32_t display_id,DisplayType type,const HWDisplayAttributes & display_attributes,const HWPanelInfo & hw_panel_info,const HWMixerAttributes & mixer_attributes,const DisplayConfigVariableInfo & fb_config,Handle * display_ctx,uint32_t * default_clk_hz)83 DisplayError CompManager::RegisterDisplay(int32_t display_id, DisplayType type,
84                                           const HWDisplayAttributes &display_attributes,
85                                           const HWPanelInfo &hw_panel_info,
86                                           const HWMixerAttributes &mixer_attributes,
87                                           const DisplayConfigVariableInfo &fb_config,
88                                           Handle *display_ctx, uint32_t *default_clk_hz) {
89   SCOPE_LOCK(locker_);
90 
91   DisplayError error = kErrorNone;
92 
93   DisplayCompositionContext *display_comp_ctx = new DisplayCompositionContext();
94   if (!display_comp_ctx) {
95     return kErrorMemory;
96   }
97 
98   Strategy *&strategy = display_comp_ctx->strategy;
99   strategy = new Strategy(extension_intf_, buffer_allocator_, display_id, type, hw_res_info_,
100                           hw_panel_info, mixer_attributes, display_attributes, fb_config);
101   if (!strategy) {
102     DLOGE("Unable to create strategy");
103     delete display_comp_ctx;
104     return kErrorMemory;
105   }
106 
107   error = strategy->Init();
108   if (error != kErrorNone) {
109     delete strategy;
110     delete display_comp_ctx;
111     return error;
112   }
113 
114   error =
115       resource_intf_->RegisterDisplay(display_id, type, display_attributes, hw_panel_info,
116                                       mixer_attributes, &display_comp_ctx->display_resource_ctx);
117   if (error != kErrorNone) {
118     strategy->Deinit();
119     delete strategy;
120     delete display_comp_ctx;
121     display_comp_ctx = NULL;
122     return error;
123   }
124 
125   error = resource_intf_->Perform(ResourceInterface::kCmdGetDefaultClk,
126                                   display_comp_ctx->display_resource_ctx, default_clk_hz);
127   if (error != kErrorNone) {
128     strategy->Deinit();
129     delete strategy;
130     resource_intf_->UnregisterDisplay(display_comp_ctx->display_resource_ctx);
131     delete display_comp_ctx;
132     display_comp_ctx = NULL;
133     return error;
134   }
135 
136   registered_displays_.insert(display_id);
137   display_comp_ctx->is_primary_panel = hw_panel_info.is_primary_panel;
138   display_comp_ctx->display_id = display_id;
139   display_comp_ctx->display_type = type;
140   display_comp_ctx->fb_config = fb_config;
141   *display_ctx = display_comp_ctx;
142   // New non-primary display device has been added, so move the composition mode to safe mode until
143   // resources for the added display is configured properly.
144   if (!display_comp_ctx->is_primary_panel) {
145     safe_mode_ = true;
146     max_sde_ext_layers_ = UINT32(Debug::GetExtMaxlayers());
147   }
148 
149   DLOGV_IF(kTagCompManager, "Registered displays [%s], configured displays [%s], display %d-%d",
150            StringDisplayList(registered_displays_).c_str(),
151            StringDisplayList(configured_displays_).c_str(),
152            display_comp_ctx->display_id, display_comp_ctx->display_type);
153 
154   return kErrorNone;
155 }
156 
UnregisterDisplay(Handle display_ctx)157 DisplayError CompManager::UnregisterDisplay(Handle display_ctx) {
158   SCOPE_LOCK(locker_);
159 
160   DisplayCompositionContext *display_comp_ctx =
161                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
162 
163   if (!display_comp_ctx) {
164     return kErrorParameters;
165   }
166 
167   resource_intf_->UnregisterDisplay(display_comp_ctx->display_resource_ctx);
168 
169   Strategy *&strategy = display_comp_ctx->strategy;
170   strategy->Deinit();
171   delete strategy;
172 
173   registered_displays_.erase(display_comp_ctx->display_id);
174   configured_displays_.erase(display_comp_ctx->display_id);
175   powered_on_displays_.erase(display_comp_ctx->display_id);
176 
177   if (display_comp_ctx->display_type == kPluggable) {
178     max_layers_ = kMaxSDELayers;
179   }
180 
181   DLOGV_IF(kTagCompManager, "Registered displays [%s], configured displays [%s], display %d-%d",
182            StringDisplayList(registered_displays_).c_str(),
183            StringDisplayList(configured_displays_).c_str(),
184            display_comp_ctx->display_id, display_comp_ctx->display_type);
185 
186   delete display_comp_ctx;
187   display_comp_ctx = NULL;
188   return kErrorNone;
189 }
190 
CheckEnforceSplit(Handle comp_handle,uint32_t new_refresh_rate)191 DisplayError CompManager::CheckEnforceSplit(Handle comp_handle,
192                                             uint32_t new_refresh_rate) {
193   SCOPE_LOCK(locker_);
194   DisplayError error = kErrorNone;
195   DisplayCompositionContext *display_comp_ctx =
196                              reinterpret_cast<DisplayCompositionContext *>(comp_handle);
197 
198   error = resource_intf_->Perform(ResourceInterface::kCmdCheckEnforceSplit,
199                                   display_comp_ctx->display_resource_ctx, new_refresh_rate);
200   return error;
201 }
202 
ReconfigureDisplay(Handle comp_handle,const HWDisplayAttributes & display_attributes,const HWPanelInfo & hw_panel_info,const HWMixerAttributes & mixer_attributes,const DisplayConfigVariableInfo & fb_config,uint32_t * default_clk_hz)203 DisplayError CompManager::ReconfigureDisplay(Handle comp_handle,
204                                              const HWDisplayAttributes &display_attributes,
205                                              const HWPanelInfo &hw_panel_info,
206                                              const HWMixerAttributes &mixer_attributes,
207                                              const DisplayConfigVariableInfo &fb_config,
208                                              uint32_t *default_clk_hz) {
209   SCOPE_LOCK(locker_);
210   DTRACE_SCOPED();
211 
212   DisplayError error = kErrorNone;
213   DisplayCompositionContext *display_comp_ctx =
214                              reinterpret_cast<DisplayCompositionContext *>(comp_handle);
215 
216   error = resource_intf_->ReconfigureDisplay(display_comp_ctx->display_resource_ctx,
217                                              display_attributes, hw_panel_info, mixer_attributes);
218   if (error != kErrorNone) {
219     return error;
220   }
221 
222   error = resource_intf_->Perform(ResourceInterface::kCmdGetDefaultClk,
223                                   display_comp_ctx->display_resource_ctx, default_clk_hz);
224   if (error != kErrorNone) {
225     return error;
226   }
227 
228   error = resource_intf_->Perform(ResourceInterface::kCmdCheckEnforceSplit,
229                                   display_comp_ctx->display_resource_ctx, display_attributes.fps);
230   if (error != kErrorNone) {
231     return error;
232   }
233 
234   if (display_comp_ctx->strategy) {
235     error = display_comp_ctx->strategy->Reconfigure(hw_panel_info, display_attributes,
236                                                     mixer_attributes, fb_config);
237     if (error != kErrorNone) {
238       DLOGE("Unable to Reconfigure strategy.");
239       display_comp_ctx->strategy->Deinit();
240       delete display_comp_ctx->strategy;
241       display_comp_ctx->strategy = NULL;
242       return error;
243     }
244   }
245 
246   // For HDMI S3D mode, set max_layers_ to 0 so that primary display would fall back
247   // to GPU composition to release pipes for HDMI.
248   if (display_comp_ctx->display_type == kPluggable) {
249     if (hw_panel_info.s3d_mode != kS3DModeNone) {
250       max_layers_ = 0;
251     } else {
252       max_layers_ = kMaxSDELayers;
253     }
254   }
255 
256   // Update new resolution.
257   display_comp_ctx->fb_config = fb_config;
258   return error;
259 }
260 
PrepareStrategyConstraints(Handle comp_handle,HWLayers * hw_layers)261 void CompManager::PrepareStrategyConstraints(Handle comp_handle, HWLayers *hw_layers) {
262   DisplayCompositionContext *display_comp_ctx =
263                              reinterpret_cast<DisplayCompositionContext *>(comp_handle);
264   StrategyConstraints *constraints = &display_comp_ctx->constraints;
265 
266   constraints->safe_mode = safe_mode_;
267   constraints->max_layers = max_layers_;
268 
269   // Limit 2 layer SDE Comp if its not a Primary Display.
270   // Safe mode is the policy for External display on a low end device.
271   if (!display_comp_ctx->is_primary_panel) {
272     bool low_end_hw = ((hw_res_info_.num_vig_pipe + hw_res_info_.num_rgb_pipe +
273                         hw_res_info_.num_dma_pipe) <= kSafeModeThreshold);
274     constraints->max_layers = display_comp_ctx->display_type == kBuiltIn ?
275                               max_sde_builtin_layers_ : max_sde_ext_layers_;
276     constraints->safe_mode = (low_end_hw && !hw_res_info_.separate_rotator) ? true : safe_mode_;
277   }
278 
279   // If a strategy fails after successfully allocating resources, then set safe mode
280   if (display_comp_ctx->remaining_strategies != display_comp_ctx->max_strategies) {
281     constraints->safe_mode = true;
282   }
283 
284   // TODO(user): App layer count will change for hybrid composition
285   uint32_t app_layer_count = UINT32(hw_layers->info.stack->layers.size()) - 1;
286   if (display_comp_ctx->idle_fallback || display_comp_ctx->thermal_fallback_) {
287     // Handle the idle timeout by falling back
288     constraints->safe_mode = true;
289   }
290 
291   // Avoid safe mode, if there is only one app layer.
292   if (app_layer_count == 1) {
293      constraints->safe_mode = false;
294   }
295 }
296 
GenerateROI(Handle display_ctx,HWLayers * hw_layers)297 void CompManager::GenerateROI(Handle display_ctx, HWLayers *hw_layers) {
298   SCOPE_LOCK(locker_);
299   DisplayCompositionContext *disp_comp_ctx =
300                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
301   return disp_comp_ctx->strategy->GenerateROI(&hw_layers->info, disp_comp_ctx->pu_constraints);
302 }
303 
PrePrepare(Handle display_ctx,HWLayers * hw_layers)304 void CompManager::PrePrepare(Handle display_ctx, HWLayers *hw_layers) {
305   SCOPE_LOCK(locker_);
306   DisplayCompositionContext *display_comp_ctx =
307                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
308   display_comp_ctx->strategy->Start(&hw_layers->info, &display_comp_ctx->max_strategies);
309   display_comp_ctx->remaining_strategies = display_comp_ctx->max_strategies;
310 }
311 
Prepare(Handle display_ctx,HWLayers * hw_layers)312 DisplayError CompManager::Prepare(Handle display_ctx, HWLayers *hw_layers) {
313   SCOPE_LOCK(locker_);
314 
315   DTRACE_SCOPED();
316   DisplayCompositionContext *display_comp_ctx =
317                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
318   Handle &display_resource_ctx = display_comp_ctx->display_resource_ctx;
319 
320   DisplayError error = kErrorUndefined;
321 
322   PrepareStrategyConstraints(display_ctx, hw_layers);
323 
324   // Select a composition strategy, and try to allocate resources for it.
325   resource_intf_->Start(display_resource_ctx);
326 
327   bool exit = false;
328   uint32_t &count = display_comp_ctx->remaining_strategies;
329   for (; !exit && count > 0; count--) {
330     error = display_comp_ctx->strategy->GetNextStrategy(&display_comp_ctx->constraints);
331     if (error != kErrorNone) {
332       // Composition strategies exhausted. Resource Manager could not allocate resources even for
333       // GPU composition. This will never happen.
334       exit = true;
335     }
336 
337     if (!exit) {
338       error = resource_intf_->Prepare(display_resource_ctx, hw_layers);
339       // Exit if successfully prepared resource, else try next strategy.
340       exit = (error == kErrorNone);
341     }
342   }
343 
344   if (error != kErrorNone) {
345     resource_intf_->Stop(display_resource_ctx, hw_layers);
346     DLOGE("Composition strategies exhausted for display = %d", display_comp_ctx->display_type);
347     return error;
348   }
349 
350   return error;
351 }
352 
PostPrepare(Handle display_ctx,HWLayers * hw_layers)353 DisplayError CompManager::PostPrepare(Handle display_ctx, HWLayers *hw_layers) {
354   SCOPE_LOCK(locker_);
355   DisplayCompositionContext *display_comp_ctx =
356                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
357   Handle &display_resource_ctx = display_comp_ctx->display_resource_ctx;
358 
359   DisplayError error = kErrorNone;
360   error = resource_intf_->PostPrepare(display_resource_ctx, hw_layers);
361   if (error != kErrorNone) {
362     return error;
363   }
364 
365   display_comp_ctx->strategy->Stop();
366 
367   return kErrorNone;
368 }
369 
Commit(Handle display_ctx,HWLayers * hw_layers)370 DisplayError CompManager::Commit(Handle display_ctx, HWLayers *hw_layers) {
371   SCOPE_LOCK(locker_);
372 
373   DisplayCompositionContext *display_comp_ctx =
374                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
375 
376   return resource_intf_->Commit(display_comp_ctx->display_resource_ctx, hw_layers);
377 }
378 
ReConfigure(Handle display_ctx,HWLayers * hw_layers)379 DisplayError CompManager::ReConfigure(Handle display_ctx, HWLayers *hw_layers) {
380   SCOPE_LOCK(locker_);
381 
382   DTRACE_SCOPED();
383   DisplayCompositionContext *display_comp_ctx =
384                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
385   Handle &display_resource_ctx = display_comp_ctx->display_resource_ctx;
386 
387   DisplayError error = kErrorUndefined;
388   resource_intf_->Start(display_resource_ctx);
389   error = resource_intf_->Prepare(display_resource_ctx, hw_layers);
390 
391   if (error != kErrorNone) {
392     DLOGE("Reconfigure failed for display = %d", display_comp_ctx->display_type);
393   }
394 
395   resource_intf_->Stop(display_resource_ctx, hw_layers);
396   if (error != kErrorNone) {
397       error = resource_intf_->PostPrepare(display_resource_ctx, hw_layers);
398   }
399 
400   return error;
401 }
402 
PostCommit(Handle display_ctx,HWLayers * hw_layers)403 DisplayError CompManager::PostCommit(Handle display_ctx, HWLayers *hw_layers) {
404   SCOPE_LOCK(locker_);
405 
406   DisplayError error = kErrorNone;
407   DisplayCompositionContext *display_comp_ctx =
408                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
409   configured_displays_.insert(display_comp_ctx->display_id);
410 
411   // Check if all poweredon displays are in the configured display list.
412   if ((powered_on_displays_.size() == configured_displays_.size())) {
413     safe_mode_ = false;
414   }
415 
416   error = resource_intf_->PostCommit(display_comp_ctx->display_resource_ctx, hw_layers);
417   if (error != kErrorNone) {
418     return error;
419   }
420 
421   display_comp_ctx->idle_fallback = false;
422 
423   Handle &display_resource_ctx = display_comp_ctx->display_resource_ctx;
424   error = resource_intf_->Stop(display_resource_ctx, hw_layers);
425 
426   DLOGV_IF(kTagCompManager, "Registered displays [%s], configured displays [%s], display %d-%d",
427            StringDisplayList(registered_displays_).c_str(),
428            StringDisplayList(configured_displays_).c_str(),
429            display_comp_ctx->display_id, display_comp_ctx->display_type);
430 
431   return error;
432 }
433 
Purge(Handle display_ctx)434 void CompManager::Purge(Handle display_ctx) {
435   SCOPE_LOCK(locker_);
436 
437   DisplayCompositionContext *display_comp_ctx =
438                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
439 
440   resource_intf_->Purge(display_comp_ctx->display_resource_ctx);
441 
442   display_comp_ctx->strategy->Purge();
443 }
444 
SetIdleTimeoutMs(Handle display_ctx,uint32_t active_ms)445 DisplayError CompManager::SetIdleTimeoutMs(Handle display_ctx, uint32_t active_ms) {
446   SCOPE_LOCK(locker_);
447 
448   DisplayCompositionContext *display_comp_ctx =
449                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
450 
451   return display_comp_ctx->strategy->SetIdleTimeoutMs(active_ms);
452 }
453 
ProcessIdleTimeout(Handle display_ctx)454 void CompManager::ProcessIdleTimeout(Handle display_ctx) {
455   SCOPE_LOCK(locker_);
456 
457   DisplayCompositionContext *display_comp_ctx =
458                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
459 
460   if (!display_comp_ctx) {
461     return;
462   }
463 
464   display_comp_ctx->idle_fallback = true;
465 }
466 
ProcessThermalEvent(Handle display_ctx,int64_t thermal_level)467 void CompManager::ProcessThermalEvent(Handle display_ctx, int64_t thermal_level) {
468   SCOPE_LOCK(locker_);
469 
470   DisplayCompositionContext *display_comp_ctx =
471           reinterpret_cast<DisplayCompositionContext *>(display_ctx);
472 
473   if (thermal_level >= kMaxThermalLevel) {
474     display_comp_ctx->thermal_fallback_ = true;
475   } else {
476     display_comp_ctx->thermal_fallback_ = false;
477   }
478 }
479 
ProcessIdlePowerCollapse(Handle display_ctx)480 void CompManager::ProcessIdlePowerCollapse(Handle display_ctx) {
481   SCOPE_LOCK(locker_);
482 
483   DisplayCompositionContext *display_comp_ctx =
484           reinterpret_cast<DisplayCompositionContext *>(display_ctx);
485 
486   if (display_comp_ctx) {
487     resource_intf_->Perform(ResourceInterface::kCmdResetLUT,
488                             display_comp_ctx->display_resource_ctx);
489   }
490 }
491 
SetMaxMixerStages(Handle display_ctx,uint32_t max_mixer_stages)492 DisplayError CompManager::SetMaxMixerStages(Handle display_ctx, uint32_t max_mixer_stages) {
493   SCOPE_LOCK(locker_);
494 
495   DisplayError error = kErrorNone;
496   DisplayCompositionContext *display_comp_ctx =
497                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
498 
499   if (display_comp_ctx) {
500     error = resource_intf_->SetMaxMixerStages(display_comp_ctx->display_resource_ctx,
501                                               max_mixer_stages);
502   }
503 
504   return error;
505 }
506 
ControlPartialUpdate(Handle display_ctx,bool enable)507 void CompManager::ControlPartialUpdate(Handle display_ctx, bool enable) {
508   SCOPE_LOCK(locker_);
509 
510   DisplayCompositionContext *display_comp_ctx =
511                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
512   display_comp_ctx->pu_constraints.enable = enable;
513 }
514 
ValidateScaling(const LayerRect & crop,const LayerRect & dst,bool rotate90)515 DisplayError CompManager::ValidateScaling(const LayerRect &crop, const LayerRect &dst,
516                                           bool rotate90) {
517   BufferLayout layout = Debug::IsUbwcTiledFrameBuffer() ? kUBWC : kLinear;
518   return resource_intf_->ValidateScaling(crop, dst, rotate90, layout, true);
519 }
520 
ValidateAndSetCursorPosition(Handle display_ctx,HWLayers * hw_layers,int x,int y)521 DisplayError CompManager::ValidateAndSetCursorPosition(Handle display_ctx, HWLayers *hw_layers,
522                                                  int x, int y) {
523   DisplayCompositionContext *display_comp_ctx =
524                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
525   Handle &display_resource_ctx = display_comp_ctx->display_resource_ctx;
526   return resource_intf_->ValidateAndSetCursorPosition(display_resource_ctx, hw_layers, x, y,
527                                                       &display_comp_ctx->fb_config);
528 }
529 
SetMaxBandwidthMode(HWBwModes mode)530 DisplayError CompManager::SetMaxBandwidthMode(HWBwModes mode) {
531   if ((!hw_res_info_.has_dyn_bw_support) || (mode >= kBwModeMax)) {
532     return kErrorNotSupported;
533   }
534 
535   return resource_intf_->SetMaxBandwidthMode(mode);
536 }
537 
GetScaleLutConfig(HWScaleLutInfo * lut_info)538 DisplayError CompManager::GetScaleLutConfig(HWScaleLutInfo *lut_info) {
539   return resource_intf_->GetScaleLutConfig(lut_info);
540 }
541 
SetDetailEnhancerData(Handle display_ctx,const DisplayDetailEnhancerData & de_data)542 DisplayError CompManager::SetDetailEnhancerData(Handle display_ctx,
543                                                 const DisplayDetailEnhancerData &de_data) {
544   SCOPE_LOCK(locker_);
545   if (!hw_res_info_.hw_dest_scalar_info.count) {
546     return kErrorResources;
547   }
548 
549   DisplayCompositionContext *display_comp_ctx =
550                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
551 
552   return resource_intf_->SetDetailEnhancerData(display_comp_ctx->display_resource_ctx, de_data);
553 }
554 
SetCompositionState(Handle display_ctx,LayerComposition composition_type,bool enable)555 DisplayError CompManager::SetCompositionState(Handle display_ctx,
556                                               LayerComposition composition_type, bool enable) {
557   SCOPE_LOCK(locker_);
558 
559   DisplayCompositionContext *display_comp_ctx =
560                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
561 
562   return display_comp_ctx->strategy->SetCompositionState(composition_type, enable);
563 }
564 
ControlDpps(bool enable)565 DisplayError CompManager::ControlDpps(bool enable) {
566   // DPPS feature and HDR using SSPP tone mapping can co-exist
567   // DPPS feature and HDR using DSPP tone mapping are mutually exclusive
568   if (dpps_ctrl_intf_ && hw_res_info_.src_tone_map.none()) {
569     return enable ? dpps_ctrl_intf_->On() : dpps_ctrl_intf_->Off();
570   }
571 
572   return kErrorNone;
573 }
574 
SetDisplayState(Handle display_ctx,DisplayState state,int sync_handle)575 bool CompManager::SetDisplayState(Handle display_ctx, DisplayState state, int sync_handle) {
576   DisplayCompositionContext *display_comp_ctx =
577       reinterpret_cast<DisplayCompositionContext *>(display_ctx);
578 
579   resource_intf_->Perform(ResourceInterface::kCmdSetDisplayState,
580                           display_comp_ctx->display_resource_ctx, state);
581 
582   switch (state) {
583   case kStateOff:
584     Purge(display_ctx);
585     configured_displays_.erase(display_comp_ctx->display_id);
586     DLOGV_IF(kTagCompManager, "Configured displays = [%s]",
587              StringDisplayList(configured_displays_).c_str());
588     powered_on_displays_.erase(display_comp_ctx->display_id);
589     break;
590 
591   case kStateOn:
592   case kStateDoze:
593     // Setting safe mode if there are multiple displays and one of display is already active.
594     if ((registered_displays_.size() > 1) && powered_on_displays_.size()) {
595       safe_mode_ = true;
596       DLOGV_IF(kTagCompManager, "safe_mode = %d", safe_mode_);
597     }
598     powered_on_displays_.insert(display_comp_ctx->display_id);
599     break;
600 
601   case kStateDozeSuspend:
602     configured_displays_.erase(display_comp_ctx->display_id);
603     powered_on_displays_.erase(display_comp_ctx->display_id);
604     break;
605 
606   default:
607     break;
608   }
609 
610   bool inactive = (state == kStateOff) || (state == kStateDozeSuspend);
611   UpdateStrategyConstraints(display_comp_ctx->is_primary_panel, inactive);
612 
613   resource_intf_->Perform(ResourceInterface::kCmdUpdateSyncHandle,
614                           display_comp_ctx->display_resource_ctx, sync_handle);
615   return true;
616 }
617 
SetColorModesInfo(Handle display_ctx,const std::vector<PrimariesTransfer> & colormodes_cs)618 DisplayError CompManager::SetColorModesInfo(Handle display_ctx,
619                                             const std::vector<PrimariesTransfer> &colormodes_cs) {
620   DisplayCompositionContext *display_comp_ctx =
621       reinterpret_cast<DisplayCompositionContext *>(display_ctx);
622 
623   display_comp_ctx->strategy->SetColorModesInfo(colormodes_cs);
624 
625   return kErrorNone;
626 }
627 
StringDisplayList(const std::set<int32_t> & displays)628 std::string CompManager::StringDisplayList(const std::set<int32_t> &displays) {
629   std::string displays_str;
630   for (auto disps : displays) {
631     if (displays_str.empty()) {
632       displays_str = std::to_string(disps);
633     } else {
634       displays_str += ", " + std::to_string(disps);
635     }
636   }
637   return displays_str;
638 }
639 
SetBlendSpace(Handle display_ctx,const PrimariesTransfer & blend_space)640 DisplayError CompManager::SetBlendSpace(Handle display_ctx, const PrimariesTransfer &blend_space) {
641   DisplayCompositionContext *display_comp_ctx =
642       reinterpret_cast<DisplayCompositionContext *>(display_ctx);
643 
644   display_comp_ctx->strategy->SetBlendSpace(blend_space);
645 
646   return kErrorNone;
647 }
648 
HandleSecureEvent(Handle display_ctx,SecureEvent secure_event)649 void CompManager::HandleSecureEvent(Handle display_ctx, SecureEvent secure_event) {
650   DisplayCompositionContext *display_comp_ctx =
651                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
652   // Disable rotator for non secure layers at the end of secure display session, because scm call
653   // has been made to end secure display session during the display commit. Since then access to
654   // non secure memory is unavailable. So this results in smmu page fault when rotator tries to
655   // access the non secure memory.
656   if (secure_event == kSecureDisplayEnd) {
657     resource_intf_->Perform(ResourceInterface::kCmdDisableRotatorOneFrame,
658                             display_comp_ctx->display_resource_ctx);
659   }
660 }
661 
UpdateStrategyConstraints(bool is_primary,bool disabled)662 void CompManager::UpdateStrategyConstraints(bool is_primary, bool disabled) {
663   if (!is_primary) {
664     return;
665   }
666 
667   // Allow builtin display to use all pipes when primary is suspended.
668   // Restore it back to 2 after primary poweron.
669   max_sde_builtin_layers_ = (disabled && (powered_on_displays_.size() <= 1)) ? kMaxSDELayers : 2;
670 }
671 
CanSkipValidate(Handle display_ctx)672 bool CompManager::CanSkipValidate(Handle display_ctx) {
673   DisplayCompositionContext *display_comp_ctx =
674       reinterpret_cast<DisplayCompositionContext *>(display_ctx);
675 
676   return display_comp_ctx->strategy->CanSkipValidate();
677 }
678 
679 }  // namespace sdm
680