diff options
Diffstat (limited to 'gfx/layers/opengl/TexturePoolOGL.cpp')
-rw-r--r-- | gfx/layers/opengl/TexturePoolOGL.cpp | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/gfx/layers/opengl/TexturePoolOGL.cpp b/gfx/layers/opengl/TexturePoolOGL.cpp new file mode 100644 index 000000000..8ee3b4cbb --- /dev/null +++ b/gfx/layers/opengl/TexturePoolOGL.cpp @@ -0,0 +1,123 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "TexturePoolOGL.h" +#include <stdlib.h> // for malloc +#include "GLContext.h" // for GLContext +#include "mozilla/Monitor.h" // for Monitor, MonitorAutoLock +#include "mozilla/mozalloc.h" // for operator delete, etc +#include "nsDebug.h" // for NS_ASSERTION, NS_ERROR, etc +#include "nsDeque.h" // for nsDeque + +#define TEXTURE_POOL_SIZE 10 + +namespace mozilla { +namespace gl { + +static GLContext* sActiveContext = nullptr; + +static Monitor* sMonitor = nullptr; +static nsDeque* sTextures = nullptr; + +GLuint TexturePoolOGL::AcquireTexture() +{ + NS_ASSERTION(sMonitor, "not initialized"); + + MonitorAutoLock lock(*sMonitor); + + if (!sActiveContext) { + // Wait for a context + sMonitor->Wait(); + + if (!sActiveContext) + return 0; + } + + GLuint texture = 0; + if (sActiveContext->IsOwningThreadCurrent()) { + sActiveContext->MakeCurrent(); + + sActiveContext->fGenTextures(1, &texture); + } else { + while (sTextures->GetSize() == 0) { + NS_WARNING("Waiting for texture"); + sMonitor->Wait(); + } + + GLuint* popped = (GLuint*) sTextures->Pop(); + if (!popped) { + NS_ERROR("Failed to pop texture pool item"); + return 0; + } + + texture = *popped; + delete popped; + + NS_ASSERTION(texture, "Failed to retrieve texture from pool"); + } + + return texture; +} + +static void Clear() +{ + if (!sActiveContext) + return; + + sActiveContext->MakeCurrent(); + + GLuint* item; + while (sTextures->GetSize()) { + item = (GLuint*)sTextures->Pop(); + sActiveContext->fDeleteTextures(1, item); + delete item; + } +} + +void TexturePoolOGL::Fill(GLContext* aContext) +{ + NS_ASSERTION(aContext, "NULL GLContext"); + NS_ASSERTION(sMonitor, "not initialized"); + + MonitorAutoLock lock(*sMonitor); + + if (sActiveContext != aContext) { + Clear(); + sActiveContext = aContext; + } + + if (sTextures->GetSize() == TEXTURE_POOL_SIZE) + return; + + sActiveContext->MakeCurrent(); + + GLuint* texture = nullptr; + while (sTextures->GetSize() < TEXTURE_POOL_SIZE) { + texture = (GLuint*)malloc(sizeof(GLuint)); + sActiveContext->fGenTextures(1, texture); + sTextures->Push((void*) texture); + } + + sMonitor->NotifyAll(); +} + +GLContext* TexturePoolOGL::GetGLContext() +{ + return sActiveContext; +} + +void TexturePoolOGL::Init() +{ + sMonitor = new Monitor("TexturePoolOGL.sMonitor"); + sTextures = new nsDeque(); +} + +void TexturePoolOGL::Shutdown() +{ + delete sMonitor; + delete sTextures; +} + +} // namespace gl +} // namespace mozilla |