OSDN Git Service

Drop explicit dependency on libva-x11.
[android-x86/hardware-intel-common-vaapi.git] / src / i965_output_dri.c
1 /*
2  * Copyright (C) 2012 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 #include "config.h"
26 #include <stdlib.h>
27 #include <string.h>
28 #include <assert.h>
29 #include <va/va_dricommon.h>
30 #include "i965_drv_video.h"
31 #include "i965_output_dri.h"
32 #include "dso_utils.h"
33
34 #define LIBVA_X11_NAME "libva-x11.so.1"
35
36 typedef struct dri_drawable *(*dri_get_drawable_func)(
37     VADriverContextP ctx, XID drawable);
38 typedef union dri_buffer *(*dri_get_rendering_buffer_func)(
39     VADriverContextP ctx, struct dri_drawable *d);
40 typedef void (*dri_swap_buffer_func)(
41     VADriverContextP ctx, struct dri_drawable *d);
42
43 struct dri_vtable {
44     dri_get_drawable_func               get_drawable;
45     dri_get_rendering_buffer_func       get_rendering_buffer;
46     dri_swap_buffer_func                swap_buffer;
47 };
48
49 struct va_dri_output {
50     struct dso_handle  *handle;
51     struct dri_vtable   vtable;
52 };
53
54 bool
55 i965_output_dri_init(VADriverContextP ctx)
56 {
57     struct i965_driver_data * const i965 = i965_driver_data(ctx); 
58     struct dso_handle *dso_handle;
59     struct dri_vtable *dri_vtable;
60
61     static const struct dso_symbol symbols[] = {
62         { "dri_get_drawable",
63           offsetof(struct dri_vtable, get_drawable) },
64         { "dri_get_rendering_buffer",
65           offsetof(struct dri_vtable, get_rendering_buffer) },
66         { "dri_swap_buffer",
67           offsetof(struct dri_vtable, swap_buffer) },
68         { NULL, }
69     };
70
71     i965->dri_output = calloc(1, sizeof(struct va_dri_output));
72     if (!i965->dri_output)
73         goto error;
74
75     i965->dri_output->handle = dso_open(LIBVA_X11_NAME);
76     if (!i965->dri_output->handle)
77         goto error;
78
79     dso_handle = i965->dri_output->handle;
80     dri_vtable = &i965->dri_output->vtable;
81     if (!dso_get_symbols(dso_handle, dri_vtable, sizeof(*dri_vtable), symbols))
82         goto error;
83     return true;
84
85 error:
86     i965_output_dri_terminate(ctx);
87     return false;
88 }
89
90 void
91 i965_output_dri_terminate(VADriverContextP ctx)
92 {
93     struct i965_driver_data * const i965 = i965_driver_data(ctx); 
94     struct va_dri_output * const dri_output = i965->dri_output;
95
96     if (!dri_output)
97         return;
98
99     if (dri_output->handle) {
100         dso_close(dri_output->handle);
101         dri_output->handle = NULL;
102     }
103
104     free(dri_output);
105     i965->dri_output = NULL;
106 }
107
108 VAStatus
109 i965_put_surface_dri(
110     VADriverContextP    ctx,
111     VASurfaceID         surface,
112     void               *draw,
113     const VARectangle  *src_rect,
114     const VARectangle  *dst_rect,
115     const VARectangle  *cliprects,
116     unsigned int        num_cliprects,
117     unsigned int        flags
118 )
119 {
120     struct i965_driver_data * const i965 = i965_driver_data(ctx); 
121     struct dri_vtable * const dri_vtable = &i965->dri_output->vtable;
122     struct dri_state * const dri_state = (struct dri_state *)ctx->drm_state;
123     struct i965_render_state * const render_state = &i965->render_state;
124     struct dri_drawable *dri_drawable;
125     union dri_buffer *buffer;
126     struct intel_region *dest_region;
127     struct object_surface *obj_surface; 
128     unsigned int pp_flag = 0;
129     bool new_region = false;
130     uint32_t name;
131     int ret;
132
133     /* Currently don't support DRI1 */
134     if (dri_state->base.auth_type != VA_DRM_AUTH_DRI2)
135         return VA_STATUS_ERROR_UNKNOWN;
136
137     /* Some broken sources such as H.264 conformance case FM2_SVA_C
138      * will get here
139      */
140     obj_surface = SURFACE(surface);
141     if (!obj_surface || !obj_surface->bo)
142         return VA_STATUS_SUCCESS;
143
144     _i965LockMutex(&i965->render_mutex);
145
146     dri_drawable = dri_vtable->get_drawable(ctx, (Drawable)draw);
147     assert(dri_drawable);
148
149     buffer = dri_vtable->get_rendering_buffer(ctx, dri_drawable);
150     assert(buffer);
151     
152     dest_region = render_state->draw_region;
153
154     if (dest_region) {
155         assert(dest_region->bo);
156         dri_bo_flink(dest_region->bo, &name);
157         
158         if (buffer->dri2.name != name) {
159             new_region = True;
160             dri_bo_unreference(dest_region->bo);
161         }
162     } else {
163         dest_region = (struct intel_region *)calloc(1, sizeof(*dest_region));
164         assert(dest_region);
165         render_state->draw_region = dest_region;
166         new_region = True;
167     }
168
169     if (new_region) {
170         dest_region->x = dri_drawable->x;
171         dest_region->y = dri_drawable->y;
172         dest_region->width = dri_drawable->width;
173         dest_region->height = dri_drawable->height;
174         dest_region->cpp = buffer->dri2.cpp;
175         dest_region->pitch = buffer->dri2.pitch;
176
177         dest_region->bo = intel_bo_gem_create_from_name(i965->intel.bufmgr, "rendering buffer", buffer->dri2.name);
178         assert(dest_region->bo);
179
180         ret = dri_bo_get_tiling(dest_region->bo, &(dest_region->tiling), &(dest_region->swizzle));
181         assert(ret == 0);
182     }
183
184     if ((flags & VA_FILTER_SCALING_MASK) == VA_FILTER_SCALING_NL_ANAMORPHIC)
185         pp_flag |= I965_PP_FLAG_AVS;
186
187     if (flags & VA_TOP_FIELD)
188         pp_flag |= I965_PP_FLAG_TOP_FIELD;
189     else if (flags & VA_BOTTOM_FIELD)
190         pp_flag |= I965_PP_FLAG_BOTTOM_FIELD;
191
192     intel_render_put_surface(ctx, surface, src_rect, dst_rect, pp_flag);
193
194     if(obj_surface->subpic != VA_INVALID_ID) {
195         intel_render_put_subpicture(ctx, surface, src_rect, dst_rect);
196     }
197
198     dri_vtable->swap_buffer(ctx, dri_drawable);
199     obj_surface->flags |= SURFACE_DISPLAYED;
200
201     if ((obj_surface->flags & SURFACE_ALL_MASK) == SURFACE_DISPLAYED) {
202         dri_bo_unreference(obj_surface->bo);
203         obj_surface->bo = NULL;
204         obj_surface->flags &= ~SURFACE_REF_DIS_MASK;
205
206         if (obj_surface->free_private_data)
207             obj_surface->free_private_data(&obj_surface->private_data);
208     }
209
210     _i965UnlockMutex(&i965->render_mutex);
211
212     return VA_STATUS_SUCCESS;
213 }