1 /*
2  * Copyright (c) 2007 Intel Corporation. All Rights Reserved.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sub license, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the
13  * next paragraph) shall be included in all copies or substantial portions
14  * of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
19  * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
20  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24 
25 #define _GNU_SOURCE 1
26 #include "sysdeps.h"
27 #include "va.h"
28 #include "va_backend.h"
29 #include "va_internal.h"
30 #include "va_trace.h"
31 #include "va_fool.h"
32 #include "va_android.h"
33 #include "va_drmcommon.h"
34 #include "va_drm_utils.h"
35 #include <stdarg.h>
36 #include <unistd.h>
37 #include <sys/types.h>
38 #include <sys/stat.h>
39 #include <fcntl.h>
40 #include <dlfcn.h>
41 #include <errno.h>
42 
43 
44 #define CHECK_SYMBOL(func) { if (!func) printf("func %s not found\n", #func); return VA_STATUS_ERROR_UNKNOWN; }
45 #define DEVICE_NAME "/dev/dri/renderD128"
46 
open_device(char * dev_name)47 static int open_device(char *dev_name)
48 {
49     struct stat st;
50     int fd;
51 
52     if (-1 == stat(dev_name, &st)) {
53         printf("Cannot identify '%s': %d, %s\n",
54                dev_name, errno, strerror(errno));
55         return -1;
56     }
57 
58     if (!S_ISCHR(st.st_mode)) {
59         printf("%s is no device\n", dev_name);
60         return -1;
61     }
62 
63     fd = open(dev_name, O_RDWR);
64 
65     if (-1 == fd) {
66         fprintf(stderr, "Cannot open '%s': %d, %s\n",
67                 dev_name, errno, strerror(errno));
68         return -1;
69     }
70 
71     return fd;
72 }
73 
va_DisplayContextIsValid(VADisplayContextP pDisplayContext)74 static int va_DisplayContextIsValid(
75     VADisplayContextP pDisplayContext
76 )
77 {
78     return (pDisplayContext != NULL &&
79             pDisplayContext->pDriverContext != NULL);
80 }
81 
va_DisplayContextDestroy(VADisplayContextP pDisplayContext)82 static void va_DisplayContextDestroy(
83     VADisplayContextP pDisplayContext
84 )
85 {
86     struct drm_state *drm_state;
87 
88     if (pDisplayContext == NULL)
89         return;
90 
91     /* close the open-ed DRM fd */
92     drm_state = (struct drm_state *)pDisplayContext->pDriverContext->drm_state;
93     close(drm_state->fd);
94 
95     free(pDisplayContext->pDriverContext->drm_state);
96     free(pDisplayContext->pDriverContext);
97     free(pDisplayContext);
98 }
99 
va_DisplayContextGetNumCandidates(VADisplayContextP pDisplayContext,int * num_candidates)100 static VAStatus va_DisplayContextGetNumCandidates(
101     VADisplayContextP pDisplayContext,
102     int *num_candidates
103 )
104 {
105     VADriverContextP const ctx = pDisplayContext->pDriverContext;
106     struct drm_state * drm_state = (struct drm_state *)ctx->drm_state;
107 
108     memset(drm_state, 0, sizeof(*drm_state));
109     drm_state->fd = open_device((char *)DEVICE_NAME);
110 
111     if (drm_state->fd < 0) {
112         fprintf(stderr, "can't open DRM devices\n");
113         return VA_STATUS_ERROR_UNKNOWN;
114     }
115     drm_state->auth_type = VA_DRM_AUTH_CUSTOM;
116     return VA_DRM_GetNumCandidates(ctx, num_candidates);
117 }
118 
va_DisplayContextGetDriverNameByIndex(VADisplayContextP pDisplayContext,char ** driver_name,int candidate_index)119 static VAStatus va_DisplayContextGetDriverNameByIndex(
120     VADisplayContextP pDisplayContext,
121     char **driver_name,
122     int candidate_index
123 )
124 {
125     VADriverContextP const ctx = pDisplayContext->pDriverContext;
126 
127     return VA_DRM_GetDriverName(ctx, driver_name, candidate_index);
128 }
129 
130 
vaGetDisplay(void * native_dpy)131 VADisplay vaGetDisplay(
132     void *native_dpy /* implementation specific */
133 )
134 {
135     VADisplayContextP pDisplayContext;
136     VADriverContextP  pDriverContext;
137     struct drm_state *drm_state;
138 
139     if (!native_dpy)
140         return NULL;
141 
142     pDisplayContext = va_newDisplayContext();
143     if (!pDisplayContext)
144         return NULL;
145 
146     pDisplayContext->vaIsValid       = va_DisplayContextIsValid;
147     pDisplayContext->vaDestroy       = va_DisplayContextDestroy;
148     pDisplayContext->vaGetDriverNameByIndex = va_DisplayContextGetDriverNameByIndex;
149     pDisplayContext->vaGetNumCandidates = va_DisplayContextGetNumCandidates;
150 
151     pDriverContext = va_newDriverContext(pDisplayContext);
152     if (!pDriverContext) {
153         free(pDisplayContext);
154         return NULL;
155     }
156 
157     pDriverContext->native_dpy   = (void *)native_dpy;
158     pDriverContext->display_type = VA_DISPLAY_ANDROID;
159 
160     drm_state = (struct drm_state*)calloc(1, sizeof(*drm_state));
161     if (!drm_state) {
162         free(pDisplayContext);
163         free(pDriverContext);
164         return NULL;
165     }
166 
167     pDriverContext->drm_state = drm_state;
168 
169     return (VADisplay)pDisplayContext;
170 }
171