Google Play New problem : 64bits

All topics about ZGameEditor goes here.

Moderator: Moderators

User avatar
VilleK
Site Admin
Posts: 2382
Joined: Mon Jan 15, 2007 4:50 pm
Location: Stockholm, Sweden
Contact:

Re: Google Play New problem : 64bits

Post by VilleK »

Ats wrote: Mon Apr 21, 2025 7:51 pm So I've been trying to fix the warnings: "Converting pointers to signed integers may result in wrong comparison results and range errors, use an unsigned type instead."
You could try if changing to NativeUInt helps with the crashes. But otherwise I would not bother. The Delphi compiler does not warn about these lines.

If you load files using the File component during the game then the comment that Gemini had about ReadAssetFile would be good to take a look at.

The TRTLCriticalSection change is most likely the main bug here. It makes sense too since you already figured out it was somehow related to threaded code. How frequent are crashes after you fixed this bug?
User avatar
Kjell
Posts: 1935
Joined: Sat Feb 23, 2008 11:15 pm

Re: Google Play New problem : 64bits

Post by Kjell »

Hi guys,

I'm no Pascal / Delphi expert .. but why not use (regular) pointer arithmetic instead of converting back & forth between a integer and pointer?

And the "does not seem to be initialized" warnings are the compiler being dumb ( afaik ):

- In case of "ScaledGravity" it's only being initialized when UseGravity is TRUE, but it's only being used when UseGravity is TRUE anyway.
- In case of "TextBuf" it's because when Self.Text isn't NULL, it uses ZStrCopy for "initialization" .. which the compiler doesn't know/understand.

In both cases the warning can be easily suppressed by setting the variable to a default value at the beginning of the procedure.

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

Re: Google Play New problem : 64bits

Post by Ats »

With the TRTLCriticalSection fix, the game can now run for several minutes. Sometimes it still crashes, not as frequently as before, but the crashes remain random.

I’m not using Platform_NetOpen, but I assume reading an embedded 3DS file uses ReadAssetFile. Since we’ve already replaced all the other ...MethodV calls with ...MethodA, let’s do the same here.


Here's the new ReadAssetFile:

Code: Select all

procedure ReadAssetFile(Filename: PAnsiChar; var Memory: pointer; var Size: integer);
var
  Env: PJNIEnv;
  AppClass: JClass;
  Mid: JMethodID;
  jniParams: array[0..0] of JValue; // For the (String) parameter
  JStr: jstring;
  Buffer: jbyteArray;
  PBuffer: pointer;
  IsCopy: JBoolean;
  BufferSize: JSize;
begin
  // Get the JNI environment
  CurVM^.GetEnv(CurVM, @Env, JNI_VERSION_1_6);

  // Log filename
  AndroidLog(PAnsiChar('Opening: ' + Filename));

  // Get class and method ID
  AppClass := Env^.GetObjectClass(Env, jobject(AndroidThis));
  Mid := Env^.GetMethodID(Env, AppClass, 'openAssetFile', '(Ljava/lang/String;)[B');

  // Create Java string and assign it to the parameter array
  JStr := Env^.NewStringUTF(Env, Filename);
  jniParams[0].l := JStr;

  // Call Java method using CallObjectMethodA
  Buffer := Env^.CallObjectMethodA(Env, jobject(AndroidThis), Mid, @jniParams[0]);

  // Clean up local ref for the string
  Env^.DeleteLocalRef(Env, JStr);

  // If Buffer is valid, extract data
  if Buffer <> nil then
  begin
    BufferSize := Env^.GetArrayLength(Env, Buffer);
    PBuffer := Env^.GetByteArrayElements(Env, Buffer, IsCopy);

    if PBuffer = nil then
      AndroidLog('Could not get buffer')
    else
    begin
      GetMem(Memory, BufferSize);
      Move(PBuffer^, Memory^, BufferSize);
      Size := BufferSize;

      // Release Java array
      Env^.ReleaseByteArrayElements(Env, Buffer, PBuffer, 0);
    end;
  end
  else
    AndroidLog('CallObjectMethodA returned null');
end;
And Platform_NetOpen:

Code: Select all

procedure Platform_NetOpen(Url: PAnsiChar; InBrowser: boolean; WebOpen: pointer);
var
  Env: PJNIEnv;
  AppClass: JClass;
  Mid: JMethodID;
  jniParams: array[0..0] of JValue;
  JStr: jstring;
