Watch, Follow, &
Connect with Us

FireMonkey Blog by Eugene



Archives:



Styles Performance in XE3

As you I hope know, styles in FireMonkey are common FireMonkey objects, working on the level of a single control. The behavior and design of the control is defined by simple objects or graphical primitives (rectangle, ellipse, text), animation, effects and event triggers. But there is still a question. Is it effective to use such a number of objects and instantiate and load them right in the process of application startup? Yes, you’re right.

Thus in the new version of FireMonkey we modified the mechanism of loading/unloading of a style for controls. Now all the processes are dynamic. After the form has been loaded, all the controls are “empty”, i.e. they have no style (as a number of objects) loaded. But at the first call of the control rendering method, the style is loaded into the control. Only visible controls are loaded with the style, rather than all of them. Basically, it’s not amount of the controls. So a FireMonkey 2.0 application is loaded and starts considerably faster.

For example, if we have a TTabControl control with some tabs on the form, the styles are loaded only for an active tab. The same is true for TListBox, when the style is loaded only for visible items. While ListBox is being scrolled, the other items will be filled with the style.

Well, the startup and style loading became faster, sometimes dramatically. One can notice as we work with the application on and on we will have more and more objects, and the time for object processing will increase. In order to remove this situation, we unload the item style, if it becames invisible (we’ve scrolled it off or switched TabControl to a different tab). Thus, the performance of controls has increased. Take a list as an example and say, only visible elements have styles loaded.

During dynamic loading/unloading the style the following methods are called pairwise in class TStyledControl:

procedure ApplyStyle; virtual;
procedure FreeStyle; virtual;

If you want to load some data in objects of a style during runtime, you can use the event OnApplyStyleLookup. This event happens anytime, when the style is loaded into a control. Even if the style is unloaded from it, the repeated loading will cause the method to be called. So the data loading is guaranteed. Otherwise when using the style data via StylesData for invisible control, the data are lost, as the style has not been loaded yet.

The example of correct loading of the data in ListBox:

Item := TListBoxItem.Create(nil);
Item.OnApplyStyleLookup := DoApplyStyleLookupFromFile;
Item.Parent := ListBox1;
...
procedure TForm1.DoApplyStyleLookup(Sender: TObject);
var
Item: TListBoxItem;
begin
Item := TListBoxItem(Sender);
Item.StylesData['resolution'] := ‘1024×768 px’; // set size
Item.StylesData['depth'] := ‘32 bit’;
Item.StylesData['visible'] := true; // set Checkbox value
Item.StylesData['visible'] := TValue.From(DoVisibleChange); // set OnChange value
Item.StylesData['info'] := TValue.From(DoInfoClick); // set OnClick value
end;

In addition, the new version of FireMonkey has a mechanism, allowing the controls to manage the travel across the tree of child elements. The TConrol class now has two interesting methods:

function GetFirstVisibleObjectIndex: Integer; virtual;
function GetLastVisibleObjectIndex: Integer; virtual;

Having overridden these methods, one can manage the tree for the child methods. For example, there is no need to check the entire tree when handling the event from the mouse or draw all the elements, if some of them are not visible. The mechanisms is used in the controls as TListBox, TTreeView. Therefore, the performance of TListBox is always the same for the different number of items, as only visible are processed.

Posted by Eugene Kryukov on October 3rd, 2012 under Styles, ednfront, firemonkey, xe3 | Comment now »


Bitmap Styles in FireMonkey 2.0

In the list of new capabilities of RAD Studio XE3 there is a line: Bitmap Sytles. What is this new Bitmap Styles?

Some theory: styles in FireMonkey are just common FM objects, which can be located on a form. But the objects are grouped in special way. For example, in order to get a button we’re using an object TRectangle. We’re setting the necessary properties, adding some effects and animations, assigning some triggers to respond to some events. The button style for a button in XE2 looks like:

Using the objects we can get beautiful or even stunning styles, but vector graphics is not enough to express all a designer can make and a user wants to get.

