1
0
Fork 0
Commit graph

235 commits

Author SHA1 Message Date
Manasi Navare
b23482b05c drm_hwcomposer: Add HDCP state tracking to request it to be enabled
This adds HDCP state tracking through Client to HwcDisplay
When Client requests HDCP to be enabled for secure layers
Hdcpstate in the corresponding HwcDisplay is set up.
This is parsed to set the Content Protection and HDCP Content Type
properties for the connector in the next commit

Change-Id: I60dd4359ee2f87faba1df83c7faf286b34af43f6
Signed-off-by: Manasi Navare <navaremanasi@google.com>
2025-10-14 19:10:56 +00:00
Andrew Wolfers
48f056ff82 Track stats per unique composition attributes
This change adds a new CompositionAttributes struct which
tracks information about a given composition as it is
validated and subsequently presented.

Previously CompositionStats were tracked as totals for each
display. This change splits the stats according to the
CompositionAttributes for each presented composition.

This change only affects the reporting behavior of
CompositionStatsTracker. The stats logged by DumpState are
totaled so as to not be affected.

Change-Id: I050cce7f63891971cc807b9c5150d9b5d30f1f0b
2025-10-08 16:44:33 +00:00
Gil Dekel
9a76e062b6 Move EdidWrapper from DrmConnector to HwcDisplay
The EdidWrapper lifecycle was previously managed by DrmConnector,
meaning the EDID parser was initialized when the connector was created.
This approach fails for physical connectors where a display is not
attached at boot, as no EDID blob is available to parse.

When a display was subsequently hot-plugged, the system would fall back
to a generic EdidWrapper. This provided incorrect or default display
properties to userspace, causing critical bugs such as:

  * Incorrect DPI calculations, leading to improperly scaled UI in
    Android.
  * Inability to detect HDR capabilities or supported color modes.

This change moves the ownership and lifecycle management of the
EdidWrapper to HwcDisplay. By creating the parser only when a display is
actually connected, we ensure that the correct EDID is always parsed,
making hot-plug functionality work as intended.

Change-Id: I5e056e423bbac2b23a411395b4ce13ccd03c4b64
Signed-off-by: Gil Dekel <gildekel@google.com>
2025-10-06 13:44:31 -04:00
Andrew Wolfers
8940921be7 drm_hwcomposer: Add GetUsablePlanes tests to DrmDisplayPipelineTest
Change-Id: I02391c51ba392795bc39b3d918b5b86e5f4079bd
2025-10-02 15:06:23 +00:00
Andrew Wolfers
a95aa3b1c7 drm_hwcomposer: Add CreatePipeline tests to DrmDisplayPipelineTest
Change-Id: If105c7773e7f4adaa9c0ab7e6f410d9cc09f476e
2025-10-02 15:06:21 +00:00
Andrew Wolfers
086a6f1fc4 drm_hwcomposer: Add drm object fakes for DrmDisplayPipelineTest
Change-Id: I1ffbf45a787bac8ce414ef03701bc544835da3a7
2025-10-02 15:06:19 +00:00
Andrew Wolfers
ec00b3dc25 drm_hwcomposer: Add PipelineBindable unit tests
Change-Id: Iada6f16cb3b72f38cbaad1b71b38c8ef201c4722
2025-10-02 15:06:16 +00:00
Andrew Wolfers
84892ec611 drm_hwcomposer: Cleanup includes for test target
Change-Id: I1332873df0109347a91e729955ba5f84cf8c7fec
2025-10-02 15:06:12 +00:00
Andrew Wolfers
ff954db228 drm_hwcomposer: Add buildflag guards around libsync deps
This change adds the buildflag HAS_LIBSYNC for managing
availability of libsync. This is necessary for the
unittests target for which libsync doesn't provide the
necessary variant.

DrmAtomicStateManager.cpp is the only file which depends
on libsync. Guards have been added using the HAS_LIBSYNC
flag, such that any method which would depend on libsync
is now stubbed when it is unavailable.

