1fa225cbcSrjs/*
2fa225cbcSrjs * Copyright © 2007 Intel Corporation
3fa225cbcSrjs *
4fa225cbcSrjs * Permission is hereby granted, free of charge, to any person obtaining a
5fa225cbcSrjs * copy of this software and associated documentation files (the "Software"),
6fa225cbcSrjs * to deal in the Software without restriction, including without limitation
7fa225cbcSrjs * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8fa225cbcSrjs * and/or sell copies of the Software, and to permit persons to whom the
9fa225cbcSrjs * Software is furnished to do so, subject to the following conditions:
10fa225cbcSrjs *
11fa225cbcSrjs * The above copyright notice and this permission notice (including the next
12fa225cbcSrjs * paragraph) shall be included in all copies or substantial portions of the
13fa225cbcSrjs * Software.
14fa225cbcSrjs *
15fa225cbcSrjs * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16fa225cbcSrjs * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17fa225cbcSrjs * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18fa225cbcSrjs * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19fa225cbcSrjs * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20fa225cbcSrjs * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21fa225cbcSrjs * SOFTWARE.
22fa225cbcSrjs *
23fa225cbcSrjs * Authors:
24fa225cbcSrjs *    Zhenyu Wang <zhenyu.z.wang@intel.com>
25fa225cbcSrjs *
26fa225cbcSrjs */
27fa225cbcSrjs#include "intel_xvmc.h"
28fa225cbcSrjs#include "dri2.h"
29fa225cbcSrjs
30fa225cbcSrjs/* global */
31fa225cbcSrjsstruct _intel_xvmc_driver *xvmc_driver = NULL;
32fa225cbcSrjs
33fa225cbcSrjs/* Lookup tables to speed common calculations for coded_block_pattern */
34fa225cbcSrjs/* each block is ((8*8) * sizeof(short)) */
35fa225cbcSrjsunsigned int mb_bytes_420[] = {
36fa225cbcSrjs    0, /* 0 */
37fa225cbcSrjs    128, /* 1 */
38fa225cbcSrjs    128, /* 10 */
39fa225cbcSrjs    256, /* 11 */
40fa225cbcSrjs    128, /* 100 */
41fa225cbcSrjs    256, /* 101 */
42fa225cbcSrjs    256, /* 110 */
43fa225cbcSrjs    384, /* 111 */
44fa225cbcSrjs    128, /* 1000 */
45fa225cbcSrjs    256, /* 1001 */
46fa225cbcSrjs    256, /* 1010 */
47fa225cbcSrjs    384, /* 1011 */
48fa225cbcSrjs    256, /* 1100 */
49fa225cbcSrjs    384, /* 1101 */
50fa225cbcSrjs    384, /* 1110 */
51fa225cbcSrjs    512, /* 1111 */
52fa225cbcSrjs    128, /* 10000 */
53fa225cbcSrjs    256, /* 10001 */
54fa225cbcSrjs    256, /* 10010 */
55fa225cbcSrjs    384, /* 10011 */
56fa225cbcSrjs    256, /* 10100 */
57fa225cbcSrjs    384, /* 10101 */
58fa225cbcSrjs    384, /* 10110 */
59fa225cbcSrjs    512, /* 10111 */
60fa225cbcSrjs    256, /* 11000 */
61fa225cbcSrjs    384, /* 11001 */
62fa225cbcSrjs    384, /* 11010 */
63fa225cbcSrjs    512, /* 11011 */
64fa225cbcSrjs    384, /* 11100 */
65fa225cbcSrjs    512, /* 11101 */
66fa225cbcSrjs    512, /* 11110 */
67fa225cbcSrjs    640, /* 11111 */
68fa225cbcSrjs    128, /* 100000 */
69fa225cbcSrjs    256, /* 100001 */
70fa225cbcSrjs    256, /* 100010 */
71fa225cbcSrjs    384, /* 100011 */
72fa225cbcSrjs    256, /* 100100 */
73fa225cbcSrjs    384, /* 100101 */
74fa225cbcSrjs    384, /* 100110 */
75fa225cbcSrjs    512, /* 100111 */
76fa225cbcSrjs    256, /* 101000 */
77fa225cbcSrjs    384, /* 101001 */
78fa225cbcSrjs    384, /* 101010 */
79fa225cbcSrjs    512, /* 101011 */
80fa225cbcSrjs    384, /* 101100 */
81fa225cbcSrjs    512, /* 101101 */
82fa225cbcSrjs    512, /* 101110 */
83fa225cbcSrjs    640, /* 101111 */
84fa225cbcSrjs    256, /* 110000 */
85fa225cbcSrjs    384, /* 110001 */
86fa225cbcSrjs    384, /* 110010 */
87fa225cbcSrjs    512, /* 110011 */
88fa225cbcSrjs    384, /* 110100 */
89fa225cbcSrjs    512, /* 110101 */
90fa225cbcSrjs    512, /* 110110 */
91fa225cbcSrjs    640, /* 110111 */
92fa225cbcSrjs    384, /* 111000 */
93fa225cbcSrjs    512, /* 111001 */
94fa225cbcSrjs    512, /* 111010 */
95fa225cbcSrjs    640, /* 111011 */
96fa225cbcSrjs    512, /* 111100 */
97fa225cbcSrjs    640, /* 111101 */
98fa225cbcSrjs    640, /* 111110 */
99fa225cbcSrjs    768  /* 111111 */
100fa225cbcSrjs};
101fa225cbcSrjs
102fa225cbcSrjsint DEBUG;
103fa225cbcSrjs
104fa225cbcSrjsstatic void intel_xvmc_debug_init(void)
105fa225cbcSrjs{
106fa225cbcSrjs    if (getenv("INTEL_XVMC_DEBUG"))
107fa225cbcSrjs	DEBUG = 1;
108fa225cbcSrjs}
109fa225cbcSrjs
110fa225cbcSrjsvoid LOCK_HARDWARE(drm_context_t ctx)
111fa225cbcSrjs{
112fa225cbcSrjs    char __ret = 0;
113fa225cbcSrjs
114fa225cbcSrjs    PPTHREAD_MUTEX_LOCK();
115fa225cbcSrjs    assert(!xvmc_driver->locked);
116fa225cbcSrjs
117fa225cbcSrjs    xvmc_driver->locked = 1;
118fa225cbcSrjs}
119fa225cbcSrjs
120fa225cbcSrjsvoid UNLOCK_HARDWARE(drm_context_t ctx)
121fa225cbcSrjs{
122fa225cbcSrjs    xvmc_driver->locked = 0;
123fa225cbcSrjs
124fa225cbcSrjs    PPTHREAD_MUTEX_UNLOCK();
125fa225cbcSrjs}
126fa225cbcSrjs
127fa225cbcSrjsstatic intel_xvmc_context_ptr intel_xvmc_new_context(Display *dpy)
128fa225cbcSrjs{
129fa225cbcSrjs    intel_xvmc_context_ptr ret;
130fa225cbcSrjs
131fa225cbcSrjs    ret = (intel_xvmc_context_ptr)calloc(1, sizeof(intel_xvmc_context_t));
132fa225cbcSrjs    if (!ret)
133fa225cbcSrjs	return NULL;
134fa225cbcSrjs
135fa225cbcSrjs    if (!xvmc_driver->ctx_list)
136fa225cbcSrjs	ret->next = NULL;
137fa225cbcSrjs    else
138fa225cbcSrjs	ret->next = xvmc_driver->ctx_list;
139fa225cbcSrjs    xvmc_driver->ctx_list = ret;
140fa225cbcSrjs    xvmc_driver->num_ctx++;
141fa225cbcSrjs
142fa225cbcSrjs    return ret;
143fa225cbcSrjs
144fa225cbcSrjs}
145fa225cbcSrjs
146fa225cbcSrjsstatic void intel_xvmc_free_context(XID id)
147fa225cbcSrjs{
148fa225cbcSrjs    intel_xvmc_context_ptr p = xvmc_driver->ctx_list;
149fa225cbcSrjs    intel_xvmc_context_ptr pre = p;
150fa225cbcSrjs
151fa225cbcSrjs    while(p) {
152fa225cbcSrjs	if (p->context && p->context->context_id == id) {
153fa225cbcSrjs	    if (p == xvmc_driver->ctx_list)
154fa225cbcSrjs		xvmc_driver->ctx_list = p->next;
155fa225cbcSrjs	    else
156fa225cbcSrjs		pre->next = p->next;
157fa225cbcSrjs	    break;
158fa225cbcSrjs	}
159fa225cbcSrjs	pre = p;
160fa225cbcSrjs	p = p->next;
161fa225cbcSrjs    }
162fa225cbcSrjs
163fa225cbcSrjs    if (p) {
164fa225cbcSrjs	free(p);
165fa225cbcSrjs	xvmc_driver->num_ctx--;
166fa225cbcSrjs    }
167fa225cbcSrjs}
168fa225cbcSrjs
169fa225cbcSrjsintel_xvmc_context_ptr intel_xvmc_find_context(XID id)
170fa225cbcSrjs{
171fa225cbcSrjs    intel_xvmc_context_ptr p = xvmc_driver->ctx_list;
172fa225cbcSrjs
173fa225cbcSrjs    while(p) {
174fa225cbcSrjs	if (p->context && p->context->context_id == id)
175fa225cbcSrjs	    return p;
176fa225cbcSrjs	p = p->next;
177fa225cbcSrjs    }
178fa225cbcSrjs    return NULL;
179fa225cbcSrjs}
180fa225cbcSrjs
181fa225cbcSrjsstatic intel_xvmc_surface_ptr intel_xvmc_new_surface(Display *dpy)
182fa225cbcSrjs{
183fa225cbcSrjs    intel_xvmc_surface_ptr ret;
184fa225cbcSrjs
185fa225cbcSrjs    ret = (intel_xvmc_surface_ptr)calloc(1, sizeof(intel_xvmc_surface_t));
186fa225cbcSrjs    if (!ret)
187fa225cbcSrjs	return NULL;
188fa225cbcSrjs
189fa225cbcSrjs    if (!xvmc_driver->surf_list)
190fa225cbcSrjs	ret->next = NULL;
191fa225cbcSrjs    else
192fa225cbcSrjs	ret->next = xvmc_driver->surf_list;
193fa225cbcSrjs    xvmc_driver->surf_list = ret;
194fa225cbcSrjs    xvmc_driver->num_surf++;
195fa225cbcSrjs
196fa225cbcSrjs    ret->image = NULL;
197fa225cbcSrjs    ret->gc_init = FALSE;
198fa225cbcSrjs
199fa225cbcSrjs    return ret;
200fa225cbcSrjs
201fa225cbcSrjs}
202fa225cbcSrjs
203fa225cbcSrjsstatic void intel_xvmc_free_surface(XID id)
204fa225cbcSrjs{
205fa225cbcSrjs    intel_xvmc_surface_ptr p = xvmc_driver->surf_list;
206fa225cbcSrjs    intel_xvmc_surface_ptr pre = p;
207fa225cbcSrjs
208fa225cbcSrjs    while(p) {
209fa225cbcSrjs	if (p->surface && p->surface->surface_id == id) {
210fa225cbcSrjs	    if (p == xvmc_driver->surf_list)
211fa225cbcSrjs		xvmc_driver->surf_list = p->next;
212fa225cbcSrjs	    else
213fa225cbcSrjs		pre->next = p->next;
214fa225cbcSrjs	    break;
215fa225cbcSrjs	}
216fa225cbcSrjs	pre = p;
217fa225cbcSrjs	p = p->next;
218fa225cbcSrjs    }
219fa225cbcSrjs
220fa225cbcSrjs    if (p) {
221fa225cbcSrjs	free(p);
222fa225cbcSrjs	xvmc_driver->num_surf--;
223fa225cbcSrjs    }
224fa225cbcSrjs}
225fa225cbcSrjs
226fa225cbcSrjsintel_xvmc_surface_ptr intel_xvmc_find_surface(XID id)
227fa225cbcSrjs{
228fa225cbcSrjs    intel_xvmc_surface_ptr p = xvmc_driver->surf_list;
229fa225cbcSrjs
230fa225cbcSrjs    while(p) {
231fa225cbcSrjs	if (p->surface && p->surface->surface_id == id)
232fa225cbcSrjs	    return p;
233fa225cbcSrjs	p = p->next;
234fa225cbcSrjs    }
235fa225cbcSrjs    return NULL;
236fa225cbcSrjs}
237fa225cbcSrjs/*
238fa225cbcSrjs* Function: XvMCCreateContext
239fa225cbcSrjs* Description: Create a XvMC context for the given surface parameters.
240fa225cbcSrjs* Arguments:
241fa225cbcSrjs*   display - Connection to the X server.
242fa225cbcSrjs*   port - XvPortID to use as avertised by the X connection.
243fa225cbcSrjs*   surface_type_id - Unique identifier for the Surface type.
244fa225cbcSrjs*   width - Width of the surfaces.
245fa225cbcSrjs*   height - Height of the surfaces.
246fa225cbcSrjs*   flags - one or more of the following
247fa225cbcSrjs*      XVMC_DIRECT - A direct rendered context is requested.
248fa225cbcSrjs*
249fa225cbcSrjs* Notes: surface_type_id and width/height parameters must match those
250fa225cbcSrjs*        returned by XvMCListSurfaceTypes.
251fa225cbcSrjs* Returns: Status
252fa225cbcSrjs*/
253fa225cbcSrjs_X_EXPORT Status XvMCCreateContext(Display *display, XvPortID port,
254fa225cbcSrjs                         int surface_type_id, int width, int height,
255fa225cbcSrjs                         int flags, XvMCContext *context)
256fa225cbcSrjs{
257fa225cbcSrjs    Status ret;
258fa225cbcSrjs    CARD32 *priv_data = NULL;
259fa225cbcSrjs    struct _intel_xvmc_common *comm;
260fa225cbcSrjs    drm_magic_t magic;
261fa225cbcSrjs    int major, minor;
262fa225cbcSrjs    int error_base;
263fa225cbcSrjs    int event_base;
264fa225cbcSrjs    int priv_count;
265fa225cbcSrjs    int isCapable;
266fa225cbcSrjs    int screen = DefaultScreen(display);
267fa225cbcSrjs    intel_xvmc_context_ptr intel_ctx;
268fa225cbcSrjs    int fd;
269fa225cbcSrjs    char *driverName = NULL, *deviceName = NULL;
270fa225cbcSrjs
271fa225cbcSrjs    /* Verify Obvious things first */
272fa225cbcSrjs    if (!display || !context)
273fa225cbcSrjs        return BadValue;
274fa225cbcSrjs
275fa225cbcSrjs    if (!(flags & XVMC_DIRECT)) {
276fa225cbcSrjs        XVMC_ERR("Indirect Rendering not supported! Using Direct.");
277fa225cbcSrjs        return BadValue;
278fa225cbcSrjs    }
279fa225cbcSrjs
280fa225cbcSrjs    intel_xvmc_debug_init();
281fa225cbcSrjs
282fa225cbcSrjs    /*
283fa225cbcSrjs       Width, Height, and flags are checked against surface_type_id
284fa225cbcSrjs       and port for validity inside the X server, no need to check
285fa225cbcSrjs       here.
286fa225cbcSrjs    */
287fa225cbcSrjs    context->surface_type_id = surface_type_id;
288fa225cbcSrjs    context->width = (unsigned short)((width + 15) & ~15);
289fa225cbcSrjs    context->height = (unsigned short)((height + 15) & ~15);
290fa225cbcSrjs    context->flags = flags;
291fa225cbcSrjs    context->port = port;
292fa225cbcSrjs
293fa225cbcSrjs    if (!XvMCQueryExtension(display, &event_base, &error_base)) {
294fa225cbcSrjs        XVMC_ERR("XvMCExtension is not available!");
295fa225cbcSrjs        return BadValue;
296fa225cbcSrjs    }
297fa225cbcSrjs    ret = XvMCQueryVersion(display, &major, &minor);
298fa225cbcSrjs    if (ret) {
299fa225cbcSrjs        XVMC_ERR("XvMCQueryVersion Failed, unable to determine protocol version.");
300fa225cbcSrjs	return ret;
301fa225cbcSrjs    }
302fa225cbcSrjs
303fa225cbcSrjs    /* XXX: major and minor could be checked in future for XvMC
304fa225cbcSrjs     * protocol capability (i.e H.264/AVC decode available)
305fa225cbcSrjs     */
306fa225cbcSrjs
307fa225cbcSrjs    /*
308fa225cbcSrjs      Pass control to the X server to create a drm_context_t for us and
309fa225cbcSrjs      validate the with/height and flags.
310fa225cbcSrjs    */
311fa225cbcSrjs    if ((ret = _xvmc_create_context(display, context, &priv_count, &priv_data))) {
312fa225cbcSrjs        XVMC_ERR("Unable to create XvMC Context.");
313fa225cbcSrjs        return ret;
314fa225cbcSrjs    }
315fa225cbcSrjs    XVMC_DBG("new context %d created\n", (int)context->context_id);
316fa225cbcSrjs
317fa225cbcSrjs    comm = (struct _intel_xvmc_common *)priv_data;
318fa225cbcSrjs
319fa225cbcSrjs    if (xvmc_driver == NULL || xvmc_driver->type != comm->type) {
320fa225cbcSrjs	switch (comm->type) {
321fa225cbcSrjs	    case XVMC_I915_MPEG2_MC:
322fa225cbcSrjs		xvmc_driver = &i915_xvmc_mc_driver;
323fa225cbcSrjs		break;
324fa225cbcSrjs	    case XVMC_I965_MPEG2_MC:
325fa225cbcSrjs		xvmc_driver = &i965_xvmc_mc_driver;
326fa225cbcSrjs		break;
327fa225cbcSrjs	    case XVMC_I965_MPEG2_VLD:
328fa225cbcSrjs		xvmc_driver = &xvmc_vld_driver;
329fa225cbcSrjs		break;
330fa225cbcSrjs	    case XVMC_I945_MPEG2_VLD:
331fa225cbcSrjs	    default:
332fa225cbcSrjs		XVMC_ERR("unimplemented xvmc type %d", comm->type);
333fa225cbcSrjs		XFree(priv_data);
334fa225cbcSrjs		priv_data = NULL;
335fa225cbcSrjs		return BadValue;
336fa225cbcSrjs	}
337fa225cbcSrjs    }
338fa225cbcSrjs
339fa225cbcSrjs    if (xvmc_driver == NULL || xvmc_driver->type != comm->type) {
340fa225cbcSrjs	XVMC_ERR("fail to load xvmc driver for type %d\n", comm->type);
341fa225cbcSrjs	return BadValue;
342fa225cbcSrjs    }
343fa225cbcSrjs
344fa225cbcSrjs    XVMC_INFO("decoder type is %s", intel_xvmc_decoder_string(comm->type));
345fa225cbcSrjs
346fa225cbcSrjs    xvmc_driver->kernel_exec_fencing = comm->kernel_exec_fencing;
347fa225cbcSrjs
348fa225cbcSrjs    /* assign local ctx info */
349fa225cbcSrjs    intel_ctx = intel_xvmc_new_context(display);
350fa225cbcSrjs    if (!intel_ctx) {
351fa225cbcSrjs	XVMC_ERR("Intel XvMC context create fail\n");
352fa225cbcSrjs	return BadAlloc;
353fa225cbcSrjs    }
354fa225cbcSrjs    intel_ctx->context = context;
355fa225cbcSrjs
356fa225cbcSrjs    /* check DRI2 */
357fa225cbcSrjs    ret = Success;
358fa225cbcSrjs    xvmc_driver->fd = -1;
359fa225cbcSrjs
360fa225cbcSrjs    do {
361fa225cbcSrjs        if (!DRI2QueryExtension(display, &event_base, &error_base)) {
362fa225cbcSrjs            ret = BadValue;
363fa225cbcSrjs            break;
364fa225cbcSrjs        }
365fa225cbcSrjs
366fa225cbcSrjs        if (!DRI2QueryVersion(display, &major, &minor)) {
367fa225cbcSrjs            ret = BadValue;
368fa225cbcSrjs            break;
369fa225cbcSrjs        }
370fa225cbcSrjs
371fa225cbcSrjs        if (!DRI2Connect(display, RootWindow(display, screen),
372fa225cbcSrjs                         &driverName, &deviceName)) {
373fa225cbcSrjs            ret = BadValue;
374fa225cbcSrjs            break;
375fa225cbcSrjs        }
376fa225cbcSrjs
377fa225cbcSrjs        xvmc_driver->fd = open(deviceName, O_RDWR);
378fa225cbcSrjs
379fa225cbcSrjs        if (xvmc_driver->fd < 0) {
380fa225cbcSrjs            XVMC_ERR("Failed to open drm device: %s\n", strerror(errno));
381fa225cbcSrjs            ret = BadValue;
382fa225cbcSrjs            break;
383fa225cbcSrjs        }
384fa225cbcSrjs
385fa225cbcSrjs        if (drmGetMagic(xvmc_driver->fd, &magic)) {
386fa225cbcSrjs            XVMC_ERR("Failed to get magic\n");
387fa225cbcSrjs            ret = BadValue;
388fa225cbcSrjs            break;
389fa225cbcSrjs        }
390fa225cbcSrjs
391fa225cbcSrjs        if (!DRI2Authenticate(display, RootWindow(display, screen), magic)) {
392fa225cbcSrjs            XVMC_ERR("Failed to authenticate magic %d\n", magic);
393fa225cbcSrjs            ret = BadValue;
394fa225cbcSrjs            break;
395fa225cbcSrjs        }
396fa225cbcSrjs    } while (0);
397fa225cbcSrjs
398fa225cbcSrjs    XFree(driverName);
399fa225cbcSrjs    XFree(deviceName);
400fa225cbcSrjs
401fa225cbcSrjs    if (ret != Success) {
402fa225cbcSrjs        XFree(priv_data);
403fa225cbcSrjs        context->privData = NULL;
404fa225cbcSrjs
405fa225cbcSrjs        if (xvmc_driver->fd >= 0)
406fa225cbcSrjs            close(xvmc_driver->fd);
407fa225cbcSrjs
408fa225cbcSrjs        xvmc_driver = NULL;
409fa225cbcSrjs        return ret;
410fa225cbcSrjs    }
411fa225cbcSrjs
412fa225cbcSrjs    if ((xvmc_driver->bufmgr =
413fa225cbcSrjs		intel_bufmgr_gem_init(xvmc_driver->fd, 1024*64)) == NULL) {
414fa225cbcSrjs	XVMC_ERR("Can't init bufmgr\n");
415fa225cbcSrjs 	return BadAlloc;
416fa225cbcSrjs    }
417fa225cbcSrjs    drm_intel_bufmgr_gem_enable_reuse(xvmc_driver->bufmgr);
418fa225cbcSrjs
419fa225cbcSrjs    /* call driver hook.
420fa225cbcSrjs     * driver hook should free priv_data after return if success.*/
421fa225cbcSrjs    ret = (xvmc_driver->create_context)(display, context, priv_count, priv_data);
422fa225cbcSrjs    if (ret) {
423fa225cbcSrjs	XVMC_ERR("driver create context failed\n");
424fa225cbcSrjs	XFree(priv_data);
425fa225cbcSrjs	context->privData = NULL;
426fa225cbcSrjs	xvmc_driver = NULL;
427fa225cbcSrjs	return ret;
428fa225cbcSrjs    }
429fa225cbcSrjs
430fa225cbcSrjs    pthread_mutex_init(&xvmc_driver->ctxmutex, NULL);
431fa225cbcSrjs    intelInitBatchBuffer();
432fa225cbcSrjs    intel_xvmc_dump_open();
433fa225cbcSrjs
434fa225cbcSrjs    return Success;
435fa225cbcSrjs}
436fa225cbcSrjs
437fa225cbcSrjs/*
438fa225cbcSrjs * Function: XvMCDestroyContext
439fa225cbcSrjs * Description: Destorys the specified context.
440fa225cbcSrjs *
441fa225cbcSrjs * Arguments:
442fa225cbcSrjs *   display - Specifies the connection to the server.
443fa225cbcSrjs *   context - The context to be destroyed.
444fa225cbcSrjs *
445fa225cbcSrjs */
446fa225cbcSrjs_X_EXPORT Status XvMCDestroyContext(Display *display, XvMCContext *context)
447fa225cbcSrjs{
448fa225cbcSrjs    Status ret;
449fa225cbcSrjs    int screen;
450fa225cbcSrjs
451fa225cbcSrjs    if (!display || !context)
452fa225cbcSrjs        return XvMCBadContext;
453fa225cbcSrjs    screen = DefaultScreen(display);
454fa225cbcSrjs    ret = (xvmc_driver->destroy_context)(display, context);
455fa225cbcSrjs    if (ret) {
456fa225cbcSrjs	XVMC_ERR("destroy context fail\n");
457fa225cbcSrjs	return ret;
458fa225cbcSrjs    }
459fa225cbcSrjs
460fa225cbcSrjs    intelFiniBatchBuffer();
461fa225cbcSrjs
462fa225cbcSrjs    dri_bufmgr_destroy(xvmc_driver->bufmgr);
463fa225cbcSrjs
464fa225cbcSrjs    intel_xvmc_free_context(context->context_id);
465fa225cbcSrjs
466fa225cbcSrjs    ret = _xvmc_destroy_context(display, context);
467fa225cbcSrjs    if (ret != Success) {
468fa225cbcSrjs	XVMC_ERR("_xvmc_destroy_context fail\n");
469fa225cbcSrjs	return ret;
470fa225cbcSrjs    }
471fa225cbcSrjs
472fa225cbcSrjs    if (xvmc_driver->num_ctx == 0) {
473fa225cbcSrjs	pthread_mutex_destroy(&xvmc_driver->ctxmutex);
474fa225cbcSrjs
475fa225cbcSrjs	if (xvmc_driver->fd >= 0)
476fa225cbcSrjs       close(xvmc_driver->fd);
477fa225cbcSrjs
478fa225cbcSrjs	xvmc_driver->fd = -1;
479fa225cbcSrjs	intel_xvmc_dump_close();
480fa225cbcSrjs    }
481fa225cbcSrjs    return Success;
482fa225cbcSrjs}
483fa225cbcSrjs
484fa225cbcSrjs/*
485fa225cbcSrjs * Function: XvMCCreateSurface
486fa225cbcSrjs */
487fa225cbcSrjs_X_EXPORT Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *surface)
488fa225cbcSrjs{
489fa225cbcSrjs    Status ret;
490fa225cbcSrjs    int priv_count;
491fa225cbcSrjs    CARD32 *priv_data;
492fa225cbcSrjs    intel_xvmc_surface_ptr intel_surf = NULL;
493fa225cbcSrjs
494fa225cbcSrjs    if (!display || !context)
495fa225cbcSrjs        return XvMCBadContext;
496fa225cbcSrjs
497fa225cbcSrjs    if (!surface)
498fa225cbcSrjs	return XvMCBadSurface;
499fa225cbcSrjs
500fa225cbcSrjs    intel_surf = intel_xvmc_new_surface(display);
501fa225cbcSrjs    if (!intel_surf)
502fa225cbcSrjs	return BadAlloc;
503fa225cbcSrjs    intel_surf->surface = surface;
504fa225cbcSrjs
505fa225cbcSrjs    if ((ret = _xvmc_create_surface(display, context, surface,
506fa225cbcSrjs                                    &priv_count, &priv_data))) {
507fa225cbcSrjs        XVMC_ERR("Unable to create XvMCSurface.");
508fa225cbcSrjs        return ret;
509fa225cbcSrjs    }
510fa225cbcSrjs
511fa225cbcSrjs    intel_surf->image = XvCreateImage(display, context->port,
512fa225cbcSrjs	    FOURCC_XVMC, (char *)&intel_surf->data, surface->width,
513fa225cbcSrjs	    surface->height);
514fa225cbcSrjs    if (!intel_surf->image) {
515fa225cbcSrjs	XVMC_ERR("Can't create XvImage for surface\n");
516fa225cbcSrjs	_xvmc_destroy_surface(display, surface);
517fa225cbcSrjs	intel_xvmc_free_surface(surface->surface_id);
518fa225cbcSrjs	return BadAlloc;
519fa225cbcSrjs    }
520fa225cbcSrjs    intel_surf->image->data = (char *)&intel_surf->data;
521fa225cbcSrjs
522fa225cbcSrjs    ret = (xvmc_driver->create_surface)(display, context, surface, priv_count,
523fa225cbcSrjs	    priv_data);
524fa225cbcSrjs    if (ret) {
525fa225cbcSrjs	XVMC_ERR("create surface failed\n");
526fa225cbcSrjs	return ret;
527fa225cbcSrjs    }
528fa225cbcSrjs
529fa225cbcSrjs    return Success;
530fa225cbcSrjs}
531fa225cbcSrjs
532fa225cbcSrjs
533fa225cbcSrjs/*
534fa225cbcSrjs * Function: XvMCDestroySurface
535fa225cbcSrjs */
536fa225cbcSrjs_X_EXPORT Status XvMCDestroySurface(Display *display, XvMCSurface *surface)
537fa225cbcSrjs{
538fa225cbcSrjs    intel_xvmc_surface_ptr intel_surf;
539fa225cbcSrjs
540fa225cbcSrjs    if (!display || !surface)
541fa225cbcSrjs        return XvMCBadSurface;
542fa225cbcSrjs
543fa225cbcSrjs    intel_surf = intel_xvmc_find_surface(surface->surface_id);
544fa225cbcSrjs    if (!intel_surf)
545fa225cbcSrjs	return XvMCBadSurface;
546fa225cbcSrjs
547fa225cbcSrjs    XFree(intel_surf->image);
548fa225cbcSrjs    if (intel_surf->gc_init)
549fa225cbcSrjs	XFreeGC(display, intel_surf->gc);
550fa225cbcSrjs    intel_xvmc_free_surface(surface->surface_id);
551fa225cbcSrjs
552fa225cbcSrjs    (xvmc_driver->destroy_surface)(display, surface);
553fa225cbcSrjs
554fa225cbcSrjs    _xvmc_destroy_surface(display, surface);
555fa225cbcSrjs
556fa225cbcSrjs    return Success;
557fa225cbcSrjs}
558fa225cbcSrjs
559fa225cbcSrjs/*
560fa225cbcSrjs * Function: XvMCCreateBlocks
561fa225cbcSrjs */
562fa225cbcSrjs_X_EXPORT Status XvMCCreateBlocks(Display *display, XvMCContext *context,
563fa225cbcSrjs                        unsigned int num_blocks,
564fa225cbcSrjs                        XvMCBlockArray *block)
565fa225cbcSrjs{
566fa225cbcSrjs    Status ret;
567fa225cbcSrjs    if (!display || !context || !num_blocks || !block)
568fa225cbcSrjs        return BadValue;
569fa225cbcSrjs
570fa225cbcSrjs    memset(block, 0, sizeof(XvMCBlockArray));
571fa225cbcSrjs
572fa225cbcSrjs    if (!(block->blocks = (short *)malloc((num_blocks << 6) * sizeof(short))))
573fa225cbcSrjs        return BadAlloc;
574fa225cbcSrjs
575fa225cbcSrjs    block->num_blocks = num_blocks;
576fa225cbcSrjs    block->context_id = context->context_id;
577fa225cbcSrjs    block->privData = NULL;
578fa225cbcSrjs
579fa225cbcSrjs    return Success;
580fa225cbcSrjs}
581fa225cbcSrjs
582fa225cbcSrjs/*
583fa225cbcSrjs * Function: XvMCDestroyBlocks
584fa225cbcSrjs */
585fa225cbcSrjs_X_EXPORT Status XvMCDestroyBlocks(Display *display, XvMCBlockArray *block)
586fa225cbcSrjs{
587fa225cbcSrjs    Status ret;
588fa225cbcSrjs    if (!display || !block)
589fa225cbcSrjs        return BadValue;
590fa225cbcSrjs
591fa225cbcSrjs    if (block->blocks)
592fa225cbcSrjs        free(block->blocks);
593fa225cbcSrjs
594fa225cbcSrjs    block->context_id = 0;
595fa225cbcSrjs    block->num_blocks = 0;
596fa225cbcSrjs    block->blocks = NULL;
597fa225cbcSrjs    block->privData = NULL;
598fa225cbcSrjs
599fa225cbcSrjs    return Success;
600fa225cbcSrjs}
601fa225cbcSrjs
602fa225cbcSrjs/*
603fa225cbcSrjs * Function: XvMCCreateMacroBlocks
604fa225cbcSrjs */
605fa225cbcSrjs_X_EXPORT Status XvMCCreateMacroBlocks(Display *display, XvMCContext *context,
606fa225cbcSrjs                             unsigned int num_blocks,
607fa225cbcSrjs                             XvMCMacroBlockArray *blocks)
608fa225cbcSrjs{
609fa225cbcSrjs    if (!display || !context || !blocks || !num_blocks)
610fa225cbcSrjs        return BadValue;
611fa225cbcSrjs
612fa225cbcSrjs    memset(blocks, 0, sizeof(XvMCMacroBlockArray));
613fa225cbcSrjs    blocks->macro_blocks = (XvMCMacroBlock *)malloc(num_blocks * sizeof(XvMCMacroBlock));
614fa225cbcSrjs
615fa225cbcSrjs    if (!blocks->macro_blocks)
616fa225cbcSrjs        return BadAlloc;
617fa225cbcSrjs
618fa225cbcSrjs    blocks->num_blocks = num_blocks;
619fa225cbcSrjs    blocks->context_id = context->context_id;
620fa225cbcSrjs    blocks->privData = NULL;
621fa225cbcSrjs
622fa225cbcSrjs    return Success;
623fa225cbcSrjs}
624fa225cbcSrjs
625fa225cbcSrjs/*
626fa225cbcSrjs * Function: XvMCDestroyMacroBlocks
627fa225cbcSrjs */
628fa225cbcSrjs_X_EXPORT Status XvMCDestroyMacroBlocks(Display *display, XvMCMacroBlockArray *block)
629fa225cbcSrjs{
630fa225cbcSrjs    if (!display || !block)
631fa225cbcSrjs        return BadValue;
632fa225cbcSrjs    if (block->macro_blocks)
633fa225cbcSrjs        free(block->macro_blocks);
634fa225cbcSrjs
635fa225cbcSrjs    block->context_id = 0;
636fa225cbcSrjs    block->num_blocks = 0;
637fa225cbcSrjs    block->macro_blocks = NULL;
638fa225cbcSrjs    block->privData = NULL;
639fa225cbcSrjs
640fa225cbcSrjs    return Success;
641fa225cbcSrjs}
642fa225cbcSrjs
643fa225cbcSrjs/*
644fa225cbcSrjs * Function: XvMCRenderSurface
645fa225cbcSrjs *
646fa225cbcSrjs * Description: This function does the actual HWMC. Given a list of
647fa225cbcSrjs *  macroblock structures it dispatched the hardware commands to execute
648fa225cbcSrjs *  them.
649fa225cbcSrjs */
650fa225cbcSrjs_X_EXPORT Status XvMCRenderSurface(Display *display, XvMCContext *context,
651fa225cbcSrjs                         unsigned int picture_structure,
652fa225cbcSrjs                         XvMCSurface *target_surface,
653fa225cbcSrjs                         XvMCSurface *past_surface,
654fa225cbcSrjs                         XvMCSurface *future_surface,
655fa225cbcSrjs                         unsigned int flags,
656fa225cbcSrjs                         unsigned int num_macroblocks,
657fa225cbcSrjs                         unsigned int first_macroblock,
658fa225cbcSrjs                         XvMCMacroBlockArray *macroblock_array,
659fa225cbcSrjs                         XvMCBlockArray *blocks)
660fa225cbcSrjs{
661fa225cbcSrjs    Status ret;
662fa225cbcSrjs
663fa225cbcSrjs    if (!display || !context) {
664fa225cbcSrjs        XVMC_ERR("Invalid Display, Context or Target!");
665fa225cbcSrjs        return XvMCBadContext;
666fa225cbcSrjs    }
667fa225cbcSrjs    if (!target_surface)
668fa225cbcSrjs	return XvMCBadSurface;
669fa225cbcSrjs
670fa225cbcSrjs    intel_xvmc_dump_render(context, picture_structure, target_surface,
671fa225cbcSrjs	    past_surface, future_surface, flags, num_macroblocks,
672fa225cbcSrjs	    first_macroblock, macroblock_array, blocks);
673fa225cbcSrjs
674fa225cbcSrjs    ret = (xvmc_driver->render_surface)(display, context, picture_structure,
675fa225cbcSrjs	    target_surface, past_surface, future_surface, flags,
676fa225cbcSrjs	    num_macroblocks, first_macroblock, macroblock_array,
677fa225cbcSrjs	    blocks);
678fa225cbcSrjs
679fa225cbcSrjs    if (ret) {
680fa225cbcSrjs	XVMC_ERR("render surface fail\n");
681fa225cbcSrjs	return ret;
682fa225cbcSrjs    }
683fa225cbcSrjs    return Success;
684fa225cbcSrjs}
685fa225cbcSrjs
686fa225cbcSrjs/*
687fa225cbcSrjs * Function: XvMCPutSurface
688fa225cbcSrjs *
689fa225cbcSrjs * Description:
690fa225cbcSrjs * Arguments:
691fa225cbcSrjs *  display: Connection to X server
692fa225cbcSrjs *  surface: Surface to be displayed
693fa225cbcSrjs *  draw: X Drawable on which to display the surface
694fa225cbcSrjs *  srcx: X coordinate of the top left corner of the region to be
695fa225cbcSrjs *          displayed within the surface.
696fa225cbcSrjs *  srcy: Y coordinate of the top left corner of the region to be
697fa225cbcSrjs *          displayed within the surface.
698fa225cbcSrjs *  srcw: Width of the region to be displayed.
699fa225cbcSrjs *  srch: Height of the region to be displayed.
700fa225cbcSrjs *  destx: X cordinate of the top left corner of the destination region
701fa225cbcSrjs *         in the drawable coordinates.
702fa225cbcSrjs *  desty: Y cordinate of the top left corner of the destination region
703fa225cbcSrjs *         in the drawable coordinates.
704fa225cbcSrjs *  destw: Width of the destination region.
705fa225cbcSrjs *  desth: Height of the destination region.
706fa225cbcSrjs *  flags: One or more of the following.
707fa225cbcSrjs *	XVMC_TOP_FIELD - Display only the Top field of the surface.
708fa225cbcSrjs *	XVMC_BOTTOM_FIELD - Display only the Bottom Field of the surface.
709fa225cbcSrjs *	XVMC_FRAME_PICTURE - Display both fields or frame.
710fa225cbcSrjs */
711fa225cbcSrjs_X_EXPORT Status XvMCPutSurface(Display *display,XvMCSurface *surface,
712fa225cbcSrjs                      Drawable draw, short srcx, short srcy,
713fa225cbcSrjs                      unsigned short srcw, unsigned short srch,
714fa225cbcSrjs                      short destx, short desty,
715fa225cbcSrjs                      unsigned short destw, unsigned short desth,
716fa225cbcSrjs                      int flags)
717fa225cbcSrjs{
718fa225cbcSrjs    Status ret = Success;
719fa225cbcSrjs    XvMCContext *context;
720fa225cbcSrjs    intel_xvmc_context_ptr intel_ctx;
721fa225cbcSrjs    intel_xvmc_surface_ptr intel_surf;
722fa225cbcSrjs
723fa225cbcSrjs    if (!display || !surface)
724fa225cbcSrjs        return XvMCBadSurface;
725fa225cbcSrjs
726fa225cbcSrjs    intel_ctx = intel_xvmc_find_context(surface->context_id);
727fa225cbcSrjs    intel_surf = intel_xvmc_find_surface(surface->surface_id);
728fa225cbcSrjs    if (!intel_ctx || !intel_surf)
729fa225cbcSrjs	return XvMCBadSurface;
730fa225cbcSrjs    context = intel_ctx->context;
731fa225cbcSrjs
732fa225cbcSrjs    if (intel_surf->gc_init == FALSE) {
733fa225cbcSrjs	intel_surf->gc = XCreateGC(display, draw, 0, NULL);
734fa225cbcSrjs	intel_surf->gc_init = TRUE;
735fa225cbcSrjs    } else if (draw != intel_surf->last_draw) {
736fa225cbcSrjs	XFreeGC(display, intel_surf->gc);
737fa225cbcSrjs	intel_surf->gc = XCreateGC(display, draw, 0, NULL);
738fa225cbcSrjs    }
739fa225cbcSrjs    intel_surf->last_draw = draw;
740fa225cbcSrjs    /* fill intel_surf->data */
741fa225cbcSrjs    ret = (xvmc_driver->put_surface)(display, surface, draw, srcx, srcy,
742fa225cbcSrjs	    srcw, srch, destx, desty, destw, desth, flags, &intel_surf->data);
743fa225cbcSrjs    if (ret) {
744fa225cbcSrjs	XVMC_ERR("put surface fail\n");
745fa225cbcSrjs	return ret;
746fa225cbcSrjs    }
747fa225cbcSrjs    ret = XvPutImage(display, context->port, draw, intel_surf->gc,
748fa225cbcSrjs	    intel_surf->image, srcx, srcy, srcw, srch, destx, desty,
749fa225cbcSrjs	    destw, desth);
750fa225cbcSrjs    return ret;
751fa225cbcSrjs}
752fa225cbcSrjs
753fa225cbcSrjs/*
754fa225cbcSrjs * Function: XvMCSyncSurface
755fa225cbcSrjs * Arguments:
756fa225cbcSrjs *   display - Connection to the X server
757fa225cbcSrjs *   surface - The surface to synchronize
758fa225cbcSrjs */
759fa225cbcSrjs_X_EXPORT Status XvMCSyncSurface(Display *display, XvMCSurface *surface)
760fa225cbcSrjs{
761fa225cbcSrjs    Status ret;
762fa225cbcSrjs    int stat = 0;
763fa225cbcSrjs
764fa225cbcSrjs    if (!display || !surface)
765fa225cbcSrjs	return XvMCBadSurface;
766fa225cbcSrjs
767fa225cbcSrjs    do {
768fa225cbcSrjs        ret = XvMCGetSurfaceStatus(display, surface, &stat);
769fa225cbcSrjs    } while (!ret && (stat & XVMC_RENDERING));
770fa225cbcSrjs
771fa225cbcSrjs    return ret;
772fa225cbcSrjs}
773fa225cbcSrjs
774fa225cbcSrjs/*
775fa225cbcSrjs * Function: XvMCFlushSurface
776fa225cbcSrjs * Description:
777fa225cbcSrjs *   This function commits pending rendering requests to ensure that they
778fa225cbcSrjs *   wll be completed in a finite amount of time.
779fa225cbcSrjs * Arguments:
780fa225cbcSrjs *   display - Connection to X server
781fa225cbcSrjs *   surface - Surface to flush
782fa225cbcSrjs * Returns: Status
783fa225cbcSrjs */
784fa225cbcSrjs_X_EXPORT Status XvMCFlushSurface(Display * display, XvMCSurface *surface)
785fa225cbcSrjs{
786fa225cbcSrjs    if (!display || !surface)
787fa225cbcSrjs	return XvMCBadSurface;
788fa225cbcSrjs    return Success;
789fa225cbcSrjs}
790fa225cbcSrjs
791fa225cbcSrjs/*
792fa225cbcSrjs * Function: XvMCGetSurfaceStatus
793fa225cbcSrjs * Description:
794fa225cbcSrjs * Arguments:
795fa225cbcSrjs *  display: connection to X server
796fa225cbcSrjs *  surface: The surface to query
797fa225cbcSrjs *  stat: One of the Following
798fa225cbcSrjs *    XVMC_RENDERING - The last XvMCRenderSurface command has not
799fa225cbcSrjs *                     completed.
800fa225cbcSrjs *    XVMC_DISPLAYING - The surface is currently being displayed or a
801fa225cbcSrjs *                     display is pending.
802fa225cbcSrjs */
803fa225cbcSrjs_X_EXPORT Status XvMCGetSurfaceStatus(Display *display, XvMCSurface *surface, int *stat)
804fa225cbcSrjs{
805fa225cbcSrjs    Status ret;
806fa225cbcSrjs
807fa225cbcSrjs    if (!display || !surface || !stat)
808fa225cbcSrjs        return XvMCBadSurface;
809fa225cbcSrjs
810fa225cbcSrjs    ret = (xvmc_driver->get_surface_status)(display, surface, stat);
811fa225cbcSrjs    if (ret) {
812fa225cbcSrjs	XVMC_ERR("get surface status fail\n");
813fa225cbcSrjs	return ret;
814fa225cbcSrjs    }
815fa225cbcSrjs
816fa225cbcSrjs    return Success;
817fa225cbcSrjs}
818fa225cbcSrjs
819fa225cbcSrjs/*
820fa225cbcSrjs * Function: XvMCHideSurface
821fa225cbcSrjs * Description: Stops the display of a surface.
822fa225cbcSrjs * Arguments:
823fa225cbcSrjs *   display - Connection to the X server.
824fa225cbcSrjs *   surface - surface to be hidden.
825fa225cbcSrjs *
826fa225cbcSrjs * Returns: Status
827fa225cbcSrjs */
828fa225cbcSrjs_X_EXPORT Status XvMCHideSurface(Display *display, XvMCSurface *surface)
829fa225cbcSrjs{
830fa225cbcSrjs    int stat = 0;
831fa225cbcSrjs    Status ret;
832fa225cbcSrjs
833fa225cbcSrjs    if (!display || !surface)
834fa225cbcSrjs        return XvMCBadSurface;
835fa225cbcSrjs
836fa225cbcSrjs    XvMCSyncSurface(display, surface);
837fa225cbcSrjs
838fa225cbcSrjs    /*
839fa225cbcSrjs      Get the status of the surface, if it is not currently displayed
840fa225cbcSrjs      we don't need to worry about it.
841fa225cbcSrjs    */
842fa225cbcSrjs    if ((ret = XvMCGetSurfaceStatus(display, surface, &stat)) != Success)
843fa225cbcSrjs        return ret;
844fa225cbcSrjs
845fa225cbcSrjs    if (!(stat & XVMC_DISPLAYING))
846fa225cbcSrjs        return Success;
847fa225cbcSrjs
848fa225cbcSrjs    /* FIXME: */
849fa225cbcSrjs    XVMC_ERR("XvMCHideSurface not implemented!\n");
850fa225cbcSrjs    return BadValue;
851fa225cbcSrjs}
852fa225cbcSrjs
853fa225cbcSrjs/*
854fa225cbcSrjs * Function: XvMCCreateSubpicture
855fa225cbcSrjs * Description: This creates a subpicture by filling out the XvMCSubpicture
856fa225cbcSrjs *              structure passed to it and returning Success.
857fa225cbcSrjs * Arguments:
858fa225cbcSrjs *   display - Connection to the X server.
859fa225cbcSrjs *   context - The context to create the subpicture for.
860fa225cbcSrjs *   subpicture - Pre-allocated XvMCSubpicture structure to be filled in.
861fa225cbcSrjs *   width - of subpicture
862fa225cbcSrjs *   height - of subpicture
863fa225cbcSrjs *   xvimage_id - The id describing the XvImage format.
864fa225cbcSrjs *
865fa225cbcSrjs * Returns: Status
866fa225cbcSrjs */
867fa225cbcSrjs_X_EXPORT Status XvMCCreateSubpicture(Display *display, XvMCContext *context,
868fa225cbcSrjs                            XvMCSubpicture *subpicture,
869fa225cbcSrjs                            unsigned short width, unsigned short height,
870fa225cbcSrjs                            int xvimage_id)
871fa225cbcSrjs{
872fa225cbcSrjs    XVMC_ERR("XvMCCreateSubpicture not implemented!\n");
873fa225cbcSrjs    return BadValue;
874fa225cbcSrjs}
875fa225cbcSrjs
876fa225cbcSrjs/*
877fa225cbcSrjs * Function: XvMCClearSubpicture
878fa225cbcSrjs * Description: Clear the area of the given subpicture to "color".
879fa225cbcSrjs *              structure passed to it and returning Success.
880fa225cbcSrjs * Arguments:
881fa225cbcSrjs *   display - Connection to the X server.
882fa225cbcSrjs *   subpicture - Subpicture to clear.
883fa225cbcSrjs *   x, y, width, height - rectangle in the subpicture to clear.
884fa225cbcSrjs *   color - The data to file the rectangle with.
885fa225cbcSrjs *
886fa225cbcSrjs * Returns: Status
887fa225cbcSrjs */
888fa225cbcSrjs_X_EXPORT Status XvMCClearSubpicture(Display *display, XvMCSubpicture *subpicture,
889fa225cbcSrjs                           short x, short y,
890fa225cbcSrjs                           unsigned short width, unsigned short height,
891fa225cbcSrjs                           unsigned int color)
892fa225cbcSrjs{
893fa225cbcSrjs    XVMC_ERR("XvMCClearSubpicture not implemented!");
894fa225cbcSrjs    return BadValue;
895fa225cbcSrjs}
896fa225cbcSrjs
897fa225cbcSrjs/*
898fa225cbcSrjs * Function: XvMCCompositeSubpicture
899fa225cbcSrjs * Description: Composite the XvImae on the subpicture. This composit uses
900fa225cbcSrjs *              non-premultiplied alpha. Destination alpha is utilized
901fa225cbcSrjs *              except for with indexed subpictures. Indexed subpictures
902fa225cbcSrjs *              use a simple "replace".
903fa225cbcSrjs * Arguments:
904fa225cbcSrjs *   display - Connection to the X server.
905fa225cbcSrjs *   subpicture - Subpicture to clear.
906fa225cbcSrjs *   image - the XvImage to be used as the source of the composite.
907fa225cbcSrjs *   srcx, srcy, width, height - The rectangle from the image to be used.
908fa225cbcSrjs *   dstx, dsty - location in the subpicture to composite the source.
909fa225cbcSrjs *
910fa225cbcSrjs * Returns: Status
911fa225cbcSrjs */
912fa225cbcSrjs_X_EXPORT Status XvMCCompositeSubpicture(Display *display, XvMCSubpicture *subpicture,
913fa225cbcSrjs                               XvImage *image,
914fa225cbcSrjs                               short srcx, short srcy,
915fa225cbcSrjs                               unsigned short width, unsigned short height,
916fa225cbcSrjs                               short dstx, short dsty)
917fa225cbcSrjs{
918fa225cbcSrjs    XVMC_ERR("XvMCCompositeSubpicture not implemented!");
919fa225cbcSrjs    return BadValue;
920fa225cbcSrjs}
921fa225cbcSrjs
922fa225cbcSrjs
923fa225cbcSrjs/*
924fa225cbcSrjs * Function: XvMCDestroySubpicture
925fa225cbcSrjs * Description: Destroys the specified subpicture.
926fa225cbcSrjs * Arguments:
927fa225cbcSrjs *   display - Connection to the X server.
928fa225cbcSrjs *   subpicture - Subpicture to be destroyed.
929fa225cbcSrjs *
930fa225cbcSrjs * Returns: Status
931fa225cbcSrjs */
932fa225cbcSrjs_X_EXPORT Status XvMCDestroySubpicture(Display *display, XvMCSubpicture *subpicture)
933fa225cbcSrjs{
934fa225cbcSrjs    XVMC_ERR("XvMCDestroySubpicture not implemented!");
935fa225cbcSrjs    return BadValue;
936fa225cbcSrjs}
937fa225cbcSrjs
938fa225cbcSrjs
939fa225cbcSrjs/*
940fa225cbcSrjs * Function: XvMCSetSubpicturePalette
941fa225cbcSrjs * Description: Set the subpictures palette
942fa225cbcSrjs * Arguments:
943fa225cbcSrjs *   display - Connection to the X server.
944fa225cbcSrjs *   subpicture - Subpiture to set palette for.
945fa225cbcSrjs *   palette - A pointer to an array holding the palette data. The array
946fa225cbcSrjs *     is num_palette_entries * entry_bytes in size.
947fa225cbcSrjs * Returns: Status
948fa225cbcSrjs */
949fa225cbcSrjs_X_EXPORT Status XvMCSetSubpicturePalette(Display *display, XvMCSubpicture *subpicture,
950fa225cbcSrjs                                unsigned char *palette)
951fa225cbcSrjs{
952fa225cbcSrjs    XVMC_ERR("XvMCSetSubpicturePalette not implemented!");
953fa225cbcSrjs    return BadValue;
954fa225cbcSrjs}
955fa225cbcSrjs
956fa225cbcSrjs/*
957fa225cbcSrjs * Function: XvMCBlendSubpicture
958fa225cbcSrjs * Description:
959fa225cbcSrjs *    The behavior of this function is different depending on whether
960fa225cbcSrjs *    or not the XVMC_BACKEND_SUBPICTURE flag is set in the XvMCSurfaceInfo.
961fa225cbcSrjs *    i915 only support frontend behavior.
962fa225cbcSrjs *
963fa225cbcSrjs *    XVMC_BACKEND_SUBPICTURE not set ("frontend" behavior):
964fa225cbcSrjs *
965fa225cbcSrjs *    XvMCBlendSubpicture is a no-op in this case.
966fa225cbcSrjs *
967fa225cbcSrjs * Arguments:
968fa225cbcSrjs *   display - Connection to the X server.
969fa225cbcSrjs *   subpicture - The subpicture to be blended into the video.
970fa225cbcSrjs *   target_surface - The surface to be displayed with the blended subpic.
971fa225cbcSrjs *   source_surface - Source surface prior to blending.
972fa225cbcSrjs *   subx, suby, subw, subh - The rectangle from the subpicture to use.
973fa225cbcSrjs *   surfx, surfy, surfw, surfh - The rectangle in the surface to blend
974fa225cbcSrjs *      blend the subpicture rectangle into. Scaling can ocure if
975fa225cbcSrjs *      XVMC_SUBPICTURE_INDEPENDENT_SCALING is set.
976fa225cbcSrjs *
977fa225cbcSrjs * Returns: Status
978fa225cbcSrjs */
979fa225cbcSrjs_X_EXPORT Status XvMCBlendSubpicture(Display *display, XvMCSurface *target_surface,
980fa225cbcSrjs                           XvMCSubpicture *subpicture,
981fa225cbcSrjs                           short subx, short suby,
982fa225cbcSrjs                           unsigned short subw, unsigned short subh,
983fa225cbcSrjs                           short surfx, short surfy,
984fa225cbcSrjs                           unsigned short surfw, unsigned short surfh)
985fa225cbcSrjs{
986fa225cbcSrjs    XVMC_ERR("XvMCBlendSubpicture not implemented!");
987fa225cbcSrjs    return BadValue;
988fa225cbcSrjs}
989fa225cbcSrjs
990fa225cbcSrjs/*
991fa225cbcSrjs * Function: XvMCBlendSubpicture2
992fa225cbcSrjs * Description:
993fa225cbcSrjs *    The behavior of this function is different depending on whether
994fa225cbcSrjs *    or not the XVMC_BACKEND_SUBPICTURE flag is set in the XvMCSurfaceInfo.
995fa225cbcSrjs *    i915 only supports frontend blending.
996fa225cbcSrjs *
997fa225cbcSrjs *    XVMC_BACKEND_SUBPICTURE not set ("frontend" behavior):
998fa225cbcSrjs *
999fa225cbcSrjs *    XvMCBlendSubpicture2 blends the source_surface and subpicture and
1000fa225cbcSrjs *    puts it in the target_surface.  This does not effect the status of
1001fa225cbcSrjs *    the source surface but will cause the target_surface to query
1002fa225cbcSrjs *    XVMC_RENDERING until the blend is completed.
1003fa225cbcSrjs *
1004fa225cbcSrjs * Arguments:
1005fa225cbcSrjs *   display - Connection to the X server.
1006fa225cbcSrjs *   subpicture - The subpicture to be blended into the video.
1007fa225cbcSrjs *   target_surface - The surface to be displayed with the blended subpic.
1008fa225cbcSrjs *   source_surface - Source surface prior to blending.
1009fa225cbcSrjs *   subx, suby, subw, subh - The rectangle from the subpicture to use.
1010fa225cbcSrjs *   surfx, surfy, surfw, surfh - The rectangle in the surface to blend
1011fa225cbcSrjs *      blend the subpicture rectangle into. Scaling can ocure if
1012fa225cbcSrjs *      XVMC_SUBPICTURE_INDEPENDENT_SCALING is set.
1013fa225cbcSrjs *
1014fa225cbcSrjs * Returns: Status
1015fa225cbcSrjs */
1016fa225cbcSrjs_X_EXPORT Status XvMCBlendSubpicture2(Display *display,
1017fa225cbcSrjs                            XvMCSurface *source_surface,
1018fa225cbcSrjs                            XvMCSurface *target_surface,
1019fa225cbcSrjs                            XvMCSubpicture *subpicture,
1020fa225cbcSrjs                            short subx, short suby,
1021fa225cbcSrjs                            unsigned short subw, unsigned short subh,
1022fa225cbcSrjs                            short surfx, short surfy,
1023fa225cbcSrjs                            unsigned short surfw, unsigned short surfh)
1024fa225cbcSrjs{
1025fa225cbcSrjs    XVMC_ERR("XvMCBlendSubpicture2 not implemented!");
1026fa225cbcSrjs    return BadValue;
1027fa225cbcSrjs}
1028fa225cbcSrjs
1029fa225cbcSrjs/*
1030fa225cbcSrjs * Function: XvMCSyncSubpicture
1031fa225cbcSrjs * Description: This function blocks until all composite/clear requests on
1032fa225cbcSrjs *              the subpicture have been complete.
1033fa225cbcSrjs * Arguments:
1034fa225cbcSrjs *   display - Connection to the X server.
1035fa225cbcSrjs *   subpicture - The subpicture to synchronize
1036fa225cbcSrjs *
1037fa225cbcSrjs * Returns: Status
1038fa225cbcSrjs */
1039fa225cbcSrjs_X_EXPORT Status XvMCSyncSubpicture(Display *display, XvMCSubpicture *subpicture)
1040fa225cbcSrjs{
1041fa225cbcSrjs    XVMC_ERR("XvMCSyncSubpicture not implemented!");
1042fa225cbcSrjs    return BadValue;
1043fa225cbcSrjs}
1044fa225cbcSrjs
1045fa225cbcSrjs/*
1046fa225cbcSrjs * Function: XvMCFlushSubpicture
1047fa225cbcSrjs * Description: This function commits pending composite/clear requests to
1048fa225cbcSrjs *              ensure that they will be completed in a finite amount of
1049fa225cbcSrjs *              time.
1050fa225cbcSrjs * Arguments:
1051fa225cbcSrjs *   display - Connection to the X server.
1052fa225cbcSrjs *   subpicture - The subpicture whos compsiting should be flushed
1053fa225cbcSrjs *
1054fa225cbcSrjs * Returns: Status
1055fa225cbcSrjs */
1056fa225cbcSrjs_X_EXPORT Status XvMCFlushSubpicture(Display *display, XvMCSubpicture *subpicture)
1057fa225cbcSrjs{
1058fa225cbcSrjs    XVMC_ERR("XvMCFlushSubpicture not implemented!");
1059fa225cbcSrjs    return BadValue;
1060fa225cbcSrjs}
1061fa225cbcSrjs
1062fa225cbcSrjs/*
1063fa225cbcSrjs * Function: XvMCGetSubpictureStatus
1064fa225cbcSrjs * Description: This function gets the current status of a subpicture
1065fa225cbcSrjs *
1066fa225cbcSrjs * Arguments:
1067fa225cbcSrjs *   display - Connection to the X server.
1068fa225cbcSrjs *   subpicture - The subpicture whos status is being queried
1069fa225cbcSrjs *   stat - The status of the subpicture. It can be any of the following
1070fa225cbcSrjs *          OR'd together:
1071fa225cbcSrjs *          XVMC_RENDERING  - Last composite or clear request not completed
1072fa225cbcSrjs *          XVMC_DISPLAYING - Suppicture currently being displayed.
1073fa225cbcSrjs *
1074fa225cbcSrjs * Returns: Status
1075fa225cbcSrjs */
1076fa225cbcSrjs_X_EXPORT Status XvMCGetSubpictureStatus(Display *display, XvMCSubpicture *subpicture,
1077fa225cbcSrjs                               int *stat)
1078fa225cbcSrjs{
1079fa225cbcSrjs    XVMC_ERR("XvMCGetSubpictureStatus not implemented!");
1080fa225cbcSrjs    return BadValue;
1081fa225cbcSrjs}
1082fa225cbcSrjs
1083fa225cbcSrjs/*
1084fa225cbcSrjs * Function: XvMCQueryAttributes
1085fa225cbcSrjs * Description: An array of XvAttributes of size "number" is returned by
1086fa225cbcSrjs *   this function. If there are no attributes, NULL is returned and number
1087fa225cbcSrjs *   is set to 0. The array may be freed with xfree().
1088fa225cbcSrjs *
1089fa225cbcSrjs * Arguments:
1090fa225cbcSrjs *   display - Connection to the X server.
1091fa225cbcSrjs *   context - The context whos attributes we are querying.
1092fa225cbcSrjs *   number - The returned number of recognized atoms
1093fa225cbcSrjs *
1094fa225cbcSrjs * Returns:
1095fa225cbcSrjs *  An array of XvAttributes.
1096fa225cbcSrjs */
1097fa225cbcSrjs_X_EXPORT XvAttribute *XvMCQueryAttributes(Display *display, XvMCContext *context,
1098fa225cbcSrjs                                 int *number)
1099fa225cbcSrjs{
1100fa225cbcSrjs    /* now XvMC has no extra attribs than Xv */
1101fa225cbcSrjs    *number = 0;
1102fa225cbcSrjs    return NULL;
1103fa225cbcSrjs}
1104fa225cbcSrjs
1105fa225cbcSrjs/*
1106fa225cbcSrjs * Function: XvMCSetAttribute
1107fa225cbcSrjs * Description: This function sets a context-specific attribute.
1108fa225cbcSrjs *
1109fa225cbcSrjs * Arguments:
1110fa225cbcSrjs *   display - Connection to the X server.
1111fa225cbcSrjs *   context - The context whos attributes we are querying.
1112fa225cbcSrjs *   attribute - The X atom of the attribute to be changed.
1113fa225cbcSrjs *   value - The new value for the attribute.
1114fa225cbcSrjs *
1115fa225cbcSrjs * Returns:
1116fa225cbcSrjs *  Status
1117fa225cbcSrjs */
1118fa225cbcSrjs_X_EXPORT Status XvMCSetAttribute(Display *display, XvMCContext *context,
1119fa225cbcSrjs                        Atom attribute, int value)
1120fa225cbcSrjs{
1121fa225cbcSrjs    return Success;
1122fa225cbcSrjs}
1123fa225cbcSrjs
1124fa225cbcSrjs/*
1125fa225cbcSrjs * Function: XvMCGetAttribute
1126fa225cbcSrjs * Description: This function queries a context-specific attribute and
1127fa225cbcSrjs *   returns the value.
1128fa225cbcSrjs *
1129fa225cbcSrjs * Arguments:
1130fa225cbcSrjs *   display - Connection to the X server.
1131fa225cbcSrjs *   context - The context whos attributes we are querying.
1132fa225cbcSrjs *   attribute - The X atom of the attribute to be queried
1133fa225cbcSrjs *   value - The returned attribute value
1134fa225cbcSrjs *
1135fa225cbcSrjs * Returns:
1136fa225cbcSrjs *  Status
1137fa225cbcSrjs */
1138fa225cbcSrjs_X_EXPORT Status XvMCGetAttribute(Display *display, XvMCContext *context,
1139fa225cbcSrjs                        Atom attribute, int *value)
1140fa225cbcSrjs{
1141fa225cbcSrjs    return Success;
1142fa225cbcSrjs}
1143fa225cbcSrjs
1144fa225cbcSrjs_X_EXPORT Status XvMCBeginSurface(Display *display, XvMCContext *context,
1145fa225cbcSrjs                         XvMCSurface *target,
1146fa225cbcSrjs                         XvMCSurface *past,
1147fa225cbcSrjs                         XvMCSurface *future,
1148fa225cbcSrjs			 const XvMCMpegControl *control)
1149fa225cbcSrjs{
1150fa225cbcSrjs    if (xvmc_driver->begin_surface(display, context,
1151fa225cbcSrjs		target, past, future, control)) {
1152fa225cbcSrjs	XVMC_ERR("BeginSurface fail\n");
1153fa225cbcSrjs	return BadValue;
1154fa225cbcSrjs    }
1155fa225cbcSrjs    return Success;
1156fa225cbcSrjs}
1157fa225cbcSrjs
1158fa225cbcSrjs_X_EXPORT Status XvMCLoadQMatrix(Display *display, XvMCContext *context,
1159fa225cbcSrjs	const XvMCQMatrix *qmx)
1160fa225cbcSrjs{
1161fa225cbcSrjs    if (xvmc_driver->load_qmatrix(display, context, qmx)) {
1162fa225cbcSrjs	XVMC_ERR("LoadQMatrix fail\n");
1163fa225cbcSrjs	return BadValue;
1164fa225cbcSrjs    }
1165fa225cbcSrjs    return Success;
1166fa225cbcSrjs}
1167fa225cbcSrjs
1168fa225cbcSrjs_X_EXPORT Status XvMCPutSlice(Display *display, XvMCContext *context,
1169fa225cbcSrjs			char *slice, int nbytes)
1170fa225cbcSrjs{
1171fa225cbcSrjs    if (xvmc_driver->put_slice(display, context, slice, nbytes)) {
1172fa225cbcSrjs	XVMC_ERR("PutSlice fail\n");
1173fa225cbcSrjs	return BadValue;
1174fa225cbcSrjs    }
1175fa225cbcSrjs    return Success;
1176fa225cbcSrjs}
1177fa225cbcSrjs
1178fa225cbcSrjs_X_EXPORT Status XvMCPutSlice2(Display *display, XvMCContext *context,
1179fa225cbcSrjs			char *slice, int nbytes, int slice_code)
1180fa225cbcSrjs{
1181fa225cbcSrjs    if (xvmc_driver->put_slice2(display, context, slice, nbytes, slice_code)) {
1182fa225cbcSrjs	XVMC_ERR("PutSlice2 fail\n");
1183fa225cbcSrjs	return BadValue;
1184fa225cbcSrjs    }
1185fa225cbcSrjs    return Success;
1186fa225cbcSrjs}
1187