Google Play New problem : 64bits

All topics about ZGameEditor goes here.

Moderator: Moderators

User avatar
Ats
Posts: 791
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: Google Play New problem : 64bits

Post by Ats »

Thanks :)

So I tried the same cubes example with a shader and ES2GL3 mode and got yet another bug (in addition to the other two):

Code: Select all

********** Crash dump: **********
Build fingerprint: 'google/cheetah/cheetah:14/AP2A.240905.003/12231197:user/release-keys'
Abort message: 'Scudo ERROR: corrupted chunk header at address 0x2000079725a3b70'
#00 0x000000000005d8e4 /apex/com.android.runtime/lib64/bionic/libc.so (abort+164) (BuildId: 1d36f8ae6e0af6158793abea7d4f4f2b)
#01 0x0000000000048d18 /apex/com.android.runtime/lib64/bionic/libc.so (scudo::die()+8) (BuildId: 1d36f8ae6e0af6158793abea7d4f4f2b)
#02 0x00000000000499ec /apex/com.android.runtime/lib64/bionic/libc.so (scudo::reportRawError(char const*)+28) (BuildId: 1d36f8ae6e0af6158793abea7d4f4f2b)
#03 0x000000000004995c /apex/com.android.runtime/lib64/bionic/libc.so (scudo::ScopedErrorReport::~ScopedErrorReport()+12) (BuildId: 1d36f8ae6e0af6158793abea7d4f4f2b)
#04 0x0000000000049ac0 /apex/com.android.runtime/lib64/bionic/libc.so (scudo::reportHeaderCorruption(void*)+96) (BuildId: 1d36f8ae6e0af6158793abea7d4f4f2b)
#05 0x000000000004bab4 /apex/com.android.runtime/lib64/bionic/libc.so (scudo::Allocator<scudo::AndroidNormalConfig, &(scudo_malloc_postinit)>::deallocate(void*, scudo::Chunk::Origin, unsigned long, unsigned long)+276) (BuildId: 1d36f8ae6e0af6158793abea7d4f4f2b)
#06 0x00000000009564e4 /vendor/lib64/egl/libGLES_mali.so (gles_texturep_replica_delete_internal+100) (BuildId: 305b0cf48058c154)
#07 0x00000000009161a4 /vendor/lib64/egl/libGLES_mali.so (gles_object_original_delete_name_process+260) (BuildId: 305b0cf48058c154)
#08 0x000000000094c3cc /vendor/lib64/egl/libGLES_mali.so (gles_texture_delete_textures+140) (BuildId: 305b0cf48058c154)
#09 0x00000000000451fc /data/app/~~kWf1P5I4nEi5N_8g8M5tDQ==/com.txori.omeganaut-ly7Ki-rOEovbzEswdlt3bg==/lib/arm64/libzgeandroid.so (ZBITMAP$_$TZBITMAP_$__$$_CLEANUP+44) (BuildId: b3c75a45b542839bd3a433c084c9e6b856d45f42)
Crash dump is completed
Which should correspond to this:

Code: Select all

procedure TZBitmap.CleanUp;
begin
  if IsInitialized then
  begin
    IsInitialized := False;
    {$ifndef minimal}
    if not HasExternalHandle then
    {$endif}
      glDeleteTextures(1, @Handle);
  end;
end;
??
User avatar
Ats
Posts: 791
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: Google Play New problem : 64bits

Post by Ats »

In ZApplication.pas, what function can I totally disable in order to reduce the scope of bug hunting?
I was thinking of disabling stuff like UpdateTime or UpdateScreen in TZApplication.Main

Edit:
Oh, that is fun. With UpdateTime and UpdateScreen disabled, it is drawing the @RefreshContent(Component:BitmapClouds); on the screen. I didn't know that was done on the screen instead of in memory before rendering the rest over it.

Oh, it is weirder than that :lol:
This isn't rendering on screen:

Code: Select all

    <Bitmap Name="BitmapClouds" Width="256" Height="256">
      <Producers>
        <BitmapNoise Name="BitmapCloudNoise" Octaves="5" Offset="0.34" />
      </Producers>
    </Bitmap>
