psb_ctexture.c revision 2f768e2db3e4074a6e9a3d5f0f6e321233d96e4c
1/*
2 * INTEL CONFIDENTIAL
3 * Copyright 2007 Intel Corporation. All Rights Reserved.
4 * Copyright 2005-2007 Imagination Technologies Limited. All Rights Reserved.
5 *
6 * The source code contained or described herein and all documents related to
7 * the source code ("Material") are owned by Intel Corporation or its suppliers
8 * or licensors. Title to the Material remains with Intel Corporation or its
9 * suppliers and licensors. The Material may contain trade secrets and
10 * proprietary and confidential information of Intel Corporation and its
11 * suppliers and licensors, and is protected by worldwide copyright and trade
12 * secret laws and treaty provisions. No part of the Material may be used,
13 * copied, reproduced, modified, published, uploaded, posted, transmitted,
14 * distributed, or disclosed in any way without Intel's prior express written
15 * permission.
16 *
17 * No license under any patent, copyright, trade secret or other intellectual
18 * property right is granted to or conferred upon you by disclosure or delivery
19 * of the Materials, either expressly, by implication, inducement, estoppel or
20 * otherwise. Any license under such intellectual property rights must be
21 * express and approved by Intel in writing.
22 */
23
24#include <stdio.h>
25#include <math.h>
26
27#include <psb_drm.h>
28#include <va/va_backend.h>
29#include <va/va_dricommon.h>
30
31#include <wsbm/wsbm_manager.h>
32#include <X11/Xlib.h>
33#include <X11/X.h>
34
35#include "psb_drv_video.h"
36#include "psb_x11.h"
37#include "psb_output.h"
38#include "psb_xrandr.h"
39#include "psb_surface_ext.h"
40
41#include "psb_texture.h"
42
43#define INIT_DRIVER_DATA    psb_driver_data_p driver_data = (psb_driver_data_p) ctx->pDriverData;
44#define INIT_OUTPUT_PRIV    psb_x11_output_p output = (psb_x11_output_p)(((psb_driver_data_p)ctx->pDriverData)->ws_priv)
45
46#define SURFACE(id) ((object_surface_p) object_heap_lookup( &driver_data->surface_heap, id ))
47#define BUFFER(id)  ((object_buffer_p) object_heap_lookup( &driver_data->buffer_heap, id ))
48#define IMAGE(id)  ((object_image_p) object_heap_lookup( &driver_data->image_heap, id ))
49#define SUBPIC(id)  ((object_subpic_p) object_heap_lookup( &driver_data->subpic_heap, id ))
50#define CONTEXT(id) ((object_context_p) object_heap_lookup( &driver_data->context_heap, id ))
51
52static VAStatus psb_dri_init(VADriverContextP ctx, VASurfaceID surface, Drawable draw)
53{
54    INIT_DRIVER_DATA;
55    INIT_OUTPUT_PRIV;
56    int i, ret;
57
58    union dri_buffer *dri_buffer;
59    union dri_buffer *extend_dri_buffer;
60
61    PPVR2DMEMINFO dri2_bb_export_meminfo;
62
63    struct psb_texture_s *texture_priv = &driver_data->ctexture_priv;
64
65    if (psb_xrandr_extvideo_mode()) {
66
67	output->extend_drawable = (Window)psb_xrandr_create_full_screen_window();
68
69	texture_priv->extend_dri_drawable = dri_get_drawable(ctx, output->extend_drawable);
70	if (!texture_priv->extend_dri_drawable) {
71	    psb__error_message("%s(): Failed to get extend_dri_drawable\n", __func__);
72	    return VA_STATUS_ERROR_UNKNOWN;
73	}
74
75	extend_dri_buffer = dri_get_rendering_buffer(ctx, texture_priv->extend_dri_drawable);
76	if (!extend_dri_buffer) {
77	    psb__error_message("%s(): Failed to get extend_dri_buffer\n", __func__);
78	    return VA_STATUS_ERROR_UNKNOWN;
79	}
80
81	ret = PVR2DMemMap(texture_priv->hPVR2DContext, 0, (PVR2D_HANDLE)extend_dri_buffer->dri2.name, &dri2_bb_export_meminfo);
82	if (ret != PVR2D_OK) {
83	    psb__error_message("%s(): PVR2DMemMap failed, ret = %d\n", __func__, ret);
84	    return VA_STATUS_ERROR_UNKNOWN;
85	}
86
87	memcpy(&texture_priv->extend_dri2_bb_export, dri2_bb_export_meminfo->pBase, sizeof(PVRDRI2BackBuffersExport));
88
89	//must be Flip-Chain mode
90	for(i = 0; i < DRI2_BLIT_BUFFERS_NUM; i++) {
91	    ret = PVR2DMemMap(texture_priv->hPVR2DContext, 0, texture_priv->extend_dri2_bb_export.hBuffers[i], &texture_priv->extend_blt_meminfo[i]);
92	    if (ret != PVR2D_OK) {
93		psb__error_message("%s(): PVR2DMemMap failed, ret = %d\n", ret);
94		return VA_STATUS_ERROR_UNKNOWN;
95	    }
96	}
97    }
98
99    texture_priv->dri_drawable = dri_get_drawable(ctx, output->output_drawable);
100    if (!texture_priv->dri_drawable) {
101        psb__error_message("%s(): Failed to get dri_drawable\n", __func__);
102	return VA_STATUS_ERROR_UNKNOWN;
103    }
104
105    dri_buffer = dri_get_rendering_buffer(ctx, texture_priv->dri_drawable);
106    if (!dri_buffer) {
107        psb__error_message("%s(): Failed to get dri_buffer\n", __func__);
108	return VA_STATUS_ERROR_UNKNOWN;
109    }
110
111    ret = PVR2DMemMap(texture_priv->hPVR2DContext, 0, (PVR2D_HANDLE)dri_buffer->dri2.name, &dri2_bb_export_meminfo);
112    if (ret != PVR2D_OK) {
113	psb__error_message("%s(): PVR2DMemMap failed, ret = %d\n", __func__, ret);
114	return VA_STATUS_ERROR_UNKNOWN;
115    }
116
117    memcpy(&texture_priv->dri2_bb_export, dri2_bb_export_meminfo->pBase, sizeof(PVRDRI2BackBuffersExport));
118
119    if (texture_priv->dri2_bb_export.ui32Type == DRI2_BACK_BUFFER_EXPORT_TYPE_BUFFERS) {
120	psb__information_message("psb_dri_init: Now map buffer, DRI2 back buffer export type: DRI2_BACK_BUFFER_EXPORT_TYPE_BUFFERS\n");
121
122	for(i = 0; i < DRI2_BLIT_BUFFERS_NUM; i++) {
123	    ret = PVR2DMemMap(texture_priv->hPVR2DContext, 0, texture_priv->dri2_bb_export.hBuffers[i], &texture_priv->blt_meminfo[i]);
124	    if (ret != PVR2D_OK) {
125		psb__error_message("%s(): PVR2DMemMap failed, ret = %d\n", ret);
126		return VA_STATUS_ERROR_UNKNOWN;
127	    }
128	}
129    } else if (texture_priv->dri2_bb_export.ui32Type == DRI2_BACK_BUFFER_EXPORT_TYPE_SWAPCHAIN) {
130	psb__information_message("psb_dri_init: Now map buffer, DRI2 back buffer export type: DRI2_BACK_BUFFER_EXPORT_TYPE_SWAPCHAIN\n");
131
132	for(i = 0; i < DRI2_FLIP_BUFFERS_NUM; i++) {
133	    ret = PVR2DMemMap(texture_priv->hPVR2DContext, 0, texture_priv->dri2_bb_export.hBuffers[i], &texture_priv->flip_meminfo[i]);
134	    if (ret != PVR2D_OK) {
135		psb__error_message("%s(): PVR2DMemMap failed, ret = %d\n", ret);
136		return VA_STATUS_ERROR_UNKNOWN;
137	    }
138	}
139    }
140
141    texture_priv->dri_init_flag = 1;
142
143    PVR2DMemFree(texture_priv->hPVR2DContext, dri2_bb_export_meminfo);
144    return VA_STATUS_SUCCESS;
145}
146
147VAStatus psb_putsurface_ctexture(
148    VADriverContextP ctx,
149    VASurfaceID surface,
150    Drawable draw,
151    short srcx,
152    short srcy,
153    unsigned short srcw,
154    unsigned short srch,
155    short destx,
156    short desty,
157    unsigned short destw,
158    unsigned short desth,
159    unsigned int flags /* de-interlacing flags */
160)
161{
162    INIT_DRIVER_DATA;
163    INIT_OUTPUT_PRIV;
164    int ret;
165    int primary_crtc_x, primary_crtc_y, extend_crtc_x, extend_crtc_y;
166    int display_width, display_height, extend_display_width, extend_display_height;
167    psb_xrandr_location extend_location;
168    object_surface_p obj_surface = SURFACE(surface);
169    psb_surface_p psb_surface;
170
171    struct psb_texture_s *texture_priv = &driver_data->ctexture_priv;
172
173    obj_surface = SURFACE(surface);
174    psb_surface = obj_surface->psb_surface;
175
176    if (output->output_drawable != draw) {
177	output->output_drawable = draw;
178        ret = psb_xrandr_init(ctx);
179        if ( ret != 0) {
180	    psb__error_message("%s: Failed to initialize psb xrandr error # %d\n", __func__, ret);
181	    return VA_STATUS_ERROR_UNKNOWN;
182        }
183    }
184
185    if (driver_data->use_xrandr_thread && !driver_data->xrandr_thread_id) {
186        ret = psb_xrandr_thread_create(ctx);
187        if ( ret != 0) {
188	    psb__error_message("%s: Failed to create psb xrandr thread error # %d\n", __func__, ret);
189	    return VA_STATUS_ERROR_UNKNOWN;
190        }
191    }
192
193    if (!texture_priv->dri_init_flag) {
194	ret = psb_dri_init(ctx, surface, draw);
195	if (ret != VA_STATUS_SUCCESS)
196	    return VA_STATUS_ERROR_UNKNOWN;
197    }
198
199    if (psb_xrandr_clone_mode()) {
200	psb__information_message("psb_putsurface_ctexture: current mode is Clone\n");
201    } else if (psb_xrandr_extend_mode()) {
202	ret = psb_xrandr_primary_crtc_coordinate(&primary_crtc_x, &primary_crtc_y, &display_width, &display_height);
203	if (ret != 0) {
204	    psb__error_message("%s: Failed to get primary crtc coordinates error # %d\n", __func__, ret);
205	    return VA_STATUS_ERROR_UNKNOWN;
206	}
207	display_width += 1;
208	display_height += 1;
209
210	ret = psb_xrandr_extend_crtc_coordinate(&extend_crtc_x, &extend_crtc_y, &extend_display_width, &extend_display_height, &extend_location);
211	if (ret != 0) {
212	    psb__error_message("%s: Failed to get extend crtc coordinates error # %d\n", __func__, ret);
213	    return VA_STATUS_ERROR_UNKNOWN;
214	}
215	extend_display_width += 1;
216	extend_display_height += 1;
217
218	switch (extend_location) {
219	    case LEFT_OF:
220		display_height = display_height > extend_display_height ? display_height : extend_display_height;
221		if (destw > display_width + extend_display_width)
222		    destw = display_width + extend_display_width;
223		if (desth > display_height)
224		    desth = display_height;
225	    break;
226	    case RIGHT_OF:
227		display_height = display_height > extend_display_height ? display_height : extend_display_height;
228		if (destw > display_width + extend_display_width)
229		    destw = display_width + extend_display_width;
230		if (desth > display_height)
231		    desth = display_height;
232	    break;
233	    case BELOW:
234		display_width = display_width > extend_display_width ? display_width : extend_display_width;
235		if (destw > display_width)
236		    destw = display_width;
237		if (desth > display_height + extend_display_height)
238		    desth = display_height + extend_display_height;
239	    break;
240	    case ABOVE:
241		display_width = display_width > extend_display_width ? display_width : extend_display_width;
242		if (destw > display_width)
243		    destw = display_width;
244		if (desth > display_height + extend_display_height)
245		    desth = display_height + extend_display_height;
246	    break;
247	    case NORMAL:
248	    default:
249	    break;
250	}
251	psb__information_message("psb_putsurface_ctexture: current mode is Extend, Location: %08x\n", extend_location);
252    } else if (psb_xrandr_extvideo_mode()) {
253
254	psb__information_message("psb_putsurface_ctexture: current mode is ExtVideo, Location: %08x\n", extend_location);
255	ret = psb_xrandr_primary_crtc_coordinate(&primary_crtc_x, &primary_crtc_y, &display_width, &display_height);
256	if (ret != 0) {
257	    psb__error_message("%s: Failed to get primary crtc coordinates error # %d\n", __func__, ret);
258	    return VA_STATUS_ERROR_UNKNOWN;
259	}
260	display_width += 1;
261	display_height += 1;
262
263	ret = psb_xrandr_extend_crtc_coordinate(&extend_crtc_x, &extend_crtc_y, &extend_display_width, &extend_display_height, &extend_location);
264	if (ret != 0) {
265	    psb__error_message("%s: Failed to get extend crtc coordinates error # %d\n", __func__, ret);
266	    return VA_STATUS_ERROR_UNKNOWN;
267	}
268	extend_display_width += 1;
269	extend_display_height += 1;
270
271	psb__information_message("psb_putsurface_ctexture: ExtVideo coordinate: srcx= %d, srcy=%d, srcw=%d, srch=%d, destx=%d, desty=%d, destw=%d, desth=%d, cur_buffer=%d\n",
272				  srcx, srcy, srcw, srch, destx, desty, extend_display_width, extend_display_height, texture_priv->current_blt_buffer);
273
274	psb_putsurface_textureblit(ctx, texture_priv->extend_blt_meminfo[texture_priv->extend_current_blt_buffer], surface, srcx, srcy, srcw, srch, extend_crtc_x, extend_crtc_y,
275				extend_display_width, extend_display_height,
276				obj_surface->width, obj_surface->height,
277				psb_surface->stride, psb_surface->buf.drm_buf,
278				psb_surface->buf.pl_flags);
279
280	dri_swap_buffer(ctx, texture_priv->extend_dri_drawable);
281	texture_priv->extend_current_blt_buffer = (texture_priv->extend_current_blt_buffer + 1) & 0x01;
282     }
283
284    if (texture_priv->dri2_bb_export.ui32Type == DRI2_BACK_BUFFER_EXPORT_TYPE_BUFFERS) {
285	psb__information_message("psb_putsurface_ctexture: SWAP BUFFER, Video coordinate: srcx= %d, srcy=%d, srcw=%d, srch=%d, destx=%d, desty=%d, destw=%d, desth=%d, cur_buffer=%d\n",
286 				  srcx, srcy, srcw, srch, destx, desty, destw, desth, texture_priv->current_blt_buffer);
287	//FIXME: Currently using Extend Mode to simulate ExtVideo mode.
288	//When resolution >= 864x480, Extend video has a white line on top.
289	//When resolution >= 864x480, testsuite should create a window with maximum resolution of 864x480, but now it creates window based on the virtual frame buffer resolution.
290	//When ExtVideo driver is ready, double check the above 2 issue.
291	psb_putsurface_textureblit(ctx, texture_priv->blt_meminfo[texture_priv->current_blt_buffer], surface, srcx, srcy, srcw, srch, destx, desty, destw, desth,
292				obj_surface->width, obj_surface->height,
293				psb_surface->stride, psb_surface->buf.drm_buf,
294				psb_surface->buf.pl_flags);
295
296	dri_swap_buffer(ctx, texture_priv->dri_drawable);
297	texture_priv->current_blt_buffer = (texture_priv->current_blt_buffer + 1) & 0x01;
298
299    } else if (texture_priv->dri2_bb_export.ui32Type == DRI2_BACK_BUFFER_EXPORT_TYPE_SWAPCHAIN) {
300	psb__information_message("psb_putsurface_ctexture: FLIP CHAIN, Video coordinate: srcx= %d, srcy=%d, srcw=%d, srch=%d, destx=%d, desty=%d, destw=%d, desth=%d, cur_buffer=%d\n",
301 				  srcx, srcy, srcw, srch, destx, desty, texture_priv->rootwin_width, texture_priv->rootwin_height, texture_priv->current_blt_buffer);
302
303	psb_putsurface_textureblit(ctx, texture_priv->flip_meminfo[texture_priv->current_blt_buffer], surface, srcx, srcy, srcw, srch, destx, desty, texture_priv->rootwin_width, texture_priv->rootwin_height,
304				obj_surface->width, obj_surface->height,
305				psb_surface->stride, psb_surface->buf.drm_buf,
306				psb_surface->buf.pl_flags);
307
308	dri_swap_buffer(ctx, texture_priv->dri_drawable);
309	texture_priv->current_blt_buffer++;
310	if(texture_priv->current_blt_buffer == DRI2_FLIP_BUFFERS_NUM)
311	    texture_priv->current_blt_buffer = 0;
312    }
313
314    return VA_STATUS_SUCCESS;
315}
316