OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 | 8 |
9 #include "gl/GrGLInterface.h" | 9 #include "gl/GrGLInterface.h" |
10 #include "GrGLDefines.h" | 10 #include "GrGLDefines.h" |
11 #include "SkTDArray.h" | 11 #include "SkTDArray.h" |
12 #include "GrGLNoOpInterface.h" | 12 #include "GrGLNoOpInterface.h" |
13 | 13 |
14 // Functions not declared in GrGLBogusInterface.h (not common with the Debug GL
interface). | 14 // Functions not declared in GrGLBogusInterface.h (not common with the Debug GL
interface). |
15 | 15 |
16 namespace { // added to suppress 'no previous prototype' warning | 16 namespace { // added to suppress 'no previous prototype' warning |
17 | 17 |
| 18 class GrBufferObj { |
| 19 public: |
| 20 GrBufferObj(GrGLuint id) : fID(id), fDataPtr(NULL), fSize(0), fMapped(false)
{ |
| 21 } |
| 22 ~GrBufferObj() { SkDELETE_ARRAY(fDataPtr); } |
| 23 |
| 24 void allocate(GrGLint size, const GrGLchar* dataPtr) { |
| 25 if (NULL != fDataPtr) { |
| 26 GrAssert(0 != fSize); |
| 27 SkDELETE_ARRAY(fDataPtr); |
| 28 } |
| 29 |
| 30 fSize = size; |
| 31 fDataPtr = SkNEW_ARRAY(char, size); |
| 32 } |
| 33 |
| 34 GrGLuint id() const { return fID; } |
| 35 GrGLchar* dataPtr() { return fDataPtr; } |
| 36 GrGLint size() const { return fSize; } |
| 37 |
| 38 void setMapped(bool mapped) { fMapped = mapped; } |
| 39 bool mapped() const { return fMapped; } |
| 40 |
| 41 private: |
| 42 GrGLuint fID; |
| 43 GrGLchar* fDataPtr; |
| 44 GrGLint fSize; // size in bytes |
| 45 bool fMapped; |
| 46 }; |
| 47 |
| 48 // In debug builds we do asserts that ensure we agree with GL about when a buffe
r |
| 49 // is mapped. |
| 50 static SkTDArray<GrBufferObj*> gBuffers; // slot 0 is reserved for head of free
list |
| 51 static GrGLuint gCurrArrayBuffer; |
| 52 static GrGLuint gCurrElementArrayBuffer; |
| 53 |
| 54 static GrBufferObj* look_up(GrGLuint id) { |
| 55 GrBufferObj* buffer = gBuffers[id]; |
| 56 GrAssert(NULL != buffer && buffer->id() == id); |
| 57 return buffer; |
| 58 } |
| 59 |
| 60 static GrBufferObj* create_buffer() { |
| 61 if (0 == gBuffers.count()) { |
| 62 // slot zero is reserved for the head of the free list |
| 63 *gBuffers.append() = NULL; |
| 64 } |
| 65 |
| 66 GrGLuint id; |
| 67 GrBufferObj* buffer; |
| 68 |
| 69 if (NULL == gBuffers[0]) { |
| 70 // no free slots - create a new one |
| 71 id = gBuffers.count(); |
| 72 buffer = SkNEW_ARGS(GrBufferObj, (id)); |
| 73 gBuffers.append(1, &buffer); |
| 74 } else { |
| 75 // recycle a slot from the free list |
| 76 id = (GrGLuint) gBuffers[0]; |
| 77 gBuffers[0] = gBuffers[id]; |
| 78 |
| 79 buffer = SkNEW_ARGS(GrBufferObj, (id)); |
| 80 gBuffers[id] = buffer; |
| 81 } |
| 82 |
| 83 return buffer; |
| 84 } |
| 85 |
| 86 static void delete_buffer(GrBufferObj* buffer) { |
| 87 GrAssert(gBuffers.count() > 0); |
| 88 |
| 89 GrGLuint id = buffer->id(); |
| 90 SkDELETE(buffer); |
| 91 |
| 92 // Add this slot to the free list |
| 93 gBuffers[id] = gBuffers[0]; |
| 94 gBuffers[0] = (GrBufferObj*) id; |
| 95 } |
| 96 |
18 GrGLvoid GR_GL_FUNCTION_TYPE nullGLActiveTexture(GrGLenum texture) {} | 97 GrGLvoid GR_GL_FUNCTION_TYPE nullGLActiveTexture(GrGLenum texture) {} |
19 GrGLvoid GR_GL_FUNCTION_TYPE nullGLAttachShader(GrGLuint program, GrGLuint shade
r) {} | 98 GrGLvoid GR_GL_FUNCTION_TYPE nullGLAttachShader(GrGLuint program, GrGLuint shade
r) {} |
20 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBeginQuery(GrGLenum target, GrGLuint id) {} | 99 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBeginQuery(GrGLenum target, GrGLuint id) {} |
21 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindAttribLocation(GrGLuint program, GrGLuint
index, const char* name) {} | 100 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindAttribLocation(GrGLuint program, GrGLuint
index, const char* name) {} |
22 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindTexture(GrGLenum target, GrGLuint texture
) {} | 101 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindTexture(GrGLenum target, GrGLuint texture
) {} |
23 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindVertexArray(GrGLuint id) {} | 102 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindVertexArray(GrGLuint id) {} |
24 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBufferData(GrGLenum target, GrGLsizeiptr size
, const GrGLvoid* data, GrGLenum usage) {} | 103 |
| 104 GrGLvoid GR_GL_FUNCTION_TYPE nullGLGenBuffers(GrGLsizei n, GrGLuint* ids) { |
| 105 |
| 106 for (int i = 0; i < n; ++i) { |
| 107 GrBufferObj* buffer = create_buffer(); |
| 108 ids[i] = buffer->id(); |
| 109 } |
| 110 } |
| 111 |
| 112 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBufferData(GrGLenum target, |
| 113 GrGLsizeiptr size, |
| 114 const GrGLvoid* data, |
| 115 GrGLenum usage) { |
| 116 GrGLuint id = 0; |
| 117 |
| 118 switch (target) { |
| 119 case GR_GL_ARRAY_BUFFER: |
| 120 id = gCurrArrayBuffer; |
| 121 break; |
| 122 case GR_GL_ELEMENT_ARRAY_BUFFER: |
| 123 id = gCurrElementArrayBuffer; |
| 124 break; |
| 125 default: |
| 126 GrCrash("Unexpected target to nullGLBufferData"); |
| 127 break; |
| 128 } |
| 129 |
| 130 if (id > 0) { |
| 131 GrBufferObj* buffer = look_up(id); |
| 132 buffer->allocate(size, (const GrGLchar*) data); |
| 133 } |
| 134 } |
| 135 |
25 GrGLvoid GR_GL_FUNCTION_TYPE nullGLPixelStorei(GrGLenum pname, GrGLint param) {} | 136 GrGLvoid GR_GL_FUNCTION_TYPE nullGLPixelStorei(GrGLenum pname, GrGLint param) {} |
26 GrGLvoid GR_GL_FUNCTION_TYPE nullGLReadPixels(GrGLint x, GrGLint y, GrGLsizei wi
dth, GrGLsizei height, GrGLenum format, GrGLenum type, GrGLvoid* pixels) {} | 137 GrGLvoid GR_GL_FUNCTION_TYPE nullGLReadPixels(GrGLint x, GrGLint y, GrGLsizei wi
dth, GrGLsizei height, GrGLenum format, GrGLenum type, GrGLvoid* pixels) {} |
27 GrGLvoid GR_GL_FUNCTION_TYPE nullGLUseProgram(GrGLuint program) {} | 138 GrGLvoid GR_GL_FUNCTION_TYPE nullGLUseProgram(GrGLuint program) {} |
28 GrGLvoid GR_GL_FUNCTION_TYPE nullGLViewport(GrGLint x, GrGLint y, GrGLsizei widt
h, GrGLsizei height) {} | 139 GrGLvoid GR_GL_FUNCTION_TYPE nullGLViewport(GrGLint x, GrGLint y, GrGLsizei widt
h, GrGLsizei height) {} |
29 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindFramebuffer(GrGLenum target, GrGLuint fra
mebuffer) {} | 140 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindFramebuffer(GrGLenum target, GrGLuint fra
mebuffer) {} |
30 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindRenderbuffer(GrGLenum target, GrGLuint re
nderbuffer) {} | 141 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindRenderbuffer(GrGLenum target, GrGLuint re
nderbuffer) {} |
31 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDeleteFramebuffers(GrGLsizei n, const GrGLuin
t *framebuffers) {} | 142 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDeleteFramebuffers(GrGLsizei n, const GrGLuin
t *framebuffers) {} |
32 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDeleteRenderbuffers(GrGLsizei n, const GrGLui
nt *renderbuffers) {} | 143 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDeleteRenderbuffers(GrGLsizei n, const GrGLui
nt *renderbuffers) {} |
33 GrGLvoid GR_GL_FUNCTION_TYPE nullGLFramebufferRenderbuffer(GrGLenum target, GrGL
enum attachment, GrGLenum renderbuffertarget, GrGLuint renderbuffer) {} | 144 GrGLvoid GR_GL_FUNCTION_TYPE nullGLFramebufferRenderbuffer(GrGLenum target, GrGL
enum attachment, GrGLenum renderbuffertarget, GrGLuint renderbuffer) {} |
34 GrGLvoid GR_GL_FUNCTION_TYPE nullGLFramebufferTexture2D(GrGLenum target, GrGLenu
m attachment, GrGLenum textarget, GrGLuint texture, GrGLint level) {} | 145 GrGLvoid GR_GL_FUNCTION_TYPE nullGLFramebufferTexture2D(GrGLenum target, GrGLenu
m attachment, GrGLenum textarget, GrGLuint texture, GrGLint level) {} |
35 | 146 |
36 GrGLuint GR_GL_FUNCTION_TYPE nullGLCreateProgram() { | 147 GrGLuint GR_GL_FUNCTION_TYPE nullGLCreateProgram() { |
37 static int gCurrID = 0; | 148 static GrGLuint gCurrID = 0; |
38 return ++gCurrID; | 149 return ++gCurrID; |
39 } | 150 } |
40 | 151 |
41 GrGLuint GR_GL_FUNCTION_TYPE nullGLCreateShader(GrGLenum type) { | 152 GrGLuint GR_GL_FUNCTION_TYPE nullGLCreateShader(GrGLenum type) { |
42 static int gCurrID = 0; | 153 static GrGLuint gCurrID = 0; |
43 return ++gCurrID; | 154 return ++gCurrID; |
44 } | 155 } |
45 | 156 |
46 // same delete used for shaders and programs | 157 // same delete used for shaders and programs |
47 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDelete(GrGLuint program) { | 158 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDelete(GrGLuint program) { |
48 } | 159 } |
49 | 160 |
50 // In debug builds we do asserts that ensure we agree with GL about when a buffe
r | |
51 // is mapped. | |
52 static SkTDArray<GrGLuint> gMappedBuffers; | |
53 static GrGLuint gCurrArrayBuffer; | |
54 static GrGLuint gCurrElementArrayBuffer; | |
55 | |
56 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindBuffer(GrGLenum target, GrGLuint buffer)
{ | 161 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindBuffer(GrGLenum target, GrGLuint buffer)
{ |
57 switch (target) { | 162 switch (target) { |
58 case GR_GL_ARRAY_BUFFER: | 163 case GR_GL_ARRAY_BUFFER: |
59 gCurrArrayBuffer = buffer; | 164 gCurrArrayBuffer = buffer; |
60 break; | 165 break; |
61 case GR_GL_ELEMENT_ARRAY_BUFFER: | 166 case GR_GL_ELEMENT_ARRAY_BUFFER: |
62 gCurrElementArrayBuffer = buffer; | 167 gCurrElementArrayBuffer = buffer; |
63 break; | 168 break; |
64 } | 169 } |
65 } | 170 } |
66 | 171 |
67 // deleting a bound buffer has the side effect of binding 0 | 172 // deleting a bound buffer has the side effect of binding 0 |
68 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDeleteBuffers(GrGLsizei n, const GrGLuint* id
s) { | 173 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDeleteBuffers(GrGLsizei n, const GrGLuint* id
s) { |
69 for (int i = 0; i < n; ++i) { | 174 for (int i = 0; i < n; ++i) { |
70 if (ids[i] == gCurrArrayBuffer) { | 175 if (ids[i] == gCurrArrayBuffer) { |
71 gCurrArrayBuffer = 0; | 176 gCurrArrayBuffer = 0; |
72 } | 177 } |
73 if (ids[i] == gCurrElementArrayBuffer) { | 178 if (ids[i] == gCurrElementArrayBuffer) { |
74 gCurrElementArrayBuffer = 0; | 179 gCurrElementArrayBuffer = 0; |
75 } | 180 } |
76 for (int j = 0; j < gMappedBuffers.count(); ++j) { | 181 |
77 if (gMappedBuffers[j] == ids[i]) { | 182 GrBufferObj* buffer = look_up(ids[i]); |
78 gMappedBuffers.remove(j); | 183 delete_buffer(buffer); |
79 // don't break b/c we didn't check for dupes on insert | |
80 --j; | |
81 } | |
82 } | |
83 } | 184 } |
84 } | 185 } |
85 | 186 |
86 GrGLvoid* GR_GL_FUNCTION_TYPE nullGLMapBuffer(GrGLenum target, GrGLenum access)
{ | 187 GrGLvoid* GR_GL_FUNCTION_TYPE nullGLMapBuffer(GrGLenum target, GrGLenum access)
{ |
87 // We just reserve 32MB of RAM for all locks and hope its big enough | 188 |
88 static SkAutoMalloc gBufferData(32 * (1 << 20)); | 189 GrGLuint id = 0; |
89 GrGLuint buf = 0; | |
90 switch (target) { | 190 switch (target) { |
91 case GR_GL_ARRAY_BUFFER: | 191 case GR_GL_ARRAY_BUFFER: |
92 buf = gCurrArrayBuffer; | 192 id = gCurrArrayBuffer; |
93 break; | 193 break; |
94 case GR_GL_ELEMENT_ARRAY_BUFFER: | 194 case GR_GL_ELEMENT_ARRAY_BUFFER: |
95 buf = gCurrElementArrayBuffer; | 195 id = gCurrElementArrayBuffer; |
96 break; | 196 break; |
97 } | 197 } |
98 if (buf) { | 198 |
99 *gMappedBuffers.append() = buf; | 199 if (id > 0) { |
| 200 GrBufferObj* buffer = look_up(id); |
| 201 GrAssert(!buffer->mapped()); |
| 202 buffer->setMapped(true); |
| 203 return buffer->dataPtr(); |
100 } | 204 } |
101 return gBufferData.get(); | 205 |
| 206 GrAssert(false); |
| 207 return NULL; // no buffer bound to target |
102 } | 208 } |
103 | 209 |
104 GrGLboolean GR_GL_FUNCTION_TYPE nullGLUnmapBuffer(GrGLenum target) { | 210 GrGLboolean GR_GL_FUNCTION_TYPE nullGLUnmapBuffer(GrGLenum target) { |
105 GrGLuint buf = 0; | 211 GrGLuint id = 0; |
106 switch (target) { | 212 switch (target) { |
107 case GR_GL_ARRAY_BUFFER: | 213 case GR_GL_ARRAY_BUFFER: |
108 buf = gCurrArrayBuffer; | 214 id = gCurrArrayBuffer; |
109 break; | 215 break; |
110 case GR_GL_ELEMENT_ARRAY_BUFFER: | 216 case GR_GL_ELEMENT_ARRAY_BUFFER: |
111 buf = gCurrElementArrayBuffer; | 217 id = gCurrElementArrayBuffer; |
112 break; | 218 break; |
113 } | 219 } |
114 if (buf) { | 220 if (id > 0) { |
115 for (int i = 0; i < gMappedBuffers.count(); ++i) { | 221 GrBufferObj* buffer = look_up(id); |
116 if (gMappedBuffers[i] == buf) { | 222 GrAssert(buffer->mapped()); |
117 gMappedBuffers.remove(i); | 223 buffer->setMapped(false); |
118 // don't break b/c we didn't check for dupes on insert | 224 return GR_GL_TRUE; |
119 --i; | |
120 } | |
121 } | |
122 } | 225 } |
123 return GR_GL_TRUE; | 226 |
| 227 GrAlwaysAssert(false); |
| 228 return GR_GL_FALSE; // GR_GL_INVALID_OPERATION; |
124 } | 229 } |
125 | 230 |
126 GrGLvoid GR_GL_FUNCTION_TYPE nullGLGetBufferParameteriv(GrGLenum target, GrGLenu
m pname, GrGLint* params) { | 231 GrGLvoid GR_GL_FUNCTION_TYPE nullGLGetBufferParameteriv(GrGLenum target, GrGLenu
m pname, GrGLint* params) { |
127 switch (pname) { | 232 switch (pname) { |
128 case GR_GL_BUFFER_MAPPED: { | 233 case GR_GL_BUFFER_MAPPED: { |
129 *params = GR_GL_FALSE; | 234 *params = GR_GL_FALSE; |
130 GrGLuint buf = 0; | 235 GrGLuint id = 0; |
131 switch (target) { | 236 switch (target) { |
132 case GR_GL_ARRAY_BUFFER: | 237 case GR_GL_ARRAY_BUFFER: |
133 buf = gCurrArrayBuffer; | 238 id = gCurrArrayBuffer; |
134 break; | 239 break; |
135 case GR_GL_ELEMENT_ARRAY_BUFFER: | 240 case GR_GL_ELEMENT_ARRAY_BUFFER: |
136 buf = gCurrElementArrayBuffer; | 241 id = gCurrElementArrayBuffer; |
137 break; | 242 break; |
138 } | 243 } |
139 if (buf) { | 244 if (id > 0) { |
140 for (int i = 0; i < gMappedBuffers.count(); ++i) { | 245 GrBufferObj* buffer = look_up(id); |
141 if (gMappedBuffers[i] == buf) { | 246 if (buffer->mapped()) { |
142 *params = GR_GL_TRUE; | 247 *params = GR_GL_TRUE; |
143 break; | |
144 } | |
145 } | 248 } |
146 } | 249 } |
147 break; } | 250 break; } |
148 default: | 251 default: |
149 GrCrash("Unexpected pname to GetBufferParamateriv"); | 252 GrCrash("Unexpected pname to GetBufferParamateriv"); |
150 break; | 253 break; |
151 } | 254 } |
152 }; | 255 }; |
153 | 256 |
154 } // end anonymous namespace | 257 } // end anonymous namespace |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
195 interface->fDrawArrays = noOpGLDrawArrays; | 298 interface->fDrawArrays = noOpGLDrawArrays; |
196 interface->fDrawBuffer = noOpGLDrawBuffer; | 299 interface->fDrawBuffer = noOpGLDrawBuffer; |
197 interface->fDrawBuffers = noOpGLDrawBuffers; | 300 interface->fDrawBuffers = noOpGLDrawBuffers; |
198 interface->fDrawElements = noOpGLDrawElements; | 301 interface->fDrawElements = noOpGLDrawElements; |
199 interface->fEnable = noOpGLEnable; | 302 interface->fEnable = noOpGLEnable; |
200 interface->fEnableVertexAttribArray = noOpGLEnableVertexAttribArray; | 303 interface->fEnableVertexAttribArray = noOpGLEnableVertexAttribArray; |
201 interface->fEndQuery = noOpGLEndQuery; | 304 interface->fEndQuery = noOpGLEndQuery; |
202 interface->fFinish = noOpGLFinish; | 305 interface->fFinish = noOpGLFinish; |
203 interface->fFlush = noOpGLFlush; | 306 interface->fFlush = noOpGLFlush; |
204 interface->fFrontFace = noOpGLFrontFace; | 307 interface->fFrontFace = noOpGLFrontFace; |
205 interface->fGenBuffers = noOpGLGenIds; | 308 interface->fGenBuffers = nullGLGenBuffers; |
206 interface->fGenQueries = noOpGLGenIds; | 309 interface->fGenQueries = noOpGLGenIds; |
207 interface->fGenTextures = noOpGLGenIds; | 310 interface->fGenTextures = noOpGLGenIds; |
208 interface->fGenVertexArrays = noOpGLGenIds; | 311 interface->fGenVertexArrays = noOpGLGenIds; |
209 interface->fGetBufferParameteriv = nullGLGetBufferParameteriv; | 312 interface->fGetBufferParameteriv = nullGLGetBufferParameteriv; |
210 interface->fGetError = noOpGLGetError; | 313 interface->fGetError = noOpGLGetError; |
211 interface->fGetIntegerv = noOpGLGetIntegerv; | 314 interface->fGetIntegerv = noOpGLGetIntegerv; |
212 interface->fGetQueryObjecti64v = noOpGLGetQueryObjecti64v; | 315 interface->fGetQueryObjecti64v = noOpGLGetQueryObjecti64v; |
213 interface->fGetQueryObjectiv = noOpGLGetQueryObjectiv; | 316 interface->fGetQueryObjectiv = noOpGLGetQueryObjectiv; |
214 interface->fGetQueryObjectui64v = noOpGLGetQueryObjectui64v; | 317 interface->fGetQueryObjectui64v = noOpGLGetQueryObjectui64v; |
215 interface->fGetQueryObjectuiv = noOpGLGetQueryObjectuiv; | 318 interface->fGetQueryObjectuiv = noOpGLGetQueryObjectuiv; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
280 interface->fRenderbufferStorageMultisample = noOpGLRenderbufferStorageMu
ltisample; | 383 interface->fRenderbufferStorageMultisample = noOpGLRenderbufferStorageMu
ltisample; |
281 interface->fBlitFramebuffer = noOpGLBlitFramebuffer; | 384 interface->fBlitFramebuffer = noOpGLBlitFramebuffer; |
282 interface->fResolveMultisampleFramebuffer = noOpGLResolveMultisampleFram
ebuffer; | 385 interface->fResolveMultisampleFramebuffer = noOpGLResolveMultisampleFram
ebuffer; |
283 interface->fMapBuffer = nullGLMapBuffer; | 386 interface->fMapBuffer = nullGLMapBuffer; |
284 interface->fUnmapBuffer = nullGLUnmapBuffer; | 387 interface->fUnmapBuffer = nullGLUnmapBuffer; |
285 interface->fBindFragDataLocationIndexed = noOpGLBindFragDataLocationInde
xed; | 388 interface->fBindFragDataLocationIndexed = noOpGLBindFragDataLocationInde
xed; |
286 } | 389 } |
287 glInterface.get()->ref(); | 390 glInterface.get()->ref(); |
288 return glInterface.get(); | 391 return glInterface.get(); |
289 } | 392 } |
OLD | NEW |