Qt 4.8
Functions | Variables
pvrqwsdrawable.c File Reference
#include "pvrqwsdrawable_p.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <linux/fb.h>
#include <fcntl.h>
#include <unistd.h>

Go to the source code of this file.

Functions

static int pvrQwsAddDrawable (void)
 
int pvrQwsAllocBuffers (PvrQwsDrawable *drawable)
 
void pvrQwsClearVisibleRegion (PvrQwsDrawable *drawable)
 
PvrQwsDrawablepvrQwsCreatePixmap (int width, int height, int screen)
 
PvrQwsDrawablepvrQwsCreateWindow (int screen, long winId, const PvrQwsRect *rect)
 
static void pvrQwsDestroyContext (void)
 
void pvrQwsDestroyDrawable (PvrQwsDrawable *drawable)
 
static void pvrQwsDestroyDrawableForced (PvrQwsDrawable *drawable)
 
void pvrQwsDisplayClose (void)
 
int pvrQwsDisplayIsOpen (void)
 
int pvrQwsDisplayOpen (void)
 
static int pvrQwsEnsureScreen (int screen)
 
PvrQwsDrawablepvrQwsFetchWindow (long winId)
 
void pvrQwsFreeBuffers (PvrQwsDrawable *drawable)
 
int pvrQwsGetBuffers (PvrQwsDrawable *drawable, PVR2DMEMINFO **source, PVR2DMEMINFO **render)
 
PvrQwsDrawableType pvrQwsGetDrawableType (PvrQwsDrawable *drawable)
 
void pvrQwsGetGeometry (PvrQwsDrawable *drawable, PvrQwsRect *rect)
 
PvrQwsPixelFormat pvrQwsGetPixelFormat (PvrQwsDrawable *drawable)
 
void * pvrQwsGetRenderBuffer (PvrQwsDrawable *drawable)
 
int pvrQwsGetStride (PvrQwsDrawable *drawable)
 
static int pvrQwsInitFbScreen (int screen)
 
void pvrQwsInvalidateBuffers (PvrQwsDrawable *drawable)
 
int pvrQwsReleaseWindow (PvrQwsDrawable *drawable)
 
PvrQwsDrawablepvrQwsScreenWindow (int screen)
 
void pvrQwsSetGeometry (PvrQwsDrawable *drawable, const PvrQwsRect *rect)
 
void pvrQwsSetRotation (PvrQwsDrawable *drawable, int angle)
 
void pvrQwsSetSwapFunction (PvrQwsDrawable *drawable, PvrQwsSwapFunction func, void *userData)
 
void pvrQwsSetVisibleRegion (PvrQwsDrawable *drawable, const PvrQwsRect *rects, int numRects)
 
int pvrQwsSwapBuffers (PvrQwsDrawable *drawable, int repaintOnly)
 

Variables

PvrQwsDisplay pvrQwsDisplay
 

Function Documentation

◆ pvrQwsAddDrawable()

static int pvrQwsAddDrawable ( void  )
static

Definition at line 184 of file pvrqwsdrawable.c.

Referenced by pvrQwsCreatePixmap(), pvrQwsCreateWindow(), and pvrQwsScreenWindow().

185 {
186  int numDevs, screen;
187  PVR2DDEVICEINFO *devs;
188  unsigned long devId;
189  unsigned long pageAddresses[2];
190  PVR2DMEMINFO *memInfo;
191  PVR2DDISPLAYINFO displayInfo;
192 
193  /* Bail out early if this is not the first drawable */
194  if (pvrQwsDisplay.numDrawables > 0) {
196  return 1;
197  }
198 
199  /* Find the first PVR2D device in the system and open it */
200  numDevs = PVR2DEnumerateDevices(0);
201  if (numDevs <= 0)
202  return 0;
203  devs = (PVR2DDEVICEINFO *)malloc(sizeof(PVR2DDEVICEINFO) * numDevs);
204  if (!devs)
205  return 0;
206  if (PVR2DEnumerateDevices(devs) != PVR2D_OK) {
207  free(devs);
208  return 0;
209  }
210  devId = devs[0].ulDevID;
211  free(devs);
212  if (PVR2DCreateDeviceContext(devId, &pvrQwsDisplay.context, 0) != PVR2D_OK)
213  return 0;
216  if (PVR2DGetDeviceInfo(pvrQwsDisplay.context, &displayInfo) == PVR2D_OK) {
217  if (displayInfo.ulMaxFlipChains > 0 && displayInfo.ulMaxBuffersInChain > 0)
218  pvrQwsDisplay.numFlipBuffers = displayInfo.ulMaxBuffersInChain;
221  }
222 
223  /* Create the PVR2DMEMINFO blocks for the active framebuffers */
224  for (screen = 0; screen < PVRQWS_MAX_SCREENS; ++screen) {
225  if (screen != 0 && pvrQwsDisplay.screens[screen].mapped) {
226  pageAddresses[0]
227  = pvrQwsDisplay.screens[screen].screenStart & 0xFFFFF000;
228  pageAddresses[1] = 0;
229  if (PVR2DMemWrap
231  pvrQwsDisplay.screens[screen].mapped,
232  PVR2D_WRAPFLAG_CONTIGUOUS,
234  pageAddresses, &memInfo) != PVR2D_OK) {
235  PVR2DDestroyDeviceContext(pvrQwsDisplay.context);
237  return 0;
238  }
239  pvrQwsDisplay.screens[screen].frameBuffer = memInfo;
240  } else if (screen == 0) {
241  if (PVR2DGetFrameBuffer
243  PVR2D_FB_PRIMARY_SURFACE, &memInfo) != PVR2D_OK) {
244  fprintf(stderr, "QWSWSEGL: could not get the primary framebuffer surface\n");
245  PVR2DDestroyDeviceContext(pvrQwsDisplay.context);
247  return 0;
248  }
249  pvrQwsDisplay.screens[screen].frameBuffer = memInfo;
250  pvrQwsDisplay.screens[screen].mapped = memInfo->pBase;
251  }
252  }
253 
254  /* Create a flip chain for the screen if supported by the hardware */
256  if (pvrQwsDisplay.numFlipBuffers > 0) {
257  long stride = 0;
258  unsigned long flipId = 0;
259  unsigned long numBuffers;
260  if (PVR2DCreateFlipChain(pvrQwsDisplay.context, 0,
261  //PVR2D_CREATE_FLIPCHAIN_SHARED |
262  //PVR2D_CREATE_FLIPCHAIN_QUERY,
267  &stride, &flipId, &(pvrQwsDisplay.flipChain))
268  == PVR2D_OK) {
269  pvrQwsDisplay.screens[0].screenStride = stride;
270  PVR2DGetFlipChainBuffers(pvrQwsDisplay.context,
272  &numBuffers,
274  } else {
277  }
278 
279  /* PVR2DPresentBlt is a little more reliable than PVR2DBlt
280  when flip chains are present, even if we cannot create a
281  flip chain at the moment */
283  }
284 
285  /* The context is ready to go */
287  return 1;
288 }
PVR2DMEMINFO * frameBuffer
PVR2DFLIPCHAINHANDLE flipChain
PVR2DCONTEXTHANDLE context
PvrQwsDisplay pvrQwsDisplay
PvrQwsRect screenRect
#define PVRQWS_MAX_SCREENS
PVR2DMEMINFO * flipBuffers[PVRQWS_MAX_FLIP_BUFFERS]
unsigned long screenStart
unsigned long numFlipBuffers
PVR2DFORMAT pixelFormat
#define PVRQWS_MAX_FLIP_BUFFERS
PvrQwsScreenInfo screens[PVRQWS_MAX_SCREENS]

