Home | History | Annotate | Download | only in core
      1 /*
      2 * Copyright (c) 2014 - 2017, 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 <utils/constants.h>
     26 #include <utils/debug.h>
     27 #include <core/buffer_allocator.h>
     28 
     29 #include "comp_manager.h"
     30 #include "strategy.h"
     31 
     32 #define __CLASS__ "CompManager"
     33 
     34 namespace sdm {
     35 
     36 static bool NeedsScaledComposition(const DisplayConfigVariableInfo &fb_config,
     37                                    const HWMixerAttributes &mixer_attributes) {
     38   return ((fb_config.x_pixels != mixer_attributes.width) ||
     39           (fb_config.y_pixels != mixer_attributes.height));
     40 }
     41 
     42 DisplayError CompManager::Init(const HWResourceInfo &hw_res_info,
     43                                ExtensionInterface *extension_intf,
     44                                BufferAllocator *buffer_allocator,
     45                                BufferSyncHandler *buffer_sync_handler,
     46                                SocketHandler *socket_handler) {
     47   SCOPE_LOCK(locker_);
     48 
     49   DisplayError error = kErrorNone;
     50 
     51   if (extension_intf) {
     52     error = extension_intf->CreateResourceExtn(hw_res_info, buffer_allocator, buffer_sync_handler,
     53                                                &resource_intf_);
     54     extension_intf->CreateDppsControlExtn(&dpps_ctrl_intf_, socket_handler);
     55   } else {
     56     error = ResourceDefault::CreateResourceDefault(hw_res_info, &resource_intf_);
     57   }
     58 
     59   if (error != kErrorNone) {
     60     if (extension_intf) {
     61       extension_intf->DestroyDppsControlExtn(dpps_ctrl_intf_);
     62     }
     63     return error;
     64   }
     65 
     66   hw_res_info_ = hw_res_info;
     67   buffer_allocator_ = buffer_allocator;
     68   extension_intf_ = extension_intf;
     69 
     70   return error;
     71 }
     72 
     73 DisplayError CompManager::Deinit() {
     74   SCOPE_LOCK(locker_);
     75 
     76   if (extension_intf_) {
     77     extension_intf_->DestroyResourceExtn(resource_intf_);
     78     extension_intf_->DestroyDppsControlExtn(dpps_ctrl_intf_);
     79   } else {
     80     ResourceDefault::DestroyResourceDefault(resource_intf_);
     81   }
     82 
     83   return kErrorNone;
     84 }
     85 
     86 DisplayError CompManager::RegisterDisplay(DisplayType type,
     87                                           const HWDisplayAttributes &display_attributes,
     88                                           const HWPanelInfo &hw_panel_info,
     89                                           const HWMixerAttributes &mixer_attributes,
     90                                           const DisplayConfigVariableInfo &fb_config,
     91                                           Handle *display_ctx) {
     92   SCOPE_LOCK(locker_);
     93 
     94   DisplayError error = kErrorNone;
     95 
     96   DisplayCompositionContext *display_comp_ctx = new DisplayCompositionContext();
     97   if (!display_comp_ctx) {
     98     return kErrorMemory;
     99   }
    100 
    101   Strategy *&strategy = display_comp_ctx->strategy;
    102   strategy = new Strategy(extension_intf_, buffer_allocator_, type, hw_res_info_, hw_panel_info,
    103                           mixer_attributes, display_attributes, fb_config);
    104   if (!strategy) {
    105     DLOGE("Unable to create strategy");
    106     delete display_comp_ctx;
    107     return kErrorMemory;
    108   }
    109 
    110   error = strategy->Init();
    111   if (error != kErrorNone) {
    112     delete strategy;
    113     delete display_comp_ctx;
    114     return error;
    115   }
    116 
    117   error = resource_intf_->RegisterDisplay(type, display_attributes, hw_panel_info, mixer_attributes,
    118                                           &display_comp_ctx->display_resource_ctx);
    119   if (error != kErrorNone) {
    120     strategy->Deinit();
    121     delete strategy;
    122     delete display_comp_ctx;
    123     display_comp_ctx = NULL;
    124     return error;
    125   }
    126 
    127   registered_displays_[type] = 1;
    128   display_comp_ctx->is_primary_panel = hw_panel_info.is_primary_panel;
    129   display_comp_ctx->display_type = type;
    130   display_comp_ctx->fb_config = fb_config;
    131   *display_ctx = display_comp_ctx;
    132   // New non-primary display device has been added, so move the composition mode to safe mode until
    133   // resources for the added display is configured properly.
    134   if (!display_comp_ctx->is_primary_panel) {
    135     safe_mode_ = true;
    136     max_sde_ext_layers_ = UINT32(Debug::GetExtMaxlayers());
    137   }
    138 
    139   display_comp_ctx->scaled_composition = NeedsScaledComposition(fb_config, mixer_attributes);
    140   DLOGV_IF(kTagCompManager, "registered display bit mask 0x%x, configured display bit mask 0x%x, " \
    141            "display type %d", registered_displays_.to_ulong(), configured_displays_.to_ulong(),
    142            display_comp_ctx->display_type);
    143 
    144   return kErrorNone;
    145 }
    146 
    147 DisplayError CompManager::UnregisterDisplay(Handle display_ctx) {
    148   SCOPE_LOCK(locker_);
    149 
    150   DisplayCompositionContext *display_comp_ctx =
    151                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
    152 
    153   if (!display_comp_ctx) {
    154     return kErrorParameters;
    155   }
    156 
    157   resource_intf_->UnregisterDisplay(display_comp_ctx->display_resource_ctx);
    158 
    159   Strategy *&strategy = display_comp_ctx->strategy;
    160   strategy->Deinit();
    161   delete strategy;
    162 
    163   registered_displays_[display_comp_ctx->display_type] = 0;
    164   configured_displays_[display_comp_ctx->display_type] = 0;
    165 
    166   if (display_comp_ctx->display_type == kHDMI) {
    167     max_layers_ = kMaxSDELayers;
    168   }
    169 
    170   DLOGV_IF(kTagCompManager, "registered display bit mask 0x%x, configured display bit mask 0x%x, " \
    171            "display type %d", registered_displays_.to_ulong(), configured_displays_.to_ulong(),
    172            display_comp_ctx->display_type);
    173 
    174   delete display_comp_ctx;
    175   display_comp_ctx = NULL;
    176   return kErrorNone;
    177 }
    178 
    179 DisplayError CompManager::ReconfigureDisplay(Handle comp_handle,
    180                                              const HWDisplayAttributes &display_attributes,
    181                                              const HWPanelInfo &hw_panel_info,
    182                                              const HWMixerAttributes &mixer_attributes,
    183                                              const DisplayConfigVariableInfo &fb_config) {
    184   SCOPE_LOCK(locker_);
    185 
    186   DisplayError error = kErrorNone;
    187   DisplayCompositionContext *display_comp_ctx =
    188                              reinterpret_cast<DisplayCompositionContext *>(comp_handle);
    189 
    190   error = resource_intf_->ReconfigureDisplay(display_comp_ctx->display_resource_ctx,
    191                                              display_attributes, hw_panel_info, mixer_attributes);
    192   if (error != kErrorNone) {
    193     return error;
    194   }
    195 
    196   if (display_comp_ctx->strategy) {
    197     error = display_comp_ctx->strategy->Reconfigure(hw_panel_info, display_attributes,
    198                                                     mixer_attributes, fb_config);
    199     if (error != kErrorNone) {
    200       DLOGE("Unable to Reconfigure strategy.");
    201       display_comp_ctx->strategy->Deinit();
    202       delete display_comp_ctx->strategy;
    203       display_comp_ctx->strategy = NULL;
    204       return error;
    205     }
    206   }
    207 
    208   // For HDMI S3D mode, set max_layers_ to 0 so that primary display would fall back
    209   // to GPU composition to release pipes for HDMI.
    210   if (display_comp_ctx->display_type == kHDMI) {
    211     if (hw_panel_info.s3d_mode != kS3DModeNone) {
    212       max_layers_ = 0;
    213     } else {
    214       max_layers_ = kMaxSDELayers;
    215     }
    216   }
    217 
    218   display_comp_ctx->scaled_composition = NeedsScaledComposition(fb_config, mixer_attributes);
    219   // Update new resolution.
    220   display_comp_ctx->fb_config = fb_config;
    221 
    222   return error;
    223 }
    224 
    225 void CompManager::PrepareStrategyConstraints(Handle comp_handle, HWLayers *hw_layers) {
    226   DisplayCompositionContext *display_comp_ctx =
    227                              reinterpret_cast<DisplayCompositionContext *>(comp_handle);
    228   StrategyConstraints *constraints = &display_comp_ctx->constraints;
    229   bool low_end_hw = ((hw_res_info_.num_vig_pipe + hw_res_info_.num_rgb_pipe +
    230                     hw_res_info_.num_dma_pipe) <= kSafeModeThreshold);
    231 
    232   constraints->safe_mode = safe_mode_;
    233   constraints->use_cursor = false;
    234   constraints->max_layers = max_layers_;
    235 
    236   // Limit 2 layer SDE Comp if its not a Primary Display.
    237   // Safe mode is the policy for External display on a low end device.
    238   if (!display_comp_ctx->is_primary_panel) {
    239     constraints->max_layers = max_sde_ext_layers_;
    240     constraints->safe_mode = (low_end_hw && !hw_res_info_.separate_rotator) ? true : safe_mode_;
    241     if(hw_layers->info.stack->flags.secure_present)
    242         secure_external_layer_ = true;
    243     else
    244         secure_external_layer_ = false;
    245   }
    246 
    247   // When Secure layer is present on external, GPU composition should be policy
    248   // for Primary on low end devices
    249   if(display_comp_ctx->is_primary_panel && (registered_displays_.count() > 1)
    250           && low_end_hw && secure_external_layer_) {
    251     DLOGV_IF(kTagCompManager,"Secure layer present for LET. Fallingback to GPU");
    252     hw_layers->info.stack->flags.skip_present = 1;
    253     for(auto &layer : hw_layers->info.stack->layers) {
    254       if(layer->composition != kCompositionGPUTarget) {
    255         layer->flags.skip = 1;
    256       }
    257     }
    258   }
    259 
    260   // If a strategy fails after successfully allocating resources, then set safe mode
    261   if (display_comp_ctx->remaining_strategies != display_comp_ctx->max_strategies) {
    262     constraints->safe_mode = true;
    263   }
    264 
    265   // Set use_cursor constraint to Strategy
    266   constraints->use_cursor = display_comp_ctx->valid_cursor;
    267 
    268   // TODO(user): App layer count will change for hybrid composition
    269   uint32_t app_layer_count = UINT32(hw_layers->info.stack->layers.size()) - 1;
    270   if (display_comp_ctx->idle_fallback || display_comp_ctx->thermal_fallback_) {
    271     // Handle the idle timeout by falling back
    272     constraints->safe_mode = true;
    273   }
    274 
    275   // Avoid safe mode, if there is only one app layer.
    276   if (app_layer_count == 1) {
    277      constraints->safe_mode = false;
    278   }
    279 }
    280 
    281 void CompManager::PrePrepare(Handle display_ctx, HWLayers *hw_layers) {
    282   SCOPE_LOCK(locker_);
    283   DisplayCompositionContext *display_comp_ctx =
    284                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
    285   display_comp_ctx->valid_cursor = SupportLayerAsCursor(display_comp_ctx, hw_layers);
    286 
    287   // pu constraints
    288   display_comp_ctx->pu_constraints.enable_cursor_pu = display_comp_ctx->valid_cursor;
    289 
    290   display_comp_ctx->strategy->Start(&hw_layers->info, &display_comp_ctx->max_strategies,
    291                                     display_comp_ctx->pu_constraints);
    292   display_comp_ctx->remaining_strategies = display_comp_ctx->max_strategies;
    293 }
    294 
    295 DisplayError CompManager::Prepare(Handle display_ctx, HWLayers *hw_layers) {
    296   SCOPE_LOCK(locker_);
    297 
    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   error = resource_intf_->Stop(display_resource_ctx, hw_layers);
    333 
    334   return error;
    335 }
    336 
    337 DisplayError CompManager::PostPrepare(Handle display_ctx, HWLayers *hw_layers) {
    338   SCOPE_LOCK(locker_);
    339   DisplayCompositionContext *display_comp_ctx =
    340                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
    341   Handle &display_resource_ctx = display_comp_ctx->display_resource_ctx;
    342 
    343   DisplayError error = kErrorNone;
    344   error = resource_intf_->PostPrepare(display_resource_ctx, hw_layers);
    345   if (error != kErrorNone) {
    346     return error;
    347   }
    348 
    349   display_comp_ctx->strategy->Stop();
    350 
    351   return kErrorNone;
    352 }
    353 
    354 DisplayError CompManager::Commit(Handle display_ctx, HWLayers *hw_layers) {
    355   SCOPE_LOCK(locker_);
    356 
    357   DisplayCompositionContext *display_comp_ctx =
    358                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
    359 
    360   return resource_intf_->Commit(display_comp_ctx->display_resource_ctx, hw_layers);
    361 }
    362 
    363 DisplayError CompManager::ReConfigure(Handle display_ctx, HWLayers *hw_layers) {
    364   SCOPE_LOCK(locker_);
    365 
    366   DisplayCompositionContext *display_comp_ctx =
    367                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
    368   Handle &display_resource_ctx = display_comp_ctx->display_resource_ctx;
    369 
    370   DisplayError error = kErrorUndefined;
    371   resource_intf_->Start(display_resource_ctx);
    372   error = resource_intf_->Prepare(display_resource_ctx, hw_layers);
    373 
    374   if (error != kErrorNone) {
    375     DLOGE("Reconfigure failed for display = %d", display_comp_ctx->display_type);
    376   }
    377 
    378   resource_intf_->Stop(display_resource_ctx, hw_layers);
    379   if (error != kErrorNone) {
    380       error = resource_intf_->PostPrepare(display_resource_ctx, hw_layers);
    381   }
    382 
    383   return error;
    384 }
    385 
    386 DisplayError CompManager::PostCommit(Handle display_ctx, HWLayers *hw_layers) {
    387   SCOPE_LOCK(locker_);
    388 
    389   DisplayError error = kErrorNone;
    390   DisplayCompositionContext *display_comp_ctx =
    391                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
    392   configured_displays_[display_comp_ctx->display_type] = 1;
    393   if (configured_displays_ == registered_displays_) {
    394     safe_mode_ = false;
    395   }
    396 
    397   error = resource_intf_->PostCommit(display_comp_ctx->display_resource_ctx, hw_layers);
    398   if (error != kErrorNone) {
    399     return error;
    400   }
    401 
    402   display_comp_ctx->idle_fallback = false;
    403 
    404   DLOGV_IF(kTagCompManager, "registered display bit mask 0x%x, configured display bit mask 0x%x, " \
    405            "display type %d", registered_displays_, configured_displays_,
    406            display_comp_ctx->display_type);
    407 
    408   return kErrorNone;
    409 }
    410 
    411 void CompManager::Purge(Handle display_ctx) {
    412   SCOPE_LOCK(locker_);
    413 
    414   DisplayCompositionContext *display_comp_ctx =
    415                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
    416 
    417   resource_intf_->Purge(display_comp_ctx->display_resource_ctx);
    418 
    419   display_comp_ctx->strategy->Purge();
    420 }
    421 
    422 DisplayError CompManager::SetIdleTimeoutMs(Handle display_ctx, uint32_t active_ms) {
    423   SCOPE_LOCK(locker_);
    424 
    425   DisplayCompositionContext *display_comp_ctx =
    426                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
    427 
    428   return display_comp_ctx->strategy->SetIdleTimeoutMs(active_ms);
    429 }
    430 
    431 void CompManager::ProcessIdleTimeout(Handle display_ctx) {
    432   SCOPE_LOCK(locker_);
    433 
    434   DisplayCompositionContext *display_comp_ctx =
    435                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
    436 
    437   if (!display_comp_ctx) {
    438     return;
    439   }
    440 
    441   display_comp_ctx->idle_fallback = true;
    442 }
    443 
    444 void CompManager::ProcessThermalEvent(Handle display_ctx, int64_t thermal_level) {
    445   SCOPE_LOCK(locker_);
    446 
    447   DisplayCompositionContext *display_comp_ctx =
    448           reinterpret_cast<DisplayCompositionContext *>(display_ctx);
    449 
    450   if (thermal_level >= kMaxThermalLevel) {
    451     display_comp_ctx->thermal_fallback_ = true;
    452   } else {
    453     display_comp_ctx->thermal_fallback_ = false;
    454   }
    455 }
    456 
    457 void CompManager::ProcessIdlePowerCollapse(Handle display_ctx) {
    458   SCOPE_LOCK(locker_);
    459 
    460   DisplayCompositionContext *display_comp_ctx =
    461           reinterpret_cast<DisplayCompositionContext *>(display_ctx);
    462 
    463   if (display_comp_ctx) {
    464     resource_intf_->Perform(ResourceInterface::kCmdResetScalarLUT,
    465                             display_comp_ctx->display_resource_ctx);
    466   }
    467 }
    468 
    469 DisplayError CompManager::SetMaxMixerStages(Handle display_ctx, uint32_t max_mixer_stages) {
    470   SCOPE_LOCK(locker_);
    471 
    472   DisplayError error = kErrorNone;
    473   DisplayCompositionContext *display_comp_ctx =
    474                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
    475 
    476   if (display_comp_ctx) {
    477     error = resource_intf_->SetMaxMixerStages(display_comp_ctx->display_resource_ctx,
    478                                               max_mixer_stages);
    479   }
    480 
    481   return error;
    482 }
    483 
    484 void CompManager::ControlPartialUpdate(Handle display_ctx, bool enable) {
    485   SCOPE_LOCK(locker_);
    486 
    487   DisplayCompositionContext *display_comp_ctx =
    488                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
    489   display_comp_ctx->pu_constraints.enable = enable;
    490 }
    491 
    492 DisplayError CompManager::ValidateScaling(const LayerRect &crop, const LayerRect &dst,
    493                                           bool rotate90) {
    494   BufferLayout layout = Debug::IsUbwcTiledFrameBuffer() ? kUBWC : kLinear;
    495   return resource_intf_->ValidateScaling(crop, dst, rotate90, layout, true);
    496 }
    497 
    498 DisplayError CompManager::ValidateAndSetCursorPosition(Handle display_ctx, HWLayers *hw_layers,
    499                                                  int x, int y) {
    500   DisplayCompositionContext *display_comp_ctx =
    501                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
    502   Handle &display_resource_ctx = display_comp_ctx->display_resource_ctx;
    503   return resource_intf_->ValidateAndSetCursorPosition(display_resource_ctx, hw_layers, x, y,
    504                                                       &display_comp_ctx->fb_config);
    505 }
    506 
    507 bool CompManager::SupportLayerAsCursor(Handle comp_handle, HWLayers *hw_layers) {
    508   DisplayCompositionContext *display_comp_ctx =
    509                              reinterpret_cast<DisplayCompositionContext *>(comp_handle);
    510   Handle &display_resource_ctx = display_comp_ctx->display_resource_ctx;
    511   LayerStack *layer_stack = hw_layers->info.stack;
    512   bool supported = false;
    513   int32_t gpu_index = -1;
    514 
    515   // HW Cursor cannot be used, if Display configuration needs scaled composition.
    516   if (display_comp_ctx->scaled_composition || !layer_stack->flags.cursor_present) {
    517     return supported;
    518   }
    519 
    520   for (int32_t i = INT32(layer_stack->layers.size() - 1); i >= 0; i--) {
    521     Layer *layer = layer_stack->layers.at(UINT32(i));
    522     if (layer->composition == kCompositionGPUTarget) {
    523       gpu_index = i;
    524       break;
    525     }
    526   }
    527   if (gpu_index <= 0) {
    528     return supported;
    529   }
    530   Layer *cursor_layer = layer_stack->layers.at(UINT32(gpu_index) - 1);
    531   if (cursor_layer->flags.cursor && !cursor_layer->flags.skip &&
    532       resource_intf_->ValidateCursorConfig(display_resource_ctx,
    533                                            cursor_layer, true) == kErrorNone) {
    534     supported = true;
    535   }
    536 
    537   return supported;
    538 }
    539 
    540 DisplayError CompManager::SetMaxBandwidthMode(HWBwModes mode) {
    541   if ((hw_res_info_.has_dyn_bw_support == false) || (mode >= kBwModeMax)) {
    542     return kErrorNotSupported;
    543   }
    544 
    545   return resource_intf_->SetMaxBandwidthMode(mode);
    546 }
    547 
    548 DisplayError CompManager::GetScaleLutConfig(HWScaleLutInfo *lut_info) {
    549   return resource_intf_->GetScaleLutConfig(lut_info);
    550 }
    551 
    552 DisplayError CompManager::SetDetailEnhancerData(Handle display_ctx,
    553                                                 const DisplayDetailEnhancerData &de_data) {
    554   SCOPE_LOCK(locker_);
    555 
    556   DisplayCompositionContext *display_comp_ctx =
    557                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
    558 
    559   return resource_intf_->SetDetailEnhancerData(display_comp_ctx->display_resource_ctx, de_data);
    560 }
    561 
    562 DisplayError CompManager::SetCompositionState(Handle display_ctx,
    563                                               LayerComposition composition_type, bool enable) {
    564   SCOPE_LOCK(locker_);
    565 
    566   DisplayCompositionContext *display_comp_ctx =
    567                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
    568 
    569   return display_comp_ctx->strategy->SetCompositionState(composition_type, enable);
    570 }
    571 
    572 DisplayError CompManager::ControlDpps(bool enable) {
    573   if (dpps_ctrl_intf_) {
    574     return enable ? dpps_ctrl_intf_->On() : dpps_ctrl_intf_->Off();
    575   }
    576 
    577   return kErrorNone;
    578 }
    579 
    580 bool CompManager::SetDisplayState(Handle display_ctx,
    581                                   DisplayState state, DisplayType display_type) {
    582   display_state_[display_type] = state;
    583 
    584   switch (state) {
    585   case kStateOff:
    586     Purge(display_ctx);
    587     configured_displays_.reset(display_type);
    588     DLOGV_IF(kTagCompManager, "configured_displays_ = 0x%x", configured_displays_);
    589     break;
    590 
    591   case kStateOn:
    592     if (registered_displays_.count() > 1) {
    593       safe_mode_ = true;
    594       DLOGV_IF(kTagCompManager, "safe_mode = %d", safe_mode_);
    595     }
    596     break;
    597 
    598   default:
    599     break;
    600   }
    601 
    602   return true;
    603 }
    604 
    605 }  // namespace sdm
    606