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