I'm trying to make a very simple SDL2 app that just scrolls a texture from an image over the screen.
I need to run it on a pretty old device though:
$ inxi -a
CPU: Single Core Intel Atom N270 (-MT-) speed/min/max: 1600/800/1600 MHz
Kernel: 4.9.126-antix.1-486-smp i686 Up: 1m Mem: 94.4/992.7 MiB (9.5%) Storage: 14.92 GiB (32.0% used)
Procs: 154 Shell: bash 4.4.12 inxi: 3.0.36
urve#urve:~
$ inxi -G
Graphics: Device-1: Intel Mobile 945GSE Express Integrated Graphics driver: i915 v: kernel
Display: server: X.org 1.19.2 driver: intel tty: 111x45
Message: Advanced graphics data unavailable in console. Try -G --display
$ free -h
total used free shared buff/cache available
Mem: 992M 76M 666M 60M 249M 833M
Swap: 2.0G 0B 2.0G
It's running Linux Antix:
$ uname -a
Linux urve 4.9.126-antix.1-486-smp #1 SMP Mon Sep 10 16:55:08 BST 2018 i686 GNU/Linux
$ lsb_release -a
No LSB modules are available.
Distributor ID: antiX
Description: antiX 17.2
Release: 17.2
Codename: stretch
Here's output of glxinfo:
DISPLAY=:0.0 glxinfo
name of display: :0.0
display: :0 screen: 0
direct rendering: Yes
server glx vendor string: SGI
server glx version string: 1.4
server glx extensions:
GLX_ARB_create_context, GLX_ARB_create_context_profile,
GLX_ARB_fbconfig_float, GLX_ARB_framebuffer_sRGB, GLX_ARB_multisample,
GLX_EXT_create_context_es2_profile, GLX_EXT_create_context_es_profile,
GLX_EXT_fbconfig_packed_float, GLX_EXT_framebuffer_sRGB,
GLX_EXT_import_context, GLX_EXT_libglvnd, GLX_EXT_texture_from_pixmap,
GLX_EXT_visual_info, GLX_EXT_visual_rating, GLX_INTEL_swap_event,
GLX_MESA_copy_sub_buffer, GLX_OML_swap_method, GLX_SGIS_multisample,
GLX_SGIX_fbconfig, GLX_SGIX_pbuffer, GLX_SGIX_visual_select_group,
GLX_SGI_make_current_read, GLX_SGI_swap_control
client glx vendor string: Mesa Project and SGI
client glx version string: 1.4
client glx extensions:
GLX_ARB_create_context, GLX_ARB_create_context_profile,
GLX_ARB_create_context_robustness, GLX_ARB_fbconfig_float,
GLX_ARB_framebuffer_sRGB, GLX_ARB_get_proc_address, GLX_ARB_multisample,
GLX_EXT_buffer_age, GLX_EXT_create_context_es2_profile,
GLX_EXT_create_context_es_profile, GLX_EXT_fbconfig_packed_float,
GLX_EXT_framebuffer_sRGB, GLX_EXT_import_context,
GLX_EXT_texture_from_pixmap, GLX_EXT_visual_info, GLX_EXT_visual_rating,
GLX_INTEL_swap_event, GLX_MESA_copy_sub_buffer,
GLX_MESA_multithread_makecurrent, GLX_MESA_query_renderer,
GLX_MESA_swap_control, GLX_OML_swap_method, GLX_OML_sync_control,
GLX_SGIS_multisample, GLX_SGIX_fbconfig, GLX_SGIX_pbuffer,
GLX_SGIX_visual_select_group, GLX_SGI_make_current_read,
GLX_SGI_swap_control, GLX_SGI_video_sync
GLX version: 1.4
GLX extensions:
GLX_ARB_create_context, GLX_ARB_create_context_profile,
GLX_ARB_fbconfig_float, GLX_ARB_framebuffer_sRGB,
GLX_ARB_get_proc_address, GLX_ARB_multisample,
GLX_EXT_create_context_es2_profile, GLX_EXT_create_context_es_profile,
GLX_EXT_fbconfig_packed_float, GLX_EXT_framebuffer_sRGB,
GLX_EXT_import_context, GLX_EXT_texture_from_pixmap, GLX_EXT_visual_info,
GLX_EXT_visual_rating, GLX_INTEL_swap_event, GLX_MESA_copy_sub_buffer,
GLX_MESA_multithread_makecurrent, GLX_MESA_query_renderer,
GLX_MESA_swap_control, GLX_OML_swap_method, GLX_OML_sync_control,
GLX_SGIS_multisample, GLX_SGIX_fbconfig, GLX_SGIX_pbuffer,
GLX_SGIX_visual_select_group, GLX_SGI_make_current_read,
GLX_SGI_swap_control, GLX_SGI_video_sync
Extended renderer info (GLX_MESA_query_renderer):
Vendor: Intel Open Source Technology Center (0x8086)
Device: Mesa DRI Intel(R) 945GME x86/MMX/SSE2 (0x27ae)
Version: 13.0.6
Accelerated: yes
Video memory: 192MB
Unified memory: yes
Preferred profile: compat (0x2)
Max core profile version: 0.0
Max compat profile version: 2.1
Max GLES1 profile version: 1.1
Max GLES[23] profile version: 2.0
OpenGL vendor string: Intel Open Source Technology Center
OpenGL renderer string: Mesa DRI Intel(R) 945GME x86/MMX/SSE2
OpenGL version string: 2.1 Mesa 13.0.6
OpenGL shading language version string: 1.20
OpenGL extensions:
GL_3DFX_texture_compression_FXT1, GL_AMD_shader_trinary_minmax,
GL_ANGLE_texture_compression_dxt3, GL_ANGLE_texture_compression_dxt5,
GL_APPLE_object_purgeable, GL_APPLE_packed_pixels,
GL_APPLE_vertex_array_object, GL_ARB_ES2_compatibility,
GL_ARB_clear_buffer_object, GL_ARB_compressed_texture_pixel_storage,
GL_ARB_copy_buffer, GL_ARB_debug_output, GL_ARB_depth_texture,
GL_ARB_draw_buffers, GL_ARB_draw_elements_base_vertex,
GL_ARB_explicit_attrib_location, GL_ARB_explicit_uniform_location,
GL_ARB_fragment_program, GL_ARB_fragment_shader,
GL_ARB_framebuffer_object, GL_ARB_get_program_binary,
GL_ARB_get_texture_sub_image, GL_ARB_half_float_pixel,
GL_ARB_internalformat_query, GL_ARB_invalidate_subdata,
GL_ARB_map_buffer_alignment, GL_ARB_map_buffer_range, GL_ARB_multi_bind,
GL_ARB_multisample, GL_ARB_multitexture, GL_ARB_occlusion_query,
GL_ARB_pixel_buffer_object, GL_ARB_point_parameters, GL_ARB_point_sprite,
GL_ARB_program_interface_query, GL_ARB_provoking_vertex,
GL_ARB_robustness, GL_ARB_sampler_objects, GL_ARB_separate_shader_objects,
GL_ARB_shader_objects, GL_ARB_shading_language_100, GL_ARB_shadow,
GL_ARB_sync, GL_ARB_texture_border_clamp, GL_ARB_texture_compression,
GL_ARB_texture_cube_map, GL_ARB_texture_env_add,
GL_ARB_texture_env_combine, GL_ARB_texture_env_crossbar,
GL_ARB_texture_env_dot3, GL_ARB_texture_mirrored_repeat,
GL_ARB_texture_non_power_of_two, GL_ARB_texture_rectangle,
GL_ARB_texture_storage, GL_ARB_transpose_matrix,
GL_ARB_vertex_array_object, GL_ARB_vertex_attrib_binding,
GL_ARB_vertex_buffer_object, GL_ARB_vertex_program, GL_ARB_vertex_shader,
GL_ARB_window_pos, GL_ATI_blend_equation_separate, GL_ATI_draw_buffers,
GL_ATI_separate_stencil, GL_ATI_texture_env_combine3, GL_EXT_abgr,
GL_EXT_bgra, GL_EXT_blend_color, GL_EXT_blend_equation_separate,
GL_EXT_blend_func_separate, GL_EXT_blend_minmax, GL_EXT_blend_subtract,
GL_EXT_compiled_vertex_array, GL_EXT_copy_texture,
GL_EXT_draw_range_elements, GL_EXT_fog_coord, GL_EXT_framebuffer_blit,
GL_EXT_framebuffer_object, GL_EXT_gpu_program_parameters,
GL_EXT_multi_draw_arrays, GL_EXT_packed_depth_stencil,
GL_EXT_packed_pixels, GL_EXT_pixel_buffer_object, GL_EXT_point_parameters,
GL_EXT_polygon_offset, GL_EXT_provoking_vertex, GL_EXT_rescale_normal,
GL_EXT_secondary_color, GL_EXT_separate_specular_color,
GL_EXT_shadow_funcs, GL_EXT_stencil_two_side, GL_EXT_stencil_wrap,
GL_EXT_subtexture, GL_EXT_texture, GL_EXT_texture3D,
GL_EXT_texture_compression_dxt1, GL_EXT_texture_cube_map,
GL_EXT_texture_edge_clamp, GL_EXT_texture_env_add,
GL_EXT_texture_env_combine, GL_EXT_texture_env_dot3,
GL_EXT_texture_filter_anisotropic, GL_EXT_texture_lod_bias,
GL_EXT_texture_object, GL_EXT_texture_rectangle, GL_EXT_texture_sRGB,
GL_EXT_texture_sRGB_decode, GL_EXT_vertex_array,
GL_IBM_multimode_draw_arrays, GL_IBM_rasterpos_clip,
GL_IBM_texture_mirrored_repeat, GL_INGR_blend_func_separate,
GL_KHR_context_flush_control, GL_KHR_debug, GL_MESA_pack_invert,
GL_MESA_window_pos, GL_MESA_ycbcr_texture, GL_NV_blend_square,
GL_NV_light_max_exponent, GL_NV_packed_depth_stencil,
GL_NV_texgen_reflection, GL_NV_texture_env_combine4,
GL_NV_texture_rectangle, GL_OES_EGL_image, GL_OES_read_format,
GL_S3_s3tc, GL_SGIS_generate_mipmap, GL_SGIS_texture_border_clamp,
GL_SGIS_texture_edge_clamp, GL_SGIS_texture_lod, GL_SUN_multi_draw_arrays
OpenGL ES profile version string: OpenGL ES 2.0 Mesa 13.0.6
OpenGL ES profile shading language version string: OpenGL ES GLSL ES 1.0.16
OpenGL ES profile extensions:
GL_ANGLE_texture_compression_dxt3, GL_ANGLE_texture_compression_dxt5,
GL_APPLE_texture_max_level, GL_EXT_blend_minmax,
GL_EXT_discard_framebuffer, GL_EXT_draw_buffers,
GL_EXT_draw_elements_base_vertex, GL_EXT_map_buffer_range,
GL_EXT_multi_draw_arrays, GL_EXT_read_format_bgra,
GL_EXT_separate_shader_objects, GL_EXT_texture_border_clamp,
GL_EXT_texture_compression_dxt1, GL_EXT_texture_filter_anisotropic,
GL_EXT_texture_format_BGRA8888, GL_EXT_texture_type_2_10_10_10_REV,
GL_EXT_unpack_subimage, GL_KHR_context_flush_control, GL_KHR_debug,
GL_NV_draw_buffers, GL_NV_fbo_color_attachments, GL_NV_read_buffer,
GL_NV_read_depth, GL_NV_read_depth_stencil, GL_NV_read_stencil,
GL_OES_EGL_image, GL_OES_EGL_sync, GL_OES_depth24, GL_OES_depth_texture,
GL_OES_draw_elements_base_vertex, GL_OES_element_index_uint,
GL_OES_fbo_render_mipmap, GL_OES_get_program_binary, GL_OES_mapbuffer,
GL_OES_packed_depth_stencil, GL_OES_rgb8_rgba8, GL_OES_stencil8,
GL_OES_surfaceless_context, GL_OES_texture_3D,
GL_OES_texture_border_clamp, GL_OES_texture_npot,
GL_OES_vertex_array_object
12 GLX Visuals
visual x bf lv rg d st colorbuffer sr ax dp st accumbuffer ms cav
id dep cl sp sz l ci b ro r g b a F gb bf th cl r g b a ns b eat
----------------------------------------------------------------------------
0x020 24 tc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None
0x021 24 dc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None
0x077 24 tc 0 32 0 r y . 8 8 8 8 . . 0 0 0 0 0 0 0 0 0 None
0x078 24 tc 0 32 0 r . . 8 8 8 8 . . 0 0 0 0 0 0 0 0 0 None
0x079 24 tc 0 32 0 r . . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None
0x07a 24 tc 0 32 0 r y . 8 8 8 8 . . 0 24 8 16 16 16 16 0 0 Slow
0x07b 24 dc 0 32 0 r y . 8 8 8 8 . . 0 0 0 0 0 0 0 0 0 None
0x07c 24 dc 0 32 0 r . . 8 8 8 8 . . 0 0 0 0 0 0 0 0 0 None
0x07d 24 dc 0 32 0 r . . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None
0x07e 24 dc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None
0x07f 24 dc 0 32 0 r y . 8 8 8 8 . . 0 24 8 16 16 16 16 0 0 Slow
0x05e 32 tc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None
24 GLXFBConfigs:
visual x bf lv rg d st colorbuffer sr ax dp st accumbuffer ms cav
id dep cl sp sz l ci b ro r g b a F gb bf th cl r g b a ns b eat
----------------------------------------------------------------------------
0x05f 0 tc 0 16 0 r y . 5 6 5 0 . . 0 0 0 0 0 0 0 0 0 None
0x060 0 tc 0 16 0 r . . 5 6 5 0 . . 0 0 0 0 0 0 0 0 0 None
0x061 0 tc 0 16 0 r y . 5 6 5 0 . . 0 16 0 0 0 0 0 0 0 None
0x062 0 tc 0 16 0 r . . 5 6 5 0 . . 0 16 0 0 0 0 0 0 0 None
0x063 24 tc 0 32 0 r y . 8 8 8 8 . . 0 0 0 0 0 0 0 0 0 None
0x064 24 tc 0 32 0 r . . 8 8 8 8 . . 0 0 0 0 0 0 0 0 0 None
0x065 24 tc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None
0x066 24 tc 0 32 0 r . . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None
0x067 0 tc 0 16 0 r y . 5 6 5 0 . . 0 16 0 0 0 0 0 0 0 None
0x068 0 tc 0 16 0 r y . 5 6 5 0 . . 0 16 0 16 16 16 0 0 0 Slow
0x069 32 tc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None
0x06a 24 tc 0 32 0 r y . 8 8 8 8 . . 0 24 8 16 16 16 16 0 0 Slow
0x06b 0 dc 0 16 0 r y . 5 6 5 0 . . 0 0 0 0 0 0 0 0 0 None
0x06c 0 dc 0 16 0 r . . 5 6 5 0 . . 0 0 0 0 0 0 0 0 0 None
0x06d 0 dc 0 16 0 r y . 5 6 5 0 . . 0 16 0 0 0 0 0 0 0 None
0x06e 0 dc 0 16 0 r . . 5 6 5 0 . . 0 16 0 0 0 0 0 0 0 None
0x06f 24 dc 0 32 0 r y . 8 8 8 8 . . 0 0 0 0 0 0 0 0 0 None
0x070 24 dc 0 32 0 r . . 8 8 8 8 . . 0 0 0 0 0 0 0 0 0 None
0x071 24 dc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None
0x072 24 dc 0 32 0 r . . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None
0x073 0 dc 0 16 0 r y . 5 6 5 0 . . 0 16 0 0 0 0 0 0 0 None
0x074 0 dc 0 16 0 r y . 5 6 5 0 . . 0 16 0 16 16 16 0 0 0 Slow
0x075 24 dc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None
0x076 24 dc 0 32 0 r y . 8 8 8 8 . . 0 24 8 16 16 16 16 0 0 Slow
The problem is, that even though the transition appears to be smooth, there is a constant jitter happening every 3 seconds or so. It looks as if the moving texture jumped back instead of moving forward.
I tried many different methods of smoothing this out. I used delta time based movement, then disabling VSync and limiting the FPS manually, then I found out this question: https://gamedev.stackexchange.com/questions/163477/how-can-i-avoid-jittery-motion-in-sdl2
And I applied the same method of capping the framerate as in the answer. Still no help.
Even when using 120FPS (which I'm actually able to achieve), it's better but there is still a visible jitter.
I printed out the difference between last X pos and current during 120FPS:
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2.01
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
So the results look very OK to me.
With 60FPS, printing the frame time and X position also looks very good:
4
Frame time: 0.01667
4
Frame time: 0.01667
4
Frame time: 0.01667
4
Frame time: 0.01667
4
Frame time: 0.01667
4
Frame time: 0.01667
4
Frame time: 0.01667
4
Frame time: 0.01667
4
Frame time: 0.01667
4
Frame time: 0.01667
4
Frame time: 0.01667
4
Frame time: 0.01667
4
Frame time: 0.01667
4.004
Frame time: 0.01668
4
Frame time: 0.01667
4
Frame time: 0.01667
4.003
Frame time: 0.01668
4
Frame time: 0.01667
4
Frame time: 0.01667
4.008
Frame time: 0.0167
4
Frame time: 0.01667
4
Frame time: 0.01667
4.002
Frame time: 0.01667
4
Frame time: 0.01667
4
Frame time: 0.01667
4.003
Frame time: 0.01668
4
Frame time: 0.01667
4
Frame time: 0.01667
4.001
Frame time: 0.01667
4
Frame time: 0.01667
4
Frame time: 0.01667
4
Frame time: 0.01667
There are no visible spikes bigger than what you see here, yet the jitter is still there.
The system is running in an forced resolution of 1280x768 #60Hz, but I tried applying other resolutions (either using gtf and cvt modelines) but it didn't change anything.
I also tried disabling VSync for the entire system using .drirc file as mentioned here: https://wiki.archlinux.org/index.php/Intel_graphics
but it's still the same, although better than when running with vsync and SDL_RENDERER_PRESENT_VSYNC.
Surprisingly, setting the AccelMethod to uxa (instead of default sna) actually gets rid of the regular jitter, but the end result is very flickery and hurts the eyes...
I'm running out of ideas.
I checked if anything is hogging the GPU, but it's not even being used at 50%:
$ sudo intel_gpu_top
render clock: 166 Mhz display clock: 200 Mhz
render busy: 33%: ██████▋ render space: 36/131072
task percent busy
Bypass FIFO: 32%: ██████▌
Color calculator: 32%: ██████▌
Map filter: 29%: █████▉
Intermediate Z: 23%: ████▋
Windowizer: 22%: ████▌
Perspective interpolation: 3%: ▋
Pixel shader: 3%: ▋
Setup engine: 2%: ▌
Dispatcher: 2%: ▌
Strips and fans: 2%: ▌
Sampler Cache: 0%:
Map L2: 0%:
Filtering: 0%:
Texture decompression: 0%:
Projection and LOD: 0%:
Dependent address calculation: 0%:
Texture fetch: 0%:
Here's a very basic one-file code of the app:
#include <iostream>
#include <iomanip>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <time.h>
#include <unistd.h>
#define WIDTH 1280
#define HEIGHT 156
SDL_Renderer* ren = nullptr;
using namespace std;
struct Timer {
Uint64 previous_ticks{};
float elapsed_seconds{};
void tick() {
const Uint64 current_ticks{SDL_GetPerformanceCounter()};
const Uint64 delta{ current_ticks - previous_ticks };
previous_ticks = current_ticks;
static const Uint64 TICKS_PER_SECOND { SDL_GetPerformanceFrequency() };
elapsed_seconds = delta / static_cast<float>(TICKS_PER_SECOND);
}
};
class Object {
public:
Object(string fileName, SDL_Renderer* ren) {
this->ren = ren;
surf = IMG_Load(fileName.c_str());
tx = SDL_CreateTextureFromSurface(ren, surf);
this->setRect(0, 0, surf->w, surf->h);
SDL_FreeSurface(surf);
}
~Object() {
SDL_DestroyTexture(tx);
}
SDL_Rect* getDest() { return &dest; };
SDL_Rect* getSrc() { return &src; };
SDL_Texture* getTexture() { return tx; };
void setRect(int x, int y, int w, int h) {
//src.x = x;
//src.y = y;
src.x = 0;
src.y = 0;
src.w = w;
src.h = h;
dest.y = y;
dest.x = x;
dest.w = w;
dest.h = h;
pos_x = static_cast<float>(x);
}
void setX(float x) {
pos_x = x;
dest.x = roundf(x);
if(dest.x <= -dest.w) {
dest.x = WIDTH;
pos_x = static_cast<float>(WIDTH); // reset
}
cout << setprecision(4) << (last_x - pos_x) << endl;
last_x = pos_x;
}
void setXY(int x, int y) {
this->setX(static_cast<float>(x));
dest.y = y;
}
void move(float timestep) {
this->setX(pos_x - (240.0f * (timestep) ));
}
void draw() {
SDL_RenderCopy(this->ren, this->tx, &this->src, &this->dest);
}
private:
float pos_x = 0.0f;
float last_x = (float)WIDTH;
SDL_Rect dest;
SDL_Rect src;
SDL_Texture *tx = nullptr;
SDL_Surface *surf = nullptr;
SDL_Renderer *ren = nullptr;
};
void loop();
int main(int argc, char *argv[]) {
// Create the SDL window, accelerated renderer without vsync
SDL_Init(0);
SDL_Window* win = SDL_CreateWindow("SDLTest", 0, 0, WIDTH, HEIGHT, 0);
ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED);
SDL_SetRenderDrawColor(ren, 255, 255, 255, 255);
loop();
SDL_Quit();
return 1;
}
void loop() {
bool running = true;
SDL_Rect bg_rect;
bg_rect.x = 0;
bg_rect.y = 0;
bg_rect.w = WIDTH;
bg_rect.h = HEIGHT;
const int UPDATE_FREQUENCY { 60 };
const float CYCLE_TIME { 1.0f / UPDATE_FREQUENCY };
static Timer timer;
float accumulated_seconds = 0.0f;
/*struct timespec tv_sleep;
tv_sleep.tv_sec = 0;
tv_sleep.tv_nsec = 10;*/
Object obj("test.png", ren);
obj.setXY(WIDTH, 20);
int iterCount = 0;
while(running) {
iterCount++;
// cap framerate
timer.tick();
accumulated_seconds += timer.elapsed_seconds;
if(accumulated_seconds >= CYCLE_TIME*2.0f || accumulated_seconds <= 0.0 )
accumulated_seconds = CYCLE_TIME;
if(std::isgreaterequal(accumulated_seconds, CYCLE_TIME)) {
SDL_Event e;
while(SDL_PollEvent(&e)) {
if(e.type == SDL_QUIT) {
running = false;
cout << "QUIT" << endl;
return;
}
}
SDL_RenderClear(ren);
SDL_RenderFillRect(ren, &bg_rect);
// Draw moving stuff here
obj.move(accumulated_seconds);
obj.draw();
SDL_RenderPresent(ren);
cout << "Frame time: " << setprecision(4) << accumulated_seconds << endl;
accumulated_seconds -= CYCLE_TIME;
}
/*if(iterCount == 1000) {
iterCount = 0;
//sleep(0);
}*/
}
}
(you just need a test.png image in the same directory as SDL loads it to a texture)
I also tried using the FPSManager from SDL2_framrate.h but it gave very similar results, if not even worse.
I wanted to apply this method of smoothing the delta: http://frankforce.com/?p=2636
But I couldn't find any implementation of the GetMonitorRefreshRate() func, and using SDL's SDL_GetDisplayMode() actually returned 0 for every value in the display mode struct. And even if it returned, the refresh_rate is an integer, so it won't really help I think.
I'm beginning it's some sort of a problem with the system itself, some missing/corrupted driver or whatever, but I tried installing almost everything I could find without luck.
Here's my /etc/X11/xorg.conf.d/20-intel-flicker-fix.conf file:
Section "Device"
Identifier "Intel Graphics"
Driver "intel"
Option "TearFree" "true"
Option "AccelMethod" "sna"
EndSection
I needed to add the TearFree option, because there was huge tearing on the image when scrolling it.
Here's the gtf modeline I'm using:
"1280x768_60.00" 80.00 1280 1344 1480 1680 768 769 772 795 -HSync +Vsync
I'm trying to search a big project for all examples of where I've declared an array with [48] as the size or any multiples of 48.
Can I use a regular expression function to find matches of 48 * n?
Thanks.
Here you go (In PHP's PCRE syntax):
^(0*|(1(01*?0)*?1|0)+?0{4})$
Usage:
preg_match('/^(0*|(1(01*?0)*?1|0)+?0{4})$/', decbin($number));
Now, why it works:
Well we know that 48 is really just 3 * 16. And 16 is just 2*2*2*2. So, any number divisible by 2^4 will have the 4 most bits in its binary representation 0. So by ending the regexp with 0{4}$ is equivalent to saying that the number is divisible by 2^4 (or 16). So then, the bits to the left need to be divisible by 3. So using the regexp from this answer, we can tell if they are divisible by 3. So if the whole regexp matches, the number is divisible by both 3 and 16, and hence 48...
QED...
(Note, the leading 0| case handles the failed match when $number is 0). I've tested this on all numbers from 0 to 48^5, and it correctly matches each time...
A generalization of your question is asking whether x is a string representing a multiple of n in base b. This is the same thing as asking whether the remainder of x divided by n is 0. You can easily create a DFA to compute this.
Create a DFA with n states, numbered from 0 to n - 1. State 0 is both the initial state and the sole accepting state. Each state will have b outgoing transitions, one for each symbol in the alphabet (since base-b gives you b digits to work with).
Each state represents the remainder of the portion of x we've seen so far, divided by n. This is why we have n of them (dividing a number by n yields a remainder in the range 0 to n - 1), and also why state 0 is the accepting state.
Since the digits of x are processed from left to right, if we have a number y from the first few digits of x and read the digit d, we get the new value of y from yb + d. But more importantly, the remainder r changes to (rb + d) mod n. So we now know how to connect the transition arcs and complete the DFA.
You can do this for any n and b. Here, for example, is one that accepts multiples of 18 in base-10 (states on the rows, inputs on the columns):
| 0 1 2 3 4 5 6 7 8 9
---+-------------------------------
→0 | 0 1 2 3 4 5 6 7 8 9 ←accept
1 | 10 11 12 13 14 15 16 17 0 1
2 | 2 3 4 5 6 7 8 9 10 11
3 | 12 13 14 15 16 17 0 1 2 3
4 | 4 5 6 7 8 9 10 11 12 13
5 | 14 15 16 17 0 1 2 3 4 5
6 | 6 7 8 9 10 11 12 13 14 15
7 | 16 17 0 1 2 3 4 5 6 7
8 | 8 9 10 11 12 13 14 15 16 17
9 | 0 1 2 3 4 5 6 7 8 9
10 | 10 11 12 13 14 15 16 17 0 1
11 | 2 3 4 5 6 7 8 9 10 11
12 | 12 13 14 15 16 17 0 1 2 3
13 | 4 5 6 7 8 9 10 11 12 13
14 | 14 15 16 17 0 1 2 3 4 5
15 | 6 7 8 9 10 11 12 13 14 15
16 | 16 17 0 1 2 3 4 5 6 7
17 | 8 9 10 11 12 13 14 15 16 17
These get really tedious as n and b get larger, but you can obviously write a program to generate them for you no problem.
1|48|2304|110592|5308416
You are unlikely to have declared an array of size 48^5 or larger.
No, regular expressions can't calculate multiples (except in the unary number system: decimal 4 = unary 1111; decimal 8 = unary 11111111, so the regex ^(1111)+$ matches multiples of 4).
import re
# For real example,
# construction of a chain with integers multiples of 48
# and integers not multiple of 48.
from random import *
w = [ 48*randint( 1,10) for j in xrange(10) ]
w.extend( 48*randint(11,20) for j in xrange(10) )
w.extend( 48*randint(21,70) for j in xrange(10) )
a = [ el if el%48!=0 else el+1 for el in sample(xrange(1000),40) ]
w.extend(a)
shuffle(w)
texte = [ ''.join(sample(' abcdefghijklmonopqrstuvwxyz',randint(1,7))) for i in xrange(40) ]
X = ''.join(texte[i]+str(w[i]) for i in xrange(40))
# Searching the multiples of 48 in the chain X
def mult48(match):
g1 = match.group()
if int(g1)%48==0:
return ( g1, X[0:match.end()] )
else:
return ( g1, 'not multiple')
for match in re.finditer('\d+',X):
print '%s %s\n' % mult48(match)
Any multiple is difficult, but here's a (python-style) regexp that matches the first 200 multiples of 48.
0$|1(?:0(?:08$|56$)|1(?:04$|52$)|2(?:00$|48$|96$)|3(?:44$|92$)|4(?:4(?:$|0$)|88$\
)|5(?:36$|84$)|6(?:32$|80$)|7(?:28$|76$)|8(?:24$|72$)|9(?:2(?:$|0$)|68$))|2(?:0(\
?:16$|64$)|1(?:12$|60$)|2(?:08$|56$)|3(?:04$|52$)|4(?:0(?:$|0$)|48$|96$)|5(?:44$\
|92$)|6(?:40$|88$)|7(?:36$|84$)|8(?:32$|8(?:$|0$))|9(?:28$|76$))|3(?:0(?:24$|72$\
)|1(?:20$|68$)|2(?:16$|64$)|3(?:12$|6(?:$|0$))|4(?:08$|56$)|5(?:04$|52$)|6(?:00$\
|48$|96$)|7(?:44$|92$)|8(?:4(?:$|0$)|88$)|9(?:36$|84$))|4(?:0(?:32$|80$)|1(?:28$\
|76$)|2(?:24$|72$)|3(?:2(?:$|0$)|68$)|4(?:16$|64$)|5(?:12$|60$)|6(?:08$|56$)|7(?\
:04$|52$)|8(?:$|0(?:$|0$)|48$|96$)|9(?:44$|92$))|5(?:0(?:40$|88$)|1(?:36$|84$)|2\
(?:32$|8(?:$|0$))|3(?:28$|76$)|4(?:24$|72$)|5(?:20$|68$)|6(?:16$|64$)|7(?:12$|6(\
?:$|0$))|8(?:08$|56$)|9(?:04$|52$))|6(?:0(?:00$|48$|96$)|1(?:44$|92$)|2(?:4(?:$|\
0$)|88$)|3(?:36$|84$)|4(?:32$|80$)|5(?:28$|76$)|6(?:24$|72$)|7(?:2(?:$|0$)|68$)|\
8(?:16$|64$)|9(?:12$|60$))|7(?:0(?:08$|56$)|1(?:04$|52$)|2(?:0(?:$|0$)|48$|96$)|\
3(?:44$|92$)|4(?:40$|88$)|5(?:36$|84$)|6(?:32$|8(?:$|0$))|7(?:28$|76$)|8(?:24$|7\
2$)|9(?:20$|68$))|8(?:0(?:16$|64$)|1(?:12$|6(?:$|0$))|2(?:08$|56$)|3(?:04$|52$)|\
4(?:00$|48$|96$)|5(?:44$|92$)|6(?:4(?:$|0$)|88$)|7(?:36$|84$)|8(?:32$|80$)|9(?:2\
8$|76$))|9(?:0(?:24$|72$)|1(?:2(?:$|0$)|68$)|2(?:16$|64$)|3(?:12$|60$)|4(?:08$|5\
6$)|5(?:04$|52$)|6(?:$|0$))