Is PNG decoding not thread safe under android?

久未见 提交于 2019-12-13 10:53:36

问题


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.


回答1:


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 ...



来源:https://stackoverflow.com/questions/52168940/is-png-decoding-not-thread-safe-under-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!