12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- Motivation:
- In complicated DMA pipelines such as graphics (multimedia, camera, gpu, display)
- a consumer of a buffer needs to know when the producer has finished producing
- it. Likewise the producer needs to know when the consumer is finished with the
- buffer so it can reuse it. A particular buffer may be consumed by multiple
- consumers which will retain the buffer for different amounts of time. In
- addition, a consumer may consume multiple buffers atomically.
- The sync framework adds an API which allows synchronization between the
- producers and consumers in a generic way while also allowing platforms which
- have shared hardware synchronization primitives to exploit them.
- Goals:
- * provide a generic API for expressing synchronization dependencies
- * allow drivers to exploit hardware synchronization between hardware
- blocks
- * provide a userspace API that allows a compositor to manage
- dependencies.
- * provide rich telemetry data to allow debugging slowdowns and stalls of
- the graphics pipeline.
- Objects:
- * sync_timeline
- * sync_pt
- * sync_fence
- sync_timeline:
- A sync_timeline is an abstract monotonically increasing counter. In general,
- each driver/hardware block context will have one of these. They can be backed
- by the appropriate hardware or rely on the generic sw_sync implementation.
- Timelines are only ever created through their specific implementations
- (i.e. sw_sync.)
- sync_pt:
- A sync_pt is an abstract value which marks a point on a sync_timeline. Sync_pts
- have a single timeline parent. They have 3 states: active, signaled, and error.
- They start in active state and transition, once, to either signaled (when the
- timeline counter advances beyond the sync_pt’s value) or error state.
- sync_fence:
- Sync_fences are the primary primitives used by drivers to coordinate
- synchronization of their buffers. They are a collection of sync_pts which may
- or may not have the same timeline parent. A sync_pt can only exist in one fence
- and the fence's list of sync_pts is immutable once created. Fences can be
- waited on synchronously or asynchronously. Two fences can also be merged to
- create a third fence containing a copy of the two fences’ sync_pts. Fences are
- backed by file descriptors to allow userspace to coordinate the display pipeline
- dependencies.
- Use:
- A driver implementing sync support should have a work submission function which:
- * takes a fence argument specifying when to begin work
- * asynchronously queues that work to kick off when the fence is signaled
- * returns a fence to indicate when its work will be done.
- * signals the returned fence once the work is completed.
- Consider an imaginary display driver that has the following API:
- /*
- * assumes buf is ready to be displayed.
- * blocks until the buffer is on screen.
- */
- void display_buffer(struct dma_buf *buf);
- The new API will become:
- /*
- * will display buf when fence is signaled.
- * returns immediately with a fence that will signal when buf
- * is no longer displayed.
- */
- struct sync_fence* display_buffer(struct dma_buf *buf,
- struct sync_fence *fence);
|