In addition, in order to get realistic pictures, one needs large amount of primitives with complicated filling (gradients, transparency), that damages the performance. And the designer should understand the theory and practice of FM styles structuring.

Having analyzed the situation, we decided to complete FireMonkey capabilities with the support of bitmap styles.

Let me show you a bitmap style for a button, but in XE3 already:

Once can see, the number of objects has been decreased and an object TSubImage has appeared. TSubImage is a special type of object, which allows to draw a special part of a bitmap. The object references to TImage (using properties Source or StyleLookup) and uses it as the source of bitmap. The part of a bitmap is defined using property SourceRect. In order to change this part one can use TRectAnimation. This animation will change the value of property SourceRect, enabling to get different button kinds depending on its state.

Here is an example of a bitmap for a button with different states:

Thus we can use the ready images to give just any graphical look to our controls. In addition, the complexity of a style (number of objects) is independent on the complexity of the graphics and design, so has no impact on the performance.

The similar style engine was already available in VCL, so now you can use these styles in FireMonkey. We have enhanced the capabilities of the style edition for VCL, and you can export VCL styles in FireMonkey styles. Any VCL style can be saved in FireMonkey format:

As the style editor has its own format, and FireMonkey style doesn’t imply some strictly defined structure, this conversion is one-directional. We can save a VCL style in FM format, but we can’t open the style in the editor. In order to change or modify a FM style (file with extension *.style), one should use the designer in IDE.

Below you can see the FireMonkey application, which uses the style, converted from VCL-style:

In addition, FireMonkey 2.0 supports styles for non-client area of the form.

The main idea is all these new capabilities provide backward compatibility. All the vector styles continue working without any changes now and in the following versions. We haven’t change the concept, we’ve just enhanced it.

Posted by Eugene Kryukov on October 3rd, 2012 under Styles, ednfront, firemonkey, xe3 | 2 Comments »


DirectX 10 in FireMonkey 2.0

You’ve possibly already heard the new version of FireMonkey in RAD Studio XE3 has a support for DirectX 10. At the first glance one can think of the part of FireMonkey (FM), which provides 3D object rendering, and this is not typical functionality in business applications. But I can note the part of FM2 providing the access to GPU by TContext3D and TContextManager classes is used not only for rendering of 3D objects. Bitmap-effects is 99% based on GPU usage, so only 2…3 basic effects have a realization independently on hardware.

In addition, if an application uses 3D engine for reporting, the capabilities to build up some spatial charts, diagrams etc., are limited by the support of GPU with minimum PixelShader 2.0. These GPUs long ago became usual hardware, but sometimes they are not available, for example, on servers.

Let’s consider what advantages an application has due to the support of DirectX 10. The most interesting new feature, provided by Microsoft team, in this version of DirectX is the “software”-mode based on a very interesting technology. The technology is named “Warp” and uses the power of modern CPUs.

This technology allows to use all the power of DirectX 10 with no limitations and without GPU.  Below there is a clear example: DirectX 10 in software-mode with 4x multisampling switched on. The image for DirectX 10 has obviously more qualitative edges in comparison with image by DirectX 9, as the test was run on a machine without physical support for multisampling.

As to performance, I can say, DirectX 10 Wrap demonstrates very good results, comparable to low-end GPU, if we talk about not very overloaded scenes, typical for business applications.

Thus, the systems with the support of DirectX 10 (Windows Vista and higher) can run FireMonkey applications at maximum power, which was not achievable in XE2.

Of course, FireMonkey 2.0 automatically uses DirectX 10 in GPU if possible.

Posted by Eugene Kryukov on October 3rd, 2012 under 3d, firemonkey | Comment now »


Растровые стили в FireMonkey 2.0

В списке новых возможностей Rad Studio XE3 многие наверное видели строчку Bitmap Styles. А что же такое собственно Bitmap Styles ?

