1 #include "display_surface.h"
3 #include <private/android_filesystem_config.h>
4 #include <utils/Trace.h>
6 #include <private/dvr/trusted_uids.h>
8 #include "display_service.h"
9 #include "hardware_composer.h"
13 using android::dvr::display::DisplayProtocol;
14 using android::pdx::BorrowedChannelHandle;
15 using android::pdx::ErrorStatus;
16 using android::pdx::LocalChannelHandle;
17 using android::pdx::LocalHandle;
18 using android::pdx::Message;
19 using android::pdx::RemoteChannelHandle;
20 using android::pdx::Status;
21 using android::pdx::rpc::DispatchRemoteMethod;
22 using android::pdx::rpc::IfAnyOf;
27 DisplaySurface::DisplaySurface(DisplayService* service,
28 SurfaceType surface_type, int surface_id,
29 int process_id, int user_id,
30 const display::SurfaceAttributes& attributes)
32 surface_type_(surface_type),
33 surface_id_(surface_id),
34 process_id_(process_id),
36 attributes_(attributes),
37 update_flags_(display::SurfaceUpdateFlags::NewSurface) {}
39 DisplaySurface::~DisplaySurface() {
41 "DisplaySurface::~DisplaySurface: surface_id=%d process_id=%d",
42 surface_id(), process_id());
45 Status<void> DisplaySurface::HandleMessage(pdx::Message& message) {
46 switch (message.GetOp()) {
47 case DisplayProtocol::SetAttributes::Opcode:
48 DispatchRemoteMethod<DisplayProtocol::SetAttributes>(
49 *this, &DisplaySurface::OnSetAttributes, message);
52 case DisplayProtocol::GetSurfaceInfo::Opcode:
53 DispatchRemoteMethod<DisplayProtocol::GetSurfaceInfo>(
54 *this, &DisplaySurface::OnGetSurfaceInfo, message);
57 case DisplayProtocol::CreateQueue::Opcode:
58 DispatchRemoteMethod<DisplayProtocol::CreateQueue>(
59 *this, &DisplaySurface::OnCreateQueue, message);
66 Status<void> DisplaySurface::OnSetAttributes(
67 pdx::Message& /*message*/, const display::SurfaceAttributes& attributes) {
68 display::SurfaceUpdateFlags update_flags;
70 for (const auto& attribute : attributes) {
71 const auto key = attribute.first;
72 const auto* variant = &attribute.second;
73 bool invalid_value = false;
74 bool visibility_changed = false;
76 // Catch attributes that have significance to the display service.
78 case display::SurfaceAttribute::ZOrder:
79 invalid_value = !IfAnyOf<int32_t, int64_t, float>::Call(
80 variant, [&](const auto& value) {
81 if (z_order_ != value) {
82 visibility_changed = true;
87 case display::SurfaceAttribute::Visible:
88 invalid_value = !IfAnyOf<int32_t, int64_t, bool>::Call(
89 variant, [&](const auto& value) {
90 if (visible_ != value) {
91 visibility_changed = true;
98 // Only update the attribute map with valid values. This check also has the
99 // effect of preventing special attributes handled above from being deleted
100 // by an empty value.
103 "DisplaySurface::OnClientSetAttributes: Failed to set display "
104 "surface attribute '%d' because of incompatible type: %d",
105 key, variant->index());
107 // An empty value indicates the attribute should be deleted.
108 if (variant->empty()) {
109 auto search = attributes_.find(key);
110 if (search != attributes_.end())
111 attributes_.erase(search);
113 attributes_[key] = *variant;
116 // All attribute changes generate a notification, even if the value
117 // doesn't change. Visibility attributes set a flag only if the value
119 update_flags.Set(display::SurfaceUpdateFlags::AttributesChanged);
120 if (visibility_changed)
121 update_flags.Set(display::SurfaceUpdateFlags::VisibilityChanged);
125 SurfaceUpdated(update_flags);
129 void DisplaySurface::SurfaceUpdated(display::SurfaceUpdateFlags update_flags) {
131 "DisplaySurface::SurfaceUpdated: surface_id=%d update_flags=0x%x",
132 surface_id(), update_flags.value());
134 update_flags_.Set(update_flags);
135 service()->SurfaceUpdated(surface_type(), update_flags_);
138 void DisplaySurface::ClearUpdate() {
139 ALOGD_IF(TRACE > 1, "DisplaySurface::ClearUpdate: surface_id=%d",
141 update_flags_ = display::SurfaceUpdateFlags::None;
144 Status<display::SurfaceInfo> DisplaySurface::OnGetSurfaceInfo(
145 Message& /*message*/) {
148 "DisplaySurface::OnGetSurfaceInfo: surface_id=%d visible=%d z_order=%d",
149 surface_id(), visible(), z_order());
150 return {{surface_id(), visible(), z_order()}};
153 Status<void> DisplaySurface::RegisterQueue(
154 const std::shared_ptr<ConsumerQueue>& consumer_queue) {
155 ALOGD_IF(TRACE, "DisplaySurface::RegisterQueue: surface_id=%d queue_id=%d",
156 surface_id(), consumer_queue->id());
157 // Capture references for the lambda to work around apparent clang bug.
158 // TODO(eieio): Figure out if there is a clang bug or C++11 ambiguity when
159 // capturing self and consumer_queue by copy in the following case:
160 // auto self = Self();
161 // [self, consumer_queue](int events) {
162 // self->OnQueueEvent(consuemr_queue, events); }
165 std::shared_ptr<DisplaySurface> surface;
166 std::shared_ptr<ConsumerQueue> queue;
168 State state{Self(), consumer_queue};
170 return service()->AddEventHandler(
171 consumer_queue->queue_fd(), EPOLLIN | EPOLLHUP | EPOLLET,
172 [state](int events) {
173 state.surface->OnQueueEvent(state.queue, events);
177 Status<void> DisplaySurface::UnregisterQueue(
178 const std::shared_ptr<ConsumerQueue>& consumer_queue) {
179 ALOGD_IF(TRACE, "DisplaySurface::UnregisterQueue: surface_id=%d queue_id=%d",
180 surface_id(), consumer_queue->id());
181 return service()->RemoveEventHandler(consumer_queue->queue_fd());
184 void DisplaySurface::OnQueueEvent(
185 const std::shared_ptr<ConsumerQueue>& /*consumer_queue*/, int /*events*/) {
187 "DisplaySurface::OnQueueEvent: ERROR base virtual method should not be "
191 std::shared_ptr<ConsumerQueue> ApplicationDisplaySurface::GetQueue(
194 "ApplicationDisplaySurface::GetQueue: surface_id=%d queue_id=%d",
195 surface_id(), queue_id);
197 std::lock_guard<std::mutex> autolock(lock_);
198 auto search = consumer_queues_.find(queue_id);
199 if (search != consumer_queues_.end())
200 return search->second;
205 std::vector<int32_t> ApplicationDisplaySurface::GetQueueIds() const {
206 std::lock_guard<std::mutex> autolock(lock_);
207 std::vector<int32_t> queue_ids;
208 for (const auto& entry : consumer_queues_)
209 queue_ids.push_back(entry.first);
213 Status<LocalChannelHandle> ApplicationDisplaySurface::OnCreateQueue(
214 Message& /*message*/, const ProducerQueueConfig& config) {
215 ATRACE_NAME("ApplicationDisplaySurface::OnCreateQueue");
217 "ApplicationDisplaySurface::OnCreateQueue: surface_id=%d, "
218 "meta_size_bytes=%zu",
219 surface_id(), config.meta_size_bytes);
221 std::lock_guard<std::mutex> autolock(lock_);
222 auto producer = ProducerQueue::Create(config, UsagePolicy{});
225 "ApplicationDisplaySurface::OnCreateQueue: Failed to create producer "
227 return ErrorStatus(ENOMEM);
230 std::shared_ptr<ConsumerQueue> consumer =
231 producer->CreateSilentConsumerQueue();
232 auto status = RegisterQueue(consumer);
235 "ApplicationDisplaySurface::OnCreateQueue: Failed to register consumer "
237 status.GetErrorMessage().c_str());
238 return status.error_status();
241 consumer_queues_[consumer->id()] = std::move(consumer);
243 SurfaceUpdated(display::SurfaceUpdateFlags::BuffersChanged);
244 return std::move(producer->GetChannelHandle());
247 void ApplicationDisplaySurface::OnQueueEvent(
248 const std::shared_ptr<ConsumerQueue>& consumer_queue, int events) {
250 "ApplicationDisplaySurface::OnQueueEvent: queue_id=%d events=%x",
251 consumer_queue->id(), events);
253 std::lock_guard<std::mutex> autolock(lock_);
255 // Always give the queue a chance to handle its internal bookkeeping.
256 consumer_queue->HandleQueueEvents();
258 // Check for hangup and remove a queue that is no longer needed.
259 if (consumer_queue->hung_up()) {
260 ALOGD_IF(TRACE, "ApplicationDisplaySurface::OnQueueEvent: Removing queue.");
261 UnregisterQueue(consumer_queue);
262 auto search = consumer_queues_.find(consumer_queue->id());
263 if (search != consumer_queues_.end()) {
264 consumer_queues_.erase(search);
267 "ApplicationDisplaySurface::OnQueueEvent: Failed to find queue_id=%d",
268 consumer_queue->id());
270 SurfaceUpdated(display::SurfaceUpdateFlags::BuffersChanged);
274 std::vector<int32_t> DirectDisplaySurface::GetQueueIds() const {
275 std::lock_guard<std::mutex> autolock(lock_);
276 std::vector<int32_t> queue_ids;
278 queue_ids.push_back(direct_queue_->id());
282 Status<LocalChannelHandle> DirectDisplaySurface::OnCreateQueue(
283 Message& /*message*/, const ProducerQueueConfig& config) {
284 ATRACE_NAME("DirectDisplaySurface::OnCreateQueue");
287 "DirectDisplaySurface::OnCreateQueue: surface_id=%d meta_size_bytes=%zu",
288 surface_id(), config.meta_size_bytes);
290 std::lock_guard<std::mutex> autolock(lock_);
291 if (!direct_queue_) {
292 // Inject the hw composer usage flag to enable the display to read the
294 auto producer = ProducerQueue::Create(
295 config, UsagePolicy{GraphicBuffer::USAGE_HW_COMPOSER, 0, 0, 0});
298 "DirectDisplaySurface::OnCreateQueue: Failed to create producer "
300 return ErrorStatus(ENOMEM);
303 direct_queue_ = producer->CreateConsumerQueue();
304 if (direct_queue_->metadata_size() > 0) {
305 metadata_.reset(new uint8_t[direct_queue_->metadata_size()]);
307 auto status = RegisterQueue(direct_queue_);
310 "DirectDisplaySurface::OnCreateQueue: Failed to register consumer "
312 status.GetErrorMessage().c_str());
313 return status.error_status();
316 return std::move(producer->GetChannelHandle());
318 return ErrorStatus(EALREADY);
322 void DirectDisplaySurface::OnQueueEvent(
323 const std::shared_ptr<ConsumerQueue>& consumer_queue, int events) {
324 ALOGD_IF(TRACE, "DirectDisplaySurface::OnQueueEvent: queue_id=%d events=%x",
325 consumer_queue->id(), events);
327 std::lock_guard<std::mutex> autolock(lock_);
329 // Always give the queue a chance to handle its internal bookkeeping.
330 consumer_queue->HandleQueueEvents();
332 // Check for hangup and remove a queue that is no longer needed.
333 if (consumer_queue->hung_up()) {
334 ALOGD_IF(TRACE, "DirectDisplaySurface::OnQueueEvent: Removing queue.");
335 UnregisterQueue(consumer_queue);
336 direct_queue_ = nullptr;
340 void DirectDisplaySurface::DequeueBuffersLocked() {
341 if (direct_queue_ == nullptr) {
343 "DirectDisplaySurface::DequeueBuffersLocked: Consumer queue is not "
349 LocalHandle acquire_fence;
351 auto buffer_status = direct_queue_->Dequeue(
352 0, &slot, metadata_.get(),
353 direct_queue_->metadata_size(), &acquire_fence);
355 "DirectDisplaySurface::DequeueBuffersLocked: Dequeue with metadata_size: %zu",
356 direct_queue_->metadata_size());
357 if (!buffer_status) {
359 TRACE > 1 && buffer_status.error() == ETIMEDOUT,
360 "DirectDisplaySurface::DequeueBuffersLocked: All buffers dequeued.");
361 ALOGE_IF(buffer_status.error() != ETIMEDOUT,
362 "DirectDisplaySurface::DequeueBuffersLocked: Failed to dequeue "
364 buffer_status.GetErrorMessage().c_str());
367 auto buffer_consumer = buffer_status.take();
370 ATRACE_NAME("DropFrameOnInvisibleSurface");
372 "DirectDisplaySurface::DequeueBuffersLocked: Discarding "
373 "buffer_id=%d on invisible surface.",
374 buffer_consumer->id());
375 buffer_consumer->Discard();
379 if (acquired_buffers_.IsFull()) {
381 "DirectDisplaySurface::DequeueBuffersLocked: Posted buffers full, "
383 acquired_buffers_.PopBack();
386 acquired_buffers_.Append(
387 AcquiredBuffer(buffer_consumer, std::move(acquire_fence)));
391 AcquiredBuffer DirectDisplaySurface::AcquireCurrentBuffer() {
392 std::lock_guard<std::mutex> autolock(lock_);
393 DequeueBuffersLocked();
395 if (acquired_buffers_.IsEmpty()) {
397 "DirectDisplaySurface::AcquireCurrentBuffer: attempt to acquire buffer "
398 "when none are posted.");
399 return AcquiredBuffer();
401 AcquiredBuffer buffer = std::move(acquired_buffers_.Front());
402 acquired_buffers_.PopFront();
403 ALOGD_IF(TRACE, "DirectDisplaySurface::AcquireCurrentBuffer: buffer_id=%d",
404 buffer.buffer()->id());
408 AcquiredBuffer DirectDisplaySurface::AcquireNewestAvailableBuffer(
409 AcquiredBuffer* skipped_buffer) {
410 std::lock_guard<std::mutex> autolock(lock_);
411 DequeueBuffersLocked();
413 AcquiredBuffer buffer;
415 // Basic latency stopgap for when the application misses a frame:
416 // If the application recovers on the 2nd or 3rd (etc) frame after
417 // missing, this code will skip frames to catch up by checking if
418 // the next frame is also available.
419 while (!acquired_buffers_.IsEmpty() &&
420 acquired_buffers_.Front().IsAvailable()) {
421 // Capture the skipped buffer into the result parameter.
422 // Note that this API only supports skipping one buffer per vsync.
423 if (frames > 0 && skipped_buffer)
424 *skipped_buffer = std::move(buffer);
426 buffer = std::move(acquired_buffers_.Front());
427 acquired_buffers_.PopFront();
432 "DirectDisplaySurface::AcquireNewestAvailableBuffer: buffer_id=%d",
433 buffer.buffer()->id());
437 bool DirectDisplaySurface::IsBufferAvailable() {
438 std::lock_guard<std::mutex> autolock(lock_);
439 DequeueBuffersLocked();
441 return !acquired_buffers_.IsEmpty() &&
442 acquired_buffers_.Front().IsAvailable();
445 bool DirectDisplaySurface::IsBufferPosted() {
446 std::lock_guard<std::mutex> autolock(lock_);
447 DequeueBuffersLocked();
449 return !acquired_buffers_.IsEmpty();
452 Status<std::shared_ptr<DisplaySurface>> DisplaySurface::Create(
453 DisplayService* service, int surface_id, int process_id, int user_id,
454 const display::SurfaceAttributes& attributes) {
456 auto search = attributes.find(display::SurfaceAttribute::Direct);
457 if (search != attributes.end()) {
458 if (!IfAnyOf<int32_t, int64_t, bool, float>::Get(&search->second,
461 "DisplaySurface::Create: Invalid type for SurfaceAttribute::Direct!");
462 return ErrorStatus(EINVAL);
467 "DisplaySurface::Create: surface_id=%d process_id=%d user_id=%d "
469 surface_id, process_id, user_id, direct);
472 const bool trusted = user_id == AID_ROOT || IsTrustedUid(user_id);
474 return {std::shared_ptr<DisplaySurface>{new DirectDisplaySurface(
475 service, surface_id, process_id, user_id, attributes)}};
478 "DisplaySurface::Create: Direct surfaces may only be created by "
479 "trusted UIDs: user_id=%d",
481 return ErrorStatus(EPERM);
484 return {std::shared_ptr<DisplaySurface>{new ApplicationDisplaySurface(
485 service, surface_id, process_id, user_id, attributes)}};
490 } // namespace android