Beispiel #1
0
static DFBResult
InitPVR2D( PVR2DData *pvr2d )
{
     PVR2DERROR       ePVR2DStatus;
     PVR2DDataShared *shared = pvr2d->shared;

     pvr2d->nDevices = PVR2DEnumerateDevices(0);
     pvr2d->pDevInfo = (PVR2DDEVICEINFO *) malloc(pvr2d->nDevices * sizeof(PVR2DDEVICEINFO));
     PVR2DEnumerateDevices(pvr2d->pDevInfo);
     pvr2d->nDeviceNum = pvr2d->pDevInfo[0].ulDevID;

     ePVR2DStatus = PVR2DCreateDeviceContext (pvr2d->nDeviceNum, &pvr2d->hPVR2DContext, 0);
     if (ePVR2DStatus) {
          D_ERROR( "DirectFB/PVR2D: PVR2DCreateDeviceContext() failed! (status %d)\n", ePVR2DStatus );
          return DFB_INIT;
     }

     ePVR2DStatus = PVR2DGetFrameBuffer( pvr2d->hPVR2DContext, PVR2D_FB_PRIMARY_SURFACE, &pvr2d->pFBMemInfo);
     if (ePVR2DStatus) {
          D_ERROR( "DirectFB/PVR2D: PVR2DGetFrameBuffer() failed! (status %d)\n", ePVR2DStatus );
          return DFB_INIT;
     }

     ePVR2DStatus = PVR2DGetScreenMode(pvr2d->hPVR2DContext, &pvr2d->eDisplayFormat, &pvr2d->lDisplayWidth, &pvr2d->lDisplayHeight, &pvr2d->lStride, &pvr2d->RefreshRate);
     if (ePVR2DStatus) {
          D_ERROR( "DirectFB/PVR2D: PVR2DGetScreenMode() failed! (status %d)\n", ePVR2DStatus );
          return DFB_INIT;
     }

     D_INFO( "DirectFB/PVR2D: Display %ldx%ld, format %d, stride %ld, refresh %d\n",
             pvr2d->lDisplayWidth, pvr2d->lDisplayHeight, pvr2d->eDisplayFormat, pvr2d->lStride, pvr2d->RefreshRate );

     shared->screen_size.w = pvr2d->lDisplayWidth;
     shared->screen_size.h = pvr2d->lDisplayHeight;

     return DFB_OK;
}
Beispiel #2
0
/* Called when a new drawable is added to ensure that we have a
   PVR2D context and framebuffer PVR2DMEMINFO blocks */