◆ pvrQwsAllocBuffers()

int pvrQwsAllocBuffers ( PvrQwsDrawable drawable)

Definition at line 651 of file pvrqwsdrawable.c.

Referenced by wseglCreatePixmapDrawable(), and wseglCreateWindowDrawable().

652 {
653  int index;
654  int numBuffers = PVRQWS_MAX_BACK_BUFFERS;
655  if (drawable->type == PvrQwsPixmap)
656  numBuffers = 1;
657  if (drawable->backBuffers[0]) {
658  if (drawable->backBuffersValid)
659  return 1;
660  if (!drawable->usingFlipBuffers) {
661  for (index = 0; index < numBuffers; ++index)
662  PVR2DMemFree(pvrQwsDisplay.context, drawable->backBuffers[index]);
663  }
664  }
665  drawable->stridePixels = (drawable->rect.width + 31) & ~31;
666  drawable->strideBytes =
667  drawable->stridePixels *
669  drawable->usingFlipBuffers =
670  (pvrQwsDisplay.numFlipBuffers > 0 && drawable->isFullScreen);
671  if (drawable->usingFlipBuffers) {
672  if (numBuffers > (int)(pvrQwsDisplay.numFlipBuffers))
673  numBuffers = pvrQwsDisplay.numFlipBuffers;
674  for (index = 0; index < numBuffers; ++index)
675  drawable->backBuffers[index] = pvrQwsDisplay.flipBuffers[index];
676  } else {
677  for (index = 0; index < numBuffers; ++index) {
678  if (PVR2DMemAlloc(pvrQwsDisplay.context,
679  drawable->strideBytes * drawable->rect.height,
680  128, 0,
681  &(drawable->backBuffers[index])) != PVR2D_OK) {
682  while (--index >= 0)
683  PVR2DMemFree(pvrQwsDisplay.context, drawable->backBuffers[index]);
684  memset(drawable->backBuffers, 0, sizeof(drawable->backBuffers));
685  drawable->backBuffersValid = 0;
686  return 0;
687  }
688  }
689  }
690  for (index = numBuffers; index < PVRQWS_MAX_BACK_BUFFERS; ++index) {
691  drawable->backBuffers[index] = drawable->backBuffers[0];
692  }
693  drawable->backBuffersValid = 1;
694  drawable->currentBackBuffer = 0;
695  return 1;
696 }
PVR2DMEMINFO * backBuffers[PVRQWS_MAX_BACK_BUFFERS]
PVR2DCONTEXTHANDLE context
#define PVRQWS_MAX_BACK_BUFFERS
PvrQwsDisplay pvrQwsDisplay
PvrQwsDrawableType type
PVR2DMEMINFO * flipBuffers[PVRQWS_MAX_FLIP_BUFFERS]
unsigned long numFlipBuffers
quint16 index
PvrQwsScreenInfo screens[PVRQWS_MAX_SCREENS]

◆ pvrQwsClearVisibleRegion()

void pvrQwsClearVisibleRegion ( PvrQwsDrawable drawable)

Definition at line 583 of file pvrqwsdrawable.c.

Referenced by PvrEglWindowSurface::setDirectRegion().

584 {
585  if (drawable->type != PvrQwsPixmap)
586  drawable->numVisibleRects = 0;
587 }
PvrQwsDrawableType type

◆ pvrQwsCreatePixmap()

