compositor-drm: move video to overlay plane

Upstream-Status: Inappropriate [i.MX-specific]

Signed-off-by: Haihua Hu <jared.hu@nxp.com>
diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index c4ad8f7..47f1412 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -2135,6 +2135,28 @@
 }
 #endif
 
+#ifdef HAVE_GBM_MODIFIERS
+static int
+drm_get_gbm_alignment(struct drm_fb *fb)
+{
+	int gbm_aligned = 1;
+
+	if (fb){
+		switch(fb->modifier) {
+#if defined(ENABLE_IMXGPU)
+			case DRM_FORMAT_MOD_VIVANTE_SUPER_TILED_FC:
+			case DRM_FORMAT_MOD_VIVANTE_SUPER_TILED:
+				gbm_aligned = 64;
+				break;
+#endif
+			default:
+				break;
+		}
+	}
+	return gbm_aligned;
+}
+#endif
+
 static void
 drm_output_render(struct drm_output_state *state, pixman_region32_t *damage)
 {
@@ -2151,15 +2173,26 @@
 						   output->scanout_plane);
 	if (scanout_state->fb)
 		return;
+	
+#ifdef HAVE_GBM_MODIFIERS
+	int gbm_aligned = drm_get_gbm_alignment (scanout_plane->state_cur->fb);
+#endif
 
 	if (!pixman_region32_not_empty(damage) &&
 	    scanout_plane->state_cur->fb &&
 	    (scanout_plane->state_cur->fb->type == BUFFER_GBM_SURFACE ||
 	     scanout_plane->state_cur->fb->type == BUFFER_PIXMAN_DUMB) &&
+#ifdef HAVE_GBM_MODIFIERS
+	    scanout_plane->state_cur->fb->width ==
+		ALIGNTO(output->base.current_mode->width, gbm_aligned) &&
+	    scanout_plane->state_cur->fb->height ==
+		ALIGNTO(output->base.current_mode->height, gbm_aligned)) {
+#else
 	    scanout_plane->state_cur->fb->width ==
 		output->base.current_mode->width &&
 	    scanout_plane->state_cur->fb->height ==
 		output->base.current_mode->height) {
+#endif
 		fb = drm_fb_ref(scanout_plane->state_cur->fb);
 	} else if (b->use_pixman) {
 		fb = drm_output_render_pixman(state, damage);
@@ -3480,8 +3513,14 @@
 			return NULL;
 		}
 
+#ifdef HAVE_GBM_MODIFIERS
+		int gbm_aligned = drm_get_gbm_alignment (scanout_fb);
+		if (scanout_fb->width != ALIGNTO(output_base->current_mode->width, gbm_aligned) ||
+		    scanout_fb->height != ALIGNTO(output_base->current_mode->height, gbm_aligned)) {
+#else
 		if (scanout_fb->width != output_base->current_mode->width ||
 		    scanout_fb->height != output_base->current_mode->height) {
+#endif
 			drm_output_state_free(state);
 			return NULL;
 		}
@@ -3512,6 +3551,7 @@
 		pixman_region32_t clipped_view;
 		bool totally_occluded = false;
 		bool overlay_occluded = false;
+		struct linux_dmabuf_buffer *dmabuf = NULL;
 
 		/* If this view doesn't touch our output at all, there's no
 		 * reason to do anything with it. */
@@ -3525,6 +3565,22 @@
 
 		if (!ev->surface->buffer_ref.buffer)
 			force_renderer = true;
+		else {
+			struct weston_buffer *buffer = ev->surface->buffer_ref.buffer;
+			dmabuf = linux_dmabuf_buffer_get(buffer->resource);
+			if (dmabuf) {
+				if (dmabuf->attributes.format == DRM_FORMAT_NV12
+					|| dmabuf->attributes.format == DRM_FORMAT_P010
+					|| dmabuf->attributes.format == DRM_FORMAT_YUYV) {
+					ps = drm_output_prepare_overlay_view(state, ev, mode);
+					if (ps)
+						goto next_view;
+					else
+						force_renderer = true;
+				} else
+					force_renderer = true;
+			}
+		}
 
 		/* Ignore views we know to be totally occluded. */
 		pixman_region32_init(&clipped_view);
@@ -3585,6 +3641,7 @@
 		if (!ps && !overlay_occluded && !force_renderer)
 			ps = drm_output_prepare_overlay_view(state, ev, mode);
 
+next_view:
 		if (ps) {
 			/* If we have been assigned to an overlay or scanout
 			 * plane, add this area to the occluded region, so