Change-Id: I101083074a9fad98e1c40c27b55f2eddf1c53581
2025-10-02 15:06:06 +00:00
Su Hong Koo
87ffe73cd7 drm_hwcomposer: Update VSyncWorker::last_timestamp_ on every present 2025-10-01 06:24:44 -06:00
Su Hong Koo
7e7e0609ee drm_hwcomposer: Add tracing around validate/present paths
Add perferto tracing around validate and present paths. Specifically
around code that blocks on the main thread (e.g. commit, fence waits).
These should increase the visibility of what is blocking the
presentation hot path in perfetto traces.

Change-Id: I6db60648c5e1d5f1a666ebc52f5ae5ad57e0e82a
2025-09-24 12:11:22 -04:00
Drew Davenport
ac727c57ae drm_hwcomposer: Fix used_plane state tracking
Ensure that the next frame's list of used_planes is correct. The list of
used planes for the new frame is initialized to the previous frame's
list of planes when creating the AtomicRequest. If there is a
composition as a part of this request, the list should be cleared before
creating the new composition, since the list will be re-populated.

Neglecting to clear this left planes on the list when they shouldn't
have been, or the same plane multiple times. This led to some spurious
commit and validation failures on single display configurations, but on
multiple display configurations also resulted in highly visible stuttering.

Change-Id: Ie3fa1fc120fde13ee80f9a144c459526be2822cb
2025-09-19 10:20:08 -06:00
Manasi Navare
d341024047 drm_hwcomposer: Clear connectors and CRTCs on Init
When DRM HWC starts, it resets all the connectors
and CRTCs to avoid the mimatch between drm hwc tracked
state and actual HW state programmed by the firmware
for the splash screen.

This fixes the MST connected boot issue.

Change-Id: I0773541b6bb227a2880d8442cc46411dc4c0127a
Signed-off-by: Manasi Navare <navaremanasi@google.com>
2025-09-18 15:00:19 -06:00
Su Hong Koo
a0f6ed9cc7 drm_hwcomposer: Wait for next present fence earlier in present
Currently, drm_hwcomposer has two main ways to lock up in the
composition hot path:

1. HwcDisplay::WaitForPresenttime(), where it looks at the expected
present time of the frame and sleeps until it is close to it (0.75
vsync period away from the target vsync).

2. DrmAtomicStateManager::WaitLastFrame(), where it waits on the
present fence of the last commit so that we don't call commit when
another present is pending

These are called in-order, which in certain multi-display configuration
with heterogenous refresh rates can lead to the slower display locking
up due to sleep in WaitForPresenttime().

This CL makes DrmAtomicStateManager::WaitLastFrame() public, and moves
its invocation to right before the call to
HwcDisplay::WaitForPresenttime(). This should minimize the impact of
WaitForPresenttime(), and allow drm_hwcomposer to hit more present
targets that it can hit.

Test: atest GraphicsComposerAidlCommandTest
Test: Manual testing w/ perfetto

Change-Id: Ic9c07ff0b6d00dfafce5dd109d8195886dd3094e
Signed-off-by: Su Hong Koo <sukoo@google.com>
2025-09-18 13:24:44 -06:00
Drew Davenport
5a1d68b1f8 drm_hwcomposer: Preserve DrmAtomicStateManager state
The next frame's state needs to be initialized with the current frame's
state to ensure that it doesn't get reset incorrectly.

Change-Id: I00caab6ad4116dceba67cbd945b83c4d45277a39
2025-09-12 10:15:36 -06:00
Andrew Wolfers
ee0b06e40c drm_hwcomposer: Preserve cursor scaling during commit
This change modifies cursor behavior during atomic commit
so that the scaling factor is preserved. Previously, the
src rect was being overwritten to match the dimensions of
the dst rect, because it was assumed that scaling is not
permitted with the cursor plane. The new behavior will
preserve any existing scaling factor while resizing the
src rect. For hardware that cannot use scaling on the
cursor plane, this behavior should now be caught during
test commit, and trigger the appropriate fallback. For
hardware that can use scaling on the cursor plane, the
behavior is fixed such that the cursor will now appear
with the correct sizing.

