Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Ускорение кэширования компонентов Firemonkey для оптимизации их отрисовки

Delphi , Графика и Игры , OpenGL

является актуальной задачей для разработчиков, работающих с технологией Delphi. В данной статье мы рассмотрим вопрос ускорения процесса кэширования с помощью TTexture или TBitmap, а также разберемся в преимуществах и недостатках каждого подхода.

Введение

Firemonkey - это кросс-платформенный инструмент для разработки приложений на Delphi, который позволяет создавать высокопроизводительные и визуально привлекательные интерфейсы. Для ускорения отрисовки визуальных компонентов можно использовать кэширование, которое заключается в сохранении отрисованного изображения в памяти и последующем использовании этого кэша вместо повторной отрисовки.

Однако, при использовании кэширования могут возникнуть определенные проблемы, связанные со скоростью создания кэша и выбором между TTexture и TBitmap. В данной статье мы рассмотрим эти вопросы и предложим решения для ускорения процесса кэширования компонентов Firemonkey.

Кэширование с помощью TTexture или TBitmap

Для кэширования визуальных компонентов можно использовать tanto TTexture, как и TBitmap. TTexture представляет собой поверхность, которая может быть использована для хранения изображений, а TBitmap - это битмап, который также может быть использован для хранения изображений, но в отличие от TTexture, он не оптимизирован для работы с графическим процессором (GPU).

При использовании кэширования с помощью TTexture или TBitmap, основной проблемой является скорость создания кэша. В приведенном выше примере кода, создание кэша занимает около 30 миллисекунд, что является достаточно долгим временем для современных приложений.

Ускорение процесса кэширования

Для ускорения процесса кэширования можно использовать несколько подходов. Первый подход заключается в использовании асинхронного кэширования, при котором процесс создания кэша происходит в фоновом режиме, не блокируя основной поток выполнения приложения. Для этого можно использовать потоки или задачи (tasks) в зависимости от версии Delphi, которую вы используете.

Второй подход заключается в использовании мультипоточности при создании кэша. При этом можно создавать несколько потоков, каждый из которых будет отвечать за создание кэша для определенной части экрана или для определенного набора компонентов. Это позволяет Parallel.ForEach или TTask.Parallel.ForEach в зависимости от версии Delphi, которую вы используете.

Третий подход заключается в использовании предварительного кэширования, при котором кэш создается заранее, до начала работы приложения. Это может быть полезно, если приложение имеет фиксированный набор визуальных компонентов, которые не меняются в течение всего времени работы приложения.

Выбор между TTexture и TBitmap

При выборе между TTexture и TBitmap следует учитывать несколько факторов. TTexture хранится в памяти GPU, что делает его более быстрым при работе с графикой, но при этом он занимает больше памяти. TBitmap, с другой стороны, хранится в локальной памяти и занимает меньше места, но может быть медленнее при работе с графикой.

Если приложение работает с большим количеством графических данных, то использование TTexture может быть более предпочтительным, так как оно позволяет ускорить работу с графикой за счет использования памяти GPU. Однако, если приложение работает с небольшим количеством графических данных, то использование TBitmap может быть более подходящим, так как оно занимает меньше памяти.

Также следует учитывать, что TTexture не может быть сжат в формате PNG, в отличие от TBitmap. Если приложению необходимо сжимать графические данные для экономии памяти, то использование TBitmap может быть более предпочтительным.

Заключение

В данной статье мы рассмотрели вопрос ускорения кэширования компонентов Firemonkey для оптимизации их отрисовки. Мы рассмотрели несколько подходов к ускорению процесса кэширования, а также разобрались в преимуществах и недостатках использования TTexture или TBitmap для кэширования.

При выборе подхода к ускорению кэширования и выбору между TTexture и TBitmap следует учитывать особенности конкретного приложения и требования, предъявляемые к нему. Правильный выбор подхода и компонентов может существенно ускорить работу приложения и улучшить пользовательский опыт.

Пример кода для ускорения процесса кэширования с использованием асинхронного кэширования:

uses
  System.SysUtils,
  System.Classes,
  FMX.Graphics,
  FMX.Types;

type
  TCacheRectangle = class(TComponent)
  private
    fBufBitmap: TTexture;
    function MakeBufBitmap: TTexture;
  public
    property BufBitmap: TTexture read fBufBitmap;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  end;

constructor TCacheRectangle.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  TThread.CreateAnonymousThread(
    procedure
    begin
      fBufBitmap := MakeBufBitmap;
      Synchronize(
        procedure
        begin
          // Обновление кэша в главном потоке
        end
      );
    end
  ).Start;
end;

destructor TCacheRectangle.Destroy;
begin
  fBufBitmap.Free;
  inherited Destroy;
end;

function TCacheRectangle.MakeBufBitmap: TTexture;
var
  TmpBitmap: TBitmap;
  M: TBitmapData;
  SaveTempCanvas: TCanvas;
  SceneScale: Single;
