Graphics synchronization, color, and HDR

Explain graphics synchronization and the boundaries of color and HDR handling.

13 min readChapter 129 of 168Intermediate → advanced
In this chapter

Before you start#

Read Wayland surfaces and buffers and compositor output paths. This chapter uses Wayland-protocols 1.36 for two synchronization extensions. That is a separate version from the Wayland 1.23.0 core library and from any compositor implementation. Neither the core version nor an advertised extension alone proves that a particular display supports HDR.

Learning goals#

Track a buffer's storage ownership, GPU dependencies, release, and presentation independently. Explain how encoded pixel values relate to linear light and why blending, output capability, and color metadata affect the result. Distinguish an available protocol from a tested hardware pipeline.

Source walkthrough#

Buffer readiness and display color
  1. Producer

    Writes pixels and signals an acquire dependency

  2. Compositor

    Waits, interprets color and blends

  3. Output

    Applies supported transforms and presents

  4. Release

    Signals when the relevant storage use is complete

Conceptual model. Conditional synchronization and color processing, not a captured GPU execution.

A producer may finish issuing drawing commands long before the GPU finishes executing them. A compositor that samples those pixels too early can read an incomplete frame. A fence represents a dependency that becomes signaled when a particular operation reaches its completion condition; it does not own the entire application object graph or prove that pixels appeared on a display. The allocation itself is retained by references held by producers, consumers, shared-buffer descriptors, driver objects and possibly display hardware. A fence and a buffer reference solve different problems: one orders work, the other keeps an object alive.

A Linux DMA-BUF is a shareable buffer object represented in userspace by a file descriptor. In an implicit synchronization path, the associated kernel reservation object can hold DMA fences describing accesses. Importers and drivers must honor the relevant synchronization rules; details vary with the API and driver. An application cannot infer that every graphics interface automatically tracks every access merely because a DMA-BUF exists. CPU access may require its own synchronization and cache-coherency procedure, and a CPU pointer or reference alone does not wait for a GPU. See Linux v6.12's DMA reservation interface and DMA-BUF documentation.

Explicit synchronization communicates dependencies through an agreed API or protocol instead of relying solely on implicit reservation fences. The historical unstable Wayland extension passes an acquire fence as a file descriptor referring to a synchronization fence. The newer DRM syncobj extension represents a timeline and a point on that timeline. These are distinct protocols with distinct versioning and error rules. A timeline point is a 64-bit value on a particular timeline object; a number alone is not a globally meaningful fence. An importer must be able to import the timeline and share its kernel object. Protocol negotiation, supported buffer type, kernel interfaces and compositor support determine whether this path is available. See explicit synchronization XML 1.36 and DRM syncobj XML 1.36.

From unstable/linux-explicit-synchronization/linux-explicit-synchronization-unstable-v1.xml, set_acquire_fence, wayland-protocols 1.36, MIT-style copyright and license in the file; surrounding protocol text is omitted:

text
        If the provided fd is not a valid dma_fence fd, then an INVALID_FENCE
        error is raised.

The first line identifies the descriptor as a required valid fence reference. The second defines a protocol error for invalid input, rather than treating an arbitrary fd as a readiness notification. The surrounding description also specifies duplicate-fence, no-surface, unsupported-buffer and no-buffer errors. A client must handle connection failure and release its own fd references according to the API's transfer rules. A failed import does not make the buffer ready, and a client must not silently substitute an unverified claim of completion.

From staging/linux-drm-syncobj/linux-drm-syncobj-v1.xml, set_acquire_point, the same pinned project release and MIT-style file notice; later validation text is omitted:

text
        Set the timeline point that must be signalled before the compositor may
        sample from the buffer attached with wl_surface.attach.

The dependency applies before the compositor samples the attached buffer, not before the client begins drawing. The surrounding XML makes the point double-buffered surface state applied at the next commit, and specifies errors for missing paired state. It also describes a release point: the compositor signals the chosen point when it has finished using the committed buffer under that protocol. The existence of such a point does not eliminate the need to keep associated timeline and buffer objects alive and to handle a destroyed surface or failed connection.

