Qt 4.8
pvrqwswsegl.c
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the plugins of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include <GLES/eglplatform.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 */
59 static WSEGLCaps const wseglDisplayCaps[] = {
62  {WSEGL_NO_CAPS, 0}
63 };
64 
65 /* Configuration information for the display */
66 static 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 */
75 static 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 */
85 static 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:
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 */
128 static WSEGLError wseglCloseDisplay(WSEGLDisplayHandle display)
129 {
130  if (display == (WSEGLDisplayHandle)&pvrQwsDisplay)
132  return WSEGL_SUCCESS;
133 }
134 
135 static 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 */
146 static 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 */
183 static 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 */
200 static WSEGLError wseglDeleteDrawable(WSEGLDrawableHandle _drawable)
201 {
202  PvrQwsDrawable *drawable = (PvrQwsDrawable *)_drawable;
203  if (!drawable || drawable->type == PvrQwsScreen)
204  return WSEGL_SUCCESS;
205  if (pvrQwsDisplay.numFlipBuffers == 0)
206  pvrQwsFreeBuffers(drawable);
207  if (pvrQwsReleaseWindow(drawable))
208  pvrQwsDestroyDrawable(drawable);
209  return WSEGL_SUCCESS;
210 }
211 
212 /* Swap the contents of a drawable to the screen */
213 static WSEGLError wseglSwapDrawable
214  (WSEGLDrawableHandle _drawable, unsigned long data)
215 {
216  WSEGL_UNUSED(data);
217  PvrQwsDrawable *drawable = (PvrQwsDrawable *)_drawable;
218  if (drawable->type != PvrQwsPixmap && !pvrQwsSwapBuffers(drawable, 0))
219  return WSEGL_BAD_DRAWABLE;
220  else
221  return WSEGL_SUCCESS;
222 }
223 
224 /* Set the swap interval of a window drawable */
225 static WSEGLError wseglSwapControlInterval
226  (WSEGLDrawableHandle drawable, unsigned long interval)
227 {
228  WSEGL_UNUSED(drawable);
229  if (pvrQwsDisplay.flipChain) {
230  PVR2DSetPresentFlipProperties
232  PVR2D_PRESENT_PROPERTY_INTERVAL, 0, 0, 0, NULL, interval);
233  }
234  return WSEGL_SUCCESS;
235 }
236 
237 /* Flush native rendering requests on a drawable */
238 static WSEGLError wseglWaitNative
239  (WSEGLDrawableHandle drawable, unsigned long engine)
240 {
241  WSEGL_UNUSED(drawable);
242  if (engine == WSEGL_DEFAULT_NATIVE_ENGINE)
243  return WSEGL_SUCCESS;
244  else
245  return WSEGL_BAD_NATIVE_ENGINE;
246 }
247 
248 /* Copy color data from a drawable to a native pixmap */
249 static WSEGLError wseglCopyFromDrawable
250  (WSEGLDrawableHandle _drawable, NativePixmapType nativePixmap)
251 {
252  PvrQwsDrawable *drawable = (PvrQwsDrawable *)_drawable;
253  PvrQwsDrawable *pixmap = (PvrQwsDrawable *)nativePixmap;
254  PVR2DBLTINFO blit;
255 
256  if (!drawable || !drawable->backBuffersValid)
257  return WSEGL_BAD_NATIVE_WINDOW;
258  if (!pixmap || !pixmap->backBuffersValid)
259  return WSEGL_BAD_NATIVE_PIXMAP;
260 
261  memset(&blit, 0, sizeof(blit));
262 
263  blit.CopyCode = PVR2DROPcopy;
264  blit.BlitFlags = PVR2D_BLIT_DISABLE_ALL;
265 
266  blit.pSrcMemInfo = drawable->backBuffers[drawable->currentBackBuffer];
267  blit.SrcStride = drawable->strideBytes;
268  blit.SrcX = 0;
269  blit.SrcY = 0;
270  blit.SizeX = drawable->rect.width;
271  blit.SizeY = drawable->rect.height;
272  blit.SrcFormat = drawable->pixelFormat;
273 
274  blit.pDstMemInfo = pixmap->backBuffers[pixmap->currentBackBuffer];
275  blit.DstStride = pixmap->strideBytes;
276  blit.DstX = 0;
277  blit.DstY = 0;
278  blit.DSizeX = pixmap->rect.width;
279  blit.DSizeY = pixmap->rect.height;
280  blit.DstFormat = pixmap->pixelFormat;
281 
282  PVR2DBlt(pvrQwsDisplay.context, &blit);
283  PVR2DQueryBlitsComplete
284  (pvrQwsDisplay.context, pixmap->backBuffers[pixmap->currentBackBuffer], 1);
285 
286  return WSEGL_SUCCESS;
287 }
288 
289 /* Copy color data from a PBuffer to a native pixmap */
290 static WSEGLError wseglCopyFromPBuffer
291  (void *address, unsigned long width, unsigned long height,
292  unsigned long stride, WSEGLPixelFormat format,
293  NativePixmapType nativePixmap)
294 {
295  PvrQwsDrawable *pixmap = (PvrQwsDrawable *)nativePixmap;
296  PVR2DFORMAT pixelFormat;
297 
298  if (!pixmap)
299  return WSEGL_BAD_NATIVE_PIXMAP;
300 
301  /* We can only copy under certain conditions */
302  switch (format) {
303  case WSEGL_PIXELFORMAT_565:
304  pixelFormat = PVR2D_RGB565; break;
305  case WSEGL_PIXELFORMAT_4444:
306  pixelFormat = PVR2D_ARGB4444; break;
307  case WSEGL_PIXELFORMAT_8888:
308  pixelFormat = PVR2D_ARGB8888; break;
309  default:
310  return WSEGL_BAD_CONFIG;
311  }
312  if (width > (unsigned long)(pixmap->rect.width) ||
313  height > (unsigned long)(pixmap->rect.height) ||
314  pixelFormat != pixmap->pixelFormat) {
315  return WSEGL_BAD_CONFIG;
316  }
317 
318  /* We'd like to use PVR2DBlt to do this, but there is no easy way
319  to map the virtual "address" into physical space to be able
320  to use the hardware assist. Use memcpy to do the work instead.
321  Note: PBuffer's are upside down, so we copy from the bottom up */
322  char *srcaddr = (char *)address;
323  char *dstaddr = (char *)(pixmap->backBuffers[pixmap->currentBackBuffer]->pBase);
324  int dststride = pixmap->strideBytes;
325  int srcwidth = ((int)width) * pvrQwsDisplay.screens[0].bytesPerPixel;
326  srcaddr += height * stride;
327  while (height > 0) {
328  srcaddr -= (int)stride;
329  memcpy(dstaddr, srcaddr, srcwidth);
330  dstaddr += dststride;
331  --height;
332  }
333  return WSEGL_SUCCESS;
334 }
335 
336 /* Return the parameters of a drawable that are needed by the EGL layer */
337 static WSEGLError wseglGetDrawableParameters
338  (WSEGLDrawableHandle _drawable, WSEGLDrawableParams *sourceParams,
339  WSEGLDrawableParams *renderParams)
340 {
341  PvrQwsDrawable *drawable = (PvrQwsDrawable *)_drawable;
342  PVR2DMEMINFO *source, *render;
343  WSEGLPixelFormat pixelFormat;
344 
345  if (!pvrQwsGetBuffers(drawable, &source, &render))
346  return WSEGL_BAD_DRAWABLE;
347 
348  switch (drawable->pixelFormat) {
349  case PVR2D_RGB565:
350  default:
351  pixelFormat = WSEGL_PIXELFORMAT_565;
352  break;
353 
354  case PVR2D_ARGB4444:
355  pixelFormat = WSEGL_PIXELFORMAT_4444;
356  break;
357 
358  case PVR2D_ARGB8888:
359  pixelFormat = WSEGL_PIXELFORMAT_8888;
360  break;
361  }
362 
363  sourceParams->ui32Width = drawable->rect.width;
364  sourceParams->ui32Height = drawable->rect.height;
365  sourceParams->ui32Stride = drawable->stridePixels;
366  sourceParams->ePixelFormat = pixelFormat;
367  sourceParams->pvLinearAddress = source->pBase;
368  sourceParams->ui32HWAddress = source->ui32DevAddr;
369  sourceParams->hPrivateData = source->hPrivateData;
370 
371  renderParams->ui32Width = drawable->rect.width;
372  renderParams->ui32Height = drawable->rect.height;
373  renderParams->ui32Stride = drawable->stridePixels;
374  renderParams->ePixelFormat = pixelFormat;
375  renderParams->pvLinearAddress = render->pBase;
376  renderParams->ui32HWAddress = render->ui32DevAddr;
377  renderParams->hPrivateData = render->hPrivateData;
378 
379  return WSEGL_SUCCESS;
380 }
381 
382 static WSEGL_FunctionTable const wseglFunctions = {
383  WSEGL_VERSION,
396 };
397 
398 /* Return the table of WSEGL functions to the EGL implementation */
399 const WSEGL_FunctionTable *WSEGL_GetFunctionTablePointer(void)
400 {
401  return &wseglFunctions;
402 }
PVR2DMEMINFO * backBuffers[PVRQWS_MAX_BACK_BUFFERS]
#define WSEGL_CAP_PIXMAPS_USE_HW_SYNC
Definition: pvrqwswsegl.c:55
int pvrQwsAllocBuffers(PvrQwsDrawable *drawable)
static WSEGLError wseglCopyFromDrawable(WSEGLDrawableHandle _drawable, NativePixmapType nativePixmap)
Definition: pvrqwswsegl.c:250
PVR2DFORMAT pixelFormat
PvrQwsDrawable * pvrQwsFetchWindow(long winId)
PVR2DFLIPCHAINHANDLE flipChain
PVR2DCONTEXTHANDLE context
static WSEGLError wseglCopyFromPBuffer(void *address, unsigned long width, unsigned long height, unsigned long stride, WSEGLPixelFormat format, NativePixmapType nativePixmap)
Definition: pvrqwswsegl.c:291
void pvrQwsFreeBuffers(PvrQwsDrawable *drawable)
PvrQwsDisplay pvrQwsDisplay
static WSEGLError wseglCloseDisplay(WSEGLDisplayHandle display)
Definition: pvrqwswsegl.c:128
int pvrQwsGetBuffers(PvrQwsDrawable *drawable, PVR2DMEMINFO **source, PVR2DMEMINFO **render)
int pvrQwsDisplayOpen(void)
static WSEGLError wseglIsDisplayValid(NativeDisplayType nativeDisplay)
Definition: pvrqwswsegl.c:75
Q_GUI_EXPORT EGLNativePixmapType nativePixmap(QPixmap *)
Definition: qegl_qpa.cpp:65
#define PVRQWS_MAX_SCREENS
static WSEGLRotationAngle wseglRotationValue(int degrees)
Definition: pvrqwswsegl.c:135
PvrQwsDrawableType type
static WSEGLError wseglSwapDrawable(WSEGLDrawableHandle _drawable, unsigned long data)
Definition: pvrqwswsegl.c:214
static WSEGLError wseglCreateWindowDrawable(WSEGLDisplayHandle display, WSEGLConfig *config, WSEGLDrawableHandle *drawable, NativeWindowType nativeWindow, WSEGLRotationAngle *rotationAngle)
Definition: pvrqwswsegl.c:147
static WSEGLError wseglSwapControlInterval(WSEGLDrawableHandle drawable, unsigned long interval)
Definition: pvrqwswsegl.c:226
static WSEGLConfig wseglDisplayConfigs[]
Definition: pvrqwswsegl.c:66
Q_GUI_EXPORT EGLDisplay display()
Definition: qegl.cpp:589
int pvrQwsReleaseWindow(PvrQwsDrawable *drawable)
static WSEGLError wseglDeleteDrawable(WSEGLDrawableHandle _drawable)
Definition: pvrqwswsegl.c:200
static const char * data(const QByteArray &arr)
const WSEGL_FunctionTable * WSEGL_GetFunctionTablePointer(void)
Definition: pvrqwswsegl.c:399
static WSEGLError wseglWaitNative(WSEGLDrawableHandle drawable, unsigned long engine)
Definition: pvrqwswsegl.c:239
#define WSEGL_UNUSED(x)
Definition: pvrqwswsegl.c:49
static WSEGLError wseglGetDrawableParameters(WSEGLDrawableHandle _drawable, WSEGLDrawableParams *sourceParams, WSEGLDrawableParams *renderParams)
Definition: pvrqwswsegl.c:338
Q_GUI_EXPORT EGLNativeDisplayType nativeDisplay()
Definition: qegl_qpa.cpp:55
unsigned long numFlipBuffers
#define WSEGL_CAP_WINDOWS_USE_HW_SYNC
Definition: pvrqwswsegl.c:54
PVR2DFORMAT pixelFormat
static WSEGLCaps const wseglDisplayCaps[]
Definition: pvrqwswsegl.c:59
int pvrQwsSwapBuffers(PvrQwsDrawable *drawable, int repaintOnly)
static WSEGLError wseglInitializeDisplay(NativeDisplayType nativeDisplay, WSEGLDisplayHandle *display, const WSEGLCaps **caps, WSEGLConfig **configs)
Definition: pvrqwswsegl.c:86
PvrQwsDrawable * pvrQwsScreenWindow(int screen)
PvrQwsScreenInfo screens[PVRQWS_MAX_SCREENS]
void pvrQwsDestroyDrawable(PvrQwsDrawable *drawable)
Q_GUI_EXPORT EGLNativeWindowType nativeWindow(QWidget *)
Definition: qegl_qpa.cpp:60
void pvrQwsDisplayClose(void)
static WSEGL_FunctionTable const wseglFunctions
Definition: pvrqwswsegl.c:382
static WSEGLError wseglCreatePixmapDrawable(WSEGLDisplayHandle display, WSEGLConfig *config, WSEGLDrawableHandle *drawable, NativePixmapType nativePixmap, WSEGLRotationAngle *rotationAngle)
Definition: pvrqwswsegl.c:184