PvrQwsDrawable* pvrQwsCreatePixmap ( int  width,
int  height,
int  screen 
)

Definition at line 465 of file pvrqwsdrawable.c.

466 {
467  PvrQwsDrawable *drawable;
468 
469  if (!pvrQwsEnsureScreen(screen))
470  return 0;
471 
472  drawable = (PvrQwsDrawable *)calloc(1, sizeof(PvrQwsDrawable));
473  if (!drawable)
474  return 0;
475 
476  drawable->type = PvrQwsPixmap;
477  drawable->screen = screen;
478  drawable->pixelFormat = pvrQwsDisplay.screens[screen].pixelFormat;
479  drawable->rect.x = 0;
480  drawable->rect.y = 0;
481  drawable->rect.width = width;
482  drawable->rect.height = height;
483 
484  if (!pvrQwsAddDrawable()) {
485  free(drawable);
486  return 0;
487  }
488 
489  return drawable;
490 }
PVR2DFORMAT pixelFormat
PvrQwsDisplay pvrQwsDisplay
PvrQwsDrawableType type
#define calloc(a, b)
PVR2DFORMAT pixelFormat
PvrQwsScreenInfo screens[PVRQWS_MAX_SCREENS]
static int pvrQwsAddDrawable(void)
static int pvrQwsEnsureScreen(int screen)

◆ pvrQwsCreateWindow()

PvrQwsDrawable* pvrQwsCreateWindow ( int  screen,
long  winId,
const PvrQwsRect rect 
)

Definition at line 417 of file pvrqwsdrawable.c.

Referenced by PvrEglWindowSurface::PvrEglWindowSurface().

418 {
419  PvrQwsDrawable *drawable;
420 
421  if (!pvrQwsEnsureScreen(screen))
422  return 0;
423 
424  drawable = (PvrQwsDrawable *)calloc(1, sizeof(PvrQwsDrawable));
425  if (!drawable)
426  return 0;
427 
428  drawable->type = PvrQwsWindow;
429  drawable->winId = winId;
430  drawable->refCount = 1;
431  drawable->screen = screen;
432  drawable->pixelFormat = pvrQwsDisplay.screens[screen].pixelFormat;
433  drawable->rect = *rect;
434 
435  if (!pvrQwsAddDrawable()) {
436  free(drawable);
437  return 0;
438  }
439 
440  drawable->nextWinId = pvrQwsDisplay.firstWinId;
441  pvrQwsDisplay.firstWinId = drawable;
442 
443  return drawable;
444 }
PVR2DFORMAT pixelFormat
PvrQwsDisplay pvrQwsDisplay
PvrQwsDrawableType type
PvrQwsDrawable * nextWinId
#define calloc(a, b)
PVR2DFORMAT pixelFormat
PvrQwsScreenInfo screens[PVRQWS_MAX_SCREENS]
static int pvrQwsAddDrawable(void)
static int pvrQwsEnsureScreen(int screen)
PvrQwsDrawable * firstWinId

◆ pvrQwsDestroyContext()

static void pvrQwsDestroyContext ( void  )
static

Definition at line 292 of file pvrqwsdrawable.c.

Referenced by pvrQwsDestroyDrawableForced().

293 {
294  int screen;
295  for (screen = 0; screen < PVRQWS_MAX_SCREENS; ++screen) {
296  if (pvrQwsDisplay.screens[screen].frameBuffer) {
297  PVR2DMemFree
300  pvrQwsDisplay.screens[screen].frameBuffer = 0;
301  }
302  }
303 
305  PVR2DDestroyFlipChain(pvrQwsDisplay.context, pvrQwsDisplay.flipChain);
306  PVR2DDestroyDeviceContext(pvrQwsDisplay.context);
311 }
PVR2DMEMINFO * frameBuffer
PVR2DFLIPCHAINHANDLE flipChain
PVR2DCONTEXTHANDLE context
PvrQwsDisplay pvrQwsDisplay
#define PVRQWS_MAX_SCREENS
unsigned long numFlipBuffers
PvrQwsScreenInfo screens[PVRQWS_MAX_SCREENS]

◆ pvrQwsDestroyDrawable()

void pvrQwsDestroyDrawable ( PvrQwsDrawable drawable)

Definition at line 516 of file pvrqwsdrawable.c.

Referenced by wseglDeleteDrawable(), and PvrEglWindowSurface::~PvrEglWindowSurface().

517 {
518  if (drawable && drawable->type != PvrQwsScreen)
519  pvrQwsDestroyDrawableForced(drawable);
520 }
PvrQwsDrawableType type
static void pvrQwsDestroyDrawableForced(PvrQwsDrawable *drawable)

◆ pvrQwsDestroyDrawableForced()

static void pvrQwsDestroyDrawableForced ( PvrQwsDrawable drawable)
static

Definition at line 492 of file pvrqwsdrawable.c.

Referenced by pvrQwsDestroyDrawable(), and pvrQwsDisplayClose().

493 {
494  /* Remove the drawable from the display's winId list */
496  PvrQwsDrawable *prev = 0;
497  while (current != 0 && current != drawable) {
498  prev = current;
499  current = current->nextWinId;
500  }
501  if (current != 0) {
502  if (prev)
503  prev->nextWinId = current->nextWinId;
504  else
506  }
507 
508  pvrQwsFreeBuffers(drawable);
509  free(drawable);
510 
512  if (pvrQwsDisplay.numDrawables == 0)
514 }
void pvrQwsFreeBuffers(PvrQwsDrawable *drawable)
PvrQwsDisplay pvrQwsDisplay
PvrQwsDrawable * nextWinId
static void pvrQwsDestroyContext(void)
PvrQwsDrawable * firstWinId

