diff options
author | Keith Packard <keithp@keithp.com> | 2013-11-07 16:06:39 -0800 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2013-11-07 16:06:39 -0800 |
commit | e8828fa0513e666fa7246cd213001c51d7957e0e (patch) | |
tree | 36d6914a283ee08ebf5fe0c6101c7ada7559c861 | |
parent | 0de6411c1702e81f54ebaed3a6c34e2aeaafa8cd (diff) |
Update to released APIs
-rw-r--r-- | Makefile | 12 | ||||
-rw-r--r-- | dri3.c | 28 | ||||
-rw-r--r-- | present.c | 152 | ||||
-rw-r--r-- | shmfd.c | 22 |
4 files changed, 134 insertions, 80 deletions
@@ -1,7 +1,7 @@ CFLAGS=-Wall -O0 -g $(shell pkg-config --cflags xcb-shm xcb-aux xcb-dri3 xcb-present xshmfence) LIBS=$(shell pkg-config --libs xcb-shm xcb-aux xcb-dri3 xcb-present xshmfence) -all: shmfd dri3 futex xfence present +all: shmfd dri3 futex xfence present pipefence shmtest SHMFD_OBJS=shmfd.o @@ -23,11 +23,21 @@ XFENCE_OBJS=xfence.o xfence: $(XFENCE_OBJS) $(CC) $(CFLAGS) -o $@ $(XFENCE_OBJS) $(LIBS) +PIPEFENCE_OBJS=pipefence.o + +pipefence: $(PIPEFENCE_OBJS) + $(CC) $(CFLAGS) -o $@ $(PIPEFENCE_OBJS) + PRESENT_OBJS=present.o present: $(PRESENT_OBJS) $(CC) $(CFLAGS) -o $@ $(PRESENT_OBJS) $(LIBS) +SHMTEST_OBJS=shmtest.o + +shmtest: $(SHMTEST_OBJS) + $(CC) $(CFLAGS) -o $@ $(SHMTEST_OBJS) + clean: rm -f shmfd $(SHMFD_OBJS) rm -f dri3 $(DRI3_OBJS) @@ -22,6 +22,7 @@ #include <xcb/xcb.h> #include <xcb/xcb_aux.h> #include <xcb/dri3.h> +#include <xcb/present.h> #define WIDTH 128 #define HEIGHT 128 @@ -33,11 +34,11 @@ main (int argc, char **argv) int screen_num; xcb_screen_t *screen; xcb_gc_t gc; - xcb_dri3_event_t dri3_event; + xcb_present_event_t present_event; xcb_window_t window; xcb_generic_event_t *event; xcb_generic_error_t *error; - const xcb_query_extension_reply_t *dri3_extension; + const xcb_query_extension_reply_t *present_extension; uint32_t window_mask; uint32_t window_values[5]; xcb_ge_event_t *xge; @@ -72,18 +73,17 @@ main (int argc, char **argv) 0, /* mask */ NULL); /* values */ - xcb_dri3_select_input(c, - (dri3_event = xcb_generate_id(c)), - window, - XCB_DRI3_INPUT_MASK_CONFIGURE_NOTIFY); + xcb_present_select_input(c, + (present_event = xcb_generate_id(c)), + window, + XCB_PRESENT_EVENT_MASK_CONFIGURE_NOTIFY); - dri3_extension = xcb_get_extension_data(c, &xcb_dri3_id); + present_extension = xcb_get_extension_data(c, &xcb_present_id); xcb_register_for_special_event(c, - dri3_extension->major_opcode, - XCB_DRI3_CONFIGURE_NOTIFY, - dri3_event, + present_extension->major_opcode, + present_event, NULL); xcb_map_window(c, window); @@ -108,11 +108,11 @@ main (int argc, char **argv) break; case XCB_GE: xge = (xcb_ge_event_t *) event; - if (xge->extension == dri3_extension->major_opcode) { + if (xge->extension == present_extension->major_opcode) { switch (xge->evtype) { - case XCB_DRI3_CONFIGURE_NOTIFY: { - xcb_dri3_configure_notify_event_t *ce = (void *) event; - printf ("dri3 configure %d %d %d %d\n", + case XCB_PRESENT_CONFIGURE_NOTIFY: { + xcb_present_configure_notify_event_t *ce = (void *) event; + printf ("present configure %d %d %d %d\n", ce->x, ce->y, ce->width, ce->height); break; } @@ -24,9 +24,10 @@ #include <xcb/xcb_aux.h> #include <xcb/present.h> -#define WIDTH 128 -#define HEIGHT 128 +#define INIT_WIDTH 500 +#define INIT_HEIGHT 500 +int width, height; xcb_connection_t *c; int screen_num; xcb_screen_t *screen; @@ -44,53 +45,84 @@ uint32_t gc_values[5]; xcb_segment_t segments[2]; xcb_rectangle_t rectangle; xcb_ge_event_t *xge; -uint32_t color; -int32_t color_inc; +int x; +int x_inc = 30; +uint64_t msc; +uint64_t target_msc; + +static void make_pixmap(void) +{ + xcb_create_pixmap(c, + 24, + (pixmap = xcb_generate_id(c)), + window, + width, + height); +} + +static void discard_pixmap(void) +{ + if (pixmap) { + xcb_free_pixmap (c, pixmap); + pixmap = 0; + } +} static void draw(void) { + if (!pixmap) + make_pixmap(); + gc_mask = XCB_GC_FOREGROUND; gc_values[0] = 0xffffffff; xcb_change_gc(c, gc, gc_mask, gc_values); rectangle.x = 0; rectangle.y = 0; - rectangle.width = WIDTH; - rectangle.height = HEIGHT; + rectangle.width = width; + rectangle.height = height; xcb_poly_fill_rectangle(c, pixmap, gc, 1, &rectangle); gc_mask = XCB_GC_FOREGROUND; - gc_values[0] = color | (color << 8) | (color << 16); + gc_values[0] = 0x0; xcb_change_gc(c, gc, gc_mask, gc_values); - segments[0].x1 = 0; - segments[0].y1 = 0; - segments[0].x2 = WIDTH; - segments[0].y2 = HEIGHT; - - segments[1].x1 = WIDTH; - segments[1].y1 = 0; - segments[1].x2 = 0; - segments[1].y2 = HEIGHT; - xcb_poly_segment(c, - pixmap, - gc, - 2, - segments); + rectangle.x = x; + rectangle.y = 0; + rectangle.width = 60; + rectangle.height = height; + xcb_poly_fill_rectangle(c, pixmap, gc, 1, &rectangle); + + x += x_inc; + if (x_inc > 0) { + if (x + rectangle.width > width) + x_inc = -x_inc; + } else { + if (x - rectangle.width < 0) + x_inc = -x_inc; + } } -static void show(int interval) +#define None 0 + +static void show(void) { - xcb_present_region (c, + xcb_present_pixmap (c, window, pixmap, 0, + None, + None, + 0, 0, + None, + None, + None, 0, + target_msc, 0, 0, - interval, 0, - 0); + NULL); } int frame_count; @@ -107,28 +139,10 @@ millis(void) static void frame(void) { - if (frame_count == 0) - start_time = millis(); - if (color_inc > 0) { - color += color_inc; - if (color > 0xff) { - color = 0xff; - color_inc = -color_inc; - } - } else { - if (color < -color_inc) { - color = 0; - color_inc = -color_inc; - } else - color += color_inc; - } draw(); - show(1); - if (++frame_count == 100) { - end_time = millis(); - printf ("frame rate: %f\n", (double) frame_count / ((double) (end_time - start_time) / 1000.0)); - frame_count = 0; - } + target_msc = msc + 1; + show(); + ++frame_count; } int @@ -145,25 +159,21 @@ main (int argc, char **argv) window_values[0] = 0xffffff; window_values[1] = XCB_EVENT_MASK_EXPOSURE; + width = INIT_WIDTH; + height = INIT_HEIGHT; xcb_create_window(c, 0, /* depth */ (window = xcb_generate_id(c)), /* window */ screen->root, /* root */ 0, /* x */ 0, /* y */ - WIDTH, /* width */ - HEIGHT, /* height */ + width, /* width */ + height, /* height */ 0, /* border_width */ XCB_WINDOW_CLASS_INPUT_OUTPUT, /* class */ screen->root_visual, /* visual */ window_mask, /* mask */ window_values); /* values */ - xcb_create_pixmap(c, - 24, - (pixmap = xcb_generate_id(c)), - window, - WIDTH, - HEIGHT); xcb_create_gc(c, (gc = xcb_generate_id(c)), /* gc */ @@ -174,16 +184,18 @@ main (int argc, char **argv) xcb_present_select_input(c, (present_event = xcb_generate_id(c)), window, - XCB_PRESENT_INPUT_MASK_CONFIGURE_NOTIFY|XCB_PRESENT_INPUT_MASK_COMPLETE_NOTIFY); - + XCB_PRESENT_EVENT_MASK_CONFIGURE_NOTIFY| + XCB_PRESENT_EVENT_MASK_COMPLETE_NOTIFY| + XCB_PRESENT_EVENT_MASK_IDLE_NOTIFY); present_extension = xcb_get_extension_data(c, &xcb_present_id); - color = 0; - color_inc = 0x10; + start_time = millis(); draw(); xcb_map_window(c, window); + show(); + xcb_present_notify_msc(c, window, 0, 0, 5 * 60, 0); printf ("mapped\n"); @@ -194,7 +206,6 @@ main (int argc, char **argv) break; switch (event->response_type) { case XCB_EXPOSE: - show(0); break; case 0: error = (xcb_generic_error_t *) event; @@ -206,16 +217,35 @@ main (int argc, char **argv) case XCB_GE: xge = (xcb_ge_event_t *) event; if (xge->extension == present_extension->major_opcode) { - switch (xge->evtype) { + switch (xge->event_type) { case XCB_PRESENT_CONFIGURE_NOTIFY: { xcb_present_configure_notify_event_t *ce = (void *) event; + discard_pixmap(); + width = ce->width; + height = ce->height; printf ("present configure %d %d %d %d\n", ce->x, ce->y, ce->width, ce->height); break; } case XCB_PRESENT_COMPLETE_NOTIFY: { xcb_present_complete_notify_event_t *ce = (void *) event; - frame(); + if (ce->kind == XCB_PRESENT_COMPLETE_KIND_PIXMAP) { + int64_t diff = ce->msc - target_msc; + + if (diff< 0) + diff = -diff; + if (diff) + printf ("target %lld actual %lld\n", target_msc, ce->msc); + msc = ce->msc; + frame(); + } else { + xcb_present_notify_msc(c, window, 0, 0, 5 * 60, 0); + end_time = millis(); + double seconds = (end_time - start_time) / 1000.0; + printf ("%5d frames in %8.3f seconds. frame rate: %f\n", frame_count, seconds, (double) frame_count / ((double) (end_time - start_time) / 1000.0)); + frame_count = 0; + start_time = millis(); + } break; } } @@ -13,6 +13,10 @@ * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * Build with + * + * cc -o shmfd shmfd.c `pkg-config --cflags --libs xcb-shm xcb-aux` */ #include <stdio.h> @@ -73,6 +77,7 @@ main (int argc, char **argv) int screen_num; xcb_screen_t *screen; int fd; + int segment_fd; void *addr; void *server_addr; xcb_shm_seg_t shm_seg; @@ -101,7 +106,7 @@ main (int argc, char **argv) xcb_shm_attach_fd (c, (shm_seg = xcb_generate_id(c)), - fd, + dup(fd), 1); shm_create_segment_cookie = xcb_shm_create_segment(c, @@ -114,9 +119,9 @@ main (int argc, char **argv) if (shm_create_segment_reply) { shm_create_segment_fds = xcb_shm_create_segment_reply_fds(c, shm_create_segment_reply); + segment_fd = shm_create_segment_fds[0]; - server_addr = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, shm_create_segment_fds[0], 0); - close(shm_create_segment_fds[0]); + server_addr = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, segment_fd, 0); free(shm_create_segment_reply); paint(server_addr, WIDTH, HEIGHT, 1); } @@ -125,7 +130,7 @@ main (int argc, char **argv) window_mask = XCB_CW_BACK_PIXEL|XCB_CW_EVENT_MASK; window_values[0] = 0xffffff; - window_values[1] = XCB_EVENT_MASK_EXPOSURE; + window_values[1] = XCB_EVENT_MASK_EXPOSURE|XCB_EVENT_MASK_KEY_PRESS; xcb_create_window(c, 0, /* depth */ @@ -187,6 +192,15 @@ main (int argc, char **argv) 0, shm_server_seg, 0); + printf ("displayed\n"); + break; + case XCB_KEY_PRESS: + if (ftruncate(fd, 0) < 0) + perror("ftruncate attach fd"); + if (ftruncate(segment_fd, 0) < 0) + perror("ftruncate create_segment"); + printf ("truncated\n"); + xcb_clear_area(c, 1, window, 0, 0, 0, 0); break; case 0: error = (xcb_generic_error_t *) event; |