• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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   std::shared_ptr<hdr_output_metadata> hdr_metadata;
44   std::optional<int32_t> min_bpc;
45 
46   std::shared_ptr<DrmFbIdHandle> writeback_fb;
47   SharedFd writeback_release_fence;
48 
49   /* out */
50   SharedFd out_fence;
51 
52   /* helpers */
53   auto HasInputs() const -> bool {
54     return display_mode || active || composition;
55   }
56 };
57 
58 class DrmAtomicStateManager {
59  public:
60   static auto CreateInstance(DrmDisplayPipeline *pipe)
61       -> std::shared_ptr<DrmAtomicStateManager>;
62 
63   ~DrmAtomicStateManager() = default;
64 
65   auto ExecuteAtomicCommit(AtomicCommitArgs &args) -> int;
66   auto ActivateDisplayUsingDPMS() -> int;
67 
StopThread()68   void StopThread() {
69     {
70       const std::unique_lock lock(mutex_);
71       exit_thread_ = true;
72     }
73     cv_.notify_all();
74   }
75 
76  private:
77   DrmAtomicStateManager() = default;
78   auto CommitFrame(AtomicCommitArgs &args) -> int;
79 
80   struct KmsState {
81     /* Required to cleanup unused planes */
82     std::vector<std::shared_ptr<BindingOwner<DrmPlane>>> used_planes;
83     /* We have to hold a reference to framebuffer while displaying it ,
84      * otherwise picture will blink */
85     std::vector<std::shared_ptr<DrmFbIdHandle>> used_framebuffers;
86 
87     DrmModeUserPropertyBlobUnique mode_blob;
88     DrmModeUserPropertyBlobUnique ctm_blob;
89     DrmModeUserPropertyBlobUnique hdr_metadata_blob;
90 
91     int release_fence_pt_index{};
92 
93     /* To avoid setting the inactive state twice, which will fail the commit */
94     bool crtc_active_state{};
95   } active_frame_state_;
96 
97   auto NewFrameState() -> KmsState {
98     auto *prev_frame_state = &active_frame_state_;
99     return (KmsState){
100         .used_planes = prev_frame_state->used_planes,
101         .crtc_active_state = prev_frame_state->crtc_active_state,
102     };
103   }
104 
105   DrmDisplayPipeline *pipe_{};
106 
107   void CleanupPriorFrameResources();
108 
109   KmsState staged_frame_state_;
110   SharedFd last_present_fence_;
111   int frames_staged_{};
112   int frames_tracked_{};
113 
114   DstRectInfo whole_display_rect_{};
115 
116   void ThreadFn(const std::shared_ptr<DrmAtomicStateManager> &dasm);
117   std::condition_variable cv_;
118   std::mutex mutex_;
119   bool exit_thread_{};
120 };
121 
122 }  // namespace android
123