103b705cfSriastradh/*
203b705cfSriastradh * Copyright © 2007 Intel Corporation
303b705cfSriastradh *
403b705cfSriastradh * Permission is hereby granted, free of charge, to any person obtaining a
503b705cfSriastradh * copy of this software and associated documentation files (the "Software"),
603b705cfSriastradh * to deal in the Software without restriction, including without limitation
703b705cfSriastradh * the rights to use, copy, modify, merge, publish, distribute, sublicense,
803b705cfSriastradh * and/or sell copies of the Software, and to permit persons to whom the
903b705cfSriastradh * Software is furnished to do so, subject to the following conditions:
1003b705cfSriastradh *
1103b705cfSriastradh * The above copyright notice and this permission notice (including the next
1203b705cfSriastradh * paragraph) shall be included in all copies or substantial portions of the
1303b705cfSriastradh * Software.
1403b705cfSriastradh *
1503b705cfSriastradh * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1603b705cfSriastradh * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1703b705cfSriastradh * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1803b705cfSriastradh * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1903b705cfSriastradh * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2003b705cfSriastradh * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2103b705cfSriastradh * SOFTWARE.
2203b705cfSriastradh *
2303b705cfSriastradh * Authors:
2403b705cfSriastradh *    Zhenyu Wang <zhenyu.z.wang@intel.com>
2503b705cfSriastradh *
2603b705cfSriastradh */
2703b705cfSriastradh#include "intel_xvmc_private.h"
2803b705cfSriastradh#include <xcb/xcb.h>
2903b705cfSriastradh#include <xcb/xcb_aux.h>
3003b705cfSriastradh#include <xcb/dri2.h>
3103b705cfSriastradh#include <X11/Xlib-xcb.h>
3203b705cfSriastradh#include <X11/extensions/dri2tokens.h>
3303b705cfSriastradh
3403b705cfSriastradh/* global */
3503b705cfSriastradhstruct _intel_xvmc_driver *xvmc_driver = NULL;
3603b705cfSriastradh
3703b705cfSriastradh/* Lookup tables to speed common calculations for coded_block_pattern */
3803b705cfSriastradh/* each block is ((8*8) * sizeof(short)) */
3903b705cfSriastradhunsigned int mb_bytes_420[] = {
4003b705cfSriastradh	0,			/* 0 */
4103b705cfSriastradh	128,			/* 1 */
4203b705cfSriastradh	128,			/* 10 */
4303b705cfSriastradh	256,			/* 11 */
4403b705cfSriastradh	128,			/* 100 */
4503b705cfSriastradh	256,			/* 101 */
4603b705cfSriastradh	256,			/* 110 */
4703b705cfSriastradh	384,			/* 111 */
4803b705cfSriastradh	128,			/* 1000 */
4903b705cfSriastradh	256,			/* 1001 */
5003b705cfSriastradh	256,			/* 1010 */
5103b705cfSriastradh	384,			/* 1011 */
5203b705cfSriastradh	256,			/* 1100 */
5303b705cfSriastradh	384,			/* 1101 */
5403b705cfSriastradh	384,			/* 1110 */
5503b705cfSriastradh	512,			/* 1111 */
5603b705cfSriastradh	128,			/* 10000 */
5703b705cfSriastradh	256,			/* 10001 */
5803b705cfSriastradh	256,			/* 10010 */
5903b705cfSriastradh	384,			/* 10011 */
6003b705cfSriastradh	256,			/* 10100 */
6103b705cfSriastradh	384,			/* 10101 */
6203b705cfSriastradh	384,			/* 10110 */
6303b705cfSriastradh	512,			/* 10111 */
6403b705cfSriastradh	256,			/* 11000 */
6503b705cfSriastradh	384,			/* 11001 */
6603b705cfSriastradh	384,			/* 11010 */
6703b705cfSriastradh	512,			/* 11011 */
6803b705cfSriastradh	384,			/* 11100 */
6903b705cfSriastradh	512,			/* 11101 */
7003b705cfSriastradh	512,			/* 11110 */
7103b705cfSriastradh	640,			/* 11111 */
7203b705cfSriastradh	128,			/* 100000 */
7303b705cfSriastradh	256,			/* 100001 */
7403b705cfSriastradh	256,			/* 100010 */
7503b705cfSriastradh	384,			/* 100011 */
7603b705cfSriastradh	256,			/* 100100 */
7703b705cfSriastradh	384,			/* 100101 */
7803b705cfSriastradh	384,			/* 100110 */
7903b705cfSriastradh	512,			/* 100111 */
8003b705cfSriastradh	256,			/* 101000 */
8103b705cfSriastradh	384,			/* 101001 */
8203b705cfSriastradh	384,			/* 101010 */
8303b705cfSriastradh	512,			/* 101011 */
8403b705cfSriastradh	384,			/* 101100 */
8503b705cfSriastradh	512,			/* 101101 */
8603b705cfSriastradh	512,			/* 101110 */
8703b705cfSriastradh	640,			/* 101111 */
8803b705cfSriastradh	256,			/* 110000 */
8903b705cfSriastradh	384,			/* 110001 */
9003b705cfSriastradh	384,			/* 110010 */
9103b705cfSriastradh	512,			/* 110011 */
9203b705cfSriastradh	384,			/* 110100 */
9303b705cfSriastradh	512,			/* 110101 */
9403b705cfSriastradh	512,			/* 110110 */
9503b705cfSriastradh	640,			/* 110111 */
9603b705cfSriastradh	384,			/* 111000 */
9703b705cfSriastradh	512,			/* 111001 */
9803b705cfSriastradh	512,			/* 111010 */
9903b705cfSriastradh	640,			/* 111011 */
10003b705cfSriastradh	512,			/* 111100 */
10103b705cfSriastradh	640,			/* 111101 */
10203b705cfSriastradh	640,			/* 111110 */
10303b705cfSriastradh	768			/* 111111 */
10403b705cfSriastradh};
10503b705cfSriastradh
10603b705cfSriastradhstatic int
10703b705cfSriastradhdri2_connect(Display *display)
10803b705cfSriastradh{
10903b705cfSriastradh	xcb_dri2_query_version_cookie_t query_version_cookie;
11003b705cfSriastradh	xcb_dri2_query_version_reply_t *query_version_reply;
11103b705cfSriastradh	xcb_dri2_connect_cookie_t connect_cookie;
11203b705cfSriastradh	xcb_dri2_connect_reply_t *connect_reply;
11303b705cfSriastradh	xcb_dri2_authenticate_cookie_t auth_cookie;
11403b705cfSriastradh	xcb_dri2_authenticate_reply_t *auth_reply;
11503b705cfSriastradh	xcb_screen_t *root;
11603b705cfSriastradh	xcb_connection_t *c = XGetXCBConnection(display);
11703b705cfSriastradh	drm_magic_t magic;
11803b705cfSriastradh	const xcb_query_extension_reply_t *dri2_reply;
11903b705cfSriastradh	char *device_name;
12003b705cfSriastradh	int len;
12103b705cfSriastradh
12203b705cfSriastradh	root = xcb_aux_get_screen(c, DefaultScreen(display));
12303b705cfSriastradh
12403b705cfSriastradh	dri2_reply = xcb_get_extension_data(c, &xcb_dri2_id);
12503b705cfSriastradh
12603b705cfSriastradh	if (!dri2_reply) {
12703b705cfSriastradh		XVMC_ERR("DRI2 required");
12803b705cfSriastradh		return BadValue;
12903b705cfSriastradh	}
13003b705cfSriastradh
13103b705cfSriastradh	/* Query the extension and make our first use of it at the same time. */
13203b705cfSriastradh	query_version_cookie = xcb_dri2_query_version(c, 1, 0);
13303b705cfSriastradh	connect_cookie = xcb_dri2_connect(c, root->root, DRI2DriverDRI);
13403b705cfSriastradh
13503b705cfSriastradh	query_version_reply =
13603b705cfSriastradh		xcb_dri2_query_version_reply(c, query_version_cookie, NULL);
13703b705cfSriastradh	connect_reply = xcb_dri2_connect_reply(c, connect_cookie, NULL);
13803b705cfSriastradh
13903b705cfSriastradh	if (!query_version_reply) {
14003b705cfSriastradh		XVMC_ERR("DRI2 required");
14103b705cfSriastradh		return BadValue;
14203b705cfSriastradh	}
14303b705cfSriastradh	free(query_version_reply);
14403b705cfSriastradh
14503b705cfSriastradh	len = xcb_dri2_connect_device_name_length(connect_reply);
14603b705cfSriastradh	device_name = malloc(len + 1);
14703b705cfSriastradh	if (!device_name) {
14803b705cfSriastradh		XVMC_ERR("malloc failure");
14903b705cfSriastradh		return BadAlloc;
15003b705cfSriastradh	}
15103b705cfSriastradh	strncpy(device_name, xcb_dri2_connect_device_name(connect_reply), len);
15203b705cfSriastradh	device_name[len] = 0;
15303b705cfSriastradh	xvmc_driver->fd = open(device_name, O_RDWR);
15403b705cfSriastradh	free(device_name);
15503b705cfSriastradh	free(connect_reply);
15603b705cfSriastradh	if (xvmc_driver->fd < 0) {
15703b705cfSriastradh		XVMC_ERR("Failed to open drm device: %s\n", strerror(errno));
15803b705cfSriastradh		return BadValue;
15903b705cfSriastradh	}
16003b705cfSriastradh
16103b705cfSriastradh	if (drmGetMagic(xvmc_driver->fd, &magic)) {
16203b705cfSriastradh		XVMC_ERR("Failed to get magic\n");
16303b705cfSriastradh		return BadValue;
16403b705cfSriastradh	}
16503b705cfSriastradh
16603b705cfSriastradh	auth_cookie = xcb_dri2_authenticate(c, root->root, magic);
16703b705cfSriastradh	auth_reply = xcb_dri2_authenticate_reply(c, auth_cookie, NULL);
16803b705cfSriastradh	if (!auth_reply) {
16903b705cfSriastradh		XVMC_ERR("Failed to authenticate magic %d\n", magic);
17003b705cfSriastradh		return BadValue;
17103b705cfSriastradh	}
17203b705cfSriastradh	free(auth_reply);
17303b705cfSriastradh
17403b705cfSriastradh	return Success;
17503b705cfSriastradh}
17603b705cfSriastradh
17703b705cfSriastradh/*
17803b705cfSriastradh* Function: XvMCCreateContext
17903b705cfSriastradh* Description: Create a XvMC context for the given surface parameters.
18003b705cfSriastradh* Arguments:
18103b705cfSriastradh*   display - Connection to the X server.
18203b705cfSriastradh*   port - XvPortID to use as avertised by the X connection.
18303b705cfSriastradh*   surface_type_id - Unique identifier for the Surface type.
18403b705cfSriastradh*   width - Width of the surfaces.
18503b705cfSriastradh*   height - Height of the surfaces.
18603b705cfSriastradh*   flags - one or more of the following
18703b705cfSriastradh*      XVMC_DIRECT - A direct rendered context is requested.
18803b705cfSriastradh*
18903b705cfSriastradh* Notes: surface_type_id and width/height parameters must match those
19003b705cfSriastradh*        returned by XvMCListSurfaceTypes.
19103b705cfSriastradh* Returns: Status
19203b705cfSriastradh*/
19303b705cfSriastradh_X_EXPORT Status XvMCCreateContext(Display * display, XvPortID port,
19403b705cfSriastradh				   int surface_type_id, int width, int height,
19503b705cfSriastradh				   int flags, XvMCContext * context)
19603b705cfSriastradh{
19703b705cfSriastradh	Status ret;
19803b705cfSriastradh	CARD32 *priv_data = NULL;
19903b705cfSriastradh	struct intel_xvmc_hw_context *comm;
20003b705cfSriastradh	int major, minor;
20103b705cfSriastradh	int error_base;
20203b705cfSriastradh	int event_base;
20303b705cfSriastradh	int priv_count;
20403b705cfSriastradh
20503b705cfSriastradh	/* Verify Obvious things first */
20603b705cfSriastradh	if (!display || !context)
20703b705cfSriastradh		return BadValue;
20803b705cfSriastradh
20903b705cfSriastradh	if (!(flags & XVMC_DIRECT)) {
21003b705cfSriastradh		XVMC_ERR("Indirect Rendering not supported! Using Direct.");
21103b705cfSriastradh		return BadValue;
21203b705cfSriastradh	}
21303b705cfSriastradh
21403b705cfSriastradh	/*
21503b705cfSriastradh	   Width, Height, and flags are checked against surface_type_id
21603b705cfSriastradh	   and port for validity inside the X server, no need to check
21703b705cfSriastradh	   here.
21803b705cfSriastradh	 */
21903b705cfSriastradh	context->surface_type_id = surface_type_id;
22003b705cfSriastradh	context->width = (unsigned short)((width + 15) & ~15);
22103b705cfSriastradh	context->height = (unsigned short)((height + 15) & ~15);
22203b705cfSriastradh	context->flags = flags;
22303b705cfSriastradh	context->port = port;
22403b705cfSriastradh
22503b705cfSriastradh	if (!XvMCQueryExtension(display, &event_base, &error_base)) {
22603b705cfSriastradh		XVMC_ERR("XvMCExtension is not available!");
22703b705cfSriastradh		return BadValue;
22803b705cfSriastradh	}
22903b705cfSriastradh
23003b705cfSriastradh	ret = XvMCQueryVersion(display, &major, &minor);
23103b705cfSriastradh	if (ret) {
23203b705cfSriastradh		XVMC_ERR
23303b705cfSriastradh		    ("XvMCQueryVersion Failed, unable to determine protocol version.");
23403b705cfSriastradh		return ret;
23503b705cfSriastradh	}
23603b705cfSriastradh
23703b705cfSriastradh	/* XXX: major and minor could be checked in future for XvMC
23803b705cfSriastradh	 * protocol capability (i.e H.264/AVC decode available)
23903b705cfSriastradh	 */
24003b705cfSriastradh
24103b705cfSriastradh	/*
24203b705cfSriastradh	   Pass control to the X server to create a drm_context_t for us and
24303b705cfSriastradh	   validate the with/height and flags.
24403b705cfSriastradh	 */
24503b705cfSriastradh	if ((ret =
24603b705cfSriastradh	     _xvmc_create_context(display, context, &priv_count, &priv_data))) {
24703b705cfSriastradh		XVMC_ERR("Unable to create XvMC Context.");
24803b705cfSriastradh		return ret;
24903b705cfSriastradh	}
25003b705cfSriastradh
25103b705cfSriastradh	comm = (struct intel_xvmc_hw_context *)priv_data;
25203b705cfSriastradh
25303b705cfSriastradh	if (xvmc_driver == NULL || xvmc_driver->type != comm->type) {
25403b705cfSriastradh		switch (comm->type) {
25503b705cfSriastradh		case XVMC_I915_MPEG2_MC:
25603b705cfSriastradh			xvmc_driver = &i915_xvmc_mc_driver;
25703b705cfSriastradh			break;
25803b705cfSriastradh		case XVMC_I965_MPEG2_MC:
25903b705cfSriastradh			xvmc_driver = &i965_xvmc_mc_driver;
26003b705cfSriastradh			break;
26103b705cfSriastradh		case XVMC_I965_MPEG2_VLD:
26203b705cfSriastradh			xvmc_driver = &xvmc_vld_driver;
26303b705cfSriastradh			break;
26403b705cfSriastradh		case XVMC_I945_MPEG2_VLD:
26503b705cfSriastradh		default:
26603b705cfSriastradh			XVMC_ERR("unimplemented xvmc type %d", comm->type);
26703b705cfSriastradh			XFree(priv_data);
26803b705cfSriastradh			priv_data = NULL;
26903b705cfSriastradh			return BadValue;
27003b705cfSriastradh		}
27103b705cfSriastradh	}
27203b705cfSriastradh
27303b705cfSriastradh	if (xvmc_driver == NULL || xvmc_driver->type != comm->type) {
27403b705cfSriastradh		XVMC_ERR("fail to load xvmc driver for type %d\n", comm->type);
27503b705cfSriastradh		return BadValue;
27603b705cfSriastradh	}
27703b705cfSriastradh
27803b705cfSriastradh	XVMC_INFO("decoder type is %s", intel_xvmc_decoder_string(comm->type));
27903b705cfSriastradh
28003b705cfSriastradh	/* check DRI2 */
28103b705cfSriastradh	ret = Success;
28203b705cfSriastradh	xvmc_driver->fd = -1;
28303b705cfSriastradh
28403b705cfSriastradh	ret = dri2_connect(display);
28503b705cfSriastradh	if (ret != Success) {
28603b705cfSriastradh		XFree(priv_data);
28703b705cfSriastradh		context->privData = NULL;
28803b705cfSriastradh		if (xvmc_driver->fd >= 0)
28903b705cfSriastradh			close(xvmc_driver->fd);
29003b705cfSriastradh		xvmc_driver = NULL;
29103b705cfSriastradh		return ret;
29203b705cfSriastradh	}
29303b705cfSriastradh
29403b705cfSriastradh	if ((xvmc_driver->bufmgr =
29503b705cfSriastradh	     intel_bufmgr_gem_init(xvmc_driver->fd, 1024 * 64)) == NULL) {
29603b705cfSriastradh		XVMC_ERR("Can't init bufmgr\n");
29703b705cfSriastradh		return BadAlloc;
29803b705cfSriastradh	}
29903b705cfSriastradh	drm_intel_bufmgr_gem_enable_reuse(xvmc_driver->bufmgr);
30003b705cfSriastradh
30142542f5fSchristos	if (!intelInitBatchBuffer()) {
30242542f5fSchristos		XFree(priv_data);
30342542f5fSchristos		context->privData = NULL;
30442542f5fSchristos
30542542f5fSchristos		dri_bufmgr_destroy(xvmc_driver->bufmgr);
30642542f5fSchristos		xvmc_driver = NULL;
30742542f5fSchristos
30842542f5fSchristos		return BadAlloc;
30942542f5fSchristos	}
31042542f5fSchristos
31103b705cfSriastradh	/* call driver hook.
31203b705cfSriastradh	 * driver hook should free priv_data after return if success.*/
31303b705cfSriastradh	ret =
31403b705cfSriastradh	    (xvmc_driver->create_context) (display, context, priv_count,
31503b705cfSriastradh					   priv_data);
31603b705cfSriastradh	if (ret) {
31703b705cfSriastradh		XVMC_ERR("driver create context failed\n");
31842542f5fSchristos		intelFiniBatchBuffer();
31942542f5fSchristos
32003b705cfSriastradh		XFree(priv_data);
32103b705cfSriastradh		context->privData = NULL;
32242542f5fSchristos
32342542f5fSchristos		dri_bufmgr_destroy(xvmc_driver->bufmgr);
32403b705cfSriastradh		xvmc_driver = NULL;
32503b705cfSriastradh		return ret;
32603b705cfSriastradh	}
32703b705cfSriastradh
32842542f5fSchristos	sigfillset(&xvmc_driver->sa_mask);
32942542f5fSchristos	sigdelset(&xvmc_driver->sa_mask, SIGFPE);
33042542f5fSchristos	sigdelset(&xvmc_driver->sa_mask, SIGILL);
33142542f5fSchristos	sigdelset(&xvmc_driver->sa_mask, SIGSEGV);
33242542f5fSchristos	sigdelset(&xvmc_driver->sa_mask, SIGBUS);
33342542f5fSchristos	sigdelset(&xvmc_driver->sa_mask, SIGKILL);
33403b705cfSriastradh	pthread_mutex_init(&xvmc_driver->ctxmutex, NULL);
33542542f5fSchristos
33603b705cfSriastradh	intel_xvmc_dump_open();
33703b705cfSriastradh
33803b705cfSriastradh	return Success;
33903b705cfSriastradh}
34003b705cfSriastradh
34103b705cfSriastradh/*
34203b705cfSriastradh * Function: XvMCDestroyContext
34303b705cfSriastradh * Description: Destorys the specified context.
34403b705cfSriastradh *
34503b705cfSriastradh * Arguments:
34603b705cfSriastradh *   display - Specifies the connection to the server.
34703b705cfSriastradh *   context - The context to be destroyed.
34803b705cfSriastradh *
34903b705cfSriastradh */
35003b705cfSriastradh_X_EXPORT Status XvMCDestroyContext(Display * display, XvMCContext * context)
35103b705cfSriastradh{
35203b705cfSriastradh	Status ret;
35303b705cfSriastradh	int screen;
35403b705cfSriastradh
35503b705cfSriastradh	if (!display || !context)
35603b705cfSriastradh		return XvMCBadContext;
35703b705cfSriastradh	screen = DefaultScreen(display);
35803b705cfSriastradh	ret = (xvmc_driver->destroy_context) (display, context);
35903b705cfSriastradh	if (ret) {
36003b705cfSriastradh		XVMC_ERR("destroy context fail\n");
36103b705cfSriastradh		return ret;
36203b705cfSriastradh	}
36303b705cfSriastradh
36403b705cfSriastradh	intelFiniBatchBuffer();
36503b705cfSriastradh
36603b705cfSriastradh	dri_bufmgr_destroy(xvmc_driver->bufmgr);
36703b705cfSriastradh
36803b705cfSriastradh	ret = _xvmc_destroy_context(display, context);
36903b705cfSriastradh	if (ret != Success) {
37003b705cfSriastradh		XVMC_ERR("_xvmc_destroy_context fail\n");
37103b705cfSriastradh		return ret;
37203b705cfSriastradh	}
37303b705cfSriastradh
37403b705cfSriastradh	if (xvmc_driver->num_ctx == 0) {
37503b705cfSriastradh		pthread_mutex_destroy(&xvmc_driver->ctxmutex);
37603b705cfSriastradh
37703b705cfSriastradh		if (xvmc_driver->fd >= 0)
37803b705cfSriastradh			close(xvmc_driver->fd);
37903b705cfSriastradh
38003b705cfSriastradh		xvmc_driver->fd = -1;
38103b705cfSriastradh		intel_xvmc_dump_close();
38203b705cfSriastradh	}
38303b705cfSriastradh	return Success;
38403b705cfSriastradh}
38503b705cfSriastradh
38603b705cfSriastradh/*
38703b705cfSriastradh * Function: XvMCCreateSurface
38803b705cfSriastradh */
38903b705cfSriastradh_X_EXPORT Status XvMCCreateSurface(Display * display, XvMCContext * context,
39003b705cfSriastradh				   XvMCSurface * surface)
39103b705cfSriastradh{
39203b705cfSriastradh	Status ret;
39303b705cfSriastradh	int priv_count;
39403b705cfSriastradh	CARD32 *priv_data;
39503b705cfSriastradh	intel_xvmc_surface_ptr intel_surf = NULL;
39603b705cfSriastradh	struct intel_xvmc_context *intel_ctx;
39703b705cfSriastradh
39803b705cfSriastradh	if (!display || !context)
39903b705cfSriastradh		return XvMCBadContext;
40003b705cfSriastradh
40103b705cfSriastradh	if (!surface)
40203b705cfSriastradh		return XvMCBadSurface;
40303b705cfSriastradh
40403b705cfSriastradh	intel_ctx = context->privData;
40503b705cfSriastradh
40603b705cfSriastradh	if ((ret = _xvmc_create_surface(display, context, surface,
40703b705cfSriastradh					&priv_count, &priv_data))) {
40803b705cfSriastradh		XVMC_ERR("Unable to create XvMCSurface.");
40903b705cfSriastradh		return ret;
41003b705cfSriastradh	}
41103b705cfSriastradh
41203b705cfSriastradh	XFree(priv_data);
41303b705cfSriastradh
41403b705cfSriastradh	surface->privData = calloc(1, sizeof(struct intel_xvmc_surface));
41503b705cfSriastradh
41642542f5fSchristos	if (!(intel_surf = surface->privData))
41742542f5fSchristos		goto out_xvmc;
41803b705cfSriastradh
41903b705cfSriastradh	intel_surf->bo = drm_intel_bo_alloc(xvmc_driver->bufmgr,
42003b705cfSriastradh					      "surface",
42103b705cfSriastradh					      intel_ctx->surface_bo_size,
42203b705cfSriastradh					      GTT_PAGE_SIZE);
42342542f5fSchristos	if (!intel_surf->bo)
42442542f5fSchristos		goto out_surf;
42503b705cfSriastradh
42642542f5fSchristos	if (drm_intel_bo_flink(intel_surf->bo, &intel_surf->gem_handle))
42742542f5fSchristos		goto out_bo;
42803b705cfSriastradh
42903b705cfSriastradh	intel_surf = surface->privData;
43003b705cfSriastradh	intel_surf->context = context;
43103b705cfSriastradh
43203b705cfSriastradh	intel_surf->image = XvCreateImage(display, context->port,
43303b705cfSriastradh					  FOURCC_XVMC,
43403b705cfSriastradh					  (char *) &intel_surf->gem_handle,
43503b705cfSriastradh					  surface->width, surface->height);
43603b705cfSriastradh	if (!intel_surf->image) {
43703b705cfSriastradh		XVMC_ERR("Can't create XvImage for surface\n");
43842542f5fSchristos		goto out_bo;
43903b705cfSriastradh	}
44003b705cfSriastradh
44103b705cfSriastradh	return Success;
44242542f5fSchristos
44342542f5fSchristosout_bo:
44442542f5fSchristos	drm_intel_bo_unreference(intel_surf->bo);
44542542f5fSchristosout_surf:
44642542f5fSchristos	free(intel_surf);
44742542f5fSchristosout_xvmc:
44842542f5fSchristos	_xvmc_destroy_surface(display, surface);
44942542f5fSchristos	return BadAlloc;
45003b705cfSriastradh}
45103b705cfSriastradh
45203b705cfSriastradh/*
45303b705cfSriastradh * Function: XvMCDestroySurface
45403b705cfSriastradh */
45503b705cfSriastradh_X_EXPORT Status XvMCDestroySurface(Display * display, XvMCSurface * surface)
45603b705cfSriastradh{
45703b705cfSriastradh	intel_xvmc_surface_ptr intel_surf;
45803b705cfSriastradh
45903b705cfSriastradh	if (!display || !surface)
46003b705cfSriastradh		return XvMCBadSurface;
46103b705cfSriastradh
46203b705cfSriastradh	intel_surf = surface->privData;
46303b705cfSriastradh	if (!intel_surf)
46403b705cfSriastradh		return XvMCBadSurface;
46503b705cfSriastradh
46603b705cfSriastradh	XFree(intel_surf->image);
46703b705cfSriastradh	if (intel_surf->gc_init)
46803b705cfSriastradh		XFreeGC(display, intel_surf->gc);
46903b705cfSriastradh
47003b705cfSriastradh	drm_intel_bo_unreference(intel_surf->bo);
47103b705cfSriastradh
47203b705cfSriastradh	free(intel_surf);
47303b705cfSriastradh
47403b705cfSriastradh	_xvmc_destroy_surface(display, surface);
47503b705cfSriastradh
47603b705cfSriastradh	return Success;
47703b705cfSriastradh}
47803b705cfSriastradh
47903b705cfSriastradh/*
48003b705cfSriastradh * Function: XvMCCreateBlocks
48103b705cfSriastradh */
48203b705cfSriastradh_X_EXPORT Status XvMCCreateBlocks(Display * display, XvMCContext * context,
48303b705cfSriastradh				  unsigned int num_blocks,
48403b705cfSriastradh				  XvMCBlockArray * block)
48503b705cfSriastradh{
48603b705cfSriastradh	if (!display || !context || !num_blocks || !block)
48703b705cfSriastradh		return BadValue;
48803b705cfSriastradh
48903b705cfSriastradh	memset(block, 0, sizeof(XvMCBlockArray));
49003b705cfSriastradh
49103b705cfSriastradh	if (!
49203b705cfSriastradh	    (block->blocks =
49303b705cfSriastradh	     (short *)malloc((num_blocks << 6) * sizeof(short))))
49403b705cfSriastradh		return BadAlloc;
49503b705cfSriastradh
49603b705cfSriastradh	block->num_blocks = num_blocks;
49703b705cfSriastradh	block->context_id = context->context_id;
49803b705cfSriastradh	block->privData = NULL;
49903b705cfSriastradh
50003b705cfSriastradh	return Success;
50103b705cfSriastradh}
50203b705cfSriastradh
50303b705cfSriastradh/*
50403b705cfSriastradh * Function: XvMCDestroyBlocks
50503b705cfSriastradh */
50603b705cfSriastradh_X_EXPORT Status XvMCDestroyBlocks(Display * display, XvMCBlockArray * block)
50703b705cfSriastradh{
50803b705cfSriastradh	if (!display || !block)
50903b705cfSriastradh		return BadValue;
51003b705cfSriastradh
51103b705cfSriastradh	if (block->blocks)
51203b705cfSriastradh		free(block->blocks);
51303b705cfSriastradh
51403b705cfSriastradh	block->context_id = 0;
51503b705cfSriastradh	block->num_blocks = 0;
51603b705cfSriastradh	block->blocks = NULL;
51703b705cfSriastradh	block->privData = NULL;
51803b705cfSriastradh
51903b705cfSriastradh	return Success;
52003b705cfSriastradh}
52103b705cfSriastradh
52203b705cfSriastradh/*
52303b705cfSriastradh * Function: XvMCCreateMacroBlocks
52403b705cfSriastradh */
52503b705cfSriastradh_X_EXPORT Status XvMCCreateMacroBlocks(Display * display, XvMCContext * context,
52603b705cfSriastradh				       unsigned int num_blocks,
52703b705cfSriastradh				       XvMCMacroBlockArray * blocks)
52803b705cfSriastradh{
52903b705cfSriastradh	if (!display || !context || !blocks || !num_blocks)
53003b705cfSriastradh		return BadValue;
53103b705cfSriastradh
53203b705cfSriastradh	memset(blocks, 0, sizeof(XvMCMacroBlockArray));
53303b705cfSriastradh	blocks->macro_blocks =
53403b705cfSriastradh	    (XvMCMacroBlock *) malloc(num_blocks * sizeof(XvMCMacroBlock));
53503b705cfSriastradh
53603b705cfSriastradh	if (!blocks->macro_blocks)
53703b705cfSriastradh		return BadAlloc;
53803b705cfSriastradh
53903b705cfSriastradh	blocks->num_blocks = num_blocks;
54003b705cfSriastradh	blocks->context_id = context->context_id;
54103b705cfSriastradh	blocks->privData = NULL;
54203b705cfSriastradh
54303b705cfSriastradh	return Success;
54403b705cfSriastradh}
54503b705cfSriastradh
54603b705cfSriastradh/*
54703b705cfSriastradh * Function: XvMCDestroyMacroBlocks
54803b705cfSriastradh */
54903b705cfSriastradh_X_EXPORT Status XvMCDestroyMacroBlocks(Display * display,
55003b705cfSriastradh					XvMCMacroBlockArray * block)
55103b705cfSriastradh{
55203b705cfSriastradh	if (!display || !block)
55303b705cfSriastradh		return BadValue;
55403b705cfSriastradh	if (block->macro_blocks)
55503b705cfSriastradh		free(block->macro_blocks);
55603b705cfSriastradh
55703b705cfSriastradh	block->context_id = 0;
55803b705cfSriastradh	block->num_blocks = 0;
55903b705cfSriastradh	block->macro_blocks = NULL;
56003b705cfSriastradh	block->privData = NULL;
56103b705cfSriastradh
56203b705cfSriastradh	return Success;
56303b705cfSriastradh}
56403b705cfSriastradh
56503b705cfSriastradh/*
56603b705cfSriastradh * Function: XvMCRenderSurface
56703b705cfSriastradh *
56803b705cfSriastradh * Description: This function does the actual HWMC. Given a list of
56903b705cfSriastradh *  macroblock structures it dispatched the hardware commands to execute
57003b705cfSriastradh *  them.
57103b705cfSriastradh */
57203b705cfSriastradh_X_EXPORT Status XvMCRenderSurface(Display * display, XvMCContext * context,
57303b705cfSriastradh				   unsigned int picture_structure,
57403b705cfSriastradh				   XvMCSurface * target_surface,
57503b705cfSriastradh				   XvMCSurface * past_surface,
57603b705cfSriastradh				   XvMCSurface * future_surface,
57703b705cfSriastradh				   unsigned int flags,
57803b705cfSriastradh				   unsigned int num_macroblocks,
57903b705cfSriastradh				   unsigned int first_macroblock,
58003b705cfSriastradh				   XvMCMacroBlockArray * macroblock_array,
58103b705cfSriastradh				   XvMCBlockArray * blocks)
58203b705cfSriastradh{
58303b705cfSriastradh	Status ret;
58403b705cfSriastradh
58503b705cfSriastradh	if (!display || !context) {
58603b705cfSriastradh		XVMC_ERR("Invalid Display, Context or Target!");
58703b705cfSriastradh		return XvMCBadContext;
58803b705cfSriastradh	}
58903b705cfSriastradh	if (!target_surface)
59003b705cfSriastradh		return XvMCBadSurface;
59103b705cfSriastradh
59203b705cfSriastradh	intel_xvmc_dump_render(context, picture_structure, target_surface,
59303b705cfSriastradh			       past_surface, future_surface, flags,
59403b705cfSriastradh			       num_macroblocks, first_macroblock,
59503b705cfSriastradh			       macroblock_array, blocks);
59603b705cfSriastradh
59703b705cfSriastradh	ret =
59803b705cfSriastradh	    (xvmc_driver->render_surface) (display, context, picture_structure,
59903b705cfSriastradh					   target_surface, past_surface,
60003b705cfSriastradh					   future_surface, flags,
60103b705cfSriastradh					   num_macroblocks, first_macroblock,
60203b705cfSriastradh					   macroblock_array, blocks);
60303b705cfSriastradh
60403b705cfSriastradh	if (ret) {
60503b705cfSriastradh		XVMC_ERR("render surface fail\n");
60603b705cfSriastradh		return ret;
60703b705cfSriastradh	}
60803b705cfSriastradh	return Success;
60903b705cfSriastradh}
61003b705cfSriastradh
61103b705cfSriastradh/*
61203b705cfSriastradh * Function: XvMCPutSurface
61303b705cfSriastradh *
61403b705cfSriastradh * Description:
61503b705cfSriastradh * Arguments:
61603b705cfSriastradh *  display: Connection to X server
61703b705cfSriastradh *  surface: Surface to be displayed
61803b705cfSriastradh *  draw: X Drawable on which to display the surface
61903b705cfSriastradh *  srcx: X coordinate of the top left corner of the region to be
62003b705cfSriastradh *          displayed within the surface.
62103b705cfSriastradh *  srcy: Y coordinate of the top left corner of the region to be
62203b705cfSriastradh *          displayed within the surface.
62303b705cfSriastradh *  srcw: Width of the region to be displayed.
62403b705cfSriastradh *  srch: Height of the region to be displayed.
62503b705cfSriastradh *  destx: X cordinate of the top left corner of the destination region
62603b705cfSriastradh *         in the drawable coordinates.
62703b705cfSriastradh *  desty: Y cordinate of the top left corner of the destination region
62803b705cfSriastradh *         in the drawable coordinates.
62903b705cfSriastradh *  destw: Width of the destination region.
63003b705cfSriastradh *  desth: Height of the destination region.
63103b705cfSriastradh *  flags: One or more of the following.
63203b705cfSriastradh *	XVMC_TOP_FIELD - Display only the Top field of the surface.
63303b705cfSriastradh *	XVMC_BOTTOM_FIELD - Display only the Bottom Field of the surface.
63403b705cfSriastradh *	XVMC_FRAME_PICTURE - Display both fields or frame.
63503b705cfSriastradh */
63603b705cfSriastradh_X_EXPORT Status XvMCPutSurface(Display * display, XvMCSurface * surface,
63703b705cfSriastradh				Drawable draw, short srcx, short srcy,
63803b705cfSriastradh				unsigned short srcw, unsigned short srch,
63903b705cfSriastradh				short destx, short desty,
64003b705cfSriastradh				unsigned short destw, unsigned short desth,
64103b705cfSriastradh				int flags)
64203b705cfSriastradh{
64303b705cfSriastradh	XvMCContext *context;
64403b705cfSriastradh	intel_xvmc_surface_ptr intel_surf;
64503b705cfSriastradh
64603b705cfSriastradh	if (!display || !surface)
64703b705cfSriastradh		return XvMCBadSurface;
64803b705cfSriastradh
64903b705cfSriastradh	intel_surf = surface->privData;
65042542f5fSchristos	if (!intel_surf)
65142542f5fSchristos		return XvMCBadSurface;
65242542f5fSchristos
65303b705cfSriastradh	context = intel_surf->context;
65442542f5fSchristos	if (!context)
65503b705cfSriastradh		return XvMCBadSurface;
65603b705cfSriastradh
65703b705cfSriastradh	if (intel_surf->gc_init == FALSE) {
65803b705cfSriastradh		intel_surf->gc = XCreateGC(display, draw, 0, NULL);
65903b705cfSriastradh		intel_surf->gc_init = TRUE;
66003b705cfSriastradh	} else if (draw != intel_surf->last_draw) {
66103b705cfSriastradh		XFreeGC(display, intel_surf->gc);
66203b705cfSriastradh		intel_surf->gc = XCreateGC(display, draw, 0, NULL);
66303b705cfSriastradh	}
66403b705cfSriastradh	intel_surf->last_draw = draw;
66503b705cfSriastradh
66642542f5fSchristos	return XvPutImage(display, context->port, draw, intel_surf->gc,
66742542f5fSchristos			  intel_surf->image, srcx, srcy, srcw, srch, destx,
66842542f5fSchristos			  desty, destw, desth);
66903b705cfSriastradh}
67003b705cfSriastradh
67103b705cfSriastradh/*
67203b705cfSriastradh * Function: XvMCSyncSurface
67303b705cfSriastradh * Arguments:
67403b705cfSriastradh *   display - Connection to the X server
67503b705cfSriastradh *   surface - The surface to synchronize
67603b705cfSriastradh */
67703b705cfSriastradh_X_EXPORT Status XvMCSyncSurface(Display * display, XvMCSurface * surface)
67803b705cfSriastradh{
67903b705cfSriastradh	if (!display || !surface)
68003b705cfSriastradh		return XvMCBadSurface;
68103b705cfSriastradh
68203b705cfSriastradh	return Success;
68303b705cfSriastradh}
68403b705cfSriastradh
68503b705cfSriastradh/*
68603b705cfSriastradh * Function: XvMCFlushSurface
68703b705cfSriastradh * Description:
68803b705cfSriastradh *   This function commits pending rendering requests to ensure that they
68903b705cfSriastradh *   wll be completed in a finite amount of time.
69003b705cfSriastradh * Arguments:
69103b705cfSriastradh *   display - Connection to X server
69203b705cfSriastradh *   surface - Surface to flush
69303b705cfSriastradh * Returns: Status
69403b705cfSriastradh */
69503b705cfSriastradh_X_EXPORT Status XvMCFlushSurface(Display * display, XvMCSurface * surface)
69603b705cfSriastradh{
69703b705cfSriastradh	if (!display || !surface)
69803b705cfSriastradh		return XvMCBadSurface;
69903b705cfSriastradh
70003b705cfSriastradh	return Success;
70103b705cfSriastradh}
70203b705cfSriastradh
70303b705cfSriastradh/*
70403b705cfSriastradh * Function: XvMCGetSurfaceStatus
70503b705cfSriastradh * Description:
70603b705cfSriastradh * Arguments:
70703b705cfSriastradh *  display: connection to X server
70803b705cfSriastradh *  surface: The surface to query
70903b705cfSriastradh *  stat: One of the Following
71003b705cfSriastradh *    XVMC_RENDERING - The last XvMCRenderSurface command has not
71103b705cfSriastradh *                     completed.
71203b705cfSriastradh *    XVMC_DISPLAYING - The surface is currently being displayed or a
71303b705cfSriastradh *                     display is pending.
71403b705cfSriastradh */
71503b705cfSriastradh_X_EXPORT Status XvMCGetSurfaceStatus(Display * display, XvMCSurface * surface,
71603b705cfSriastradh				      int *stat)
71703b705cfSriastradh{
71803b705cfSriastradh	if (!display || !surface || !stat)
71903b705cfSriastradh		return XvMCBadSurface;
72003b705cfSriastradh
72103b705cfSriastradh	*stat = 0;
72203b705cfSriastradh
72303b705cfSriastradh	return Success;
72403b705cfSriastradh}
72503b705cfSriastradh
72603b705cfSriastradh/*
72703b705cfSriastradh * Function: XvMCHideSurface
72803b705cfSriastradh * Description: Stops the display of a surface.
72903b705cfSriastradh * Arguments:
73003b705cfSriastradh *   display - Connection to the X server.
73103b705cfSriastradh *   surface - surface to be hidden.
73203b705cfSriastradh *
73303b705cfSriastradh * Returns: Status
73403b705cfSriastradh */
73503b705cfSriastradh_X_EXPORT Status XvMCHideSurface(Display * display, XvMCSurface * surface)
73603b705cfSriastradh{
73703b705cfSriastradh	if (!display || !surface)
73803b705cfSriastradh		return XvMCBadSurface;
73903b705cfSriastradh
74003b705cfSriastradh	return Success;
74103b705cfSriastradh}
74203b705cfSriastradh
74303b705cfSriastradh/*
74403b705cfSriastradh * Function: XvMCCreateSubpicture
74503b705cfSriastradh * Description: This creates a subpicture by filling out the XvMCSubpicture
74603b705cfSriastradh *              structure passed to it and returning Success.
74703b705cfSriastradh * Arguments:
74803b705cfSriastradh *   display - Connection to the X server.
74903b705cfSriastradh *   context - The context to create the subpicture for.
75003b705cfSriastradh *   subpicture - Pre-allocated XvMCSubpicture structure to be filled in.
75103b705cfSriastradh *   width - of subpicture
75203b705cfSriastradh *   height - of subpicture
75303b705cfSriastradh *   xvimage_id - The id describing the XvImage format.
75403b705cfSriastradh *
75503b705cfSriastradh * Returns: Status
75603b705cfSriastradh */
75703b705cfSriastradh_X_EXPORT Status XvMCCreateSubpicture(Display * display, XvMCContext * context,
75803b705cfSriastradh				      XvMCSubpicture * subpicture,
75903b705cfSriastradh				      unsigned short width,
76003b705cfSriastradh				      unsigned short height, int xvimage_id)
76103b705cfSriastradh{
76203b705cfSriastradh	XVMC_ERR("XvMCCreateSubpicture not implemented!\n");
76303b705cfSriastradh	return BadValue;
76403b705cfSriastradh}
76503b705cfSriastradh
76603b705cfSriastradh/*
76703b705cfSriastradh * Function: XvMCClearSubpicture
76803b705cfSriastradh * Description: Clear the area of the given subpicture to "color".
76903b705cfSriastradh *              structure passed to it and returning Success.
77003b705cfSriastradh * Arguments:
77103b705cfSriastradh *   display - Connection to the X server.
77203b705cfSriastradh *   subpicture - Subpicture to clear.
77303b705cfSriastradh *   x, y, width, height - rectangle in the subpicture to clear.
77403b705cfSriastradh *   color - The data to file the rectangle with.
77503b705cfSriastradh *
77603b705cfSriastradh * Returns: Status
77703b705cfSriastradh */
77803b705cfSriastradh_X_EXPORT Status XvMCClearSubpicture(Display * display,
77903b705cfSriastradh				     XvMCSubpicture * subpicture, short x,
78003b705cfSriastradh				     short y, unsigned short width,
78103b705cfSriastradh				     unsigned short height, unsigned int color)
78203b705cfSriastradh{
78303b705cfSriastradh	XVMC_ERR("XvMCClearSubpicture not implemented!");
78403b705cfSriastradh	return BadValue;
78503b705cfSriastradh}
78603b705cfSriastradh
78703b705cfSriastradh/*
78803b705cfSriastradh * Function: XvMCCompositeSubpicture
78903b705cfSriastradh * Description: Composite the XvImae on the subpicture. This composit uses
79003b705cfSriastradh *              non-premultiplied alpha. Destination alpha is utilized
79103b705cfSriastradh *              except for with indexed subpictures. Indexed subpictures
79203b705cfSriastradh *              use a simple "replace".
79303b705cfSriastradh * Arguments:
79403b705cfSriastradh *   display - Connection to the X server.
79503b705cfSriastradh *   subpicture - Subpicture to clear.
79603b705cfSriastradh *   image - the XvImage to be used as the source of the composite.
79703b705cfSriastradh *   srcx, srcy, width, height - The rectangle from the image to be used.
79803b705cfSriastradh *   dstx, dsty - location in the subpicture to composite the source.
79903b705cfSriastradh *
80003b705cfSriastradh * Returns: Status
80103b705cfSriastradh */
80203b705cfSriastradh_X_EXPORT Status XvMCCompositeSubpicture(Display * display,
80303b705cfSriastradh					 XvMCSubpicture * subpicture,
80403b705cfSriastradh					 XvImage * image, short srcx,
80503b705cfSriastradh					 short srcy, unsigned short width,
80603b705cfSriastradh					 unsigned short height, short dstx,
80703b705cfSriastradh					 short dsty)
80803b705cfSriastradh{
80903b705cfSriastradh	XVMC_ERR("XvMCCompositeSubpicture not implemented!");
81003b705cfSriastradh	return BadValue;
81103b705cfSriastradh}
81203b705cfSriastradh
81303b705cfSriastradh/*
81403b705cfSriastradh * Function: XvMCDestroySubpicture
81503b705cfSriastradh * Description: Destroys the specified subpicture.
81603b705cfSriastradh * Arguments:
81703b705cfSriastradh *   display - Connection to the X server.
81803b705cfSriastradh *   subpicture - Subpicture to be destroyed.
81903b705cfSriastradh *
82003b705cfSriastradh * Returns: Status
82103b705cfSriastradh */
82203b705cfSriastradh_X_EXPORT Status XvMCDestroySubpicture(Display * display,
82303b705cfSriastradh				       XvMCSubpicture * subpicture)
82403b705cfSriastradh{
82503b705cfSriastradh	XVMC_ERR("XvMCDestroySubpicture not implemented!");
82603b705cfSriastradh	return BadValue;
82703b705cfSriastradh}
82803b705cfSriastradh
82903b705cfSriastradh/*
83003b705cfSriastradh * Function: XvMCSetSubpicturePalette
83103b705cfSriastradh * Description: Set the subpictures palette
83203b705cfSriastradh * Arguments:
83303b705cfSriastradh *   display - Connection to the X server.
83403b705cfSriastradh *   subpicture - Subpiture to set palette for.
83503b705cfSriastradh *   palette - A pointer to an array holding the palette data. The array
83603b705cfSriastradh *     is num_palette_entries * entry_bytes in size.
83703b705cfSriastradh * Returns: Status
83803b705cfSriastradh */
83903b705cfSriastradh_X_EXPORT Status XvMCSetSubpicturePalette(Display * display,
84003b705cfSriastradh					  XvMCSubpicture * subpicture,
84103b705cfSriastradh					  unsigned char *palette)
84203b705cfSriastradh{
84303b705cfSriastradh	XVMC_ERR("XvMCSetSubpicturePalette not implemented!");
84403b705cfSriastradh	return BadValue;
84503b705cfSriastradh}
84603b705cfSriastradh
84703b705cfSriastradh/*
84803b705cfSriastradh * Function: XvMCBlendSubpicture
84903b705cfSriastradh * Description:
85003b705cfSriastradh *    The behavior of this function is different depending on whether
85103b705cfSriastradh *    or not the XVMC_BACKEND_SUBPICTURE flag is set in the XvMCSurfaceInfo.
85203b705cfSriastradh *    i915 only support frontend behavior.
85303b705cfSriastradh *
85403b705cfSriastradh *    XVMC_BACKEND_SUBPICTURE not set ("frontend" behavior):
85503b705cfSriastradh *
85603b705cfSriastradh *    XvMCBlendSubpicture is a no-op in this case.
85703b705cfSriastradh *
85803b705cfSriastradh * Arguments:
85903b705cfSriastradh *   display - Connection to the X server.
86003b705cfSriastradh *   subpicture - The subpicture to be blended into the video.
86103b705cfSriastradh *   target_surface - The surface to be displayed with the blended subpic.
86203b705cfSriastradh *   source_surface - Source surface prior to blending.
86303b705cfSriastradh *   subx, suby, subw, subh - The rectangle from the subpicture to use.
86403b705cfSriastradh *   surfx, surfy, surfw, surfh - The rectangle in the surface to blend
86503b705cfSriastradh *      blend the subpicture rectangle into. Scaling can ocure if
86603b705cfSriastradh *      XVMC_SUBPICTURE_INDEPENDENT_SCALING is set.
86703b705cfSriastradh *
86803b705cfSriastradh * Returns: Status
86903b705cfSriastradh */
87003b705cfSriastradh_X_EXPORT Status XvMCBlendSubpicture(Display * display,
87103b705cfSriastradh				     XvMCSurface * target_surface,
87203b705cfSriastradh				     XvMCSubpicture * subpicture, short subx,
87303b705cfSriastradh				     short suby, unsigned short subw,
87403b705cfSriastradh				     unsigned short subh, short surfx,
87503b705cfSriastradh				     short surfy, unsigned short surfw,
87603b705cfSriastradh				     unsigned short surfh)
87703b705cfSriastradh{
87803b705cfSriastradh	XVMC_ERR("XvMCBlendSubpicture not implemented!");
87903b705cfSriastradh	return BadValue;
88003b705cfSriastradh}
88103b705cfSriastradh
88203b705cfSriastradh/*
88303b705cfSriastradh * Function: XvMCBlendSubpicture2
88403b705cfSriastradh * Description:
88503b705cfSriastradh *    The behavior of this function is different depending on whether
88603b705cfSriastradh *    or not the XVMC_BACKEND_SUBPICTURE flag is set in the XvMCSurfaceInfo.
88703b705cfSriastradh *    i915 only supports frontend blending.
88803b705cfSriastradh *
88903b705cfSriastradh *    XVMC_BACKEND_SUBPICTURE not set ("frontend" behavior):
89003b705cfSriastradh *
89103b705cfSriastradh *    XvMCBlendSubpicture2 blends the source_surface and subpicture and
89203b705cfSriastradh *    puts it in the target_surface.  This does not effect the status of
89303b705cfSriastradh *    the source surface but will cause the target_surface to query
89403b705cfSriastradh *    XVMC_RENDERING until the blend is completed.
89503b705cfSriastradh *
89603b705cfSriastradh * Arguments:
89703b705cfSriastradh *   display - Connection to the X server.
89803b705cfSriastradh *   subpicture - The subpicture to be blended into the video.
89903b705cfSriastradh *   target_surface - The surface to be displayed with the blended subpic.
90003b705cfSriastradh *   source_surface - Source surface prior to blending.
90103b705cfSriastradh *   subx, suby, subw, subh - The rectangle from the subpicture to use.
90203b705cfSriastradh *   surfx, surfy, surfw, surfh - The rectangle in the surface to blend
90303b705cfSriastradh *      blend the subpicture rectangle into. Scaling can ocure if
90403b705cfSriastradh *      XVMC_SUBPICTURE_INDEPENDENT_SCALING is set.
90503b705cfSriastradh *
90603b705cfSriastradh * Returns: Status
90703b705cfSriastradh */
90803b705cfSriastradh_X_EXPORT Status XvMCBlendSubpicture2(Display * display,
90903b705cfSriastradh				      XvMCSurface * source_surface,
91003b705cfSriastradh				      XvMCSurface * target_surface,
91103b705cfSriastradh				      XvMCSubpicture * subpicture,
91203b705cfSriastradh				      short subx, short suby,
91303b705cfSriastradh				      unsigned short subw, unsigned short subh,
91403b705cfSriastradh				      short surfx, short surfy,
91503b705cfSriastradh				      unsigned short surfw,
91603b705cfSriastradh				      unsigned short surfh)
91703b705cfSriastradh{
91803b705cfSriastradh	XVMC_ERR("XvMCBlendSubpicture2 not implemented!");
91903b705cfSriastradh	return BadValue;
92003b705cfSriastradh}
92103b705cfSriastradh
92203b705cfSriastradh/*
92303b705cfSriastradh * Function: XvMCSyncSubpicture
92403b705cfSriastradh * Description: This function blocks until all composite/clear requests on
92503b705cfSriastradh *              the subpicture have been complete.
92603b705cfSriastradh * Arguments:
92703b705cfSriastradh *   display - Connection to the X server.
92803b705cfSriastradh *   subpicture - The subpicture to synchronize
92903b705cfSriastradh *
93003b705cfSriastradh * Returns: Status
93103b705cfSriastradh */
93203b705cfSriastradh_X_EXPORT Status XvMCSyncSubpicture(Display * display,
93303b705cfSriastradh				    XvMCSubpicture * subpicture)
93403b705cfSriastradh{
93503b705cfSriastradh	XVMC_ERR("XvMCSyncSubpicture not implemented!");
93603b705cfSriastradh	return BadValue;
93703b705cfSriastradh}
93803b705cfSriastradh
93903b705cfSriastradh/*
94003b705cfSriastradh * Function: XvMCFlushSubpicture
94103b705cfSriastradh * Description: This function commits pending composite/clear requests to
94203b705cfSriastradh *              ensure that they will be completed in a finite amount of
94303b705cfSriastradh *              time.
94403b705cfSriastradh * Arguments:
94503b705cfSriastradh *   display - Connection to the X server.
94603b705cfSriastradh *   subpicture - The subpicture whos compsiting should be flushed
94703b705cfSriastradh *
94803b705cfSriastradh * Returns: Status
94903b705cfSriastradh */
95003b705cfSriastradh_X_EXPORT Status XvMCFlushSubpicture(Display * display,
95103b705cfSriastradh				     XvMCSubpicture * subpicture)
95203b705cfSriastradh{
95303b705cfSriastradh	XVMC_ERR("XvMCFlushSubpicture not implemented!");
95403b705cfSriastradh	return BadValue;
95503b705cfSriastradh}
95603b705cfSriastradh
95703b705cfSriastradh/*
95803b705cfSriastradh * Function: XvMCGetSubpictureStatus
95903b705cfSriastradh * Description: This function gets the current status of a subpicture
96003b705cfSriastradh *
96103b705cfSriastradh * Arguments:
96203b705cfSriastradh *   display - Connection to the X server.
96303b705cfSriastradh *   subpicture - The subpicture whos status is being queried
96403b705cfSriastradh *   stat - The status of the subpicture. It can be any of the following
96503b705cfSriastradh *          OR'd together:
96603b705cfSriastradh *          XVMC_RENDERING  - Last composite or clear request not completed
96703b705cfSriastradh *          XVMC_DISPLAYING - Suppicture currently being displayed.
96803b705cfSriastradh *
96903b705cfSriastradh * Returns: Status
97003b705cfSriastradh */
97103b705cfSriastradh_X_EXPORT Status XvMCGetSubpictureStatus(Display * display,
97203b705cfSriastradh					 XvMCSubpicture * subpicture, int *stat)
97303b705cfSriastradh{
97403b705cfSriastradh	XVMC_ERR("XvMCGetSubpictureStatus not implemented!");
97503b705cfSriastradh	return BadValue;
97603b705cfSriastradh}
97703b705cfSriastradh
97803b705cfSriastradh/*
97903b705cfSriastradh * Function: XvMCQueryAttributes
98003b705cfSriastradh * Description: An array of XvAttributes of size "number" is returned by
98103b705cfSriastradh *   this function. If there are no attributes, NULL is returned and number
98203b705cfSriastradh *   is set to 0. The array may be freed with free().
98303b705cfSriastradh *
98403b705cfSriastradh * Arguments:
98503b705cfSriastradh *   display - Connection to the X server.
98603b705cfSriastradh *   context - The context whos attributes we are querying.
98703b705cfSriastradh *   number - The returned number of recognized atoms
98803b705cfSriastradh *
98903b705cfSriastradh * Returns:
99003b705cfSriastradh *  An array of XvAttributes.
99103b705cfSriastradh */
99203b705cfSriastradh_X_EXPORT XvAttribute *XvMCQueryAttributes(Display * display,
99303b705cfSriastradh					   XvMCContext * context, int *number)
99403b705cfSriastradh{
99503b705cfSriastradh	/* now XvMC has no extra attribs than Xv */
99603b705cfSriastradh	*number = 0;
99703b705cfSriastradh	return NULL;
99803b705cfSriastradh}
99903b705cfSriastradh
100003b705cfSriastradh/*
100103b705cfSriastradh * Function: XvMCSetAttribute
100203b705cfSriastradh * Description: This function sets a context-specific attribute.
100303b705cfSriastradh *
100403b705cfSriastradh * Arguments:
100503b705cfSriastradh *   display - Connection to the X server.
100603b705cfSriastradh *   context - The context whos attributes we are querying.
100703b705cfSriastradh *   attribute - The X atom of the attribute to be changed.
100803b705cfSriastradh *   value - The new value for the attribute.
100903b705cfSriastradh *
101003b705cfSriastradh * Returns:
101103b705cfSriastradh *  Status
101203b705cfSriastradh */
101303b705cfSriastradh_X_EXPORT Status XvMCSetAttribute(Display * display, XvMCContext * context,
101403b705cfSriastradh				  Atom attribute, int value)
101503b705cfSriastradh{
101603b705cfSriastradh	return Success;
101703b705cfSriastradh}
101803b705cfSriastradh
101903b705cfSriastradh/*
102003b705cfSriastradh * Function: XvMCGetAttribute
102103b705cfSriastradh * Description: This function queries a context-specific attribute and
102203b705cfSriastradh *   returns the value.
102303b705cfSriastradh *
102403b705cfSriastradh * Arguments:
102503b705cfSriastradh *   display - Connection to the X server.
102603b705cfSriastradh *   context - The context whos attributes we are querying.
102703b705cfSriastradh *   attribute - The X atom of the attribute to be queried
102803b705cfSriastradh *   value - The returned attribute value
102903b705cfSriastradh *
103003b705cfSriastradh * Returns:
103103b705cfSriastradh *  Status
103203b705cfSriastradh */
103303b705cfSriastradh_X_EXPORT Status XvMCGetAttribute(Display * display, XvMCContext * context,
103403b705cfSriastradh				  Atom attribute, int *value)
103503b705cfSriastradh{
103603b705cfSriastradh	return Success;
103703b705cfSriastradh}
103803b705cfSriastradh
103903b705cfSriastradh_X_EXPORT Status XvMCBeginSurface(Display * display, XvMCContext * context,
104003b705cfSriastradh				  XvMCSurface * target,
104103b705cfSriastradh				  XvMCSurface * past,
104203b705cfSriastradh				  XvMCSurface * future,
104303b705cfSriastradh				  const XvMCMpegControl * control)
104403b705cfSriastradh{
104503b705cfSriastradh	if (xvmc_driver->begin_surface(display, context,
104603b705cfSriastradh				       target, past, future, control)) {
104703b705cfSriastradh		XVMC_ERR("BeginSurface fail\n");
104803b705cfSriastradh		return BadValue;
104903b705cfSriastradh	}
105003b705cfSriastradh	return Success;
105103b705cfSriastradh}
105203b705cfSriastradh
105303b705cfSriastradh_X_EXPORT Status XvMCLoadQMatrix(Display * display, XvMCContext * context,
105403b705cfSriastradh				 const XvMCQMatrix * qmx)
105503b705cfSriastradh{
105603b705cfSriastradh	if (xvmc_driver->load_qmatrix(display, context, qmx)) {
105703b705cfSriastradh		XVMC_ERR("LoadQMatrix fail\n");
105803b705cfSriastradh		return BadValue;
105903b705cfSriastradh	}
106003b705cfSriastradh	return Success;
106103b705cfSriastradh}
106203b705cfSriastradh
106303b705cfSriastradh_X_EXPORT Status XvMCPutSlice(Display * display, XvMCContext * context,
106403b705cfSriastradh			      char *slice, int nbytes)
106503b705cfSriastradh{
106603b705cfSriastradh	if (xvmc_driver->put_slice(display, context, (unsigned char *) slice, nbytes)) {
106703b705cfSriastradh		XVMC_ERR("PutSlice fail\n");
106803b705cfSriastradh		return BadValue;
106903b705cfSriastradh	}
107003b705cfSriastradh	return Success;
107103b705cfSriastradh}
107203b705cfSriastradh
107303b705cfSriastradh_X_EXPORT Status XvMCPutSlice2(Display * display, XvMCContext * context,
107403b705cfSriastradh			       char *slice, int nbytes, int slice_code)
107503b705cfSriastradh{
107603b705cfSriastradh	if (xvmc_driver->put_slice2
107703b705cfSriastradh	    (display, context, (unsigned char *) slice, nbytes, slice_code)) {
107803b705cfSriastradh		XVMC_ERR("PutSlice2 fail\n");
107903b705cfSriastradh		return BadValue;
108003b705cfSriastradh	}
108103b705cfSriastradh	return Success;
108203b705cfSriastradh}
1083