blob: 4aab34d4607d1703abb9aaf1860280ac0ba82ec1 [file] [log] [blame]
/*
* Copyright (c) 2014, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <utils/constants.h>
#include <utils/debug.h>
#include "strategy_default.h"
#define __CLASS__ "StrategyDefault"
namespace sde {
StrategyDefault::StrategyDefault(DisplayType type, const HWResourceInfo &hw_resource_info,
const HWPanelInfo &hw_panel_info) : type_(type),
hw_resource_info_(hw_resource_info),
hw_panel_info_(hw_panel_info), hw_layers_info_(NULL) {
}
DisplayError StrategyDefault::CreateStrategyInterface(uint16_t version, DisplayType type,
const HWResourceInfo &hw_resource_info,
const HWPanelInfo &hw_panel_info,
StrategyInterface **interface) {
StrategyDefault *strategy_default = new StrategyDefault(type, hw_resource_info, hw_panel_info);
if (!strategy_default) {
return kErrorMemory;
}
*interface = strategy_default;
return kErrorNone;
}
DisplayError StrategyDefault::DestroyStrategyInterface(StrategyInterface *interface) {
StrategyDefault *strategy_default = static_cast<StrategyDefault *>(interface);
if (!strategy_default) {
return kErrorParameters;
}
delete strategy_default;
return kErrorNone;
}
bool StrategyDefault::IsDisplaySplit(uint32_t fb_x_res) {
if (fb_x_res > hw_resource_info_.max_mixer_width) {
return true;
}
if ((type_ == kPrimary) && hw_panel_info_.split_info.right_split) {
return true;
}
return false;
}
DisplayError StrategyDefault::Start(HWLayersInfo *hw_layers_info, uint32_t *max_attempts) {
if (!hw_layers_info) {
return kErrorParameters;
}
hw_layers_info_ = hw_layers_info;
*max_attempts = 1;
const LayerStack *layer_stack = hw_layers_info_->stack;
for (uint32_t i = 0; i < layer_stack->layer_count; i++) {
LayerComposition &composition = layer_stack->layers[i].composition;
if (composition == kCompositionGPUTarget) {
fb_layer_index_ = i;
break;
}
}
const LayerRect &src_rect = hw_layers_info_->stack->layers[fb_layer_index_].src_rect;
// TODO(user): read panels x_pixels and y_pixels instead of fb_x_res and fb_y_res
const float fb_x_res = src_rect.right - src_rect.left;
const float fb_y_res = src_rect.bottom - src_rect.top;
if (IsDisplaySplit(INT(fb_x_res))) {
float left_split = FLOAT(hw_panel_info_.split_info.left_split);
hw_layers_info->left_partial_update = (LayerRect) {0.0, 0.0, left_split, fb_y_res};
hw_layers_info->right_partial_update = (LayerRect) {left_split, 0.0, fb_x_res, fb_y_res};
} else {
hw_layers_info->left_partial_update = (LayerRect) {0.0, 0.0, fb_x_res, fb_y_res};
hw_layers_info->right_partial_update = (LayerRect) {0.0, 0.0, 0.0, 0.0};
}
return kErrorNone;
}
DisplayError StrategyDefault::Stop() {
return kErrorNone;
}
DisplayError StrategyDefault::GetNextStrategy(StrategyConstraints *constraints) {
// Mark all layers for GPU composition. Find GPU target buffer and store its index for programming
// the hardware.
LayerStack *layer_stack = hw_layers_info_->stack;
uint32_t &hw_layer_count = hw_layers_info_->count;
hw_layer_count = 0;
for (uint32_t i = 0; i < layer_stack->layer_count; i++) {
LayerComposition &composition = layer_stack->layers[i].composition;
if (composition != kCompositionGPUTarget) {
composition = kCompositionGPU;
} else {
hw_layers_info_->index[hw_layer_count++] = i;
}
}
// There can be one and only one GPU target buffer.
if (hw_layer_count != 1) {
return kErrorParameters;
}
return kErrorNone;
}
} // namespace sde