Change-Id: I1d3e01441bdc5d7076b15d66b1a7a1a498ea64a9
2025-09-11 13:17:00 +00:00
Andrew Wolfers
2261f81762 drm_hwcomposer: Add Rect utility type
This change refactors the IRect and FRect types into a single
templated type Rect<T>, which allows the implementation to be
shared across both variants. This change also adds convenience
getters for the rect widths and heights, and updates callsites
accordingly.

Change-Id: I38509631d57706266186a7b7fa21bd43c0860890
2025-09-10 13:41:51 +00:00
Andrew Wolfers
9255d0d10b drm_hwcomposer: Migrate to android::drm_hwcomposer namespace
Change-Id: I2859aa8f55532d88231389724956fc77b0625339
2025-09-08 18:53:00 +00:00
Andrew Wolfers
d4ab368f7f drm_hwcomposer: Add missing namespaces
Change-Id: I2ac3580664018cf63dc14e9f8025c2e60f843e3c
2025-09-08 18:52:59 +00:00
Drew Davenport
bd61cdab1f drm_hwcomposer: Make CleanFailedCommit private
This is only called from DrmAtomicStateManager so make it private.

Change-Id: I2ad884875514e910fc664e74fc546dbb51821f7e
2025-09-05 14:57:05 -06:00
Drew Davenport
5c7f0d6e53 drm_hwcomposer: const-correctness
Make AtomicCommitArgs const in the different helper functions to build
the AtomicRequest. Additionally, reorder the parameters to reflect the
convention that input parameters are listed first, and out parameters
are listed after.

Change-Id: I0277ec4129fbcd6312e6df9ae3f15600e9755520
2025-09-05 14:57:03 -06:00
Drew Davenport
9e59a16a2c drm_hwcomposer: Don't reset writeback fence
It's not necessary to close the fence after waiting.

Change-Id: I6cfa4dc9e2cfa9fff8a2d40a50b4badf8cb7ce1f
2025-09-05 14:55:26 -06:00
Drew Davenport
faab5a4912 drm_hwcomposer: Make some structs private
Move structs definitions that are only used inside the
DrmAtomicStateManager class to private.

Change-Id: I6f3c48cf14645dae721d0e4f9d9b1e5767f08914
2025-09-05 14:55:24 -06:00
Drew Davenport
c4c008f63a drm_hwcomposer: Use AtomicRequest struct
Add AtomicRequest struct to wrap the pending DrmModeAtomicReq and
related kms objects and state for the pending atomic commit.

After the AtomicRequest's property set has been committed, update the
internal DrmAtomicStateManager state to reflect what has been committed.

Change-Id: I49d39649eb957d69f724b53b91577a347a75527e
2025-09-05 14:54:55 -06:00
Drew Davenport
88527cddf2 drm_hwcomposer: Clear new frame state
Rather than initializing the state associated with a new frame by
copying committed_frame_state_, check committed_frame_state_ directly
when needed.

Change-Id: I62043e15e70669ce6a8ac4635101d13d8efd7f15
2025-09-05 13:42:58 -06:00
Andrew Wolfers
9e75410677 drm_hwcomposer: Fix cursor positioning
In some cases, the position of the cursor is controlled by the src rect.
For example, this is done when the cursor extends beyond the top or left
edges of the screen. This is not compatible with the hw cursor plane
however, because scaling and panning are both disallowed. As a workaround,
the position of the dst rect needs to be adjusted in the opposite
direction (in some cases taking a negative-valued position,) which
will correctly position the cursor while also assigning an acceptible
value to the src rect.

Change-Id: Ide7f75e01481bcd602a33d222d1ae6862703a1cd
2025-08-28 17:32:50 +00:00
Drew Davenport
bf4210c17e drm_hwcomposer: Make TestComposition const
Making TestComposition const ensures that the Backend can't modify any
HwcDisplay state while creating and validating a composition.

Also make a bunch of other stuff const-correct since there is a const
version of GetPipe()

Change-Id: Ib7769d290148ce496b0165b64806dbd0a601b213
2025-08-26 09:27:21 -06:00
Drew Davenport
4a84e27035 drm_hwcomposer: Make HwcLayer const in Backend
Backend shouldn't directly mutate HwcLayer state, so make HwcLayer
const. Make a few other related functions const correct as well.

