michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this file, michael@0: * You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "TexturePoolOGL.h" michael@0: #include // for malloc michael@0: #include "GLContext.h" // for GLContext michael@0: #include "mozilla/Monitor.h" // for Monitor, MonitorAutoLock michael@0: #include "mozilla/mozalloc.h" // for operator delete, etc michael@0: #include "nsDebug.h" // for NS_ASSERTION, NS_ERROR, etc michael@0: #include "nsDeque.h" // for nsDeque michael@0: michael@0: #define TEXTURE_POOL_SIZE 10 michael@0: michael@0: namespace mozilla { michael@0: namespace gl { michael@0: michael@0: static GLContext* sActiveContext = nullptr; michael@0: michael@0: static Monitor* sMonitor = nullptr; michael@0: static nsDeque* sTextures = nullptr; michael@0: michael@0: GLuint TexturePoolOGL::AcquireTexture() michael@0: { michael@0: NS_ASSERTION(sMonitor, "not initialized"); michael@0: michael@0: MonitorAutoLock lock(*sMonitor); michael@0: michael@0: if (!sActiveContext) { michael@0: // Wait for a context michael@0: sMonitor->Wait(); michael@0: michael@0: if (!sActiveContext) michael@0: return 0; michael@0: } michael@0: michael@0: GLuint texture = 0; michael@0: if (sActiveContext->IsOwningThreadCurrent()) { michael@0: sActiveContext->MakeCurrent(); michael@0: michael@0: sActiveContext->fGenTextures(1, &texture); michael@0: } else { michael@0: while (sTextures->GetSize() == 0) { michael@0: NS_WARNING("Waiting for texture"); michael@0: sMonitor->Wait(); michael@0: } michael@0: michael@0: GLuint* popped = (GLuint*) sTextures->Pop(); michael@0: if (!popped) { michael@0: NS_ERROR("Failed to pop texture pool item"); michael@0: return 0; michael@0: } michael@0: michael@0: texture = *popped; michael@0: delete popped; michael@0: michael@0: NS_ASSERTION(texture, "Failed to retrieve texture from pool"); michael@0: } michael@0: michael@0: return texture; michael@0: } michael@0: michael@0: static void Clear() michael@0: { michael@0: if (!sActiveContext) michael@0: return; michael@0: michael@0: sActiveContext->MakeCurrent(); michael@0: michael@0: GLuint* item; michael@0: while (sTextures->GetSize()) { michael@0: item = (GLuint*)sTextures->Pop(); michael@0: sActiveContext->fDeleteTextures(1, item); michael@0: delete item; michael@0: } michael@0: } michael@0: michael@0: void TexturePoolOGL::Fill(GLContext* aContext) michael@0: { michael@0: NS_ASSERTION(aContext, "NULL GLContext"); michael@0: NS_ASSERTION(sMonitor, "not initialized"); michael@0: michael@0: MonitorAutoLock lock(*sMonitor); michael@0: michael@0: if (sActiveContext != aContext) { michael@0: Clear(); michael@0: sActiveContext = aContext; michael@0: } michael@0: michael@0: if (sTextures->GetSize() == TEXTURE_POOL_SIZE) michael@0: return; michael@0: michael@0: sActiveContext->MakeCurrent(); michael@0: michael@0: GLuint* texture = nullptr; michael@0: while (sTextures->GetSize() < TEXTURE_POOL_SIZE) { michael@0: texture = (GLuint*)malloc(sizeof(GLuint)); michael@0: sActiveContext->fGenTextures(1, texture); michael@0: sTextures->Push((void*) texture); michael@0: } michael@0: michael@0: sMonitor->NotifyAll(); michael@0: } michael@0: michael@0: void TexturePoolOGL::Init() michael@0: { michael@0: sMonitor = new Monitor("TexturePoolOGL.sMonitor"); michael@0: sTextures = new nsDeque(); michael@0: } michael@0: michael@0: void TexturePoolOGL::Shutdown() michael@0: { michael@0: delete sMonitor; michael@0: delete sTextures; michael@0: } michael@0: michael@0: } // gl michael@0: } // mozilla