DisplaySurface::DisplaySurface(DisplayService* service,
SurfaceType surface_type, int surface_id,
- int process_id, int user_id,
- const display::SurfaceAttributes& attributes)
+ int process_id, int user_id)
: service_(service),
surface_type_(surface_type),
surface_id_(surface_id),
process_id_(process_id),
user_id_(user_id),
- attributes_(attributes),
update_flags_(display::SurfaceUpdateFlags::NewSurface) {}
DisplaySurface::~DisplaySurface() {
display::SurfaceUpdateFlags update_flags;
for (const auto& attribute : attributes) {
- const auto& key = attribute.first;
+ const auto key = attribute.first;
const auto* variant = &attribute.second;
bool invalid_value = false;
bool visibility_changed = false;
break;
}
+ // Only update the attribute map with valid values. This check also has the
+ // effect of preventing special attributes handled above from being deleted
+ // by an empty value.
if (invalid_value) {
ALOGW(
"DisplaySurface::OnClientSetAttributes: Failed to set display "
"surface attribute '%d' because of incompatible type: %d",
key, variant->index());
} else {
- // Only update the attribute map with valid values.
- attributes_[attribute.first] = attribute.second;
+ // An empty value indicates the attribute should be deleted.
+ if (variant->empty()) {
+ auto search = attributes_.find(key);
+ if (search != attributes_.end())
+ attributes_.erase(search);
+ } else {
+ attributes_[key] = *variant;
+ }
// All attribute changes generate a notification, even if the value
// doesn't change. Visibility attributes set a flag only if the value
}
void DisplaySurface::ClearUpdate() {
- ALOGD_IF(TRACE, "DisplaySurface::ClearUpdate: surface_id=%d", surface_id());
+ ALOGD_IF(TRACE > 1, "DisplaySurface::ClearUpdate: surface_id=%d",
+ surface_id());
update_flags_ = display::SurfaceUpdateFlags::None;
}
"ApplicationDisplaySurface::GetQueue: surface_id=%d queue_id=%d",
surface_id(), queue_id);
+ std::lock_guard<std::mutex> autolock(lock_);
auto search = consumer_queues_.find(queue_id);
if (search != consumer_queues_.end())
return search->second;
}
std::vector<int32_t> ApplicationDisplaySurface::GetQueueIds() const {
+ std::lock_guard<std::mutex> autolock(lock_);
std::vector<int32_t> queue_ids;
for (const auto& entry : consumer_queues_)
queue_ids.push_back(entry.first);
}
Status<LocalChannelHandle> ApplicationDisplaySurface::OnCreateQueue(
- Message& /*message*/, size_t meta_size_bytes) {
+ Message& /*message*/, const ProducerQueueConfig& config) {
ATRACE_NAME("ApplicationDisplaySurface::OnCreateQueue");
ALOGD_IF(TRACE,
"ApplicationDisplaySurface::OnCreateQueue: surface_id=%d, "
"meta_size_bytes=%zu",
- surface_id(), meta_size_bytes);
+ surface_id(), config.meta_size_bytes);
std::lock_guard<std::mutex> autolock(lock_);
- auto producer = ProducerQueue::Create(meta_size_bytes);
+ auto producer = ProducerQueue::Create(config, UsagePolicy{});
if (!producer) {
ALOGE(
"ApplicationDisplaySurface::OnCreateQueue: Failed to create producer "
"ApplicationDisplaySurface::OnQueueEvent: queue_id=%d events=%x",
consumer_queue->id(), events);
+ std::lock_guard<std::mutex> autolock(lock_);
+
// Always give the queue a chance to handle its internal bookkeeping.
consumer_queue->HandleQueueEvents();
// Check for hangup and remove a queue that is no longer needed.
- std::lock_guard<std::mutex> autolock(lock_);
if (consumer_queue->hung_up()) {
ALOGD_IF(TRACE, "ApplicationDisplaySurface::OnQueueEvent: Removing queue.");
UnregisterQueue(consumer_queue);
}
}
+std::vector<int32_t> DirectDisplaySurface::GetQueueIds() const {
+ std::lock_guard<std::mutex> autolock(lock_);
+ std::vector<int32_t> queue_ids;
+ if (direct_queue_)
+ queue_ids.push_back(direct_queue_->id());
+ return queue_ids;
+}
+
Status<LocalChannelHandle> DirectDisplaySurface::OnCreateQueue(
- Message& /*message*/, size_t meta_size_bytes) {
+ Message& /*message*/, const ProducerQueueConfig& config) {
ATRACE_NAME("DirectDisplaySurface::OnCreateQueue");
ALOGD_IF(
TRACE,
"DirectDisplaySurface::OnCreateQueue: surface_id=%d meta_size_bytes=%zu",
- surface_id(), meta_size_bytes);
+ surface_id(), config.meta_size_bytes);
std::lock_guard<std::mutex> autolock(lock_);
if (!direct_queue_) {
- auto producer = ProducerQueue::Create(meta_size_bytes);
+ // Inject the hw composer usage flag to enable the display to read the
+ // buffers.
+ auto producer = ProducerQueue::Create(
+ config, UsagePolicy{GraphicBuffer::USAGE_HW_COMPOSER, 0, 0, 0});
if (!producer) {
ALOGE(
"DirectDisplaySurface::OnCreateQueue: Failed to create producer "
}
direct_queue_ = producer->CreateConsumerQueue();
+ if (direct_queue_->metadata_size() > 0) {
+ metadata_.reset(new uint8_t[direct_queue_->metadata_size()]);
+ }
auto status = RegisterQueue(direct_queue_);
if (!status) {
ALOGE(
ALOGD_IF(TRACE, "DirectDisplaySurface::OnQueueEvent: queue_id=%d events=%x",
consumer_queue->id(), events);
+ std::lock_guard<std::mutex> autolock(lock_);
+
// Always give the queue a chance to handle its internal bookkeeping.
consumer_queue->HandleQueueEvents();
// Check for hangup and remove a queue that is no longer needed.
- std::lock_guard<std::mutex> autolock(lock_);
if (consumer_queue->hung_up()) {
ALOGD_IF(TRACE, "DirectDisplaySurface::OnQueueEvent: Removing queue.");
UnregisterQueue(consumer_queue);
while (true) {
LocalHandle acquire_fence;
size_t slot;
- auto buffer_status = direct_queue_->Dequeue(0, &slot, &acquire_fence);
+ auto buffer_status = direct_queue_->Dequeue(
+ 0, &slot, metadata_.get(),
+ direct_queue_->metadata_size(), &acquire_fence);
+ ALOGD_IF(TRACE,
+ "DirectDisplaySurface::DequeueBuffersLocked: Dequeue with metadata_size: %zu",
+ direct_queue_->metadata_size());
if (!buffer_status) {
ALOGD_IF(
- TRACE && buffer_status.error() == ETIMEDOUT,
+ TRACE > 1 && buffer_status.error() == ETIMEDOUT,
"DirectDisplaySurface::DequeueBuffersLocked: All buffers dequeued.");
ALOGE_IF(buffer_status.error() != ETIMEDOUT,
"DirectDisplaySurface::DequeueBuffersLocked: Failed to dequeue "
}
AcquiredBuffer buffer = std::move(acquired_buffers_.Front());
acquired_buffers_.PopFront();
- ALOGD_IF(TRACE, "DirectDisplaySurface::AcquireCurrentBuffer: buffer: %p",
- buffer.buffer().get());
+ ALOGD_IF(TRACE, "DirectDisplaySurface::AcquireCurrentBuffer: buffer_id=%d",
+ buffer.buffer()->id());
return buffer;
}
break;
}
ALOGD_IF(TRACE,
- "DirectDisplaySurface::AcquireNewestAvailableBuffer: buffer: %p",
- buffer.buffer().get());
+ "DirectDisplaySurface::AcquireNewestAvailableBuffer: buffer_id=%d",
+ buffer.buffer()->id());
return buffer;
}
if (direct) {
const bool trusted = user_id == AID_ROOT || IsTrustedUid(user_id);
if (trusted) {
- return {std::shared_ptr<DisplaySurface>{new DirectDisplaySurface(
- service, surface_id, process_id, user_id, attributes)}};
+ return {std::shared_ptr<DisplaySurface>{
+ new DirectDisplaySurface(service, surface_id, process_id, user_id)}};
} else {
ALOGE(
"DisplaySurface::Create: Direct surfaces may only be created by "
}
} else {
return {std::shared_ptr<DisplaySurface>{new ApplicationDisplaySurface(
- service, surface_id, process_id, user_id, attributes)}};
+ service, surface_id, process_id, user_id)}};
}
}