Change-Id: Id7f8e255e9e72b756399b1a4dabc3db779d64bc9
2025-08-19 09:16:22 -06:00
Gil Dekel
860b363563 drm_hwcomposer: Defer display rect update to prevent state pollution
A test commit or failed modesets, particularly when with modes of a
different resolution, would cause all subsequent pafe-flip commits to
fail.

The root cause was a premature state update within
SetDisplayModeIfNeeded. The `whole_display_rect_` member was being
modified during the commit preparation phase. This polluted the state
manager's internal view of the active display size, causing subsequent
frame compositions to be built with incorrect dimensions, which were
then rejected by the kernel on certain drivers that cannot handle
scaling on the fly.

This change fixes the issue by deferring the state update until after a
commit is successfully applied:

1. `whole_display_rect_` is now only updated inside `CommitFrame` after
   a modesetting commit has been successfully applied to hardware.

2. `SetCompositionIfNeeded` is updated to use the dimensions from the
   incoming `args.display_mode`, if available, when preparing a modeset.
   Otherwise it will use the existing size in `whole_display_rect_`.
   This ensures the plane is correctly configured for either the
   requested mode, or the currently active one (for page-flips).

This prevents test-only operations from having side effects and ensures
the state manager's internal state remains consistent. It also prevents
state pollution on failed modesets.

Change-Id: Icf08b32c13879d394f883f34e6fed3d96a748a4f
Co-authored-by: Lucas Berthou <berlu@google.com>
Signed-off-by: Gil Dekel <gildekel@google.com>
2025-08-13 13:09:01 -04:00
Gil Dekel
3b2050b7f2 drm_hwcomposer: Re-enable MRR on AL devices
Configuration groups for the Multiple Refresh Rate (MRR) feature support
is currently disabled in DRM HWComposer. This is because it is
insufficient to group modes solely based on their active region size.

The primary reasons for this insufficiency are:
1. drm-hwc clients may assume they can seamlessly switch between
   configurations within the same group to support variable refresh
   rates.
2. Not all System-on-a-Chip (SoC) architectures support seamless mode
   transitions.
3. For SoCs that do support seamless switching, transitions often depend
   on other hardware-specific properties like matching blanking periods.
4. A fallback to a non-seamless (blocking) modeset is unacceptable for
   internal displays if a seamless transition fails, as this causes
   flickering. The current framework does not handle such failures
   gracefully.

To Resolve these challenges and re-enable seamless Multiple Refresh-Rate
transitions on internal panels, we add logic to validate all configs
against the preferred initial active config. This validation preforms a
seamless modeset test on each available config against the config that
was set during the display initialization. Configs that fail the
screening are assigned new group IDs.

Caveats:
1. Currently, this is only implemented for internal panels. External
   display seamless transition between variable refresh rates is not
   support. However this work can be extended to support seamless
   transitions on external displays as well.
2. Grouping is only preformed for the preffered/active config at the
   time of display init, and is valid only for the duration of the
   current full modeset commit. No other groups are not created (since
   they cannot be validated), and any new full commits will not honor
   the guarantee provided by the check. This work can be extended to
   refresh and validate all configs within the same group ID of any
   incoming full modeset commit.

Change-Id: Ie2661e74bd3ff704b40c8c7ef50c56e604e5e8df
Signed-off-by: Gil Dekel <gildekel@google.com>
2025-07-29 16:14:12 -04:00
Gil Dekel
109a3d3553 drm_hwcomposer: Return bool for CommitFrame and ExecuteAtomicCommit
Error codes are never checked and working with errors as booleans
results in somewhat counter-intuitive logic.

Change CommitFrame() and ExecuteAtomicCommit() to return bools instead.

Change-Id: I5e8041fd4ddc99ef06184081a7f6def028bbe356
Signed-off-by: Gil Dekel <gildekel@google.com>
2025-07-29 14:47:47 -04:00
Drew Davenport
677e72987b drm_hwcomposer: Remove sleep in unplug handling
SurfaceFlinger should now be handling this race condition more robustly
and it is find to return BAD_DISPLAY in this case. Additionally, there
is no other thread which might be holding a resource resulting in a
deadlock or race during teardown.