Two buffers, four kinds of completion

Suppose two buffers A and B have independent backing storage. Initially both are free. The client renders into A and commits it with acquire timeline point 10 and release point 11. The compositor must not sample A before point 10 signals. When point 10 signals, the rendering dependency is satisfied; A is not yet free for modification because the compositor may still sample it or keep it for scanout. It can request and receive a frame callback while A is still in use. The client renders B and commits it with its own appropriate acquire and release points. Only the completion condition for A's relevant use, signaled through the negotiated release mechanism, permits its storage to be reused. The actual signal ordering and sharing rules must follow the selected protocol and timeline implementation; these values are illustrative.

Two buffers, separate completions

Synthetic teaching data, not a device capture.

Two buffers, separate completions1. Client to Compositor: commit A: acquire 10, release 11. 2. Compositor to Output: present A when scanout is permitted. 3. Compositor to Client (return): frame callback paces next update. 4. Client to Compositor: commit B with its own timelines. 5. Compositor to Client (return): release 11 after A has no compositor use. 6. Output to Compositor (return): page flip completion (conditional).ClientCompositorOutputcommit A: acquire 10,release 11present A when scanoutis permittedframe callback pacesnext updatecommit B with its owntimelinesrelease 11 after A hasno compositor usepage flip completion(conditional)
  1. ClientCompositor

    commit A: acquire 10, release 11

  2. CompositorOutput

    present A when scanout is permitted

  3. CompositorClient

    Return. frame callback paces next update

  4. ClientCompositor

    commit B with its own timelines

  5. CompositorClient

    Return. release 11 after A has no compositor use

  6. OutputCompositor

    Return. page flip completion (conditional)

Time runs downward. Dashed arrows show returns.

Read the text version
  1. Client → Compositor: commit A: acquire 10, release 11
  2. Compositor → Output: present A when scanout is permitted
  3. Compositor → Client (return): frame callback paces next update
  4. Client → Compositor: commit B with its own timelines
  5. Compositor → Client (return): release 11 after A has no compositor use
  6. Output → Compositor (return): page flip completion (conditional)
Synthetic teaching data. Illustrative timeline using the chapter values for points 10 and 11; not a captured compositor run. Each event has a different meaning.

A wl_buffer.release event, explicit release point, frame callback, and presentation feedback are not interchangeable. A frame callback helps pace future updates. A buffer release communicates a compositor-use lifetime under core protocol rules. An explicit synchronization protocol can alter the release contract for the associated surface and buffer, so the client must follow that extension rather than assume both signals are always required or always equivalent. Presentation feedback, when supported, reports presentation or discard for a commit; it is not a general buffer ownership reference. An output can be occluded, disconnected, replaced, or fail to present. Neither an acquire signal nor a successful submit proves that a person saw the frame.

From wayland-protocols 1.36 unstable/linux-explicit-synchronization/linux-explicit-synchronization-unstable-v1.xml, fenced_release, MIT-style permission notice in the file header (the XML attributes and the immediate_release event are omitted):

text
        Sent when the compositor has finalised its usage of the associated
        buffer for the relevant commit, providing a dma_fence which will be
        signaled when all operations by the compositor on that buffer for that
        commit have finished.

        Once the fence has signaled, and assuming the associated buffer is not
        pending release from other wl_surface.commit requests, no additional
        explicit or implicit synchronization is required to safely reuse or
        destroy the buffer.

The description ties release to the compositor's finished use of a buffer for one commit, with a fence that signals when those operations complete. Reuse is still conditional on other pending commits for the same buffer. The excerpt does not cover immediate_release, how the client imports the fence file descriptor, or whether presentation occurred.

When a client closes a DMA-BUF fd after a successful transfer, another process's received fd and an existing mapping have independent lifetimes. The client still has to coordinate GPU work and every alias of the allocation. On protocol disconnect, the application should stop scheduling new work, cancel or join its own workers, release local resources and not wait forever for a release event that can no longer arrive. GPU submissions and driver object lifetimes remain API-specific; destroying a userspace wrapper is not a universal substitute for completion or safe deferred destruction. A compositor facing import failure must discard or reject the candidate and unwind references; it cannot read memory it failed to import.

