2 * Copyright (C) 2015 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #ifndef ANDROID_DRM_DISPLAY_COMPOSITOR_H_
18 #define ANDROID_DRM_DISPLAY_COMPOSITOR_H_
20 #include "drmhwcomposer.h"
21 #include "drmcomposition.h"
22 #include "drmcompositorworker.h"
23 #include "drmframebuffer.h"
24 #include "separate_rects.h"
32 #include <hardware/hardware.h>
33 #include <hardware/hwcomposer.h>
35 // One for the front, one for the back, and one for cases where we need to
36 // squash a frame that the hw can't display with hw overlays.
37 #define DRM_DISPLAY_BUFFERS 3
41 class GLWorkerCompositor;
45 static const unsigned kHistoryLength = 6; // TODO: make this number not magic
46 static const unsigned kMaxLayers = 64;
50 std::bitset<kMaxLayers> layer_refs;
51 std::bitset<kHistoryLength> change_history;
52 bool squashed = false;
55 bool is_stable(int region_index) const {
56 return valid_history_ >= kHistoryLength &&
57 regions_[region_index].change_history.none();
60 const std::vector<Region> ®ions() const {
64 void Init(DrmHwcLayer *layers, size_t num_layers);
65 void GenerateHistory(DrmHwcLayer *layers, size_t num_layers,
66 std::vector<bool> &changed_regions) const;
67 void StableRegionsWithMarginalHistory(
68 const std::vector<bool> &changed_regions,
69 std::vector<bool> &stable_regions) const;
70 void RecordHistory(DrmHwcLayer *layers, size_t num_layers,
71 const std::vector<bool> &changed_regions);
72 bool RecordAndCompareSquashed(const std::vector<bool> &squashed_regions);
74 void Dump(std::ostringstream *out) const;
77 size_t generation_number_ = 0;
78 unsigned valid_history_ = 0;
79 std::vector<buffer_handle_t> last_handles_;
81 std::vector<Region> regions_;
84 class DrmDisplayCompositor {
86 DrmDisplayCompositor();
87 ~DrmDisplayCompositor();
89 int Init(DrmResources *drm, int display);
91 std::unique_ptr<DrmDisplayComposition> CreateComposition() const;
92 int QueueComposition(std::unique_ptr<DrmDisplayComposition> composition);
95 void Dump(std::ostringstream *out) const;
97 std::tuple<uint32_t, uint32_t, int> GetActiveModeResolution();
99 bool HaveQueuedComposites() const;
101 SquashState *squash_state() {
102 return &squash_state_;
107 std::unique_ptr<DrmDisplayComposition> composition;
111 class FrameWorker : public Worker {
113 FrameWorker(DrmDisplayCompositor *compositor);
114 ~FrameWorker() override;
117 void QueueFrame(std::unique_ptr<DrmDisplayComposition> composition,
121 void Routine() override;
124 DrmDisplayCompositor *compositor_;
125 std::queue<FrameState> frame_queue_;
129 bool needs_modeset = false;
131 uint32_t blob_id = 0;
132 uint32_t old_blob_id = 0;
135 DrmDisplayCompositor(const DrmDisplayCompositor &) = delete;
137 // We'll wait for acquire fences to fire for kAcquireWaitTimeoutMs,
138 // kAcquireWaitTries times, logging a warning in between.
139 static const int kAcquireWaitTries = 5;
140 static const int kAcquireWaitTimeoutMs = 100;
142 int PrepareFramebuffer(DrmFramebuffer &fb,
143 DrmDisplayComposition *display_comp);
144 int ApplySquash(DrmDisplayComposition *display_comp);
145 int ApplyPreComposite(DrmDisplayComposition *display_comp);
146 int PrepareFrame(DrmDisplayComposition *display_comp);
147 int CommitFrame(DrmDisplayComposition *display_comp, bool test_only);
148 int SquashFrame(DrmDisplayComposition *src, DrmDisplayComposition *dst);
149 int ApplyDpms(DrmDisplayComposition *display_comp);
150 int DisablePlanes(DrmDisplayComposition *display_comp);
153 void ApplyFrame(std::unique_ptr<DrmDisplayComposition> composition,
156 std::tuple<int, uint32_t> CreateModeBlob(const DrmMode &mode);
161 DrmCompositorWorker worker_;
162 FrameWorker frame_worker_;
164 std::queue<std::unique_ptr<DrmDisplayComposition>> composite_queue_;
165 std::unique_ptr<DrmDisplayComposition> active_composition_;
169 bool use_hw_overlays_;
173 int framebuffer_index_;
174 DrmFramebuffer framebuffers_[DRM_DISPLAY_BUFFERS];
175 std::unique_ptr<GLWorkerCompositor> pre_compositor_;
177 SquashState squash_state_;
178 int squash_framebuffer_index_;
179 DrmFramebuffer squash_framebuffers_[2];
181 // mutable since we need to acquire in HaveQueuedComposites
182 mutable pthread_mutex_t lock_;
184 // State tracking progress since our last Dump(). These are mutable since
185 // we need to reset them on every Dump() call.
186 mutable uint64_t dump_frames_composited_;
187 mutable uint64_t dump_last_timestamp_ns_;
191 #endif // ANDROID_DRM_DISPLAY_COMPOSITOR_H_