diff --git a/.gitmodules b/.gitmodules index c8fcad98ec..10f9f7de96 100644 --- a/.gitmodules +++ b/.gitmodules @@ -19,9 +19,6 @@ [submodule "cpp-httplib"] path = externals/cpp-httplib url = https://github.com/yhirose/cpp-httplib.git -[submodule "ffmpeg"] - path = externals/ffmpeg/ffmpeg - url = https://github.com/FFmpeg/FFmpeg.git [submodule "vcpkg"] path = externals/vcpkg url = https://github.com/microsoft/vcpkg.git diff --git a/CMakeLists.txt b/CMakeLists.txt index b9d19b3c1b..0c2a880ae0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -491,6 +491,8 @@ set(FFmpeg_COMPONENTS avutil swscale) +set(CPM_SOURCE_CACHE ${CMAKE_SOURCE_DIR}/.cache/cpm) + add_subdirectory(externals) if (ENABLE_QT) diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt index cdb0c0bb5b..cd7b80a33c 100644 --- a/externals/CMakeLists.txt +++ b/externals/CMakeLists.txt @@ -84,17 +84,22 @@ if (YUZU_USE_EXTERNAL_SDL2) endif() include(CPM) - set(CPM_SOURCE_CACHE ${CMAKE_SOURCE_DIR}/.cache/cpm) set(CPM_USE_LOCAL_PACKAGES OFF) if ("${YUZU_SYSTEM_PROFILE}" STREQUAL "steamdeck") set(SDL_HASH cc016b0046) set(SDL_PIPEWIRE OFF) # build errors out with this on + set(SDL_SHA512SUM 34d5ef58da6a4f9efa6689c82f67badcbd741f5a4f562a9c2c30828fa839830fb07681c5dc6a7851520e261c8405a416ac0a2c2513b51984fb3b4fa4dcb3e20b) else() set(SDL_HASH 2e4c12cd2c) + set(SDL_SHA512SUM d95af47f469a312876f8ab361074a1e7b8083db19935a102d9c6e5887ace6008e64475a8c54b00164b40cad86492bb1b2366084efdd0b2555e5fea6d9c5da80e) endif() - CPMAddPackage("gh:libsdl-org/SDL#${SDL_HASH}") + CPMAddPackage( + NAME SDL2 + URL "https://github.com/libsdl-org/SDL/archive/${SDL_HASH}.zip" + URL_HASH SHA512=${SDL_SHA512SUM} + ) endif() # ENet diff --git a/externals/ffmpeg/CMakeLists.txt b/externals/ffmpeg/CMakeLists.txt index 9eb71418a0..3222efba70 100644 --- a/externals/ffmpeg/CMakeLists.txt +++ b/externals/ffmpeg/CMakeLists.txt @@ -19,8 +19,17 @@ if (NOT WIN32 AND NOT ANDROID) message(FATAL_ERROR "Required program `autoconf` not found.") endif() - set(FFmpeg_PREFIX ${PROJECT_SOURCE_DIR}/externals/ffmpeg/ffmpeg) - set(FFmpeg_BUILD_DIR ${PROJECT_BINARY_DIR}/externals/ffmpeg-build) + include(CPM) + set(CPM_USE_LOCAL_PACKAGES OFF) + + CPMAddPackage( + NAME ffmpeg + URL "https://github.com/ffmpeg/ffmpeg/archive/9c1294eadd.zip" + URL_HASH SHA512=2076e4cb843787c44718c70c4452517273dbc963ef98442f343762ade6c7b9f78555ae9b50a7c628844a15d8cb5e866c04e2f1acfb77093cea4fbc9edf3ad21a + ) + + set(FFmpeg_PREFIX ${ffmpeg_SOURCE_DIR}) + set(FFmpeg_BUILD_DIR ${ffmpeg_BINARY_DIR}) set(FFmpeg_MAKEFILE ${FFmpeg_BUILD_DIR}/Makefile) make_directory(${FFmpeg_BUILD_DIR}) diff --git a/externals/ffmpeg/ffmpeg b/externals/ffmpeg/ffmpeg deleted file mode 160000 index 9c1294eadd..0000000000 --- a/externals/ffmpeg/ffmpeg +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 9c1294eaddb88cb0e044c675ccae059a85fc9c6c diff --git a/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp b/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp index 4317aee1c4..1bb88a45fa 100644 --- a/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp +++ b/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp @@ -728,22 +728,26 @@ Status BufferQueueProducer::Connect(const std::shared_ptr& li return status; } +// https://android.googlesource.com/platform/frameworks/native/%2B/master/libs/gui/BufferQueueProducer.cpp#1457 Status BufferQueueProducer::Disconnect(NativeWindowApi api) { - LOG_DEBUG(Service_Nvnflinger, "api = {}", api); + LOG_DEBUG(Service_Nvnflinger, "disconnect api = {}", api); - Status status = Status::NoError; std::shared_ptr listener; + Status status = Status::NoError; { std::scoped_lock lock{core->mutex}; - core->WaitWhileAllocatingLocked(); if (core->is_abandoned) { - // Disconnecting after the surface has been abandoned is a no-op. return Status::NoError; } + if (core->connected_api == NativeWindowApi::NoConnectedApi) { + LOG_DEBUG(Service_Nvnflinger, "disconnect: not connected (req = {})", api); + return Status::NoInit; + } + switch (api) { case NativeWindowApi::Egl: case NativeWindowApi::Cpu: @@ -758,20 +762,20 @@ Status BufferQueueProducer::Disconnect(NativeWindowApi api) { buffer_wait_event->Signal(); listener = core->consumer_listener; } else { - LOG_ERROR(Service_Nvnflinger, "still connected to another api (cur = {} req = {})", + LOG_ERROR(Service_Nvnflinger, + "disconnect: still connected to another api (cur = {} req = {})", core->connected_api, api); status = Status::BadValue; } break; default: - LOG_ERROR(Service_Nvnflinger, "unknown api = {}", api); + LOG_ERROR(Service_Nvnflinger, "disconnect: unknown api = {}", api); status = Status::BadValue; break; } } - // Call back without lock held - if (listener != nullptr) { + if (listener) { listener->OnBuffersReleased(); } diff --git a/src/core/hle/service/nvnflinger/hos_binder_driver.cpp b/src/core/hle/service/nvnflinger/hos_binder_driver.cpp index 8629a2e89b..d30aa3717d 100644 --- a/src/core/hle/service/nvnflinger/hos_binder_driver.cpp +++ b/src/core/hle/service/nvnflinger/hos_binder_driver.cpp @@ -40,17 +40,22 @@ Result IHOSBinderDriver::TransactParcel(s32 binder_id, u32 transaction_id, } Result IHOSBinderDriver::AdjustRefcount(s32 binder_id, s32 addval, s32 type) { - LOG_WARNING(Service_VI, "(STUBBED) called id={}, addval={}, type={}", binder_id, addval, type); + LOG_DEBUG(Service_VI, "called id={}, addval={}, type={}", binder_id, addval, type); + R_UNLESS(type == 0 || type == 1, ResultUnknown); + m_server->AdjustRefcount(binder_id, addval, type == 1); R_SUCCEED(); } Result IHOSBinderDriver::GetNativeHandle(s32 binder_id, u32 type_id, OutCopyHandle out_handle) { - LOG_WARNING(Service_VI, "(STUBBED) called id={}, type_id={}", binder_id, type_id); + LOG_DEBUG(Service_VI, "called id={}, type_id={}", binder_id, type_id); const auto binder = m_server->TryGetBinder(binder_id); R_UNLESS(binder != nullptr, ResultUnknown); + auto native_handle = binder->GetNativeHandle(type_id); + R_UNLESS(native_handle != nullptr, ResultUnknown); + *out_handle = binder->GetNativeHandle(type_id); R_SUCCEED(); diff --git a/src/core/hle/service/nvnflinger/hos_binder_driver_server.cpp b/src/core/hle/service/nvnflinger/hos_binder_driver_server.cpp index 29addda44d..b85f1a4fa4 100644 --- a/src/core/hle/service/nvnflinger/hos_binder_driver_server.cpp +++ b/src/core/hle/service/nvnflinger/hos_binder_driver_server.cpp @@ -17,6 +17,7 @@ s32 HosBinderDriverServer::RegisterBinder(std::shared_ptr&& bi last_id++; binders[last_id] = std::move(binder); + refcounts[last_id] = {}; // strong = 1, weak = 0 return last_id; } @@ -25,6 +26,29 @@ void HosBinderDriverServer::UnregisterBinder(s32 binder_id) { std::scoped_lock lk{lock}; binders.erase(binder_id); + refcounts.erase(binder_id); +} + +void HosBinderDriverServer::AdjustRefcount(s32 binder_id, s32 delta, bool is_weak) { + std::scoped_lock lk{lock}; + + auto search_rc = refcounts.find(binder_id); + if (search_rc == refcounts.end()) { + LOG_WARNING(Service_VI, "AdjustRefcount called for unknown binder id {}", binder_id); + return; + } + + auto& rc = search_rc->second; + s32& counter = is_weak ? rc.weak : rc.strong; + counter += delta; + + if (counter < 0) + counter = 0; + + if (rc.strong == 0 && rc.weak == 0) { + binders.erase(binder_id); + refcounts.erase(search_rc); + } } std::shared_ptr HosBinderDriverServer::TryGetBinder(s32 id) const { diff --git a/src/core/hle/service/nvnflinger/hos_binder_driver_server.h b/src/core/hle/service/nvnflinger/hos_binder_driver_server.h index d72b50833d..f4b4060115 100644 --- a/src/core/hle/service/nvnflinger/hos_binder_driver_server.h +++ b/src/core/hle/service/nvnflinger/hos_binder_driver_server.h @@ -26,10 +26,18 @@ public: std::shared_ptr TryGetBinder(s32 id) const; + void AdjustRefcount(s32 binder_id, s32 delta, bool is_weak); + private: - std::unordered_map> binders; + struct RefCounts { + s32 strong{1}; + s32 weak{0}; + }; + mutable std::mutex lock; - s32 last_id{}; + s32 last_id = 0; + std::unordered_map> binders; + std::unordered_map refcounts; }; } // namespace Service::Nvnflinger diff --git a/src/video_core/vulkan_common/vulkan_wrapper.cpp b/src/video_core/vulkan_common/vulkan_wrapper.cpp index c05e21a2c8..5d80531b47 100644 --- a/src/video_core/vulkan_common/vulkan_wrapper.cpp +++ b/src/video_core/vulkan_common/vulkan_wrapper.cpp @@ -440,13 +440,14 @@ Instance Instance::Create(u32 version, Span layers, Span