Merge pull request #13221 from hrydgard/android-minor-cleanup

Android: Various minor cleanup
This commit is contained in:
Unknown W. Brackets authored and GitHub committed 2020-07-29 02:51:50 -04:00
commit 5c1bb52ce6
18 files changed
+270 -201

No files matched your search

+4 -4
View File
@@ -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
View File
@@ -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
+20 -10
View File
@@ -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() {
}
+2
View File
@@ -34,6 +34,8 @@ public:
Draw::DrawContext *GetDrawContext() override { return draw_; }
private:
void ReleaseGLContext();
bool renderThread_;
Draw::DrawContext *draw_;
GLRenderManager *renderManager_;
+4 -4
View File
@@ -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>
+12 -12
View File
@@ -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">
+2 -2
View File
@@ -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 -4
View File
@@ -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() {
+1 -1
View File
@@ -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
View File
@@ -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();
}
+1
View File
@@ -136,6 +136,7 @@ enum class Primitive {
TRIANGLE_STRIP_ADJ,
UNDEFINED,
PRIMITIVE_TYPE_COUNT,
};
enum VertexShaderPreset : int {
+23 -3
View File
@@ -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" });