begin
  if Scene <> nil then SceneScale := Scene.GetSceneScale
  else SceneScale := 1;

  TmpBitmap := TBitmap.Create(round(Width * SceneScale), round(Height * SceneScale));
  try
    TmpBitmap.BitmapScale := SceneScale;
    TmpBitmap.Clear(0);
    if TmpBitmap.Canvas.BeginScene then
      try
        SaveTempCanvas := TempCanvas;
        try
          TempCanvas := TmpBitmap.Canvas;
          inherited Paint;
        finally
          TempCanvas := SaveTempCanvas;
        end;
      finally
        TmpBitmap.Canvas.EndScene;
      end;

    //-----
    fBufBitmap := TTexture.Create;
    fBufBitmap.Assign(TmpBitmap);
    if (TCanvasStyle.NeedGPUSurface in TmpBitmap.CanvasClass.GetCanvasStyle) then begin
      if TmpBitmap.Map(TMapAccess.Read, M) then begin
        try
          fBufBitmap.UpdateTexture(M.Data, M.Pitch);
        finally
          TmpBitmap.Unmap(M);
        end;
      end;
    end;
    //-----
  finally
    TmpBitmap.Free;
  end;
end;

Пример кода для ускорения процесса кэширования с использованием мультипоточности:

uses
  System.SysUtils,
  System.Classes,
  FMX.Graphics,
  FMX.Types,
  System.Parallel;

type
  TCacheRectangle = class(TComponent)
  private
    fBufBitmap: TTexture;
    function MakeBufBitmap: TTexture;
  public
    property BufBitmap: TTexture read fBufBitmap;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  end;

constructor TCacheRectangle.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  TTask.Create(
    procedure
    begin
      fBufBitmap := MakeBufBitmap;
    end
  ).Start;
end;

destructor TCacheRectangle.Destroy;
begin
  fBufBitmap.Free;
  inherited Destroy;
end;

function TCacheRectangle.MakeBufBitmap: TTexture;
var
  TmpBitmap: TBitmap;
  M: TBitmapData;
  SaveTempCanvas: TCanvas;
  SceneScale: Single;
  I: Integer;
begin
  if Scene <> nil then SceneScale := Scene.GetSceneScale
  else SceneScale := 1;

  TmpBitmap := TBitmap.Create(round(Width * SceneScale), round(Height * SceneScale));
  try
    TmpBitmap.BitmapScale := SceneScale;
    TmpBitmap.Clear(0);
    if TmpBitmap.Canvas.BeginScene then
      try
        SaveTempCanvas := TempCanvas;
        try
          TempCanvas := TmpBitmap.Canvas;
          inherited Paint;
        finally
          TempCanvas := SaveTempCanvas;
        end;
      finally
        TmpBitmap.Canvas.EndScene;
      end;

    //-----
    fBufBitmap := TTexture.Create;
    fBufBitmap.Assign(TmpBitmap);
    if (TCanvasStyle.NeedGPUSurface in TmpBitmap.CanvasClass.GetCanvasStyle) then begin
      TParallel.For(0, TmpBitmap.Width div 16, procedure(I: Integer)
        begin
          if TmpBitmap.Map(TMapAccess.Read, M) then begin
            try
              fBufBitmap.UpdateTexture(M.Data, M.Pitch);
            finally
              TmpBitmap.Unmap(M);
            end;
          end;
        end
      );
    end;
    //-----
  finally
    TmpBitmap.Free;
  end;
end;

Пример кода для предварительного кэширования:

uses
  System.SysUtils,
  System.Classes,
  FMX.Graphics,
  FMX.Types;

type
  TCacheRectangle = class(TComponent)
  private
    fBufBitmap: TTexture;
    function MakeBufBitmap: TTexture;
  public
    property BufBitmap: TTexture read fBufBitmap;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  end;

constructor TCacheRectangle.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  fBufBitmap := MakeBufBitmap;
end;

destructor TCacheRectangle.Destroy;
begin
  fBufBitmap.Free;
  inherited Destroy;
end;

function TCacheRectangle.MakeBufBitmap: TTexture;
var
  TmpBitmap: TBitmap;
  M: TBitmapData;
  SaveTempCanvas: TCanvas;
  SceneScale: Single;
begin
  if Scene <> nil then SceneScale := Scene.GetSceneScale
  else SceneScale := 1;

  TmpBitmap := TBitmap.Create(round(Width * SceneScale), round(Height * SceneScale));
  try
    TmpBitmap.BitmapScale := SceneScale;
    TmpBitmap.Clear(0);
    if TmpBitmap.Canvas.BeginScene then
      try
        SaveTempCanvas := TempCanvas;
        try
          TempCanvas := TmpBitmap.Canvas;
          inherited Paint;
        finally
          TempCanvas := SaveTempCanvas;
        end;
      finally
        TmpBitmap.Canvas.EndScene;
      end;

    //-----
    fBufBitmap := TTexture.Create;
    fBufBitmap.Assign(TmpBitmap);
    if (TCanvasStyle.NeedGPUSurface in TmpBitmap.CanvasClass.GetCanvasStyle) then begin
      if TmpBitmap.Map(TMapAccess.Read, M) then begin
        try
          fBufBitmap.UpdateTexture(M.Data, M.Pitch);
        finally
          TmpBitmap.Unmap(M);
        end;
      end;
    end;
    //-----
  finally
    TmpBitmap.Free;
  end;
end;

Надеемся, что данная статья поможет вам ускорить процесс кэширования компонентов Firemonkey и оптимизировать их отрисовку в ваших приложениях.

Создано по материалам из источника по ссылке.

Данная статья посвящена ускорению процесса кэширования визуальных компонентов в Firemonkey с использованием TTexture или TBitmap для оптимизации их отрисовки. В ней рассматриваются различные подходы к ускорению кэширования, такие как асинхронное кэширован


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: OpenGL ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-02-05 19:03:58/0.0042071342468262/0