Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 8d3512f1 in mainline


Ignore:
Timestamp:
2014-08-31T14:53:51Z (7 years ago)
Author:
Martin Sucha <sucha14@…>
Branches:
lfn, master
Children:
00ddb40
Parents:
c6c39d4f
Message:

Implement a bilinear filter and use it when compositing windows.

Location:
uspace
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/softrend/filter.c

    rc6c39d4f r8d3512f1  
    11/*
    22 * Copyright (c) 2012 Petr Koupy
     3 * Copyright (c) 2014 Martin Sucha
    34 * All rights reserved.
    45 *
     
    3536
    3637#include "filter.h"
     38#include <io/pixel.h>
     39
     40static long round(double val)
     41{
     42        return val > 0 ? (long) (val + 0.5) : (long) (val - 0.5);
     43}
     44
     45static long floor(double val)
     46{
     47        long lval = (long) val;
     48        if (val < 0 && lval != val)
     49                return lval - 1;
     50        return lval;
     51}
     52
     53static long ceil(double val)
     54{
     55        long lval = (long) val;
     56        if (val > 0 && lval != val)
     57                return lval + 1;
     58        return lval;
     59}
     60
     61static pixel_t get_pixel(pixelmap_t *pixmap, sysarg_t x, sysarg_t y, bool tile)
     62{
     63        if (tile) {
     64                x %= pixmap->width;
     65                y %= pixmap->height;
     66        }
     67
     68        return pixelmap_get_pixel(pixmap, (sysarg_t) x, (sysarg_t) y);
     69}
     70
     71static inline pixel_t blend_pixels(size_t count, float *weights,
     72    pixel_t *pixels)
     73{
     74        float alpha = 0, red = 0, green = 0, blue = 0;
     75        for (size_t index = 0; index < count; index++) {
     76                alpha += weights[index] * ALPHA(pixels[index]);
     77                red   += weights[index] *   RED(pixels[index]);
     78                green += weights[index] * GREEN(pixels[index]);
     79                blue  += weights[index] *  BLUE(pixels[index]);
     80        }
     81       
     82        return PIXEL((uint8_t) alpha, (uint8_t) red, (uint8_t) green,
     83            (uint8_t) blue);
     84}
    3785
    3886pixel_t filter_nearest(pixelmap_t *pixmap, double x, double y, bool tile)
    3987{
    40         long _x = x > 0 ? (long) (x + 0.5) : (long) (x - 0.5);
    41         long _y = y > 0 ? (long) (y + 0.5) : (long) (y - 0.5);
    42 
    43         if (tile) {
    44                 _x %= pixmap->width;
    45                 _y %= pixmap->height;
    46         }
    47 
    48         return pixelmap_get_pixel(pixmap, (sysarg_t) _x, (sysarg_t) _y);
     88        return get_pixel(pixmap, round(x), round(y), tile);
    4989}
    5090
    5191pixel_t filter_bilinear(pixelmap_t *pixmap, double x, double y, bool tile)
    5292{
    53         // TODO
    54         return 0;
     93        long x1 = floor(x);
     94        long x2 = ceil(x);
     95        long y1 = floor(y);
     96        long y2 = ceil(y);
     97       
     98        if (y1 == y2 && x1 == x2) {
     99                return get_pixel(pixmap, (sysarg_t) x1, (sysarg_t) y1,
     100                    tile);
     101        }
     102       
     103        double x_delta = x - x1;
     104        double y_delta = y - y1;
     105       
     106        pixel_t pixels[4];
     107        pixels[0] = get_pixel(pixmap, x1, y1, tile);
     108        pixels[1] = get_pixel(pixmap, x2, y1, tile);
     109        pixels[2] = get_pixel(pixmap, x1, y2, tile);
     110        pixels[3] = get_pixel(pixmap, x2, y2, tile);
     111       
     112        float weights[4];
     113        weights[0] = (1 - x_delta) * (1 - y_delta);
     114        weights[1] = (    x_delta) * (1 - y_delta);
     115        weights[2] = (1 - x_delta) * (    y_delta);
     116        weights[3] = (    x_delta) * (    y_delta);
     117       
     118        return blend_pixels(4, weights, pixels);
    55119}
    56120
  • uspace/srv/hid/compositor/compositor.c

    rc6c39d4f r8d3512f1  
    8484static sysarg_t coord_origin;
    8585static pixel_t bg_color;
     86static filter_t filter = filter_bilinear;
     87static unsigned int filter_index = 1;
    8688
    8789typedef struct {
     
    408410
    409411                        source_init(&source);
    410                         source_set_filter(&source, filter_nearest);
     412                        source_set_filter(&source, filter);
    411413                        drawctx_init(&context, vp->surface);
    412414                        drawctx_set_compose(&context, compose_over);
     
    18181820            key == KC_O || key == KC_P);
    18191821        bool kconsole_switch = (mods & KM_ALT) && (key == KC_M);
    1820 
    1821         bool filter = (type == KEY_RELEASE) && (win_transform || win_resize ||
     1822        bool filter_switch = (mods & KM_ALT) && (key == KC_Y);
     1823
     1824        bool key_filter = (type == KEY_RELEASE) && (win_transform || win_resize ||
    18221825            win_opacity || win_close || win_switch || viewport_move ||
    1823             viewport_change || kconsole_switch);
    1824 
    1825         if (filter) {
     1826            viewport_change || kconsole_switch || filter_switch);
     1827
     1828        if (key_filter) {
    18261829                /* no-op */
    18271830        } else if (win_transform) {
     
    20912094                if (console_kcon())
    20922095                        active = false;
     2096        } else if (filter_switch) {
     2097                filter_index++;
     2098                if (filter_index > 1)
     2099                        filter_index = 0;
     2100                if (filter_index == 0) {
     2101                        filter = filter_nearest;
     2102                }
     2103                else {
     2104                        filter = filter_bilinear;
     2105                }
     2106                comp_damage(0, 0, UINT32_MAX, UINT32_MAX);
    20932107        } else {
    20942108                window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
Note: See TracChangeset for help on using the changeset viewer.