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
Strategy(ExtensionInterface * extension_intf,DisplayType type,const HWResourceInfo & hw_resource_info,const HWPanelInfo & hw_panel_info,const HWMixerAttributes & mixer_attributes,const HWDisplayAttributes & display_attributes,const DisplayConfigVariableInfo & fb_config)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
Init()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
Deinit()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
Start(HWLayersInfo * hw_layers_info,uint32_t * max_attempts,bool partial_update_enable)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
Stop()115 DisplayError Strategy::Stop() {
116 if (strategy_intf_) {
117 return strategy_intf_->Stop();
118 }
119
120 return kErrorNone;
121 }
122
GetNextStrategy(StrategyConstraints * constraints)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
GenerateROI()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
Reconfigure(const HWPanelInfo & hw_panel_info,const HWDisplayAttributes & display_attributes,const HWMixerAttributes & mixer_attributes,const DisplayConfigVariableInfo & fb_config)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