Merge pull request #20385 from hrydgard/android-shortcut-fix

Android shortcut fix
This commit is contained in:
Henrik Rydgård authored and GitHub committed 2025-05-22 09:24:41 +02:00
commit d782382f28
11 files changed
+95 -27

No files matched your search

+4 -6
View File
@@ -1301,7 +1301,7 @@ bool VulkanContext::ChooseQueue() {
// Okay, take the first one then.
swapchainFormat_ = surfFormats_[0].format;
}
INFO_LOG(Log::G3D, "swapchain_format: %d (/%d)", swapchainFormat_, formatCount);
INFO_LOG(Log::G3D, "swapchain_format: %s (%d) (/%d)", VulkanFormatToString(swapchainFormat_), (int)swapchainFormat_, formatCount);
}
vkGetDeviceQueue(device_, graphics_queue_family_index_, 0, &gfx_queue_);
@@ -1388,7 +1388,6 @@ bool VulkanContext::InitSwapchain() {
availablePresentModes_.push_back(presentModes[i]);
}
INFO_LOG(Log::G3D, "Supported present modes: %s", modes.c_str());
for (size_t i = 0; i < presentModeCount; i++) {
bool match = false;
match = match || ((flags_ & VulkanInitFlags::PRESENT_MAILBOX) && presentModes[i] == VK_PRESENT_MODE_MAILBOX_KHR);
@@ -1415,8 +1414,8 @@ bool VulkanContext::InitSwapchain() {
desiredNumberOfSwapChainImages = surfCapabilities_.maxImageCount;
}
INFO_LOG(Log::G3D, "Chosen present mode: %d (%s). numSwapChainImages: %d (max: %d)",
swapchainPresentMode, VulkanPresentModeToString(swapchainPresentMode),
INFO_LOG(Log::G3D, "Supported present modes: %s. Chosen present mode: %d (%s). numSwapChainImages: %d (max: %d)",
modes.c_str(), swapchainPresentMode, VulkanPresentModeToString(swapchainPresentMode),
desiredNumberOfSwapChainImages, surfCapabilities_.maxImageCount);
// We mostly follow the practices from
@@ -1503,7 +1502,6 @@ bool VulkanContext::InitSwapchain() {
// We don't support screenshots on Android if TRANSFER_SRC usage flag is not supported.
if (surfCapabilities_.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) {
INFO_LOG(Log::G3D, "Swapchain supports TRANSFER_SRC");
swap_chain_info.imageUsage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
}
@@ -1523,7 +1521,7 @@ bool VulkanContext::InitSwapchain() {
ERROR_LOG(Log::G3D, "vkCreateSwapchainKHR failed!");
return false;
}
INFO_LOG(Log::G3D, "Created swapchain: %dx%d", swap_chain_info.imageExtent.width, swap_chain_info.imageExtent.height);
INFO_LOG(Log::G3D, "Created swapchain: %dx%d %s", swap_chain_info.imageExtent.width, swap_chain_info.imageExtent.height, (surfCapabilities_.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) ? "(TRANSFER_SRC_BIT supported)" : "");
return true;
}
-2
View File
@@ -893,8 +893,6 @@ VKContext::VKContext(VulkanContext *vulkan, bool useRenderThread)
: vulkan_(vulkan), renderManager_(vulkan, useRenderThread, frameTimeHistory_) {
shaderLanguageDesc_.Init(GLSL_VULKAN);
INFO_LOG(Log::G3D, "Determining Vulkan device caps");
caps_.coordConvention = CoordConvention::Vulkan;
caps_.setMaxFrameLatencySupported = true;
caps_.anisoSupported = vulkan->GetDeviceFeatures().enabled.standard.samplerAnisotropy != 0;
+33
View File
@@ -44,15 +44,22 @@ ScreenManager::~ScreenManager() {
void ScreenManager::switchScreen(Screen *screen) {
// TODO: inputLock_ ?
INFO_LOG(Log::UI, "ScreenManager::switchScreen('%s')", screen->tag());
if (!nextStack_.empty() && screen == nextStack_.front().screen) {
ERROR_LOG(Log::UI, "Already switching to this screen");
return;
}
// Note that if a dialog is found, this will be a silent background switch that
// will only become apparent if the dialog is closed. The previous screen will stick around
// until that switch.
// TODO: is this still true?
if (!nextStack_.empty()) {
for (int i = 0; i < nextStack_.size(); i++) {
INFO_LOG(Log::UI, "NextStack contents[%d].screen->tag(): '%s'", i, nextStack_[i].screen->tag());
}
ERROR_LOG(Log::UI, "Already had a nextStack_! Asynchronous open while doing something? Deleting the new screen.");
delete screen;
return;
@@ -68,12 +75,38 @@ void ScreenManager::switchScreen(Screen *screen) {
}
}
void ScreenManager::cancelScreensAbove(Screen *screen) {
bool found = false;
for (int i = 0; i < stack_.size(); i++) {
if (stack_[i].screen == screen) {
found = true;
}
}
if (found) {
cancelScreensAbove_ = screen;
}
}
void ScreenManager::update() {
std::lock_guard<std::recursive_mutex> guard(inputLock_);
if (!nextStack_.empty()) {
switchToNext();
}
if (cancelScreensAbove_) {
bool found = false;
for (int i = stack_.size() - 1; i >= 0; i--) {
if (stack_[i].screen == cancelScreensAbove_) {
break;
}
Layer temp = stack_.back();
stack_.pop_back();
delete temp.screen;
}
cancelScreensAbove_ = nullptr;
}
if (overlayScreen_) {
// NOTE: This is not a full UIScreen update, to avoid double global event processing.
overlayScreen_->update();
+4
View File
@@ -177,6 +177,8 @@ public:
return stack_.empty() ? nullptr : stack_.back().screen;
}
void cancelScreensAbove(Screen *screen);
void getFocusPosition(float &x, float &y, float &z);
// Will delete any existing overlay screen.
@@ -201,6 +203,8 @@ private:
Screen *backgroundScreen_ = nullptr;
Screen *overlayScreen_ = nullptr;
Screen *cancelScreensAbove_ = nullptr;
struct Layer {
Screen *screen;
int flags; // From LAYER_ enum above
+1 -1
View File
@@ -111,7 +111,7 @@ void GPU_Vulkan::LoadCache(const Path &filename) {
// First compile shaders to SPIR-V, then load the pipeline cache and recreate the pipelines.
// It's when recreating the pipelines that the pipeline cache is useful - in the ideal case,
// it can just memcpy the finished shader binaries out of the pipeline cache file.
bool result = shaderManagerVulkan_->LoadCacheFlags(f, &drawEngine_);
bool result = ShaderManagerVulkan::LoadCacheFlags(f, &drawEngine_);
if (!result) {
WARN_LOG(Log::G3D, "ShaderManagerVulkan failed to load cache header.");
}
+16 -4
View File
@@ -551,6 +551,8 @@ void EmuScreen::sendMessage(UIMessage message, const char *value) {
return;
}
} else if (message == UIMessage::REQUEST_GAME_BOOT) {
INFO_LOG(Log::Loader, "EmuScreen received REQUEST_GAME_BOOT: %s", value);
if (bootPending_) {
ERROR_LOG(Log::Loader, "Can't boot a new game during a pending boot");
return;
@@ -560,17 +562,27 @@ void EmuScreen::sendMessage(UIMessage message, const char *value) {
WARN_LOG(Log::Loader, "Game already running, ignoring");
return;
}
const char *ext = strrchr(value, '.');
if (ext != nullptr && !strcmp(ext, ".ppst")) {
SaveState::Load(Path(value), -1, [](SaveState::Status status, std::string_view message) {
// TODO: Create a path first and
Path newGamePath(value);
if (newGamePath.GetFileExtension() == ".ppst") {
// TODO: Should verify that it's for the correct game....
INFO_LOG(Log::Loader, "New game is a save state - just load it.");
SaveState::Load(newGamePath, -1, [](SaveState::Status status, std::string_view message) {
Core_Resume();
System_Notify(SystemNotification::DISASSEMBLY);
});
} else {
PSP_Shutdown(true);
Achievements::UnloadGame();
// OK, now pop any open settings screens and stuff that are running above us.
// Otherwise, we can get strange results with game-specific settings.
screenManager()->cancelScreensAbove(this);
bootPending_ = true;
gamePath_ = Path(value);
gamePath_ = newGamePath;
}
} else if (message == UIMessage::CONFIG_LOADED) {
// In case we need to position touch controls differently.
+3 -1
View File
@@ -643,6 +643,7 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch
fprintf(stderr, "File not found: %s\n", boot_filename.c_str());
#if defined(_WIN32) || defined(__ANDROID__)
// Ignore and proceed.
boot_filename.clear();
#else
// Bail.
exit(1);
@@ -756,7 +757,8 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch
} else if (gotoDeveloperTools) {
g_screenManager->switchScreen(new MainScreen());
g_screenManager->push(new DeveloperToolsScreen(Path()));
} else if (skipLogo) {
} else if (skipLogo && !boot_filename.empty()) {
INFO_LOG(Log::System, "Launching EmuScreen with boot filename '%s'", boot_filename.c_str());
g_screenManager->switchScreen(new EmuScreen(boot_filename));
} else {
g_screenManager->switchScreen(new LogoScreen(AfterLogoScreen::DEFAULT));
+1
View File
@@ -53,6 +53,7 @@
android:name=".PpssppActivity"
android:configChanges="locale|keyboard|keyboardHidden|navigation|uiMode"
android:theme="@style/ppsspp_style"
android:launchMode="singleInstance"
android:exported="true">
<!-- android:screenOrientation="landscape" -->
<intent-filter>
@@ -977,7 +977,7 @@ public abstract class NativeActivity extends Activity {
buffer += input.getDebugString();
}
if (buffer.isEmpty()) {
buffer = "(no devices)";
return "(no devices)";
}
return buffer;
} else {
@@ -85,30 +85,46 @@ public class PpssppActivity extends NativeActivity {
// In case app launched from homescreen shortcut, get shortcut parameter
// using Intent extra string. Intent extra will be null if launch normal
// (from app drawer or file explorer).
Intent intent = getIntent();
String param = parseIntent(getIntent());
if (param != null) {
Log.i(TAG, "Found Shortcut Parameter in data, passing on: " + param);
super.setShortcutParam(param);
}
super.onCreate(savedInstanceState);
}
private static String parseIntent(Intent intent) {
// String action = intent.getAction();
Uri data = intent.getData();
if (data != null) {
String path = data.toString();
Log.i(TAG, "Found Shortcut Parameter in data: " + path);
String escaped = "\"" + path.replace("\\", "\\\\").replace("\"", "\\\"") + "\"";
Log.i(TAG, "Escaped: " + escaped);
super.setShortcutParam(escaped);
// Do some unescaping. Not really sure why needed.
return "\"" + path.replace("\\", "\\\\").replace("\"", "\\\"") + "\"";
// Toast.makeText(getApplicationContext(), path, Toast.LENGTH_SHORT).show();
} else {
String param = getIntent().getStringExtra(SHORTCUT_EXTRA_KEY);
String args = getIntent().getStringExtra(ARGS_EXTRA_KEY);
String param = intent.getStringExtra(SHORTCUT_EXTRA_KEY);
String args = intent.getStringExtra(ARGS_EXTRA_KEY);
if (param != null) {
Log.i(TAG, "Found Shortcut Parameter in extra-data: " + param);
super.setShortcutParam("\"" + param.replace("\\", "\\\\").replace("\"", "\\\"") + "\"");
return "\"" + param.replace("\\", "\\\\").replace("\"", "\\\"") + "\"";
} else if (args != null) {
Log.i(TAG, "Found args parameter in extra-data: " + args);
super.setShortcutParam(args);
return args;
} else {
super.setShortcutParam("");
return null;
}
}
super.onCreate(savedInstanceState);
}
@Override
public void onNewIntent(Intent intent) {
String value = parseIntent(intent);
if (value != null) {
// TODO: Actually send a command to the native code to launch the new game.
Log.i(TAG, "NEW INTENT AT RUNTIME: " + value);
Log.i(TAG, "Posting a 'shortcutParam' message to the C++ code.");
NativeApp.sendMessageFromJava("shortcutParam", value);
}
}
// called by the C++ code through JNI. Dispatch anything we can't directly handle
@@ -100,7 +100,11 @@ public class SizeManager implements SurfaceHolder.Callback {
getDesiredBackbufferSize(desiredSize);
// Note that desiredSize might be 0,0 here - but that's fine when calling setFixedSize! It means auto.
Log.d(TAG, "Setting fixed size " + desiredSize.x + " x " + desiredSize.y);
if (desiredSize.x == 0) {
Log.d(TAG, "Setting auto surface size (not fixed)");
} else {
Log.d(TAG, "Setting fixed surface size " + desiredSize.x + " x " + desiredSize.y);
}
holder.setFixedSize(desiredSize.x, desiredSize.y);
}