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 HWDisplayAttributes & hw_display_attributes)34 Strategy::Strategy(ExtensionInterface *extension_intf, DisplayType type,
35 const HWResourceInfo &hw_resource_info, const HWPanelInfo &hw_panel_info,
36 const HWDisplayAttributes &hw_display_attributes)
37 : extension_intf_(extension_intf), display_type_(type), hw_resource_info_(hw_resource_info),
38 hw_panel_info_(hw_panel_info), hw_display_attributes_(hw_display_attributes) {
39 }
40
Init()41 DisplayError Strategy::Init() {
42 DisplayError error = kErrorNone;
43
44 if (extension_intf_) {
45 error = extension_intf_->CreateStrategyExtn(display_type_, hw_panel_info_.mode,
46 hw_panel_info_.s3d_mode, &strategy_intf_);
47 if (error != kErrorNone) {
48 DLOGE("Failed to create strategy");
49 return error;
50 }
51
52 error = extension_intf_->CreatePartialUpdate(display_type_, hw_resource_info_,
53 hw_panel_info_, &partial_update_intf_);
54 }
55
56 return kErrorNone;
57 }
58
Deinit()59 DisplayError Strategy::Deinit() {
60 if (strategy_intf_) {
61 if (partial_update_intf_) {
62 extension_intf_->DestroyPartialUpdate(partial_update_intf_);
63 }
64
65 extension_intf_->DestroyStrategyExtn(strategy_intf_);
66 }
67
68 return kErrorNone;
69 }
70
Start(HWLayersInfo * hw_layers_info,uint32_t * max_attempts,bool partial_update_enable)71 DisplayError Strategy::Start(HWLayersInfo *hw_layers_info, uint32_t *max_attempts,
72 bool partial_update_enable) {
73 DisplayError error = kErrorNone;
74
75 hw_layers_info_ = hw_layers_info;
76 extn_start_success_ = false;
77 tried_default_ = false;
78
79 uint32_t i = 0;
80 LayerStack *layer_stack = hw_layers_info_->stack;
81 for (; i < layer_stack->layer_count; i++) {
82 if (layer_stack->layers[i].composition == kCompositionGPUTarget) {
83 fb_layer_index_ = i;
84 break;
85 }
86 }
87
88 if (i == layer_stack->layer_count) {
89 return kErrorUndefined;
90 }
91
92 if (partial_update_intf_) {
93 partial_update_intf_->ControlPartialUpdate(partial_update_enable);
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
Stop()110 DisplayError Strategy::Stop() {
111 if (extn_start_success_) {
112 return strategy_intf_->Stop();
113 }
114
115 return kErrorNone;
116 }
117
GetNextStrategy(StrategyConstraints * constraints)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 // Default composition is already tried.
129 if (tried_default_) {
130 return kErrorUndefined;
131 }
132
133 // Mark all application layers for GPU composition. Find GPU target buffer and store its index for
134 // programming the hardware.
135 LayerStack *layer_stack = hw_layers_info_->stack;
136 uint32_t &hw_layer_count = hw_layers_info_->count;
137 hw_layer_count = 0;
138
139 for (uint32_t i = 0; i < layer_stack->layer_count; i++) {
140 LayerComposition &composition = layer_stack->layers[i].composition;
141 if (composition == kCompositionGPUTarget) {
142 hw_layers_info_->updated_src_rect[hw_layer_count] = layer_stack->layers[i].src_rect;
143 hw_layers_info_->updated_dst_rect[hw_layer_count] = layer_stack->layers[i].dst_rect;
144 hw_layers_info_->index[hw_layer_count++] = i;
145 } else if (composition != kCompositionBlitTarget) {
146 composition = kCompositionGPU;
147 }
148 }
149
150 tried_default_ = true;
151
152 // There can be one and only one GPU target buffer.
153 if (hw_layer_count != 1) {
154 return kErrorParameters;
155 }
156
157 return kErrorNone;
158 }
159
GenerateROI()160 void Strategy::GenerateROI() {
161 bool split_display = false;
162
163 if (partial_update_intf_ && partial_update_intf_->GenerateROI(hw_layers_info_) == kErrorNone) {
164 return;
165 }
166
167 float disp_x_res = hw_display_attributes_.x_pixels;
168 float disp_y_res = hw_display_attributes_.y_pixels;
169
170 if (!hw_resource_info_.is_src_split &&
171 ((disp_x_res > hw_resource_info_.max_mixer_width) ||
172 ((display_type_ == kPrimary) && hw_panel_info_.split_info.right_split))) {
173 split_display = true;
174 }
175
176 if (split_display) {
177 float left_split = FLOAT(hw_panel_info_.split_info.left_split);
178 hw_layers_info_->left_partial_update = (LayerRect) {0.0f, 0.0f, left_split, disp_y_res};
179 hw_layers_info_->right_partial_update = (LayerRect) {left_split, 0.0f, disp_x_res, disp_y_res};
180 } else {
181 hw_layers_info_->left_partial_update = (LayerRect) {0.0f, 0.0f, disp_x_res, disp_y_res};
182 hw_layers_info_->right_partial_update = (LayerRect) {0.0f, 0.0f, 0.0f, 0.0f};
183 }
184 }
185
186 } // namespace sdm
187
188