Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
363 views
in Technique[技术] by (71.8m points)

multithreading - Is PNG decoding not thread safe under android?

Using Delphi 10.2.3:

I am writing code that repeat-decodes the same set of PNG images in multiple threads over and over again.

Once the thread is executed, it uses an FMX TBitmap component's "LoadFromStream" method to decode a PNG file loaded into a TMemoryStream (within the thread).

Running under Windows, no issues.

Running under Android I get multiple exceptions and it appears to trigger randomly on just some of the threads:
1. Exception "Can not activate current context"
2. EReadError "stream error"

If I capture the exception and save the stream to a file, the PNG is valid.

If I synchronize the decoding "Bitmap.LoadFromStream(MemoryStream)" function everything works.

If the answer is that PNG decoding is not thread safe using the native library, is there an alternative solution that does support multithreaded PNG decoding under Android?

Sample code:

procedure TImageDecodeThread.Execute;
var
  memStream  : TMemoryStream;
  dlBitmap   : TBitmap;
Begin
  memStream := TMemoryStream.Create;
  Try
    memStream.LoadFromFile('image'+ThreadName+'.png');
  Except
    on E : Exception do
    Begin
      DebugEntry('memstream:'+E.ClassName+', "'+E.Message+'", Size='+IntToStr(memStream.Size));
    End;
  End;
  memStream.Position := 0;

  dlBitmap := TBitmap.Create;
  Try
    dlBitmap.LoadFromStream(memStream);
  Except
    on E : Exception do
    Begin
      DebugEntry('decode'+E.ClassName+', "'+E.Message+'", Size='+IntToStr(memStream.Size));
      memStream.Position := 0;
      memStream.SaveToFile(ThreadName+'exception'.png');
    End
  End;
  memStream.Free;
  dlBitmap.Free;
End;

Update
I tried to wrap the TBitmap's LoadFromStream method inside a critical section and it still raises the "Can not activate current context" exception.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

PNG images can work in background threads under android, BUT maybe Tbitmap not ;) Embarcedero say that from delphi tokyo Tbitmap can work in background thread, but in the reality it's false (or better say completely buggy)! For exemple when you create a Ttexture then the control will register some message to listen (like context lost), but message event can be sent and read ONLY from the main thread! so their is a problem, most often resulting at some access violation or crash at random time. I make some notes of what must be corrected in texture to make Tbitmap fully work in background thread in https://github.com/Zeus64/alcinoe

Note also, you say it's work under windows, but it's also false! it's depend of your video driver and the version of directx. on some windows it's abslutely not work, i also report many bug like this under quality portal of embarcadero

As a conclusion: Tbitmap can't be use right now in background thread ...


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...