summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2013-11-07 16:06:39 -0800
committerKeith Packard <keithp@keithp.com>2013-11-07 16:06:39 -0800
commite8828fa0513e666fa7246cd213001c51d7957e0e (patch)
tree36d6914a283ee08ebf5fe0c6101c7ada7559c861
parent0de6411c1702e81f54ebaed3a6c34e2aeaafa8cd (diff)
Update to released APIs
-rw-r--r--Makefile12
-rw-r--r--dri3.c28
-rw-r--r--present.c152
-rw-r--r--shmfd.c22
4 files changed, 134 insertions, 80 deletions
diff --git a/Makefile b/Makefile
index 7b79b87..e77f938 100644
--- a/Makefile
+++ b/Makefile
@@ -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)
diff --git a/dri3.c b/dri3.c
index f1fc20b..59fb753 100644
--- a/dri3.c
+++ b/dri3.c
@@ -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;
}
diff --git a/present.c b/present.c
index 81b6b57..f992f6d 100644
--- a/present.c
+++ b/present.c
@@ -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;
}
}
diff --git a/shmfd.c b/shmfd.c
index a7fb8e4..45b9067 100644
--- a/shmfd.c
+++ b/shmfd.c
@@ -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;