Change-Id: I45740febccf2efae2fa470fdbdbe050daadb053b
2025-07-16 17:49:31 -06:00
Drew Davenport
5cdddc176e drm_hwcomposer: Join UEventListener thread on exit
Ensure that the UEventListener has cleanly stopped and joined in the
destructor.

Change-Id: I8e5068b67fcdc235870a8fdbbeb09d1dd8f25520
2025-07-16 17:49:31 -06:00
Lucas Berthou
446c229f98 drm_hwcomposer: refactor drmAtomicStateManager
This is a prerequisit to allow for multi-display commit at once.
It also removes the cognitive complexity of CommitFrame through addition
of helpers for all drm properties to be set.

Change-Id: Ifad7e574c9ea6ced09c677923868ce29656f33f3
Signed-off-by: Lucas Berthou <berlu@google.com>
2025-07-15 21:50:01 +00:00
Andrew Wolfers
f35210964c drm_hwcomposer: Remove cursor buffor validity check
This change removes a check in DrmPlane::IsValidForLayer which would
verify that the buffer size matches known accepted values from the
DRM_CAP_CURSOR or SIZE_HINTS properties. Those properties are required
to return valid buffer sizes for committing to the cursor plane, but
they are not meant to be exhaustive. As a result, this check was
returning false negatives, and forcing the cursor into client
composition unnecessarily. The intended usage is that these props
should be checked during buffer allocation, not during composition.
Instead, test commits are sufficient for detecting whether a buffer
is valid for the cursor plane, and triggering fallback logic as needed.

Change-Id: Iae14436a6f50e45a113a4d18de67e73810b2a83e
Signed-off-by: Andrew Wolfers <aswolfers@google.com>
2025-06-20 15:43:33 +00:00
Drew Davenport
f4cebdbec7 drm_hwcomposer: Move device path to Properties
Add Properties::GetDevicePath to query the value of the
vendor.hwc.drm.device sysprop.

Change-Id: I8c2f9e6f06f3d7f11f03051e21b885413da81c47
2025-06-12 01:51:29 +00:00
Drew Davenport
0f9eae2291 drm_hwcomposer: Move GetCtm to Properties
Move the handling of the sysprop for how to handle CTM to the Properties
class.

Change-Id: I049c8a726fc68576e884b2a7a618a23521d5ed2b
2025-06-12 01:51:29 +00:00
Drew Davenport
e91805b9ae drm_hwcomposer: Cleanly exit DrmAtomicStateManager helper thread
Now that the helper thread doesn't acquire the global lock, we can wait
for the helper thread to exit without risk of deadlock.

Change-Id: Ibaf8a1a64fb1aa64f8b75fd9a8ae1eff81dae0df
2025-06-12 01:39:23 +00:00
Drew Davenport
6443ccecc2 drm_hwcomposer: Remove main_lock and protect shared state
Remove the usage of main_lock_ and ensure that mutex_ is held for no
larger a scope than is necessary.

Reorder some class members to keep protected members together.

Change-Id: Iaf29cf53e11d692fb3779b61b147abfcacf95746
2025-06-12 01:39:23 +00:00
Drew Davenport
457c6b2520 drm_hwcomposer: Use queue for tracked KmsObjects
The distinction between active/staged isn't important for state
tracking, so simplify management of these by using a std::queue.

Change-Id: I1871d3c2f5c6e6686baa9b6473bbbb7072077efc
2025-06-12 01:39:23 +00:00
Drew Davenport
9715b7c9e9 drm_hwcomposer: Separate KmsState and KmsObjects
Since the helper thread doesn't need to access KmsState, and we are only
using the most recently committed state, track the KmsState separately
from the KmsObjects.

The tracked KmsState doesn't need to be synchronized with the helper
thread.

Change-Id: Ic62e0753ee11d3870eb31892f18023688558ff9a
2025-06-12 01:39:23 +00:00
Drew Davenport
c75973027a drm_hwcomposer: Use most recently committed state
When preparing the properties for a commit, the state for the currently
active frame is used, rather than the last committed frame. This is
incorrect and could lead to a scenario such as:

