From nobody Thu Jul 3 15:56:49 2025 Delivered-To: importer2@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1621896478; cv=none; d=zohomail.com; s=zohoarc; b=KmMnOMYrK5CfSpc4a3WARmVozCkUnj5wxT2AXY76XGEbTlwK98Ml5bUVO+mvMKD5pdKCI2D+Vml2lzFVi0zRgJDKctVFTX3su7cVVkmTTkrqUO6SP2Lf4JqkpoQoieCU8C+SDphYr3nTQEQWMCr4iiMV5qK36pFIKW4nMv72sYs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1621896478; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=lBC9+HGk/PN47DgFmKzWXJ112QLeuRsL84KH8zVW1Zs=; b=XqLz+vcnJE+I4bEQ95ahRL+mW2EavrOU4AXUM2ekQWr9B2lxoA0OnlxYw6N0U5qGZ+bDgne+zU4mh/nUDcUL0GSwXNudSl2/ehL1s1n5zXz50GtIFzWeHTRVdt/vryRqJ86ns3baO8rJZtvdrgrOT3ipOr1+631rcKD12jR7r4Y= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1621896478937860.5393085033298; Mon, 24 May 2021 15:47:58 -0700 (PDT) Received: from localhost ([::1]:37676 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llJMb-0005Pv-VA for importer2@patchew.org; Mon, 24 May 2021 18:47:57 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:33472) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llJIM-0006ui-J7 for qemu-devel@nongnu.org; Mon, 24 May 2021 18:43:34 -0400 Received: from mga05.intel.com ([192.55.52.43]:11770) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llJIJ-0006mt-R4 for qemu-devel@nongnu.org; Mon, 24 May 2021 18:43:34 -0400 Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 May 2021 15:43:17 -0700 Received: from vkasired-desk2.fm.intel.com ([10.105.128.127]) by fmsmga001-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 May 2021 15:43:17 -0700 IronPort-SDR: rEmrgThHacCSk130mis1TckAhEECIO6Eyw2JTNKawF7rZBK/0IEuywuEJRl6SUlHLvgkG3gYY/ elOQb5BVeDww== X-IronPort-AV: E=McAfee;i="6200,9189,9994"; a="287620902" X-IronPort-AV: E=Sophos;i="5.82,327,1613462400"; d="scan'208";a="287620902" IronPort-SDR: LCJY2E/EXHtTKd4Y+cpvUP8KRtt8/PNy5h4Cyrux/qD+rCce68mPOhHRblywtnSzYkeSgonFBe 71Z65CtrZ/xg== X-IronPort-AV: E=Sophos;i="5.82,327,1613462400"; d="scan'208";a="546246753" From: Vivek Kasireddy To: qemu-devel@nongnu.org Subject: [PATCH v6 05/13] virtio-gpu: Refactor virtio_gpu_set_scanout Date: Mon, 24 May 2021 15:30:55 -0700 Message-Id: <20210524223103.922910-6-vivek.kasireddy@intel.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210524223103.922910-1-vivek.kasireddy@intel.com> References: <20210524223103.922910-1-vivek.kasireddy@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer2=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=192.55.52.43; envelope-from=vivek.kasireddy@intel.com; helo=mga05.intel.com X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Vivek Kasireddy , Gerd Hoffmann Errors-To: qemu-devel-bounces+importer2=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Store the meta-data associated with a FB in a new object (struct virtio_gpu_framebuffer) and pass the object to set_scanout. Also move code in set_scanout into a do_set_scanout function. This will be helpful when adding set_scanout_blob API. Based-on-patch-by: Gerd Hoffmann Cc: Gerd Hoffmann Signed-off-by: Vivek Kasireddy --- hw/display/virtio-gpu.c | 151 +++++++++++++++++++-------------- include/hw/virtio/virtio-gpu.h | 8 ++ 2 files changed, 95 insertions(+), 64 deletions(-) diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c index 7b5296f0d0..fdcedfc61e 100644 --- a/hw/display/virtio-gpu.c +++ b/hw/display/virtio-gpu.c @@ -500,95 +500,118 @@ static void virtio_unref_resource(pixman_image_t *im= age, void *data) pixman_image_unref(data); } =20 -static void virtio_gpu_set_scanout(VirtIOGPU *g, - struct virtio_gpu_ctrl_command *cmd) +static void virtio_gpu_do_set_scanout(VirtIOGPU *g, + uint32_t scanout_id, + struct virtio_gpu_framebuffer *fb, + struct virtio_gpu_simple_resource *r= es, + struct virtio_gpu_rect *r, + uint32_t *error) { - struct virtio_gpu_simple_resource *res, *ores; + struct virtio_gpu_simple_resource *ores; struct virtio_gpu_scanout *scanout; - pixman_format_code_t format; - uint32_t offset; - int bpp; - struct virtio_gpu_set_scanout ss; + uint8_t *data; =20 - VIRTIO_GPU_FILL_CMD(ss); - virtio_gpu_bswap_32(&ss, sizeof(ss)); - trace_virtio_gpu_cmd_set_scanout(ss.scanout_id, ss.resource_id, - ss.r.width, ss.r.height, ss.r.x, ss.r= .y); - - if (ss.scanout_id >=3D g->parent_obj.conf.max_outputs) { + if (scanout_id >=3D g->parent_obj.conf.max_outputs) { qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal scanout id specified %= d", - __func__, ss.scanout_id); - cmd->error =3D VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID; + __func__, scanout_id); + *error =3D VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID; return; } - - g->parent_obj.enable =3D 1; - if (ss.resource_id =3D=3D 0) { - virtio_gpu_disable_scanout(g, ss.scanout_id); - return; - } - - /* create a surface for this scanout */ - res =3D virtio_gpu_find_check_resource(g, ss.resource_id, true, - __func__, &cmd->error); - if (!res) { - return; - } - - if (ss.r.x > res->width || - ss.r.y > res->height || - ss.r.width < 16 || - ss.r.height < 16 || - ss.r.width > res->width || - ss.r.height > res->height || - ss.r.x + ss.r.width > res->width || - ss.r.y + ss.r.height > res->height) { + scanout =3D &g->parent_obj.scanout[scanout_id]; + + if (r->x > fb->width || + r->y > fb->height || + r->width < 16 || + r->height < 16 || + r->width > fb->width || + r->height > fb->height || + r->x + r->width > fb->width || + r->y + r->height > fb->height) { qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal scanout %d bounds for" - " resource %d, (%d,%d)+%d,%d vs %d %d\n", - __func__, ss.scanout_id, ss.resource_id, ss.r.x, ss.= r.y, - ss.r.width, ss.r.height, res->width, res->height); - cmd->error =3D VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER; + " resource %d, rect (%d,%d)+%d,%d, fb %d %d\n", + __func__, scanout_id, res->resource_id, + r->x, r->y, r->width, r->height, + fb->width, fb->height); + *error =3D VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER; return; } =20 - scanout =3D &g->parent_obj.scanout[ss.scanout_id]; + g->parent_obj.enable =3D 1; + data =3D (uint8_t *)pixman_image_get_data(res->image); =20 - format =3D pixman_image_get_format(res->image); - bpp =3D DIV_ROUND_UP(PIXMAN_FORMAT_BPP(format), 8); - offset =3D (ss.r.x * bpp) + ss.r.y * pixman_image_get_stride(res->imag= e); - if (!scanout->ds || surface_data(scanout->ds) - !=3D ((uint8_t *)pixman_image_get_data(res->image) + offset) || - scanout->width !=3D ss.r.width || - scanout->height !=3D ss.r.height) { + /* create a surface for this scanout */ + if (!scanout->ds || + surface_data(scanout->ds) !=3D data + fb->offset || + scanout->width !=3D r->width || + scanout->height !=3D r->height) { pixman_image_t *rect; - void *ptr =3D (uint8_t *)pixman_image_get_data(res->image) + offse= t; - rect =3D pixman_image_create_bits(format, ss.r.width, ss.r.height,= ptr, - pixman_image_get_stride(res->image= )); - pixman_image_ref(res->image); - pixman_image_set_destroy_function(rect, virtio_unref_resource, - res->image); + void *ptr =3D data + fb->offset; + rect =3D pixman_image_create_bits(fb->format, r->width, r->height, + ptr, fb->stride); + + if (res->image) { + pixman_image_ref(res->image); + pixman_image_set_destroy_function(rect, virtio_unref_resource, + res->image); + } + /* realloc the surface ptr */ scanout->ds =3D qemu_create_displaysurface_pixman(rect); if (!scanout->ds) { - cmd->error =3D VIRTIO_GPU_RESP_ERR_UNSPEC; + *error =3D VIRTIO_GPU_RESP_ERR_UNSPEC; return; } + pixman_image_unref(rect); - dpy_gfx_replace_surface(g->parent_obj.scanout[ss.scanout_id].con, + dpy_gfx_replace_surface(g->parent_obj.scanout[scanout_id].con, scanout->ds); } =20 ores =3D virtio_gpu_find_resource(g, scanout->resource_id); if (ores) { - ores->scanout_bitmask &=3D ~(1 << ss.scanout_id); + ores->scanout_bitmask &=3D ~(1 << scanout_id); + } + + res->scanout_bitmask |=3D (1 << scanout_id); + scanout->resource_id =3D res->resource_id; + scanout->x =3D r->x; + scanout->y =3D r->y; + scanout->width =3D r->width; + scanout->height =3D r->height; +} + +static void virtio_gpu_set_scanout(VirtIOGPU *g, + struct virtio_gpu_ctrl_command *cmd) +{ + struct virtio_gpu_simple_resource *res; + struct virtio_gpu_framebuffer fb =3D { 0 }; + struct virtio_gpu_set_scanout ss; + + VIRTIO_GPU_FILL_CMD(ss); + virtio_gpu_bswap_32(&ss, sizeof(ss)); + trace_virtio_gpu_cmd_set_scanout(ss.scanout_id, ss.resource_id, + ss.r.width, ss.r.height, ss.r.x, ss.r= .y); + + if (ss.resource_id =3D=3D 0) { + virtio_gpu_disable_scanout(g, ss.scanout_id); + return; } =20 - res->scanout_bitmask |=3D (1 << ss.scanout_id); - scanout->resource_id =3D ss.resource_id; - scanout->x =3D ss.r.x; - scanout->y =3D ss.r.y; - scanout->width =3D ss.r.width; - scanout->height =3D ss.r.height; + res =3D virtio_gpu_find_check_resource(g, ss.resource_id, true, + __func__, &cmd->error); + if (!res) { + return; + } + + fb.format =3D pixman_image_get_format(res->image); + fb.bytes_pp =3D DIV_ROUND_UP(PIXMAN_FORMAT_BPP(fb.format), 8); + fb.width =3D pixman_image_get_width(res->image); + fb.height =3D pixman_image_get_height(res->image); + fb.stride =3D pixman_image_get_stride(res->image); + fb.offset =3D ss.r.x * fb.bytes_pp + ss.r.y * fb.stride; + + virtio_gpu_do_set_scanout(g, ss.scanout_id, + &fb, res, &ss.r, &cmd->error); } =20 int virtio_gpu_create_mapping_iov(VirtIOGPU *g, diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h index 265b1c516c..b83a91a67f 100644 --- a/include/hw/virtio/virtio-gpu.h +++ b/include/hw/virtio/virtio-gpu.h @@ -59,6 +59,14 @@ struct virtio_gpu_simple_resource { QTAILQ_ENTRY(virtio_gpu_simple_resource) next; }; =20 +struct virtio_gpu_framebuffer { + pixman_format_code_t format; + uint32_t bytes_pp; + uint32_t width, height; + uint32_t stride; + uint32_t offset; +}; + struct virtio_gpu_scanout { QemuConsole *con; DisplaySurface *ds; --=20 2.30.2