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 
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)191 DisplayError CompManager::ReconfigureDisplay(Handle comp_handle,
192                                              const HWDisplayAttributes &display_attributes,
193                                              const HWPanelInfo &hw_panel_info,
194                                              const HWMixerAttributes &mixer_attributes,
195                                              const DisplayConfigVariableInfo &fb_config,
196                                              uint32_t *default_clk_hz) {
197   SCOPE_LOCK(locker_);
198   DTRACE_SCOPED();
199 
200   DisplayError error = kErrorNone;
201   DisplayCompositionContext *display_comp_ctx =
202                              reinterpret_cast<DisplayCompositionContext *>(comp_handle);
203 
204   error = resource_intf_->ReconfigureDisplay(display_comp_ctx->display_resource_ctx,
205                                              display_attributes, hw_panel_info, mixer_attributes);
206   if (error != kErrorNone) {
207     return error;
208   }
209 
210   error = resource_intf_->Perform(ResourceInterface::kCmdGetDefaultClk,
211                                   display_comp_ctx->display_resource_ctx, default_clk_hz);
212   if (error != kErrorNone) {
213     return error;
214   }
215 
216   if (display_comp_ctx->strategy) {
217     error = display_comp_ctx->strategy->Reconfigure(hw_panel_info, display_attributes,
218                                                     mixer_attributes, fb_config);
219     if (error != kErrorNone) {
220       DLOGE("Unable to Reconfigure strategy.");
221       display_comp_ctx->strategy->Deinit();
222       delete display_comp_ctx->strategy;
223       display_comp_ctx->strategy = NULL;
224       return error;
225     }
226   }
227 
228   // For HDMI S3D mode, set max_layers_ to 0 so that primary display would fall back
229   // to GPU composition to release pipes for HDMI.
230   if (display_comp_ctx->display_type == kPluggable) {
231     if (hw_panel_info.s3d_mode != kS3DModeNone) {
232       max_layers_ = 0;
233     } else {
234       max_layers_ = kMaxSDELayers;
235     }
236   }
237 
238   // Update new resolution.
239   display_comp_ctx->fb_config = fb_config;
240   return error;
241 }
242 
PrepareStrategyConstraints(Handle comp_handle,HWLayers * hw_layers)243 void CompManager::PrepareStrategyConstraints(Handle comp_handle, HWLayers *hw_layers) {
244   DisplayCompositionContext *display_comp_ctx =
245                              reinterpret_cast<DisplayCompositionContext *>(comp_handle);
246   StrategyConstraints *constraints = &display_comp_ctx->constraints;
247 
248   constraints->safe_mode = safe_mode_;
249   constraints->max_layers = max_layers_;
250 
251   // Limit 2 layer SDE Comp if its not a Primary Display.
252   // Safe mode is the policy for External display on a low end device.
253   if (!display_comp_ctx->is_primary_panel) {
254     bool low_end_hw = ((hw_res_info_.num_vig_pipe + hw_res_info_.num_rgb_pipe +
255                         hw_res_info_.num_dma_pipe) <= kSafeModeThreshold);
256     constraints->max_layers = display_comp_ctx->display_type == kBuiltIn ?
257                               max_sde_builtin_layers_ : max_sde_ext_layers_;
258     constraints->safe_mode = (low_end_hw && !hw_res_info_.separate_rotator) ? true : safe_mode_;
259   }
260 
261   // If a strategy fails after successfully allocating resources, then set safe mode
262   if (display_comp_ctx->remaining_strategies != display_comp_ctx->max_strategies) {
263     constraints->safe_mode = true;
264   }
265 
266   // TODO(user): App layer count will change for hybrid composition
267   uint32_t app_layer_count = UINT32(hw_layers->info.stack->layers.size()) - 1;
268   if (display_comp_ctx->idle_fallback || display_comp_ctx->thermal_fallback_) {
269     // Handle the idle timeout by falling back
270     constraints->safe_mode = true;
271   }
272 
273   // Avoid safe mode, if there is only one app layer.
274   if (app_layer_count == 1) {
275      constraints->safe_mode = false;
276   }
277 }
278 
GenerateROI(Handle display_ctx,HWLayers * hw_layers)279 void CompManager::GenerateROI(Handle display_ctx, HWLayers *hw_layers) {
280   SCOPE_LOCK(locker_);
281   DisplayCompositionContext *disp_comp_ctx =
282                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
283   return disp_comp_ctx->strategy->GenerateROI(&hw_layers->info, disp_comp_ctx->pu_constraints);
284 }
285 
PrePrepare(Handle display_ctx,HWLayers * hw_layers)286 void CompManager::PrePrepare(Handle display_ctx, HWLayers *hw_layers) {
287   SCOPE_LOCK(locker_);
288   DisplayCompositionContext *display_comp_ctx =
289                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
290   display_comp_ctx->strategy->Start(&hw_layers->info, &display_comp_ctx->max_strategies);
291   display_comp_ctx->remaining_strategies = display_comp_ctx->max_strategies;
292 }
293 
Prepare(Handle display_ctx,HWLayers * hw_layers)294 DisplayError CompManager::Prepare(Handle display_ctx, HWLayers *hw_layers) {
295   SCOPE_LOCK(locker_);
296 
297   DTRACE_SCOPED();
298   DisplayCompositionContext *display_comp_ctx =
299                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
300   Handle &display_resource_ctx = display_comp_ctx->display_resource_ctx;
301 
302   DisplayError error = kErrorUndefined;
303 
304   PrepareStrategyConstraints(display_ctx, hw_layers);
305 
306   // Select a composition strategy, and try to allocate resources for it.
307   resource_intf_->Start(display_resource_ctx);
308 
309   bool exit = false;
310   uint32_t &count = display_comp_ctx->remaining_strategies;
311   for (; !exit && count > 0; count--) {
312     error = display_comp_ctx->strategy->GetNextStrategy(&display_comp_ctx->constraints);
313     if (error != kErrorNone) {
314       // Composition strategies exhausted. Resource Manager could not allocate resources even for
315       // GPU composition. This will never happen.
316       exit = true;
317     }
318 
319     if (!exit) {
320       error = resource_intf_->Prepare(display_resource_ctx, hw_layers);
321       // Exit if successfully prepared resource, else try next strategy.
322       exit = (error == kErrorNone);
323     }
324   }
325 
326   if (error != kErrorNone) {
327     resource_intf_->Stop(display_resource_ctx, hw_layers);
328     DLOGE("Composition strategies exhausted for display = %d", display_comp_ctx->display_type);
329     return error;
330   }
331 
332   return error;
333 }
334 
PostPrepare(Handle display_ctx,HWLayers * hw_layers)335 DisplayError CompManager::PostPrepare(Handle display_ctx, HWLayers *hw_layers) {
336   SCOPE_LOCK(locker_);
337   DisplayCompositionContext *display_comp_ctx =
338                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
339   Handle &display_resource_ctx = display_comp_ctx->display_resource_ctx;
340 
341   DisplayError error = kErrorNone;
342   error = resource_intf_->PostPrepare(display_resource_ctx, hw_layers);
343   if (error != kErrorNone) {
344     return error;
345   }
346 
347   display_comp_ctx->strategy->Stop();
348 
349   return kErrorNone;
350 }
351 
Commit(Handle display_ctx,HWLayers * hw_layers)352 DisplayError CompManager::Commit(Handle display_ctx, HWLayers *hw_layers) {
353   SCOPE_LOCK(locker_);
354 
355   DisplayCompositionContext *display_comp_ctx =
356                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
357 
358   return resource_intf_->Commit(display_comp_ctx->display_resource_ctx, hw_layers);
359 }
360 
ReConfigure(Handle display_ctx,HWLayers * hw_layers)361 DisplayError CompManager::ReConfigure(Handle display_ctx, HWLayers *hw_layers) {
362   SCOPE_LOCK(locker_);
363 
364   DTRACE_SCOPED();
365   DisplayCompositionContext *display_comp_ctx =
366                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
367   Handle &display_resource_ctx = display_comp_ctx->display_resource_ctx;
368 
369   DisplayError error = kErrorUndefined;
370   resource_intf_->Start(display_resource_ctx);
371   error = resource_intf_->Prepare(display_resource_ctx, hw_layers);
372 
373   if (error != kErrorNone) {
374     DLOGE("Reconfigure failed for display = %d", display_comp_ctx->display_type);
375   }
376 
377   resource_intf_->Stop(display_resource_ctx, hw_layers);
378   if (error != kErrorNone) {
379       error = resource_intf_->PostPrepare(display_resource_ctx, hw_layers);
380   }
381 
382   return error;
383 }
384 
PostCommit(Handle display_ctx,HWLayers * hw_layers)385 DisplayError CompManager::PostCommit(Handle display_ctx, HWLayers *hw_layers) {
386   SCOPE_LOCK(locker_);
387 
388   DisplayError error = kErrorNone;
389   DisplayCompositionContext *display_comp_ctx =
390                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
391   configured_displays_.insert(display_comp_ctx->display_id);
392 
393   // Check if all poweredon displays are in the configured display list.
394   if ((powered_on_displays_.size() == configured_displays_.size())) {
395     safe_mode_ = false;
396   }
397 
398   error = resource_intf_->PostCommit(display_comp_ctx->display_resource_ctx, hw_layers);
399   if (error != kErrorNone) {
400     return error;
401   }
402 
403   display_comp_ctx->idle_fallback = false;
404 
405   Handle &display_resource_ctx = display_comp_ctx->display_resource_ctx;
406   error = resource_intf_->Stop(display_resource_ctx, hw_layers);
407 
408   DLOGV_IF(kTagCompManager, "Registered displays [%s], configured displays [%s], display %d-%d",
409            StringDisplayList(registered_displays_).c_str(),
410            StringDisplayList(configured_displays_).c_str(),
411            display_comp_ctx->display_id, display_comp_ctx->display_type);
412 
413   return error;
414 }
415 
Purge(Handle display_ctx)416 void CompManager::Purge(Handle display_ctx) {
417   SCOPE_LOCK(locker_);
418 
419   DisplayCompositionContext *display_comp_ctx =
420                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
421 
422   resource_intf_->Purge(display_comp_ctx->display_resource_ctx);
423 
424   display_comp_ctx->strategy->Purge();
425 }
426 
SetIdleTimeoutMs(Handle display_ctx,uint32_t active_ms)427 DisplayError CompManager::SetIdleTimeoutMs(Handle display_ctx, uint32_t active_ms) {
428   SCOPE_LOCK(locker_);
429 
430   DisplayCompositionContext *display_comp_ctx =
431                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
432 
433   return display_comp_ctx->strategy->SetIdleTimeoutMs(active_ms);
434 }
435 
ProcessIdleTimeout(Handle display_ctx)436 void CompManager::ProcessIdleTimeout(Handle display_ctx) {
437   SCOPE_LOCK(locker_);
438 
439   DisplayCompositionContext *display_comp_ctx =
440                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
441 
442   if (!display_comp_ctx) {
443     return;
444   }
445 
446   display_comp_ctx->idle_fallback = true;
447 }
448 
ProcessThermalEvent(Handle display_ctx,int64_t thermal_level)449 void CompManager::ProcessThermalEvent(Handle display_ctx, int64_t thermal_level) {
450   SCOPE_LOCK(locker_);
451 
452   DisplayCompositionContext *display_comp_ctx =
453           reinterpret_cast<DisplayCompositionContext *>(display_ctx);
454 
455   if (thermal_level >= kMaxThermalLevel) {
456     display_comp_ctx->thermal_fallback_ = true;
457   } else {
458     display_comp_ctx->thermal_fallback_ = false;
459   }
460 }
461 
ProcessIdlePowerCollapse(Handle display_ctx)462 void CompManager::ProcessIdlePowerCollapse(Handle display_ctx) {
463   SCOPE_LOCK(locker_);
464 
465   DisplayCompositionContext *display_comp_ctx =
466           reinterpret_cast<DisplayCompositionContext *>(display_ctx);
467 
468   if (display_comp_ctx) {
469     resource_intf_->Perform(ResourceInterface::kCmdResetLUT,
470                             display_comp_ctx->display_resource_ctx);
471   }
472 }
473 
SetMaxMixerStages(Handle display_ctx,uint32_t max_mixer_stages)474 DisplayError CompManager::SetMaxMixerStages(Handle display_ctx, uint32_t max_mixer_stages) {
475   SCOPE_LOCK(locker_);
476 
477   DisplayError error = kErrorNone;
478   DisplayCompositionContext *display_comp_ctx =
479                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
480 
481   if (display_comp_ctx) {
482     error = resource_intf_->SetMaxMixerStages(display_comp_ctx->display_resource_ctx,
483                                               max_mixer_stages);
484   }
485 
486   return error;
487 }
488 
ControlPartialUpdate(Handle display_ctx,bool enable)489 void CompManager::ControlPartialUpdate(Handle display_ctx, bool enable) {
490   SCOPE_LOCK(locker_);
491 
492   DisplayCompositionContext *display_comp_ctx =
493                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
494   display_comp_ctx->pu_constraints.enable = enable;
495 }
496 
ValidateScaling(const LayerRect & crop,const LayerRect & dst,bool rotate90)497 DisplayError CompManager::ValidateScaling(const LayerRect &crop, const LayerRect &dst,
498                                           bool rotate90) {
499   BufferLayout layout = Debug::IsUbwcTiledFrameBuffer() ? kUBWC : kLinear;
500   return resource_intf_->ValidateScaling(crop, dst, rotate90, layout, true);
501 }
502 
ValidateAndSetCursorPosition(Handle display_ctx,HWLayers * hw_layers,int x,int y)503 DisplayError CompManager::ValidateAndSetCursorPosition(Handle display_ctx, HWLayers *hw_layers,
504                                                  int x, int y) {
505   DisplayCompositionContext *display_comp_ctx =
506                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
507   Handle &display_resource_ctx = display_comp_ctx->display_resource_ctx;
508   return resource_intf_->ValidateAndSetCursorPosition(display_resource_ctx, hw_layers, x, y,
509                                                       &display_comp_ctx->fb_config);
510 }
511 
SetMaxBandwidthMode(HWBwModes mode)512 DisplayError CompManager::SetMaxBandwidthMode(HWBwModes mode) {
513   if ((!hw_res_info_.has_dyn_bw_support) || (mode >= kBwModeMax)) {
514     return kErrorNotSupported;
515   }
516 
517   return resource_intf_->SetMaxBandwidthMode(mode);
518 }
519 
GetScaleLutConfig(HWScaleLutInfo * lut_info)520 DisplayError CompManager::GetScaleLutConfig(HWScaleLutInfo *lut_info) {
521   return resource_intf_->GetScaleLutConfig(lut_info);
522 }
523 
SetDetailEnhancerData(Handle display_ctx,const DisplayDetailEnhancerData & de_data)524 DisplayError CompManager::SetDetailEnhancerData(Handle display_ctx,
525                                                 const DisplayDetailEnhancerData &de_data) {
526   SCOPE_LOCK(locker_);
527   if (!hw_res_info_.hw_dest_scalar_info.count) {
528     return kErrorResources;
529   }
530 
531   DisplayCompositionContext *display_comp_ctx =
532                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
533 
534   return resource_intf_->SetDetailEnhancerData(display_comp_ctx->display_resource_ctx, de_data);
535 }
536 
SetCompositionState(Handle display_ctx,LayerComposition composition_type,bool enable)537 DisplayError CompManager::SetCompositionState(Handle display_ctx,
538                                               LayerComposition composition_type, bool enable) {
539   SCOPE_LOCK(locker_);
540 
541   DisplayCompositionContext *display_comp_ctx =
542                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
543 
544   return display_comp_ctx->strategy->SetCompositionState(composition_type, enable);
545 }
546 
ControlDpps(bool enable)547 DisplayError CompManager::ControlDpps(bool enable) {
548   // DPPS feature and HDR using SSPP tone mapping can co-exist
549   // DPPS feature and HDR using DSPP tone mapping are mutually exclusive
550   if (dpps_ctrl_intf_ && hw_res_info_.src_tone_map.none()) {
551     return enable ? dpps_ctrl_intf_->On() : dpps_ctrl_intf_->Off();
552   }
553 
554   return kErrorNone;
555 }
556 
SetDisplayState(Handle display_ctx,DisplayState state)557 bool CompManager::SetDisplayState(Handle display_ctx, DisplayState state) {
558   DisplayCompositionContext *display_comp_ctx =
559       reinterpret_cast<DisplayCompositionContext *>(display_ctx);
560 
561   resource_intf_->Perform(ResourceInterface::kCmdSetDisplayState,
562                           display_comp_ctx->display_resource_ctx, state);
563 
564   switch (state) {
565   case kStateOff:
566     Purge(display_ctx);
567     configured_displays_.erase(display_comp_ctx->display_id);
568     DLOGV_IF(kTagCompManager, "Configured displays = [%s]",
569              StringDisplayList(configured_displays_).c_str());
570     powered_on_displays_.erase(display_comp_ctx->display_id);
571     break;
572 
573   case kStateOn:
574   case kStateDoze:
575     // Setting safe mode if there are multiple displays and one of display is already active.
576     if ((registered_displays_.size() > 1) && powered_on_displays_.size()) {
577       safe_mode_ = true;
578       DLOGV_IF(kTagCompManager, "safe_mode = %d", safe_mode_);
579     }
580     powered_on_displays_.insert(display_comp_ctx->display_id);
581     break;
582 
583   case kStateDozeSuspend:
584     configured_displays_.erase(display_comp_ctx->display_id);
585     powered_on_displays_.erase(display_comp_ctx->display_id);
586     break;
587 
588   default:
589     break;
590   }
591 
592   bool inactive = (state == kStateOff) || (state == kStateDozeSuspend);
593   UpdateStrategyConstraints(display_comp_ctx->is_primary_panel, inactive);
594 
595   return true;
596 }
597 
SetColorModesInfo(Handle display_ctx,const std::vector<PrimariesTransfer> & colormodes_cs)598 DisplayError CompManager::SetColorModesInfo(Handle display_ctx,
599                                             const std::vector<PrimariesTransfer> &colormodes_cs) {
600   DisplayCompositionContext *display_comp_ctx =
601       reinterpret_cast<DisplayCompositionContext *>(display_ctx);
602 
603   display_comp_ctx->strategy->SetColorModesInfo(colormodes_cs);
604 
605   return kErrorNone;
606 }
607 
StringDisplayList(const std::set<int32_t> & displays)608 std::string CompManager::StringDisplayList(const std::set<int32_t> &displays) {
609   std::string displays_str;
610   for (auto disps : displays) {
611     if (displays_str.empty()) {
612       displays_str = std::to_string(disps);
613     } else {
614       displays_str += ", " + std::to_string(disps);
615     }
616   }
617   return displays_str;
618 }
619 
SetBlendSpace(Handle display_ctx,const PrimariesTransfer & blend_space)620 DisplayError CompManager::SetBlendSpace(Handle display_ctx, const PrimariesTransfer &blend_space) {
621   DisplayCompositionContext *display_comp_ctx =
622       reinterpret_cast<DisplayCompositionContext *>(display_ctx);
623 
624   display_comp_ctx->strategy->SetBlendSpace(blend_space);
625 
626   return kErrorNone;
627 }
628 
HandleSecureEvent(Handle display_ctx,SecureEvent secure_event)629 void CompManager::HandleSecureEvent(Handle display_ctx, SecureEvent secure_event) {
630   DisplayCompositionContext *display_comp_ctx =
631                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
632   // Disable rotator for non secure layers at the end of secure display session, because scm call
633   // has been made to end secure display session during the display commit. Since then access to
634   // non secure memory is unavailable. So this results in smmu page fault when rotator tries to
635   // access the non secure memory.
636   if (secure_event == kSecureDisplayEnd) {
637     resource_intf_->Perform(ResourceInterface::kCmdDisableRotatorOneFrame,
638                             display_comp_ctx->display_resource_ctx);
639   }
640 }
641 
UpdateStrategyConstraints(bool is_primary,bool disabled)642 void CompManager::UpdateStrategyConstraints(bool is_primary, bool disabled) {
643   if (!is_primary) {
644     return;
645   }
646 
647   // Allow builtin display to use all pipes when primary is suspended.
648   // Restore it back to 2 after primary poweron.
649   max_sde_builtin_layers_ = (disabled && (powered_on_displays_.size() <= 1)) ? kMaxSDELayers : 2;
650 }
651 
652 }  // namespace sdm
653