- Frame N: commit enables plane 1
- Frame N+1: commit uses plane 1, 2, 3
- Frame N+2: if executed before staged_frame_state_ is moved to
    active_frame_state_, the new KmsState::used_framebuffers will be
    initialized to {1}
  - commit uses planes 1, 2
  - plane 3 is not disabled by the unused_planes code in CommitFrame

A similar problem exists for the KmsState::crtc_active_state.

To avoid this issue, always use the last committed state, regardless of
whether the previous frame has been presented or not.

Change-Id: I840b5b0ca3a3cf477882cacf6b1d5c0313ae80cf
2025-06-12 01:39:23 +00:00
Drew Davenport
80d7c469d5 drm_hwcomposer: Gather kms objects for a commit in a struct
Define DrmAtomicStateManager::KmsObjects struct to distinguish between
objects that are tracked for lifetime management and state that is
tracked for the purpose of preparing subsequent commits.

Change-Id: I5402959f17298102a904b83fbbf01577ae673e48
2025-06-12 01:39:23 +00:00
Drew Davenport
cdf3401f1d drm_hwcomposer: Remove unused struct member
This is not used anywhere, so remove it.

Change-Id: Ic6a885d523d2c0f6b1b725110bf0ca4fb896a95f
2025-06-12 01:39:23 +00:00
Drew Davenport
b9e2bdb8f3 drm_hwcomposer: Add thread annotations for DrmAtomicStateManager
Shared state is protected by a combination of the local mutex_ and the
global lock. This change attempts to document and enforce that more
clearly using clang-tidy thread annotations.

Change unique_lock usage to lock_guard for cases that do not require
release of the mutex such as when using a condition variable.

Temporarily add a main_lock_ mutex which mirrors how
the global lock is being used for synchronization. Lock this at the
entry point to all public methods. This lock will be removed as a part
of subsequent refactoring and it used to more cleanly break up the
following changes in this series.

Some state is not properly protected by any lock, so temporarily disable
the warnings around access to that state until the synchronization is
resolved in subsequent changes.

Change-Id: I6f4f30c4e97f266146b0879c5255d6f2432f12a3
2025-06-12 01:39:23 +00:00
Drew Davenport
19c5d5e973 drm_hwcomposer: Reorder some class members
Ensure that the std::lock is declared early so that it can be referenced
by clang thread annotations.

Change-Id: I64e7290cc6ff6fcdebb119dc2ec7537387f4ae5c
2025-06-12 01:39:23 +00:00
Drew Davenport
6be6ee958d drm_hwcomposer: Use android-base/thread_annotations.h
This file already exists in android-base, so use this instead of
duplicating the macros in this project.

Since the copy in android-base provides a helper class to assist with
std::unique_lock, use that instead of disabling the warnings.

Change-Id: Ib1724045e3eea29946799fb99b3fbcfcc14a5013
2025-06-12 01:39:23 +00:00
Drew Davenport
23e05e0b85 drm_hwcomposer: Move common files out of hwc2_device directory
HwcDisplay etc. are shared between frontends and shouldn't live in the
hwc2_device directory.

Change-Id: I4bf3845f6cf7adde5f625a736cc1dffea27e5168
2025-05-23 09:01:32 -06:00
Drew Davenport
ca711e95bf drm_hwcomposer: Remove hwc2_display_t
Add DisplayHandle which is a typedef for int64_t. Use this type instead
of the HWC2 hwc2_display_t type.

Additionally, rename variable names to prefer `display_handle` over
`display_id`, since "DisplayId" is overloaded and carries a different
meaning in the Android framework.

Change-Id: I2a8ecce3b2c19fcd5e945d6c645f83d6a7d27a42
2025-05-23 09:01:26 -06:00
Sasha McIntosh
c469d14a19 drm_hwcomposer: Fixup downstream cherry-picks
Wrap Android16 APIs in an if block to prevent breaking Android15
integration.

s/AidlHdcpLevels/drm::HdcpLevels

Add support for external HDR displays (dropped in previous cleanup).

clang-format-diff-19 nits

Change-Id: I897e0b42e0065a61ecfe28c280094b6c375d8a72
Signed-off-by: Sasha McIntosh <sashamcintosh@google.com>
2025-05-20 13:36:18 -04:00