Changeset e1c6d5df in mainline for uspace/lib


Ignore:
Timestamp:
2012-11-29T07:44:58Z (13 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
3194d83
Parents:
ff98ce8 (diff), 82edef2 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge from lp:~petr-koupy/helenos/gui-optim.

The main improvements are:

  • significantly faster rendering (making qemu/non-KVM usable) if user limits himself just to window movement and resizing (i.e. avoiding rotation, scaling and transparency)
  • preview of the result of window transformation is depicted by a "ghost" frame following the mouse pointer
  • changing of window focus feels more natural and intuitive (mouse click handler behaves more like in mainstream operating systems, window titles changes color to reflect whether they have focus or not)
Location:
uspace/lib
Files:
15 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/io/window.c

    rff98ce8 re1c6d5df  
    4040#include <stdio.h>
    4141
    42 int win_register(async_sess_t *sess, service_id_t *in, service_id_t *out)
     42int win_register(async_sess_t *sess, service_id_t *in, service_id_t *out,
     43    sysarg_t x_offset, sysarg_t y_offset)
    4344{
    4445        async_exch_t *exch = async_exchange_begin(sess);
    45         int ret = async_req_0_2(exch, WINDOW_REGISTER, in, out);
     46        int ret = async_req_2_2(exch, WINDOW_REGISTER, x_offset, y_offset, in, out);
    4647        async_exchange_end(exch);
    4748
  • uspace/lib/c/include/io/pixel.h

    rff98ce8 re1c6d5df  
    4242        ((channel) >> (8 - (bits)))
    4343
     44#define INVERT(pixel) ((pixel) ^ 0x00ffffff)
     45
    4446#define ALPHA(pixel)  ((pixel) >> 24)
    4547#define RED(pixel)    (((pixel) & 0x00ff0000) >> 16)
  • uspace/lib/c/include/io/pixelmap.h

    rff98ce8 re1c6d5df  
    5252    sysarg_t y)
    5353{
    54         size_t offset = y * pixelmap->width + x;
    55         pixel_t *pixel = pixelmap->data + offset;
    56         return pixel;
     54        if (x < pixelmap->width && y < pixelmap->height) {
     55                size_t offset = y * pixelmap->width + x;
     56                pixel_t *pixel = pixelmap->data + offset;
     57                return pixel;
     58        } else {
     59                return NULL;
     60        }
    5761}
    5862
  • uspace/lib/c/include/io/window.h

    rff98ce8 re1c6d5df  
    7171        ET_POSITION_EVENT,
    7272        ET_SIGNAL_EVENT,
     73        ET_WINDOW_FOCUS,
     74        ET_WINDOW_UNFOCUS,
    7375        ET_WINDOW_RESIZE,
    7476        ET_WINDOW_REFRESH,
     
    100102} window_grab_flags_t;
    101103
    102 extern int win_register(async_sess_t *, service_id_t *, service_id_t *);
     104extern int win_register(async_sess_t *, service_id_t *, service_id_t *, sysarg_t, sysarg_t);
    103105
    104106extern int win_get_event(async_sess_t *, window_event_t *);
  • uspace/lib/draw/drawctx.c

    rff98ce8 re1c6d5df  
    129129        }
    130130
    131         bool clipped = false;
    132         bool masked = false;
    133 
    134         for (sysarg_t _y = y; _y < y + height; ++_y) {
    135                 for (sysarg_t _x = x; _x < x + width; ++_x) {
    136                         if (context->shall_clip) {
    137                                 clipped = _x < context->clip_x && _x >= context->clip_width
    138                                     && _y < context->clip_y && _y >= context->clip_height;
    139                         }
    140                        
    141                         if (context->mask) {
    142                                 pixel_t p = surface_get_pixel(context->mask, _x, _y);
    143                                 masked = p > 0 ? false : true;
    144                         }
    145 
    146                         if (!clipped && !masked) {
    147                                 pixel_t p_src = source_determine_pixel(context->source, _x, _y);
    148                                 pixel_t p_dst = surface_get_pixel(context->surface, _x, _y);
    149                                 pixel_t p_res = context->compose(p_src, p_dst);
    150                                 surface_put_pixel(context->surface, _x, _y, p_res);
     131        bool transfer_fast = source_is_fast(context->source)
     132            && (context->shall_clip == false)
     133            && (context->mask == NULL)
     134            && (context->compose == compose_src || context->compose == compose_over);
     135
     136        if (transfer_fast) {
     137
     138                for (sysarg_t _y = y; _y < y + height; ++_y) {
     139                        pixel_t *src = source_direct_access(context->source, x, _y);
     140                        pixel_t *dst = pixelmap_pixel_at(surface_pixmap_access(context->surface), x, _y);
     141                        if (src && dst) {
     142                                sysarg_t count = width;
     143                                while (count-- != 0) {
     144                                        *dst++ = *src++;
     145                                }
    151146                        }
    152147                }
     148                surface_add_damaged_region(context->surface, x, y, width, height);
     149
     150        } else {
     151
     152                bool clipped = false;
     153                bool masked = false;
     154                for (sysarg_t _y = y; _y < y + height; ++_y) {
     155                        for (sysarg_t _x = x; _x < x + width; ++_x) {
     156                                if (context->shall_clip) {
     157                                        clipped = _x < context->clip_x && _x >= context->clip_width
     158                                            && _y < context->clip_y && _y >= context->clip_height;
     159                                }
     160
     161                                if (context->mask) {
     162                                        pixel_t p = surface_get_pixel(context->mask, _x, _y);
     163                                        masked = p > 0 ? false : true;
     164                                }
     165
     166                                if (!clipped && !masked) {
     167                                        pixel_t p_src = source_determine_pixel(context->source, _x, _y);
     168                                        pixel_t p_dst = surface_get_pixel(context->surface, _x, _y);
     169                                        pixel_t p_res = context->compose(p_src, p_dst);
     170                                        surface_put_pixel(context->surface, _x, _y, p_res);
     171                                }
     172                        }
     173                }
     174
    153175        }
    154176}
  • uspace/lib/draw/source.c

    rff98ce8 re1c6d5df  
    9090}
    9191
     92bool source_is_fast(source_t *source)
     93{
     94        return (source->mask == NULL)
     95            && (source->alpha == (pixel_t) PIXEL(255, 0, 0, 0))
     96            && (source->texture != NULL)
     97            && (source->texture_tile == false)
     98            && transform_is_fast(&source->transform);
     99}
     100
     101pixel_t *source_direct_access(source_t *source, double x, double y)
     102{
     103        assert(source_is_fast(source));
     104
     105        long _x = (long) (x + source->transform.m[0][2]);
     106        long _y = (long) (y + source->transform.m[1][2]);
     107
     108        return pixelmap_pixel_at(
     109            surface_pixmap_access(source->texture), (sysarg_t) _x, (sysarg_t) _y);
     110}
     111
    92112pixel_t source_determine_pixel(source_t *source, double x, double y)
    93113{
  • uspace/lib/draw/source.h

    rff98ce8 re1c6d5df  
    7171extern void source_set_mask(source_t *, surface_t *, bool);
    7272
     73extern bool source_is_fast(source_t *);
     74extern pixel_t *source_direct_access(source_t *, double, double);
    7375extern pixel_t source_determine_pixel(source_t *, double, double);
    7476
  • uspace/lib/draw/surface.c

    rff98ce8 re1c6d5df  
    143143}
    144144
     145void surface_add_damaged_region(surface_t *surface, surface_coord_t x, surface_coord_t y,
     146    surface_coord_t width, surface_coord_t height)
     147{
     148        surface->dirty_x_lo = surface->dirty_x_lo > x ? x : surface->dirty_x_lo;
     149        surface->dirty_y_lo = surface->dirty_y_lo > y ? y : surface->dirty_y_lo;
     150
     151        surface_coord_t x_hi = x + width - 1;
     152        surface_coord_t y_hi = y + height - 1;
     153
     154        surface->dirty_x_hi = surface->dirty_x_hi < x_hi ? x_hi : surface->dirty_x_hi;
     155        surface->dirty_y_hi = surface->dirty_y_hi < y_hi ? y_hi : surface->dirty_y_hi;
     156}
     157
    145158void surface_reset_damaged_region(surface_t *surface)
    146159{
     
    158171        surface->dirty_y_hi = surface->dirty_y_hi < y ? y : surface->dirty_y_hi;
    159172
    160         if (x < surface->pixmap.width && y < surface->pixmap.height) {
    161                 pixelmap_put_pixel(&surface->pixmap, x, y, pixel);
    162         }
     173        pixelmap_put_pixel(&surface->pixmap, x, y, pixel);
    163174}
    164175
    165176pixel_t surface_get_pixel(surface_t *surface, surface_coord_t x, surface_coord_t y)
    166177{
    167         if (x < surface->pixmap.width && y < surface->pixmap.height) {
    168                 return pixelmap_get_pixel(&surface->pixmap, x, y);
    169         } else {
    170                 return 0;
    171         }
     178        return pixelmap_get_pixel(&surface->pixmap, x, y);
    172179}
    173180
  • uspace/lib/draw/surface.h

    rff98ce8 re1c6d5df  
    6161extern void surface_get_damaged_region(surface_t *, surface_coord_t *, surface_coord_t *,
    6262    surface_coord_t *, surface_coord_t *);
     63extern void surface_add_damaged_region(surface_t *, surface_coord_t , surface_coord_t ,
     64    surface_coord_t , surface_coord_t );
    6365extern void surface_reset_damaged_region(surface_t *);
    6466
  • uspace/lib/gui/terminal.c

    rff98ce8 re1c6d5df  
    196196        uint16_t glyph = fb_font_glyph(field->ch);
    197197       
    198         // FIXME: This font drawing routine is shamelessly
    199         //        suboptimal. It should be optimized for
    200         //        aligned memory transfers, etc.
    201        
    202198        for (unsigned int y = 0; y < FONT_SCANLINES; y++) {
    203                 for (unsigned int x = 0; x < FONT_WIDTH; x++) {
    204                         pixel_t pixel =
    205                             (fb_font[glyph][y] & (1 << (7 - x))) ? fgcolor : bgcolor;
    206                         surface_put_pixel(surface, bx + x, by + y, pixel);
     199                pixel_t *dst = pixelmap_pixel_at(
     200                    surface_pixmap_access(surface), bx, by + y);
     201                pixel_t *dst_max = pixelmap_pixel_at(
     202                    surface_pixmap_access(surface), bx + FONT_WIDTH - 1, by + y);
     203                if (!dst || !dst_max) continue;
     204                int count = FONT_WIDTH;
     205                while (count-- != 0) {
     206                        *dst++ = (fb_font[glyph][y] & (1 << count)) ? fgcolor : bgcolor;
    207207                }
    208208        }
     209        surface_add_damaged_region(surface, bx, by, FONT_WIDTH, FONT_SCANLINES);
    209210}
    210211
  • uspace/lib/gui/window.c

    rff98ce8 re1c6d5df  
    6666
    6767static pixel_t border_color = PIXEL(255, 0, 0, 0);
    68 static pixel_t header_bgcolor = PIXEL(255, 25, 25, 112);
    69 static pixel_t header_fgcolor = PIXEL(255, 255, 255, 255);
     68static pixel_t header_bg_focus_color = PIXEL(255, 25, 25, 112);
     69static pixel_t header_fg_focus_color = PIXEL(255, 255, 255, 255);
     70static pixel_t header_bg_unfocus_color = PIXEL(255, 70, 130, 180);
     71static pixel_t header_fg_unfocus_color = PIXEL(255, 255, 255, 255);
    7072
    7173static void paint_internal(widget_t *w)
     
    9496            w->vpos + w->height - border_thickness, w->width, border_thickness);
    9597
    96         source_set_color(&source, header_bgcolor);
     98        source_set_color(&source,
     99            w->window->is_focused ? header_bg_focus_color : header_bg_unfocus_color);
    97100        drawctx_transfer(&drawctx,
    98101            w->hpos + border_thickness, w->vpos + border_thickness,
     
    106109        char cls_pict[] = "x";
    107110        font_get_box(&font, cls_pict, &cls_width, &cls_height);
    108         source_set_color(&source, header_fgcolor);
     111        source_set_color(&source,
     112            w->window->is_focused ? header_fg_focus_color : header_fg_unfocus_color);
    109113        sysarg_t cls_x = ((close_width - cls_width) / 2) + w->hpos + w->width -
    110114            border_thickness - close_width;
     
    447451                        break;
    448452                case ET_POSITION_EVENT:
     453                        if (!win->is_focused) {
     454                                win->is_focused = true;
     455                                handle_refresh(win);
     456                        }
    449457                        deliver_position_event(win, event->data.pos);
    450458                        break;
     
    454462                case ET_WINDOW_RESIZE:
    455463                        handle_resize(win, event->data.rsz.width, event->data.rsz.height);
     464                        break;
     465                case ET_WINDOW_FOCUS:
     466                        if (!win->is_focused) {
     467                                win->is_focused = true;
     468                                handle_refresh(win);
     469                        }
     470                        break;
     471                case ET_WINDOW_UNFOCUS:
     472                        if (win->is_focused) {
     473                                win->is_focused = false;
     474                                handle_refresh(win);
     475                        }
    456476                        break;
    457477                case ET_WINDOW_REFRESH:
     
    514534}
    515535
    516 window_t *window_open(char *winreg, bool is_main, bool is_decorated, const char *caption)
     536window_t *window_open(char *winreg, bool is_main, bool is_decorated,
     537    const char *caption, sysarg_t x_offset, sysarg_t y_offset)
    517538{
    518539        int rc;
     
    525546        win->is_main = is_main;
    526547        win->is_decorated = is_decorated;
     548        win->is_focused = true;
    527549        prodcons_initialize(&win->events);
    528550        fibril_mutex_initialize(&win->guard);
     
    557579        service_id_t out_dsid;
    558580       
    559         rc = win_register(reg_sess, &in_dsid, &out_dsid);
     581        rc = win_register(reg_sess, &in_dsid, &out_dsid, x_offset, y_offset);
    560582        async_hangup(reg_sess);
    561583        if (rc != EOK) {
  • uspace/lib/gui/window.h

    rff98ce8 re1c6d5df  
    5050        bool is_main; /**< True for the main window of the application. */
    5151        bool is_decorated; /**< True if the window decorations should be rendered. */
     52        bool is_focused; /**< True for the top level window of the desktop. */
    5253        char *caption; /**< Text title of the window header. */
    5354        async_sess_t *isess; /**< Input events from compositor. */
     
    6566 * If the window is declared as main, its closure causes termination of the
    6667 * whole application. Note that opened window does not have any surface yet. */
    67 extern window_t *window_open(char *, bool, bool, const char *);
     68extern window_t *window_open(char *, bool, bool, const char *, sysarg_t, sysarg_t);
    6869
    6970/**
  • uspace/lib/softrend/filter.c

    rff98ce8 re1c6d5df  
    4444                _x %= pixmap->width;
    4545                _y %= pixmap->height;
    46         } else if (_x < 0 || _x >= (long) pixmap->width || _y < 0 || _y >= (long) pixmap->height) {
    47                 return 0;
    4846        }
    4947
  • uspace/lib/softrend/transform.c

    rff98ce8 re1c6d5df  
    136136}
    137137
     138bool transform_is_fast(transform_t *t)
     139{
     140        return (t->m[0][0] == 1) && (t->m[0][1] == 0)
     141            && (t->m[1][0] == 0) && (t->m[1][1] == 1)
     142            && ((t->m[0][2] - ((long) t->m[0][2])) == 0.0)
     143            && ((t->m[1][2] - ((long) t->m[1][2])) == 0.0);
     144}
     145
    138146void transform_apply_linear(const transform_t *t, double *x, double *y)
    139147{
  • uspace/lib/softrend/transform.h

    rff98ce8 re1c6d5df  
    3737#define SOFTREND_TRANSFORM_H_
    3838
     39#include <bool.h>
     40
    3941#ifndef PI
    4042#define PI 3.141592653589793
     
    5355extern void transform_rotate(transform_t *, double);
    5456
     57extern bool transform_is_fast(transform_t *);
     58
    5559extern void transform_apply_linear(const transform_t *, double *, double *);
    5660extern void transform_apply_affine(const transform_t *, double *, double *);
Note: See TracChangeset for help on using the changeset viewer.