/* Called when the last drawable is destroyed. The PVR2D context will be destroyed but the raw framebuffer memory will stay mapped */ static void pvrQwsDestroyContext(void) { int screen; for (screen = 0; screen < PVRQWS_MAX_SCREENS; ++screen) { if (pvrQwsDisplay.screens[screen].frameBuffer) { PVR2DMemFree (pvrQwsDisplay.context, pvrQwsDisplay.screens[screen].frameBuffer); pvrQwsDisplay.screens[screen].frameBuffer = 0; } } if (pvrQwsDisplay.numFlipBuffers > 0) PVR2DDestroyFlipChain(pvrQwsDisplay.context, pvrQwsDisplay.flipChain); PVR2DDestroyDeviceContext(pvrQwsDisplay.context); pvrQwsDisplay.context = 0; pvrQwsDisplay.flipChain = 0; pvrQwsDisplay.numFlipBuffers = 0; pvrQwsDisplay.usePresentBlit = 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; #ifndef QT_WEBOS 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) { #else // QT_WEBOS if (PVR2DCreateFlipChain(pvrQwsDisplay.context, PVR2D_CREATE_FLIPCHAIN_FB0, //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) { #endif // QT_WEBOS 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; } /* Called when the last drawable is destroyed. The PVR2D context will be destroyed but the raw framebuffer memory will stay mapped */ static void pvrQwsDestroyContext(void) { int screen; for (screen = 0; screen < PVRQWS_MAX_SCREENS; ++screen) { if (pvrQwsDisplay.screens[screen].frameBuffer) { PVR2DMemFree (pvrQwsDisplay.context, pvrQwsDisplay.screens[screen].frameBuffer); pvrQwsDisplay.screens[screen].frameBuffer = 0; } } if (pvrQwsDisplay.numFlipBuffers > 0) PVR2DDestroyFlipChain(pvrQwsDisplay.context, pvrQwsDisplay.flipChain); PVR2DDestroyDeviceContext(pvrQwsDisplay.context); pvrQwsDisplay.context = 0; pvrQwsDisplay.flipChain = 0; pvrQwsDisplay.numFlipBuffers = 0; pvrQwsDisplay.usePresentBlit = 0; }