What a pixel value means

A pixel format specifies the arrangement and numerical representation of channels, such as components stored in eight-bit fields. It does not by itself fully identify the colors those values represent. Primaries define a set of reference colors and thereby a gamut, the range of chromaticities representable using those primaries under the relevant model. A white point anchors the interpretation of neutral values. A transfer function relates encoded channel values to light or scene quantities. The same stored value in two encodings can represent different light levels. An ICC profile can describe a color space and transforms using standardized profile data, but its correctness depends on the profile, rendering intent, pipeline and device characterization.

The familiar sRGB transfer curve is nonlinear. PQ and HLG are different transfer systems used in HDR workflows; they are not interchangeable with sRGB or with each other. PQ's absolute luminance relationship and HLG's system-dependent interpretation require more context than the bit depth of a buffer. HDR usually concerns the relationship between content, luminance range, color encoding and a display's capabilities, not simply whether a channel has ten bits. A wide-gamut buffer can contain ordinary low-dynamic-range content, while an HDR transfer function does not guarantee a display can reproduce the intended range.

Composition should account for color spaces and alpha conventions. With premultiplied alpha, stored color components already include their coverage or opacity factor. A common source-over operation adds the premultiplied source to the background multiplied by one minus source alpha, with compatible linear-light values. Applying that equation directly to nonlinear encoded values produces a different result. The compositor must also understand whether the source was premultiplied and whether its metadata is trustworthy; treating straight-alpha data as premultiplied can produce fringes. Converting between color spaces can require clipping or gamut mapping, and tone mapping can map a high-luminance scene onto a less capable output.

Worked linear blend

Assume a simplified neutral channel normalized so 1.0 means the reference white for this example. A foreground emits 0.8 linear units at alpha 0.25 over a background of 0.2 linear units. Premultiply the foreground: 0.8 times 0.25 equals 0.20. The remaining background contributes 0.2 times 0.75, or 0.15. The result is 0.35 linear units. These are relative linear-light values, not nits and not sRGB-encoded bytes. The result then needs the output's appropriate transfer encoding before storage in a nonlinear output format.

Blend in linear units, encode last

Synthetic teaching data, not a device capture.

  1. Premultiply

    Foreground 0.8 times alpha 0.25 gives 0.20 linear units.

  2. Background term

    Background 0.2 times (1 - 0.25) gives 0.15.

  3. Sum

    Source-over result is 0.35 relative linear light.

  4. Encode last

    Apply the output transfer function separately; sRGB, PQ and HLG are not interchangeable.

Synthetic teaching data. Arithmetic on synthetic relative values; not nits, not sRGB bytes, and not a measurement of any display.

As a counterexample, blindly averaging two encoded byte values and calling the result a linear-light mixture assumes a transfer function that is linear. sRGB is not. Similarly, interpreting an HDR metadata field as proof of actual output luminance ignores the selected monitor mode, compositor policy, display processing and hardware limits. A correct calculation in one assumed space is not proof that an end-to-end display pipeline is calibrated.

Output hardware and capabilities

KMS can expose color-related properties and lookup tables, depending on driver and hardware. A compositor may perform a transform in a shader, use hardware tables, use plane properties, or combine them. Output limitations, precision, available planes and the chosen mode influence the result. A direct-scanout candidate may bypass some compositor rendering steps but still needs appropriate color and synchronization handling. An unsupported property, atomic validation failure, absent display metadata or inability to import a buffer must be handled as a conditional failure, not interpreted as automatic HDR support or guaranteed zero-copy.

The Wayland core 1.23.0 baseline does not itself provide a universal HDR color-management protocol. Color-management extensions and implementations have their own revisions and availability; this chapter does not claim that the synchronization XML defines a color protocol. A compositor can negotiate one protocol while lacking another. A client must test the advertised interfaces, versions, supported formats and configuration, then choose a supported fallback. Metadata can communicate an intended interpretation; it is not a hardware calibration measurement and does not prove the display emitted a particular number of nits.