Немного теории - стили в FireMonkey это такие же обычные объекты FM, которые можно положить на форму. Правда сгруппированы они особым образом. Так вот, например, чтоб получить кнопку мы используем объект TRectangle. Устанавливаем нужные свойства, добавляем необходимые объекты эффектов и анимации, устанавливаем триггеры для реакции на события. Вот как выглядел стиль кнопки в XE2:

Используя эти объекты можно получить красивые стили, но с помошью векторной графики очень сложно (зачатую невозможно) передать все то что хотел выразить дизайнер. Кроме того чтоб получить реалистичные картины, необходимо использовать большое количество объектов со сложными типами заливок (градианты, прозрачность) - что в итоге приводит в потере производительности. Кроме того, чтоб создать стиль - дизайнеру необходимо знать структуру стелей FM.

Проанализировав ситуацию, мы приняли решения дополнить возможности FireMonkey поддержкой растровых (Bitmap) стилей.

Так что же такое растровый стиль, вот скриншот той же кнопки, но уже их XE3:

Заметно, что объектов стало меньше и появился новый тип объекта TSubImage. TSubImage это специальный тип объекта, который позволяет рисовать определенную часть битмапа. Этот объект ссылается на TImage (по средствам свойста Source или StyleLookup) и иcпользует его как источник изображения. Область же задается при помощи свойства SourceRect. Для изменения области можно использовать TRectAnimation. Эта анимация изменяет значения свойста SourceRect, тем самым мы получаем различные виды кнопок в зависимости от состояния.

Вот пример битмапа для кнопки с разлиными состояними:

Таким образом, мы можем использовать готовую графику для придания нового вида нашим контролам. Причем - зачатую сложность стиля (количество объектов) не изменяется в зависимости от сложности графики и соотвествено производительноть остается неизменной.

Кроме того, т.к. подобные стили уже были в VCL, появилась возможность использовать эти стили в FireMonkey. Мы расширили возможности редактора стилей для VCL - добавив возможность экспортировать стили в FireMonkey. Теперь можно сохранить любой стиль VCL в формате FireMonkey:

Т.к. редактор стилей имеет собственный формат, а формат стиля в FireMonkey не имеет какой-то четко заданой структуры - конвертация это односторонняя. Т.е. мы можем сохранить VCL стиль в формате FM, но не можем открыть стиль FM в этом редакторе. Для изменения и модификации стиля FM ( файл с расширением Style) нужно использовать дизайнер находящися в IDE.

Приложение FireMonkey с использованием сконвертированное стиля VCL:

Кроме того, в FM2 появилась поддержка стилизации неклиентской части окна.

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

Posted by Eugene Kryukov on October 3rd, 2012 under Styles | 1 Comment »


Производительность стилей в FireMonkey 2.0

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

Поэтому в новой версии FireMonkey, мы модифировали механизм загрузки и выгрузки стиля для контролов. Теперь все эти вызовы динамические. После загрузки формы, все контролы "пустые" - т.е. в них не загружены стили. Но при первом вызове метода отрисоки контрола, стиль загружается в контрол. Но загрузка проиходит только для тех контролов, которые реально видимы на экране. Обычно, это небольшое количество контролов. В следствии чего - загрузка приложения в FireMonkey 2.0 существенно быстрее. Например, если мы имеем на форме TTabControl с несколькими вкладками, стили загрузятся сразу только для активной вкладки. То же самое для TListBox - стиль будет загружен только для видимых элеметов. По мере прокрутки стиль будет подгружаться в остальные элементы.

И так, загрузка стала быстрее, при чем в некоторых ситуация существенно. Но получается, что по мере загрузки стиля мы имеем все больше и больше объектов и соотвестно время прохода по дереву объектов становится все больше и больше. Для исключения такой ситуации, если контрол становится невидимым (например при прокрутки его за пределы контейнера или при переключении вкладки у TTabControl) - стиль у этого контрола выгружается. Таким образом, производительность контролов существенно возрасла. На примере списка можно сказать - что в любой момент времени стиль загружен только у видимых элементов.

