buffer_queue.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. // Copyright 2018 yuzu emulator team
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include <algorithm>
  5. #include "common/alignment.h"
  6. #include "common/scope_exit.h"
  7. #include "core/core_timing.h"
  8. #include "core/hle/service/nvflinger/buffer_queue.h"
  9. namespace Service {
  10. namespace NVFlinger {
  11. BufferQueue::BufferQueue(u32 id, u64 layer_id) : id(id), layer_id(layer_id) {
  12. native_handle = Kernel::Event::Create(Kernel::ResetType::OneShot, "BufferQueue NativeHandle");
  13. native_handle->Signal();
  14. }
  15. void BufferQueue::SetPreallocatedBuffer(u32 slot, IGBPBuffer& igbp_buffer) {
  16. Buffer buffer{};
  17. buffer.slot = slot;
  18. buffer.igbp_buffer = igbp_buffer;
  19. buffer.status = Buffer::Status::Free;
  20. LOG_WARNING(Service, "Adding graphics buffer {}", slot);
  21. queue.emplace_back(buffer);
  22. if (buffer_wait_event) {
  23. buffer_wait_event->Signal();
  24. }
  25. }
  26. boost::optional<u32> BufferQueue::DequeueBuffer(u32 width, u32 height) {
  27. auto itr = std::find_if(queue.begin(), queue.end(), [&](const Buffer& buffer) {
  28. // Only consider free buffers. Buffers become free once again after they've been Acquired
  29. // and Released by the compositor, see the NVFlinger::Compose method.
  30. if (buffer.status != Buffer::Status::Free) {
  31. return false;
  32. }
  33. // Make sure that the parameters match.
  34. return buffer.igbp_buffer.width == width && buffer.igbp_buffer.height == height;
  35. });
  36. if (itr == queue.end()) {
  37. return boost::none;
  38. }
  39. buffer_wait_event = nullptr;
  40. itr->status = Buffer::Status::Dequeued;
  41. return itr->slot;
  42. }
  43. const IGBPBuffer& BufferQueue::RequestBuffer(u32 slot) const {
  44. auto itr = std::find_if(queue.begin(), queue.end(),
  45. [&](const Buffer& buffer) { return buffer.slot == slot; });
  46. ASSERT(itr != queue.end());
  47. ASSERT(itr->status == Buffer::Status::Dequeued);
  48. return itr->igbp_buffer;
  49. }
  50. void BufferQueue::QueueBuffer(u32 slot, BufferTransformFlags transform) {
  51. auto itr = std::find_if(queue.begin(), queue.end(),
  52. [&](const Buffer& buffer) { return buffer.slot == slot; });
  53. ASSERT(itr != queue.end());
  54. ASSERT(itr->status == Buffer::Status::Dequeued);
  55. itr->status = Buffer::Status::Queued;
  56. itr->transform = transform;
  57. }
  58. boost::optional<const BufferQueue::Buffer&> BufferQueue::AcquireBuffer() {
  59. auto itr = std::find_if(queue.begin(), queue.end(), [](const Buffer& buffer) {
  60. return buffer.status == Buffer::Status::Queued;
  61. });
  62. if (itr == queue.end())
  63. return boost::none;
  64. itr->status = Buffer::Status::Acquired;
  65. return *itr;
  66. }
  67. void BufferQueue::ReleaseBuffer(u32 slot) {
  68. auto itr = std::find_if(queue.begin(), queue.end(),
  69. [&](const Buffer& buffer) { return buffer.slot == slot; });
  70. ASSERT(itr != queue.end());
  71. ASSERT(itr->status == Buffer::Status::Acquired);
  72. itr->status = Buffer::Status::Free;
  73. if (buffer_wait_event) {
  74. buffer_wait_event->Signal();
  75. }
  76. }
  77. u32 BufferQueue::Query(QueryType type) {
  78. LOG_WARNING(Service, "(STUBBED) called type={}", static_cast<u32>(type));
  79. switch (type) {
  80. case QueryType::NativeWindowFormat:
  81. // TODO(Subv): Use an enum for this
  82. static constexpr u32 FormatABGR8 = 1;
  83. return FormatABGR8;
  84. }
  85. UNIMPLEMENTED();
  86. return 0;
  87. }
  88. void BufferQueue::SetBufferWaitEvent(Kernel::SharedPtr<Kernel::Event>&& wait_event) {
  89. ASSERT_MSG(!buffer_wait_event, "buffer_wait_event only supports a single waiting thread!");
  90. buffer_wait_event = std::move(wait_event);
  91. }
  92. } // namespace NVFlinger
  93. } // namespace Service