intel_xvmc.c revision 03b705cf
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
10603b705cfSriastradhvoid LOCK_HARDWARE(drm_context_t ctx)
10703b705cfSriastradh{
10803b705cfSriastradh	PPTHREAD_MUTEX_LOCK();
10903b705cfSriastradh	assert(!xvmc_driver->locked);
11003b705cfSriastradh
11103b705cfSriastradh	xvmc_driver->locked = 1;
11203b705cfSriastradh}
11303b705cfSriastradh
11403b705cfSriastradhvoid UNLOCK_HARDWARE(drm_context_t ctx)
11503b705cfSriastradh{
11603b705cfSriastradh	xvmc_driver->locked = 0;
11703b705cfSriastradh
11803b705cfSriastradh	PPTHREAD_MUTEX_UNLOCK();
11903b705cfSriastradh}
12003b705cfSriastradh
12103b705cfSriastradhstatic int
12203b705cfSriastradhdri2_connect(Display *display)
12303b705cfSriastradh{
12403b705cfSriastradh	xcb_dri2_query_version_cookie_t query_version_cookie;
12503b705cfSriastradh	xcb_dri2_query_version_reply_t *query_version_reply;
12603b705cfSriastradh	xcb_dri2_connect_cookie_t connect_cookie;
12703b705cfSriastradh	xcb_dri2_connect_reply_t *connect_reply;
12803b705cfSriastradh	xcb_dri2_authenticate_cookie_t auth_cookie;
12903b705cfSriastradh	xcb_dri2_authenticate_reply_t *auth_reply;
13003b705cfSriastradh	xcb_screen_t *root;
13103b705cfSriastradh	xcb_connection_t *c = XGetXCBConnection(display);
13203b705cfSriastradh	drm_magic_t magic;
13303b705cfSriastradh	const xcb_query_extension_reply_t *dri2_reply;
13403b705cfSriastradh	char *device_name;
13503b705cfSriastradh	int len;
13603b705cfSriastradh
13703b705cfSriastradh	root = xcb_aux_get_screen(c, DefaultScreen(display));
13803b705cfSriastradh
13903b705cfSriastradh	dri2_reply = xcb_get_extension_data(c, &xcb_dri2_id);
14003b705cfSriastradh
14103b705cfSriastradh	if (!dri2_reply) {
14203b705cfSriastradh		XVMC_ERR("DRI2 required");
14303b705cfSriastradh		return BadValue;
14403b705cfSriastradh	}
14503b705cfSriastradh
14603b705cfSriastradh	/* Query the extension and make our first use of it at the same time. */
14703b705cfSriastradh	query_version_cookie = xcb_dri2_query_version(c, 1, 0);
14803b705cfSriastradh	connect_cookie = xcb_dri2_connect(c, root->root, DRI2DriverDRI);
14903b705cfSriastradh
15003b705cfSriastradh	query_version_reply =
15103b705cfSriastradh		xcb_dri2_query_version_reply(c, query_version_cookie, NULL);
15203b705cfSriastradh	connect_reply = xcb_dri2_connect_reply(c, connect_cookie, NULL);
15303b705cfSriastradh
15403b705cfSriastradh	if (!query_version_reply) {
15503b705cfSriastradh		XVMC_ERR("DRI2 required");
15603b705cfSriastradh		return BadValue;
15703b705cfSriastradh	}
15803b705cfSriastradh	free(query_version_reply);
15903b705cfSriastradh
16003b705cfSriastradh	len = xcb_dri2_connect_device_name_length(connect_reply);
16103b705cfSriastradh	device_name = malloc(len + 1);
16203b705cfSriastradh	if (!device_name) {
16303b705cfSriastradh		XVMC_ERR("malloc failure");
16403b705cfSriastradh		return BadAlloc;
16503b705cfSriastradh	}
16603b705cfSriastradh	strncpy(device_name, xcb_dri2_connect_device_name(connect_reply), len);
16703b705cfSriastradh	device_name[len] = 0;
16803b705cfSriastradh	xvmc_driver->fd = open(device_name, O_RDWR);
16903b705cfSriastradh	free(device_name);
17003b705cfSriastradh	free(connect_reply);
17103b705cfSriastradh	if (xvmc_driver->fd < 0) {
17203b705cfSriastradh		XVMC_ERR("Failed to open drm device: %s\n", strerror(errno));
17303b705cfSriastradh		return BadValue;
17403b705cfSriastradh	}
17503b705cfSriastradh
17603b705cfSriastradh	if (drmGetMagic(xvmc_driver->fd, &magic)) {
17703b705cfSriastradh		XVMC_ERR("Failed to get magic\n");
17803b705cfSriastradh		return BadValue;
17903b705cfSriastradh	}
18003b705cfSriastradh
18103b705cfSriastradh	auth_cookie = xcb_dri2_authenticate(c, root->root, magic);
18203b705cfSriastradh	auth_reply = xcb_dri2_authenticate_reply(c, auth_cookie, NULL);
18303b705cfSriastradh	if (!auth_reply) {
18403b705cfSriastradh		XVMC_ERR("Failed to authenticate magic %d\n", magic);
18503b705cfSriastradh		return BadValue;
18603b705cfSriastradh	}
18703b705cfSriastradh	free(auth_reply);
18803b705cfSriastradh
18903b705cfSriastradh	return Success;
19003b705cfSriastradh}
19103b705cfSriastradh
19203b705cfSriastradh/*
19303b705cfSriastradh* Function: XvMCCreateContext
19403b705cfSriastradh* Description: Create a XvMC context for the given surface parameters.
19503b705cfSriastradh* Arguments:
19603b705cfSriastradh*   display - Connection to the X server.
19703b705cfSriastradh*   port - XvPortID to use as avertised by the X connection.
19803b705cfSriastradh*   surface_type_id - Unique identifier for the Surface type.
19903b705cfSriastradh*   width - Width of the surfaces.
20003b705cfSriastradh*   height - Height of the surfaces.
20103b705cfSriastradh*   flags - one or more of the following
20203b705cfSriastradh*      XVMC_DIRECT - A direct rendered context is requested.
20303b705cfSriastradh*
20403b705cfSriastradh* Notes: surface_type_id and width/height parameters must match those
20503b705cfSriastradh*        returned by XvMCListSurfaceTypes.
20603b705cfSriastradh* Returns: Status
20703b705cfSriastradh*/
20803b705cfSriastradh_X_EXPORT Status XvMCCreateContext(Display * display, XvPortID port,
20903b705cfSriastradh				   int surface_type_id, int width, int height,
21003b705cfSriastradh				   int flags, XvMCContext * context)
21103b705cfSriastradh{
21203b705cfSriastradh	Status ret;
21303b705cfSriastradh	CARD32 *priv_data = NULL;
21403b705cfSriastradh	struct intel_xvmc_hw_context *comm;
21503b705cfSriastradh	int major, minor;
21603b705cfSriastradh	int error_base;
21703b705cfSriastradh	int event_base;
21803b705cfSriastradh	int priv_count;
21903b705cfSriastradh
22003b705cfSriastradh	/* Verify Obvious things first */
22103b705cfSriastradh	if (!display || !context)
22203b705cfSriastradh		return BadValue;
22303b705cfSriastradh
22403b705cfSriastradh	if (!(flags & XVMC_DIRECT)) {
22503b705cfSriastradh		XVMC_ERR("Indirect Rendering not supported! Using Direct.");
22603b705cfSriastradh		return BadValue;
22703b705cfSriastradh	}
22803b705cfSriastradh
22903b705cfSriastradh	/*
23003b705cfSriastradh	   Width, Height, and flags are checked against surface_type_id
23103b705cfSriastradh	   and port for validity inside the X server, no need to check
23203b705cfSriastradh	   here.
23303b705cfSriastradh	 */
23403b705cfSriastradh	context->surface_type_id = surface_type_id;
23503b705cfSriastradh	context->width = (unsigned short)((width + 15) & ~15);
23603b705cfSriastradh	context->height = (unsigned short)((height + 15) & ~15);
23703b705cfSriastradh	context->flags = flags;
23803b705cfSriastradh	context->port = port;
23903b705cfSriastradh
24003b705cfSriastradh	if (!XvMCQueryExtension(display, &event_base, &error_base)) {
24103b705cfSriastradh		XVMC_ERR("XvMCExtension is not available!");
24203b705cfSriastradh		return BadValue;
24303b705cfSriastradh	}
24403b705cfSriastradh
24503b705cfSriastradh	ret = XvMCQueryVersion(display, &major, &minor);
24603b705cfSriastradh	if (ret) {
24703b705cfSriastradh		XVMC_ERR
24803b705cfSriastradh		    ("XvMCQueryVersion Failed, unable to determine protocol version.");
24903b705cfSriastradh		return ret;
25003b705cfSriastradh	}
25103b705cfSriastradh
25203b705cfSriastradh	/* XXX: major and minor could be checked in future for XvMC
25303b705cfSriastradh	 * protocol capability (i.e H.264/AVC decode available)
25403b705cfSriastradh	 */
25503b705cfSriastradh
25603b705cfSriastradh	/*
25703b705cfSriastradh	   Pass control to the X server to create a drm_context_t for us and
25803b705cfSriastradh	   validate the with/height and flags.
25903b705cfSriastradh	 */
26003b705cfSriastradh	if ((ret =
26103b705cfSriastradh	     _xvmc_create_context(display, context, &priv_count, &priv_data))) {
26203b705cfSriastradh		XVMC_ERR("Unable to create XvMC Context.");
26303b705cfSriastradh		return ret;
26403b705cfSriastradh	}
26503b705cfSriastradh
26603b705cfSriastradh	comm = (struct intel_xvmc_hw_context *)priv_data;
26703b705cfSriastradh
26803b705cfSriastradh	if (xvmc_driver == NULL || xvmc_driver->type != comm->type) {
26903b705cfSriastradh		switch (comm->type) {
27003b705cfSriastradh		case XVMC_I915_MPEG2_MC:
27103b705cfSriastradh			xvmc_driver = &i915_xvmc_mc_driver;
27203b705cfSriastradh			break;
27303b705cfSriastradh		case XVMC_I965_MPEG2_MC:
27403b705cfSriastradh			xvmc_driver = &i965_xvmc_mc_driver;
27503b705cfSriastradh			break;
27603b705cfSriastradh		case XVMC_I965_MPEG2_VLD:
27703b705cfSriastradh			xvmc_driver = &xvmc_vld_driver;
27803b705cfSriastradh			break;
27903b705cfSriastradh		case XVMC_I945_MPEG2_VLD:
28003b705cfSriastradh		default:
28103b705cfSriastradh			XVMC_ERR("unimplemented xvmc type %d", comm->type);
28203b705cfSriastradh			XFree(priv_data);
28303b705cfSriastradh			priv_data = NULL;
28403b705cfSriastradh			return BadValue;
28503b705cfSriastradh		}
28603b705cfSriastradh	}
28703b705cfSriastradh
28803b705cfSriastradh	if (xvmc_driver == NULL || xvmc_driver->type != comm->type) {
28903b705cfSriastradh		XVMC_ERR("fail to load xvmc driver for type %d\n", comm->type);
29003b705cfSriastradh		return BadValue;
29103b705cfSriastradh	}
29203b705cfSriastradh
29303b705cfSriastradh	XVMC_INFO("decoder type is %s", intel_xvmc_decoder_string(comm->type));
29403b705cfSriastradh
29503b705cfSriastradh	/* check DRI2 */
29603b705cfSriastradh	ret = Success;
29703b705cfSriastradh	xvmc_driver->fd = -1;
29803b705cfSriastradh
29903b705cfSriastradh	ret = dri2_connect(display);
30003b705cfSriastradh	if (ret != Success) {
30103b705cfSriastradh		XFree(priv_data);
30203b705cfSriastradh		context->privData = NULL;
30303b705cfSriastradh		if (xvmc_driver->fd >= 0)
30403b705cfSriastradh			close(xvmc_driver->fd);
30503b705cfSriastradh		xvmc_driver = NULL;
30603b705cfSriastradh		return ret;
30703b705cfSriastradh	}
30803b705cfSriastradh
30903b705cfSriastradh	if ((xvmc_driver->bufmgr =
31003b705cfSriastradh	     intel_bufmgr_gem_init(xvmc_driver->fd, 1024 * 64)) == NULL) {
31103b705cfSriastradh		XVMC_ERR("Can't init bufmgr\n");
31203b705cfSriastradh		return BadAlloc;
31303b705cfSriastradh	}
31403b705cfSriastradh	drm_intel_bufmgr_gem_enable_reuse(xvmc_driver->bufmgr);
31503b705cfSriastradh
31603b705cfSriastradh	/* call driver hook.
31703b705cfSriastradh	 * driver hook should free priv_data after return if success.*/
31803b705cfSriastradh	ret =
31903b705cfSriastradh	    (xvmc_driver->create_context) (display, context, priv_count,
32003b705cfSriastradh					   priv_data);
32103b705cfSriastradh	if (ret) {
32203b705cfSriastradh		XVMC_ERR("driver create context failed\n");
32303b705cfSriastradh		XFree(priv_data);
32403b705cfSriastradh		context->privData = NULL;
32503b705cfSriastradh		xvmc_driver = NULL;
32603b705cfSriastradh		return ret;
32703b705cfSriastradh	}
32803b705cfSriastradh
32903b705cfSriastradh	pthread_mutex_init(&xvmc_driver->ctxmutex, NULL);
33003b705cfSriastradh	intelInitBatchBuffer();
33103b705cfSriastradh	intel_xvmc_dump_open();
33203b705cfSriastradh
33303b705cfSriastradh	return Success;
33403b705cfSriastradh}
33503b705cfSriastradh
33603b705cfSriastradh/*
33703b705cfSriastradh * Function: XvMCDestroyContext
33803b705cfSriastradh * Description: Destorys the specified context.
33903b705cfSriastradh *
34003b705cfSriastradh * Arguments:
34103b705cfSriastradh *   display - Specifies the connection to the server.
34203b705cfSriastradh *   context - The context to be destroyed.
34303b705cfSriastradh *
34403b705cfSriastradh */
34503b705cfSriastradh_X_EXPORT Status XvMCDestroyContext(Display * display, XvMCContext * context)
34603b705cfSriastradh{
34703b705cfSriastradh	Status ret;
34803b705cfSriastradh	int screen;
34903b705cfSriastradh
35003b705cfSriastradh	if (!display || !context)
35103b705cfSriastradh		return XvMCBadContext;
35203b705cfSriastradh	screen = DefaultScreen(display);
35303b705cfSriastradh	ret = (xvmc_driver->destroy_context) (display, context);
35403b705cfSriastradh	if (ret) {
35503b705cfSriastradh		XVMC_ERR("destroy context fail\n");
35603b705cfSriastradh		return ret;
35703b705cfSriastradh	}
35803b705cfSriastradh
35903b705cfSriastradh	intelFiniBatchBuffer();
36003b705cfSriastradh
36103b705cfSriastradh	dri_bufmgr_destroy(xvmc_driver->bufmgr);
36203b705cfSriastradh
36303b705cfSriastradh	ret = _xvmc_destroy_context(display, context);
36403b705cfSriastradh	if (ret != Success) {
36503b705cfSriastradh		XVMC_ERR("_xvmc_destroy_context fail\n");
36603b705cfSriastradh		return ret;
36703b705cfSriastradh	}
36803b705cfSriastradh
36903b705cfSriastradh	if (xvmc_driver->num_ctx == 0) {
37003b705cfSriastradh		pthread_mutex_destroy(&xvmc_driver->ctxmutex);
37103b705cfSriastradh
37203b705cfSriastradh		if (xvmc_driver->fd >= 0)
37303b705cfSriastradh			close(xvmc_driver->fd);
37403b705cfSriastradh
37503b705cfSriastradh		xvmc_driver->fd = -1;
37603b705cfSriastradh		intel_xvmc_dump_close();
37703b705cfSriastradh	}
37803b705cfSriastradh	return Success;
37903b705cfSriastradh}
38003b705cfSriastradh
38103b705cfSriastradh/*
38203b705cfSriastradh * Function: XvMCCreateSurface
38303b705cfSriastradh */
38403b705cfSriastradh_X_EXPORT Status XvMCCreateSurface(Display * display, XvMCContext * context,
38503b705cfSriastradh				   XvMCSurface * surface)
38603b705cfSriastradh{
38703b705cfSriastradh	Status ret;
38803b705cfSriastradh	int priv_count;
38903b705cfSriastradh	CARD32 *priv_data;
39003b705cfSriastradh	intel_xvmc_surface_ptr intel_surf = NULL;
39103b705cfSriastradh	struct intel_xvmc_context *intel_ctx;
39203b705cfSriastradh
39303b705cfSriastradh	if (!display || !context)
39403b705cfSriastradh		return XvMCBadContext;
39503b705cfSriastradh
39603b705cfSriastradh	if (!surface)
39703b705cfSriastradh		return XvMCBadSurface;
39803b705cfSriastradh
39903b705cfSriastradh	intel_ctx = context->privData;
40003b705cfSriastradh
40103b705cfSriastradh	if ((ret = _xvmc_create_surface(display, context, surface,
40203b705cfSriastradh					&priv_count, &priv_data))) {
40303b705cfSriastradh		XVMC_ERR("Unable to create XvMCSurface.");
40403b705cfSriastradh		return ret;
40503b705cfSriastradh	}
40603b705cfSriastradh
40703b705cfSriastradh	XFree(priv_data);
40803b705cfSriastradh
40903b705cfSriastradh	surface->privData = calloc(1, sizeof(struct intel_xvmc_surface));
41003b705cfSriastradh
41103b705cfSriastradh	if (!(intel_surf = surface->privData)) {
41203b705cfSriastradh		PPTHREAD_MUTEX_UNLOCK();
41303b705cfSriastradh		return BadAlloc;
41403b705cfSriastradh	}
41503b705cfSriastradh
41603b705cfSriastradh	intel_surf->bo = drm_intel_bo_alloc(xvmc_driver->bufmgr,
41703b705cfSriastradh					      "surface",
41803b705cfSriastradh					      intel_ctx->surface_bo_size,
41903b705cfSriastradh					      GTT_PAGE_SIZE);
42003b705cfSriastradh	if (!intel_surf->bo) {
42103b705cfSriastradh		free(intel_surf);
42203b705cfSriastradh		return BadAlloc;
42303b705cfSriastradh	}
42403b705cfSriastradh
42503b705cfSriastradh	drm_intel_bo_disable_reuse(intel_surf->bo);
42603b705cfSriastradh
42703b705cfSriastradh	intel_surf = surface->privData;
42803b705cfSriastradh	intel_surf->context = context;
42903b705cfSriastradh
43003b705cfSriastradh	intel_surf->image = XvCreateImage(display, context->port,
43103b705cfSriastradh					  FOURCC_XVMC,
43203b705cfSriastradh					  (char *) &intel_surf->gem_handle,
43303b705cfSriastradh					  surface->width, surface->height);
43403b705cfSriastradh	if (!intel_surf->image) {
43503b705cfSriastradh		XVMC_ERR("Can't create XvImage for surface\n");
43603b705cfSriastradh		free(intel_surf);
43703b705cfSriastradh		_xvmc_destroy_surface(display, surface);
43803b705cfSriastradh		return BadAlloc;
43903b705cfSriastradh	}
44003b705cfSriastradh
44103b705cfSriastradh	return Success;
44203b705cfSriastradh}
44303b705cfSriastradh
44403b705cfSriastradh/*
44503b705cfSriastradh * Function: XvMCDestroySurface
44603b705cfSriastradh */
44703b705cfSriastradh_X_EXPORT Status XvMCDestroySurface(Display * display, XvMCSurface * surface)
44803b705cfSriastradh{
44903b705cfSriastradh	intel_xvmc_surface_ptr intel_surf;
45003b705cfSriastradh
45103b705cfSriastradh	if (!display || !surface)
45203b705cfSriastradh		return XvMCBadSurface;
45303b705cfSriastradh
45403b705cfSriastradh	intel_surf = surface->privData;
45503b705cfSriastradh	if (!intel_surf)
45603b705cfSriastradh		return XvMCBadSurface;
45703b705cfSriastradh
45803b705cfSriastradh	XFree(intel_surf->image);
45903b705cfSriastradh	if (intel_surf->gc_init)
46003b705cfSriastradh		XFreeGC(display, intel_surf->gc);
46103b705cfSriastradh
46203b705cfSriastradh	drm_intel_bo_unreference(intel_surf->bo);
46303b705cfSriastradh
46403b705cfSriastradh	free(intel_surf);
46503b705cfSriastradh
46603b705cfSriastradh	_xvmc_destroy_surface(display, surface);
46703b705cfSriastradh
46803b705cfSriastradh	return Success;
46903b705cfSriastradh}
47003b705cfSriastradh
47103b705cfSriastradh/*
47203b705cfSriastradh * Function: XvMCCreateBlocks
47303b705cfSriastradh */
47403b705cfSriastradh_X_EXPORT Status XvMCCreateBlocks(Display * display, XvMCContext * context,
47503b705cfSriastradh				  unsigned int num_blocks,
47603b705cfSriastradh				  XvMCBlockArray * block)
47703b705cfSriastradh{
47803b705cfSriastradh	if (!display || !context || !num_blocks || !block)
47903b705cfSriastradh		return BadValue;
48003b705cfSriastradh
48103b705cfSriastradh	memset(block, 0, sizeof(XvMCBlockArray));
48203b705cfSriastradh
48303b705cfSriastradh	if (!
48403b705cfSriastradh	    (block->blocks =
48503b705cfSriastradh	     (short *)malloc((num_blocks << 6) * sizeof(short))))
48603b705cfSriastradh		return BadAlloc;
48703b705cfSriastradh
48803b705cfSriastradh	block->num_blocks = num_blocks;
48903b705cfSriastradh	block->context_id = context->context_id;
49003b705cfSriastradh	block->privData = NULL;
49103b705cfSriastradh
49203b705cfSriastradh	return Success;
49303b705cfSriastradh}
49403b705cfSriastradh
49503b705cfSriastradh/*
49603b705cfSriastradh * Function: XvMCDestroyBlocks
49703b705cfSriastradh */
49803b705cfSriastradh_X_EXPORT Status XvMCDestroyBlocks(Display * display, XvMCBlockArray * block)
49903b705cfSriastradh{
50003b705cfSriastradh	if (!display || !block)
50103b705cfSriastradh		return BadValue;
50203b705cfSriastradh
50303b705cfSriastradh	if (block->blocks)
50403b705cfSriastradh		free(block->blocks);
50503b705cfSriastradh
50603b705cfSriastradh	block->context_id = 0;
50703b705cfSriastradh	block->num_blocks = 0;
50803b705cfSriastradh	block->blocks = NULL;
50903b705cfSriastradh	block->privData = NULL;
51003b705cfSriastradh
51103b705cfSriastradh	return Success;
51203b705cfSriastradh}
51303b705cfSriastradh
51403b705cfSriastradh/*
51503b705cfSriastradh * Function: XvMCCreateMacroBlocks
51603b705cfSriastradh */
51703b705cfSriastradh_X_EXPORT Status XvMCCreateMacroBlocks(Display * display, XvMCContext * context,
51803b705cfSriastradh				       unsigned int num_blocks,
51903b705cfSriastradh				       XvMCMacroBlockArray * blocks)
52003b705cfSriastradh{
52103b705cfSriastradh	if (!display || !context || !blocks || !num_blocks)
52203b705cfSriastradh		return BadValue;
52303b705cfSriastradh
52403b705cfSriastradh	memset(blocks, 0, sizeof(XvMCMacroBlockArray));
52503b705cfSriastradh	blocks->macro_blocks =
52603b705cfSriastradh	    (XvMCMacroBlock *) malloc(num_blocks * sizeof(XvMCMacroBlock));
52703b705cfSriastradh
52803b705cfSriastradh	if (!blocks->macro_blocks)
52903b705cfSriastradh		return BadAlloc;
53003b705cfSriastradh
53103b705cfSriastradh	blocks->num_blocks = num_blocks;
53203b705cfSriastradh	blocks->context_id = context->context_id;
53303b705cfSriastradh	blocks->privData = NULL;
53403b705cfSriastradh
53503b705cfSriastradh	return Success;
53603b705cfSriastradh}
53703b705cfSriastradh
53803b705cfSriastradh/*
53903b705cfSriastradh * Function: XvMCDestroyMacroBlocks
54003b705cfSriastradh */
54103b705cfSriastradh_X_EXPORT Status XvMCDestroyMacroBlocks(Display * display,
54203b705cfSriastradh					XvMCMacroBlockArray * block)
54303b705cfSriastradh{
54403b705cfSriastradh	if (!display || !block)
54503b705cfSriastradh		return BadValue;
54603b705cfSriastradh	if (block->macro_blocks)
54703b705cfSriastradh		free(block->macro_blocks);
54803b705cfSriastradh
54903b705cfSriastradh	block->context_id = 0;
55003b705cfSriastradh	block->num_blocks = 0;
55103b705cfSriastradh	block->macro_blocks = NULL;
55203b705cfSriastradh	block->privData = NULL;
55303b705cfSriastradh
55403b705cfSriastradh	return Success;
55503b705cfSriastradh}
55603b705cfSriastradh
55703b705cfSriastradh/*
55803b705cfSriastradh * Function: XvMCRenderSurface
55903b705cfSriastradh *
56003b705cfSriastradh * Description: This function does the actual HWMC. Given a list of
56103b705cfSriastradh *  macroblock structures it dispatched the hardware commands to execute
56203b705cfSriastradh *  them.
56303b705cfSriastradh */
56403b705cfSriastradh_X_EXPORT Status XvMCRenderSurface(Display * display, XvMCContext * context,
56503b705cfSriastradh				   unsigned int picture_structure,
56603b705cfSriastradh				   XvMCSurface * target_surface,
56703b705cfSriastradh				   XvMCSurface * past_surface,
56803b705cfSriastradh				   XvMCSurface * future_surface,
56903b705cfSriastradh				   unsigned int flags,
57003b705cfSriastradh				   unsigned int num_macroblocks,
57103b705cfSriastradh				   unsigned int first_macroblock,
57203b705cfSriastradh				   XvMCMacroBlockArray * macroblock_array,
57303b705cfSriastradh				   XvMCBlockArray * blocks)
57403b705cfSriastradh{
57503b705cfSriastradh	Status ret;
57603b705cfSriastradh
57703b705cfSriastradh	if (!display || !context) {
57803b705cfSriastradh		XVMC_ERR("Invalid Display, Context or Target!");
57903b705cfSriastradh		return XvMCBadContext;
58003b705cfSriastradh	}
58103b705cfSriastradh	if (!target_surface)
58203b705cfSriastradh		return XvMCBadSurface;
58303b705cfSriastradh
58403b705cfSriastradh	intel_xvmc_dump_render(context, picture_structure, target_surface,
58503b705cfSriastradh			       past_surface, future_surface, flags,
58603b705cfSriastradh			       num_macroblocks, first_macroblock,
58703b705cfSriastradh			       macroblock_array, blocks);
58803b705cfSriastradh
58903b705cfSriastradh	ret =
59003b705cfSriastradh	    (xvmc_driver->render_surface) (display, context, picture_structure,
59103b705cfSriastradh					   target_surface, past_surface,
59203b705cfSriastradh					   future_surface, flags,
59303b705cfSriastradh					   num_macroblocks, first_macroblock,
59403b705cfSriastradh					   macroblock_array, blocks);
59503b705cfSriastradh
59603b705cfSriastradh	if (ret) {
59703b705cfSriastradh		XVMC_ERR("render surface fail\n");
59803b705cfSriastradh		return ret;
59903b705cfSriastradh	}
60003b705cfSriastradh	return Success;
60103b705cfSriastradh}
60203b705cfSriastradh
60303b705cfSriastradh/*
60403b705cfSriastradh * Function: XvMCPutSurface
60503b705cfSriastradh *
60603b705cfSriastradh * Description:
60703b705cfSriastradh * Arguments:
60803b705cfSriastradh *  display: Connection to X server
60903b705cfSriastradh *  surface: Surface to be displayed
61003b705cfSriastradh *  draw: X Drawable on which to display the surface
61103b705cfSriastradh *  srcx: X coordinate of the top left corner of the region to be
61203b705cfSriastradh *          displayed within the surface.
61303b705cfSriastradh *  srcy: Y coordinate of the top left corner of the region to be
61403b705cfSriastradh *          displayed within the surface.
61503b705cfSriastradh *  srcw: Width of the region to be displayed.
61603b705cfSriastradh *  srch: Height of the region to be displayed.
61703b705cfSriastradh *  destx: X cordinate of the top left corner of the destination region
61803b705cfSriastradh *         in the drawable coordinates.
61903b705cfSriastradh *  desty: Y cordinate of the top left corner of the destination region
62003b705cfSriastradh *         in the drawable coordinates.
62103b705cfSriastradh *  destw: Width of the destination region.
62203b705cfSriastradh *  desth: Height of the destination region.
62303b705cfSriastradh *  flags: One or more of the following.
62403b705cfSriastradh *	XVMC_TOP_FIELD - Display only the Top field of the surface.
62503b705cfSriastradh *	XVMC_BOTTOM_FIELD - Display only the Bottom Field of the surface.
62603b705cfSriastradh *	XVMC_FRAME_PICTURE - Display both fields or frame.
62703b705cfSriastradh */
62803b705cfSriastradh_X_EXPORT Status XvMCPutSurface(Display * display, XvMCSurface * surface,
62903b705cfSriastradh				Drawable draw, short srcx, short srcy,
63003b705cfSriastradh				unsigned short srcw, unsigned short srch,
63103b705cfSriastradh				short destx, short desty,
63203b705cfSriastradh				unsigned short destw, unsigned short desth,
63303b705cfSriastradh				int flags)
63403b705cfSriastradh{
63503b705cfSriastradh	Status ret = Success;
63603b705cfSriastradh	XvMCContext *context;
63703b705cfSriastradh	intel_xvmc_surface_ptr intel_surf;
63803b705cfSriastradh
63903b705cfSriastradh	if (!display || !surface)
64003b705cfSriastradh		return XvMCBadSurface;
64103b705cfSriastradh
64203b705cfSriastradh	intel_surf = surface->privData;
64303b705cfSriastradh	context = intel_surf->context;
64403b705cfSriastradh	if (!context || !intel_surf)
64503b705cfSriastradh		return XvMCBadSurface;
64603b705cfSriastradh
64703b705cfSriastradh	if (intel_surf->gc_init == FALSE) {
64803b705cfSriastradh		intel_surf->gc = XCreateGC(display, draw, 0, NULL);
64903b705cfSriastradh		intel_surf->gc_init = TRUE;
65003b705cfSriastradh	} else if (draw != intel_surf->last_draw) {
65103b705cfSriastradh		XFreeGC(display, intel_surf->gc);
65203b705cfSriastradh		intel_surf->gc = XCreateGC(display, draw, 0, NULL);
65303b705cfSriastradh	}
65403b705cfSriastradh	intel_surf->last_draw = draw;
65503b705cfSriastradh
65603b705cfSriastradh	drm_intel_bo_flink(intel_surf->bo, &intel_surf->gem_handle);
65703b705cfSriastradh
65803b705cfSriastradh	ret = XvPutImage(display, context->port, draw, intel_surf->gc,
65903b705cfSriastradh			 intel_surf->image, srcx, srcy, srcw, srch, destx,
66003b705cfSriastradh			 desty, destw, desth);
66103b705cfSriastradh	return ret;
66203b705cfSriastradh}
66303b705cfSriastradh
66403b705cfSriastradh/*
66503b705cfSriastradh * Function: XvMCSyncSurface
66603b705cfSriastradh * Arguments:
66703b705cfSriastradh *   display - Connection to the X server
66803b705cfSriastradh *   surface - The surface to synchronize
66903b705cfSriastradh */
67003b705cfSriastradh_X_EXPORT Status XvMCSyncSurface(Display * display, XvMCSurface * surface)
67103b705cfSriastradh{
67203b705cfSriastradh	if (!display || !surface)
67303b705cfSriastradh		return XvMCBadSurface;
67403b705cfSriastradh
67503b705cfSriastradh	return Success;
67603b705cfSriastradh}
67703b705cfSriastradh
67803b705cfSriastradh/*
67903b705cfSriastradh * Function: XvMCFlushSurface
68003b705cfSriastradh * Description:
68103b705cfSriastradh *   This function commits pending rendering requests to ensure that they
68203b705cfSriastradh *   wll be completed in a finite amount of time.
68303b705cfSriastradh * Arguments:
68403b705cfSriastradh *   display - Connection to X server
68503b705cfSriastradh *   surface - Surface to flush
68603b705cfSriastradh * Returns: Status
68703b705cfSriastradh */
68803b705cfSriastradh_X_EXPORT Status XvMCFlushSurface(Display * display, XvMCSurface * surface)
68903b705cfSriastradh{
69003b705cfSriastradh	if (!display || !surface)
69103b705cfSriastradh		return XvMCBadSurface;
69203b705cfSriastradh
69303b705cfSriastradh	return Success;
69403b705cfSriastradh}
69503b705cfSriastradh
69603b705cfSriastradh/*
69703b705cfSriastradh * Function: XvMCGetSurfaceStatus
69803b705cfSriastradh * Description:
69903b705cfSriastradh * Arguments:
70003b705cfSriastradh *  display: connection to X server
70103b705cfSriastradh *  surface: The surface to query
70203b705cfSriastradh *  stat: One of the Following
70303b705cfSriastradh *    XVMC_RENDERING - The last XvMCRenderSurface command has not
70403b705cfSriastradh *                     completed.
70503b705cfSriastradh *    XVMC_DISPLAYING - The surface is currently being displayed or a
70603b705cfSriastradh *                     display is pending.
70703b705cfSriastradh */
70803b705cfSriastradh_X_EXPORT Status XvMCGetSurfaceStatus(Display * display, XvMCSurface * surface,
70903b705cfSriastradh				      int *stat)
71003b705cfSriastradh{
71103b705cfSriastradh	if (!display || !surface || !stat)
71203b705cfSriastradh		return XvMCBadSurface;
71303b705cfSriastradh
71403b705cfSriastradh	*stat = 0;
71503b705cfSriastradh
71603b705cfSriastradh	return Success;
71703b705cfSriastradh}
71803b705cfSriastradh
71903b705cfSriastradh/*
72003b705cfSriastradh * Function: XvMCHideSurface
72103b705cfSriastradh * Description: Stops the display of a surface.
72203b705cfSriastradh * Arguments:
72303b705cfSriastradh *   display - Connection to the X server.
72403b705cfSriastradh *   surface - surface to be hidden.
72503b705cfSriastradh *
72603b705cfSriastradh * Returns: Status
72703b705cfSriastradh */
72803b705cfSriastradh_X_EXPORT Status XvMCHideSurface(Display * display, XvMCSurface * surface)
72903b705cfSriastradh{
73003b705cfSriastradh	if (!display || !surface)
73103b705cfSriastradh		return XvMCBadSurface;
73203b705cfSriastradh
73303b705cfSriastradh	return Success;
73403b705cfSriastradh}
73503b705cfSriastradh
73603b705cfSriastradh/*
73703b705cfSriastradh * Function: XvMCCreateSubpicture
73803b705cfSriastradh * Description: This creates a subpicture by filling out the XvMCSubpicture
73903b705cfSriastradh *              structure passed to it and returning Success.
74003b705cfSriastradh * Arguments:
74103b705cfSriastradh *   display - Connection to the X server.
74203b705cfSriastradh *   context - The context to create the subpicture for.
74303b705cfSriastradh *   subpicture - Pre-allocated XvMCSubpicture structure to be filled in.
74403b705cfSriastradh *   width - of subpicture
74503b705cfSriastradh *   height - of subpicture
74603b705cfSriastradh *   xvimage_id - The id describing the XvImage format.
74703b705cfSriastradh *
74803b705cfSriastradh * Returns: Status
74903b705cfSriastradh */
75003b705cfSriastradh_X_EXPORT Status XvMCCreateSubpicture(Display * display, XvMCContext * context,
75103b705cfSriastradh				      XvMCSubpicture * subpicture,
75203b705cfSriastradh				      unsigned short width,
75303b705cfSriastradh				      unsigned short height, int xvimage_id)
75403b705cfSriastradh{
75503b705cfSriastradh	XVMC_ERR("XvMCCreateSubpicture not implemented!\n");
75603b705cfSriastradh	return BadValue;
75703b705cfSriastradh}
75803b705cfSriastradh
75903b705cfSriastradh/*
76003b705cfSriastradh * Function: XvMCClearSubpicture
76103b705cfSriastradh * Description: Clear the area of the given subpicture to "color".
76203b705cfSriastradh *              structure passed to it and returning Success.
76303b705cfSriastradh * Arguments:
76403b705cfSriastradh *   display - Connection to the X server.
76503b705cfSriastradh *   subpicture - Subpicture to clear.
76603b705cfSriastradh *   x, y, width, height - rectangle in the subpicture to clear.
76703b705cfSriastradh *   color - The data to file the rectangle with.
76803b705cfSriastradh *
76903b705cfSriastradh * Returns: Status
77003b705cfSriastradh */
77103b705cfSriastradh_X_EXPORT Status XvMCClearSubpicture(Display * display,
77203b705cfSriastradh				     XvMCSubpicture * subpicture, short x,
77303b705cfSriastradh				     short y, unsigned short width,
77403b705cfSriastradh				     unsigned short height, unsigned int color)
77503b705cfSriastradh{
77603b705cfSriastradh	XVMC_ERR("XvMCClearSubpicture not implemented!");
77703b705cfSriastradh	return BadValue;
77803b705cfSriastradh}
77903b705cfSriastradh
78003b705cfSriastradh/*
78103b705cfSriastradh * Function: XvMCCompositeSubpicture
78203b705cfSriastradh * Description: Composite the XvImae on the subpicture. This composit uses
78303b705cfSriastradh *              non-premultiplied alpha. Destination alpha is utilized
78403b705cfSriastradh *              except for with indexed subpictures. Indexed subpictures
78503b705cfSriastradh *              use a simple "replace".
78603b705cfSriastradh * Arguments:
78703b705cfSriastradh *   display - Connection to the X server.
78803b705cfSriastradh *   subpicture - Subpicture to clear.
78903b705cfSriastradh *   image - the XvImage to be used as the source of the composite.
79003b705cfSriastradh *   srcx, srcy, width, height - The rectangle from the image to be used.
79103b705cfSriastradh *   dstx, dsty - location in the subpicture to composite the source.
79203b705cfSriastradh *
79303b705cfSriastradh * Returns: Status
79403b705cfSriastradh */
79503b705cfSriastradh_X_EXPORT Status XvMCCompositeSubpicture(Display * display,
79603b705cfSriastradh					 XvMCSubpicture * subpicture,
79703b705cfSriastradh					 XvImage * image, short srcx,
79803b705cfSriastradh					 short srcy, unsigned short width,
79903b705cfSriastradh					 unsigned short height, short dstx,
80003b705cfSriastradh					 short dsty)
80103b705cfSriastradh{
80203b705cfSriastradh	XVMC_ERR("XvMCCompositeSubpicture not implemented!");
80303b705cfSriastradh	return BadValue;
80403b705cfSriastradh}
80503b705cfSriastradh
80603b705cfSriastradh/*
80703b705cfSriastradh * Function: XvMCDestroySubpicture
80803b705cfSriastradh * Description: Destroys the specified subpicture.
80903b705cfSriastradh * Arguments:
81003b705cfSriastradh *   display - Connection to the X server.
81103b705cfSriastradh *   subpicture - Subpicture to be destroyed.
81203b705cfSriastradh *
81303b705cfSriastradh * Returns: Status
81403b705cfSriastradh */
81503b705cfSriastradh_X_EXPORT Status XvMCDestroySubpicture(Display * display,
81603b705cfSriastradh				       XvMCSubpicture * subpicture)
81703b705cfSriastradh{
81803b705cfSriastradh	XVMC_ERR("XvMCDestroySubpicture not implemented!");
81903b705cfSriastradh	return BadValue;
82003b705cfSriastradh}
82103b705cfSriastradh
82203b705cfSriastradh/*
82303b705cfSriastradh * Function: XvMCSetSubpicturePalette
82403b705cfSriastradh * Description: Set the subpictures palette
82503b705cfSriastradh * Arguments:
82603b705cfSriastradh *   display - Connection to the X server.
82703b705cfSriastradh *   subpicture - Subpiture to set palette for.
82803b705cfSriastradh *   palette - A pointer to an array holding the palette data. The array
82903b705cfSriastradh *     is num_palette_entries * entry_bytes in size.
83003b705cfSriastradh * Returns: Status
83103b705cfSriastradh */
83203b705cfSriastradh_X_EXPORT Status XvMCSetSubpicturePalette(Display * display,
83303b705cfSriastradh					  XvMCSubpicture * subpicture,
83403b705cfSriastradh					  unsigned char *palette)
83503b705cfSriastradh{
83603b705cfSriastradh	XVMC_ERR("XvMCSetSubpicturePalette not implemented!");
83703b705cfSriastradh	return BadValue;
83803b705cfSriastradh}
83903b705cfSriastradh
84003b705cfSriastradh/*
84103b705cfSriastradh * Function: XvMCBlendSubpicture
84203b705cfSriastradh * Description:
84303b705cfSriastradh *    The behavior of this function is different depending on whether
84403b705cfSriastradh *    or not the XVMC_BACKEND_SUBPICTURE flag is set in the XvMCSurfaceInfo.
84503b705cfSriastradh *    i915 only support frontend behavior.
84603b705cfSriastradh *
84703b705cfSriastradh *    XVMC_BACKEND_SUBPICTURE not set ("frontend" behavior):
84803b705cfSriastradh *
84903b705cfSriastradh *    XvMCBlendSubpicture is a no-op in this case.
85003b705cfSriastradh *
85103b705cfSriastradh * Arguments:
85203b705cfSriastradh *   display - Connection to the X server.
85303b705cfSriastradh *   subpicture - The subpicture to be blended into the video.
85403b705cfSriastradh *   target_surface - The surface to be displayed with the blended subpic.
85503b705cfSriastradh *   source_surface - Source surface prior to blending.
85603b705cfSriastradh *   subx, suby, subw, subh - The rectangle from the subpicture to use.
85703b705cfSriastradh *   surfx, surfy, surfw, surfh - The rectangle in the surface to blend
85803b705cfSriastradh *      blend the subpicture rectangle into. Scaling can ocure if
85903b705cfSriastradh *      XVMC_SUBPICTURE_INDEPENDENT_SCALING is set.
86003b705cfSriastradh *
86103b705cfSriastradh * Returns: Status
86203b705cfSriastradh */
86303b705cfSriastradh_X_EXPORT Status XvMCBlendSubpicture(Display * display,
86403b705cfSriastradh				     XvMCSurface * target_surface,
86503b705cfSriastradh				     XvMCSubpicture * subpicture, short subx,
86603b705cfSriastradh				     short suby, unsigned short subw,
86703b705cfSriastradh				     unsigned short subh, short surfx,
86803b705cfSriastradh				     short surfy, unsigned short surfw,
86903b705cfSriastradh				     unsigned short surfh)
87003b705cfSriastradh{
87103b705cfSriastradh	XVMC_ERR("XvMCBlendSubpicture not implemented!");
87203b705cfSriastradh	return BadValue;
87303b705cfSriastradh}
87403b705cfSriastradh
87503b705cfSriastradh/*
87603b705cfSriastradh * Function: XvMCBlendSubpicture2
87703b705cfSriastradh * Description:
87803b705cfSriastradh *    The behavior of this function is different depending on whether
87903b705cfSriastradh *    or not the XVMC_BACKEND_SUBPICTURE flag is set in the XvMCSurfaceInfo.
88003b705cfSriastradh *    i915 only supports frontend blending.
88103b705cfSriastradh *
88203b705cfSriastradh *    XVMC_BACKEND_SUBPICTURE not set ("frontend" behavior):
88303b705cfSriastradh *
88403b705cfSriastradh *    XvMCBlendSubpicture2 blends the source_surface and subpicture and
88503b705cfSriastradh *    puts it in the target_surface.  This does not effect the status of
88603b705cfSriastradh *    the source surface but will cause the target_surface to query
88703b705cfSriastradh *    XVMC_RENDERING until the blend is completed.
88803b705cfSriastradh *
88903b705cfSriastradh * Arguments:
89003b705cfSriastradh *   display - Connection to the X server.
89103b705cfSriastradh *   subpicture - The subpicture to be blended into the video.
89203b705cfSriastradh *   target_surface - The surface to be displayed with the blended subpic.
89303b705cfSriastradh *   source_surface - Source surface prior to blending.
89403b705cfSriastradh *   subx, suby, subw, subh - The rectangle from the subpicture to use.
89503b705cfSriastradh *   surfx, surfy, surfw, surfh - The rectangle in the surface to blend
89603b705cfSriastradh *      blend the subpicture rectangle into. Scaling can ocure if
89703b705cfSriastradh *      XVMC_SUBPICTURE_INDEPENDENT_SCALING is set.
89803b705cfSriastradh *
89903b705cfSriastradh * Returns: Status
90003b705cfSriastradh */
90103b705cfSriastradh_X_EXPORT Status XvMCBlendSubpicture2(Display * display,
90203b705cfSriastradh				      XvMCSurface * source_surface,
90303b705cfSriastradh				      XvMCSurface * target_surface,
90403b705cfSriastradh				      XvMCSubpicture * subpicture,
90503b705cfSriastradh				      short subx, short suby,
90603b705cfSriastradh				      unsigned short subw, unsigned short subh,
90703b705cfSriastradh				      short surfx, short surfy,
90803b705cfSriastradh				      unsigned short surfw,
90903b705cfSriastradh				      unsigned short surfh)
91003b705cfSriastradh{
91103b705cfSriastradh	XVMC_ERR("XvMCBlendSubpicture2 not implemented!");
91203b705cfSriastradh	return BadValue;
91303b705cfSriastradh}
91403b705cfSriastradh
91503b705cfSriastradh/*
91603b705cfSriastradh * Function: XvMCSyncSubpicture
91703b705cfSriastradh * Description: This function blocks until all composite/clear requests on
91803b705cfSriastradh *              the subpicture have been complete.
91903b705cfSriastradh * Arguments:
92003b705cfSriastradh *   display - Connection to the X server.
92103b705cfSriastradh *   subpicture - The subpicture to synchronize
92203b705cfSriastradh *
92303b705cfSriastradh * Returns: Status
92403b705cfSriastradh */
92503b705cfSriastradh_X_EXPORT Status XvMCSyncSubpicture(Display * display,
92603b705cfSriastradh				    XvMCSubpicture * subpicture)
92703b705cfSriastradh{
92803b705cfSriastradh	XVMC_ERR("XvMCSyncSubpicture not implemented!");
92903b705cfSriastradh	return BadValue;
93003b705cfSriastradh}
93103b705cfSriastradh
93203b705cfSriastradh/*
93303b705cfSriastradh * Function: XvMCFlushSubpicture
93403b705cfSriastradh * Description: This function commits pending composite/clear requests to
93503b705cfSriastradh *              ensure that they will be completed in a finite amount of
93603b705cfSriastradh *              time.
93703b705cfSriastradh * Arguments:
93803b705cfSriastradh *   display - Connection to the X server.
93903b705cfSriastradh *   subpicture - The subpicture whos compsiting should be flushed
94003b705cfSriastradh *
94103b705cfSriastradh * Returns: Status
94203b705cfSriastradh */
94303b705cfSriastradh_X_EXPORT Status XvMCFlushSubpicture(Display * display,
94403b705cfSriastradh				     XvMCSubpicture * subpicture)
94503b705cfSriastradh{
94603b705cfSriastradh	XVMC_ERR("XvMCFlushSubpicture not implemented!");
94703b705cfSriastradh	return BadValue;
94803b705cfSriastradh}
94903b705cfSriastradh
95003b705cfSriastradh/*
95103b705cfSriastradh * Function: XvMCGetSubpictureStatus
95203b705cfSriastradh * Description: This function gets the current status of a subpicture
95303b705cfSriastradh *
95403b705cfSriastradh * Arguments:
95503b705cfSriastradh *   display - Connection to the X server.
95603b705cfSriastradh *   subpicture - The subpicture whos status is being queried
95703b705cfSriastradh *   stat - The status of the subpicture. It can be any of the following
95803b705cfSriastradh *          OR'd together:
95903b705cfSriastradh *          XVMC_RENDERING  - Last composite or clear request not completed
96003b705cfSriastradh *          XVMC_DISPLAYING - Suppicture currently being displayed.
96103b705cfSriastradh *
96203b705cfSriastradh * Returns: Status
96303b705cfSriastradh */
96403b705cfSriastradh_X_EXPORT Status XvMCGetSubpictureStatus(Display * display,
96503b705cfSriastradh					 XvMCSubpicture * subpicture, int *stat)
96603b705cfSriastradh{
96703b705cfSriastradh	XVMC_ERR("XvMCGetSubpictureStatus not implemented!");
96803b705cfSriastradh	return BadValue;
96903b705cfSriastradh}
97003b705cfSriastradh
97103b705cfSriastradh/*
97203b705cfSriastradh * Function: XvMCQueryAttributes
97303b705cfSriastradh * Description: An array of XvAttributes of size "number" is returned by
97403b705cfSriastradh *   this function. If there are no attributes, NULL is returned and number
97503b705cfSriastradh *   is set to 0. The array may be freed with free().
97603b705cfSriastradh *
97703b705cfSriastradh * Arguments:
97803b705cfSriastradh *   display - Connection to the X server.
97903b705cfSriastradh *   context - The context whos attributes we are querying.
98003b705cfSriastradh *   number - The returned number of recognized atoms
98103b705cfSriastradh *
98203b705cfSriastradh * Returns:
98303b705cfSriastradh *  An array of XvAttributes.
98403b705cfSriastradh */
98503b705cfSriastradh_X_EXPORT XvAttribute *XvMCQueryAttributes(Display * display,
98603b705cfSriastradh					   XvMCContext * context, int *number)
98703b705cfSriastradh{
98803b705cfSriastradh	/* now XvMC has no extra attribs than Xv */
98903b705cfSriastradh	*number = 0;
99003b705cfSriastradh	return NULL;
99103b705cfSriastradh}
99203b705cfSriastradh
99303b705cfSriastradh/*
99403b705cfSriastradh * Function: XvMCSetAttribute
99503b705cfSriastradh * Description: This function sets a context-specific attribute.
99603b705cfSriastradh *
99703b705cfSriastradh * Arguments:
99803b705cfSriastradh *   display - Connection to the X server.
99903b705cfSriastradh *   context - The context whos attributes we are querying.
100003b705cfSriastradh *   attribute - The X atom of the attribute to be changed.
100103b705cfSriastradh *   value - The new value for the attribute.
100203b705cfSriastradh *
100303b705cfSriastradh * Returns:
100403b705cfSriastradh *  Status
100503b705cfSriastradh */
100603b705cfSriastradh_X_EXPORT Status XvMCSetAttribute(Display * display, XvMCContext * context,
100703b705cfSriastradh				  Atom attribute, int value)
100803b705cfSriastradh{
100903b705cfSriastradh	return Success;
101003b705cfSriastradh}
101103b705cfSriastradh
101203b705cfSriastradh/*
101303b705cfSriastradh * Function: XvMCGetAttribute
101403b705cfSriastradh * Description: This function queries a context-specific attribute and
101503b705cfSriastradh *   returns the value.
101603b705cfSriastradh *
101703b705cfSriastradh * Arguments:
101803b705cfSriastradh *   display - Connection to the X server.
101903b705cfSriastradh *   context - The context whos attributes we are querying.
102003b705cfSriastradh *   attribute - The X atom of the attribute to be queried
102103b705cfSriastradh *   value - The returned attribute value
102203b705cfSriastradh *
102303b705cfSriastradh * Returns:
102403b705cfSriastradh *  Status
102503b705cfSriastradh */
102603b705cfSriastradh_X_EXPORT Status XvMCGetAttribute(Display * display, XvMCContext * context,
102703b705cfSriastradh				  Atom attribute, int *value)
102803b705cfSriastradh{
102903b705cfSriastradh	return Success;
103003b705cfSriastradh}
103103b705cfSriastradh
103203b705cfSriastradh_X_EXPORT Status XvMCBeginSurface(Display * display, XvMCContext * context,
103303b705cfSriastradh				  XvMCSurface * target,
103403b705cfSriastradh				  XvMCSurface * past,
103503b705cfSriastradh				  XvMCSurface * future,
103603b705cfSriastradh				  const XvMCMpegControl * control)
103703b705cfSriastradh{
103803b705cfSriastradh	if (xvmc_driver->begin_surface(display, context,
103903b705cfSriastradh				       target, past, future, control)) {
104003b705cfSriastradh		XVMC_ERR("BeginSurface fail\n");
104103b705cfSriastradh		return BadValue;
104203b705cfSriastradh	}
104303b705cfSriastradh	return Success;
104403b705cfSriastradh}
104503b705cfSriastradh
104603b705cfSriastradh_X_EXPORT Status XvMCLoadQMatrix(Display * display, XvMCContext * context,
104703b705cfSriastradh				 const XvMCQMatrix * qmx)
104803b705cfSriastradh{
104903b705cfSriastradh	if (xvmc_driver->load_qmatrix(display, context, qmx)) {
105003b705cfSriastradh		XVMC_ERR("LoadQMatrix fail\n");
105103b705cfSriastradh		return BadValue;
105203b705cfSriastradh	}
105303b705cfSriastradh	return Success;
105403b705cfSriastradh}
105503b705cfSriastradh
105603b705cfSriastradh_X_EXPORT Status XvMCPutSlice(Display * display, XvMCContext * context,
105703b705cfSriastradh			      char *slice, int nbytes)
105803b705cfSriastradh{
105903b705cfSriastradh	if (xvmc_driver->put_slice(display, context, (unsigned char *) slice, nbytes)) {
106003b705cfSriastradh		XVMC_ERR("PutSlice fail\n");
106103b705cfSriastradh		return BadValue;
106203b705cfSriastradh	}
106303b705cfSriastradh	return Success;
106403b705cfSriastradh}
106503b705cfSriastradh
106603b705cfSriastradh_X_EXPORT Status XvMCPutSlice2(Display * display, XvMCContext * context,
106703b705cfSriastradh			       char *slice, int nbytes, int slice_code)
106803b705cfSriastradh{
106903b705cfSriastradh	if (xvmc_driver->put_slice2
107003b705cfSriastradh	    (display, context, (unsigned char *) slice, nbytes, slice_code)) {
107103b705cfSriastradh		XVMC_ERR("PutSlice2 fail\n");
107203b705cfSriastradh		return BadValue;
107303b705cfSriastradh	}
107403b705cfSriastradh	return Success;
107503b705cfSriastradh}
1076