https://github.com/mozilla/gecko-dev
Raw File
Tip revision: ada020a603076a1c7dd7e89ba02cb2fd210d55e6 authored by Jeff Walden on 30 May 2014, 02:59:41 UTC
Bug 999651, bug 995679, bug 1009952, bug 1011007, bug 991981. r=sfink, r=shu, r=jandem, r=jdm, r=luke, r=bbouvier, r=nmatsakis, r=bz, r=ehsan, r=jgilbert, r=smaug, r=sicking, r=terrence, r=bholley, r=bent, r=efaust, r=jorendorff, a=1.2.x+
Tip revision: ada020a
TexturePoolOGL.cpp
/* 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();
}

void TexturePoolOGL::Init()
{
  sMonitor = new Monitor("TexturePoolOGL.sMonitor");
  sTextures = new nsDeque();
}

void TexturePoolOGL::Shutdown()
{
  delete sMonitor;
  delete sTextures;
}

} // gl
} // mozilla
back to top