1 #include <stdlib.h> 2 #include <fcntl.h> 3 #include <unistd.h> 4 #include <sys/mman.h> 5 #include <assert.h> 6 7 #include <xf86drm.h> 8 9 #include "X11/Xlib.h" 10 #include "va.h" 11 #include "va_backend.h" 12 13 #include "va_dri.h" 14 #include "va_dricommon.h" 15 16 struct dri1_drawable 17 { 18 struct dri_drawable base; 19 union dri_buffer buffer; 20 int width; 21 int height; 22 }; 23 24 static struct dri_drawable * 25 dri1CreateDrawable(VADriverContextP ctx, XID x_drawable) 26 { 27 struct dri1_drawable *dri1_drawable; 28 29 dri1_drawable = calloc(1, sizeof(*dri1_drawable)); 30 31 if (!dri1_drawable) 32 return NULL; 33 34 dri1_drawable->base.x_drawable = x_drawable; 35 36 return &dri1_drawable->base; 37 } 38 39 static void 40 dri1DestroyDrawable(VADriverContextP ctx, struct dri_drawable *dri_drawable) 41 { 42 free(dri_drawable); 43 } 44 45 static void 46 dri1SwapBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable) 47 { 48 49 } 50 51 static union dri_buffer * 52 dri1GetRenderingBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable) 53 { 54 struct dri1_drawable *dri1_drawable = (struct dri1_drawable *)dri_drawable; 55 56 return &dri1_drawable->buffer; 57 } 58 59 static void 60 dri1Close(VADriverContextP ctx) 61 { 62 struct dri_state *dri_state = (struct dri_state *)ctx->drm_state; 63 64 free_drawable_hashtable(ctx); 65 VA_DRIDestroyContext(ctx->native_dpy, ctx->x11_screen, dri_state->hwContextID); 66 assert(dri_state->pSAREA != MAP_FAILED); 67 drmUnmap(dri_state->pSAREA, SAREA_MAX); 68 assert(dri_state->base.fd >= 0); 69 drmCloseOnce(dri_state->base.fd); 70 VA_DRICloseConnection(ctx->native_dpy, ctx->x11_screen); 71 } 72 73 Bool 74 isDRI1Connected(VADriverContextP ctx, char **driver_name) 75 { 76 struct dri_state *dri_state = (struct dri_state *)ctx->drm_state; 77 int direct_capable; 78 int driver_major; 79 int driver_minor; 80 int driver_patch; 81 int newlyopened; 82 char *BusID; 83 drm_magic_t magic; 84 85 *driver_name = NULL; 86 dri_state->base.fd = -1; 87 dri_state->pSAREA = MAP_FAILED; 88 dri_state->base.auth_type = VA_NONE; 89 90 if (!VA_DRIQueryDirectRenderingCapable(ctx->native_dpy, 91 ctx->x11_screen, 92 &direct_capable)) 93 goto err_out0; 94 95 if (!direct_capable) 96 goto err_out0; 97 98 if (!VA_DRIGetClientDriverName(ctx->native_dpy, ctx->x11_screen, 99 &driver_major, &driver_minor, 100 &driver_patch, driver_name)) 101 goto err_out0; 102 103 if (!VA_DRIOpenConnection(ctx->native_dpy, ctx->x11_screen, 104 &dri_state->hSAREA, &BusID)) 105 goto err_out0; 106 107 108 dri_state->base.fd = drmOpenOnce(NULL, BusID, &newlyopened); 109 XFree(BusID); 110 111 if (dri_state->base.fd < 0) 112 goto err_out1; 113 114 115 if (drmGetMagic(dri_state->base.fd, &magic)) 116 goto err_out1; 117 118 if (newlyopened && !VA_DRIAuthConnection(ctx->native_dpy, ctx->x11_screen, magic)) 119 goto err_out1; 120 121 if (drmMap(dri_state->base.fd, dri_state->hSAREA, SAREA_MAX, &dri_state->pSAREA)) 122 goto err_out1; 123 124 if (!VA_DRICreateContext(ctx->native_dpy, ctx->x11_screen, 125 DefaultVisual(ctx->native_dpy, ctx->x11_screen), 126 &dri_state->hwContextID, &dri_state->hwContext)) 127 goto err_out1; 128 129 dri_state->base.auth_type = VA_DRI1; 130 dri_state->createDrawable = dri1CreateDrawable; 131 dri_state->destroyDrawable = dri1DestroyDrawable; 132 dri_state->swapBuffer = dri1SwapBuffer; 133 dri_state->getRenderingBuffer = dri1GetRenderingBuffer; 134 dri_state->close = dri1Close; 135 136 return True; 137 138 err_out1: 139 if (dri_state->pSAREA != MAP_FAILED) 140 drmUnmap(dri_state->pSAREA, SAREA_MAX); 141 142 if (dri_state->base.fd >= 0) 143 drmCloseOnce(dri_state->base.fd); 144 145 VA_DRICloseConnection(ctx->native_dpy, ctx->x11_screen); 146 147 err_out0: 148 if (*driver_name) 149 XFree(*driver_name); 150 151 dri_state->pSAREA = MAP_FAILED; 152 dri_state->base.fd = -1; 153 *driver_name = NULL; 154 155 return False; 156 } 157 158