But with a blur, it is rendering:

Code: Select all

    <Bitmap Name="BitmapClouds" Width="256" Height="256">
      <Producers>
        <BitmapNoise Name="BitmapCloudNoise" Octaves="5" Offset="0.34" />
        <BitmapBlur/>
      </Producers>
    </Bitmap>
I suppose that the blur is done over the pixels rendered on screen.

Oh, in 64 bits, it is rendering only one instance of that bitmap, whereas in 32bit, it is displaying a paper wall of it :lol:
Last edited by Ats on Fri Oct 25, 2024 8:49 am, edited 1 time in total.
User avatar
VilleK
Site Admin
Posts: 2365
Joined: Mon Jan 15, 2007 4:50 pm
Location: Stockholm, Sweden
Contact:

Re: Google Play New problem : 64bits

Post by VilleK »

Ats wrote: Fri Oct 25, 2024 8:14 am Oh, that is fun. With UpdateTime and UpdateScreen disabled, it is drawing the @RefreshContent(Component:BitmapClouds); on the screen. I didn't know that was done on the screen instead of in memory before rendering the rest over it.
This happens only on Android because using GL ES we cannot ask the texture to give us the pixels back to memory. Instead ZGE must paint the texture to screen and then read the pixels back from screen memory. It does this when there are multiple bitmapproducers connected to each other, since they operate on the output from the previous one.

I hope the root of the problem you are having is not about bugs in the GL ES implementation on Android 64.

Does the crash not happen in emulation using Android Studio?
User avatar
Ats
Posts: 791
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: Google Play New problem : 64bits

Post by Ats »

In the emulator, Omeganaut will crash randomly with that error:

Code: Select all

