/* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include #include #include #include #include "compositor/DisplayInfo.h" #include "compositor/DrmKmsPlan.h" #include "compositor/LayerData.h" #include "drm/DrmPlane.h" #include "drm/ResourceManager.h" #include "drm/VSyncWorker.h" namespace android { struct AtomicCommitArgs { /* inputs. All fields are optional, but at least one has to be specified */ bool test_only = false; bool blocking = false; bool teardown = false; std::optional display_mode; std::optional active; std::shared_ptr composition; std::shared_ptr color_matrix; std::optional colorspace; std::optional content_type; std::shared_ptr hdr_metadata; std::optional min_bpc; std::shared_ptr writeback_fb; SharedFd writeback_release_fence; /* out */ SharedFd out_writeback_complete_fence; SharedFd out_fence; /* helpers */ auto HasInputs() const -> bool { return display_mode || active || composition; } }; class DrmAtomicStateManager { public: static auto CreateInstance(DrmDisplayPipeline *pipe) -> std::shared_ptr; ~DrmAtomicStateManager(); auto ExecuteAtomicCommit(AtomicCommitArgs &args) -> int; auto ActivateDisplayUsingDPMS() -> int; void StopThread() { { const std::lock_guard lock(mutex_); exit_thread_ = true; } cv_.notify_all(); } private: void ThreadFn(); DrmAtomicStateManager() = default; int CommitFrame(AtomicCommitArgs &args); // Collection of kms objects that were committed to the kernel. There must be // a userspace handle to keep these from being removed/unregistered until the // commit that used them is no longer being presented. struct KmsObjects { /* We have to hold a reference to framebuffer while displaying it , * otherwise picture will blink */ std::vector> framebuffers; std::vector blobs; }; struct KmsState { /* Required to cleanup unused planes */ std::vector>> used_planes; /* To avoid setting the inactive state twice, which will fail the commit */ bool crtc_active_state{}; }; // Only accessed from main thread. DrmDisplayPipeline *pipe_{}; KmsState committed_frame_state_; DstRectInfo whole_display_rect_{}; std::thread thread_; std::condition_variable cv_; std::mutex mutex_; // Accessed from both threads. // void CleanupPriorFrameResources() REQUIRES(mutex_); bool exit_thread_ GUARDED_BY(mutex_){}; // Front of the queue is the objects for the currently presented frame. // Objects for nonblocking frames are pushed to the back of the queue. std::queue frame_objects_ GUARDED_BY(mutex_); SharedFd last_present_fence_ GUARDED_BY(mutex_); int frames_staged_ GUARDED_BY(mutex_){}; int frames_tracked_ GUARDED_BY(mutex_){}; }; } // namespace android