mirror of
https://github.com/libretro/ppsspp.git
synced 2024-11-23 16:19:44 +00:00
Add some paranoid checks hoping to fix crashes reported in Google Play developer console.
This commit is contained in:
parent
774539dea8
commit
4197148dc4
@ -677,7 +677,3 @@ bool ElfReader::LoadSymbols()
|
|||||||
}
|
}
|
||||||
return hasSymbols;
|
return hasSymbols;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1703,29 +1703,29 @@ void __KernelReSchedule(const char *reason)
|
|||||||
|
|
||||||
// Execute any pending events while we're doing scheduling.
|
// Execute any pending events while we're doing scheduling.
|
||||||
CoreTiming::Advance();
|
CoreTiming::Advance();
|
||||||
if (__IsInInterrupt() || !__KernelIsDispatchEnabled())
|
if (__IsInInterrupt() || !__KernelIsDispatchEnabled()) {
|
||||||
{
|
|
||||||
// Threads don't get changed within interrupts or while dispatch is disabled.
|
// Threads don't get changed within interrupts or while dispatch is disabled.
|
||||||
reason = "In Interrupt Or Callback";
|
reason = "In Interrupt Or Callback";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread *nextThread = __KernelNextThread();
|
Thread *nextThread = __KernelNextThread();
|
||||||
if (nextThread)
|
if (nextThread) {
|
||||||
__KernelSwitchContext(nextThread, reason);
|
__KernelSwitchContext(nextThread, reason);
|
||||||
|
}
|
||||||
// Otherwise, no need to switch.
|
// Otherwise, no need to switch.
|
||||||
}
|
}
|
||||||
|
|
||||||
void __KernelReSchedule(bool doCallbacks, const char *reason)
|
void __KernelReSchedule(bool doCallbacks, const char *reason)
|
||||||
{
|
{
|
||||||
Thread *thread = __GetCurrentThread();
|
Thread *thread = __GetCurrentThread();
|
||||||
if (doCallbacks)
|
if (doCallbacks && thread != nullptr) {
|
||||||
{
|
thread->isProcessingCallbacks = doCallbacks;
|
||||||
if (thread)
|
|
||||||
thread->isProcessingCallbacks = doCallbacks;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Note - this calls the function above, not this one. Overloading...
|
||||||
__KernelReSchedule(reason);
|
__KernelReSchedule(reason);
|
||||||
if (doCallbacks && thread != NULL && thread->GetUID() == currentThread) {
|
if (doCallbacks && thread != nullptr && thread->GetUID() == currentThread) {
|
||||||
if (thread->isRunning()) {
|
if (thread->isRunning()) {
|
||||||
thread->isProcessingCallbacks = false;
|
thread->isProcessingCallbacks = false;
|
||||||
}
|
}
|
||||||
|
@ -155,15 +155,18 @@ namespace Reporting
|
|||||||
if (output == NULL)
|
if (output == NULL)
|
||||||
output = &theVoid;
|
output = &theVoid;
|
||||||
|
|
||||||
if (http.Resolve(ServerHostname(), ServerPort()))
|
const char *serverHost = ServerHostname();
|
||||||
{
|
if (!serverHost)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (http.Resolve(serverHost, ServerPort())) {
|
||||||
http.Connect();
|
http.Connect();
|
||||||
http.POST(uri, data, mimeType, output);
|
http.POST(uri, data, mimeType, output);
|
||||||
http.Disconnect();
|
http.Disconnect();
|
||||||
result = true;
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string StripTrailingNull(const std::string &str)
|
std::string StripTrailingNull(const std::string &str)
|
||||||
|
@ -206,6 +206,9 @@ int PlayBackgroundAudio() {
|
|||||||
// last changed... (to prevent crazy amount of reads when skipping through a list)
|
// last changed... (to prevent crazy amount of reads when skipping through a list)
|
||||||
if (!at3Reader && bgGamePath.size() && (time_now_d() - gameLastChanged > 0.5)) {
|
if (!at3Reader && bgGamePath.size() && (time_now_d() - gameLastChanged > 0.5)) {
|
||||||
// Grab some audio from the current game and play it.
|
// Grab some audio from the current game and play it.
|
||||||
|
if (!g_gameInfoCache)
|
||||||
|
return 0; // race condition?
|
||||||
|
|
||||||
GameInfo *gameInfo = g_gameInfoCache->GetInfo(NULL, bgGamePath, GAMEINFO_WANTSND);
|
GameInfo *gameInfo = g_gameInfoCache->GetInfo(NULL, bgGamePath, GAMEINFO_WANTSND);
|
||||||
if (!gameInfo)
|
if (!gameInfo)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -611,7 +611,9 @@ void NativeShutdownGraphics() {
|
|||||||
delete g_gameInfoCache;
|
delete g_gameInfoCache;
|
||||||
g_gameInfoCache = nullptr;
|
g_gameInfoCache = nullptr;
|
||||||
|
|
||||||
uiTexture->Release();
|
if (uiTexture->Release()) {
|
||||||
|
uiTexture = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
delete uiContext;
|
delete uiContext;
|
||||||
uiContext = NULL;
|
uiContext = NULL;
|
||||||
@ -619,7 +621,10 @@ void NativeShutdownGraphics() {
|
|||||||
ui_draw2d.Shutdown();
|
ui_draw2d.Shutdown();
|
||||||
ui_draw2d_front.Shutdown();
|
ui_draw2d_front.Shutdown();
|
||||||
|
|
||||||
thin3d->Release();
|
// TODO: Reconsider this annoying ref counting stuff.
|
||||||
|
if (thin3d->Release()) {
|
||||||
|
thin3d = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TakeScreenshot() {
|
void TakeScreenshot() {
|
||||||
|
@ -73,19 +73,22 @@ bool OpenSLWrap_Init(AndroidAudioCallback cb, int _FramesPerBuffer, int _SampleR
|
|||||||
framesPerBuffer = 256;
|
framesPerBuffer = 256;
|
||||||
if (framesPerBuffer < 32)
|
if (framesPerBuffer < 32)
|
||||||
framesPerBuffer = 32;
|
framesPerBuffer = 32;
|
||||||
|
if (framesPerBuffer > 4096)
|
||||||
|
framesPerBuffer = 4096;
|
||||||
|
|
||||||
sampleRate = _SampleRate;
|
sampleRate = _SampleRate;
|
||||||
if (sampleRate != 44100 && sampleRate != 48000) {
|
if (sampleRate != 44100 && sampleRate != 48000) {
|
||||||
ELOG("Invalid sample rate %i - choosing 44100", sampleRate);
|
ELOG("Invalid sample rate %i - choosing 44100", sampleRate);
|
||||||
sampleRate = 44100;
|
sampleRate = 44100;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer[0] = new short[framesPerBuffer * 2];
|
|
||||||
buffer[1] = new short[framesPerBuffer * 2];
|
|
||||||
|
|
||||||
SLresult result;
|
SLresult result;
|
||||||
// create engine
|
// create engine
|
||||||
result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
|
result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
|
||||||
assert(SL_RESULT_SUCCESS == result);
|
if (result != SL_RESULT_SUCCESS) {
|
||||||
|
ELOG("OpenSL ES: Failed to create the engine: %d", (int)result);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_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);
|
result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
|
||||||
@ -98,7 +101,7 @@ bool OpenSLWrap_Init(AndroidAudioCallback cb, int _FramesPerBuffer, int _SampleR
|
|||||||
SLuint32 sr = SL_SAMPLINGRATE_44_1;
|
SLuint32 sr = SL_SAMPLINGRATE_44_1;
|
||||||
if (sampleRate == 48000) {
|
if (sampleRate == 48000) {
|
||||||
sr = SL_SAMPLINGRATE_48;
|
sr = SL_SAMPLINGRATE_48;
|
||||||
}
|
} // Don't allow any other sample rates.
|
||||||
|
|
||||||
SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2};
|
SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2};
|
||||||
SLDataFormat_PCM format_pcm = {
|
SLDataFormat_PCM format_pcm = {
|
||||||
@ -121,7 +124,11 @@ bool OpenSLWrap_Init(AndroidAudioCallback cb, int _FramesPerBuffer, int _SampleR
|
|||||||
const SLInterfaceID ids[2] = {SL_IID_BUFFERQUEUE, SL_IID_VOLUME};
|
const SLInterfaceID ids[2] = {SL_IID_BUFFERQUEUE, SL_IID_VOLUME};
|
||||||
const SLboolean req[2] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
|
const SLboolean req[2] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
|
||||||
result = (*engineEngine)->CreateAudioPlayer(engineEngine, &bqPlayerObject, &audioSrc, &audioSnk, 2, ids, req);
|
result = (*engineEngine)->CreateAudioPlayer(engineEngine, &bqPlayerObject, &audioSrc, &audioSnk, 2, ids, req);
|
||||||
assert(SL_RESULT_SUCCESS == result);
|
if (result != SL_RESULT_SUCCESS) {
|
||||||
|
ELOG("OpenSL ES: CreateAudioPlayer failed: %d", (int)result);
|
||||||
|
// Should really tear everything down here. Sigh.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
result = (*bqPlayerObject)->Realize(bqPlayerObject, SL_BOOLEAN_FALSE);
|
result = (*bqPlayerObject)->Realize(bqPlayerObject, SL_BOOLEAN_FALSE);
|
||||||
assert(SL_RESULT_SUCCESS == result);
|
assert(SL_RESULT_SUCCESS == result);
|
||||||
@ -138,6 +145,9 @@ bool OpenSLWrap_Init(AndroidAudioCallback cb, int _FramesPerBuffer, int _SampleR
|
|||||||
assert(SL_RESULT_SUCCESS == result);
|
assert(SL_RESULT_SUCCESS == result);
|
||||||
|
|
||||||
// Render and enqueue a first buffer. (or should we just play the buffer empty?)
|
// Render and enqueue a first buffer. (or should we just play the buffer empty?)
|
||||||
|
buffer[0] = new short[framesPerBuffer * 2];
|
||||||
|
buffer[1] = new short[framesPerBuffer * 2];
|
||||||
|
|
||||||
curBuffer = 0;
|
curBuffer = 0;
|
||||||
audioCallback(buffer[curBuffer], framesPerBuffer);
|
audioCallback(buffer[curBuffer], framesPerBuffer);
|
||||||
|
|
||||||
@ -151,40 +161,44 @@ bool OpenSLWrap_Init(AndroidAudioCallback cb, int _FramesPerBuffer, int _SampleR
|
|||||||
|
|
||||||
// shut down the native audio system
|
// shut down the native audio system
|
||||||
void OpenSLWrap_Shutdown() {
|
void OpenSLWrap_Shutdown() {
|
||||||
SLresult result;
|
if (bqPlayerPlay) {
|
||||||
ILOG("OpenSLWrap_Shutdown - stopping playback");
|
ILOG("OpenSLWrap_Shutdown - stopping playback");
|
||||||
result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_STOPPED);
|
SLresult result;
|
||||||
if (SL_RESULT_SUCCESS != result) {
|
result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_STOPPED);
|
||||||
ELOG("SetPlayState failed");
|
if (SL_RESULT_SUCCESS != result) {
|
||||||
|
ELOG("SetPlayState failed");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ILOG("OpenSLWrap_Shutdown - deleting player object");
|
ILOG("OpenSLWrap_Shutdown - deleting player object");
|
||||||
|
|
||||||
if (bqPlayerObject != NULL) {
|
if (bqPlayerObject) {
|
||||||
(*bqPlayerObject)->Destroy(bqPlayerObject);
|
(*bqPlayerObject)->Destroy(bqPlayerObject);
|
||||||
bqPlayerObject = NULL;
|
bqPlayerObject = nullptr;
|
||||||
bqPlayerPlay = NULL;
|
bqPlayerPlay = nullptr;
|
||||||
bqPlayerBufferQueue = NULL;
|
bqPlayerBufferQueue = nullptr;
|
||||||
bqPlayerMuteSolo = NULL;
|
bqPlayerMuteSolo = nullptr;
|
||||||
bqPlayerVolume = NULL;
|
bqPlayerVolume = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ILOG("OpenSLWrap_Shutdown - deleting mix object");
|
ILOG("OpenSLWrap_Shutdown - deleting mix object");
|
||||||
|
|
||||||
if (outputMixObject != NULL) {
|
if (outputMixObject) {
|
||||||
(*outputMixObject)->Destroy(outputMixObject);
|
(*outputMixObject)->Destroy(outputMixObject);
|
||||||
outputMixObject = NULL;
|
outputMixObject = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ILOG("OpenSLWrap_Shutdown - deleting engine object");
|
ILOG("OpenSLWrap_Shutdown - deleting engine object");
|
||||||
|
|
||||||
if (engineObject != NULL) {
|
if (engineObject) {
|
||||||
(*engineObject)->Destroy(engineObject);
|
(*engineObject)->Destroy(engineObject);
|
||||||
engineObject = NULL;
|
engineObject = nullptr;
|
||||||
engineEngine = NULL;
|
engineEngine = nullptr;
|
||||||
}
|
}
|
||||||
delete [] buffer[0];
|
delete [] buffer[0];
|
||||||
delete [] buffer[1];
|
delete [] buffer[1];
|
||||||
|
buffer[0] = nullptr;
|
||||||
|
buffer[1] = nullptr;
|
||||||
ILOG("OpenSLWrap_Shutdown - finished");
|
ILOG("OpenSLWrap_Shutdown - finished");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "base/logging.h"
|
||||||
|
|
||||||
class Matrix4x4;
|
class Matrix4x4;
|
||||||
|
|
||||||
enum T3DBlendEquation : int {
|
enum T3DBlendEquation : int {
|
||||||
@ -212,8 +214,20 @@ public:
|
|||||||
Thin3DObject() : refcount_(1) {}
|
Thin3DObject() : refcount_(1) {}
|
||||||
virtual ~Thin3DObject() {}
|
virtual ~Thin3DObject() {}
|
||||||
|
|
||||||
|
// TODO: Reconsider this annoying ref counting stuff.
|
||||||
virtual void AddRef() { refcount_++; }
|
virtual void AddRef() { refcount_++; }
|
||||||
virtual void Release() { refcount_--; if (!refcount_) delete this; }
|
virtual bool Release() {
|
||||||
|
if (refcount_ > 0 && refcount_ < 10000) {
|
||||||
|
refcount_--;
|
||||||
|
if (refcount_ == 0) {
|
||||||
|
delete this;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ELOG("Refcount (%d) invalid for object %p - corrupt?", refcount_, this);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int refcount_;
|
int refcount_;
|
||||||
|
@ -58,6 +58,9 @@ void UIScreen::update(InputState &input) {
|
|||||||
|
|
||||||
void UIScreen::preRender() {
|
void UIScreen::preRender() {
|
||||||
Thin3DContext *thin3d = screenManager()->getThin3DContext();
|
Thin3DContext *thin3d = screenManager()->getThin3DContext();
|
||||||
|
if (!thin3d) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
thin3d->Begin(true, 0xFF000000, 0.0f, 0);
|
thin3d->Begin(true, 0xFF000000, 0.0f, 0);
|
||||||
|
|
||||||
T3DViewport viewport;
|
T3DViewport viewport;
|
||||||
@ -73,6 +76,9 @@ void UIScreen::preRender() {
|
|||||||
|
|
||||||
void UIScreen::postRender() {
|
void UIScreen::postRender() {
|
||||||
Thin3DContext *thin3d = screenManager()->getThin3DContext();
|
Thin3DContext *thin3d = screenManager()->getThin3DContext();
|
||||||
|
if (!thin3d) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
thin3d->End();
|
thin3d->End();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user