static WSEGLError allocateBackBuffers(struct wl_egl_display *egldisplay, NativeWindowType nativeWindow)
{
    int index;
    
    if (nativeWindow->numFlipBuffers)
    {
        long stride = 0;
        
        unsigned long flipId = 0;
        unsigned long numBuffers;
        PVR2DERROR ret = PVR2DCreateFlipChain(egldisplay->context, 0,
                                 //PVR2D_CREATE_FLIPCHAIN_SHARED |
                                 //PVR2D_CREATE_FLIPCHAIN_QUERY,
                                 nativeWindow->numFlipBuffers,
                                 nativeWindow->width,
                                 nativeWindow->height,
                                 wsegl2pvr2dformat(nativeWindow->format),
                                 &stride, &flipId, &(nativeWindow->flipChain));
        assert(ret == PVR2D_OK); 
        PVR2DGetFlipChainBuffers(egldisplay->context,
                                     nativeWindow->flipChain,
                                     &numBuffers,
                                     nativeWindow->flipBuffers);
        for (index = 0; index < numBuffers; ++index)
        {
             nativeWindow->backBuffers[index] = nativeWindow->flipBuffers[index];
        }
    }
    else {
	    for (index = 0; index < WAYLANDWSEGL_MAX_BACK_BUFFERS; ++index)
	    {
		if (PVR2DMemAlloc(egldisplay->context,
			      nativeWindow->strideBytes * nativeWindow->height,
	 		      128, 0,
			      &(nativeWindow->backBuffers[index])) != PVR2D_OK)
	        {
		       assert(0);
					       
		       while (--index >= 0)
				PVR2DMemFree(egldisplay->context, nativeWindow->backBuffers[index]);
			       
	               memset(nativeWindow->backBuffers, 0, sizeof(nativeWindow->backBuffers));
		       
		       nativeWindow->backBuffersValid = 0;
   		       
			       
		       return WSEGL_OUT_OF_MEMORY;
	        }
	    }
    }
    nativeWindow->backBuffersValid = 1;
    nativeWindow->currentBackBuffer = 0;
    return WSEGL_SUCCESS;
}
Exemplo n.º 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;
}