diff options
author | Vishal Mahaveer <vishalm@ti.com> | 2018-01-09 16:34:37 -0600 |
---|---|---|
committer | Vishal Mahaveer <vishalm@ti.com> | 2018-01-09 16:34:37 -0600 |
commit | 7e4136f7722b28ef1e445a6c1994a6d88f936163 (patch) | |
tree | d3fefbee3caf2c2a6acd88b2a6249fea329a2e28 | |
parent | 3ef51f882bf0ed8a1048762fe87550ac13914f4c (diff) | |
parent | 01ce70d558cfa06a6aa2f56cb7be1c0d2d286780 (diff) | |
download | dra7xx-7e4136f7722b28ef1e445a6c1994a6d88f936163.tar.gz |
Merge remote-tracking branch 'omap-mirror/d-oreo-r6-release' into d-oreo-mr1-release
* omap-mirror/d-oreo-r6-release:
hwc: Add support for pageflip display update mode
hwc: code cleanup: Remove obsolete num_buffers
hwc: Enable single layer NV12 DSS composition
hwc: Add a dummy fb buffer
hwc: Add plane property setter utility function
hwc: Use index buffer for overlay asssignment
hwc: Fix used overlay count
hwc: Increment timeline on display udpate failures
-rw-r--r-- | hwcomposer/Android.mk | 7 | ||||
-rw-r--r-- | hwcomposer/display.c | 243 | ||||
-rw-r--r-- | hwcomposer/display.h | 4 | ||||
-rw-r--r-- | hwcomposer/hwc.c | 39 |
4 files changed, 203 insertions, 90 deletions
diff --git a/hwcomposer/Android.mk b/hwcomposer/Android.mk index dd463b6..d76dd8d 100644 --- a/hwcomposer/Android.mk +++ b/hwcomposer/Android.mk @@ -7,7 +7,7 @@ include $(CLEAR_VARS) LOCAL_PRELINK_MODULE := false LOCAL_ARM_MODE := arm LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/lib/hw -LOCAL_SHARED_LIBRARIES := liblog libcutils libutils libhardware libdrm libsync libhardware_legacy +LOCAL_SHARED_LIBRARIES := liblog libcutils libutils libhardware libdrm libsync libhardware_legacy libdrm_omap LOCAL_CFLAGS += -DSUPPORT_ANDROID_MEMTRACK_HAL @@ -15,6 +15,7 @@ LOCAL_C_INCLUDES += \ hardware/libhardware/gralloc \ external/libdrm \ external/libdrm/include/drm \ + external/libdrm/omap \ hardware/libhardware/include \ system/core/libsync \ system/core/libsync/include @@ -27,6 +28,10 @@ LOCAL_SRC_FILES := \ sw_vsync.c \ utils.c +ifeq ($(HWC_USE_DRM_PAGEFLIP_MODE),true) + LOCAL_CFLAGS += -DHWC_USE_DRM_PAGEFLIP_MODE +endif + LOCAL_MODULE_TAGS := optional LOCAL_MODULE := hwcomposer.$(TARGET_BOARD_PLATFORM) diff --git a/hwcomposer/display.c b/hwcomposer/display.c index de1aa25..098643f 100644 --- a/hwcomposer/display.c +++ b/hwcomposer/display.c @@ -26,6 +26,8 @@ #include <sync/sync.h> #include <linux/fb.h> +#include <omap/omap_drm.h> +#include <omap/omap_drmif.h> #include "hwc_dev.h" #include "color_fmt.h" @@ -318,6 +320,9 @@ bool can_dss_render_all_layers(omap_hwc_device_t *hwc_dev, int disp) if (disp) return false; + if (!display->disp_link.is_crtc_set) + return false; + if (layer_stats->bgr) return false; @@ -343,6 +348,62 @@ bool can_dss_render_layer(omap_hwc_device_t *hwc_dev, int disp, hwc_layer_1_t *l return is_composable_layer(hwc_dev, disp, layer); } +static void display_free_dummy_fb(display_t *display) +{ + display_release_drm_fb(display, &display->disp_link.dummy_fb); +} + +static int display_init_dummy_fb(display_t *display) +{ + kms_display_t *kdisp = &display->disp_link; + int drm_fd = kdisp->ctx->drm_fd; + struct omap_bo *bo; + struct omap_device *dev; + uint32_t size; + int err = 0; + int width, height; + + width = kdisp->mode->hdisplay; + height = kdisp->mode->vdisplay; + size = width * height * 4; + + dev = omap_device_new(drm_fd); + if (!dev) { + ALOGE("Failed to get omap device (%s)", strerror(errno)); + return -1; + } + bo = omap_bo_new(dev, size, OMAP_BO_WC); + if (!bo) { + ALOGE("Failed to create dummy bo (%s)", strerror(errno)); + return -1; + } + void *vaddr = omap_bo_map(bo); + memset(vaddr, 0x0, size); + + memset(&kdisp->dummy_fb, 0x0, sizeof(kdisp->dummy_fb)); + kdisp->dummy_fb.bo[0] = omap_bo_handle(bo); + kdisp->dummy_fb.pitches[0] = width * 4; + + err = drmModeAddFB2(drm_fd, width, height, DRM_FORMAT_ARGB8888, + kdisp->dummy_fb.bo, kdisp->dummy_fb.pitches, + kdisp->dummy_fb.offsets, &kdisp->dummy_fb.fb_id, 0); + if (err) { + ALOGE("Failed to create dummy drm fb (%s)", strerror(err)); + goto free_bo; + } + + kdisp->dummy_fb.width = width; + kdisp->dummy_fb.height = height; + kdisp->dummy_fb.format = DRM_FORMAT_ARGB8888; + omap_device_del(dev); + return err; + +free_bo: + omap_bo_del(bo); + omap_device_del(dev); + return err; +} + static void free_display(display_t *display) { if (display) { @@ -351,6 +412,8 @@ static void free_display(display_t *display) if (display->composition.buffers) free(display->composition.buffers); + display_free_dummy_fb(display); + if (display->retire_sync.timeline >= 0) { /* increment timeline to signal any pending fences */ timeline_inc(&display->retire_sync); @@ -738,6 +801,8 @@ static int display_get_connector_type(int disp) return type; } + + int init_primary_display(omap_hwc_device_t *hwc_dev) { if (hwc_dev->displays[HWC_DISPLAY_PRIMARY]) { @@ -775,11 +840,14 @@ int init_primary_display(omap_hwc_device_t *hwc_dev) ALOGE("failed to set DRM_CLIENT_CAP_UNIVERSAL_PLANES"); goto close; } + +#ifndef HWC_USE_DRM_PAGEFLIP_API i = drmSetClientCap(drm_fd, DRM_CLIENT_CAP_ATOMIC, 1); if (i) { ALOGE("omapdrm is not capable of atomic modesetting"); goto close; } +#endif resources = drmModeGetResources(drm_fd); if (!resources) { @@ -847,6 +915,11 @@ int init_primary_display(omap_hwc_device_t *hwc_dev) display->mgr_ix = 0; display->blanked = true; + n = display_init_dummy_fb(display); + if (n) { + ALOGE("Failed to create dummy fb"); + } + display_assign_pipes_for_composition(display, HWC_DISPLAY_PRIMARY); display->retire_sync.timeline = sw_sync_timeline_create(); @@ -1055,97 +1128,102 @@ static int fence_wait(int fence) return err; } +static int set_plane_properties(drmModeAtomicReqPtr req, + drm_plane_props_t *plane, drm_fb_info_t *fb) +{ + int err = 0; + + if (!fb->fb_id) { + /* disable plane */ + ALOGI("Disabling plane %d", plane->plane_id); + err = drmModeAtomicAddProperty(req, plane->plane_id, + 14, 0) < 0; + err |= drmModeAtomicAddProperty(req, plane->plane_id, + 15, 0) < 0; + return err; + } + + err = drmModeAtomicAddProperty(req, plane->plane_id, + 6, plane->src_x << 16) < 0; + err |= drmModeAtomicAddProperty(req, plane->plane_id, + 7, plane->src_y << 16) < 0; + err |= drmModeAtomicAddProperty(req, plane->plane_id, + 8, plane->src_w << 16) < 0; + err |= drmModeAtomicAddProperty(req, plane->plane_id, + 9, plane->src_h << 16) < 0; + err |= drmModeAtomicAddProperty(req, plane->plane_id, + 10, plane->crtc_x) < 0; + err |= drmModeAtomicAddProperty(req, plane->plane_id, + 11, plane->crtc_y) < 0; + err |= drmModeAtomicAddProperty(req, plane->plane_id, + 12, plane->crtc_w) < 0; + err |= drmModeAtomicAddProperty(req, plane->plane_id, + 13, plane->crtc_h) < 0; + err |= drmModeAtomicAddProperty(req, plane->plane_id, + 14, fb->fb_id) < 0; + err |= drmModeAtomicAddProperty(req, plane->plane_id, + 15, plane->crtc_id) < 0; + err |= drmModeAtomicAddProperty(req, plane->plane_id, + 24, plane->zorder) < 0; + err |= drmModeAtomicAddProperty(req, plane->plane_id, + 26, plane->pre_mult_alpha) < 0; + + return err; +} + static int display_configure_pipes(display_t *display) { int err = 0; kms_display_t *kdisp = &display->disp_link; composition_t *comp = &display->composition; - omap_hwc_device_t *hwc_dev = kdisp->ctx; + drm_plane_props_t *plane_info = NULL; uint32_t i = 0; if (!kdisp->is_crtc_set) return 0; for (i = 0; i < comp->used_ovls; i++) { - if (comp->plane_info[i].layer) { + plane_info = &comp->plane_info[comp->ovl_indices[i]]; + if (plane_info->layer && plane_info->layer->handle) { drm_fb_info_t fb_info = { 0 }; - drm_plane_props_t *plane_info = &comp->plane_info[i]; buffer_handle_t handle = plane_info->layer->handle; - /* if blitter is enabled we use only one pipe and the - * buffer handle comes from blitter - */ if (comp->use_blitter) { - handle = - hwc_dev->blitter->get_fb_handle(hwc_dev->blitter, - display->type - 1); + omap_hwc_device_t *dev = kdisp->ctx; + handle = dev->blitter->get_fb_handle(dev->blitter, + display->type - 1); } - err = display_create_drm_fb(display, handle, - (void *)plane_info, &fb_info); + err = display_create_drm_fb(display, handle, (void *)plane_info, + &fb_info); if (err) { - ALOGE("Plane %d: Error in creating drm fb: %d (%s)", i, - err, strerror(err)); - return err; - } - err = drmModeAtomicAddProperty(kdisp->atomic_req, - plane_info->plane_id, 14, fb_info.fb_id); - /* This returns -EINVAL or -ENOMEM on error */ - if (err == -EINVAL || err == -ENOMEM) { - ALOGE("Failed to add property %d (%s)", errno, strerror(errno)); + ALOGE("Plane %d: Error in creating drm fb %d (%s)", + plane_info->plane_id, err, strerror(err)); return err; } plane_info->fb_info = fb_info; - /* region where the layer is displayed */ - err = drmModeAtomicAddProperty(kdisp->atomic_req, plane_info->plane_id, - 10, plane_info->crtc_x); - if (err == -EINVAL || err == -ENOMEM) - ALOGE("Failed setting crtc_x"); - err = drmModeAtomicAddProperty(kdisp->atomic_req, plane_info->plane_id, - 11, plane_info->crtc_y); - if (err == -EINVAL || err == -ENOMEM) - ALOGE("Failed setting crtc_y"); - err = drmModeAtomicAddProperty(kdisp->atomic_req, plane_info->plane_id, - 12, plane_info->crtc_w); - if (err == -EINVAL || err == -ENOMEM) - ALOGE("Failed setting crtc_w"); - err = drmModeAtomicAddProperty(kdisp->atomic_req, plane_info->plane_id, - 13, plane_info->crtc_h); - if (err == -EINVAL || err == -ENOMEM) - ALOGE("Failed setting crtc_h"); - - /* region of the source to be displayed */ - err = drmModeAtomicAddProperty(kdisp->atomic_req, plane_info->plane_id, - 6, plane_info->src_x << 16); - if (err == -EINVAL || err == -ENOMEM) - ALOGE("Failed setting src_x"); - err = drmModeAtomicAddProperty(kdisp->atomic_req, plane_info->plane_id, - 7, plane_info->src_y << 16); - if (err == -EINVAL || err == -ENOMEM) - ALOGE("Failed setting src_y"); - err = drmModeAtomicAddProperty(kdisp->atomic_req, plane_info->plane_id, - 8, plane_info->src_w << 16); - if (err == -EINVAL || err == -ENOMEM) - ALOGE("Failed setting src_w"); - err = drmModeAtomicAddProperty(kdisp->atomic_req, plane_info->plane_id, - 9, plane_info->src_h << 16); - if (err == -EINVAL || err == -ENOMEM) - ALOGE("Failed setting src_h"); - - /* z-order, blending, and rotation */ - err = drmModeAtomicAddProperty(kdisp->atomic_req, plane_info->plane_id, - 24, plane_info->zorder); - if (err == -EINVAL || err == -ENOMEM) - ALOGE("Failed setting zorder"); - - err = drmModeAtomicAddProperty(kdisp->atomic_req, plane_info->plane_id, - 26, comp->plane_info[i].pre_mult_alpha); - - err = drmModeAtomicAddProperty(kdisp->atomic_req, plane_info->plane_id, - 15, plane_info->crtc_id); - if (err == -EINVAL || err == -ENOMEM) - ALOGE("Failed setting crtc_id"); +#ifndef HWC_USE_DRM_PAGEFLIP_MODE + err = set_plane_properties(kdisp->atomic_req, plane_info, &fb_info); + if (err) { + ALOGE("Failed to configure plane %d (error: %s)", + plane_info->plane_id, strerror(err)); + } +#endif + } + } + if (comp->used_ovls == 1 && comp->use_dss && display->layer_stats.nv12) { + plane_info = &comp->plane_info[comp->ovl_indices[1]]; + plane_info->crtc_w = kdisp->dummy_fb.width; + plane_info->crtc_h = kdisp->dummy_fb.height; + plane_info->src_w = kdisp->dummy_fb.width; + plane_info->src_h = kdisp->dummy_fb.height; + plane_info->zorder = 0; + err = set_plane_properties(kdisp->atomic_req, + plane_info, &kdisp->dummy_fb); + if (err) { + ALOGE("Failed to configure pipe with dummy fb (%s)", + strerror(err)); } } return err; @@ -1165,7 +1243,7 @@ int update_display(omap_hwc_device_t *ctx, int disp, if (!kdisp->con) return 0; - hwc_layer_1_t *target = comp->plane_info[0].layer; + hwc_layer_1_t *target = comp->plane_info[comp->ovl_indices[0]].layer; buffer_handle_t hnd; if (ctx->blitter && ctx->displays[disp]->composition.use_blitter) { @@ -1173,11 +1251,14 @@ int update_display(omap_hwc_device_t *ctx, int disp, } else { hnd = target->handle; for (i = 0; i < comp->used_ovls; i++) { - hwc_layer_1_t *layer = comp->plane_info[i].layer; - if (comp->plane_info[i].layer) { + hwc_layer_1_t *layer = comp->plane_info[comp->ovl_indices[i]].layer; + if (layer) { ret = fence_wait(layer->acquireFenceFd); - if (ret) + if (ret) { + ALOGE("Wait on acquirefence failed for overlay %d\n", i); + timeline_inc(&display->retire_sync); return -EBUSY; + } close(layer->acquireFenceFd); layer->acquireFenceFd = -1; } @@ -1232,25 +1313,35 @@ int update_display(omap_hwc_device_t *ctx, int disp, fence_fd = timeline_create_fence(&display->retire_sync, "hwc_retire_fence2", TWO_FLIP_EVENTS); +#ifndef HWC_USE_DRM_PAGEFLIP_MODE kdisp->atomic_req = drmModeAtomicAlloc(); +#endif ret = display_configure_pipes(display); +#ifndef HWC_USE_DRM_PAGEFLIP_MODE ret = drmModeAtomicCommit(ctx->drm_fd, kdisp->atomic_req, DRM_MODE_PAGE_FLIP_EVENT | DRM_MODE_ATOMIC_NONBLOCK, display); - +#else + ret = drmModePageFlip(ctx->drm_fd, kdisp->crtc_id, + comp->plane_info[comp->ovl_indices[0]].fb_info.fb_id, + DRM_MODE_PAGE_FLIP_EVENT, display); +#endif if (ret) { - ALOGE("cannot do atomic commit %d (%s): %d", + ALOGE("cannot do atomic commit/page flip %d (%s): %d", errno, strerror(errno), ret); pthread_mutex_unlock(&display->lock); close(fence_fd); fence_fd = -1; + timeline_inc(&display->retire_sync); goto fb_cleanup; } +#ifndef HWC_USE_DRM_PAGEFLIP_MODE drmModeAtomicFree(kdisp->atomic_req); +#endif for (i = 0; i < DSS_AVAILABLE_PIPES; i++) { - kdisp->fb_bufs[i].next = comp->plane_info[i].fb_info; + kdisp->fb_bufs[i].next = comp->plane_info[comp->ovl_indices[i]].fb_info; kdisp->fb_bufs[i].updated = true; } display->is_flip_pending = true; diff --git a/hwcomposer/display.h b/hwcomposer/display.h index 688642f..bfd52a7 100644 --- a/hwcomposer/display.h +++ b/hwcomposer/display.h @@ -140,7 +140,6 @@ typedef struct drm_plane_props drm_plane_props_t; struct composition { buffer_handle_t *buffers; - uint32_t num_buffers; /* # of buffers used in composition */ bool use_sgx; bool use_blitter; /* blitter usage flag */ @@ -148,13 +147,13 @@ struct composition { bool swap_rb; uint32_t tiler1d_slot_size; - uint32_t ovl_ix_base; /* index of first overlay used in composition */ uint32_t wanted_ovls; /* # of overlays required for current composition */ uint32_t avail_ovls; /* # of overlays available for current composition */ uint32_t scaling_ovls; /* # of overlays available with scaling caps */ uint32_t used_ovls; /* # of overlays used in composition */ drm_plane_props_t plane_info[DSS_AVAILABLE_PIPES]; + uint32_t ovl_indices[DSS_AVAILABLE_PIPES]; drmModePlane planes[4]; /* TODO: Rename to dss_pipeline_planes to */ /* from the above drm plane info distinguish */ @@ -179,6 +178,7 @@ typedef struct kms_display { drmModeFB fb; uint32_t plane_id; drmModeAtomicReqPtr atomic_req; + drm_fb_info_t dummy_fb; fb_buffers_t fb_bufs[DSS_AVAILABLE_PIPES]; int vsync_on; diff --git a/hwcomposer/hwc.c b/hwcomposer/hwc.c index 343778f..8016d36 100644 --- a/hwcomposer/hwc.c +++ b/hwcomposer/hwc.c @@ -105,7 +105,6 @@ static void reserve_overlays_for_displays(omap_hwc_device_t *hwc_dev) max_pipes -= 2; avail_gfx_pipes = 0; - primary_comp->ovl_ix_base = OMAP_DSS_GFX; primary_comp->wanted_ovls = max_pipes; primary_comp->avail_ovls = max_pipes; primary_comp->scaling_ovls = max_pipes - avail_gfx_pipes; @@ -114,7 +113,6 @@ static void reserve_overlays_for_displays(omap_hwc_device_t *hwc_dev) if (hdmi_display) { composition_t *hdmi_comp = &hdmi_display->composition; - hdmi_comp->ovl_ix_base = OMAP_DSS_VIDEO1; hdmi_comp->wanted_ovls = max_pipes; hdmi_comp->avail_ovls = 0; primary_comp->scaling_ovls = 0; @@ -162,7 +160,12 @@ static void hwc_check_dss_composition(omap_hwc_device_t *hwc_dev, int disp) hwc_layer_1_t *layer = NULL; uint32_t i, j; - if (disp || list->numHwLayers <= 2 || comp->use_blitter) +#ifdef HWC_USE_DRM_PAGEFLIP_MODE + /* DSS composition is supported only for atomic mode API usage */ + return; +#endif + + if (disp || list->numHwLayers == 1 || comp->use_blitter) return; if (!property_get_bool("persist.hwc.dss.comp", 1)) @@ -171,14 +174,15 @@ static void hwc_check_dss_composition(omap_hwc_device_t *hwc_dev, int disp) if (can_dss_render_all_layers(hwc_dev, disp)) { comp->use_dss = true; comp->use_sgx = false; + comp->used_ovls = 0; for (i = 0; i < list->numHwLayers - 1; i++) { hwc_layer_1_t *layer = &list->hwLayers[i]; layer->compositionType = HWC_OVERLAY; adjust_drm_plane_to_layer(layer, i, &comp->plane_info[i]); + comp->used_ovls++; + if (i) comp->avail_ovls--; } - comp->used_ovls += comp->avail_ovls; - comp->avail_ovls = 0; return; } @@ -229,10 +233,10 @@ static int hwc_prepare_for_display(omap_hwc_device_t *hwc_dev, int disp) composition_t *comp = &display->composition; uint32_t i = 0; - for (i = 0; i < DSS_AVAILABLE_PIPES; i++) + for (i = 0; i < DSS_AVAILABLE_PIPES; i++) { reset_drm_plane(&comp->plane_info[i]); - - comp->num_buffers = 0; + comp->ovl_indices[i] = i; + } /* Default composition policy */ comp->use_sgx = true; @@ -253,8 +257,15 @@ static int hwc_prepare_for_display(omap_hwc_device_t *hwc_dev, int disp) /* GFX pipe cannot handle NV12, swap out if layer[0] is NV12, * assuming second is non-NV12. FIXME */ - adjust_drm_plane_to_layer(&list->hwLayers[0], 0, &comp->plane_info[1]); - adjust_drm_plane_to_layer(&list->hwLayers[1], 1, &comp->plane_info[0]); + if (comp->used_ovls > 1) { + adjust_drm_plane_to_layer(&list->hwLayers[0], 0, &comp->plane_info[1]); + adjust_drm_plane_to_layer(&list->hwLayers[1], 1, &comp->plane_info[0]); + } else { + adjust_drm_plane_to_layer(&list->hwLayers[0], 1, &comp->plane_info[1]); + reset_drm_plane(&comp->plane_info[0]); + } + comp->ovl_indices[0] = 1; + comp->ovl_indices[1] = 0; } } @@ -342,6 +353,7 @@ static int hwc_set_for_display(omap_hwc_device_t *hwc_dev, int disp, hwc_display layer_statistics_t *layer_stats = &display->layer_stats; composition_t *comp = &display->composition; blit_device_t *blitter = hwc_dev->blitter; + hwc_layer_1_t *layer = NULL; uint32_t i = 0; int err = 0; @@ -360,7 +372,8 @@ static int hwc_set_for_display(omap_hwc_device_t *hwc_dev, int disp, hwc_display } list->retireFenceFd = -1; - if (!comp->plane_info[0].layer || !comp->plane_info[0].layer->handle) { + layer = comp->plane_info[comp->ovl_indices[0]].layer; + if (!layer || !layer->handle) { ALOGE("Got empty handle, nothing we can do here"); goto clear_acquire_fences; } @@ -868,6 +881,10 @@ static int hwc_device_open(const hw_module_t* module, const char* name, hw_devic hwc_dev->upscaled_nv12_limit = 2.; } +#ifdef HWC_USE_DRM_PAGEFLIP_MODE + ALOGI("Using older drm pageflip API to update display"); +#endif + hwc_dev->tiler1d_slot_size = 32*1024*1024; //32MB /* |