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