OSDN Git Service

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