From 0606247b029fc74679fa88759abd106498e29480 Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Mon, 15 Aug 2022 10:45:55 +0800 Subject: [PATCH] ACRN:DM:VGPU: Calibrate the offset in dmabuf/pixman_image to display the scanout_window Sometimes the virtio_gpu in guest_vm doesn't pass the zero coord_x/y for the displayed framebuffer. In such case the offset should be calibrated for pixman_image/dmabuf so that it can display the image from the correct image. Tracked-On: #7988 Signed-off-by: Zhao Yakui Reviewed-by: Peng Sun --- devicemodel/hw/pci/virtio/virtio_gpu.c | 6 ++++++ devicemodel/hw/vdisplay_sdl.c | 2 +- devicemodel/include/vdisplay.h | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/devicemodel/hw/pci/virtio/virtio_gpu.c b/devicemodel/hw/pci/virtio/virtio_gpu.c index 8e79af25f..24d865a72 100644 --- a/devicemodel/hw/pci/virtio/virtio_gpu.c +++ b/devicemodel/hw/pci/virtio/virtio_gpu.c @@ -838,6 +838,7 @@ virtio_gpu_cmd_set_scanout(struct virtio_gpu_command *cmd) struct surface surf; struct virtio_gpu *gpu; struct virtio_gpu_scanout *gpu_scanout; + int bytes_pp; gpu = cmd->gpu; memcpy(&req, cmd->iov[0].iov_base, sizeof(req)); @@ -872,6 +873,7 @@ virtio_gpu_cmd_set_scanout(struct virtio_gpu_command *cmd) resp.type = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER; } else { virtio_gpu_update_scanout(gpu, req.scanout_id, req.resource_id, &req.r); + bytes_pp = PIXMAN_FORMAT_BPP(r2d->format) / 8; pixman_image_ref(r2d->image); surf.pixel = pixman_image_get_data(r2d->image); surf.x = req.r.x; @@ -881,6 +883,7 @@ virtio_gpu_cmd_set_scanout(struct virtio_gpu_command *cmd) surf.stride = pixman_image_get_stride(r2d->image); surf.surf_format = r2d->format; surf.surf_type = SURFACE_PIXMAN; + surf.pixel += bytes_pp * surf.x + surf.y * surf.stride; vdpy_surface_set(gpu->vdpy_handle, req.scanout_id, &surf); pixman_image_unref(r2d->image); resp.type = VIRTIO_GPU_RESP_OK_NODATA; @@ -1254,6 +1257,7 @@ virtio_gpu_cmd_set_scanout_blob(struct virtio_gpu_command *cmd) uint32_t drm_fourcc; struct virtio_gpu *gpu; struct virtio_gpu_scanout *gpu_scanout; + int bytes_pp; gpu = cmd->gpu; memset(&surf, 0, sizeof(surf)); @@ -1300,6 +1304,7 @@ virtio_gpu_cmd_set_scanout_blob(struct virtio_gpu_command *cmd) surf.stride = req.strides[0]; surf.dma_info.dmabuf_fd = r2d->dma_info->dmabuf_fd; surf.surf_type = SURFACE_DMABUF; + bytes_pp = 4; switch (req.format) { case VIRTIO_GPU_FORMAT_B8G8R8X8_UNORM: drm_fourcc = DRM_FORMAT_XRGB8888; @@ -1319,6 +1324,7 @@ virtio_gpu_cmd_set_scanout_blob(struct virtio_gpu_command *cmd) drm_fourcc = DRM_FORMAT_ARGB8888; break; } + surf.dma_info.dmabuf_offset = req.offsets[0] + bytes_pp * surf.x + surf.y * surf.stride; surf.dma_info.surf_fourcc = drm_fourcc; vdpy_surface_set(gpu->vdpy_handle, req.scanout_id, &surf); resp.type = VIRTIO_GPU_RESP_OK_NODATA; diff --git a/devicemodel/hw/vdisplay_sdl.c b/devicemodel/hw/vdisplay_sdl.c index 4cf19f985..16c9d59bb 100644 --- a/devicemodel/hw/vdisplay_sdl.c +++ b/devicemodel/hw/vdisplay_sdl.c @@ -700,7 +700,7 @@ vdpy_surface_set(int handle, int scanout_id, struct surface *surf) attrs[i++] = EGL_DMA_BUF_PLANE0_PITCH_EXT; attrs[i++] = surf->stride; attrs[i++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT; - attrs[i++] = 0; + attrs[i++] = surf->dma_info.dmabuf_offset; attrs[i++] = EGL_NONE; egl_img = gl_ops->eglCreateImageKHR(vdpy.eglDisplay, diff --git a/devicemodel/include/vdisplay.h b/devicemodel/include/vdisplay.h index ab15566d9..961d615bc 100644 --- a/devicemodel/include/vdisplay.h +++ b/devicemodel/include/vdisplay.h @@ -67,6 +67,7 @@ struct surface { struct { int dmabuf_fd; uint32_t surf_fourcc; + uint32_t dmabuf_offset; } dma_info; };