mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-29 13:18:36 +01:00
Merge pull request #13221 from hrydgard/android-minor-cleanup
Android: Various minor cleanup
This commit is contained in:
18 files changed
+270
-201
No files matched your search
+4
-4
@@ -730,10 +730,10 @@ if(ANDROID)
|
||||
android/jni/AndroidVulkanContext.cpp
|
||||
android/jni/AndroidVulkanContext.h
|
||||
android/jni/AndroidGraphicsContext.h
|
||||
android/jni/native_audio.cpp
|
||||
android/jni/native_audio.h
|
||||
android/jni/native-audio-so.cpp
|
||||
android/jni/native-audio-so.h
|
||||
android/jni/AndroidAudio.cpp
|
||||
android/jni/AndroidAudio.h
|
||||
android/jni/OpenSLContext.cpp
|
||||
android/jni/OpenSLContext.h
|
||||
)
|
||||
# No target
|
||||
elseif(IOS)
|
||||
|
||||
+58
-47
@@ -255,8 +255,6 @@ std::string NativeQueryConfig(std::string query) {
|
||||
int max_res = std::max(System_GetPropertyInt(SYSPROP_DISPLAY_XRES), System_GetPropertyInt(SYSPROP_DISPLAY_YRES)) / 480 + 1;
|
||||
snprintf(temp, sizeof(temp), "%d", std::min(scale, max_res));
|
||||
return std::string(temp);
|
||||
} else if (query == "force44khz") {
|
||||
return std::string("0");
|
||||
} else if (query == "androidJavaGL") {
|
||||
// If we're using Vulkan, we say no... need C++ to use Vulkan.
|
||||
if (GetGPUBackend() == GPUBackend::VULKAN) {
|
||||
@@ -805,29 +803,34 @@ static void UIThemeInit() {
|
||||
}
|
||||
|
||||
void RenderOverlays(UIContext *dc, void *userdata);
|
||||
bool CreateGlobalPipelines();
|
||||
|
||||
bool NativeInitGraphics(GraphicsContext *graphicsContext) {
|
||||
ILOG("NativeInitGraphics");
|
||||
_assert_msg_(graphicsContext, "No graphics context!");
|
||||
|
||||
// We set this now so any resize during init is processed later.
|
||||
resized = false;
|
||||
|
||||
using namespace Draw;
|
||||
Core_SetGraphicsContext(graphicsContext);
|
||||
g_draw = graphicsContext->GetDrawContext();
|
||||
_assert_msg_(g_draw, "No draw context available!");
|
||||
_assert_msg_(g_draw->GetVshaderPreset(VS_COLOR_2D) != nullptr, "Failed to compile presets");
|
||||
|
||||
if (!CreateGlobalPipelines()) {
|
||||
ERROR_LOG(G3D, "Failed to create global pipelines");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Load the atlas.
|
||||
|
||||
size_t atlas_data_size = 0;
|
||||
if (!g_ui_atlas.IsMetadataLoaded()) {
|
||||
const uint8_t *atlas_data = VFSReadFile("ui_atlas.meta", &atlas_data_size);
|
||||
bool load_success = atlas_data != nullptr && g_ui_atlas.Load(atlas_data, atlas_data_size);
|
||||
_assert_msg_(load_success, "Failed to load ui_atlas.meta");
|
||||
if (!load_success) {
|
||||
ERROR_LOG(G3D, "Failed to load ui_atlas.meta - graphics will be broken.");
|
||||
// Stumble along with broken visuals instead of dying.
|
||||
}
|
||||
delete[] atlas_data;
|
||||
}
|
||||
|
||||
ui_draw2d.SetAtlas(&g_ui_atlas);
|
||||
ui_draw2d_front.SetAtlas(&g_ui_atlas);
|
||||
|
||||
@@ -836,43 +839,10 @@ bool NativeInitGraphics(GraphicsContext *graphicsContext) {
|
||||
uiContext = new UIContext();
|
||||
uiContext->theme = &ui_theme;
|
||||
|
||||
Draw::InputLayout *inputLayout = ui_draw2d.CreateInputLayout(g_draw);
|
||||
Draw::BlendState *blendNormal = g_draw->CreateBlendState({ true, 0xF, BlendFactor::SRC_ALPHA, BlendFactor::ONE_MINUS_SRC_ALPHA });
|
||||
Draw::DepthStencilState *depth = g_draw->CreateDepthStencilState({ false, false, Comparison::LESS });
|
||||
Draw::RasterState *rasterNoCull = g_draw->CreateRasterState({});
|
||||
|
||||
PipelineDesc colorDesc{
|
||||
Primitive::TRIANGLE_LIST,
|
||||
{ g_draw->GetVshaderPreset(VS_COLOR_2D), g_draw->GetFshaderPreset(FS_COLOR_2D) },
|
||||
inputLayout, depth, blendNormal, rasterNoCull, &vsColBufDesc,
|
||||
};
|
||||
PipelineDesc texColorDesc{
|
||||
Primitive::TRIANGLE_LIST,
|
||||
{ g_draw->GetVshaderPreset(VS_TEXTURE_COLOR_2D), g_draw->GetFshaderPreset(FS_TEXTURE_COLOR_2D) },
|
||||
inputLayout, depth, blendNormal, rasterNoCull, &vsTexColBufDesc,
|
||||
};
|
||||
|
||||
colorPipeline = g_draw->CreateGraphicsPipeline(colorDesc);
|
||||
texColorPipeline = g_draw->CreateGraphicsPipeline(texColorDesc);
|
||||
|
||||
_assert_(colorPipeline);
|
||||
_assert_(texColorPipeline);
|
||||
|
||||
// Release these now, reference counting should ensure that they get completely released
|
||||
// once we delete both pipelines.
|
||||
inputLayout->Release();
|
||||
rasterNoCull->Release();
|
||||
blendNormal->Release();
|
||||
depth->Release();
|
||||
|
||||
ui_draw2d.Init(g_draw, texColorPipeline);
|
||||
ui_draw2d_front.Init(g_draw, texColorPipeline);
|
||||
|
||||
uiContext->Init(g_draw, texColorPipeline, colorPipeline, &ui_draw2d, &ui_draw2d_front);
|
||||
RasterStateDesc desc;
|
||||
desc.cull = CullMode::NONE;
|
||||
desc.frontFace = Facing::CCW;
|
||||
|
||||
if (uiContext->Text())
|
||||
uiContext->Text()->SetFont("Tahoma", 20, 0);
|
||||
|
||||
@@ -899,13 +869,54 @@ bool NativeInitGraphics(GraphicsContext *graphicsContext) {
|
||||
|
||||
g_gameInfoCache = new GameInfoCache();
|
||||
|
||||
if (gpu)
|
||||
if (gpu) {
|
||||
gpu->DeviceRestore();
|
||||
}
|
||||
|
||||
ILOG("NativeInitGraphics completed");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CreateGlobalPipelines() {
|
||||
using namespace Draw;
|
||||
|
||||
InputLayout *inputLayout = ui_draw2d.CreateInputLayout(g_draw);
|
||||
BlendState *blendNormal = g_draw->CreateBlendState({ true, 0xF, BlendFactor::SRC_ALPHA, BlendFactor::ONE_MINUS_SRC_ALPHA });
|
||||
DepthStencilState *depth = g_draw->CreateDepthStencilState({ false, false, Comparison::LESS });
|
||||
RasterState *rasterNoCull = g_draw->CreateRasterState({});
|
||||
|
||||
PipelineDesc colorDesc{
|
||||
Primitive::TRIANGLE_LIST,
|
||||
{ g_draw->GetVshaderPreset(VS_COLOR_2D), g_draw->GetFshaderPreset(FS_COLOR_2D) },
|
||||
inputLayout, depth, blendNormal, rasterNoCull, &vsColBufDesc,
|
||||
};
|
||||
PipelineDesc texColorDesc{
|
||||
Primitive::TRIANGLE_LIST,
|
||||
{ g_draw->GetVshaderPreset(VS_TEXTURE_COLOR_2D), g_draw->GetFshaderPreset(FS_TEXTURE_COLOR_2D) },
|
||||
inputLayout, depth, blendNormal, rasterNoCull, &vsTexColBufDesc,
|
||||
};
|
||||
|
||||
colorPipeline = g_draw->CreateGraphicsPipeline(colorDesc);
|
||||
if (!colorPipeline) {
|
||||
// Something really critical is wrong, don't care much about correct releasing of the states.
|
||||
return false;
|
||||
}
|
||||
|
||||
texColorPipeline = g_draw->CreateGraphicsPipeline(texColorDesc);
|
||||
if (!texColorPipeline) {
|
||||
// Something really critical is wrong, don't care much about correct releasing of the states.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Release these now, reference counting should ensure that they get completely released
|
||||
// once we delete both pipelines.
|
||||
inputLayout->Release();
|
||||
rasterNoCull->Release();
|
||||
blendNormal->Release();
|
||||
depth->Release();
|
||||
return true;
|
||||
}
|
||||
|
||||
void NativeShutdownGraphics() {
|
||||
screenManager->deviceLost();
|
||||
|
||||
@@ -914,12 +925,12 @@ void NativeShutdownGraphics() {
|
||||
|
||||
ILOG("NativeShutdownGraphics");
|
||||
|
||||
#ifdef _WIN32
|
||||
#if PPSSPP_PLATFORM(WINDOWS)
|
||||
delete winAudioBackend;
|
||||
winAudioBackend = nullptr;
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) && !PPSSPP_PLATFORM(UWP)
|
||||
#if PPSSPP_PLATFORM(WINDOWS) && !PPSSPP_PLATFORM(UWP)
|
||||
if (winCamera) {
|
||||
winCamera->sendMessage({ CAPTUREDEVIDE_COMMAND::SHUTDOWN, nullptr });
|
||||
while (!winCamera->isShutDown()) {};// Wait for shutting down.
|
||||
@@ -1088,7 +1099,7 @@ void NativeRender(GraphicsContext *graphicsContext) {
|
||||
screenManager->resized();
|
||||
|
||||
// TODO: Move this to the GraphicsContext objects for each backend.
|
||||
#if !defined(_WIN32) && !defined(ANDROID)
|
||||
#if !PPSSPP_PLATFORM(WINDOWS) && !defined(ANDROID)
|
||||
PSP_CoreParameter().pixelWidth = pixel_xres;
|
||||
PSP_CoreParameter().pixelHeight = pixel_yres;
|
||||
NativeMessageReceived("gpu_resized", "");
|
||||
@@ -1135,7 +1146,7 @@ void HandleGlobalMessage(const std::string &msg, const std::string &value) {
|
||||
if (msg == "core_powerSaving") {
|
||||
if (value != "false") {
|
||||
auto sy = GetI18NCategory("System");
|
||||
#ifdef __ANDROID__
|
||||
#if PPSSPP_PLATFORM(ANDROID)
|
||||
osm.Show(sy->T("WARNING: Android battery save mode is on"), 2.0f, 0xFFFFFF, -1, true, "core_powerSaving");
|
||||
#else
|
||||
osm.Show(sy->T("WARNING: Battery save mode is on"), 2.0f, 0xFFFFFF, -1, true, "core_powerSaving");
|
||||
@@ -1144,7 +1155,7 @@ void HandleGlobalMessage(const std::string &msg, const std::string &value) {
|
||||
Core_SetPowerSaving(value != "false");
|
||||
}
|
||||
if (msg == "permission_granted" && value == "storage") {
|
||||
#ifdef __ANDROID__
|
||||
#if PPSSPP_PLATFORM(ANDROID)
|
||||
CreateDirectoriesAndroid();
|
||||
#endif
|
||||
// We must have failed to load the config before, so load it now to avoid overwriting the old config
|
||||
|
||||
@@ -399,17 +399,23 @@ bool WindowsGLContext::InitFromRenderThread(std::string *error_message) {
|
||||
pauseRequested = false;
|
||||
resumeRequested = false;
|
||||
|
||||
CheckGLExtensions();
|
||||
draw_ = Draw::T3DCreateGLContext();
|
||||
bool success = draw_->CreatePresets(); // if we get this far, there will always be a GLSL compiler capable of compiling these.
|
||||
if (!success) {
|
||||
delete draw_;
|
||||
draw_ = nullptr;
|
||||
ReleaseGLContext();
|
||||
return false;
|
||||
}
|
||||
|
||||
// These are auto-reset events.
|
||||
pauseEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
resumeEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
|
||||
CheckGLExtensions();
|
||||
draw_ = Draw::T3DCreateGLContext();
|
||||
renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
|
||||
renderManager_->SetInflightFrames(g_Config.iInflightFrames);
|
||||
SetGPUBackend(GPUBackend::OPENGL);
|
||||
bool success = draw_->CreatePresets(); // if we get this far, there will always be a GLSL compiler capable of compiling these.
|
||||
_assert_msg_(success, "Failed to compile preset shaders");
|
||||
renderManager_->SetSwapFunction([&]() {::SwapBuffers(hDC); });
|
||||
if (wglSwapIntervalEXT) {
|
||||
// glew loads wglSwapIntervalEXT if available
|
||||
@@ -430,14 +436,10 @@ void WindowsGLContext::Shutdown() {
|
||||
glslang::FinalizeProcess();
|
||||
}
|
||||
|
||||
void WindowsGLContext::ShutdownFromRenderThread() {
|
||||
delete draw_;
|
||||
draw_ = nullptr;
|
||||
CloseHandle(pauseEvent);
|
||||
CloseHandle(resumeEvent);
|
||||
void WindowsGLContext::ReleaseGLContext() {
|
||||
if (hRC) {
|
||||
// Are we able to release the DC and RC contexts?
|
||||
if (!wglMakeCurrent(NULL,NULL)) {
|
||||
if (!wglMakeCurrent(NULL, NULL)) {
|
||||
MessageBox(NULL, L"Release of DC and RC failed.", L"SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
|
||||
}
|
||||
|
||||
@@ -458,6 +460,14 @@ void WindowsGLContext::ShutdownFromRenderThread() {
|
||||
hWnd_ = NULL;
|
||||
}
|
||||
|
||||
void WindowsGLContext::ShutdownFromRenderThread() {
|
||||
delete draw_;
|
||||
draw_ = nullptr;
|
||||
CloseHandle(pauseEvent);
|
||||
CloseHandle(resumeEvent);
|
||||
ReleaseGLContext();
|
||||
}
|
||||
|
||||
void WindowsGLContext::Resize() {
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,8 @@ public:
|
||||
Draw::DrawContext *GetDrawContext() override { return draw_; }
|
||||
|
||||
private:
|
||||
void ReleaseGLContext();
|
||||
|
||||
bool renderThread_;
|
||||
Draw::DrawContext *draw_;
|
||||
GLRenderManager *renderManager_;
|
||||
|
||||
@@ -600,7 +600,7 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\android\jni\native-audio-so.cpp">
|
||||
<ClCompile Include="..\android\jni\OpenSLContext.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
@@ -610,7 +610,7 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\android\jni\native_audio.cpp">
|
||||
<ClCompile Include="..\android\jni\AndroidAudio.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
@@ -1028,7 +1028,7 @@
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\android\jni\ArmEmitterTest.h" />
|
||||
<ClInclude Include="..\android\jni\Arm64EmitterTest.h" />
|
||||
<ClInclude Include="..\android\jni\native-audio-so.h">
|
||||
<ClInclude Include="..\android\jni\OpenSLContext.h">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
@@ -1038,7 +1038,7 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</ExcludedFromBuild>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\android\jni\native_audio.h">
|
||||
<ClInclude Include="..\android\jni\AndroidAudio.h">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
|
||||
@@ -205,12 +205,6 @@
|
||||
<ClCompile Include="..\android\jni\app-android.cpp">
|
||||
<Filter>Other Platforms\Android</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\android\jni\native_audio.cpp">
|
||||
<Filter>Other Platforms\Android</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\android\jni\native-audio-so.cpp">
|
||||
<Filter>Other Platforms\Android</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\ios\SmartKeyboardMap.cpp">
|
||||
<Filter>Other Platforms\iOS</Filter>
|
||||
</ClCompile>
|
||||
@@ -271,6 +265,12 @@
|
||||
<ClCompile Include="..\UWP\pch.cpp">
|
||||
<Filter>Other Platforms\UWP</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\android\jni\AndroidAudio.cpp">
|
||||
<Filter>Other Platforms\Android</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\android\jni\OpenSLContext.cpp">
|
||||
<Filter>Other Platforms\Android</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Debugger\CtrlDisAsmView.h">
|
||||
@@ -430,12 +430,6 @@
|
||||
<ClInclude Include="..\android\jni\app-android.h">
|
||||
<Filter>Other Platforms\Android</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\android\jni\native_audio.h">
|
||||
<Filter>Other Platforms\Android</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\android\jni\native-audio-so.h">
|
||||
<Filter>Other Platforms\Android</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\ios\ViewController.h">
|
||||
<Filter>Other Platforms\iOS</Filter>
|
||||
</ClInclude>
|
||||
@@ -538,6 +532,12 @@
|
||||
<ClInclude Include="..\UWP\pch.h">
|
||||
<Filter>Other Platforms\UWP</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\android\jni\AndroidAudio.h">
|
||||
<Filter>Other Platforms\Android</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\android\jni\OpenSLContext.h">
|
||||
<Filter>Other Platforms\Android</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="icon1.ico">
|
||||
|
||||
@@ -499,8 +499,8 @@ LOCAL_SRC_FILES := \
|
||||
$(SRC)/android/jni/AndroidEGLContext.cpp \
|
||||
$(SRC)/android/jni/AndroidJavaGLContext.cpp \
|
||||
$(SRC)/android/jni/AndroidVulkanContext.cpp \
|
||||
$(SRC)/android/jni/native_audio.cpp \
|
||||
$(SRC)/android/jni/native-audio-so.cpp \
|
||||
$(SRC)/android/jni/AndroidAudio.cpp \
|
||||
$(SRC)/android/jni/OpenSLContext.cpp \
|
||||
$(SRC)/UI/BackgroundAudio.cpp \
|
||||
$(SRC)/UI/DiscordIntegration.cpp \
|
||||
$(SRC)/UI/ChatScreen.cpp \
|
||||
|
||||
@@ -1,6 +1,18 @@
|
||||
#include "base/logging.h"
|
||||
#include "android/jni/native_audio.h"
|
||||
#include "android/jni/native-audio-so.h"
|
||||
#include "android/jni/AndroidAudio.h"
|
||||
#include "android/jni/OpenSLContext.h"
|
||||
|
||||
AudioContext::AudioContext(AndroidAudioCallback cb, int _FramesPerBuffer, int _SampleRate)
|
||||
: audioCallback(cb), framesPerBuffer(_FramesPerBuffer), sampleRate(_SampleRate) {
|
||||
if (framesPerBuffer == 0)
|
||||
framesPerBuffer = 256;
|
||||
if (framesPerBuffer < 32)
|
||||
framesPerBuffer = 32;
|
||||
if (framesPerBuffer > 4096)
|
||||
framesPerBuffer = 4096;
|
||||
|
||||
sampleRate = _SampleRate;
|
||||
}
|
||||
|
||||
struct AndroidAudioState {
|
||||
AudioContext *ctx = nullptr;
|
||||
@@ -1,8 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include "native-audio-so.h"
|
||||
#include <string>
|
||||
|
||||
typedef int (*AndroidAudioCallback)(short *buffer, int num_samples);
|
||||
|
||||
class AudioContext {
|
||||
public:
|
||||
AudioContext(AndroidAudioCallback cb, int _FramesPerBuffer, int _SampleRate);
|
||||
virtual bool Init() { return false; }
|
||||
virtual ~AudioContext() {}
|
||||
|
||||
protected:
|
||||
AndroidAudioCallback audioCallback;
|
||||
|
||||
int framesPerBuffer;
|
||||
int sampleRate;
|
||||
};
|
||||
|
||||
struct AndroidAudioState;
|
||||
|
||||
// It's okay for optimalFramesPerBuffer and optimalSampleRate to be 0. Defaults will be used.
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "base/display.h"
|
||||
#include "base/NativeApp.h"
|
||||
#include "gfx_es2/gpu_features.h"
|
||||
#include "Common/Log.h"
|
||||
#include "Core/ConfigValues.h"
|
||||
#include "Core/System.h"
|
||||
|
||||
@@ -17,12 +18,11 @@ bool AndroidJavaEGLGraphicsContext::InitFromRenderThread(ANativeWindow *wnd, int
|
||||
// OpenGL handles rotated rendering in the driver.
|
||||
g_display_rotation = DisplayRotation::ROTATE_0;
|
||||
g_display_rot_matrix.setIdentity();
|
||||
draw_ = Draw::T3DCreateGLContext();
|
||||
draw_ = Draw::T3DCreateGLContext(); // Can't fail
|
||||
renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
|
||||
renderManager_->SetInflightFrames(g_Config.iInflightFrames);
|
||||
bool success = draw_->CreatePresets();
|
||||
_assert_msg_(success, "Failed to compile preset shaders");
|
||||
return success;
|
||||
draw_->CreatePresets();
|
||||
return true;
|
||||
}
|
||||
|
||||
void AndroidJavaEGLGraphicsContext::ShutdownFromRenderThread() {
|
||||
|
||||
@@ -71,7 +71,6 @@ bool AndroidVulkanContext::InitAPI() {
|
||||
}
|
||||
|
||||
g_Vulkan->ChooseDevice(physicalDevice);
|
||||
// Here we can enable device extensions if we like.
|
||||
|
||||
ILOG("Creating Vulkan device");
|
||||
if (g_Vulkan->CreateDevice() != VK_SUCCESS) {
|
||||
@@ -82,6 +81,7 @@ bool AndroidVulkanContext::InitAPI() {
|
||||
g_Vulkan = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
ILOG("Vulkan device created!");
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
//
|
||||
// Loosely based on the Android NDK sample code.
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <cstring>
|
||||
#include <unistd.h>
|
||||
|
||||
// for native audio
|
||||
@@ -11,19 +10,8 @@
|
||||
#include <SLES/OpenSLES_Android.h>
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "native-audio-so.h"
|
||||
|
||||
AudioContext::AudioContext(AndroidAudioCallback cb, int _FramesPerBuffer, int _SampleRate)
|
||||
: audioCallback(cb), framesPerBuffer(_FramesPerBuffer), sampleRate(_SampleRate) {
|
||||
if (framesPerBuffer == 0)
|
||||
framesPerBuffer = 256;
|
||||
if (framesPerBuffer < 32)
|
||||
framesPerBuffer = 32;
|
||||
if (framesPerBuffer > 4096)
|
||||
framesPerBuffer = 4096;
|
||||
|
||||
sampleRate = _SampleRate;
|
||||
}
|
||||
#include "Common/Log.h"
|
||||
#include "OpenSLContext.h"
|
||||
|
||||
// This callback handler is called every time a buffer finishes playing.
|
||||
// The documentation available is very unclear about how to best manage buffers.
|
||||
@@ -36,7 +24,7 @@ void OpenSLContext::bqPlayerCallbackWrap(SLAndroidSimpleBufferQueueItf bq, void
|
||||
|
||||
void OpenSLContext::BqPlayerCallback(SLAndroidSimpleBufferQueueItf bq) {
|
||||
if (bq != bqPlayerBufferQueue) {
|
||||
ELOG("Wrong bq!");
|
||||
ELOG("OpenSL: Wrong bq!");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -53,7 +41,7 @@ void OpenSLContext::BqPlayerCallback(SLAndroidSimpleBufferQueueItf bq) {
|
||||
// the most likely other result is SL_RESULT_BUFFER_INSUFFICIENT,
|
||||
// which for this code example would indicate a programming error
|
||||
if (result != SL_RESULT_SUCCESS) {
|
||||
ELOG("OpenSL ES: Failed to enqueue! %i %i", renderedFrames, sizeInBytes);
|
||||
ELOG("OpenSL: Failed to enqueue! %i %i", renderedFrames, sizeInBytes);
|
||||
}
|
||||
|
||||
curBuffer += 1; // Switch buffer
|
||||
@@ -70,24 +58,26 @@ bool OpenSLContext::Init() {
|
||||
// create engine
|
||||
result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
|
||||
if (result != SL_RESULT_SUCCESS) {
|
||||
ELOG("OpenSL ES: Failed to create the engine: %d", (int)result);
|
||||
ELOG("OpenSL: Failed to create the engine: %d", (int)result);
|
||||
engineObject = nullptr;
|
||||
return false;
|
||||
}
|
||||
result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
|
||||
assert(SL_RESULT_SUCCESS == result);
|
||||
_assert_(SL_RESULT_SUCCESS == result);
|
||||
|
||||
result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
|
||||
assert(SL_RESULT_SUCCESS == result);
|
||||
_assert_(SL_RESULT_SUCCESS == result);
|
||||
|
||||
result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 0, 0, 0);
|
||||
if (result != SL_RESULT_SUCCESS) {
|
||||
ELOG("OpenSL ES: Failed to create output mix: %d", (int)result);
|
||||
ELOG("OpenSL: Failed to create output mix: %d", (int)result);
|
||||
(*engineObject)->Destroy(engineObject);
|
||||
engineEngine = nullptr;
|
||||
engineObject = nullptr;
|
||||
return false;
|
||||
}
|
||||
result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
|
||||
assert(SL_RESULT_SUCCESS == result);
|
||||
_assert_(SL_RESULT_SUCCESS == result);
|
||||
|
||||
// The constants, such as SL_SAMPLINGRATE_44_1, are just 44100000.
|
||||
SLuint32 sr = (SLuint32)sampleRate * 1000;
|
||||
@@ -114,7 +104,7 @@ bool OpenSLContext::Init() {
|
||||
const SLboolean req[2] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
|
||||
result = (*engineEngine)->CreateAudioPlayer(engineEngine, &bqPlayerObject, &audioSrc, &audioSnk, 2, ids, req);
|
||||
if (result != SL_RESULT_SUCCESS) {
|
||||
ELOG("OpenSL ES: CreateAudioPlayer failed: %d", (int)result);
|
||||
ELOG("OpenSL: CreateAudioPlayer failed: %d", (int)result);
|
||||
(*outputMixObject)->Destroy(outputMixObject);
|
||||
outputMixObject = nullptr;
|
||||
|
||||
@@ -126,18 +116,18 @@ bool OpenSLContext::Init() {
|
||||
}
|
||||
|
||||
result = (*bqPlayerObject)->Realize(bqPlayerObject, SL_BOOLEAN_FALSE);
|
||||
assert(SL_RESULT_SUCCESS == result);
|
||||
_assert_(SL_RESULT_SUCCESS == result);
|
||||
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_PLAY, &bqPlayerPlay);
|
||||
assert(SL_RESULT_SUCCESS == result);
|
||||
_assert_(SL_RESULT_SUCCESS == result);
|
||||
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_BUFFERQUEUE,
|
||||
&bqPlayerBufferQueue);
|
||||
assert(SL_RESULT_SUCCESS == result);
|
||||
_assert_(SL_RESULT_SUCCESS == result);
|
||||
result = (*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue, &bqPlayerCallbackWrap, this);
|
||||
assert(SL_RESULT_SUCCESS == result);
|
||||
_assert_(SL_RESULT_SUCCESS == result);
|
||||
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_VOLUME, &bqPlayerVolume);
|
||||
assert(SL_RESULT_SUCCESS == result);
|
||||
_assert_(SL_RESULT_SUCCESS == result);
|
||||
result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PLAYING);
|
||||
assert(SL_RESULT_SUCCESS == result);
|
||||
_assert_(SL_RESULT_SUCCESS == result);
|
||||
|
||||
// Allocate and enqueue N empty buffers.
|
||||
for (int i = 0; i < NUM_BUFFERS; i++) {
|
||||
@@ -159,7 +149,7 @@ bool OpenSLContext::Init() {
|
||||
// shut down the native audio system
|
||||
OpenSLContext::~OpenSLContext() {
|
||||
if (bqPlayerPlay) {
|
||||
ILOG("OpenSLWrap_Shutdown - stopping playback");
|
||||
ILOG("OpenSL: Shutdown - stopping playback");
|
||||
SLresult result;
|
||||
result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_STOPPED);
|
||||
if (SL_RESULT_SUCCESS != result) {
|
||||
@@ -167,7 +157,7 @@ OpenSLContext::~OpenSLContext() {
|
||||
}
|
||||
}
|
||||
|
||||
ILOG("OpenSLWrap_Shutdown - deleting player object");
|
||||
ILOG("OpenSL: Shutdown - deleting player object");
|
||||
|
||||
if (bqPlayerObject) {
|
||||
(*bqPlayerObject)->Destroy(bqPlayerObject);
|
||||
@@ -177,14 +167,14 @@ OpenSLContext::~OpenSLContext() {
|
||||
bqPlayerVolume = nullptr;
|
||||
}
|
||||
|
||||
ILOG("OpenSLWrap_Shutdown - deleting mix object");
|
||||
ILOG("OpenSL: Shutdown - deleting mix object");
|
||||
|
||||
if (outputMixObject) {
|
||||
(*outputMixObject)->Destroy(outputMixObject);
|
||||
outputMixObject = nullptr;
|
||||
}
|
||||
|
||||
ILOG("OpenSLWrap_Shutdown - deleting engine object");
|
||||
ILOG("OpenSL: Shutdown - deleting engine object");
|
||||
|
||||
if (engineObject) {
|
||||
(*engineObject)->Destroy(engineObject);
|
||||
@@ -196,6 +186,6 @@ OpenSLContext::~OpenSLContext() {
|
||||
delete[] buffer[i];
|
||||
buffer[i] = nullptr;
|
||||
}
|
||||
ILOG("OpenSLWrap_Shutdown - finished");
|
||||
ILOG("OpenSL: Shutdown - finished");
|
||||
}
|
||||
|
||||
@@ -3,20 +3,7 @@
|
||||
#include <SLES/OpenSLES.h>
|
||||
#include <SLES/OpenSLES_Android.h>
|
||||
|
||||
typedef int (*AndroidAudioCallback)(short *buffer, int num_samples);
|
||||
|
||||
class AudioContext {
|
||||
public:
|
||||
AudioContext(AndroidAudioCallback cb, int _FramesPerBuffer, int _SampleRate);
|
||||
virtual bool Init() { return false; }
|
||||
virtual ~AudioContext() {}
|
||||
|
||||
protected:
|
||||
AndroidAudioCallback audioCallback;
|
||||
|
||||
int framesPerBuffer;
|
||||
int sampleRate;
|
||||
};
|
||||
#include "AndroidAudio.h"
|
||||
|
||||
class OpenSLContext : public AudioContext {
|
||||
public:
|
||||
+32
-12
@@ -4,7 +4,6 @@
|
||||
// It calls a set of methods defined in NativeApp.h. These should be implemented
|
||||
// by your game or app.
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <cstdint>
|
||||
|
||||
@@ -63,7 +62,7 @@ struct JNIEnv {};
|
||||
#include "math/math_util.h"
|
||||
#include "net/resolve.h"
|
||||
#include "util/text/parsers.h"
|
||||
#include "android/jni/native_audio.h"
|
||||
#include "android/jni/AndroidAudio.h"
|
||||
#include "gfx/gl_common.h"
|
||||
#include "gfx_es2/gpu_features.h"
|
||||
|
||||
@@ -594,7 +593,6 @@ retry:
|
||||
ELOG("NativeApp.init(): iGPUBackend %d not supported. Switching to OpenGL.", (int)g_Config.iGPUBackend);
|
||||
g_Config.iGPUBackend = (int)GPUBackend::OPENGL;
|
||||
goto retry;
|
||||
// Crash();
|
||||
}
|
||||
|
||||
if (useCPUThread) {
|
||||
@@ -605,7 +603,7 @@ retry:
|
||||
|
||||
extern "C" void Java_org_ppsspp_ppsspp_NativeApp_audioInit(JNIEnv *, jclass) {
|
||||
sampleRate = optimalSampleRate;
|
||||
if (NativeQueryConfig("force44khz") != "0" || optimalSampleRate == 0) {
|
||||
if (optimalSampleRate == 0) {
|
||||
sampleRate = 44100;
|
||||
}
|
||||
if (optimalFramesPerBuffer > 0) {
|
||||
@@ -688,7 +686,7 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeApp_shutdown(JNIEnv *, jclass) {
|
||||
}
|
||||
|
||||
// JavaEGL
|
||||
extern "C" void Java_org_ppsspp_ppsspp_NativeRenderer_displayInit(JNIEnv * env, jobject obj) {
|
||||
extern "C" bool Java_org_ppsspp_ppsspp_NativeRenderer_displayInit(JNIEnv * env, jobject obj) {
|
||||
// We should be running on the render thread here.
|
||||
std::string errorMessage;
|
||||
if (renderer_inited) {
|
||||
@@ -712,21 +710,34 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeRenderer_displayInit(JNIEnv * env,
|
||||
|
||||
ILOG("Shut down both threads. Now let's bring it up again!");
|
||||
|
||||
graphicsContext->InitFromRenderThread(nullptr, 0, 0, 0, 0);
|
||||
if (!graphicsContext->InitFromRenderThread(nullptr, 0, 0, 0, 0)) {
|
||||
SystemToast("Graphics initialization failed. Quitting.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (useCPUThread) {
|
||||
EmuThreadStart();
|
||||
} else {
|
||||
NativeInitGraphics(graphicsContext);
|
||||
if (!NativeInitGraphics(graphicsContext)) {
|
||||
// Gonna be in a weird state here, not good.
|
||||
SystemToast("Failed to initialize graphics.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
graphicsContext->ThreadStart();
|
||||
ILOG("Restored.");
|
||||
} else {
|
||||
ILOG("NativeApp.displayInit() first time");
|
||||
graphicsContext->InitFromRenderThread(nullptr, 0, 0, 0, 0);
|
||||
if (!graphicsContext->InitFromRenderThread(nullptr, 0, 0, 0, 0)) {
|
||||
SystemToast("Graphics initialization failed. Quitting.");
|
||||
return false;
|
||||
}
|
||||
graphicsContext->ThreadStart();
|
||||
renderer_inited = true;
|
||||
}
|
||||
NativeMessageReceived("recreateviews", "");
|
||||
return true;
|
||||
}
|
||||
|
||||
static void recalculateDpi() {
|
||||
@@ -1156,6 +1167,11 @@ static void ProcessFrameCommands(JNIEnv *env) {
|
||||
}
|
||||
|
||||
extern "C" bool JNICALL Java_org_ppsspp_ppsspp_NativeActivity_runEGLRenderLoop(JNIEnv *env, jobject obj, jobject _surf) {
|
||||
if (!graphicsContext) {
|
||||
ELOG("runEGLRenderLoop: Tried to enter without a created graphics context.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Needed for Vulkan, even if we're not using the old EGL path.
|
||||
|
||||
exitRenderLoop = false;
|
||||
@@ -1175,10 +1191,11 @@ extern "C" bool JNICALL Java_org_ppsspp_ppsspp_NativeActivity_runEGLRenderLoop(J
|
||||
auto tryInit = [&]() {
|
||||
if (graphicsContext->InitFromRenderThread(wnd, desiredBackbufferSizeX, desiredBackbufferSizeY, backbuffer_format, androidVersion)) {
|
||||
return true;
|
||||
} else {
|
||||
ELOG("Failed to initialize graphics context.");
|
||||
SystemToast("Failed to initialize graphics context.");
|
||||
return false;
|
||||
}
|
||||
|
||||
ELOG("Failed to initialize graphics context.");
|
||||
return false;
|
||||
};
|
||||
|
||||
bool initSuccess = tryInit();
|
||||
@@ -1202,7 +1219,10 @@ extern "C" bool JNICALL Java_org_ppsspp_ppsspp_NativeActivity_runEGLRenderLoop(J
|
||||
|
||||
if (!exitRenderLoop) {
|
||||
if (!useCPUThread) {
|
||||
NativeInitGraphics(graphicsContext);
|
||||
if (!NativeInitGraphics(graphicsContext)) {
|
||||
ELOG("Failed to initialize graphics.");
|
||||
// Gonna be in a weird state here..
|
||||
}
|
||||
}
|
||||
graphicsContext->ThreadStart();
|
||||
renderer_inited = true;
|
||||
|
||||
@@ -18,7 +18,6 @@ import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.res.Configuration;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.Point;
|
||||
import android.media.AudioManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
@@ -51,11 +50,12 @@ import java.util.Locale;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
public abstract class NativeActivity extends Activity {
|
||||
// Remember to loadLibrary your JNI .so in a static {} block
|
||||
|
||||
// Adjust these as necessary
|
||||
private static String TAG = "PPSSPPNativeActivity";
|
||||
private static final String TAG = "PPSSPPNativeActivity";
|
||||
|
||||
// Allows us to skip a lot of initialization on secondary calls to onCreate.
|
||||
private static boolean initialized = false;
|
||||
@@ -98,7 +98,7 @@ public abstract class NativeActivity extends Activity {
|
||||
// This is to avoid losing the game/menu state etc when we are just
|
||||
// switched-away from or rotated etc.
|
||||
private boolean shuttingDown;
|
||||
private static int RESULT_LOAD_IMAGE = 1;
|
||||
private static final int RESULT_LOAD_IMAGE = 1;
|
||||
|
||||
// Allow for multiple connected gamepads but just consider them the same for now.
|
||||
// Actually this is not entirely true, see the code.
|
||||
@@ -132,10 +132,6 @@ public abstract class NativeActivity extends Activity {
|
||||
public native void registerCallbacks();
|
||||
public native void unregisterCallbacks();
|
||||
|
||||
public boolean useLowProfileButtons() {
|
||||
return true;
|
||||
}
|
||||
|
||||
NativeRenderer getRenderer() {
|
||||
return nativeRenderer;
|
||||
}
|
||||
@@ -209,7 +205,7 @@ public abstract class NativeActivity extends Activity {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
|
||||
public void onRequestPermissionsResult(int requestCode, String [] permissions, int[] grantResults) {
|
||||
switch (requestCode) {
|
||||
case REQUEST_CODE_STORAGE_PERMISSION:
|
||||
if (permissionsGranted(permissions, grantResults)) {
|
||||
@@ -248,7 +244,7 @@ public abstract class NativeActivity extends Activity {
|
||||
}
|
||||
powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
if (powerManager.isSustainedPerformanceModeSupported()) {
|
||||
if (powerManager != null && powerManager.isSustainedPerformanceModeSupported()) {
|
||||
sustainedPerfSupported = true;
|
||||
NativeApp.sendMessage("sustained_perf_supported", "1");
|
||||
}
|
||||
@@ -259,10 +255,10 @@ public abstract class NativeActivity extends Activity {
|
||||
Log.d(TAG, "Landscape: " + landscape);
|
||||
|
||||
// Get system information
|
||||
ApplicationInfo appInfo = null;
|
||||
|
||||
PackageManager packMgmr = getPackageManager();
|
||||
String packageName = getPackageName();
|
||||
|
||||
ApplicationInfo appInfo;
|
||||
try {
|
||||
appInfo = packMgmr.getApplicationInfo(packageName, 0);
|
||||
} catch (NameNotFoundException e) {
|
||||
@@ -345,22 +341,20 @@ public abstract class NativeActivity extends Activity {
|
||||
private void updateSustainedPerformanceMode() {
|
||||
if (sustainedPerfSupported) {
|
||||
// Query the native application on the desired rotation.
|
||||
int enable = 0;
|
||||
String str = NativeApp.queryConfig("sustainedPerformanceMode");
|
||||
try {
|
||||
enable = Integer.parseInt(str);
|
||||
int enable = Integer.parseInt(str);
|
||||
getWindow().setSustainedPerformanceMode(enable != 0);
|
||||
} catch (NumberFormatException e) {
|
||||
Log.e(TAG, "Invalid perf mode: " + str);
|
||||
return;
|
||||
}
|
||||
getWindow().setSustainedPerformanceMode(enable != 0);
|
||||
}
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.GINGERBREAD)
|
||||
private void updateScreenRotation(String cause) {
|
||||
// Query the native application on the desired rotation.
|
||||
int rot = 0;
|
||||
int rot;
|
||||
String rotString = NativeApp.queryConfig("screenRotation");
|
||||
try {
|
||||
rot = Integer.parseInt(rotString);
|
||||
@@ -407,10 +401,7 @@ public abstract class NativeActivity extends Activity {
|
||||
}
|
||||
|
||||
// Compute our _desired_ systemUiVisibility
|
||||
int flags = 0;
|
||||
if (useLowProfileButtons()) {
|
||||
flags |= View.SYSTEM_UI_FLAG_LOW_PROFILE;
|
||||
}
|
||||
int flags = View.SYSTEM_UI_FLAG_LOW_PROFILE;
|
||||
if (useImmersive()) {
|
||||
flags |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
|
||||
flags |= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN;
|
||||
@@ -436,7 +427,7 @@ public abstract class NativeActivity extends Activity {
|
||||
}
|
||||
}
|
||||
|
||||
private Runnable mEmulationRunner = new Runnable() {
|
||||
private final Runnable mEmulationRunner = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Log.i(TAG, "Starting the render loop: " + mSurface);
|
||||
@@ -616,6 +607,7 @@ public abstract class NativeActivity extends Activity {
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
Log.i(TAG, "onDestroy");
|
||||
if (javaGL) {
|
||||
if (nativeRenderer.isRenderingFrame()) {
|
||||
Log.i(TAG, "Waiting for renderer to finish.");
|
||||
@@ -628,21 +620,23 @@ public abstract class NativeActivity extends Activity {
|
||||
tries--;
|
||||
} while (nativeRenderer.isRenderingFrame() && tries > 0);
|
||||
}
|
||||
Log.i(TAG, "onDestroy");
|
||||
mGLSurfaceView.onDestroy();
|
||||
// Probably vain attempt to help the garbage collector...
|
||||
mGLSurfaceView = null;
|
||||
audioFocusChangeListener = null;
|
||||
audioManager = null;
|
||||
} else {
|
||||
mSurfaceView.onDestroy();
|
||||
mSurfaceView = null;
|
||||
}
|
||||
|
||||
// Probably vain attempt to help the garbage collector...
|
||||
audioFocusChangeListener = null;
|
||||
audioManager = null;
|
||||
|
||||
sizeManager.setSurfaceView(null);
|
||||
if (mPowerSaveModeReceiver != null) {
|
||||
mPowerSaveModeReceiver.destroy(this);
|
||||
mPowerSaveModeReceiver = null;
|
||||
}
|
||||
|
||||
// TODO: Can we ensure that the GL thread has stopped rendering here?
|
||||
// I've seen crashes that seem to indicate that sometimes it hasn't...
|
||||
NativeApp.audioShutdown();
|
||||
@@ -697,6 +691,7 @@ public abstract class NativeActivity extends Activity {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
|
||||
updateSystemUiVisibility();
|
||||
}
|
||||
|
||||
// OK, config should be initialized, we can query for screen rotation.
|
||||
if (javaGL || Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
|
||||
updateScreenRotation("onResume");
|
||||
@@ -991,30 +986,29 @@ public abstract class NativeActivity extends Activity {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data) {
|
||||
Uri selectedImage = data.getData();
|
||||
String[] filePathColumn = {MediaStore.Images.Media.DATA};
|
||||
Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
|
||||
cursor.moveToFirst();
|
||||
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
|
||||
String picturePath = cursor.getString(columnIndex);
|
||||
cursor.close();
|
||||
NativeApp.sendMessage("bgImage_updated", picturePath);
|
||||
if (selectedImage != null) {
|
||||
String[] filePathColumn = {MediaStore.Images.Media.DATA};
|
||||
Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
|
||||
cursor.moveToFirst();
|
||||
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
|
||||
String picturePath = cursor.getString(columnIndex);
|
||||
cursor.close();
|
||||
NativeApp.sendMessage("bgImage_updated", picturePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
||||
@SuppressWarnings("deprecation")
|
||||
private AlertDialog.Builder createDialogBuilderWithTheme() {
|
||||
return new AlertDialog.Builder(this, AlertDialog.THEME_HOLO_DARK);
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
|
||||
@SuppressWarnings("deprecation")
|
||||
private AlertDialog.Builder createDialogBuilderWithDeviceTheme() {
|
||||
return new AlertDialog.Builder(this, AlertDialog.THEME_DEVICE_DEFAULT_DARK);
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
|
||||
@SuppressWarnings("deprecation")
|
||||
private AlertDialog.Builder createDialogBuilderWithDeviceThemeAndUiVisibility() {
|
||||
AlertDialog.Builder bld = new AlertDialog.Builder(this, AlertDialog.THEME_DEVICE_DEFAULT_DARK);
|
||||
bld.setOnDismissListener(new DialogInterface.OnDismissListener() {
|
||||
@@ -1065,7 +1059,7 @@ public abstract class NativeActivity extends Activity {
|
||||
else
|
||||
bld = createDialogBuilderNew();
|
||||
|
||||
AlertDialog dlg = bld
|
||||
AlertDialog.Builder builder = bld
|
||||
.setView(fl)
|
||||
.setTitle(title)
|
||||
.setPositiveButton(defaultAction, new DialogInterface.OnClickListener() {
|
||||
@@ -1081,15 +1075,17 @@ public abstract class NativeActivity extends Activity {
|
||||
NativeApp.sendInputBox(seqID, false, "");
|
||||
d.cancel();
|
||||
}
|
||||
})
|
||||
.setOnDismissListener(new DialogInterface.OnDismissListener() {
|
||||
});
|
||||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
|
||||
@Override
|
||||
public void onDismiss(DialogInterface d) {
|
||||
NativeApp.sendInputBox(seqID, false, "");
|
||||
updateSystemUiVisibility();
|
||||
}
|
||||
})
|
||||
.create();
|
||||
});
|
||||
}
|
||||
AlertDialog dlg = builder.create();
|
||||
|
||||
dlg.setCancelable(true);
|
||||
dlg.show();
|
||||
@@ -1188,11 +1184,10 @@ public abstract class NativeActivity extends Activity {
|
||||
inputMethodManager.toggleSoftInputFromWindow(surfView.getApplicationWindowToken(), InputMethodManager.SHOW_FORCED, 0);
|
||||
return true;
|
||||
} else if (command.equals("inputbox")) {
|
||||
String seqID = "";
|
||||
String title = "Input";
|
||||
String defString = "";
|
||||
String[] param = params.split(":@:", 3);
|
||||
seqID = param[0];
|
||||
String seqID = param[0];
|
||||
if (param.length > 1 && param[1].length() > 0)
|
||||
title = param[1];
|
||||
if (param.length > 2)
|
||||
@@ -1202,7 +1197,7 @@ public abstract class NativeActivity extends Activity {
|
||||
return true;
|
||||
} else if (command.equals("vibrate")) {
|
||||
int milliseconds = -1;
|
||||
if (params != "") {
|
||||
if (!params.equals("")) {
|
||||
try {
|
||||
milliseconds = Integer.parseInt(params);
|
||||
} catch (NumberFormatException e) {
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.ppsspp.ppsspp;
|
||||
|
||||
import android.opengl.GLSurfaceView;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import javax.microedition.khronos.egl.EGL10;
|
||||
import javax.microedition.khronos.egl.EGLConfig;
|
||||
@@ -12,7 +13,8 @@ import javax.microedition.khronos.opengles.GL10;
|
||||
public class NativeRenderer implements GLSurfaceView.Renderer {
|
||||
private static String TAG = "NativeRenderer";
|
||||
private NativeActivity mActivity;
|
||||
private boolean inFrame;
|
||||
private boolean inFrame = false;
|
||||
private boolean failed = false;
|
||||
|
||||
NativeRenderer(NativeActivity act) {
|
||||
mActivity = act;
|
||||
@@ -22,6 +24,9 @@ public class NativeRenderer implements GLSurfaceView.Renderer {
|
||||
return inFrame;
|
||||
}
|
||||
|
||||
// TODO: Make use of this somehow.
|
||||
public boolean hasFailedInit() { return failed; }
|
||||
|
||||
public void onDrawFrame(GL10 unused /*use GLES20*/) {
|
||||
inFrame = true;
|
||||
displayRender();
|
||||
@@ -29,6 +34,7 @@ public class NativeRenderer implements GLSurfaceView.Renderer {
|
||||
}
|
||||
|
||||
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
|
||||
failed = false;
|
||||
Log.i(TAG, "NativeRenderer: onSurfaceCreated");
|
||||
|
||||
EGL10 egl = (EGL10)EGLContext.getEGL();
|
||||
@@ -47,17 +53,18 @@ public class NativeRenderer implements GLSurfaceView.Renderer {
|
||||
} else {
|
||||
Log.e(TAG, "egl == null");
|
||||
}
|
||||
// Log.i(TAG, "onSurfaceCreated - EGL context is new or was lost");
|
||||
// Actually, it seems that it is here we should recreate lost GL objects.
|
||||
displayInit();
|
||||
|
||||
if (!displayInit()) {
|
||||
Log.e(TAG, "Display init failed");
|
||||
Toast.makeText(mActivity, "Failed to initialize rendering. Close the app and try again.", Toast.LENGTH_LONG);
|
||||
failed = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void onSurfaceChanged(GL10 unused, int width, int height) {
|
||||
}
|
||||
public void onSurfaceChanged(GL10 unused, int width, int height) {}
|
||||
|
||||
// Note: This also means "device lost" and you should reload
|
||||
// all buffered objects.
|
||||
public native void displayInit();
|
||||
|
||||
public native boolean displayInit();
|
||||
public native void displayRender();
|
||||
}
|
||||
@@ -136,6 +136,7 @@ enum class Primitive {
|
||||
TRIANGLE_STRIP_ADJ,
|
||||
|
||||
UNDEFINED,
|
||||
PRIMITIVE_TYPE_COUNT,
|
||||
};
|
||||
|
||||
enum VertexShaderPreset : int {
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <cassert>
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "math/dataconv.h"
|
||||
@@ -961,6 +960,15 @@ Pipeline *OpenGLContext::CreateGraphicsPipeline(const PipelineDesc &desc) {
|
||||
ELOG("Pipeline requires at least one shader");
|
||||
return nullptr;
|
||||
}
|
||||
if ((int)desc.prim >= (int)Primitive::PRIMITIVE_TYPE_COUNT) {
|
||||
ELOG("Invalid primitive type");
|
||||
return nullptr;
|
||||
}
|
||||
if (!desc.depthStencil || !desc.blend || !desc.raster || !desc.inputLayout) {
|
||||
ELOG("Incomplete prim desciption");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
OpenGLPipeline *pipeline = new OpenGLPipeline(&renderManager_);
|
||||
for (auto iter : desc.shaders) {
|
||||
if (iter) {
|
||||
@@ -1045,9 +1053,21 @@ ShaderModule *OpenGLContext::CreateShaderModule(ShaderStage stage, ShaderLanguag
|
||||
|
||||
bool OpenGLPipeline::LinkShaders() {
|
||||
std::vector<GLRShader *> linkShaders;
|
||||
for (auto iter : shaders) {
|
||||
linkShaders.push_back(iter->GetShader());
|
||||
for (auto shaderModule : shaders) {
|
||||
if (shaderModule) {
|
||||
GLRShader *shader = shaderModule->GetShader();
|
||||
if (shader) {
|
||||
linkShaders.push_back(shader);
|
||||
} else {
|
||||
ELOG("LinkShaders: Bad shader module");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
ELOG("LinkShaders: Bad shader in module");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<GLRProgram::Semantic> semantics;
|
||||
// Bind all the common vertex data points. Mismatching ones will be ignored.
|
||||
semantics.push_back({ SEM_POSITION, "Position" });
|
||||
|
||||
Reference in new issue
Block a user