void pvrQwsDisplayClose(void) { int screen; if (pvrQwsDisplay.refCount == 0) return; if (--(pvrQwsDisplay.refCount) > 0) return; /* Prevent pvrQwsDestroyContext from being called for the time being */ ++pvrQwsDisplay.numDrawables; /* Free the screens */ for (screen = 0; screen < PVRQWS_MAX_SCREENS; ++screen) { PvrQwsScreenInfo *info = &(pvrQwsDisplay.screens[screen]); if (info->screenDrawable) pvrQwsDestroyDrawableForced(info->screenDrawable); if (info->frameBuffer) PVR2DMemFree(pvrQwsDisplay.context, info->frameBuffer); if (info->mapped && info->needsUnmap) munmap(info->mapped, info->mappedLength); } /* Now it is safe to destroy the PVR2D context */ --pvrQwsDisplay.numDrawables; if (pvrQwsDisplay.context) PVR2DDestroyDeviceContext(pvrQwsDisplay.context); memset(&pvrQwsDisplay, 0, sizeof(pvrQwsDisplay)); }
static void wseglReleaseContext(struct wl_egl_display *nativeDisplay) { if (nativeDisplay->context_refcnt > 0) { nativeDisplay->context_refcnt--; if (nativeDisplay->context_refcnt == 0) { PVR2DDestroyDeviceContext(nativeDisplay->context); nativeDisplay->context = 0; } } }
/* 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; 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; }