Android fb driver中的fence机制

    Android HardwareComposer中的fence机制中讨论了hwc中的fence,hwc最终把layer的acqireFenceFd送进fb driver,再由fb drvier生成新的reitreFenceFd并return回user space.本篇文章我们来探讨下fb driver中的fence,看看S3CFB_WIN_CONFIG ioctl都做了些什么.

    kernel代码下载地址: https://android.googlesource.com/kernel/exynos.git

    文章中用到的code:

    exynos/include/linux/sync.h

    exynos/drivers/base/sync.c

    exynos/include/linux/sw_sync.h

    exynos/drivers/base/sw_sync.c

    exynos/drivers/video/s3c-fb.c 

    在讨论fb driver中的fence之前,先来简单介绍几个和fence相关的基本数据结构:

/**
 * struct sync_timeline - sync object
 * @kref:		reference count on fence.
 * @ops:		ops that define the implementaiton of the sync_timeline
 * @name:		name of the sync_timeline. Useful for debugging
 * @destoryed:		set when sync_timeline is destroyed
 * @child_list_head:	list of children sync_pts for this sync_timeline
 * @child_list_lock:	lock protecting @child_list_head, destroyed, and
 *			  sync_pt.status
 * @active_list_head:	list of active (unsignaled/errored) sync_pts
 * @sync_timeline_list:	membership in global sync_timeline_list
 */
struct sync_timeline {
	struct kref		kref;
	const struct sync_timeline_ops	*ops;
	char			name[32];

	/* protected by child_list_lock */
	bool			destroyed;

	struct list_head	child_list_head;
	spinlock_t		child_list_lock;

	struct list_head	active_list_head;
	spinlock_t		active_list_lock;

	struct list_head	sync_timeline_list;
};
    sync_timeline中包含一个由list_head串起来的sync_pt双向链表child_list_head.

/**
 * struct sync_pt - sync point
 * @parent:		sync_timeline to which this sync_pt belongs
 * @child_list:		membership in sync_timeline.child_list_head
 * @active_list:	membership in sync_timeline.active_list_head
 * @signaled_list:	membership in temorary signaled_list on stack
 * @fence:		sync_fence to which the sync_pt belongs
 * @pt_list:		membership in sync_fence.pt_list_head
 * @status:		1: signaled, 0:active, <0: error
 * @timestamp:		time which sync_pt status transitioned from active to
 *			  singaled or error.
 */
struct sync_pt {
	struct sync_timeline		*parent;
	struct list_head	child_list;

	struct list_head	active_list;
	struct list_head	signaled_list;

	struct sync_fence	*fence;
	struct list_head	pt_list;

	/* protected by parent->active_list_lock */
	int			status;

	ktime_t			timestamp;
};
    sync_pt中parent指针指向了sync_pt所属的sync_timeline,child_list表示了sync_pt在sync_timeline.child_list_head中的位置.fence指针指向了sync_pt所属的fence,pt_list表示了sync_pt在fence.pt_list_head中的位置.

/**
 * struct sync_fence - sync fence
 * @file:		file representing this fence
 * @kref:		referenace count on fence.
 * @name:		name of sync_fence.  Useful for debugging
 * @pt_list_head:	list of sync_pts in ths fence.  immutable once fence
 *			  is created
 * @waiter_list_head:	list of asynchronous waiters on this fence
 * @waiter_list_lock:	lock protecting @waiter_list_head and @status
 * @status:		1: signaled, 0:active, <0: error
 *
 * @wq:			wait queue for fence signaling
 * @sync_fence_list:	membership in global fence list
 */
struct sync_fence {
	struct file		*file;
	struct kref		kref;
	char			name[32];

	/* this list is immutable once the fence is created */
	struct list_head	pt_list_head;

	struct list_head	waiter_list_head;
	spinlock_t		waiter_list_lock; /* also protects status */
	int			status;

	wait_queue_head_t	wq;

	struct list_head	sync_fence_list;
};
    file指针表示fence所对应的file,linux中一切皆是file.pt_list_head是一个由list_head串起来的sync_pt双向链表.

sync_timeline,sync_pt和sync_fence的关系可以用下面的图来表示:

    syc_timeline来管理所有在这条timeline上的sync_pt,可以决定sync_pt何时被signal.sync_fence中可以包含一个或者多个sync_pt,当sync_fence中所有的sync_pt被signal的时候,sync_fence被signal.

    不过sync_timeline sync_pt有点像一个virtual class,真正在使用的时候需要"继承"它,并实现它定义的sync_timeline_ops  *ops接口,s3c-fb.c 使用的是sw_sync_timeline和sw_sync_pt,定义如下:

struct sw_sync_timeline {
	struct	sync_timeline	obj;

	u32			value;
};

struct sw_sync_pt {
	struct sync_pt		pt;

	u32			value;
};
    sw_sync_timeline和sw_sync_pt相当简单,只不过是在原本的sync_timeline和sync_pt基础上多加了一个u32的value而已.另外sw_sync_timeline和sync_pt还开出了几个新的api.

struct sw_sync_timeline *sw_sync_timeline_create(const char *name);
void sw_sync_timeline_inc(struct sw_sync_timeline *obj, u32 inc);

struct sync_pt *sw_sync_pt_create(struct sw_sync_timeline *obj, u32 value);
    上面这三个api在s3c-fb.c 中都会用到,我们在分析到对应code的时候再来深入分析.


    接下来我们进入s3c-fb.c,具体看下sw_sync_timeline,sw_sync_pt和sync_fence是如何使用的.首先,s3c-fb定义了一些和处理fence相关的member

struct s3c_fb {
    ...
    struct fb_info		*fbinfo;
    struct list_head    updat
  • 4
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值