display_surface.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488
  1. #include "display_surface.h"
  2. #include <private/android_filesystem_config.h>
  3. #include <utils/Trace.h>
  4. #include <private/dvr/trusted_uids.h>
  5. #include "display_service.h"
  6. #include "hardware_composer.h"
  7. #define LOCAL_TRACE 1
  8. using android::dvr::display::DisplayProtocol;
  9. using android::pdx::BorrowedChannelHandle;
  10. using android::pdx::ErrorStatus;
  11. using android::pdx::LocalChannelHandle;
  12. using android::pdx::LocalHandle;
  13. using android::pdx::Message;
  14. using android::pdx::RemoteChannelHandle;
  15. using android::pdx::Status;
  16. using android::pdx::rpc::DispatchRemoteMethod;
  17. using android::pdx::rpc::IfAnyOf;
  18. namespace android {
  19. namespace dvr {
  20. DisplaySurface::DisplaySurface(DisplayService* service,
  21. SurfaceType surface_type, int surface_id,
  22. int process_id, int user_id)
  23. : service_(service),
  24. surface_type_(surface_type),
  25. surface_id_(surface_id),
  26. process_id_(process_id),
  27. user_id_(user_id),
  28. update_flags_(display::SurfaceUpdateFlags::NewSurface) {}
  29. DisplaySurface::~DisplaySurface() {
  30. ALOGD_IF(LOCAL_TRACE,
  31. "DisplaySurface::~DisplaySurface: surface_id=%d process_id=%d",
  32. surface_id(), process_id());
  33. }
  34. Status<void> DisplaySurface::HandleMessage(pdx::Message& message) {
  35. switch (message.GetOp()) {
  36. case DisplayProtocol::SetAttributes::Opcode:
  37. DispatchRemoteMethod<DisplayProtocol::SetAttributes>(
  38. *this, &DisplaySurface::OnSetAttributes, message);
  39. break;
  40. case DisplayProtocol::GetSurfaceInfo::Opcode:
  41. DispatchRemoteMethod<DisplayProtocol::GetSurfaceInfo>(
  42. *this, &DisplaySurface::OnGetSurfaceInfo, message);
  43. break;
  44. case DisplayProtocol::CreateQueue::Opcode:
  45. DispatchRemoteMethod<DisplayProtocol::CreateQueue>(
  46. *this, &DisplaySurface::OnCreateQueue, message);
  47. break;
  48. }
  49. return {};
  50. }
  51. Status<void> DisplaySurface::OnSetAttributes(
  52. pdx::Message& /*message*/, const display::SurfaceAttributes& attributes) {
  53. display::SurfaceUpdateFlags update_flags;
  54. for (const auto& attribute : attributes) {
  55. const auto key = attribute.first;
  56. const auto* variant = &attribute.second;
  57. bool invalid_value = false;
  58. bool visibility_changed = false;
  59. // Catch attributes that have significance to the display service.
  60. switch (key) {
  61. case display::SurfaceAttribute::ZOrder:
  62. invalid_value = !IfAnyOf<int32_t, int64_t, float>::Call(
  63. variant, [&](const auto& value) {
  64. if (z_order_ != value) {
  65. visibility_changed = true;
  66. z_order_ = value;
  67. }
  68. });
  69. break;
  70. case display::SurfaceAttribute::Visible:
  71. invalid_value = !IfAnyOf<int32_t, int64_t, bool>::Call(
  72. variant, [&](const auto& value) {
  73. if (visible_ != value) {
  74. visibility_changed = true;
  75. visible_ = value;
  76. }
  77. });
  78. break;
  79. }
  80. // Only update the attribute map with valid values. This check also has the
  81. // effect of preventing special attributes handled above from being deleted
  82. // by an empty value.
  83. if (invalid_value) {
  84. ALOGW(
  85. "DisplaySurface::OnClientSetAttributes: Failed to set display "
  86. "surface attribute '%d' because of incompatible type: %d",
  87. key, variant->index());
  88. } else {
  89. // An empty value indicates the attribute should be deleted.
  90. if (variant->empty()) {
  91. auto search = attributes_.find(key);
  92. if (search != attributes_.end())
  93. attributes_.erase(search);
  94. } else {
  95. attributes_[key] = *variant;
  96. }
  97. // All attribute changes generate a notification, even if the value
  98. // doesn't change. Visibility attributes set a flag only if the value
  99. // changes.
  100. update_flags.Set(display::SurfaceUpdateFlags::AttributesChanged);
  101. if (visibility_changed)
  102. update_flags.Set(display::SurfaceUpdateFlags::VisibilityChanged);
  103. }
  104. }
  105. SurfaceUpdated(update_flags);
  106. return {};
  107. }
  108. void DisplaySurface::SurfaceUpdated(display::SurfaceUpdateFlags update_flags) {
  109. ALOGD_IF(TRACE,
  110. "DisplaySurface::SurfaceUpdated: surface_id=%d update_flags=0x%x",
  111. surface_id(), update_flags.value());
  112. update_flags_.Set(update_flags);
  113. service()->SurfaceUpdated(surface_type(), update_flags_);
  114. }
  115. void DisplaySurface::ClearUpdate() {
  116. ALOGD_IF(TRACE > 1, "DisplaySurface::ClearUpdate: surface_id=%d",
  117. surface_id());
  118. update_flags_ = display::SurfaceUpdateFlags::None;
  119. }
  120. Status<display::SurfaceInfo> DisplaySurface::OnGetSurfaceInfo(
  121. Message& /*message*/) {
  122. ALOGD_IF(
  123. TRACE,
  124. "DisplaySurface::OnGetSurfaceInfo: surface_id=%d visible=%d z_order=%d",
  125. surface_id(), visible(), z_order());
  126. return {{surface_id(), visible(), z_order()}};
  127. }
  128. Status<void> DisplaySurface::RegisterQueue(
  129. const std::shared_ptr<ConsumerQueue>& consumer_queue) {
  130. ALOGD_IF(TRACE, "DisplaySurface::RegisterQueue: surface_id=%d queue_id=%d",
  131. surface_id(), consumer_queue->id());
  132. // Capture references for the lambda to work around apparent clang bug.
  133. // TODO(eieio): Figure out if there is a clang bug or C++11 ambiguity when
  134. // capturing self and consumer_queue by copy in the following case:
  135. // auto self = Self();
  136. // [self, consumer_queue](int events) {
  137. // self->OnQueueEvent(consuemr_queue, events); }
  138. //
  139. struct State {
  140. std::shared_ptr<DisplaySurface> surface;
  141. std::shared_ptr<ConsumerQueue> queue;
  142. };
  143. State state{Self(), consumer_queue};
  144. return service()->AddEventHandler(
  145. consumer_queue->queue_fd(), EPOLLIN | EPOLLHUP | EPOLLET,
  146. [state](int events) {
  147. state.surface->OnQueueEvent(state.queue, events);
  148. });
  149. }
  150. Status<void> DisplaySurface::UnregisterQueue(
  151. const std::shared_ptr<ConsumerQueue>& consumer_queue) {
  152. ALOGD_IF(TRACE, "DisplaySurface::UnregisterQueue: surface_id=%d queue_id=%d",
  153. surface_id(), consumer_queue->id());
  154. return service()->RemoveEventHandler(consumer_queue->queue_fd());
  155. }
  156. void DisplaySurface::OnQueueEvent(
  157. const std::shared_ptr<ConsumerQueue>& /*consumer_queue*/, int /*events*/) {
  158. ALOGE(
  159. "DisplaySurface::OnQueueEvent: ERROR base virtual method should not be "
  160. "called!!!");
  161. }
  162. std::shared_ptr<ConsumerQueue> ApplicationDisplaySurface::GetQueue(
  163. int32_t queue_id) {
  164. ALOGD_IF(TRACE,
  165. "ApplicationDisplaySurface::GetQueue: surface_id=%d queue_id=%d",
  166. surface_id(), queue_id);
  167. std::lock_guard<std::mutex> autolock(lock_);
  168. auto search = consumer_queues_.find(queue_id);
  169. if (search != consumer_queues_.end())
  170. return search->second;
  171. else
  172. return nullptr;
  173. }
  174. std::vector<int32_t> ApplicationDisplaySurface::GetQueueIds() const {
  175. std::lock_guard<std::mutex> autolock(lock_);
  176. std::vector<int32_t> queue_ids;
  177. for (const auto& entry : consumer_queues_)
  178. queue_ids.push_back(entry.first);
  179. return queue_ids;
  180. }
  181. Status<LocalChannelHandle> ApplicationDisplaySurface::OnCreateQueue(
  182. Message& /*message*/, const ProducerQueueConfig& config) {
  183. ATRACE_NAME("ApplicationDisplaySurface::OnCreateQueue");
  184. ALOGD_IF(TRACE,
  185. "ApplicationDisplaySurface::OnCreateQueue: surface_id=%d, "
  186. "user_metadata_size=%zu",
  187. surface_id(), config.user_metadata_size);
  188. std::lock_guard<std::mutex> autolock(lock_);
  189. auto producer = ProducerQueue::Create(config, UsagePolicy{});
  190. if (!producer) {
  191. ALOGE(
  192. "ApplicationDisplaySurface::OnCreateQueue: Failed to create producer "
  193. "queue!");
  194. return ErrorStatus(ENOMEM);
  195. }
  196. std::shared_ptr<ConsumerQueue> consumer =
  197. producer->CreateSilentConsumerQueue();
  198. auto status = RegisterQueue(consumer);
  199. if (!status) {
  200. ALOGE(
  201. "ApplicationDisplaySurface::OnCreateQueue: Failed to register consumer "
  202. "queue: %s",
  203. status.GetErrorMessage().c_str());
  204. return status.error_status();
  205. }
  206. consumer_queues_[consumer->id()] = std::move(consumer);
  207. SurfaceUpdated(display::SurfaceUpdateFlags::BuffersChanged);
  208. return std::move(producer->GetChannelHandle());
  209. }
  210. void ApplicationDisplaySurface::OnQueueEvent(
  211. const std::shared_ptr<ConsumerQueue>& consumer_queue, int events) {
  212. ALOGD_IF(TRACE,
  213. "ApplicationDisplaySurface::OnQueueEvent: queue_id=%d events=%x",
  214. consumer_queue->id(), events);
  215. std::lock_guard<std::mutex> autolock(lock_);
  216. // Always give the queue a chance to handle its internal bookkeeping.
  217. consumer_queue->HandleQueueEvents();
  218. // Check for hangup and remove a queue that is no longer needed.
  219. if (consumer_queue->hung_up()) {
  220. ALOGD_IF(TRACE, "ApplicationDisplaySurface::OnQueueEvent: Removing queue.");
  221. UnregisterQueue(consumer_queue);
  222. auto search = consumer_queues_.find(consumer_queue->id());
  223. if (search != consumer_queues_.end()) {
  224. consumer_queues_.erase(search);
  225. } else {
  226. ALOGE(
  227. "ApplicationDisplaySurface::OnQueueEvent: Failed to find queue_id=%d",
  228. consumer_queue->id());
  229. }
  230. SurfaceUpdated(display::SurfaceUpdateFlags::BuffersChanged);
  231. }
  232. }
  233. std::vector<int32_t> DirectDisplaySurface::GetQueueIds() const {
  234. std::lock_guard<std::mutex> autolock(lock_);
  235. std::vector<int32_t> queue_ids;
  236. if (direct_queue_)
  237. queue_ids.push_back(direct_queue_->id());
  238. return queue_ids;
  239. }
  240. Status<LocalChannelHandle> DirectDisplaySurface::OnCreateQueue(
  241. Message& /*message*/, const ProducerQueueConfig& config) {
  242. ATRACE_NAME("DirectDisplaySurface::OnCreateQueue");
  243. ALOGD_IF(TRACE,
  244. "DirectDisplaySurface::OnCreateQueue: surface_id=%d "
  245. "user_metadata_size=%zu",
  246. surface_id(), config.user_metadata_size);
  247. std::lock_guard<std::mutex> autolock(lock_);
  248. if (!direct_queue_) {
  249. // Inject the hw composer usage flag to enable the display to read the
  250. // buffers.
  251. auto producer = ProducerQueue::Create(
  252. config, UsagePolicy{GraphicBuffer::USAGE_HW_COMPOSER, 0, 0, 0});
  253. if (!producer) {
  254. ALOGE(
  255. "DirectDisplaySurface::OnCreateQueue: Failed to create producer "
  256. "queue!");
  257. return ErrorStatus(ENOMEM);
  258. }
  259. direct_queue_ = producer->CreateConsumerQueue();
  260. if (direct_queue_->metadata_size() > 0) {
  261. metadata_.reset(new uint8_t[direct_queue_->metadata_size()]);
  262. }
  263. auto status = RegisterQueue(direct_queue_);
  264. if (!status) {
  265. ALOGE(
  266. "DirectDisplaySurface::OnCreateQueue: Failed to register consumer "
  267. "queue: %s",
  268. status.GetErrorMessage().c_str());
  269. return status.error_status();
  270. }
  271. return std::move(producer->GetChannelHandle());
  272. } else {
  273. return ErrorStatus(EALREADY);
  274. }
  275. }
  276. void DirectDisplaySurface::OnQueueEvent(
  277. const std::shared_ptr<ConsumerQueue>& consumer_queue, int events) {
  278. ALOGD_IF(TRACE, "DirectDisplaySurface::OnQueueEvent: queue_id=%d events=%x",
  279. consumer_queue->id(), events);
  280. std::lock_guard<std::mutex> autolock(lock_);
  281. // Always give the queue a chance to handle its internal bookkeeping.
  282. consumer_queue->HandleQueueEvents();
  283. // Check for hangup and remove a queue that is no longer needed.
  284. if (consumer_queue->hung_up()) {
  285. ALOGD_IF(TRACE, "DirectDisplaySurface::OnQueueEvent: Removing queue.");
  286. UnregisterQueue(consumer_queue);
  287. direct_queue_ = nullptr;
  288. }
  289. }
  290. void DirectDisplaySurface::DequeueBuffersLocked() {
  291. if (direct_queue_ == nullptr) {
  292. ALOGE(
  293. "DirectDisplaySurface::DequeueBuffersLocked: Consumer queue is not "
  294. "initialized.");
  295. return;
  296. }
  297. while (true) {
  298. LocalHandle acquire_fence;
  299. size_t slot;
  300. auto buffer_status = direct_queue_->Dequeue(
  301. 0, &slot, metadata_.get(),
  302. direct_queue_->metadata_size(), &acquire_fence);
  303. ALOGD_IF(TRACE,
  304. "DirectDisplaySurface::DequeueBuffersLocked: Dequeue with metadata_size: %zu",
  305. direct_queue_->metadata_size());
  306. if (!buffer_status) {
  307. ALOGD_IF(
  308. TRACE > 1 && buffer_status.error() == ETIMEDOUT,
  309. "DirectDisplaySurface::DequeueBuffersLocked: All buffers dequeued.");
  310. ALOGE_IF(buffer_status.error() != ETIMEDOUT,
  311. "DirectDisplaySurface::DequeueBuffersLocked: Failed to dequeue "
  312. "buffer: %s",
  313. buffer_status.GetErrorMessage().c_str());
  314. return;
  315. }
  316. auto buffer_consumer = buffer_status.take();
  317. if (!visible()) {
  318. ATRACE_NAME("DropFrameOnInvisibleSurface");
  319. ALOGD_IF(TRACE,
  320. "DirectDisplaySurface::DequeueBuffersLocked: Discarding "
  321. "buffer_id=%d on invisible surface.",
  322. buffer_consumer->id());
  323. buffer_consumer->Discard();
  324. continue;
  325. }
  326. if (acquired_buffers_.IsFull()) {
  327. ALOGE(
  328. "DirectDisplaySurface::DequeueBuffersLocked: Posted buffers full, "
  329. "overwriting.");
  330. acquired_buffers_.PopBack();
  331. }
  332. acquired_buffers_.Append(
  333. AcquiredBuffer(buffer_consumer, std::move(acquire_fence), slot));
  334. }
  335. }
  336. AcquiredBuffer DirectDisplaySurface::AcquireCurrentBuffer() {
  337. std::lock_guard<std::mutex> autolock(lock_);
  338. DequeueBuffersLocked();
  339. if (acquired_buffers_.IsEmpty()) {
  340. ALOGE(
  341. "DirectDisplaySurface::AcquireCurrentBuffer: attempt to acquire buffer "
  342. "when none are posted.");
  343. return AcquiredBuffer();
  344. }
  345. AcquiredBuffer buffer = std::move(acquired_buffers_.Front());
  346. acquired_buffers_.PopFront();
  347. ALOGD_IF(TRACE, "DirectDisplaySurface::AcquireCurrentBuffer: buffer_id=%d",
  348. buffer.buffer()->id());
  349. return buffer;
  350. }
  351. AcquiredBuffer DirectDisplaySurface::AcquireNewestAvailableBuffer(
  352. AcquiredBuffer* skipped_buffer) {
  353. std::lock_guard<std::mutex> autolock(lock_);
  354. DequeueBuffersLocked();
  355. AcquiredBuffer buffer;
  356. int frames = 0;
  357. // Basic latency stopgap for when the application misses a frame:
  358. // If the application recovers on the 2nd or 3rd (etc) frame after
  359. // missing, this code will skip frames to catch up by checking if
  360. // the next frame is also available.
  361. while (!acquired_buffers_.IsEmpty() &&
  362. acquired_buffers_.Front().IsAvailable()) {
  363. // Capture the skipped buffer into the result parameter.
  364. // Note that this API only supports skipping one buffer per vsync.
  365. if (frames > 0 && skipped_buffer)
  366. *skipped_buffer = std::move(buffer);
  367. ++frames;
  368. buffer = std::move(acquired_buffers_.Front());
  369. acquired_buffers_.PopFront();
  370. if (frames == 2)
  371. break;
  372. }
  373. ALOGD_IF(TRACE,
  374. "DirectDisplaySurface::AcquireNewestAvailableBuffer: buffer_id=%d",
  375. buffer.buffer()->id());
  376. return buffer;
  377. }
  378. bool DirectDisplaySurface::IsBufferAvailable() {
  379. std::lock_guard<std::mutex> autolock(lock_);
  380. DequeueBuffersLocked();
  381. return !acquired_buffers_.IsEmpty() &&
  382. acquired_buffers_.Front().IsAvailable();
  383. }
  384. bool DirectDisplaySurface::IsBufferPosted() {
  385. std::lock_guard<std::mutex> autolock(lock_);
  386. DequeueBuffersLocked();
  387. return !acquired_buffers_.IsEmpty();
  388. }
  389. Status<std::shared_ptr<DisplaySurface>> DisplaySurface::Create(
  390. DisplayService* service, int surface_id, int process_id, int user_id,
  391. const display::SurfaceAttributes& attributes) {
  392. bool direct = false;
  393. auto search = attributes.find(display::SurfaceAttribute::Direct);
  394. if (search != attributes.end()) {
  395. if (!IfAnyOf<int32_t, int64_t, bool, float>::Get(&search->second,
  396. &direct)) {
  397. ALOGE(
  398. "DisplaySurface::Create: Invalid type for SurfaceAttribute::Direct!");
  399. return ErrorStatus(EINVAL);
  400. }
  401. }
  402. ALOGD_IF(TRACE,
  403. "DisplaySurface::Create: surface_id=%d process_id=%d user_id=%d "
  404. "direct=%d",
  405. surface_id, process_id, user_id, direct);
  406. if (direct) {
  407. const bool trusted = user_id == AID_ROOT || IsTrustedUid(user_id);
  408. if (trusted) {
  409. return {std::shared_ptr<DisplaySurface>{
  410. new DirectDisplaySurface(service, surface_id, process_id, user_id)}};
  411. } else {
  412. ALOGE(
  413. "DisplaySurface::Create: Direct surfaces may only be created by "
  414. "trusted UIDs: user_id=%d",
  415. user_id);
  416. return ErrorStatus(EPERM);
  417. }
  418. } else {
  419. return {std::shared_ptr<DisplaySurface>{new ApplicationDisplaySurface(
  420. service, surface_id, process_id, user_id)}};
  421. }
  422. }
  423. } // namespace dvr
  424. } // namespace android