summaryrefslogtreecommitdiffstats
path: root/gfx/layers/opengl/TexturePoolOGL.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/layers/opengl/TexturePoolOGL.cpp')
-rw-r--r--gfx/layers/opengl/TexturePoolOGL.cpp123
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