/* Delete a specific drawable */ static WSEGLError wseglDeleteDrawable(WSEGLDrawableHandle _drawable) { struct wl_egl_window *drawable = (struct wl_egl_window *) _drawable; int index; int numBuffers = WAYLANDWSEGL_MAX_BACK_BUFFERS; if (drawable->header.type == WWSEGL_DRAWABLE_TYPE_WINDOW) { for (index = 0; index < numBuffers; ++index) { if (drawable->drmbuffers[index]) wl_buffer_destroy(drawable->drmbuffers[index]); if (drawable->backBuffers[index]) PVR2DMemFree(drawable->display->context, drawable->backBuffers[index]); } memset(drawable->drmbuffers, 0, sizeof(drawable->drmbuffers)); memset(drawable->backBuffers, 0, sizeof(drawable->backBuffers)); drawable->backBuffersValid = 0; return WSEGL_SUCCESS; } else if (drawable->header.type == WWSEGL_DRAWABLE_TYPE_PIXMAP) { struct wl_egl_pixmap *pixmap = (struct wl_egl_pixmap *)drawable; PVR2DMemFree(pixmap->display->context, pixmap->pvrmem); } else { assert(0); } return WSEGL_SUCCESS; }
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 doDestroyMemory(struct PVR2DPixmap *ppix) { CALLTRACE("%s: Start\n", __func__); #if SGX_CACHE_SEGMENTS if (AddToCache (ppix)) return; #endif if (ppix->pvr2dmem) { PVR2DMemFree(pvr2d_get_screen()->context, ppix->pvr2dmem); ppix->pvr2dmem = NULL; } if (ppix->shmid != -1) { shmdt(ppix->shmaddr); ppix->shmaddr = NULL; ppix->shmid = -1; PERF_DECREMENT2(shm_bytes, ppix->shmsize); PERF_DECREMENT(shm_segments); ppix->shmsize = 0; } if (ppix->mallocaddr) { free(ppix->mallocaddr); ppix->mallocaddr = NULL; PERF_DECREMENT2(malloc_bytes, ppix->mallocsize); PERF_DECREMENT(malloc_segments); ppix->mallocsize = 0; } }
int pvrQwsAllocBuffers(PvrQwsDrawable *drawable) { int index; int numBuffers = PVRQWS_MAX_BACK_BUFFERS; if (drawable->type == PvrQwsPixmap) numBuffers = 1; if (drawable->backBuffers[0]) { if (drawable->backBuffersValid) return 1; if (!drawable->usingFlipBuffers) { for (index = 0; index < numBuffers; ++index) PVR2DMemFree(pvrQwsDisplay.context, drawable->backBuffers[index]); } } drawable->stridePixels = (drawable->rect.width + 31) & ~31; drawable->strideBytes = drawable->stridePixels * pvrQwsDisplay.screens[drawable->screen].bytesPerPixel; drawable->usingFlipBuffers = (pvrQwsDisplay.numFlipBuffers > 0 && drawable->isFullScreen); if (drawable->usingFlipBuffers) { if (numBuffers > (int)(pvrQwsDisplay.numFlipBuffers)) numBuffers = pvrQwsDisplay.numFlipBuffers; for (index = 0; index < numBuffers; ++index) drawable->backBuffers[index] = pvrQwsDisplay.flipBuffers[index]; } else { for (index = 0; index < numBuffers; ++index) { if (PVR2DMemAlloc(pvrQwsDisplay.context, drawable->strideBytes * drawable->rect.height, 128, 0, &(drawable->backBuffers[index])) != PVR2D_OK) { while (--index >= 0) PVR2DMemFree(pvrQwsDisplay.context, drawable->backBuffers[index]); memset(drawable->backBuffers, 0, sizeof(drawable->backBuffers)); drawable->backBuffersValid = 0; return 0; } } } for (index = numBuffers; index < PVRQWS_MAX_BACK_BUFFERS; ++index) { drawable->backBuffers[index] = drawable->backBuffers[0]; } drawable->backBuffersValid = 1; drawable->currentBackBuffer = 0; return 1; }
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; }
static void gst_ducati_buffer_finalize (GstDucatiBuffer * self) { PVR2DERROR pvr_error; GstPvrBufferPool *pool = self->pool; gboolean resuscitated = FALSE; GST_LOG_OBJECT (pool->element, "finalizing buffer %p", self); GST_PVR_BUFFERPOOL_LOCK (pool); g_queue_remove (pool->used_buffers, self); if (pool->running) { resuscitated = TRUE; GST_LOG_OBJECT (pool->element, "reviving buffer %p", self); g_queue_push_head (pool->free_buffers, self); } else { GST_LOG_OBJECT (pool->element, "the pool is shutting down"); } GST_PVR_BUFFERPOOL_UNLOCK (pool); if (resuscitated) { GST_LOG_OBJECT (pool->element, "reviving buffer %p, %d", self, index); gst_buffer_ref (GST_BUFFER (self)); GST_BUFFER_SIZE (self) = 0; } if (!resuscitated) { GST_LOG_OBJECT (pool->element, "buffer %p (data %p, len %u) not recovered, freeing", self, GST_BUFFER_DATA (self), GST_BUFFER_SIZE (self)); if (self->wrapped) { pvr_error = PVR2DMemFree (pool->pvr_context, self->src_mem); if (pvr_error != PVR2D_OK) { GST_ERROR_OBJECT (pool->element, "Failed to Unwrap buffer memory" "returned %d", pvr_error); } self->wrapped = FALSE; } MemMgr_Free ((void *) GST_BUFFER_DATA (self)); GST_BUFFER_DATA (self) = NULL; gst_mini_object_unref (GST_MINI_OBJECT (pool)); GST_MINI_OBJECT_CLASS (buffer_parent_class)->finalize (GST_MINI_OBJECT (self)); } }
void pvrQwsFreeBuffers(PvrQwsDrawable *drawable) { int index; int numBuffers = PVRQWS_MAX_BACK_BUFFERS; if (drawable->type == PvrQwsPixmap) numBuffers = 1; if (!drawable->usingFlipBuffers) { for (index = 0; index < numBuffers; ++index) { if (drawable->backBuffers[index]) PVR2DMemFree(pvrQwsDisplay.context, drawable->backBuffers[index]); } } memset(drawable->backBuffers, 0, sizeof(drawable->backBuffers)); drawable->backBuffersValid = 0; drawable->usingFlipBuffers = 0; }
static void unwrap_buffer (gpointer buffer, gpointer user_data) { PVR2DERROR pvr_error; GstDucatiBuffer *buf = GST_DUCATIBUFFER (buffer); GstPvrBufferPool *pool = (GstPvrBufferPool *) user_data; if (buf->wrapped) { pvr_error = PVR2DMemFree (pool->pvr_context, buf->src_mem); if (pvr_error != PVR2D_OK) { GST_ERROR_OBJECT (pool->element, "Failed to Unwrap buffer memory" "returned %d", pvr_error); } buf->wrapped = FALSE; } }
/* 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; }