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 "GrNonAtomicRef.h" |
9 #include "gl/GrGLInterface.h" | 10 #include "gl/GrGLInterface.h" |
10 #include "GrGLTestInterface.h" | 11 #include "GrGLTestInterface.h" |
11 #include "SkMutex.h" | 12 #include "SkMutex.h" |
12 #include "SkTDArray.h" | 13 #include "SkTDArray.h" |
| 14 #include <type_traits> |
13 | 15 |
14 // added to suppress 'no previous prototype' warning and because this code is du
plicated in | 16 // added to suppress 'no previous prototype' warning and because this code is du
plicated in |
15 // SkNullGLContext.cpp | 17 // SkNullGLContext.cpp |
16 namespace { | 18 namespace { |
17 | 19 |
18 class BufferObj { | 20 class GLObject : public GrNonAtomicRef<GLObject> { |
19 public: | 21 public: |
20 BufferObj(GrGLuint id) : fID(id), fDataPtr(nullptr), fSize(0), fMapped(false
) {} | 22 GLObject(GrGLuint id) : fID(id) {} |
21 ~BufferObj() { delete[] fDataPtr; } | 23 virtual ~GLObject() {} |
| 24 |
| 25 GrGLuint id() const { return fID; } |
| 26 |
| 27 private: |
| 28 GrGLuint fID; |
| 29 }; |
| 30 |
| 31 // This class maintains a sparsely populated array of object pointers. |
| 32 template<typename T> class TGLObjectManager { |
| 33 static_assert(std::is_convertible<T*, GLObject*>::value, "T must be a subclas
s of GLObject"); |
| 34 |
| 35 public: |
| 36 TGLObjectManager() : fFreeListHead(kFreeListEnd) { |
| 37 *fGLObjects.append() = nullptr; // 0 is not a valid GL object id. |
| 38 } |
| 39 |
| 40 ~TGLObjectManager() { |
| 41 // nullptr out the entries that are really free list links rather than p
trs before deleting. |
| 42 intptr_t curr = fFreeListHead; |
| 43 while (kFreeListEnd != curr) { |
| 44 intptr_t next = reinterpret_cast<intptr_t>(fGLObjects[SkToS32(curr)]
); |
| 45 fGLObjects[SkToS32(curr)] = nullptr; |
| 46 curr = next; |
| 47 } |
| 48 |
| 49 fGLObjects.safeUnrefAll(); |
| 50 } |
| 51 |
| 52 T* lookUp(GrGLuint id) { |
| 53 T* object = fGLObjects[id]; |
| 54 SkASSERT(object && object->id() == id); |
| 55 return object; |
| 56 } |
| 57 |
| 58 T* create() { |
| 59 GrGLuint id; |
| 60 T* object; |
| 61 |
| 62 if (kFreeListEnd == fFreeListHead) { |
| 63 // no free slots - create a new one |
| 64 id = fGLObjects.count(); |
| 65 object = new T(id); |
| 66 *fGLObjects.append() = object; |
| 67 } else { |
| 68 // grab the head of the free list and advance the head to the next f
ree slot. |
| 69 id = static_cast<GrGLuint>(fFreeListHead); |
| 70 fFreeListHead = reinterpret_cast<intptr_t>(fGLObjects[id]); |
| 71 |
| 72 object = new T(id); |
| 73 fGLObjects[id] = object; |
| 74 } |
| 75 |
| 76 return object; |
| 77 } |
| 78 |
| 79 void free(T* object) { |
| 80 SkASSERT(object); |
| 81 SkASSERT(fGLObjects.count() > 0); |
| 82 |
| 83 GrGLuint id = object->id(); |
| 84 object->unref(); |
| 85 |
| 86 fGLObjects[id] = reinterpret_cast<T*>(fFreeListHead); |
| 87 fFreeListHead = id; |
| 88 } |
| 89 |
| 90 private: |
| 91 static const intptr_t kFreeListEnd = -1; |
| 92 // Index of the first entry of fGLObjects in the free list. Free slots in fG
LObjects are indices |
| 93 // to the next free slot. The last free slot has a value of kFreeListEnd. |
| 94 intptr_t fFreeListHead; |
| 95 SkTDArray<T*> fGLObjects; |
| 96 }; |
| 97 |
| 98 class Buffer : public GLObject { |
| 99 public: |
| 100 Buffer(GrGLuint id) : INHERITED(id), fDataPtr(nullptr), fSize(0), fMapped(fa
lse) {} |
| 101 ~Buffer() { delete[] fDataPtr; } |
22 | 102 |
23 void allocate(GrGLsizeiptr size, const GrGLchar* dataPtr) { | 103 void allocate(GrGLsizeiptr size, const GrGLchar* dataPtr) { |
24 if (fDataPtr) { | 104 if (fDataPtr) { |
25 SkASSERT(0 != fSize); | 105 SkASSERT(0 != fSize); |
26 delete[] fDataPtr; | 106 delete[] fDataPtr; |
27 } | 107 } |
28 | 108 |
29 fSize = size; | 109 fSize = size; |
30 fDataPtr = new char[size]; | 110 fDataPtr = new char[size]; |
31 } | 111 } |
32 | 112 |
33 GrGLuint id() const { return fID; } | |
34 GrGLchar* dataPtr() { return fDataPtr; } | 113 GrGLchar* dataPtr() { return fDataPtr; } |
35 GrGLsizeiptr size() const { return fSize; } | 114 GrGLsizeiptr size() const { return fSize; } |
36 | 115 |
37 void setMapped(bool mapped) { fMapped = mapped; } | 116 void setMapped(bool mapped) { fMapped = mapped; } |
38 bool mapped() const { return fMapped; } | 117 bool mapped() const { return fMapped; } |
39 | 118 |
40 private: | 119 private: |
41 GrGLuint fID; | |
42 GrGLchar* fDataPtr; | 120 GrGLchar* fDataPtr; |
43 GrGLsizeiptr fSize; // size in bytes | 121 GrGLsizeiptr fSize; // size in bytes |
44 bool fMapped; | 122 bool fMapped; |
45 }; | 123 |
46 | 124 typedef GLObject INHERITED; |
47 // This class maintains a sparsely populated array of buffer pointers. | 125 }; |
48 class BufferManager { | 126 |
49 public: | 127 class FramebufferAttachment : public GLObject { |
50 BufferManager() : fFreeListHead(kFreeListEnd) { | 128 public: |
51 *fBuffers.append() = nullptr; // 0 is not a valid GL buffer id. | 129 int numSamples() const { return fNumSamples; } |
52 } | 130 |
53 | 131 protected: |
54 ~BufferManager() { | 132 FramebufferAttachment(int id) : INHERITED(id), fNumSamples(1) {} |
55 // nullptr out the entries that are really free list links rather than p
trs before deleting. | 133 |
56 intptr_t curr = fFreeListHead; | 134 int fNumSamples; |
57 while (kFreeListEnd != curr) { | 135 |
58 intptr_t next = reinterpret_cast<intptr_t>(fBuffers[SkToS32(curr)]); | 136 typedef GLObject INHERITED; |
59 fBuffers[SkToS32(curr)] = nullptr; | 137 }; |
60 curr = next; | 138 |
61 } | 139 class Renderbuffer : public FramebufferAttachment { |
62 | 140 public: |
63 fBuffers.deleteAll(); | 141 Renderbuffer(int id) : INHERITED(id) {} |
64 } | 142 void setNumSamples(int numSamples) { fNumSamples = numSamples; } |
65 | 143 |
66 BufferObj* lookUp(GrGLuint id) { | 144 private: |
67 BufferObj* buffer = fBuffers[id]; | 145 typedef FramebufferAttachment INHERITED; |
68 SkASSERT(buffer && buffer->id() == id); | 146 }; |
69 return buffer; | 147 |
70 } | 148 class Texture : public FramebufferAttachment { |
71 | 149 public: |
72 BufferObj* create() { | 150 Texture() : INHERITED(1) {} |
73 GrGLuint id; | 151 |
74 BufferObj* buffer; | 152 private: |
75 | 153 typedef FramebufferAttachment INHERITED; |
76 if (kFreeListEnd == fFreeListHead) { | 154 }; |
77 // no free slots - create a new one | 155 |
78 id = fBuffers.count(); | 156 class Framebuffer : public GLObject { |
79 buffer = new BufferObj(id); | 157 public: |
80 *fBuffers.append() = buffer; | 158 Framebuffer(int id) : INHERITED(id) {} |
81 } else { | 159 |
82 // grab the head of the free list and advance the head to the next f
ree slot. | 160 void setAttachment(GrGLenum attachmentPoint, const FramebufferAttachment* at
tachment) { |
83 id = static_cast<GrGLuint>(fFreeListHead); | 161 switch (attachmentPoint) { |
84 fFreeListHead = reinterpret_cast<intptr_t>(fBuffers[id]); | 162 default: |
85 | 163 SK_ABORT("Invalid framebuffer attachment."); |
86 buffer = new BufferObj(id); | 164 break; |
87 fBuffers[id] = buffer; | 165 case GR_GL_STENCIL_ATTACHMENT: |
88 } | 166 fAttachments[(int)AttachmentPoint::kStencil].reset(SkRef(attachm
ent)); |
89 | 167 break; |
90 return buffer; | 168 case GR_GL_DEPTH_ATTACHMENT: |
91 } | 169 fAttachments[(int)AttachmentPoint::kDepth].reset(SkRef(attachmen
t)); |
92 | 170 break; |
93 void free(BufferObj* buffer) { | 171 case GR_GL_COLOR_ATTACHMENT0: |
94 SkASSERT(buffer); | 172 fAttachments[(int)AttachmentPoint::kColor].reset(SkRef(attachmen
t)); |
95 SkASSERT(fBuffers.count() > 0); | 173 break; |
96 | 174 } |
97 GrGLuint id = buffer->id(); | 175 } |
98 delete buffer; | 176 |
99 | 177 void notifyAttachmentDeleteWhileBound(const FramebufferAttachment* deleted)
{ |
100 fBuffers[id] = reinterpret_cast<BufferObj*>(fFreeListHead); | 178 for (auto& attachment : fAttachments) { |
101 fFreeListHead = id; | 179 if (attachment == deleted) { |
102 } | 180 attachment.reset(nullptr); |
103 | 181 } |
104 private: | 182 } |
105 static const intptr_t kFreeListEnd = -1; | 183 } |
106 // Index of the first entry of fBuffers in the free list. Free slots in fBuf
fers are indices to | 184 |
107 // the next free slot. The last free slot has a value of kFreeListEnd. | 185 int numSamples() const { |
108 intptr_t fFreeListHead; | 186 int numSamples = 0; |
109 SkTDArray<BufferObj*> fBuffers; | 187 for (auto& attachment : fAttachments) { |
| 188 if (!attachment) { |
| 189 continue; |
| 190 } |
| 191 if (numSamples) { |
| 192 GrAlwaysAssert(attachment->numSamples() == numSamples); |
| 193 continue; |
| 194 } |
| 195 numSamples = attachment->numSamples(); |
| 196 } |
| 197 GrAlwaysAssert(numSamples); |
| 198 return numSamples; |
| 199 } |
| 200 |
| 201 private: |
| 202 enum AttachmentPoint { |
| 203 kStencil, |
| 204 kDepth, |
| 205 kColor |
| 206 }; |
| 207 constexpr int static kNumAttachmentPoints = 1 + (int)AttachmentPoint::kColor
; |
| 208 |
| 209 SkAutoTUnref<const FramebufferAttachment> fAttachments[kNumAttachmentPoints]
; |
| 210 |
| 211 typedef GLObject INHERITED; |
110 }; | 212 }; |
111 | 213 |
112 /** Null interface implementation */ | 214 /** Null interface implementation */ |
113 class NullInterface : public GrGLTestInterface { | 215 class NullInterface : public GrGLTestInterface { |
114 public: | 216 public: |
115 NullInterface(bool enableNVPR) | 217 NullInterface(bool enableNVPR) |
116 : fCurrProgramID(0) | 218 : fCurrDrawFramebuffer(0) |
| 219 , fCurrReadFramebuffer(0) |
| 220 , fCurrRenderbuffer(0) |
| 221 , fCurrProgramID(0) |
117 , fCurrShaderID(0) | 222 , fCurrShaderID(0) |
118 , fCurrGenericID(0) | 223 , fCurrGenericID(0) |
119 , fCurrUniformLocation(0) | 224 , fCurrUniformLocation(0) |
120 , fCurrPathID(0) { | 225 , fCurrPathID(0) { |
121 memset(fBoundBuffers, 0, sizeof(fBoundBuffers)); | 226 memset(fBoundBuffers, 0, sizeof(fBoundBuffers)); |
122 fExtensions.push_back("GL_ARB_framebuffer_object"); | 227 fExtensions.push_back("GL_ARB_framebuffer_object"); |
123 fExtensions.push_back("GL_ARB_blend_func_extended"); | 228 fExtensions.push_back("GL_ARB_blend_func_extended"); |
124 fExtensions.push_back("GL_ARB_timer_query"); | 229 fExtensions.push_back("GL_ARB_timer_query"); |
125 fExtensions.push_back("GL_ARB_draw_buffers"); | 230 fExtensions.push_back("GL_ARB_draw_buffers"); |
126 fExtensions.push_back("GL_ARB_occlusion_query"); | 231 fExtensions.push_back("GL_ARB_occlusion_query"); |
127 fExtensions.push_back("GL_EXT_stencil_wrap"); | 232 fExtensions.push_back("GL_EXT_stencil_wrap"); |
128 if (enableNVPR) { | 233 if (enableNVPR) { |
129 fExtensions.push_back("GL_NV_path_rendering"); | 234 fExtensions.push_back("GL_NV_path_rendering"); |
130 fExtensions.push_back("GL_ARB_program_interface_query"); | 235 fExtensions.push_back("GL_ARB_program_interface_query"); |
131 } | 236 } |
132 fExtensions.push_back(nullptr); | 237 fExtensions.push_back(nullptr); |
133 | 238 |
134 this->init(kGL_GrGLStandard); | 239 this->init(kGL_GrGLStandard); |
135 } | 240 } |
136 | 241 |
137 GrGLenum checkFramebufferStatus(GrGLenum target) override { | 242 GrGLenum checkFramebufferStatus(GrGLenum target) override { |
138 return GR_GL_FRAMEBUFFER_COMPLETE; | 243 return GR_GL_FRAMEBUFFER_COMPLETE; |
139 } | 244 } |
140 | 245 |
141 GrGLvoid genBuffers(GrGLsizei n, GrGLuint* ids) override { | 246 GrGLvoid genBuffers(GrGLsizei n, GrGLuint* ids) override { |
142 for (int i = 0; i < n; ++i) { | 247 for (int i = 0; i < n; ++i) { |
143 BufferObj* buffer = fBufferManager.create(); | 248 Buffer* buffer = fBufferManager.create(); |
144 ids[i] = buffer->id(); | 249 ids[i] = buffer->id(); |
145 } | 250 } |
146 } | 251 } |
147 | 252 |
148 GrGLvoid bufferData(GrGLenum target, GrGLsizeiptr size, const GrGLvoid* data
, | 253 GrGLvoid bufferData(GrGLenum target, GrGLsizeiptr size, const GrGLvoid* data
, |
149 GrGLenum usage) override { | 254 GrGLenum usage) override { |
150 GrGLuint id = fBoundBuffers[GetBufferIndex(target)]; | 255 GrGLuint id = fBoundBuffers[GetBufferIndex(target)]; |
151 if (id > 0) { | 256 if (id > 0) { |
152 BufferObj* buffer = fBufferManager.lookUp(id); | 257 Buffer* buffer = fBufferManager.lookUp(id); |
153 buffer->allocate(size, (const GrGLchar*) data); | 258 buffer->allocate(size, (const GrGLchar*) data); |
154 } | 259 } |
155 } | 260 } |
156 | 261 |
157 GrGLuint createProgram() override { | 262 GrGLuint createProgram() override { |
158 return ++fCurrProgramID; | 263 return ++fCurrProgramID; |
159 } | 264 } |
160 | 265 |
161 GrGLuint createShader(GrGLenum type) override { | 266 GrGLuint createShader(GrGLenum type) override { |
162 return ++fCurrShaderID; | 267 return ++fCurrShaderID; |
(...skipping 14 matching lines...) Expand all Loading... |
177 if (ids[i] == fBoundBuffers[buffIdx]) { | 282 if (ids[i] == fBoundBuffers[buffIdx]) { |
178 fBoundBuffers[buffIdx] = 0; | 283 fBoundBuffers[buffIdx] = 0; |
179 break; | 284 break; |
180 } | 285 } |
181 } | 286 } |
182 } | 287 } |
183 | 288 |
184 // Then actually "delete" the buffers. | 289 // Then actually "delete" the buffers. |
185 for (int i = 0; i < n; ++i) { | 290 for (int i = 0; i < n; ++i) { |
186 if (ids[i] > 0) { | 291 if (ids[i] > 0) { |
187 BufferObj* buffer = fBufferManager.lookUp(ids[i]); | 292 Buffer* buffer = fBufferManager.lookUp(ids[i]); |
188 fBufferManager.free(buffer); | 293 fBufferManager.free(buffer); |
189 } | 294 } |
190 } | 295 } |
191 } | 296 } |
192 | 297 |
193 GrGLvoid genFramebuffers(GrGLsizei n, GrGLuint *framebuffers) override { | 298 GrGLvoid genFramebuffers(GrGLsizei n, GrGLuint *framebuffers) override { |
194 this->genGenericIds(n, framebuffers); | 299 for (int i = 0; i < n; ++i) { |
| 300 Framebuffer* framebuffer = fFramebufferManager.create(); |
| 301 framebuffers[i] = framebuffer->id(); |
| 302 } |
| 303 } |
| 304 |
| 305 GrGLvoid bindFramebuffer(GrGLenum target, GrGLuint framebuffer) override { |
| 306 SkASSERT(GR_GL_FRAMEBUFFER == target || GR_GL_DRAW_FRAMEBUFFER == target
|| |
| 307 GR_GL_READ_FRAMEBUFFER == target); |
| 308 if (GR_GL_READ_FRAMEBUFFER != target) { |
| 309 fCurrDrawFramebuffer = framebuffer; |
| 310 } |
| 311 if (GR_GL_DRAW_FRAMEBUFFER != target) { |
| 312 fCurrReadFramebuffer = framebuffer; |
| 313 } |
| 314 } |
| 315 |
| 316 GrGLvoid deleteFramebuffers(GrGLsizei n, const GrGLuint* ids) override { |
| 317 for (int i = 0; i < n; ++i) { |
| 318 if (ids[i] == fCurrDrawFramebuffer) { |
| 319 fCurrDrawFramebuffer = 0; |
| 320 } |
| 321 if (ids[i] == fCurrReadFramebuffer) { |
| 322 fCurrReadFramebuffer = 0; |
| 323 } |
| 324 |
| 325 if (ids[i] > 0) { |
| 326 Framebuffer* framebuffer = fFramebufferManager.lookUp(ids[i]); |
| 327 fFramebufferManager.free(framebuffer); |
| 328 } |
| 329 } |
195 } | 330 } |
196 | 331 |
197 GrGLvoid genQueries(GrGLsizei n, GrGLuint *ids) override { this->genGenericI
ds(n, ids); } | 332 GrGLvoid genQueries(GrGLsizei n, GrGLuint *ids) override { this->genGenericI
ds(n, ids); } |
198 | 333 |
199 GrGLvoid genRenderbuffers(GrGLsizei n, GrGLuint *renderbuffers) override { | 334 GrGLvoid genRenderbuffers(GrGLsizei n, GrGLuint *renderbuffers) override { |
200 this->genGenericIds(n, renderbuffers); | 335 for (int i = 0; i < n; ++i) { |
| 336 Renderbuffer* renderbuffer = fRenderbufferManager.create(); |
| 337 renderbuffers[i] = renderbuffer->id(); |
| 338 } |
| 339 } |
| 340 |
| 341 GrGLvoid bindRenderbuffer(GrGLenum target, GrGLuint renderbuffer) override { |
| 342 SkASSERT(GR_GL_RENDERBUFFER == target); |
| 343 fCurrRenderbuffer = renderbuffer; |
| 344 } |
| 345 |
| 346 GrGLvoid deleteRenderbuffers(GrGLsizei n, const GrGLuint* ids) override { |
| 347 for (int i = 0; i < n; ++i) { |
| 348 if (ids[i] <= 0) { |
| 349 continue; |
| 350 } |
| 351 if (ids[i] == fCurrRenderbuffer) { |
| 352 fCurrRenderbuffer = 0; |
| 353 } |
| 354 Renderbuffer* renderbuffer = fRenderbufferManager.lookUp(ids[i]); |
| 355 |
| 356 if (fCurrDrawFramebuffer) { |
| 357 Framebuffer* drawFramebuffer = fFramebufferManager.lookUp(fCurrD
rawFramebuffer); |
| 358 drawFramebuffer->notifyAttachmentDeleteWhileBound(renderbuffer); |
| 359 } |
| 360 if (fCurrReadFramebuffer) { |
| 361 Framebuffer* readFramebuffer = fFramebufferManager.lookUp(fCurrR
eadFramebuffer); |
| 362 readFramebuffer->notifyAttachmentDeleteWhileBound(renderbuffer); |
| 363 } |
| 364 |
| 365 fRenderbufferManager.free(renderbuffer); |
| 366 } |
| 367 } |
| 368 |
| 369 GrGLvoid renderbufferStorage(GrGLenum target, GrGLenum internalformat, GrGLs
izei width, |
| 370 GrGLsizei height) override { |
| 371 GrAlwaysAssert(GR_GL_RENDERBUFFER == target); |
| 372 GrAlwaysAssert(fCurrRenderbuffer); |
| 373 Renderbuffer* renderbuffer = fRenderbufferManager.lookUp(fCurrRenderbuff
er); |
| 374 renderbuffer->setNumSamples(1); |
| 375 } |
| 376 |
| 377 GrGLvoid renderbufferStorageMultisample(GrGLenum target, GrGLsizei samples, |
| 378 GrGLenum internalformat, GrGLsizei w
idth, |
| 379 GrGLsizei height) override { |
| 380 GrAlwaysAssert(GR_GL_RENDERBUFFER == target); |
| 381 GrAlwaysAssert(samples > 0); |
| 382 GrAlwaysAssert(fCurrRenderbuffer); |
| 383 Renderbuffer* renderbuffer = fRenderbufferManager.lookUp(fCurrRenderbuff
er); |
| 384 renderbuffer->setNumSamples(samples); |
| 385 } |
| 386 |
| 387 GrGLvoid namedRenderbufferStorage(GrGLuint renderbuffer, GrGLenum GrGLintern
alformat, |
| 388 GrGLsizei width, GrGLsizei height) overrid
e { |
| 389 SK_ABORT("Not implemented"); |
| 390 } |
| 391 |
| 392 GrGLvoid namedRenderbufferStorageMultisample(GrGLuint renderbuffer, GrGLsize
i samples, |
| 393 GrGLenum GrGLinternalformat, Gr
GLsizei width, |
| 394 GrGLsizei height) override { |
| 395 SK_ABORT("Not implemented"); |
| 396 } |
| 397 |
| 398 GrGLvoid framebufferRenderbuffer(GrGLenum target, GrGLenum attachment, |
| 399 GrGLenum renderbuffertarget, |
| 400 GrGLuint renderBufferID) override { |
| 401 GrGLuint id = this->getBoundFramebufferID(target); |
| 402 GrAlwaysAssert(id); |
| 403 Framebuffer* framebuffer = fFramebufferManager.lookUp(id); |
| 404 |
| 405 GrAlwaysAssert(GR_GL_RENDERBUFFER == renderbuffertarget); |
| 406 GrAlwaysAssert(fCurrRenderbuffer); |
| 407 Renderbuffer* renderbuffer = fRenderbufferManager.lookUp(fCurrRenderbuff
er); |
| 408 |
| 409 framebuffer->setAttachment(attachment, renderbuffer); |
| 410 } |
| 411 |
| 412 GrGLvoid namedFramebufferRenderbuffer(GrGLuint framebuffer, GrGLenum attachm
ent, |
| 413 GrGLenum renderbuffertarget, |
| 414 GrGLuint renderbuffer) override { |
| 415 SK_ABORT("Not implemented"); |
201 } | 416 } |
202 | 417 |
203 GrGLvoid genTextures(GrGLsizei n, GrGLuint *textures) override { | 418 GrGLvoid genTextures(GrGLsizei n, GrGLuint *textures) override { |
204 this->genGenericIds(n, textures); | 419 this->genGenericIds(n, textures); |
205 } | 420 } |
206 | 421 |
| 422 GrGLvoid framebufferTexture2D(GrGLenum target, GrGLenum attachment, GrGLenum
textarget, |
| 423 GrGLuint textureID, GrGLint level) override { |
| 424 GrGLuint id = this->getBoundFramebufferID(target); |
| 425 GrAlwaysAssert(id); |
| 426 Framebuffer* framebuffer = fFramebufferManager.lookUp(id); |
| 427 framebuffer->setAttachment(attachment, this->getSingleTextureObject()); |
| 428 } |
| 429 |
| 430 GrGLvoid framebufferTexture2DMultisample(GrGLenum target, GrGLenum attachmen
t, |
| 431 GrGLenum textarget, GrGLuint textur
e, GrGLint level, |
| 432 GrGLsizei samples) override { |
| 433 SK_ABORT("Not implemented"); |
| 434 } |
| 435 |
| 436 GrGLvoid namedFramebufferTexture1D(GrGLuint framebuffer, GrGLenum attachment
, |
| 437 GrGLenum textarget, GrGLuint texture, |
| 438 GrGLint level) override { |
| 439 SK_ABORT("Not implemented"); |
| 440 } |
| 441 |
| 442 GrGLvoid namedFramebufferTexture2D(GrGLuint framebuffer, GrGLenum attachment
, |
| 443 GrGLenum textarget, GrGLuint texture, |
| 444 GrGLint level) override { |
| 445 SK_ABORT("Not implemented"); |
| 446 } |
| 447 |
| 448 GrGLvoid namedFramebufferTexture3D(GrGLuint framebuffer, GrGLenum attachment
, |
| 449 GrGLenum textarget, GrGLuint texture, GrG
Lint level, |
| 450 GrGLint zoffset) override { |
| 451 SK_ABORT("Not implemented"); |
| 452 } |
| 453 |
207 GrGLvoid genVertexArrays(GrGLsizei n, GrGLuint *arrays) override { | 454 GrGLvoid genVertexArrays(GrGLsizei n, GrGLuint *arrays) override { |
208 this->genGenericIds(n, arrays); | 455 this->genGenericIds(n, arrays); |
209 } | 456 } |
210 | 457 |
211 GrGLenum getError() override { return GR_GL_NO_ERROR; } | 458 GrGLenum getError() override { return GR_GL_NO_ERROR; } |
212 | 459 |
213 GrGLvoid getIntegerv(GrGLenum pname, GrGLint* params) override { | 460 GrGLvoid getIntegerv(GrGLenum pname, GrGLint* params) override { |
214 // TODO: remove from Ganesh the #defines for gets we don't use. | 461 // TODO: remove from Ganesh the #defines for gets we don't use. |
215 // We would like to minimize gets overall due to performance issues | 462 // We would like to minimize gets overall due to performance issues |
216 switch (pname) { | 463 switch (pname) { |
217 case GR_GL_CONTEXT_PROFILE_MASK: | 464 case GR_GL_CONTEXT_PROFILE_MASK: |
218 *params = GR_GL_CONTEXT_COMPATIBILITY_PROFILE_BIT; | 465 *params = GR_GL_CONTEXT_COMPATIBILITY_PROFILE_BIT; |
219 break; | 466 break; |
220 case GR_GL_STENCIL_BITS: | 467 case GR_GL_STENCIL_BITS: |
221 *params = 8; | 468 *params = 8; |
222 break; | 469 break; |
223 case GR_GL_SAMPLES: | 470 case GR_GL_SAMPLES: { |
224 *params = 1; | 471 GrAlwaysAssert(fCurrDrawFramebuffer); |
| 472 Framebuffer* framebuffer = fFramebufferManager.lookUp(fCurrDrawF
ramebuffer); |
| 473 *params = framebuffer->numSamples(); |
225 break; | 474 break; |
| 475 } |
226 case GR_GL_FRAMEBUFFER_BINDING: | 476 case GR_GL_FRAMEBUFFER_BINDING: |
227 *params = 0; | 477 *params = 0; |
228 break; | 478 break; |
229 case GR_GL_VIEWPORT: | 479 case GR_GL_VIEWPORT: |
230 params[0] = 0; | 480 params[0] = 0; |
231 params[1] = 0; | 481 params[1] = 0; |
232 params[2] = 800; | 482 params[2] = 800; |
233 params[3] = 600; | 483 params[3] = 600; |
234 break; | 484 break; |
235 case GR_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: | 485 case GR_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
369 | 619 |
370 GrGLint getUniformLocation(GrGLuint program, const char* name) override { | 620 GrGLint getUniformLocation(GrGLuint program, const char* name) override { |
371 return ++fCurrUniformLocation; | 621 return ++fCurrUniformLocation; |
372 } | 622 } |
373 | 623 |
374 GrGLvoid* mapBufferRange(GrGLenum target, GrGLintptr offset, GrGLsizeiptr le
ngth, | 624 GrGLvoid* mapBufferRange(GrGLenum target, GrGLintptr offset, GrGLsizeiptr le
ngth, |
375 GrGLbitfield access) override { | 625 GrGLbitfield access) override { |
376 GrGLuint id = fBoundBuffers[GetBufferIndex(target)]; | 626 GrGLuint id = fBoundBuffers[GetBufferIndex(target)]; |
377 if (id > 0) { | 627 if (id > 0) { |
378 // We just ignore the offset and length here. | 628 // We just ignore the offset and length here. |
379 BufferObj* buffer = fBufferManager.lookUp(id); | 629 Buffer* buffer = fBufferManager.lookUp(id); |
380 SkASSERT(!buffer->mapped()); | 630 SkASSERT(!buffer->mapped()); |
381 buffer->setMapped(true); | 631 buffer->setMapped(true); |
382 return buffer->dataPtr(); | 632 return buffer->dataPtr(); |
383 } | 633 } |
384 return nullptr; | 634 return nullptr; |
385 } | 635 } |
386 | 636 |
387 GrGLvoid* mapBuffer(GrGLenum target, GrGLenum access) override { | 637 GrGLvoid* mapBuffer(GrGLenum target, GrGLenum access) override { |
388 GrGLuint id = fBoundBuffers[GetBufferIndex(target)]; | 638 GrGLuint id = fBoundBuffers[GetBufferIndex(target)]; |
389 if (id > 0) { | 639 if (id > 0) { |
390 BufferObj* buffer = fBufferManager.lookUp(id); | 640 Buffer* buffer = fBufferManager.lookUp(id); |
391 SkASSERT(!buffer->mapped()); | 641 SkASSERT(!buffer->mapped()); |
392 buffer->setMapped(true); | 642 buffer->setMapped(true); |
393 return buffer->dataPtr(); | 643 return buffer->dataPtr(); |
394 } | 644 } |
395 | 645 |
396 SkASSERT(false); | 646 SkASSERT(false); |
397 return nullptr; // no buffer bound to target | 647 return nullptr; // no buffer bound to target |
398 } | 648 } |
399 | 649 |
400 GrGLboolean unmapBuffer(GrGLenum target) override { | 650 GrGLboolean unmapBuffer(GrGLenum target) override { |
401 GrGLuint id = fBoundBuffers[GetBufferIndex(target)]; | 651 GrGLuint id = fBoundBuffers[GetBufferIndex(target)]; |
402 if (id > 0) { | 652 if (id > 0) { |
403 BufferObj* buffer = fBufferManager.lookUp(id); | 653 Buffer* buffer = fBufferManager.lookUp(id); |
404 SkASSERT(buffer->mapped()); | 654 SkASSERT(buffer->mapped()); |
405 buffer->setMapped(false); | 655 buffer->setMapped(false); |
406 return GR_GL_TRUE; | 656 return GR_GL_TRUE; |
407 } | 657 } |
408 | 658 |
409 GrAlwaysAssert(false); | 659 GrAlwaysAssert(false); |
410 return GR_GL_FALSE; // GR_GL_INVALID_OPERATION; | 660 return GR_GL_FALSE; // GR_GL_INVALID_OPERATION; |
411 } | 661 } |
412 | 662 |
413 GrGLvoid getBufferParameteriv(GrGLenum target, GrGLenum pname, GrGLint* para
ms) override { | 663 GrGLvoid getBufferParameteriv(GrGLenum target, GrGLenum pname, GrGLint* para
ms) override { |
414 switch (pname) { | 664 switch (pname) { |
415 case GR_GL_BUFFER_MAPPED: { | 665 case GR_GL_BUFFER_MAPPED: { |
416 *params = GR_GL_FALSE; | 666 *params = GR_GL_FALSE; |
417 GrGLuint id = fBoundBuffers[GetBufferIndex(target)]; | 667 GrGLuint id = fBoundBuffers[GetBufferIndex(target)]; |
418 if (id > 0) { | 668 if (id > 0) { |
419 BufferObj* buffer = fBufferManager.lookUp(id); | 669 Buffer* buffer = fBufferManager.lookUp(id); |
420 if (buffer->mapped()) { | 670 if (buffer->mapped()) { |
421 *params = GR_GL_TRUE; | 671 *params = GR_GL_TRUE; |
422 } | 672 } |
423 } | 673 } |
424 break; } | 674 break; } |
425 default: | 675 default: |
426 SkFAIL("Unexpected pname to GetBufferParamateriv"); | 676 SkFAIL("Unexpected pname to GetBufferParamateriv"); |
427 break; | 677 break; |
428 } | 678 } |
429 }; | 679 }; |
(...skipping 11 matching lines...) Expand all Loading... |
441 case GR_GL_ARRAY_BUFFER: return 0; | 691 case GR_GL_ARRAY_BUFFER: return 0; |
442 case GR_GL_ELEMENT_ARRAY_BUFFER: return 1; | 692 case GR_GL_ELEMENT_ARRAY_BUFFER: return 1; |
443 case GR_GL_TEXTURE_BUFFER: return 2; | 693 case GR_GL_TEXTURE_BUFFER: return 2; |
444 case GR_GL_DRAW_INDIRECT_BUFFER: return 3; | 694 case GR_GL_DRAW_INDIRECT_BUFFER: return 3; |
445 case GR_GL_PIXEL_PACK_BUFFER: return 4; | 695 case GR_GL_PIXEL_PACK_BUFFER: return 4; |
446 case GR_GL_PIXEL_UNPACK_BUFFER: return 5; | 696 case GR_GL_PIXEL_UNPACK_BUFFER: return 5; |
447 } | 697 } |
448 } | 698 } |
449 constexpr int static kNumBufferTargets = 6; | 699 constexpr int static kNumBufferTargets = 6; |
450 | 700 |
451 BufferManager fBufferManager; | 701 TGLObjectManager<Buffer> fBufferManager; |
452 GrGLuint fBoundBuffers[kNumBufferTargets]; | 702 GrGLuint fBoundBuffers[kNumBufferTargets]; |
453 GrGLuint fCurrProgramID; | 703 TGLObjectManager<Framebuffer> fFramebufferManager; |
454 GrGLuint fCurrShaderID; | 704 GrGLuint fCurrDrawFramebuffer; |
455 GrGLuint fCurrGenericID; | 705 GrGLuint fCurrReadFramebuffer; |
456 GrGLuint fCurrUniformLocation; | 706 TGLObjectManager<Renderbuffer> fRenderbufferManager; |
457 GrGLuint fCurrPathID; | 707 GrGLuint fCurrRenderbuffer; |
458 SkTArray<const char*> fExtensions; | 708 GrGLuint fCurrProgramID; |
| 709 GrGLuint fCurrShaderID; |
| 710 GrGLuint fCurrGenericID; |
| 711 GrGLuint fCurrUniformLocation; |
| 712 GrGLuint fCurrPathID; |
| 713 SkAutoTUnref<const Texture> fSingleTextureObject; |
| 714 SkTArray<const char*> fExtensions; |
459 | 715 |
460 // the OpenGLES 2.0 spec says this must be >= 128 | 716 // the OpenGLES 2.0 spec says this must be >= 128 |
461 static const GrGLint kDefaultMaxVertexUniformVectors = 128; | 717 static const GrGLint kDefaultMaxVertexUniformVectors = 128; |
462 | 718 |
463 // the OpenGLES 2.0 spec says this must be >=16 | 719 // the OpenGLES 2.0 spec says this must be >=16 |
464 static const GrGLint kDefaultMaxFragmentUniformVectors = 16; | 720 static const GrGLint kDefaultMaxFragmentUniformVectors = 16; |
465 | 721 |
466 // the OpenGLES 2.0 spec says this must be >= 8 | 722 // the OpenGLES 2.0 spec says this must be >= 8 |
467 static const GrGLint kDefaultMaxVertexAttribs = 8; | 723 static const GrGLint kDefaultMaxVertexAttribs = 8; |
468 | 724 |
469 // the OpenGLES 2.0 spec says this must be >= 8 | 725 // the OpenGLES 2.0 spec says this must be >= 8 |
470 static const GrGLint kDefaultMaxVaryingVectors = 8; | 726 static const GrGLint kDefaultMaxVaryingVectors = 8; |
471 | 727 |
| 728 GrGLuint getBoundFramebufferID(GrGLenum target) { |
| 729 switch (target) { |
| 730 case GR_GL_FRAMEBUFFER: |
| 731 case GR_GL_DRAW_FRAMEBUFFER: |
| 732 return fCurrDrawFramebuffer; |
| 733 case GR_GL_READ_FRAMEBUFFER: |
| 734 return fCurrReadFramebuffer; |
| 735 default: |
| 736 SK_ABORT("Invalid framebuffer target."); |
| 737 return 0; |
| 738 } |
| 739 } |
| 740 |
| 741 const Texture* getSingleTextureObject() { |
| 742 // We currently only use FramebufferAttachment objects for a sample coun
t, and all textures |
| 743 // in Skia have one sample, so there is no need as of yet to track indiv
idual textures. This |
| 744 // also works around a bug in chromium's cc_unittests where they send us
texture IDs that |
| 745 // were generated by cc::TestGLES2Interface. |
| 746 if (!fSingleTextureObject) { |
| 747 fSingleTextureObject.reset(new Texture); |
| 748 } |
| 749 return fSingleTextureObject; |
| 750 } |
| 751 |
472 const GrGLubyte* CombinedExtensionString() { | 752 const GrGLubyte* CombinedExtensionString() { |
473 static SkString gExtString; | 753 static SkString gExtString; |
474 static SkMutex gMutex; | 754 static SkMutex gMutex; |
475 gMutex.acquire(); | 755 gMutex.acquire(); |
476 if (0 == gExtString.size()) { | 756 if (0 == gExtString.size()) { |
477 int i = 0; | 757 int i = 0; |
478 while (fExtensions[i]) { | 758 while (fExtensions[i]) { |
479 if (i > 0) { | 759 if (i > 0) { |
480 gExtString.append(" "); | 760 gExtString.append(" "); |
481 } | 761 } |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
533 break; | 813 break; |
534 } | 814 } |
535 } | 815 } |
536 | 816 |
537 typedef GrGLTestInterface INHERITED; | 817 typedef GrGLTestInterface INHERITED; |
538 }; | 818 }; |
539 | 819 |
540 } // anonymous namespace | 820 } // anonymous namespace |
541 | 821 |
542 const GrGLInterface* GrGLCreateNullInterface(bool enableNVPR) { return new NullI
nterface(enableNVPR); } | 822 const GrGLInterface* GrGLCreateNullInterface(bool enableNVPR) { return new NullI
nterface(enableNVPR); } |
OLD | NEW |