diff options
-rw-r--r-- | Android.mk | 3 | ||||
-rw-r--r-- | displayengine/include/core/layer_buffer.h | 4 | ||||
-rw-r--r-- | displayengine/include/core/layer_stack.h | 4 | ||||
-rw-r--r-- | displayengine/libs/core/display_base.cpp | 1 | ||||
-rw-r--r-- | displayengine/libs/core/hw_framebuffer.cpp | 196 | ||||
-rw-r--r-- | displayengine/libs/core/hw_framebuffer.h | 21 | ||||
-rw-r--r-- | displayengine/libs/core/res_config.cpp | 2 | ||||
-rw-r--r-- | displayengine/libs/core/res_manager.cpp | 4 | ||||
-rw-r--r-- | displayengine/libs/hwc/hwc_display.cpp | 231 | ||||
-rw-r--r-- | displayengine/libs/hwc/hwc_display.h | 54 | ||||
-rw-r--r-- | displayengine/libs/hwc/hwc_display_external.cpp | 23 | ||||
-rw-r--r-- | displayengine/libs/hwc/hwc_display_primary.cpp | 2 |
12 files changed, 300 insertions, 245 deletions
@@ -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; |