xref: /aosp_15_r20/external/drm_hwcomposer/drm/DrmAtomicStateManager.h (revision 0a9764fe0a15e71ebbeb85e87e10990c23aab47f)
1*0a9764feSAndroid Build Coastguard Worker /*
2*0a9764feSAndroid Build Coastguard Worker  * Copyright (C) 2015 The Android Open Source Project
3*0a9764feSAndroid Build Coastguard Worker  *
4*0a9764feSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*0a9764feSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*0a9764feSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*0a9764feSAndroid Build Coastguard Worker  *
8*0a9764feSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*0a9764feSAndroid Build Coastguard Worker  *
10*0a9764feSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*0a9764feSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*0a9764feSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*0a9764feSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*0a9764feSAndroid Build Coastguard Worker  * limitations under the License.
15*0a9764feSAndroid Build Coastguard Worker  */
16*0a9764feSAndroid Build Coastguard Worker 
17*0a9764feSAndroid Build Coastguard Worker #pragma once
18*0a9764feSAndroid Build Coastguard Worker 
19*0a9764feSAndroid Build Coastguard Worker #include <pthread.h>
20*0a9764feSAndroid Build Coastguard Worker 
21*0a9764feSAndroid Build Coastguard Worker #include <memory>
22*0a9764feSAndroid Build Coastguard Worker #include <optional>
23*0a9764feSAndroid Build Coastguard Worker 
24*0a9764feSAndroid Build Coastguard Worker #include "compositor/DisplayInfo.h"
25*0a9764feSAndroid Build Coastguard Worker #include "compositor/DrmKmsPlan.h"
26*0a9764feSAndroid Build Coastguard Worker #include "compositor/LayerData.h"
27*0a9764feSAndroid Build Coastguard Worker #include "drm/DrmPlane.h"
28*0a9764feSAndroid Build Coastguard Worker #include "drm/ResourceManager.h"
29*0a9764feSAndroid Build Coastguard Worker #include "drm/VSyncWorker.h"
30*0a9764feSAndroid Build Coastguard Worker 
31*0a9764feSAndroid Build Coastguard Worker namespace android {
32*0a9764feSAndroid Build Coastguard Worker 
33*0a9764feSAndroid Build Coastguard Worker struct AtomicCommitArgs {
34*0a9764feSAndroid Build Coastguard Worker   /* inputs. All fields are optional, but at least one has to be specified */
35*0a9764feSAndroid Build Coastguard Worker   bool test_only = false;
36*0a9764feSAndroid Build Coastguard Worker   bool blocking = false;
37*0a9764feSAndroid Build Coastguard Worker   std::optional<DrmMode> display_mode;
38*0a9764feSAndroid Build Coastguard Worker   std::optional<bool> active;
39*0a9764feSAndroid Build Coastguard Worker   std::shared_ptr<DrmKmsPlan> composition;
40*0a9764feSAndroid Build Coastguard Worker   std::shared_ptr<drm_color_ctm> color_matrix;
41*0a9764feSAndroid Build Coastguard Worker   std::optional<Colorspace> colorspace;
42*0a9764feSAndroid Build Coastguard Worker   std::optional<int32_t> content_type;
43*0a9764feSAndroid Build Coastguard Worker 
44*0a9764feSAndroid Build Coastguard Worker   std::shared_ptr<DrmFbIdHandle> writeback_fb;
45*0a9764feSAndroid Build Coastguard Worker   SharedFd writeback_release_fence;
46*0a9764feSAndroid Build Coastguard Worker 
47*0a9764feSAndroid Build Coastguard Worker   /* out */
48*0a9764feSAndroid Build Coastguard Worker   SharedFd out_fence;
49*0a9764feSAndroid Build Coastguard Worker 
50*0a9764feSAndroid Build Coastguard Worker   /* helpers */
51*0a9764feSAndroid Build Coastguard Worker   auto HasInputs() const -> bool {
52*0a9764feSAndroid Build Coastguard Worker     return display_mode || active || composition;
53*0a9764feSAndroid Build Coastguard Worker   }
54*0a9764feSAndroid Build Coastguard Worker };
55*0a9764feSAndroid Build Coastguard Worker 
56*0a9764feSAndroid Build Coastguard Worker class DrmAtomicStateManager {
57*0a9764feSAndroid Build Coastguard Worker  public:
58*0a9764feSAndroid Build Coastguard Worker   static auto CreateInstance(DrmDisplayPipeline *pipe)
59*0a9764feSAndroid Build Coastguard Worker       -> std::shared_ptr<DrmAtomicStateManager>;
60*0a9764feSAndroid Build Coastguard Worker 
61*0a9764feSAndroid Build Coastguard Worker   ~DrmAtomicStateManager() = default;
62*0a9764feSAndroid Build Coastguard Worker 
63*0a9764feSAndroid Build Coastguard Worker   auto ExecuteAtomicCommit(AtomicCommitArgs &args) -> int;
64*0a9764feSAndroid Build Coastguard Worker   auto ActivateDisplayUsingDPMS() -> int;
65*0a9764feSAndroid Build Coastguard Worker 
StopThread()66*0a9764feSAndroid Build Coastguard Worker   void StopThread() {
67*0a9764feSAndroid Build Coastguard Worker     {
68*0a9764feSAndroid Build Coastguard Worker       const std::unique_lock lock(mutex_);
69*0a9764feSAndroid Build Coastguard Worker       exit_thread_ = true;
70*0a9764feSAndroid Build Coastguard Worker     }
71*0a9764feSAndroid Build Coastguard Worker     cv_.notify_all();
72*0a9764feSAndroid Build Coastguard Worker   }
73*0a9764feSAndroid Build Coastguard Worker 
74*0a9764feSAndroid Build Coastguard Worker  private:
75*0a9764feSAndroid Build Coastguard Worker   DrmAtomicStateManager() = default;
76*0a9764feSAndroid Build Coastguard Worker   auto CommitFrame(AtomicCommitArgs &args) -> int;
77*0a9764feSAndroid Build Coastguard Worker 
78*0a9764feSAndroid Build Coastguard Worker   struct KmsState {
79*0a9764feSAndroid Build Coastguard Worker     /* Required to cleanup unused planes */
80*0a9764feSAndroid Build Coastguard Worker     std::vector<std::shared_ptr<BindingOwner<DrmPlane>>> used_planes;
81*0a9764feSAndroid Build Coastguard Worker     /* We have to hold a reference to framebuffer while displaying it ,
82*0a9764feSAndroid Build Coastguard Worker      * otherwise picture will blink */
83*0a9764feSAndroid Build Coastguard Worker     std::vector<std::shared_ptr<DrmFbIdHandle>> used_framebuffers;
84*0a9764feSAndroid Build Coastguard Worker 
85*0a9764feSAndroid Build Coastguard Worker     DrmModeUserPropertyBlobUnique mode_blob;
86*0a9764feSAndroid Build Coastguard Worker     DrmModeUserPropertyBlobUnique ctm_blob;
87*0a9764feSAndroid Build Coastguard Worker 
88*0a9764feSAndroid Build Coastguard Worker     int release_fence_pt_index{};
89*0a9764feSAndroid Build Coastguard Worker 
90*0a9764feSAndroid Build Coastguard Worker     /* To avoid setting the inactive state twice, which will fail the commit */
91*0a9764feSAndroid Build Coastguard Worker     bool crtc_active_state{};
92*0a9764feSAndroid Build Coastguard Worker   } active_frame_state_;
93*0a9764feSAndroid Build Coastguard Worker 
94*0a9764feSAndroid Build Coastguard Worker   auto NewFrameState() -> KmsState {
95*0a9764feSAndroid Build Coastguard Worker     auto *prev_frame_state = &active_frame_state_;
96*0a9764feSAndroid Build Coastguard Worker     return (KmsState){
97*0a9764feSAndroid Build Coastguard Worker         .used_planes = prev_frame_state->used_planes,
98*0a9764feSAndroid Build Coastguard Worker         .crtc_active_state = prev_frame_state->crtc_active_state,
99*0a9764feSAndroid Build Coastguard Worker     };
100*0a9764feSAndroid Build Coastguard Worker   }
101*0a9764feSAndroid Build Coastguard Worker 
102*0a9764feSAndroid Build Coastguard Worker   DrmDisplayPipeline *pipe_{};
103*0a9764feSAndroid Build Coastguard Worker 
104*0a9764feSAndroid Build Coastguard Worker   void CleanupPriorFrameResources();
105*0a9764feSAndroid Build Coastguard Worker 
106*0a9764feSAndroid Build Coastguard Worker   KmsState staged_frame_state_;
107*0a9764feSAndroid Build Coastguard Worker   SharedFd last_present_fence_;
108*0a9764feSAndroid Build Coastguard Worker   int frames_staged_{};
109*0a9764feSAndroid Build Coastguard Worker   int frames_tracked_{};
110*0a9764feSAndroid Build Coastguard Worker 
111*0a9764feSAndroid Build Coastguard Worker   void ThreadFn(const std::shared_ptr<DrmAtomicStateManager> &dasm);
112*0a9764feSAndroid Build Coastguard Worker   std::condition_variable cv_;
113*0a9764feSAndroid Build Coastguard Worker   std::mutex mutex_;
114*0a9764feSAndroid Build Coastguard Worker   bool exit_thread_{};
115*0a9764feSAndroid Build Coastguard Worker };
116*0a9764feSAndroid Build Coastguard Worker 
117*0a9764feSAndroid Build Coastguard Worker }  // namespace android
118