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 #ifndef ANDROID_DRM_DISPLAY_COMPOSITOR_H_ 18 #define ANDROID_DRM_DISPLAY_COMPOSITOR_H_ 19 20 #include "drm_hwcomposer.h" 21 #include "drmcomposition.h" 22 #include "drmcompositorworker.h" 23 #include "drmframebuffer.h" 24 #include "seperate_rects.h" 25 26 #include <pthread.h> 27 #include <memory> 28 #include <queue> 29 #include <sstream> 30 #include <tuple> 31 32 #include <hardware/hardware.h> 33 #include <hardware/hwcomposer.h> 34 35 #define DRM_DISPLAY_BUFFERS 2 36 37 namespace android { 38 39 class GLWorkerCompositor; 40 41 class SquashState { 42 public: 43 static const unsigned kHistoryLength = 6; // TODO: make this number not magic 44 static const unsigned kMaxLayers = 64; 45 46 struct Region { 47 DrmHwcRect<int> rect; 48 std::bitset<kMaxLayers> layer_refs; 49 std::bitset<kHistoryLength> change_history; 50 bool squashed = false; 51 }; 52 is_stable(int region_index)53 bool is_stable(int region_index) const { 54 return valid_history_ >= kHistoryLength && 55 regions_[region_index].change_history.none(); 56 } 57 regions()58 const std::vector<Region> ®ions() const { 59 return regions_; 60 } 61 62 void Init(DrmHwcLayer *layers, size_t num_layers); 63 void GenerateHistory(DrmHwcLayer *layers, size_t num_layers, 64 std::vector<bool> &changed_regions) const; 65 void StableRegionsWithMarginalHistory( 66 const std::vector<bool> &changed_regions, 67 std::vector<bool> &stable_regions) const; 68 void RecordHistory(DrmHwcLayer *layers, size_t num_layers, 69 const std::vector<bool> &changed_regions); 70 bool RecordAndCompareSquashed(const std::vector<bool> &squashed_regions); 71 72 void Dump(std::ostringstream *out) const; 73 74 private: 75 size_t generation_number_ = 0; 76 unsigned valid_history_ = 0; 77 std::vector<buffer_handle_t> last_handles_; 78 79 std::vector<Region> regions_; 80 }; 81 82 class DrmDisplayCompositor { 83 public: 84 DrmDisplayCompositor(); 85 ~DrmDisplayCompositor(); 86 87 int Init(DrmResources *drm, int display); 88 89 std::unique_ptr<DrmDisplayComposition> CreateComposition() const; 90 int QueueComposition(std::unique_ptr<DrmDisplayComposition> composition); 91 int Composite(); 92 void Dump(std::ostringstream *out) const; 93 94 std::tuple<uint32_t, uint32_t, int> GetActiveModeResolution(); 95 96 bool HaveQueuedComposites() const; 97 squash_state()98 SquashState *squash_state() { 99 return &squash_state_; 100 } 101 102 private: 103 struct FrameState { 104 std::unique_ptr<DrmDisplayComposition> composition; 105 int status = 0; 106 }; 107 108 class FrameWorker : public Worker { 109 public: 110 FrameWorker(DrmDisplayCompositor *compositor); 111 ~FrameWorker() override; 112 113 int Init(); 114 void QueueFrame(std::unique_ptr<DrmDisplayComposition> composition, 115 int status); 116 117 protected: 118 void Routine() override; 119 120 private: 121 DrmDisplayCompositor *compositor_; 122 std::queue<FrameState> frame_queue_; 123 }; 124 125 DrmDisplayCompositor(const DrmDisplayCompositor &) = delete; 126 127 // We'll wait for acquire fences to fire for kAcquireWaitTimeoutMs, 128 // kAcquireWaitTries times, logging a warning in between. 129 static const int kAcquireWaitTries = 5; 130 static const int kAcquireWaitTimeoutMs = 100; 131 132 int PrepareFramebuffer(DrmFramebuffer &fb, 133 DrmDisplayComposition *display_comp); 134 int ApplySquash(DrmDisplayComposition *display_comp); 135 int ApplyPreComposite(DrmDisplayComposition *display_comp); 136 int PrepareFrame(DrmDisplayComposition *display_comp); 137 int CommitFrame(DrmDisplayComposition *display_comp); 138 int ApplyDpms(DrmDisplayComposition *display_comp); 139 int DisablePlanes(DrmDisplayComposition *display_comp); 140 141 void ApplyFrame(std::unique_ptr<DrmDisplayComposition> composition, 142 int status); 143 144 DrmResources *drm_; 145 int display_; 146 147 DrmCompositorWorker worker_; 148 FrameWorker frame_worker_; 149 150 std::queue<std::unique_ptr<DrmDisplayComposition>> composite_queue_; 151 std::unique_ptr<DrmDisplayComposition> active_composition_; 152 153 bool initialized_; 154 bool active_; 155 156 DrmMode next_mode_; 157 bool needs_modeset_; 158 159 int framebuffer_index_; 160 DrmFramebuffer framebuffers_[DRM_DISPLAY_BUFFERS]; 161 std::unique_ptr<GLWorkerCompositor> pre_compositor_; 162 163 SquashState squash_state_; 164 int squash_framebuffer_index_; 165 DrmFramebuffer squash_framebuffers_[2]; 166 167 // mutable since we need to acquire in HaveQueuedComposites 168 mutable pthread_mutex_t lock_; 169 170 // State tracking progress since our last Dump(). These are mutable since 171 // we need to reset them on every Dump() call. 172 mutable uint64_t dump_frames_composited_; 173 mutable uint64_t dump_last_timestamp_ns_; 174 }; 175 } 176 177 #endif // ANDROID_DRM_DISPLAY_COMPOSITOR_H_ 178