diff options
author | android-build-team Robot | 2017-10-01 23:19:31 -0500 |
---|---|---|
committer | android-build-team Robot | 2017-10-01 23:19:31 -0500 |
commit | 6ee9f0c7577c98438871f6ae98896c4b3c70b043 (patch) | |
tree | d449f9574085b121c68f89198f8df6ca921228a0 | |
parent | 8fbe9367bdb82058dfe6c4fef94b5d81d183e71a (diff) | |
parent | c026c52ee67c7019a8018e2a5ec05d32b208ed94 (diff) | |
download | frameworks-native-6ee9f0c7577c98438871f6ae98896c4b3c70b043.tar.gz frameworks-native-6ee9f0c7577c98438871f6ae98896c4b3c70b043.tar.xz frameworks-native-6ee9f0c7577c98438871f6ae98896c4b3c70b043.zip |
release-request-53526352-7b51-4ab1-a661-632ffc55dd7c-for-git_oc-mr1-release-4371241 snap-temp-L10900000107789672
Change-Id: I4a64d37aab8dde4ad6abc1bc37a2477683696a39
-rw-r--r-- | libs/vr/libvrflinger/acquired_buffer.cpp | 23 | ||||
-rw-r--r-- | libs/vr/libvrflinger/acquired_buffer.h | 9 | ||||
-rw-r--r-- | libs/vr/libvrflinger/display_surface.cpp | 2 | ||||
-rw-r--r-- | libs/vr/libvrflinger/hardware_composer.cpp | 30 | ||||
-rw-r--r-- | libs/vr/libvrflinger/hardware_composer.h | 37 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 17 |
6 files changed, 85 insertions, 33 deletions
diff --git a/libs/vr/libvrflinger/acquired_buffer.cpp b/libs/vr/libvrflinger/acquired_buffer.cpp index fda9585dc..9614c6d30 100644 --- a/libs/vr/libvrflinger/acquired_buffer.cpp +++ b/libs/vr/libvrflinger/acquired_buffer.cpp | |||
@@ -9,8 +9,8 @@ namespace android { | |||
9 | namespace dvr { | 9 | namespace dvr { |
10 | 10 | ||
11 | AcquiredBuffer::AcquiredBuffer(const std::shared_ptr<BufferConsumer>& buffer, | 11 | AcquiredBuffer::AcquiredBuffer(const std::shared_ptr<BufferConsumer>& buffer, |
12 | LocalHandle acquire_fence) | 12 | LocalHandle acquire_fence, std::size_t slot) |
13 | : buffer_(buffer), acquire_fence_(std::move(acquire_fence)) {} | 13 | : buffer_(buffer), acquire_fence_(std::move(acquire_fence)), slot_(slot) {} |
14 | 14 | ||
15 | AcquiredBuffer::AcquiredBuffer(const std::shared_ptr<BufferConsumer>& buffer, | 15 | AcquiredBuffer::AcquiredBuffer(const std::shared_ptr<BufferConsumer>& buffer, |
16 | int* error) { | 16 | int* error) { |
@@ -31,18 +31,20 @@ AcquiredBuffer::AcquiredBuffer(const std::shared_ptr<BufferConsumer>& buffer, | |||
31 | } | 31 | } |
32 | } | 32 | } |
33 | 33 | ||
34 | AcquiredBuffer::AcquiredBuffer(AcquiredBuffer&& other) | 34 | AcquiredBuffer::AcquiredBuffer(AcquiredBuffer&& other) { |
35 | : buffer_(std::move(other.buffer_)), | 35 | *this = std::move(other); |
36 | acquire_fence_(std::move(other.acquire_fence_)) {} | 36 | } |
37 | 37 | ||
38 | AcquiredBuffer::~AcquiredBuffer() { Release(LocalHandle(kEmptyFence)); } | 38 | AcquiredBuffer::~AcquiredBuffer() { Release(LocalHandle(kEmptyFence)); } |
39 | 39 | ||
40 | AcquiredBuffer& AcquiredBuffer::operator=(AcquiredBuffer&& other) { | 40 | AcquiredBuffer& AcquiredBuffer::operator=(AcquiredBuffer&& other) { |
41 | if (this != &other) { | 41 | if (this != &other) { |
42 | Release(LocalHandle(kEmptyFence)); | 42 | Release(); |
43 | 43 | ||
44 | buffer_ = std::move(other.buffer_); | 44 | using std::swap; |
45 | acquire_fence_ = std::move(other.acquire_fence_); | 45 | swap(buffer_, other.buffer_); |
46 | swap(acquire_fence_, other.acquire_fence_); | ||
47 | swap(slot_, other.slot_); | ||
46 | } | 48 | } |
47 | return *this; | 49 | return *this; |
48 | } | 50 | } |
@@ -81,8 +83,6 @@ int AcquiredBuffer::Release(LocalHandle release_fence) { | |||
81 | ALOGD_IF(TRACE, "AcquiredBuffer::Release: buffer_id=%d release_fence=%d", | 83 | ALOGD_IF(TRACE, "AcquiredBuffer::Release: buffer_id=%d release_fence=%d", |
82 | buffer_ ? buffer_->id() : -1, release_fence.Get()); | 84 | buffer_ ? buffer_->id() : -1, release_fence.Get()); |
83 | if (buffer_) { | 85 | if (buffer_) { |
84 | // Close the release fence since we can't transfer it with an async release. | ||
85 | release_fence.Close(); | ||
86 | const int ret = buffer_->ReleaseAsync(); | 86 | const int ret = buffer_->ReleaseAsync(); |
87 | if (ret < 0) { | 87 | if (ret < 0) { |
88 | ALOGE("AcquiredBuffer::Release: Failed to release buffer %d: %s", | 88 | ALOGE("AcquiredBuffer::Release: Failed to release buffer %d: %s", |
@@ -92,9 +92,10 @@ int AcquiredBuffer::Release(LocalHandle release_fence) { | |||
92 | } | 92 | } |
93 | 93 | ||
94 | buffer_ = nullptr; | 94 | buffer_ = nullptr; |
95 | acquire_fence_.Close(); | ||
96 | } | 95 | } |
97 | 96 | ||
97 | acquire_fence_.Close(); | ||
98 | slot_ = 0; | ||
98 | return 0; | 99 | return 0; |
99 | } | 100 | } |
100 | 101 | ||
diff --git a/libs/vr/libvrflinger/acquired_buffer.h b/libs/vr/libvrflinger/acquired_buffer.h index e0dc9f2ac..32e912a65 100644 --- a/libs/vr/libvrflinger/acquired_buffer.h +++ b/libs/vr/libvrflinger/acquired_buffer.h | |||
@@ -21,7 +21,7 @@ class AcquiredBuffer { | |||
21 | // this constructor; the constructor does not attempt to ACQUIRE the buffer | 21 | // this constructor; the constructor does not attempt to ACQUIRE the buffer |
22 | // itself. | 22 | // itself. |
23 | AcquiredBuffer(const std::shared_ptr<BufferConsumer>& buffer, | 23 | AcquiredBuffer(const std::shared_ptr<BufferConsumer>& buffer, |
24 | pdx::LocalHandle acquire_fence); | 24 | pdx::LocalHandle acquire_fence, std::size_t slot = 0); |
25 | 25 | ||
26 | // Constructs an AcquiredBuffer from a BufferConsumer. The BufferConsumer MUST | 26 | // Constructs an AcquiredBuffer from a BufferConsumer. The BufferConsumer MUST |
27 | // be in the POSTED state prior to calling this constructor, as this | 27 | // be in the POSTED state prior to calling this constructor, as this |
@@ -64,13 +64,18 @@ class AcquiredBuffer { | |||
64 | // to the producer. On success, the BufferConsumer and acquire fence are set | 64 | // to the producer. On success, the BufferConsumer and acquire fence are set |
65 | // to empty state; if release fails, the BufferConsumer and acquire fence are | 65 | // to empty state; if release fails, the BufferConsumer and acquire fence are |
66 | // left in place and a negative error code is returned. | 66 | // left in place and a negative error code is returned. |
67 | int Release(pdx::LocalHandle release_fence); | 67 | int Release(pdx::LocalHandle release_fence = {}); |
68 | |||
69 | // Returns the slot in the queue this buffer belongs to. Buffers that are not | ||
70 | // part of a queue return 0. | ||
71 | std::size_t slot() const { return slot_; } | ||
68 | 72 | ||
69 | private: | 73 | private: |
70 | std::shared_ptr<BufferConsumer> buffer_; | 74 | std::shared_ptr<BufferConsumer> buffer_; |
71 | // Mutable so that the fence can be closed when it is determined to be | 75 | // Mutable so that the fence can be closed when it is determined to be |
72 | // signaled during IsAvailable(). | 76 | // signaled during IsAvailable(). |
73 | mutable pdx::LocalHandle acquire_fence_; | 77 | mutable pdx::LocalHandle acquire_fence_; |
78 | std::size_t slot_{0}; | ||
74 | 79 | ||
75 | AcquiredBuffer(const AcquiredBuffer&) = delete; | 80 | AcquiredBuffer(const AcquiredBuffer&) = delete; |
76 | void operator=(const AcquiredBuffer&) = delete; | 81 | void operator=(const AcquiredBuffer&) = delete; |
diff --git a/libs/vr/libvrflinger/display_surface.cpp b/libs/vr/libvrflinger/display_surface.cpp index 685378133..3d132c95e 100644 --- a/libs/vr/libvrflinger/display_surface.cpp +++ b/libs/vr/libvrflinger/display_surface.cpp | |||
@@ -382,7 +382,7 @@ void DirectDisplaySurface::DequeueBuffersLocked() { | |||
382 | } | 382 | } |
383 | 383 | ||
384 | acquired_buffers_.Append( | 384 | acquired_buffers_.Append( |
385 | AcquiredBuffer(buffer_consumer, std::move(acquire_fence))); | 385 | AcquiredBuffer(buffer_consumer, std::move(acquire_fence), slot)); |
386 | } | 386 | } |
387 | } | 387 | } |
388 | 388 | ||
diff --git a/libs/vr/libvrflinger/hardware_composer.cpp b/libs/vr/libvrflinger/hardware_composer.cpp index de6477b1e..b3da120c7 100644 --- a/libs/vr/libvrflinger/hardware_composer.cpp +++ b/libs/vr/libvrflinger/hardware_composer.cpp | |||
@@ -605,7 +605,7 @@ int HardwareComposer::PostThreadPollInterruptible( | |||
605 | } else if (pfd[0].revents != 0) { | 605 | } else if (pfd[0].revents != 0) { |
606 | return 0; | 606 | return 0; |
607 | } else if (pfd[1].revents != 0) { | 607 | } else if (pfd[1].revents != 0) { |
608 | ALOGI("VrHwcPost thread interrupted"); | 608 | ALOGI("VrHwcPost thread interrupted: revents=%x", pfd[1].revents); |
609 | return kPostThreadInterrupted; | 609 | return kPostThreadInterrupted; |
610 | } else { | 610 | } else { |
611 | return 0; | 611 | return 0; |
@@ -1069,6 +1069,7 @@ void Layer::Reset() { | |||
1069 | acquire_fence_.Close(); | 1069 | acquire_fence_.Close(); |
1070 | surface_rect_functions_applied_ = false; | 1070 | surface_rect_functions_applied_ = false; |
1071 | pending_visibility_settings_ = true; | 1071 | pending_visibility_settings_ = true; |
1072 | cached_buffer_map_.clear(); | ||
1072 | } | 1073 | } |
1073 | 1074 | ||
1074 | Layer::Layer(const std::shared_ptr<DirectDisplaySurface>& surface, | 1075 | Layer::Layer(const std::shared_ptr<DirectDisplaySurface>& surface, |
@@ -1112,6 +1113,7 @@ Layer& Layer::operator=(Layer&& other) { | |||
1112 | swap(surface_rect_functions_applied_, | 1113 | swap(surface_rect_functions_applied_, |
1113 | other.surface_rect_functions_applied_); | 1114 | other.surface_rect_functions_applied_); |
1114 | swap(pending_visibility_settings_, other.pending_visibility_settings_); | 1115 | swap(pending_visibility_settings_, other.pending_visibility_settings_); |
1116 | swap(cached_buffer_map_, other.cached_buffer_map_); | ||
1115 | } | 1117 | } |
1116 | return *this; | 1118 | return *this; |
1117 | } | 1119 | } |
@@ -1205,15 +1207,30 @@ void Layer::CommonLayerSetup() { | |||
1205 | UpdateLayerSettings(); | 1207 | UpdateLayerSettings(); |
1206 | } | 1208 | } |
1207 | 1209 | ||
1210 | bool Layer::CheckAndUpdateCachedBuffer(std::size_t slot, int buffer_id) { | ||
1211 | auto search = cached_buffer_map_.find(slot); | ||
1212 | if (search != cached_buffer_map_.end() && search->second == buffer_id) | ||
1213 | return true; | ||
1214 | |||
1215 | // Assign or update the buffer slot. | ||
1216 | if (buffer_id >= 0) | ||
1217 | cached_buffer_map_[slot] = buffer_id; | ||
1218 | return false; | ||
1219 | } | ||
1220 | |||
1208 | void Layer::Prepare() { | 1221 | void Layer::Prepare() { |
1209 | int right, bottom; | 1222 | int right, bottom, id; |
1210 | sp<GraphicBuffer> handle; | 1223 | sp<GraphicBuffer> handle; |
1224 | std::size_t slot; | ||
1211 | 1225 | ||
1212 | // Acquire the next buffer according to the type of source. | 1226 | // Acquire the next buffer according to the type of source. |
1213 | IfAnyOf<SourceSurface, SourceBuffer>::Call(&source_, [&](auto& source) { | 1227 | IfAnyOf<SourceSurface, SourceBuffer>::Call(&source_, [&](auto& source) { |
1214 | std::tie(right, bottom, handle, acquire_fence_) = source.Acquire(); | 1228 | std::tie(right, bottom, id, handle, acquire_fence_, slot) = |
1229 | source.Acquire(); | ||
1215 | }); | 1230 | }); |
1216 | 1231 | ||
1232 | TRACE_FORMAT("Layer::Prepare|buffer_id=%d;slot=%zu|", id, slot); | ||
1233 | |||
1217 | // Update any visibility (blending, z-order) changes that occurred since | 1234 | // Update any visibility (blending, z-order) changes that occurred since |
1218 | // last prepare. | 1235 | // last prepare. |
1219 | UpdateVisibilitySettings(); | 1236 | UpdateVisibilitySettings(); |
@@ -1243,10 +1260,15 @@ void Layer::Prepare() { | |||
1243 | composition_type_.cast<Hwc2::IComposerClient::Composition>()); | 1260 | composition_type_.cast<Hwc2::IComposerClient::Composition>()); |
1244 | } | 1261 | } |
1245 | 1262 | ||
1263 | // See if the HWC cache already has this buffer. | ||
1264 | const bool cached = CheckAndUpdateCachedBuffer(slot, id); | ||
1265 | if (cached) | ||
1266 | handle = nullptr; | ||
1267 | |||
1246 | HWC::Error error{HWC::Error::None}; | 1268 | HWC::Error error{HWC::Error::None}; |
1247 | error = | 1269 | error = |
1248 | composer_->setLayerBuffer(HWC_DISPLAY_PRIMARY, hardware_composer_layer_, | 1270 | composer_->setLayerBuffer(HWC_DISPLAY_PRIMARY, hardware_composer_layer_, |
1249 | 0, handle, acquire_fence_.Get()); | 1271 | slot, handle, acquire_fence_.Get()); |
1250 | 1272 | ||
1251 | ALOGE_IF(error != HWC::Error::None, | 1273 | ALOGE_IF(error != HWC::Error::None, |
1252 | "Layer::Prepare: Error setting layer buffer: %s", | 1274 | "Layer::Prepare: Error setting layer buffer: %s", |
diff --git a/libs/vr/libvrflinger/hardware_composer.h b/libs/vr/libvrflinger/hardware_composer.h index 8131e5098..7010db963 100644 --- a/libs/vr/libvrflinger/hardware_composer.h +++ b/libs/vr/libvrflinger/hardware_composer.h | |||
@@ -161,6 +161,14 @@ class Layer { | |||
161 | // Applies visibility settings that may have changed. | 161 | // Applies visibility settings that may have changed. |
162 | void UpdateVisibilitySettings(); | 162 | void UpdateVisibilitySettings(); |
163 | 163 | ||
164 | // Checks whether the buffer, given by id, is associated with the given slot | ||
165 | // in the HWC buffer cache. If the slot is not associated with the given | ||
166 | // buffer the cache is updated to establish the association and the buffer | ||
167 | // should be sent to HWC using setLayerBuffer. Returns true if the association | ||
168 | // was already established, false if not. A buffer_id of -1 is never | ||
169 | // associated and always returns false. | ||
170 | bool CheckAndUpdateCachedBuffer(std::size_t slot, int buffer_id); | ||
171 | |||
164 | // Composer instance shared by all instances of Layer. This must be set | 172 | // Composer instance shared by all instances of Layer. This must be set |
165 | // whenever a new instance of the Composer is created. This may be set to | 173 | // whenever a new instance of the Composer is created. This may be set to |
166 | // nullptr as long as there are no instances of Layer that might need to use | 174 | // nullptr as long as there are no instances of Layer that might need to use |
@@ -198,19 +206,21 @@ class Layer { | |||
198 | // the previous buffer is returned or an empty value if no buffer has ever | 206 | // the previous buffer is returned or an empty value if no buffer has ever |
199 | // been posted. When a new buffer is acquired the previous buffer's release | 207 | // been posted. When a new buffer is acquired the previous buffer's release |
200 | // fence is passed out automatically. | 208 | // fence is passed out automatically. |
201 | std::tuple<int, int, sp<GraphicBuffer>, pdx::LocalHandle> Acquire() { | 209 | std::tuple<int, int, int, sp<GraphicBuffer>, pdx::LocalHandle, std::size_t> |
210 | Acquire() { | ||
202 | if (surface->IsBufferAvailable()) { | 211 | if (surface->IsBufferAvailable()) { |
203 | acquired_buffer.Release(std::move(release_fence)); | 212 | acquired_buffer.Release(std::move(release_fence)); |
204 | acquired_buffer = surface->AcquireCurrentBuffer(); | 213 | acquired_buffer = surface->AcquireCurrentBuffer(); |
205 | ATRACE_ASYNC_END("BufferPost", acquired_buffer.buffer()->id()); | 214 | ATRACE_ASYNC_END("BufferPost", acquired_buffer.buffer()->id()); |
206 | } | 215 | } |
207 | if (!acquired_buffer.IsEmpty()) { | 216 | if (!acquired_buffer.IsEmpty()) { |
208 | return std::make_tuple(acquired_buffer.buffer()->width(), | 217 | return std::make_tuple( |
209 | acquired_buffer.buffer()->height(), | 218 | acquired_buffer.buffer()->width(), |
210 | acquired_buffer.buffer()->buffer()->buffer(), | 219 | acquired_buffer.buffer()->height(), acquired_buffer.buffer()->id(), |
211 | acquired_buffer.ClaimAcquireFence()); | 220 | acquired_buffer.buffer()->buffer()->buffer(), |
221 | acquired_buffer.ClaimAcquireFence(), acquired_buffer.slot()); | ||
212 | } else { | 222 | } else { |
213 | return std::make_tuple(0, 0, nullptr, pdx::LocalHandle{}); | 223 | return std::make_tuple(0, 0, -1, nullptr, pdx::LocalHandle{}, 0); |
214 | } | 224 | } |
215 | } | 225 | } |
216 | 226 | ||
@@ -242,12 +252,13 @@ class Layer { | |||
242 | struct SourceBuffer { | 252 | struct SourceBuffer { |
243 | std::shared_ptr<IonBuffer> buffer; | 253 | std::shared_ptr<IonBuffer> buffer; |
244 | 254 | ||
245 | std::tuple<int, int, sp<GraphicBuffer>, pdx::LocalHandle> Acquire() { | 255 | std::tuple<int, int, int, sp<GraphicBuffer>, pdx::LocalHandle, std::size_t> |
256 | Acquire() { | ||
246 | if (buffer) | 257 | if (buffer) |
247 | return std::make_tuple(buffer->width(), buffer->height(), | 258 | return std::make_tuple(buffer->width(), buffer->height(), -1, |
248 | buffer->buffer(), pdx::LocalHandle{}); | 259 | buffer->buffer(), pdx::LocalHandle{}, 0); |
249 | else | 260 | else |
250 | return std::make_tuple(0, 0, nullptr, pdx::LocalHandle{}); | 261 | return std::make_tuple(0, 0, -1, nullptr, pdx::LocalHandle{}, 0); |
251 | } | 262 | } |
252 | 263 | ||
253 | void Finish(pdx::LocalHandle /*fence*/) {} | 264 | void Finish(pdx::LocalHandle /*fence*/) {} |
@@ -266,6 +277,12 @@ class Layer { | |||
266 | bool surface_rect_functions_applied_ = false; | 277 | bool surface_rect_functions_applied_ = false; |
267 | bool pending_visibility_settings_ = true; | 278 | bool pending_visibility_settings_ = true; |
268 | 279 | ||
280 | // Map of buffer slot assignments that have already been established with HWC: | ||
281 | // slot -> buffer_id. When this map contains a matching slot and buffer_id the | ||
282 | // buffer argument to setLayerBuffer may be nullptr to avoid the cost of | ||
283 | // importing a buffer HWC already knows about. | ||
284 | std::map<std::size_t, int> cached_buffer_map_; | ||
285 | |||
269 | Layer(const Layer&) = delete; | 286 | Layer(const Layer&) = delete; |
270 | void operator=(const Layer&) = delete; | 287 | void operator=(const Layer&) = delete; |
271 | }; | 288 | }; |
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 12205af91..c05ac8aaa 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp | |||
@@ -604,11 +604,18 @@ void SurfaceFlinger::init() { | |||
604 | 604 | ||
605 | if (useVrFlinger) { | 605 | if (useVrFlinger) { |
606 | auto vrFlingerRequestDisplayCallback = [this] (bool requestDisplay) { | 606 | auto vrFlingerRequestDisplayCallback = [this] (bool requestDisplay) { |
607 | ALOGI("VR request display mode: requestDisplay=%d", requestDisplay); | 607 | // This callback is called from the vr flinger dispatch thread. We |
608 | mVrFlingerRequestsDisplay = requestDisplay; | 608 | // need to call signalTransaction(), which requires holding |
609 | ConditionalLock _l(mStateLock, | 609 | // mStateLock when we're not on the main thread. Acquiring |
610 | std::this_thread::get_id() != mMainThreadId); | 610 | // mStateLock from the vr flinger dispatch thread might trigger a |
611 | signalTransaction(); | 611 | // deadlock in surface flinger (see b/66916578), so post a message |
612 | // to be handled on the main thread instead. | ||
613 | sp<LambdaMessage> message = new LambdaMessage([=]() { | ||
614 | ALOGI("VR request display mode: requestDisplay=%d", requestDisplay); | ||
615 | mVrFlingerRequestsDisplay = requestDisplay; | ||
616 | signalTransaction(); | ||
617 | }); | ||
618 | postMessageAsync(message); | ||
612 | }; | 619 | }; |
613 | mVrFlinger = dvr::VrFlinger::Create(mHwc->getComposer(), | 620 | mVrFlinger = dvr::VrFlinger::Create(mHwc->getComposer(), |
614 | vrFlingerRequestDisplayCallback); | 621 | vrFlingerRequestDisplayCallback); |