From nobody Sun May 19 04:05:33 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=me.com ARC-Seal: i=1; a=rsa-sha256; t=1628587095; cv=none; d=zohomail.com; s=zohoarc; b=ZHca+LfXpsupZMWW2cvHwOp0cgxiiCZ4BdXFtr32dy5xV/60mQEZFlXvx3BS+gMZguC8aSpO/L8u79lgA4DIIECsUyhA+aVrfWdtZjc8mGqZazL8MdGxjdZrNOdMInnMXJvhnslQ3zh4+P211MJNifHQsa0Cr3H7+7IfCFe8r8M= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1628587095; h=Content-Transfer-Encoding:Cc:Date:From:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:To; bh=Bi9rOH9P8chejeLCuLEZyIzFFbF7kQJlghGm8+mr+uY=; b=l0LhPtH2g35L1767L7unyqtzAWHKwcP5FTm8IbDRoB3IbvB6p5eeyPvXIL3O6+xl+uy48UiSu6/MwLBhzHIl/ZzqzRBBGHPxGKpGAnB0l/TqaEQAZYjz5jAzKe9yR4jqGxTElv7oce6s1zLRjJzn2eaLJqYrmm8goNcgYptej9s= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1628587095503866.8315136801823; Tue, 10 Aug 2021 02:18:15 -0700 (PDT) Received: from localhost ([::1]:60996 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mDNtl-0000ig-Uv for importer@patchew.org; Tue, 10 Aug 2021 05:18:13 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:44012) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mDNt8-0008Tb-Og for qemu-devel@nongnu.org; Tue, 10 Aug 2021 05:17:34 -0400 Received: from pv50p00im-ztbu10011701.me.com ([17.58.6.53]:47677) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mDNt6-0005Th-Vy for qemu-devel@nongnu.org; Tue, 10 Aug 2021 05:17:34 -0400 Received: from localhost.localdomain (unknown [125.38.22.94]) by pv50p00im-ztbu10011701.me.com (Postfix) with ESMTPSA id 0CB6D8A012C; Tue, 10 Aug 2021 09:17:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=me.com; s=1a1hai; t=1628587049; bh=Bi9rOH9P8chejeLCuLEZyIzFFbF7kQJlghGm8+mr+uY=; h=From:To:Subject:Date:Message-Id:MIME-Version; b=A1k9oKaBHLPVtZ2efYDCdNsXRHqehY3OoGQDAdFHkNrEWIom828uK9ypU+7J6PhNC 27DtZsilpFa13O96ARWJM0rbFJXRy4upyqRVidxSO83iRldI0gWJZHw48ObMw6dbtK SL0oWFuEA8aKnAlVT2mKd2s7EFM2cjUx76MXuGiaG9kL+uQObWbKnkm8buqPDOdg+u 56uTygIwTl6RrSI8AMdgeHs8xobaipix8ssESIRzTFCauFOSpegESFiiaJgrfFkVc2 qO19inJ+iVYlQkgIl3ZGqz6ztxD+DVs/4ZjKiTFekgw1ZAH0h6CJiHjsuGoUDaCbAr ba6P4hkl8jJIg== From: Zhang Chen To: qemu-devel@nongnu.org Cc: Zhang Chen , Peter Maydell , Gerd Hoffmann Subject: [PATCH] ui/cocoa: Implement dcl operators for guest cursor Date: Tue, 10 Aug 2021 17:17:06 +0800 Message-Id: <20210810091706.65576-1-tgfbeta@me.com> X-Mailer: git-send-email 2.30.2 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.391, 18.0.790 definitions=2021-08-10_03:2021-08-06, 2021-08-10 signatures=0 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=0 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 clxscore=1011 mlxscore=0 mlxlogscore=760 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-2009150000 definitions=main-2108100058 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=17.58.6.53; envelope-from=tgfbeta@me.com; helo=pv50p00im-ztbu10011701.me.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-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: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @me.com) X-ZM-MESSAGEID: 1628587095802100003 Content-Type: text/plain; charset="utf-8" In this patch, two dcl operators were implemented for Cocoa display, to prepare, update and draw guest cursor on screen canvas. After this implementation, Cocoa display could support virtio-vga device, which is better supported in guest side, especially for Linux. In contrast to the default vga device, virtio-vga with dcl operators for cursors showed less flicker in cursor drawing. Two fields were added in the struct QemuScreen to pass dimensions to dcl operators. Signed-off-by: Zhang Chen --- ui/cocoa.m | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/ui/cocoa.m b/ui/cocoa.m index 68a6302184..9d3a8eac28 100644 --- a/ui/cocoa.m +++ b/ui/cocoa.m @@ -73,6 +73,8 @@ typedef struct { int width; int height; + int bitsPerComponent; + int bitsPerPixel; } QEMUScreen; =20 static void cocoa_update(DisplayChangeListener *dcl, @@ -83,12 +85,19 @@ static void cocoa_switch(DisplayChangeListener *dcl, =20 static void cocoa_refresh(DisplayChangeListener *dcl); =20 +static void cocoa_mouse_set(DisplayChangeListener *dcl, + int x, int y, int visible); + +static void cocoa_cursor_define(DisplayChangeListener *dcl, QEMUCursor *c); + static NSWindow *normalWindow, *about_window; static const DisplayChangeListenerOps dcl_ops =3D { .dpy_name =3D "cocoa", .dpy_gfx_update =3D cocoa_update, .dpy_gfx_switch =3D cocoa_switch, .dpy_refresh =3D cocoa_refresh, + .dpy_mouse_set =3D cocoa_mouse_set, + .dpy_cursor_define =3D cocoa_cursor_define, }; static DisplayChangeListener dcl =3D { .ops =3D &dcl_ops, @@ -309,6 +318,9 @@ static void handleAnyDeviceErrors(Error * err) BOOL isMouseGrabbed; BOOL isFullscreen; BOOL isAbsoluteEnabled; + CGRect cursorRect; + CGImageRef cursorImage; + BOOL cursorVisible; } - (void) switchSurface:(pixman_image_t *)image; - (void) grabMouse; @@ -344,6 +356,8 @@ QemuCocoaView *cocoaView; self =3D [super initWithFrame:frameRect]; if (self) { =20 + screen.bitsPerComponent =3D 8; + screen.bitsPerPixel =3D 32; screen.width =3D frameRect.size.width; screen.height =3D frameRect.size.height; kbd =3D qkbd_state_init(dcl.con); @@ -484,6 +498,12 @@ QemuCocoaView *cocoaView; ); CGContextDrawImage (viewContextRef, cgrect(rectList[i]), clipI= mageRef); CGImageRelease (clipImageRef); + + } + CGRect cursorDrawRect =3D stretch_video ? + [self convertRectFromQemuScreen:cursor= Rect] : cursorRect; + if (cursorVisible && cursorImage && NSIntersectsRect(rect, cursorD= rawRect)) { + CGContextDrawImage (viewContextRef, cursorDrawRect, cursorImag= e); } CGImageRelease (imageRef); CGDataProviderRelease(dataProviderRef); @@ -1075,6 +1095,28 @@ QemuCocoaView *cocoaView; - (float) cdy {return cdy;} - (QEMUScreen) gscreen {return screen;} =20 +- (CGRect) cursorRect {return cursorRect;} +- (void) setCursorRect:(CGRect)rect {cursorRect =3D rect;} +- (CGImageRef) cursorImage {return cursorImage;} +- (void) setCursorImage:(CGImageRef)image +{ + if (cursorImage && cursorImage !=3D image) { + CGImageRelease(cursorImage); + } + cursorImage =3D image; +} +- (BOOL) isCursorVisible {return cursorVisible;} +- (void) setCursorVisible:(BOOL)visible {cursorVisible =3D visible;} + +- (CGRect) convertRectFromQemuScreen:(CGRect)rect +{ + CGRect viewRect =3D rect; + viewRect.origin.x *=3D cdx; + viewRect.origin.y *=3D cdy; + viewRect.size.width *=3D cdx; + viewRect.size.height *=3D cdy; + return viewRect; +} /* * Makes the target think all down keys are being released. * This prevents a stuck key problem, since we will not see @@ -2022,6 +2064,63 @@ static void cocoa_refresh(DisplayChangeListener *dcl) [pool release]; } =20 +static void cocoa_cursor_define(DisplayChangeListener *dcl, QEMUCursor *c) +{ + NSAutoreleasePool * pool =3D [[NSAutoreleasePool alloc] init]; + int bitsPerComponent =3D [cocoaView gscreen].bitsPerComponent; + int bitsPerPixel =3D [cocoaView gscreen].bitsPerPixel; + int stride =3D c->width * bitsPerComponent / 2; + CGDataProviderRef provider =3D CGDataProviderCreateWithData(NULL, c->d= ata, c->width * 4 * c->height, NULL); + + CGImageRef img =3D CGImageCreate( + c->width, + c->height, + bitsPerComponent, + bitsPerPixel, + stride, + CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB), //colorspace + kCGBitmapByteOrder32Little | kCGImageAlphaFirst, + provider, + NULL, + 0, + kCGRenderingIntentDefault + ); + + CGDataProviderRelease(provider); + CGFloat width =3D c->width; + CGFloat height =3D c->height; + dispatch_async(dispatch_get_main_queue(), ^{ + [cocoaView setCursorImage:img]; + CGRect rect =3D [cocoaView cursorRect]; + rect.size =3D CGSizeMake(width, height); + [cocoaView setCursorRect:rect]; + }); + [pool release]; +} + +static void cocoa_mouse_set(DisplayChangeListener *dcl, + int x, int y, int visible) +{ + NSAutoreleasePool * pool =3D [[NSAutoreleasePool alloc] init]; + dispatch_async(dispatch_get_main_queue(), ^{ + QEMUScreen screen =3D [cocoaView gscreen]; + // Mark old cursor rect as dirty + CGRect rect =3D [cocoaView cursorRect]; + CGRect dirtyRect =3D stretch_video ? + [cocoaView convertRectFromQemuScreen:rect] : rect; + [cocoaView setNeedsDisplayInRect:dirtyRect]; + // Update rect for cursor sprite + rect.origin =3D CGPointMake(x, screen.height - (y + rect.size.heig= ht)); + [cocoaView setCursorRect:rect]; + [cocoaView setCursorVisible:visible ? YES : NO]; + // Mark new cursor rect as dirty + dirtyRect =3D stretch_video ? + [cocoaView convertRectFromQemuScreen:rect] : rect; + [cocoaView setNeedsDisplayInRect:dirtyRect]; + }); + [pool release]; +} + static void cocoa_display_init(DisplayState *ds, DisplayOptions *opts) { COCOA_DEBUG("qemu_cocoa: cocoa_display_init\n"); --=20 2.30.2