display:weston渲染流程:commit

接上一篇

display:weston渲染流程:buffer+attach+damage+frame

display:weston渲染流程:buffer+attach+damage+frame_maze的专栏-CSDN博客

5.commit

Wayland源码分析-Commit相关流程

Surface state (input, opaque and damage regions, attached buffers, etc.) is double-buffered.

表面状态(输入,不透明和损坏区域,附加缓冲区等)是双缓冲的。=>[防止图像抖动]

commit操作本质上就是为double buffer而设计,多次操作、一次提交。注意到之前的操作attach,damage,frame等仅仅在commit以后才会生效。(之前的操作都是对pending结构体的操作,只有commit以后才会切换到current结构体上)

client:
wl_surface_commit(window->surface);
server:    weston/libweston/compositor.c::surface_commit
surface_commit
...
weston_surface_is_pending_viewport_source_valid  //对pending的buffer进行缩放/旋转相关操作
这里写错了,没有旋转相关操作!只有裁剪或者缩放
weston_surface_is_pending_viewport_dst_size_int  //缩放相关校验,服务为wp_viewporter;
...
if (surface->pending.acquire_fence_fd >= 0) {    //fence相关的内容,同步保证互斥buffer的fence
		/* We support fences for both wp_linux_dmabuf and opaque EGL
		 * buffers, as mandated by minor version 2 of the
		 * zwp_linux_explicit_synchronization_v1 protocol. Since
		 * renderers that support fences currently only support these
		 * two buffer types plus SHM buffers, we can just check for the
		 * SHM buffer case here.
		 */
    if(!surface->pending,buffer)
        fd_clear(&surface->pending.acquire_fence_fd);
    if(wl_shm_buffer_get(surface->pending.buffer->resource))
        fd_clear(******fd);

    如果没buffer,清空对应fence,如果buffer是shm的,清空fence
...
}
...
if (sub) {
 	weston_subsurface_commit(sub); //1
 	return;
}
weston_surface_commit(surface);
...

wl_list_for_each(sub, &surface->subsurface_list, parent_link) {
    if (sub->surface != surface)
			weston_subsurface_parent_commit(sub, 0); //看上去主要是处理subsurface的view对应的位置
                ...
                weston_view_set_position //这个是绝对坐标
                ...
}    

如果是subsurface则走subsurface_commit,否则走surface_commit


1.weston_subsurface_commit(struct weston_subsurface *sub)
    if (weston_subsurface_is_synchronized(sub)) {
	    weston_subsurface_commit_to_cache(sub);
    } else {
	    if (sub->has_cached_data) {
		    /* flush accumulated state from cache */
		    weston_subsurface_commit_to_cache(sub);
		    weston_subsurface_commit_from_cache(sub);
	    } else {
		    weston_surface_commit(surface);
	    }

	    wl_list_for_each(tmp, &surface->subsurface_list, parent_link) {
		    if (tmp->surface != surface)
			    weston_subsurface_parent_commit(tmp, 0);
	    }
    }

    判断父子surface为同步或异步,并完成相应的commit操作
...

目前weston在commit的逻辑里面加载了对fence的支持。 shm-buffer还不支持

 buffer对应绘画的部分,viewport对应最终显示的状态,中间有一个缩放或者裁剪的过程。

 补充:

wl_subsurface::set_sync - set sub-surface to synchronized mode
Change the commit behaviour of the sub-surface to synchronized mode, also described
as the parent dependent mode.

In synchronized mode, wl_surface.commit on a sub-surface will accumulate the
committed state in a cache, but the state will not be applied and hence will not
change the compositor output. The cached state is applied to the sub-surface
immediately after the parent surface's state is applied. This ensures atomic
updates of the parent and all its synchronized sub-surfaces. Applying the cached
state will invalidate the cache, so further parent surface commits do not
(re-)apply old state.

