Разве PNG декодирование не безопасно для потоков под Android? - PullRequest
0 голосов
/ 04 сентября 2018

Использование Delphi 10.2.3:

Я пишу код, который многократно повторяет и декодирует один и тот же набор изображений PNG в нескольких потоках.

Как только поток выполняется, он использует метод LoadFromStream компонента FMX TBitmap для декодирования файла PNG, загруженного в TMemoryStream (в потоке).

Запуск под Windows, без проблем.

Работая под Android, я получаю несколько исключений, и кажется, что он запускается случайным образом только в некоторых потоках:
1. Исключение «Не удается активировать текущий контекст»
2. EReadError "Ошибка потока"

Если я фиксирую исключение и сохраняю поток в файл, PNG действителен.

Если я синхронизирую функцию декодирования «Bitmap.LoadFromStream (MemoryStream)», все работает.

Если ответ заключается в том, что декодирование PNG не является потокобезопасным с использованием собственной библиотеки, существует ли альтернативное решение, которое поддерживает многопоточное декодирование PNG под Android?

Пример кода:

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;

Обновление
Я попытался обернуть метод LoadFromStream TBitmap внутри критического раздела, и он по-прежнему вызывает исключение «Не удается активировать текущий контекст».

1 Ответ

0 голосов
/ 06 сентября 2018

PNG изображения могут работать в фоновых потоках под android, НО, может быть, Tbitmap нет;) Embarcedero говорит, что из delphi tokyo Tbitmap может работать в фоновом потоке, но в действительности это неверно (или, лучше сказать, полностью глючит)! Например, когда вы создаете Ttexture, элемент управления зарегистрирует некоторое сообщение для прослушивания (например, потерянный контекст), но событие сообщения может быть отправлено и прочитано ТОЛЬКО из основного потока! таким образом, это проблема, чаще всего приводящая к некоторому нарушению доступа или сбою в случайное время. Я делаю некоторые заметки о том, что должно быть исправлено в текстуре, чтобы Tbitmap полностью работал в фоновом потоке в https://github.com/Zeus64/alcinoe

Обратите внимание, вы говорите, что это работает под окнами, но это также ложно! это зависит от вашего видео драйвера и версии DirectX. в некоторых окнах это абсолютно не работает, я также сообщаю о многих подобных ошибках на качественном портале embarcadero

В заключение: Tbitmap нельзя использовать прямо сейчас в фоновом потоке ...

...