|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
|
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 #include "TexturePoolOGL.h" |
|
6 #include <stdlib.h> // for malloc |
|
7 #include "GLContext.h" // for GLContext |
|
8 #include "mozilla/Monitor.h" // for Monitor, MonitorAutoLock |
|
9 #include "mozilla/mozalloc.h" // for operator delete, etc |
|
10 #include "nsDebug.h" // for NS_ASSERTION, NS_ERROR, etc |
|
11 #include "nsDeque.h" // for nsDeque |
|
12 |
|
13 #define TEXTURE_POOL_SIZE 10 |
|
14 |
|
15 namespace mozilla { |
|
16 namespace gl { |
|
17 |
|
18 static GLContext* sActiveContext = nullptr; |
|
19 |
|
20 static Monitor* sMonitor = nullptr; |
|
21 static nsDeque* sTextures = nullptr; |
|
22 |
|
23 GLuint TexturePoolOGL::AcquireTexture() |
|
24 { |
|
25 NS_ASSERTION(sMonitor, "not initialized"); |
|
26 |
|
27 MonitorAutoLock lock(*sMonitor); |
|
28 |
|
29 if (!sActiveContext) { |
|
30 // Wait for a context |
|
31 sMonitor->Wait(); |
|
32 |
|
33 if (!sActiveContext) |
|
34 return 0; |
|
35 } |
|
36 |
|
37 GLuint texture = 0; |
|
38 if (sActiveContext->IsOwningThreadCurrent()) { |
|
39 sActiveContext->MakeCurrent(); |
|
40 |
|
41 sActiveContext->fGenTextures(1, &texture); |
|
42 } else { |
|
43 while (sTextures->GetSize() == 0) { |
|
44 NS_WARNING("Waiting for texture"); |
|
45 sMonitor->Wait(); |
|
46 } |
|
47 |
|
48 GLuint* popped = (GLuint*) sTextures->Pop(); |
|
49 if (!popped) { |
|
50 NS_ERROR("Failed to pop texture pool item"); |
|
51 return 0; |
|
52 } |
|
53 |
|
54 texture = *popped; |
|
55 delete popped; |
|
56 |
|
57 NS_ASSERTION(texture, "Failed to retrieve texture from pool"); |
|
58 } |
|
59 |
|
60 return texture; |
|
61 } |
|
62 |
|
63 static void Clear() |
|
64 { |
|
65 if (!sActiveContext) |
|
66 return; |
|
67 |
|
68 sActiveContext->MakeCurrent(); |
|
69 |
|
70 GLuint* item; |
|
71 while (sTextures->GetSize()) { |
|
72 item = (GLuint*)sTextures->Pop(); |
|
73 sActiveContext->fDeleteTextures(1, item); |
|
74 delete item; |
|
75 } |
|
76 } |
|
77 |
|
78 void TexturePoolOGL::Fill(GLContext* aContext) |
|
79 { |
|
80 NS_ASSERTION(aContext, "NULL GLContext"); |
|
81 NS_ASSERTION(sMonitor, "not initialized"); |
|
82 |
|
83 MonitorAutoLock lock(*sMonitor); |
|
84 |
|
85 if (sActiveContext != aContext) { |
|
86 Clear(); |
|
87 sActiveContext = aContext; |
|
88 } |
|
89 |
|
90 if (sTextures->GetSize() == TEXTURE_POOL_SIZE) |
|
91 return; |
|
92 |
|
93 sActiveContext->MakeCurrent(); |
|
94 |
|
95 GLuint* texture = nullptr; |
|
96 while (sTextures->GetSize() < TEXTURE_POOL_SIZE) { |
|
97 texture = (GLuint*)malloc(sizeof(GLuint)); |
|
98 sActiveContext->fGenTextures(1, texture); |
|
99 sTextures->Push((void*) texture); |
|
100 } |
|
101 |
|
102 sMonitor->NotifyAll(); |
|
103 } |
|
104 |
|
105 void TexturePoolOGL::Init() |
|
106 { |
|
107 sMonitor = new Monitor("TexturePoolOGL.sMonitor"); |
|
108 sTextures = new nsDeque(); |
|
109 } |
|
110 |
|
111 void TexturePoolOGL::Shutdown() |
|
112 { |
|
113 delete sMonitor; |
|
114 delete sTextures; |
|
115 } |
|
116 |
|
117 } // gl |
|
118 } // mozilla |