Evas Rendering Concept and Method
Evas is a canvas display library. It is markedly different from most display and windowing systems as the canvas is structural and is also a state engine, whereas most display and windowing systems are immediate mode display targets. Evas handles the logic between a structural display via its state engine, and controls the target windowing system in order to produce rendered results of the current canvas' state on the display.
Immediate mode display systems retain very little or no state. A program executes a series of commands, as in the following pseudo code.
draw line from position (0, 0) to position (100, 200); draw rectangle from position (10, 30) to position (50, 500); bitmap_handle = create_bitmap(); scale bitmap_handle to size 100 x 100; draw image bitmap_handle at position (10, 30);
The series of commands is executed by the windowing system and the results are typically displayed on the screen. Once the commands are executed, the display system does not know how to reproduce this image again, and has to be instructed by the application on how to redraw sections of the screen if needed. Each successive command is executed as instructed by the application and either emulated by software or sent to the graphics hardware on the device to be performed.
The advantage of such a system is that it is simple and gives a program tight control over how something looks and is drawn. Given the increasing complexity of displays and demands by users to have better looking interfaces, more work needs to be done at this level by the internals of UI component sets, custom display components and other programs. This means that more logic and display rendering code needs to be written again each time the application needs to figure out how to minimize redraws so that display is fast and interactive, and keep track of redraw logic.
For example, if in the scene below, the windowing system requires the application to redraw the area from 0, 0 to 50, 50 (also referred to as the "expose event"). Then the programmer calculates manually the updates and repaints it again.
Redraw from position (0, 0) to position (50, 50): // What was in area (0, 0, 50, 50)? // 1. intersection part of line (0, 0) to (100, 200)? draw line from position (0, 0) to position (25, 50); // 2. intersection part of rectangle (10, 30) to (50, 500)? draw rectangle from position (10, 30) to position (50, 50) // 3. intersection part of image at (10, 30), size 100 x 100? bitmap_subimage = subregion from position (0, 0) to position (40, 20) draw image bitmap_subimage at position (10, 30);
If all elements in the above scene are opaque, the system is doing useless paints: part of the line is behind the rectangle, and part of the rectangle is behind the image. These useless paints tend to be very costly.
Evas is a structural system in which the programmer creates and manages display objects and their properties, and as a result of this higher level state management, the canvas is able to redraw the set of objects when needed to represent the current state of the canvas.
For example, see the following pseudo code.
line_handle = create_line(); set line_handle from position (0, 0) to position (100, 200); show line_handle; rectangle_handle = create_rectangle(); move rectangle_handle to position (10, 30); resize rectangle_handle to size 40 x 470; show rectangle_handle; bitmap_handle = create_bitmap(); scale bitmap_handle to size 100 x 100; move bitmap_handle to position (10, 30); show bitmap_handle; render scene;
This looks longer, but when the display needs to be refreshed or updated, the programmer only moves, resizes, shows, hides etc. the objects that need to change. The programmer thinks at the object logic level, and the canvas software does the rest of the work, figuring out what changed in the canvas since it was last drawn, how to most efficiently redraw the canvas and its contents to reflect the current state, and doing the actual drawing of the canvas.
This allows the programmer think in a more natural way when dealing with a display, and saves time and effort of working out how to load and display images, to render given the current display system etc. Since Evas is portable across different display systems, this gives the programmer the ability to port and display the code on different display systems with little work.
Evas is a display system somewhere between a UI component set and an immediate mode display system. It retains basic display logic, but does little high-level logic such as scrollbars, sliders, push buttons etc.
For more information on the UI rendering modes (immediate and retained), see UI Rendering Mode.
Evas Engines Concept
Evas delegates most of the actual rendering work to its engines. Engines are the backends that Evas uses to render (primitive) objects on a canvas. The canvas can be the screen, or a buffer in the memory.
Evas can work with and provides multiple engines, such as (this list is non-exhaustive):
- buffer: all the rendering takes place in a buffer
- fb: the rendering takes place in the system's framebuffer
- software_x11: this is the most used, using X11
- gl_x11: this also renders to an X11 window, except that it uses OpenGL
These implement the rendering of all the basic objects by themselves, because they often can be accelerated by the hardware or backend software libraries to provide fast rendering.
If a particular engine does not have the provision for a certain primitive object, it reverts back to using a default software version.
UI Rendering Mode
Evas removes the need to know about the characteristics of your display system or what graphics calls are used to draw them and how. It deals on an object level where all you do is create and manipulate objects in a canvas, set their properties, and the rest is done for you. This rendering method is called the retained mode, whereas the immediate mode is an alternative rendering method.
Immediate Mode
The immediate mode is the most commonly used in graphics toolkit libraries, such as GTK+, GDI, and GDI+. The application is responsible for repainting the portion of the client area that is invalidated.
Figure: Immediate mode
The application commands any drawing issues as it needs, and the display system draws some GUIs. After the drawing is done, it appears in the destination. This mode allows you to have a exact control over the render cycles. However, if the draw commands are misused, unnecessary drawing can be performed or drawing never happen at all.
The following example explains the common usage of the immediate mode:
void update() { Image *img = load_image(NEW_IMG); // Switch button image to new one update_button_image(img); // Issue the invalidate area (button area) to be redrawn on the screen invalidate_area(button_x, button_y, button_w, button_h); // Move rectangle from (200, 200) to (300, 300) int rect_prev_x = rect_x; int rect_prev_y = rect_y; rectangle_x = 300; rectangle_y = 300; set_rect_position(rect_x, rect_y); // Issue the invalidate area (changed area) to be redrawn on the screen int diff_x = rect_x – rect_prev_x; int diff_y = rect_y – rect_prev_y; invalidate_area(rect_prev_x, rect_prev_y, (rect_w + diff_x), (rect_h + diff_y)); // After setting the invalidate area, request rendering to update the screen render(); // Now you can see how the button image and rectangle position are changed }
Retained Mode
A graphics system adopting the retained mode is basically responsible for responding to all repaint requests for rendering the application objects. Clients do not directly cause actual rendering, but objects are redrawn when parts of them are updated.
Figure: Retained mode
Since Evas works with the retained mode, there is no need to command any drawings. The following example shows how to write a GUI code with Evas for your application:
void create_image() { // Initialize an image object to be displayed on the screen Evas_Object *img = evas_object_image_add(e); // Set image resource evas_object_image_file_set(img, IMG, NULL); // Set image position evas_object_move(img, 100, 100); // Set image size evas_object_resize(img, 200, 200); // Set image visibility (show or hide) evas_object_show(img); } void create_rectangle() { // Initialize an rectangle object to be displayed on the screen Evas_Object *rect = evas_object_rectangle_add(e); // Set rectangle color evas_object_color_set(rect, 255, 0, 0, 255); // Set rectangle position evas_object_move(rect, 200, 200); // Set rectangle size evas_object_resize(rect, 200, 200); // Set rectangle visibility (show or hide) evas_object_show(rect); }
A few main loops later you can replace the image with another one and move the rectangle. You only need to set a new image file to the image object and move the rectangle object. Evas computes the invalidate area and redraws the image and rectangle behind the application when it's on rendering time.
void update() { // Set new image resource elm_image_file_set(img, NEW_IMG, NULL); // Set new rectangle position evas_object_move(rect, 300, 300); }
Evas Rendering
Tizen Native applications work on the ecore main loop, and the loop goes on a few steps for every frame. Evas redraws some changes in the objects when the main loop goes to the idle enterer step. If there are no changes, Evas rendering is skipped. Otherwise, Evas calculates any changed portions of all display objects and redraws them.
Figure: Evas rendering in the main loop
To minimize the rendering, Evas tracks the states of all display objects, such as position, size, visibility, and color. Even if some of these states are changed but the object is hidden by other obscured objects, it is not redrawn. In other words, Evas draws only the necessary changes in the screen.
The following figures illustrate how Evas redraws the changed area:
-
In the first example, there is a blue-color background object (a sky-blue color rectangle) and a partially hidden cloud image object. Above them, there are a red and green rectangle, and the "Hello out there" text is printed on the green rectangle.
Figure: Evas redrawing example 1
-
In the second example, some of the objects have moved (the cloud image is moved to right and the green rectangle is moved downwards).
Figure: Evas redrawing example 2
-
As a result, the third example illustrates some regions that require updates.
Figure: Evas redrawing example 3
-
Evas decides which portions are invalid and to be redrawn. The fourth example shows the cleaned portion of the screen, which is the redrawn area.
Evas redraws the content only in the redrawn portions.
Figure: Evas redrawing example 4
-
Finally, the fifth example shows how the screen is updated and the result is visible.
Figure: Evas redrawing example 5
If Evas worked in an immediate mode style, the application would need to calculate the changed areas themselves, adding extra work. With Evas, you can let Evas figure out the updates and you can yourself concentrate on the application and UI core and logic.
Note |
---|
Except as noted, this content is licensed under LGPLv2.1+. |