• 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/DrmKmsPlan.h"
25 #include "compositor/LayerData.h"
26 #include "drm/DrmPlane.h"
27 #include "drm/ResourceManager.h"
28 #include "drm/VSyncWorker.h"
29 
30 namespace android {
31 
32 struct AtomicCommitArgs {
33   /* inputs. All fields are optional, but at least one has to be specified */
34   bool test_only = false;
35   std::optional<DrmMode> display_mode;
36   std::optional<bool> active;
37   std::shared_ptr<DrmKmsPlan> composition;
38   std::shared_ptr<drm_color_ctm> color_matrix;
39 
40   std::shared_ptr<DrmFbIdHandle> writeback_fb;
41   SharedFd writeback_release_fence;
42 
43   /* out */
44   SharedFd out_fence;
45 
46   /* helpers */
47   auto HasInputs() const -> bool {
48     return display_mode || active || composition;
49   }
50 };
51 
52 class DrmAtomicStateManager {
53  public:
54   static auto CreateInstance(DrmDisplayPipeline *pipe)
55       -> std::shared_ptr<DrmAtomicStateManager>;
56 
57   ~DrmAtomicStateManager() = default;
58 
59   auto ExecuteAtomicCommit(AtomicCommitArgs &args) -> int;
60   auto ActivateDisplayUsingDPMS() -> int;
61 
StopThread()62   void StopThread() {
63     {
64       const std::unique_lock lock(mutex_);
65       exit_thread_ = true;
66     }
67     cv_.notify_all();
68   }
69 
70  private:
71   DrmAtomicStateManager() = default;
72   auto CommitFrame(AtomicCommitArgs &args) -> int;
73 
74   struct KmsState {
75     /* Required to cleanup unused planes */
76     std::vector<std::shared_ptr<BindingOwner<DrmPlane>>> used_planes;
77     /* We have to hold a reference to framebuffer while displaying it ,
78      * otherwise picture will blink */
79     std::vector<std::shared_ptr<DrmFbIdHandle>> used_framebuffers;
80 
81     DrmModeUserPropertyBlobUnique mode_blob;
82     DrmModeUserPropertyBlobUnique ctm_blob;
83 
84     int release_fence_pt_index{};
85 
86     /* To avoid setting the inactive state twice, which will fail the commit */
87     bool crtc_active_state{};
88   } active_frame_state_;
89 
90   auto NewFrameState() -> KmsState {
91     auto *prev_frame_state = &active_frame_state_;
92     return (KmsState){
93         .used_planes = prev_frame_state->used_planes,
94         .crtc_active_state = prev_frame_state->crtc_active_state,
95     };
96   }
97 
98   DrmDisplayPipeline *pipe_{};
99 
100   void CleanupPriorFrameResources();
101 
102   KmsState staged_frame_state_;
103   SharedFd last_present_fence_;
104   int frames_staged_{};
105   int frames_tracked_{};
106 
107   void ThreadFn(const std::shared_ptr<DrmAtomicStateManager> &dasm);
108   std::condition_variable cv_;
109   std::mutex mutex_;
110   bool exit_thread_{};
111 };
112 
113 }  // namespace android
114