1a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include "display_surface.h" 2a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 32251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka#include <private/android_filesystem_config.h> 4a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include <utils/Trace.h> 5a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 62251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka#include <private/dvr/trusted_uids.h> 7a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 8a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include "display_service.h" 9a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include "hardware_composer.h" 10a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 11a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#define LOCAL_TRACE 1 12a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 132251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakausing android::dvr::display::DisplayProtocol; 14a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkousing android::pdx::BorrowedChannelHandle; 152251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakausing android::pdx::ErrorStatus; 16a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkousing android::pdx::LocalChannelHandle; 172251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakausing android::pdx::LocalHandle; 18a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkousing android::pdx::Message; 19a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkousing android::pdx::RemoteChannelHandle; 20a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkousing android::pdx::Status; 21a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkousing android::pdx::rpc::DispatchRemoteMethod; 22a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkousing android::pdx::rpc::IfAnyOf; 23a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 24a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkonamespace android { 25a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkonamespace dvr { 26a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 272251d822dac2a96aad4184a6fdc2690f0a58af7cCorey TabakaDisplaySurface::DisplaySurface(DisplayService* service, 282251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka SurfaceType surface_type, int surface_id, 292251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka int process_id, int user_id, 302251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka const display::SurfaceAttributes& attributes) 312251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka : service_(service), 322251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka surface_type_(surface_type), 332251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka surface_id_(surface_id), 34a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko process_id_(process_id), 352251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka user_id_(user_id), 362251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka attributes_(attributes), 372251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka update_flags_(display::SurfaceUpdateFlags::NewSurface) {} 38a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 39a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex VakulenkoDisplaySurface::~DisplaySurface() { 40a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko ALOGD_IF(LOCAL_TRACE, 41a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko "DisplaySurface::~DisplaySurface: surface_id=%d process_id=%d", 422251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka surface_id(), process_id()); 43a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 44a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 452251d822dac2a96aad4184a6fdc2690f0a58af7cCorey TabakaStatus<void> DisplaySurface::HandleMessage(pdx::Message& message) { 462251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka switch (message.GetOp()) { 472251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka case DisplayProtocol::SetAttributes::Opcode: 482251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka DispatchRemoteMethod<DisplayProtocol::SetAttributes>( 492251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka *this, &DisplaySurface::OnSetAttributes, message); 502251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka break; 512251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 522251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka case DisplayProtocol::GetSurfaceInfo::Opcode: 532251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka DispatchRemoteMethod<DisplayProtocol::GetSurfaceInfo>( 542251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka *this, &DisplaySurface::OnGetSurfaceInfo, message); 552251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka break; 562251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 572251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka case DisplayProtocol::CreateQueue::Opcode: 582251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka DispatchRemoteMethod<DisplayProtocol::CreateQueue>( 592251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka *this, &DisplaySurface::OnCreateQueue, message); 602251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka break; 612251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka } 622251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 632251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka return {}; 64a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 65a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 662251d822dac2a96aad4184a6fdc2690f0a58af7cCorey TabakaStatus<void> DisplaySurface::OnSetAttributes( 672251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka pdx::Message& /*message*/, const display::SurfaceAttributes& attributes) { 682251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka display::SurfaceUpdateFlags update_flags; 692251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 702251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka for (const auto& attribute : attributes) { 712251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka const auto& key = attribute.first; 722251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka const auto* variant = &attribute.second; 732251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka bool invalid_value = false; 742251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka bool visibility_changed = false; 752251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 762251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // Catch attributes that have significance to the display service. 772251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka switch (key) { 782251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka case display::SurfaceAttribute::ZOrder: 792251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka invalid_value = !IfAnyOf<int32_t, int64_t, float>::Call( 802251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka variant, [&](const auto& value) { 812251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (z_order_ != value) { 822251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka visibility_changed = true; 832251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka z_order_ = value; 842251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka } 852251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka }); 862251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka break; 872251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka case display::SurfaceAttribute::Visible: 882251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka invalid_value = !IfAnyOf<int32_t, int64_t, bool>::Call( 892251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka variant, [&](const auto& value) { 902251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (visible_ != value) { 912251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka visibility_changed = true; 922251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka visible_ = value; 932251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka } 942251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka }); 952251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka break; 962251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka } 972251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 982251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (invalid_value) { 992251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGW( 1002251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "DisplaySurface::OnClientSetAttributes: Failed to set display " 1012251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "surface attribute '%d' because of incompatible type: %d", 1022251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka key, variant->index()); 1032251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka } else { 1042251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // Only update the attribute map with valid values. 1052251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka attributes_[attribute.first] = attribute.second; 1062251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 1072251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // All attribute changes generate a notification, even if the value 1082251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // doesn't change. Visibility attributes set a flag only if the value 1092251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // changes. 1102251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka update_flags.Set(display::SurfaceUpdateFlags::AttributesChanged); 1112251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (visibility_changed) 1122251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka update_flags.Set(display::SurfaceUpdateFlags::VisibilityChanged); 1132251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka } 1142251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka } 1152251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 1162251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka SurfaceUpdated(update_flags); 1172251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka return {}; 118a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 119a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 1202251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakavoid DisplaySurface::SurfaceUpdated(display::SurfaceUpdateFlags update_flags) { 1212251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGD_IF(TRACE, 1222251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "DisplaySurface::SurfaceUpdated: surface_id=%d update_flags=0x%x", 1232251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka surface_id(), update_flags.value()); 1242251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 1252251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka update_flags_.Set(update_flags); 1262251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka service()->SurfaceUpdated(surface_type(), update_flags_); 1272251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka} 1282251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 1292251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakavoid DisplaySurface::ClearUpdate() { 1302251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGD_IF(TRACE, "DisplaySurface::ClearUpdate: surface_id=%d", surface_id()); 1312251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka update_flags_ = display::SurfaceUpdateFlags::None; 132a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 133a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 1342251d822dac2a96aad4184a6fdc2690f0a58af7cCorey TabakaStatus<display::SurfaceInfo> DisplaySurface::OnGetSurfaceInfo( 1352251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka Message& /*message*/) { 1362251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGD_IF( 1372251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka TRACE, 1382251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "DisplaySurface::OnGetSurfaceInfo: surface_id=%d visible=%d z_order=%d", 1392251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka surface_id(), visible(), z_order()); 1402251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka return {{surface_id(), visible(), z_order()}}; 1412251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka} 1422251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 1432251d822dac2a96aad4184a6fdc2690f0a58af7cCorey TabakaStatus<void> DisplaySurface::RegisterQueue( 1442251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka const std::shared_ptr<ConsumerQueue>& consumer_queue) { 1452251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGD_IF(TRACE, "DisplaySurface::RegisterQueue: surface_id=%d queue_id=%d", 1462251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka surface_id(), consumer_queue->id()); 1472251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // Capture references for the lambda to work around apparent clang bug. 1482251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // TODO(eieio): Figure out if there is a clang bug or C++11 ambiguity when 1492251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // capturing self and consumer_queue by copy in the following case: 1502251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // auto self = Self(); 1512251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // [self, consumer_queue](int events) { 1522251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // self->OnQueueEvent(consuemr_queue, events); } 1532251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // 1542251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka struct State { 1552251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka std::shared_ptr<DisplaySurface> surface; 1562251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka std::shared_ptr<ConsumerQueue> queue; 1572251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka }; 1582251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka State state{Self(), consumer_queue}; 1592251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 1602251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka return service()->AddEventHandler( 1612251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka consumer_queue->queue_fd(), EPOLLIN | EPOLLHUP | EPOLLET, 1622251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka [state](int events) { 1632251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka state.surface->OnQueueEvent(state.queue, events); 1642251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka }); 1652251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka} 1662251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 1672251d822dac2a96aad4184a6fdc2690f0a58af7cCorey TabakaStatus<void> DisplaySurface::UnregisterQueue( 1682251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka const std::shared_ptr<ConsumerQueue>& consumer_queue) { 1692251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGD_IF(TRACE, "DisplaySurface::UnregisterQueue: surface_id=%d queue_id=%d", 1702251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka surface_id(), consumer_queue->id()); 1712251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka return service()->RemoveEventHandler(consumer_queue->queue_fd()); 1722251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka} 1732251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 1742251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakavoid DisplaySurface::OnQueueEvent( 1752251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka const std::shared_ptr<ConsumerQueue>& /*consumer_queue*/, int /*events*/) { 1762251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGE( 1772251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "DisplaySurface::OnQueueEvent: ERROR base virtual method should not be " 1782251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "called!!!"); 1792251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka} 1802251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 1812251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakastd::shared_ptr<ConsumerQueue> ApplicationDisplaySurface::GetQueue( 1822251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka int32_t queue_id) { 1832251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGD_IF(TRACE, 1842251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "ApplicationDisplaySurface::GetQueue: surface_id=%d queue_id=%d", 1852251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka surface_id(), queue_id); 1862251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 1872251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka auto search = consumer_queues_.find(queue_id); 1882251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (search != consumer_queues_.end()) 1892251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka return search->second; 1902251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka else 1912251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka return nullptr; 1922251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka} 1932251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 1942251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakastd::vector<int32_t> ApplicationDisplaySurface::GetQueueIds() const { 1952251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka std::vector<int32_t> queue_ids; 1962251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka for (const auto& entry : consumer_queues_) 1972251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka queue_ids.push_back(entry.first); 1982251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka return queue_ids; 1992251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka} 2002251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 2012251d822dac2a96aad4184a6fdc2690f0a58af7cCorey TabakaStatus<LocalChannelHandle> ApplicationDisplaySurface::OnCreateQueue( 2022251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka Message& /*message*/, size_t meta_size_bytes) { 2032251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ATRACE_NAME("ApplicationDisplaySurface::OnCreateQueue"); 2042251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGD_IF(TRACE, 2052251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "ApplicationDisplaySurface::OnCreateQueue: surface_id=%d, " 2062251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "meta_size_bytes=%zu", 2072251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka surface_id(), meta_size_bytes); 2082251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 209a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko std::lock_guard<std::mutex> autolock(lock_); 2102251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka auto producer = ProducerQueue::Create(meta_size_bytes); 2112251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (!producer) { 2122251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGE( 2132251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "ApplicationDisplaySurface::OnCreateQueue: Failed to create producer " 2142251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "queue!"); 2152251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka return ErrorStatus(ENOMEM); 2162251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka } 2172251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 2182251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka std::shared_ptr<ConsumerQueue> consumer = 2192251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka producer->CreateSilentConsumerQueue(); 2202251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka auto status = RegisterQueue(consumer); 2212251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (!status) { 2222251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGE( 2232251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "ApplicationDisplaySurface::OnCreateQueue: Failed to register consumer " 2242251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "queue: %s", 2252251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka status.GetErrorMessage().c_str()); 2262251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka return status.error_status(); 2272251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka } 2282251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 2292251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka consumer_queues_[consumer->id()] = std::move(consumer); 2302251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 2312251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka SurfaceUpdated(display::SurfaceUpdateFlags::BuffersChanged); 2322251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka return std::move(producer->GetChannelHandle()); 233a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 234a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 2352251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakavoid ApplicationDisplaySurface::OnQueueEvent( 2362251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka const std::shared_ptr<ConsumerQueue>& consumer_queue, int events) { 2372251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGD_IF(TRACE, 2382251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "ApplicationDisplaySurface::OnQueueEvent: queue_id=%d events=%x", 2392251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka consumer_queue->id(), events); 2402251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 2412251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // Always give the queue a chance to handle its internal bookkeeping. 2422251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka consumer_queue->HandleQueueEvents(); 2432251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 2442251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // Check for hangup and remove a queue that is no longer needed. 245a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko std::lock_guard<std::mutex> autolock(lock_); 2462251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (consumer_queue->hung_up()) { 2472251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGD_IF(TRACE, "ApplicationDisplaySurface::OnQueueEvent: Removing queue."); 2482251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka UnregisterQueue(consumer_queue); 2492251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka auto search = consumer_queues_.find(consumer_queue->id()); 2502251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (search != consumer_queues_.end()) { 2512251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka consumer_queues_.erase(search); 2522251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka } else { 2532251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGE( 2542251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "ApplicationDisplaySurface::OnQueueEvent: Failed to find queue_id=%d", 2552251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka consumer_queue->id()); 2562251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka } 2572251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka SurfaceUpdated(display::SurfaceUpdateFlags::BuffersChanged); 2582251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka } 259a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 260a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 2612251d822dac2a96aad4184a6fdc2690f0a58af7cCorey TabakaStatus<LocalChannelHandle> DirectDisplaySurface::OnCreateQueue( 2622251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka Message& /*message*/, size_t meta_size_bytes) { 2632251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ATRACE_NAME("DirectDisplaySurface::OnCreateQueue"); 2642251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGD_IF( 2652251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka TRACE, 2662251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "DirectDisplaySurface::OnCreateQueue: surface_id=%d meta_size_bytes=%zu", 2672251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka surface_id(), meta_size_bytes); 2682251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 269a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko std::lock_guard<std::mutex> autolock(lock_); 2702251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (!direct_queue_) { 2712251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka auto producer = ProducerQueue::Create(meta_size_bytes); 2722251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (!producer) { 2732251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGE( 2742251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "DirectDisplaySurface::OnCreateQueue: Failed to create producer " 2752251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "queue!"); 2762251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka return ErrorStatus(ENOMEM); 2772251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka } 2782251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 2792251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka direct_queue_ = producer->CreateConsumerQueue(); 2802251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka auto status = RegisterQueue(direct_queue_); 2812251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (!status) { 2822251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGE( 2832251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "DirectDisplaySurface::OnCreateQueue: Failed to register consumer " 2842251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "queue: %s", 2852251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka status.GetErrorMessage().c_str()); 2862251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka return status.error_status(); 2872251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka } 2882251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 2892251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka return std::move(producer->GetChannelHandle()); 2902251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka } else { 2912251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka return ErrorStatus(EALREADY); 2922251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka } 293a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 294a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 2952251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakavoid DirectDisplaySurface::OnQueueEvent( 2962251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka const std::shared_ptr<ConsumerQueue>& consumer_queue, int events) { 2972251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGD_IF(TRACE, "DirectDisplaySurface::OnQueueEvent: queue_id=%d events=%x", 2982251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka consumer_queue->id(), events); 2992251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 3002251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // Always give the queue a chance to handle its internal bookkeeping. 3012251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka consumer_queue->HandleQueueEvents(); 3022251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 3032251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // Check for hangup and remove a queue that is no longer needed. 304a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko std::lock_guard<std::mutex> autolock(lock_); 3052251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (consumer_queue->hung_up()) { 3062251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGD_IF(TRACE, "DirectDisplaySurface::OnQueueEvent: Removing queue."); 3072251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka UnregisterQueue(consumer_queue); 3082251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka direct_queue_ = nullptr; 3092251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka } 310a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 311a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 3122251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakavoid DirectDisplaySurface::DequeueBuffersLocked() { 3132251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (direct_queue_ == nullptr) { 314a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai ALOGE( 3152251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "DirectDisplaySurface::DequeueBuffersLocked: Consumer queue is not " 316a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai "initialized."); 317a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai return; 318a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai } 319a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai 320a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai while (true) { 321a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai LocalHandle acquire_fence; 3222251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka size_t slot; 3232251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka auto buffer_status = direct_queue_->Dequeue(0, &slot, &acquire_fence); 3242251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (!buffer_status) { 3252251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGD_IF( 3262251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka TRACE && buffer_status.error() == ETIMEDOUT, 3272251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "DirectDisplaySurface::DequeueBuffersLocked: All buffers dequeued."); 3282251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGE_IF(buffer_status.error() != ETIMEDOUT, 3292251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "DirectDisplaySurface::DequeueBuffersLocked: Failed to dequeue " 3302251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "buffer: %s", 3312251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka buffer_status.GetErrorMessage().c_str()); 332a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai return; 333a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai } 3342251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka auto buffer_consumer = buffer_status.take(); 335a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai 3362251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (!visible()) { 337a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai ATRACE_NAME("DropFrameOnInvisibleSurface"); 338a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai ALOGD_IF(TRACE, 3392251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "DirectDisplaySurface::DequeueBuffersLocked: Discarding " 3402251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "buffer_id=%d on invisible surface.", 341a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai buffer_consumer->id()); 342a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai buffer_consumer->Discard(); 343a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai continue; 344a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai } 345a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai 346a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai if (acquired_buffers_.IsFull()) { 347a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai ALOGE( 3482251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "DirectDisplaySurface::DequeueBuffersLocked: Posted buffers full, " 349a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai "overwriting."); 350a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai acquired_buffers_.PopBack(); 351a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai } 352a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai 353a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai acquired_buffers_.Append( 3542251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka AcquiredBuffer(buffer_consumer, std::move(acquire_fence))); 355a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai } 356a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai} 357a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai 3582251d822dac2a96aad4184a6fdc2690f0a58af7cCorey TabakaAcquiredBuffer DirectDisplaySurface::AcquireCurrentBuffer() { 359a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai std::lock_guard<std::mutex> autolock(lock_); 360a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai DequeueBuffersLocked(); 361a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai 362a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai if (acquired_buffers_.IsEmpty()) { 363a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai ALOGE( 3642251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "DirectDisplaySurface::AcquireCurrentBuffer: attempt to acquire buffer " 3652251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "when none are posted."); 366a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai return AcquiredBuffer(); 367a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai } 368a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai AcquiredBuffer buffer = std::move(acquired_buffers_.Front()); 369a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai acquired_buffers_.PopFront(); 3702251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGD_IF(TRACE, "DirectDisplaySurface::AcquireCurrentBuffer: buffer: %p", 371a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai buffer.buffer().get()); 372a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai return buffer; 373a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai} 374a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai 3752251d822dac2a96aad4184a6fdc2690f0a58af7cCorey TabakaAcquiredBuffer DirectDisplaySurface::AcquireNewestAvailableBuffer( 376a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko AcquiredBuffer* skipped_buffer) { 377a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko std::lock_guard<std::mutex> autolock(lock_); 378a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai DequeueBuffersLocked(); 379a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai 380a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko AcquiredBuffer buffer; 381a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko int frames = 0; 382a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // Basic latency stopgap for when the application misses a frame: 383a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // If the application recovers on the 2nd or 3rd (etc) frame after 384a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // missing, this code will skip frames to catch up by checking if 385a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // the next frame is also available. 386a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai while (!acquired_buffers_.IsEmpty() && 387a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai acquired_buffers_.Front().IsAvailable()) { 388a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // Capture the skipped buffer into the result parameter. 389a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // Note that this API only supports skipping one buffer per vsync. 390a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko if (frames > 0 && skipped_buffer) 391a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko *skipped_buffer = std::move(buffer); 392a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko ++frames; 393a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai buffer = std::move(acquired_buffers_.Front()); 394a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai acquired_buffers_.PopFront(); 395a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko if (frames == 2) 396a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko break; 397a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 3982251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGD_IF(TRACE, 3992251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "DirectDisplaySurface::AcquireNewestAvailableBuffer: buffer: %p", 400a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai buffer.buffer().get()); 401a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko return buffer; 402a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 403a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 4042251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakabool DirectDisplaySurface::IsBufferAvailable() { 405a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko std::lock_guard<std::mutex> autolock(lock_); 406a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai DequeueBuffersLocked(); 407a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 408a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai return !acquired_buffers_.IsEmpty() && 409a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai acquired_buffers_.Front().IsAvailable(); 410a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 411a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 4122251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakabool DirectDisplaySurface::IsBufferPosted() { 413a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko std::lock_guard<std::mutex> autolock(lock_); 414a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai DequeueBuffersLocked(); 415a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 416a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai return !acquired_buffers_.IsEmpty(); 417a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 418a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 4192251d822dac2a96aad4184a6fdc2690f0a58af7cCorey TabakaStatus<std::shared_ptr<DisplaySurface>> DisplaySurface::Create( 4202251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka DisplayService* service, int surface_id, int process_id, int user_id, 4212251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka const display::SurfaceAttributes& attributes) { 4222251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka bool direct = false; 4232251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka auto search = attributes.find(display::SurfaceAttribute::Direct); 4242251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (search != attributes.end()) { 4252251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (!IfAnyOf<int32_t, int64_t, bool, float>::Get(&search->second, 4262251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka &direct)) { 4272251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGE( 4282251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "DisplaySurface::Create: Invalid type for SurfaceAttribute::Direct!"); 4292251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka return ErrorStatus(EINVAL); 430a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 431a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 432a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 4332251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGD_IF(TRACE, 4342251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "DisplaySurface::Create: surface_id=%d process_id=%d user_id=%d " 4352251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "direct=%d", 4362251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka surface_id, process_id, user_id, direct); 437a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 4382251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (direct) { 4392251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka const bool trusted = user_id == AID_ROOT || IsTrustedUid(user_id); 4402251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (trusted) { 4412251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka return {std::shared_ptr<DisplaySurface>{new DirectDisplaySurface( 4422251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka service, surface_id, process_id, user_id, attributes)}}; 443a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } else { 4442251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGE( 4452251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "DisplaySurface::Create: Direct surfaces may only be created by " 4462251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "trusted UIDs: user_id=%d", 4472251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka user_id); 4482251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka return ErrorStatus(EPERM); 449a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 4502251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka } else { 4512251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka return {std::shared_ptr<DisplaySurface>{new ApplicationDisplaySurface( 4522251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka service, surface_id, process_id, user_id, attributes)}}; 453a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 454a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 455a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 456a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} // namespace dvr 457a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} // namespace android 458