1Motivation: 2 3In complicated DMA pipelines such as graphics (multimedia, camera, gpu, display) 4a consumer of a buffer needs to know when the producer has finished producing 5it. Likewise the producer needs to know when the consumer is finished with the 6buffer so it can reuse it. A particular buffer may be consumed by multiple 7consumers which will retain the buffer for different amounts of time. In 8addition, a consumer may consume multiple buffers atomically. 9The sync framework adds an API which allows synchronization between the 10producers and consumers in a generic way while also allowing platforms which 11have shared hardware synchronization primitives to exploit them. 12 13Goals: 14 * provide a generic API for expressing synchronization dependencies 15 * allow drivers to exploit hardware synchronization between hardware 16 blocks 17 * provide a userspace API that allows a compositor to manage 18 dependencies. 19 * provide rich telemetry data to allow debugging slowdowns and stalls of 20 the graphics pipeline. 21 22Objects: 23 * sync_timeline 24 * sync_pt 25 * sync_fence 26 27sync_timeline: 28 29A sync_timeline is an abstract monotonically increasing counter. In general, 30each driver/hardware block context will have one of these. They can be backed 31by the appropriate hardware or rely on the generic sw_sync implementation. 32Timelines are only ever created through their specific implementations 33(i.e. sw_sync.) 34 35sync_pt: 36 37A sync_pt is an abstract value which marks a point on a sync_timeline. Sync_pts 38have a single timeline parent. They have 3 states: active, signaled, and error. 39They start in active state and transition, once, to either signaled (when the 40timeline counter advances beyond the sync_pt’s value) or error state. 41 42sync_fence: 43 44Sync_fences are the primary primitives used by drivers to coordinate 45synchronization of their buffers. They are a collection of sync_pts which may 46or may not have the same timeline parent. A sync_pt can only exist in one fence 47and the fence's list of sync_pts is immutable once created. Fences can be 48waited on synchronously or asynchronously. Two fences can also be merged to 49create a third fence containing a copy of the two fences’ sync_pts. Fences are 50backed by file descriptors to allow userspace to coordinate the display pipeline 51dependencies. 52 53Use: 54 55A driver implementing sync support should have a work submission function which: 56 * takes a fence argument specifying when to begin work 57 * asynchronously queues that work to kick off when the fence is signaled 58 * returns a fence to indicate when its work will be done. 59 * signals the returned fence once the work is completed. 60 61Consider an imaginary display driver that has the following API: 62/* 63 * assumes buf is ready to be displayed. 64 * blocks until the buffer is on screen. 65 */ 66 void display_buffer(struct dma_buf *buf); 67 68The new API will become: 69/* 70 * will display buf when fence is signaled. 71 * returns immediately with a fence that will signal when buf 72 * is no longer displayed. 73 */ 74struct sync_fence* display_buffer(struct dma_buf *buf, 75 struct sync_fence *fence); 76