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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1703,29 +1703,29 @@ void __KernelReSchedule(const char *reason)
|
||||
|
||||
// Execute any pending events while we're doing scheduling.
|
||||
CoreTiming::Advance();
|
||||
if (__IsInInterrupt() || !__KernelIsDispatchEnabled())
|
||||
{
|
||||
if (__IsInInterrupt() || !__KernelIsDispatchEnabled()) {
|
||||
// Threads don't get changed within interrupts or while dispatch is disabled.
|
||||
reason = "In Interrupt Or Callback";
|
||||
return;
|
||||
}
|
||||
|
||||
Thread *nextThread = __KernelNextThread();
|
||||
if (nextThread)
|
||||
if (nextThread) {
|
||||
__KernelSwitchContext(nextThread, reason);
|
||||
}
|
||||
// Otherwise, no need to switch.
|
||||
}
|
||||
|
||||
void __KernelReSchedule(bool doCallbacks, const char *reason)
|
||||
{
|
||||
Thread *thread = __GetCurrentThread();
|
||||
if (doCallbacks)
|
||||
{
|
||||
if (thread)
|
||||
thread->isProcessingCallbacks = doCallbacks;
|
||||
if (doCallbacks && thread != nullptr) {
|
||||
thread->isProcessingCallbacks = doCallbacks;
|
||||
}
|
||||
|
||||
// Note - this calls the function above, not this one. Overloading...
|
||||
__KernelReSchedule(reason);
|
||||
if (doCallbacks && thread != NULL && thread->GetUID() == currentThread) {
|
||||
if (doCallbacks && thread != nullptr && thread->GetUID() == currentThread) {
|
||||
if (thread->isRunning()) {
|
||||
thread->isProcessingCallbacks = false;
|
||||
}
|
||||
|
@ -155,15 +155,18 @@ namespace Reporting
|
||||
if (output == NULL)
|
||||
output = &theVoid;
|
||||
|
||||
if (http.Resolve(ServerHostname(), ServerPort()))
|
||||
{
|
||||
const char *serverHost = ServerHostname();
|
||||
if (!serverHost)
|
||||
return false;
|
||||
|
||||
if (http.Resolve(serverHost, ServerPort())) {
|
||||
http.Connect();
|
||||
http.POST(uri, data, mimeType, output);
|
||||
http.Disconnect();
|
||||
result = true;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
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)
|
||||
if (!at3Reader && bgGamePath.size() && (time_now_d() - gameLastChanged > 0.5)) {
|
||||
// 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);
|
||||
if (!gameInfo)
|
||||
return 0;
|
||||
|
@ -611,7 +611,9 @@ void NativeShutdownGraphics() {
|
||||
delete g_gameInfoCache;
|
||||
g_gameInfoCache = nullptr;
|
||||
|
||||
uiTexture->Release();
|
||||
if (uiTexture->Release()) {
|
||||
uiTexture = nullptr;
|
||||
}
|
||||
|
||||
delete uiContext;
|
||||
uiContext = NULL;
|
||||
@ -619,7 +621,10 @@ void NativeShutdownGraphics() {
|
||||
ui_draw2d.Shutdown();
|
||||
ui_draw2d_front.Shutdown();
|
||||
|
||||
thin3d->Release();
|
||||
// TODO: Reconsider this annoying ref counting stuff.
|
||||
if (thin3d->Release()) {
|
||||
thin3d = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void TakeScreenshot() {
|
||||
|
@ -73,19 +73,22 @@ bool OpenSLWrap_Init(AndroidAudioCallback cb, int _FramesPerBuffer, int _SampleR
|
||||
framesPerBuffer = 256;
|
||||
if (framesPerBuffer < 32)
|
||||
framesPerBuffer = 32;
|
||||
if (framesPerBuffer > 4096)
|
||||
framesPerBuffer = 4096;
|
||||
|
||||
sampleRate = _SampleRate;
|
||||
if (sampleRate != 44100 && sampleRate != 48000) {
|
||||
ELOG("Invalid sample rate %i - choosing 44100", sampleRate);
|
||||
sampleRate = 44100;
|
||||
}
|
||||
|
||||
buffer[0] = new short[framesPerBuffer * 2];
|
||||
buffer[1] = new short[framesPerBuffer * 2];
|
||||
|
||||
SLresult result;
|
||||
// create engine
|
||||
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);
|
||||
assert(SL_RESULT_SUCCESS == result);
|
||||
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;
|
||||
if (sampleRate == 48000) {
|
||||
sr = SL_SAMPLINGRATE_48;
|
||||
}
|
||||
} // Don't allow any other sample rates.
|
||||
|
||||
SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2};
|
||||
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 SLboolean req[2] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
|
||||
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);
|
||||
assert(SL_RESULT_SUCCESS == result);
|
||||
@ -138,6 +145,9 @@ bool OpenSLWrap_Init(AndroidAudioCallback cb, int _FramesPerBuffer, int _SampleR
|
||||
assert(SL_RESULT_SUCCESS == result);
|
||||
|
||||
// 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;
|
||||
audioCallback(buffer[curBuffer], framesPerBuffer);
|
||||
|
||||
@ -151,40 +161,44 @@ bool OpenSLWrap_Init(AndroidAudioCallback cb, int _FramesPerBuffer, int _SampleR
|
||||
|
||||
// shut down the native audio system
|
||||
void OpenSLWrap_Shutdown() {
|
||||
SLresult result;
|
||||
ILOG("OpenSLWrap_Shutdown - stopping playback");
|
||||
result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_STOPPED);
|
||||
if (SL_RESULT_SUCCESS != result) {
|
||||
ELOG("SetPlayState failed");
|
||||
if (bqPlayerPlay) {
|
||||
ILOG("OpenSLWrap_Shutdown - stopping playback");
|
||||
SLresult result;
|
||||
result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_STOPPED);
|
||||
if (SL_RESULT_SUCCESS != result) {
|
||||
ELOG("SetPlayState failed");
|
||||
}
|
||||
}
|
||||
|
||||
ILOG("OpenSLWrap_Shutdown - deleting player object");
|
||||
|
||||
if (bqPlayerObject != NULL) {
|
||||
if (bqPlayerObject) {
|
||||
(*bqPlayerObject)->Destroy(bqPlayerObject);
|
||||
bqPlayerObject = NULL;
|
||||
bqPlayerPlay = NULL;
|
||||
bqPlayerBufferQueue = NULL;
|
||||
bqPlayerMuteSolo = NULL;
|
||||
bqPlayerVolume = NULL;
|
||||
bqPlayerObject = nullptr;
|
||||
bqPlayerPlay = nullptr;
|
||||
bqPlayerBufferQueue = nullptr;
|
||||
bqPlayerMuteSolo = nullptr;
|
||||
bqPlayerVolume = nullptr;
|
||||
}
|
||||
|
||||
ILOG("OpenSLWrap_Shutdown - deleting mix object");
|
||||
|
||||
if (outputMixObject != NULL) {
|
||||
if (outputMixObject) {
|
||||
(*outputMixObject)->Destroy(outputMixObject);
|
||||
outputMixObject = NULL;
|
||||
outputMixObject = nullptr;
|
||||
}
|
||||
|
||||
ILOG("OpenSLWrap_Shutdown - deleting engine object");
|
||||
|
||||
if (engineObject != NULL) {
|
||||
if (engineObject) {
|
||||
(*engineObject)->Destroy(engineObject);
|
||||
engineObject = NULL;
|
||||
engineEngine = NULL;
|
||||
engineObject = nullptr;
|
||||
engineEngine = nullptr;
|
||||
}
|
||||
delete [] buffer[0];
|
||||
delete [] buffer[1];
|
||||
buffer[0] = nullptr;
|
||||
buffer[1] = nullptr;
|
||||
ILOG("OpenSLWrap_Shutdown - finished");
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,8 @@
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "base/logging.h"
|
||||
|
||||
class Matrix4x4;
|
||||
|
||||
enum T3DBlendEquation : int {
|
||||
@ -212,8 +214,20 @@ public:
|
||||
Thin3DObject() : refcount_(1) {}
|
||||
virtual ~Thin3DObject() {}
|
||||
|
||||
// TODO: Reconsider this annoying ref counting stuff.
|
||||
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:
|
||||
int refcount_;
|
||||
|
@ -58,6 +58,9 @@ void UIScreen::update(InputState &input) {
|
||||
|
||||
void UIScreen::preRender() {
|
||||
Thin3DContext *thin3d = screenManager()->getThin3DContext();
|
||||
if (!thin3d) {
|
||||
return;
|
||||
}
|
||||
thin3d->Begin(true, 0xFF000000, 0.0f, 0);
|
||||
|
||||
T3DViewport viewport;
|
||||
@ -73,6 +76,9 @@ void UIScreen::preRender() {
|
||||
|
||||
void UIScreen::postRender() {
|
||||
Thin3DContext *thin3d = screenManager()->getThin3DContext();
|
||||
if (!thin3d) {
|
||||
return;
|
||||
}
|
||||
thin3d->End();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user