When a display pipeline changes

Imagine a client renders an HDR scene while a window straddles two outputs with different capabilities. The surface is one logical object, but each output may require a distinct transform or tone-mapping decision. Moving the window does not automatically rewrite its pixel data or change the source primaries. A compositor that understands the content can potentially render separate output-specific results; a direct-scanout optimization may no longer be feasible on one output. This is a conditional example: actual protocol support, policy, available planes and driver capabilities determine what any compositor does. A color conversion is also not necessarily reversible after clipping or tone mapping.

Suppose a render completion fence signals but the display disconnects before the corresponding presentation. The signal still indicates completion of the producer's work under that fence's contract; it does not establish that presentation occurred. The compositor has to retire or cancel its own output work and honor the selected release protocol where possible. The client must be prepared for a discarded presentation or connection failure, and its teardown must handle its own references even if expected future callbacks never arrive. If it passes the same allocation to another consumer, release by the first consumer does not prove the second has finished. Tracking each use separately avoids treating a single event as a global property of all aliases.

A timeline value is likewise meaningful only with its associated timeline object. Point 10 on timeline X and point 10 on timeline Y are different dependencies. If an application chooses the wrong timeline or reuses a point contrary to its synchronization design, a correct-looking integer comparison cannot repair the missing ordering. This is why the protocol transports a timeline object as well as high and low halves of the point value. Kernel object handles, shared descriptors, GPU command completion and the application's own state machine must agree about which operation the point represents.

Practice#

This local arithmetic model requires Python 3. It does not connect to a GPU or display and does not measure a color:

sh
python3 - <<'PY'
foreground, background, alpha = 0.8, 0.2, 0.25
result = foreground * alpha + background * (1-alpha)
print(f'linear result: {result:.2f}')
assert abs(result - 0.35) < 1e-9
PY

Expected output is linear result: 0.35. A counterexample is to treat the same numbers as nonlinear encoded values and claim the arithmetic establishes physical luminance; the assumptions do not support that conclusion. As a source-only alternative, use the two-buffer sequence above and write a table for A containing acquire point, sample permission, frame callback, release point and reuse permission. Explain why frame callback alone leaves A busy. The deliverable is that table plus the blend calculation, with units and assumptions stated.

Knowledge check#

  1. What is the difference between a buffer reference and an acquire fence?
  2. Can a frame callback establish that buffer A is reusable?
  3. What happens when the explicit-sync acquire fd is invalid?
  4. Why does an HDR metadata field not prove correct HDR output?
  5. Why is 0.35 in the worked example not automatically an encoded sRGB value?

Answers#

  1. A reference preserves an object's lifetime; an acquire fence orders a consumer's access after a producer's work. Either without the other can leave an unsafe pipeline.
  2. No. It is a pacing event. Reuse follows the applicable buffer-release or explicit-release contract after all relevant uses are complete.
  3. The specified protocol raises INVALID_FENCE; the application must handle the resulting protocol failure and cleanup rather than assume the buffer became ready.
  4. Monitor capabilities, mode, transforms, compositor implementation and calibration all matter. Metadata describes intended content, not measured emitted light.
  5. The inputs and result were defined in relative linear-light units. sRGB encoding is nonlinear and must be applied separately for an sRGB output representation.

Checkpoint#

Submit the A/B timeline and the 0.35 calculation. Pass when the timeline separates acquire, frame pacing, release and presentation, and the calculation labels linear units and premultiplied alpha. If any event is conflated, reread the pinned XML and repeat the state table. This exercise is practice, not certification.

Sources#

Read Wayland explicit synchronization, Wayland DRM syncobj, Linux reservation fences, and DMA-BUF documentation. The diagram and numerical sequence are explanatory models, not measured GPU or display behavior.

A little further beneath the surface.

Check your understanding with the checkpoint. Marking a chapter as read saves a bookmark, not a proficiency assessment.