Delphi FMX Android FillText работает медленно и требует больших ресурсов

Я рисую (большую) логическую таблицу (двоичные значения 0,1 в большой сетке) с помощью PaintBox. Как в коде ниже. Примечание. Код упрощен, для представления проблемы рисуются только случайные 0 и 1. Также я обновил вопрос полным кодом, поскольку комментатор заявил, что первоначальный вопрос был расплывчатым.

Использование FillText для рисования (сотни) отдельных двоичных значений (0 или 1) оказалось МЕДЛЕННЫМ! Кроме того, при частом панорамировании PaintBox приложение зависало и принудительно закрывалось на устройстве Android.

Итак, очевидно, что FillText недостаточно для этого случая, и вам интересно, знает ли кто-нибудь о лучшей технике?

procedure TMainWin.PaintBoxPaint(Sender: TObject; Canvas: TCanvas);
VAR Fcstroke:TStrokeBrush;
    xp,yp,Tsze:INTEGER;
    tw,th:SINGLE;
    p1,p2:TPointF;
    MyRect:TRectF;
begin
   Canvas.BeginScene;
   // Clear
   Canvas.Clear(TAlphaColorRec.Beige);
   Canvas.Fill.Color:= TAlphaColorRec.Black;
   Canvas.Fill.Kind:= TBrushKind.Solid;
   // Text Prop
   Canvas.Font.Family:= 'Roboto';
   Canvas.Font.Style:= [];
   Canvas.Font.Size:= 40;
   Canvas.Stroke.Thickness:= 2;
   Canvas.Stroke.Kind:= TBrushKind.Solid;
   Canvas.Stroke.DefaultColor:= TAlphaColorRec.Black;
   tw:= Canvas.TextWidth('0')*1.2;
   th:= Canvas.TextHeight('0');
   Fcstroke:= TStrokeBrush.Create(TBrushKind.Solid,TAlphaColorRec.Green);
   Fcstroke.DefaultColor:= TAlphaColorRec.Green;
   Fcstroke.Thickness:= 2;
   // Table
   Tsze:= 50;
   FOR yp:= 1 TO Tsze DO
   BEGIN
      // Horz table Line
      p1:= TPointF.Create(         tw,yp*th);
      p2:= TPointF.Create((Tsze+1)*tw,yp*th);
      Canvas.DrawLine(p1,p2,1,Fcstroke);
      // Vert table Line
      p1:= TPointF.Create(yp*tw,         th);
      p2:= TPointF.Create(yp*tw,(Tsze+1)*th);
      Canvas.DrawLine(p1,p2,1,Fcstroke);
      // Text
      FOR xp:= 1 TO Tsze DO
      BEGIN
         MyRect:= TRectF.Create(xp*tw,yp*th,xp*tw+tw,yp*th+th);
         IF (Random(10)>5) THEN
           Canvas.FillText(MyRect,'0',False,100,[],TTextAlign.Center,TTextAlign.Center)
         ELSE
           Canvas.FillText(MyRect,'1',False,100,[],TTextAlign.Center,TTextAlign.Center);
      END;
   END;
   // End
   Canvas.EndScene;
end;

person ChasH    schedule 11.09.2018    source источник
comment
Canvas.FillText не подходит для рисования большого количества текста в цикле. Я не уверен, есть ли более подходящий метод (поэтому я не буду отвечать), но FillText создает временный объект TTextLayout для фактического рисования. Вы можете интегрировать этот код в свой, чтобы создать этот экземпляр только один раз, а затем использовать его для рисования текста в цикле без вызова Canvas.FillText.   -  person Dalija Prasnikar    schedule 15.09.2018


Ответы (1)


Вы должны инкапсулировать свой рисунок с помощью BeginScene и EndScene, иначе рисунок будет очень медленным:

Canvas.BeginScene;
try
  //all your painting routines here
  Canvas.FillText(...);
  ... 
finally
  Canvas.EndScene;
end;
person Hans    schedule 11.09.2018
comment
Да, я хорошо знаю, что нужны BeginScene и EndScene, и в моем коде они уже есть. Тем не менее, команды FillText кажутся очень ресурсоемкими. Когда я использую Circles (DrawEllipse) для 0 и Lines (DrawLine) для 1, код работает нормально, быстро и не падает (принудительно закрывается). Так что для FillText есть что-то очень ресурсоемкое. Я могу продолжать использовать круги и линии для 0 и 1, но в долгосрочной перспективе я хотел бы использовать фактические символы 0 и 1, - person ChasH; 12.09.2018
comment
В этом случае ваш вопрос не очень хорош, потому что вы вообще не упоминаете об этом в своем вопросе. Самая распространенная причина плохой производительности в FMX — отсутствие Begin/EndScene, и я ответил именно на это. Нет причин отрицать мой ответ, потому что вы задали неполный вопрос! Пожалуйста, исправьте свой вопрос. - person Hans; 12.09.2018
comment
@Hans OP не смог проголосовать против вашего ответа, потому что у него недостаточно репутации, чтобы проголосовать против. У него даже недостаточно репутации, чтобы проголосовать. - person Dalija Prasnikar; 15.09.2018
comment
Вы опубликовали дикий ответ, который не имеет ничего общего с вопросом. Даже в исходном вопросе (хотя в нем не было больше кода) было достаточно информации, чтобы точно определить проблему. Проблема заключается в FillText, а не в BeginScene/EndScene. - person Dalija Prasnikar; 15.09.2018
comment
@DalijaPrasnikar Вы правы в том, что это предположение, но, конечно, не дикое предположение, поскольку именно по этой причине наиболее распространенная причина низкой производительности рисования на FMX. Поскольку ChasH новичок в SO, я также предположил, что он новичок в FMX. Конечно, я мог бы вместо этого прокомментировать вопрос, но я пытался работать против тенденции на SO, что все отвечают как комментарий, боясь отрицательных голосов и флейма. - person Hans; 15.09.2018
comment
@Hans Если вы готовы гадать, то вы должны принять возможность того, что ваш ответ может быть неправильным. Я предлагаю вам удалить этот ответ. Со временем он не станет более правильным (если только вы его полностью не перепишете), и он может только накопить больше голосов против. - person Dalija Prasnikar; 15.09.2018