sde: Make validate and commit ioctl calls on driver.
1. Update hw framebuffer implementation to compose layers for
validation with driver.
2. Use atomic commit ioctl to send layers for validation
and commit on driver.
3. Add different buffer formats handling in hw framebuffer.
Change-Id: I13f9c245c14859c8e2680ef724cfebb59a0d990e
diff --git a/Android.mk b/Android.mk
index 4a951c8..b3015af 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 421ab87..26b477c 100644
--- a/displayengine/include/core/layer_buffer.h
+++ b/displayengine/include/core/layer_buffer.h
@@ -76,6 +76,10 @@
//!< 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 74c1960..6a99701 100644
--- a/displayengine/include/core/layer_stack.h
+++ b/displayengine/include/core/layer_stack.h
@@ -43,7 +43,7 @@
@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 @@
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 5b2d0af..d5a34f2 100644
--- a/displayengine/libs/core/display_base.cpp
+++ b/displayengine/libs/core/display_base.cpp
@@ -233,6 +233,7 @@
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 63adf8c..309dbd6 100644
--- a/displayengine/libs/core/hw_framebuffer.cpp
+++ b/displayengine/libs/core/hw_framebuffer.cpp
@@ -53,8 +53,6 @@
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::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;
-
- // 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);
-
LayerStack *stack = hw_layer_info.stack;
- uint32_t num_overlays = 0;
+
+ 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;
+
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 @@
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];
+ 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;
- 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;
+ mdp_layer_buffer &mdp_buffer_left = mdp_layer_left.buffer;
+ mdp_buffer_left.width = input_buffer->width;
+ mdp_buffer_left.height = input_buffer->height;
- num_overlays++;
+ 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;
+}
- if (UNLIKELY(ioctl_(hw_context->device_fd, MSMFB_ATOMIC_COMMIT, &atomic_commit) == -1)) {
- IOCTL_LOGE(MSMFB_ATOMIC_COMMIT);
+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;
+
+ 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(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;
}
}
-void HWFrameBuffer::SetBlending(uint32_t *target, const LayerBlending &source) {
- switch (source) {
- 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 @@
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 @@
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 d74d03e..f1d6b39 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 @@
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 @@
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 6e642ed..3831eb3 100644
--- a/displayengine/libs/core/res_config.cpp
+++ b/displayengine/libs/core/res_config.cpp
@@ -64,7 +64,7 @@
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 3f5bd32..7439f1a 100644
--- a/displayengine/libs/core/res_manager.cpp
+++ b/displayengine/libs/core/res_manager.cpp
@@ -195,10 +195,6 @@
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 ce81fdd..292b71b 100644
--- a/displayengine/libs/hwc/hwc_display.cpp
+++ b/displayengine/libs/hwc/hwc_display.cpp
@@ -56,8 +56,8 @@
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 @@
// 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 @@
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::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 @@
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 @@
}
}
- 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 @@
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,55 +312,33 @@
return 0;
}
-void HWCDisplay::CacheLayerStackInfo(hwc_display_contents_1_t *content_list) {
- uint32_t layer_count = layer_stack_.layer_count;
-
- for (size_t i = 0; i < layer_count; 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;
- }
- layer_stack_cache_.layer_count = layer_count;
-}
-
-bool HWCDisplay::NeedsFrameBufferRefresh(hwc_display_contents_1_t *content_list) {
- uint32_t layer_count = layer_stack_.layer_count;
-
- // Frame buffer needs to be refreshed for the following reasons:
- // 1. Any layer is marked skip in the current layer stack.
- // 2. Any layer is added/removed/layer properties changes in the current layer stack.
- // 3. Any layer handle is changed and it is marked for GPU composition
- // 4. Any layer's current composition is different from previous composition.
- if ((layer_stack_cache_.layer_count != layer_count) || layer_stack_.flags.skip_present ||
- layer_stack_.flags.geometry_changed) {
- return true;
- }
-
- for (size_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_cache.composition != layer.composition) {
- return true;
- }
- if ((layer.composition == kCompositionGPU) && (layer_cache.handle != hwc_layer.handle)) {
- return true;
- }
- }
-
- 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)) {
+ 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;
}
@@ -380,79 +365,103 @@
return 0;
}
-void HWCDisplay::SetRect(LayerRect *target, const hwc_rect_t &source) {
+bool HWCDisplay::NeedsFrameBufferRefresh(hwc_display_contents_1_t *content_list) {
+ uint32_t layer_count = layer_stack_.layer_count;
+
+ // Frame buffer needs to be refreshed for the following reasons:
+ // 1. Any layer is marked skip in the current layer stack.
+ // 2. Any layer is added/removed/layer properties changes in the current layer stack.
+ // 3. Any layer handle is changed and it is marked for GPU composition
+ // 4. Any layer's current composition is different from previous composition.
+ if ((layer_stack_cache_.layer_count != layer_count) || layer_stack_.flags.skip_present ||
+ layer_stack_.flags.geometry_changed) {
+ return true;
+ }
+
+ 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;
+ }
+ }
+
+ return false;
+}
+
+void HWCDisplay::CacheLayerStackInfo(hwc_display_contents_1_t *content_list) {
+ uint32_t layer_count = layer_stack_.layer_count;
+
+ for (uint32_t i = 0; i < layer_count; i++) {
+ Layer &layer = layer_stack_.layers[i];
+
+ if (layer.composition == kCompositionGPUTarget) {
+ continue;
+ }
+
+ layer_stack_cache_.layer_cache[i].handle = content_list->hwLayers[i].handle;
+ layer_stack_cache_.layer_cache[i].composition = layer.composition;
+ }
+
+ layer_stack_cache_.layer_count = layer_count;
+}
+
+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 67356af..2ad1987 100644
--- a/displayengine/libs/hwc/hwc_display.h
+++ b/displayengine/libs/hwc/hwc_display.h
@@ -47,39 +47,14 @@
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 @@
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 369d286..8334605 100644
--- a/displayengine/libs/hwc/hwc_display_external.cpp
+++ b/displayengine/libs/hwc/hwc_display_external.cpp
@@ -45,10 +45,33 @@
}
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 d0c0734..b23d89c 100644
--- a/displayengine/libs/hwc/hwc_display_primary.cpp
+++ b/displayengine/libs/hwc/hwc_display_primary.cpp
@@ -52,6 +52,8 @@
return status;
}
+ layer_stack_.retire_fence_fd = -1;
+
status = PrepareLayerStack(content_list);
if (UNLIKELY(status)) {
return status;