При динамической загрузке/удалении стиля у класса TStyledControl попарно вызываются методы:

procedure ApplyStyle; virtual;
procedure FreeStyle; virtual;

А для загрузки данных в объекты стиля в режиме выполнения, можно использовать событие OnApplyStyleLookup. Это событие каждый раз вызывается при загрузки стиля в контрол. Даже после того как стиль выгрузился из него, при повторной загрузке вызовется этот метод. Используя его, можно гарантировать загрузку данных. Иначе, при обращении в данным стиля через StylesData для невидимого контрола, данные просто потеряются, т.к. стиль еще не загружен.

Пример корректной загрузки данных в стиль в ListBox:

Item := TListBoxItem.Create(nil);
Item.OnApplyStyleLookup := DoApplyStyleLookupFromFile;
Item.Parent := ListBox1;
...
procedure TForm1.DoApplyStyleLookup(Sender: TObject);
var
Item: TListBoxItem;
begin
Item := TListBoxItem(Sender);
Item.StylesData['resolution'] := ‘1024×768 px’; // set size
Item.StylesData['depth'] := ‘32 bit’;
Item.StylesData['visible'] := true; // set Checkbox value
Item.StylesData['visible'] := TValue.From(DoVisibleChange); // set OnChange value
Item.StylesData['info'] := TValue.From(DoInfoClick); // set OnClick value
end;

Кроме того, в новой версии FireMonkey появился механизм позволяющий контролам регулировать дерево обхода дочерних элементов. У класса TControl появились два интересных метода:

function GetFirstVisibleObjectIndex: Integer; virtual;
function GetLastVisibleObjectIndex: Integer; virtual;

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

Posted by Eugene Kryukov on October 2nd, 2012 under Styles | 2 Comments »


DirectX 10 в FireMonkey 2.0

Наверное многие слышали, что в новой версии FireMonkey в Rad Studion XE3 появилась поддержка DirectX 10. На первый взгляд кажется, что речь идет о той части FM, которая отвечает за отображения 3D объектов – не часто используемых в бизнес приложениях. Но замечу, что часть FM2, которая обеспечивает доступ к GPU по средствам классов TContext3D и TContextManager использует не только для отображения 3D объектов. Механизм битмап-эффектов на 99% процентов базируется на использовании GPU, только 2-3 базовых эффекта имею реализации не зависящие от hardware.

Кроме того, если приложение использует 3D для генерации отчётов,  отображения различных графиков и т.п., так же ограничено оборудованием с поддержкой GPU минимум с PixelShader 2.0. Такие GPU давно считаются стандартным оборудованием, но бывают ситуации когда и таких нету в наличии – например в серверной конфигурации.

Так какие же плюсы получает обычное приложение FM2 от использование DirectX 10. Самое интересное для нас нововедение, которое сделали ребята из компании Microsoft в этой версии DirectX – это поддержка software-режима, базирующегося на очень интересной технологии, которая использует преимущества современных СPU, именуемой Warp.

Эта технология, которая позволяет использовать все приемущества DirectX 10 без ограничений и без использования GPU. Вот наглядный пример, на котором видно что при использовании DirectX 10 в software-режиме, с включенным режимом 4x multisampling. Картинка из DirectX 10 имеет заметно качественные края, т.к. GPU на котором запущен тестовый пример физически не поддерживает multisampling и это заметно в режиме DirectX 9.


Что касается производительности, я могу сказать, что на не очень сложных сценах (как раз используемых в бизнес приложениях) DirectX 10 Wrap показывает  очень хорошие результаты, сопоставимые с low-end GPU.

Таким образом, на конфигурациях поддерживающих DirectX 10 (Windows Vista и выше),  приложения FireMonkey могут использовать все свои возможности, что было не возможно в версии для XE2.

Конечно FireMonkey 2 автоматически  использует DirectX 10 в режиме GPU если это возможно.

Posted by Eugene Kryukov on October 2nd, 2012 under 3d | 2 Comments »




Server Response from: BLOGS1