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