ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Wayland helloworld (四)之窗口显示

2019-09-08 12:00:52  阅读:446  来源: 互联网

标签:窗口 buffer lpBuffer wl surface listener Wayland helloworld pool


原文链接:https://my.oschina.net/txl/blog/266931

Wayland窗口绘制

    Wayland窗口绘制有两种:1) 共享内存方式、2)EGL。

本文使用方式1绘制窗口。


Wayland窗口:wl_surface

    Wayland窗口绘制完全由程序控制,包括标题栏绘制,边框绘制,窗口移动,改变大小等。 其中与窗口绘制有关的函数有:

wl_surface_attach() 将缓存绑定到窗口上,窗口大小会根据缓存重新计算。

wl_surface_damage() 标记窗口失效的区域

wl_surface_commit() 缓存提交请求,合成器会锁定提交的缓存,直到下一次wl_surface_attach或合成器主动释放。

wl_surface_frame() 申请帧绘制回调,每当绘制完一帧就发送wl_callback::done消息。


Walyand缓存:wl_buffer

    Wayland窗口显示的内容由wl_buffer负责。Wayland与X Server不同,Wayland只支持客户端直接绘制,合成器不提供对wl_buffer的绘制操作。与wl_buffer有关的函数有:

wl_shm_create_pool() 创建一个缓存池,缓存池可以mmap到程序的内存空间中。

wl_shm_pool_create() 创建一个wl_buffer。

示例代码:

lpBuffer->data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
	//lpBuffer->data == MAP_FAILED

	HSHMPOOL pool = wl_shm_create_pool(wlGetRegistry()->s_shm, fd, size);
	lpBuffer->buffer = wl_shm_pool_create_buffer(pool, 0, width, height, stride, WL_SHM_FORMAT_XRGB8888);
其中:fd是临时文件,大小为size,用于mmap用。

窗口绘制:

void buffer_release(void *data, struct wl_buffer *buffer)
{
	LPPAINTBUFFER lpBuffer = data;
	lpBuffer->busy = 0;
}

static const struct wl_buffer_listener buffer_listener = 
{
	.release = buffer_release
};

void _wlCreatePaintStructure(int width, int height, LPPAINTBUFFER lpBuffer)
{
	int stride = width * 4;
	int size = stride * height;

	char filename[] = "/tmp/weston-shared-XXXXXX";
	int fd = mkstemp(filename);
	fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
	unlink(filename);
	ftruncate(fd, size);

	lpBuffer->busy = 0;

	lpBuffer->data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
	//lpBuffer->data == MAP_FAILED

	HSHMPOOL pool = wl_shm_create_pool(wlGetRegistry()->s_shm, fd, size);
	lpBuffer->buffer = wl_shm_pool_create_buffer(pool, 0, width, height, stride, WL_SHM_FORMAT_XRGB8888);
	wl_buffer_add_listener(lpBuffer->buffer, &buffer_listener, lpBuffer);
	wl_shm_pool_destroy(pool);
	close(fd);
}

void wlBeginPaint(HSURFACE surface, LPPAINTSTRUCTURE lpPaint)
{
	LPSURFACEPRIVATE _priv = _wlGetSurfacePrivate(surface);
	if (!_priv->buffer[0].busy && _priv->buffer[0].buffer)
	{
		lpPaint->buffer = &_priv->buffer[0];
	}
	else if (!_priv->buffer[1].busy && _priv->buffer[1].buffer)
	{
		lpPaint->buffer = &_priv->buffer[1];
	}
	else
	{
		SIZE sz = wlGetSurfaceSize(surface);
		_wlCreatePaintStructure(sz.width, sz.height, &_priv->buffer[0]);
		lpPaint->buffer = &_priv->buffer[0];
	}
}

void wlEndPaint(HSURFACE surface, LPPAINTSTRUCTURE lpPaint)
{
	lpPaint->buffer->busy = 1;
	wl_surface_attach(surface, lpPaint->buffer->buffer, 0, 0);
	SIZE sz = wlGetSurfaceSize(surface);
	wl_surface_damage(surface, 0, 0, sz.width, sz.height);
	wl_surface_commit(surface);
}

void frame_listener_done(void *data, HCALLBACK callback, uint32_t time)
{
	HSURFACE surface = (HSURFACE)data;
	/* 每次都需要重新设置回调函数 */
	_wlSetFrameListener(surface);
	
	/* 绘制一帧 */
	_wlDrawFrame(surface, time);
}

static struct wl_callback_listener frame_listener = { frame_listener_done };

void _wlSetFrameListener(HSURFACE surface)
{
	static struct wl_callback_listener frame_listener;
	frame_listener.done = frame_listener_done;
	HCALLBACK callback = wl_surface_frame(surface);
	wl_callback_add_listener(callback, &frame_listener, surface);
}

void _wlDrawFrame(HSURFACE surface, uint32_t time)
{
	PAINTSTRUCTURE ps;
	memset(&ps, 0, sizeof(ps));
	wlBeginPaint(surface, &ps);
	wlCallPaintProc(surface, &ps, time);
	wlEndPaint(surface, &ps);
}

void wlSetPaintProc(HSURFACE surface, REPAINTPROC surfaceproc)
{
	_wlGetSurfacePrivate(surface)->surfaceproc = surfaceproc;
	_wlSetFrameListener(surface);
	_wlDrawFrame(surface, 0);
}








转载于:https://my.oschina.net/txl/blog/266931

标签:窗口,buffer,lpBuffer,wl,surface,listener,Wayland,helloworld,pool
来源: https://blog.csdn.net/chenie3544/article/details/100623492

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有