summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.mk3
-rw-r--r--displayengine/include/core/layer_buffer.h4
-rw-r--r--displayengine/include/core/layer_stack.h4
-rw-r--r--displayengine/libs/core/display_base.cpp1
-rw-r--r--displayengine/libs/core/hw_framebuffer.cpp196
-rw-r--r--displayengine/libs/core/hw_framebuffer.h21
-rw-r--r--displayengine/libs/core/res_config.cpp2
-rw-r--r--displayengine/libs/core/res_manager.cpp4
-rw-r--r--displayengine/libs/hwc/hwc_display.cpp231
-rw-r--r--displayengine/libs/hwc/hwc_display.h54
-rw-r--r--displayengine/libs/hwc/hwc_display_external.cpp23
-rw-r--r--displayengine/libs/hwc/hwc_display_primary.cpp2
12 files changed, 300 insertions, 245 deletions
diff --git a/Android.mk b/Android.mk
index 4a951c83..b3015af3 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1,14 +1,13 @@
# This flag will be set to true during migration to Snapdragon Display Engine.
TARGET_USES_SDE = false
-display-hals := libgralloc libcopybit liblight libmemtrack
+display-hals := libgralloc libcopybit liblight libmemtrack libqservice
ifeq ($(TARGET_USES_SDE), true)
sde-libs := displayengine/libs
display-hals += $(sde-libs)/utils $(sde-libs)/core $(sde-libs)/hwc
else
display-hals += libgenlock libhwcomposer liboverlay libqdutils libhdmi
- display-hals += libqservice
endif
ifeq ($(call is-vendor-board-platform,QCOM),true)
diff --git a/displayengine/include/core/layer_buffer.h b/displayengine/include/core/layer_buffer.h
index 421ab870..26b477cd 100644
--- a/displayengine/include/core/layer_buffer.h
+++ b/displayengine/include/core/layer_buffer.h
@@ -76,6 +76,10 @@ enum LayerBufferFormat {
//!< v(0), u(0), v(2), u(2) ... v(n-1), u(n-1)
//!< aka NV21.
+ kFormatYCbCr420SemiPlanarVenus, //!< Y-plane: y(0), y(1), y(2) ... y(n)
+ //!< 2x2 subsampled interleaved UV-plane:
+ //!< u(0), v(0), u(2), v(2) ... u(n-1), v(n-1)
+
/* All YUV-Packed formats, Any new format will be added towards end of this group to maintain
backward compatibility.
*/
diff --git a/displayengine/include/core/layer_stack.h b/displayengine/include/core/layer_stack.h
index 74c19600..6a99701e 100644
--- a/displayengine/include/core/layer_stack.h
+++ b/displayengine/include/core/layer_stack.h
@@ -43,7 +43,7 @@ namespace sde {
@sa Layer
*/
enum LayerBlending {
- kBlendingNone = 0, //!< Blend operation is not specified.
+ kBlendingNone, //!< Blend operation is not specified.
kBlendingOpaque, //!< Pixel color is expressed using straight alpha in color tuples. It
//!< is constant blend operation. The layer would appear opaque if plane
@@ -217,7 +217,7 @@ struct LayerStack {
uint32_t layer_count; //!< Total number of layers.
LayerStackFlags flags; //!< Flags associated with this layer set.
- LayerStack() : output_buffer(NULL) { }
+ LayerStack() : output_buffer(NULL), layers(NULL), layer_count(0) { }
};
} // namespace sde
diff --git a/displayengine/libs/core/display_base.cpp b/displayengine/libs/core/display_base.cpp
index 5b2d0af6..d5a34f21 100644
--- a/displayengine/libs/core/display_base.cpp
+++ b/displayengine/libs/core/display_base.cpp
@@ -233,6 +233,7 @@ DisplayError DisplayBase::SetDisplayState(DisplayState state) {
switch (state) {
case kStateOff:
+ hw_layers_.info.count = 0;
comp_manager_->Purge(display_comp_ctx_);
error = hw_intf_->PowerOff(hw_device_);
break;
diff --git a/displayengine/libs/core/hw_framebuffer.cpp b/displayengine/libs/core/hw_framebuffer.cpp
index 63adf8c3..309dbd62 100644
--- a/displayengine/libs/core/hw_framebuffer.cpp
+++ b/displayengine/libs/core/hw_framebuffer.cpp
@@ -53,8 +53,6 @@ extern ssize_t virtual_pread(int fd, void *data, size_t count, off_t offset);
extern FILE* virtual_fopen(const char *fname, const char *mode);
extern int virtual_fclose(FILE* fileptr);
extern ssize_t virtual_getline(char **lineptr, size_t *linelen, FILE *stream);
-
-
#endif
namespace sde {
@@ -325,28 +323,18 @@ DisplayError HWFrameBuffer::SetVSyncState(Handle device, bool enable) {
}
DisplayError HWFrameBuffer::Validate(Handle device, HWLayers *hw_layers) {
+ DisplayError error = kErrorNone;
HWContext *hw_context = reinterpret_cast<HWContext *>(device);
- return kErrorNone;
-}
-
-DisplayError HWFrameBuffer::Commit(Handle device, HWLayers *hw_layers) {
- HWContext *hw_context = reinterpret_cast<HWContext *>(device);
+ hw_context->ResetMDPCommit();
HWLayersInfo &hw_layer_info = hw_layers->info;
+ LayerStack *stack = hw_layer_info.stack;
- // Assuming left & right both pipe are required, maximum possible number of overlays.
- uint32_t max_overlay_count = hw_layer_info.count * 2;
-
- int acquire_fences[hw_layer_info.count]; // NOLINT
- int release_fence = -1;
- int retire_fence = -1;
- uint32_t acquire_fence_count = 0;
- STRUCT_VAR_ARRAY(mdp_overlay, overlay_array, max_overlay_count);
- STRUCT_VAR_ARRAY(msmfb_overlay_data, data_array, max_overlay_count);
+ mdp_layer_commit_v1 &mdp_commit = hw_context->mdp_commit.commit_v1;
+ mdp_input_layer *mdp_layers = hw_context->mdp_layers;
+ uint32_t &mdp_layer_count = mdp_commit.input_layer_cnt;
- LayerStack *stack = hw_layer_info.stack;
- uint32_t num_overlays = 0;
for (uint32_t i = 0; i < hw_layer_info.count; i++) {
uint32_t layer_index = hw_layer_info.index[i];
Layer &layer = stack->layers[layer_index];
@@ -355,110 +343,135 @@ DisplayError HWFrameBuffer::Commit(Handle device, HWLayers *hw_layers) {
HWPipeInfo &left_pipe = config.left_pipe;
// Configure left pipe
- mdp_overlay &left_overlay = overlay_array[num_overlays];
- msmfb_overlay_data &left_data = data_array[num_overlays];
-
- left_overlay.id = left_pipe.pipe_id;
- left_overlay.flags |= MDP_BLEND_FG_PREMULT;
- left_overlay.transp_mask = 0xffffffff;
- left_overlay.z_order = i;
- left_overlay.alpha = layer.plane_alpha;
- left_overlay.src.width = input_buffer->planes[0].stride;
- left_overlay.src.height = input_buffer->height;
- SetBlending(&left_overlay.blend_op, layer.blending);
- SetFormat(&left_overlay.src.format, layer.input_buffer->format);
- SetRect(&left_overlay.src_rect, left_pipe.src_roi);
- SetRect(&left_overlay.dst_rect, left_pipe.dst_roi);
- left_data.id = left_pipe.pipe_id;
- left_data.data.memory_id = input_buffer->planes[0].fd;
- left_data.data.offset = input_buffer->planes[0].offset;
-
- num_overlays++;
+ mdp_input_layer &mdp_layer_left = mdp_layers[mdp_layer_count];
+ mdp_layer_left.alpha = layer.plane_alpha;
+ mdp_layer_left.z_order = static_cast<uint16_t>(i);
+ mdp_layer_left.transp_mask = 0xffffffff;
+ SetBlending(layer.blending, &mdp_layer_left.blend_op);
+ SetRect(left_pipe.src_roi, &mdp_layer_left.src_rect);
+ SetRect(left_pipe.dst_roi, &mdp_layer_left.dst_rect);
+ mdp_layer_left.pipe_ndx = left_pipe.pipe_id;
+
+ mdp_layer_buffer &mdp_buffer_left = mdp_layer_left.buffer;
+ mdp_buffer_left.width = input_buffer->width;
+ mdp_buffer_left.height = input_buffer->height;
+
+ error = SetFormat(layer.input_buffer->format, &mdp_buffer_left.format);
+ if (error != kErrorNone) {
+ return error;
+ }
+
+ mdp_layer_count++;
// Configure right pipe
if (config.is_right_pipe) {
HWPipeInfo &right_pipe = config.right_pipe;
- mdp_overlay &right_overlay = overlay_array[num_overlays];
- msmfb_overlay_data &right_data = data_array[num_overlays];
+ mdp_input_layer &mdp_layer_right = mdp_layers[mdp_layer_count];
- right_overlay = left_overlay;
- right_data = left_data;
- right_overlay.id = right_pipe.pipe_id;
- right_data.id = right_pipe.pipe_id;
- SetRect(&right_overlay.src_rect, right_pipe.src_roi);
- SetRect(&right_overlay.dst_rect, right_pipe.dst_roi);
+ mdp_layer_right = mdp_layer_left;
- num_overlays++;
- }
+ mdp_layer_right.pipe_ndx = right_pipe.pipe_id;
+ SetRect(right_pipe.src_roi, &mdp_layer_right.src_rect);
+ SetRect(right_pipe.dst_roi, &mdp_layer_right.dst_rect);
- if (input_buffer->acquire_fence_fd >= 0) {
- acquire_fences[acquire_fence_count] = input_buffer->acquire_fence_fd;
- acquire_fence_count++;
+ mdp_layer_count++;
}
}
- mdp_overlay *overlay_list[num_overlays];
- msmfb_overlay_data *data_list[num_overlays];
- for (uint32_t i = 0; i < num_overlays; i++) {
- overlay_list[i] = &overlay_array[i];
- data_list[i] = &data_array[i];
+ mdp_commit.flags |= MDP_VALIDATE_LAYER;
+ if (ioctl_(hw_context->device_fd, MSMFB_ATOMIC_COMMIT, &hw_context->mdp_commit) == -1) {
+ IOCTL_LOGE("validate:"MSMFB_ATOMIC_COMMIT);
+ return kErrorHardware;
}
- // TODO(user): Replace with Atomic commit call.
- STRUCT_VAR(mdp_atomic_commit, atomic_commit);
- atomic_commit.overlay_list = overlay_list;
- atomic_commit.data_list = data_list;
- atomic_commit.num_overlays = num_overlays;
- atomic_commit.buf_sync.acq_fen_fd = acquire_fences;
- atomic_commit.buf_sync.acq_fen_fd_cnt = acquire_fence_count;
- atomic_commit.buf_sync.rel_fen_fd = &release_fence;
- atomic_commit.buf_sync.retire_fen_fd = &retire_fence;
- atomic_commit.buf_sync.flags = MDP_BUF_SYNC_FLAG_RETIRE_FENCE;
+ return kErrorNone;
+}
+
+DisplayError HWFrameBuffer::Commit(Handle device, HWLayers *hw_layers) {
+ HWContext *hw_context = reinterpret_cast<HWContext *>(device);
+ HWLayersInfo &hw_layer_info = hw_layers->info;
+ LayerStack *stack = hw_layer_info.stack;
- if (UNLIKELY(ioctl_(hw_context->device_fd, MSMFB_ATOMIC_COMMIT, &atomic_commit) == -1)) {
- IOCTL_LOGE(MSMFB_ATOMIC_COMMIT);
+ mdp_layer_commit_v1 &mdp_commit = hw_context->mdp_commit.commit_v1;
+ mdp_input_layer *mdp_layers = hw_context->mdp_layers;
+ uint32_t mdp_layer_index = 0;
+
+ for (uint32_t i = 0; i < hw_layer_info.count; i++) {
+ uint32_t layer_index = hw_layer_info.index[i];
+ LayerBuffer *input_buffer = stack->layers[layer_index].input_buffer;
+
+ uint32_t split_count = hw_layers->config[i].is_right_pipe ? 2 : 1;
+ for (uint32_t j = 0; j < split_count; j++) {
+ mdp_layer_buffer &mdp_buffer = mdp_layers[mdp_layer_index].buffer;
+
+ if (input_buffer->planes[0].fd >= 0) {
+ mdp_buffer.plane_count = 1;
+ mdp_buffer.planes[0].fd = input_buffer->planes[0].fd;
+ mdp_buffer.planes[0].offset = input_buffer->planes[0].offset;
+ mdp_buffer.planes[0].stride = input_buffer->planes[0].stride;
+ } else {
+ DLOGW("Invalid buffer fd, setting plane count to 0");
+ mdp_buffer.plane_count = 0;
+ }
+
+ mdp_buffer.fence = input_buffer->acquire_fence_fd;
+ mdp_layer_index++;
+ }
+ }
+
+ mdp_commit.flags |= MDP_COMMIT_RETIRE_FENCE;
+ mdp_commit.flags &= ~MDP_VALIDATE_LAYER;
+ if (ioctl_(hw_context->device_fd, MSMFB_ATOMIC_COMMIT, &hw_context->mdp_commit) == -1) {
+ IOCTL_LOGE("commit:"MSMFB_ATOMIC_COMMIT);
return kErrorHardware;
}
// MDP returns only one release fence for the entire layer stack. Duplicate this fence into all
// layers being composed by MDP.
- stack->retire_fence_fd = retire_fence;
+ stack->retire_fence_fd = mdp_commit.retire_fence;
for (uint32_t i = 0; i < hw_layer_info.count; i++) {
uint32_t layer_index = hw_layer_info.index[i];
- Layer &layer = stack->layers[layer_index];
- LayerBuffer *input_buffer = layer.input_buffer;
- input_buffer->release_fence_fd = dup(release_fence);
+ LayerBuffer *input_buffer = stack->layers[layer_index].input_buffer;
+
+ input_buffer->release_fence_fd = dup(mdp_commit.release_fence);
}
- close(release_fence);
+ close(mdp_commit.release_fence);
return kErrorNone;
}
-void HWFrameBuffer::SetFormat(uint32_t *target, const LayerBufferFormat &source) {
+DisplayError HWFrameBuffer::SetFormat(const LayerBufferFormat &source, uint32_t *target) {
switch (source) {
+ case kFormatARGB8888: *target = MDP_ARGB_8888; break;
+ case kFormatRGBA8888: *target = MDP_RGBA_8888; break;
+ case kFormatBGRA8888: *target = MDP_BGRA_8888; break;
+ case kFormatRGBX8888: *target = MDP_RGBX_8888; break;
+ case kFormatBGRX8888: *target = MDP_BGRX_8888; break;
+ case kFormatRGB888: *target = MDP_RGB_888; break;
+ case kFormatRGB565: *target = MDP_RGB_565; break;
+ case kFormatYCbCr420Planar: *target = MDP_Y_CB_CR_H2V2; break;
+ case kFormatYCrCb420Planar: *target = MDP_Y_CR_CB_H2V2; break;
+ case kFormatYCbCr420SemiPlanar: *target = MDP_Y_CBCR_H2V2; break;
+ case kFormatYCrCb420SemiPlanar: *target = MDP_Y_CRCB_H2V2; break;
+ case kFormatYCbCr422Packed: *target = MDP_YCBYCR_H2V1; break;
+ case kFormatYCbCr420SemiPlanarVenus: *target = MDP_Y_CBCR_H2V2_VENUS; break;
default:
- *target = MDP_RGBA_8888;
- break;
+ DLOGE("Unsupported format type %d", source);
+ return kErrorParameters;
}
+
+ return kErrorNone;
}
-void HWFrameBuffer::SetBlending(uint32_t *target, const LayerBlending &source) {
+void HWFrameBuffer::SetBlending(const LayerBlending &source, mdss_mdp_blend_op *target) {
switch (source) {
- case kBlendingPremultiplied:
- *target = BLEND_OP_PREMULTIPLIED;
- break;
-
- case kBlendingCoverage:
- *target = BLEND_OP_COVERAGE;
- break;
-
- default:
- *target = BLEND_OP_NOT_DEFINED;
- break;
+ case kBlendingPremultiplied: *target = BLEND_OP_PREMULTIPLIED; break;
+ case kBlendingCoverage: *target = BLEND_OP_COVERAGE; break;
+ default: *target = BLEND_OP_NOT_DEFINED; break;
}
}
-void HWFrameBuffer::SetRect(mdp_rect *target, const LayerRect &source) {
+void HWFrameBuffer::SetRect(const LayerRect &source, mdp_rect *target) {
target->x = INT(ceilf(source.left));
target->y = INT(ceilf(source.top));
target->w = INT(floorf(source.right)) - target->x;
@@ -498,7 +511,7 @@ void* HWFrameBuffer::DisplayEventThreadHandler() {
pthread_exit(0);
}
- typedef void (HWFrameBuffer::*EventHandler)(int, char*);
+ typedef void (HWFrameBuffer::*EventHandler)(int, char *);
EventHandler event_handler[kNumDisplayEvents] = { &HWFrameBuffer::HandleVSync,
&HWFrameBuffer::HandleBlank };
@@ -538,13 +551,10 @@ void HWFrameBuffer::HandleVSync(int display_id, char *data) {
timestamp = strtoull(data + strlen("VSYNC="), NULL, 0);
}
event_handler_[display_id]->VSync(timestamp);
-
- return;
}
-void HWFrameBuffer::HandleBlank(int display_id, char* data) {
+void HWFrameBuffer::HandleBlank(int display_id, char *data) {
// TODO(user): Need to send blank Event
- return;
}
void HWFrameBuffer::PopulateFBNodeIndex() {
diff --git a/displayengine/libs/core/hw_framebuffer.h b/displayengine/libs/core/hw_framebuffer.h
index d74d03e8..f1d6b396 100644
--- a/displayengine/libs/core/hw_framebuffer.h
+++ b/displayengine/libs/core/hw_framebuffer.h
@@ -27,7 +27,7 @@
#include <stdio.h>
#include <stdlib.h>
-#include <linux/msm_mdp.h>
+#include <linux/msm_mdp_ext.h>
#include <poll.h>
#include <pthread.h>
@@ -58,6 +58,19 @@ class HWFrameBuffer : public HWInterface {
struct HWContext {
HWBlockType type;
int device_fd;
+ mdp_layer_commit mdp_commit;
+ mdp_input_layer mdp_layers[kMaxSDELayers * 2]; // split panel (left + right) for worst case
+
+ HWContext() : type(kHWBlockMax), device_fd(-1) {
+ ResetMDPCommit();
+ }
+
+ void ResetMDPCommit() {
+ memset(&mdp_commit, 0, sizeof(mdp_commit));
+ memset(&mdp_layers, 0, sizeof(mdp_layers));
+ mdp_commit.version = MDP_COMMIT_VERSION_1_0;
+ mdp_commit.commit_v1.input_layers = mdp_layers;
+ }
};
enum PanelType {
@@ -100,9 +113,9 @@ class HWFrameBuffer : public HWInterface {
static const int kNumDisplayEvents = 2;
static const int kHWMdssVersion5 = 500; // MDSS_V5
- inline void SetFormat(uint32_t *target, const LayerBufferFormat &source);
- inline void SetBlending(uint32_t *target, const LayerBlending &source);
- inline void SetRect(mdp_rect *target, const LayerRect &source);
+ inline DisplayError SetFormat(const LayerBufferFormat &source, uint32_t *target);
+ inline void SetBlending(const LayerBlending &source, mdss_mdp_blend_op *target);
+ inline void SetRect(const LayerRect &source, mdp_rect *target);
// Event Thread to receive vsync/blank events
static void* DisplayEventThread(void *context);
diff --git a/displayengine/libs/core/res_config.cpp b/displayengine/libs/core/res_config.cpp
index 6e642ed9..3831eb36 100644
--- a/displayengine/libs/core/res_config.cpp
+++ b/displayengine/libs/core/res_config.cpp
@@ -64,7 +64,7 @@ DisplayError ResManager::Config(DisplayResourceContext *display_resource_ctx, HW
pipe_info = &hw_layers->config[i].right_pipe;
if ((dstRight.right - dstRight.left) > kMaxInterfaceWidth ||
crop_width > kMaxInterfaceWidth ||
- ((hw_block_id == kHWPrimary) && hw_res_info_.is_src_split &&
+ ((hw_block_id == kHWPrimary) &&
(crop_width > display_attributes.split_left))) {
scissor.left = FLOAT(display_attributes.split_left);
scissor.top = 0.0f;
diff --git a/displayengine/libs/core/res_manager.cpp b/displayengine/libs/core/res_manager.cpp
index 3f5bd32a..7439f1a0 100644
--- a/displayengine/libs/core/res_manager.cpp
+++ b/displayengine/libs/core/res_manager.cpp
@@ -195,10 +195,6 @@ DisplayError ResManager::Acquire(Handle display_ctx, HWLayers *hw_layers) {
DisplayError error = kErrorNone;
const struct HWLayersInfo &layer_info = hw_layers->info;
- if (UNLIKELY(!layer_info.count)) {
- return kErrorNone;
- }
-
if (UNLIKELY(layer_info.count > num_pipe_)) {
return kErrorResources;
}
diff --git a/displayengine/libs/hwc/hwc_display.cpp b/displayengine/libs/hwc/hwc_display.cpp
index ce81fdd7..292b71b7 100644
--- a/displayengine/libs/hwc/hwc_display.cpp
+++ b/displayengine/libs/hwc/hwc_display.cpp
@@ -56,8 +56,8 @@ int HWCDisplay::Deinit() {
return -EINVAL;
}
- if (LIKELY(layer_stack_.raw)) {
- delete[] layer_stack_.raw;
+ if (LIKELY(layer_stack_memory_.raw)) {
+ delete[] layer_stack_memory_.raw;
}
return 0;
@@ -174,27 +174,28 @@ int HWCDisplay::AllocateLayerStack(hwc_display_contents_1_t *content_list) {
// Layer array may be large enough to hold current number of layers.
// If not, re-allocate it now.
- if (UNLIKELY(layer_stack_.size < required_size)) {
- if (LIKELY(layer_stack_.raw)) {
- delete[] layer_stack_.raw;
- layer_stack_.size = 0;
+ if (UNLIKELY(layer_stack_memory_.size < required_size)) {
+ if (LIKELY(layer_stack_memory_.raw)) {
+ delete[] layer_stack_memory_.raw;
+ layer_stack_memory_.size = 0;
}
// Allocate in multiple of kSizeSteps.
- required_size = ROUND_UP(required_size, layer_stack_.kSizeSteps);
+ required_size = ROUND_UP(required_size, layer_stack_memory_.kSizeSteps);
- layer_stack_.raw = new uint8_t[required_size];
- if (UNLIKELY(!layer_stack_.raw)) {
+ layer_stack_memory_.raw = new uint8_t[required_size];
+ if (UNLIKELY(!layer_stack_memory_.raw)) {
return -ENOMEM;
}
- layer_stack_.size = required_size;
+ layer_stack_memory_.size = required_size;
}
// Assign memory addresses now.
- uint8_t *current_address = layer_stack_.raw;
+ uint8_t *current_address = layer_stack_memory_.raw;
// Layer array address
+ layer_stack_ = LayerStack();
layer_stack_.layers = reinterpret_cast<Layer *>(current_address);
layer_stack_.layer_count = static_cast<uint32_t>(num_hw_layers);
current_address += num_hw_layers * sizeof(Layer);
@@ -202,19 +203,25 @@ int HWCDisplay::AllocateLayerStack(hwc_display_contents_1_t *content_list) {
for (size_t i = 0; i < num_hw_layers; i++) {
hwc_layer_1_t &hwc_layer = content_list->hwLayers[i];
Layer &layer = layer_stack_.layers[i];
+ layer = Layer();
// Layer buffer handle address
layer.input_buffer = reinterpret_cast<LayerBuffer *>(current_address);
+ *layer.input_buffer = LayerBuffer();
current_address += sizeof(LayerBuffer);
// Visible rectangle address
layer.visible_regions.rect = reinterpret_cast<LayerRect *>(current_address);
layer.visible_regions.count = static_cast<uint32_t>(hwc_layer.visibleRegionScreen.numRects);
+ for (size_t i = 0; i < layer.visible_regions.count; i++) {
+ *layer.visible_regions.rect = LayerRect();
+ }
current_address += hwc_layer.visibleRegionScreen.numRects * sizeof(LayerRect);
// Dirty rectangle address
layer.dirty_regions.rect = reinterpret_cast<LayerRect *>(current_address);
layer.dirty_regions.count = 1;
+ *layer.dirty_regions.rect = LayerRect();
current_address += sizeof(LayerRect);
}
@@ -223,13 +230,10 @@ int HWCDisplay::AllocateLayerStack(hwc_display_contents_1_t *content_list) {
int HWCDisplay::PrepareLayerStack(hwc_display_contents_1_t *content_list) {
size_t num_hw_layers = content_list->numHwLayers;
- if (UNLIKELY(num_hw_layers <= 1)) {
+ if (num_hw_layers <= 1) {
return 0;
}
- // Reset Layer stack flags
- layer_stack_.flags = LayerStackFlags();
-
// Configure each layer
for (size_t i = 0; i < num_hw_layers; i++) {
hwc_layer_1_t &hwc_layer = content_list->hwLayers[i];
@@ -239,15 +243,12 @@ int HWCDisplay::PrepareLayerStack(hwc_display_contents_1_t *content_list) {
LayerBuffer *layer_buffer = layer.input_buffer;
if (pvt_handle) {
- if (UNLIKELY(SetFormat(&layer_buffer->format, pvt_handle->format))) {
+ if (SetFormat(pvt_handle->format, &layer_buffer->format)) {
return -EINVAL;
}
layer_buffer->width = pvt_handle->width;
layer_buffer->height = pvt_handle->height;
- layer_buffer->planes[0].fd = pvt_handle->fd;
- layer_buffer->planes[0].offset = pvt_handle->offset;
- layer_buffer->planes[0].stride = pvt_handle->width;
if (pvt_handle->bufferType == BUFFER_TYPE_VIDEO) {
layer_stack_.flags.video_present = true;
}
@@ -256,20 +257,20 @@ int HWCDisplay::PrepareLayerStack(hwc_display_contents_1_t *content_list) {
}
}
- SetRect(&layer.dst_rect, hwc_layer.displayFrame);
- SetRect(&layer.src_rect, hwc_layer.sourceCropf);
+ SetRect(hwc_layer.displayFrame, &layer.dst_rect);
+ SetRect(hwc_layer.sourceCropf, &layer.src_rect);
for (size_t j = 0; j < hwc_layer.visibleRegionScreen.numRects; j++) {
- SetRect(&layer.visible_regions.rect[j], hwc_layer.visibleRegionScreen.rects[j]);
+ SetRect(hwc_layer.visibleRegionScreen.rects[j], &layer.visible_regions.rect[j]);
}
- SetRect(&layer.dirty_regions.rect[0], hwc_layer.dirtyRect);
- SetComposition(&layer.composition, hwc_layer.compositionType);
- SetBlending(&layer.blending, hwc_layer.blending);
+ SetRect(hwc_layer.dirtyRect, &layer.dirty_regions.rect[0]);
+ SetComposition(hwc_layer.compositionType, &layer.composition);
+ SetBlending(hwc_layer.blending, &layer.blending);
LayerTransform &layer_transform = layer.transform;
uint32_t &hwc_transform = hwc_layer.transform;
layer_transform.flip_horizontal = ((hwc_transform & HWC_TRANSFORM_FLIP_H) > 0);
layer_transform.flip_vertical = ((hwc_transform & HWC_TRANSFORM_FLIP_V) > 0);
- layer_transform.rotation = ((hwc_transform& HWC_TRANSFORM_ROT_90) ? 90.0f : 0.0f);
+ layer_transform.rotation = ((hwc_transform & HWC_TRANSFORM_ROT_90) ? 90.0f : 0.0f);
layer.plane_alpha = hwc_layer.planeAlpha;
layer.flags.skip = ((hwc_layer.flags & HWC_SKIP_LAYER) > 0);
@@ -294,10 +295,16 @@ int HWCDisplay::PrepareLayerStack(hwc_display_contents_1_t *content_list) {
for (size_t i = 0; i < num_hw_layers; i++) {
hwc_layer_1_t &hwc_layer = content_list->hwLayers[i];
Layer &layer = layer_stack_.layers[i];
- // if current frame does not need frame buffer redraw, then mark them for HWC_OVERLAY
- LayerComposition composition = needs_fb_refresh ? layer.composition : kCompositionSDE;
- SetComposition(&hwc_layer.compositionType, composition);
+ LayerComposition composition = layer.composition;
+
+ // If current layer does not need frame buffer redraw, then mark it as HWC_OVERLAY
+ if (!needs_fb_refresh && (composition != kCompositionGPUTarget)) {
+ composition = kCompositionSDE;
+ }
+
+ SetComposition(composition, &hwc_layer.compositionType);
}
+
// Cache the current layer stack information like layer_count, composition type and layer handle
// for the future.
CacheLayerStackInfo(content_list);
@@ -305,15 +312,57 @@ int HWCDisplay::PrepareLayerStack(hwc_display_contents_1_t *content_list) {
return 0;
}
-void HWCDisplay::CacheLayerStackInfo(hwc_display_contents_1_t *content_list) {
- uint32_t layer_count = layer_stack_.layer_count;
+int HWCDisplay::CommitLayerStack(hwc_display_contents_1_t *content_list) {
+ size_t num_hw_layers = content_list->numHwLayers;
+ if (num_hw_layers <= 1) {
+ if (!num_hw_layers) {
+ return 0;
+ }
+
+ // TODO(user): handle if only 1 layer(fb target) is received.
+ int &acquireFenceFd = content_list->hwLayers[0].acquireFenceFd;
+ if (acquireFenceFd >= 0) {
+ close(acquireFenceFd);
+ }
+
+ return 0;
+ }
+
+ for (size_t i = 0; i < num_hw_layers; i++) {
+ hwc_layer_1_t &hwc_layer = content_list->hwLayers[i];
+ const private_handle_t *pvt_handle = static_cast<const private_handle_t *>(hwc_layer.handle);
+ LayerBuffer *layer_buffer = layer_stack_.layers[i].input_buffer;
+
+ if (pvt_handle) {
+ layer_buffer->planes[0].fd = pvt_handle->fd;
+ layer_buffer->planes[0].offset = pvt_handle->offset;
+ layer_buffer->planes[0].stride = pvt_handle->width;
+ }
+
+ layer_buffer->acquire_fence_fd = hwc_layer.acquireFenceFd;
+ }
+
+ DisplayError error = display_intf_->Commit(&layer_stack_);
+ if (UNLIKELY(error != kErrorNone)) {
+ DLOGE("Commit failed. Error = %d", error);
+ return -EINVAL;
+ }
- for (size_t i = 0; i < layer_count; i++) {
+ for (size_t i = 0; i < num_hw_layers; i++) {
+ hwc_layer_1_t &hwc_layer = content_list->hwLayers[i];
Layer &layer = layer_stack_.layers[i];
- layer_stack_cache_.layer_cache[i].handle = content_list->hwLayers[i].handle;
- layer_stack_cache_.layer_cache[i].composition = layer.composition;
+ LayerBuffer *layer_buffer = layer_stack_.layers[i].input_buffer;
+
+ if (layer.composition == kCompositionSDE || layer.composition == kCompositionGPUTarget) {
+ hwc_layer.releaseFenceFd = layer_buffer->release_fence_fd;
+ }
+
+ if (hwc_layer.acquireFenceFd >= 0) {
+ close(hwc_layer.acquireFenceFd);
+ }
}
- layer_stack_cache_.layer_count = layer_count;
+
+ return 0;
}
bool HWCDisplay::NeedsFrameBufferRefresh(hwc_display_contents_1_t *content_list) {
@@ -329,13 +378,19 @@ bool HWCDisplay::NeedsFrameBufferRefresh(hwc_display_contents_1_t *content_list)
return true;
}
- for (size_t i = 0; i < layer_count; i++) {
+ for (uint32_t i = 0; i < layer_count; i++) {
hwc_layer_1_t &hwc_layer = content_list->hwLayers[i];
Layer &layer = layer_stack_.layers[i];
LayerCache &layer_cache = layer_stack_cache_.layer_cache[i];
+
+ if (layer.composition == kCompositionGPUTarget) {
+ continue;
+ }
+
if (layer_cache.composition != layer.composition) {
return true;
}
+
if ((layer.composition == kCompositionGPU) && (layer_cache.handle != hwc_layer.handle)) {
return true;
}
@@ -344,115 +399,69 @@ bool HWCDisplay::NeedsFrameBufferRefresh(hwc_display_contents_1_t *content_list)
return false;
}
-int HWCDisplay::CommitLayerStack(hwc_display_contents_1_t *content_list) {
- size_t num_hw_layers = content_list->numHwLayers;
- if (UNLIKELY(num_hw_layers <= 1)) {
- return 0;
- }
-
- for (size_t i = 0; i < num_hw_layers; i++) {
- hwc_layer_1_t &hwc_layer = content_list->hwLayers[i];
- LayerBuffer *layer_buffer = layer_stack_.layers[i].input_buffer;
-
- layer_buffer->acquire_fence_fd = hwc_layer.acquireFenceFd;
- }
-
- DisplayError error = display_intf_->Commit(&layer_stack_);
- if (UNLIKELY(error != kErrorNone)) {
- DLOGE("Commit failed. Error = %d", error);
- return -EINVAL;
- }
+void HWCDisplay::CacheLayerStackInfo(hwc_display_contents_1_t *content_list) {
+ uint32_t layer_count = layer_stack_.layer_count;
- for (size_t i = 0; i < num_hw_layers; i++) {
- hwc_layer_1_t &hwc_layer = content_list->hwLayers[i];
+ for (uint32_t i = 0; i < layer_count; i++) {
Layer &layer = layer_stack_.layers[i];
- LayerBuffer *layer_buffer = layer_stack_.layers[i].input_buffer;
- if (layer.composition == kCompositionSDE || layer.composition == kCompositionGPUTarget) {
- hwc_layer.releaseFenceFd = layer_buffer->release_fence_fd;
+ if (layer.composition == kCompositionGPUTarget) {
+ continue;
}
- if (hwc_layer.acquireFenceFd >= 0) {
- close(hwc_layer.acquireFenceFd);
- }
+ layer_stack_cache_.layer_cache[i].handle = content_list->hwLayers[i].handle;
+ layer_stack_cache_.layer_cache[i].composition = layer.composition;
}
- return 0;
+ layer_stack_cache_.layer_count = layer_count;
}
-void HWCDisplay::SetRect(LayerRect *target, const hwc_rect_t &source) {
+void HWCDisplay::SetRect(const hwc_rect_t &source, LayerRect *target) {
target->left = FLOAT(source.left);
target->top = FLOAT(source.top);
target->right = FLOAT(source.right);
target->bottom = FLOAT(source.bottom);
}
-void HWCDisplay::SetRect(LayerRect *target, const hwc_frect_t &source) {
+void HWCDisplay::SetRect(const hwc_frect_t &source, LayerRect *target) {
target->left = source.left;
target->top = source.top;
target->right = source.right;
target->bottom = source.bottom;
}
-void HWCDisplay::SetComposition(LayerComposition *target, const int32_t &source) {
+void HWCDisplay::SetComposition(const int32_t &source, LayerComposition *target) {
switch (source) {
- case HWC_FRAMEBUFFER_TARGET:
- *target = kCompositionGPUTarget;
- break;
- default:
- *target = kCompositionSDE;
- break;
+ case HWC_FRAMEBUFFER_TARGET: *target = kCompositionGPUTarget; break;
+ default: *target = kCompositionSDE; break;
}
}
-void HWCDisplay::SetComposition(int32_t *target, const LayerComposition &source) {
+void HWCDisplay::SetComposition(const int32_t &source, int32_t *target) {
switch (source) {
- case kCompositionGPUTarget:
- *target = HWC_FRAMEBUFFER_TARGET;
- break;
- case kCompositionSDE:
- *target = HWC_OVERLAY;
- break;
- default:
- *target = HWC_FRAMEBUFFER;
- break;
+ case kCompositionGPUTarget: *target = HWC_FRAMEBUFFER_TARGET; break;
+ case kCompositionSDE: *target = HWC_OVERLAY; break;
+ default: *target = HWC_FRAMEBUFFER; break;
}
}
-void HWCDisplay::SetBlending(LayerBlending *target, const int32_t &source) {
+void HWCDisplay::SetBlending(const int32_t &source, LayerBlending *target) {
switch (source) {
- case HWC_BLENDING_PREMULT:
- *target = kBlendingPremultiplied;
- break;
- case HWC_BLENDING_COVERAGE:
- *target = kBlendingCoverage;
- break;
- default:
- *target = kBlendingNone;
- break;
+ case HWC_BLENDING_PREMULT: *target = kBlendingPremultiplied; break;
+ case HWC_BLENDING_COVERAGE: *target = kBlendingCoverage; break;
+ default: *target = kBlendingNone; break;
}
}
-int HWCDisplay::SetFormat(LayerBufferFormat *target, const int &source) {
+int HWCDisplay::SetFormat(const int32_t &source, LayerBufferFormat *target) {
switch (source) {
- case HAL_PIXEL_FORMAT_RGBA_8888:
- *target = kFormatRGBA8888;
- break;
- case HAL_PIXEL_FORMAT_BGRA_8888:
- *target = kFormatBGRA8888;
- break;
- case HAL_PIXEL_FORMAT_RGBX_8888:
- *target = kFormatRGBX8888;
- break;
- case HAL_PIXEL_FORMAT_BGRX_8888:
- *target = kFormatBGRX8888;
- break;
- case HAL_PIXEL_FORMAT_RGB_888:
- *target = kFormatRGB888;
- break;
- case HAL_PIXEL_FORMAT_RGB_565:
- *target = kFormatRGB565;
- break;
+ case HAL_PIXEL_FORMAT_RGBA_8888: *target = kFormatRGBA8888; break;
+ case HAL_PIXEL_FORMAT_BGRA_8888: *target = kFormatBGRA8888; break;
+ case HAL_PIXEL_FORMAT_RGBX_8888: *target = kFormatRGBX8888; break;
+ case HAL_PIXEL_FORMAT_BGRX_8888: *target = kFormatBGRX8888; break;
+ case HAL_PIXEL_FORMAT_RGB_888: *target = kFormatRGB888; break;
+ case HAL_PIXEL_FORMAT_RGB_565: *target = kFormatRGB565; break;
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: *target = kFormatYCbCr420SemiPlanarVenus; break;
default:
DLOGE("Unsupported format type %d", source);
return -EINVAL;
diff --git a/displayengine/libs/hwc/hwc_display.h b/displayengine/libs/hwc/hwc_display.h
index 67356af2..2ad1987f 100644
--- a/displayengine/libs/hwc/hwc_display.h
+++ b/displayengine/libs/hwc/hwc_display.h
@@ -47,39 +47,14 @@ class HWCDisplay : public DisplayEventHandler {
static const uint32_t kMaxLayerCount = 32;
// Structure to track memory allocation for layer stack (layers, rectangles) object.
- struct LayerStackMemory : LayerStack {
- static const size_t kSizeSteps = 4096; // Default memory allocation.
+ struct LayerStackMemory {
+ static const size_t kSizeSteps = 1024; // Default memory allocation.
uint8_t *raw; // Pointer to byte array.
size_t size; // Current number of allocated bytes.
LayerStackMemory() : raw(NULL), size(0) { }
};
- HWCDisplay(CoreInterface *core_intf, hwc_procs_t const **hwc_procs, DisplayType type, int id);
- virtual ~HWCDisplay() { }
-
- // DisplayEventHandler methods
- virtual DisplayError VSync(const DisplayEventVSync &vsync);
- virtual DisplayError Refresh();
-
- virtual int AllocateLayerStack(hwc_display_contents_1_t *content_list);
- virtual int PrepareLayerStack(hwc_display_contents_1_t *content_list);
- virtual int CommitLayerStack(hwc_display_contents_1_t *content_list);
- inline void SetRect(LayerRect *target, const hwc_rect_t &source);
- inline void SetRect(LayerRect *target, const hwc_frect_t &source);
- inline void SetComposition(LayerComposition *target, const int32_t &source);
- inline void SetComposition(int32_t *target, const LayerComposition &source);
- inline void SetBlending(LayerBlending *target, const int32_t &source);
- inline int SetFormat(LayerBufferFormat *target, const int &source);
-
- LayerStackMemory layer_stack_;
- CoreInterface *core_intf_;
- hwc_procs_t const **hwc_procs_;
- DisplayType type_;
- int id_;
- DisplayInterface *display_intf_;
-
- private:
struct LayerCache {
buffer_handle_t handle;
LayerComposition composition;
@@ -94,10 +69,33 @@ class HWCDisplay : public DisplayEventHandler {
LayerStackCache() : layer_count(0) { }
};
+ HWCDisplay(CoreInterface *core_intf, hwc_procs_t const **hwc_procs, DisplayType type, int id);
+ virtual ~HWCDisplay() { }
+
+ // DisplayEventHandler methods
+ virtual DisplayError VSync(const DisplayEventVSync &vsync);
+ virtual DisplayError Refresh();
+
+ virtual int AllocateLayerStack(hwc_display_contents_1_t *content_list);
+ virtual int PrepareLayerStack(hwc_display_contents_1_t *content_list);
+ virtual int CommitLayerStack(hwc_display_contents_1_t *content_list);
bool NeedsFrameBufferRefresh(hwc_display_contents_1_t *content_list);
void CacheLayerStackInfo(hwc_display_contents_1_t *content_list);
-
+ inline void SetRect(const hwc_rect_t &source, LayerRect *target);
+ inline void SetRect(const hwc_frect_t &source, LayerRect *target);
+ inline void SetComposition(const int32_t &source, LayerComposition *target);
+ inline void SetComposition(const int32_t &source, int32_t *target);
+ inline void SetBlending(const int32_t &source, LayerBlending *target);
+ inline int SetFormat(const int32_t &source, LayerBufferFormat *target);
+
+ LayerStackMemory layer_stack_memory_;
+ LayerStack layer_stack_;
LayerStackCache layer_stack_cache_;
+ CoreInterface *core_intf_;
+ hwc_procs_t const **hwc_procs_;
+ DisplayType type_;
+ int id_;
+ DisplayInterface *display_intf_;
};
} // namespace sde
diff --git a/displayengine/libs/hwc/hwc_display_external.cpp b/displayengine/libs/hwc/hwc_display_external.cpp
index 369d2860..8334605a 100644
--- a/displayengine/libs/hwc/hwc_display_external.cpp
+++ b/displayengine/libs/hwc/hwc_display_external.cpp
@@ -45,10 +45,33 @@ int HWCDisplayExternal::Deinit() {
}
int HWCDisplayExternal::Prepare(hwc_display_contents_1_t *content_list) {
+ int status = 0;
+
+ status = AllocateLayerStack(content_list);
+ if (UNLIKELY(status)) {
+ return status;
+ }
+
+ layer_stack_.retire_fence_fd = -1;
+
+ status = PrepareLayerStack(content_list);
+ if (UNLIKELY(status)) {
+ return status;
+ }
+
return 0;
}
int HWCDisplayExternal::Commit(hwc_display_contents_1_t *content_list) {
+ int status = 0;
+
+ status = HWCDisplay::CommitLayerStack(content_list);
+ if (UNLIKELY(status)) {
+ return status;
+ }
+
+ content_list->retireFenceFd = layer_stack_.retire_fence_fd;
+
return 0;
}
diff --git a/displayengine/libs/hwc/hwc_display_primary.cpp b/displayengine/libs/hwc/hwc_display_primary.cpp
index d0c0734a..b23d89cc 100644
--- a/displayengine/libs/hwc/hwc_display_primary.cpp
+++ b/displayengine/libs/hwc/hwc_display_primary.cpp
@@ -52,6 +52,8 @@ int HWCDisplayPrimary::Prepare(hwc_display_contents_1_t *content_list) {
return status;
}
+ layer_stack_.retire_fence_fd = -1;
+
status = PrepareLayerStack(content_list);
if (UNLIKELY(status)) {
return status;