Page 12 of 19
Re: Google Play New problem : 64bits
Posted: Wed Oct 09, 2024 5:00 pm
by Ats
I'm not sure if I understand why and where adding that line

So I added it to my last version of function C, with the cases, and run Omeganaut. And it doesn't change a thing.
Edit:
Back at it. So it's for making sure Params is empty before feeding it. And yeah, still the same crash:
Code: Select all
Build fingerprint: 'google/sargo/sargo:12/SP2A.220505.008/8782922:user/release-keys'
#00 0x00000000000363fc /data/app/~~pfsPeFYLh-L6FI0mvTvzTg==/com.txori.omeganaut-Dmhu9_LgECRb2AUxwz8HSg==/lib/arm64/libzgeandroid.so (SYSTEM_$$_WAITFREE_VAR$PMEMCHUNK_VAR+36) (BuildId: 7726e3554d60999736f344641edf0bf3b5d22bec)
I'm going to try to obtain a bug like that from the simple sound test.
Edit 2:
So, in Omeganaut, the game is crashing if the ZGEBullet world is set:
World = zbtCreateWorld();
Or, if a certain KeyPress component has his parameter Keys set. Out of many other KeyPress that doesn't pose problems...
And the mere presence of Keys set in this peculiar KeyPress crash the game. Even if it's not accessible when running.
Oh and if the Keys isn't set, it won't crash.
So that is just too weird...
And with sound disabled in libzgeandroid.so, all those weird problems disappears.
I didn't manage to replicate that bug on a smaller project.
Re: Google Play New problem : 64bits
Posted: Thu Oct 10, 2024 8:18 am
by VilleK
Try this change:
Code: Select all
MixAndCopyData(PBuffer, Min(OnePassSize, bufferSizeInBytes));
env^.ReleasePrimitiveArrayCritical(env, buffer, pBuffer, 0);
env^.CallNonvirtualIntMethodV(env, track, cAudioTrack, mWrite, C([buffer, 0, Min(OnePassSize, bufferSizeInBytes)]));
Re: Google Play New problem : 64bits
Posted: Thu Oct 10, 2024 10:59 am
by Ats
With
env^.CallNonvirtualIntMethodV(env, track, cAudioTrack, mWrite, C([buffer, 0, Min(OnePassSize, bufferSizeInBytes)]));
the simplest sound test crashes after a few frames, just as before. So I tried
env^.CallNonvirtualIntMethodA(env, track, cAudioTrack, mWrite, C([buffer, 0, Min(OnePassSize, bufferSizeInBytes)]));
Simple sound works, but Omeganaut still behave weirdly.
What is the use of mRelease?
mRelease := env^.GetMethodID(env, cAudioTrack, 'release', '()V');
Re: Google Play New problem : 64bits
Posted: Thu Oct 10, 2024 11:56 am
by VilleK
Indeed, it seems you should always use the "A" version over the "V" version for 64-bit, I forgot that in the code I posted.
While the game is running, the code will stay in the "while not AudioTerminated do" loop. So the "mRelease" part is for cleanup when the game is closing.
Re: Google Play New problem : 64bits
Posted: Thu Oct 10, 2024 1:34 pm
by VilleK
Maybe we should try disabling more specific stuff. What happens if you comment out this line:
env^.CallNonvirtualIntMethodA(env, track, cAudioTrack, mWrite ..
Re: Google Play New problem : 64bits
Posted: Thu Oct 10, 2024 2:32 pm
by Ats
That's a great idea. And while it still crashes, I also tried to simply exit AudioCallback right away, and Omeganaut is still crashing.
For simple audio test:
- Everything is working perfectly
For Omeganaut:
- AudioCallback: exit; is crashing with the weird things described before, same as if there was no exit
- Platform_InitAudio: exit; is working nicely (no sound)
- And if I just deactivate BeginThread( AudioCallback, nil, id); in Platform_InitAudio, it is working nicely too (no sound)
Where is BeginThread defined? In order to know what kind of parameters it is expecting, or to add logs in it (and that's why I was looking at sdlthread.inc the other day). Edit:
found it
Does it need threads to be activated? If so, I'll have the problem with BitmapExpression and MeshExpression.
Since there is no explanations in the code, I wonder in AudioCallback,
env^.PushLocalFrame(env, 2); why 2?
Env^.PopLocalFrame(Env, nil); why nil?
Re: Google Play New problem : 64bits
Posted: Thu Oct 10, 2024 4:19 pm
by VilleK
The "2" parameter is the number of local Java handles needed. You can try raising it to 20.
The nil in pop seems to be ok, it just indicates that we do not need a result.
I'm not sure why simply calling BeginThread will causing things to fail. Do you still have cthreads as first unit in ZzDC.dpr?
Re: Google Play New problem : 64bits
Posted: Thu Oct 10, 2024 4:28 pm
by Ats
cthreads and cmem.
Maybe we could ask help on Lazarus forum?
There's a thread about BeginThread() on Android here:
https://forum.lazarus.freepascal.org/in ... ic=25710.0
But the links they are referencing are pretty old (android API 8 ):
https://wiki.freepascal.org/Custom_Draw ... level_8.29
Edit:
New idea: tomorrow, I'll strip down Omeganaut of all audio to see if it still crash weirdly.
Re: Google Play New problem : 64bits
Posted: Fri Oct 11, 2024 8:30 am
by Ats
So I stripped down Omeganaut from all its sounds, and commented out all calls to them, and the game is running just fine.
But if I add one sound component again, then it crashes after a few frames with the SYSTEM_$$_WAITFREE_VAR$PMEMCHUNK_VAR+36
So, the issue might be related to audio or possibly another problem that's not present in the simple audio test but appears in Omeganaut—such as BitmapExpression, MeshExpression, or other factors. I'm going to focus on tracking down BitmapExpression bugs with threads activated, tracing everything to see if I can find something, just like I did with the audio
Edit:
That was fast
Calling exit directly on TBitmapExpression.PixelTask displays black pixels, but still crashes after a while.
BUT
Calling exit directly onTBitmapExpression.ProduceOutput displays white pixels and doesn't crash!!!
Edit 2:
More precisely, the problem seems to be coming around
TaskCount := ZMath.Min(H, Tasks.WorkerCount);
So I added traces:
Code: Select all
procedure TBitmapExpression.ProduceOutput(Content : TContent; Stack: TZArrayList);
var
SourceB,B : TZBitmap;
H,W,I : integer;
Pixels,P : PColorf;
TaskCount,RowsLeft : integer;
TaskList : pointer;
Task : PPixelTask;
TaskH : integer;
begin
AndroidLog(PAnsiChar('TBitmapExpression.ProduceOutput: Entering function'));
SourceB := GetOptionalArgument(Stack);
if SourceB<>nil then
begin
AndroidLog(PAnsiChar('TBitmapExpression.ProduceOutput: SourceB assigned from optional argument'));
B := TZBitmap.CreateFromBitmap( SourceB );
Pixels := SourceB.GetCopyAsFloats;
SourceB.Free;
end
else
begin
AndroidLog(PAnsiChar('TBitmapExpression.ProduceOutput: SourceB assigned from Content'));
B := TZBitmap.CreateFromBitmap( TZBitmap(Content) );
Pixels := nil;
end;
W := B.PixelWidth;
H := B.PixelHeight;
AndroidLog(PAnsiChar('TBitmapExpression.ProduceOutput: Bitmap dimensions: W=' + IntToStr(W) + ', H=' + IntToStr(H)));
if Pixels=nil then
begin
AndroidLog(PAnsiChar('TBitmapExpression.ProduceOutput: Pixels is nil, allocating memory'));
GetMem(Pixels,W * H * 16 );
FillChar(Pixels^,W * H * 16, 0);
end;
B.SetMemory(Pixels,GL_RGBA,GL_FLOAT);
AndroidLog(PAnsiChar('TBitmapExpression.ProduceOutput: Tasks.WorkerCount= ' + IntToStr(Tasks.WorkerCount)));
TaskCount := ZMath.Min(H, Tasks.WorkerCount);
AndroidLog(PAnsiChar('TBitmapExpression.ProduceOutput: TaskCount= ' + IntToStr(TaskCount)));
GetMem(TaskList,TaskCount*SizeOf(TPixelTask));
AndroidLog(PAnsiChar('TBitmapExpression.ProduceOutput: TaskList memory allocated'));
Task := TaskList;
RowsLeft := H;
TaskH := H div TaskCount;
P := Pixels;
for I := 0 to TaskCount-1 do
begin
Task.P := P;
Task.W := W;
Task.H := TaskH;
Dec(RowsLeft,TaskH);
if I=TaskCount-1 then
Inc(Task.H,RowsLeft); //if any rows are left then add to last task
Task.Y := I*TaskH;
Task.YStep := 1/(H-1);
AndroidLog(PAnsiChar('TBitmapExpression.ProduceOutput: Task ' + IntToStr(I) + ' - Y=' + IntToStr(Task.Y) + ', H=' + IntToStr(Task.H)));
Inc(Task);
Inc(P,W*TaskH);
end;
AndroidLog(PAnsiChar('TBitmapExpression.ProduceOutput: Running tasks'));
Tasks.Run(Self.PixelTask,TaskList,TaskCount,SizeOf(TPixelTask));
AndroidLog(PAnsiChar('TBitmapExpression.ProduceOutput: Freeing memory...'));
FreeMem(TaskList);
AndroidLog(PAnsiChar('TBitmapExpression.ProduceOutput: TaskList memory freed'));
// Needed to send the bitmap to OpenGL
B.UseTextureBegin;
AndroidLog(PAnsiChar('TBitmapExpression.ProduceOutput: Texture use started'));
FreeMem(Pixels);
AndroidLog(PAnsiChar('TBitmapExpression.ProduceOutput: Pixels memory freed'));
Stack.Push(B);
AndroidLog(PAnsiChar('TBitmapExpression.ProduceOutput: Bitmap pushed to stack, exiting function'));
end;
Oh, and with threads deactivated (just ZClasses.Tasks.Enabled := False; is sufficient now), it runs fine.
Here's the full log:
Re: Google Play New problem : 64bits
Posted: Fri Oct 11, 2024 2:08 pm
by VilleK
The log look normal to me.
It seems to boil down to that there is some general problem with Freepascal and threads on Android 64-bit.
Please remind me how you install the Freepascal compiler. Do you build it from source (if so from what branch) or do you use a prebuilt version?
Re: Google Play New problem : 64bits
Posted: Fri Oct 11, 2024 2:56 pm
by Ats
Re: Google Play New problem : 64bits
Posted: Sat Oct 12, 2024 1:04 pm
by VilleK
That version is from 2021 but I see that is the latest released version.
It would be good to test with latest trunk version. If you feel up for it, please check how to build Freepascal from source.
Re: Google Play New problem : 64bits
Posted: Sun Oct 13, 2024 8:48 am
by Ats
So I'm back at square "early September" when I was happy to find that 3.2.2 had an Android cross-compiler already compiled. Because, with the latest source code, I can build FPC from source without issues, but building the cross-compiler for Android gives:
Code: Select all
make[4]: Entering directory `C:/FPC/fpc/rtl/android'
C:/FPC/3.2.2/bin/i386-win32/gmkdir.exe -p C:/FPC/fpc/rtl/units/arm-android
arm-linux-androideabi-as -o C:/FPC/fpc/rtl/units/arm-android/prt0.o --defsym CPU32=1 prt0.as
arm-linux-androideabi-as -o C:/FPC/fpc/rtl/units/arm-android/dllprt0.o --defsym CPU32=1 dllprt0.as
C:/FPC/fpc/compiler/ppcrossarm.exe -Ur -Tandroid -Parm -XParm-linux-androideabi- -Ur -Xs -O2 -n -Fi../inc -Fi../arm -Fi../unix -Fiarm -Fi../linux -Fi../linux/arm -FE. -FUC:/FPC/fpc/rtl/units/arm-android -darm -dRELEASE -dANDROID -CpARMv7A -CfVFPv3 -Us -Sg ../linux/system.pp
C:/FPC/fpc/compiler/ppcrossarm.exe -Ur -Tandroid -Parm -XParm-linux-androideabi- -Ur -Xs -O2 -n -Fi../inc -Fi../arm -Fi../unix -Fiarm -Fi../linux -Fi../linux/arm -FE. -FUC:/FPC/fpc/rtl/units/arm-android -darm -dRELEASE -dANDROID -CpARMv7A -CfVFPv3 -Fi../objpas ../objpas/objpas.pp
C:/FPC/fpc/compiler/ppcrossarm.exe -Ur -Tandroid -Parm -XParm-linux-androideabi- -Ur -Xs -O2 -n -Fi../inc -Fi../arm -Fi../unix -Fiarm -Fi../linux -Fi../linux/arm -FE. -FUC:/FPC/fpc/rtl/units/arm-android -darm -dRELEASE -dANDROID -CpARMv7A -CfVFPv3 ../objpas/sysconst.pp
C:/FPC/fpc/compiler/ppcrossarm.exe -Ur -Tandroid -Parm -XParm-linux-androideabi- -Ur -Xs -O2 -n -Fi../inc -Fi../arm -Fi../unix -Fiarm -Fi../linux -Fi../linux/arm -FE. -FUC:/FPC/fpc/rtl/units/arm-android -darm -dRELEASE -dANDROID -CpARMv7A -CfVFPv3 ../unix/unixtype.pp
C:/FPC/fpc/compiler/ppcrossarm.exe -Ur -Tandroid -Parm -XParm-linux-androideabi- -Ur -Xs -O2 -n -Fi../inc -Fi../arm -Fi../unix -Fiarm -Fi../linux -Fi../linux/arm -FE. -FUC:/FPC/fpc/rtl/units/arm-android -darm -dRELEASE -dANDROID -CpARMv7A -CfVFPv3 ../inc/ctypes.pp
C:/FPC/fpc/compiler/ppcrossarm.exe -Ur -Tandroid -Parm -XParm-linux-androideabi- -Ur -Xs -O2 -n -Fi../inc -Fi../arm -Fi../unix -Fiarm -Fi../linux -Fi../linux/arm -FE. -FUC:/FPC/fpc/rtl/units/arm-android -darm -dRELEASE -dANDROID -CpARMv7A -CfVFPv3 ../unix/dl.pp
C:/FPC/fpc/compiler/ppcrossarm.exe -Ur -Tandroid -Parm -XParm-linux-androideabi- -Ur -Xs -O2 -n -Fi../inc -Fi../arm -Fi../unix -Fiarm -Fi../linux -Fi../linux/arm -FE. -FUC:/FPC/fpc/rtl/units/arm-android -darm -dRELEASE -dANDROID -CpARMv7A -CfVFPv3 ../inc/strings.pp
make[4]: *** No rule to make target `ptypes.inc', needed by `baseunix.ppu'. Stop.
make[4]: Leaving directory `C:/FPC/fpc/rtl/android'
make[3]: *** [android_all] Error 2
make[3]: Leaving directory `C:/FPC/fpc/rtl'
make[2]: *** [rtl_all] Error 2
make[2]: Leaving directory `C:/FPC/fpc'
make[1]: *** [build-stamp.arm-android] Error 2
make[1]: Leaving directory `C:/FPC/fpc'
make: *** [crossall] Error 2
I'm building it for 32bits using:
Code: Select all
PATH=C:\FPC\3.2.2\bin\i386-win32;C:\Android\android-ndk-r21e\toolchains\arm-linux-androideabi-4.9\prebuilt\windows-x86_64\bin;
SET FPC=C:\FPC\3.2.2\bin\i386-win32\fpc.exe
SET CROSSOPT="-dANDROID -CpARMv7A -CfVFPv3"
make clean crossall crossinstall OS_TARGET=android CPU_TARGET=arm CROSSOPT=%CROSSOPT% INSTALL_PREFIX=C:\FPC\trunk
pause
and 64bits:
Code: Select all
PATH=C:\FPC\3.2.2\bin\i386-win32;C:\Android\android-ndk-r21e\toolchains\aarch64-linux-android-4.9\prebuilt\windows-x86_64\bin;
SET FPC=C:\FPC\3.2.2\bin\i386-win32\fpc.exe
SET CROSSOPT="-dANDROID"
make clean crossall crossinstall OS_TARGET=android CPU_TARGET=aarch64 CROSSOPT=%CROSSOPT% INSTALL_PREFIX=C:\FPC\trunk
pause
But ptypes.inc is only present in those specific folders, so I don't understand why making the cross-compiler for Android would need it
in its own makefile:

- Screenshot 2024-10-13 112604.png (65.38 KiB) Viewed 3526 times
And I could build everything just fine back in 2019 with fpc 3.0.4
Re: Google Play New problem : 64bits
Posted: Sun Oct 13, 2024 2:21 pm
by Ats
Other than that, I just stumbled upon a topic saying that threads need to be synchronized with CheckSynchronize on Android.
https://forum.lazarus.freepascal.org/in ... ic=57311.0
Re: Google Play New problem : 64bits
Posted: Mon Oct 14, 2024 7:21 am
by VilleK
I think the Fpc devs are developing on Linux and Mac so they rarely test compiler building on Windows.
Maybe the "fixes_3_2" branch works better to build?
https://github.com/fpc/FPCSource/tree/fixes_3_2
The CheckSynchronize call is only needed if we use the Synchronize method but ZGE does not use that.