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 
     28 #include "strategy.h"
     29 #include "utils/rect.h"
     30 
     31 #define __CLASS__ "Strategy"
     32 
     33 namespace sdm {
     34 
     35 Strategy::Strategy(ExtensionInterface *extension_intf, BufferAllocator *buffer_allocator,
     36                    DisplayType type,
     37                    const HWResourceInfo &hw_resource_info, const HWPanelInfo &hw_panel_info,
     38                    const HWMixerAttributes &mixer_attributes,
     39                    const HWDisplayAttributes &display_attributes,
     40                    const DisplayConfigVariableInfo &fb_config)
     41   : extension_intf_(extension_intf), display_type_(type), hw_resource_info_(hw_resource_info),
     42     hw_panel_info_(hw_panel_info), mixer_attributes_(mixer_attributes),
     43     display_attributes_(display_attributes), fb_config_(fb_config),
     44     buffer_allocator_(buffer_allocator) {
     45 }
     46 
     47 DisplayError Strategy::Init() {
     48   DisplayError error = kErrorNone;
     49 
     50   if (extension_intf_) {
     51     error = extension_intf_->CreateStrategyExtn(display_type_, buffer_allocator_, hw_resource_info_,
     52                                                 hw_panel_info_, mixer_attributes_, fb_config_,
     53                                                 &strategy_intf_);
     54     if (error != kErrorNone) {
     55       DLOGE("Failed to create strategy");
     56       return error;
     57     }
     58 
     59     error = extension_intf_->CreatePartialUpdate(display_type_, hw_resource_info_, hw_panel_info_,
     60                                                  mixer_attributes_, display_attributes_, fb_config_,
     61                                                  &partial_update_intf_);
     62   }
     63 
     64   return kErrorNone;
     65 }
     66 
     67 DisplayError Strategy::Deinit() {
     68   if (strategy_intf_) {
     69     if (partial_update_intf_) {
     70       extension_intf_->DestroyPartialUpdate(partial_update_intf_);
     71     }
     72 
     73     extension_intf_->DestroyStrategyExtn(strategy_intf_);
     74   }
     75 
     76   return kErrorNone;
     77 }
     78 
     79 DisplayError Strategy::Start(HWLayersInfo *hw_layers_info, uint32_t *max_attempts,
     80                              const PUConstraints &pu_constraints) {
     81   DisplayError error = kErrorNone;
     82 
     83   hw_layers_info_ = hw_layers_info;
     84   extn_start_success_ = false;
     85   tried_default_ = false;
     86 
     87   if (!disable_gpu_comp_ && !hw_layers_info_->gpu_target_index) {
     88     DLOGE("GPU composition is enabled and GPU target buffer not provided.");
     89     return kErrorNotSupported;
     90   }
     91 
     92   if (partial_update_intf_) {
     93     partial_update_intf_->Start(pu_constraints);
     94   }
     95   GenerateROI();
     96 
     97   if (strategy_intf_) {
     98     error = strategy_intf_->Start(hw_layers_info_, max_attempts);
     99     if (error == kErrorNone) {
    100       extn_start_success_ = true;
    101       return kErrorNone;
    102     }
    103   }
    104 
    105   *max_attempts = 1;
    106 
    107   return kErrorNone;
    108 }
    109 
    110 DisplayError Strategy::Stop() {
    111   if (strategy_intf_) {
    112     return strategy_intf_->Stop();
    113   }
    114 
    115   return kErrorNone;
    116 }
    117 
    118 DisplayError Strategy::GetNextStrategy(StrategyConstraints *constraints) {
    119   DisplayError error = kErrorNone;
    120 
    121   if (extn_start_success_) {
    122     error = strategy_intf_->GetNextStrategy(constraints);
    123     if (error == kErrorNone) {
    124       return kErrorNone;
    125     }
    126   }
    127 
    128   // Do not fallback to GPU if GPU comp is disabled.
    129   if (disable_gpu_comp_) {
    130     return kErrorNotSupported;
    131   }
    132 
    133   // Default composition is already tried.
    134   if (tried_default_) {
    135     return kErrorUndefined;
    136   }
    137 
    138   // Mark all application layers for GPU composition. Find GPU target buffer and store its index for
    139   // programming the hardware.
    140   LayerStack *layer_stack = hw_layers_info_->stack;
    141   for (uint32_t i = 0; i < hw_layers_info_->app_layer_count; i++) {
    142     layer_stack->layers.at(i)->composition = kCompositionGPU;
    143     layer_stack->layers.at(i)->request.flags.request_flags = 0;  // Reset layer request
    144   }
    145 
    146   if (!extn_start_success_) {
    147     // When mixer resolution and panel resolutions are same (1600x2560) and FB resolution is
    148     // 1080x1920 FB_Target destination coordinates(mapped to FB resolution 1080x1920) need to
    149     // be mapped to destination coordinates of mixer resolution(1600x2560).
    150     Layer *gpu_target_layer = layer_stack->layers.at(hw_layers_info_->gpu_target_index);
    151     float layer_mixer_width = FLOAT(mixer_attributes_.width);
    152     float layer_mixer_height = FLOAT(mixer_attributes_.height);
    153     float fb_width = FLOAT(fb_config_.x_pixels);
    154     float fb_height = FLOAT(fb_config_.y_pixels);
    155     LayerRect src_domain = (LayerRect){0.0f, 0.0f, fb_width, fb_height};
    156     LayerRect dst_domain = (LayerRect){0.0f, 0.0f, layer_mixer_width, layer_mixer_height};
    157 
    158     Layer layer = *gpu_target_layer;
    159     hw_layers_info_->index[0] = hw_layers_info_->gpu_target_index;
    160     MapRect(src_domain, dst_domain, layer.dst_rect, &layer.dst_rect);
    161     hw_layers_info_->hw_layers.clear();
    162     hw_layers_info_->hw_layers.push_back(layer);
    163   }
    164 
    165   tried_default_ = true;
    166 
    167   return kErrorNone;
    168 }
    169 
    170 void Strategy::GenerateROI() {
    171   bool split_display = false;
    172 
    173   if (partial_update_intf_ && partial_update_intf_->GenerateROI(hw_layers_info_) == kErrorNone) {
    174     return;
    175   }
    176 
    177   float layer_mixer_width = mixer_attributes_.width;
    178   float layer_mixer_height = mixer_attributes_.height;
    179 
    180   if (!hw_resource_info_.is_src_split && display_attributes_.is_device_split) {
    181     split_display = true;
    182   }
    183 
    184   hw_layers_info_->left_frame_roi = {};
    185   hw_layers_info_->right_frame_roi = {};
    186 
    187   if (split_display) {
    188     float left_split = FLOAT(mixer_attributes_.split_left);
    189     hw_layers_info_->left_frame_roi.push_back(LayerRect(0.0f, 0.0f,
    190                                 left_split, layer_mixer_height));
    191     hw_layers_info_->right_frame_roi.push_back(LayerRect(left_split,
    192                                 0.0f, layer_mixer_width, layer_mixer_height));
    193   } else {
    194     hw_layers_info_->left_frame_roi.push_back(LayerRect(0.0f, 0.0f,
    195                                 layer_mixer_width, layer_mixer_height));
    196     hw_layers_info_->right_frame_roi.push_back(LayerRect(0.0f, 0.0f, 0.0f, 0.0f));
    197   }
    198 }
    199 
    200 DisplayError Strategy::Reconfigure(const HWPanelInfo &hw_panel_info,
    201                          const HWDisplayAttributes &display_attributes,
    202                          const HWMixerAttributes &mixer_attributes,
    203                          const DisplayConfigVariableInfo &fb_config) {
    204   DisplayError error = kErrorNone;
    205 
    206   if (!extension_intf_) {
    207     return kErrorNone;
    208   }
    209 
    210   // TODO(user): PU Intf will not be created for video mode panels, hence re-evaluate if
    211   // reconfigure is needed.
    212   if (partial_update_intf_) {
    213     extension_intf_->DestroyPartialUpdate(partial_update_intf_);
    214     partial_update_intf_ = NULL;
    215   }
    216 
    217   extension_intf_->CreatePartialUpdate(display_type_, hw_resource_info_, hw_panel_info,
    218                                        mixer_attributes, display_attributes, fb_config,
    219                                        &partial_update_intf_);
    220 
    221   error = strategy_intf_->Reconfigure(hw_panel_info, hw_resource_info_, mixer_attributes,
    222                                       fb_config);
    223   if (error != kErrorNone) {
    224     return error;
    225   }
    226 
    227   hw_panel_info_ = hw_panel_info;
    228   display_attributes_ = display_attributes;
    229   mixer_attributes_ = mixer_attributes;
    230   fb_config_ = fb_config;
    231 
    232   return kErrorNone;
    233 }
    234 
    235 DisplayError Strategy::SetCompositionState(LayerComposition composition_type, bool enable) {
    236   DLOGI("composition type = %d, enable = %d", composition_type, enable);
    237 
    238   if (composition_type == kCompositionGPU) {
    239     disable_gpu_comp_ = !enable;
    240   }
    241 
    242   if (strategy_intf_) {
    243     return strategy_intf_->SetCompositionState(composition_type, enable);
    244   }
    245 
    246   return kErrorNone;
    247 }
    248 
    249 DisplayError Strategy::Purge() {
    250   if (strategy_intf_) {
    251     return strategy_intf_->Purge();
    252   }
    253 
    254   return kErrorNone;
    255 }
    256 
    257 DisplayError Strategy::SetIdleTimeoutMs(uint32_t active_ms) {
    258   if (strategy_intf_) {
    259     return strategy_intf_->SetIdleTimeoutMs(active_ms);
    260   }
    261 
    262   return kErrorNotSupported;
    263 }
    264 
    265 }  // namespace sdm
    266