◆ pvrQwsDisplayClose()

void pvrQwsDisplayClose ( void  )

Definition at line 338 of file pvrqwsdrawable.c.

Referenced by PvrEglScreen::connect(), PvrEglScreen::disconnect(), wseglCloseDisplay(), and wseglInitializeDisplay().

339 {
340  int screen;
341 
342  if (pvrQwsDisplay.refCount == 0)
343  return;
344  if (--(pvrQwsDisplay.refCount) > 0)
345  return;
346 
347  /* Prevent pvrQwsDestroyContext from being called for the time being */
349 
350  /* Free the screens */
351  for (screen = 0; screen < PVRQWS_MAX_SCREENS; ++screen) {
353  if (info->screenDrawable)
355  if (info->frameBuffer)
356  PVR2DMemFree(pvrQwsDisplay.context, info->frameBuffer);
357  if (info->mapped && info->needsUnmap)
358  munmap(info->mapped, info->mappedLength);
359  }
360 
361  /* Now it is safe to destroy the PVR2D context */
364  PVR2DDestroyDeviceContext(pvrQwsDisplay.context);
365 
366  memset(&pvrQwsDisplay, 0, sizeof(pvrQwsDisplay));
367 }
PVR2DMEMINFO * frameBuffer
static mach_timebase_info_data_t info
PVR2DCONTEXTHANDLE context
PvrQwsDisplay pvrQwsDisplay
#define PVRQWS_MAX_SCREENS
static void pvrQwsDestroyDrawableForced(PvrQwsDrawable *drawable)
PvrQwsScreenInfo screens[PVRQWS_MAX_SCREENS]
PvrQwsDrawable * screenDrawable

◆ pvrQwsDisplayIsOpen()

int pvrQwsDisplayIsOpen ( void  )

Definition at line 369 of file pvrqwsdrawable.c.

370 {
371  return (pvrQwsDisplay.refCount > 0);
372 }
PvrQwsDisplay pvrQwsDisplay

◆ pvrQwsDisplayOpen()

int pvrQwsDisplayOpen ( void  )

Definition at line 313 of file pvrqwsdrawable.c.

Referenced by PvrEglScreen::connect(), and wseglInitializeDisplay().

314 {
315  int screen;
316 
317  /* If the display is already open, increase reference count and return */
318  if (pvrQwsDisplay.refCount > 0) {
320  return 1;
321  }
322 
323  /* Open the framebuffer and map it directly */
324  if (!pvrQwsInitFbScreen(0)) {
326  return 0;
327  }
328 
329  /* Clear the other screens. We will create them if they are referenced */
330  for (screen = 1; screen < PVRQWS_MAX_SCREENS; ++screen)
331  memset(&(pvrQwsDisplay.screens[screen]), 0, sizeof(PvrQwsScreenInfo));
332 
333  /* The display is open and ready */
335  return 1;
336 }
static int pvrQwsInitFbScreen(int screen)
PvrQwsDisplay pvrQwsDisplay
#define PVRQWS_MAX_SCREENS
PvrQwsScreenInfo screens[PVRQWS_MAX_SCREENS]

◆ pvrQwsEnsureScreen()

static int pvrQwsEnsureScreen ( int  screen)
static

Definition at line 375 of file pvrqwsdrawable.c.

Referenced by pvrQwsCreatePixmap(), pvrQwsCreateWindow(), and pvrQwsScreenWindow().

376 {
377  if (screen < 0 || screen >= PVRQWS_MAX_SCREENS)
378  return 0;
379  if (!screen)
380  return 1;
381  return pvrQwsInitFbScreen(screen);
382 }
static int pvrQwsInitFbScreen(int screen)
#define PVRQWS_MAX_SCREENS

◆ pvrQwsFetchWindow()

PvrQwsDrawable* pvrQwsFetchWindow ( long  winId)

Definition at line 446 of file pvrqwsdrawable.c.

Referenced by PvrEglWindowSurface::PvrEglWindowSurface(), and wseglCreateWindowDrawable().

447 {
449  while (drawable != 0 && drawable->winId != winId)
450  drawable = drawable->nextWinId;
451 
452  if (drawable)
453  ++(drawable->refCount);
454  return drawable;
455 }
PvrQwsDisplay pvrQwsDisplay
PvrQwsDrawable * nextWinId
PvrQwsDrawable * firstWinId

◆ pvrQwsFreeBuffers()

void pvrQwsFreeBuffers ( PvrQwsDrawable drawable)

Definition at line 698 of file pvrqwsdrawable.c.

Referenced by pvrQwsDestroyDrawableForced(), and wseglDeleteDrawable().

699 {
700  int index;
701  int numBuffers = PVRQWS_MAX_BACK_BUFFERS;
702  if (drawable->type == PvrQwsPixmap)
703  numBuffers = 1;
704  if (!drawable->usingFlipBuffers) {
705  for (index = 0; index < numBuffers; ++index) {
706  if (drawable->backBuffers[index])
707  PVR2DMemFree(pvrQwsDisplay.context, drawable->backBuffers[index]);
708  }
709  }
710  memset(drawable->backBuffers, 0, sizeof(drawable->backBuffers));
711  drawable->backBuffersValid = 0;
712  drawable->usingFlipBuffers = 0;
713 }
PVR2DMEMINFO * backBuffers[PVRQWS_MAX_BACK_BUFFERS]
PVR2DCONTEXTHANDLE context
#define PVRQWS_MAX_BACK_BUFFERS
PvrQwsDisplay pvrQwsDisplay
PvrQwsDrawableType type
quint16 index

