1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
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
|