OSDN Git Service

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