◆ pvrQwsGetBuffers()

int pvrQwsGetBuffers ( PvrQwsDrawable drawable,
PVR2DMEMINFO **  source,
PVR2DMEMINFO **  render 
)

Definition at line 721 of file pvrqwsdrawable.c.

Referenced by pvrQwsInvalidateBuffers(), and wseglGetDrawableParameters().

722 {
723  if (!drawable->backBuffersValid)
724  return 0;
725  *render = drawable->backBuffers[drawable->currentBackBuffer];
726  *source = drawable->backBuffers
727  [(drawable->currentBackBuffer + PVRQWS_MAX_BACK_BUFFERS - 1) %
729  return 1;
730 }
PVR2DMEMINFO * backBuffers[PVRQWS_MAX_BACK_BUFFERS]
#define PVRQWS_MAX_BACK_BUFFERS

◆ pvrQwsGetDrawableType()

PvrQwsDrawableType pvrQwsGetDrawableType ( PvrQwsDrawable drawable)

Definition at line 522 of file pvrqwsdrawable.c.

523 {
524  return drawable->type;
525 }
PvrQwsDrawableType type

◆ pvrQwsGetGeometry()

void pvrQwsGetGeometry ( PvrQwsDrawable drawable,
PvrQwsRect rect 
)

Definition at line 615 of file pvrqwsdrawable.c.

Referenced by PvrEglWindowSurface::image().

616 {
617  *rect = drawable->rect;
618 }

◆ pvrQwsGetPixelFormat()

PvrQwsPixelFormat pvrQwsGetPixelFormat ( PvrQwsDrawable drawable)

Definition at line 638 of file pvrqwsdrawable.c.

639 {
640  return (PvrQwsPixelFormat)(drawable->pixelFormat);
641 }
PvrQwsPixelFormat
PVR2DFORMAT pixelFormat

◆ pvrQwsGetRenderBuffer()

void* pvrQwsGetRenderBuffer ( PvrQwsDrawable drawable)

Definition at line 643 of file pvrqwsdrawable.c.

Referenced by PvrEglWindowSurface::image().

644 {
645  if (drawable->backBuffersValid)
646  return drawable->backBuffers[drawable->currentBackBuffer]->pBase;
647  else
648  return 0;
649 }
PVR2DMEMINFO * backBuffers[PVRQWS_MAX_BACK_BUFFERS]

◆ pvrQwsGetStride()

int pvrQwsGetStride ( PvrQwsDrawable drawable)

Definition at line 630 of file pvrqwsdrawable.c.

Referenced by PvrEglWindowSurface::image().

631 {
632  if (drawable->backBuffersValid)
633  return drawable->strideBytes;
634  else
635  return 0;
636 }

◆ pvrQwsInitFbScreen()

static int pvrQwsInitFbScreen ( int  screen)
static

Definition at line 58 of file pvrqwsdrawable.c.

Referenced by pvrQwsDisplayOpen(), and pvrQwsEnsureScreen().

59 {
60  struct fb_var_screeninfo var;
61  struct fb_fix_screeninfo fix;
62  unsigned long start;
63  unsigned long length;
64  int width, height, stride;
65  PVR2DFORMAT format;
66  void *mapped;
67  int fd, bytesPerPixel;
68  char name[64];
69  PVR2DMEMINFO *memInfo;
70  unsigned long pageAddresses[2];
71 
72  /* Bail out if already initialized, or the number is incorrect */
73  if (screen < 0 || screen >= PVRQWS_MAX_SCREENS)
74  return 0;
75  if (pvrQwsDisplay.screens[screen].initialized)
76  return 1;
77 
78  /* Open the framebuffer and fetch its properties */
79  sprintf(name, "/dev/fb%d", screen);
80  fd = open(name, O_RDWR, 0);
81  if (fd < 0) {
82  perror(name);
83  return 0;
84  }
85  if (ioctl(fd, FBIOGET_VSCREENINFO, &var) < 0) {
86  perror("FBIOGET_VSCREENINFO");
87  close(fd);
88  return 0;
89  }
90  if (ioctl(fd, FBIOGET_FSCREENINFO, &fix) < 0) {
91  perror("FBIOGET_FSCREENINFO");
92  close(fd);
93  return 0;
94  }
95  width = var.xres;
96  height = var.yres;
97  bytesPerPixel = var.bits_per_pixel / 8;
98  stride = fix.line_length;
99  format = PVR2D_1BPP;
100  if (var.bits_per_pixel == 16) {
101  if (var.red.length == 5 && var.green.length == 6 &&
102  var.blue.length == 5 && var.red.offset == 11 &&
103  var.green.offset == 5 && var.blue.offset == 0) {
104  format = PVR2D_RGB565;
105  }
106  if (var.red.length == 4 && var.green.length == 4 &&
107  var.blue.length == 4 && var.transp.length == 4 &&
108  var.red.offset == 8 && var.green.offset == 4 &&
109  var.blue.offset == 0 && var.transp.offset == 12) {
110  format = PVR2D_ARGB4444;
111  }
112  } else if (var.bits_per_pixel == 32) {
113  if (var.red.length == 8 && var.green.length == 8 &&
114  var.blue.length == 8 && var.transp.length == 8 &&
115  var.red.offset == 16 && var.green.offset == 8 &&
116  var.blue.offset == 0 && var.transp.offset == 24) {
117  format = PVR2D_ARGB8888;
118  }
119  }
120  if (format == PVR2D_1BPP) {
121  fprintf(stderr, "%s: could not find a suitable PVR2D pixel format\n", name);
122  close(fd);
123  return 0;
124  }
125  start = fix.smem_start;
126  length = var.xres_virtual * var.yres_virtual * bytesPerPixel;
127 
128  if (screen == 0) {
129  /* We use PVR2DGetFrameBuffer to map the first screen.
130  On some chipsets it is more reliable than using PVR2DMemWrap */
131  mapped = 0;
132  memInfo = 0;
133  } else {
134  /* Other screens: map the framebuffer region into memory */
135  mapped = mmap(0, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
136  if (!mapped || mapped == (void *)(-1)) {
137  perror("mmap");
138  close(fd);
139  return 0;
140  }
141 
142  /* Allocate a PVR2D memory region for the framebuffer */
143  memInfo = 0;
144  if (pvrQwsDisplay.context) {
145  pageAddresses[0] = start & 0xFFFFF000;
146  pageAddresses[1] = 0;
147  if (PVR2DMemWrap
148  (pvrQwsDisplay.context, mapped, PVR2D_WRAPFLAG_CONTIGUOUS,
149  length, pageAddresses, &memInfo) != PVR2D_OK) {
150  munmap(mapped, length);
151  close(fd);
152  return 0;
153  }
154  }
155  }
156 
157  /* We don't need the file descriptor any more */
158  close(fd);
159 
160  /* The framebuffer is ready, so initialize the PvrQwsScreenInfo */
161  pvrQwsDisplay.screens[screen].screenRect.x = 0;
162  pvrQwsDisplay.screens[screen].screenRect.y = 0;
163  pvrQwsDisplay.screens[screen].screenRect.width = width;
164  pvrQwsDisplay.screens[screen].screenRect.height = height;
165  pvrQwsDisplay.screens[screen].screenStride = stride;
169  if (mapped) {
170  /* Don't set these fields if mapped is 0, because PVR2DGetFrameBuffer
171  may have already been called and set them */
172  pvrQwsDisplay.screens[screen].frameBuffer = memInfo;
174  }
175  pvrQwsDisplay.screens[screen].mappedLength = length;
176  pvrQwsDisplay.screens[screen].screenStart = start;
177  pvrQwsDisplay.screens[screen].needsUnmap = (mapped != 0);
178  pvrQwsDisplay.screens[screen].initialized = 1;
179  return 1;
180 }
PVR2DMEMINFO * frameBuffer
PVR2DCONTEXTHANDLE context
static int bytesPerPixel(QImage::Format format)
PvrQwsDisplay pvrQwsDisplay
PvrQwsRect screenRect
#define PVRQWS_MAX_SCREENS
QFuture< T > mapped(const Sequence &sequence, MapFunction function)
const char * name
unsigned long screenStart
PVR2DFORMAT pixelFormat
PvrQwsScreenInfo screens[PVRQWS_MAX_SCREENS]
PvrQwsDrawable * screenDrawable
#define O_RDWR
int open(const char *, int,...)

◆ pvrQwsInvalidateBuffers()

void pvrQwsInvalidateBuffers ( PvrQwsDrawable drawable)

Definition at line 715 of file pvrqwsdrawable.c.

Referenced by pvrQwsSetGeometry(), and pvrQwsSetRotation().

716 {
717  drawable->backBuffersValid = 0;
718 }

◆ pvrQwsReleaseWindow()

int pvrQwsReleaseWindow ( PvrQwsDrawable drawable)

Definition at line 457 of file pvrqwsdrawable.c.

Referenced by wseglDeleteDrawable(), and PvrEglWindowSurface::~PvrEglWindowSurface().

458 {
459  if (drawable->type == PvrQwsWindow)
460  return (--(drawable->refCount) <= 0);
461  else
462  return 0;
463 }
PvrQwsDrawableType type

◆ pvrQwsScreenWindow()

PvrQwsDrawable* pvrQwsScreenWindow ( int  screen)

Definition at line 384 of file pvrqwsdrawable.c.

Referenced by PvrEglScreen::PvrEglScreen(), and wseglCreateWindowDrawable().

385 {
386  PvrQwsDrawable *drawable;
387 
388  if (!pvrQwsEnsureScreen(screen))
389  return 0;
390 
391  drawable = pvrQwsDisplay.screens[screen].screenDrawable;
392  if (drawable)
393  return drawable;
394 
395  drawable = (PvrQwsDrawable *)calloc(1, sizeof(PvrQwsDrawable));
396  if (!drawable)
397  return 0;
398 
399  drawable->type = PvrQwsScreen;
400  drawable->screen = screen;
401  drawable->pixelFormat = pvrQwsDisplay.screens[screen].pixelFormat;
402  drawable->rect = pvrQwsDisplay.screens[screen].screenRect;
403  drawable->visibleRects[0] = drawable->rect;
404  drawable->numVisibleRects = 1;
405  drawable->isFullScreen = 1;
406 
407  if (!pvrQwsAddDrawable()) {
408  free(drawable);
409  return 0;
410  }
411 
412  pvrQwsDisplay.screens[screen].screenDrawable = drawable;
413 
414  return drawable;
415 }
PVR2DFORMAT pixelFormat
PvrQwsDisplay pvrQwsDisplay
PvrQwsRect screenRect
PvrQwsRect visibleRects[PVRQWS_MAX_VISIBLE_RECTS]
PvrQwsDrawableType type
#define calloc(a, b)
PVR2DFORMAT pixelFormat
PvrQwsScreenInfo screens[PVRQWS_MAX_SCREENS]
static int pvrQwsAddDrawable(void)
PvrQwsDrawable * screenDrawable
static int pvrQwsEnsureScreen(int screen)

◆ pvrQwsSetGeometry()

void pvrQwsSetGeometry ( PvrQwsDrawable drawable,
const PvrQwsRect rect 
)

Definition at line 589 of file pvrqwsdrawable.c.

Referenced by PvrEglWindowSurface::move(), PvrEglWindowSurface::PvrEglWindowSurface(), and PvrEglWindowSurface::setGeometry().

590 {
591  /* We can only change the geometry of window drawables */
592  if (drawable->type != PvrQwsWindow)
593  return;
594 
595  /* If the position has changed, then clear the visible region */
596  if (drawable->rect.x != rect->x || drawable->rect.y != rect->y) {
597  drawable->rect.x = rect->x;
598  drawable->rect.y = rect->y;
599  drawable->numVisibleRects = 0;
600  }
601 
602  /* If the size has changed, then clear the visible region and
603  invalidate the drawable's buffers. Invalidating the buffers
604  will force EGL to recreate the drawable, which will then
605  allocate new buffers for the new size */
606  if (drawable->rect.width != rect->width ||
607  drawable->rect.height != rect->height) {
608  drawable->rect.width = rect->width;
609  drawable->rect.height = rect->height;
610  drawable->numVisibleRects = 0;
611  pvrQwsInvalidateBuffers(drawable);
612  }
613 }
PvrQwsDrawableType type
void pvrQwsInvalidateBuffers(PvrQwsDrawable *drawable)

◆ pvrQwsSetRotation()

void pvrQwsSetRotation ( PvrQwsDrawable drawable,
int  angle 
)

Definition at line 620 of file pvrqwsdrawable.c.

Referenced by PvrEglWindowSurface::move(), PvrEglWindowSurface::PvrEglWindowSurface(), PvrEglWindowSurface::setDirectRegion(), and PvrEglWindowSurface::setGeometry().

621 {
622  if (drawable->rotationAngle != angle) {
623  drawable->rotationAngle = angle;
624 
625  /* Force the buffers to be recreated if the rotation angle changes */
626  pvrQwsInvalidateBuffers(drawable);
627  }
628 }
void pvrQwsInvalidateBuffers(PvrQwsDrawable *drawable)
qreal angle(const QPointF &p1, const QPointF &p2)

◆ pvrQwsSetSwapFunction()

void pvrQwsSetSwapFunction ( PvrQwsDrawable drawable,
PvrQwsSwapFunction  func,
void *  userData 
)

Definition at line 826 of file pvrqwsdrawable.c.

Referenced by pvrQwsSwapBuffers().

827 {
828  drawable->swapFunction = func;
829  drawable->userData = userData;
830 }
PvrQwsSwapFunction swapFunction

◆ pvrQwsSetVisibleRegion()

void pvrQwsSetVisibleRegion ( PvrQwsDrawable drawable,
const PvrQwsRect rects,
int  numRects 
)

Definition at line 528 of file pvrqwsdrawable.c.

Referenced by pvrQwsGetDrawableType(), and PvrEglWindowSurface::setDirectRegion().

529 {
530  int index, indexOut;
531  PvrQwsRect *rect;
532  PvrQwsRect *screenRect;
533 
534  /* Visible regions don't make sense for pixmaps */
535  if (drawable->type == PvrQwsPixmap)
536  return;
537 
538  /* Restrict the number of rectangles to prevent buffer overflow */
539  if (numRects > PVRQWS_MAX_VISIBLE_RECTS)
540  numRects = PVRQWS_MAX_VISIBLE_RECTS;
541  if (numRects > 0)
542  memcpy(drawable->visibleRects, rects, numRects * sizeof(PvrQwsRect));
543 
544  /* Convert the rectangles into screen-relative co-ordinates and
545  then clamp them to the screen boundaries. If any of the
546  clamped rectangles are empty, remove them from the list */
547  screenRect = &(pvrQwsDisplay.screens[drawable->screen].screenRect);
548  indexOut = 0;
549  for (index = 0, rect = drawable->visibleRects; index < numRects; ++index, ++rect) {
550  if (rect->x < 0) {
551  rect->width += rect->x;
552  rect->x = 0;
553  if (rect->width < 0)
554  rect->width = 0;
555  } else if (rect->x >= screenRect->width) {
556  rect->x = screenRect->width;
557  rect->width = 0;
558  }
559  if ((rect->x + rect->width) > screenRect->width) {
560  rect->width = screenRect->width - rect->x;
561  }
562  if (rect->y < 0) {
563  rect->height += rect->y;
564  rect->y = 0;
565  if (rect->height < 0)
566  rect->height = 0;
567  } else if (rect->y >= screenRect->height) {
568  rect->y = screenRect->height;
569  rect->height = 0;
570  }
571  if ((rect->y + rect->height) > screenRect->height) {
572  rect->height = screenRect->height - rect->y;
573  }
574  if (rect->width > 0 && rect->height > 0) {
575  if (index != indexOut)
576  drawable->visibleRects[indexOut] = *rect;
577  ++indexOut;
578  }
579  }
580  drawable->numVisibleRects = indexOut;
581 }
PvrQwsDisplay pvrQwsDisplay
PvrQwsRect screenRect
PvrQwsRect visibleRects[PVRQWS_MAX_VISIBLE_RECTS]
PvrQwsDrawableType type
quint16 index
#define PVRQWS_MAX_VISIBLE_RECTS
PvrQwsScreenInfo screens[PVRQWS_MAX_SCREENS]

◆ pvrQwsSwapBuffers()

int pvrQwsSwapBuffers ( PvrQwsDrawable drawable,
int  repaintOnly 
)

Definition at line 732 of file pvrqwsdrawable.c.

Referenced by PvrEglWindowSurface::setDirectRegion(), and wseglSwapDrawable().

733 {
734  PVR2DMEMINFO *buffer;
735  PvrQwsRect *rect;
736  int index;
737 
738  /* Bail out if the back buffers have been invalidated */
739  if (!drawable->backBuffersValid)
740  return 0;
741 
742  /* If there is a swap function, then use that instead */
743  if (drawable->swapFunction) {
744  (*(drawable->swapFunction))(drawable, drawable->userData, repaintOnly);
745  if (!repaintOnly) {
746  drawable->currentBackBuffer
747  = (drawable->currentBackBuffer + 1) % PVRQWS_MAX_BACK_BUFFERS;
748  }
749  return 1;
750  }
751 
752  /* Iterate through the visible rectangles and blit them to the screen */
753  if (!repaintOnly) {
754  index = drawable->currentBackBuffer;
755  } else {
756  index = (drawable->currentBackBuffer + PVRQWS_MAX_BACK_BUFFERS - 1)
758  }
759  buffer = drawable->backBuffers[index];
760  rect = drawable->visibleRects;
761  if (drawable->usingFlipBuffers) {
762  PVR2DPresentFlip(pvrQwsDisplay.context, pvrQwsDisplay.flipChain, buffer, 0);
763  } else if (pvrQwsDisplay.usePresentBlit && drawable->numVisibleRects > 0) {
764  PVR2DRECT pvrRects[PVRQWS_MAX_VISIBLE_RECTS];
765  for (index = 0; index < drawable->numVisibleRects; ++index, ++rect) {
766  pvrRects[index].left = rect->x;
767  pvrRects[index].top = rect->y;
768  pvrRects[index].right = rect->x + rect->width;
769  pvrRects[index].bottom = rect->y + rect->height;
770  }
771  for (index = 0; index < drawable->numVisibleRects; index += 4) {
772  int numClip = drawable->numVisibleRects - index;
773  if (numClip > 4) /* No more than 4 clip rects at a time */
774  numClip = 4;
775  PVR2DSetPresentBltProperties
777  PVR2D_PRESENT_PROPERTY_SRCSTRIDE |
778  PVR2D_PRESENT_PROPERTY_DSTSIZE |
779  PVR2D_PRESENT_PROPERTY_DSTPOS |
780  PVR2D_PRESENT_PROPERTY_CLIPRECTS,
781  drawable->strideBytes,
782  drawable->rect.width, drawable->rect.height,
783  drawable->rect.x, drawable->rect.y,
784  numClip, pvrRects + index, 0);
785  PVR2DPresentBlt(pvrQwsDisplay.context, buffer, 0);
786  }
787  PVR2DQueryBlitsComplete(pvrQwsDisplay.context, buffer, 1);
788  } else {
789  /* TODO: use PVR2DBltClipped for faster transfers of clipped windows */
790  PVR2DBLTINFO blit;
791  for (index = 0; index < drawable->numVisibleRects; ++index, ++rect) {
792  memset(&blit, 0, sizeof(blit));
793 
794  blit.CopyCode = PVR2DROPcopy;
795  blit.BlitFlags = PVR2D_BLIT_DISABLE_ALL;
796 
797  blit.pSrcMemInfo = buffer;
798  blit.SrcStride = drawable->strideBytes;
799  blit.SrcX = rect->x - drawable->rect.x;
800  blit.SrcY = rect->y - drawable->rect.y;
801  blit.SizeX = rect->width;
802  blit.SizeY = rect->height;
803  blit.SrcFormat = drawable->pixelFormat;
804 
805  blit.pDstMemInfo = pvrQwsDisplay.screens[drawable->screen].frameBuffer;
806  blit.DstStride = pvrQwsDisplay.screens[drawable->screen].screenStride;
807  blit.DstX = rect->x;
808  blit.DstY = rect->y;
809  blit.DSizeX = rect->width;
810  blit.DSizeY = rect->height;
811  blit.DstFormat = pvrQwsDisplay.screens[drawable->screen].pixelFormat;
812 
813  PVR2DBlt(pvrQwsDisplay.context, &blit);
814  }
815  }
816 
817  /* Swap the buffers */
818  if (!repaintOnly) {
819  drawable->currentBackBuffer
820  = (drawable->currentBackBuffer + 1) % PVRQWS_MAX_BACK_BUFFERS;
821  }
822  return 1;
823 }
PVR2DMEMINFO * backBuffers[PVRQWS_MAX_BACK_BUFFERS]
PVR2DMEMINFO * frameBuffer
PVR2DFORMAT pixelFormat
PVR2DFLIPCHAINHANDLE flipChain
PVR2DCONTEXTHANDLE context
#define PVRQWS_MAX_BACK_BUFFERS
PvrQwsDisplay pvrQwsDisplay
PvrQwsRect visibleRects[PVRQWS_MAX_VISIBLE_RECTS]
PvrQwsSwapFunction swapFunction
PVR2DFORMAT pixelFormat
quint16 index
#define PVRQWS_MAX_VISIBLE_RECTS
PvrQwsScreenInfo screens[PVRQWS_MAX_SCREENS]

Variable Documentation

◆ pvrQwsDisplay

PvrQwsDisplay pvrQwsDisplay