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