+static void
+fill8888(unsigned char *virtual, int width, int height, int stride)
+{
+ int i, j;
+ /* paint the buffer with colored tiles */
+ for (j = 0; j < height; j++) {
+ uint32_t *ptr = (uint32_t*)((char*)virtual + j * stride);
+ for (i = 0; i < width; i++) {
+ div_t d = div(i, width);
+ ptr[i] =
+ 0x00130502 * (d.quot >> 6) +
+ 0x000a1120 * (d.rem >> 6);
+ }
+ }
+
+ make_pwetty(virtual, width, height, stride);
+}
+
+static void
+fill_grey(unsigned char *virtual, int width, int height, int stride)
+{
+ memset(virtual, 0x77, stride * height);
+}
+
+static struct kms_bo *
+create_test_buffer(struct kms_driver *kms, unsigned int format,
+ int width, int height, int handles[4],
+ int pitches[4], int offsets[4], int grey)
+{
+ struct kms_bo *bo;
+ int ret, stride;
+ void *virtual;
+
+ bo = allocate_buffer(kms, width, height, &pitches[0]);
+ if (!bo)
+ return NULL;
+
+ ret = kms_bo_map(bo, &virtual);
+ if (ret) {
+ fprintf(stderr, "failed to map buffer: %s\n",
+ strerror(-ret));
+ kms_bo_destroy(&bo);
+ return NULL;
+ }
+
+ /* just testing a limited # of formats to test single
+ * and multi-planar path.. would be nice to add more..
+ */
+ switch (format) {
+ case DRM_FORMAT_YUYV:
+ pitches[0] = width * 2;
+ offsets[0] = 0;
+ kms_bo_get_prop(bo, KMS_HANDLE, &handles[0]);
+
+ fill422(virtual, 0, width, height, pitches[0]);
+ break;
+
+ case DRM_FORMAT_NV12:
+ pitches[0] = width;
+ offsets[0] = 0;
+ kms_bo_get_prop(bo, KMS_HANDLE, &handles[0]);
+ pitches[1] = width;
+ offsets[1] = width * height;
+ kms_bo_get_prop(bo, KMS_HANDLE, &handles[1]);
+
+ fill420(virtual, virtual+offsets[1], virtual+offsets[1]+1,
+ 2, 0, width, height, pitches[0]);
+ break;
+
+ case DRM_FORMAT_YVU420:
+ pitches[0] = width;
+ offsets[0] = 0;
+ kms_bo_get_prop(bo, KMS_HANDLE, &handles[0]);
+ pitches[1] = width / 2;
+ offsets[1] = width * height;
+ kms_bo_get_prop(bo, KMS_HANDLE, &handles[1]);
+ pitches[2] = width / 2;
+ offsets[2] = offsets[1] + (width * height) / 4;
+ kms_bo_get_prop(bo, KMS_HANDLE, &handles[2]);
+
+ fill420(virtual, virtual+offsets[1], virtual+offsets[2],
+ 1, 0, width, height, pitches[0]);
+ break;
+
+ case DRM_FORMAT_XRGB1555:
+ pitches[0] = width * 2;
+ offsets[0] = 0;
+ kms_bo_get_prop(bo, KMS_HANDLE, &handles[0]);
+
+ fill1555(virtual, 0, width, height, pitches[0]);
+ break;
+
+ case DRM_FORMAT_XRGB8888:
+ pitches[0] = width * 4;
+ offsets[0] = 0;
+ kms_bo_get_prop(bo, KMS_HANDLE, &handles[0]);
+
+ if (grey)
+ fill_grey(virtual, width, height, pitches[0]);
+ else
+ fill8888(virtual, width, height, pitches[0]);
+ break;
+
+ case DRM_FORMAT_ARGB1555:
+ pitches[0] = width * 2;
+ offsets[0] = 0;
+ kms_bo_get_prop(bo, KMS_HANDLE, &handles[0]);
+
+ fill1555(virtual, 0, width, height, pitches[0]);
+ break;
+ }
+
+ kms_bo_unmap(bo);
+
+ return bo;
+}
+
+/* -------------------------------------------------------------------------- */
+
+void
+page_flip_handler(int fd, unsigned int frame,
+ unsigned int sec, unsigned int usec, void *data)
+{
+ struct connector *c;
+ unsigned int new_fb_id;
+ struct timeval end;
+ double t;
+
+ c = data;
+ if (c->current_fb_id == c->fb_id[0])
+ new_fb_id = c->fb_id[1];
+ else
+ new_fb_id = c->fb_id[0];
+
+ drmModePageFlip(fd, c->crtc, new_fb_id,
+ DRM_MODE_PAGE_FLIP_EVENT, c);
+ c->current_fb_id = new_fb_id;
+ c->swap_count++;
+ if (c->swap_count == 60) {
+ gettimeofday(&end, NULL);
+ t = end.tv_sec + end.tv_usec * 1e-6 -
+ (c->start.tv_sec + c->start.tv_usec * 1e-6);
+ fprintf(stderr, "freq: %.02fHz\n", c->swap_count / t);
+ c->swap_count = 0;
+ c->start = end;
+ }
+}
+