2024-10-25 11:21:40.616   582-634   ActivityTaskManager     system_server                        I  Displayed com.txori.omeganaut/org.zgameeditor.ZgeActivity for user 0: +1s54ms
2024-10-25 11:21:41.401  7603-7629  SurfaceSyncGroup        com.txori.omeganaut                  E  Failed to receive transaction ready in 1000ms. Marking SurfaceSyncGroup(wmsSync-VRI[ZgeActivity]#1) as ready
2024-10-25 11:21:41.401  7603-7629  SurfaceSyncGroup        com.txori.omeganaut                  E  Failed to receive transaction ready in 1000ms. Marking SurfaceSyncGroup(VRI[ZgeActivity]#2) as ready
2024-10-25 11:21:41.403  7603-7629  SurfaceSyncGroup        com.txori.omeganaut                  E  Failed to receive transaction ready in 1000ms. Marking SurfaceSyncGroup(SurfaceView[com.txori.omeganaut/org.zgameeditor.ZgeActivity]#0) as ready
2024-10-25 11:21:41.507  7639-7639  DEBUG                   crash_dump64                         A        #01 pc 0000000000045fec  /data/app/~~vokSXyszjYpZfy3-b4FtSw==/com.txori.omeganaut-b80DmRnGf1FX-9XtZRhE-g==/lib/arm64/libzgeandroid.so (BITMAPPRODUCERS$_$TBITMAPEXPRESSION_$__$$_PIXELTASK$POINTER+140) (BuildId: db7f48cb4d54c874d5802d20cc48632d50eb895f)
2024-10-25 11:21:41.516   582-7645  ActivityTaskManager     system_server                        W    Force finishing activity com.txori.omeganaut/org.zgameeditor.ZgeActivity
2024-10-25 11:21:41.540   582-628   WindowManager           system_server                        I  WIN DEATH: Window{9316d78 u0 com.txori.omeganaut/org.zgameeditor.ZgeActivity}
2024-10-25 11:21:41.541   582-628   InputManager-JNI        system_server                        W  Input channel object '9316d78 com.txori.omeganaut/org.zgameeditor.ZgeActivity (client)' was disposed without first being removed with the input manager!
2024-10-25 11:21:42.019   582-637   ActivityTaskManager     system_server                        W  Activity top resumed state loss timeout for ActivityRecord{258b52b u0 com.txori.omeganaut/org.zgameeditor.ZgeActivity t22 f} isExiting}
2024-10-25 11:21:42.269   582-1428  WindowManager           system_server                        W  Exception thrown during dispatchAppVisibility Window{9316d78 u0 com.txori.omeganaut/org.zgameeditor.ZgeActivity EXITING}
                                                                                                    android.os.DeadObjectException
                                                                                                    	at android.os.BinderProxy.transactNative(Native Method)
                                                                                                    	at android.os.BinderProxy.transact(BinderProxy.java:586)
                                                                                                    	at android.view.IWindow$Stub$Proxy.dispatchAppVisibility(IWindow.java:553)
                                                                                                    	at com.android.server.wm.WindowState.sendAppVisibilityToClients(WindowState.java:3253)
                                                                                                    	at com.android.server.wm.WindowContainer.sendAppVisibilityToClients(WindowContainer.java:1289)
                                                                                                    	at com.android.server.wm.WindowToken.setClientVisible(WindowToken.java:403)
                                                                                                    	at com.android.server.wm.ActivityRecord.setClientVisible(ActivityRecord.java:7166)
                                                                                                    	at com.android.server.wm.ActivityRecord.postApplyAnimation(ActivityRecord.java:5881)
                                                                                                    	at com.android.server.wm.ActivityRecord.commitVisibility(ActivityRecord.java:5823)
                                                                                                    	at com.android.server.wm.Transition.finishTransition(Transition.java:1286)
                                                                                                    	at com.android.server.wm.TransitionController.finishTransition(TransitionController.java:937)
                                                                                                    	at com.android.server.wm.WindowOrganizerController.finishTransition(WindowOrganizerController.java:494)
                                                                                                    	at android.window.IWindowOrganizerController$Stub.onTransact(IWindowOrganizerController.java:289)
                                                                                                    	at com.android.server.wm.WindowOrganizerController.onTransact(WindowOrganizerController.java:204)
                                                                                                    	at android.os.Binder.execTransactInternal(Binder.java:1505)
                                                                                                    	at android.os.Binder.execTransact(Binder.java:1444)
And after turning on the linux laptop and copying libzgeandroid.so on it in order to run addr2line, it says the problem is coming from this line in procedure TBitmapExpression.PixelTask(Task: pointer);

Env.StackPushPointer(A);

Which is defined in ZExpression.pas:

Code: Select all

//Push 32 or 64-bit value depending on architechture
procedure TExecutionEnvironment.StackPushPointer(const X);
begin
  {$ifdef debug}
  if StackGetDepth>=High(ZcStack) then
    ScriptError('Zc Stack Overflow (infinite recursion?)');
  {$endif}
  ZcStackPtr^ := TStackElement( PPointer(@X)^ );
  Inc(ZcStackPtr);
end;
Pointers, 64bits... Could that be it?

Edit:
I added some traces to that function:

Code: Select all

2024-10-25 11:55:10.278  8504-8528  ZgeAndroid              com.txori.omeganaut                  E  StackPushPointer: Attempting to push pointer onto stack
2024-10-25 11:55:10.278  8504-8528  ZgeAndroid              com.txori.omeganaut                  E  StackPushPointer: Pushed pointer value = 133805396783184
2024-10-25 11:55:10.278  8504-8528  ZgeAndroid              com.txori.omeganaut                  E  StackPushPointer: Stack pointer incremented
2024-10-25 11:55:10.304  8504-8528  ZgeAndroid              com.txori.omeganaut                  E  StackPushPointer: Attempting to push pointer onto stack
2024-10-25 11:55:10.305  8504-8528  ZgeAndroid              com.txori.omeganaut                  E  StackPushPointer: Pushed pointer value = 133808886490664
2024-10-25 11:55:10.305  8504-8528  ZgeAndroid              com.txori.omeganaut                  E  StackPushPointer: Stack pointer incremented
2024-10-25 11:55:10.306  8504-8535  ZgeAndroid              com.txori.omeganaut                  E  StackPushPointer: Attempting to push pointer onto stack
2024-10-25 11:55:10.306  8504-8535  ZgeAndroid              com.txori.omeganaut                  E  StackPushPointer: Pushed pointer value = 133808349650728
2024-10-25 11:55:10.306  8504-8535  ZgeAndroid              com.txori.omeganaut                  E  StackPushPointer: Stack pointer incremented
2024-10-25 11:55:10.441  8504-8529  SurfaceSyncGroup        com.txori.omeganaut                  E  Failed to receive transaction ready in 1000ms. Marking SurfaceSyncGroup(wmsSync-VRI[ZgeActivity]#1) as ready
2024-10-25 11:55:10.442  8504-8529  SurfaceSyncGroup        com.txori.omeganaut                  E  Failed to receive transaction ready in 1000ms. Marking SurfaceSyncGroup(VRI[ZgeActivity]#2) as ready
2024-10-25 11:55:10.443  8504-8529  SurfaceSyncGroup        com.txori.omeganaut                  E  Failed to receive transaction ready in 1000ms. Marking SurfaceSyncGroup(SurfaceView[com.txori.omeganaut/org.zgameeditor.ZgeActivity]#0) as ready
2024-10-25 11:55:11.182  8541-8541  DEBUG                                                        A        #01 pc 000000000004601c  /data/app/~~gxsrDWhkfKHpV04LqWWLQw==/com.txori.omeganaut-K-jVDimzbhxXHqPY66al8Q==/lib/arm64/libzgeandroid.so (BITMAPPRODUCERS$_$TBITMAPEXPRESSION_$__$$_PIXELTASK$POINTER+140) (BuildId: 85879bf926d87c11b24acdfb6233d38583868e06)
User avatar
VilleK
Site Admin
Posts: 2365
Joined: Mon Jan 15, 2007 4:50 pm
Location: Stockholm, Sweden
Contact:

Re: Google Play New problem : 64bits

Post by VilleK »

Ats wrote: Fri Oct 25, 2024 9:22 am Pointers, 64bits... Could that be it?
I doubt it, but you can test this change:

Code: Select all

procedure TExecutionEnvironment.StackPushPointer(X: pointer);
begin
  {$ifdef debug}
  if StackGetDepth>=High(ZcStack) then
    ScriptError('Zc Stack Overflow (infinite recursion?)');
  {$endif}
  ZcStackPtr^ := TStackElement( X );
  Inc(ZcStackPtr);
end;
Then you also need to add some pointer casts where ever it complains.

Code: Select all

    loLoad: Env.StackPushPointer(pointer(P^));  // added "pointer() around p^
User avatar
Ats
Posts: 791
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: Google Play New problem : 64bits

Post by Ats »

Nope, that's not it...

So I tried something else:
In Android Studio, the old version of Omeganaut crash instantly with this message:

Code: Select all

2024-10-25 16:22:47.539 11986-11986 DEBUG                   crash_dump64                         A        #01 pc 0000000000045fec  /data/app/~~HS9PFsTspxTG-3gCY_1big==/com.txori.omeganaut-NAXMKI2-Q7qBcBbaqtxJrA==/lib/arm64/libzgeandroid.so (BITMAPPRODUCERS$_$TBITMAPEXPRESSION_$__$$_PIXELTASK$POINTER+140) (BuildId: a899f161e77f412a27f84b58778092b43fa9c8a2)
But it can run fine for a while if I add a direct exit() on TBitmapExpression.PixelTask. Then it randomly crashes later on with some other message that I posted several times already.


Other than that, in the log, beside all the gl functions not found, there is this one: 'Function not found: JNI_OnLoad'
This message comes from:

Code: Select all

function Platform_GetModuleProc(Module : NativeUInt; const Name : PAnsiChar) : pointer;
begin
  Result := dlsym(Pointer(Module), Name);
  if Result=nil then
    Platform_Error(PChar('Function not found: ' + Name));
end;
Why doesn't it trace 'Found JNI_OnLoad function, calling now...' from this function instead?

Code: Select all

function Platform_LoadModule(const Name : PAnsiChar) : NativeUInt;
var
  Buf : array[0..511] of AnsiChar;
  TheName : PAnsiChar;
  InitFunc : function(vm:PJavaVM;reserved:pointer):jint; cdecl;
begin
  if Name^='.' then
  begin
    MakeFullPath(Name,AndroidLibraryPath,Buf);
    TheName := @Buf;
  end
  else
    TheName := Name;
  Result := NativeUInt( dlopen(TheName,1) );
  if Result=0 then
  begin
    Platform_Error( PAnsiChar('failed to load: ' + TheName) );
  end;

  InitFunc := Platform_GetModuleProc(Result,'JNI_OnLoad');
  if @InitFunc<>nil then
  begin
    AndroidLog('Found JNI_OnLoad function, calling now...');
    InitFunc(curVM,nil);
  end;

end;
User avatar
Ats
Posts: 791
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: Google Play New problem : 64bits

Post by Ats »

I may have found something!!! 8)

In procedure TBitmapExpression.PixelTask(Task: pointer);
XStep is calculated like that: XStep := 1/(T.W-1);

But in Omeganaut, I have a texture with width = 1. Since it is stretched on the entire screen, I thought that it would prevent to calculate a lot of pixels for nothing. Also, nothing prevents the user to do that in the ZGameEditor interface, and it was running fine on Android 32 for years.

Code: Select all

<Bitmap Name="Bitmap_Sky_Gradient" Width="1" Height="5">
  <Producers>
    <BitmapExpression Name="SkyColorBitmap">
      <Expression>
<![CDATA[if(Y > 0.8)
{
  // Top color
  Pixel.R = GradientData[3];
  Pixel.G = GradientData[4];
  Pixel.B = GradientData[5];
}
else if (Y > 0.7 && Y <= 0.8)
{
  // Middle color
  Pixel.R = (GradientData[0] + GradientData[3]) * 0.5;
  Pixel.G = (GradientData[1] + GradientData[4]) * 0.5;
  Pixel.B = (GradientData[2] + GradientData[5]) * 0.5;
}
else
{
  // Bottom color
  Pixel.R = GradientData[0];
  Pixel.G = GradientData[1];
  Pixel.B = GradientData[2];
}

Pixel.A = 1;]]>
      </Expression>
    </BitmapExpression>
  </Producers>
</Bitmap>
So when I log XStep with AndroidLog(PAnsiChar('PixelTask: XStep calculated as ' + FloatToStr(XStep)));
I get 'PixelTask: XStep calculated as +Inf' and a crash a bit later, as it is not instantaneous...

So I modified TBitmapExpression.PixelTask with:

Code: Select all

var
  stepCount: integer;

...

  stepCount := T.W - 1;
  if stepCount <= 0 then
    stepCount := 1;
  XStep := 1 / stepCount;
And now it is running perfectly without crashing right away on Android Studio.
It can still crash later on during the game, but as I said earlier, this might be coming from somewhere else.
Since I had that 1x5 bitmap for years, is Android 64 handling infinite number differently than Android 32?

The only drawback I see with this modification is that bitmap circles such as :

Code: Select all

<Bitmap Name="VGBitmap" Width="128" Height="128">
  <Producers>
    <BitmapExpression>
      <Expression>
<![CDATA[float u, v;

u = 0.5-X;
v = 0.5-Y;

Pixel.R = 1;
Pixel.G = 1;
Pixel.B = 1;
Pixel.A = clamp(8 - sqrt(u*u+v*v) * 16, 0, 0.2);]]>
      </Expression>
    </BitmapExpression>
  </Producers>
</Bitmap>
are now broken:
1000022049.png
1000022049.png (524.71 KiB) Viewed 2783 times

But I don't know why. Can XStep be negative?

Edit:
Maybe this is faster code, I'm not sure:

Code: Select all

stepCount := T.W - 1;
XStep := 1 / (stepCount + Ord(stepCount = 0));
Last edited by Ats on Fri Oct 25, 2024 4:57 pm, edited 2 times in total.
User avatar
VilleK
Site Admin
Posts: 2365
Joined: Mon Jan 15, 2007 4:50 pm
Location: Stockholm, Sweden
Contact:

Re: Google Play New problem : 64bits

Post by VilleK »

Interesting, nice find! It should not have any effect on the circle bitmap so not sure what that is about. I won't have time to look at this over the weekend but please keep me posted if you find anything else.
User avatar
Ats
Posts: 791
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: Google Play New problem : 64bits

Post by Ats »

So I reverted every test I made for the last few days, and just added the modification to calculate XStep, and now the circles are fine. I'm going to play for a while and see if there are other surprises :wink:

Edit:
I played for a long while and only got it to bug once, the bug with the unhelpful message:

Code: Select all

Build fingerprint: 'google/cheetah/cheetah:14/AP2A.240905.003/12231197:user/release-keys'
#00 0x0000000000000004 <anonymous:7a63242000>
Edit 2:
While it is definitely better, there are still some hiccups going on here and there.
For instance, any app on libzgeandroid 64 can crash right from the start with the bugs listed here: https://www.emix8.org/forum/viewtopic.p ... &start=195
User avatar
Ats
Posts: 791
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: Google Play New problem : 64bits

Post by Ats »

I already asked this before, but is it normal that JNI_OnLoad isn't found at startup?

It is defined in jni.pas

Code: Select all

function JNI_OnLoad(vm:PJavaVM;reserved:pointer):jint;{$ifdef mswindows}stdcall;{$else}cdecl;{$endif}
const curVM:PJavaVM=nil;
      curEnv:PJNIEnv=nil;
implementation
function JNI_OnLoad(vm:PJavaVM;reserved:pointer):jint;{$ifdef mswindows}stdcall;{$else}cdecl;{$endif}
begin
 curVM:=vm;
 result:=JNI_VERSION_1_6;
end;
It is exported in ZgeAndroid.pas:

Code: Select all

exports JNI_OnLoad;
Yet, Platform_GetModuleProc isn't able to find it:

Code: Select all

function Platform_GetModuleProc(Module : NativeUInt; const Name : PAnsiChar) : pointer;
begin
  AndroidLog(PAnsiChar('Platform_GetModuleProc: Looking for function ' + Name));
  
  Result := dlsym(Pointer(Module), Name);
  
  if Result = nil then
  begin
    AndroidLog(PAnsiChar('Platform_GetModuleProc: Function not found: ' + Name + ' !!!!'));
  end
  else
  begin
    AndroidLog(PAnsiChar('Platform_GetModuleProc: Found function ' + Name));
  end;
end;
dlsym is declared like that:

Code: Select all

function dlsym  ( Lib : Pointer; Name : PAnsiChar) : Pointer; cdecl; external 'dl';
Is that normal or is that a problem?

I added a few traces here:

Code: Select all

function Platform_LoadModule(const Name : PAnsiChar) : NativeUInt;
var
  Buf : array[0..511] of AnsiChar;
  TheName : PAnsiChar;
  InitFunc : function(vm:PJavaVM;reserved:pointer):jint; cdecl;
begin
  AndroidLog(PAnsiChar('Platform_LoadModule: Attempting to load module ' + Name));

  if Name^ = '.' then
  begin
    MakeFullPath(Name, AndroidLibraryPath, Buf);
    TheName := @Buf;
    AndroidLog(PAnsiChar('Platform_LoadModule: Resolved full path to ' + TheName));
  end
  else
  begin
    TheName := Name;
    AndroidLog(PAnsiChar('Platform_LoadModule: Using provided path ' + TheName));
  end;

  Result := NativeUInt(dlopen(TheName, 1));
  if Result = 0 then
  begin
    Platform_Error(PAnsiChar('Platform_LoadModule: Failed to load module ' + TheName));
    //Exit;  // Exit early if the module failed to load
  end
  else
  begin
    AndroidLog(PAnsiChar('Platform_LoadModule: Successfully loaded module ' + TheName));
  end;

  AndroidLog(PChar('Platform_GetModuleProc trying to get InitFunc with ' + IntToStr(Result)));

  InitFunc := Platform_GetModuleProc(Result, 'JNI_OnLoad');
  if @InitFunc = nil then
  begin
    AndroidLog('Platform_GetModuleProc did not find JNI_OnLoad');
  end
  else
  begin
    AndroidLog('Found JNI_OnLoad function, calling now...');
    InitFunc(curVM, nil);
    AndroidLog('JNI_OnLoad function executed successfully');
  end;
end;
It gives:

Code: Select all

10-26 13:25:55.603 21821 21847 E ZgeAndroid: Platform_LoadModule: Attempting to load module libGLESv2.so
10-26 13:25:55.603 21821 21847 E ZgeAndroid: Platform_LoadModule: Using provided path libGLESv2.so
10-26 13:25:55.607 21821 21847 E ZgeAndroid: Platform_LoadModule: Successfully loaded module libGLESv2.so
10-26 13:25:55.610 21821 21847 E ZgeAndroid: Platform_GetModuleProc trying to get InitFunc with 5725710770757954339 (each time a new random number)
10-26 13:25:55.629 21821 21847 E ZgeAndroid: Platform_GetModuleProc: Function not found: JNI_OnLoad !!!!
10-26 13:25:55.629 21821 21847 E ZgeAndroid: Platform_GetModuleProc did not find JNI_OnLoad
User avatar
VilleK
Site Admin
Posts: 2365
Joined: Mon Jan 15, 2007 4:50 pm
Location: Stockholm, Sweden
Contact:

Re: Google Play New problem : 64bits

Post by VilleK »

I believe JNI_OnLoad is called automatically when the ZGE app is loaded. ZGE only needs to call this when loading other modules, if it exists.

You can try writing logging something in the JNI_OnLoad function to show that it is called.

The thing with floating point errors is interesting and perhaps the reason it crashes after a while.

Does it crash with this expression that forces a division by zero, and if so what does the crash log looks like?

Code: Select all

float x=1, y=0, z=x/y;
User avatar
Ats
Posts: 791
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: Google Play New problem : 64bits

Post by Ats »

Code: Select all

float x=1, y=0, z=x/y;
doesn't seem to bother the phone, but it crashes on Android Studio if it is located in OnUpdate. It doesn't crash if it is calculated only once at start.

Shouldn't this be handled by ZPlatform_Android.inc ?

Code: Select all

Math.SetExceptionMask([exZeroDivide,exOverflow,exUnderflow,exPrecision,exDenormalized,exInvalidOp]);
There's a discussion about exZeroDivide in Lazarus forum:
For floating point operations I can set an exception mask for division-by- zero as SetExceptionMask([exZeroDivide]); However, this doesn't work for integer div-by-zero (Show_exception(E) returns "Exception class: EDivByZero").



Also, I think I managed to locate one last thing that can randomly crash on the phone, and crashes 95% of the time on Android Studio, just like the division by zero that could happen in BitmapProducers.pas
I'm currently stripping it down.
Last edited by Ats on Mon Oct 28, 2024 12:43 pm, edited 2 times in total.
User avatar
Ats
Posts: 791
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: Google Play New problem : 64bits

Post by Ats »

All right, the problem seems to be coming from here:

Code: Select all

<Bitmap Name="BitmapSpaceColors" Width="5" Height="1">
  <Producers>
    <BitmapExpression>
      <Expression>
<![CDATA[float c1 = cos(X + 1);
float c2 = cos(X - 1);

Pixel.R = NebulaeColor1.R * c1 + NebulaeColor2.R * c2;
Pixel.G = NebulaeColor1.G * c1 + NebulaeColor2.G * c2;
Pixel.B = NebulaeColor1.B * c1 + NebulaeColor2.B * c2;
Pixel.A = 1;

// Sauvegarde de la couleur centrale pour le FOG
// 0.5 fonctionne sin Bitmap width est impair
//if (X > 0.48 && X < 0.51)
if (X == 0.5)
{
  CloudColorPicker.X = Pixel.R * 0.4;
  CloudColorPicker.Y = Pixel.G * 0.4;
  CloudColorPicker.Z = Pixel.B * 0.4;
 // trace(intToStr(CloudColorPicker.X * 100)+"  "+intToStr(CloudColorPicker.Y * 100)+"  "+intToStr(CloudColorPicker.Z * 100));
}]]>
      </Expression>
    </BitmapExpression>
  </Producers>
</Bitmap>
It doesn't crash if I modify the bitmap height which is currently 1.
User avatar
Ats
Posts: 791
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: Google Play New problem : 64bits

Post by Ats »

And the problem comes from
Task.YStep := 1/(H-1);

in

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
  SourceB := GetOptionalArgument(Stack);
  if SourceB<>nil then
  begin
    B := TZBitmap.CreateFromBitmap( SourceB );
    Pixels := SourceB.GetCopyAsFloats;
    SourceB.Free;
  end
  else
  begin
    B := TZBitmap.CreateFromBitmap( TZBitmap(Content) );
    Pixels := nil;
  end;

  W := B.PixelWidth;
  H := B.PixelHeight;

  if Pixels=nil then
  begin
    GetMem(Pixels,W * H * 16 );
    FillChar(Pixels^,W * H * 16, 0);
  end;

  B.SetMemory(Pixels,GL_RGBA,GL_FLOAT);


  TaskCount := ZMath.Min(H, Tasks.WorkerCount);
  GetMem(TaskList,TaskCount*SizeOf(TPixelTask));
  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);
    Inc(Task);
    Inc(P,W*TaskH);
  end;

  Tasks.Run(Self.PixelTask,TaskList,TaskCount,SizeOf(TPixelTask));

  FreeMem(TaskList);

  //Needed to send the bitmap to opengl
  B.UseTextureBegin;

  FreeMem(Pixels);

  Stack.Push(B);
end;
It can be handled by doing this:

Code: Select all

if H > 1 then
  Task.YStep := 1 / (H - 1)
else
  Task.YStep := 0;
or maybe doing it like I did for
XStep := 1 / (stepCount + Ord(stepCount = 0));

in

Code: Select all

procedure TBitmapExpression.PixelTask(Task: pointer);
var
  Env : TExecutionEnvironment;
  A : TDefineArray;
  X,Y : PSingle;
  XStep : single;
  T : PPixelTask;
  I,J,stepCount: integer;
begin
  T := PPixelTask(Task);

  A := TDefineArray.Create(nil);
  A.SizeDim1 := 4;

  Env.Init;
  Env.StackPush(X);
  Env.StackPush(Y);
  Env.StackPushPointer(A);

  X := PSingle(Env.StackGetPtrToItem(0));
  Y := PSingle(Env.StackGetPtrToItem(1));

  stepCount := T.W - 1;
  XStep := 1 / (stepCount + Ord(stepCount = 0));

  Y^ := T.Y*T.YStep;

  for I := 0 to T.H-1 do
  begin
    X^ := 0.0;
    for J := 0 to T.W-1 do
    begin
      A.SetExternalData(T.P);
      ZExpressions.RunCode(Expression.Code,@Env);
      Inc(T.P);
      X^ := X^ + XStep;
    end;
    Y^ := Y^ + T.YStep;
  end;

  A.Free;
end;
I don't know how you prefer to handle this in your code :wink:
User avatar
VilleK
Site Admin
Posts: 2365
Joined: Mon Jan 15, 2007 4:50 pm
Location: Stockholm, Sweden
Contact:

Re: Google Play New problem : 64bits

Post by VilleK »

I guess we need to set the exception flags per thread. Try this change in zclasses.pas:

Code: Select all

procedure TTasks.TWorkerThread.Execute;
begin
  Math.SetExceptionMask([exZeroDivide,exOverflow,exUnderflow,exPrecision,exDenormalized,exInvalidOp]);  // <<-- add this line
  while not Terminated do
  begin
    Platform_WaitEvent(Self.Tasks.Event);
    while (not Terminated) and Self.Tasks.RunNext do ;
  end;
end;
Post Reply