dotnet X11 多次调用 XPutImage 是否能做到渲染同步

news/2024/11/16 14:57:53/文章来源:https://www.cnblogs.com/lindexi/p/18377330

本文将告诉大家我在麒麟系统和统信系统以及分别搭配飞腾和兆芯处理器的设备上,使用连续的 XPutImage 方法推送界面,测试是否能够在一次渲染内完成。测试结论是不能做到渲染同步

本文的核心测试代码如下

        XPutImage(display, handle, gc, ref xImage, @event.ExposeEvent.x, @event.ExposeEvent.y, @event.ExposeEvent.x, @event.ExposeEvent.y, (uint) @event.ExposeEvent.width,(uint) @event.ExposeEvent.height);XPutImage(display, handle, gc, ref halfImage, 0, 0, halfWidth, 0, (uint) halfWidth,(uint) height);

即连续调用两次 XPutImage 方法,其中最后一次的 XPutImage 方法是让右半边覆盖掉。如果渲染能对齐同步的话,预期右半边是不会出现闪烁问题,即不会出现先在屏幕显示首个 XPutImage 绘制的全窗口图片,再显示回最后一次的 XPutImage 覆盖的画面

然而经过实际测试,窗口显示的内容将会闪烁,即连续两次 XPutImage 不能做到渲染同步,这也符合阅读 XLib 和 XServer 和 KWin 的代码了解的行为

全部的测试代码如下

