xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

present_fake.c (4674B)


      1 /*
      2  * Copyright © 2013 Keith Packard
      3  *
      4  * Permission to use, copy, modify, distribute, and sell this software and its
      5  * documentation for any purpose is hereby granted without fee, provided that
      6  * the above copyright notice appear in all copies and that both that copyright
      7  * notice and this permission notice appear in supporting documentation, and
      8  * that the name of the copyright holders not be used in advertising or
      9  * publicity pertaining to distribution of the software without specific,
     10  * written prior permission.  The copyright holders make no representations
     11  * about the suitability of this software for any purpose.  It is provided "as
     12  * is" without express or implied warranty.
     13  *
     14  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
     15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
     16  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
     17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
     18  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
     19  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
     20  * OF THIS SOFTWARE.
     21  */
     22 
     23 #include "present_priv.h"
     24 #include "list.h"
     25 
     26 static struct xorg_list fake_vblank_queue;
     27 
     28 typedef struct present_fake_vblank {
     29     struct xorg_list            list;
     30     uint64_t                    event_id;
     31     OsTimerPtr                  timer;
     32     ScreenPtr                   screen;
     33 } present_fake_vblank_rec, *present_fake_vblank_ptr;
     34 
     35 int
     36 present_fake_get_ust_msc(ScreenPtr screen, uint64_t *ust, uint64_t *msc)
     37 {
     38     present_screen_priv_ptr screen_priv = present_screen_priv(screen);
     39 
     40     *ust = GetTimeInMicros();
     41     *msc = (*ust + screen_priv->fake_interval / 2) / screen_priv->fake_interval;
     42     return Success;
     43 }
     44 
     45 static void
     46 present_fake_notify(ScreenPtr screen, uint64_t event_id)
     47 {
     48     uint64_t                    ust, msc;
     49 
     50     present_fake_get_ust_msc(screen, &ust, &msc);
     51     present_event_notify(event_id, ust, msc);
     52 }
     53 
     54 static CARD32
     55 present_fake_do_timer(OsTimerPtr timer,
     56                       CARD32 time,
     57                       void *arg)
     58 {
     59     present_fake_vblank_ptr     fake_vblank = arg;
     60 
     61     present_fake_notify(fake_vblank->screen, fake_vblank->event_id);
     62     xorg_list_del(&fake_vblank->list);
     63     TimerFree(fake_vblank->timer);
     64     free(fake_vblank);
     65     return 0;
     66 }
     67 
     68 void
     69 present_fake_abort_vblank(ScreenPtr screen, uint64_t event_id, uint64_t msc)
     70 {
     71     present_fake_vblank_ptr     fake_vblank, tmp;
     72 
     73     xorg_list_for_each_entry_safe(fake_vblank, tmp, &fake_vblank_queue, list) {
     74         if (fake_vblank->event_id == event_id) {
     75             TimerFree(fake_vblank->timer); /* TimerFree will call TimerCancel() */
     76             xorg_list_del(&fake_vblank->list);
     77             free (fake_vblank);
     78             break;
     79         }
     80     }
     81 }
     82 
     83 int
     84 present_fake_queue_vblank(ScreenPtr     screen,
     85                           uint64_t      event_id,
     86                           uint64_t      msc)
     87 {
     88     present_screen_priv_ptr     screen_priv = present_screen_priv(screen);
     89     uint64_t                    ust = msc * screen_priv->fake_interval;
     90     uint64_t                    now = GetTimeInMicros();
     91     INT32                       delay = ((int64_t) (ust - now)) / 1000;
     92     present_fake_vblank_ptr     fake_vblank;
     93 
     94     if (delay <= 0) {
     95         present_fake_notify(screen, event_id);
     96         return Success;
     97     }
     98 
     99     fake_vblank = calloc (1, sizeof (present_fake_vblank_rec));
    100     if (!fake_vblank)
    101         return BadAlloc;
    102 
    103     fake_vblank->screen = screen;
    104     fake_vblank->event_id = event_id;
    105     fake_vblank->timer = TimerSet(NULL, 0, delay, present_fake_do_timer, fake_vblank);
    106     if (!fake_vblank->timer) {
    107         free(fake_vblank);
    108         return BadAlloc;
    109     }
    110 
    111     xorg_list_add(&fake_vblank->list, &fake_vblank_queue);
    112 
    113     return Success;
    114 }
    115 
    116 uint32_t FakeScreenFps = 0;
    117 
    118 void
    119 present_fake_screen_init(ScreenPtr screen)
    120 {
    121     uint32_t                fake_fps;
    122     present_screen_priv_ptr screen_priv = present_screen_priv(screen);
    123 
    124     if (FakeScreenFps)
    125         fake_fps = FakeScreenFps;
    126     else {
    127         /* For screens with hardware vblank support, the fake code
    128         * will be used for off-screen windows and while screens are blanked,
    129         * in which case we want a large interval here: 1Hz
    130         *
    131         * Otherwise, pretend that the screen runs at 60Hz
    132         */
    133         if (screen_priv->info && screen_priv->info->get_crtc)
    134             fake_fps = 1;
    135         else
    136             fake_fps = 60;
    137     }
    138     screen_priv->fake_interval = 1000000 / fake_fps;
    139 }
    140 
    141 void
    142 present_fake_queue_init(void)
    143 {
    144     xorg_list_init(&fake_vblank_queue);
    145 }