Work on making the kernel thread-safe #1 + add asynchronous ROM scanning

This commit makes the kernel thread safe in some instances (but not fully) and showcases the significantly improved performance over the ptrace method used prior. In addition, scanning for ROMs is now done asynchronously.
This commit is contained in:
◱ PixelyIon
2020-01-09 07:07:54 +05:30
committed by ◱ PixelyIon
parent 970dde8c27
commit de6d8d8f48
21 changed files with 804 additions and 157 deletions

View File

@ -49,25 +49,22 @@ namespace skyline::gpu {
state.logger->Debug("RequestBuffer: Slot: {}", slot, sizeof(GbpBuffer));
}
bool BufferQueue::DequeueBuffer(Parcel &in, Parcel &out, kernel::ipc::OutputBuffer& buffer) {
void BufferQueue::DequeueBuffer(Parcel &in, Parcel &out) {
auto *data = reinterpret_cast<DequeueIn *>(in.data.data() + constant::TokenLength);
i64 slot{-1};
for (auto &buffer : queue) {
if (buffer.second->status == BufferStatus::Free && buffer.second->resolution.width == data->width && buffer.second->resolution.height == data->height && buffer.second->gbpBuffer.usage == data->usage) {
slot = buffer.first;
buffer.second->status = BufferStatus::Dequeued;
while(slot == -1) {
for (auto &buffer : queue) {
if (buffer.second->status == BufferStatus::Free && buffer.second->resolution.width == data->width && buffer.second->resolution.height == data->height && buffer.second->gbpBuffer.usage == data->usage) {
slot = buffer.first;
buffer.second->status = BufferStatus::Dequeued;
break;
}
}
}
if (slot == -1) {
state.thread->Sleep();
waitVec.emplace_back(state.thread, *data, buffer);
state.logger->Debug("DequeueBuffer: Width: {}, Height: {}, Format: {}, Usage: {}, Timestamps: {}, No Free Buffers", data->width, data->height, data->format, data->usage, data->timestamps);
return true;
sched_yield();
}
DequeueOut output(static_cast<u32>(slot));
out.WriteData(output);
state.logger->Debug("DequeueBuffer: Width: {}, Height: {}, Format: {}, Usage: {}, Timestamps: {}, Slot: {}", data->width, data->height, data->format, data->usage, data->timestamps, slot);
return false;
}
void BufferQueue::QueueBuffer(Parcel &in, Parcel &out) {
@ -85,6 +82,7 @@ namespace skyline::gpu {
} *data = reinterpret_cast<Data *>(in.data.data() + constant::TokenLength);
auto buffer = queue.at(data->slot);
buffer->status = BufferStatus::Queued;
buffer->UpdateBuffer();
displayQueue.emplace(buffer);
state.gpu->bufferEvent->Signal();
struct {

View File

@ -106,6 +106,7 @@ namespace skyline::gpu {
GbpBuffer gbpBuffer; //!< The information about the underlying buffer
BufferStatus status{BufferStatus::Free}; //!< The status of this buffer
std::vector<u8> dataBuffer; //!< The vector holding the actual pixel data
std::vector<u8> swizzBuffer; //!< The vector holding the swizzled pixel data
std::shared_ptr<device::NvMap::NvMapObject> nvBuffer{}; //!< A shared pointer to the buffer's nvmap object
/**
@ -187,10 +188,8 @@ namespace skyline::gpu {
/**
* @brief This returns the slot of a free buffer
* @param buffer The output parcel buffer
* @return If the process is waiting for a buffer or not
*/
bool DequeueBuffer(Parcel &in, Parcel &out, kernel::ipc::OutputBuffer& buffer);
void DequeueBuffer(Parcel &in, Parcel &out);
/**
* @brief This queues a buffer to be displayed