using CPF.Linux;using SkiaSharp;using static CPF.Linux.XLib;XInitThreads();
var display = XOpenDisplay(IntPtr.Zero);
var screen = XDefaultScreen(display);
var rootWindow = XDefaultRootWindow(display);XMatchVisualInfo(display, screen, 32, 4, out var info);
var visual = info.visual;var valueMask =//SetWindowValuemask.BackPixmap0| SetWindowValuemask.BackPixel| SetWindowValuemask.BorderPixel| SetWindowValuemask.BitGravity| SetWindowValuemask.WinGravity| SetWindowValuemask.BackingStore| SetWindowValuemask.ColorMap//| SetWindowValuemask.OverrideRedirect;
var xSetWindowAttributes = new XSetWindowAttributes
{backing_store = 1,bit_gravity = Gravity.NorthWestGravity,win_gravity = Gravity.NorthWestGravity,//override_redirect = true, // 设置窗口的override_redirect属性为True,以避免窗口管理器的干预colormap = XCreateColormap(display, rootWindow, visual, 0),border_pixel = 0,background_pixel = 0,
};var xDisplayWidth = XDisplayWidth(display, screen);
var xDisplayHeight = XDisplayHeight(display, screen);var width = xDisplayWidth;
var height = xDisplayHeight;var handle = XCreateWindow(display, rootWindow, 0, 0, width, height, 5,32,(int) CreateWindowArgs.InputOutput,visual,(nuint) valueMask, ref xSetWindowAttributes);XEventMask ignoredMask = XEventMask.SubstructureRedirectMask | XEventMask.ResizeRedirectMask |XEventMask.PointerMotionHintMask;
var mask = new IntPtr(0xffffff ^ (int) ignoredMask);
XSelectInput(display, handle, mask);XMapWindow(display, handle);
XFlush(display);var gc = XCreateGC(display, handle, 0, 0);
var skBitmap = new SKBitmap(width, height, SKColorType.Bgra8888, SKAlphaType.Premul);
var skCanvas = new SKCanvas(skBitmap);
var xImage = CreateImage(skBitmap);skCanvas.Clear(SKColors.Blue);
skCanvas.Flush();var halfWidth = width / 2;
var halfSkBitmap = new SKBitmap(halfWidth, height, SKColorType.Bgra8888, SKAlphaType.Premul);
var halfSkCanvas = new SKCanvas(halfSkBitmap);
halfSkCanvas.Clear();
halfSkCanvas.Flush();
var halfImage = CreateImage(halfSkBitmap);_ = Task.Run(() =>
{var newDisplay = XOpenDisplay(IntPtr.Zero);while (true){Console.ReadLine();var xEvent = new XEvent{ExposeEvent ={type = XEventName.Expose,send_event = true,window = handle,count = 1,display = newDisplay,x = 0,y = 0,width = width,height = height,}};// [Xlib Programming Manual: Expose Events](https://tronche.com/gui/x/xlib/events/exposure/expose.html )XLib.XSendEvent(newDisplay, handle, propagate: false,new IntPtr((int) (EventMask.ExposureMask)),ref xEvent);XFlush(newDisplay);}XCloseDisplay(newDisplay);
});while (true)
{var xNextEvent = XNextEvent(display, out var @event);if (xNextEvent != 0){break;}if (@event.type == XEventName.Expose){skCanvas.Clear(new SKColor((uint)Random.Shared.Next()).WithAlpha(0xFF));skCanvas.Flush();XPutImage(display, handle, gc, ref xImage, @event.ExposeEvent.x, @event.ExposeEvent.y, @event.ExposeEvent.x, @event.ExposeEvent.y, (uint) @event.ExposeEvent.width,(uint) @event.ExposeEvent.height);XPutImage(display, handle, gc, ref halfImage, 0, 0, halfWidth, 0, (uint) halfWidth,(uint) height);XFlush(display);}
}static XImage CreateImage(SKBitmap skBitmap)
{const int bytePerPixelCount = 4; // RGBA 一共4个 byte 长度var bitPerByte = 8;var bitmapWidth = skBitmap.Width;var bitmapHeight = skBitmap.Height;var img = new XImage();int bitsPerPixel = bytePerPixelCount * bitPerByte;img.width = bitmapWidth;img.height = bitmapHeight;img.format = 2; //ZPixmap;img.data = skBitmap.GetPixels();img.byte_order = 0; // LSBFirst;img.bitmap_unit = bitsPerPixel;img.bitmap_bit_order = 0; // LSBFirst;img.bitmap_pad = bitsPerPixel;img.depth = bitsPerPixel;img.bytes_per_line = bitmapWidth * bytePerPixelCount;img.bits_per_pixel = bitsPerPixel;XInitImage(ref img);return img;
}

本文代码放在 github 和 gitee 上,可以使用如下命令行拉取代码。我整个代码仓库比较庞大,使用以下命令行可以进行部分拉取,拉取速度比较快

先创建一个空文件夹,接着使用命令行 cd 命令进入此空文件夹,在命令行里面输入以下代码,即可获取到本文的代码

git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin b54f37030aec86fda474e99c0ad9ae941e23e1da

以上使用的是国内的 gitee 的源,如果 gitee 不能访问,请替换为 github 的源。请在命令行继续输入以下代码,将 gitee 源换成 github 源进行拉取代码。如果依然拉取不到代码,可以发邮件向我要代码

git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
git pull origin b54f37030aec86fda474e99c0ad9ae941e23e1da

获取代码之后,进入 X11/ChihewigiKurwawhalcelfe 文件夹,即可获取到源代码

更多技术博客,请参阅 博客导航

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/786418.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

dotnet C# 结构体出方法弹栈之后的行为

本文记录我在 .NET 9 里测试的行为,在方法里面创建的在栈上的结构体,在方法执行结束之后,栈上的结构体将会被弹栈进入不受管理区域,此时的结构体内存内容不会立刻被清空或被改写这是我在对 dotnet X11 栈空间被回收导致调用 XPutShmImage 闪退 博客的内容进行更多的测试,确…

Tesla 开发者 API 指南:BLE 密钥 – 身份验证和车辆命令

注意:本工具只能运行于 mac 或者 linux, win下不支持。 1. 克隆项目到本地 https://github.com/teslamotors/vehicle-command.git 2. 项目根目录下执行命令 go get ./... go build ./... go install ./... cd cmd cd tesla-control go build 3. 生成密钥 生成私钥 openssl e…

it程序员常用的技术社区网站有哪些?

it程序员常用的技术社区网站有哪些??作为程序员,选择好合适的开发社区对提高自己的编程能力会有很大的帮助,技术人员经常会在各种技术交流社区游逛。优秀的实时开发社区确实能帮你积累不少开发经验1、gitHub是一个面向开源及私有软件项目的托管平台,因为只支持git作为唯一…

推荐7款美观且功能强大的WPF UI库

前言 经常看到有小伙伴在DotNetGuide技术社区交流群里提问:WPF有什么好用或者好看的UI组件库推荐的?,今天大姚给大家分享7款开源、美观、功能强大、简单易用的WPF UI组件库。 WPF介绍 WPF 是一个强大的桌面应用程序框架,用于构建具有丰富用户界面的 Windows 应用。它提供了灵…

HTML+JS初试水

情境 参加了培训的第二次课, 这里是第二颗的作业题, 及我的解答. 1、使用 html 写一个网页,要求满足以下条件: (1)网页中含有任意一张图片,图片路径使用绝对路径,鼠标悬停在图片时出现“马哥教育”文本,且点击图片可跳转至马哥教育官方页面 (2)网页中包含账号、密码登…

Vue3的学习---8

8. Vue可复用解决方案 Vue可复用方案是指在Vue.js项目中,通过创建可复用的组件、指令、插件等,来提高代码的复用性和可维护性常见的Vue可复用方案有:组件(Components)、指令(Directives)、插件(Plugins)、混入(Mixins)、高阶组件(Higher-Order Components, HOC)等…

蓝帽杯2020-Misc-熟悉的解密

蓝帽杯2020-MISC-熟悉的解密 前言 怎么说呢,我觉得对我一个不懂加解密算法的人来说,应该算是Crypto,不过对于专业人员来说可能TEA、AES、RSA、LCG这种应该都比较ez(like 编码?) 一、题目 IyEvdXNyL2Jpbi9lbnYgcHl0aG9uDT== Iy0qLSBjb2Rpbmc6IHV0Zi04IC0qLQ0= aW1wb3J0IHN…

051、Vue3+TypeScript基础,页面通讯之v-model的基本用法

1、main.ts代码如下:// 引入createApp用于创建Vue实例 import {createApp} from vue // 引入App.vue根组件 import App from ./App.vue// 引入emitter用于全局事件总线 // import emitter from @/utils/emitterconst app = createApp(App);// App.vue的根元素id为app app.moun…

InternLM 2.5 书生浦语 开源大模型本地部署体验

上海人工智能实验室发布了书生浦语(InternLM)新开源版本,增强了在复杂场景下的推理能力,本文介绍在本地进行部署和推理……老牛同学之前偶尔刷到过InternLM大模型相关的介绍文章,因为在老牛同学心中,Qwen2千问才是国内开源模型中最适合自己的大模型,原因是自己在本地部署…

全网最适合入门的面向对象编程教程:37 Python常用复合数据类型-列表和列表推导式

在Python中,列表是一个非常灵活且常用的复合数据类型。它允许存储多个项,这些项可以是任意的数据类型,包括其他列表。列表推导式是一种简洁的方式来创建和操作列表。全网最适合入门的面向对象编程教程:37 Python 常用复合数据类型-列表和列表推导式摘要: 在 Python 中,列…

CareUEyes(调节屏幕亮度和颜色) v2.4.3.0 多语便携版

概述 CareUEyes 是一款用于调节屏幕亮度和颜色的软件,旨在保护用户眼睛的健康。它提供了多种功能和特点,使用户在使用电脑时能够更加舒适和健康。软件功能 蓝光过滤:该软件可以调整屏幕的色温,减少蓝光的强度,有助于减少眼部疲劳和视觉压力。休息提醒:软件会定时提醒用户…

050、Vue3+TypeScript基础,页面通讯之使用mitt在任意组件中通讯

01、main.js代码如下:// 引入createApp用于创建Vue实例 import {createApp} from vue // 引入App.vue根组件 import App from ./App.vue// 引入emitter用于全局事件总线 // import emitter from @/utils/emitterconst app = createApp(App);// App.vue的根元素id为app app.mou…