OSDN Git Service

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