begin
  if InBrowser then
  begin
    // Get JNI environment
    CurVM^.GetEnv(CurVM, @Env, JNI_VERSION_1_6);

    AndroidLog(PAnsiChar('Opening: ' + Url));

    // Get class and method ID
    AppClass := Env^.GetObjectClass(Env, jobject(AndroidThis));
    Mid := Env^.GetMethodID(Env, AppClass, 'openURL', '(Ljava/lang/String;)V');

    // Create Java string and set as argument
    JStr := Env^.NewStringUTF(Env, Url);
    jniParams[0].l := JStr;

    // Call Java method using CallVoidMethodA
    Env^.CallVoidMethodA(Env, jobject(AndroidThis), Mid, @jniParams[0]);

    // Clean up local reference
    Env^.DeleteLocalRef(Env, JStr);
  end;
end;

However, it still crashes randomly without any clear hint in the logs. That’s why I was trying to change the NativeInt warnings to NativeUInt.

********** Crash dump: **********
Build fingerprint: 'google/cheetah/cheetah:15/BP1A.250305.019/13003188:user/release-keys'
#00 0x0000000000000010 <anonymous:7f1917b000>
Crash dump is completed
User avatar
Kjell
Posts: 1935
Joined: Sat Feb 23, 2008 11:15 pm

Re: Google Play New problem : 64bits

Post by Kjell »

Hi Ats,
Ats wrote: Tue Apr 22, 2025 9:29 amI assume reading an embedded 3DS file uses ReadAssetFile.
The MeshImport component uses TZInputStream and its CreateFromMemory constructor specifically, so no Platform_ReadFile ( nor ReadAssetFile ) is involved.

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

Re: Google Play New problem : 64bits

Post by Ats »

After writing down what I was doing in my game each time it crashed, I finally made a breakthrough!!!

This is running fine:

Code: Select all

<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="Android Bug Finder 1" ScreenMode="0" FileVersion="2" AndroidPackageName="com.txori.android_bug_finder_1" AndroidPortrait="2">
  <OnUpdate>
    <ZExpression>
      <Expression>
<![CDATA[for (int i = 0; i < 100; i++) {
  Life = 1 + rnd();
  ModelBox.Position = random(0, 5);
  ModelBox.Rotation = rnd();
  @SpawnModel(Model: ModelBox);
}]]>
      </Expression>
    </ZExpression>
  </OnUpdate>
  <Content>
    <Mesh Name="MeshBox">
      <Producers>
        <MeshBox/>
      </Producers>
    </Mesh>
    <Model Name="ModelBox" Position="-1.6079 2.6198 -2.6551" Rotation="0.1601 0.7024 0.7286">
      <Definitions>
        <Variable Name="Life"/>
      </Definitions>
      <OnSpawn>
        <ZExpression Expression="BoxColor.Color = rnd();"/>
      </OnSpawn>
      <OnUpdate>
        <ZExpression>
          <Expression>
<![CDATA[Life -= App.DeltaTime;
CurrentModel.Scale = Life / 10;
if (Life <= 0) @RemoveModel();]]>
          </Expression>
        </ZExpression>
      </OnUpdate>
      <OnRender>
        <RenderSetColor Name="BoxColor"/>
        <RenderMesh Mesh="MeshBox"/>
      </OnRender>
    </Model>
  </Content>
</ZApplication>
While this is crashing on Android 64:

Code: Select all

<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="Android Bug Finder 2" ScreenMode="0" FileVersion="2" AndroidPackageName="com.txori.android_bug_finder_2" AndroidPortrait="2">
  <OnLoaded>
    <ZExternalLibrary ModuleName="opengl32">
      <BeforeInitExp>