static int pvrQwsAddDrawable(void)
{
    int numDevs, screen;
    PVR2DDEVICEINFO *devs;
    unsigned long devId;
    unsigned long pageAddresses[2];
    PVR2DMEMINFO *memInfo;
    PVR2DDISPLAYINFO displayInfo;

    /* Bail out early if this is not the first drawable */
    if (pvrQwsDisplay.numDrawables > 0) {
        ++(pvrQwsDisplay.numDrawables);
        return 1;
    }

    /* Find the first PVR2D device in the system and open it */
    numDevs = PVR2DEnumerateDevices(0);
    if (numDevs <= 0)
        return 0;
    devs = (PVR2DDEVICEINFO *)malloc(sizeof(PVR2DDEVICEINFO) * numDevs);
    if (!devs)
        return 0;
    if (PVR2DEnumerateDevices(devs) != PVR2D_OK) {
        free(devs);
        return 0;
    }
    devId = devs[0].ulDevID;
    free(devs);
    if (PVR2DCreateDeviceContext(devId, &pvrQwsDisplay.context, 0) != PVR2D_OK)
        return 0;
    pvrQwsDisplay.numFlipBuffers = 0;
    pvrQwsDisplay.flipChain = 0;
    if (PVR2DGetDeviceInfo(pvrQwsDisplay.context, &displayInfo) == PVR2D_OK) {
        if (displayInfo.ulMaxFlipChains > 0 && displayInfo.ulMaxBuffersInChain > 0)
            pvrQwsDisplay.numFlipBuffers = displayInfo.ulMaxBuffersInChain;
        if (pvrQwsDisplay.numFlipBuffers > PVRQWS_MAX_FLIP_BUFFERS)
            pvrQwsDisplay.numFlipBuffers = PVRQWS_MAX_FLIP_BUFFERS;
    }

    /* Create the PVR2DMEMINFO blocks for the active framebuffers */
    for (screen = 0; screen < PVRQWS_MAX_SCREENS; ++screen) {
        if (screen != 0 && pvrQwsDisplay.screens[screen].mapped) {
            pageAddresses[0]
                = pvrQwsDisplay.screens[screen].screenStart & 0xFFFFF000;
            pageAddresses[1] = 0;
            if (PVR2DMemWrap
                    (pvrQwsDisplay.context,
                     pvrQwsDisplay.screens[screen].mapped,
                     PVR2D_WRAPFLAG_CONTIGUOUS,
                     pvrQwsDisplay.screens[screen].mappedLength,
                     pageAddresses, &memInfo) != PVR2D_OK) {
                PVR2DDestroyDeviceContext(pvrQwsDisplay.context);
                pvrQwsDisplay.context = 0;
                return 0;
            }
            pvrQwsDisplay.screens[screen].frameBuffer = memInfo;
        } else if (screen == 0) {
            if (PVR2DGetFrameBuffer
                    (pvrQwsDisplay.context,
                     PVR2D_FB_PRIMARY_SURFACE, &memInfo) != PVR2D_OK) {
                fprintf(stderr, "QWSWSEGL: could not get the primary framebuffer surface\n");
                PVR2DDestroyDeviceContext(pvrQwsDisplay.context);
                pvrQwsDisplay.context = 0;
                return 0;
            }
            pvrQwsDisplay.screens[screen].frameBuffer = memInfo;
            pvrQwsDisplay.screens[screen].mapped = memInfo->pBase;
        }
    }

    /* Create a flip chain for the screen if supported by the hardware */
    pvrQwsDisplay.usePresentBlit = 0;
    if (pvrQwsDisplay.numFlipBuffers > 0) {
        long stride = 0;
        unsigned long flipId = 0;
        unsigned long numBuffers;
        if (PVR2DCreateFlipChain(pvrQwsDisplay.context, 0,
                                 //PVR2D_CREATE_FLIPCHAIN_SHARED |
                                 //PVR2D_CREATE_FLIPCHAIN_QUERY,
                                 pvrQwsDisplay.numFlipBuffers,
                                 pvrQwsDisplay.screens[0].screenRect.width,
                                 pvrQwsDisplay.screens[0].screenRect.height,
                                 pvrQwsDisplay.screens[0].pixelFormat,
                                 &stride, &flipId, &(pvrQwsDisplay.flipChain))
                == PVR2D_OK) {
            pvrQwsDisplay.screens[0].screenStride = stride;
            PVR2DGetFlipChainBuffers(pvrQwsDisplay.context,
                                     pvrQwsDisplay.flipChain,
                                     &numBuffers,
                                     pvrQwsDisplay.flipBuffers);
        } else {
            pvrQwsDisplay.flipChain = 0;
            pvrQwsDisplay.numFlipBuffers = 0;
        }

        /* PVR2DPresentBlt is a little more reliable than PVR2DBlt
           when flip chains are present, even if we cannot create a
           flip chain at the moment */
        pvrQwsDisplay.usePresentBlit = 1;
    }

    /* The context is ready to go */
    ++(pvrQwsDisplay.numDrawables);
    return 1;
}
/* Create the WSEGL drawable version of a native window */
static WSEGLError wseglCreateWindowDrawable
    (WSEGLDisplayHandle display, WSEGLConfig *config,
     WSEGLDrawableHandle *drawable, NativeWindowType nativeWindow,
     WSEGLRotationAngle *rotationAngle)
{
    struct wl_egl_display *egldisplay = (struct wl_egl_display *) display;
    int index;
    /* Framebuffer */
    if (nativeWindow == NULL)
    {
       PVR2DDISPLAYINFO displayInfo;

       assert(egldisplay->display == NULL);

       /* Let's create a fake wl_egl_window to simplify code */

       nativeWindow = wl_egl_window_create(NULL, egldisplay->var.xres, egldisplay->var.yres);
       nativeWindow->format = getwseglPixelFormat(egldisplay);
       nativeWindow->display = egldisplay;

       assert(PVR2DGetDeviceInfo(egldisplay->context, &displayInfo) == PVR2D_OK);

       wsegl_debug("ulMaxFlipChains: %lu", displayInfo.ulMaxFlipChains);
       wsegl_debug("ulMaxBuffersInChain: %lu", displayInfo.ulMaxBuffersInChain);
       wsegl_debug("eFormat: %d", displayInfo.eFormat);
       wsegl_debug("ulWidth: %lu", displayInfo.ulWidth);
       wsegl_debug("ulHeight: %lu", displayInfo.ulHeight);
       wsegl_debug("lStride: %lu", displayInfo.lStride);
       wsegl_debug("ulMinFlipInterval: %lu", displayInfo.ulMinFlipInterval);
       wsegl_debug("ulMaxFlipInterval: %lu", displayInfo.ulMaxFlipInterval);

       if (displayInfo.ulMaxFlipChains > 0 && displayInfo.ulMaxBuffersInChain > 0)
              nativeWindow->numFlipBuffers = displayInfo.ulMaxBuffersInChain;
       if (nativeWindow->numFlipBuffers > WAYLANDWSEGL_MAX_FLIP_BUFFERS)
              nativeWindow->numFlipBuffers = WAYLANDWSEGL_MAX_FLIP_BUFFERS;

       /* Workaround for broken devices, seen in debugging */
//       if (nativeWindow->numFlipBuffers < 2)
              nativeWindow->numFlipBuffers = 0;
    }
    else
    {
       nativeWindow->display = egldisplay;
       nativeWindow->format = config->ePixelFormat;
    }

    /* We can't do empty buffers, so let's make a 8x8 one. */
    if (nativeWindow->width == 0 || nativeWindow->height == 0)
    {
        nativeWindow->width = nativeWindow->height = 8;
    }


    /* If we don't have back buffers allocated already */
    if (!(nativeWindow->backBuffers[0] && nativeWindow->backBuffersValid))
    {
       nativeWindow->stridePixels = (nativeWindow->width + 7) & ~7; 
       nativeWindow->strideBytes = nativeWindow->stridePixels * wseglPixelFormatBytesPP(nativeWindow->format);

       if (allocateBackBuffers(egldisplay, nativeWindow) == WSEGL_OUT_OF_MEMORY)
          return WSEGL_OUT_OF_MEMORY;

       /* Wayland window */  
       if (nativeWindow->display->display != NULL)
       {
            for (index = 0; index < WAYLANDWSEGL_MAX_BACK_BUFFERS; index++)
            {
              PVR2D_HANDLE name;

              assert(PVR2DMemExport(egldisplay->context, 0, nativeWindow->backBuffers[index], &name) == PVR2D_OK);
              nativeWindow->exporthandles[index] = name;

              // TODO: clear exporthandles up
            }
       }
       /* Framebuffer */
       else
       {
           /* XXX should assert something about stride etc.. */
           assert(PVR2DGetFrameBuffer(egldisplay->context, PVR2D_FB_PRIMARY_SURFACE, &nativeWindow->frontBufferPVRMEM) == PVR2D_OK);
           // nativeWindow->frontBuffer = (void *) nativeWindow->frontBufferPVRMEM->pBase;
       }
    }      
  
    *drawable = (WSEGLDrawableHandle) nativeWindow; /* Reuse the egldisplay */
    *rotationAngle = WSEGL_ROTATE_0;
    return WSEGL_SUCCESS;
}
Beispiel #4
0
/* Create the WSEGL drawable version of a native window */
static WSEGLError wseglCreateWindowDrawable
    (WSEGLDisplayHandle display, WSEGLConfig *config,
     WSEGLDrawableHandle *drawable, NativeWindowType nativeWindow,
     WSEGLRotationAngle *rotationAngle)
{
    struct wl_egl_display *egldisplay = (struct wl_egl_display *) display;
    int index;
    /* Framebuffer */
    if (nativeWindow == NULL)
    {
       PVR2DDISPLAYINFO displayInfo;

       assert(egldisplay->display == NULL);

       /* Let's create a fake wl_egl_window to simplify code */

       nativeWindow = wl_egl_window_create(NULL, egldisplay->var.xres, egldisplay->var.yres);
       nativeWindow->format = getwseglPixelFormat(egldisplay);
       nativeWindow->display = egldisplay;

       assert(PVR2DGetDeviceInfo(egldisplay->context, &displayInfo) == PVR2D_OK);

       if (displayInfo.ulMaxFlipChains > 0 && displayInfo.ulMaxBuffersInChain > 0)
              nativeWindow->numFlipBuffers = displayInfo.ulMaxBuffersInChain;
       if (nativeWindow->numFlipBuffers > WAYLANDWSEGL_MAX_FLIP_BUFFERS)
              nativeWindow->numFlipBuffers = WAYLANDWSEGL_MAX_FLIP_BUFFERS;

       /* Workaround for broken devices, seen in debugging */
       if (nativeWindow->numFlipBuffers < 2)
              nativeWindow->numFlipBuffers = 0;
    }
    else
    {
       nativeWindow->display = egldisplay;
           nativeWindow->format = WSEGL_PIXELFORMAT_8888;
    }

    /* We can't do empty buffers, so let's make a 8x8 one. */
    if (nativeWindow->width == 0 || nativeWindow->height == 0)
    {
        nativeWindow->width = nativeWindow->height = 8;
    }


    /* If we don't have back buffers allocated already */
    if (!(nativeWindow->backBuffers[0] && nativeWindow->backBuffersValid))
    {
       nativeWindow->stridePixels = (nativeWindow->width + 7) & ~7; 
       nativeWindow->strideBytes = nativeWindow->stridePixels * wseglPixelFormatBytesPP(nativeWindow->format);

       if (allocateBackBuffers(egldisplay, nativeWindow) == WSEGL_OUT_OF_MEMORY)
          return WSEGL_OUT_OF_MEMORY;

       /* Wayland window */  
       if (nativeWindow->display->display != NULL)
       {
            for (index = 0; index < WAYLANDWSEGL_MAX_BACK_BUFFERS; index++)
            {
              PVR2D_HANDLE name;

              assert(PVR2DMemExport(egldisplay->context, 0, nativeWindow->backBuffers[index], &name) == PVR2D_OK);                 

              nativeWindow->drmbuffers[index] = wl_drm_create_buffer(egldisplay->drm, (uint32_t)name, 
                 nativeWindow->width, nativeWindow->height, nativeWindow->strideBytes, nativeWindow->format);
              assert(nativeWindow->drmbuffers[index] != NULL);
            }
       }
       /* Framebuffer */
       else
       {
           assert(PVR2DGetFrameBuffer(egldisplay->context, PVR2D_FB_PRIMARY_SURFACE, &nativeWindow->frontBufferPVRMEM) == PVR2D_OK);
       }
    }      
  
    *drawable = (WSEGLDrawableHandle) nativeWindow; /* Reuse the egldisplay */
    *rotationAngle = WSEGL_ROTATE_0;
    return WSEGL_SUCCESS;
}