source: trunk/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwswsegl.c

Last change on this file was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

  • Property svn:eol-style set to native
File size: 13.3 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation (qt-info@nokia.com)
6**
7** This file is part of the plugins of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at qt-info@nokia.com.
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include <GLES/egltypes.h>
43#include <wsegl.h>
44#include <pvr2d.h>
45#include <string.h>
46#include <sys/mman.h>
47#include "pvrqwsdrawable_p.h"
48
49#define WSEGL_UNUSED(x) (void)x;
50
51// If the PVR2D version is not specified, then assume MBX-style headers.
52// If the version is defined, then we assume that we have SGX-style headers.
53#if !defined(PVR2D_REV_MAJOR)
54#define WSEGL_CAP_WINDOWS_USE_HW_SYNC WSEGL_CAP_WINDOWS_USE_MBX_SYNC
55#define WSEGL_CAP_PIXMAPS_USE_HW_SYNC WSEGL_CAP_PIXMAPS_USE_MBX_SYNC
56#endif
57
58/* Capability information for the display */
59static WSEGLCaps const wseglDisplayCaps[] = {
60 {WSEGL_CAP_WINDOWS_USE_HW_SYNC, 1},
61 {WSEGL_CAP_PIXMAPS_USE_HW_SYNC, 1},
62 {WSEGL_NO_CAPS, 0}
63};
64
65/* Configuration information for the display */
66static WSEGLConfig wseglDisplayConfigs[] = {
67 {WSEGL_DRAWABLE_WINDOW, WSEGL_PIXELFORMAT_565, WSEGL_FALSE,
68 0, 0, 0, WSEGL_OPAQUE, 0},
69 {WSEGL_DRAWABLE_PIXMAP, WSEGL_PIXELFORMAT_565, WSEGL_FALSE,
70 0, 0, 0, WSEGL_OPAQUE, 0},
71 {WSEGL_NO_DRAWABLE, 0, 0, 0, 0, 0, 0, 0}
72};
73
74/* Determine if nativeDisplay is a valid display handle */
75static WSEGLError wseglIsDisplayValid(NativeDisplayType nativeDisplay)
76{
77 /* We only have the default display in this system */
78 if (nativeDisplay == WSEGL_DEFAULT_DISPLAY)
79 return WSEGL_SUCCESS;
80 else
81 return WSEGL_BAD_NATIVE_DISPLAY;
82}
83
84/* Initialize a native display for use with WSEGL */
85static WSEGLError wseglInitializeDisplay
86 (NativeDisplayType nativeDisplay, WSEGLDisplayHandle *display,
87 const WSEGLCaps **caps, WSEGLConfig **configs)
88{
89 WSEGLPixelFormat pixelFormat;
90
91 /* Bail out if the native display is incorrect */
92 if (nativeDisplay != WSEGL_DEFAULT_DISPLAY)
93 return WSEGL_CANNOT_INITIALISE;
94
95 /* Open the PVR/QWS display, which will initialize the framebuffer */
96 if (!pvrQwsDisplayOpen())
97 return WSEGL_CANNOT_INITIALISE;
98
99 /* Convert the PVR2D pixel format into a WSEGL pixel format */
100 switch (pvrQwsDisplay.screens[0].pixelFormat) {
101 case PVR2D_RGB565:
102 pixelFormat = WSEGL_PIXELFORMAT_565;
103 break;
104
105 case PVR2D_ARGB4444:
106 pixelFormat = WSEGL_PIXELFORMAT_4444;
107 break;
108
109 case PVR2D_ARGB8888:
110 pixelFormat = WSEGL_PIXELFORMAT_8888;
111 break;
112
113 default:
114 pvrQwsDisplayClose();
115 return WSEGL_CANNOT_INITIALISE;
116 }
117 wseglDisplayConfigs[0].ePixelFormat = pixelFormat;
118 wseglDisplayConfigs[1].ePixelFormat = pixelFormat;
119
120 /* The display has been initialized */
121 *display = (WSEGLDisplayHandle)&pvrQwsDisplay;
122 *caps = wseglDisplayCaps;
123 *configs = wseglDisplayConfigs;
124 return WSEGL_SUCCESS;
125}
126
127/* Close the WSEGL display */
128static WSEGLError wseglCloseDisplay(WSEGLDisplayHandle display)
129{
130 if (display == (WSEGLDisplayHandle)&pvrQwsDisplay)
131 pvrQwsDisplayClose();
132 return WSEGL_SUCCESS;
133}
134
135static WSEGLRotationAngle wseglRotationValue(int degrees)
136{
137 switch (degrees) {
138 case 90: return WSEGL_ROTATE_90;
139 case 180: return WSEGL_ROTATE_180;
140 case 270: return WSEGL_ROTATE_270;
141 default: return WSEGL_ROTATE_0;
142 }
143}
144
145/* Create the WSEGL drawable version of a native window */
146static WSEGLError wseglCreateWindowDrawable
147 (WSEGLDisplayHandle display, WSEGLConfig *config,
148 WSEGLDrawableHandle *drawable, NativeWindowType nativeWindow,
149 WSEGLRotationAngle *rotationAngle)
150{
151 PvrQwsDrawable *draw;
152
153 WSEGL_UNUSED(display);
154 WSEGL_UNUSED(config);
155
156 /* Check for special handles that indicate framebuffer screens */
157 if (nativeWindow >= (NativeWindowType)0 &&
158 nativeWindow < (NativeWindowType)PVRQWS_MAX_SCREENS) {
159 PvrQwsDrawable *screen = pvrQwsScreenWindow((int)nativeWindow);
160 if (!screen)
161 return WSEGL_OUT_OF_MEMORY;
162 *drawable = (WSEGLDrawableHandle)screen;
163 if (!pvrQwsAllocBuffers(screen))
164 return WSEGL_OUT_OF_MEMORY;
165 *rotationAngle = wseglRotationValue(screen->rotationAngle);
166 return WSEGL_SUCCESS;
167 }
168
169 /* The native window is the winId - fetch the underlying drawable */
170 draw = pvrQwsFetchWindow((long)nativeWindow);
171 if (!draw)
172 return WSEGL_BAD_DRAWABLE;
173
174 /* The drawable is ready to go */
175 *drawable = (WSEGLDrawableHandle)draw;
176 *rotationAngle = wseglRotationValue(draw->rotationAngle);
177 if (!pvrQwsAllocBuffers(draw))
178 return WSEGL_OUT_OF_MEMORY;
179 return WSEGL_SUCCESS;
180}
181
182/* Create the WSEGL drawable version of a native pixmap */
183static WSEGLError wseglCreatePixmapDrawable
184 (WSEGLDisplayHandle display, WSEGLConfig *config,
185 WSEGLDrawableHandle *drawable, NativePixmapType nativePixmap,
186 WSEGLRotationAngle *rotationAngle)
187{
188 WSEGL_UNUSED(display);
189 WSEGL_UNUSED(config);
190 if (!nativePixmap)
191 return WSEGL_BAD_NATIVE_PIXMAP;
192 if (!pvrQwsAllocBuffers((PvrQwsDrawable *)nativePixmap))
193 return WSEGL_OUT_OF_MEMORY;
194 *drawable = (WSEGLDrawableHandle)nativePixmap;
195 *rotationAngle = WSEGL_ROTATE_0;
196 return WSEGL_SUCCESS;
197}
198
199/* Delete a specific drawable */
200static WSEGLError wseglDeleteDrawable(WSEGLDrawableHandle _drawable)
201{
202 PvrQwsDrawable *drawable = (PvrQwsDrawable *)_drawable;
203 if (!drawable || drawable->type == PvrQwsScreen)
204 return WSEGL_SUCCESS;
205 pvrQwsFreeBuffers(drawable);
206 if (pvrQwsReleaseWindow(drawable))
207 pvrQwsDestroyDrawable(drawable);
208 return WSEGL_SUCCESS;
209}
210
211/* Swap the contents of a drawable to the screen */
212static WSEGLError wseglSwapDrawable
213 (WSEGLDrawableHandle _drawable, unsigned long data)
214{
215 WSEGL_UNUSED(data);
216 PvrQwsDrawable *drawable = (PvrQwsDrawable *)_drawable;
217 if (drawable->type != PvrQwsPixmap && !pvrQwsSwapBuffers(drawable, 0))
218 return WSEGL_BAD_DRAWABLE;
219 else
220 return WSEGL_SUCCESS;
221}
222
223/* Set the swap interval of a window drawable */
224static WSEGLError wseglSwapControlInterval
225 (WSEGLDrawableHandle drawable, unsigned long interval)
226{
227 WSEGL_UNUSED(drawable);
228 if (pvrQwsDisplay.flipChain) {
229 PVR2DSetPresentFlipProperties
230 (pvrQwsDisplay.context, pvrQwsDisplay.flipChain,
231 PVR2D_PRESENT_PROPERTY_INTERVAL, 0, 0, 0, NULL, interval);
232 }
233 return WSEGL_SUCCESS;
234}
235
236/* Flush native rendering requests on a drawable */
237static WSEGLError wseglWaitNative
238 (WSEGLDrawableHandle drawable, unsigned long engine)
239{
240 WSEGL_UNUSED(drawable);
241 if (engine == WSEGL_DEFAULT_NATIVE_ENGINE)
242 return WSEGL_SUCCESS;
243 else
244 return WSEGL_BAD_NATIVE_ENGINE;
245}
246
247/* Copy color data from a drawable to a native pixmap */
248static WSEGLError wseglCopyFromDrawable
249 (WSEGLDrawableHandle _drawable, NativePixmapType nativePixmap)
250{
251 PvrQwsDrawable *drawable = (PvrQwsDrawable *)_drawable;
252 PvrQwsDrawable *pixmap = (PvrQwsDrawable *)nativePixmap;
253 PVR2DBLTINFO blit;
254
255 if (!drawable || !drawable->backBuffersValid)
256 return WSEGL_BAD_NATIVE_WINDOW;
257 if (!pixmap || !pixmap->backBuffersValid)
258 return WSEGL_BAD_NATIVE_PIXMAP;
259
260 memset(&blit, 0, sizeof(blit));
261
262 blit.CopyCode = PVR2DROPcopy;
263 blit.BlitFlags = PVR2D_BLIT_DISABLE_ALL;
264
265 blit.pSrcMemInfo = drawable->backBuffers[drawable->currentBackBuffer];
266 blit.SrcStride = drawable->strideBytes;
267 blit.SrcX = 0;
268 blit.SrcY = 0;
269 blit.SizeX = drawable->rect.width;
270 blit.SizeY = drawable->rect.height;
271 blit.SrcFormat = drawable->pixelFormat;
272
273 blit.pDstMemInfo = pixmap->backBuffers[pixmap->currentBackBuffer];
274 blit.DstStride = pixmap->strideBytes;
275 blit.DstX = 0;
276 blit.DstY = 0;
277 blit.DSizeX = pixmap->rect.width;
278 blit.DSizeY = pixmap->rect.height;
279 blit.DstFormat = pixmap->pixelFormat;
280
281 PVR2DBlt(pvrQwsDisplay.context, &blit);
282 PVR2DQueryBlitsComplete
283 (pvrQwsDisplay.context, pixmap->backBuffers[pixmap->currentBackBuffer], 1);
284
285 return WSEGL_SUCCESS;
286}
287
288/* Copy color data from a PBuffer to a native pixmap */
289static WSEGLError wseglCopyFromPBuffer
290 (void *address, unsigned long width, unsigned long height,
291 unsigned long stride, WSEGLPixelFormat format,
292 NativePixmapType nativePixmap)
293{
294 PvrQwsDrawable *pixmap = (PvrQwsDrawable *)nativePixmap;
295 PVR2DFORMAT pixelFormat;
296
297 if (!pixmap)
298 return WSEGL_BAD_NATIVE_PIXMAP;
299
300 /* We can only copy under certain conditions */
301 switch (format) {
302 case WSEGL_PIXELFORMAT_565:
303 pixelFormat = PVR2D_RGB565; break;
304 case WSEGL_PIXELFORMAT_4444:
305 pixelFormat = PVR2D_ARGB4444; break;
306 case WSEGL_PIXELFORMAT_8888:
307 pixelFormat = PVR2D_ARGB8888; break;
308 default:
309 return WSEGL_BAD_CONFIG;
310 }
311 if (width > (unsigned long)(pixmap->rect.width) ||
312 height > (unsigned long)(pixmap->rect.height) ||
313 pixelFormat != pixmap->pixelFormat) {
314 return WSEGL_BAD_CONFIG;
315 }
316
317 /* We'd like to use PVR2DBlt to do this, but there is no easy way
318 to map the virtual "address" into physical space to be able
319 to use the hardware assist. Use memcpy to do the work instead.
320 Note: PBuffer's are upside down, so we copy from the bottom up */
321 char *srcaddr = (char *)address;
322 char *dstaddr = (char *)(pixmap->backBuffers[pixmap->currentBackBuffer]->pBase);
323 int dststride = pixmap->strideBytes;
324 int srcwidth = ((int)width) * pvrQwsDisplay.screens[0].bytesPerPixel;
325 srcaddr += height * stride;
326 while (height > 0) {
327 srcaddr -= (int)stride;
328 memcpy(dstaddr, srcaddr, srcwidth);
329 dstaddr += dststride;
330 --height;
331 }
332 return WSEGL_SUCCESS;
333}
334
335/* Return the parameters of a drawable that are needed by the EGL layer */
336static WSEGLError wseglGetDrawableParameters
337 (WSEGLDrawableHandle _drawable, WSEGLDrawableParams *sourceParams,
338 WSEGLDrawableParams *renderParams)
339{
340 PvrQwsDrawable *drawable = (PvrQwsDrawable *)_drawable;
341 PVR2DMEMINFO *source, *render;
342 WSEGLPixelFormat pixelFormat;
343
344 if (!pvrQwsGetBuffers(drawable, &source, &render))
345 return WSEGL_BAD_DRAWABLE;
346
347 switch (drawable->pixelFormat) {
348 case PVR2D_RGB565:
349 default:
350 pixelFormat = WSEGL_PIXELFORMAT_565;
351 break;
352
353 case PVR2D_ARGB4444:
354 pixelFormat = WSEGL_PIXELFORMAT_4444;
355 break;
356
357 case PVR2D_ARGB8888:
358 pixelFormat = WSEGL_PIXELFORMAT_8888;
359 break;
360 }
361
362 sourceParams->ui32Width = drawable->rect.width;
363 sourceParams->ui32Height = drawable->rect.height;
364 sourceParams->ui32Stride = drawable->stridePixels;
365 sourceParams->ePixelFormat = pixelFormat;
366 sourceParams->pvLinearAddress = source->pBase;
367 sourceParams->ui32HWAddress = source->ui32DevAddr;
368 sourceParams->hPrivateData = source->hPrivateData;
369
370 renderParams->ui32Width = drawable->rect.width;
371 renderParams->ui32Height = drawable->rect.height;
372 renderParams->ui32Stride = drawable->stridePixels;
373 renderParams->ePixelFormat = pixelFormat;
374 renderParams->pvLinearAddress = render->pBase;
375 renderParams->ui32HWAddress = render->ui32DevAddr;
376 renderParams->hPrivateData = render->hPrivateData;
377
378 return WSEGL_SUCCESS;
379}
380
381static WSEGL_FunctionTable const wseglFunctions = {
382 WSEGL_VERSION,
383 wseglIsDisplayValid,
384 wseglInitializeDisplay,
385 wseglCloseDisplay,
386 wseglCreateWindowDrawable,
387 wseglCreatePixmapDrawable,
388 wseglDeleteDrawable,
389 wseglSwapDrawable,
390 wseglSwapControlInterval,
391 wseglWaitNative,
392 wseglCopyFromDrawable,
393 wseglCopyFromPBuffer,
394 wseglGetDrawableParameters
395};
396
397/* Return the table of WSEGL functions to the EGL implementation */
398const WSEGL_FunctionTable *WSEGL_GetFunctionTablePointer(void)
399{
400 return &wseglFunctions;
401}
Note: See TracBrowser for help on using the repository browser.