From patchwork Fri Mar 12 10:00:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 12134163 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 31CFCC433DB for ; Fri, 12 Mar 2021 10:05:40 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B71D365004 for ; Fri, 12 Mar 2021 10:05:39 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org B71D365004 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:57636 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lKefq-0002eh-NJ for qemu-devel@archiver.kernel.org; Fri, 12 Mar 2021 05:05:38 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:34184) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lKebr-0006jF-AW for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:01:32 -0500 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:43977) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1lKebi-00029p-It for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:01:31 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1615543281; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=EX4SCqUu9TjjEb0u/oZndKEfA8JC/LvHoqNIFbvdD8A=; b=BNjYmCpwnFukoqv4c+iYmkvb75mtaR/ccBKpDQqEylqEqmtSGPKZUO9gVBbAUSRtHFqFQK ZpXVuwc6y6ww7GFhMgEx16nTL6ssJS0VswLK7GmKhi+1ibgnfNy+ljO7wrYDn7xPpnbgkv qhOiLxjednTqhXjAARL7seugJXABpUk= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-266-CSCwdUaPNGavKBTydbYUVA-1; Fri, 12 Mar 2021 05:01:20 -0500 X-MC-Unique: CSCwdUaPNGavKBTydbYUVA-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 25B5D8015BD for ; Fri, 12 Mar 2021 10:01:19 +0000 (UTC) Received: from localhost (unknown [10.36.110.50]) by smtp.corp.redhat.com (Postfix) with ESMTP id D7CCA196E3; Fri, 12 Mar 2021 10:01:17 +0000 (UTC) From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH 01/27] ui: fold qemu_alloc_display in only caller Date: Fri, 12 Mar 2021 14:00:42 +0400 Message-Id: <20210312100108.2706195-2-marcandre.lureau@redhat.com> In-Reply-To: <20210312100108.2706195-1-marcandre.lureau@redhat.com> References: <20210312100108.2706195-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=63.128.21.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -29 X-Spam_score: -3.0 X-Spam_bar: --- X-Spam_report: (-3.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.25, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, 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: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Gerd Hoffmann Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau A minor code simplification. Signed-off-by: Marc-André Lureau --- ui/console.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/ui/console.c b/ui/console.c index 171a7bf14b..bab32723b5 100644 --- a/ui/console.c +++ b/ui/console.c @@ -1386,26 +1386,18 @@ static QemuConsole *new_console(DisplayState *ds, console_type_t console_type, return s; } -static void qemu_alloc_display(DisplaySurface *surface, int width, int height) +DisplaySurface *qemu_create_displaysurface(int width, int height) { - qemu_pixman_image_unref(surface->image); - surface->image = NULL; + DisplaySurface *surface = g_new0(DisplaySurface, 1); + trace_displaysurface_create(surface, width, height); surface->format = PIXMAN_x8r8g8b8; surface->image = pixman_image_create_bits(surface->format, width, height, NULL, width * 4); assert(surface->image != NULL); - surface->flags = QEMU_ALLOCATED_FLAG; -} -DisplaySurface *qemu_create_displaysurface(int width, int height) -{ - DisplaySurface *surface = g_new0(DisplaySurface, 1); - - trace_displaysurface_create(surface, width, height); - qemu_alloc_display(surface, width, height); return surface; } From patchwork Fri Mar 12 10:00:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 12134175 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C6366C433DB for ; Fri, 12 Mar 2021 10:08:44 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 4D72564FB9 for ; Fri, 12 Mar 2021 10:08:44 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 4D72564FB9 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:41456 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lKeip-0007t0-Cg for qemu-devel@archiver.kernel.org; Fri, 12 Mar 2021 05:08:43 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:34228) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lKebw-0006kO-NG for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:01:36 -0500 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:21143) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1lKebq-0002CH-VC for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:01:36 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1615543288; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=anZGjpekYslS55upOI4Avz282/asVORYsyeL1008Bbg=; b=iEh0KjNcWOCIn4vaJi844PA39MK4jSmb2nSgKGtAi5xd+nhZT9RRYhaiMqcVFV5bPQ75EA qNP3wmcO3q6VM0r2DrxQMneof7DV/EX8qMpa2+M7I/9FLIzPrlptV9t5ZmtjwRvb79eV7p htbGTvsVtTn7N+YrjgOiCPNrqLq+Fh4= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-428-apTzP48zPGiiytaV92962w-1; Fri, 12 Mar 2021 05:01:26 -0500 X-MC-Unique: apTzP48zPGiiytaV92962w-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id E0BE983DD20 for ; Fri, 12 Mar 2021 10:01:25 +0000 (UTC) Received: from localhost (unknown [10.36.110.50]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8322B610A8; Fri, 12 Mar 2021 10:01:23 +0000 (UTC) From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH 02/27] vhost-user-gpu: glFlush before notifying clients Date: Fri, 12 Mar 2021 14:00:43 +0400 Message-Id: <20210312100108.2706195-3-marcandre.lureau@redhat.com> In-Reply-To: <20210312100108.2706195-1-marcandre.lureau@redhat.com> References: <20210312100108.2706195-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=63.128.21.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -29 X-Spam_score: -3.0 X-Spam_bar: --- X-Spam_report: (-3.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.25, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, 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: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Gerd Hoffmann Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau For similar reasons as commit 3af1671852 ("spice: flush on GL update before notifying client"), vhost-user-gpu must ensure the GL state is flushed before sharing its rendering result. Signed-off-by: Marc-André Lureau --- contrib/vhost-user-gpu/virgl.c | 3 +++ contrib/vhost-user-gpu/meson.build | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/contrib/vhost-user-gpu/virgl.c b/contrib/vhost-user-gpu/virgl.c index 8bb3c563d9..9e6660c7ab 100644 --- a/contrib/vhost-user-gpu/virgl.c +++ b/contrib/vhost-user-gpu/virgl.c @@ -16,6 +16,8 @@ #include #include "virgl.h" +#include + void vg_virgl_update_cursor_data(VuGpu *g, uint32_t resource_id, gpointer data) @@ -372,6 +374,7 @@ virgl_cmd_resource_flush(VuGpu *g, VUGPU_FILL_CMD(rf); + glFlush(); if (!rf.resource_id) { g_debug("bad resource id for flush..?"); return; diff --git a/contrib/vhost-user-gpu/meson.build b/contrib/vhost-user-gpu/meson.build index 2fc2320b52..0ce1515a10 100644 --- a/contrib/vhost-user-gpu/meson.build +++ b/contrib/vhost-user-gpu/meson.build @@ -2,7 +2,7 @@ if 'CONFIG_TOOLS' in config_host and 'CONFIG_VIRGL' in config_host \ and 'CONFIG_GBM' in config_host and 'CONFIG_LINUX' in config_host \ and pixman.found() executable('vhost-user-gpu', files('vhost-user-gpu.c', 'virgl.c', 'vugbm.c'), - dependencies: [qemuutil, pixman, gbm, virgl, vhost_user], + dependencies: [qemuutil, pixman, gbm, virgl, vhost_user, opengl], install: true, install_dir: get_option('libexecdir')) From patchwork Fri Mar 12 10:00:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 12134173 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C1BF0C433DB for ; Fri, 12 Mar 2021 10:07:47 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7B57F6500F for ; Fri, 12 Mar 2021 10:07:47 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 7B57F6500F Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:37848 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lKehu-0006MB-JF for qemu-devel@archiver.kernel.org; Fri, 12 Mar 2021 05:07:46 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:34242) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lKeby-0006nO-B0 for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:01:38 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:52605) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1lKebw-0002IY-ED for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:01:38 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1615543295; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Dfy+XpSJ2UwD5uiWvJktRkJ4rAc79gIr7V3kV7OpfsE=; b=WgwDuDBN3en3HS224ffFeqEMe1vy17R1u6ILnPYwweWiDjZTrYetulSPEaqAbjcuIt5Vzi YujiyilFhY9iaT21ZpeJnLgT+CSIBpwB55qosSLzIG936vsYgpDWaVaQjrCvD38pLmSRLs 1p1L8PmyXJ+6IH0EbaRO5XH7HR/AZDs= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-24-u0lBUwyrPOaW_TntfavkeA-1; Fri, 12 Mar 2021 05:01:33 -0500 X-MC-Unique: u0lBUwyrPOaW_TntfavkeA-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 58EF619200D3 for ; Fri, 12 Mar 2021 10:01:32 +0000 (UTC) Received: from localhost (unknown [10.36.110.50]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9F2B7610A8; Fri, 12 Mar 2021 10:01:30 +0000 (UTC) From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH 03/27] vhost-user-gpu: fix vugbm_device_init fallback Date: Fri, 12 Mar 2021 14:00:44 +0400 Message-Id: <20210312100108.2706195-4-marcandre.lureau@redhat.com> In-Reply-To: <20210312100108.2706195-1-marcandre.lureau@redhat.com> References: <20210312100108.2706195-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=170.10.133.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -29 X-Spam_score: -3.0 X-Spam_bar: --- X-Spam_report: (-3.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.25, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, 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: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Gerd Hoffmann Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau vugbm implements GBM device wrapping, udmabuf and memory fallback. However, the fallback/detection logic is flawed, as if "/dev/udmabuf" failed to be opened, it will not initialize vugbm and crash later. Rework the vugbm_device_init() logic to initialize correctly in all cases. Signed-off-by: Marc-André Lureau --- contrib/vhost-user-gpu/vugbm.h | 2 +- contrib/vhost-user-gpu/vhost-user-gpu.c | 6 +--- contrib/vhost-user-gpu/vugbm.c | 44 +++++++++++-------------- 3 files changed, 22 insertions(+), 30 deletions(-) diff --git a/contrib/vhost-user-gpu/vugbm.h b/contrib/vhost-user-gpu/vugbm.h index 66f1520764..82bc4934e1 100644 --- a/contrib/vhost-user-gpu/vugbm.h +++ b/contrib/vhost-user-gpu/vugbm.h @@ -54,7 +54,7 @@ struct vugbm_buffer { uint32_t format; }; -bool vugbm_device_init(struct vugbm_device *dev, int fd); +void vugbm_device_init(struct vugbm_device *dev, int fd); void vugbm_device_destroy(struct vugbm_device *dev); bool vugbm_buffer_create(struct vugbm_buffer *buffer, struct vugbm_device *dev, diff --git a/contrib/vhost-user-gpu/vhost-user-gpu.c b/contrib/vhost-user-gpu/vhost-user-gpu.c index b27990ffdb..ef40fbccbb 100644 --- a/contrib/vhost-user-gpu/vhost-user-gpu.c +++ b/contrib/vhost-user-gpu/vhost-user-gpu.c @@ -1186,11 +1186,7 @@ main(int argc, char *argv[]) exit(EXIT_FAILURE); } - if (g.drm_rnode_fd >= 0) { - if (!vugbm_device_init(&g.gdev, g.drm_rnode_fd)) { - g_warning("Failed to init DRM device, using fallback path"); - } - } + vugbm_device_init(&g.gdev, g.drm_rnode_fd); if ((!!opt_socket_path + (opt_fdnum != -1)) != 1) { g_printerr("Please specify either --fd or --socket-path\n"); diff --git a/contrib/vhost-user-gpu/vugbm.c b/contrib/vhost-user-gpu/vugbm.c index f5304ada2f..fb15d0372c 100644 --- a/contrib/vhost-user-gpu/vugbm.c +++ b/contrib/vhost-user-gpu/vugbm.c @@ -199,55 +199,51 @@ vugbm_device_destroy(struct vugbm_device *dev) dev->device_destroy(dev); } -bool +void vugbm_device_init(struct vugbm_device *dev, int fd) { - dev->fd = fd; + assert(!dev->inited); #ifdef CONFIG_GBM - dev->dev = gbm_create_device(fd); -#endif - - if (0) { - /* nothing */ + if (fd >= 0) { + dev->dev = gbm_create_device(fd); } -#ifdef CONFIG_GBM - else if (dev->dev != NULL) { + if (dev->dev != NULL) { + dev->fd = fd; dev->alloc_bo = alloc_bo; dev->free_bo = free_bo; dev->get_fd = get_fd; dev->map_bo = map_bo; dev->unmap_bo = unmap_bo; dev->device_destroy = device_destroy; + dev->inited = true; } #endif #ifdef CONFIG_MEMFD - else if (g_file_test("/dev/udmabuf", G_FILE_TEST_EXISTS)) { + if (!dev->inited && g_file_test("/dev/udmabuf", G_FILE_TEST_EXISTS)) { dev->fd = open("/dev/udmabuf", O_RDWR); - if (dev->fd < 0) { - return false; + if (dev->fd >= 0) { + g_debug("Using experimental udmabuf backend"); + dev->alloc_bo = udmabuf_alloc_bo; + dev->free_bo = udmabuf_free_bo; + dev->get_fd = udmabuf_get_fd; + dev->map_bo = udmabuf_map_bo; + dev->unmap_bo = udmabuf_unmap_bo; + dev->device_destroy = udmabuf_device_destroy; + dev->inited = true; } - g_debug("Using experimental udmabuf backend"); - dev->alloc_bo = udmabuf_alloc_bo; - dev->free_bo = udmabuf_free_bo; - dev->get_fd = udmabuf_get_fd; - dev->map_bo = udmabuf_map_bo; - dev->unmap_bo = udmabuf_unmap_bo; - dev->device_destroy = udmabuf_device_destroy; } #endif - else { + if (!dev->inited) { g_debug("Using mem fallback"); dev->alloc_bo = mem_alloc_bo; dev->free_bo = mem_free_bo; dev->map_bo = mem_map_bo; dev->unmap_bo = mem_unmap_bo; dev->device_destroy = mem_device_destroy; - return false; + dev->inited = true; } - - dev->inited = true; - return true; + assert(dev->inited); } static bool From patchwork Fri Mar 12 10:00:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 12134161 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 80B2CC433DB for ; Fri, 12 Mar 2021 10:05:11 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 28F5765004 for ; Fri, 12 Mar 2021 10:05:11 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 28F5765004 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:56074 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lKefO-0001z1-8q for qemu-devel@archiver.kernel.org; Fri, 12 Mar 2021 05:05:10 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:34290) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lKecE-0006rA-SE for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:01:54 -0500 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:49237) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1lKec8-0002MA-IV for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:01:50 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1615543307; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=/7TfOlwtk+oXkEHe++07r6GbU+hgq4A9HJpOV3lez7c=; b=epLedIfmJDy7cwz89hLqG5+NVhETxfq7Cqo/kUuB09Okyy81F+TMsclkMzInaSkaWf9ykz ObPUp5NlqK6mXImnXb6EbPE3Ari+BBqVgtutV92lJKRKCSiZMb5RzhTmBIdnBzx2HTYxsK MgmyJoC61kuKhdDOHV3OM+5HmBboXXQ= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-597-gIMxVuK-MG2A-3edA6wfWg-1; Fri, 12 Mar 2021 05:01:45 -0500 X-MC-Unique: gIMxVuK-MG2A-3edA6wfWg-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 7741183DD23 for ; Fri, 12 Mar 2021 10:01:44 +0000 (UTC) Received: from localhost (unknown [10.36.110.50]) by smtp.corp.redhat.com (Postfix) with ESMTP id 18DA61969E; Fri, 12 Mar 2021 10:01:36 +0000 (UTC) From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH 04/27] vhost-user-gpu: fix cursor move/update Date: Fri, 12 Mar 2021 14:00:45 +0400 Message-Id: <20210312100108.2706195-5-marcandre.lureau@redhat.com> In-Reply-To: <20210312100108.2706195-1-marcandre.lureau@redhat.com> References: <20210312100108.2706195-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=216.205.24.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -29 X-Spam_score: -3.0 X-Spam_bar: --- X-Spam_report: (-3.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.25, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, 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: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Gerd Hoffmann Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau "move" is incorrectly initialized. Fix it by using a switch statement and also treating unknown commands with a fallback. Signed-off-by: Marc-André Lureau --- contrib/vhost-user-gpu/vhost-user-gpu.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/contrib/vhost-user-gpu/vhost-user-gpu.c b/contrib/vhost-user-gpu/vhost-user-gpu.c index ef40fbccbb..f73f292c9f 100644 --- a/contrib/vhost-user-gpu/vhost-user-gpu.c +++ b/contrib/vhost-user-gpu/vhost-user-gpu.c @@ -892,11 +892,8 @@ update_cursor_data_simple(VuGpu *g, uint32_t resource_id, gpointer data) static void vg_process_cursor_cmd(VuGpu *g, struct virtio_gpu_update_cursor *cursor) { - bool move = cursor->hdr.type != VIRTIO_GPU_CMD_MOVE_CURSOR; - - g_debug("%s move:%d\n", G_STRFUNC, move); - - if (move) { + switch (cursor->hdr.type) { + case VIRTIO_GPU_CMD_MOVE_CURSOR: { VhostUserGpuMsg msg = { .request = cursor->resource_id ? VHOST_USER_GPU_CURSOR_POS : VHOST_USER_GPU_CURSOR_POS_HIDE, @@ -907,8 +904,11 @@ vg_process_cursor_cmd(VuGpu *g, struct virtio_gpu_update_cursor *cursor) .y = cursor->pos.y, } }; + g_debug("%s: move", G_STRFUNC); vg_send_msg(g, &msg, -1); - } else { + break; + } + case VIRTIO_GPU_CMD_UPDATE_CURSOR: { VhostUserGpuMsg msg = { .request = VHOST_USER_GPU_CURSOR_UPDATE, .size = sizeof(VhostUserGpuCursorUpdate), @@ -922,6 +922,7 @@ vg_process_cursor_cmd(VuGpu *g, struct virtio_gpu_update_cursor *cursor) .hot_y = cursor->hot_y, } }; + g_debug("%s: update", G_STRFUNC); if (g->virgl) { vg_virgl_update_cursor_data(g, cursor->resource_id, msg.payload.cursor_update.data); @@ -930,6 +931,11 @@ vg_process_cursor_cmd(VuGpu *g, struct virtio_gpu_update_cursor *cursor) msg.payload.cursor_update.data); } vg_send_msg(g, &msg, -1); + break; + } + default: + g_debug("%s: unknown cmd %d", G_STRFUNC, cursor->hdr.type); + break; } } From patchwork Fri Mar 12 10:00:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 12134183 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D5544C433E0 for ; Fri, 12 Mar 2021 10:10:59 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7154964FD6 for ; Fri, 12 Mar 2021 10:10:59 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 7154964FD6 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:49752 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lKel0-0002tB-AN for qemu-devel@archiver.kernel.org; Fri, 12 Mar 2021 05:10:58 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:34334) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lKecN-0006wk-CK for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:02:04 -0500 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:55797) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1lKecJ-0002OW-Kq for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:02:03 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1615543318; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=s72+FnV7ci5SGKLY9sLo0/QMvHq/wCtUPb4EGHuCu3M=; b=Dy6RPL0hHcCbSTz0J8j0ozxw+iM+TILB7xJv1c5pJBWd2F9PLhqhGleMDO3gE/2D1K8dAP NpthgxmaBsLjfFiahcdpHesq7q11udQXtiDFRfsspOjF55lpc38tLgEUYNjMIn1LMKezlB SA0Ku4ZFFiQZNqtRe2tcfoLVxxTNC1U= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-497-1EkBv_IIPFu3DIgK-z1D9A-1; Fri, 12 Mar 2021 05:01:56 -0500 X-MC-Unique: 1EkBv_IIPFu3DIgK-z1D9A-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 93FF5107ACCD for ; Fri, 12 Mar 2021 10:01:55 +0000 (UTC) Received: from localhost (unknown [10.36.110.50]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9963110016FD; Fri, 12 Mar 2021 10:01:48 +0000 (UTC) From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH 05/27] ui: factor out qemu_console_set_display_gl_ctx() Date: Fri, 12 Mar 2021 14:00:46 +0400 Message-Id: <20210312100108.2706195-6-marcandre.lureau@redhat.com> In-Reply-To: <20210312100108.2706195-1-marcandre.lureau@redhat.com> References: <20210312100108.2706195-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=216.205.24.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -29 X-Spam_score: -3.0 X-Spam_bar: --- X-Spam_report: (-3.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.25, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, 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: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Gerd Hoffmann Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau The next patch will make use of this function to dissociate DisplayChangeListener from GL context. Signed-off-by: Marc-André Lureau Reviewed-by: Philippe Mathieu-Daudé --- include/ui/console.h | 2 ++ ui/console.c | 21 +++++++++++++-------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/include/ui/console.h b/include/ui/console.h index c960b7066c..9391fb052b 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -413,6 +413,8 @@ void graphic_hw_gl_flushed(QemuConsole *con); void qemu_console_early_init(void); +void qemu_console_set_display_gl_ctx(QemuConsole *con, DisplayChangeListener *dcl); + QemuConsole *qemu_console_lookup_by_index(unsigned int index); QemuConsole *qemu_console_lookup_by_device(DeviceState *dev, uint32_t head); QemuConsole *qemu_console_lookup_by_device_name(const char *device_id, diff --git a/ui/console.c b/ui/console.c index bab32723b5..83475bd8c3 100644 --- a/ui/console.c +++ b/ui/console.c @@ -1502,6 +1502,18 @@ static bool dpy_compatible_with(QemuConsole *con, return true; } +void qemu_console_set_display_gl_ctx(QemuConsole *con, DisplayChangeListener *dcl) +{ + /* display has opengl support */ + assert(dcl->con); + if (dcl->con->gl) { + fprintf(stderr, "can't register two opengl displays (%s, %s)\n", + dcl->ops->dpy_name, dcl->con->gl->ops->dpy_name); + exit(1); + } + dcl->con->gl = dcl; +} + void register_displaychangelistener(DisplayChangeListener *dcl) { static const char nodev[] = @@ -1513,14 +1525,7 @@ void register_displaychangelistener(DisplayChangeListener *dcl) assert(!dcl->ds); if (dcl->ops->dpy_gl_ctx_create) { - /* display has opengl support */ - assert(dcl->con); - if (dcl->con->gl) { - fprintf(stderr, "can't register two opengl displays (%s, %s)\n", - dcl->ops->dpy_name, dcl->con->gl->ops->dpy_name); - exit(1); - } - dcl->con->gl = dcl; + qemu_console_set_display_gl_ctx(dcl->con, dcl); } if (dcl->con && !dpy_compatible_with(dcl->con, dcl, &err)) { From patchwork Fri Mar 12 10:00:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 12134169 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AAB63C43381 for ; Fri, 12 Mar 2021 10:07:26 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 5E9BF6500D for ; Fri, 12 Mar 2021 10:07:26 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5E9BF6500D Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:35940 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lKehZ-0005YU-GI for qemu-devel@archiver.kernel.org; Fri, 12 Mar 2021 05:07:25 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:34400) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lKecZ-0007Bu-Bt for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:02:15 -0500 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:22934) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1lKecW-0002Vg-Cj for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:02:15 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1615543330; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=3ZX8ydjlmAN6znczBh8iFPRumuy9vxrO2la01caU/Ek=; b=ZhPVsjsWAk/3hOlhUCaBNKzn8B3/ruHB3MVf0sBCUGY+dKpbRjKJBVHCNKU++6z3u5qYWk t0yjGC8KsrtFBfBgl4bn++12htrBWVi8/QjNrf6Xd/kuAlNNrDY7yApvnhjpMy/t7RExaA 6YAG4ORJ2WzpkeSizn788TGzKkUA150= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-510-6LekOhJpP1-xJgT6iH7TAg-1; Fri, 12 Mar 2021 05:02:08 -0500 X-MC-Unique: 6LekOhJpP1-xJgT6iH7TAg-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id A5582E5761 for ; Fri, 12 Mar 2021 10:02:07 +0000 (UTC) Received: from localhost (unknown [10.36.110.50]) by smtp.corp.redhat.com (Postfix) with ESMTP id C68335D6BA; Fri, 12 Mar 2021 10:01:59 +0000 (UTC) From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH 06/27] ui: associate GL context outside of display listener registration Date: Fri, 12 Mar 2021 14:00:47 +0400 Message-Id: <20210312100108.2706195-7-marcandre.lureau@redhat.com> In-Reply-To: <20210312100108.2706195-1-marcandre.lureau@redhat.com> References: <20210312100108.2706195-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=63.128.21.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -29 X-Spam_score: -3.0 X-Spam_bar: --- X-Spam_report: (-3.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.25, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, 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: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Gerd Hoffmann Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau Signed-off-by: Marc-André Lureau --- ui/console.c | 7 +++++-- ui/egl-headless.c | 1 + ui/gtk.c | 3 +++ ui/sdl2.c | 3 +++ ui/spice-display.c | 3 +++ 5 files changed, 15 insertions(+), 2 deletions(-) diff --git a/ui/console.c b/ui/console.c index 83475bd8c3..53eba2019e 100644 --- a/ui/console.c +++ b/ui/console.c @@ -1524,8 +1524,11 @@ void register_displaychangelistener(DisplayChangeListener *dcl) assert(!dcl->ds); - if (dcl->ops->dpy_gl_ctx_create) { - qemu_console_set_display_gl_ctx(dcl->con, dcl); + if (dcl->con && dcl->con->gl && + dcl->con->gl != dcl) { + error_report("Display %s is incompatible with the GL context", + dcl->ops->dpy_name); + exit(1); } if (dcl->con && !dpy_compatible_with(dcl->con, dcl, &err)) { diff --git a/ui/egl-headless.c b/ui/egl-headless.c index da377a74af..773520bc17 100644 --- a/ui/egl-headless.c +++ b/ui/egl-headless.c @@ -197,6 +197,7 @@ static void egl_headless_init(DisplayState *ds, DisplayOptions *opts) edpy->dcl.con = con; edpy->dcl.ops = &egl_ops; edpy->gls = qemu_gl_init_shader(); + qemu_console_set_display_gl_ctx(con, &edpy->dcl); register_displaychangelistener(&edpy->dcl); } } diff --git a/ui/gtk.c b/ui/gtk.c index 3edaf041de..d8b3784bf0 100644 --- a/ui/gtk.c +++ b/ui/gtk.c @@ -2082,6 +2082,9 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, VirtualConsole *vc, vc->gfx.kbd = qkbd_state_init(con); vc->gfx.dcl.con = con; + if (display_opengl) { + qemu_console_set_display_gl_ctx(con, &vc->gfx.dcl); + } register_displaychangelistener(&vc->gfx.dcl); gd_connect_vc_gfx_signals(vc); diff --git a/ui/sdl2.c b/ui/sdl2.c index a203cb0239..0593a333f5 100644 --- a/ui/sdl2.c +++ b/ui/sdl2.c @@ -863,6 +863,9 @@ static void sdl2_display_init(DisplayState *ds, DisplayOptions *o) #endif sdl2_console[i].dcl.con = con; sdl2_console[i].kbd = qkbd_state_init(con); + if (display_opengl) { + qemu_console_set_display_gl_ctx(con, &sdl2_console[i].dcl); + } register_displaychangelistener(&sdl2_console[i].dcl); #if defined(SDL_VIDEO_DRIVER_WINDOWS) || defined(SDL_VIDEO_DRIVER_X11) diff --git a/ui/spice-display.c b/ui/spice-display.c index d22781a23d..f637fd1bc6 100644 --- a/ui/spice-display.c +++ b/ui/spice-display.c @@ -1152,6 +1152,9 @@ static void qemu_spice_display_init_one(QemuConsole *con) qemu_spice_create_host_memslot(ssd); + if (spice_opengl) { + qemu_console_set_display_gl_ctx(con, &ssd->dcl); + } register_displaychangelistener(&ssd->dcl); } From patchwork Fri Mar 12 10:00:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 12134181 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A1034C433DB for ; Fri, 12 Mar 2021 10:09:50 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 5ED4464FB9 for ; Fri, 12 Mar 2021 10:09:50 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5ED4464FB9 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:46196 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lKejt-0001Oz-Bv for qemu-devel@archiver.kernel.org; Fri, 12 Mar 2021 05:09:49 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:34490) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lKeci-0007Y5-Gj for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:02:24 -0500 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:27584) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1lKecg-0002cf-S5 for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:02:24 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1615543342; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Q0/It68BtTor5WmZUIcCjF1/wNNhCAIm49SImi80Xr0=; b=OvrG33DNMONx6F3HlWVrNSAtkH4PfsppkoXi792I8uJ4Xz7z29ZXO10Jzuq1QBfSMz43EU J0BbJklJmyJlI4QAb1zwjFAHfvl8NzW0T1C3F2qKYdiSwLtZjbdMSEbJo5j7PXO/WYvZ2x cI/Pp4zSKDqGNjurJ8lbOuN0SWD3WeU= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-391-b7rL-K-mM6a8iSpNwF8xew-1; Fri, 12 Mar 2021 05:02:20 -0500 X-MC-Unique: b7rL-K-mM6a8iSpNwF8xew-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 33CD983DD20 for ; Fri, 12 Mar 2021 10:02:19 +0000 (UTC) Received: from localhost (unknown [10.36.110.50]) by smtp.corp.redhat.com (Postfix) with ESMTP id EB1D01037EBB; Fri, 12 Mar 2021 10:02:11 +0000 (UTC) From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH 07/27] ui: make gl_block use a counter Date: Fri, 12 Mar 2021 14:00:48 +0400 Message-Id: <20210312100108.2706195-8-marcandre.lureau@redhat.com> In-Reply-To: <20210312100108.2706195-1-marcandre.lureau@redhat.com> References: <20210312100108.2706195-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=216.205.24.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -29 X-Spam_score: -3.0 X-Spam_bar: --- X-Spam_report: (-3.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.25, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, 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: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Gerd Hoffmann Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau Track multiple callers blocking requests. Signed-off-by: Marc-André Lureau --- ui/console.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/ui/console.c b/ui/console.c index 53eba2019e..fedb9d8b13 100644 --- a/ui/console.c +++ b/ui/console.c @@ -128,7 +128,7 @@ struct QemuConsole { DisplaySurface *surface; int dcls; DisplayChangeListener *gl; - bool gl_block; + int gl_block; int window_id; /* Graphic console state. */ @@ -288,10 +288,19 @@ void graphic_hw_gl_block(QemuConsole *con, bool block) { assert(con != NULL); - con->gl_block = block; - if (con->hw_ops->gl_block) { - con->hw_ops->gl_block(con->hw, block); + if (block) { + con->gl_block++; + } else { + con->gl_block--; + } + assert(con->gl_block >= 0); + if (!con->hw_ops->gl_block) { + return; + } + if ((block && con->gl_block != 1) || (!block && con->gl_block != 0)) { + return; } + con->hw_ops->gl_block(con->hw, block); } void graphic_hw_gl_flushed(QemuConsole *con) From patchwork Fri Mar 12 10:00:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 12134171 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 197D9C433DB for ; Fri, 12 Mar 2021 10:07:32 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B927365002 for ; Fri, 12 Mar 2021 10:07:31 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org B927365002 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:36440 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lKehe-0005my-Ro for qemu-devel@archiver.kernel.org; Fri, 12 Mar 2021 05:07:30 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:34534) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lKeco-0007gF-M7 for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:02:31 -0500 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:32307) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1lKecm-0002g6-E0 for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:02:30 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1615543347; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=snAAmm/PgOxqi8o/tLYKU78db/Bu2vNj/3kOO/Kl8oU=; b=Qb9rKxvoxXmWhERFwJ7DsLsXOmvZhr/sTJwFi13e6dlx7cJvjWfrnCwpLPIunF8+6nvFRa 1ueApaabNM+2a/97K0AOd1GdluqYJKRWacfMFiGY/ZBKT/Kgp9GCLpEgqsxUl9RLO3R5Mg ThpXM/jwRHLbvlQYl1mzVsRerz+SCcc= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-580-njH0_VwNPGqfkxulignLlw-1; Fri, 12 Mar 2021 05:02:26 -0500 X-MC-Unique: njH0_VwNPGqfkxulignLlw-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 5EA13E5760 for ; Fri, 12 Mar 2021 10:02:25 +0000 (UTC) Received: from localhost (unknown [10.36.110.50]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3A11F10016FD; Fri, 12 Mar 2021 10:02:23 +0000 (UTC) From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH 08/27] ui: add a gl-unblock warning timer Date: Fri, 12 Mar 2021 14:00:49 +0400 Message-Id: <20210312100108.2706195-9-marcandre.lureau@redhat.com> In-Reply-To: <20210312100108.2706195-1-marcandre.lureau@redhat.com> References: <20210312100108.2706195-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=63.128.21.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -29 X-Spam_score: -3.0 X-Spam_bar: --- X-Spam_report: (-3.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.25, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, 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: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Gerd Hoffmann Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau Similar to the one that exists for Spice, so we can investigate if something is locked. Signed-off-by: Marc-André Lureau --- ui/console.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/ui/console.c b/ui/console.c index fedb9d8b13..808f82fa64 100644 --- a/ui/console.c +++ b/ui/console.c @@ -129,6 +129,7 @@ struct QemuConsole { int dcls; DisplayChangeListener *gl; int gl_block; + QEMUTimer *gl_unblock_timer; int window_id; /* Graphic console state. */ @@ -284,8 +285,14 @@ void graphic_hw_update(QemuConsole *con) } } +static void graphic_hw_gl_unblock_timer(void *opaque) +{ + warn_report("console: no gl-unblock within one second"); +} + void graphic_hw_gl_block(QemuConsole *con, bool block) { + uint64_t timeout; assert(con != NULL); if (block) { @@ -301,6 +308,14 @@ void graphic_hw_gl_block(QemuConsole *con, bool block) return; } con->hw_ops->gl_block(con->hw, block); + + if (block) { + timeout = qemu_clock_get_ms(QEMU_CLOCK_REALTIME); + timeout += 1000; /* one sec */ + timer_mod(con->gl_unblock_timer, timeout); + } else { + timer_del(con->gl_unblock_timer); + } } void graphic_hw_gl_flushed(QemuConsole *con) @@ -2025,6 +2040,8 @@ QemuConsole *graphic_console_init(DeviceState *dev, uint32_t head, surface = qemu_create_placeholder_surface(width, height, noinit); dpy_gfx_replace_surface(s, surface); + s->gl_unblock_timer = timer_new_ms(QEMU_CLOCK_REALTIME, + graphic_hw_gl_unblock_timer, s); return s; } From patchwork Fri Mar 12 10:00:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 12134193 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 220C6C433E0 for ; Fri, 12 Mar 2021 10:14:24 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A760064FC9 for ; Fri, 12 Mar 2021 10:14:23 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A760064FC9 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:59528 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lKeoI-000782-Jc for qemu-devel@archiver.kernel.org; Fri, 12 Mar 2021 05:14:22 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:34580) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lKed3-0007p9-IG for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:02:45 -0500 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:60578) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1lKed1-0002mb-FI for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:02:45 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1615543362; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=6XQtA/7VxM2SGRl2uQMaUGl4+XSYoSfwJPVEkf1MQdA=; b=IsWnDWZdZub38s8mEZwCW8DQN6MWCHzh7DKQ7CWcijh1VUmGNXUOmVKdqyR1jNuK+hpt6P XNvqHaU7300cIkJ3Q4ouAVT+HtwD79bSj7N0TziFrPr8bREoZbQTDVXqkomhPQBHmL9ZW+ lDfJNbPgwud9z7yGWbgt6IAHcATmjUc= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-173-ZNzy_tHFPOq_PimiJM5otA-1; Fri, 12 Mar 2021 05:02:40 -0500 X-MC-Unique: ZNzy_tHFPOq_PimiJM5otA-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id CC020800D55 for ; Fri, 12 Mar 2021 10:02:37 +0000 (UTC) Received: from localhost (unknown [10.36.110.50]) by smtp.corp.redhat.com (Postfix) with ESMTP id AF7F75C1C5; Fri, 12 Mar 2021 10:02:29 +0000 (UTC) From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH 09/27] ui: simplify gl unblock & flush Date: Fri, 12 Mar 2021 14:00:50 +0400 Message-Id: <20210312100108.2706195-10-marcandre.lureau@redhat.com> In-Reply-To: <20210312100108.2706195-1-marcandre.lureau@redhat.com> References: <20210312100108.2706195-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=216.205.24.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -29 X-Spam_score: -3.0 X-Spam_bar: --- X-Spam_report: (-3.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.25, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, 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: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Gerd Hoffmann Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau GraphicHw.gl_flushed was introduced to notify the device (vhost-user-gpu) that the GL resources (the display scanout) are no longer needed. It was decoupled from QEMU own gl-blocking mechanism, but that difference isn't really helping. Instead, we can reuse QEMU gl-blocking and notify virtio_gpu_gl_flueshd() when unblocking (to unlock vhost-user-gpu). An extra block/unblock is added arount dpy_gl_update() so existing backends that don't block will have the flush event handled. It will also help when there are no backends associated. Signed-off-by: Marc-André Lureau --- include/ui/console.h | 2 -- hw/display/vhost-user-gpu.c | 2 +- hw/display/virtio-gpu-base.c | 5 ++++- hw/display/virtio-vga.c | 11 ----------- ui/console.c | 12 +++--------- ui/gtk-egl.c | 1 - ui/gtk-gl-area.c | 1 - ui/sdl2-gl.c | 2 -- ui/spice-display.c | 1 - 9 files changed, 8 insertions(+), 29 deletions(-) diff --git a/include/ui/console.h b/include/ui/console.h index 9391fb052b..a8c2b9f479 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -393,7 +393,6 @@ typedef struct GraphicHwOps { void (*update_interval)(void *opaque, uint64_t interval); int (*ui_info)(void *opaque, uint32_t head, QemuUIInfo *info); void (*gl_block)(void *opaque, bool block); - void (*gl_flushed)(void *opaque); } GraphicHwOps; QemuConsole *graphic_console_init(DeviceState *dev, uint32_t head, @@ -409,7 +408,6 @@ void graphic_hw_update_done(QemuConsole *con); void graphic_hw_invalidate(QemuConsole *con); void graphic_hw_text_update(QemuConsole *con, console_ch_t *chardata); void graphic_hw_gl_block(QemuConsole *con, bool block); -void graphic_hw_gl_flushed(QemuConsole *con); void qemu_console_early_init(void); diff --git a/hw/display/vhost-user-gpu.c b/hw/display/vhost-user-gpu.c index a01f9315e1..a2a011e9cc 100644 --- a/hw/display/vhost-user-gpu.c +++ b/hw/display/vhost-user-gpu.c @@ -254,8 +254,8 @@ vhost_user_gpu_handle_display(VhostUserGPU *g, VhostUserGpuMsg *msg) vhost_user_gpu_unblock(g); break; } - dpy_gl_update(con, m->x, m->y, m->width, m->height); g->backend_blocked = true; + dpy_gl_update(con, m->x, m->y, m->width, m->height); break; } case VHOST_USER_GPU_UPDATE: { diff --git a/hw/display/virtio-gpu-base.c b/hw/display/virtio-gpu-base.c index 25f8920fdb..ee2753001a 100644 --- a/hw/display/virtio-gpu-base.c +++ b/hw/display/virtio-gpu-base.c @@ -118,6 +118,10 @@ virtio_gpu_gl_block(void *opaque, bool block) g->renderer_blocked--; } assert(g->renderer_blocked >= 0); + + if (!block && g->renderer_blocked == 0) { + virtio_gpu_gl_flushed(g); + } } static int @@ -144,7 +148,6 @@ static const GraphicHwOps virtio_gpu_ops = { .text_update = virtio_gpu_text_update, .ui_info = virtio_gpu_ui_info, .gl_block = virtio_gpu_gl_block, - .gl_flushed = virtio_gpu_gl_flushed, }; bool diff --git a/hw/display/virtio-vga.c b/hw/display/virtio-vga.c index d3c6404061..b071909b68 100644 --- a/hw/display/virtio-vga.c +++ b/hw/display/virtio-vga.c @@ -68,16 +68,6 @@ static void virtio_vga_base_gl_block(void *opaque, bool block) } } -static void virtio_vga_base_gl_flushed(void *opaque) -{ - VirtIOVGABase *vvga = opaque; - VirtIOGPUBase *g = vvga->vgpu; - - if (g->hw_ops->gl_flushed) { - g->hw_ops->gl_flushed(g); - } -} - static int virtio_vga_base_get_flags(void *opaque) { VirtIOVGABase *vvga = opaque; @@ -93,7 +83,6 @@ static const GraphicHwOps virtio_vga_base_ops = { .text_update = virtio_vga_base_text_update, .ui_info = virtio_vga_base_ui_info, .gl_block = virtio_vga_base_gl_block, - .gl_flushed = virtio_vga_base_gl_flushed, }; static const VMStateDescription vmstate_virtio_vga_base = { diff --git a/ui/console.c b/ui/console.c index 808f82fa64..18311707bd 100644 --- a/ui/console.c +++ b/ui/console.c @@ -318,15 +318,6 @@ void graphic_hw_gl_block(QemuConsole *con, bool block) } } -void graphic_hw_gl_flushed(QemuConsole *con) -{ - assert(con != NULL); - - if (con->hw_ops->gl_flushed) { - con->hw_ops->gl_flushed(con->hw); - } -} - int qemu_console_get_window_id(QemuConsole *con) { return con->window_id; @@ -1953,7 +1944,10 @@ void dpy_gl_update(QemuConsole *con, uint32_t x, uint32_t y, uint32_t w, uint32_t h) { assert(con->gl); + + graphic_hw_gl_block(con, true); con->gl->ops->dpy_gl_update(con->gl, x, y, w, h); + graphic_hw_gl_block(con, false); } /***********************************************************/ diff --git a/ui/gtk-egl.c b/ui/gtk-egl.c index 2a2e6d3a17..48603abfbd 100644 --- a/ui/gtk-egl.c +++ b/ui/gtk-egl.c @@ -94,7 +94,6 @@ void gd_egl_draw(VirtualConsole *vc) } glFlush(); - graphic_hw_gl_flushed(vc->gfx.dcl.con); } void gd_egl_update(DisplayChangeListener *dcl, diff --git a/ui/gtk-gl-area.c b/ui/gtk-gl-area.c index dd5783fec7..e895938a96 100644 --- a/ui/gtk-gl-area.c +++ b/ui/gtk-gl-area.c @@ -72,7 +72,6 @@ void gd_gl_area_draw(VirtualConsole *vc) } glFlush(); - graphic_hw_gl_flushed(vc->gfx.dcl.con); } void gd_gl_area_update(DisplayChangeListener *dcl, diff --git a/ui/sdl2-gl.c b/ui/sdl2-gl.c index a21d2deed9..5b950fbbea 100644 --- a/ui/sdl2-gl.c +++ b/ui/sdl2-gl.c @@ -58,7 +58,6 @@ static void sdl2_gl_render_surface(struct sdl2_console *scon) surface_gl_render_texture(scon->gls, scon->surface); SDL_GL_SwapWindow(scon->real_window); - graphic_hw_gl_flushed(scon->dcl.con); } void sdl2_gl_update(DisplayChangeListener *dcl, @@ -241,5 +240,4 @@ void sdl2_gl_scanout_flush(DisplayChangeListener *dcl, egl_fb_blit(&scon->win_fb, &scon->guest_fb, !scon->y0_top); SDL_GL_SwapWindow(scon->real_window); - graphic_hw_gl_flushed(dcl->con); } diff --git a/ui/spice-display.c b/ui/spice-display.c index f637fd1bc6..24f5cc30f1 100644 --- a/ui/spice-display.c +++ b/ui/spice-display.c @@ -826,7 +826,6 @@ static void qemu_spice_gl_unblock_bh(void *opaque) SimpleSpiceDisplay *ssd = opaque; qemu_spice_gl_block(ssd, false); - graphic_hw_gl_flushed(ssd->dcl.con); } static void qemu_spice_gl_block_timer(void *opaque) From patchwork Fri Mar 12 10:00:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 12134197 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 83F72C433E0 for ; Fri, 12 Mar 2021 10:16:35 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 2A62E64FDA for ; Fri, 12 Mar 2021 10:16:35 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 2A62E64FDA Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:39738 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lKeqQ-0002OR-7W for qemu-devel@archiver.kernel.org; Fri, 12 Mar 2021 05:16:34 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:34614) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lKedD-0008AA-6Q for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:02:55 -0500 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:44650) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1lKedB-0002sG-6E for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:02:54 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1615543372; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=QFp9zu36PTVBseYtJOmpGkX5LMTIvhKMevsrcnFy/sU=; b=ggZtgBFlwDoMw3A11weyWHAaA5EeQMakNvLLSm8IjqufDvnOkLr/oGmlekn7Xm2V1bdQ9/ ijLnFVFCtV2Zp9WXH0BieKcE85fp18otWB7Wtwhd+Stq77ymTIyaste1upGc29qnIeXUpL DaXUbA7kKzFLmAAJa78I4CJH+042reE= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-35-iNJwbOu3MPeGb3dBEAecNQ-1; Fri, 12 Mar 2021 05:02:50 -0500 X-MC-Unique: iNJwbOu3MPeGb3dBEAecNQ-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 77A1C19200C0 for ; Fri, 12 Mar 2021 10:02:49 +0000 (UTC) Received: from localhost (unknown [10.36.110.50]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3C00A610AE; Fri, 12 Mar 2021 10:02:41 +0000 (UTC) From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH 10/27] ui: dispatch GL events to all listeners Date: Fri, 12 Mar 2021 14:00:51 +0400 Message-Id: <20210312100108.2706195-11-marcandre.lureau@redhat.com> In-Reply-To: <20210312100108.2706195-1-marcandre.lureau@redhat.com> References: <20210312100108.2706195-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=216.205.24.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -29 X-Spam_score: -3.0 X-Spam_bar: --- X-Spam_report: (-3.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.25, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, 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: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Gerd Hoffmann Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau For now, only one listener can receive GL events. Let's dispatch to all listeners. (preliminary check ensure there is a single listener now during regitration, and in next patches, compatible listeners only) Signed-off-by: Marc-André Lureau --- ui/console.c | 58 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 16 deletions(-) diff --git a/ui/console.c b/ui/console.c index 18311707bd..a0910671f7 100644 --- a/ui/console.c +++ b/ui/console.c @@ -1883,8 +1883,12 @@ int dpy_gl_ctx_make_current(QemuConsole *con, QEMUGLContext ctx) void dpy_gl_scanout_disable(QemuConsole *con) { - assert(con->gl); - con->gl->ops->dpy_gl_scanout_disable(con->gl); + DisplayState *s = con->ds; + DisplayChangeListener *dcl; + + QLIST_FOREACH(dcl, &s->listeners, next) { + dcl->ops->dpy_gl_scanout_disable(dcl); + } } void dpy_gl_scanout_texture(QemuConsole *con, @@ -1895,58 +1899,80 @@ void dpy_gl_scanout_texture(QemuConsole *con, uint32_t x, uint32_t y, uint32_t width, uint32_t height) { - assert(con->gl); - con->gl->ops->dpy_gl_scanout_texture(con->gl, backing_id, + DisplayState *s = con->ds; + DisplayChangeListener *dcl; + + QLIST_FOREACH(dcl, &s->listeners, next) { + dcl->ops->dpy_gl_scanout_texture(dcl, backing_id, backing_y_0_top, backing_width, backing_height, x, y, width, height); + } } void dpy_gl_scanout_dmabuf(QemuConsole *con, QemuDmaBuf *dmabuf) { - assert(con->gl); - con->gl->ops->dpy_gl_scanout_dmabuf(con->gl, dmabuf); + DisplayState *s = con->ds; + DisplayChangeListener *dcl; + + QLIST_FOREACH(dcl, &s->listeners, next) { + dcl->ops->dpy_gl_scanout_dmabuf(dcl, dmabuf); + } } void dpy_gl_cursor_dmabuf(QemuConsole *con, QemuDmaBuf *dmabuf, bool have_hot, uint32_t hot_x, uint32_t hot_y) { - assert(con->gl); + DisplayState *s = con->ds; + DisplayChangeListener *dcl; - if (con->gl->ops->dpy_gl_cursor_dmabuf) { - con->gl->ops->dpy_gl_cursor_dmabuf(con->gl, dmabuf, + QLIST_FOREACH(dcl, &s->listeners, next) { + if (dcl->ops->dpy_gl_cursor_dmabuf) { + dcl->ops->dpy_gl_cursor_dmabuf(dcl, dmabuf, have_hot, hot_x, hot_y); + } } } void dpy_gl_cursor_position(QemuConsole *con, uint32_t pos_x, uint32_t pos_y) { - assert(con->gl); + DisplayState *s = con->ds; + DisplayChangeListener *dcl; - if (con->gl->ops->dpy_gl_cursor_position) { - con->gl->ops->dpy_gl_cursor_position(con->gl, pos_x, pos_y); + QLIST_FOREACH(dcl, &s->listeners, next) { + if (dcl->ops->dpy_gl_cursor_position) { + dcl->ops->dpy_gl_cursor_position(dcl, pos_x, pos_y); + } } } void dpy_gl_release_dmabuf(QemuConsole *con, QemuDmaBuf *dmabuf) { - assert(con->gl); + DisplayState *s = con->ds; + DisplayChangeListener *dcl; - if (con->gl->ops->dpy_gl_release_dmabuf) { - con->gl->ops->dpy_gl_release_dmabuf(con->gl, dmabuf); + QLIST_FOREACH(dcl, &s->listeners, next) { + if (dcl->ops->dpy_gl_release_dmabuf) { + dcl->ops->dpy_gl_release_dmabuf(dcl, dmabuf); + } } } void dpy_gl_update(QemuConsole *con, uint32_t x, uint32_t y, uint32_t w, uint32_t h) { + DisplayState *s = con->ds; + DisplayChangeListener *dcl; + assert(con->gl); graphic_hw_gl_block(con, true); - con->gl->ops->dpy_gl_update(con->gl, x, y, w, h); + QLIST_FOREACH(dcl, &s->listeners, next) { + dcl->ops->dpy_gl_update(dcl, x, y, w, h); + } graphic_hw_gl_block(con, false); } From patchwork Fri Mar 12 10:00:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 12134179 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3F025C433DB for ; Fri, 12 Mar 2021 10:09:40 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id C626D64FB9 for ; Fri, 12 Mar 2021 10:09:39 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C626D64FB9 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:45024 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lKeji-0000vn-Ul for qemu-devel@archiver.kernel.org; Fri, 12 Mar 2021 05:09:38 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:34680) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lKedT-00008d-2P for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:03:12 -0500 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:47232) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1lKedP-00030i-Kk for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:03:10 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1615543386; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=VMSKuNWZmaHyPL7t5wx9YhNsppt2e3Ux+tz86rNmh38=; b=OUhw2c2z/c8NR/Sm/9Kl6fIXuvAxsthdNXPQuk2MK64WDHKCm2gXeRNc4ROO2IaOakKLJL occt1mF0PTo9wtXVMalU/dyVRUtjcALbHL5hym+0Uowrnu5ukBcxBygIIPUaKKxsJeur9A NN9vPc5Vm58Sfzj716vGYXsqxM5ogW0= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-31-_kIHeboWPHutYf3-nwGi3w-1; Fri, 12 Mar 2021 05:03:05 -0500 X-MC-Unique: _kIHeboWPHutYf3-nwGi3w-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 1300619200C0 for ; Fri, 12 Mar 2021 10:03:04 +0000 (UTC) Received: from localhost (unknown [10.36.110.50]) by smtp.corp.redhat.com (Postfix) with ESMTP id F0C1B5C276; Fri, 12 Mar 2021 10:02:53 +0000 (UTC) From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH 11/27] ui: split the GL context in a different object Date: Fri, 12 Mar 2021 14:00:52 +0400 Message-Id: <20210312100108.2706195-12-marcandre.lureau@redhat.com> In-Reply-To: <20210312100108.2706195-1-marcandre.lureau@redhat.com> References: <20210312100108.2706195-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=216.205.24.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -29 X-Spam_score: -3.0 X-Spam_bar: --- X-Spam_report: (-3.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.25, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, 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: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Gerd Hoffmann Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau This will allow to have one GL context but a variable number of listeners. Signed-off-by: Marc-André Lureau --- include/ui/console.h | 31 ++++++++++++++++++++----------- include/ui/egl-context.h | 6 +++--- include/ui/gtk.h | 11 ++++++----- include/ui/sdl2.h | 7 ++++--- include/ui/spice-display.h | 1 + ui/console.c | 24 +++++++++++++++--------- ui/egl-context.c | 6 +++--- ui/egl-headless.c | 21 ++++++++++++++------- ui/gtk-egl.c | 10 +++++----- ui/gtk-gl-area.c | 8 ++++---- ui/gtk.c | 24 ++++++++++++++++-------- ui/sdl2-gl.c | 10 +++++----- ui/sdl2.c | 13 +++++++++---- ui/spice-display.c | 18 +++++++++++------- 14 files changed, 116 insertions(+), 74 deletions(-) diff --git a/include/ui/console.h b/include/ui/console.h index a8c2b9f479..b271bb1c51 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -171,6 +171,7 @@ typedef struct QemuDmaBuf { } QemuDmaBuf; typedef struct DisplayState DisplayState; +typedef struct DisplayGLCtx DisplayGLCtx; typedef struct DisplayChangeListenerOps { const char *dpy_name; @@ -205,16 +206,6 @@ typedef struct DisplayChangeListenerOps { void (*dpy_cursor_define)(DisplayChangeListener *dcl, QEMUCursor *cursor); - /* required if GL */ - QEMUGLContext (*dpy_gl_ctx_create)(DisplayChangeListener *dcl, - QEMUGLParams *params); - /* required if GL */ - void (*dpy_gl_ctx_destroy)(DisplayChangeListener *dcl, - QEMUGLContext ctx); - /* required if GL */ - int (*dpy_gl_ctx_make_current)(DisplayChangeListener *dcl, - QEMUGLContext ctx); - /* required if GL */ void (*dpy_gl_scanout_disable)(DisplayChangeListener *dcl); /* required if GL */ @@ -255,6 +246,24 @@ struct DisplayChangeListener { QLIST_ENTRY(DisplayChangeListener) next; }; +typedef struct DisplayGLCtxOps { + /* We only check if the GLCtx is compatible with a DCL via ops. A natural + * evolution of this would be a callback to check some runtime requirements + * and allow various DCL kinds. */ + const DisplayChangeListenerOps *compatible_dcl; + + QEMUGLContext (*dpy_gl_ctx_create)(DisplayGLCtx *dgc, + QEMUGLParams *params); + void (*dpy_gl_ctx_destroy)(DisplayGLCtx *dgc, + QEMUGLContext ctx); + int (*dpy_gl_ctx_make_current)(DisplayGLCtx *dgc, + QEMUGLContext ctx); +} DisplayGLCtxOps; + +struct DisplayGLCtx { + const DisplayGLCtxOps *ops; +}; + DisplayState *init_displaystate(void); DisplaySurface *qemu_create_displaysurface_from(int width, int height, pixman_format_code_t format, @@ -411,7 +420,7 @@ void graphic_hw_gl_block(QemuConsole *con, bool block); void qemu_console_early_init(void); -void qemu_console_set_display_gl_ctx(QemuConsole *con, DisplayChangeListener *dcl); +void qemu_console_set_display_gl_ctx(QemuConsole *con, DisplayGLCtx *ctx); QemuConsole *qemu_console_lookup_by_index(unsigned int index); QemuConsole *qemu_console_lookup_by_device(DeviceState *dev, uint32_t head); diff --git a/include/ui/egl-context.h b/include/ui/egl-context.h index 9374fe41e3..c2761d747a 100644 --- a/include/ui/egl-context.h +++ b/include/ui/egl-context.h @@ -4,10 +4,10 @@ #include "ui/console.h" #include "ui/egl-helpers.h" -QEMUGLContext qemu_egl_create_context(DisplayChangeListener *dcl, +QEMUGLContext qemu_egl_create_context(DisplayGLCtx *dgc, QEMUGLParams *params); -void qemu_egl_destroy_context(DisplayChangeListener *dcl, QEMUGLContext ctx); -int qemu_egl_make_context_current(DisplayChangeListener *dcl, +void qemu_egl_destroy_context(DisplayGLCtx *dgc, QEMUGLContext ctx); +int qemu_egl_make_context_current(DisplayGLCtx *dgc, QEMUGLContext ctx); #endif /* EGL_CONTEXT_H */ diff --git a/include/ui/gtk.h b/include/ui/gtk.h index 5ae0ad60a6..802c619a39 100644 --- a/include/ui/gtk.h +++ b/include/ui/gtk.h @@ -28,6 +28,7 @@ typedef struct GtkDisplayState GtkDisplayState; typedef struct VirtualGfxConsole { GtkWidget *drawing_area; + DisplayGLCtx dgc; DisplayChangeListener dcl; QKbdState *kbd; DisplaySurface *ds; @@ -97,7 +98,7 @@ void gd_egl_update(DisplayChangeListener *dcl, void gd_egl_refresh(DisplayChangeListener *dcl); void gd_egl_switch(DisplayChangeListener *dcl, DisplaySurface *surface); -QEMUGLContext gd_egl_create_context(DisplayChangeListener *dcl, +QEMUGLContext gd_egl_create_context(DisplayGLCtx *dgc, QEMUGLParams *params); void gd_egl_scanout_disable(DisplayChangeListener *dcl); void gd_egl_scanout_texture(DisplayChangeListener *dcl, @@ -119,7 +120,7 @@ void gd_egl_release_dmabuf(DisplayChangeListener *dcl, void gd_egl_scanout_flush(DisplayChangeListener *dcl, uint32_t x, uint32_t y, uint32_t w, uint32_t h); void gtk_egl_init(DisplayGLMode mode); -int gd_egl_make_current(DisplayChangeListener *dcl, +int gd_egl_make_current(DisplayGLCtx *dgc, QEMUGLContext ctx); /* ui/gtk-gl-area.c */ @@ -130,9 +131,9 @@ void gd_gl_area_update(DisplayChangeListener *dcl, void gd_gl_area_refresh(DisplayChangeListener *dcl); void gd_gl_area_switch(DisplayChangeListener *dcl, DisplaySurface *surface); -QEMUGLContext gd_gl_area_create_context(DisplayChangeListener *dcl, +QEMUGLContext gd_gl_area_create_context(DisplayGLCtx *dgc, QEMUGLParams *params); -void gd_gl_area_destroy_context(DisplayChangeListener *dcl, +void gd_gl_area_destroy_context(DisplayGLCtx *dgc, QEMUGLContext ctx); void gd_gl_area_scanout_dmabuf(DisplayChangeListener *dcl, QemuDmaBuf *dmabuf); @@ -147,7 +148,7 @@ void gd_gl_area_scanout_disable(DisplayChangeListener *dcl); void gd_gl_area_scanout_flush(DisplayChangeListener *dcl, uint32_t x, uint32_t y, uint32_t w, uint32_t h); void gtk_gl_area_init(void); -int gd_gl_area_make_current(DisplayChangeListener *dcl, +int gd_gl_area_make_current(DisplayGLCtx *dgc, QEMUGLContext ctx); #endif /* UI_GTK_H */ diff --git a/include/ui/sdl2.h b/include/ui/sdl2.h index f85c117a78..71bcf7ebda 100644 --- a/include/ui/sdl2.h +++ b/include/ui/sdl2.h @@ -16,6 +16,7 @@ #endif struct sdl2_console { + DisplayGLCtx dgc; DisplayChangeListener dcl; DisplaySurface *surface; DisplayOptions *opts; @@ -65,10 +66,10 @@ void sdl2_gl_switch(DisplayChangeListener *dcl, void sdl2_gl_refresh(DisplayChangeListener *dcl); void sdl2_gl_redraw(struct sdl2_console *scon); -QEMUGLContext sdl2_gl_create_context(DisplayChangeListener *dcl, +QEMUGLContext sdl2_gl_create_context(DisplayGLCtx *dgc, QEMUGLParams *params); -void sdl2_gl_destroy_context(DisplayChangeListener *dcl, QEMUGLContext ctx); -int sdl2_gl_make_context_current(DisplayChangeListener *dcl, +void sdl2_gl_destroy_context(DisplayGLCtx *dgc, QEMUGLContext ctx); +int sdl2_gl_make_context_current(DisplayGLCtx *dgc, QEMUGLContext ctx); void sdl2_gl_scanout_disable(DisplayChangeListener *dcl); diff --git a/include/ui/spice-display.h b/include/ui/spice-display.h index ed298d58f0..a2fbf62c52 100644 --- a/include/ui/spice-display.h +++ b/include/ui/spice-display.h @@ -86,6 +86,7 @@ typedef struct SimpleSpiceCursor SimpleSpiceCursor; struct SimpleSpiceDisplay { DisplaySurface *ds; + DisplayGLCtx dgc; DisplayChangeListener dcl; void *buf; int bufsize; diff --git a/ui/console.c b/ui/console.c index a0910671f7..07357fd328 100644 --- a/ui/console.c +++ b/ui/console.c @@ -127,7 +127,7 @@ struct QemuConsole { DisplayState *ds; DisplaySurface *surface; int dcls; - DisplayChangeListener *gl; + DisplayGLCtx *gl; int gl_block; QEMUTimer *gl_unblock_timer; int window_id; @@ -1517,16 +1517,23 @@ static bool dpy_compatible_with(QemuConsole *con, return true; } -void qemu_console_set_display_gl_ctx(QemuConsole *con, DisplayChangeListener *dcl) +void qemu_console_set_display_gl_ctx(QemuConsole *con, DisplayGLCtx *gl) { /* display has opengl support */ - assert(dcl->con); - if (dcl->con->gl) { - fprintf(stderr, "can't register two opengl displays (%s, %s)\n", - dcl->ops->dpy_name, dcl->con->gl->ops->dpy_name); + assert(con); + if (con->gl) { + error_report("The console already has an OpenGL context."); exit(1); } - dcl->con->gl = dcl; + con->gl = gl; +} + +static bool dpy_gl_compatible_with(QemuConsole *con, DisplayChangeListener *dcl) +{ + if (!con->gl) + return true; + + return con->gl->ops->compatible_dcl == dcl->ops; } void register_displaychangelistener(DisplayChangeListener *dcl) @@ -1539,8 +1546,7 @@ void register_displaychangelistener(DisplayChangeListener *dcl) assert(!dcl->ds); - if (dcl->con && dcl->con->gl && - dcl->con->gl != dcl) { + if (dcl->con && !dpy_gl_compatible_with(dcl->con, dcl)) { error_report("Display %s is incompatible with the GL context", dcl->ops->dpy_name); exit(1); diff --git a/ui/egl-context.c b/ui/egl-context.c index 368ffa49d8..eb5f520fc4 100644 --- a/ui/egl-context.c +++ b/ui/egl-context.c @@ -1,7 +1,7 @@ #include "qemu/osdep.h" #include "ui/egl-context.h" -QEMUGLContext qemu_egl_create_context(DisplayChangeListener *dcl, +QEMUGLContext qemu_egl_create_context(DisplayGLCtx *dgc, QEMUGLParams *params) { EGLContext ctx; @@ -24,12 +24,12 @@ QEMUGLContext qemu_egl_create_context(DisplayChangeListener *dcl, return ctx; } -void qemu_egl_destroy_context(DisplayChangeListener *dcl, QEMUGLContext ctx) +void qemu_egl_destroy_context(DisplayGLCtx *dgc, QEMUGLContext ctx) { eglDestroyContext(qemu_egl_display, ctx); } -int qemu_egl_make_context_current(DisplayChangeListener *dcl, +int qemu_egl_make_context_current(DisplayGLCtx *dgc, QEMUGLContext ctx) { return eglMakeCurrent(qemu_egl_display, diff --git a/ui/egl-headless.c b/ui/egl-headless.c index 773520bc17..f492591d4e 100644 --- a/ui/egl-headless.c +++ b/ui/egl-headless.c @@ -38,12 +38,12 @@ static void egl_gfx_switch(DisplayChangeListener *dcl, edpy->ds = new_surface; } -static QEMUGLContext egl_create_context(DisplayChangeListener *dcl, +static QEMUGLContext egl_create_context(DisplayGLCtx *dgc, QEMUGLParams *params) { eglMakeCurrent(qemu_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, qemu_egl_rn_ctx); - return qemu_egl_create_context(dcl, params); + return qemu_egl_create_context(dgc, params); } static void egl_scanout_disable(DisplayChangeListener *dcl) @@ -157,10 +157,6 @@ static const DisplayChangeListenerOps egl_ops = { .dpy_gfx_update = egl_gfx_update, .dpy_gfx_switch = egl_gfx_switch, - .dpy_gl_ctx_create = egl_create_context, - .dpy_gl_ctx_destroy = qemu_egl_destroy_context, - .dpy_gl_ctx_make_current = qemu_egl_make_context_current, - .dpy_gl_scanout_disable = egl_scanout_disable, .dpy_gl_scanout_texture = egl_scanout_texture, .dpy_gl_scanout_dmabuf = egl_scanout_dmabuf, @@ -170,6 +166,13 @@ static const DisplayChangeListenerOps egl_ops = { .dpy_gl_update = egl_scanout_flush, }; +static const DisplayGLCtxOps eglctx_ops = { + .compatible_dcl = &egl_ops, + .dpy_gl_ctx_create = egl_create_context, + .dpy_gl_ctx_destroy = qemu_egl_destroy_context, + .dpy_gl_ctx_make_current = qemu_egl_make_context_current, +}; + static void early_egl_headless_init(DisplayOptions *opts) { display_opengl = 1; @@ -188,6 +191,8 @@ static void egl_headless_init(DisplayState *ds, DisplayOptions *opts) } for (idx = 0;; idx++) { + DisplayGLCtx *ctx; + con = qemu_console_lookup_by_index(idx); if (!con || !qemu_console_is_graphic(con)) { break; @@ -197,7 +202,9 @@ static void egl_headless_init(DisplayState *ds, DisplayOptions *opts) edpy->dcl.con = con; edpy->dcl.ops = &egl_ops; edpy->gls = qemu_gl_init_shader(); - qemu_console_set_display_gl_ctx(con, &edpy->dcl); + ctx = g_new0(DisplayGLCtx, 1); + ctx->ops = &eglctx_ops; + qemu_console_set_display_gl_ctx(con, ctx); register_displaychangelistener(&edpy->dcl); } } diff --git a/ui/gtk-egl.c b/ui/gtk-egl.c index 48603abfbd..199717495d 100644 --- a/ui/gtk-egl.c +++ b/ui/gtk-egl.c @@ -163,14 +163,14 @@ void gd_egl_switch(DisplayChangeListener *dcl, } } -QEMUGLContext gd_egl_create_context(DisplayChangeListener *dcl, +QEMUGLContext gd_egl_create_context(DisplayGLCtx *dgc, QEMUGLParams *params) { - VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl); + VirtualConsole *vc = container_of(dgc, VirtualConsole, gfx.dgc); eglMakeCurrent(qemu_egl_display, vc->gfx.esurface, vc->gfx.esurface, vc->gfx.ectx); - return qemu_egl_create_context(dcl, params); + return qemu_egl_create_context(dgc, params); } void gd_egl_scanout_disable(DisplayChangeListener *dcl) @@ -303,10 +303,10 @@ void gtk_egl_init(DisplayGLMode mode) display_opengl = 1; } -int gd_egl_make_current(DisplayChangeListener *dcl, +int gd_egl_make_current(DisplayGLCtx *dgc, QEMUGLContext ctx) { - VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl); + VirtualConsole *vc = container_of(dgc, VirtualConsole, gfx.dgc); return eglMakeCurrent(qemu_egl_display, vc->gfx.esurface, vc->gfx.esurface, ctx); diff --git a/ui/gtk-gl-area.c b/ui/gtk-gl-area.c index e895938a96..f0d00d000d 100644 --- a/ui/gtk-gl-area.c +++ b/ui/gtk-gl-area.c @@ -138,10 +138,10 @@ void gd_gl_area_switch(DisplayChangeListener *dcl, } } -QEMUGLContext gd_gl_area_create_context(DisplayChangeListener *dcl, +QEMUGLContext gd_gl_area_create_context(DisplayGLCtx *dgc, QEMUGLParams *params) { - VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl); + VirtualConsole *vc = container_of(dgc, VirtualConsole, gfx.dgc); GdkWindow *window; GdkGLContext *ctx; GError *err = NULL; @@ -167,7 +167,7 @@ QEMUGLContext gd_gl_area_create_context(DisplayChangeListener *dcl, return ctx; } -void gd_gl_area_destroy_context(DisplayChangeListener *dcl, QEMUGLContext ctx) +void gd_gl_area_destroy_context(DisplayGLCtx *dgc, QEMUGLContext ctx) { /* FIXME */ } @@ -238,7 +238,7 @@ void gtk_gl_area_init(void) display_opengl = 1; } -int gd_gl_area_make_current(DisplayChangeListener *dcl, +int gd_gl_area_make_current(DisplayGLCtx *dgc, QEMUGLContext ctx) { gdk_gl_context_make_current(ctx); diff --git a/ui/gtk.c b/ui/gtk.c index d8b3784bf0..63ce4fd980 100644 --- a/ui/gtk.c +++ b/ui/gtk.c @@ -643,9 +643,6 @@ static const DisplayChangeListenerOps dcl_gl_area_ops = { .dpy_mouse_set = gd_mouse_set, .dpy_cursor_define = gd_cursor_define, - .dpy_gl_ctx_create = gd_gl_area_create_context, - .dpy_gl_ctx_destroy = gd_gl_area_destroy_context, - .dpy_gl_ctx_make_current = gd_gl_area_make_current, .dpy_gl_scanout_texture = gd_gl_area_scanout_texture, .dpy_gl_scanout_disable = gd_gl_area_scanout_disable, .dpy_gl_update = gd_gl_area_scanout_flush, @@ -653,8 +650,14 @@ static const DisplayChangeListenerOps dcl_gl_area_ops = { .dpy_has_dmabuf = gd_has_dmabuf, }; -#ifdef CONFIG_X11 +static const DisplayGLCtxOps gl_area_ctx_ops = { + .compatible_dcl = &dcl_gl_area_ops, + .dpy_gl_ctx_create = gd_gl_area_create_context, + .dpy_gl_ctx_destroy = gd_gl_area_destroy_context, + .dpy_gl_ctx_make_current = gd_gl_area_make_current, +}; +#ifdef CONFIG_X11 static const DisplayChangeListenerOps dcl_egl_ops = { .dpy_name = "gtk-egl", .dpy_gfx_update = gd_egl_update, @@ -664,9 +667,6 @@ static const DisplayChangeListenerOps dcl_egl_ops = { .dpy_mouse_set = gd_mouse_set, .dpy_cursor_define = gd_cursor_define, - .dpy_gl_ctx_create = gd_egl_create_context, - .dpy_gl_ctx_destroy = qemu_egl_destroy_context, - .dpy_gl_ctx_make_current = gd_egl_make_current, .dpy_gl_scanout_disable = gd_egl_scanout_disable, .dpy_gl_scanout_texture = gd_egl_scanout_texture, .dpy_gl_scanout_dmabuf = gd_egl_scanout_dmabuf, @@ -677,6 +677,12 @@ static const DisplayChangeListenerOps dcl_egl_ops = { .dpy_has_dmabuf = gd_has_dmabuf, }; +static const DisplayGLCtxOps egl_ctx_ops = { + .compatible_dcl = &dcl_egl_ops, + .dpy_gl_ctx_create = gd_egl_create_context, + .dpy_gl_ctx_destroy = qemu_egl_destroy_context, + .dpy_gl_ctx_make_current = gd_egl_make_current, +}; #endif #endif /* CONFIG_OPENGL */ @@ -2034,6 +2040,7 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, VirtualConsole *vc, g_signal_connect(vc->gfx.drawing_area, "realize", G_CALLBACK(gl_area_realize), vc); vc->gfx.dcl.ops = &dcl_gl_area_ops; + vc->gfx.dgc.ops = &gl_area_ctx_ops; } else { #ifdef CONFIG_X11 vc->gfx.drawing_area = gtk_drawing_area_new(); @@ -2048,6 +2055,7 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, VirtualConsole *vc, gtk_widget_set_double_buffered(vc->gfx.drawing_area, FALSE); #pragma GCC diagnostic pop vc->gfx.dcl.ops = &dcl_egl_ops; + vc->gfx.dgc.ops = &egl_ctx_ops; vc->gfx.has_dmabuf = qemu_egl_has_dmabuf(); #else abort(); @@ -2083,7 +2091,7 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, VirtualConsole *vc, vc->gfx.dcl.con = con; if (display_opengl) { - qemu_console_set_display_gl_ctx(con, &vc->gfx.dcl); + qemu_console_set_display_gl_ctx(con, &vc->gfx.dgc); } register_displaychangelistener(&vc->gfx.dcl); diff --git a/ui/sdl2-gl.c b/ui/sdl2-gl.c index 5b950fbbea..39cab8cde7 100644 --- a/ui/sdl2-gl.c +++ b/ui/sdl2-gl.c @@ -132,10 +132,10 @@ void sdl2_gl_redraw(struct sdl2_console *scon) } } -QEMUGLContext sdl2_gl_create_context(DisplayChangeListener *dcl, +QEMUGLContext sdl2_gl_create_context(DisplayGLCtx *dgc, QEMUGLParams *params) { - struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl); + struct sdl2_console *scon = container_of(dgc, struct sdl2_console, dgc); SDL_GLContext ctx; assert(scon->opengl); @@ -167,17 +167,17 @@ QEMUGLContext sdl2_gl_create_context(DisplayChangeListener *dcl, return (QEMUGLContext)ctx; } -void sdl2_gl_destroy_context(DisplayChangeListener *dcl, QEMUGLContext ctx) +void sdl2_gl_destroy_context(DisplayGLCtx *dgc, QEMUGLContext ctx) { SDL_GLContext sdlctx = (SDL_GLContext)ctx; SDL_GL_DeleteContext(sdlctx); } -int sdl2_gl_make_context_current(DisplayChangeListener *dcl, +int sdl2_gl_make_context_current(DisplayGLCtx *dgc, QEMUGLContext ctx) { - struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl); + struct sdl2_console *scon = container_of(dgc, struct sdl2_console, dgc); SDL_GLContext sdlctx = (SDL_GLContext)ctx; assert(scon->opengl); diff --git a/ui/sdl2.c b/ui/sdl2.c index 0593a333f5..97ba283c49 100644 --- a/ui/sdl2.c +++ b/ui/sdl2.c @@ -778,13 +778,17 @@ static const DisplayChangeListenerOps dcl_gl_ops = { .dpy_mouse_set = sdl_mouse_warp, .dpy_cursor_define = sdl_mouse_define, - .dpy_gl_ctx_create = sdl2_gl_create_context, - .dpy_gl_ctx_destroy = sdl2_gl_destroy_context, - .dpy_gl_ctx_make_current = sdl2_gl_make_context_current, .dpy_gl_scanout_disable = sdl2_gl_scanout_disable, .dpy_gl_scanout_texture = sdl2_gl_scanout_texture, .dpy_gl_update = sdl2_gl_scanout_flush, }; + +static const DisplayGLCtxOps gl_ctx_ops = { + .compatible_dcl = &dcl_gl_ops, + .dpy_gl_ctx_create = sdl2_gl_create_context, + .dpy_gl_ctx_destroy = sdl2_gl_destroy_context, + .dpy_gl_ctx_make_current = sdl2_gl_make_context_current, +}; #endif static void sdl2_display_early_init(DisplayOptions *o) @@ -857,6 +861,7 @@ static void sdl2_display_init(DisplayState *ds, DisplayOptions *o) #ifdef CONFIG_OPENGL sdl2_console[i].opengl = display_opengl; sdl2_console[i].dcl.ops = display_opengl ? &dcl_gl_ops : &dcl_2d_ops; + sdl2_console[i].dgc.ops = display_opengl ? &gl_ctx_ops : NULL; #else sdl2_console[i].opengl = 0; sdl2_console[i].dcl.ops = &dcl_2d_ops; @@ -864,7 +869,7 @@ static void sdl2_display_init(DisplayState *ds, DisplayOptions *o) sdl2_console[i].dcl.con = con; sdl2_console[i].kbd = qkbd_state_init(con); if (display_opengl) { - qemu_console_set_display_gl_ctx(con, &sdl2_console[i].dcl); + qemu_console_set_display_gl_ctx(con, &sdl2_console[i].dgc); } register_displaychangelistener(&sdl2_console[i].dcl); diff --git a/ui/spice-display.c b/ui/spice-display.c index 24f5cc30f1..0b787d12df 100644 --- a/ui/spice-display.c +++ b/ui/spice-display.c @@ -904,12 +904,12 @@ static void spice_gl_switch(DisplayChangeListener *dcl, } } -static QEMUGLContext qemu_spice_gl_create_context(DisplayChangeListener *dcl, +static QEMUGLContext qemu_spice_gl_create_context(DisplayGLCtx *dgc, QEMUGLParams *params) { eglMakeCurrent(qemu_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, qemu_egl_rn_ctx); - return qemu_egl_create_context(dcl, params); + return qemu_egl_create_context(dgc, params); } static void qemu_spice_gl_scanout_disable(DisplayChangeListener *dcl) @@ -1101,10 +1101,6 @@ static const DisplayChangeListenerOps display_listener_gl_ops = { .dpy_mouse_set = display_mouse_set, .dpy_cursor_define = display_mouse_define, - .dpy_gl_ctx_create = qemu_spice_gl_create_context, - .dpy_gl_ctx_destroy = qemu_egl_destroy_context, - .dpy_gl_ctx_make_current = qemu_egl_make_context_current, - .dpy_gl_scanout_disable = qemu_spice_gl_scanout_disable, .dpy_gl_scanout_texture = qemu_spice_gl_scanout_texture, .dpy_gl_scanout_dmabuf = qemu_spice_gl_scanout_dmabuf, @@ -1114,6 +1110,13 @@ static const DisplayChangeListenerOps display_listener_gl_ops = { .dpy_gl_update = qemu_spice_gl_update, }; +static const DisplayGLCtxOps gl_ctx_ops = { + .compatible_dcl = &display_listener_gl_ops, + .dpy_gl_ctx_create = qemu_spice_gl_create_context, + .dpy_gl_ctx_destroy = qemu_egl_destroy_context, + .dpy_gl_ctx_make_current = qemu_egl_make_context_current, +}; + #endif /* HAVE_SPICE_GL */ static void qemu_spice_display_init_one(QemuConsole *con) @@ -1126,6 +1129,7 @@ static void qemu_spice_display_init_one(QemuConsole *con) #ifdef HAVE_SPICE_GL if (spice_opengl) { ssd->dcl.ops = &display_listener_gl_ops; + ssd->dgc.ops = &gl_ctx_ops; ssd->gl_unblock_bh = qemu_bh_new(qemu_spice_gl_unblock_bh, ssd); ssd->gl_unblock_timer = timer_new_ms(QEMU_CLOCK_REALTIME, qemu_spice_gl_block_timer, ssd); @@ -1152,7 +1156,7 @@ static void qemu_spice_display_init_one(QemuConsole *con) qemu_spice_create_host_memslot(ssd); if (spice_opengl) { - qemu_console_set_display_gl_ctx(con, &ssd->dcl); + qemu_console_set_display_gl_ctx(con, &ssd->dgc); } register_displaychangelistener(&ssd->dcl); } From patchwork Fri Mar 12 10:00:53 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 12134185 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5FF40C433DB for ; Fri, 12 Mar 2021 10:11:48 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id EA17164FC9 for ; Fri, 12 Mar 2021 10:11:47 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org EA17164FC9 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:53594 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lKeln-0004bN-2T for qemu-devel@archiver.kernel.org; Fri, 12 Mar 2021 05:11:47 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:34792) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lKedf-0000JU-BC for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:03:23 -0500 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:28966) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1lKedd-000377-3C for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:03:23 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1615543400; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=uH8FQtcVOWObNnSx2E/9vhaDLZ8kg5cN31rmkw7boNc=; b=LJ/voJYXrwmnEQMVUw1byZUesYq3khcqO56Oswvxp5/yiXwfbV7f7GV/uX2qPMAOYIt1/Q IW9AX3uWTgoMCAhTJABYCj4k7f+E7sH9Lo1rL409+9Pv/ioIqqyaHmXSICng9pt4QOYA8K ABE1tZ0pbmq9KPmMHU5fmvojQ12UFus= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-575-tIHfrqK2Me27yROFljUEMw-1; Fri, 12 Mar 2021 05:03:17 -0500 X-MC-Unique: tIHfrqK2Me27yROFljUEMw-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id ABBC183DD21 for ; Fri, 12 Mar 2021 10:03:16 +0000 (UTC) Received: from localhost (unknown [10.36.110.50]) by smtp.corp.redhat.com (Postfix) with ESMTP id F13CF18B5E; Fri, 12 Mar 2021 10:03:08 +0000 (UTC) From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH 12/27] ui: move qemu_spice_fill_device_address to ui/util.c Date: Fri, 12 Mar 2021 14:00:53 +0400 Message-Id: <20210312100108.2706195-13-marcandre.lureau@redhat.com> In-Reply-To: <20210312100108.2706195-1-marcandre.lureau@redhat.com> References: <20210312100108.2706195-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=216.205.24.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -29 X-Spam_score: -3.0 X-Spam_bar: --- X-Spam_report: (-3.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.25, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, 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: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Gerd Hoffmann Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau Other backends can use it. Signed-off-by: Marc-André Lureau --- include/ui/console.h | 6 +++ include/ui/spice-display.h | 4 -- hw/display/qxl.c | 5 ++- ui/spice-core.c | 50 ------------------------- ui/spice-display.c | 5 ++- ui/util.c | 75 ++++++++++++++++++++++++++++++++++++++ ui/meson.build | 1 + 7 files changed, 90 insertions(+), 56 deletions(-) create mode 100644 ui/util.c diff --git a/include/ui/console.h b/include/ui/console.h index b271bb1c51..793f4c09ee 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -489,4 +489,10 @@ int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp); /* input.c */ int index_from_key(const char *key, size_t key_length); +/* util.c */ +bool qemu_console_fill_device_address(QemuConsole *con, + char *device_address, + size_t size, + Error **errp); + #endif diff --git a/include/ui/spice-display.h b/include/ui/spice-display.h index a2fbf62c52..e271e011da 100644 --- a/include/ui/spice-display.h +++ b/include/ui/spice-display.h @@ -184,8 +184,4 @@ void qemu_spice_display_start(void); void qemu_spice_display_stop(void); int qemu_spice_display_is_running(SimpleSpiceDisplay *ssd); -bool qemu_spice_fill_device_address(QemuConsole *con, - char *device_address, - size_t size); - #endif diff --git a/hw/display/qxl.c b/hw/display/qxl.c index 6784d32920..ac56aeeff4 100644 --- a/hw/display/qxl.c +++ b/hw/display/qxl.c @@ -2202,12 +2202,15 @@ static void qxl_realize_common(PCIQXLDevice *qxl, Error **errp) } #if SPICE_SERVER_VERSION >= 0x000e02 /* release 0.14.2 */ + Error *err = NULL; char device_address[256] = ""; - if (qemu_spice_fill_device_address(qxl->vga.con, device_address, 256)) { + if (qemu_console_fill_device_address(qxl->vga.con, device_address, 256, &err)) { spice_qxl_set_device_info(&qxl->ssd.qxl, device_address, 0, qxl->max_outputs); + } else { + error_report_err(err); } #endif diff --git a/ui/spice-core.c b/ui/spice-core.c index beee932f55..2c21d923c8 100644 --- a/ui/spice-core.c +++ b/ui/spice-core.c @@ -861,56 +861,6 @@ bool qemu_spice_have_display_interface(QemuConsole *con) return false; } -/* - * Recursively (in reverse order) appends addresses of PCI devices as it moves - * up in the PCI hierarchy. - * - * @returns true on success, false when the buffer wasn't large enough - */ -static bool append_pci_address(char *buf, size_t buf_size, const PCIDevice *pci) -{ - PCIBus *bus = pci_get_bus(pci); - /* - * equivalent to if (!pci_bus_is_root(bus)), but the function is not built - * with PCI_CONFIG=n, avoid using an #ifdef by checking directly - */ - if (bus->parent_dev != NULL) { - append_pci_address(buf, buf_size, bus->parent_dev); - } - - size_t len = strlen(buf); - ssize_t written = snprintf(buf + len, buf_size - len, "/%02x.%x", - PCI_SLOT(pci->devfn), PCI_FUNC(pci->devfn)); - - return written > 0 && written < buf_size - len; -} - -bool qemu_spice_fill_device_address(QemuConsole *con, - char *device_address, - size_t size) -{ - DeviceState *dev = DEVICE(object_property_get_link(OBJECT(con), - "device", - &error_abort)); - PCIDevice *pci = (PCIDevice *) object_dynamic_cast(OBJECT(dev), - TYPE_PCI_DEVICE); - - if (pci == NULL) { - warn_report("Setting device address of a display device to SPICE: " - "Not a PCI device."); - return false; - } - - strncpy(device_address, "pci/0000", size); - if (!append_pci_address(device_address, size, pci)) { - warn_report("Setting device address of a display device to SPICE: " - "Too many PCI devices in the chain."); - return false; - } - - return true; -} - int qemu_spice_add_display_interface(QXLInstance *qxlin, QemuConsole *con) { if (g_slist_find(spice_consoles, con)) { diff --git a/ui/spice-display.c b/ui/spice-display.c index 0b787d12df..278a11b1d5 100644 --- a/ui/spice-display.c +++ b/ui/spice-display.c @@ -1144,12 +1144,15 @@ static void qemu_spice_display_init_one(QemuConsole *con) qemu_spice_add_display_interface(&ssd->qxl, con); #if SPICE_SERVER_VERSION >= 0x000e02 /* release 0.14.2 */ + Error *err = NULL; char device_address[256] = ""; - if (qemu_spice_fill_device_address(con, device_address, 256)) { + if (qemu_console_fill_device_address(con, device_address, 256, &err)) { spice_qxl_set_device_info(&ssd->qxl, device_address, qemu_console_get_head(con), 1); + } else { + error_report_err(err); } #endif diff --git a/ui/util.c b/ui/util.c new file mode 100644 index 0000000000..7e8fc1ea53 --- /dev/null +++ b/ui/util.c @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2021 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 or + * (at your option) version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "qemu/osdep.h" + +#include "hw/pci/pci.h" +#include "hw/pci/pci_bus.h" +#include "qapi/error.h" +#include "ui/console.h" + +/* + * Recursively (in reverse order) appends addresses of PCI devices as it moves + * up in the PCI hierarchy. + * + * @returns true on success, false when the buffer wasn't large enough + */ +static bool append_pci_address(char *buf, size_t buf_size, const PCIDevice *pci) +{ + PCIBus *bus = pci_get_bus(pci); + /* + * equivalent to if (!pci_bus_is_root(bus)), but the function is not built + * with PCI_CONFIG=n, avoid using an #ifdef by checking directly + */ + if (bus->parent_dev != NULL) { + append_pci_address(buf, buf_size, bus->parent_dev); + } + + size_t len = strlen(buf); + ssize_t written = snprintf(buf + len, buf_size - len, "/%02x.%x", + PCI_SLOT(pci->devfn), PCI_FUNC(pci->devfn)); + + return written > 0 && written < buf_size - len; +} + +bool qemu_console_fill_device_address(QemuConsole *con, + char *device_address, + size_t size, + Error **errp) +{ + ERRP_GUARD(); + DeviceState *dev = DEVICE(object_property_get_link(OBJECT(con), + "device", + &error_abort)); + PCIDevice *pci = (PCIDevice *) object_dynamic_cast(OBJECT(dev), + TYPE_PCI_DEVICE); + + if (pci == NULL) { + error_setg(errp, "Setting device address of a display device: " + "Not a PCI device."); + return false; + } + + strncpy(device_address, "pci/0000", size); + if (!append_pci_address(device_address, size, pci)) { + error_setg(errp, "Setting device address of a display device: " + "Too many PCI devices in the chain."); + return false; + } + + return true; +} diff --git a/ui/meson.build b/ui/meson.build index e8d3ff41b9..97cdd58856 100644 --- a/ui/meson.build +++ b/ui/meson.build @@ -11,6 +11,7 @@ softmmu_ss.add(files( 'kbd-state.c', 'keymaps.c', 'qemu-pixman.c', + 'util.c', )) softmmu_ss.add([spice_headers, files('spice-module.c')]) From patchwork Fri Mar 12 10:00:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 12134177 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 98AB2C433E0 for ; Fri, 12 Mar 2021 10:09:34 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 3BFBD64FB5 for ; Fri, 12 Mar 2021 10:09:34 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3BFBD64FB5 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:44510 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lKejd-0000is-CT for qemu-devel@archiver.kernel.org; Fri, 12 Mar 2021 05:09:33 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:34860) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lKedu-0000e6-9B for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:03:39 -0500 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:43616) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1lKedq-0003Eb-BX for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:03:37 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1615543413; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=U56jl4RwrMMI3LkyODtdHAQLikCIdgIcdSjtLAbLA58=; b=KHIRl327LVl8VSKP6ssVRCBq77T0RaQjSlbYQyojRxaNhSQenivyTHw8sZBXtkAoMgsllH MUTGadgH1O5dOr4yE8wMw8ouNhXGMLxM2f4jPJXsp4Xk+o6xeJHhOKsDRDWtWU4gvCQHv8 QKC2S3mijF6dXk3XMiJrRa5ECInP4Jc= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-372-y7vQeKOyPO6N994Q2HxSeQ-1; Fri, 12 Mar 2021 05:03:31 -0500 X-MC-Unique: y7vQeKOyPO6N994Q2HxSeQ-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id A7520817468 for ; Fri, 12 Mar 2021 10:03:30 +0000 (UTC) Received: from localhost (unknown [10.36.110.50]) by smtp.corp.redhat.com (Postfix) with ESMTP id C92F56B8E5; Fri, 12 Mar 2021 10:03:20 +0000 (UTC) From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH 13/27] console: save current scanout details Date: Fri, 12 Mar 2021 14:00:54 +0400 Message-Id: <20210312100108.2706195-14-marcandre.lureau@redhat.com> In-Reply-To: <20210312100108.2706195-1-marcandre.lureau@redhat.com> References: <20210312100108.2706195-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=63.128.21.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -29 X-Spam_score: -3.0 X-Spam_bar: --- X-Spam_report: (-3.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.25, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, 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: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Gerd Hoffmann Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau Add a new DisplayScanout structure to save the current scanout details. This allows to attach later UI backends and set the scanout. Introduce displaychangelistener_display_console() helper function to handle the dpy_gfx_switch/gl_scanout() & dpy_gfx_update() calls. Signed-off-by: Marc-André Lureau --- include/ui/console.h | 27 ++++++++ ui/console.c | 161 ++++++++++++++++++++++++++++--------------- 2 files changed, 134 insertions(+), 54 deletions(-) diff --git a/include/ui/console.h b/include/ui/console.h index 793f4c09ee..31141955d9 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -108,6 +108,17 @@ struct QemuConsoleClass { #define QEMU_ALLOCATED_FLAG 0x01 #define QEMU_PLACEHOLDER_FLAG 0x02 +typedef struct ScanoutTexture { + uint32_t backing_id; + bool backing_y_0_top; + uint32_t backing_width; + uint32_t backing_height; + uint32_t x; + uint32_t y; + uint32_t width; + uint32_t height; +} ScanoutTexture; + typedef struct DisplaySurface { pixman_format_code_t format; pixman_image_t *image; @@ -170,6 +181,22 @@ typedef struct QemuDmaBuf { bool y0_top; } QemuDmaBuf; +enum display_scanout { + SCANOUT_NONE, + SCANOUT_SURFACE, + SCANOUT_TEXTURE, + SCANOUT_DMABUF, +}; + +typedef struct DisplayScanout { + enum display_scanout kind; + union { + /* DisplaySurface *surface; is kept in QemuConsole */ + ScanoutTexture texture; + QemuDmaBuf *dmabuf; + }; +} DisplayScanout; + typedef struct DisplayState DisplayState; typedef struct DisplayGLCtx DisplayGLCtx; diff --git a/ui/console.c b/ui/console.c index 07357fd328..3c3be032ad 100644 --- a/ui/console.c +++ b/ui/console.c @@ -126,6 +126,7 @@ struct QemuConsole { console_type_t console_type; DisplayState *ds; DisplaySurface *surface; + DisplayScanout scanout; int dcls; DisplayGLCtx *gl; int gl_block; @@ -197,6 +198,7 @@ static void dpy_refresh(DisplayState *s); static DisplayState *get_alloc_displaystate(void); static void text_console_update_cursor_timer(void); static void text_console_update_cursor(void *opaque); +static bool displaychangelistener_has_dmabuf(DisplayChangeListener *dcl); static void gui_update(void *opaque) { @@ -532,6 +534,8 @@ static void text_console_resize(QemuConsole *s) TextCell *cells, *c, *c1; int w1, x, y, last_width; + assert(s->scanout.kind == SCANOUT_SURFACE); + last_width = s->width; s->width = surface_width(s->surface) / FONT_WIDTH; s->height = surface_height(s->surface) / FONT_HEIGHT; @@ -1103,6 +1107,45 @@ static void console_putchar(QemuConsole *s, int ch) } } +static void displaychangelistener_display_console(DisplayChangeListener *dcl, + QemuConsole *con) +{ + static const char nodev[] = + "This VM has no graphic display device."; + static DisplaySurface *dummy; + + if (!con) { + if (!dcl->ops->dpy_gfx_switch) { + return; + } + if (!dummy) { + dummy = qemu_create_placeholder_surface(640, 480, nodev); + } + dcl->ops->dpy_gfx_switch(dcl, dummy); + return; + } + + if (con->scanout.kind == SCANOUT_DMABUF && displaychangelistener_has_dmabuf(dcl)) { + dcl->ops->dpy_gl_scanout_dmabuf(dcl, con->scanout.dmabuf); + } else if (con->scanout.kind == SCANOUT_TEXTURE && dcl->ops->dpy_gl_scanout_texture) { + dcl->ops->dpy_gl_scanout_texture(dcl, + con->scanout.texture.backing_id, + con->scanout.texture.backing_y_0_top, + con->scanout.texture.backing_width, + con->scanout.texture.backing_height, + con->scanout.texture.x, + con->scanout.texture.y, + con->scanout.texture.width, + con->scanout.texture.height); + } else if (con->scanout.kind == SCANOUT_SURFACE && dcl->ops->dpy_gfx_switch) { + dcl->ops->dpy_gfx_switch(dcl, con->surface); + } + + dcl->ops->dpy_gfx_update(dcl, 0, 0, + qemu_console_get_width(con, 0), + qemu_console_get_height(con, 0)); +} + void console_select(unsigned int index) { DisplayChangeListener *dcl; @@ -1119,13 +1162,7 @@ void console_select(unsigned int index) if (dcl->con != NULL) { continue; } - if (dcl->ops->dpy_gfx_switch) { - dcl->ops->dpy_gfx_switch(dcl, s->surface); - } - } - if (s->surface) { - dpy_gfx_update(s, 0, 0, surface_width(s->surface), - surface_height(s->surface)); + displaychangelistener_display_console(dcl, s); } } if (ds->have_text) { @@ -1538,9 +1575,6 @@ static bool dpy_gl_compatible_with(QemuConsole *con, DisplayChangeListener *dcl) void register_displaychangelistener(DisplayChangeListener *dcl) { - static const char nodev[] = - "This VM has no graphic display device."; - static DisplaySurface *dummy; QemuConsole *con; Error *err = NULL; @@ -1567,16 +1601,7 @@ void register_displaychangelistener(DisplayChangeListener *dcl) } else { con = active_console; } - if (dcl->ops->dpy_gfx_switch) { - if (con) { - dcl->ops->dpy_gfx_switch(dcl, con->surface); - } else { - if (!dummy) { - dummy = qemu_create_placeholder_surface(640, 480, nodev); - } - dcl->ops->dpy_gfx_switch(dcl, dummy); - } - } + displaychangelistener_display_console(dcl, con); text_console_update_cursor(NULL); } @@ -1656,13 +1681,9 @@ void dpy_gfx_update(QemuConsole *con, int x, int y, int w, int h) { DisplayState *s = con->ds; DisplayChangeListener *dcl; - int width = w; - int height = h; + int width = qemu_console_get_width(con, x + w); + int height = qemu_console_get_height(con, y + h); - if (con->surface) { - width = surface_width(con->surface); - height = surface_height(con->surface); - } x = MAX(x, 0); y = MAX(y, 0); x = MIN(x, width); @@ -1685,12 +1706,10 @@ void dpy_gfx_update(QemuConsole *con, int x, int y, int w, int h) void dpy_gfx_update_full(QemuConsole *con) { - if (!con->surface) { - return; - } - dpy_gfx_update(con, 0, 0, - surface_width(con->surface), - surface_height(con->surface)); + int w = qemu_console_get_width(con, 0); + int h = qemu_console_get_height(con, 0); + + dpy_gfx_update(con, 0, 0, w, h); } void dpy_gfx_replace_surface(QemuConsole *con, @@ -1717,6 +1736,7 @@ void dpy_gfx_replace_surface(QemuConsole *con, assert(old_surface != surface); + con->scanout.kind = SCANOUT_SURFACE; con->surface = surface; QLIST_FOREACH(dcl, &s->listeners, next) { if (con != (dcl->con ? dcl->con : active_console)) { @@ -1892,6 +1912,9 @@ void dpy_gl_scanout_disable(QemuConsole *con) DisplayState *s = con->ds; DisplayChangeListener *dcl; + if (con->scanout.kind != SCANOUT_SURFACE) { + con->scanout.kind = SCANOUT_NONE; + } QLIST_FOREACH(dcl, &s->listeners, next) { dcl->ops->dpy_gl_scanout_disable(dcl); } @@ -1908,6 +1931,10 @@ void dpy_gl_scanout_texture(QemuConsole *con, DisplayState *s = con->ds; DisplayChangeListener *dcl; + con->scanout.kind = SCANOUT_TEXTURE; + con->scanout.texture = (ScanoutTexture) { + backing_id, backing_y_0_top, backing_width, backing_height, x, y, width, height + }; QLIST_FOREACH(dcl, &s->listeners, next) { dcl->ops->dpy_gl_scanout_texture(dcl, backing_id, backing_y_0_top, @@ -1922,6 +1949,8 @@ void dpy_gl_scanout_dmabuf(QemuConsole *con, DisplayState *s = con->ds; DisplayChangeListener *dcl; + con->scanout.kind = SCANOUT_DMABUF; + con->scanout.dmabuf = dmabuf; QLIST_FOREACH(dcl, &s->listeners, next) { dcl->ops->dpy_gl_scanout_dmabuf(dcl, dmabuf); } @@ -2048,10 +2077,8 @@ QemuConsole *graphic_console_init(DeviceState *dev, uint32_t head, s = qemu_console_lookup_unused(); if (s) { trace_console_gfx_reuse(s->index); - if (s->surface) { - width = surface_width(s->surface); - height = surface_height(s->surface); - } + width = qemu_console_get_width(s, 0); + height = qemu_console_get_height(s, 0); } else { trace_console_gfx_new(); s = new_console(ds, GRAPHIC_CONSOLE, head); @@ -2080,13 +2107,8 @@ void graphic_console_close(QemuConsole *con) static const char unplugged[] = "Guest display has been unplugged"; DisplaySurface *surface; - int width = 640; - int height = 480; - - if (con->surface) { - width = surface_width(con->surface); - height = surface_height(con->surface); - } + int width = qemu_console_get_width(con, 640); + int height = qemu_console_get_height(con, 480); trace_console_gfx_close(con->index); object_property_set_link(OBJECT(con), "device", NULL, &error_abort); @@ -2238,7 +2260,19 @@ int qemu_console_get_width(QemuConsole *con, int fallback) if (con == NULL) { con = active_console; } - return con ? surface_width(con->surface) : fallback; + if (con == NULL) { + return fallback; + } + switch (con->scanout.kind) { + case SCANOUT_DMABUF: + return con->scanout.dmabuf->width; + case SCANOUT_TEXTURE: + return con->scanout.texture.width; + case SCANOUT_SURFACE: + return surface_width(con->surface); + default: + return fallback; + } } int qemu_console_get_height(QemuConsole *con, int fallback) @@ -2246,7 +2280,19 @@ int qemu_console_get_height(QemuConsole *con, int fallback) if (con == NULL) { con = active_console; } - return con ? surface_height(con->surface) : fallback; + if (con == NULL) { + return fallback; + } + switch (con->scanout.kind) { + case SCANOUT_DMABUF: + return con->scanout.dmabuf->height; + case SCANOUT_TEXTURE: + return con->scanout.texture.height; + case SCANOUT_SURFACE: + return surface_height(con->surface); + default: + return fallback; + } } static void vc_chr_set_echo(Chardev *chr, bool echo) @@ -2306,12 +2352,13 @@ static void text_console_do_init(Chardev *chr, DisplayState *ds) s->total_height = DEFAULT_BACKSCROLL; s->x = 0; s->y = 0; - if (!s->surface) { - if (active_console && active_console->surface) { - g_width = surface_width(active_console->surface); - g_height = surface_height(active_console->surface); + if (s->scanout.kind != SCANOUT_SURFACE) { + if (active_console && active_console->scanout.kind == SCANOUT_SURFACE) { + g_width = qemu_console_get_width(active_console, g_width); + g_height = qemu_console_get_height(active_console, g_height); } s->surface = qemu_create_displaysurface(g_width, g_height); + s->scanout.kind = SCANOUT_SURFACE; } s->hw_ops = &text_console_ops; @@ -2370,6 +2417,7 @@ static void vc_chr_open(Chardev *chr, s = new_console(NULL, TEXT_CONSOLE, 0); } else { s = new_console(NULL, TEXT_CONSOLE_FIXED_SIZE, 0); + s->scanout.kind = SCANOUT_SURFACE; s->surface = qemu_create_displaysurface(width, height); } @@ -2393,13 +2441,13 @@ static void vc_chr_open(Chardev *chr, void qemu_console_resize(QemuConsole *s, int width, int height) { - DisplaySurface *surface; + DisplaySurface *surface = qemu_console_surface(s); assert(s->console_type == GRAPHIC_CONSOLE); - if (s->surface && (s->surface->flags & QEMU_ALLOCATED_FLAG) && - pixman_image_get_width(s->surface->image) == width && - pixman_image_get_height(s->surface->image) == height) { + if (surface && (surface->flags & QEMU_ALLOCATED_FLAG) && + pixman_image_get_width(surface->image) == width && + pixman_image_get_height(surface->image) == height) { return; } @@ -2409,7 +2457,12 @@ void qemu_console_resize(QemuConsole *s, int width, int height) DisplaySurface *qemu_console_surface(QemuConsole *console) { - return console->surface; + switch (console->scanout.kind) { + case SCANOUT_SURFACE: + return console->surface; + default: + return NULL; + } } PixelFormat qemu_default_pixelformat(int bpp) From patchwork Fri Mar 12 10:00:55 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 12134209 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,MENTIONS_GIT_HOSTING,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 316B7C433DB for ; Fri, 12 Mar 2021 10:22:12 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 8D7BE64FF3 for ; Fri, 12 Mar 2021 10:22:11 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 8D7BE64FF3 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:57616 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lKevq-00026Q-Dm for qemu-devel@archiver.kernel.org; Fri, 12 Mar 2021 05:22:10 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:34916) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lKeeF-00016e-OM for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:03:59 -0500 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:21087) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1lKee6-0003Li-9E for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:03:59 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1615543428; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=raAfJTt7SIJXtuPeXu6ObzdzXeSU3RI0/3D9VMQvfgU=; b=En0qt9AH6GCGocsVv5NoStV5KME9vskCLC6/Y/IWLWYd3pqtMWJryKuOJvqR3IFSvXlqZd P7DvmSRP7yq0g9EkjsC25TV3oN7uhVJhLMI5/I/YIsTLEOuEVDTEC+2xG/l/vhmY2sDLtQ KdZiNJCw/47ZEoMKU87Z2EJAKA09WmM= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-261-SyZQbrroP9ub73C5zMc2fA-1; Fri, 12 Mar 2021 05:03:44 -0500 X-MC-Unique: SyZQbrroP9ub73C5zMc2fA-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id B5E04E5760 for ; Fri, 12 Mar 2021 10:03:43 +0000 (UTC) Received: from localhost (unknown [10.36.110.50]) by smtp.corp.redhat.com (Postfix) with ESMTP id B475D69FB5; Fri, 12 Mar 2021 10:03:34 +0000 (UTC) From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH 14/27] ui: add a D-Bus display backend Date: Fri, 12 Mar 2021 14:00:55 +0400 Message-Id: <20210312100108.2706195-15-marcandre.lureau@redhat.com> In-Reply-To: <20210312100108.2706195-1-marcandre.lureau@redhat.com> References: <20210312100108.2706195-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=216.205.24.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -29 X-Spam_score: -3.0 X-Spam_bar: --- X-Spam_report: (-3.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.25, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, 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: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Gerd Hoffmann Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau The "dbus" ui/display backend exports the QEMU consoles over a currently unstable D-Bus protocol defined in ui/dbus-display1.xml (it is subject to changes at each releases, so only client shipped with the same QEMU release will be fully compatible). By default, the connection is done on the session bus, but you can specify a different bus with the "addr" option. The backend takes the "org.qemu" service name, while still allowing further instances to queue on the same name (so you can lookup all the available instances too). It accepts any number of clients at this point, although this is expected to evolve with options to restrict clients, or only accept p2p via fd passing. The interface is intentionally very close to the internal QEMU API, and can be introspected or interacted with busctl/dfeet etc: $ ./qemu-system-x86_64 -name MyVM -display dbus $ busctl --user introspect org.qemu /org/qemu/Display1/Console_0 org.qemu.Display1.Console interface - - - .RegisterListener method h - - .SetUIInfo method qqiiuu - - .DeviceAddress property s "pci/0000/01.0" emits-change .Head property u 0 emits-change .Height property u 480 emits-change .Label property s "VGA" emits-change .Type property s "Graphic" emits-change .Width property u 640 emits-change org.qemu.Display1.Keyboard interface - - - .Press method u - - .Release method u - - .Modifiers property u 0 emits-change writable org.qemu.Display1.Mouse interface - - - .Press method u - - .Release method u - - .SetAbsPosition method uu - - The "RegisterListener" method takes a FD as argument and expect the client to implement the org.qemu.Display1.Listener D-Bus p2p interface over it. This allows to notify of display updates, sending big chunk of data if necessary without going through the bus. However, DMABUF updates are preferred. Signed-off-by: Marc-André Lureau --- meson.build | 5 + qapi/ui.json | 24 ++- include/qemu/dbus.h | 20 ++ ui/dbus.h | 68 ++++++ ui/dbus-console.c | 457 ++++++++++++++++++++++++++++++++++++++++ ui/dbus-error.c | 45 ++++ ui/dbus-listener.c | 480 +++++++++++++++++++++++++++++++++++++++++++ ui/dbus.c | 255 +++++++++++++++++++++++ util/module.c | 2 + qemu-options.hx | 8 + ui/dbus-display1.xml | 123 +++++++++++ ui/meson.build | 17 ++ ui/trace-events | 11 + 13 files changed, 1513 insertions(+), 2 deletions(-) create mode 100644 ui/dbus.h create mode 100644 ui/dbus-console.c create mode 100644 ui/dbus-error.c create mode 100644 ui/dbus-listener.c create mode 100644 ui/dbus.c create mode 100644 ui/dbus-display1.xml diff --git a/meson.build b/meson.build index a7d2dd429d..b6f680bd34 100644 --- a/meson.build +++ b/meson.build @@ -1861,6 +1861,11 @@ if 'CONFIG_VHOST_USER' in config_host vhost_user = libvhost_user.get_variable('vhost_user_dep') endif +# FIXME enable_modules shouldn't be necessary, but: https://github.com/mesonbuild/meson/issues/8333 +if enable_modules and config_host.has_key('CONFIG_GIO') and config_host.has_key('GDBUS_CODEGEN') + config_host += {'CONFIG_UI_DBUS': 'y'} +endif + subdir('qapi') subdir('qobject') subdir('stubs') diff --git a/qapi/ui.json b/qapi/ui.json index d08d72b439..bdfab800c0 100644 --- a/qapi/ui.json +++ b/qapi/ui.json @@ -1068,6 +1068,23 @@ { 'struct' : 'DisplayEGLHeadless', 'data' : { '*rendernode' : 'str' } } +## +# @DisplayDBus: +# +# DBus display options. +# +# @addr: The D-Bus bus address (default to the session bus). +# +# @rendernode: Which DRM render node should be used. Default is the first +# available node on the host. +# +# Since: X.X +# +## +{ 'struct' : 'DisplayDBus', + 'data' : { '*rendernode' : 'str', + '*addr': 'str' } } + ## # @DisplayGLMode: # @@ -1133,13 +1150,15 @@ # application to connect to it. The server will redirect # the serial console and QEMU monitors. (Since 4.0) # +# @dbus: Start a D-Bus service for the display. (Since X.X) +# # Since: 2.12 # ## { 'enum' : 'DisplayType', 'data' : [ 'default', 'none', 'gtk', 'sdl', 'egl-headless', 'curses', 'cocoa', - 'spice-app'] } + 'spice-app', 'dbus'] } ## # @DisplayOptions: @@ -1165,7 +1184,8 @@ 'discriminator' : 'type', 'data' : { 'gtk' : 'DisplayGTK', 'curses' : 'DisplayCurses', - 'egl-headless' : 'DisplayEGLHeadless'} } + 'egl-headless' : 'DisplayEGLHeadless', + 'dbus' : 'DisplayDBus'} } ## # @query-display-options: diff --git a/include/qemu/dbus.h b/include/qemu/dbus.h index 9d591f9ee4..c2d7f55379 100644 --- a/include/qemu/dbus.h +++ b/include/qemu/dbus.h @@ -12,6 +12,26 @@ #include +/* glib/gio 2.68 */ +#define DBUS_METHOD_INVOCATION_HANDLED TRUE +#define DBUS_METHOD_INVOCATION_UNHANDLED FALSE + +/* in msec */ +#define DBUS_DEFAULT_TIMEOUT 1000 + +#define DBUS_DISPLAY1_ROOT "/org/qemu/Display1" + +#define DBUS_DISPLAY_ERROR (dbus_display_error_quark ()) +GQuark dbus_display_error_quark (void); + +typedef enum +{ + DBUS_DISPLAY_ERROR_FAILED, + DBUS_DISPLAY_ERROR_INVALID, + DBUS_DISPLAY_ERROR_UNSUPPORTED, + DBUS_DISPLAY_N_ERRORS, +} DBusDisplayError; + GStrv qemu_dbus_get_queued_owners(GDBusConnection *connection, const char *name, Error **errp); diff --git a/ui/dbus.h b/ui/dbus.h new file mode 100644 index 0000000000..f554084a27 --- /dev/null +++ b/ui/dbus.h @@ -0,0 +1,68 @@ +/* + * QEMU DBus display + * + * Copyright (c) 2021 Marc-André Lureau + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#ifndef UI_DBUS_H_ +#define UI_DBUS_H_ + +#include "qemu/dbus.h" +#include "qom/object.h" +#include "ui/console.h" + +#include "dbus-display1.h" + +struct DBusDisplay { + Object parent; + + DisplayGLMode gl_mode; + char *dbus_addr; + DisplayGLCtx glctx; + + GDBusConnection *bus; + GDBusObjectManagerServer *server; + DBusDisplayDisplay1VM *iface; + GPtrArray *consoles; +}; + +#define TYPE_DBUS_DISPLAY "dbus-display" +OBJECT_DECLARE_SIMPLE_TYPE(DBusDisplay, DBUS_DISPLAY) + +#define DBUS_DISPLAY_TYPE_CONSOLE dbus_display_console_get_type() +G_DECLARE_FINAL_TYPE(DBusDisplayConsole, dbus_display_console, DBUS_DISPLAY, CONSOLE, GDBusObjectSkeleton) + +DBusDisplayConsole *dbus_display_console_new(DBusDisplay *display, QemuConsole *con); +int dbus_display_console_get_index(DBusDisplayConsole *self); + +#define DBUS_DISPLAY_TYPE_LISTENER dbus_display_listener_get_type() +G_DECLARE_FINAL_TYPE(DBusDisplayListener, dbus_display_listener, DBUS_DISPLAY, LISTENER, GObject) + +DBusDisplayListener *dbus_display_listener_new(const char *bus_name, + GDBusConnection *conn, + DBusDisplayConsole *console); + +DBusDisplayConsole *dbus_display_listener_get_console(DBusDisplayListener *self); +const char *dbus_display_listener_get_bus_name(DBusDisplayListener *self); + +extern const DisplayChangeListenerOps dbus_gl_dcl_ops; +extern const DisplayChangeListenerOps dbus_dcl_ops; + +#endif /* UI_DBUS_H_ */ diff --git a/ui/dbus-console.c b/ui/dbus-console.c new file mode 100644 index 0000000000..3487a8f5cb --- /dev/null +++ b/ui/dbus-console.c @@ -0,0 +1,457 @@ +/* + * QEMU DBus display console + * + * Copyright (c) 2021 Marc-André Lureau + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "ui/input.h" +#include "ui/kbd-state.h" +#include "trace.h" + +#include + +#include "dbus.h" + +struct _DBusDisplayConsole { + GDBusObjectSkeleton parent_instance; + DisplayChangeListener dcl; + + DBusDisplay *display; + QemuConsole *con; + GHashTable *listeners; + DBusDisplayDisplay1Console *iface; + + DBusDisplayDisplay1Keyboard *iface_kbd; + QKbdState *kbd; + + DBusDisplayDisplay1Mouse *iface_mouse; + gboolean last_set; + guint last_x; + guint last_y; +}; + +G_DEFINE_TYPE(DBusDisplayConsole, dbus_display_console, G_TYPE_DBUS_OBJECT_SKELETON) + +static void +dbus_display_console_set_size(DBusDisplayConsole *self, uint32_t width, uint32_t height) +{ + g_object_set(self->iface, + "width", width, + "height", height, + NULL); +} + +static void +dbus_gfx_switch(DisplayChangeListener *dcl, + struct DisplaySurface *new_surface) +{ + DBusDisplayConsole *self = container_of(dcl, DBusDisplayConsole, dcl); + + dbus_display_console_set_size(self, + surface_width(new_surface), + surface_height(new_surface)); +} + +static void +dbus_gfx_update(DisplayChangeListener *dcl, + int x, int y, int w, int h) +{ +} + +static void +dbus_gl_scanout_disable(DisplayChangeListener *dcl) +{ +} + +static void +dbus_gl_scanout_texture(DisplayChangeListener *dcl, + uint32_t tex_id, + bool backing_y_0_top, + uint32_t backing_width, + uint32_t backing_height, + uint32_t x, uint32_t y, + uint32_t w, uint32_t h) +{ + DBusDisplayConsole *self = container_of(dcl, DBusDisplayConsole, dcl); + + dbus_display_console_set_size(self, w, h); +} + +static void +dbus_gl_scanout_dmabuf(DisplayChangeListener *dcl, + QemuDmaBuf *dmabuf) +{ + DBusDisplayConsole *self = container_of(dcl, DBusDisplayConsole, dcl); + + dbus_display_console_set_size(self, + dmabuf->width, + dmabuf->height); +} + +static void +dbus_gl_scanout_update(DisplayChangeListener *dcl, + uint32_t x, uint32_t y, + uint32_t w, uint32_t h) +{ +} + +static const DisplayChangeListenerOps dbus_console_dcl_ops = { + .dpy_name = "dbus-console", + .dpy_gfx_switch = dbus_gfx_switch, + .dpy_gfx_update = dbus_gfx_update, + .dpy_gl_scanout_disable = dbus_gl_scanout_disable, + .dpy_gl_scanout_texture = dbus_gl_scanout_texture, + .dpy_gl_scanout_dmabuf = dbus_gl_scanout_dmabuf, + .dpy_gl_update = dbus_gl_scanout_update, +}; + +static void +dbus_display_console_init(DBusDisplayConsole *object) +{ + DBusDisplayConsole *self = DBUS_DISPLAY_CONSOLE(object); + + self->listeners = g_hash_table_new_full(g_str_hash, g_str_equal, + NULL, g_object_unref); + self->dcl.ops = &dbus_console_dcl_ops; +} + +static void +dbus_display_console_dispose(GObject *object) +{ + DBusDisplayConsole *self = DBUS_DISPLAY_CONSOLE(object); + + unregister_displaychangelistener(&self->dcl); + g_clear_object(&self->iface_kbd); + g_clear_object(&self->iface); + g_clear_pointer(&self->listeners, g_hash_table_unref); + g_clear_pointer(&self->kbd, qkbd_state_free); + + G_OBJECT_CLASS(dbus_display_console_parent_class)->dispose(object); +} + +static void +dbus_display_console_class_init(DBusDisplayConsoleClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = dbus_display_console_dispose; +} + +static void +listener_vanished_cb(DBusDisplayListener *listener) +{ + DBusDisplayConsole *self = dbus_display_listener_get_console(listener); + const char *name = dbus_display_listener_get_bus_name(listener); + + trace_dbus_listener_vanished(name); + + g_hash_table_remove(self->listeners, name); + qkbd_state_lift_all_keys(self->kbd); +} + +static gboolean +dbus_console_set_ui_info(DBusDisplayConsole *self, + GDBusMethodInvocation *invocation, + guint16 arg_width_mm, + guint16 arg_height_mm, + gint arg_xoff, + gint arg_yoff, + guint arg_width, + guint arg_height) +{ + QemuUIInfo info = { + .width_mm = arg_width_mm, + .height_mm = arg_height_mm, + .xoff = arg_xoff, + .yoff = arg_yoff, + .width = arg_width, + .height = arg_height, + }; + + if (!dpy_ui_info_supported(self->con)) { + g_dbus_method_invocation_return_error(invocation, + DBUS_DISPLAY_ERROR, + DBUS_DISPLAY_ERROR_UNSUPPORTED, + "SetUIInfo is not supported by guest"); + return DBUS_METHOD_INVOCATION_HANDLED; + } + + dpy_set_ui_info(self->con, &info); + dbus_display_display1_console_complete_set_uiinfo(self->iface, invocation); + return DBUS_METHOD_INVOCATION_HANDLED; +} + +static gboolean +dbus_console_register_listener(DBusDisplayConsole *self, + GDBusMethodInvocation *invocation, + GUnixFDList *fd_list, + GVariant *arg_listener) +{ + const char *sender = g_dbus_method_invocation_get_sender(invocation); + GDBusConnection *listener_conn; + g_autoptr(GError) err = NULL; + g_autoptr(GSocket) socket = NULL; + g_autoptr(GSocketConnection) socket_conn = NULL; + g_autofree char *guid = g_dbus_generate_guid(); + DBusDisplayListener *listener; + int fd; + + if (g_hash_table_contains(self->listeners, sender)) { + g_dbus_method_invocation_return_error(invocation, + DBUS_DISPLAY_ERROR, + DBUS_DISPLAY_ERROR_INVALID, + "`%s` is already registered!", + sender); + return DBUS_METHOD_INVOCATION_HANDLED; + } + + fd = g_unix_fd_list_get(fd_list, g_variant_get_handle(arg_listener), &err); + if (err) { + g_dbus_method_invocation_return_error(invocation, + DBUS_DISPLAY_ERROR, + DBUS_DISPLAY_ERROR_FAILED, + "Couldn't get peer fd: %s", err->message); + return DBUS_METHOD_INVOCATION_HANDLED; + } + + socket = g_socket_new_from_fd(fd, &err); + if (err) { + g_dbus_method_invocation_return_error(invocation, + DBUS_DISPLAY_ERROR, + DBUS_DISPLAY_ERROR_FAILED, + "Couldn't make a socket: %s", err->message); + close(fd); + return DBUS_METHOD_INVOCATION_HANDLED; + } + socket_conn = g_socket_connection_factory_create_connection(socket); + /* return now: easier for the other end, as it may handle priv dbus synchronously */ + dbus_display_display1_console_complete_register_listener(self->iface, invocation, NULL); + + listener_conn = g_dbus_connection_new_sync(G_IO_STREAM(socket_conn), + guid, + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER, + NULL, NULL, &err); + if (err) { + error_report("Failed to setup peer connection: %s", err->message); + return DBUS_METHOD_INVOCATION_HANDLED; + } + + listener = dbus_display_listener_new(sender, listener_conn, self); + if (!listener) { + return DBUS_METHOD_INVOCATION_HANDLED; + } + + g_hash_table_insert(self->listeners, + (gpointer)dbus_display_listener_get_bus_name(listener), + listener); + g_object_connect(listener_conn, + "swapped-signal::closed", listener_vanished_cb, listener, + NULL); + + trace_dbus_registered_listener(sender); + return DBUS_METHOD_INVOCATION_HANDLED; +} + +static gboolean +dbus_kbd_press(DBusDisplayConsole *self, + GDBusMethodInvocation *invocation, + guint arg_keycode) +{ + QKeyCode qcode = qemu_input_key_number_to_qcode(arg_keycode); + + trace_dbus_kbd_press(arg_keycode); + + qkbd_state_key_event(self->kbd, qcode, true); + + dbus_display_display1_keyboard_complete_press(self->iface_kbd, invocation); + + return DBUS_METHOD_INVOCATION_HANDLED; +} + +static gboolean +dbus_kbd_release(DBusDisplayConsole *self, + GDBusMethodInvocation *invocation, + guint arg_keycode) +{ + QKeyCode qcode = qemu_input_key_number_to_qcode(arg_keycode); + + trace_dbus_kbd_release(arg_keycode); + + qkbd_state_key_event(self->kbd, qcode, false); + + dbus_display_display1_keyboard_complete_release(self->iface_kbd, invocation); + + return DBUS_METHOD_INVOCATION_HANDLED; +} + +static void +dbus_kbd_modifiers_changed(DBusDisplayConsole *self, + GParamSpec *pspec) +{ + guint modifiers = dbus_display_display1_keyboard_get_modifiers(self->iface_kbd); + + trace_dbus_kbd_modifiers_changed(modifiers); +} + +static void +dbus_kbd_qemu_leds_updated(void *data, int ledstate) +{ + DBusDisplayConsole *self = DBUS_DISPLAY_CONSOLE(data); + + // FIXME: what about self->kbd state? + dbus_display_display1_keyboard_set_modifiers(self->iface_kbd, ledstate); +} + +static gboolean +dbus_mouse_set_pos(DBusDisplayConsole *self, + GDBusMethodInvocation *invocation, + guint x, guint y) +{ + int width, height; + + trace_dbus_mouse_set_pos(x, y); + + width = qemu_console_get_width(self->con, 0); + height = qemu_console_get_height(self->con, 0); + if (qemu_input_is_absolute()) { + if (x >= width || y >= height) { + g_dbus_method_invocation_return_error(invocation, + DBUS_DISPLAY_ERROR, + DBUS_DISPLAY_ERROR_INVALID, + "Invalid mouse position"); + return DBUS_METHOD_INVOCATION_HANDLED; + } + qemu_input_queue_abs(self->con, INPUT_AXIS_X, x, 0, width); + qemu_input_queue_abs(self->con, INPUT_AXIS_Y, y, 0, height); + qemu_input_event_sync(); + } else if (self->last_set) { + qemu_input_queue_rel(self->con, INPUT_AXIS_X, x - self->last_x); + qemu_input_queue_rel(self->con, INPUT_AXIS_Y, y - self->last_y); + qemu_input_event_sync(); + } + + self->last_x = x; + self->last_y = y; + self->last_set = TRUE; + + dbus_display_display1_mouse_complete_set_abs_position(self->iface_mouse, invocation); + + return DBUS_METHOD_INVOCATION_HANDLED; +} + +static gboolean +dbus_mouse_press(DBusDisplayConsole *self, + GDBusMethodInvocation *invocation, + guint button) +{ + trace_dbus_mouse_press(button); + + qemu_input_queue_btn(self->con, button, true); + qemu_input_event_sync(); + + dbus_display_display1_mouse_complete_press(self->iface_mouse, invocation); + + return DBUS_METHOD_INVOCATION_HANDLED; +} + +static gboolean +dbus_mouse_release(DBusDisplayConsole *self, + GDBusMethodInvocation *invocation, + guint button) +{ + trace_dbus_mouse_release(button); + + qemu_input_queue_btn(self->con, button, false); + qemu_input_event_sync(); + + dbus_display_display1_mouse_complete_release(self->iface_mouse, invocation); + + return DBUS_METHOD_INVOCATION_HANDLED; +} + +int dbus_display_console_get_index(DBusDisplayConsole *self) +{ + return qemu_console_get_index(self->con); +} + +DBusDisplayConsole * +dbus_display_console_new(DBusDisplay *display, QemuConsole *con) +{ + g_autofree char *path = NULL; + g_autofree char *label = NULL; + char device_addr[256] = ""; + DBusDisplayConsole *self; + int idx; + + assert(display); + assert(con); + + label = qemu_console_get_label(con); + idx = qemu_console_get_index(con); + path = g_strdup_printf(DBUS_DISPLAY1_ROOT "/Console_%d", idx); + self = g_object_new(DBUS_DISPLAY_TYPE_CONSOLE, + "g-object-path", path, + NULL); + self->display = display; + self->con = con; + /* we should handle errors, and skip non graphics? */ + qemu_console_fill_device_address(con, device_addr, sizeof(device_addr), NULL); + + self->iface = dbus_display_display1_console_skeleton_new(); + g_object_set(self->iface, + "label", label, + "type", qemu_console_is_graphic(con) ? "Graphic" : "Text", + "head", qemu_console_get_head(con), + "width", qemu_console_get_width(con, 0), + "height", qemu_console_get_height(con, 0), + "device-address", device_addr, + NULL); + g_object_connect(self->iface, + "swapped-signal::handle-register-listener", dbus_console_register_listener, self, + "swapped-signal::handle-set-uiinfo", dbus_console_set_ui_info, self, + NULL); + g_dbus_object_skeleton_add_interface(G_DBUS_OBJECT_SKELETON(self), + G_DBUS_INTERFACE_SKELETON(self->iface)); + + self->kbd = qkbd_state_init(con); + self->iface_kbd = dbus_display_display1_keyboard_skeleton_new(); + qemu_add_led_event_handler(dbus_kbd_qemu_leds_updated, self); + g_object_connect(self->iface_kbd, + "swapped-signal::handle-press", dbus_kbd_press, self, + "swapped-signal::handle-release", dbus_kbd_release, self, + "swapped-signal::notify::modifiers", dbus_kbd_modifiers_changed, self, + NULL); + g_dbus_object_skeleton_add_interface(G_DBUS_OBJECT_SKELETON(self), + G_DBUS_INTERFACE_SKELETON(self->iface_kbd)); + + self->iface_mouse = dbus_display_display1_mouse_skeleton_new(); + g_object_connect(self->iface_mouse, + "swapped-signal::handle-set-abs-position", dbus_mouse_set_pos, self, + "swapped-signal::handle-press", dbus_mouse_press, self, + "swapped-signal::handle-release", dbus_mouse_release, self, + NULL); + g_dbus_object_skeleton_add_interface(G_DBUS_OBJECT_SKELETON(self), + G_DBUS_INTERFACE_SKELETON(self->iface_mouse)); + + register_displaychangelistener(&self->dcl); + return self; +} diff --git a/ui/dbus-error.c b/ui/dbus-error.c new file mode 100644 index 0000000000..9575bb6aa9 --- /dev/null +++ b/ui/dbus-error.c @@ -0,0 +1,45 @@ +/* + * QEMU DBus display errors + * + * Copyright (c) 2021 Marc-André Lureau + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include "qemu/osdep.h" +#include "dbus.h" + +static const GDBusErrorEntry dbus_display_error_entries[] = +{ + { DBUS_DISPLAY_ERROR_FAILED, "org.qemu.Display1.Error.Failed" }, + { DBUS_DISPLAY_ERROR_INVALID, "org.qemu.Display1.Error.Invalid" }, + { DBUS_DISPLAY_ERROR_UNSUPPORTED, "org.qemu.Display1.Error.Unsupported" }, +}; + +G_STATIC_ASSERT(G_N_ELEMENTS(dbus_display_error_entries) == DBUS_DISPLAY_N_ERRORS); + +GQuark +dbus_display_error_quark(void) +{ + static volatile gsize quark_volatile = 0; + g_dbus_error_register_error_domain("dbus-display-error-quark", + &quark_volatile, + dbus_display_error_entries, + G_N_ELEMENTS(dbus_display_error_entries)); + return (GQuark)quark_volatile; +} diff --git a/ui/dbus-listener.c b/ui/dbus-listener.c new file mode 100644 index 0000000000..2ef8e0e921 --- /dev/null +++ b/ui/dbus-listener.c @@ -0,0 +1,480 @@ +/* + * QEMU DBus display console + * + * Copyright (c) 2021 Marc-André Lureau + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include "qemu/osdep.h" +#include "sysemu/sysemu.h" +#include "dbus.h" +#include + +#include "ui/shader.h" +#include "ui/egl-helpers.h" +#include "ui/egl-context.h" +#include "trace.h" + +struct _DBusDisplayListener +{ + GObject parent; + + char *bus_name; + DBusDisplayConsole *console; + GDBusConnection *conn; + + DBusDisplayDisplay1Listener *proxy; + + DisplayChangeListener dcl; + DisplaySurface *ds; + QemuGLShader *gls; + int gl_updates; +}; + +G_DEFINE_TYPE(DBusDisplayListener, dbus_display_listener, G_TYPE_OBJECT) + +static void dbus_update_gl_cb(GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + g_autoptr(GError) err = NULL; + DBusDisplayListener *self = user_data; + + if (!dbus_display_display1_listener_call_update_dmabuf_finish(self->proxy, res, &err)) { + error_report("Failed to call update: %s", err->message); + } + + graphic_hw_gl_block(self->dcl.con, false); + g_object_unref(self); +} + +static void dbus_call_update_gl(DBusDisplayListener *self, + int x, int y, int w, int h) +{ + graphic_hw_gl_block(self->dcl.con, true); + glFlush(); + dbus_display_display1_listener_call_update_dmabuf(self->proxy, + x, y, w, h, + G_DBUS_CALL_FLAGS_NONE, + DBUS_DEFAULT_TIMEOUT, NULL, + dbus_update_gl_cb, + g_object_ref(self)); +} + +static void dbus_scanout_disable(DisplayChangeListener *dcl) +{ + DBusDisplayListener *self = container_of(dcl, DBusDisplayListener, dcl); + + self->ds = NULL; + dbus_display_display1_listener_call_disable( + self->proxy, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); +} + +static void dbus_scanout_dmabuf(DisplayChangeListener *dcl, + QemuDmaBuf *dmabuf) +{ + DBusDisplayListener *self = container_of(dcl, DBusDisplayListener, dcl); + g_autoptr(GError) err = NULL; + g_autoptr(GUnixFDList) fd_list = NULL; + + fd_list = g_unix_fd_list_new(); + if (g_unix_fd_list_append(fd_list, dmabuf->fd, &err) != 0) { + error_report("Failed to setup dmabuf fdlist: %s", err->message); + return; + } + + dbus_display_display1_listener_call_scanout_dmabuf( + self->proxy, + g_variant_new_handle(0), + dmabuf->width, + dmabuf->height, + dmabuf->stride, + dmabuf->fourcc, + dmabuf->modifier, + dmabuf->y0_top, + G_DBUS_CALL_FLAGS_NONE, + -1, + fd_list, + NULL, NULL, NULL); +} + +static void dbus_scanout_texture(DisplayChangeListener *dcl, + uint32_t tex_id, + bool backing_y_0_top, + uint32_t backing_width, + uint32_t backing_height, + uint32_t x, uint32_t y, + uint32_t w, uint32_t h) +{ + QemuDmaBuf dmabuf = { + .width = backing_width, + .height = backing_height, + .y0_top = backing_y_0_top, + }; + + assert(tex_id); + dmabuf.fd = egl_get_fd_for_texture(tex_id, (EGLint *)&dmabuf.stride, + (EGLint *)&dmabuf.fourcc, &dmabuf.modifier); + if (dmabuf.fd < 0) { + error_report("%s: failed to get fd for texture", __func__); + return; + } + + dbus_scanout_dmabuf(dcl, &dmabuf); + close(dmabuf.fd); +} + +static void dbus_cursor_dmabuf(DisplayChangeListener *dcl, + QemuDmaBuf *dmabuf, bool have_hot, + uint32_t hot_x, uint32_t hot_y) +{ + DBusDisplayListener *self = container_of(dcl, DBusDisplayListener, dcl); + DisplaySurface *ds; + GVariant *v_data = NULL; + egl_fb cursor_fb; + + if (!dmabuf) { + dbus_display_display1_listener_call_mouse_set( + self->proxy, 0, 0, false, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); + return; + } + + egl_dmabuf_import_texture(dmabuf); + if (!dmabuf->texture) { + return; + } + egl_fb_setup_for_tex(&cursor_fb, dmabuf->width, dmabuf->height, + dmabuf->texture, false); + ds = qemu_create_displaysurface(dmabuf->width, dmabuf->height); + egl_fb_read(ds, &cursor_fb); + + v_data = g_variant_new_from_data( + G_VARIANT_TYPE("ay"), + surface_data(ds), + surface_width(ds) * surface_height(ds) * 4, + TRUE, + (GDestroyNotify)qemu_free_displaysurface, + ds); + dbus_display_display1_listener_call_cursor_define( + self->proxy, + surface_width(ds), + surface_height(ds), + hot_x, + hot_y, + v_data, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + NULL, + NULL); +} + +static void dbus_cursor_position(DisplayChangeListener *dcl, + uint32_t pos_x, uint32_t pos_y) +{ + DBusDisplayListener *self = container_of(dcl, DBusDisplayListener, dcl); + + dbus_display_display1_listener_call_mouse_set( + self->proxy, pos_x, pos_y, true, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); +} + +static void dbus_release_dmabuf(DisplayChangeListener *dcl, + QemuDmaBuf *dmabuf) +{ + dbus_scanout_disable(dcl); +} + +static void dbus_scanout_update(DisplayChangeListener *dcl, + uint32_t x, uint32_t y, + uint32_t w, uint32_t h) +{ + DBusDisplayListener *self = container_of(dcl, DBusDisplayListener, dcl); + + dbus_call_update_gl(self, x, y, w, h); +} + +static void dbus_gl_refresh(DisplayChangeListener *dcl) +{ + DBusDisplayListener *self = container_of(dcl, DBusDisplayListener, dcl); + + if (!self->ds || qemu_console_is_gl_blocked(self->dcl.con)) { + return; + } + + graphic_hw_update(dcl->con); + if (self->gl_updates) { + dbus_call_update_gl(self, 0, 0, + surface_width(self->ds), surface_height(self->ds)); + self->gl_updates = 0; + } +} + +static void dbus_refresh(DisplayChangeListener *dcl) +{ + graphic_hw_update(dcl->con); +} + +static void dbus_gl_gfx_update(DisplayChangeListener *dcl, + int x, int y, int w, int h) +{ + DBusDisplayListener *self = container_of(dcl, DBusDisplayListener, dcl); + + if (self->ds) { + surface_gl_update_texture(self->gls, self->ds, x, y, w, h); + } + + self->gl_updates++; +} + +static void dbus_gfx_update(DisplayChangeListener *dcl, + int x, int y, int w, int h) +{ + DBusDisplayListener *self = container_of(dcl, DBusDisplayListener, dcl); + pixman_image_t *img; + GVariant *v_data; + size_t stride; + + assert(self->ds); + stride = w * DIV_ROUND_UP(PIXMAN_FORMAT_BPP(surface_format(self->ds)), 8); + + trace_dbus_update(x, y, w, h); + + /* make a copy, since gvariant only handles linear data */ + img = pixman_image_create_bits(surface_format(self->ds), + w, h, NULL, stride); + pixman_image_composite(PIXMAN_OP_SRC, self->ds->image, NULL, img, + x, y, 0, 0, 0, 0, w, h); + + v_data = g_variant_new_from_data( + G_VARIANT_TYPE("ay"), + pixman_image_get_data(img), + pixman_image_get_stride(img) * h, + TRUE, + (GDestroyNotify)pixman_image_unref, + img); + dbus_display_display1_listener_call_update(self->proxy, + x, y, w, h, pixman_image_get_stride(img), pixman_image_get_format(img), + v_data, + G_DBUS_CALL_FLAGS_NONE, + DBUS_DEFAULT_TIMEOUT, NULL, NULL, NULL); +} + +static void dbus_gl_gfx_switch(DisplayChangeListener *dcl, + struct DisplaySurface *new_surface) +{ + DBusDisplayListener *self = container_of(dcl, DBusDisplayListener, dcl); + + if (self->ds) { + surface_gl_destroy_texture(self->gls, self->ds); + } + self->ds = new_surface; + if (self->ds) { + int width = surface_width(self->ds); + int height = surface_height(self->ds); + + surface_gl_create_texture(self->gls, self->ds); + dbus_scanout_texture(&self->dcl, self->ds->texture, true, + width, height, 0, 0, width, height); + } +} + +static void dbus_gfx_switch(DisplayChangeListener *dcl, + struct DisplaySurface *new_surface) +{ + DBusDisplayListener *self = container_of(dcl, DBusDisplayListener, dcl); + GVariant *v_data = NULL; + + self->ds = new_surface; + if (!self->ds) { + /* why not call disable instead? */ + return; + } + + v_data = g_variant_new_from_data( + G_VARIANT_TYPE("ay"), + surface_data(self->ds), + surface_stride(self->ds) * surface_height(self->ds), + TRUE, + (GDestroyNotify)pixman_image_unref, + pixman_image_ref(self->ds->image)); + dbus_display_display1_listener_call_scanout(self->proxy, + surface_width(self->ds), + surface_height(self->ds), + surface_stride(self->ds), + surface_format(self->ds), + v_data, + G_DBUS_CALL_FLAGS_NONE, + DBUS_DEFAULT_TIMEOUT, NULL, NULL, NULL); +} + +static void dbus_mouse_set(DisplayChangeListener *dcl, + int x, int y, int on) +{ + DBusDisplayListener *self = container_of(dcl, DBusDisplayListener, dcl); + + dbus_display_display1_listener_call_mouse_set( + self->proxy, x, y, on, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); +} + +static void dbus_cursor_define(DisplayChangeListener *dcl, + QEMUCursor *c) +{ + DBusDisplayListener *self = container_of(dcl, DBusDisplayListener, dcl); + GVariant *v_data = NULL; + + cursor_get(c); + v_data = g_variant_new_from_data( + G_VARIANT_TYPE("ay"), + c->data, + c->width * c->height * 4, + TRUE, + (GDestroyNotify)cursor_put, + c); + + dbus_display_display1_listener_call_cursor_define( + self->proxy, + c->width, + c->height, + c->hot_x, + c->hot_y, + v_data, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + NULL, + NULL); +} + +const DisplayChangeListenerOps dbus_gl_dcl_ops = { + .dpy_name = "dbus-gl", + .dpy_gfx_update = dbus_gl_gfx_update, + .dpy_gfx_switch = dbus_gl_gfx_switch, + .dpy_gfx_check_format = console_gl_check_format, + .dpy_refresh = dbus_gl_refresh, + .dpy_mouse_set = dbus_mouse_set, + .dpy_cursor_define = dbus_cursor_define, + + .dpy_gl_scanout_disable = dbus_scanout_disable, + .dpy_gl_scanout_texture = dbus_scanout_texture, + .dpy_gl_scanout_dmabuf = dbus_scanout_dmabuf, + .dpy_gl_cursor_dmabuf = dbus_cursor_dmabuf, + .dpy_gl_cursor_position = dbus_cursor_position, + .dpy_gl_release_dmabuf = dbus_release_dmabuf, + .dpy_gl_update = dbus_scanout_update, +}; + +const DisplayChangeListenerOps dbus_dcl_ops = { + .dpy_name = "dbus", + .dpy_gfx_update = dbus_gfx_update, + .dpy_gfx_switch = dbus_gfx_switch, + .dpy_refresh = dbus_refresh, + .dpy_mouse_set = dbus_mouse_set, + .dpy_cursor_define = dbus_cursor_define, +}; + +static void +dbus_display_listener_dispose(GObject *object) +{ + DBusDisplayListener *self = DBUS_DISPLAY_LISTENER(object); + + unregister_displaychangelistener(&self->dcl); + g_clear_object(&self->conn); + g_clear_pointer(&self->bus_name, g_free); + g_clear_object(&self->proxy); + g_clear_pointer(&self->gls, qemu_gl_fini_shader); + + G_OBJECT_CLASS(dbus_display_listener_parent_class)->dispose(object); +} + +static void +dbus_display_listener_constructed(GObject *object) +{ + DBusDisplayListener *self = DBUS_DISPLAY_LISTENER(object); + + if (display_opengl) { + self->gls = qemu_gl_init_shader(); + self->dcl.ops = &dbus_gl_dcl_ops; + } else { + self->dcl.ops = &dbus_dcl_ops; + } + + G_OBJECT_CLASS(dbus_display_listener_parent_class)->constructed(object); +} + +static void +dbus_display_listener_class_init(DBusDisplayListenerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS(klass); + + object_class->dispose = dbus_display_listener_dispose; + object_class->constructed = dbus_display_listener_constructed; +} + +static void +dbus_display_listener_init(DBusDisplayListener *self) +{ +} + +const char * +dbus_display_listener_get_bus_name(DBusDisplayListener *self) +{ + return self->bus_name; +} + +DBusDisplayConsole * +dbus_display_listener_get_console(DBusDisplayListener *self) +{ + return self->console; +} + +DBusDisplayListener * +dbus_display_listener_new(const char *bus_name, + GDBusConnection *conn, + DBusDisplayConsole *console) +{ + DBusDisplayListener *self; + QemuConsole *con; + g_autoptr(GError) err = NULL; + + self = g_object_new(DBUS_DISPLAY_TYPE_LISTENER, NULL); + self->proxy = + dbus_display_display1_listener_proxy_new_sync(conn, + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + NULL, + "/org/qemu/Display1/Listener", + NULL, + &err); + if (!self->proxy) { + error_report("Failed to setup proxy: %s", err->message); + g_object_unref(conn); + g_object_unref(self); + return NULL; + } + + self->bus_name = g_strdup(bus_name); + self->conn = conn; + self->console = console; + + con = qemu_console_lookup_by_index(dbus_display_console_get_index(console)); + assert(con); + self->dcl.con = con; + register_displaychangelistener(&self->dcl); + + return self; +} diff --git a/ui/dbus.c b/ui/dbus.c new file mode 100644 index 0000000000..089a92cedf --- /dev/null +++ b/ui/dbus.c @@ -0,0 +1,255 @@ +/* + * QEMU DBus display + * + * Copyright (c) 2021 Marc-André Lureau + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include "qemu/osdep.h" +#include "qemu/dbus.h" +#include "qemu/option.h" +#include "qom/object_interfaces.h" +#include "sysemu/sysemu.h" +#include "ui/egl-helpers.h" +#include "ui/egl-context.h" +#include "qapi/error.h" +#include "trace.h" + +#include "dbus.h" + +static QEMUGLContext dbus_create_context(DisplayGLCtx *dgc, + QEMUGLParams *params) +{ + eglMakeCurrent(qemu_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, + qemu_egl_rn_ctx); + return qemu_egl_create_context(dgc, params); +} + +static const DisplayGLCtxOps dbus_gl_ops = { + .compatible_dcl = &dbus_gl_dcl_ops, + .dpy_gl_ctx_create = dbus_create_context, + .dpy_gl_ctx_destroy = qemu_egl_destroy_context, + .dpy_gl_ctx_make_current = qemu_egl_make_context_current, +}; + +static void +dbus_display_init(Object *o) +{ + DBusDisplay *self = DBUS_DISPLAY(o); + g_autoptr(GDBusObjectSkeleton) vm = NULL; + + self->glctx.ops = &dbus_gl_ops; + self->iface = dbus_display_display1_vm_skeleton_new(); + self->consoles = g_ptr_array_new_with_free_func(g_object_unref); + + self->server = g_dbus_object_manager_server_new(DBUS_DISPLAY1_ROOT); + + vm = g_dbus_object_skeleton_new(DBUS_DISPLAY1_ROOT "/VM"); + g_dbus_object_skeleton_add_interface(vm, G_DBUS_INTERFACE_SKELETON(self->iface)); + g_dbus_object_manager_server_export(self->server, vm); +} + +static void +dbus_display_finalize(Object *o) +{ + DBusDisplay *self = DBUS_DISPLAY(o); + + g_clear_object(&self->server); + g_clear_pointer(&self->consoles, g_ptr_array_unref); + g_clear_object(&self->bus); + g_clear_object(&self->iface); + g_free(self->dbus_addr); +} + +static bool +dbus_display_add_console(DBusDisplay *self, int idx, Error **errp) +{ + QemuConsole *con; + DBusDisplayConsole *dbus_console; + + con = qemu_console_lookup_by_index(idx); + assert(con); + + if (qemu_console_is_graphic(con) && + self->gl_mode != DISPLAYGL_MODE_OFF) { + qemu_console_set_display_gl_ctx(con, &self->glctx); + } + + dbus_console = dbus_display_console_new(self, con); + g_ptr_array_insert(self->consoles, idx, dbus_console); + g_dbus_object_manager_server_export(self->server, + G_DBUS_OBJECT_SKELETON(dbus_console)); + return true; +} + +static void +dbus_display_complete(UserCreatable *uc, Error **errp) +{ + DBusDisplay *self = DBUS_DISPLAY(uc); + g_autoptr(GError) err = NULL; + g_autofree char *uuid = qemu_uuid_unparse_strdup(&qemu_uuid); + g_autoptr(GArray) consoles = NULL; + GVariant *console_ids; + int idx; + + if (!object_resolve_path_type("", TYPE_DBUS_DISPLAY, NULL)) { + error_setg(errp, "There is already an instance of %s", + TYPE_DBUS_DISPLAY); + return; + } + + if (self->dbus_addr && *self->dbus_addr) { + self->bus = g_dbus_connection_new_for_address_sync(self->dbus_addr, + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT | + G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION, + NULL, NULL, &err); + } else { + self->bus = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &err); + } + if (err) { + error_setg(errp, "failed to connect to DBus: %s", err->message); + return; + } + + + consoles = g_array_new(FALSE, FALSE, sizeof(guint32)); + for (idx = 0;; idx++) { + if (!qemu_console_lookup_by_index(idx)) { + break; + } + if (!dbus_display_add_console(self, idx, errp)) { + return; + } + g_array_append_val(consoles, idx); + } + + console_ids = g_variant_new_from_data(G_VARIANT_TYPE("au"), + consoles->data, consoles->len * sizeof(guint32), TRUE, + (GDestroyNotify)g_array_unref, consoles); + g_steal_pointer(&consoles); + g_object_set(self->iface, + "name", qemu_name ?: "QEMU " QEMU_VERSION, + "uuid", uuid, + "console-ids", console_ids, + NULL); + + g_dbus_object_manager_server_set_connection(self->server, self->bus); + g_bus_own_name_on_connection(self->bus, "org.qemu", G_BUS_NAME_OWNER_FLAGS_NONE, + NULL, NULL, NULL, NULL); +} + +static char * +get_dbus_addr(Object *o, Error **errp) +{ + DBusDisplay *self = DBUS_DISPLAY(o); + + return g_strdup(self->dbus_addr); +} + +static void +set_dbus_addr(Object *o, const char *str, Error **errp) +{ + DBusDisplay *self = DBUS_DISPLAY(o); + + g_free(self->dbus_addr); + self->dbus_addr = g_strdup(str); +} + +static int +get_gl_mode(Object *o, Error **errp) +{ + DBusDisplay *self = DBUS_DISPLAY(o); + + return self->gl_mode; +} + +static void +set_gl_mode(Object *o, int val, Error **errp) +{ + DBusDisplay *self = DBUS_DISPLAY(o); + + self->gl_mode = val; +} + +static void +dbus_display_class_init(ObjectClass *oc, void *data) +{ + UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc); + + ucc->complete = dbus_display_complete; + object_class_property_add_str(oc, "addr", get_dbus_addr, set_dbus_addr); + object_class_property_add_enum(oc, "gl-mode", + "DisplayGLMode", &DisplayGLMode_lookup, + get_gl_mode, set_gl_mode); +} + +static void +early_dbus_init(DisplayOptions *opts) +{ + DisplayGLMode mode = opts->has_gl ? opts->gl : DISPLAYGL_MODE_OFF; + + if (mode != DISPLAYGL_MODE_OFF) { + if (egl_rendernode_init(opts->u.dbus.rendernode, mode) < 0) { + error_report("dbus: render node init failed"); + exit(1); + } + + display_opengl = 1; + } +} + +static void +dbus_init(DisplayState *ds, DisplayOptions *opts) +{ + DisplayGLMode mode = opts->has_gl ? opts->gl : DISPLAYGL_MODE_OFF; + + object_new_with_props(TYPE_DBUS_DISPLAY, + object_get_objects_root(), + "dbus-display", &error_fatal, + "addr", opts->u.dbus.addr ?: "", + "gl-mode", DisplayGLMode_str(mode), + NULL); +} + +static const TypeInfo dbus_display_info = { + .name = TYPE_DBUS_DISPLAY, + .parent = TYPE_OBJECT, + .instance_size = sizeof(DBusDisplay), + .instance_init = dbus_display_init, + .instance_finalize = dbus_display_finalize, + .class_init = dbus_display_class_init, + .interfaces = (InterfaceInfo[]) { + { TYPE_USER_CREATABLE }, + { } + } +}; + +static QemuDisplay qemu_display_dbus = { + .type = DISPLAY_TYPE_DBUS, + .early_init = early_dbus_init, + .init = dbus_init, +}; + +static void register_dbus(void) +{ + type_register_static(&dbus_display_info); + qemu_display_register(&qemu_display_dbus); +} + +type_init(register_dbus); diff --git a/util/module.c b/util/module.c index c65060c167..f228067d0d 100644 --- a/util/module.c +++ b/util/module.c @@ -183,6 +183,7 @@ static const struct { { "ui-spice-app", "chardev-spice" }, #ifdef CONFIG_OPENGL + { "ui-dbus", "ui-opengl" }, { "ui-egl-headless", "ui-opengl" }, { "ui-gtk", "ui-opengl" }, { "ui-sdl", "ui-opengl" }, @@ -294,6 +295,7 @@ static struct { const char *prefix; const char *module; } const qom_modules[] = { + { "dbus-display", "backends-", "dbus" }, { "ccid-card-passthru", "hw-", "usb-smartcard" }, { "ccid-card-emulated", "hw-", "usb-smartcard" }, { "usb-redir", "hw-", "usb-redirect" }, diff --git a/qemu-options.hx b/qemu-options.hx index 90801286c6..9b42f15f53 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -1765,6 +1765,10 @@ DEF("display", HAS_ARG, QEMU_OPTION_display, #endif #if defined(CONFIG_OPENGL) "-display egl-headless[,rendernode=]\n" +#endif +#if defined(CONFIG_UI_DBUS) + "-display dbus[,addr=]\n" + " [,gl=on|core|es|off][,rendernode=]\n" #endif "-display none\n" " select display backend type\n" @@ -1827,6 +1831,10 @@ SRST Start QEMU as a Spice server and launch the default Spice client application. The Spice server will redirect the serial consoles and QEMU monitors. (Since 4.0) + + ``dbus`` + Start a D-Bus service for the display. (Since X.X) + ERST DEF("nographic", 0, QEMU_OPTION_nographic, diff --git a/ui/dbus-display1.xml b/ui/dbus-display1.xml new file mode 100644 index 0000000000..df2ffcea07 --- /dev/null +++ b/ui/dbus-display1.xml @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ui/meson.build b/ui/meson.build index 97cdd58856..fe75c40f38 100644 --- a/ui/meson.build +++ b/ui/meson.build @@ -59,6 +59,23 @@ if config_host.has_key('CONFIG_OPENGL') and gbm.found() ui_modules += {'egl-headless' : egl_headless_ss} endif +if 'CONFIG_UI_DBUS' in config_host + dbus_ss = ss.source_set() + dbus_display1 = custom_target('dbus-display gdbus-codegen', + output: ['dbus-display1.h', 'dbus-display1.c'], + input: files('dbus-display1.xml'), + command: [config_host['GDBUS_CODEGEN'], + '@INPUT@', + '--glib-min-required', '2.64', + '--output-directory', meson.current_build_dir(), + '--interface-prefix', 'org.qemu.', + '--c-namespace', 'DBusDisplay', + '--generate-c-code', '@BASENAME@']).to_list() + dbus_ss.add(when: [gio, pixman, opengl, 'CONFIG_GIO'], + if_true: files('dbus.c', 'dbus-console.c', 'dbus-listener.c', 'dbus-error.c') + dbus_display1) + ui_modules += {'dbus' : dbus_ss} +endif + if gtk.found() softmmu_ss.add(when: 'CONFIG_WIN32', if_true: files('win32-kbd-hook.c')) diff --git a/ui/trace-events b/ui/trace-events index 0ffcdb4408..a821f51dc3 100644 --- a/ui/trace-events +++ b/ui/trace-events @@ -108,3 +108,14 @@ xkeymap_extension(const char *name) "extension '%s'" xkeymap_vendor(const char *name) "vendor '%s'" xkeymap_keycodes(const char *name) "keycodes '%s'" xkeymap_keymap(const char *name) "keymap '%s'" + +# dbus.c +dbus_registered_listener(const char *bus_name) "peer %s" +dbus_listener_vanished(const char *bus_name) "peer %s" +dbus_kbd_press(unsigned int keycode) "keycode %u" +dbus_kbd_release(unsigned int keycode) "keycode %u" +dbus_kbd_modifiers_changed(unsigned int modifiers) "modifiers %u" +dbus_mouse_press(unsigned int button) "button %u" +dbus_mouse_release(unsigned int button) "button %u" +dbus_mouse_set_pos(unsigned int x, unsigned int y) "x=%u, y=%u" +dbus_update(int x, int y, int w, int h) "x=%d, y=%d, w=%d, h=%d" From patchwork Fri Mar 12 10:00:56 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 12134191 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5373BC433E9 for ; Fri, 12 Mar 2021 10:13:00 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id C29DA64FD6 for ; Fri, 12 Mar 2021 10:12:59 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C29DA64FD6 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:56338 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lKemw-0005ji-UG for qemu-devel@archiver.kernel.org; Fri, 12 Mar 2021 05:12:58 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:35000) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lKeeM-0001LZ-4d for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:04:06 -0500 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:47708) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1lKeeI-0003Uz-1j for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:04:05 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1615543441; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=qHnosIXKjvzFtSo+7EI3ABq8vVTZ7AUUA6q/EsWmcj8=; b=hgyHYPtnuhXnHDJUOiNtmA3S2HrnHzzN9sFG4AvKuQk/zwWoYSM5zAAf/81CsV5ch1HwH2 7s9aOxraRMZ7tur5eODqtfqNxDXA1ztqlVRPfbavk2AHFLTx8xBLmY5QTrLSTiyj8Fe6oU dYcJOmP6X74yOCiZa6clitg5tHzoZBM= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-400-cIytvRogPB6QVUvokTRcXA-1; Fri, 12 Mar 2021 05:03:58 -0500 X-MC-Unique: cIytvRogPB6QVUvokTRcXA-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 8709A19200C0 for ; Fri, 12 Mar 2021 10:03:57 +0000 (UTC) Received: from localhost (unknown [10.36.110.50]) by smtp.corp.redhat.com (Postfix) with ESMTP id E8FC45C1C5; Fri, 12 Mar 2021 10:03:47 +0000 (UTC) From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH 15/27] audio: add dbusaudio backend Date: Fri, 12 Mar 2021 14:00:56 +0400 Message-Id: <20210312100108.2706195-16-marcandre.lureau@redhat.com> In-Reply-To: <20210312100108.2706195-1-marcandre.lureau@redhat.com> References: <20210312100108.2706195-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=63.128.21.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -29 X-Spam_score: -3.0 X-Spam_bar: --- X-Spam_report: (-3.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.25, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, 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: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Gerd Hoffmann Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau Add a new -audio backend that accepts DBus clients/listeners to handle playback & recording, to be exported via the -display dbus. Example usage: -audiodev dbus,in.mixing-engine=off,out.mixing-engine=off,id=dbus -display dbus,audiodev=dbus Signed-off-by: Marc-André Lureau --- qapi/audio.json | 3 +- qapi/ui.json | 7 +- audio/audio_int.h | 7 + audio/audio_template.h | 2 + ui/dbus.h | 1 + audio/audio.c | 1 + audio/dbusaudio.c | 649 +++++++++++++++++++++++++++++++++++++++++ ui/dbus.c | 35 +++ util/module.c | 1 + audio/meson.build | 3 +- audio/trace-events | 5 + qemu-options.hx | 3 + ui/dbus-display1.xml | 82 ++++++ 13 files changed, 795 insertions(+), 4 deletions(-) create mode 100644 audio/dbusaudio.c diff --git a/qapi/audio.json b/qapi/audio.json index 9cba0df8a4..693e327c6b 100644 --- a/qapi/audio.json +++ b/qapi/audio.json @@ -386,7 +386,7 @@ # Since: 4.0 ## { 'enum': 'AudiodevDriver', - 'data': [ 'none', 'alsa', 'coreaudio', 'dsound', 'jack', 'oss', 'pa', + 'data': [ 'none', 'alsa', 'coreaudio', 'dbus', 'dsound', 'jack', 'oss', 'pa', 'sdl', 'spice', 'wav' ] } ## @@ -412,6 +412,7 @@ 'none': 'AudiodevGenericOptions', 'alsa': 'AudiodevAlsaOptions', 'coreaudio': 'AudiodevCoreaudioOptions', + 'dbus': 'AudiodevGenericOptions', 'dsound': 'AudiodevDsoundOptions', 'jack': 'AudiodevJackOptions', 'oss': 'AudiodevOssOptions', diff --git a/qapi/ui.json b/qapi/ui.json index bdfab800c0..0344f75f69 100644 --- a/qapi/ui.json +++ b/qapi/ui.json @@ -1078,12 +1078,15 @@ # @rendernode: Which DRM render node should be used. Default is the first # available node on the host. # +# @audiodev: Use the specified DBus audiodev to export audio. +# # Since: X.X # ## { 'struct' : 'DisplayDBus', - 'data' : { '*rendernode' : 'str', - '*addr': 'str' } } + 'data' : { '*rendernode': 'str', + '*addr': 'str', + '*audiodev': 'str' } } ## # @DisplayGLMode: diff --git a/audio/audio_int.h b/audio/audio_int.h index 06f0913835..294c7f2342 100644 --- a/audio/audio_int.h +++ b/audio/audio_int.h @@ -31,6 +31,10 @@ #endif #include "mixeng.h" +#ifdef CONFIG_GIO +#include +#endif + struct audio_pcm_ops; struct audio_callback { @@ -140,6 +144,9 @@ struct audio_driver { const char *descr; void *(*init) (Audiodev *); void (*fini) (void *); +#ifdef CONFIG_GIO + void (*set_dbus_server) (AudioState *s, GDBusObjectManagerServer *manager); +#endif struct audio_pcm_ops *pcm_ops; int can_be_default; int max_voices_out; diff --git a/audio/audio_template.h b/audio/audio_template.h index c6714946aa..d2d348638b 100644 --- a/audio/audio_template.h +++ b/audio/audio_template.h @@ -327,6 +327,8 @@ AudiodevPerDirectionOptions *glue(audio_get_pdo_, TYPE)(Audiodev *dev) case AUDIODEV_DRIVER_COREAUDIO: return qapi_AudiodevCoreaudioPerDirectionOptions_base( dev->u.coreaudio.TYPE); + case AUDIODEV_DRIVER_DBUS: + return dev->u.dbus.TYPE; case AUDIODEV_DRIVER_DSOUND: return dev->u.dsound.TYPE; case AUDIODEV_DRIVER_JACK: diff --git a/ui/dbus.h b/ui/dbus.h index f554084a27..10a019564f 100644 --- a/ui/dbus.h +++ b/ui/dbus.h @@ -35,6 +35,7 @@ struct DBusDisplay { DisplayGLMode gl_mode; char *dbus_addr; + char *audiodev; DisplayGLCtx glctx; GDBusConnection *bus; diff --git a/audio/audio.c b/audio/audio.c index 6734c8af70..fbcf676e78 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -1989,6 +1989,7 @@ void audio_create_pdos(Audiodev *dev) CASE(NONE, none, ); CASE(ALSA, alsa, Alsa); CASE(COREAUDIO, coreaudio, Coreaudio); + CASE(DBUS, dbus, ); CASE(DSOUND, dsound, ); CASE(JACK, jack, Jack); CASE(OSS, oss, Oss); diff --git a/audio/dbusaudio.c b/audio/dbusaudio.c new file mode 100644 index 0000000000..4f1e51d951 --- /dev/null +++ b/audio/dbusaudio.c @@ -0,0 +1,649 @@ +/* + * QEMU DBus audio + * + * Copyright (c) 2021 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "qemu/osdep.h" +#include "qemu/error-report.h" +#include "qemu/host-utils.h" +#include "qemu/module.h" +#include "qemu/timer.h" +#include "qemu/dbus.h" + +#include +#include "ui/dbus-display1.h" + +#define AUDIO_CAP "dbus" +#include "audio.h" +#include "audio_int.h" +#include "trace.h" + +#define DBUS_DISPLAY1_AUDIO DBUS_DISPLAY1_ROOT "/Audio" + +#define DBUS_AUDIO_NSAMPLES 1024 /* could be configured? */ + +typedef struct DBusAudio { + GDBusObjectManagerServer *server; + GDBusObjectSkeleton *audio; + DBusDisplayDisplay1Audio *iface; + GHashTable *out_listeners; + GHashTable *in_listeners; +} DBusAudio; + +typedef struct DBusVoiceOut { + HWVoiceOut hw; + bool enabled; + RateCtl rate; + + void *buf; + size_t buf_pos; + size_t buf_size; + + bool has_volume; + Volume volume; +} DBusVoiceOut; + +typedef struct DBusVoiceIn { + HWVoiceIn hw; + bool enabled; + RateCtl rate; + + bool has_volume; + Volume volume; +} DBusVoiceIn; + +static void *dbus_get_buffer_out(HWVoiceOut *hw, size_t *size) +{ + DBusVoiceOut *vo = container_of(hw, DBusVoiceOut, hw); + + if (!vo->buf) { + vo->buf_size = hw->samples * hw->info.bytes_per_frame; + vo->buf = g_malloc(vo->buf_size); + vo->buf_pos = 0; + } + + *size = MIN(vo->buf_size - vo->buf_pos, *size); + *size = audio_rate_get_bytes(&hw->info, &vo->rate, *size); + + return vo->buf + vo->buf_pos; + +} + +static size_t dbus_put_buffer_out(HWVoiceOut *hw, void *buf, size_t size) +{ + DBusAudio *da = (DBusAudio *)hw->s->drv_opaque; + DBusVoiceOut *vo = container_of(hw, DBusVoiceOut, hw); + GHashTableIter iter; + DBusDisplayDisplay1AudioOutListener *listener = NULL; + g_autoptr(GBytes) bytes = NULL; + g_autoptr(GVariant) v_data = NULL; + + assert(buf == vo->buf + vo->buf_pos && vo->buf_pos + size <= vo->buf_size); + vo->buf_pos += size; + + trace_dbus_put_buffer_out(size); + + if (vo->buf_pos < vo->buf_size) { + return size; + } + + bytes = g_bytes_new_take(g_steal_pointer(&vo->buf), vo->buf_size); + v_data = g_variant_new_from_bytes(G_VARIANT_TYPE("ay"), bytes, TRUE); + g_variant_ref_sink(v_data); + + g_hash_table_iter_init(&iter, da->out_listeners); + while (g_hash_table_iter_next(&iter, NULL, (void **)&listener)) { + dbus_display_display1_audio_out_listener_call_write( + listener, + (uintptr_t)hw, + v_data, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); + } + + return size; +} + +#ifdef HOST_WORDS_BIGENDIAN +#define AUDIO_HOST_BE TRUE +#else +#define AUDIO_HOST_BE FALSE +#endif + +static void +dbus_init_out_listener(DBusDisplayDisplay1AudioOutListener *listener, HWVoiceOut *hw) +{ + dbus_display_display1_audio_out_listener_call_init( + listener, + (uintptr_t)hw, + hw->info.bits, + hw->info.is_signed, + hw->info.is_float, + hw->info.freq, + hw->info.nchannels, + hw->info.bytes_per_frame, + hw->info.bytes_per_second, + hw->info.swap_endianness ? !AUDIO_HOST_BE : AUDIO_HOST_BE, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); +} + +static int +dbus_init_out(HWVoiceOut *hw, struct audsettings *as, void *drv_opaque) +{ + DBusAudio *da = (DBusAudio *)hw->s->drv_opaque; + DBusVoiceOut *vo = container_of(hw, DBusVoiceOut, hw); + GHashTableIter iter; + DBusDisplayDisplay1AudioOutListener *listener = NULL; + + audio_pcm_init_info(&hw->info, as); + hw->samples = DBUS_AUDIO_NSAMPLES; + audio_rate_start(&vo->rate); + + g_hash_table_iter_init(&iter, da->out_listeners); + while (g_hash_table_iter_next(&iter, NULL, (void **)&listener)) { + dbus_init_out_listener(listener, hw); + } + return 0; +} + +static void +dbus_fini_out(HWVoiceOut *hw) +{ + DBusAudio *da = (DBusAudio *)hw->s->drv_opaque; + DBusVoiceOut *vo = container_of(hw, DBusVoiceOut, hw); + GHashTableIter iter; + DBusDisplayDisplay1AudioOutListener *listener = NULL; + + g_hash_table_iter_init(&iter, da->out_listeners); + while (g_hash_table_iter_next(&iter, NULL, (void **)&listener)) { + dbus_display_display1_audio_out_listener_call_fini( + listener, + (uintptr_t)hw, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); + } + + g_clear_pointer(&vo->buf, g_free); +} + +static void +dbus_enable_out(HWVoiceOut *hw, bool enable) +{ + DBusAudio *da = (DBusAudio *)hw->s->drv_opaque; + DBusVoiceOut *vo = container_of(hw, DBusVoiceOut, hw); + GHashTableIter iter; + DBusDisplayDisplay1AudioOutListener *listener = NULL; + + vo->enabled = enable; + if (enable) { + audio_rate_start(&vo->rate); + } + + g_hash_table_iter_init(&iter, da->out_listeners); + while (g_hash_table_iter_next(&iter, NULL, (void **)&listener)) { + dbus_display_display1_audio_out_listener_call_set_enabled( + listener, (uintptr_t)hw, enable, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); + } +} + +static void +dbus_volume_out_listener(HWVoiceOut *hw, + DBusDisplayDisplay1AudioOutListener *listener) +{ + DBusVoiceOut *vo = container_of(hw, DBusVoiceOut, hw); + Volume *vol = &vo->volume; + g_autoptr(GBytes) bytes = NULL; + GVariant *v_vol = NULL; + + if (!vo->has_volume) { + return; + } + + assert(vol->channels < sizeof(vol->vol)); + bytes = g_bytes_new(vol->vol, vol->channels); + v_vol = g_variant_new_from_bytes(G_VARIANT_TYPE("ay"), bytes, TRUE); + dbus_display_display1_audio_out_listener_call_set_volume( + listener, (uintptr_t)hw, vol->mute, v_vol, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); +} + +static void +dbus_volume_out(HWVoiceOut *hw, Volume *vol) +{ + DBusAudio *da = (DBusAudio *)hw->s->drv_opaque; + DBusVoiceOut *vo = container_of(hw, DBusVoiceOut, hw); + GHashTableIter iter; + DBusDisplayDisplay1AudioOutListener *listener = NULL; + + vo->has_volume = true; + vo->volume = *vol; + + g_hash_table_iter_init(&iter, da->out_listeners); + while (g_hash_table_iter_next(&iter, NULL, (void **)&listener)) { + dbus_volume_out_listener(hw, listener); + } +} + +static void +dbus_init_in_listener(DBusDisplayDisplay1AudioInListener *listener, HWVoiceIn *hw) +{ + dbus_display_display1_audio_in_listener_call_init( + listener, + (uintptr_t)hw, + hw->info.bits, + hw->info.is_signed, + hw->info.is_float, + hw->info.freq, + hw->info.nchannels, + hw->info.bytes_per_frame, + hw->info.bytes_per_second, + hw->info.swap_endianness ? !AUDIO_HOST_BE : AUDIO_HOST_BE, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); +} + +static int +dbus_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) +{ + DBusAudio *da = (DBusAudio *)hw->s->drv_opaque; + DBusVoiceIn *vo = container_of(hw, DBusVoiceIn, hw); + GHashTableIter iter; + DBusDisplayDisplay1AudioInListener *listener = NULL; + + audio_pcm_init_info(&hw->info, as); + hw->samples = DBUS_AUDIO_NSAMPLES; + audio_rate_start(&vo->rate); + + g_hash_table_iter_init(&iter, da->in_listeners); + while (g_hash_table_iter_next(&iter, NULL, (void **)&listener)) { + dbus_init_in_listener(listener, hw); + } + return 0; +} + +static void +dbus_fini_in(HWVoiceIn *hw) +{ + DBusAudio *da = (DBusAudio *)hw->s->drv_opaque; + GHashTableIter iter; + DBusDisplayDisplay1AudioInListener *listener = NULL; + + g_hash_table_iter_init(&iter, da->in_listeners); + while (g_hash_table_iter_next(&iter, NULL, (void **)&listener)) { + dbus_display_display1_audio_in_listener_call_fini( + listener, + (uintptr_t)hw, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); + } +} + +static void +dbus_volume_in_listener(HWVoiceIn *hw, + DBusDisplayDisplay1AudioInListener *listener) +{ + DBusVoiceIn *vo = container_of(hw, DBusVoiceIn, hw); + Volume *vol = &vo->volume; + g_autoptr(GBytes) bytes = NULL; + GVariant *v_vol = NULL; + + if (!vo->has_volume) { + return; + } + + assert(vol->channels < sizeof(vol->vol)); + bytes = g_bytes_new(vol->vol, vol->channels); + v_vol = g_variant_new_from_bytes(G_VARIANT_TYPE("ay"), bytes, TRUE); + dbus_display_display1_audio_in_listener_call_set_volume( + listener, (uintptr_t)hw, vol->mute, v_vol, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); +} + +static void +dbus_volume_in(HWVoiceIn *hw, Volume *vol) +{ + DBusAudio *da = (DBusAudio *)hw->s->drv_opaque; + DBusVoiceIn *vo = container_of(hw, DBusVoiceIn, hw); + GHashTableIter iter; + DBusDisplayDisplay1AudioInListener *listener = NULL; + + vo->has_volume = true; + vo->volume = *vol; + + g_hash_table_iter_init(&iter, da->in_listeners); + while (g_hash_table_iter_next(&iter, NULL, (void **)&listener)) { + dbus_volume_in_listener(hw, listener); + } +} + +static size_t +dbus_read(HWVoiceIn *hw, void *buf, size_t size) +{ + DBusAudio *da = (DBusAudio *)hw->s->drv_opaque; + /* DBusVoiceIn *vo = container_of(hw, DBusVoiceIn, hw); */ + GHashTableIter iter; + DBusDisplayDisplay1AudioInListener *listener = NULL; + + trace_dbus_read(size); + + /* size = audio_rate_get_bytes(&hw->info, &vo->rate, size); */ + + g_hash_table_iter_init(&iter, da->in_listeners); + while (g_hash_table_iter_next(&iter, NULL, (void **)&listener)) { + g_autoptr(GVariant) v_data = NULL; + const char *data; + gsize n = 0; + + if (dbus_display_display1_audio_in_listener_call_read_sync( + listener, + (uintptr_t)hw, + size, + G_DBUS_CALL_FLAGS_NONE, -1, + &v_data, NULL, NULL)) { + data = g_variant_get_fixed_array(v_data, &n, 1); + g_warn_if_fail(n <= size); + size = MIN(n, size); + memcpy(buf, data, size); + break; + } + } + + return size; +} + +static void +dbus_enable_in(HWVoiceIn *hw, bool enable) +{ + DBusAudio *da = (DBusAudio *)hw->s->drv_opaque; + DBusVoiceIn *vo = container_of(hw, DBusVoiceIn, hw); + GHashTableIter iter; + DBusDisplayDisplay1AudioInListener *listener = NULL; + + vo->enabled = enable; + if (enable) { + audio_rate_start(&vo->rate); + } + + g_hash_table_iter_init(&iter, da->in_listeners); + while (g_hash_table_iter_next(&iter, NULL, (void **)&listener)) { + dbus_display_display1_audio_in_listener_call_set_enabled( + listener, (uintptr_t)hw, enable, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); + } +} + +static void * +dbus_audio_init(Audiodev *dev) +{ + DBusAudio *self = g_new0(DBusAudio, 1); + + self->out_listeners = g_hash_table_new_full(g_str_hash, g_str_equal, + g_free, g_object_unref); + self->in_listeners = g_hash_table_new_full(g_str_hash, g_str_equal, + g_free, g_object_unref); + return self; +} + +static void +dbus_audio_fini(void *opaque) +{ + DBusAudio *self = opaque; + + if (self->server) { + g_dbus_object_manager_server_unexport(self->server, DBUS_DISPLAY1_AUDIO); + } + g_clear_object(&self->audio); + g_clear_object(&self->iface); + g_clear_pointer(&self->in_listeners, g_hash_table_unref); + g_clear_pointer(&self->out_listeners, g_hash_table_unref); + g_clear_object(&self->server); + g_free(self); +} + +static void +listener_out_vanished_cb(GDBusConnection *connection, + gboolean remote_peer_vanished, + GError *error, + DBusAudio *self) +{ + char *name = g_object_get_data(G_OBJECT(connection), "name"); + + g_hash_table_remove(self->out_listeners, name); +} + +static void +listener_in_vanished_cb(GDBusConnection *connection, + gboolean remote_peer_vanished, + GError *error, + DBusAudio *self) +{ + char *name = g_object_get_data(G_OBJECT(connection), "name"); + + g_hash_table_remove(self->in_listeners, name); +} + +static gboolean +dbus_audio_register_listener(AudioState *s, + GDBusMethodInvocation *invocation, + GUnixFDList *fd_list, + GVariant *arg_listener, + bool out) +{ + DBusAudio *self = s->drv_opaque; + const char *sender = g_dbus_method_invocation_get_sender(invocation); + g_autoptr(GDBusConnection) listener_conn = NULL; + g_autoptr(GError) err = NULL; + g_autoptr(GSocket) socket = NULL; + g_autoptr(GSocketConnection) socket_conn = NULL; + g_autofree char *guid = g_dbus_generate_guid(); + GHashTable *listeners = out ? self->out_listeners : self->in_listeners; + GObject *listener; + int fd; + + trace_dbus_register(sender, out ? "out" : "in"); + + if (g_hash_table_contains(listeners, sender)) { + g_dbus_method_invocation_return_error(invocation, + DBUS_DISPLAY_ERROR, + DBUS_DISPLAY_ERROR_INVALID, + "`%s` is already registered!", + sender); + return DBUS_METHOD_INVOCATION_HANDLED; + } + + fd = g_unix_fd_list_get(fd_list, g_variant_get_handle(arg_listener), &err); + if (err) { + g_dbus_method_invocation_return_error(invocation, + DBUS_DISPLAY_ERROR, + DBUS_DISPLAY_ERROR_FAILED, + "Couldn't get peer fd: %s", + err->message); + return DBUS_METHOD_INVOCATION_HANDLED; + } + + socket = g_socket_new_from_fd(fd, &err); + if (err) { + g_dbus_method_invocation_return_error(invocation, + DBUS_DISPLAY_ERROR, + DBUS_DISPLAY_ERROR_FAILED, + "Couldn't make a socket: %s", + err->message); + return DBUS_METHOD_INVOCATION_HANDLED; + } + socket_conn = g_socket_connection_factory_create_connection(socket); + if (out) { + dbus_display_display1_audio_complete_register_out_listener( + self->iface, invocation, NULL); + } else { + dbus_display_display1_audio_complete_register_in_listener( + self->iface, invocation, NULL); + } + + listener_conn = + g_dbus_connection_new_sync( + G_IO_STREAM(socket_conn), + guid, + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER, + NULL, NULL, &err); + if (err) { + error_report("Failed to setup peer connection: %s", err->message); + return DBUS_METHOD_INVOCATION_HANDLED; + } + + listener = out ? + G_OBJECT(dbus_display_display1_audio_out_listener_proxy_new_sync( + listener_conn, + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + NULL, + "/org/qemu/Display1/AudioOutListener", + NULL, + &err)) : + G_OBJECT(dbus_display_display1_audio_in_listener_proxy_new_sync( + listener_conn, + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + NULL, + "/org/qemu/Display1/AudioInListener", + NULL, + &err)); + if (!listener) { + error_report("Failed to setup proxy: %s", err->message); + return DBUS_METHOD_INVOCATION_HANDLED; + } + + if (out) { + HWVoiceOut *hw; + + QLIST_FOREACH(hw, &s->hw_head_out, entries) { + DBusVoiceOut *vo = container_of(hw, DBusVoiceOut, hw); + DBusDisplayDisplay1AudioOutListener *l = + DBUS_DISPLAY_DISPLAY1_AUDIO_OUT_LISTENER(listener); + + dbus_init_out_listener(l, hw); + dbus_display_display1_audio_out_listener_call_set_enabled( + l, (uintptr_t)hw, vo->enabled, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); + } + } else { + HWVoiceIn *hw; + + QLIST_FOREACH(hw, &s->hw_head_in, entries) { + DBusVoiceIn *vo = container_of(hw, DBusVoiceIn, hw); + DBusDisplayDisplay1AudioInListener *l = + DBUS_DISPLAY_DISPLAY1_AUDIO_IN_LISTENER(listener); + + dbus_init_in_listener(DBUS_DISPLAY_DISPLAY1_AUDIO_IN_LISTENER(listener), hw); + dbus_display_display1_audio_in_listener_call_set_enabled( + l, (uintptr_t)hw, vo->enabled, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); + } + } + + g_object_set_data_full(G_OBJECT(listener_conn), "name", + g_strdup(sender), g_free); + g_hash_table_insert(listeners, g_strdup(sender), listener); + g_object_connect(listener_conn, + "signal::closed", + out ? listener_out_vanished_cb : listener_in_vanished_cb, + self, + NULL); + + return DBUS_METHOD_INVOCATION_HANDLED; +} + +static gboolean +dbus_audio_register_out_listener(AudioState *s, + GDBusMethodInvocation *invocation, + GUnixFDList *fd_list, + GVariant *arg_listener) +{ + return dbus_audio_register_listener(s, invocation, + fd_list, arg_listener, true); + +} + +static gboolean +dbus_audio_register_in_listener(AudioState *s, + GDBusMethodInvocation *invocation, + GUnixFDList *fd_list, + GVariant *arg_listener) +{ + return dbus_audio_register_listener(s, invocation, + fd_list, arg_listener, false); +} + +static void +dbus_audio_set_server(AudioState *s, GDBusObjectManagerServer *server) +{ + DBusAudio *self = s->drv_opaque; + + g_assert(self); + g_assert(!self->server); + + self->server = g_object_ref(server); + + self->audio = g_dbus_object_skeleton_new(DBUS_DISPLAY1_AUDIO); + self->iface = g_object_new(DBUS_DISPLAY_TYPE_DISPLAY1_AUDIO_SKELETON, NULL); + g_object_connect(self->iface, + "swapped-signal::handle-register-in-listener", + dbus_audio_register_in_listener, s, + "swapped-signal::handle-register-out-listener", + dbus_audio_register_out_listener, s, + NULL); + + g_dbus_object_skeleton_add_interface(G_DBUS_OBJECT_SKELETON(self->audio), + G_DBUS_INTERFACE_SKELETON(self->iface)); + g_dbus_object_manager_server_export(self->server, self->audio); +} + +static struct audio_pcm_ops dbus_pcm_ops = { + .init_out = dbus_init_out, + .fini_out = dbus_fini_out, + .write = audio_generic_write, + .get_buffer_out = dbus_get_buffer_out, + .put_buffer_out = dbus_put_buffer_out, + .enable_out = dbus_enable_out, + .volume_out = dbus_volume_out, + + .init_in = dbus_init_in, + .fini_in = dbus_fini_in, + .read = dbus_read, + .run_buffer_in = audio_generic_run_buffer_in, + .enable_in = dbus_enable_in, + .volume_in = dbus_volume_in, +}; + +static struct audio_driver dbus_audio_driver = { + .name = "dbus", + .descr = "Timer based audio exposed with DBus interface", + .init = dbus_audio_init, + .fini = dbus_audio_fini, + .set_dbus_server = dbus_audio_set_server, + .pcm_ops = &dbus_pcm_ops, + .can_be_default = 1, + .max_voices_out = INT_MAX, + .max_voices_in = INT_MAX, + .voice_size_out = sizeof(DBusVoiceOut), + .voice_size_in = sizeof(DBusVoiceIn) +}; + +static void register_audio_dbus(void) +{ + audio_driver_register(&dbus_audio_driver); +} +type_init(register_audio_dbus); diff --git a/ui/dbus.c b/ui/dbus.c index 089a92cedf..cc0d0665f0 100644 --- a/ui/dbus.c +++ b/ui/dbus.c @@ -28,6 +28,8 @@ #include "sysemu/sysemu.h" #include "ui/egl-helpers.h" #include "ui/egl-context.h" +#include "audio/audio.h" +#include "audio/audio_int.h" #include "qapi/error.h" #include "trace.h" @@ -75,6 +77,7 @@ dbus_display_finalize(Object *o) g_clear_object(&self->bus); g_clear_object(&self->iface); g_free(self->dbus_addr); + g_free(self->audiodev); } static bool @@ -127,6 +130,18 @@ dbus_display_complete(UserCreatable *uc, Error **errp) return; } + if (self->audiodev && *self->audiodev) { + AudioState *audio_state = audio_state_by_name(self->audiodev); + if (!audio_state) { + error_setg(errp, "Audiodev '%s' not found", self->audiodev); + return; + } + if (!g_str_equal(audio_state->drv->name, "dbus")) { + error_setg(errp, "Audiodev '%s' is not compatible with DBus", self->audiodev); + return; + } + audio_state->drv->set_dbus_server(audio_state, self->server); + } consoles = g_array_new(FALSE, FALSE, sizeof(guint32)); for (idx = 0;; idx++) { @@ -171,6 +186,24 @@ set_dbus_addr(Object *o, const char *str, Error **errp) self->dbus_addr = g_strdup(str); } +static char * +get_audiodev(Object *o, Error **errp) +{ + DBusDisplay *self = DBUS_DISPLAY(o); + + return g_strdup(self->audiodev); +} + +static void +set_audiodev(Object *o, const char *str, Error **errp) +{ + DBusDisplay *self = DBUS_DISPLAY(o); + + g_free(self->audiodev); + self->audiodev = g_strdup(str); +} + + static int get_gl_mode(Object *o, Error **errp) { @@ -194,6 +227,7 @@ dbus_display_class_init(ObjectClass *oc, void *data) ucc->complete = dbus_display_complete; object_class_property_add_str(oc, "addr", get_dbus_addr, set_dbus_addr); + object_class_property_add_str(oc, "audiodev", get_audiodev, set_audiodev); object_class_property_add_enum(oc, "gl-mode", "DisplayGLMode", &DisplayGLMode_lookup, get_gl_mode, set_gl_mode); @@ -223,6 +257,7 @@ dbus_init(DisplayState *ds, DisplayOptions *opts) object_get_objects_root(), "dbus-display", &error_fatal, "addr", opts->u.dbus.addr ?: "", + "audiodev", opts->u.dbus.audiodev ?: "", "gl-mode", DisplayGLMode_str(mode), NULL); } diff --git a/util/module.c b/util/module.c index f228067d0d..858f13e86f 100644 --- a/util/module.c +++ b/util/module.c @@ -176,6 +176,7 @@ static const struct { const char *name; const char *dep; } module_deps[] = { + { "audio-dbus", "ui-dbus" }, { "audio-spice", "ui-spice-core" }, { "chardev-spice", "ui-spice-core" }, { "hw-display-qxl", "ui-spice-core" }, diff --git a/audio/meson.build b/audio/meson.build index 7d53b0f920..5eca175779 100644 --- a/audio/meson.build +++ b/audio/meson.build @@ -18,7 +18,8 @@ foreach m : [ ['CONFIG_AUDIO_PA', 'pa', pulse, 'paaudio.c'], ['CONFIG_AUDIO_SDL', 'sdl', sdl, 'sdlaudio.c'], ['CONFIG_AUDIO_JACK', 'jack', jack, 'jackaudio.c'], - ['CONFIG_SPICE', 'spice', spice, 'spiceaudio.c'] + ['CONFIG_SPICE', 'spice', spice, 'spiceaudio.c'], + ['CONFIG_UI_DBUS', 'dbus', gio, 'dbusaudio.c'], ] if config_host.has_key(m[0]) module_ss = ss.source_set() diff --git a/audio/trace-events b/audio/trace-events index 6aec535763..02d6d70ed3 100644 --- a/audio/trace-events +++ b/audio/trace-events @@ -13,6 +13,11 @@ alsa_resume_out(void) "Resuming suspended output stream" # ossaudio.c oss_version(int version) "OSS version = 0x%x" +# dbusaudio.c +dbus_register(const char *s, const char *dir) "sender = %s, dir = %s" +dbus_put_buffer_out(size_t len) "len = %zu" +dbus_read(size_t len) "len = %zu" + # audio.c audio_timer_start(int interval) "interval %d ms" audio_timer_stop(void) "" diff --git a/qemu-options.hx b/qemu-options.hx index 9b42f15f53..826dfc503d 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -616,6 +616,9 @@ DEF("audiodev", HAS_ARG, QEMU_OPTION_audiodev, #endif #ifdef CONFIG_SPICE "-audiodev spice,id=id[,prop[=value][,...]]\n" +#endif +#ifdef CONFIG_UI_DBUS + "-audiodev dbus,id=id[,prop[=value][,...]]\n" #endif "-audiodev wav,id=id[,prop[=value][,...]]\n" " path= path of wav file to record\n", diff --git a/ui/dbus-display1.xml b/ui/dbus-display1.xml index df2ffcea07..61afbed727 100644 --- a/ui/dbus-display1.xml +++ b/ui/dbus-display1.xml @@ -120,4 +120,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From patchwork Fri Mar 12 10:00:57 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 12134195 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7A7DBC433DB for ; Fri, 12 Mar 2021 10:14:58 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 22B5A64FE0 for ; Fri, 12 Mar 2021 10:14:58 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 22B5A64FE0 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:33774 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lKeor-0008DU-2L for qemu-devel@archiver.kernel.org; Fri, 12 Mar 2021 05:14:57 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:35070) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lKeeT-0001dQ-Mm for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:04:13 -0500 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:51734) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1lKeeR-0003bJ-W3 for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:04:13 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1615543451; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=cKRfBZkSvtMBQ2Oho3jsinCzQg5se417u2EKUQvW77M=; b=am9UNmqImte3aMRP6UK5XU9ORBSCSgBOtd2ByDPd3+R/rPAZ1iedpBcYUWJJ/9RsQQzk2y PPmNAt0QAhOYSG0PX5CDED8sxi5mg3TFxY3pU29erBJIedGQokM0q/MCdfmnpJP1mMmIlv awfGeYFfbz01PW3k9hoSCSCbbyi8/8Y= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-511-1Yk0i7P9MtaNC2rAMJlldA-1; Fri, 12 Mar 2021 05:04:09 -0500 X-MC-Unique: 1Yk0i7P9MtaNC2rAMJlldA-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 800BB107ACCD for ; Fri, 12 Mar 2021 10:04:08 +0000 (UTC) Received: from localhost (unknown [10.36.110.50]) by smtp.corp.redhat.com (Postfix) with ESMTP id C6CCA5DAA5; Fri, 12 Mar 2021 10:04:01 +0000 (UTC) From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH 16/27] vhost-user-gpu: add vg_send_disable_scanout() Date: Fri, 12 Mar 2021 14:00:57 +0400 Message-Id: <20210312100108.2706195-17-marcandre.lureau@redhat.com> In-Reply-To: <20210312100108.2706195-1-marcandre.lureau@redhat.com> References: <20210312100108.2706195-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=216.205.24.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -29 X-Spam_score: -3.0 X-Spam_bar: --- X-Spam_report: (-3.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.25, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, 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: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Gerd Hoffmann Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau Signed-off-by: Marc-André Lureau --- contrib/vhost-user-gpu/vugpu.h | 1 + contrib/vhost-user-gpu/vhost-user-gpu.c | 24 ++++++++++++++++-------- contrib/vhost-user-gpu/virgl.c | 8 +------- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/contrib/vhost-user-gpu/vugpu.h b/contrib/vhost-user-gpu/vugpu.h index 04d5615812..e19abb670d 100644 --- a/contrib/vhost-user-gpu/vugpu.h +++ b/contrib/vhost-user-gpu/vugpu.h @@ -179,5 +179,6 @@ void vg_send_msg(VuGpu *g, const VhostUserGpuMsg *msg, int fd); bool vg_recv_msg(VuGpu *g, uint32_t expect_req, uint32_t expect_size, gpointer payload); +void vg_send_disable_scanout(VuGpu *g, int scanout_id); #endif diff --git a/contrib/vhost-user-gpu/vhost-user-gpu.c b/contrib/vhost-user-gpu/vhost-user-gpu.c index f73f292c9f..69fedd376b 100644 --- a/contrib/vhost-user-gpu/vhost-user-gpu.c +++ b/contrib/vhost-user-gpu/vhost-user-gpu.c @@ -356,6 +356,21 @@ vg_resource_create_2d(VuGpu *g, QTAILQ_INSERT_HEAD(&g->reslist, res, next); } +void +vg_send_disable_scanout(VuGpu *g, int scanout_id) +{ + g_debug("send disable scanout %d", scanout_id); + + if (g->sock_fd >= 0) { + VhostUserGpuMsg msg = { + .request = VHOST_USER_GPU_SCANOUT, + .size = sizeof(VhostUserGpuScanout), + .payload.scanout.scanout_id = scanout_id, + }; + vg_send_msg(g, &msg, -1); + } +} + static void vg_disable_scanout(VuGpu *g, int scanout_id) { @@ -374,14 +389,7 @@ vg_disable_scanout(VuGpu *g, int scanout_id) scanout->width = 0; scanout->height = 0; - if (g->sock_fd >= 0) { - VhostUserGpuMsg msg = { - .request = VHOST_USER_GPU_SCANOUT, - .size = sizeof(VhostUserGpuScanout), - .payload.scanout.scanout_id = scanout_id, - }; - vg_send_msg(g, &msg, -1); - } + vg_send_disable_scanout(g, scanout_id); } static void diff --git a/contrib/vhost-user-gpu/virgl.c b/contrib/vhost-user-gpu/virgl.c index 9e6660c7ab..fe153425f5 100644 --- a/contrib/vhost-user-gpu/virgl.c +++ b/contrib/vhost-user-gpu/virgl.c @@ -354,13 +354,7 @@ virgl_cmd_set_scanout(VuGpu *g, vg_send_msg(g, &msg, fd); close(fd); } else { - VhostUserGpuMsg msg = { - .request = VHOST_USER_GPU_DMABUF_SCANOUT, - .size = sizeof(VhostUserGpuDMABUFScanout), - .payload.dmabuf_scanout.scanout_id = ss.scanout_id, - }; - g_debug("disable scanout"); - vg_send_msg(g, &msg, -1); + vg_send_disable_scanout(g, ss.scanout_id); } g->scanout[ss.scanout_id].resource_id = ss.resource_id; } From patchwork Fri Mar 12 10:00:58 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 12134211 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id EB7B6C433DB for ; Fri, 12 Mar 2021 10:24:34 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7D1C865002 for ; Fri, 12 Mar 2021 10:24:32 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 7D1C865002 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:38204 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lKey4-00067o-7e for qemu-devel@archiver.kernel.org; Fri, 12 Mar 2021 05:24:28 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:35120) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lKeeh-0001ot-31 for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:04:27 -0500 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:58356) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1lKeee-0003hR-ON for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:04:26 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1615543463; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=R6pxl5yDwflMgqVOKCxk4hLs6wLJ80bog2NQ9POr9wk=; b=a14/k9UcZxHioc2ZMJvvgSnGoCvHXwVQM5SrLHCAAxN812eF77hgJCDZm7ZDmhmu3mdjb9 nP+M6wWNjxY8By5rjSo8ss5G4X7cvD1ot2eKB0SN67NjSr1EA+a1X6VTbu9hIvMzIj5Piy 9nBhQy1yWeXa14k7UtKnIoDblNJENYw= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-604-IkAdlEsKPx6HTOw9Do7Ohw-1; Fri, 12 Mar 2021 05:04:21 -0500 X-MC-Unique: IkAdlEsKPx6HTOw9Do7Ohw-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 7750F100C619 for ; Fri, 12 Mar 2021 10:04:20 +0000 (UTC) Received: from localhost (unknown [10.36.110.50]) by smtp.corp.redhat.com (Postfix) with ESMTP id 99C481969E; Fri, 12 Mar 2021 10:04:12 +0000 (UTC) From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH 17/27] vhost-user-gpu: add vg_send_scanout_dmabuf() Date: Fri, 12 Mar 2021 14:00:58 +0400 Message-Id: <20210312100108.2706195-18-marcandre.lureau@redhat.com> In-Reply-To: <20210312100108.2706195-1-marcandre.lureau@redhat.com> References: <20210312100108.2706195-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=63.128.21.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -29 X-Spam_score: -3.0 X-Spam_bar: --- X-Spam_report: (-3.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.25, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, 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: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Gerd Hoffmann Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau Signed-off-by: Marc-André Lureau --- contrib/vhost-user-gpu/vugpu.h | 8 ++++ contrib/vhost-user-gpu/vhost-user-gpu.c | 57 +++++++++++++++++-------- contrib/vhost-user-gpu/virgl.c | 23 ++++------ 3 files changed, 56 insertions(+), 32 deletions(-) diff --git a/contrib/vhost-user-gpu/vugpu.h b/contrib/vhost-user-gpu/vugpu.h index e19abb670d..759de56502 100644 --- a/contrib/vhost-user-gpu/vugpu.h +++ b/contrib/vhost-user-gpu/vugpu.h @@ -180,5 +180,13 @@ bool vg_recv_msg(VuGpu *g, uint32_t expect_req, uint32_t expect_size, gpointer payload); void vg_send_disable_scanout(VuGpu *g, int scanout_id); +void vg_send_dmabuf_scanout(VuGpu *g, + const struct virtio_gpu_set_scanout *ss, + uint32_t fd_width, + uint32_t fd_height, + uint32_t fd_stride, + int fd_drm_fourcc, + uint32_t fd_flags, + int fd); #endif diff --git a/contrib/vhost-user-gpu/vhost-user-gpu.c b/contrib/vhost-user-gpu/vhost-user-gpu.c index 69fedd376b..8c3ee8aad8 100644 --- a/contrib/vhost-user-gpu/vhost-user-gpu.c +++ b/contrib/vhost-user-gpu/vhost-user-gpu.c @@ -587,6 +587,38 @@ vg_transfer_to_host_2d(VuGpu *g, } } +void +vg_send_dmabuf_scanout(VuGpu *g, + const struct virtio_gpu_set_scanout *ss, + uint32_t fd_width, + uint32_t fd_height, + uint32_t fd_stride, + int fd_drm_fourcc, + uint32_t fd_flags, + int fd) +{ + VhostUserGpuMsg msg = { + .request = VHOST_USER_GPU_DMABUF_SCANOUT, + .size = sizeof(VhostUserGpuDMABUFScanout), + .payload.dmabuf_scanout = (VhostUserGpuDMABUFScanout) { + .scanout_id = ss->scanout_id, + .x = ss->r.x, + .y = ss->r.y, + .width = ss->r.width, + .height = ss->r.height, + .fd_width = fd_width, + .fd_height = fd_height, + .fd_stride = fd_stride, + .fd_drm_fourcc = fd_drm_fourcc, + .fd_flags = fd_flags, + } + }; + + g_debug("send dmabuf scanout: %d", ss->scanout_id); + vg_send_msg(g, &msg, fd); +} + + static void vg_set_scanout(VuGpu *g, struct virtio_gpu_ctrl_command *cmd) @@ -651,24 +683,15 @@ vg_set_scanout(VuGpu *g, struct vugbm_buffer *buffer = &res->buffer; if (vugbm_buffer_can_get_dmabuf_fd(buffer)) { - VhostUserGpuMsg msg = { - .request = VHOST_USER_GPU_DMABUF_SCANOUT, - .size = sizeof(VhostUserGpuDMABUFScanout), - .payload.dmabuf_scanout = (VhostUserGpuDMABUFScanout) { - .scanout_id = ss.scanout_id, - .x = ss.r.x, - .y = ss.r.y, - .width = ss.r.width, - .height = ss.r.height, - .fd_width = buffer->width, - .fd_height = buffer->height, - .fd_stride = buffer->stride, - .fd_drm_fourcc = buffer->format - } - }; - if (vugbm_buffer_get_dmabuf_fd(buffer, &fd)) { - vg_send_msg(g, &msg, fd); + vg_send_dmabuf_scanout(g, + &ss, + buffer->width, + buffer->height, + buffer->stride, + buffer->format, + 0, + fd); close(fd); } } else { diff --git a/contrib/vhost-user-gpu/virgl.c b/contrib/vhost-user-gpu/virgl.c index fe153425f5..0c7f118556 100644 --- a/contrib/vhost-user-gpu/virgl.c +++ b/contrib/vhost-user-gpu/virgl.c @@ -337,21 +337,14 @@ virgl_cmd_set_scanout(VuGpu *g, return; } assert(fd >= 0); - VhostUserGpuMsg msg = { - .request = VHOST_USER_GPU_DMABUF_SCANOUT, - .size = sizeof(VhostUserGpuDMABUFScanout), - .payload.dmabuf_scanout.scanout_id = ss.scanout_id, - .payload.dmabuf_scanout.x = ss.r.x, - .payload.dmabuf_scanout.y = ss.r.y, - .payload.dmabuf_scanout.width = ss.r.width, - .payload.dmabuf_scanout.height = ss.r.height, - .payload.dmabuf_scanout.fd_width = info.width, - .payload.dmabuf_scanout.fd_height = info.height, - .payload.dmabuf_scanout.fd_stride = info.stride, - .payload.dmabuf_scanout.fd_flags = info.flags, - .payload.dmabuf_scanout.fd_drm_fourcc = info.drm_fourcc - }; - vg_send_msg(g, &msg, fd); + vg_send_dmabuf_scanout(g, + &ss, + info.width, + info.height, + info.stride, + info.drm_fourcc, + info.flags, + fd); close(fd); } else { vg_send_disable_scanout(g, ss.scanout_id); From patchwork Fri Mar 12 10:00:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 12134189 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id ADEFAC433DB for ; Fri, 12 Mar 2021 10:12:01 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 695B564FB9 for ; Fri, 12 Mar 2021 10:12:01 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 695B564FB9 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:54894 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lKem0-00057t-Gr for qemu-devel@archiver.kernel.org; Fri, 12 Mar 2021 05:12:00 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:35190) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lKees-0001y6-JU for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:04:38 -0500 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:60239) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1lKeeq-0003pI-Qm for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:04:38 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1615543476; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=29uN9b+TR+Ruixt9pZtraK6VYZFptSAxO2ZoujOTlps=; b=YNaeS1apmZVlOrFfPERBBP3QfBvkY570DQVDd7jprqEGotHyP2HwDYtkLtykzgcqrCChWc o9cay8D9gPURyXXo4qSAQbmSGi+BAD8PQF5c42n7b/OdNRGlSD6dpDQPm6zsGwuaFt4mma 0KJLYmfQq8QLl7OQ4Cla2oAg1XECO+o= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-271--sNotPwCOPmCavaSvDuFMw-1; Fri, 12 Mar 2021 05:04:34 -0500 X-MC-Unique: -sNotPwCOPmCavaSvDuFMw-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 4B08319200C0 for ; Fri, 12 Mar 2021 10:04:33 +0000 (UTC) Received: from localhost (unknown [10.36.110.50]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1E8DF5C1C5; Fri, 12 Mar 2021 10:04:24 +0000 (UTC) From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH 18/27] vhost-user-gpu: add vg_send_dmabuf_update() Date: Fri, 12 Mar 2021 14:00:59 +0400 Message-Id: <20210312100108.2706195-19-marcandre.lureau@redhat.com> In-Reply-To: <20210312100108.2706195-1-marcandre.lureau@redhat.com> References: <20210312100108.2706195-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=216.205.24.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -29 X-Spam_score: -3.0 X-Spam_bar: --- X-Spam_report: (-3.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.25, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, 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: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Gerd Hoffmann Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau Signed-off-by: Marc-André Lureau --- contrib/vhost-user-gpu/vugpu.h | 6 +++++ contrib/vhost-user-gpu/vhost-user-gpu.c | 32 +++++++++++++++---------- contrib/vhost-user-gpu/virgl.c | 11 +-------- 3 files changed, 27 insertions(+), 22 deletions(-) diff --git a/contrib/vhost-user-gpu/vugpu.h b/contrib/vhost-user-gpu/vugpu.h index 759de56502..f2e80d255d 100644 --- a/contrib/vhost-user-gpu/vugpu.h +++ b/contrib/vhost-user-gpu/vugpu.h @@ -188,5 +188,11 @@ void vg_send_dmabuf_scanout(VuGpu *g, int fd_drm_fourcc, uint32_t fd_flags, int fd); +void vg_send_dmabuf_update(VuGpu *g, + uint32_t scanout_id, + uint32_t x, + uint32_t y, + uint32_t width, + uint32_t height); #endif diff --git a/contrib/vhost-user-gpu/vhost-user-gpu.c b/contrib/vhost-user-gpu/vhost-user-gpu.c index 8c3ee8aad8..fc8e62f20e 100644 --- a/contrib/vhost-user-gpu/vhost-user-gpu.c +++ b/contrib/vhost-user-gpu/vhost-user-gpu.c @@ -618,6 +618,25 @@ vg_send_dmabuf_scanout(VuGpu *g, vg_send_msg(g, &msg, fd); } +void +vg_send_dmabuf_update(VuGpu *g, + uint32_t scanout_id, + uint32_t x, + uint32_t y, + uint32_t width, + uint32_t height) +{ + VhostUserGpuMsg msg = { + .request = VHOST_USER_GPU_DMABUF_UPDATE, + .size = sizeof(VhostUserGpuUpdate), + .payload.update.scanout_id = scanout_id, + .payload.update.x = x, + .payload.update.y = y, + .payload.update.width = width, + .payload.update.height = height + }; + vg_send_msg(g, &msg, -1); +} static void vg_set_scanout(VuGpu *g, @@ -765,18 +784,7 @@ vg_resource_flush(VuGpu *g, size_t height = extents->y2 - extents->y1; if (vugbm_buffer_can_get_dmabuf_fd(&res->buffer)) { - VhostUserGpuMsg vmsg = { - .request = VHOST_USER_GPU_DMABUF_UPDATE, - .size = sizeof(VhostUserGpuUpdate), - .payload.update = (VhostUserGpuUpdate) { - .scanout_id = i, - .x = extents->x1, - .y = extents->y1, - .width = width, - .height = height, - } - }; - vg_send_msg(g, &vmsg, -1); + vg_send_dmabuf_update(g, i, extents->x1, extents->y1, width, height); vg_wait_ok(g); } else { size_t bpp = diff --git a/contrib/vhost-user-gpu/virgl.c b/contrib/vhost-user-gpu/virgl.c index 0c7f118556..b17cf22986 100644 --- a/contrib/vhost-user-gpu/virgl.c +++ b/contrib/vhost-user-gpu/virgl.c @@ -370,16 +370,7 @@ virgl_cmd_resource_flush(VuGpu *g, if (g->scanout[i].resource_id != rf.resource_id) { continue; } - VhostUserGpuMsg msg = { - .request = VHOST_USER_GPU_DMABUF_UPDATE, - .size = sizeof(VhostUserGpuUpdate), - .payload.update.scanout_id = i, - .payload.update.x = rf.r.x, - .payload.update.y = rf.r.y, - .payload.update.width = rf.r.width, - .payload.update.height = rf.r.height - }; - vg_send_msg(g, &msg, -1); + vg_send_dmabuf_update(g, i, rf.r.x, rf.r.y, rf.r.width, rf.r.height); vg_wait_ok(g); } } From patchwork Fri Mar 12 10:01:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 12134219 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 21F94C433E6 for ; Fri, 12 Mar 2021 10:27:08 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 9D71464FDD for ; Fri, 12 Mar 2021 10:27:07 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 9D71464FDD Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:45828 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lKf0c-0001r8-Ll for qemu-devel@archiver.kernel.org; Fri, 12 Mar 2021 05:27:06 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:35240) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lKef6-0002Gv-DT for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:04:53 -0500 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:23365) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1lKef3-0003wQ-3c for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:04:52 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1615543487; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=58c+YZnAcY8nmu25pTsnfz7IsqwKksSTHctTkETWfcU=; b=DN7zF1kjkO5m2g7d9leLbmLKqTM9OCu5AaNXxxUglCbmGWeyk8OintH787k1KiasI8Gh+N IcH+MLjIFEM/+4JyS1bWBRwMfapupu5y3fzkV1a/skpRsd0pPvcHtfbiWO+wNT6uxRuqZP a7LP3KZTjY/GMIhd49/XUME1vigzGX8= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-319-6EkO0w7TM2WFxblO2U4vqQ-1; Fri, 12 Mar 2021 05:04:46 -0500 X-MC-Unique: 6EkO0w7TM2WFxblO2U4vqQ-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 10AC881744F for ; Fri, 12 Mar 2021 10:04:45 +0000 (UTC) Received: from localhost (unknown [10.36.110.50]) by smtp.corp.redhat.com (Postfix) with ESMTP id 06B7410016FD; Fri, 12 Mar 2021 10:04:37 +0000 (UTC) From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH 19/27] vhost-user-gpu: add vg_send_scanout() Date: Fri, 12 Mar 2021 14:01:00 +0400 Message-Id: <20210312100108.2706195-20-marcandre.lureau@redhat.com> In-Reply-To: <20210312100108.2706195-1-marcandre.lureau@redhat.com> References: <20210312100108.2706195-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=216.205.24.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -29 X-Spam_score: -3.0 X-Spam_bar: --- X-Spam_report: (-3.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.25, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, 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: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Gerd Hoffmann Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau Signed-off-by: Marc-André Lureau --- contrib/vhost-user-gpu/vugpu.h | 1 + contrib/vhost-user-gpu/vhost-user-gpu.c | 27 ++++++++++++++++--------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/contrib/vhost-user-gpu/vugpu.h b/contrib/vhost-user-gpu/vugpu.h index f2e80d255d..bf513e9295 100644 --- a/contrib/vhost-user-gpu/vugpu.h +++ b/contrib/vhost-user-gpu/vugpu.h @@ -194,5 +194,6 @@ void vg_send_dmabuf_update(VuGpu *g, uint32_t y, uint32_t width, uint32_t height); +void vg_send_scanout(VuGpu *g, uint32_t scanout_id); #endif diff --git a/contrib/vhost-user-gpu/vhost-user-gpu.c b/contrib/vhost-user-gpu/vhost-user-gpu.c index fc8e62f20e..a11f406350 100644 --- a/contrib/vhost-user-gpu/vhost-user-gpu.c +++ b/contrib/vhost-user-gpu/vhost-user-gpu.c @@ -638,6 +638,22 @@ vg_send_dmabuf_update(VuGpu *g, vg_send_msg(g, &msg, -1); } +void +vg_send_scanout(VuGpu *g, uint32_t scanout_id) +{ + struct virtio_gpu_scanout *scanout = &g->scanout[scanout_id]; + VhostUserGpuMsg msg = { + .request = VHOST_USER_GPU_SCANOUT, + .size = sizeof(VhostUserGpuScanout), + .payload.scanout = (VhostUserGpuScanout) { + .scanout_id = scanout_id, + .width = scanout->width, + .height = scanout->height + } + }; + vg_send_msg(g, &msg, -1); +} + static void vg_set_scanout(VuGpu *g, struct virtio_gpu_ctrl_command *cmd) @@ -714,16 +730,7 @@ vg_set_scanout(VuGpu *g, close(fd); } } else { - VhostUserGpuMsg msg = { - .request = VHOST_USER_GPU_SCANOUT, - .size = sizeof(VhostUserGpuScanout), - .payload.scanout = (VhostUserGpuScanout) { - .scanout_id = ss.scanout_id, - .width = scanout->width, - .height = scanout->height - } - }; - vg_send_msg(g, &msg, -1); + vg_send_scanout(g, ss.scanout_id); } } From patchwork Fri Mar 12 10:01:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 12134225 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 66C04C433E0 for ; Fri, 12 Mar 2021 10:29:33 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 0749164F9E for ; Fri, 12 Mar 2021 10:29:32 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 0749164F9E Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:54484 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lKf2y-0005SM-2U for qemu-devel@archiver.kernel.org; Fri, 12 Mar 2021 05:29:32 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:35294) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lKefJ-0002Pl-BX for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:05:05 -0500 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:29234) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1lKefH-000470-H6 for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:05:05 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1615543501; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=eJIXxnKvWoutgHnZL1y3kNVVV/NbgaNgiGk58iEOQgU=; b=Nr9umOeAQRr+7zkJOc9xzkoXczCDMZwBbsVUlzVdbT07wHmkmqGfcozzlO/cZS684C80Xd T5u5XjEmEuEOhMY5D3FqD/5g0JzWUqBO37w+dl1NqDhT6ltZ7ktCli2hcYwlJYUkHcu0Zs sY58Hg2Ro3NAAvBIj35zAHtNExxSWTk= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-117-QrX3NiLRP_CfZ-NKSsObbg-1; Fri, 12 Mar 2021 05:05:00 -0500 X-MC-Unique: QrX3NiLRP_CfZ-NKSsObbg-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 55D5919200C0 for ; Fri, 12 Mar 2021 10:04:57 +0000 (UTC) Received: from localhost (unknown [10.36.110.50]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9546D5C1C5; Fri, 12 Mar 2021 10:04:49 +0000 (UTC) From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH 20/27] vhost-user-gpu: add vg_send_cursor_update() Date: Fri, 12 Mar 2021 14:01:01 +0400 Message-Id: <20210312100108.2706195-21-marcandre.lureau@redhat.com> In-Reply-To: <20210312100108.2706195-1-marcandre.lureau@redhat.com> References: <20210312100108.2706195-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=216.205.24.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -29 X-Spam_score: -3.0 X-Spam_bar: --- X-Spam_report: (-3.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.25, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, 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: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Gerd Hoffmann Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau Signed-off-by: Marc-André Lureau --- contrib/vhost-user-gpu/vugpu.h | 4 ++- contrib/vhost-user-gpu/vhost-user-gpu.c | 46 +++++++++++++++---------- 2 files changed, 31 insertions(+), 19 deletions(-) diff --git a/contrib/vhost-user-gpu/vugpu.h b/contrib/vhost-user-gpu/vugpu.h index bf513e9295..02a22bae34 100644 --- a/contrib/vhost-user-gpu/vugpu.h +++ b/contrib/vhost-user-gpu/vugpu.h @@ -195,5 +195,7 @@ void vg_send_dmabuf_update(VuGpu *g, uint32_t width, uint32_t height); void vg_send_scanout(VuGpu *g, uint32_t scanout_id); - +void vg_send_cursor_update(VuGpu *g, + const struct virtio_gpu_update_cursor *cursor, + const void *data); #endif diff --git a/contrib/vhost-user-gpu/vhost-user-gpu.c b/contrib/vhost-user-gpu/vhost-user-gpu.c index a11f406350..32bcbaa9a1 100644 --- a/contrib/vhost-user-gpu/vhost-user-gpu.c +++ b/contrib/vhost-user-gpu/vhost-user-gpu.c @@ -935,6 +935,30 @@ update_cursor_data_simple(VuGpu *g, uint32_t resource_id, gpointer data) memcpy(data, pixman_image_get_data(res->image), 64 * 64 * sizeof(uint32_t)); } +void +vg_send_cursor_update(VuGpu *g, + const struct virtio_gpu_update_cursor *cursor, + const void *data) +{ + VhostUserGpuMsg msg = { + .request = VHOST_USER_GPU_CURSOR_UPDATE, + .size = sizeof(VhostUserGpuCursorUpdate), + .payload.cursor_update = { + .pos = { + .scanout_id = cursor->pos.scanout_id, + .x = cursor->pos.x, + .y = cursor->pos.y, + }, + .hot_x = cursor->hot_x, + .hot_y = cursor->hot_y, + } + }; + /* we can afford that cursor copy */ + memcpy(msg.payload.cursor_update.data, data, + sizeof(msg.payload.cursor_update.data)); + vg_send_msg(g, &msg, -1); +} + static void vg_process_cursor_cmd(VuGpu *g, struct virtio_gpu_update_cursor *cursor) { @@ -955,28 +979,14 @@ vg_process_cursor_cmd(VuGpu *g, struct virtio_gpu_update_cursor *cursor) break; } case VIRTIO_GPU_CMD_UPDATE_CURSOR: { - VhostUserGpuMsg msg = { - .request = VHOST_USER_GPU_CURSOR_UPDATE, - .size = sizeof(VhostUserGpuCursorUpdate), - .payload.cursor_update = { - .pos = { - .scanout_id = cursor->pos.scanout_id, - .x = cursor->pos.x, - .y = cursor->pos.y, - }, - .hot_x = cursor->hot_x, - .hot_y = cursor->hot_y, - } - }; + uint32_t data[64 * 64] = { 0, }; g_debug("%s: update", G_STRFUNC); if (g->virgl) { - vg_virgl_update_cursor_data(g, cursor->resource_id, - msg.payload.cursor_update.data); + vg_virgl_update_cursor_data(g, cursor->resource_id, data); } else { - update_cursor_data_simple(g, cursor->resource_id, - msg.payload.cursor_update.data); + update_cursor_data_simple(g, cursor->resource_id, data); } - vg_send_msg(g, &msg, -1); + vg_send_cursor_update(g, cursor, data); break; } default: From patchwork Fri Mar 12 10:01:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 12134201 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3FB29C433DB for ; Fri, 12 Mar 2021 10:17:13 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id EA48564FE2 for ; Fri, 12 Mar 2021 10:17:12 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org EA48564FE2 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:42300 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lKer2-0003Ro-0p for qemu-devel@archiver.kernel.org; Fri, 12 Mar 2021 05:17:12 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:35330) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lKefX-0002rC-Mz for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:05:20 -0500 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:39933) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1lKefU-0004Ed-Eg for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:05:19 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1615543515; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=tXEZqmWWPXX4nkjljdJFPSS++pDg79FX4p5JF5FGaL0=; b=hjkPgm5I34kF3dxI2DIErrMt6Han4H+0lbVhWMcNGprlvSbsZDnXMMq5tF+Zk/HYA+JNop gGPviSoLmAfCH8iMGCD8U9BRYJKGrCoJAkmQGsyxfepHHJXVYIEkNCQQ9vuPp7je58yeM2 v0PCTCjeId9wqPrAM+nZl7cCNdgITx0= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-377-_DL60FNiM8WUtKri1w6Pvg-1; Fri, 12 Mar 2021 05:05:14 -0500 X-MC-Unique: _DL60FNiM8WUtKri1w6Pvg-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 09DE781746B for ; Fri, 12 Mar 2021 10:05:13 +0000 (UTC) Received: from localhost (unknown [10.36.110.50]) by smtp.corp.redhat.com (Postfix) with ESMTP id A6A041F065; Fri, 12 Mar 2021 10:05:03 +0000 (UTC) From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH 21/27] vhost-user-gpu: add vg_send_cursor_pos() Date: Fri, 12 Mar 2021 14:01:02 +0400 Message-Id: <20210312100108.2706195-22-marcandre.lureau@redhat.com> In-Reply-To: <20210312100108.2706195-1-marcandre.lureau@redhat.com> References: <20210312100108.2706195-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=216.205.24.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -29 X-Spam_score: -3.0 X-Spam_bar: --- X-Spam_report: (-3.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.25, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, 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: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Gerd Hoffmann Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau Signed-off-by: Marc-André Lureau --- contrib/vhost-user-gpu/vugpu.h | 3 +++ contrib/vhost-user-gpu/vhost-user-gpu.c | 28 +++++++++++++++---------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/contrib/vhost-user-gpu/vugpu.h b/contrib/vhost-user-gpu/vugpu.h index 02a22bae34..1927fb4f24 100644 --- a/contrib/vhost-user-gpu/vugpu.h +++ b/contrib/vhost-user-gpu/vugpu.h @@ -198,4 +198,7 @@ void vg_send_scanout(VuGpu *g, uint32_t scanout_id); void vg_send_cursor_update(VuGpu *g, const struct virtio_gpu_update_cursor *cursor, const void *data); +void vg_send_cursor_pos(VuGpu *g, + const struct virtio_gpu_update_cursor *cursor); + #endif diff --git a/contrib/vhost-user-gpu/vhost-user-gpu.c b/contrib/vhost-user-gpu/vhost-user-gpu.c index 32bcbaa9a1..4972448dbc 100644 --- a/contrib/vhost-user-gpu/vhost-user-gpu.c +++ b/contrib/vhost-user-gpu/vhost-user-gpu.c @@ -959,23 +959,29 @@ vg_send_cursor_update(VuGpu *g, vg_send_msg(g, &msg, -1); } +void +vg_send_cursor_pos(VuGpu *g, const struct virtio_gpu_update_cursor *cursor) +{ + VhostUserGpuMsg msg = { + .request = cursor->resource_id ? + VHOST_USER_GPU_CURSOR_POS : VHOST_USER_GPU_CURSOR_POS_HIDE, + .size = sizeof(VhostUserGpuCursorPos), + .payload.cursor_pos = { + .scanout_id = cursor->pos.scanout_id, + .x = cursor->pos.x, + .y = cursor->pos.y, + } + }; + vg_send_msg(g, &msg, -1); +} + static void vg_process_cursor_cmd(VuGpu *g, struct virtio_gpu_update_cursor *cursor) { switch (cursor->hdr.type) { case VIRTIO_GPU_CMD_MOVE_CURSOR: { - VhostUserGpuMsg msg = { - .request = cursor->resource_id ? - VHOST_USER_GPU_CURSOR_POS : VHOST_USER_GPU_CURSOR_POS_HIDE, - .size = sizeof(VhostUserGpuCursorPos), - .payload.cursor_pos = { - .scanout_id = cursor->pos.scanout_id, - .x = cursor->pos.x, - .y = cursor->pos.y, - } - }; g_debug("%s: move", G_STRFUNC); - vg_send_msg(g, &msg, -1); + vg_send_cursor_pos(g, cursor); break; } case VIRTIO_GPU_CMD_UPDATE_CURSOR: { From patchwork Fri Mar 12 10:01:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 12134203 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 02863C433DB for ; Fri, 12 Mar 2021 10:19:33 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 9F4D064FEE for ; Fri, 12 Mar 2021 10:19:32 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 9F4D064FEE Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:48330 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lKetH-0006M2-Qm for qemu-devel@archiver.kernel.org; Fri, 12 Mar 2021 05:19:31 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:35412) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lKefk-00033X-Ny for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:05:32 -0500 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:25131) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1lKefh-0004ML-Ro for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:05:32 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1615543529; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=aFlE2Il60LS/G7WTjCexwj1yhou10TIF5HHB94K1prQ=; b=RTl4iXS4EmPkLSqqL5i1VMljL9Q/efqKNJG73DCEU93/psIDQdig7fq6ealf01bvqJEvYL o3PqxqlohsBp3AulPtZyRLN+fjmUuV0vklwa2kJANnX8KGTCSjvenC/YtqplVBu9egXgKS vZsSZE6kmKpCNi6N2k3XgKi5yZijklM= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-338-701fKpVpPoyVWefp4wV0qA-1; Fri, 12 Mar 2021 05:05:26 -0500 X-MC-Unique: 701fKpVpPoyVWefp4wV0qA-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 2453580006E for ; Fri, 12 Mar 2021 10:05:25 +0000 (UTC) Received: from localhost (unknown [10.36.110.50]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8739610016FD; Fri, 12 Mar 2021 10:05:17 +0000 (UTC) From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH 22/27] vhost-user-gpu: add vg_send_update() Date: Fri, 12 Mar 2021 14:01:03 +0400 Message-Id: <20210312100108.2706195-23-marcandre.lureau@redhat.com> In-Reply-To: <20210312100108.2706195-1-marcandre.lureau@redhat.com> References: <20210312100108.2706195-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=63.128.21.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -29 X-Spam_score: -3.0 X-Spam_bar: --- X-Spam_report: (-3.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.25, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, 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: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Gerd Hoffmann Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau Signed-off-by: Marc-André Lureau --- contrib/vhost-user-gpu/vugpu.h | 11 ++++ contrib/vhost-user-gpu/vhost-user-gpu.c | 84 +++++++++++++++++-------- 2 files changed, 68 insertions(+), 27 deletions(-) diff --git a/contrib/vhost-user-gpu/vugpu.h b/contrib/vhost-user-gpu/vugpu.h index 1927fb4f24..370fd10667 100644 --- a/contrib/vhost-user-gpu/vugpu.h +++ b/contrib/vhost-user-gpu/vugpu.h @@ -201,4 +201,15 @@ void vg_send_cursor_update(VuGpu *g, void vg_send_cursor_pos(VuGpu *g, const struct virtio_gpu_update_cursor *cursor); +typedef void (*VgUpdateFill)(VuGpu *g, VhostUserGpuMsg *msg, void *fill_data); + +void vg_send_update(VuGpu *g, + uint32_t scanout_id, + uint32_t x, + uint32_t y, + uint32_t width, + uint32_t height, + size_t data_size, + VgUpdateFill fill_cb, + void *fill_data); #endif diff --git a/contrib/vhost-user-gpu/vhost-user-gpu.c b/contrib/vhost-user-gpu/vhost-user-gpu.c index 4972448dbc..d74ea127d8 100644 --- a/contrib/vhost-user-gpu/vhost-user-gpu.c +++ b/contrib/vhost-user-gpu/vhost-user-gpu.c @@ -734,6 +734,61 @@ vg_set_scanout(VuGpu *g, } } +void +vg_send_update(VuGpu *g, + uint32_t scanout_id, + uint32_t x, + uint32_t y, + uint32_t width, + uint32_t height, + size_t data_size, + VgUpdateFill fill_cb, + void *fill_data) +{ + void *p = g_malloc(VHOST_USER_GPU_HDR_SIZE + + sizeof(VhostUserGpuUpdate) + data_size); + VhostUserGpuMsg *msg = p; + msg->request = VHOST_USER_GPU_UPDATE; + msg->size = sizeof(VhostUserGpuUpdate) + data_size; + msg->payload.update = (VhostUserGpuUpdate) { + .scanout_id = scanout_id, + .x = x, + .y = y, + .width = width, + .height = height, + }; + fill_cb(g, msg, fill_data); + vg_send_msg(g, msg, -1); + g_free(msg); +} + +static void +fill_update_data(VuGpu *g, VhostUserGpuMsg *msg, void *fill_data) +{ + struct virtio_gpu_simple_resource *res = fill_data; + pixman_image_t *i; + size_t bpp; + uint32_t x, y, width, height; + + x = msg->payload.update.x; + y = msg->payload.update.y; + width = msg->payload.update.width; + height = msg->payload.update.height; + + bpp = PIXMAN_FORMAT_BPP(pixman_image_get_format(res->image)) / 8; + i = pixman_image_create_bits(pixman_image_get_format(res->image), + width, height, + (void *)msg + offsetof(VhostUserGpuMsg, + payload.update.data), + width * bpp); + pixman_image_composite(PIXMAN_OP_SRC, + res->image, NULL, i, + x, y, + 0, 0, 0, 0, + width, height); + pixman_image_unref(i); +} + static void vg_resource_flush(VuGpu *g, struct virtio_gpu_ctrl_command *cmd) @@ -798,33 +853,8 @@ vg_resource_flush(VuGpu *g, PIXMAN_FORMAT_BPP(pixman_image_get_format(res->image)) / 8; size_t size = width * height * bpp; - void *p = g_malloc(VHOST_USER_GPU_HDR_SIZE + - sizeof(VhostUserGpuUpdate) + size); - VhostUserGpuMsg *msg = p; - msg->request = VHOST_USER_GPU_UPDATE; - msg->size = sizeof(VhostUserGpuUpdate) + size; - msg->payload.update = (VhostUserGpuUpdate) { - .scanout_id = i, - .x = extents->x1, - .y = extents->y1, - .width = width, - .height = height, - }; - pixman_image_t *i = - pixman_image_create_bits(pixman_image_get_format(res->image), - msg->payload.update.width, - msg->payload.update.height, - p + offsetof(VhostUserGpuMsg, - payload.update.data), - width * bpp); - pixman_image_composite(PIXMAN_OP_SRC, - res->image, NULL, i, - extents->x1, extents->y1, - 0, 0, 0, 0, - width, height); - pixman_image_unref(i); - vg_send_msg(g, msg, -1); - g_free(msg); + vg_send_update(g, i, extents->x1, extents->y1, width, height, + size, fill_update_data, res); } pixman_region_fini(®ion); pixman_region_fini(&finalregion); From patchwork Fri Mar 12 10:01:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 12134207 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8CDADC433E0 for ; Fri, 12 Mar 2021 10:22:02 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 17F0D64FEE for ; Fri, 12 Mar 2021 10:22:02 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 17F0D64FEE Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:56850 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lKevh-0001nB-1j for qemu-devel@archiver.kernel.org; Fri, 12 Mar 2021 05:22:01 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:35478) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lKefx-0003UV-8Q for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:05:45 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:42932) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1lKefv-0004Ud-5Q for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:05:44 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1615543542; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=U1RmmHc7zYLdHOEPjFkgrHdDpu2H+Nsohs7CxSmlv+Q=; b=byLwwt8lq2QE/EUgfvEzGIPeB3E+5rY0p6hmaSj3/pF/7khUEFdknum8Y4Rnv0KsP0/XgH LsB1X5OljeQNlgfLlN1eCoiBx+/fkGNTD5QZJ6sg/SyJwfZ2rrF5mN0yz1oGT0juFMuAwn 7T5ogN2kdPrQjvWvUj9V3pzootfeKfo= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-148-mk1HyR8SMsu9in8MzZwiDw-1; Fri, 12 Mar 2021 05:05:41 -0500 X-MC-Unique: mk1HyR8SMsu9in8MzZwiDw-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 26C15100C61A for ; Fri, 12 Mar 2021 10:05:40 +0000 (UTC) Received: from localhost (unknown [10.36.110.50]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1AD8B610AE; Fri, 12 Mar 2021 10:05:29 +0000 (UTC) From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH 23/27] vhost-user: add VHOST_USER_GPU_QEMU_DBUS_LISTENER Date: Fri, 12 Mar 2021 14:01:04 +0400 Message-Id: <20210312100108.2706195-24-marcandre.lureau@redhat.com> In-Reply-To: <20210312100108.2706195-1-marcandre.lureau@redhat.com> References: <20210312100108.2706195-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=170.10.133.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -29 X-Spam_score: -3.0 X-Spam_bar: --- X-Spam_report: (-3.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.25, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, 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: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Gerd Hoffmann Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau Add a new feature & message to register a QEMU DBus console listener. Signed-off-by: Marc-André Lureau --- docs/interop/vhost-user.rst | 10 ++++++++++ include/hw/virtio/vhost-backend.h | 2 ++ subprojects/libvhost-user/libvhost-user.h | 5 +++++ hw/virtio/vhost-user.c | 23 +++++++++++++++++++++++ 4 files changed, 40 insertions(+) diff --git a/docs/interop/vhost-user.rst b/docs/interop/vhost-user.rst index d6085f7045..13515fb948 100644 --- a/docs/interop/vhost-user.rst +++ b/docs/interop/vhost-user.rst @@ -834,6 +834,7 @@ Protocol features #define VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS 14 #define VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS 15 #define VHOST_USER_PROTOCOL_F_STATUS 16 + #define VHOST_USER_PROTOCOL_F_GPU_QEMU_DBUS_LISTENER 17 Master message types -------------------- @@ -1347,6 +1348,15 @@ Master message types query the backend for its device status as defined in the Virtio specification. +``VHOST_USER_GPU_QEMU_DBUS_LISTENER`` + :id: 41 + :equivalent ioctl: N/A + :request payload: ``u32`` the scanout to listen for + + When the ``VHOST_USER_PROTOCOL_F_GPU_QEMU_DBUS_LISTENER`` protocol feature has + been successfully negotiated, this message is submitted by the frontend to + register a graphical listener using a currently private QEMU DBus protocol. + Slave message types ------------------- diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h index 8a6f8e2a7a..a64b92b863 100644 --- a/include/hw/virtio/vhost-backend.h +++ b/include/hw/virtio/vhost-backend.h @@ -190,5 +190,7 @@ int vhost_backend_handle_iotlb_msg(struct vhost_dev *dev, struct vhost_iotlb_msg *imsg); int vhost_user_gpu_set_socket(struct vhost_dev *dev, int fd); +int vhost_user_gpu_register_dbus_listener(struct vhost_dev *dev, + uint8_t idx, int fd); #endif /* VHOST_BACKEND_H */ diff --git a/subprojects/libvhost-user/libvhost-user.h b/subprojects/libvhost-user/libvhost-user.h index 3d13dfadde..d4152acde1 100644 --- a/subprojects/libvhost-user/libvhost-user.h +++ b/subprojects/libvhost-user/libvhost-user.h @@ -64,6 +64,8 @@ enum VhostUserProtocolFeature { VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD = 12, VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS = 14, VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS = 15, + VHOST_USER_PROTOCOL_F_STATUS = 16, + VHOST_USER_PROTOCOL_F_GPU_QEMU_DBUS_LISTENER = 17, VHOST_USER_PROTOCOL_F_MAX }; @@ -109,6 +111,9 @@ typedef enum VhostUserRequest { VHOST_USER_GET_MAX_MEM_SLOTS = 36, VHOST_USER_ADD_MEM_REG = 37, VHOST_USER_REM_MEM_REG = 38, + VHOST_USER_SET_STATUS = 39, + VHOST_USER_GET_STATUS = 40, + VHOST_USER_GPU_QEMU_DBUS_LISTENER = 41, VHOST_USER_MAX } VhostUserRequest; diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c index 2fdd5daf74..45758c84f9 100644 --- a/hw/virtio/vhost-user.c +++ b/hw/virtio/vhost-user.c @@ -79,6 +79,8 @@ enum VhostUserProtocolFeature { VHOST_USER_PROTOCOL_F_RESET_DEVICE = 13, /* Feature 14 reserved for VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS. */ VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS = 15, + VHOST_USER_PROTOCOL_F_STATUS = 16, + VHOST_USER_PROTOCOL_F_GPU_QEMU_DBUS_LISTENER = 17, VHOST_USER_PROTOCOL_F_MAX }; @@ -124,6 +126,9 @@ typedef enum VhostUserRequest { VHOST_USER_GET_MAX_MEM_SLOTS = 36, VHOST_USER_ADD_MEM_REG = 37, VHOST_USER_REM_MEM_REG = 38, + VHOST_USER_SET_STATUS = 39, + VHOST_USER_GET_STATUS = 40, + VHOST_USER_GPU_QEMU_DBUS_LISTENER = 41, VHOST_USER_MAX } VhostUserRequest; @@ -407,6 +412,24 @@ int vhost_user_gpu_set_socket(struct vhost_dev *dev, int fd) return vhost_user_write(dev, &msg, &fd, 1); } +int vhost_user_gpu_register_dbus_listener(struct vhost_dev *dev, uint8_t idx, int fd) +{ + VhostUserMsg msg = { + .hdr.request = VHOST_USER_GPU_QEMU_DBUS_LISTENER, + .hdr.flags = VHOST_USER_VERSION, + .payload.u64 = idx, + .hdr.size = sizeof(msg.payload.u64), + }; + + if (!(dev->protocol_features & + (1ULL << VHOST_USER_PROTOCOL_F_GPU_QEMU_DBUS_LISTENER))) { + return -1; + } + + return vhost_user_write(dev, &msg, &fd, 1); +} + + static int vhost_user_set_log_base(struct vhost_dev *dev, uint64_t base, struct vhost_log *log) { From patchwork Fri Mar 12 10:01:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 12134233 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5E44EC433DB for ; Fri, 12 Mar 2021 10:32:12 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 1270865004 for ; Fri, 12 Mar 2021 10:32:12 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 1270865004 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:34746 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lKf5W-0000vM-Vt for qemu-devel@archiver.kernel.org; Fri, 12 Mar 2021 05:32:11 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:35598) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lKegB-00043S-BC for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:05:59 -0500 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:60264) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1lKeg8-0004i6-7i for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:05:59 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1615543555; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=6ew4o0fCxQ1bs3uawov35sEUBDjwdabNRDce1/V/7Zk=; b=jTAVXycjq9nms/HVOm+8IKaKFCW0cvrp+INoqQkB0tztY6X2MzrpvasEdvJLCjrK+1WWDq +9RhPHjxKc2Rm3lkl7IBo+eJBlUIrTsjyxDsNwiyYEIvVLIXWwHQiV8GQ7GXcTY/2VJ2Wy VWoxC3LzGwEbRwz4fp+L+STWiJc5BWA= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-486-DmZezW-aNi60ndqaZk9Bpw-1; Fri, 12 Mar 2021 05:05:53 -0500 X-MC-Unique: DmZezW-aNi60ndqaZk9Bpw-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id A103B18460E2 for ; Fri, 12 Mar 2021 10:05:52 +0000 (UTC) Received: from localhost (unknown [10.36.110.50]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3704F5DAA5; Fri, 12 Mar 2021 10:05:44 +0000 (UTC) From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH 24/27] ui: add GraphicHwOps.register_dbus_listener() Date: Fri, 12 Mar 2021 14:01:05 +0400 Message-Id: <20210312100108.2706195-25-marcandre.lureau@redhat.com> In-Reply-To: <20210312100108.2706195-1-marcandre.lureau@redhat.com> References: <20210312100108.2706195-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=63.128.21.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -29 X-Spam_score: -3.0 X-Spam_bar: --- X-Spam_report: (-3.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.25, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, 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: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Gerd Hoffmann Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau Signed-off-by: Marc-André Lureau --- include/ui/console.h | 2 ++ ui/console.c | 11 +++++++++++ ui/dbus-console.c | 5 ++++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/include/ui/console.h b/include/ui/console.h index 31141955d9..0ad0d3ad66 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -429,6 +429,7 @@ typedef struct GraphicHwOps { void (*update_interval)(void *opaque, uint64_t interval); int (*ui_info)(void *opaque, uint32_t head, QemuUIInfo *info); void (*gl_block)(void *opaque, bool block); + bool (*register_dbus_listener)(void *opaque, QemuConsole *console, int fd); } GraphicHwOps; QemuConsole *graphic_console_init(DeviceState *dev, uint32_t head, @@ -444,6 +445,7 @@ void graphic_hw_update_done(QemuConsole *con); void graphic_hw_invalidate(QemuConsole *con); void graphic_hw_text_update(QemuConsole *con, console_ch_t *chardata); void graphic_hw_gl_block(QemuConsole *con, bool block); +bool graphic_hw_register_dbus_listener(QemuConsole *con, int fd); void qemu_console_early_init(void); diff --git a/ui/console.c b/ui/console.c index 3c3be032ad..8c2a29a5d8 100644 --- a/ui/console.c +++ b/ui/console.c @@ -320,6 +320,17 @@ void graphic_hw_gl_block(QemuConsole *con, bool block) } } +bool graphic_hw_register_dbus_listener(QemuConsole *con, int fd) +{ + assert(con != NULL); + + if (con->hw_ops->register_dbus_listener) { + return con->hw_ops->register_dbus_listener(con->hw, con, fd); + } + + return false; +} + int qemu_console_get_window_id(QemuConsole *con) { return con->window_id; diff --git a/ui/dbus-console.c b/ui/dbus-console.c index 3487a8f5cb..eaae914199 100644 --- a/ui/dbus-console.c +++ b/ui/dbus-console.c @@ -242,10 +242,13 @@ dbus_console_register_listener(DBusDisplayConsole *self, close(fd); return DBUS_METHOD_INVOCATION_HANDLED; } - socket_conn = g_socket_connection_factory_create_connection(socket); /* return now: easier for the other end, as it may handle priv dbus synchronously */ dbus_display_display1_console_complete_register_listener(self->iface, invocation, NULL); + if (graphic_hw_register_dbus_listener(self->con, fd)) { + return DBUS_METHOD_INVOCATION_HANDLED; + } + socket_conn = g_socket_connection_factory_create_connection(socket); listener_conn = g_dbus_connection_new_sync(G_IO_STREAM(socket_conn), guid, G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER, From patchwork Fri Mar 12 10:01:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 12134205 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E3225C433E0 for ; Fri, 12 Mar 2021 10:20:17 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 5EF2464FEE for ; Fri, 12 Mar 2021 10:20:17 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5EF2464FEE Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:50872 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lKeu0-0007Yq-Cy for qemu-devel@archiver.kernel.org; Fri, 12 Mar 2021 05:20:16 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:35646) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lKegG-0004Gk-0P for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:06:04 -0500 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:51524) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1lKegE-0004mS-0H for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:06:03 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1615543561; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=iqcirxw7PlLOaqPlNIi9jaYlIKwyGNvgiE8y1ygFVKo=; b=JgsedziwM50iQb98ca+IJMYy/KEvhnSQ7bDKb4nU7wPLxN7FK3PZshFE/ViT0lDwKU3sUc PlmYvZ19+9wj2fC6LSeuhsWbgZEqWeU2eVZ8QaNEpTFY1SYwxoYOpYh3R6IeSUuMfHTZ7t C+5/M2YRbAE56PBhjJc8pEeCePf8LXQ= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-476-s1m-rMORMYCgme-vS3xzIQ-1; Fri, 12 Mar 2021 05:05:59 -0500 X-MC-Unique: s1m-rMORMYCgme-vS3xzIQ-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 773E5100C618 for ; Fri, 12 Mar 2021 10:05:58 +0000 (UTC) Received: from localhost (unknown [10.36.110.50]) by smtp.corp.redhat.com (Postfix) with ESMTP id F021D5DDAD; Fri, 12 Mar 2021 10:05:56 +0000 (UTC) From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH 25/27] vhost-user-gpu: implement register_dbus_listener() Date: Fri, 12 Mar 2021 14:01:06 +0400 Message-Id: <20210312100108.2706195-26-marcandre.lureau@redhat.com> In-Reply-To: <20210312100108.2706195-1-marcandre.lureau@redhat.com> References: <20210312100108.2706195-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=63.128.21.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -29 X-Spam_score: -3.0 X-Spam_bar: --- X-Spam_report: (-3.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.25, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, 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: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Gerd Hoffmann Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau Send the listener fd over the vhost-user connection if the backend supports it. Signed-off-by: Marc-André Lureau --- include/hw/virtio/virtio-gpu.h | 1 + hw/display/vhost-user-gpu.c | 33 +++++++++++++++++++++++++++++++++ hw/display/virtio-gpu-base.c | 14 ++++++++++++++ hw/display/virtio-vga.c | 10 ++++++++++ 4 files changed, 58 insertions(+) diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h index fae149235c..bf33c05121 100644 --- a/include/hw/virtio/virtio-gpu.h +++ b/include/hw/virtio/virtio-gpu.h @@ -122,6 +122,7 @@ struct VirtIOGPUBaseClass { VirtioDeviceClass parent; void (*gl_flushed)(VirtIOGPUBase *g); + bool (*register_dbus_listener)(VirtIOGPUBase *g, QemuConsole *con, int fd); }; #define VIRTIO_GPU_BASE_PROPERTIES(_state, _conf) \ diff --git a/hw/display/vhost-user-gpu.c b/hw/display/vhost-user-gpu.c index a2a011e9cc..b48ddabcc8 100644 --- a/hw/display/vhost-user-gpu.c +++ b/hw/display/vhost-user-gpu.c @@ -370,6 +370,38 @@ vhost_user_gpu_gl_flushed(VirtIOGPUBase *b) vhost_user_gpu_update_blocked(VHOST_USER_GPU(g), false); } +static bool +vhost_user_gpu_scanout_idx(VirtIOGPUBase *b, QemuConsole *con, uint8_t *idx) +{ + VhostUserGPU *g = VHOST_USER_GPU(b); + struct virtio_gpu_scanout *s; + uint8_t i; + + for (i = 0; i < G_N_ELEMENTS(g->parent_obj.scanout); i++) { + s = &g->parent_obj.scanout[i]; + if (s->con == con) { + *idx = i; + return true; + } + } + + return false; +} + +static bool +vhost_user_gpu_do_register_dbus_listener(VirtIOGPUBase *b, QemuConsole *con, int fd) +{ + VhostUserGPU *g = VHOST_USER_GPU(b); + uint8_t idx = 0; + + if (!vhost_user_gpu_scanout_idx(b, con, &idx)) { + error_report("Failed to find attached console %p", con); + return false; + } + + return vhost_user_gpu_register_dbus_listener(&g->vhost->dev, idx, fd) == 0; +} + static bool vhost_user_gpu_do_set_socket(VhostUserGPU *g, Error **errp) { @@ -577,6 +609,7 @@ vhost_user_gpu_class_init(ObjectClass *klass, void *data) VirtIOGPUBaseClass *vgc = VIRTIO_GPU_BASE_CLASS(klass); vgc->gl_flushed = vhost_user_gpu_gl_flushed; + vgc->register_dbus_listener = vhost_user_gpu_do_register_dbus_listener; vdc->realize = vhost_user_gpu_device_realize; vdc->reset = vhost_user_gpu_reset; diff --git a/hw/display/virtio-gpu-base.c b/hw/display/virtio-gpu-base.c index ee2753001a..392719a830 100644 --- a/hw/display/virtio-gpu-base.c +++ b/hw/display/virtio-gpu-base.c @@ -141,6 +141,19 @@ virtio_gpu_get_flags(void *opaque) return flags; } +static bool +virtio_gpu_register_dbus_listener(void *opaque, QemuConsole *con, int fd) +{ + VirtIOGPUBase *g = opaque; + VirtIOGPUBaseClass *vgc = VIRTIO_GPU_BASE_GET_CLASS(g); + + if (vgc->register_dbus_listener) { + return vgc->register_dbus_listener(g, con, fd); + } + + return false; +} + static const GraphicHwOps virtio_gpu_ops = { .get_flags = virtio_gpu_get_flags, .invalidate = virtio_gpu_invalidate_display, @@ -148,6 +161,7 @@ static const GraphicHwOps virtio_gpu_ops = { .text_update = virtio_gpu_text_update, .ui_info = virtio_gpu_ui_info, .gl_block = virtio_gpu_gl_block, + .register_dbus_listener = virtio_gpu_register_dbus_listener, }; bool diff --git a/hw/display/virtio-vga.c b/hw/display/virtio-vga.c index b071909b68..777c7fc409 100644 --- a/hw/display/virtio-vga.c +++ b/hw/display/virtio-vga.c @@ -76,6 +76,15 @@ static int virtio_vga_base_get_flags(void *opaque) return g->hw_ops->get_flags(g); } +static bool virtio_vga_base_register_dbus_listener(void *opaque, + QemuConsole *con, int fd) +{ + VirtIOVGABase *vvga = opaque; + VirtIOGPUBase *g = vvga->vgpu; + + return g->hw_ops->register_dbus_listener(g, con, fd); +} + static const GraphicHwOps virtio_vga_base_ops = { .get_flags = virtio_vga_base_get_flags, .invalidate = virtio_vga_base_invalidate_display, @@ -83,6 +92,7 @@ static const GraphicHwOps virtio_vga_base_ops = { .text_update = virtio_vga_base_text_update, .ui_info = virtio_vga_base_ui_info, .gl_block = virtio_vga_base_gl_block, + .register_dbus_listener = virtio_vga_base_register_dbus_listener, }; static const VMStateDescription vmstate_virtio_vga_base = { From patchwork Fri Mar 12 10:01:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 12134235 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 59D8EC433E0 for ; Fri, 12 Mar 2021 10:34:58 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 0B54E64EF6 for ; Fri, 12 Mar 2021 10:34:58 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 0B54E64EF6 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:43296 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lKf8C-0004ZO-Ux for qemu-devel@archiver.kernel.org; Fri, 12 Mar 2021 05:34:56 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:35736) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lKegV-0004yS-MN for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:06:19 -0500 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:42695) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1lKegT-0004vf-05 for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:06:19 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1615543576; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=UvRUo7aVsztGNeFkLV32pQrkuDChRldxQ+7b8SU05lw=; b=Dr5pqcfwklx0iowKYxN/V4Hx2KCKCO5cGQrOBLPSan5QORZpPFE7GH56ktR7hB5DyhOmcG 1TdXmCciNSGUEHSO/XAEumTBut+oFsZ5gcG66Q4V1F+iGV+luvgPyXICInPG4wzXtRH+cm IiDuXn9EGpJMrL11WAtWjikXQk2iMtE= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-555-kKVPLLs-NPSWWqibcmLtOg-1; Fri, 12 Mar 2021 05:06:11 -0500 X-MC-Unique: kKVPLLs-NPSWWqibcmLtOg-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id CAE6318460E4 for ; Fri, 12 Mar 2021 10:06:10 +0000 (UTC) Received: from localhost (unknown [10.36.110.50]) by smtp.corp.redhat.com (Postfix) with ESMTP id EF42218B5E; Fri, 12 Mar 2021 10:06:03 +0000 (UTC) From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH 26/27] vhost-user-gpu: check the PIXMAN format is supported Date: Fri, 12 Mar 2021 14:01:07 +0400 Message-Id: <20210312100108.2706195-27-marcandre.lureau@redhat.com> In-Reply-To: <20210312100108.2706195-1-marcandre.lureau@redhat.com> References: <20210312100108.2706195-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=216.205.24.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -29 X-Spam_score: -3.0 X-Spam_bar: --- X-Spam_report: (-3.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.25, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, 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: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Gerd Hoffmann Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau There is no support for other PIXMAN formats atm. Signed-off-by: Marc-André Lureau --- contrib/vhost-user-gpu/vhost-user-gpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/vhost-user-gpu/vhost-user-gpu.c b/contrib/vhost-user-gpu/vhost-user-gpu.c index d74ea127d8..36d7f1d9e6 100644 --- a/contrib/vhost-user-gpu/vhost-user-gpu.c +++ b/contrib/vhost-user-gpu/vhost-user-gpu.c @@ -332,7 +332,7 @@ vg_resource_create_2d(VuGpu *g, res->resource_id = c2d.resource_id; pformat = virtio_gpu_get_pixman_format(c2d.format); - if (!pformat) { + if (!pformat || pformat != PIXMAN_x8r8g8b8) { g_critical("%s: host couldn't handle guest format %d", __func__, c2d.format); g_free(res); From patchwork Fri Mar 12 10:01:08 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 12134213 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0254DC433E0 for ; Fri, 12 Mar 2021 10:24:33 +0000 (UTC) Received: from lists.gnu.org (unknown [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 291E665002 for ; Fri, 12 Mar 2021 10:24:21 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 291E665002 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:37096 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lKexs-0005bK-6p for qemu-devel@archiver.kernel.org; Fri, 12 Mar 2021 05:24:16 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:35800) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lKegd-00059h-CA for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:06:27 -0500 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:36306) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1lKegY-00051m-MU for qemu-devel@nongnu.org; Fri, 12 Mar 2021 05:06:26 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1615543582; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=WwZqhmUTQYMcloAHb8BHNauyoNuJJH4ziRo3JEaroZQ=; b=hM5VJtD7cMoAh8uw7CCPQg4tPVwQjv5EPROiANCAJr2UrQgdh4l+w6r8J8Xy0SOWlrPAZA 0oRzGyy7o5VGGW0vRy0bsN58AZ/m8meX4WfVJUEPWtYj7RHJ4/3AMdQX+WyFZuwTpYnkf4 5sv3ew3OHChuRwEYFfHgcfKthvCHwpk= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-111-QmE3LEGlPN6trhfSKJQ9HQ-1; Fri, 12 Mar 2021 05:06:18 -0500 X-MC-Unique: QmE3LEGlPN6trhfSKJQ9HQ-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id D3277100C619 for ; Fri, 12 Mar 2021 10:06:17 +0000 (UTC) Received: from localhost (unknown [10.36.110.50]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9599069FB4; Fri, 12 Mar 2021 10:06:15 +0000 (UTC) From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH 27/27] vhost-user-gpu: implement GPU_QEMU_DBUS_LISTENER Date: Fri, 12 Mar 2021 14:01:08 +0400 Message-Id: <20210312100108.2706195-28-marcandre.lureau@redhat.com> In-Reply-To: <20210312100108.2706195-1-marcandre.lureau@redhat.com> References: <20210312100108.2706195-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=216.205.24.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -29 X-Spam_score: -3.0 X-Spam_bar: --- X-Spam_report: (-3.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.25, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, 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: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Gerd Hoffmann Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau Implement the QEMU DBus listener feature. This allows vhost-user-gpu to notify directly the console/ui clients. However, QEMU is still notified with the vhost-user-gpu protocol, for compatibility reasons. A future mechanism should allow qemu to opt-out for display updates. Signed-off-by: Marc-André Lureau --- contrib/vhost-user-gpu/vugpu.h | 3 + contrib/vhost-user-gpu/vhost-user-gpu.c | 272 +++++++++++++++++++++++- contrib/vhost-user-gpu/meson.build | 6 +- 3 files changed, 269 insertions(+), 12 deletions(-) diff --git a/contrib/vhost-user-gpu/vugpu.h b/contrib/vhost-user-gpu/vugpu.h index 370fd10667..81ffddf347 100644 --- a/contrib/vhost-user-gpu/vugpu.h +++ b/contrib/vhost-user-gpu/vugpu.h @@ -119,12 +119,15 @@ typedef struct VuGpu { int drm_rnode_fd; GSource *renderer_source; guint wait_in; + guint wait_dbus; bool virgl; bool virgl_inited; uint32_t inflight; struct virtio_gpu_scanout scanout[VIRTIO_GPU_MAX_SCANOUTS]; + GHashTable *listeners[VIRTIO_GPU_MAX_SCANOUTS]; + QTAILQ_HEAD(, virtio_gpu_simple_resource) reslist; QTAILQ_HEAD(, virtio_gpu_ctrl_command) fenceq; } VuGpu; diff --git a/contrib/vhost-user-gpu/vhost-user-gpu.c b/contrib/vhost-user-gpu/vhost-user-gpu.c index 36d7f1d9e6..261a909fd4 100644 --- a/contrib/vhost-user-gpu/vhost-user-gpu.c +++ b/contrib/vhost-user-gpu/vhost-user-gpu.c @@ -18,6 +18,7 @@ #include #include +#include #include "vugpu.h" #include "hw/virtio/virtio-gpu-bswap.h" @@ -25,6 +26,8 @@ #include "virgl.h" #include "vugbm.h" +#include "ui/dbus-display1.h" + enum { VHOST_USER_GPU_MAX_QUEUES = 2, }; @@ -359,7 +362,11 @@ vg_resource_create_2d(VuGpu *g, void vg_send_disable_scanout(VuGpu *g, int scanout_id) { + GHashTableIter iter; + DBusDisplayDisplay1Listener *listener; + g_debug("send disable scanout %d", scanout_id); + g_return_if_fail(scanout_id < VIRTIO_GPU_MAX_SCANOUTS); if (g->sock_fd >= 0) { VhostUserGpuMsg msg = { @@ -369,6 +376,12 @@ vg_send_disable_scanout(VuGpu *g, int scanout_id) }; vg_send_msg(g, &msg, -1); } + + g_hash_table_iter_init(&iter, g->listeners[scanout_id]); + while (g_hash_table_iter_next(&iter, (void **)&listener, NULL)) { + dbus_display_display1_listener_call_disable( + listener, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); + } } static void @@ -597,6 +610,10 @@ vg_send_dmabuf_scanout(VuGpu *g, uint32_t fd_flags, int fd) { + GHashTableIter iter; + DBusDisplayDisplay1Listener *listener; + g_autoptr(GError) err = NULL; + g_autoptr(GUnixFDList) fd_list = NULL; VhostUserGpuMsg msg = { .request = VHOST_USER_GPU_DMABUF_SCANOUT, .size = sizeof(VhostUserGpuDMABUFScanout), @@ -615,7 +632,49 @@ vg_send_dmabuf_scanout(VuGpu *g, }; g_debug("send dmabuf scanout: %d", ss->scanout_id); + g_return_if_fail(ss->scanout_id < VIRTIO_GPU_MAX_SCANOUTS); + vg_send_msg(g, &msg, fd); + + fd_list = g_unix_fd_list_new(); + if (g_unix_fd_list_append(fd_list, fd, &err) != 0) { + g_warning("Failed to setup dmabuf fdlist: %s", err->message); + return; + } + + g_hash_table_iter_init(&iter, g->listeners[ss->scanout_id]); + while (g_hash_table_iter_next(&iter, (void **)&listener, NULL)) { + dbus_display_display1_listener_call_scanout_dmabuf( + listener, + g_variant_new_handle(0), + fd_width, + fd_height, + fd_stride, + fd_drm_fourcc, + 0, /* modifier */ + fd_flags & VIRTIO_GPU_RESOURCE_FLAG_Y_0_TOP, /* == VIRGL_Y_0_TOP */ + G_DBUS_CALL_FLAGS_NONE, + -1, + fd_list, + NULL, NULL, NULL); + } +} + +static void +dbus_update_gl_cb(GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + g_autoptr(GError) err = NULL; + VuGpu *g = user_data; + + if (!dbus_display_display1_listener_call_update_dmabuf_finish( + DBUS_DISPLAY_DISPLAY1_LISTENER(source_object), res, &err)) { + g_warning("Failed to call update dmabuf: %s", err->message); + } + + g->wait_dbus--; + vg_handle_ctrl(&g->dev.parent, 0); } void @@ -626,6 +685,8 @@ vg_send_dmabuf_update(VuGpu *g, uint32_t width, uint32_t height) { + GHashTableIter iter; + DBusDisplayDisplay1Listener *listener; VhostUserGpuMsg msg = { .request = VHOST_USER_GPU_DMABUF_UPDATE, .size = sizeof(VhostUserGpuUpdate), @@ -635,7 +696,22 @@ vg_send_dmabuf_update(VuGpu *g, .payload.update.width = width, .payload.update.height = height }; + + g_return_if_fail(scanout_id < VIRTIO_GPU_MAX_SCANOUTS); + vg_send_msg(g, &msg, -1); + + g_hash_table_iter_init(&iter, g->listeners[scanout_id]); + while (g_hash_table_iter_next(&iter, (void **)&listener, NULL)) { + g->wait_dbus++; + dbus_display_display1_listener_call_update_dmabuf( + listener, + x, y, width, height, + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, + dbus_update_gl_cb, + g); + } } void @@ -652,6 +728,8 @@ vg_send_scanout(VuGpu *g, uint32_t scanout_id) } }; vg_send_msg(g, &msg, -1); + + /* dbus-listener is postponed until data is available */ } static void @@ -745,9 +823,17 @@ vg_send_update(VuGpu *g, VgUpdateFill fill_cb, void *fill_data) { - void *p = g_malloc(VHOST_USER_GPU_HDR_SIZE + + GHashTableIter iter; + DBusDisplayDisplay1Listener *listener; + g_autoptr(GVariant) v_data = NULL; + bool scanout = false; + VhostUserGpuMsg *msg; + void *p = NULL; + + g_return_if_fail(scanout_id < VIRTIO_GPU_MAX_SCANOUTS); + + msg = p = g_malloc(VHOST_USER_GPU_HDR_SIZE + sizeof(VhostUserGpuUpdate) + data_size); - VhostUserGpuMsg *msg = p; msg->request = VHOST_USER_GPU_UPDATE; msg->size = sizeof(VhostUserGpuUpdate) + data_size; msg->payload.update = (VhostUserGpuUpdate) { @@ -759,7 +845,40 @@ vg_send_update(VuGpu *g, }; fill_cb(g, msg, fill_data); vg_send_msg(g, msg, -1); - g_free(msg); + + if (x == 0 && y == 0 && + width == g->scanout[scanout_id].width && + height == g->scanout[scanout_id].height) { + scanout = true; + } + + v_data = g_variant_new_from_data( + G_VARIANT_TYPE("ay"), + p + offsetof(VhostUserGpuMsg, payload.update.data), + data_size, + TRUE, + g_free, + p); + g_variant_ref_sink(v_data); + + g_hash_table_iter_init(&iter, g->listeners[scanout_id]); + while (g_hash_table_iter_next(&iter, (void **)&listener, NULL)) { + if (scanout) { + dbus_display_display1_listener_call_scanout( + listener, + width, height, width * 4, PIXMAN_x8r8g8b8, + v_data, + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, NULL, NULL); + } else { + dbus_display_display1_listener_call_update( + listener, + x, y, width, height, width * 4, PIXMAN_x8r8g8b8, + v_data, + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, NULL, NULL); + } + } } static void @@ -912,7 +1031,7 @@ vg_handle_ctrl(VuDev *dev, int qidx) size_t len; for (;;) { - if (vg->wait_in != 0) { + if (vg->wait_in != 0 || vg->wait_dbus > 0) { return; } @@ -970,7 +1089,15 @@ vg_send_cursor_update(VuGpu *g, const struct virtio_gpu_update_cursor *cursor, const void *data) { - VhostUserGpuMsg msg = { + GHashTableIter iter; + DBusDisplayDisplay1Listener *listener; + VhostUserGpuMsg *msg; + g_autoptr(GVariant) v_data = NULL; + + g_return_if_fail(cursor->pos.scanout_id < VIRTIO_GPU_MAX_SCANOUTS); + + msg = g_new0(VhostUserGpuMsg, 1); + *msg = (VhostUserGpuMsg) { .request = VHOST_USER_GPU_CURSOR_UPDATE, .size = sizeof(VhostUserGpuCursorUpdate), .payload.cursor_update = { @@ -983,15 +1110,43 @@ vg_send_cursor_update(VuGpu *g, .hot_y = cursor->hot_y, } }; + /* we can afford that cursor copy */ - memcpy(msg.payload.cursor_update.data, data, - sizeof(msg.payload.cursor_update.data)); - vg_send_msg(g, &msg, -1); + memcpy(msg->payload.cursor_update.data, data, + sizeof(msg->payload.cursor_update.data)); + vg_send_msg(g, msg, -1); + + v_data = g_variant_new_from_data( + G_VARIANT_TYPE("ay"), + msg->payload.cursor_update.data, + sizeof(msg->payload.cursor_update.data), + TRUE, + g_free, + msg); + g_variant_ref_sink(v_data); + + g_hash_table_iter_init(&iter, g->listeners[cursor->pos.scanout_id]); + while (g_hash_table_iter_next(&iter, (void **)&listener, NULL)) { + dbus_display_display1_listener_call_cursor_define( + listener, + 64, + 64, + cursor->hot_x, + cursor->hot_y, + v_data, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + NULL, + NULL); + } } void vg_send_cursor_pos(VuGpu *g, const struct virtio_gpu_update_cursor *cursor) { + GHashTableIter iter; + DBusDisplayDisplay1Listener *listener; VhostUserGpuMsg msg = { .request = cursor->resource_id ? VHOST_USER_GPU_CURSOR_POS : VHOST_USER_GPU_CURSOR_POS_HIDE, @@ -1002,7 +1157,20 @@ vg_send_cursor_pos(VuGpu *g, const struct virtio_gpu_update_cursor *cursor) .y = cursor->pos.y, } }; + + g_return_if_fail(cursor->pos.scanout_id < VIRTIO_GPU_MAX_SCANOUTS); + vg_send_msg(g, &msg, -1); + + g_hash_table_iter_init(&iter, g->listeners[cursor->pos.scanout_id]); + while (g_hash_table_iter_next(&iter, (void **)&listener, NULL)) { + dbus_display_display1_listener_call_mouse_set( + listener, + cursor->pos.x, + cursor->pos.y, + cursor->resource_id != 0, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); + } } static void @@ -1127,6 +1295,70 @@ set_gpu_protocol_features(VuGpu *g) protocol_features_cb, g); } +static void +listener_vanished_cb(GDBusConnection *connection, + gboolean remote_peer_vanished, + GError *error, + VuGpu *g) +{ + DBusDisplayDisplay1Listener *listener; + uint8_t idx; + + listener = g_object_get_data(G_OBJECT(connection), "listener"); + g_debug("Removing dbus-listener %p", listener); + + idx = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(listener), "idx")); + g_hash_table_remove(g->listeners[idx], listener); +} + +static void +vg_register_dbus_listener(VuGpu *g, uint8_t idx, int fd) +{ + GDBusConnection *listener_conn; + g_autoptr(GError) err = NULL; + g_autoptr(GSocket) socket = NULL; + g_autoptr(GSocketConnection) socket_conn = NULL; + g_autofree char *guid = g_dbus_generate_guid(); + DBusDisplayDisplay1Listener *listener; + + socket = g_socket_new_from_fd(fd, &err); + if (err) { + g_warning("Couldn't make a socket: %s", err->message); + close(fd); + return; + } + socket_conn = g_socket_connection_factory_create_connection(socket); + listener_conn = g_dbus_connection_new_sync(G_IO_STREAM(socket_conn), + guid, + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER, + NULL, NULL, &err); + if (err) { + g_warning("Failed to setup peer connection: %s", err->message); + return; + } + + listener = dbus_display_display1_listener_proxy_new_sync( + listener_conn, + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + NULL, + "/org/qemu/Display1/Listener", + NULL, + &err); + if (!listener) { + g_warning("failed to setup proxy: %s", err->message); + return; + } + + g_debug("Adding dbus-listener %p", listener); + + g_object_set_data(G_OBJECT(listener), "idx", GINT_TO_POINTER(idx)); + g_object_set_data(G_OBJECT(listener_conn), "listener", listener); + g_hash_table_add(g->listeners[idx], listener); + g_object_connect(listener_conn, + "signal::closed", listener_vanished_cb, g, + NULL); +} + static int vg_process_msg(VuDev *dev, VhostUserMsg *msg, int *do_reply) { @@ -1140,6 +1372,12 @@ vg_process_msg(VuDev *dev, VhostUserMsg *msg, int *do_reply) set_gpu_protocol_features(g); return 1; } + case VHOST_USER_GPU_QEMU_DBUS_LISTENER: { + g_return_val_if_fail(msg->fd_num == 1, 1); + g_return_val_if_fail(msg->payload.u64 < VIRTIO_GPU_MAX_SCANOUTS, 1); + vg_register_dbus_listener(g, msg->payload.u64, msg->fds[0]); + return 1; + } default: return 0; } @@ -1175,6 +1413,12 @@ vg_set_features(VuDev *dev, uint64_t features) g->virgl = virgl; } +static uint64_t +vg_get_protocol_features(VuDev *dev) +{ + return 1 << VHOST_USER_PROTOCOL_F_GPU_QEMU_DBUS_LISTENER; +} + static int vg_get_config(VuDev *dev, uint8_t *config, uint32_t len) { @@ -1211,6 +1455,7 @@ vg_set_config(VuDev *dev, const uint8_t *data, static const VuDevIface vuiface = { .set_features = vg_set_features, .get_features = vg_get_features, + .get_protocol_features = vg_get_protocol_features, .queue_set_started = vg_queue_set_started, .process_msg = vg_process_msg, .get_config = vg_get_config, @@ -1221,9 +1466,14 @@ static void vg_destroy(VuGpu *g) { struct virtio_gpu_simple_resource *res, *tmp; + int i; vug_deinit(&g->dev); + for (i = 0; i < VIRTIO_GPU_MAX_SCANOUTS; i++) { + g_clear_pointer(&g->listeners[i], g_hash_table_unref); + } + vg_sock_fd_close(g); QTAILQ_FOREACH_SAFE(res, &g->reslist, next, tmp) { @@ -1253,7 +1503,7 @@ main(int argc, char *argv[]) GOptionContext *context; GError *error = NULL; GMainLoop *loop = NULL; - int fd; + int i, fd; VuGpu g = { .sock_fd = -1, .drm_rnode_fd = -1 }; QTAILQ_INIT(&g.reslist); @@ -1307,6 +1557,10 @@ main(int argc, char *argv[]) exit(EXIT_FAILURE); } + for (i = 0; i < VIRTIO_GPU_MAX_SCANOUTS; i++) { + g.listeners[i] = g_hash_table_new_full(NULL, NULL, g_object_unref, NULL); + } + if (!vug_init(&g.dev, VHOST_USER_GPU_MAX_QUEUES, fd, vg_panic, &vuiface)) { g_printerr("Failed to initialize libvhost-user-glib.\n"); exit(EXIT_FAILURE); diff --git a/contrib/vhost-user-gpu/meson.build b/contrib/vhost-user-gpu/meson.build index 0ce1515a10..773823e5bf 100644 --- a/contrib/vhost-user-gpu/meson.build +++ b/contrib/vhost-user-gpu/meson.build @@ -1,8 +1,8 @@ if 'CONFIG_TOOLS' in config_host and 'CONFIG_VIRGL' in config_host \ and 'CONFIG_GBM' in config_host and 'CONFIG_LINUX' in config_host \ - and pixman.found() - executable('vhost-user-gpu', files('vhost-user-gpu.c', 'virgl.c', 'vugbm.c'), - dependencies: [qemuutil, pixman, gbm, virgl, vhost_user, opengl], + and pixman.found() and 'CONFIG_UI_DBUS' in config_host + executable('vhost-user-gpu', files('vhost-user-gpu.c', 'virgl.c', 'vugbm.c') + dbus_display1, + dependencies: [qemuutil, pixman, gbm, virgl, vhost_user, opengl, gio], install: true, install_dir: get_option('libexecdir'))