summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/vi/vi.cpp52
-rw-r--r--src/core/hle/service/vi/vi.h19
2 files changed, 58 insertions, 13 deletions
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp
index fab7a12e4..67d82c2bf 100644
--- a/src/core/hle/service/vi/vi.cpp
+++ b/src/core/hle/service/vi/vi.cpp
@@ -3,6 +3,7 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "common/alignment.h" 5#include "common/alignment.h"
6#include "common/scope_exit.h"
6#include "core/core_timing.h" 7#include "core/core_timing.h"
7#include "core/hle/ipc_helpers.h" 8#include "core/hle/ipc_helpers.h"
8#include "core/hle/service/vi/vi.h" 9#include "core/hle/service/vi/vi.h"
@@ -721,8 +722,30 @@ Layer& NVFlinger::GetLayer(u64 display_id, u64 layer_id) {
721 722
722void NVFlinger::Compose() { 723void NVFlinger::Compose() {
723 for (auto& display : displays) { 724 for (auto& display : displays) {
724 // TODO(Subv): Gather the surfaces and forward them to the GPU for drawing. 725 // Trigger vsync for this display at the end of drawing
725 display.vsync_event->Signal(); 726 SCOPE_EXIT({ display.vsync_event->Signal(); });
727
728 // Don't do anything for displays without layers.
729 if (display.layers.empty())
730 continue;
731
732 // TODO(Subv): Support more than 1 layer.
733 ASSERT_MSG(display.layers.size() == 1, "Max 1 layer per display is supported");
734
735 Layer& layer = display.layers[0];
736 auto& buffer_queue = layer.buffer_queue;
737
738 // Search for a queued buffer and acquire it
739 auto buffer = buffer_queue->AcquireBuffer();
740
741 if (buffer == boost::none) {
742 // There was no queued buffer to draw.
743 continue;
744 }
745
746 // TODO(Subv): Send the buffer to the GPU for drawing.
747
748 buffer_queue->ReleaseBuffer(buffer->slot);
726 } 749 }
727} 750}
728 751
@@ -732,7 +755,7 @@ void BufferQueue::SetPreallocatedBuffer(u32 slot, IGBPBuffer& igbp_buffer) {
732 Buffer buffer{}; 755 Buffer buffer{};
733 buffer.slot = slot; 756 buffer.slot = slot;
734 buffer.igbp_buffer = igbp_buffer; 757 buffer.igbp_buffer = igbp_buffer;
735 buffer.status = Buffer::Status::Queued; 758 buffer.status = Buffer::Status::Free;
736 759
737 LOG_WARNING(Service, "Adding graphics buffer %u", slot); 760 LOG_WARNING(Service, "Adding graphics buffer %u", slot);
738 761
@@ -741,8 +764,9 @@ void BufferQueue::SetPreallocatedBuffer(u32 slot, IGBPBuffer& igbp_buffer) {
741 764
742u32 BufferQueue::DequeueBuffer(u32 pixel_format, u32 width, u32 height) { 765u32 BufferQueue::DequeueBuffer(u32 pixel_format, u32 width, u32 height) {
743 auto itr = std::find_if(queue.begin(), queue.end(), [&](const Buffer& buffer) { 766 auto itr = std::find_if(queue.begin(), queue.end(), [&](const Buffer& buffer) {
744 // Only consider enqueued buffers 767 // Only consider free buffers. Buffers become free once again after they've been Acquired
745 if (buffer.status != Buffer::Status::Queued) 768 // and Released by the compositor, see the NVFlinger::Compose method.
769 if (buffer.status != Buffer::Status::Free)
746 return false; 770 return false;
747 771
748 // Make sure that the parameters match. 772 // Make sure that the parameters match.
@@ -772,6 +796,24 @@ void BufferQueue::QueueBuffer(u32 slot) {
772 itr->status = Buffer::Status::Queued; 796 itr->status = Buffer::Status::Queued;
773} 797}
774 798
799boost::optional<const BufferQueue::Buffer&> BufferQueue::AcquireBuffer() {
800 auto itr = std::find_if(queue.begin(), queue.end(), [](const Buffer& buffer) {
801 return buffer.status == Buffer::Status::Queued;
802 });
803 if (itr == queue.end())
804 return boost::none;
805 itr->status = Buffer::Status::Acquired;
806 return *itr;
807}
808
809void BufferQueue::ReleaseBuffer(u32 slot) {
810 auto itr = std::find_if(queue.begin(), queue.end(),
811 [&](const Buffer& buffer) { return buffer.slot == slot; });
812 ASSERT(itr != queue.end());
813 ASSERT(itr->status == Buffer::Status::Acquired);
814 itr->status = Buffer::Status::Free;
815}
816
775Layer::Layer(u64 id, std::shared_ptr<BufferQueue> queue) : id(id), buffer_queue(std::move(queue)) {} 817Layer::Layer(u64 id, std::shared_ptr<BufferQueue> queue) : id(id), buffer_queue(std::move(queue)) {}
776 818
777Display::Display(u64 id, std::string name) : id(id), name(std::move(name)) { 819Display::Display(u64 id, std::string name) : id(id), name(std::move(name)) {
diff --git a/src/core/hle/service/vi/vi.h b/src/core/hle/service/vi/vi.h
index 1bd8f7472..576c4ce32 100644
--- a/src/core/hle/service/vi/vi.h
+++ b/src/core/hle/service/vi/vi.h
@@ -5,6 +5,7 @@
5#pragma once 5#pragma once
6 6
7#include <memory> 7#include <memory>
8#include <boost/optional.hpp>
8#include "core/hle/kernel/event.h" 9#include "core/hle/kernel/event.h"
9#include "core/hle/service/service.h" 10#include "core/hle/service/service.h"
10 11
@@ -34,10 +35,20 @@ public:
34 BufferQueue(u32 id, u64 layer_id); 35 BufferQueue(u32 id, u64 layer_id);
35 ~BufferQueue() = default; 36 ~BufferQueue() = default;
36 37
38 struct Buffer {
39 enum class Status { Free = 0, Queued = 1, Dequeued = 2, Acquired = 3 };
40
41 u32 slot;
42 Status status = Status::Free;
43 IGBPBuffer igbp_buffer;
44 };
45
37 void SetPreallocatedBuffer(u32 slot, IGBPBuffer& buffer); 46 void SetPreallocatedBuffer(u32 slot, IGBPBuffer& buffer);
38 u32 DequeueBuffer(u32 pixel_format, u32 width, u32 height); 47 u32 DequeueBuffer(u32 pixel_format, u32 width, u32 height);
39 const IGBPBuffer& RequestBuffer(u32 slot) const; 48 const IGBPBuffer& RequestBuffer(u32 slot) const;
40 void QueueBuffer(u32 slot); 49 void QueueBuffer(u32 slot);
50 boost::optional<const Buffer&> AcquireBuffer();
51 void ReleaseBuffer(u32 slot);
41 52
42 u32 GetId() const { 53 u32 GetId() const {
43 return id; 54 return id;
@@ -47,14 +58,6 @@ private:
47 u32 id; 58 u32 id;
48 u64 layer_id; 59 u64 layer_id;
49 60
50 struct Buffer {
51 enum class Status { None = 0, Queued = 1, Dequeued = 2 };
52
53 u32 slot;
54 Status status = Status::None;
55 IGBPBuffer igbp_buffer;
56 };
57
58 std::vector<Buffer> queue; 61 std::vector<Buffer> queue;
59}; 62};
60 63