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