Home | History | Annotate | Download | only in core
      1 /*
      2 * Copyright (c) 2014 - 2016, 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 
     30 #define __CLASS__ "Strategy"
     31 
     32 namespace sdm {
     33 
     34 Strategy::Strategy(ExtensionInterface *extension_intf, DisplayType type,
     35                    const HWResourceInfo &hw_resource_info, const HWPanelInfo &hw_panel_info,
     36                    const HWMixerAttributes &mixer_attributes,
     37                    const HWDisplayAttributes &display_attributes,
     38                    const DisplayConfigVariableInfo &fb_config)
     39   : extension_intf_(extension_intf), display_type_(type), hw_resource_info_(hw_resource_info),
     40     hw_panel_info_(hw_panel_info), mixer_attributes_(mixer_attributes),
     41     display_attributes_(display_attributes), fb_config_(fb_config) {
     42 }
     43 
     44 DisplayError Strategy::Init() {
     45   DisplayError error = kErrorNone;
     46 
     47   if (extension_intf_) {
     48     error = extension_intf_->CreateStrategyExtn(display_type_, hw_panel_info_.mode,
     49                                                 hw_panel_info_.s3d_mode, mixer_attributes_,
     50                                                 fb_config_, &strategy_intf_);
     51     if (error != kErrorNone) {
     52       DLOGE("Failed to create strategy");
     53       return error;
     54     }
     55 
     56     error = extension_intf_->CreatePartialUpdate(display_type_, hw_resource_info_, hw_panel_info_,
     57                                                  mixer_attributes_, display_attributes_,
     58                                                  &partial_update_intf_);
     59   }
     60 
     61   return kErrorNone;
     62 }
     63 
     64 DisplayError Strategy::Deinit() {
     65   if (strategy_intf_) {
     66     if (partial_update_intf_) {
     67       extension_intf_->DestroyPartialUpdate(partial_update_intf_);
     68     }
     69 
     70     extension_intf_->DestroyStrategyExtn(strategy_intf_);
     71   }
     72 
     73   return kErrorNone;
     74 }
     75 
     76 DisplayError Strategy::Start(HWLayersInfo *hw_layers_info, uint32_t *max_attempts,
     77                              bool partial_update_enable) {
     78   DisplayError error = kErrorNone;
     79 
     80   hw_layers_info_ = hw_layers_info;
     81   extn_start_success_ = false;
     82   tried_default_ = false;
     83   uint32_t i = 0;
     84   LayerStack *layer_stack = hw_layers_info_->stack;
     85   uint32_t layer_count = UINT32(layer_stack->layers.size());
     86   for (; i < layer_count; i++) {
     87     if (layer_stack->layers.at(i)->composition == kCompositionGPUTarget) {
     88       fb_layer_index_ = i;
     89       break;
     90     }
     91   }
     92 
     93   if (i == layer_count) {
     94     return kErrorUndefined;
     95   }
     96 
     97   if (partial_update_intf_) {
     98     partial_update_intf_->ControlPartialUpdate(partial_update_enable);
     99   }
    100   GenerateROI();
    101 
    102   if (strategy_intf_) {
    103     error = strategy_intf_->Start(hw_layers_info_, max_attempts);
    104     if (error == kErrorNone) {
    105       extn_start_success_ = true;
    106       return kErrorNone;
    107     }
    108   }
    109 
    110   *max_attempts = 1;
    111 
    112   return kErrorNone;
    113 }
    114 
    115 DisplayError Strategy::Stop() {
    116   if (strategy_intf_) {
    117     return strategy_intf_->Stop();
    118   }
    119 
    120   return kErrorNone;
    121 }
    122 
    123 DisplayError Strategy::GetNextStrategy(StrategyConstraints *constraints) {
    124   DisplayError error = kErrorNone;
    125 
    126   if (extn_start_success_) {
    127     error = strategy_intf_->GetNextStrategy(constraints);
    128     if (error == kErrorNone) {
    129       return kErrorNone;
    130     }
    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   uint32_t &hw_layer_count = hw_layers_info_->count;
    142   hw_layer_count = 0;
    143 
    144   for (uint32_t i = 0; i < layer_stack->layers.size(); i++) {
    145     Layer *layer = layer_stack->layers.at(i);
    146     LayerComposition &composition = layer->composition;
    147     if (composition == kCompositionGPUTarget) {
    148       hw_layers_info_->updated_src_rect[hw_layer_count] = layer->src_rect;
    149       hw_layers_info_->updated_dst_rect[hw_layer_count] = layer->dst_rect;
    150       hw_layers_info_->index[hw_layer_count++] = i;
    151     } else if (composition != kCompositionBlitTarget) {
    152       composition = kCompositionGPU;
    153     }
    154   }
    155 
    156   tried_default_ = true;
    157 
    158   // There can be one and only one GPU target buffer.
    159   if (hw_layer_count != 1) {
    160     return kErrorParameters;
    161   }
    162 
    163   return kErrorNone;
    164 }
    165 
    166 void Strategy::GenerateROI() {
    167   bool split_display = false;
    168 
    169   if (partial_update_intf_ && partial_update_intf_->GenerateROI(hw_layers_info_) == kErrorNone) {
    170     return;
    171   }
    172 
    173   float layer_mixer_width = mixer_attributes_.width;
    174   float layer_mixer_height = mixer_attributes_.height;
    175 
    176   if (!hw_resource_info_.is_src_split &&
    177      ((layer_mixer_width > hw_resource_info_.max_mixer_width) ||
    178      ((hw_panel_info_.is_primary_panel) && hw_panel_info_.split_info.right_split))) {
    179     split_display = true;
    180   }
    181 
    182   if (split_display) {
    183     float left_split = FLOAT(mixer_attributes_.split_left);
    184     hw_layers_info_->left_partial_update = (LayerRect) {0.0f, 0.0f, left_split, layer_mixer_height};
    185     hw_layers_info_->right_partial_update = (LayerRect) {left_split, 0.0f, layer_mixer_width,
    186                                             layer_mixer_height};
    187   } else {
    188     hw_layers_info_->left_partial_update = (LayerRect) {0.0f, 0.0f, layer_mixer_width,
    189                                            layer_mixer_height};
    190     hw_layers_info_->right_partial_update = (LayerRect) {0.0f, 0.0f, 0.0f, 0.0f};
    191   }
    192 }
    193 
    194 DisplayError Strategy::Reconfigure(const HWPanelInfo &hw_panel_info,
    195                          const HWDisplayAttributes &display_attributes,
    196                          const HWMixerAttributes &mixer_attributes,
    197                          const DisplayConfigVariableInfo &fb_config) {
    198   hw_panel_info_ = hw_panel_info;
    199   display_attributes_ = display_attributes;
    200   mixer_attributes_ = mixer_attributes;
    201 
    202   if (!extension_intf_) {
    203     return kErrorNone;
    204   }
    205 
    206   // TODO(user): PU Intf will not be created for video mode panels, hence re-evaluate if
    207   // reconfigure is needed.
    208   if (partial_update_intf_) {
    209     extension_intf_->DestroyPartialUpdate(partial_update_intf_);
    210     partial_update_intf_ = NULL;
    211   }
    212 
    213   extension_intf_->CreatePartialUpdate(display_type_, hw_resource_info_, hw_panel_info_,
    214                                        mixer_attributes_, display_attributes_,
    215                                        &partial_update_intf_);
    216 
    217   return strategy_intf_->Reconfigure(hw_panel_info_.mode, hw_panel_info_.s3d_mode, mixer_attributes,
    218                                      fb_config);
    219 }
    220 
    221 }  // namespace sdm
    222