wl_subsurface::set_sync—将subsurface设置为同步模式
将子表面的提交行为更改为同步模式,也就是描述作为父依赖模式。
在同步模式下,子表面上的wl_surface.commit将提交状态累积在缓存中,
if (weston_subsurface_is_synchronized(sub)) {
		weston_subsurface_commit_to_cache(sub);
但是该状态不会被应用,因此也不会被更改compositor的输出。
在应用父表面的状态之后立即执行“缓存的状态应用于子表面”。
这样可以确保原子性父类及其所有同步子表面的更新。
已经使用的subsurface的缓存将被使用后无效话,下次父表面的提交将不会再次应用子表面的老的state.



另外一种:
wl_subsurface::set_desync - set sub-surface to desynchronized mode
Change the commit behaviour of the sub-surface to desynchronized mode, also described as 
independent or freely running mode.
In desynchronized mode, wl_surface.commit on a sub-surface will apply the pending state 
directly, without caching, as happens normally with a wl_surface. Calling
wl_surface.commit on the parent surface has no effect on the sub-surface's wl_surface
state. This mode allows a sub-surface to be updated on its own.
If cached state exists when wl_surface.commit is called in desynchronized mode, the
pending state is added to the cached state, and applied as a whole. This invalidates the cache.

Note: even if a sub-surface is set to desynchronized, a parent sub-surface may override
it to behave as synchronized. For details, see wl_subsurface.
If a surface's parent surface behaves as desynchronized, then the cached state is applied
on set_desync.
将子表面的提交行为更改为去同步模式,也称为独立或自由运行模式。
在不同步模式下,子表面上的wl_surface.commit将直接应用挂起状态,而不使用缓存,就像在wl_surface上
通常所做的那样。在父表面上调用wl_surface.commit对子表面的wl_surface状态没有影响。此模式允许子表
面自行更新。
如果在以非同步模式调用wl_surface.commit时存在缓存状态,则将挂起状态添加到缓存状态,并作为一个整
体应用。这会使缓存失效。也就是,本来应该是对pending结构体做操作,变量换成了cached结构体

server:
2.weston_surface_commit
    weston_surface_commit_state(surface, &surface->pending);
            //注意参数,一个是之前的pending;把pending里面存储的状态转移给surface
                      
    weston_surface_commit_subsurface_order(surface);
            //更新subsurface的顺序,其实也是将subsurface从pending列表换到当前的列表中
            ...【todo】

    weston_surface_schedule_repaint(surface);
            //重绘界面,这块逻辑复杂

 weston_surface_commit::weston_surface_commit_state

里面很多egl函数看不懂,见此参考gl-renderer.c的gl_renderer_setup 里面存在关联操作,如:

3728     gr->image_target_texture_2d =
3729         (void *) eglGetProcAddress("glEGLImageTargetTexture2DOES");

weston_surface_commit_state
0    surface->buffer_viewport = state->buffer_viewport;
     具体内容查看buffer_viewport结构体,主要与缩放设置相关
     把pending交给对应的surface
...
if(state->newly_attached) {
     fence相关,也是把pending的acquire_fence_fd给到surface,
//attach。之前已经画好的图,在attach里面绑定到surface上面,gl_renderer创建texture。将之前client自己画好的buffer和这个[不一定一个]texture关联上。
1    weston_surface_attach(surface, state->buffer);  
        weston_buffer_reference(&surface->buffer_ref, buffer);     //先关联weston_surface和weston_buffer
        surface->compositor->renderer->attach(surface, buffer);    //一般来说,有gl_renderer就不会使用pixman等软件渲染backend;关于attach,本质上是执行ensure_textures(gs, num_planes); 
            gl_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
                weston_buffer_reference(&gs->buffer_ref, buffer);  //再关联gl_surface_state和weston_buffer
            最终调用gl_renderer_attach;根据buffer->resource的不同,调用不同的attch函数:
                gl_renderer_attach_shm                    //不同的图像格式需要的plane不一样,yuv普遍多一些[yuv分开存放,一个存y,一个存v或者uv...];app申请了shm的server,有wl_shm_buffer的实例,会走入这个逻辑;
                //创建gl_sruface_state gs对象指针,填充gs结构体,为gs对象生成并绑定GL_TEXTURE_2D texture对象
                    gs->target = GL_TEXTURE_2D; //设置为2D纹理
                    gs->surface = es;  //es是weston_surface;gs是gl_surface_state
                    ensure_textures(gs, GL_TEXTURE_2D, num_planes); //为从client传过来的buffer创建2d纹理;不同format的纹理数不一样,shm里面的逻辑只有在第一次创建次client的时候才有,后续无论图片如何变化都不再进入。也就是为新的buffer创建texture
                gl_renderer_attach_egl
                    buffer->legacy_buffer = (struct wl_buffer *)buffer->resource;   
                    ensure_textures //同上
                    egl_image_create //为对应buffer创建egl_image
                        eglCreateImage    //这部分请查看我文章对eglapi的笔记!!! 
                    image_target_
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值