OSDN Git Service

6f192666c3ba6df70086a3b8bb36c5cb1fa4c198
[android-x86/external-IA-Hardware-Composer.git] / common / compositor / compositorthread.cpp
1 /*
2 // Copyright (c) 2017 Intel Corporation
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 #include "compositorthread.h"
18
19 #include "hwcutils.h"
20 #include "hwctrace.h"
21 #include "nativegpuresource.h"
22 #include "overlaylayer.h"
23 #include "renderer.h"
24 #include "displayplanemanager.h"
25 #include "nativesurface.h"
26
27 namespace hwcomposer {
28
29 CompositorThread::CompositorThread() : HWCThread(-8, "CompositorThread") {
30   if (!cevent_.Initialize())
31     return;
32
33   fd_chandler_.AddFd(cevent_.get_fd());
34 }
35
36 CompositorThread::~CompositorThread() {
37 }
38
39 void CompositorThread::Initialize(DisplayPlaneManager *plane_manager) {
40   gpu_resource_handler_.reset(CreateNativeGpuResourceHandler());
41   plane_manager_ = plane_manager;
42   if (!InitWorker()) {
43     ETRACE("Failed to initalize CompositorThread. %s", PRINTERROR());
44   }
45 }
46
47 void CompositorThread::SetExplicitSyncSupport(bool disable_explicit_sync) {
48   disable_explicit_sync_ = disable_explicit_sync;
49 }
50
51 void CompositorThread::EnsureTasksAreDone() {
52   tasks_lock_.lock();
53   tasks_lock_.unlock();
54 }
55
56 void CompositorThread::FreeResources(bool all_resources) {
57   release_all_resources_ = all_resources;
58   tasks_lock_.lock();
59   tasks_ |= kReleaseResources;
60   tasks_lock_.unlock();
61   Resume();
62 }
63
64 void CompositorThread::Wait() {
65   if (fd_chandler_.Poll(-1) <= 0) {
66     ETRACE("Poll Failed in DisplayManager %s", PRINTERROR());
67     return;
68   }
69
70   if (fd_chandler_.IsReady(cevent_.get_fd())) {
71     // If eventfd_ is ready, we need to wait on it (using read()) to clean
72     // the flag that says it is ready.
73     cevent_.Wait();
74   }
75 }
76
77 void CompositorThread::Draw(std::vector<DrawState> &states,
78                             const std::vector<OverlayLayer> &layers) {
79   states_.swap(states);
80   std::vector<OverlayBuffer *>().swap(buffers_);
81   for (auto &layer : layers) {
82     buffers_.emplace_back(layer.GetBuffer());
83   }
84
85   tasks_lock_.lock();
86   tasks_ |= kRender;
87   tasks_lock_.unlock();
88   Resume();
89   Wait();
90 }
91
92 void CompositorThread::ExitThread() {
93   release_all_resources_ = true;
94   FreeResources(true);
95   HWCThread::Exit();
96   renderer_.reset(nullptr);
97   std::vector<DrawState>().swap(states_);
98   std::vector<OverlayBuffer *>().swap(buffers_);
99 }
100
101 void CompositorThread::ReleaseGpuResources() {
102   gpu_resource_handler_->ReleaseGPUResources();
103 }
104
105 void CompositorThread::HandleRoutine() {
106   if (tasks_ & kRender) {
107     HandleDrawRequest();
108     cevent_.Signal();
109   }
110
111   if (tasks_ & kReleaseResources) {
112     HandleReleaseRequest();
113   }
114 }
115
116 void CompositorThread::HandleReleaseRequest() {
117   ScopedSpinLock lock(tasks_lock_);
118   tasks_ &= ~kReleaseResources;
119
120   if (!plane_manager_)
121     return;
122
123   if (!plane_manager_->HasSurfaces())
124     return;
125
126   if (!renderer_) {
127     renderer_.reset(CreateRenderer());
128     if (!renderer_->Init()) {
129       ETRACE("Failed to initialize OpenGL compositor %s", PRINTERROR());
130       renderer_.reset(nullptr);
131       return;
132     }
133   }
134
135   if (release_all_resources_) {
136     plane_manager_->ReleaseAllOffScreenTargets();
137   } else {
138     plane_manager_->ReleaseFreeOffScreenTargets();
139   }
140 }
141
142 void CompositorThread::HandleDrawRequest() {
143   tasks_lock_.lock();
144   tasks_ &= ~kRender;
145   tasks_lock_.unlock();
146
147   if (!renderer_) {
148     renderer_.reset(CreateRenderer());
149     if (!renderer_->Init()) {
150       ETRACE("Failed to initialize OpenGL compositor %s", PRINTERROR());
151       renderer_.reset(nullptr);
152       return;
153     }
154   }
155
156   renderer_->SetExplicitSyncSupport(disable_explicit_sync_);
157
158   if (!gpu_resource_handler_->PrepareResources(buffers_)) {
159     ETRACE(
160         "Failed to prepare GPU resources for compositing the frame, "
161         "error: %s",
162         PRINTERROR());
163     ReleaseGpuResources();
164     return;
165   }
166
167   size_t size = states_.size();
168   for (size_t i = 0; i < size; i++) {
169     DrawState &draw_state = states_.at(i);
170     for (RenderState &render_state : draw_state.states_) {
171       std::vector<RenderState::LayerState> &layer_state =
172           render_state.layer_state_;
173
174       for (RenderState::LayerState &temp : layer_state) {
175         temp.handle_ =
176             gpu_resource_handler_->GetResourceHandle(temp.layer_index_);
177       }
178     }
179
180     const std::vector<int32_t> &fences = draw_state.acquire_fences_;
181     for (int32_t fence : fences) {
182       renderer_->InsertFence(fence);
183     }
184
185     if (!renderer_->Draw(draw_state.states_, draw_state.surface_,
186                          draw_state.clear_surface_)) {
187       ETRACE(
188           "Failed to prepare GPU resources for compositing the frame, "
189           "error: %s",
190           PRINTERROR());
191       break;
192     }
193
194     if (draw_state.destroy_surface_) {
195       draw_state.retire_fence_ =
196           draw_state.surface_->GetLayer()->ReleaseAcquireFence();
197       delete draw_state.surface_;
198     }
199   }
200
201   if (disable_explicit_sync_)
202     renderer_->InsertFence(-1);
203 }
204
205 }  // namespace hwcomposer