<![CDATA[//

if (ANDROID)
{
  if(App.GLBase==0) this.ModuleName="libGLESv1_CM.so";
  else this.ModuleName="libGLESv2.so";
}
else if (LINUX)
{
  this.ModuleName = "libGL.so";
}
else
{
  this.ModuleName = "opengl32";
}

//]]>
      </BeforeInitExp>
      <Source>
<![CDATA[//

/* BlendingFactorDest */
const int GL_SRC_COLOR = 0x0300;
const int GL_ONE_MINUS_SRC_COLOR = 0x0301;
const int GL_SRC_ALPHA = 0x0302;
const int GL_ONE_MINUS_SRC_ALPHA = 0x0303;
const int GL_DST_ALPHA = 0x0304;
const int GL_ONE_MINUS_DST_ALPHA = 0x0305;

/* EnableCap */
const int GL_BLEND = 0x0BE2;

/* LogicOp */

void glDisable(int cap){}
void glEnable(int cap){}

void glBegin(int mode){}
void glEnd(){}

void glBlendFunc(int sfactor, int dfactor){}

//]]>
      </Source>
    </ZExternalLibrary>
  </OnLoaded>
  <OnUpdate>
    <ZExpression>
      <Expression>
<![CDATA[for (int i = 0; i < 100; i++) {
  Life = 1 + rnd();
  ModelBox.Position = random(0, 5);
  ModelBox.Rotation = rnd();
  @SpawnModel(Model: ModelBox);
}]]>
      </Expression>
    </ZExpression>
  </OnUpdate>
  <Content>
    <Mesh Name="MeshBox">
      <Producers>
        <MeshBox/>
      </Producers>
    </Mesh>
    <Model Name="ModelBox" Position="4.8621 -4.6274 -4.9799" Rotation="0.1516 0.6719 0.0986">
      <Definitions>
        <Variable Name="Life"/>
      </Definitions>
      <OnSpawn>
        <ZExpression Expression="BoxColor.Color = rnd();"/>
      </OnSpawn>
      <OnUpdate>
        <ZExpression>
          <Expression>
<![CDATA[Life -= App.DeltaTime;
CurrentModel.Scale = Life / 10;
if (Life <= 0) @RemoveModel();]]>
          </Expression>
        </ZExpression>
      </OnUpdate>
      <OnRender>
        <ZExpression>
          <Expression>
<![CDATA[glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);]]>
          </Expression>
        </ZExpression>
        <RenderSetColor Name="BoxColor"/>
        <RenderMesh Mesh="MeshBox"/>
        <ZExpression Expression="glDisable(GL_BLEND);"/>
      </OnRender>
    </Model>
  </Content>
</ZApplication>
Maybe it’s due to the sheer number of cubes I’m generating in the example. But if I disable transparency on the FX speed lines, lasers, and explosions in my game, it doesn’t crash (or it seems) and there aren’t that many of them.

I'm currently charging the 32 bit device to see how it goes.

Edit:
All right, the 32 bit version isn't crashing at all!

Edit 2:
I deactivated glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); and it's still crashing on Android 64 with only

Code: Select all

glEnable(GL_BLEND);
@RenderMesh(Mesh:MeshBox);
glDisable(GL_BLEND);
Edit 3:
It also randomly crash if there is only glEnable(GL_BLEND); or glDisable(GL_BLEND);
User avatar
Kjell
Posts: 1935
Joined: Sat Feb 23, 2008 11:15 pm

Re: Google Play New problem : 64bits

Post by Kjell »

Hi Ats,

Have you tried other ( basic ) OpenGL calls to see if it still crashes on 64-bit Android? For example something like:

Code: Select all

<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="ZGameEditor application" ClearScreenMode="1" FileVersion="2">
  <OnLoaded>
    <ZExternalLibrary ModuleName="opengl32">
      <BeforeInitExp>
<![CDATA[//

if(ANDROID)
{
  if(App.GLBase)
  {
    this.ModuleName = "libGLESv2.so";
  }
  else
  {
    this.ModuleName = "libGLESv1_CM.so";
  }
}
else if(LINUX)
{
  this.ModuleName = "libGL.so";
}
else
{
  this.ModuleName = "opengl32";
}]]>
      </BeforeInitExp>
      <Source>
<![CDATA[//

void glClear(int mask){}
void glClearColor(float red, float green, float blue, float alpha){}]]>
      </Source>
    </ZExternalLibrary>
  </OnLoaded>
  <OnRender>
    <ZExpression>
      <Expression>
<![CDATA[//

float t = App.Time;

glClearColor(0.5+sin(t/3)/2, 0.5+cos(t/2)/2, 1, 1);
glClear(0x4000);]]>
      </Expression>
    </ZExpression>
  </OnRender>
</ZApplication>
I doubt it has anything to do with glEnable(GL_BLEND) specifically ... but that either the library doesn't load properly on 64-bit Android, or that the address of the module isn't stored properly, or that the procedure pointers don't get stored properly, or that the calls to those procedures aren't done properly.

But i'm afraid i don't really have a clue either :cry:

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

Re: Google Play New problem : 64bits

Post by Ats »

Sorry, your colored background isn't crashing on Android 64. I tested it for a while. I even added the basic cubes from my first example over it to force compute things...

I was thinking, do I really need to use
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
to set 3D objects transparent? Or can that be done with the shaders? Since my app is ES2/GL3 and everything is rendered using shaders...

Or maybe I could handle GL errors? Something like:

Code: Select all

int err = glGetError();
if (err == GL_NO_ERROR) {
    glEnable(GL_BLEND);
    err = glGetError();
    if (err != GL_NO_ERROR) {
        // Handle error
    }
}
User avatar
Kjell
Posts: 1935
Joined: Sat Feb 23, 2008 11:15 pm

Re: Google Play New problem : 64bits

Post by Kjell »

Hmm,
Ats wrote: Sat Jun 28, 2025 6:04 pmSorry, your colored background isn't crashing on Android 64.
So weird .. :? What if you swap the glEnable/glDisable(GL_BLEND) calls with two Materials that do the equivalent?

Code: Select all

<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="Android Bug Finder 2" ScreenMode="0" FileVersion="2" AndroidPackageName="com.txori.android_bug_finder_2" AndroidPortrait="2">
  <OnUpdate>
    <ZExpression>
      <Expression>
<![CDATA[for (int i = 0; i < 100; i++) {
  Life = 1 + rnd();
  ModelBox.Position = random(0, 5);
  ModelBox.Rotation = rnd();
  @SpawnModel(Model: ModelBox);
}]]>
      </Expression>
    </ZExpression>
  </OnUpdate>
  <Content>
    <Mesh Name="MeshBox">
      <Producers>
        <MeshBox/>
      </Producers>
    </Mesh>
    <Model Name="ModelBox" Position="3.7726 -3.3874 -2.812" Rotation="0.7355 0.9202 0.3812">
      <Definitions>
        <Variable Name="Life"/>
      </Definitions>
      <OnSpawn>
        <ZExpression Expression="BoxColor.Color = rnd();"/>
      </OnSpawn>
      <OnUpdate>
        <ZExpression>
          <Expression>
<![CDATA[Life -= App.DeltaTime;
CurrentModel.Scale = Life / 10;
if (Life <= 0) @RemoveModel();]]>
          </Expression>
        </ZExpression>
      </OnUpdate>
      <OnRender>
        <ZExpression>
          <Expression>
<![CDATA[//glEnable(GL_BLEND);
//glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

@UseMaterial(Material: EnableBlendMaterial);]]>
          </Expression>
        </ZExpression>
        <RenderSetColor Name="BoxColor"/>
        <RenderMesh Mesh="MeshBox"/>
        <ZExpression>
          <Expression>
<![CDATA[//glDisable(GL_BLEND);

@UseMaterial(Material: DisableBlendMaterial);]]>
          </Expression>
        </ZExpression>
      </OnRender>
    </Model>
    <Material Name="DisableBlendMaterial"/>
    <Material Name="EnableBlendMaterial" Blend="1"/>
  </Content>
</ZApplication>
Ats wrote: Sat Jun 28, 2025 6:04 pmI was thinking, do I really need to use glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); to set 3D objects transparent? Or can that be done with the shaders?
With just shaders? You could in theory, but it would be very troublesome & slow. It's similar to wanting the behavior of a z-buffer without using/enabling the built-in OpenGL z-buffer. It's possible, but you really don't want to :wink:

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

Re: Google Play New problem : 64bits

Post by Ats »

So I tried your last test several times, and for quite a while. It’s not crashing at all.
Then I tried enabling and disabling GL_BLEND again, just to be sure. It randomly crashes at some point, every time.

Weird, but I think we’re onto something :wink:


Edit:
I tried setting my transparent materials and removing the glEnable/glDisable calls in my game, but using glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) isn’t rendering the same as using a material with Alpha/OneMinusSourceAlpha. The first one seems to add up light, making the explosions bright yellow to white, while the second creates more of a middle range of colors, shifting them from brown to dark yellow. Is there a good way to compare all these blending modes with some kind of “official” reference rendering?
User avatar
Kjell
Posts: 1935
Joined: Sat Feb 23, 2008 11:15 pm

