sde: resource manager: rotator resource allocation
Only mark dedicate block for rotator allocation. Use
rotate array other than left_rotate and right_rotate.
Use bit mask to indicate rotation usage because rotation
can be shared by multi displays.
Change-Id: I70bd03250080a24dcf7f38c39dbd6391c0bba97c
diff --git a/displayengine/include/utils/constants.h b/displayengine/include/utils/constants.h
index a0f2bfb..a7b9f0f 100644
--- a/displayengine/include/utils/constants.h
+++ b/displayengine/include/utils/constants.h
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2015, 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:
@@ -52,6 +52,7 @@
namespace sde {
const int kThreadPriorityUrgent = -9;
+ const int kMaxRotatePerLayer = 2;
typedef void * Handle;
diff --git a/displayengine/libs/core/hw_interface.h b/displayengine/libs/core/hw_interface.h
index 99d392d..7309c32 100644
--- a/displayengine/libs/core/hw_interface.h
+++ b/displayengine/libs/core/hw_interface.h
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2015, 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:
@@ -122,10 +122,10 @@
bool is_right_pipe; // indicate if right pipe is valid
HWPipeInfo left_pipe; // pipe for left side of the buffer
HWPipeInfo right_pipe; // pipe for right side of the buffer
- HWRotateInfo left_rotate; // rotation for left side of the buffer
- HWRotateInfo right_rotate; // rotation for right side of the buffer
+ uint32_t num_rotate; // number of rotate
+ HWRotateInfo rotates[kMaxRotatePerLayer]; // rotation for the buffer
- HWLayerConfig() : use_non_dma_pipe(false), is_right_pipe(false) { }
+ HWLayerConfig() : use_non_dma_pipe(false), is_right_pipe(false), num_rotate(0) { }
};
struct HWLayers {
diff --git a/displayengine/libs/core/res_config.cpp b/displayengine/libs/core/res_config.cpp
index 974897c..d093ab2 100644
--- a/displayengine/libs/core/res_config.cpp
+++ b/displayengine/libs/core/res_config.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2015, 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:
@@ -32,26 +32,30 @@
namespace sde {
-void ResManager::RotationConfig(const LayerTransform &transform, LayerRect *src_rect,
- HWRotateInfo *left_rotate, HWRotateInfo *right_rotate,
- uint32_t *rotate_count) {
+void ResManager::RotationConfig(const LayerTransform &transform, const float &scale_x,
+ const float &scale_y, LayerRect *src_rect,
+ struct HWLayerConfig *layer_config, uint32_t *rotate_count) {
+ HWRotateInfo *rotate = &layer_config->rotates[0];
float src_width = src_rect->right - src_rect->left;
float src_height = src_rect->bottom - src_rect->top;
LayerRect dst_rect;
// Rotate output is a temp buffer, always output to the top left corner for saving memory
dst_rect.top = 0.0f;
dst_rect.left = 0.0f;
- // downscale when doing rotation
- dst_rect.right = src_height / left_rotate->downscale_ratio_x;
- dst_rect.bottom = src_width / left_rotate->downscale_ratio_y;
- left_rotate->src_roi = *src_rect;
- left_rotate->pipe_id = kPipeIdNeedsAssignment;
- left_rotate->dst_roi = dst_rect;
- // Always use one rotator for now
- right_rotate->Reset();
+ rotate->downscale_ratio_x = scale_x;
+ rotate->downscale_ratio_y = scale_y;
+
+ // downscale when doing rotation
+ dst_rect.right = src_height / rotate->downscale_ratio_x;
+ dst_rect.bottom = src_width / rotate->downscale_ratio_y;
+
+ rotate->src_roi = *src_rect;
+ rotate->pipe_id = kPipeIdNeedsAssignment;
+ rotate->dst_roi = dst_rect;
*src_rect = dst_rect;
+ layer_config->num_rotate = 1;
(*rotate_count)++;
}
@@ -180,49 +184,44 @@
if (ValidateScaling(layer, src_rect, dst_rect, &rot_scale_x, &rot_scale_y))
return kErrorNotSupported;
- HWRotateInfo *left_rotate, *right_rotate;
+ struct HWLayerConfig *layer_config = &hw_layers->config[i];
// config rotator first
- left_rotate = &hw_layers->config[i].left_rotate;
- right_rotate = &hw_layers->config[i].right_rotate;
+ for (uint32_t j = 0; j < kMaxRotatePerLayer; j++) {
+ layer_config->rotates[j].Reset();
+ }
+ layer_config->num_rotate = 0;
LayerTransform transform = layer.transform;
if (IsRotationNeeded(transform.rotation) ||
UINT32(rot_scale_x) != 1 || UINT32(rot_scale_y) != 1) {
- left_rotate->downscale_ratio_x = rot_scale_x;
- right_rotate->downscale_ratio_x = rot_scale_x;
- left_rotate->downscale_ratio_y = rot_scale_y;
- right_rotate->downscale_ratio_y = rot_scale_y;
-
- RotationConfig(layer.transform, &src_rect, left_rotate, right_rotate, rotate_count);
+ RotationConfig(layer.transform, rot_scale_x, rot_scale_y, &src_rect, layer_config,
+ rotate_count);
// rotator will take care of flipping, reset tranform
transform = LayerTransform();
- } else {
- left_rotate->Reset();
- right_rotate->Reset();
}
if (hw_res_info_.is_src_split) {
error = SrcSplitConfig(display_resource_ctx, transform, src_rect,
- dst_rect, &hw_layers->config[i]);
+ dst_rect, layer_config);
} else {
error = DisplaySplitConfig(display_resource_ctx, transform, src_rect,
- dst_rect, &hw_layers->config[i]);
+ dst_rect, layer_config);
}
if (error != kErrorNone)
break;
DLOGV_IF(kTagResources, "layer = %d, left pipe_id = %x",
- i, hw_layers->config[i].left_pipe.pipe_id);
+ i, layer_config->left_pipe.pipe_id);
LogRectVerbose("input layer src_rect", layer.src_rect);
LogRectVerbose("input layer dst_rect", layer.dst_rect);
LogRectVerbose("cropped src_rect", src_rect);
LogRectVerbose("cropped dst_rect", dst_rect);
- LogRectVerbose("left pipe src", hw_layers->config[i].left_pipe.src_roi);
- LogRectVerbose("left pipe dst", hw_layers->config[i].left_pipe.dst_roi);
+ LogRectVerbose("left pipe src", layer_config->left_pipe.src_roi);
+ LogRectVerbose("left pipe dst", layer_config->left_pipe.dst_roi);
if (hw_layers->config[i].right_pipe.pipe_id) {
- LogRectVerbose("right pipe src", hw_layers->config[i].right_pipe.src_roi);
- LogRectVerbose("right pipe dst", hw_layers->config[i].right_pipe.dst_roi);
+ LogRectVerbose("right pipe src", layer_config->right_pipe.src_roi);
+ LogRectVerbose("right pipe dst", layer_config->right_pipe.dst_roi);
}
}
@@ -473,7 +472,7 @@
}
void ResManager::LogRectVerbose(const char *prefix, const LayerRect &roi) {
- DLOGV_IF(kTagResources,"%s: left = %.0f, top = %.0f, right = %.0f, bottom = %.0f",
+ DLOGV_IF(kTagResources, "%s: left = %.0f, top = %.0f, right = %.0f, bottom = %.0f",
prefix, roi.left, roi.top, roi.right, roi.bottom);
}
diff --git a/displayengine/libs/core/res_manager.cpp b/displayengine/libs/core/res_manager.cpp
index 38ef319..7b36563 100644
--- a/displayengine/libs/core/res_manager.cpp
+++ b/displayengine/libs/core/res_manager.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2015, 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:
@@ -40,7 +40,7 @@
DisplayError error = kErrorNone;
- // TODO: Remove this. Disable src_split as kernel not supported yet
+ // TODO(user): Remove this. Disable src_split as kernel not supported yet
hw_res_info_.is_src_split = false;
num_pipe_ = hw_res_info_.num_vig_pipe + hw_res_info_.num_rgb_pipe + hw_res_info_.num_dma_pipe;
@@ -123,7 +123,7 @@
break;
case kVirtual:
- // assume only WB2 can be used for virtual display
+ // TODO(user): read this block id from kernel
virtual_count_++;
hw_block_id = kHWWriteback2;
break;
@@ -159,7 +159,6 @@
DisplayResourceContext *display_resource_ctx =
reinterpret_cast<DisplayResourceContext *>(display_ctx);
- Purge(display_ctx);
if (display_resource_ctx->hw_block_id == kHWWriteback2) {
virtual_count_--;
if (!virtual_count_)
@@ -167,8 +166,9 @@
} else {
hw_block_ctx_[display_resource_ctx->hw_block_id].is_in_use = false;
}
+
if (!hw_block_ctx_[display_resource_ctx->hw_block_id].is_in_use)
- ClearDedicated(display_resource_ctx->hw_block_id);
+ Purge(display_ctx);
delete display_resource_ctx;
@@ -202,13 +202,13 @@
for (uint32_t i = 0; i < hw_res_info_.num_rotator; i++) {
uint32_t pipe_index;
pipe_index = rotators_[i].pipe_index;
+ rotators_[i].ClearState(display_resource_ctx->hw_block_id);
if (rotators_[i].client_bit_mask == 0 &&
src_pipes_[pipe_index].state == kPipeStateToRelease &&
src_pipes_[pipe_index].hw_block_id == rotators_[i].writeback_id) {
src_pipes_[pipe_index].dedicated_hw_block = kHWBlockMax;
src_pipes_[pipe_index].state = kPipeStateIdle;
}
- CLEAR_BIT(rotators_[i].client_bit_mask, display_resource_ctx->hw_block_id);
}
return kErrorNone;
@@ -259,17 +259,19 @@
rotate_count = 0;
for (uint32_t i = 0; i < layer_info.count; i++) {
Layer &layer = layer_info.stack->layers[layer_info.index[i]];
- bool use_non_dma_pipe = hw_layers->config[i].use_non_dma_pipe;
+ struct HWLayerConfig &layer_config = hw_layers->config[i];
+ bool use_non_dma_pipe = layer_config.use_non_dma_pipe;
- // Temp setting, this should be set by comp_manager
+ // TODO(user): set this from comp_manager
if (hw_block_id == kHWPrimary) {
use_non_dma_pipe = true;
}
- AssignRotator(&hw_layers->config[i].left_rotate, &rotate_count);
- AssignRotator(&hw_layers->config[i].right_rotate, &rotate_count);
+ for (uint32_t j = 0; j < layer_config.num_rotate; j++) {
+ AssignRotator(&layer_config.rotates[j], &rotate_count);
+ }
- HWPipeInfo *pipe_info = &hw_layers->config[i].left_pipe;
+ HWPipeInfo *pipe_info = &layer_config.left_pipe;
// Should have a generic macro
bool is_yuv = IsYuvFormat(layer.input_buffer->format);
@@ -286,11 +288,11 @@
SetDecimationFactor(pipe_info);
- pipe_info = &hw_layers->config[i].right_pipe;
+ pipe_info = &layer_config.right_pipe;
if (pipe_info->pipe_id == 0) {
// assign single pipe
if (left_index < num_pipe_) {
- hw_layers->config[i].left_pipe.pipe_id = src_pipes_[left_index].mdss_pipe_id;
+ layer_config.left_pipe.pipe_id = src_pipes_[left_index].mdss_pipe_id;
src_pipes_[left_index].at_right = false;
}
continue;
@@ -315,11 +317,11 @@
src_pipes_[right_index].at_right = true;
src_pipes_[left_index].reserved_hw_block = hw_block_id;
src_pipes_[left_index].at_right = false;
- hw_layers->config[i].left_pipe.pipe_id = src_pipes_[left_index].mdss_pipe_id;
+ layer_config.left_pipe.pipe_id = src_pipes_[left_index].mdss_pipe_id;
SetDecimationFactor(pipe_info);
DLOGV_IF(kTagResources, "Pipe acquired, layer index = %d, left_pipe = %x, right_pipe = %x",
- i, hw_layers->config[i].left_pipe.pipe_id, pipe_info->pipe_id);
+ i, layer_config.left_pipe.pipe_id, pipe_info->pipe_id);
}
if (!CheckBandwidth(display_resource_ctx, hw_layers)) {
@@ -580,16 +582,20 @@
}
// set rotator pipes
for (uint32_t i = 0; i < hw_res_info_.num_rotator; i++) {
- uint32_t pipe_index;
- pipe_index = rotators_[i].pipe_index;
+ uint32_t pipe_index = rotators_[i].pipe_index;
+
if (IS_BIT_SET(rotators_[i].client_bit_mask, hw_block_id)) {
src_pipes_[pipe_index].hw_block_id = rotators_[i].writeback_id;
src_pipes_[pipe_index].state = kPipeStateAcquired;
- } else if (!rotators_[i].client_bit_mask) {
+ } else if (!rotators_[i].client_bit_mask &&
+ src_pipes_[pipe_index].hw_block_id == rotators_[i].writeback_id &&
+ src_pipes_[pipe_index].state == kPipeStateAcquired) {
+ src_pipes_[pipe_index].state = kPipeStateToRelease;
+ src_pipes_[pipe_index].state_frame_count = frame_count;
+ }
+ // If no request on the rotation, release the pipe.
+ if (!rotators_[i].request_bit_mask) {
src_pipes_[pipe_index].dedicated_hw_block = kHWBlockMax;
- if (src_pipes_[pipe_index].hw_block_id == rotators_[i].writeback_id &&
- src_pipes_[pipe_index].state == kPipeStateAcquired)
- src_pipes_[pipe_index].state = kPipeStateToRelease;
}
}
display_resource_ctx->frame_start = false;
@@ -762,116 +768,9 @@
for (uint32_t i = 0; i < num_pipe_; i++) {
SourcePipe *src_pipe = &src_pipes_[i];
AppendString(buffer, length,
- "\nindex = %d, id = %x, reserved = %d, state = %d, at_right = %d, dedicated = %d",
+ "\nindex = %d, id = %x, reserved = %d, state = %d, hw_block = %d, dedicated = %d",
src_pipe->index, src_pipe->mdss_pipe_id, src_pipe->reserved_hw_block,
- src_pipe->state, src_pipe->at_right, src_pipe->dedicated_hw_block);
- }
-}
-
-// This is to reserve resources for the device or rotator
-DisplayError ResManager::MarkDedicated(DisplayResourceContext *display_resource_ctx,
- struct HWRotator *rotator) {
- uint32_t num_base_pipe = 0, base_pipe_index = 0, num_vig_pipe = 0, i, vig_pipe_index = 0;
- bool force = false;
- SourcePipe *src_pipe = NULL;
- HWBlockType hw_block_id;
- if (rotator == NULL) {
- hw_block_id = display_resource_ctx->hw_block_id;
- switch (display_resource_ctx->display_type) {
- case kPrimary:
- src_pipe= rgb_pipes_;
- if (display_resource_ctx->display_attributes.is_device_split ||
- hw_res_info_.is_src_split) {
- num_base_pipe = 2;
- num_vig_pipe = 2;
- } else {
- num_base_pipe = 1;
- num_vig_pipe = 1;
- }
- src_pipe = rgb_pipes_;
- force = true;
- break;
- // HDMI and Virtual are using the same strategy
- case kHDMI:
- case kVirtual:
- if (display_resource_ctx && display_resource_ctx->display_attributes.is_device_split) {
- num_base_pipe = 2;
- num_vig_pipe = 2;
- } else {
- num_base_pipe = 1;
- num_vig_pipe = 1;
- }
- break;
- default:
- DLOGE("Wrong device type %d", display_resource_ctx->display_type);
- break;
- }
- } else {
- hw_block_id = rotator->writeback_id;
- num_base_pipe = 1;
- base_pipe_index = rotator->pipe_index;
- src_pipe = &src_pipes_[base_pipe_index];
- force = true;
- }
-
- if (!num_base_pipe) {
- DLOGE("Cannot reserve dedicated pipe %d", hw_block_id);
- return kErrorResources;
- }
-
- // Only search the assigned pipe type
- if (force) {
- for (i = 0; i < num_base_pipe; i++) {
- if (src_pipe->dedicated_hw_block != kHWBlockMax)
- DLOGV_IF(kTagResources, "Overwrite dedicated block %d", src_pipe->dedicated_hw_block);
- src_pipe->dedicated_hw_block = hw_block_id;
- src_pipe++;
- }
- num_base_pipe = 0;
- } else {
- // search available pipes
- src_pipe = rgb_pipes_;
- uint32_t num_pipe = hw_res_info_.num_rgb_pipe + hw_res_info_.num_vig_pipe;
- for (i = 0; i < num_pipe; i++) {
- if (src_pipe->dedicated_hw_block == kHWBlockMax ||
- src_pipe->dedicated_hw_block == hw_block_id) {
- src_pipe->dedicated_hw_block = hw_block_id;
- num_base_pipe--;
- if (!num_base_pipe)
- break;
- }
- src_pipe++;
- }
- if (num_base_pipe) {
- for (i = 0; i < num_pipe; i++) {
- if (src_pipe->dedicated_hw_block == hw_block_id)
- src_pipe->dedicated_hw_block = kHWBlockMax;
- src_pipe++;
- }
- DLOGE("Cannot reserve dedicated pipe %d", hw_block_id);
- return kErrorResources;
- }
- }
- // optional for vig pipes
- src_pipe= vig_pipes_;
- for (i = 0; i < num_vig_pipe; i++) {
- if (src_pipe->dedicated_hw_block == kHWBlockMax ||
- src_pipe->dedicated_hw_block == hw_block_id) {
- src_pipe->dedicated_hw_block = hw_block_id;
- num_vig_pipe--;
- if (!num_vig_pipe)
- break;
- }
- src_pipe++;
- }
- return kErrorNone;
-}
-
-void ResManager::ClearDedicated(HWBlockType hw_block_id) {
- SourcePipe *src_pipe = src_pipes_;
- for (uint32_t i = 0; i < num_pipe_; i++) {
- if (src_pipe->dedicated_hw_block == hw_block_id)
- src_pipe->dedicated_hw_block = kHWBlockMax;
+ src_pipe->state, src_pipe->hw_block_id, src_pipe->dedicated_hw_block);
}
}
@@ -890,7 +789,16 @@
for (i = 0; i < num_rotator; i++) {
uint32_t rotate_pipe_index = rotators_[i].pipe_index;
- MarkDedicated(display_resource_ctx, &rotators_[i]);
+ SourcePipe *src_pipe = &src_pipes_[rotate_pipe_index];
+
+ if (src_pipe->dedicated_hw_block != kHWBlockMax)
+ DLOGV_IF(kTagResources, "Overwrite dedicated block %d", src_pipe->dedicated_hw_block);
+ src_pipe->dedicated_hw_block = rotators_[i].writeback_id;
+ SET_BIT(rotators_[i].request_bit_mask, display_resource_ctx->hw_block_id);
+ }
+
+ for (i = 0; i < num_rotator; i++) {
+ uint32_t rotate_pipe_index = rotators_[i].pipe_index;
if (src_pipes_[rotate_pipe_index].reserved_hw_block != kHWBlockMax) {
DLOGV_IF(kTagResources, "pipe %x is reserved by block:%d",
src_pipes_[rotate_pipe_index].mdss_pipe_id,
@@ -929,11 +837,14 @@
for (uint32_t i = 0; i < hw_res_info_.num_rotator; i++) {
uint32_t pipe_index;
pipe_index = rotators_[i].pipe_index;
- CLEAR_BIT(rotators_[i].client_bit_mask, display_resource_ctx->hw_block_id);
- if (rotators_[i].client_bit_mask == 0 &&
- src_pipes_[pipe_index].dedicated_hw_block == rotators_[i].writeback_id) {
+ rotators_[i].ClearState(display_resource_ctx->hw_block_id);
+ if (rotators_[i].client_bit_mask)
+ continue;
+
+ if (src_pipes_[pipe_index].hw_block_id == rotators_[i].writeback_id) {
+ src_pipes_[pipe_index].ResetState();
+ } else if (src_pipes_[pipe_index].dedicated_hw_block == rotators_[i].writeback_id) {
src_pipes_[pipe_index].dedicated_hw_block = kHWBlockMax;
- src_pipes_[pipe_index].state = kPipeStateIdle;
}
}
}
diff --git a/displayengine/libs/core/res_manager.h b/displayengine/libs/core/res_manager.h
index 18900f3..5b63299 100644
--- a/displayengine/libs/core/res_manager.h
+++ b/displayengine/libs/core/res_manager.h
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2015, 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:
@@ -107,7 +107,6 @@
inline void ResetState() { state = kPipeStateIdle; hw_block_id = kHWBlockMax;
at_right = false; reserved_hw_block = kHWBlockMax; dedicated_hw_block = kHWBlockMax; }
-
};
struct DisplayResourceContext {
@@ -131,7 +130,12 @@
uint32_t pipe_index;
HWBlockType writeback_id;
uint32_t client_bit_mask;
- HWRotator() : pipe_index(0), writeback_id(kHWBlockMax), client_bit_mask(0) { }
+ uint32_t request_bit_mask;
+ HWRotator() : pipe_index(0), writeback_id(kHWBlockMax), client_bit_mask(0),
+ request_bit_mask(0) { }
+
+ inline void ClearState(HWBlockType block) { CLEAR_BIT(client_bit_mask, block);
+ CLEAR_BIT(request_bit_mask, block); }
};
static const int kPipeIdNeedsAssignment = -1;
@@ -172,11 +176,9 @@
bool IsRotationNeeded(float rotation)
{ return (UINT32(rotation) == 90 || UINT32(rotation) == 270); }
void LogRectVerbose(const char *prefix, const LayerRect &roi);
- DisplayError MarkDedicated(DisplayResourceContext *display_resource_ctx,
- struct HWRotator *rotator);
- void ClearDedicated(HWBlockType hw_block_id);
- void RotationConfig(const LayerTransform &transform, LayerRect *src_rect,
- HWRotateInfo *left_rotate, HWRotateInfo *right_rotate, uint32_t *rotate_cnt);
+ void RotationConfig(const LayerTransform &transform, const float &scale_x,
+ const float &scale_y,LayerRect *src_rect,
+ struct HWLayerConfig *layer_config, uint32_t *rotate_count);
DisplayError AcquireRotator(DisplayResourceContext *display_resource_ctx,
const uint32_t roate_cnt);
void AssignRotator(HWRotateInfo *rotate, uint32_t *rotate_cnt);