Re: Google Play New problem : 64bits

Post by Kjell »

Hi Ats,
Ats wrote: Sat Jun 28, 2025 10:45 pmSo I tried your last test several times, and for quite a while. It’s not crashing at all.
Then I tried enabling and disabling GL_BLEND again, just to be sure. It randomly crashes at some point, every time.
Yea .. it's not GL_BLEND specifically. Something related to ZExternalLibrary is causing crashes on 64-bit Android.
Ats wrote: Sat Jun 28, 2025 10:45 pmI tried setting my transparent materials and removing the glEnable/glDisable calls in my game, but using glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) isn’t rendering the same as using a material with Alpha/OneMinusSourceAlpha. The first one seems to add up light, making the explosions bright yellow to white, while the second creates more of a middle range of colors, shifting them from brown to dark yellow.
I double-checked the version i posted in gDEBugger, and it uses the same glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) call that you're using.

Image

Which means the difference you're seeing is caused by something else. Keep in mind that when you're using "Compatible" GLBase, ambient light ( App.AmbientLightColor ) and the default light source ( App.LightPosition ) will be enabled. But when you're using ES2/GL3 it's entirely* up to your shaders.

*And just to be clear, blending happens outside / independently from shaders .. so that's not part of it.

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

Re: Google Play New problem : 64bits

Post by Ats »

Oh, all right.
Yeah, that might not be coming from the GL functions, but my example does have the merit of crashing really quickly on 64-bit :lol:
I’m going to recompile the ZGE Android library with threading completely disabled and see if my glEnable cubes still crash.
User avatar
Ats
Posts: 829
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: Google Play New problem : 64bits

Post by Ats »

The glEnable cubes are still randomly crashing even with threads disabled like that:
In TZApplication.Init insert this line
ZClasses.Tasks.Enabled := False;
Post Reply