1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 // Context.cpp: Implements the es2::Context class, managing all GL state and performing
16 // rendering operations. It is the GLES2 specific implementation of EGLContext.
17
18 #include "Context.h"
19
20 #include "main.h"
21 #include "mathutil.h"
22 #include "utilities.h"
23 #include "ResourceManager.h"
24 #include "Buffer.h"
25 #include "Fence.h"
26 #include "Framebuffer.h"
27 #include "Program.h"
28 #include "Query.h"
29 #include "Renderbuffer.h"
30 #include "Sampler.h"
31 #include "Shader.h"
32 #include "Texture.h"
33 #include "TransformFeedback.h"
34 #include "VertexArray.h"
35 #include "VertexDataManager.h"
36 #include "IndexDataManager.h"
37 #include "libEGL/Display.h"
38 #include "common/Surface.hpp"
39 #include "Common/Half.hpp"
40
41 #include <EGL/eglext.h>
42
43 #include <algorithm>
44 #include <string>
45
46 namespace es2
47 {
Context(egl::Display * display,const Context * shareContext,const egl::Config * config)48 Context::Context(egl::Display *display, const Context *shareContext, const egl::Config *config)
49 : egl::Context(display), config(config)
50 {
51 sw::Context *context = new sw::Context();
52 device = new es2::Device(context);
53
54 setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
55
56 mState.depthClearValue = 1.0f;
57 mState.stencilClearValue = 0;
58
59 mState.cullFaceEnabled = false;
60 mState.cullMode = GL_BACK;
61 mState.frontFace = GL_CCW;
62 mState.depthTestEnabled = false;
63 mState.depthFunc = GL_LESS;
64 mState.blendEnabled = false;
65 mState.sourceBlendRGB = GL_ONE;
66 mState.sourceBlendAlpha = GL_ONE;
67 mState.destBlendRGB = GL_ZERO;
68 mState.destBlendAlpha = GL_ZERO;
69 mState.blendEquationRGB = GL_FUNC_ADD;
70 mState.blendEquationAlpha = GL_FUNC_ADD;
71 mState.blendColor.red = 0;
72 mState.blendColor.green = 0;
73 mState.blendColor.blue = 0;
74 mState.blendColor.alpha = 0;
75 mState.stencilTestEnabled = false;
76 mState.stencilFunc = GL_ALWAYS;
77 mState.stencilRef = 0;
78 mState.stencilMask = 0xFFFFFFFFu;
79 mState.stencilWritemask = 0xFFFFFFFFu;
80 mState.stencilBackFunc = GL_ALWAYS;
81 mState.stencilBackRef = 0;
82 mState.stencilBackMask = 0xFFFFFFFFu;
83 mState.stencilBackWritemask = 0xFFFFFFFFu;
84 mState.stencilFail = GL_KEEP;
85 mState.stencilPassDepthFail = GL_KEEP;
86 mState.stencilPassDepthPass = GL_KEEP;
87 mState.stencilBackFail = GL_KEEP;
88 mState.stencilBackPassDepthFail = GL_KEEP;
89 mState.stencilBackPassDepthPass = GL_KEEP;
90 mState.polygonOffsetFillEnabled = false;
91 mState.polygonOffsetFactor = 0.0f;
92 mState.polygonOffsetUnits = 0.0f;
93 mState.sampleAlphaToCoverageEnabled = false;
94 mState.sampleCoverageEnabled = false;
95 mState.sampleCoverageValue = 1.0f;
96 mState.sampleCoverageInvert = false;
97 mState.scissorTestEnabled = false;
98 mState.ditherEnabled = true;
99 mState.primitiveRestartFixedIndexEnabled = false;
100 mState.rasterizerDiscardEnabled = false;
101 mState.generateMipmapHint = GL_DONT_CARE;
102 mState.fragmentShaderDerivativeHint = GL_DONT_CARE;
103 mState.textureFilteringHint = GL_DONT_CARE;
104
105 mState.lineWidth = 1.0f;
106
107 mState.viewportX = 0;
108 mState.viewportY = 0;
109 mState.viewportWidth = 0;
110 mState.viewportHeight = 0;
111 mState.zNear = 0.0f;
112 mState.zFar = 1.0f;
113
114 mState.scissorX = 0;
115 mState.scissorY = 0;
116 mState.scissorWidth = 0;
117 mState.scissorHeight = 0;
118
119 mState.colorMaskRed = true;
120 mState.colorMaskGreen = true;
121 mState.colorMaskBlue = true;
122 mState.colorMaskAlpha = true;
123 mState.depthMask = true;
124
125 if(shareContext)
126 {
127 mResourceManager = shareContext->mResourceManager;
128 mResourceManager->addRef();
129 }
130 else
131 {
132 mResourceManager = new ResourceManager();
133 }
134
135 // [OpenGL ES 2.0.24] section 3.7 page 83:
136 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
137 // and cube map texture state vectors respectively associated with them.
138 // In order that access to these initial textures not be lost, they are treated as texture
139 // objects all of whose names are 0.
140
141 mTexture2DZero = new Texture2D(0);
142 mTexture3DZero = new Texture3D(0);
143 mTexture2DArrayZero = new Texture2DArray(0);
144 mTextureCubeMapZero = new TextureCubeMap(0);
145 mTexture2DRectZero = new Texture2DRect(0);
146 mTextureExternalZero = new TextureExternal(0);
147
148 mState.activeSampler = 0;
149
150 for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
151 {
152 bindTexture((TextureType)type, 0);
153 }
154
155 bindVertexArray(0);
156 bindArrayBuffer(0);
157 bindElementArrayBuffer(0);
158 bindReadFramebuffer(0);
159 bindDrawFramebuffer(0);
160 bindRenderbuffer(0);
161 bindGenericUniformBuffer(0);
162 bindTransformFeedback(0);
163
164 mState.currentProgram = 0;
165
166 mVertexDataManager = nullptr;
167 mIndexDataManager = nullptr;
168
169 mInvalidEnum = false;
170 mInvalidValue = false;
171 mInvalidOperation = false;
172 mOutOfMemory = false;
173 mInvalidFramebufferOperation = false;
174
175 mHasBeenCurrent = false;
176
177 markAllStateDirty();
178 }
179
~Context()180 Context::~Context()
181 {
182 if(mState.currentProgram != 0)
183 {
184 Program *programObject = mResourceManager->getProgram(mState.currentProgram);
185 if(programObject)
186 {
187 programObject->release();
188 }
189 mState.currentProgram = 0;
190 }
191
192 while(!mFramebufferNameSpace.empty())
193 {
194 deleteFramebuffer(mFramebufferNameSpace.firstName());
195 }
196
197 while(!mFenceNameSpace.empty())
198 {
199 deleteFence(mFenceNameSpace.firstName());
200 }
201
202 while(!mQueryNameSpace.empty())
203 {
204 deleteQuery(mQueryNameSpace.firstName());
205 }
206
207 while(!mVertexArrayNameSpace.empty())
208 {
209 deleteVertexArray(mVertexArrayNameSpace.lastName());
210 }
211
212 while(!mTransformFeedbackNameSpace.empty())
213 {
214 deleteTransformFeedback(mTransformFeedbackNameSpace.firstName());
215 }
216
217 for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
218 {
219 for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
220 {
221 mState.samplerTexture[type][sampler] = nullptr;
222 }
223 }
224
225 for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
226 {
227 mState.vertexAttribute[i].mBoundBuffer = nullptr;
228 }
229
230 for(int i = 0; i < QUERY_TYPE_COUNT; i++)
231 {
232 mState.activeQuery[i] = nullptr;
233 }
234
235 mState.arrayBuffer = nullptr;
236 mState.copyReadBuffer = nullptr;
237 mState.copyWriteBuffer = nullptr;
238 mState.pixelPackBuffer = nullptr;
239 mState.pixelUnpackBuffer = nullptr;
240 mState.genericUniformBuffer = nullptr;
241 mState.genericTransformFeedbackBuffer = nullptr;
242
243 for(int i = 0; i < MAX_UNIFORM_BUFFER_BINDINGS; i++) {
244 mState.uniformBuffers[i].set(nullptr, 0, 0);
245 }
246
247 mState.renderbuffer = nullptr;
248
249 for(int i = 0; i < MAX_COMBINED_TEXTURE_IMAGE_UNITS; ++i)
250 {
251 mState.sampler[i] = nullptr;
252 }
253
254 mTexture2DZero = nullptr;
255 mTexture3DZero = nullptr;
256 mTexture2DArrayZero = nullptr;
257 mTextureCubeMapZero = nullptr;
258 mTexture2DRectZero = nullptr;
259 mTextureExternalZero = nullptr;
260
261 delete mVertexDataManager;
262 delete mIndexDataManager;
263
264 mResourceManager->release();
265 delete device;
266 }
267
makeCurrent(gl::Surface * surface)268 void Context::makeCurrent(gl::Surface *surface)
269 {
270 if(!mHasBeenCurrent)
271 {
272 mVertexDataManager = new VertexDataManager(this);
273 mIndexDataManager = new IndexDataManager();
274
275 mState.viewportX = 0;
276 mState.viewportY = 0;
277 mState.viewportWidth = surface ? surface->getWidth() : 0;
278 mState.viewportHeight = surface ? surface->getHeight() : 0;
279
280 mState.scissorX = 0;
281 mState.scissorY = 0;
282 mState.scissorWidth = surface ? surface->getWidth() : 0;
283 mState.scissorHeight = surface ? surface->getHeight() : 0;
284
285 mHasBeenCurrent = true;
286 }
287
288 if(surface)
289 {
290 // Wrap the existing resources into GL objects and assign them to the '0' names
291 egl::Image *defaultRenderTarget = surface->getRenderTarget();
292 egl::Image *depthStencil = surface->getDepthStencil();
293
294 Colorbuffer *colorbufferZero = new Colorbuffer(defaultRenderTarget);
295 DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(depthStencil);
296 Framebuffer *framebufferZero = new DefaultFramebuffer(colorbufferZero, depthStencilbufferZero);
297
298 setFramebufferZero(framebufferZero);
299
300 if(defaultRenderTarget)
301 {
302 defaultRenderTarget->release();
303 }
304
305 if(depthStencil)
306 {
307 depthStencil->release();
308 }
309 }
310 else
311 {
312 setFramebufferZero(nullptr);
313 }
314
315 markAllStateDirty();
316 }
317
getClientVersion() const318 EGLint Context::getClientVersion() const
319 {
320 return 3;
321 }
322
getConfigID() const323 EGLint Context::getConfigID() const
324 {
325 return config->mConfigID;
326 }
327
328 // This function will set all of the state-related dirty flags, so that all state is set during next pre-draw.
markAllStateDirty()329 void Context::markAllStateDirty()
330 {
331 mAppliedProgramSerial = 0;
332
333 mDepthStateDirty = true;
334 mMaskStateDirty = true;
335 mBlendStateDirty = true;
336 mStencilStateDirty = true;
337 mPolygonOffsetStateDirty = true;
338 mSampleStateDirty = true;
339 mDitherStateDirty = true;
340 mFrontFaceDirty = true;
341 }
342
setClearColor(float red,float green,float blue,float alpha)343 void Context::setClearColor(float red, float green, float blue, float alpha)
344 {
345 mState.colorClearValue.red = red;
346 mState.colorClearValue.green = green;
347 mState.colorClearValue.blue = blue;
348 mState.colorClearValue.alpha = alpha;
349 }
350
setClearDepth(float depth)351 void Context::setClearDepth(float depth)
352 {
353 mState.depthClearValue = depth;
354 }
355
setClearStencil(int stencil)356 void Context::setClearStencil(int stencil)
357 {
358 mState.stencilClearValue = stencil;
359 }
360
setCullFaceEnabled(bool enabled)361 void Context::setCullFaceEnabled(bool enabled)
362 {
363 mState.cullFaceEnabled = enabled;
364 }
365
isCullFaceEnabled() const366 bool Context::isCullFaceEnabled() const
367 {
368 return mState.cullFaceEnabled;
369 }
370
setCullMode(GLenum mode)371 void Context::setCullMode(GLenum mode)
372 {
373 mState.cullMode = mode;
374 }
375
setFrontFace(GLenum front)376 void Context::setFrontFace(GLenum front)
377 {
378 if(mState.frontFace != front)
379 {
380 mState.frontFace = front;
381 mFrontFaceDirty = true;
382 }
383 }
384
setDepthTestEnabled(bool enabled)385 void Context::setDepthTestEnabled(bool enabled)
386 {
387 if(mState.depthTestEnabled != enabled)
388 {
389 mState.depthTestEnabled = enabled;
390 mDepthStateDirty = true;
391 }
392 }
393
isDepthTestEnabled() const394 bool Context::isDepthTestEnabled() const
395 {
396 return mState.depthTestEnabled;
397 }
398
setDepthFunc(GLenum depthFunc)399 void Context::setDepthFunc(GLenum depthFunc)
400 {
401 if(mState.depthFunc != depthFunc)
402 {
403 mState.depthFunc = depthFunc;
404 mDepthStateDirty = true;
405 }
406 }
407
setDepthRange(float zNear,float zFar)408 void Context::setDepthRange(float zNear, float zFar)
409 {
410 mState.zNear = zNear;
411 mState.zFar = zFar;
412 }
413
setBlendEnabled(bool enabled)414 void Context::setBlendEnabled(bool enabled)
415 {
416 if(mState.blendEnabled != enabled)
417 {
418 mState.blendEnabled = enabled;
419 mBlendStateDirty = true;
420 }
421 }
422
isBlendEnabled() const423 bool Context::isBlendEnabled() const
424 {
425 return mState.blendEnabled;
426 }
427
setBlendFactors(GLenum sourceRGB,GLenum destRGB,GLenum sourceAlpha,GLenum destAlpha)428 void Context::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
429 {
430 if(mState.sourceBlendRGB != sourceRGB ||
431 mState.sourceBlendAlpha != sourceAlpha ||
432 mState.destBlendRGB != destRGB ||
433 mState.destBlendAlpha != destAlpha)
434 {
435 mState.sourceBlendRGB = sourceRGB;
436 mState.destBlendRGB = destRGB;
437 mState.sourceBlendAlpha = sourceAlpha;
438 mState.destBlendAlpha = destAlpha;
439 mBlendStateDirty = true;
440 }
441 }
442
setBlendColor(float red,float green,float blue,float alpha)443 void Context::setBlendColor(float red, float green, float blue, float alpha)
444 {
445 if(mState.blendColor.red != red ||
446 mState.blendColor.green != green ||
447 mState.blendColor.blue != blue ||
448 mState.blendColor.alpha != alpha)
449 {
450 mState.blendColor.red = red;
451 mState.blendColor.green = green;
452 mState.blendColor.blue = blue;
453 mState.blendColor.alpha = alpha;
454 mBlendStateDirty = true;
455 }
456 }
457
setBlendEquation(GLenum rgbEquation,GLenum alphaEquation)458 void Context::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
459 {
460 if(mState.blendEquationRGB != rgbEquation ||
461 mState.blendEquationAlpha != alphaEquation)
462 {
463 mState.blendEquationRGB = rgbEquation;
464 mState.blendEquationAlpha = alphaEquation;
465 mBlendStateDirty = true;
466 }
467 }
468
setStencilTestEnabled(bool enabled)469 void Context::setStencilTestEnabled(bool enabled)
470 {
471 if(mState.stencilTestEnabled != enabled)
472 {
473 mState.stencilTestEnabled = enabled;
474 mStencilStateDirty = true;
475 }
476 }
477
isStencilTestEnabled() const478 bool Context::isStencilTestEnabled() const
479 {
480 return mState.stencilTestEnabled;
481 }
482
setStencilParams(GLenum stencilFunc,GLint stencilRef,GLuint stencilMask)483 void Context::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
484 {
485 if(mState.stencilFunc != stencilFunc ||
486 mState.stencilRef != stencilRef ||
487 mState.stencilMask != stencilMask)
488 {
489 mState.stencilFunc = stencilFunc;
490 mState.stencilRef = (stencilRef > 0) ? stencilRef : 0;
491 mState.stencilMask = stencilMask;
492 mStencilStateDirty = true;
493 }
494 }
495
setStencilBackParams(GLenum stencilBackFunc,GLint stencilBackRef,GLuint stencilBackMask)496 void Context::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
497 {
498 if(mState.stencilBackFunc != stencilBackFunc ||
499 mState.stencilBackRef != stencilBackRef ||
500 mState.stencilBackMask != stencilBackMask)
501 {
502 mState.stencilBackFunc = stencilBackFunc;
503 mState.stencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
504 mState.stencilBackMask = stencilBackMask;
505 mStencilStateDirty = true;
506 }
507 }
508
setStencilWritemask(GLuint stencilWritemask)509 void Context::setStencilWritemask(GLuint stencilWritemask)
510 {
511 if(mState.stencilWritemask != stencilWritemask)
512 {
513 mState.stencilWritemask = stencilWritemask;
514 mStencilStateDirty = true;
515 }
516 }
517
setStencilBackWritemask(GLuint stencilBackWritemask)518 void Context::setStencilBackWritemask(GLuint stencilBackWritemask)
519 {
520 if(mState.stencilBackWritemask != stencilBackWritemask)
521 {
522 mState.stencilBackWritemask = stencilBackWritemask;
523 mStencilStateDirty = true;
524 }
525 }
526
setStencilOperations(GLenum stencilFail,GLenum stencilPassDepthFail,GLenum stencilPassDepthPass)527 void Context::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
528 {
529 if(mState.stencilFail != stencilFail ||
530 mState.stencilPassDepthFail != stencilPassDepthFail ||
531 mState.stencilPassDepthPass != stencilPassDepthPass)
532 {
533 mState.stencilFail = stencilFail;
534 mState.stencilPassDepthFail = stencilPassDepthFail;
535 mState.stencilPassDepthPass = stencilPassDepthPass;
536 mStencilStateDirty = true;
537 }
538 }
539
setStencilBackOperations(GLenum stencilBackFail,GLenum stencilBackPassDepthFail,GLenum stencilBackPassDepthPass)540 void Context::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
541 {
542 if(mState.stencilBackFail != stencilBackFail ||
543 mState.stencilBackPassDepthFail != stencilBackPassDepthFail ||
544 mState.stencilBackPassDepthPass != stencilBackPassDepthPass)
545 {
546 mState.stencilBackFail = stencilBackFail;
547 mState.stencilBackPassDepthFail = stencilBackPassDepthFail;
548 mState.stencilBackPassDepthPass = stencilBackPassDepthPass;
549 mStencilStateDirty = true;
550 }
551 }
552
setPolygonOffsetFillEnabled(bool enabled)553 void Context::setPolygonOffsetFillEnabled(bool enabled)
554 {
555 if(mState.polygonOffsetFillEnabled != enabled)
556 {
557 mState.polygonOffsetFillEnabled = enabled;
558 mPolygonOffsetStateDirty = true;
559 }
560 }
561
isPolygonOffsetFillEnabled() const562 bool Context::isPolygonOffsetFillEnabled() const
563 {
564 return mState.polygonOffsetFillEnabled;
565 }
566
setPolygonOffsetParams(GLfloat factor,GLfloat units)567 void Context::setPolygonOffsetParams(GLfloat factor, GLfloat units)
568 {
569 if(mState.polygonOffsetFactor != factor ||
570 mState.polygonOffsetUnits != units)
571 {
572 mState.polygonOffsetFactor = factor;
573 mState.polygonOffsetUnits = units;
574 mPolygonOffsetStateDirty = true;
575 }
576 }
577
setSampleAlphaToCoverageEnabled(bool enabled)578 void Context::setSampleAlphaToCoverageEnabled(bool enabled)
579 {
580 if(mState.sampleAlphaToCoverageEnabled != enabled)
581 {
582 mState.sampleAlphaToCoverageEnabled = enabled;
583 mSampleStateDirty = true;
584 }
585 }
586
isSampleAlphaToCoverageEnabled() const587 bool Context::isSampleAlphaToCoverageEnabled() const
588 {
589 return mState.sampleAlphaToCoverageEnabled;
590 }
591
setSampleCoverageEnabled(bool enabled)592 void Context::setSampleCoverageEnabled(bool enabled)
593 {
594 if(mState.sampleCoverageEnabled != enabled)
595 {
596 mState.sampleCoverageEnabled = enabled;
597 mSampleStateDirty = true;
598 }
599 }
600
isSampleCoverageEnabled() const601 bool Context::isSampleCoverageEnabled() const
602 {
603 return mState.sampleCoverageEnabled;
604 }
605
setSampleCoverageParams(GLclampf value,bool invert)606 void Context::setSampleCoverageParams(GLclampf value, bool invert)
607 {
608 if(mState.sampleCoverageValue != value ||
609 mState.sampleCoverageInvert != invert)
610 {
611 mState.sampleCoverageValue = value;
612 mState.sampleCoverageInvert = invert;
613 mSampleStateDirty = true;
614 }
615 }
616
setScissorTestEnabled(bool enabled)617 void Context::setScissorTestEnabled(bool enabled)
618 {
619 mState.scissorTestEnabled = enabled;
620 }
621
isScissorTestEnabled() const622 bool Context::isScissorTestEnabled() const
623 {
624 return mState.scissorTestEnabled;
625 }
626
setDitherEnabled(bool enabled)627 void Context::setDitherEnabled(bool enabled)
628 {
629 if(mState.ditherEnabled != enabled)
630 {
631 mState.ditherEnabled = enabled;
632 mDitherStateDirty = true;
633 }
634 }
635
isDitherEnabled() const636 bool Context::isDitherEnabled() const
637 {
638 return mState.ditherEnabled;
639 }
640
setPrimitiveRestartFixedIndexEnabled(bool enabled)641 void Context::setPrimitiveRestartFixedIndexEnabled(bool enabled)
642 {
643 mState.primitiveRestartFixedIndexEnabled = enabled;
644 }
645
isPrimitiveRestartFixedIndexEnabled() const646 bool Context::isPrimitiveRestartFixedIndexEnabled() const
647 {
648 return mState.primitiveRestartFixedIndexEnabled;
649 }
650
setRasterizerDiscardEnabled(bool enabled)651 void Context::setRasterizerDiscardEnabled(bool enabled)
652 {
653 mState.rasterizerDiscardEnabled = enabled;
654 }
655
isRasterizerDiscardEnabled() const656 bool Context::isRasterizerDiscardEnabled() const
657 {
658 return mState.rasterizerDiscardEnabled;
659 }
660
setLineWidth(GLfloat width)661 void Context::setLineWidth(GLfloat width)
662 {
663 mState.lineWidth = width;
664 device->setLineWidth(clamp(width, ALIASED_LINE_WIDTH_RANGE_MIN, ALIASED_LINE_WIDTH_RANGE_MAX));
665 }
666
setGenerateMipmapHint(GLenum hint)667 void Context::setGenerateMipmapHint(GLenum hint)
668 {
669 mState.generateMipmapHint = hint;
670 }
671
setFragmentShaderDerivativeHint(GLenum hint)672 void Context::setFragmentShaderDerivativeHint(GLenum hint)
673 {
674 mState.fragmentShaderDerivativeHint = hint;
675 // TODO: Propagate the hint to shader translator so we can write
676 // ddx, ddx_coarse, or ddx_fine depending on the hint.
677 // Ignore for now. It is valid for implementations to ignore hint.
678 }
679
setTextureFilteringHint(GLenum hint)680 void Context::setTextureFilteringHint(GLenum hint)
681 {
682 mState.textureFilteringHint = hint;
683 }
684
setViewportParams(GLint x,GLint y,GLsizei width,GLsizei height)685 void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
686 {
687 mState.viewportX = x;
688 mState.viewportY = y;
689 mState.viewportWidth = std::min<GLsizei>(width, IMPLEMENTATION_MAX_RENDERBUFFER_SIZE); // GL_MAX_VIEWPORT_DIMS[0]
690 mState.viewportHeight = std::min<GLsizei>(height, IMPLEMENTATION_MAX_RENDERBUFFER_SIZE); // GL_MAX_VIEWPORT_DIMS[1]
691 }
692
setScissorParams(GLint x,GLint y,GLsizei width,GLsizei height)693 void Context::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
694 {
695 mState.scissorX = x;
696 mState.scissorY = y;
697
698 // An overflow happens when (infinite precision) X + Width > INT32_MAX. We
699 // can change that formula to "X > INT32_MAX - Width". And when we bring it
700 // down to 32-bit precision, we know it's safe because width is non-negative.
701 if (x > INT32_MAX - width)
702 {
703 width = INT32_MAX - x;
704 }
705
706 if (y > INT32_MAX - height)
707 {
708 height = INT32_MAX - y;
709 }
710
711 mState.scissorWidth = width;
712 mState.scissorHeight = height;
713 }
714
setColorMask(bool red,bool green,bool blue,bool alpha)715 void Context::setColorMask(bool red, bool green, bool blue, bool alpha)
716 {
717 if(mState.colorMaskRed != red || mState.colorMaskGreen != green ||
718 mState.colorMaskBlue != blue || mState.colorMaskAlpha != alpha)
719 {
720 mState.colorMaskRed = red;
721 mState.colorMaskGreen = green;
722 mState.colorMaskBlue = blue;
723 mState.colorMaskAlpha = alpha;
724 mMaskStateDirty = true;
725 }
726 }
727
getColorMask() const728 unsigned int Context::getColorMask() const
729 {
730 return (mState.colorMaskRed ? 0x1 : 0) |
731 (mState.colorMaskGreen ? 0x2 : 0) |
732 (mState.colorMaskBlue ? 0x4 : 0) |
733 (mState.colorMaskAlpha ? 0x8 : 0);
734 }
735
setDepthMask(bool mask)736 void Context::setDepthMask(bool mask)
737 {
738 if(mState.depthMask != mask)
739 {
740 mState.depthMask = mask;
741 mMaskStateDirty = true;
742 }
743 }
744
setActiveSampler(unsigned int active)745 void Context::setActiveSampler(unsigned int active)
746 {
747 mState.activeSampler = active;
748 }
749
getReadFramebufferName() const750 GLuint Context::getReadFramebufferName() const
751 {
752 return mState.readFramebuffer;
753 }
754
getDrawFramebufferName() const755 GLuint Context::getDrawFramebufferName() const
756 {
757 return mState.drawFramebuffer;
758 }
759
getRenderbufferName() const760 GLuint Context::getRenderbufferName() const
761 {
762 return mState.renderbuffer.name();
763 }
764
setFramebufferReadBuffer(GLuint buf)765 void Context::setFramebufferReadBuffer(GLuint buf)
766 {
767 Framebuffer *framebuffer = getReadFramebuffer();
768
769 if(framebuffer)
770 {
771 framebuffer->setReadBuffer(buf);
772 }
773 else
774 {
775 return error(GL_INVALID_OPERATION);
776 }
777 }
778
setFramebufferDrawBuffers(GLsizei n,const GLenum * bufs)779 void Context::setFramebufferDrawBuffers(GLsizei n, const GLenum *bufs)
780 {
781 Framebuffer *drawFramebuffer = getDrawFramebuffer();
782
783 if(drawFramebuffer)
784 {
785 for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++)
786 {
787 drawFramebuffer->setDrawBuffer(i, (i < n) ? bufs[i] : GL_NONE);
788 }
789 }
790 else
791 {
792 return error(GL_INVALID_OPERATION);
793 }
794 }
795
getArrayBufferName() const796 GLuint Context::getArrayBufferName() const
797 {
798 return mState.arrayBuffer.name();
799 }
800
getElementArrayBufferName() const801 GLuint Context::getElementArrayBufferName() const
802 {
803 Buffer* elementArrayBuffer = getCurrentVertexArray()->getElementArrayBuffer();
804 return elementArrayBuffer ? elementArrayBuffer->name : 0;
805 }
806
getActiveQuery(GLenum target) const807 GLuint Context::getActiveQuery(GLenum target) const
808 {
809 Query *queryObject = nullptr;
810
811 switch(target)
812 {
813 case GL_ANY_SAMPLES_PASSED_EXT:
814 queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED];
815 break;
816 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
817 queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE];
818 break;
819 case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
820 queryObject = mState.activeQuery[QUERY_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN];
821 break;
822 default:
823 ASSERT(false);
824 }
825
826 if(queryObject)
827 {
828 return queryObject->name;
829 }
830
831 return 0;
832 }
833
setVertexAttribArrayEnabled(unsigned int attribNum,bool enabled)834 void Context::setVertexAttribArrayEnabled(unsigned int attribNum, bool enabled)
835 {
836 getCurrentVertexArray()->enableAttribute(attribNum, enabled);
837 }
838
setVertexAttribDivisor(unsigned int attribNum,GLuint divisor)839 void Context::setVertexAttribDivisor(unsigned int attribNum, GLuint divisor)
840 {
841 getCurrentVertexArray()->setVertexAttribDivisor(attribNum, divisor);
842 }
843
getVertexAttribState(unsigned int attribNum) const844 const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum) const
845 {
846 return getCurrentVertexArray()->getVertexAttribute(attribNum);
847 }
848
setVertexAttribState(unsigned int attribNum,Buffer * boundBuffer,GLint size,GLenum type,bool normalized,bool pureInteger,GLsizei stride,const void * pointer)849 void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type,
850 bool normalized, bool pureInteger, GLsizei stride, const void *pointer)
851 {
852 getCurrentVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, pureInteger, stride, pointer);
853 }
854
getVertexAttribPointer(unsigned int attribNum) const855 const void *Context::getVertexAttribPointer(unsigned int attribNum) const
856 {
857 return getCurrentVertexArray()->getVertexAttribute(attribNum).mPointer;
858 }
859
getVertexArrayAttributes()860 const VertexAttributeArray &Context::getVertexArrayAttributes()
861 {
862 return getCurrentVertexArray()->getVertexAttributes();
863 }
864
getCurrentVertexAttributes()865 const VertexAttributeArray &Context::getCurrentVertexAttributes()
866 {
867 return mState.vertexAttribute;
868 }
869
setPackAlignment(GLint alignment)870 void Context::setPackAlignment(GLint alignment)
871 {
872 mState.packParameters.alignment = alignment;
873 }
874
setUnpackAlignment(GLint alignment)875 void Context::setUnpackAlignment(GLint alignment)
876 {
877 mState.unpackParameters.alignment = alignment;
878 }
879
getUnpackParameters() const880 const gl::PixelStorageModes &Context::getUnpackParameters() const
881 {
882 return mState.unpackParameters;
883 }
884
setPackRowLength(GLint rowLength)885 void Context::setPackRowLength(GLint rowLength)
886 {
887 mState.packParameters.rowLength = rowLength;
888 }
889
setPackSkipPixels(GLint skipPixels)890 void Context::setPackSkipPixels(GLint skipPixels)
891 {
892 mState.packParameters.skipPixels = skipPixels;
893 }
894
setPackSkipRows(GLint skipRows)895 void Context::setPackSkipRows(GLint skipRows)
896 {
897 mState.packParameters.skipRows = skipRows;
898 }
899
setUnpackRowLength(GLint rowLength)900 void Context::setUnpackRowLength(GLint rowLength)
901 {
902 mState.unpackParameters.rowLength = rowLength;
903 }
904
setUnpackImageHeight(GLint imageHeight)905 void Context::setUnpackImageHeight(GLint imageHeight)
906 {
907 mState.unpackParameters.imageHeight = imageHeight;
908 }
909
setUnpackSkipPixels(GLint skipPixels)910 void Context::setUnpackSkipPixels(GLint skipPixels)
911 {
912 mState.unpackParameters.skipPixels = skipPixels;
913 }
914
setUnpackSkipRows(GLint skipRows)915 void Context::setUnpackSkipRows(GLint skipRows)
916 {
917 mState.unpackParameters.skipRows = skipRows;
918 }
919
setUnpackSkipImages(GLint skipImages)920 void Context::setUnpackSkipImages(GLint skipImages)
921 {
922 mState.unpackParameters.skipImages = skipImages;
923 }
924
createBuffer()925 GLuint Context::createBuffer()
926 {
927 return mResourceManager->createBuffer();
928 }
929
createProgram()930 GLuint Context::createProgram()
931 {
932 return mResourceManager->createProgram();
933 }
934
createShader(GLenum type)935 GLuint Context::createShader(GLenum type)
936 {
937 return mResourceManager->createShader(type);
938 }
939
createTexture()940 GLuint Context::createTexture()
941 {
942 return mResourceManager->createTexture();
943 }
944
createRenderbuffer()945 GLuint Context::createRenderbuffer()
946 {
947 return mResourceManager->createRenderbuffer();
948 }
949
950 // Returns an unused framebuffer name
createFramebuffer()951 GLuint Context::createFramebuffer()
952 {
953 return mFramebufferNameSpace.allocate();
954 }
955
createFence()956 GLuint Context::createFence()
957 {
958 return mFenceNameSpace.allocate(new Fence());
959 }
960
961 // Returns an unused query name
createQuery()962 GLuint Context::createQuery()
963 {
964 return mQueryNameSpace.allocate();
965 }
966
967 // Returns an unused vertex array name
createVertexArray()968 GLuint Context::createVertexArray()
969 {
970 return mVertexArrayNameSpace.allocate();
971 }
972
createFenceSync(GLenum condition,GLbitfield flags)973 GLsync Context::createFenceSync(GLenum condition, GLbitfield flags)
974 {
975 GLuint handle = mResourceManager->createFenceSync(condition, flags);
976
977 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
978 }
979
980 // Returns an unused transform feedback name
createTransformFeedback()981 GLuint Context::createTransformFeedback()
982 {
983 return mTransformFeedbackNameSpace.allocate();
984 }
985
986 // Returns an unused sampler name
createSampler()987 GLuint Context::createSampler()
988 {
989 return mResourceManager->createSampler();
990 }
991
deleteBuffer(GLuint buffer)992 void Context::deleteBuffer(GLuint buffer)
993 {
994 detachBuffer(buffer);
995
996 mResourceManager->deleteBuffer(buffer);
997 }
998
deleteShader(GLuint shader)999 void Context::deleteShader(GLuint shader)
1000 {
1001 mResourceManager->deleteShader(shader);
1002 }
1003
deleteProgram(GLuint program)1004 void Context::deleteProgram(GLuint program)
1005 {
1006 mResourceManager->deleteProgram(program);
1007 }
1008
deleteTexture(GLuint texture)1009 void Context::deleteTexture(GLuint texture)
1010 {
1011 detachTexture(texture);
1012
1013 mResourceManager->deleteTexture(texture);
1014 }
1015
deleteRenderbuffer(GLuint renderbuffer)1016 void Context::deleteRenderbuffer(GLuint renderbuffer)
1017 {
1018 if(mResourceManager->getRenderbuffer(renderbuffer))
1019 {
1020 detachRenderbuffer(renderbuffer);
1021 }
1022
1023 mResourceManager->deleteRenderbuffer(renderbuffer);
1024 }
1025
deleteFramebuffer(GLuint framebuffer)1026 void Context::deleteFramebuffer(GLuint framebuffer)
1027 {
1028 detachFramebuffer(framebuffer);
1029
1030 Framebuffer *framebufferObject = mFramebufferNameSpace.remove(framebuffer);
1031
1032 if(framebufferObject)
1033 {
1034 delete framebufferObject;
1035 }
1036 }
1037
deleteFence(GLuint fence)1038 void Context::deleteFence(GLuint fence)
1039 {
1040 Fence *fenceObject = mFenceNameSpace.remove(fence);
1041
1042 if(fenceObject)
1043 {
1044 delete fenceObject;
1045 }
1046 }
1047
deleteQuery(GLuint query)1048 void Context::deleteQuery(GLuint query)
1049 {
1050 Query *queryObject = mQueryNameSpace.remove(query);
1051
1052 if(queryObject)
1053 {
1054 queryObject->release();
1055 }
1056 }
1057
deleteVertexArray(GLuint vertexArray)1058 void Context::deleteVertexArray(GLuint vertexArray)
1059 {
1060 // [OpenGL ES 3.0.2] section 2.10 page 43:
1061 // If a vertex array object that is currently bound is deleted, the binding
1062 // for that object reverts to zero and the default vertex array becomes current.
1063 if(getCurrentVertexArray()->name == vertexArray)
1064 {
1065 bindVertexArray(0);
1066 }
1067
1068 VertexArray *vertexArrayObject = mVertexArrayNameSpace.remove(vertexArray);
1069
1070 if(vertexArrayObject)
1071 {
1072 delete vertexArrayObject;
1073 }
1074 }
1075
deleteFenceSync(GLsync fenceSync)1076 void Context::deleteFenceSync(GLsync fenceSync)
1077 {
1078 // The spec specifies the underlying Fence object is not deleted until all current
1079 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
1080 // and since our API is currently designed for being called from a single thread, we can delete
1081 // the fence immediately.
1082 mResourceManager->deleteFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
1083 }
1084
deleteTransformFeedback(GLuint transformFeedback)1085 void Context::deleteTransformFeedback(GLuint transformFeedback)
1086 {
1087 TransformFeedback *transformFeedbackObject = mTransformFeedbackNameSpace.remove(transformFeedback);
1088
1089 // Detach if currently bound.
1090 if(mState.transformFeedback == transformFeedback)
1091 {
1092 mState.transformFeedback = 0;
1093 }
1094
1095 if(transformFeedbackObject)
1096 {
1097 delete transformFeedbackObject;
1098 }
1099 }
1100
deleteSampler(GLuint sampler)1101 void Context::deleteSampler(GLuint sampler)
1102 {
1103 detachSampler(sampler);
1104
1105 mResourceManager->deleteSampler(sampler);
1106 }
1107
getBuffer(GLuint handle) const1108 Buffer *Context::getBuffer(GLuint handle) const
1109 {
1110 return mResourceManager->getBuffer(handle);
1111 }
1112
getShader(GLuint handle) const1113 Shader *Context::getShader(GLuint handle) const
1114 {
1115 return mResourceManager->getShader(handle);
1116 }
1117
getProgram(GLuint handle) const1118 Program *Context::getProgram(GLuint handle) const
1119 {
1120 return mResourceManager->getProgram(handle);
1121 }
1122
getTexture(GLuint handle) const1123 Texture *Context::getTexture(GLuint handle) const
1124 {
1125 return mResourceManager->getTexture(handle);
1126 }
1127
getRenderbuffer(GLuint handle) const1128 Renderbuffer *Context::getRenderbuffer(GLuint handle) const
1129 {
1130 return mResourceManager->getRenderbuffer(handle);
1131 }
1132
getReadFramebuffer() const1133 Framebuffer *Context::getReadFramebuffer() const
1134 {
1135 return getFramebuffer(mState.readFramebuffer);
1136 }
1137
getDrawFramebuffer() const1138 Framebuffer *Context::getDrawFramebuffer() const
1139 {
1140 return getFramebuffer(mState.drawFramebuffer);
1141 }
1142
bindArrayBuffer(unsigned int buffer)1143 void Context::bindArrayBuffer(unsigned int buffer)
1144 {
1145 mResourceManager->checkBufferAllocation(buffer);
1146
1147 mState.arrayBuffer = getBuffer(buffer);
1148 }
1149
bindElementArrayBuffer(unsigned int buffer)1150 void Context::bindElementArrayBuffer(unsigned int buffer)
1151 {
1152 mResourceManager->checkBufferAllocation(buffer);
1153
1154 getCurrentVertexArray()->setElementArrayBuffer(getBuffer(buffer));
1155 }
1156
bindCopyReadBuffer(GLuint buffer)1157 void Context::bindCopyReadBuffer(GLuint buffer)
1158 {
1159 mResourceManager->checkBufferAllocation(buffer);
1160
1161 mState.copyReadBuffer = getBuffer(buffer);
1162 }
1163
bindCopyWriteBuffer(GLuint buffer)1164 void Context::bindCopyWriteBuffer(GLuint buffer)
1165 {
1166 mResourceManager->checkBufferAllocation(buffer);
1167
1168 mState.copyWriteBuffer = getBuffer(buffer);
1169 }
1170
bindPixelPackBuffer(GLuint buffer)1171 void Context::bindPixelPackBuffer(GLuint buffer)
1172 {
1173 mResourceManager->checkBufferAllocation(buffer);
1174
1175 mState.pixelPackBuffer = getBuffer(buffer);
1176 }
1177
bindPixelUnpackBuffer(GLuint buffer)1178 void Context::bindPixelUnpackBuffer(GLuint buffer)
1179 {
1180 mResourceManager->checkBufferAllocation(buffer);
1181
1182 mState.pixelUnpackBuffer = getBuffer(buffer);
1183 }
1184
bindTransformFeedbackBuffer(GLuint buffer)1185 void Context::bindTransformFeedbackBuffer(GLuint buffer)
1186 {
1187 mResourceManager->checkBufferAllocation(buffer);
1188
1189 mState.genericTransformFeedbackBuffer = getBuffer(buffer);
1190 }
1191
bindTexture(TextureType type,GLuint texture)1192 void Context::bindTexture(TextureType type, GLuint texture)
1193 {
1194 mResourceManager->checkTextureAllocation(texture, type);
1195
1196 mState.samplerTexture[type][mState.activeSampler] = getTexture(texture);
1197 }
1198
bindReadFramebuffer(GLuint framebuffer)1199 void Context::bindReadFramebuffer(GLuint framebuffer)
1200 {
1201 if(!getFramebuffer(framebuffer))
1202 {
1203 if(framebuffer == 0)
1204 {
1205 mFramebufferNameSpace.insert(framebuffer, new DefaultFramebuffer());
1206 }
1207 else
1208 {
1209 mFramebufferNameSpace.insert(framebuffer, new Framebuffer());
1210 }
1211 }
1212
1213 mState.readFramebuffer = framebuffer;
1214 }
1215
bindDrawFramebuffer(GLuint framebuffer)1216 void Context::bindDrawFramebuffer(GLuint framebuffer)
1217 {
1218 if(!getFramebuffer(framebuffer))
1219 {
1220 if(framebuffer == 0)
1221 {
1222 mFramebufferNameSpace.insert(framebuffer, new DefaultFramebuffer());
1223 }
1224 else
1225 {
1226 mFramebufferNameSpace.insert(framebuffer, new Framebuffer());
1227 }
1228 }
1229
1230 mState.drawFramebuffer = framebuffer;
1231 }
1232
bindRenderbuffer(GLuint renderbuffer)1233 void Context::bindRenderbuffer(GLuint renderbuffer)
1234 {
1235 mResourceManager->checkRenderbufferAllocation(renderbuffer);
1236
1237 mState.renderbuffer = getRenderbuffer(renderbuffer);
1238 }
1239
bindVertexArray(GLuint array)1240 void Context::bindVertexArray(GLuint array)
1241 {
1242 VertexArray *vertexArray = getVertexArray(array);
1243
1244 if(!vertexArray)
1245 {
1246 vertexArray = new VertexArray(array);
1247 mVertexArrayNameSpace.insert(array, vertexArray);
1248 }
1249
1250 mState.vertexArray = array;
1251 }
1252
bindGenericUniformBuffer(GLuint buffer)1253 void Context::bindGenericUniformBuffer(GLuint buffer)
1254 {
1255 mResourceManager->checkBufferAllocation(buffer);
1256
1257 mState.genericUniformBuffer = getBuffer(buffer);
1258 }
1259
bindIndexedUniformBuffer(GLuint buffer,GLuint index,GLintptr offset,GLsizeiptr size)1260 void Context::bindIndexedUniformBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
1261 {
1262 mResourceManager->checkBufferAllocation(buffer);
1263
1264 Buffer* bufferObject = getBuffer(buffer);
1265 mState.uniformBuffers[index].set(bufferObject, static_cast<int>(offset), static_cast<int>(size));
1266 }
1267
bindGenericTransformFeedbackBuffer(GLuint buffer)1268 void Context::bindGenericTransformFeedbackBuffer(GLuint buffer)
1269 {
1270 mResourceManager->checkBufferAllocation(buffer);
1271
1272 mState.genericTransformFeedbackBuffer = getBuffer(buffer);
1273 }
1274
bindIndexedTransformFeedbackBuffer(GLuint buffer,GLuint index,GLintptr offset,GLsizeiptr size)1275 void Context::bindIndexedTransformFeedbackBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
1276 {
1277 mResourceManager->checkBufferAllocation(buffer);
1278
1279 Buffer* bufferObject = getBuffer(buffer);
1280 getTransformFeedback()->setBuffer(index, bufferObject, offset, size);
1281 mState.genericTransformFeedbackBuffer = bufferObject;
1282 }
1283
bindTransformFeedback(GLuint id)1284 void Context::bindTransformFeedback(GLuint id)
1285 {
1286 if(!getTransformFeedback(id))
1287 {
1288 mTransformFeedbackNameSpace.insert(id, new TransformFeedback(id));
1289 }
1290
1291 mState.transformFeedback = id;
1292 }
1293
bindSampler(GLuint unit,GLuint sampler)1294 bool Context::bindSampler(GLuint unit, GLuint sampler)
1295 {
1296 mResourceManager->checkSamplerAllocation(sampler);
1297
1298 Sampler* samplerObject = getSampler(sampler);
1299
1300 mState.sampler[unit] = samplerObject;
1301
1302 return !!samplerObject;
1303 }
1304
useProgram(GLuint program)1305 void Context::useProgram(GLuint program)
1306 {
1307 GLuint priorProgram = mState.currentProgram;
1308 mState.currentProgram = program; // Must switch before trying to delete, otherwise it only gets flagged.
1309
1310 if(priorProgram != program)
1311 {
1312 Program *newProgram = mResourceManager->getProgram(program);
1313 Program *oldProgram = mResourceManager->getProgram(priorProgram);
1314
1315 if(newProgram)
1316 {
1317 newProgram->addRef();
1318 }
1319
1320 if(oldProgram)
1321 {
1322 oldProgram->release();
1323 }
1324 }
1325 }
1326
beginQuery(GLenum target,GLuint query)1327 void Context::beginQuery(GLenum target, GLuint query)
1328 {
1329 // From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id>
1330 // of zero, if the active query object name for <target> is non-zero (for the
1331 // targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if
1332 // the active query for either target is non-zero), if <id> is the name of an
1333 // existing query object whose type does not match <target>, or if <id> is the
1334 // active query object name for any query type, the error INVALID_OPERATION is
1335 // generated.
1336
1337 // Ensure no other queries are active
1338 // NOTE: If other queries than occlusion are supported, we will need to check
1339 // separately that:
1340 // a) The query ID passed is not the current active query for any target/type
1341 // b) There are no active queries for the requested target (and in the case
1342 // of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
1343 // no query may be active for either if glBeginQuery targets either.
1344 for(int i = 0; i < QUERY_TYPE_COUNT; i++)
1345 {
1346 if(mState.activeQuery[i])
1347 {
1348 switch(mState.activeQuery[i]->getType())
1349 {
1350 case GL_ANY_SAMPLES_PASSED_EXT:
1351 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
1352 if((target == GL_ANY_SAMPLES_PASSED_EXT) ||
1353 (target == GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT))
1354 {
1355 return error(GL_INVALID_OPERATION);
1356 }
1357 break;
1358 case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
1359 if(target == GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN)
1360 {
1361 return error(GL_INVALID_OPERATION);
1362 }
1363 break;
1364 default:
1365 break;
1366 }
1367 }
1368 }
1369
1370 QueryType qType;
1371 switch(target)
1372 {
1373 case GL_ANY_SAMPLES_PASSED_EXT:
1374 qType = QUERY_ANY_SAMPLES_PASSED;
1375 break;
1376 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
1377 qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE;
1378 break;
1379 case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
1380 qType = QUERY_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN;
1381 break;
1382 default:
1383 UNREACHABLE(target);
1384 return error(GL_INVALID_ENUM);
1385 }
1386
1387 Query *queryObject = createQuery(query, target);
1388
1389 // Check that name was obtained with glGenQueries
1390 if(!queryObject)
1391 {
1392 return error(GL_INVALID_OPERATION);
1393 }
1394
1395 // Check for type mismatch
1396 if(queryObject->getType() != target)
1397 {
1398 return error(GL_INVALID_OPERATION);
1399 }
1400
1401 // Set query as active for specified target
1402 mState.activeQuery[qType] = queryObject;
1403
1404 // Begin query
1405 queryObject->begin();
1406 }
1407
endQuery(GLenum target)1408 void Context::endQuery(GLenum target)
1409 {
1410 QueryType qType;
1411
1412 switch(target)
1413 {
1414 case GL_ANY_SAMPLES_PASSED_EXT: qType = QUERY_ANY_SAMPLES_PASSED; break;
1415 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE; break;
1416 case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: qType = QUERY_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN; break;
1417 default: UNREACHABLE(target); return;
1418 }
1419
1420 Query *queryObject = mState.activeQuery[qType];
1421
1422 if(!queryObject)
1423 {
1424 return error(GL_INVALID_OPERATION);
1425 }
1426
1427 queryObject->end();
1428
1429 mState.activeQuery[qType] = nullptr;
1430 }
1431
setFramebufferZero(Framebuffer * buffer)1432 void Context::setFramebufferZero(Framebuffer *buffer)
1433 {
1434 delete mFramebufferNameSpace.remove(0);
1435 mFramebufferNameSpace.insert(0, buffer);
1436 }
1437
setRenderbufferStorage(RenderbufferStorage * renderbuffer)1438 void Context::setRenderbufferStorage(RenderbufferStorage *renderbuffer)
1439 {
1440 Renderbuffer *renderbufferObject = mState.renderbuffer;
1441 renderbufferObject->setStorage(renderbuffer);
1442 }
1443
getFramebuffer(unsigned int handle) const1444 Framebuffer *Context::getFramebuffer(unsigned int handle) const
1445 {
1446 return mFramebufferNameSpace.find(handle);
1447 }
1448
getFence(unsigned int handle) const1449 Fence *Context::getFence(unsigned int handle) const
1450 {
1451 return mFenceNameSpace.find(handle);
1452 }
1453
getFenceSync(GLsync handle) const1454 FenceSync *Context::getFenceSync(GLsync handle) const
1455 {
1456 return mResourceManager->getFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
1457 }
1458
getQuery(unsigned int handle) const1459 Query *Context::getQuery(unsigned int handle) const
1460 {
1461 return mQueryNameSpace.find(handle);
1462 }
1463
createQuery(unsigned int handle,GLenum type)1464 Query *Context::createQuery(unsigned int handle, GLenum type)
1465 {
1466 if(!mQueryNameSpace.isReserved(handle))
1467 {
1468 return nullptr;
1469 }
1470 else
1471 {
1472 Query *query = mQueryNameSpace.find(handle);
1473 if(!query)
1474 {
1475 query = new Query(handle, type);
1476 query->addRef();
1477 mQueryNameSpace.insert(handle, query);
1478 }
1479
1480 return query;
1481 }
1482 }
1483
getVertexArray(GLuint array) const1484 VertexArray *Context::getVertexArray(GLuint array) const
1485 {
1486 return mVertexArrayNameSpace.find(array);
1487 }
1488
getCurrentVertexArray() const1489 VertexArray *Context::getCurrentVertexArray() const
1490 {
1491 return getVertexArray(mState.vertexArray);
1492 }
1493
isVertexArray(GLuint array) const1494 bool Context::isVertexArray(GLuint array) const
1495 {
1496 return mVertexArrayNameSpace.isReserved(array);
1497 }
1498
hasZeroDivisor() const1499 bool Context::hasZeroDivisor() const
1500 {
1501 // Verify there is at least one active attribute with a divisor of zero
1502 es2::Program *programObject = getCurrentProgram();
1503 for(int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
1504 {
1505 bool active = (programObject->getAttributeStream(attributeIndex) != -1);
1506 if(active && getCurrentVertexArray()->getVertexAttribute(attributeIndex).mDivisor == 0)
1507 {
1508 return true;
1509 }
1510 }
1511
1512 return false;
1513 }
1514
getTransformFeedback(GLuint transformFeedback) const1515 TransformFeedback *Context::getTransformFeedback(GLuint transformFeedback) const
1516 {
1517 return mTransformFeedbackNameSpace.find(transformFeedback);
1518 }
1519
isTransformFeedback(GLuint array) const1520 bool Context::isTransformFeedback(GLuint array) const
1521 {
1522 return mTransformFeedbackNameSpace.isReserved(array);
1523 }
1524
getSampler(GLuint sampler) const1525 Sampler *Context::getSampler(GLuint sampler) const
1526 {
1527 return mResourceManager->getSampler(sampler);
1528 }
1529
isSampler(GLuint sampler) const1530 bool Context::isSampler(GLuint sampler) const
1531 {
1532 return mResourceManager->isSampler(sampler);
1533 }
1534
getArrayBuffer() const1535 Buffer *Context::getArrayBuffer() const
1536 {
1537 return mState.arrayBuffer;
1538 }
1539
getElementArrayBuffer() const1540 Buffer *Context::getElementArrayBuffer() const
1541 {
1542 return getCurrentVertexArray()->getElementArrayBuffer();
1543 }
1544
getCopyReadBuffer() const1545 Buffer *Context::getCopyReadBuffer() const
1546 {
1547 return mState.copyReadBuffer;
1548 }
1549
getCopyWriteBuffer() const1550 Buffer *Context::getCopyWriteBuffer() const
1551 {
1552 return mState.copyWriteBuffer;
1553 }
1554
getPixelPackBuffer() const1555 Buffer *Context::getPixelPackBuffer() const
1556 {
1557 return mState.pixelPackBuffer;
1558 }
1559
getPixelUnpackBuffer() const1560 Buffer *Context::getPixelUnpackBuffer() const
1561 {
1562 return mState.pixelUnpackBuffer;
1563 }
1564
getGenericUniformBuffer() const1565 Buffer *Context::getGenericUniformBuffer() const
1566 {
1567 return mState.genericUniformBuffer;
1568 }
1569
1570 // The "required buffer size" is the number of bytes from the start of the
1571 // buffer to the last byte referenced within the buffer. If the caller of this
1572 // function has to worry about offsets within the buffer, it only needs to add
1573 // that byte offset to this function's return value to get its required buffer
1574 // size.
getRequiredBufferSize(GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLenum type) const1575 size_t Context::getRequiredBufferSize(GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type) const
1576 {
1577 // 0-dimensional images have no bytes in them.
1578 if (width == 0 || height == 0 || depth == 0)
1579 {
1580 return 0;
1581 }
1582
1583 GLint pixelsPerRow = (mState.unpackParameters.rowLength) > 0 ? mState.unpackParameters.rowLength : width;
1584 GLint rowsPerImage = (mState.unpackParameters.imageHeight) > 0 ? mState.unpackParameters.imageHeight : height;
1585
1586 GLint bytesPerPixel = gl::ComputePixelSize(format, type);
1587 GLint bytesPerRow = gl::ComputePitch(pixelsPerRow, format, type, mState.unpackParameters.alignment);
1588 GLint bytesPerImage = rowsPerImage * bytesPerRow;
1589
1590 // Depth and height are subtracted by 1, while width is not, because we're not
1591 // reading the full last row or image, but we are reading the full last pixel.
1592 return (mState.unpackParameters.skipImages + (depth - 1)) * bytesPerImage
1593 + (mState.unpackParameters.skipRows + (height - 1)) * bytesPerRow
1594 + (mState.unpackParameters.skipPixels + (width)) * bytesPerPixel;
1595 }
1596
getPixels(const GLvoid ** pixels,GLenum type,size_t imageSize) const1597 GLenum Context::getPixels(const GLvoid **pixels, GLenum type, size_t imageSize) const
1598 {
1599 if(mState.pixelUnpackBuffer)
1600 {
1601 ASSERT(mState.pixelUnpackBuffer->name != 0);
1602
1603 if(mState.pixelUnpackBuffer->isMapped())
1604 {
1605 return GL_INVALID_OPERATION;
1606 }
1607
1608 size_t offset = static_cast<size_t>((ptrdiff_t)(*pixels));
1609
1610 if(offset % GetTypeSize(type) != 0)
1611 {
1612 return GL_INVALID_OPERATION;
1613 }
1614
1615 if(offset > mState.pixelUnpackBuffer->size())
1616 {
1617 return GL_INVALID_OPERATION;
1618 }
1619
1620 if(mState.pixelUnpackBuffer->size() - offset < imageSize)
1621 {
1622 return GL_INVALID_OPERATION;
1623 }
1624
1625 *pixels = static_cast<const unsigned char*>(mState.pixelUnpackBuffer->data()) + offset;
1626 }
1627
1628 return GL_NO_ERROR;
1629 }
1630
getBuffer(GLenum target,es2::Buffer ** buffer) const1631 bool Context::getBuffer(GLenum target, es2::Buffer **buffer) const
1632 {
1633 switch(target)
1634 {
1635 case GL_ARRAY_BUFFER:
1636 *buffer = getArrayBuffer();
1637 break;
1638 case GL_ELEMENT_ARRAY_BUFFER:
1639 *buffer = getElementArrayBuffer();
1640 break;
1641 case GL_COPY_READ_BUFFER:
1642 *buffer = getCopyReadBuffer();
1643 break;
1644 case GL_COPY_WRITE_BUFFER:
1645 *buffer = getCopyWriteBuffer();
1646 break;
1647 case GL_PIXEL_PACK_BUFFER:
1648 *buffer = getPixelPackBuffer();
1649 break;
1650 case GL_PIXEL_UNPACK_BUFFER:
1651 *buffer = getPixelUnpackBuffer();
1652 break;
1653 case GL_TRANSFORM_FEEDBACK_BUFFER:
1654 *buffer = static_cast<es2::Buffer*>(mState.genericTransformFeedbackBuffer);
1655 break;
1656 case GL_UNIFORM_BUFFER:
1657 *buffer = getGenericUniformBuffer();
1658 break;
1659 default:
1660 return false;
1661 }
1662 return true;
1663 }
1664
getTransformFeedback() const1665 TransformFeedback *Context::getTransformFeedback() const
1666 {
1667 return getTransformFeedback(mState.transformFeedback);
1668 }
1669
getCurrentProgram() const1670 Program *Context::getCurrentProgram() const
1671 {
1672 return mResourceManager->getProgram(mState.currentProgram);
1673 }
1674
getTargetTexture(GLenum target) const1675 Texture *Context::getTargetTexture(GLenum target) const
1676 {
1677 Texture *texture = nullptr;
1678
1679 switch(target)
1680 {
1681 case GL_TEXTURE_2D: texture = getTexture2D(); break;
1682 case GL_TEXTURE_2D_ARRAY: texture = getTexture2DArray(); break;
1683 case GL_TEXTURE_3D: texture = getTexture3D(); break;
1684 case GL_TEXTURE_CUBE_MAP: texture = getTextureCubeMap(); break;
1685 case GL_TEXTURE_EXTERNAL_OES: texture = getTextureExternal(); break;
1686 case GL_TEXTURE_RECTANGLE_ARB: texture = getTexture2DRect(); break;
1687 default:
1688 return error(GL_INVALID_ENUM, nullptr);
1689 }
1690
1691 ASSERT(texture); // Must always have a default texture to fall back to.
1692
1693 return texture;
1694 }
1695
getTexture2D() const1696 Texture2D *Context::getTexture2D() const
1697 {
1698 return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D));
1699 }
1700
getTexture2D(GLenum target) const1701 Texture2D *Context::getTexture2D(GLenum target) const
1702 {
1703 switch(target)
1704 {
1705 case GL_TEXTURE_2D: return getTexture2D();
1706 case GL_TEXTURE_RECTANGLE_ARB: return getTexture2DRect();
1707 case GL_TEXTURE_EXTERNAL_OES: return getTextureExternal();
1708 default: UNREACHABLE(target);
1709 }
1710
1711 return nullptr;
1712 }
1713
getTexture3D() const1714 Texture3D *Context::getTexture3D() const
1715 {
1716 return static_cast<Texture3D*>(getSamplerTexture(mState.activeSampler, TEXTURE_3D));
1717 }
1718
getTexture2DArray() const1719 Texture2DArray *Context::getTexture2DArray() const
1720 {
1721 return static_cast<Texture2DArray*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D_ARRAY));
1722 }
1723
getTextureCubeMap() const1724 TextureCubeMap *Context::getTextureCubeMap() const
1725 {
1726 return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, TEXTURE_CUBE));
1727 }
1728
getTexture2DRect() const1729 Texture2DRect *Context::getTexture2DRect() const
1730 {
1731 return static_cast<Texture2DRect*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D_RECT));
1732 }
1733
getTextureExternal() const1734 TextureExternal *Context::getTextureExternal() const
1735 {
1736 return static_cast<TextureExternal*>(getSamplerTexture(mState.activeSampler, TEXTURE_EXTERNAL));
1737 }
1738
getSamplerTexture(unsigned int sampler,TextureType type) const1739 Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type) const
1740 {
1741 GLuint texid = mState.samplerTexture[type][sampler].name();
1742
1743 if(texid == 0) // Special case: 0 refers to different initial textures based on the target
1744 {
1745 switch(type)
1746 {
1747 case TEXTURE_2D: return mTexture2DZero;
1748 case TEXTURE_3D: return mTexture3DZero;
1749 case TEXTURE_2D_ARRAY: return mTexture2DArrayZero;
1750 case TEXTURE_CUBE: return mTextureCubeMapZero;
1751 case TEXTURE_2D_RECT: return mTexture2DRectZero;
1752 case TEXTURE_EXTERNAL: return mTextureExternalZero;
1753 default: UNREACHABLE(type);
1754 }
1755 }
1756
1757 return mState.samplerTexture[type][sampler];
1758 }
1759
samplerParameteri(GLuint sampler,GLenum pname,GLint param)1760 void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
1761 {
1762 mResourceManager->checkSamplerAllocation(sampler);
1763
1764 Sampler *samplerObject = getSampler(sampler);
1765 ASSERT(samplerObject);
1766
1767 switch(pname)
1768 {
1769 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(static_cast<GLenum>(param)); break;
1770 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(static_cast<GLenum>(param)); break;
1771 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(static_cast<GLenum>(param)); break;
1772 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(static_cast<GLenum>(param)); break;
1773 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(static_cast<GLenum>(param)); break;
1774 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(static_cast<GLfloat>(param)); break;
1775 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(static_cast<GLfloat>(param)); break;
1776 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(static_cast<GLenum>(param)); break;
1777 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(static_cast<GLenum>(param)); break;
1778 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(static_cast<GLfloat>(param)); break;
1779 default: UNREACHABLE(pname); break;
1780 }
1781 }
1782
samplerParameterf(GLuint sampler,GLenum pname,GLfloat param)1783 void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
1784 {
1785 mResourceManager->checkSamplerAllocation(sampler);
1786
1787 Sampler *samplerObject = getSampler(sampler);
1788 ASSERT(samplerObject);
1789
1790 switch(pname)
1791 {
1792 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(static_cast<GLenum>(roundf(param))); break;
1793 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(static_cast<GLenum>(roundf(param))); break;
1794 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(static_cast<GLenum>(roundf(param))); break;
1795 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(static_cast<GLenum>(roundf(param))); break;
1796 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(static_cast<GLenum>(roundf(param))); break;
1797 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(param); break;
1798 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(param); break;
1799 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(static_cast<GLenum>(roundf(param))); break;
1800 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(static_cast<GLenum>(roundf(param))); break;
1801 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(param); break;
1802 default: UNREACHABLE(pname); break;
1803 }
1804 }
1805
getSamplerParameteri(GLuint sampler,GLenum pname)1806 GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname)
1807 {
1808 mResourceManager->checkSamplerAllocation(sampler);
1809
1810 Sampler *samplerObject = getSampler(sampler);
1811 ASSERT(samplerObject);
1812
1813 switch(pname)
1814 {
1815 case GL_TEXTURE_MIN_FILTER: return static_cast<GLint>(samplerObject->getMinFilter());
1816 case GL_TEXTURE_MAG_FILTER: return static_cast<GLint>(samplerObject->getMagFilter());
1817 case GL_TEXTURE_WRAP_S: return static_cast<GLint>(samplerObject->getWrapS());
1818 case GL_TEXTURE_WRAP_T: return static_cast<GLint>(samplerObject->getWrapT());
1819 case GL_TEXTURE_WRAP_R: return static_cast<GLint>(samplerObject->getWrapR());
1820 case GL_TEXTURE_MIN_LOD: return static_cast<GLint>(roundf(samplerObject->getMinLod()));
1821 case GL_TEXTURE_MAX_LOD: return static_cast<GLint>(roundf(samplerObject->getMaxLod()));
1822 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLint>(samplerObject->getCompareMode());
1823 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLint>(samplerObject->getCompareFunc());
1824 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return static_cast<GLint>(samplerObject->getMaxAnisotropy());
1825 default: UNREACHABLE(pname); return 0;
1826 }
1827 }
1828
getSamplerParameterf(GLuint sampler,GLenum pname)1829 GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname)
1830 {
1831 mResourceManager->checkSamplerAllocation(sampler);
1832
1833 Sampler *samplerObject = getSampler(sampler);
1834 ASSERT(samplerObject);
1835
1836 switch(pname)
1837 {
1838 case GL_TEXTURE_MIN_FILTER: return static_cast<GLfloat>(samplerObject->getMinFilter());
1839 case GL_TEXTURE_MAG_FILTER: return static_cast<GLfloat>(samplerObject->getMagFilter());
1840 case GL_TEXTURE_WRAP_S: return static_cast<GLfloat>(samplerObject->getWrapS());
1841 case GL_TEXTURE_WRAP_T: return static_cast<GLfloat>(samplerObject->getWrapT());
1842 case GL_TEXTURE_WRAP_R: return static_cast<GLfloat>(samplerObject->getWrapR());
1843 case GL_TEXTURE_MIN_LOD: return samplerObject->getMinLod();
1844 case GL_TEXTURE_MAX_LOD: return samplerObject->getMaxLod();
1845 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLfloat>(samplerObject->getCompareMode());
1846 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLfloat>(samplerObject->getCompareFunc());
1847 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return samplerObject->getMaxAnisotropy();
1848 default: UNREACHABLE(pname); return 0;
1849 }
1850 }
1851
getBooleanv(GLenum pname,GLboolean * params) const1852 bool Context::getBooleanv(GLenum pname, GLboolean *params) const
1853 {
1854 switch(pname)
1855 {
1856 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
1857 case GL_SAMPLE_COVERAGE_INVERT: *params = mState.sampleCoverageInvert; break;
1858 case GL_DEPTH_WRITEMASK: *params = mState.depthMask; break;
1859 case GL_COLOR_WRITEMASK:
1860 params[0] = mState.colorMaskRed;
1861 params[1] = mState.colorMaskGreen;
1862 params[2] = mState.colorMaskBlue;
1863 params[3] = mState.colorMaskAlpha;
1864 break;
1865 case GL_CULL_FACE: *params = mState.cullFaceEnabled; break;
1866 case GL_POLYGON_OFFSET_FILL: *params = mState.polygonOffsetFillEnabled; break;
1867 case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.sampleAlphaToCoverageEnabled; break;
1868 case GL_SAMPLE_COVERAGE: *params = mState.sampleCoverageEnabled; break;
1869 case GL_SCISSOR_TEST: *params = mState.scissorTestEnabled; break;
1870 case GL_STENCIL_TEST: *params = mState.stencilTestEnabled; break;
1871 case GL_DEPTH_TEST: *params = mState.depthTestEnabled; break;
1872 case GL_BLEND: *params = mState.blendEnabled; break;
1873 case GL_DITHER: *params = mState.ditherEnabled; break;
1874 case GL_PRIMITIVE_RESTART_FIXED_INDEX: *params = mState.primitiveRestartFixedIndexEnabled; break;
1875 case GL_RASTERIZER_DISCARD: *params = mState.rasterizerDiscardEnabled; break;
1876 case GL_TRANSFORM_FEEDBACK_ACTIVE:
1877 {
1878 TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
1879 if(transformFeedback)
1880 {
1881 *params = transformFeedback->isActive();
1882 break;
1883 }
1884 else return false;
1885 }
1886 case GL_TRANSFORM_FEEDBACK_PAUSED:
1887 {
1888 TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
1889 if(transformFeedback)
1890 {
1891 *params = transformFeedback->isPaused();
1892 break;
1893 }
1894 else return false;
1895 }
1896 default:
1897 return false;
1898 }
1899
1900 return true;
1901 }
1902
getFloatv(GLenum pname,GLfloat * params) const1903 bool Context::getFloatv(GLenum pname, GLfloat *params) const
1904 {
1905 // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
1906 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1907 // GetIntegerv as its native query function. As it would require conversion in any
1908 // case, this should make no difference to the calling application.
1909 switch(pname)
1910 {
1911 case GL_LINE_WIDTH: *params = mState.lineWidth; break;
1912 case GL_SAMPLE_COVERAGE_VALUE: *params = mState.sampleCoverageValue; break;
1913 case GL_DEPTH_CLEAR_VALUE: *params = mState.depthClearValue; break;
1914 case GL_POLYGON_OFFSET_FACTOR: *params = mState.polygonOffsetFactor; break;
1915 case GL_POLYGON_OFFSET_UNITS: *params = mState.polygonOffsetUnits; break;
1916 case GL_ALIASED_LINE_WIDTH_RANGE:
1917 params[0] = ALIASED_LINE_WIDTH_RANGE_MIN;
1918 params[1] = ALIASED_LINE_WIDTH_RANGE_MAX;
1919 break;
1920 case GL_ALIASED_POINT_SIZE_RANGE:
1921 params[0] = ALIASED_POINT_SIZE_RANGE_MIN;
1922 params[1] = ALIASED_POINT_SIZE_RANGE_MAX;
1923 break;
1924 case GL_DEPTH_RANGE:
1925 params[0] = mState.zNear;
1926 params[1] = mState.zFar;
1927 break;
1928 case GL_COLOR_CLEAR_VALUE:
1929 params[0] = mState.colorClearValue.red;
1930 params[1] = mState.colorClearValue.green;
1931 params[2] = mState.colorClearValue.blue;
1932 params[3] = mState.colorClearValue.alpha;
1933 break;
1934 case GL_BLEND_COLOR:
1935 params[0] = mState.blendColor.red;
1936 params[1] = mState.blendColor.green;
1937 params[2] = mState.blendColor.blue;
1938 params[3] = mState.blendColor.alpha;
1939 break;
1940 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1941 *params = MAX_TEXTURE_MAX_ANISOTROPY;
1942 break;
1943 default:
1944 return false;
1945 }
1946
1947 return true;
1948 }
1949
1950 template bool Context::getIntegerv<GLint>(GLenum pname, GLint *params) const;
1951 template bool Context::getIntegerv<GLint64>(GLenum pname, GLint64 *params) const;
1952
getIntegerv(GLenum pname,T * params) const1953 template<typename T> bool Context::getIntegerv(GLenum pname, T *params) const
1954 {
1955 // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
1956 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1957 // GetIntegerv as its native query function. As it would require conversion in any
1958 // case, this should make no difference to the calling application. You may find it in
1959 // Context::getFloatv.
1960 switch(pname)
1961 {
1962 case GL_MAX_VERTEX_ATTRIBS: *params = MAX_VERTEX_ATTRIBS; return true;
1963 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = MAX_VERTEX_UNIFORM_VECTORS; return true;
1964 case GL_MAX_VARYING_VECTORS: *params = MAX_VARYING_VECTORS; return true;
1965 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = MAX_COMBINED_TEXTURE_IMAGE_UNITS; return true;
1966 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = MAX_VERTEX_TEXTURE_IMAGE_UNITS; return true;
1967 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = MAX_TEXTURE_IMAGE_UNITS; return true;
1968 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = MAX_FRAGMENT_UNIFORM_VECTORS; return true;
1969 case GL_MAX_RENDERBUFFER_SIZE: *params = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE; return true;
1970 case GL_NUM_SHADER_BINARY_FORMATS: *params = 0; return true;
1971 case GL_SHADER_BINARY_FORMATS: /* no shader binary formats are supported */ return true;
1972 case GL_ARRAY_BUFFER_BINDING: *params = getArrayBufferName(); return true;
1973 case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = getElementArrayBufferName(); return true;
1974 // case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1975 case GL_DRAW_FRAMEBUFFER_BINDING: *params = mState.drawFramebuffer; return true;
1976 case GL_READ_FRAMEBUFFER_BINDING: *params = mState.readFramebuffer; return true;
1977 case GL_RENDERBUFFER_BINDING: *params = mState.renderbuffer.name(); return true;
1978 case GL_CURRENT_PROGRAM: *params = mState.currentProgram; return true;
1979 case GL_PACK_ALIGNMENT: *params = mState.packParameters.alignment; return true;
1980 case GL_UNPACK_ALIGNMENT: *params = mState.unpackParameters.alignment; return true;
1981 case GL_GENERATE_MIPMAP_HINT: *params = mState.generateMipmapHint; return true;
1982 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mState.fragmentShaderDerivativeHint; return true;
1983 case GL_TEXTURE_FILTERING_HINT_CHROMIUM: *params = mState.textureFilteringHint; return true;
1984 case GL_ACTIVE_TEXTURE: *params = (mState.activeSampler + GL_TEXTURE0); return true;
1985 case GL_STENCIL_FUNC: *params = mState.stencilFunc; return true;
1986 case GL_STENCIL_REF: *params = mState.stencilRef; return true;
1987 case GL_STENCIL_VALUE_MASK: *params = sw::clampToSignedInt(mState.stencilMask); return true;
1988 case GL_STENCIL_BACK_FUNC: *params = mState.stencilBackFunc; return true;
1989 case GL_STENCIL_BACK_REF: *params = mState.stencilBackRef; return true;
1990 case GL_STENCIL_BACK_VALUE_MASK: *params = sw::clampToSignedInt(mState.stencilBackMask); return true;
1991 case GL_STENCIL_FAIL: *params = mState.stencilFail; return true;
1992 case GL_STENCIL_PASS_DEPTH_FAIL: *params = mState.stencilPassDepthFail; return true;
1993 case GL_STENCIL_PASS_DEPTH_PASS: *params = mState.stencilPassDepthPass; return true;
1994 case GL_STENCIL_BACK_FAIL: *params = mState.stencilBackFail; return true;
1995 case GL_STENCIL_BACK_PASS_DEPTH_FAIL: *params = mState.stencilBackPassDepthFail; return true;
1996 case GL_STENCIL_BACK_PASS_DEPTH_PASS: *params = mState.stencilBackPassDepthPass; return true;
1997 case GL_DEPTH_FUNC: *params = mState.depthFunc; return true;
1998 case GL_BLEND_SRC_RGB: *params = mState.sourceBlendRGB; return true;
1999 case GL_BLEND_SRC_ALPHA: *params = mState.sourceBlendAlpha; return true;
2000 case GL_BLEND_DST_RGB: *params = mState.destBlendRGB; return true;
2001 case GL_BLEND_DST_ALPHA: *params = mState.destBlendAlpha; return true;
2002 case GL_BLEND_EQUATION_RGB: *params = mState.blendEquationRGB; return true;
2003 case GL_BLEND_EQUATION_ALPHA: *params = mState.blendEquationAlpha; return true;
2004 case GL_STENCIL_WRITEMASK: *params = sw::clampToSignedInt(mState.stencilWritemask); return true;
2005 case GL_STENCIL_BACK_WRITEMASK: *params = sw::clampToSignedInt(mState.stencilBackWritemask); return true;
2006 case GL_STENCIL_CLEAR_VALUE: *params = mState.stencilClearValue; return true;
2007 case GL_SUBPIXEL_BITS: *params = 4; return true;
2008 case GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB:
2009 case GL_MAX_TEXTURE_SIZE: *params = IMPLEMENTATION_MAX_TEXTURE_SIZE; return true;
2010 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE; return true;
2011 case GL_NUM_COMPRESSED_TEXTURE_FORMATS: *params = NUM_COMPRESSED_TEXTURE_FORMATS; return true;
2012 case GL_MAX_SAMPLES: *params = IMPLEMENTATION_MAX_SAMPLES; return true;
2013 case GL_SAMPLE_BUFFERS:
2014 case GL_SAMPLES:
2015 {
2016 Framebuffer *framebuffer = getDrawFramebuffer();
2017 int width, height, samples;
2018
2019 if(framebuffer && (framebuffer->completeness(width, height, samples) == GL_FRAMEBUFFER_COMPLETE))
2020 {
2021 switch(pname)
2022 {
2023 case GL_SAMPLE_BUFFERS:
2024 if(samples > 1)
2025 {
2026 *params = 1;
2027 }
2028 else
2029 {
2030 *params = 0;
2031 }
2032 break;
2033 case GL_SAMPLES:
2034 *params = samples;
2035 break;
2036 }
2037 }
2038 else
2039 {
2040 *params = 0;
2041 }
2042 }
2043 return true;
2044 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
2045 {
2046 Framebuffer *framebuffer = getReadFramebuffer();
2047 if(framebuffer)
2048 {
2049 *params = framebuffer->getImplementationColorReadType();
2050 }
2051 else
2052 {
2053 return error(GL_INVALID_OPERATION, true);
2054 }
2055 }
2056 return true;
2057 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
2058 {
2059 Framebuffer *framebuffer = getReadFramebuffer();
2060 if(framebuffer)
2061 {
2062 *params = framebuffer->getImplementationColorReadFormat();
2063 }
2064 else
2065 {
2066 return error(GL_INVALID_OPERATION, true);
2067 }
2068 }
2069 return true;
2070 case GL_MAX_VIEWPORT_DIMS:
2071 {
2072 int maxDimension = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE;
2073 params[0] = maxDimension;
2074 params[1] = maxDimension;
2075 }
2076 return true;
2077 case GL_COMPRESSED_TEXTURE_FORMATS:
2078 {
2079 for(int i = 0; i < NUM_COMPRESSED_TEXTURE_FORMATS; i++)
2080 {
2081 params[i] = compressedTextureFormats[i];
2082 }
2083 }
2084 return true;
2085 case GL_VIEWPORT:
2086 params[0] = mState.viewportX;
2087 params[1] = mState.viewportY;
2088 params[2] = mState.viewportWidth;
2089 params[3] = mState.viewportHeight;
2090 return true;
2091 case GL_SCISSOR_BOX:
2092 params[0] = mState.scissorX;
2093 params[1] = mState.scissorY;
2094 params[2] = mState.scissorWidth;
2095 params[3] = mState.scissorHeight;
2096 return true;
2097 case GL_CULL_FACE_MODE: *params = mState.cullMode; return true;
2098 case GL_FRONT_FACE: *params = mState.frontFace; return true;
2099 case GL_RED_BITS:
2100 case GL_GREEN_BITS:
2101 case GL_BLUE_BITS:
2102 case GL_ALPHA_BITS:
2103 {
2104 Framebuffer *framebuffer = getDrawFramebuffer();
2105 Renderbuffer *colorbuffer = framebuffer ? framebuffer->getColorbuffer(0) : nullptr;
2106
2107 if(colorbuffer)
2108 {
2109 switch(pname)
2110 {
2111 case GL_RED_BITS: *params = colorbuffer->getRedSize(); return true;
2112 case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); return true;
2113 case GL_BLUE_BITS: *params = colorbuffer->getBlueSize(); return true;
2114 case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); return true;
2115 }
2116 }
2117 else
2118 {
2119 *params = 0;
2120 }
2121 }
2122 return true;
2123 case GL_DEPTH_BITS:
2124 {
2125 Framebuffer *framebuffer = getDrawFramebuffer();
2126 Renderbuffer *depthbuffer = framebuffer ? framebuffer->getDepthbuffer() : nullptr;
2127
2128 if(depthbuffer)
2129 {
2130 *params = depthbuffer->getDepthSize();
2131 }
2132 else
2133 {
2134 *params = 0;
2135 }
2136 }
2137 return true;
2138 case GL_STENCIL_BITS:
2139 {
2140 Framebuffer *framebuffer = getDrawFramebuffer();
2141 Renderbuffer *stencilbuffer = framebuffer ? framebuffer->getStencilbuffer() : nullptr;
2142
2143 if(stencilbuffer)
2144 {
2145 *params = stencilbuffer->getStencilSize();
2146 }
2147 else
2148 {
2149 *params = 0;
2150 }
2151 }
2152 return true;
2153 case GL_TEXTURE_BINDING_2D:
2154 if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
2155 {
2156 error(GL_INVALID_OPERATION);
2157 return false;
2158 }
2159
2160 *params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].name();
2161 return true;
2162 case GL_TEXTURE_BINDING_CUBE_MAP:
2163 if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
2164 {
2165 error(GL_INVALID_OPERATION);
2166 return false;
2167 }
2168
2169 *params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].name();
2170 return true;
2171 case GL_TEXTURE_BINDING_RECTANGLE_ARB:
2172 if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
2173 {
2174 error(GL_INVALID_OPERATION);
2175 return false;
2176 }
2177
2178 *params = mState.samplerTexture[TEXTURE_2D_RECT][mState.activeSampler].name();
2179 return true;
2180 case GL_TEXTURE_BINDING_EXTERNAL_OES:
2181 if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
2182 {
2183 error(GL_INVALID_OPERATION);
2184 return false;
2185 }
2186
2187 *params = mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler].name();
2188 return true;
2189 case GL_TEXTURE_BINDING_3D_OES:
2190 if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
2191 {
2192 error(GL_INVALID_OPERATION);
2193 return false;
2194 }
2195
2196 *params = mState.samplerTexture[TEXTURE_3D][mState.activeSampler].name();
2197 return true;
2198 case GL_DRAW_BUFFER0:
2199 case GL_DRAW_BUFFER1:
2200 case GL_DRAW_BUFFER2:
2201 case GL_DRAW_BUFFER3:
2202 case GL_DRAW_BUFFER4:
2203 case GL_DRAW_BUFFER5:
2204 case GL_DRAW_BUFFER6:
2205 case GL_DRAW_BUFFER7:
2206 case GL_DRAW_BUFFER8:
2207 case GL_DRAW_BUFFER9:
2208 case GL_DRAW_BUFFER10:
2209 case GL_DRAW_BUFFER11:
2210 case GL_DRAW_BUFFER12:
2211 case GL_DRAW_BUFFER13:
2212 case GL_DRAW_BUFFER14:
2213 case GL_DRAW_BUFFER15:
2214 if((pname - GL_DRAW_BUFFER0) < MAX_DRAW_BUFFERS)
2215 {
2216 Framebuffer* framebuffer = getDrawFramebuffer();
2217 *params = framebuffer ? framebuffer->getDrawBuffer(pname - GL_DRAW_BUFFER0) : GL_NONE;
2218 }
2219 else
2220 {
2221 return false;
2222 }
2223 return true;
2224 case GL_MAX_DRAW_BUFFERS:
2225 *params = MAX_DRAW_BUFFERS;
2226 return true;
2227 case GL_MAX_COLOR_ATTACHMENTS: // Note: MAX_COLOR_ATTACHMENTS_EXT added by GL_EXT_draw_buffers
2228 *params = MAX_COLOR_ATTACHMENTS;
2229 return true;
2230 case GL_TEXTURE_BINDING_2D_ARRAY:
2231 if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
2232 {
2233 error(GL_INVALID_OPERATION);
2234 return false;
2235 }
2236
2237 *params = mState.samplerTexture[TEXTURE_2D_ARRAY][mState.activeSampler].name();
2238 return true;
2239 case GL_COPY_READ_BUFFER_BINDING:
2240 *params = mState.copyReadBuffer.name();
2241 return true;
2242 case GL_COPY_WRITE_BUFFER_BINDING:
2243 *params = mState.copyWriteBuffer.name();
2244 return true;
2245 case GL_MAJOR_VERSION:
2246 *params = 3;
2247 return true;
2248 case GL_MINOR_VERSION:
2249 *params = 0;
2250 return true;
2251 case GL_MAX_3D_TEXTURE_SIZE:
2252 *params = IMPLEMENTATION_MAX_3D_TEXTURE_SIZE;
2253 return true;
2254 case GL_MAX_ARRAY_TEXTURE_LAYERS:
2255 *params = IMPLEMENTATION_MAX_TEXTURE_SIZE;
2256 return true;
2257 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
2258 *params = MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS;
2259 return true;
2260 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
2261 *params = MAX_VERTEX_UNIFORM_BLOCKS + MAX_FRAGMENT_UNIFORM_BLOCKS;
2262 return true;
2263 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
2264 *params = MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS;
2265 return true;
2266 case GL_MAX_ELEMENT_INDEX:
2267 *params = MAX_ELEMENT_INDEX;
2268 return true;
2269 case GL_MAX_ELEMENTS_INDICES:
2270 *params = MAX_ELEMENTS_INDICES;
2271 return true;
2272 case GL_MAX_ELEMENTS_VERTICES:
2273 *params = MAX_ELEMENTS_VERTICES;
2274 return true;
2275 case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
2276 *params = MAX_FRAGMENT_INPUT_VECTORS * 4;
2277 return true;
2278 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
2279 *params = MAX_FRAGMENT_UNIFORM_BLOCKS;
2280 return true;
2281 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
2282 *params = MAX_FRAGMENT_UNIFORM_COMPONENTS;
2283 return true;
2284 case GL_MAX_PROGRAM_TEXEL_OFFSET:
2285 // Note: SwiftShader has no actual texel offset limit, so this limit can be modified if required.
2286 // In any case, any behavior outside the specified range is valid since the spec mentions:
2287 // (see OpenGL ES 3.0.5, 3.8.10.1 Scale Factor and Level of Detail, p.153)
2288 // "If any of the offset values are outside the range of the implementation-defined values
2289 // MIN_PROGRAM_TEXEL_OFFSET and MAX_PROGRAM_TEXEL_OFFSET, results of the texture lookup are
2290 // undefined."
2291 *params = MAX_PROGRAM_TEXEL_OFFSET;
2292 return true;
2293 case GL_MAX_SERVER_WAIT_TIMEOUT:
2294 *params = 0;
2295 return true;
2296 case GL_MAX_TEXTURE_LOD_BIAS:
2297 *params = MAX_TEXTURE_LOD_BIAS;
2298 return true;
2299 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
2300 *params = sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS;
2301 return true;
2302 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
2303 *params = MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS;
2304 return true;
2305 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
2306 *params = sw::MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS;
2307 return true;
2308 case GL_MAX_UNIFORM_BLOCK_SIZE:
2309 *params = MAX_UNIFORM_BLOCK_SIZE;
2310 return true;
2311 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
2312 *params = MAX_UNIFORM_BUFFER_BINDINGS;
2313 return true;
2314 case GL_MAX_VARYING_COMPONENTS:
2315 *params = MAX_VARYING_VECTORS * 4;
2316 return true;
2317 case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
2318 *params = MAX_VERTEX_OUTPUT_VECTORS * 4;
2319 return true;
2320 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
2321 *params = MAX_VERTEX_UNIFORM_BLOCKS;
2322 return true;
2323 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
2324 *params = MAX_VERTEX_UNIFORM_COMPONENTS;
2325 return true;
2326 case GL_MIN_PROGRAM_TEXEL_OFFSET:
2327 // Note: SwiftShader has no actual texel offset limit, so this limit can be modified if required.
2328 // In any case, any behavior outside the specified range is valid since the spec mentions:
2329 // (see OpenGL ES 3.0.5, 3.8.10.1 Scale Factor and Level of Detail, p.153)
2330 // "If any of the offset values are outside the range of the implementation-defined values
2331 // MIN_PROGRAM_TEXEL_OFFSET and MAX_PROGRAM_TEXEL_OFFSET, results of the texture lookup are
2332 // undefined."
2333 *params = MIN_PROGRAM_TEXEL_OFFSET;
2334 return true;
2335 case GL_NUM_EXTENSIONS:
2336 GLuint numExtensions;
2337 getExtensions(0, &numExtensions);
2338 *params = numExtensions;
2339 return true;
2340 case GL_NUM_PROGRAM_BINARY_FORMATS:
2341 *params = NUM_PROGRAM_BINARY_FORMATS;
2342 return true;
2343 case GL_PACK_ROW_LENGTH:
2344 *params = mState.packParameters.rowLength;
2345 return true;
2346 case GL_PACK_SKIP_PIXELS:
2347 *params = mState.packParameters.skipPixels;
2348 return true;
2349 case GL_PACK_SKIP_ROWS:
2350 *params = mState.packParameters.skipRows;
2351 return true;
2352 case GL_PIXEL_PACK_BUFFER_BINDING:
2353 *params = mState.pixelPackBuffer.name();
2354 return true;
2355 case GL_PIXEL_UNPACK_BUFFER_BINDING:
2356 *params = mState.pixelUnpackBuffer.name();
2357 return true;
2358 case GL_PROGRAM_BINARY_FORMATS:
2359 // Since NUM_PROGRAM_BINARY_FORMATS is 0, the input
2360 // should be a 0 sized array, so don't write to params
2361 return true;
2362 case GL_READ_BUFFER:
2363 {
2364 Framebuffer* framebuffer = getReadFramebuffer();
2365 *params = framebuffer ? framebuffer->getReadBuffer() : GL_NONE;
2366 }
2367 return true;
2368 case GL_SAMPLER_BINDING:
2369 *params = mState.sampler[mState.activeSampler].name();
2370 return true;
2371 case GL_UNIFORM_BUFFER_BINDING:
2372 *params = mState.genericUniformBuffer.name();
2373 return true;
2374 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
2375 *params = UNIFORM_BUFFER_OFFSET_ALIGNMENT;
2376 return true;
2377 case GL_UNPACK_IMAGE_HEIGHT:
2378 *params = mState.unpackParameters.imageHeight;
2379 return true;
2380 case GL_UNPACK_ROW_LENGTH:
2381 *params = mState.unpackParameters.rowLength;
2382 return true;
2383 case GL_UNPACK_SKIP_IMAGES:
2384 *params = mState.unpackParameters.skipImages;
2385 return true;
2386 case GL_UNPACK_SKIP_PIXELS:
2387 *params = mState.unpackParameters.skipPixels;
2388 return true;
2389 case GL_UNPACK_SKIP_ROWS:
2390 *params = mState.unpackParameters.skipRows;
2391 return true;
2392 case GL_VERTEX_ARRAY_BINDING:
2393 *params = getCurrentVertexArray()->name;
2394 return true;
2395 case GL_TRANSFORM_FEEDBACK_BINDING:
2396 {
2397 TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
2398 if(transformFeedback)
2399 {
2400 *params = transformFeedback->name;
2401 }
2402 else
2403 {
2404 return false;
2405 }
2406 }
2407 return true;
2408 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
2409 {
2410 TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
2411 if(transformFeedback)
2412 {
2413 *params = mState.genericTransformFeedbackBuffer.name();
2414 }
2415 else
2416 {
2417 return false;
2418 }
2419 }
2420 return true;
2421 default:
2422 break;
2423 }
2424
2425 return false;
2426 }
2427
2428 template bool Context::getTransformFeedbackiv<GLint>(GLuint index, GLenum pname, GLint *param) const;
2429 template bool Context::getTransformFeedbackiv<GLint64>(GLuint index, GLenum pname, GLint64 *param) const;
2430
getTransformFeedbackiv(GLuint index,GLenum pname,T * param) const2431 template<typename T> bool Context::getTransformFeedbackiv(GLuint index, GLenum pname, T *param) const
2432 {
2433 TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
2434 if(!transformFeedback)
2435 {
2436 return false;
2437 }
2438
2439 switch(pname)
2440 {
2441 case GL_TRANSFORM_FEEDBACK_BINDING: // GLint, initially 0
2442 *param = transformFeedback->name;
2443 break;
2444 case GL_TRANSFORM_FEEDBACK_ACTIVE: // boolean, initially GL_FALSE
2445 *param = transformFeedback->isActive();
2446 break;
2447 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: // name, initially 0
2448 *param = transformFeedback->getBufferName(index);
2449 break;
2450 case GL_TRANSFORM_FEEDBACK_PAUSED: // boolean, initially GL_FALSE
2451 *param = transformFeedback->isPaused();
2452 break;
2453 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: // indexed[n] 64-bit integer, initially 0
2454 if(transformFeedback->getBuffer(index))
2455 {
2456 *param = transformFeedback->getSize(index);
2457 break;
2458 }
2459 else return false;
2460 case GL_TRANSFORM_FEEDBACK_BUFFER_START: // indexed[n] 64-bit integer, initially 0
2461 if(transformFeedback->getBuffer(index))
2462 {
2463 *param = transformFeedback->getOffset(index);
2464 break;
2465 }
2466 else return false;
2467 default:
2468 return false;
2469 }
2470
2471 return true;
2472 }
2473
2474 template bool Context::getUniformBufferiv<GLint>(GLuint index, GLenum pname, GLint *param) const;
2475 template bool Context::getUniformBufferiv<GLint64>(GLuint index, GLenum pname, GLint64 *param) const;
2476
getUniformBufferiv(GLuint index,GLenum pname,T * param) const2477 template<typename T> bool Context::getUniformBufferiv(GLuint index, GLenum pname, T *param) const
2478 {
2479 switch(pname)
2480 {
2481 case GL_UNIFORM_BUFFER_BINDING:
2482 case GL_UNIFORM_BUFFER_SIZE:
2483 case GL_UNIFORM_BUFFER_START:
2484 break;
2485 default:
2486 return false;
2487 }
2488
2489 if(index >= MAX_UNIFORM_BUFFER_BINDINGS)
2490 {
2491 return error(GL_INVALID_VALUE, true);
2492 }
2493
2494 const BufferBinding& uniformBuffer = mState.uniformBuffers[index];
2495
2496 switch(pname)
2497 {
2498 case GL_UNIFORM_BUFFER_BINDING: // name, initially 0
2499 *param = uniformBuffer.get().name();
2500 break;
2501 case GL_UNIFORM_BUFFER_SIZE: // indexed[n] 64-bit integer, initially 0
2502 *param = uniformBuffer.getSize();
2503 break;
2504 case GL_UNIFORM_BUFFER_START: // indexed[n] 64-bit integer, initially 0
2505 *param = uniformBuffer.getOffset();
2506 break;
2507 default:
2508 return false;
2509 }
2510
2511 return true;
2512 }
2513
getQueryParameterInfo(GLenum pname,GLenum * type,unsigned int * numParams) const2514 bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams) const
2515 {
2516 // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
2517 // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
2518 // to the fact that it is stored internally as a float, and so would require conversion
2519 // if returned from Context::getIntegerv. Since this conversion is already implemented
2520 // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
2521 // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
2522 // application.
2523 switch(pname)
2524 {
2525 case GL_COMPRESSED_TEXTURE_FORMATS:
2526 {
2527 *type = GL_INT;
2528 *numParams = NUM_COMPRESSED_TEXTURE_FORMATS;
2529 }
2530 break;
2531 case GL_SHADER_BINARY_FORMATS:
2532 {
2533 *type = GL_INT;
2534 *numParams = 0;
2535 }
2536 break;
2537 case GL_MAX_VERTEX_ATTRIBS:
2538 case GL_MAX_VERTEX_UNIFORM_VECTORS:
2539 case GL_MAX_VARYING_VECTORS:
2540 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
2541 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
2542 case GL_MAX_TEXTURE_IMAGE_UNITS:
2543 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
2544 case GL_MAX_RENDERBUFFER_SIZE:
2545 case GL_NUM_SHADER_BINARY_FORMATS:
2546 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
2547 case GL_ARRAY_BUFFER_BINDING:
2548 case GL_FRAMEBUFFER_BINDING: // Same as GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
2549 case GL_READ_FRAMEBUFFER_BINDING: // Same as GL_READ_FRAMEBUFFER_BINDING_ANGLE
2550 case GL_RENDERBUFFER_BINDING:
2551 case GL_CURRENT_PROGRAM:
2552 case GL_PACK_ALIGNMENT:
2553 case GL_UNPACK_ALIGNMENT:
2554 case GL_GENERATE_MIPMAP_HINT:
2555 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
2556 case GL_TEXTURE_FILTERING_HINT_CHROMIUM:
2557 case GL_RED_BITS:
2558 case GL_GREEN_BITS:
2559 case GL_BLUE_BITS:
2560 case GL_ALPHA_BITS:
2561 case GL_DEPTH_BITS:
2562 case GL_STENCIL_BITS:
2563 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
2564 case GL_CULL_FACE_MODE:
2565 case GL_FRONT_FACE:
2566 case GL_ACTIVE_TEXTURE:
2567 case GL_STENCIL_FUNC:
2568 case GL_STENCIL_VALUE_MASK:
2569 case GL_STENCIL_REF:
2570 case GL_STENCIL_FAIL:
2571 case GL_STENCIL_PASS_DEPTH_FAIL:
2572 case GL_STENCIL_PASS_DEPTH_PASS:
2573 case GL_STENCIL_BACK_FUNC:
2574 case GL_STENCIL_BACK_VALUE_MASK:
2575 case GL_STENCIL_BACK_REF:
2576 case GL_STENCIL_BACK_FAIL:
2577 case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
2578 case GL_STENCIL_BACK_PASS_DEPTH_PASS:
2579 case GL_DEPTH_FUNC:
2580 case GL_BLEND_SRC_RGB:
2581 case GL_BLEND_SRC_ALPHA:
2582 case GL_BLEND_DST_RGB:
2583 case GL_BLEND_DST_ALPHA:
2584 case GL_BLEND_EQUATION_RGB:
2585 case GL_BLEND_EQUATION_ALPHA:
2586 case GL_STENCIL_WRITEMASK:
2587 case GL_STENCIL_BACK_WRITEMASK:
2588 case GL_STENCIL_CLEAR_VALUE:
2589 case GL_SUBPIXEL_BITS:
2590 case GL_MAX_TEXTURE_SIZE:
2591 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
2592 case GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB:
2593 case GL_SAMPLE_BUFFERS:
2594 case GL_SAMPLES:
2595 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
2596 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
2597 case GL_TEXTURE_BINDING_2D:
2598 case GL_TEXTURE_BINDING_CUBE_MAP:
2599 case GL_TEXTURE_BINDING_RECTANGLE_ARB:
2600 case GL_TEXTURE_BINDING_EXTERNAL_OES:
2601 case GL_TEXTURE_BINDING_3D_OES:
2602 case GL_COPY_READ_BUFFER_BINDING:
2603 case GL_COPY_WRITE_BUFFER_BINDING:
2604 case GL_DRAW_BUFFER0:
2605 case GL_DRAW_BUFFER1:
2606 case GL_DRAW_BUFFER2:
2607 case GL_DRAW_BUFFER3:
2608 case GL_DRAW_BUFFER4:
2609 case GL_DRAW_BUFFER5:
2610 case GL_DRAW_BUFFER6:
2611 case GL_DRAW_BUFFER7:
2612 case GL_DRAW_BUFFER8:
2613 case GL_DRAW_BUFFER9:
2614 case GL_DRAW_BUFFER10:
2615 case GL_DRAW_BUFFER11:
2616 case GL_DRAW_BUFFER12:
2617 case GL_DRAW_BUFFER13:
2618 case GL_DRAW_BUFFER14:
2619 case GL_DRAW_BUFFER15:
2620 case GL_MAJOR_VERSION:
2621 case GL_MAX_3D_TEXTURE_SIZE:
2622 case GL_MAX_ARRAY_TEXTURE_LAYERS:
2623 case GL_MAX_COLOR_ATTACHMENTS:
2624 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
2625 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
2626 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
2627 case GL_MAX_DRAW_BUFFERS:
2628 case GL_MAX_ELEMENT_INDEX:
2629 case GL_MAX_ELEMENTS_INDICES:
2630 case GL_MAX_ELEMENTS_VERTICES:
2631 case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
2632 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
2633 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
2634 case GL_MAX_PROGRAM_TEXEL_OFFSET:
2635 case GL_MAX_SERVER_WAIT_TIMEOUT:
2636 case GL_MAX_TEXTURE_LOD_BIAS:
2637 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
2638 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
2639 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
2640 case GL_MAX_UNIFORM_BLOCK_SIZE:
2641 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
2642 case GL_MAX_VARYING_COMPONENTS:
2643 case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
2644 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
2645 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
2646 case GL_MIN_PROGRAM_TEXEL_OFFSET:
2647 case GL_MINOR_VERSION:
2648 case GL_NUM_EXTENSIONS:
2649 case GL_NUM_PROGRAM_BINARY_FORMATS:
2650 case GL_PACK_ROW_LENGTH:
2651 case GL_PACK_SKIP_PIXELS:
2652 case GL_PACK_SKIP_ROWS:
2653 case GL_PIXEL_PACK_BUFFER_BINDING:
2654 case GL_PIXEL_UNPACK_BUFFER_BINDING:
2655 case GL_PROGRAM_BINARY_FORMATS:
2656 case GL_READ_BUFFER:
2657 case GL_SAMPLER_BINDING:
2658 case GL_TEXTURE_BINDING_2D_ARRAY:
2659 case GL_UNIFORM_BUFFER_BINDING:
2660 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
2661 case GL_UNPACK_IMAGE_HEIGHT:
2662 case GL_UNPACK_ROW_LENGTH:
2663 case GL_UNPACK_SKIP_IMAGES:
2664 case GL_UNPACK_SKIP_PIXELS:
2665 case GL_UNPACK_SKIP_ROWS:
2666 case GL_VERTEX_ARRAY_BINDING:
2667 case GL_TRANSFORM_FEEDBACK_BINDING:
2668 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
2669 {
2670 *type = GL_INT;
2671 *numParams = 1;
2672 }
2673 break;
2674 case GL_MAX_SAMPLES:
2675 {
2676 *type = GL_INT;
2677 *numParams = 1;
2678 }
2679 break;
2680 case GL_MAX_VIEWPORT_DIMS:
2681 {
2682 *type = GL_INT;
2683 *numParams = 2;
2684 }
2685 break;
2686 case GL_VIEWPORT:
2687 case GL_SCISSOR_BOX:
2688 {
2689 *type = GL_INT;
2690 *numParams = 4;
2691 }
2692 break;
2693 case GL_SHADER_COMPILER:
2694 case GL_SAMPLE_COVERAGE_INVERT:
2695 case GL_DEPTH_WRITEMASK:
2696 case GL_CULL_FACE: // CULL_FACE through DITHER are natural to IsEnabled,
2697 case GL_POLYGON_OFFSET_FILL: // but can be retrieved through the Get{Type}v queries.
2698 case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
2699 case GL_SAMPLE_COVERAGE:
2700 case GL_SCISSOR_TEST:
2701 case GL_STENCIL_TEST:
2702 case GL_DEPTH_TEST:
2703 case GL_BLEND:
2704 case GL_DITHER:
2705 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
2706 case GL_RASTERIZER_DISCARD:
2707 case GL_TRANSFORM_FEEDBACK_ACTIVE:
2708 case GL_TRANSFORM_FEEDBACK_PAUSED:
2709 {
2710 *type = GL_BOOL;
2711 *numParams = 1;
2712 }
2713 break;
2714 case GL_COLOR_WRITEMASK:
2715 {
2716 *type = GL_BOOL;
2717 *numParams = 4;
2718 }
2719 break;
2720 case GL_POLYGON_OFFSET_FACTOR:
2721 case GL_POLYGON_OFFSET_UNITS:
2722 case GL_SAMPLE_COVERAGE_VALUE:
2723 case GL_DEPTH_CLEAR_VALUE:
2724 case GL_LINE_WIDTH:
2725 {
2726 *type = GL_FLOAT;
2727 *numParams = 1;
2728 }
2729 break;
2730 case GL_ALIASED_LINE_WIDTH_RANGE:
2731 case GL_ALIASED_POINT_SIZE_RANGE:
2732 case GL_DEPTH_RANGE:
2733 {
2734 *type = GL_FLOAT;
2735 *numParams = 2;
2736 }
2737 break;
2738 case GL_COLOR_CLEAR_VALUE:
2739 case GL_BLEND_COLOR:
2740 {
2741 *type = GL_FLOAT;
2742 *numParams = 4;
2743 }
2744 break;
2745 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
2746 *type = GL_FLOAT;
2747 *numParams = 1;
2748 break;
2749 default:
2750 return false;
2751 }
2752
2753 return true;
2754 }
2755
applyScissor(int width,int height)2756 void Context::applyScissor(int width, int height)
2757 {
2758 if(mState.scissorTestEnabled)
2759 {
2760 sw::Rect scissor = { mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight };
2761 scissor.clip(0, 0, width, height);
2762
2763 device->setScissorRect(scissor);
2764 device->setScissorEnable(true);
2765 }
2766 else
2767 {
2768 device->setScissorEnable(false);
2769 }
2770 }
2771
2772 // Applies the render target surface, depth stencil surface, viewport rectangle and scissor rectangle
applyRenderTarget()2773 bool Context::applyRenderTarget()
2774 {
2775 Framebuffer *framebuffer = getDrawFramebuffer();
2776 int width, height, samples;
2777
2778 if(!framebuffer || (framebuffer->completeness(width, height, samples) != GL_FRAMEBUFFER_COMPLETE))
2779 {
2780 return error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
2781 }
2782
2783 for(int i = 0; i < MAX_DRAW_BUFFERS; i++)
2784 {
2785 if(framebuffer->getDrawBuffer(i) != GL_NONE)
2786 {
2787 egl::Image *renderTarget = framebuffer->getRenderTarget(i);
2788 GLint layer = framebuffer->getColorbufferLayer(i);
2789 device->setRenderTarget(i, renderTarget, layer);
2790 if(renderTarget) renderTarget->release();
2791 }
2792 else
2793 {
2794 device->setRenderTarget(i, nullptr, 0);
2795 }
2796 }
2797
2798 egl::Image *depthBuffer = framebuffer->getDepthBuffer();
2799 GLint dLayer = framebuffer->getDepthbufferLayer();
2800 device->setDepthBuffer(depthBuffer, dLayer);
2801 if(depthBuffer) depthBuffer->release();
2802
2803 egl::Image *stencilBuffer = framebuffer->getStencilBuffer();
2804 GLint sLayer = framebuffer->getStencilbufferLayer();
2805 device->setStencilBuffer(stencilBuffer, sLayer);
2806 if(stencilBuffer) stencilBuffer->release();
2807
2808 Viewport viewport;
2809 float zNear = clamp01(mState.zNear);
2810 float zFar = clamp01(mState.zFar);
2811
2812 viewport.x0 = mState.viewportX;
2813 viewport.y0 = mState.viewportY;
2814 viewport.width = mState.viewportWidth;
2815 viewport.height = mState.viewportHeight;
2816 viewport.minZ = zNear;
2817 viewport.maxZ = zFar;
2818
2819 if (viewport.x0 > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
2820 viewport.y0 > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE)
2821 {
2822 TransformFeedback* transformFeedback = getTransformFeedback();
2823 if (!transformFeedback->isActive() || transformFeedback->isPaused())
2824 {
2825 return false;
2826 }
2827 else
2828 {
2829 viewport.x0 = 0;
2830 viewport.y0 = 0;
2831 viewport.width = 0;
2832 viewport.height = 0;
2833 }
2834 }
2835
2836 device->setViewport(viewport);
2837
2838 applyScissor(width, height);
2839
2840 Program *program = getCurrentProgram();
2841
2842 if(program)
2843 {
2844 GLfloat nearFarDiff[3] = {zNear, zFar, zFar - zNear};
2845 program->setUniform1fv(program->getUniformLocation("gl_DepthRange.near"), 1, &nearFarDiff[0]);
2846 program->setUniform1fv(program->getUniformLocation("gl_DepthRange.far"), 1, &nearFarDiff[1]);
2847 program->setUniform1fv(program->getUniformLocation("gl_DepthRange.diff"), 1, &nearFarDiff[2]);
2848 }
2849
2850 return true;
2851 }
2852
2853 // Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc)
applyState(GLenum drawMode)2854 void Context::applyState(GLenum drawMode)
2855 {
2856 Framebuffer *framebuffer = getDrawFramebuffer();
2857 bool frontFaceCCW = (mState.frontFace == GL_CCW);
2858
2859 if(mState.cullFaceEnabled)
2860 {
2861 device->setCullMode(es2sw::ConvertCullMode(mState.cullMode, mState.frontFace), frontFaceCCW);
2862 }
2863 else
2864 {
2865 device->setCullMode(sw::CULL_NONE, frontFaceCCW);
2866 }
2867
2868 if(mDepthStateDirty)
2869 {
2870 if(mState.depthTestEnabled)
2871 {
2872 device->setDepthBufferEnable(true);
2873 device->setDepthCompare(es2sw::ConvertDepthComparison(mState.depthFunc));
2874 }
2875 else
2876 {
2877 device->setDepthBufferEnable(false);
2878 }
2879
2880 mDepthStateDirty = false;
2881 }
2882
2883 if(mBlendStateDirty)
2884 {
2885 if(mState.blendEnabled)
2886 {
2887 device->setAlphaBlendEnable(true);
2888 device->setSeparateAlphaBlendEnable(true);
2889
2890 device->setBlendConstant(es2sw::ConvertColor(mState.blendColor));
2891
2892 device->setSourceBlendFactor(es2sw::ConvertBlendFunc(mState.sourceBlendRGB));
2893 device->setDestBlendFactor(es2sw::ConvertBlendFunc(mState.destBlendRGB));
2894 device->setBlendOperation(es2sw::ConvertBlendOp(mState.blendEquationRGB));
2895
2896 device->setSourceBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.sourceBlendAlpha));
2897 device->setDestBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.destBlendAlpha));
2898 device->setBlendOperationAlpha(es2sw::ConvertBlendOp(mState.blendEquationAlpha));
2899 }
2900 else
2901 {
2902 device->setAlphaBlendEnable(false);
2903 }
2904
2905 mBlendStateDirty = false;
2906 }
2907
2908 if(mStencilStateDirty || mFrontFaceDirty)
2909 {
2910 if(mState.stencilTestEnabled && framebuffer->hasStencil())
2911 {
2912 device->setStencilEnable(true);
2913 device->setTwoSidedStencil(true);
2914
2915 // get the maximum size of the stencil ref
2916 Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
2917 GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1;
2918
2919 if(mState.frontFace == GL_CCW)
2920 {
2921 device->setStencilWriteMask(mState.stencilWritemask);
2922 device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilFunc));
2923
2924 device->setStencilReference((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
2925 device->setStencilMask(mState.stencilMask);
2926
2927 device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilFail));
2928 device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));
2929 device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));
2930
2931 device->setStencilWriteMaskCCW(mState.stencilBackWritemask);
2932 device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilBackFunc));
2933
2934 device->setStencilReferenceCCW((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);
2935 device->setStencilMaskCCW(mState.stencilBackMask);
2936
2937 device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackFail));
2938 device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail));
2939 device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass));
2940 }
2941 else
2942 {
2943 device->setStencilWriteMaskCCW(mState.stencilWritemask);
2944 device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilFunc));
2945
2946 device->setStencilReferenceCCW((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
2947 device->setStencilMaskCCW(mState.stencilMask);
2948
2949 device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilFail));
2950 device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));
2951 device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));
2952
2953 device->setStencilWriteMask(mState.stencilBackWritemask);
2954 device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilBackFunc));
2955
2956 device->setStencilReference((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);
2957 device->setStencilMask(mState.stencilBackMask);
2958
2959 device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilBackFail));
2960 device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail));
2961 device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass));
2962 }
2963 }
2964 else
2965 {
2966 device->setStencilEnable(false);
2967 }
2968
2969 mStencilStateDirty = false;
2970 mFrontFaceDirty = false;
2971 }
2972
2973 if(mMaskStateDirty)
2974 {
2975 for(int i = 0; i < MAX_DRAW_BUFFERS; i++)
2976 {
2977 device->setColorWriteMask(i, es2sw::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, mState.colorMaskBlue, mState.colorMaskAlpha));
2978 }
2979
2980 device->setDepthWriteEnable(mState.depthMask);
2981
2982 mMaskStateDirty = false;
2983 }
2984
2985 if(mPolygonOffsetStateDirty)
2986 {
2987 if(mState.polygonOffsetFillEnabled)
2988 {
2989 Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
2990 if(depthbuffer)
2991 {
2992 device->setSlopeDepthBias(mState.polygonOffsetFactor);
2993 float depthBias = ldexp(mState.polygonOffsetUnits, -23); // We use 32-bit floating-point for all depth formats, with 23 mantissa bits.
2994 device->setDepthBias(depthBias);
2995 }
2996 }
2997 else
2998 {
2999 device->setSlopeDepthBias(0);
3000 device->setDepthBias(0);
3001 }
3002
3003 mPolygonOffsetStateDirty = false;
3004 }
3005
3006 if(mSampleStateDirty)
3007 {
3008 if(mState.sampleAlphaToCoverageEnabled)
3009 {
3010 device->setTransparencyAntialiasing(sw::TRANSPARENCY_ALPHA_TO_COVERAGE);
3011 }
3012 else
3013 {
3014 device->setTransparencyAntialiasing(sw::TRANSPARENCY_NONE);
3015 }
3016
3017 if(mState.sampleCoverageEnabled)
3018 {
3019 unsigned int mask = 0;
3020 if(mState.sampleCoverageValue != 0)
3021 {
3022 int width, height, samples;
3023 framebuffer->completeness(width, height, samples);
3024
3025 float threshold = 0.5f;
3026
3027 for(int i = 0; i < samples; i++)
3028 {
3029 mask <<= 1;
3030
3031 if((i + 1) * mState.sampleCoverageValue >= threshold)
3032 {
3033 threshold += 1.0f;
3034 mask |= 1;
3035 }
3036 }
3037 }
3038
3039 if(mState.sampleCoverageInvert)
3040 {
3041 mask = ~mask;
3042 }
3043
3044 device->setMultiSampleMask(mask);
3045 }
3046 else
3047 {
3048 device->setMultiSampleMask(0xFFFFFFFF);
3049 }
3050
3051 mSampleStateDirty = false;
3052 }
3053
3054 if(mDitherStateDirty)
3055 {
3056 // UNIMPLEMENTED(); // FIXME
3057
3058 mDitherStateDirty = false;
3059 }
3060
3061 device->setRasterizerDiscard(mState.rasterizerDiscardEnabled);
3062 }
3063
applyVertexBuffer(GLint base,GLint first,GLsizei count,GLsizei instanceId)3064 GLenum Context::applyVertexBuffer(GLint base, GLint first, GLsizei count, GLsizei instanceId)
3065 {
3066 TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS];
3067
3068 GLenum err = mVertexDataManager->prepareVertexData(first, count, attributes, instanceId);
3069 if(err != GL_NO_ERROR)
3070 {
3071 return err;
3072 }
3073
3074 Program *program = getCurrentProgram();
3075
3076 device->resetInputStreams(false);
3077
3078 for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
3079 {
3080 if(program->getAttributeStream(i) == -1)
3081 {
3082 continue;
3083 }
3084
3085 sw::Resource *resource = attributes[i].vertexBuffer;
3086 const void *buffer = (char*)resource->data() + attributes[i].offset;
3087
3088 int stride = attributes[i].stride;
3089
3090 buffer = (char*)buffer + stride * base;
3091
3092 sw::Stream attribute(resource, buffer, stride);
3093
3094 attribute.type = attributes[i].type;
3095 attribute.count = attributes[i].count;
3096 attribute.normalized = attributes[i].normalized;
3097
3098 int stream = program->getAttributeStream(i);
3099 device->setInputStream(stream, attribute);
3100 }
3101
3102 return GL_NO_ERROR;
3103 }
3104
3105 // Applies the indices and element array bindings
applyIndexBuffer(const void * indices,GLuint start,GLuint end,GLsizei count,GLenum mode,GLenum type,TranslatedIndexData * indexInfo)3106 GLenum Context::applyIndexBuffer(const void *indices, GLuint start, GLuint end, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
3107 {
3108 GLenum err = mIndexDataManager->prepareIndexData(mode, type, start, end, count, getCurrentVertexArray()->getElementArrayBuffer(), indices, indexInfo, isPrimitiveRestartFixedIndexEnabled());
3109
3110 if(err == GL_NO_ERROR)
3111 {
3112 device->setIndexBuffer(indexInfo->indexBuffer);
3113 }
3114
3115 return err;
3116 }
3117
3118 // Applies the shaders and shader constants
applyShaders()3119 void Context::applyShaders()
3120 {
3121 Program *programObject = getCurrentProgram();
3122 sw::VertexShader *vertexShader = programObject->getVertexShader();
3123 sw::PixelShader *pixelShader = programObject->getPixelShader();
3124
3125 device->setVertexShader(vertexShader);
3126 device->setPixelShader(pixelShader);
3127
3128 if(programObject->getSerial() != mAppliedProgramSerial)
3129 {
3130 programObject->dirtyAllUniforms();
3131 mAppliedProgramSerial = programObject->getSerial();
3132 }
3133
3134 programObject->applyTransformFeedback(device, getTransformFeedback());
3135 programObject->applyUniformBuffers(device, mState.uniformBuffers);
3136 programObject->applyUniforms(device);
3137 }
3138
applyTextures()3139 void Context::applyTextures()
3140 {
3141 applyTextures(sw::SAMPLER_PIXEL);
3142 applyTextures(sw::SAMPLER_VERTEX);
3143 }
3144
applyTextures(sw::SamplerType samplerType)3145 void Context::applyTextures(sw::SamplerType samplerType)
3146 {
3147 Program *programObject = getCurrentProgram();
3148
3149 int samplerCount = (samplerType == sw::SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : MAX_VERTEX_TEXTURE_IMAGE_UNITS; // Range of samplers of given sampler type
3150
3151 for(int samplerIndex = 0; samplerIndex < samplerCount; samplerIndex++)
3152 {
3153 int textureUnit = programObject->getSamplerMapping(samplerType, samplerIndex); // OpenGL texture image unit index
3154
3155 if(textureUnit != -1)
3156 {
3157 TextureType textureType = programObject->getSamplerTextureType(samplerType, samplerIndex);
3158
3159 Texture *texture = getSamplerTexture(textureUnit, textureType);
3160 Sampler *samplerObject = mState.sampler[textureUnit];
3161
3162 if(texture->isSamplerComplete(samplerObject))
3163 {
3164 GLenum wrapS, wrapT, wrapR, minFilter, magFilter, compFunc, compMode;
3165 GLfloat minLOD, maxLOD, maxAnisotropy;
3166
3167 if(samplerObject)
3168 {
3169 wrapS = samplerObject->getWrapS();
3170 wrapT = samplerObject->getWrapT();
3171 wrapR = samplerObject->getWrapR();
3172 minFilter = samplerObject->getMinFilter();
3173 magFilter = samplerObject->getMagFilter();
3174 minLOD = samplerObject->getMinLod();
3175 maxLOD = samplerObject->getMaxLod();
3176 compFunc = samplerObject->getCompareFunc();
3177 compMode = samplerObject->getCompareMode();
3178 maxAnisotropy = samplerObject->getMaxAnisotropy();
3179 }
3180 else
3181 {
3182 wrapS = texture->getWrapS();
3183 wrapT = texture->getWrapT();
3184 wrapR = texture->getWrapR();
3185 minFilter = texture->getMinFilter();
3186 magFilter = texture->getMagFilter();
3187 minLOD = texture->getMinLOD();
3188 maxLOD = texture->getMaxLOD();
3189 compFunc = texture->getCompareFunc();
3190 compMode = texture->getCompareMode();
3191 maxAnisotropy = texture->getMaxAnisotropy();
3192 }
3193
3194 GLint baseLevel = texture->getBaseLevel();
3195 GLint maxLevel = texture->getMaxLevel();
3196 GLenum swizzleR = texture->getSwizzleR();
3197 GLenum swizzleG = texture->getSwizzleG();
3198 GLenum swizzleB = texture->getSwizzleB();
3199 GLenum swizzleA = texture->getSwizzleA();
3200
3201 device->setAddressingModeU(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapS));
3202 device->setAddressingModeV(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapT));
3203 device->setAddressingModeW(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapR));
3204 device->setCompareFunc(samplerType, samplerIndex, es2sw::ConvertCompareFunc(compFunc, compMode));
3205 device->setSwizzleR(samplerType, samplerIndex, es2sw::ConvertSwizzleType(swizzleR));
3206 device->setSwizzleG(samplerType, samplerIndex, es2sw::ConvertSwizzleType(swizzleG));
3207 device->setSwizzleB(samplerType, samplerIndex, es2sw::ConvertSwizzleType(swizzleB));
3208 device->setSwizzleA(samplerType, samplerIndex, es2sw::ConvertSwizzleType(swizzleA));
3209 device->setMinLod(samplerType, samplerIndex, minLOD);
3210 device->setMaxLod(samplerType, samplerIndex, maxLOD);
3211 device->setBaseLevel(samplerType, samplerIndex, baseLevel);
3212 device->setMaxLevel(samplerType, samplerIndex, maxLevel);
3213 device->setTextureFilter(samplerType, samplerIndex, es2sw::ConvertTextureFilter(minFilter, magFilter, maxAnisotropy));
3214 device->setMipmapFilter(samplerType, samplerIndex, es2sw::ConvertMipMapFilter(minFilter));
3215 device->setMaxAnisotropy(samplerType, samplerIndex, maxAnisotropy);
3216 device->setHighPrecisionFiltering(samplerType, samplerIndex, mState.textureFilteringHint == GL_NICEST);
3217 device->setSyncRequired(samplerType, samplerIndex, texture->requiresSync());
3218
3219 applyTexture(samplerType, samplerIndex, texture);
3220 }
3221 else
3222 {
3223 applyTexture(samplerType, samplerIndex, nullptr);
3224 }
3225 }
3226 else
3227 {
3228 applyTexture(samplerType, samplerIndex, nullptr);
3229 }
3230 }
3231 }
3232
applyTexture(sw::SamplerType type,int index,Texture * baseTexture)3233 void Context::applyTexture(sw::SamplerType type, int index, Texture *baseTexture)
3234 {
3235 Program *program = getCurrentProgram();
3236 int sampler = (type == sw::SAMPLER_PIXEL) ? index : 16 + index;
3237 bool textureUsed = false;
3238
3239 if(type == sw::SAMPLER_PIXEL)
3240 {
3241 textureUsed = program->getPixelShader()->usesSampler(index);
3242 }
3243 else if(type == sw::SAMPLER_VERTEX)
3244 {
3245 textureUsed = program->getVertexShader()->usesSampler(index);
3246 }
3247 else UNREACHABLE(type);
3248
3249 sw::Resource *resource = nullptr;
3250
3251 if(baseTexture && textureUsed)
3252 {
3253 resource = baseTexture->getResource();
3254 }
3255
3256 device->setTextureResource(sampler, resource);
3257
3258 if(baseTexture && textureUsed)
3259 {
3260 int baseLevel = baseTexture->getBaseLevel();
3261 int maxLevel = std::min(baseTexture->getTopLevel(), baseTexture->getMaxLevel());
3262 GLenum target = baseTexture->getTarget();
3263
3264 switch(target)
3265 {
3266 case GL_TEXTURE_2D:
3267 case GL_TEXTURE_EXTERNAL_OES:
3268 case GL_TEXTURE_RECTANGLE_ARB:
3269 {
3270 Texture2D *texture = static_cast<Texture2D*>(baseTexture);
3271
3272 for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
3273 {
3274 int surfaceLevel = mipmapLevel + baseLevel;
3275
3276 if(surfaceLevel > maxLevel)
3277 {
3278 surfaceLevel = maxLevel;
3279 }
3280
3281 egl::Image *surface = texture->getImage(surfaceLevel);
3282 device->setTextureLevel(sampler, 0, mipmapLevel, surface,
3283 (target == GL_TEXTURE_RECTANGLE_ARB) ? sw::TEXTURE_RECTANGLE : sw::TEXTURE_2D);
3284 }
3285 }
3286 break;
3287 case GL_TEXTURE_3D:
3288 {
3289 Texture3D *texture = static_cast<Texture3D*>(baseTexture);
3290
3291 for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
3292 {
3293 int surfaceLevel = mipmapLevel + baseLevel;
3294
3295 if(surfaceLevel > maxLevel)
3296 {
3297 surfaceLevel = maxLevel;
3298 }
3299
3300 egl::Image *surface = texture->getImage(surfaceLevel);
3301 device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_3D);
3302 }
3303 }
3304 break;
3305 case GL_TEXTURE_2D_ARRAY:
3306 {
3307 Texture2DArray *texture = static_cast<Texture2DArray*>(baseTexture);
3308
3309 for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
3310 {
3311 int surfaceLevel = mipmapLevel + baseLevel;
3312
3313 if(surfaceLevel > maxLevel)
3314 {
3315 surfaceLevel = maxLevel;
3316 }
3317
3318 egl::Image *surface = texture->getImage(surfaceLevel);
3319 device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_2D_ARRAY);
3320 }
3321 }
3322 break;
3323 case GL_TEXTURE_CUBE_MAP:
3324 {
3325 TextureCubeMap *cubeTexture = static_cast<TextureCubeMap*>(baseTexture);
3326
3327 for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
3328 {
3329 cubeTexture->updateBorders(mipmapLevel);
3330
3331 for(int face = 0; face < 6; face++)
3332 {
3333 int surfaceLevel = mipmapLevel + baseLevel;
3334
3335 if(surfaceLevel > maxLevel)
3336 {
3337 surfaceLevel = maxLevel;
3338 }
3339
3340 egl::Image *surface = cubeTexture->getImage(face, surfaceLevel);
3341 device->setTextureLevel(sampler, face, mipmapLevel, surface, sw::TEXTURE_CUBE);
3342 }
3343 }
3344 }
3345 break;
3346 default:
3347 UNIMPLEMENTED();
3348 break;
3349 }
3350 }
3351 else
3352 {
3353 device->setTextureLevel(sampler, 0, 0, 0, sw::TEXTURE_NULL);
3354 }
3355 }
3356
readPixels(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei * bufSize,void * pixels)3357 void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
3358 {
3359 Framebuffer *framebuffer = getReadFramebuffer();
3360 int framebufferWidth, framebufferHeight, framebufferSamples;
3361
3362 if(!framebuffer || (framebuffer->completeness(framebufferWidth, framebufferHeight, framebufferSamples) != GL_FRAMEBUFFER_COMPLETE))
3363 {
3364 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
3365 }
3366
3367 if(getReadFramebufferName() != 0 && framebufferSamples != 0)
3368 {
3369 return error(GL_INVALID_OPERATION);
3370 }
3371
3372 if(!ValidateReadPixelsFormatType(framebuffer, format, type))
3373 {
3374 return;
3375 }
3376
3377 GLsizei outputWidth = (mState.packParameters.rowLength > 0) ? mState.packParameters.rowLength : width;
3378 GLsizei outputPitch = gl::ComputePitch(outputWidth, format, type, mState.packParameters.alignment);
3379 GLsizei outputHeight = (mState.packParameters.imageHeight == 0) ? height : mState.packParameters.imageHeight;
3380 pixels = getPixelPackBuffer() ? (unsigned char*)getPixelPackBuffer()->data() + (ptrdiff_t)pixels : (unsigned char*)pixels;
3381 pixels = ((char*)pixels) + gl::ComputePackingOffset(format, type, outputWidth, outputHeight, mState.packParameters);
3382
3383 // Sized query sanity check
3384 if(bufSize)
3385 {
3386 int requiredSize = outputPitch * height;
3387 if(requiredSize > *bufSize)
3388 {
3389 return error(GL_INVALID_OPERATION);
3390 }
3391 }
3392
3393 egl::Image *renderTarget = nullptr;
3394 switch(format)
3395 {
3396 case GL_DEPTH_COMPONENT: // GL_NV_read_depth
3397 renderTarget = framebuffer->getDepthBuffer();
3398 break;
3399 case GL_STENCIL_INDEX_OES: // GL_NV_read_stencil
3400 renderTarget = framebuffer->getStencilBuffer();
3401 break;
3402 default:
3403 renderTarget = framebuffer->getReadRenderTarget();
3404 break;
3405 }
3406
3407 if(!renderTarget)
3408 {
3409 return error(GL_INVALID_OPERATION);
3410 }
3411
3412 sw::SliceRectF srcRect((float)x, (float)y, (float)(x + width), (float)(y + height), 0);
3413 sw::SliceRect dstRect(0, 0, width, height, 0);
3414 srcRect.clip(0.0f, 0.0f, (float)renderTarget->getWidth(), (float)renderTarget->getHeight());
3415
3416 ASSERT(format != GL_DEPTH_STENCIL_OES); // The blitter only handles reading either depth or stencil.
3417 sw::Surface *externalSurface = sw::Surface::create(width, height, 1, es2::ConvertReadFormatType(format, type), pixels, outputPitch, outputPitch * outputHeight);
3418 device->blit(renderTarget, srcRect, externalSurface, dstRect, false, false, false);
3419 externalSurface->lockExternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);
3420 externalSurface->unlockExternal();
3421 delete externalSurface;
3422
3423 renderTarget->release();
3424 }
3425
clear(GLbitfield mask)3426 void Context::clear(GLbitfield mask)
3427 {
3428 if(mState.rasterizerDiscardEnabled)
3429 {
3430 return;
3431 }
3432
3433 Framebuffer *framebuffer = getDrawFramebuffer();
3434
3435 if(!framebuffer || (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE))
3436 {
3437 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
3438 }
3439
3440 if(!applyRenderTarget())
3441 {
3442 return;
3443 }
3444
3445 if(mask & GL_COLOR_BUFFER_BIT)
3446 {
3447 unsigned int rgbaMask = getColorMask();
3448
3449 if(rgbaMask != 0)
3450 {
3451 device->clearColor(mState.colorClearValue.red, mState.colorClearValue.green, mState.colorClearValue.blue, mState.colorClearValue.alpha, rgbaMask);
3452 }
3453 }
3454
3455 if(mask & GL_DEPTH_BUFFER_BIT)
3456 {
3457 if(mState.depthMask != 0)
3458 {
3459 float depth = clamp01(mState.depthClearValue);
3460 device->clearDepth(depth);
3461 }
3462 }
3463
3464 if(mask & GL_STENCIL_BUFFER_BIT)
3465 {
3466 if(mState.stencilWritemask != 0)
3467 {
3468 int stencil = mState.stencilClearValue & 0x000000FF;
3469 device->clearStencil(stencil, mState.stencilWritemask);
3470 }
3471 }
3472 }
3473
clearColorBuffer(GLint drawbuffer,void * value,sw::Format format)3474 void Context::clearColorBuffer(GLint drawbuffer, void *value, sw::Format format)
3475 {
3476 unsigned int rgbaMask = getColorMask();
3477 if(rgbaMask && !mState.rasterizerDiscardEnabled)
3478 {
3479 Framebuffer *framebuffer = getDrawFramebuffer();
3480 if(!framebuffer || (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE))
3481 {
3482 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
3483 }
3484 egl::Image *colorbuffer = framebuffer->getRenderTarget(drawbuffer);
3485
3486 if(colorbuffer)
3487 {
3488 sw::Rect clearRect = colorbuffer->getRect();
3489
3490 if(mState.scissorTestEnabled)
3491 {
3492 clearRect.clip(mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight);
3493 }
3494
3495 device->clear(value, format, colorbuffer, clearRect, rgbaMask);
3496
3497 colorbuffer->release();
3498 }
3499 }
3500 }
3501
clearColorBuffer(GLint drawbuffer,const GLint * value)3502 void Context::clearColorBuffer(GLint drawbuffer, const GLint *value)
3503 {
3504 clearColorBuffer(drawbuffer, (void*)value, sw::FORMAT_A32B32G32R32I);
3505 }
3506
clearColorBuffer(GLint drawbuffer,const GLuint * value)3507 void Context::clearColorBuffer(GLint drawbuffer, const GLuint *value)
3508 {
3509 clearColorBuffer(drawbuffer, (void*)value, sw::FORMAT_A32B32G32R32UI);
3510 }
3511
clearColorBuffer(GLint drawbuffer,const GLfloat * value)3512 void Context::clearColorBuffer(GLint drawbuffer, const GLfloat *value)
3513 {
3514 clearColorBuffer(drawbuffer, (void*)value, sw::FORMAT_A32B32G32R32F);
3515 }
3516
clearDepthBuffer(const GLfloat value)3517 void Context::clearDepthBuffer(const GLfloat value)
3518 {
3519 if(mState.depthMask && !mState.rasterizerDiscardEnabled)
3520 {
3521 Framebuffer *framebuffer = getDrawFramebuffer();
3522 if(!framebuffer || (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE))
3523 {
3524 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
3525 }
3526 egl::Image *depthbuffer = framebuffer->getDepthBuffer();
3527
3528 if(depthbuffer)
3529 {
3530 float depth = clamp01(value);
3531 sw::Rect clearRect = depthbuffer->getRect();
3532
3533 if(mState.scissorTestEnabled)
3534 {
3535 clearRect.clip(mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight);
3536 }
3537
3538 depthbuffer->clearDepth(depth, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());
3539
3540 depthbuffer->release();
3541 }
3542 }
3543 }
3544
clearStencilBuffer(const GLint value)3545 void Context::clearStencilBuffer(const GLint value)
3546 {
3547 if(mState.stencilWritemask && !mState.rasterizerDiscardEnabled)
3548 {
3549 Framebuffer *framebuffer = getDrawFramebuffer();
3550 if(!framebuffer || (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE))
3551 {
3552 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
3553 }
3554 egl::Image *stencilbuffer = framebuffer->getStencilBuffer();
3555
3556 if(stencilbuffer)
3557 {
3558 unsigned char stencil = value < 0 ? 0 : static_cast<unsigned char>(value & 0x000000FF);
3559 sw::Rect clearRect = stencilbuffer->getRect();
3560
3561 if(mState.scissorTestEnabled)
3562 {
3563 clearRect.clip(mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight);
3564 }
3565
3566 stencilbuffer->clearStencil(stencil, static_cast<unsigned char>(mState.stencilWritemask), clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());
3567
3568 stencilbuffer->release();
3569 }
3570 }
3571 }
3572
drawArrays(GLenum mode,GLint first,GLsizei count,GLsizei instanceCount)3573 void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
3574 {
3575 if(!applyRenderTarget())
3576 {
3577 return;
3578 }
3579
3580 if(mState.currentProgram == 0)
3581 {
3582 return; // Nothing to process.
3583 }
3584
3585 sw::DrawType primitiveType;
3586 int primitiveCount;
3587 int verticesPerPrimitive;
3588
3589 if(!es2sw::ConvertPrimitiveType(mode, count, GL_NONE, primitiveType, primitiveCount, verticesPerPrimitive))
3590 {
3591 return error(GL_INVALID_ENUM);
3592 }
3593
3594 applyState(mode);
3595
3596 for(int i = 0; i < instanceCount; ++i)
3597 {
3598 device->setInstanceID(i);
3599
3600 GLenum err = applyVertexBuffer(0, first, count, i);
3601 if(err != GL_NO_ERROR)
3602 {
3603 return error(err);
3604 }
3605
3606 applyShaders();
3607 applyTextures();
3608
3609 if(!getCurrentProgram()->validateSamplers(false))
3610 {
3611 return error(GL_INVALID_OPERATION);
3612 }
3613
3614 if(primitiveCount <= 0)
3615 {
3616 return;
3617 }
3618
3619 TransformFeedback* transformFeedback = getTransformFeedback();
3620 if(!cullSkipsDraw(mode) || (transformFeedback->isActive() && !transformFeedback->isPaused()))
3621 {
3622 device->drawPrimitive(primitiveType, primitiveCount);
3623 }
3624 if(transformFeedback)
3625 {
3626 transformFeedback->addVertexOffset(primitiveCount * verticesPerPrimitive);
3627 }
3628 }
3629 }
3630
drawElements(GLenum mode,GLuint start,GLuint end,GLsizei count,GLenum type,const void * indices,GLsizei instanceCount)3631 void Context::drawElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)
3632 {
3633 if(!applyRenderTarget())
3634 {
3635 return;
3636 }
3637
3638 if(mState.currentProgram == 0)
3639 {
3640 return; // Nothing to process.
3641 }
3642
3643 if(count == 0)
3644 {
3645 return;
3646 }
3647
3648 if(!indices && !getCurrentVertexArray()->getElementArrayBuffer())
3649 {
3650 return error(GL_INVALID_OPERATION);
3651 }
3652
3653 GLenum internalMode = mode;
3654 if(isPrimitiveRestartFixedIndexEnabled())
3655 {
3656 switch(mode)
3657 {
3658 case GL_TRIANGLE_FAN:
3659 case GL_TRIANGLE_STRIP:
3660 internalMode = GL_TRIANGLES;
3661 break;
3662 case GL_LINE_LOOP:
3663 case GL_LINE_STRIP:
3664 internalMode = GL_LINES;
3665 break;
3666 default:
3667 break;
3668 }
3669 }
3670
3671 sw::DrawType primitiveType;
3672 int primitiveCount;
3673 int verticesPerPrimitive;
3674
3675 if(!es2sw::ConvertPrimitiveType(internalMode, count, type, primitiveType, primitiveCount, verticesPerPrimitive))
3676 {
3677 return error(GL_INVALID_ENUM);
3678 }
3679
3680 TranslatedIndexData indexInfo(primitiveCount);
3681 GLenum err = applyIndexBuffer(indices, start, end, count, mode, type, &indexInfo);
3682 if(err != GL_NO_ERROR)
3683 {
3684 return error(err);
3685 }
3686
3687 applyState(internalMode);
3688
3689 for(int i = 0; i < instanceCount; ++i)
3690 {
3691 device->setInstanceID(i);
3692
3693 GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
3694 err = applyVertexBuffer(-(int)indexInfo.minIndex, indexInfo.minIndex, vertexCount, i);
3695 if(err != GL_NO_ERROR)
3696 {
3697 return error(err);
3698 }
3699
3700 applyShaders();
3701 applyTextures();
3702
3703 if(!getCurrentProgram()->validateSamplers(false))
3704 {
3705 return error(GL_INVALID_OPERATION);
3706 }
3707
3708 if(primitiveCount <= 0)
3709 {
3710 return;
3711 }
3712
3713 TransformFeedback* transformFeedback = getTransformFeedback();
3714 if(!cullSkipsDraw(internalMode) || (transformFeedback->isActive() && !transformFeedback->isPaused()))
3715 {
3716 device->drawIndexedPrimitive(primitiveType, indexInfo.indexOffset, indexInfo.primitiveCount);
3717 }
3718 if(transformFeedback)
3719 {
3720 transformFeedback->addVertexOffset(indexInfo.primitiveCount * verticesPerPrimitive);
3721 }
3722 }
3723 }
3724
blit(sw::Surface * source,const sw::SliceRect & sRect,sw::Surface * dest,const sw::SliceRect & dRect)3725 void Context::blit(sw::Surface *source, const sw::SliceRect &sRect, sw::Surface *dest, const sw::SliceRect &dRect)
3726 {
3727 sw::SliceRectF sRectF((float)sRect.x0, (float)sRect.y0, (float)sRect.x1, (float)sRect.y1, sRect.slice);
3728 device->blit(source, sRectF, dest, dRect, false);
3729 }
3730
finish()3731 void Context::finish()
3732 {
3733 device->finish();
3734 }
3735
flush()3736 void Context::flush()
3737 {
3738 // We don't queue anything without processing it as fast as possible
3739 }
3740
recordInvalidEnum()3741 void Context::recordInvalidEnum()
3742 {
3743 mInvalidEnum = true;
3744 }
3745
recordInvalidValue()3746 void Context::recordInvalidValue()
3747 {
3748 mInvalidValue = true;
3749 }
3750
recordInvalidOperation()3751 void Context::recordInvalidOperation()
3752 {
3753 mInvalidOperation = true;
3754 }
3755
recordOutOfMemory()3756 void Context::recordOutOfMemory()
3757 {
3758 mOutOfMemory = true;
3759 }
3760
recordInvalidFramebufferOperation()3761 void Context::recordInvalidFramebufferOperation()
3762 {
3763 mInvalidFramebufferOperation = true;
3764 }
3765
3766 // Get one of the recorded errors and clear its flag, if any.
3767 // [OpenGL ES 2.0.24] section 2.5 page 13.
getError()3768 GLenum Context::getError()
3769 {
3770 if(mInvalidEnum)
3771 {
3772 mInvalidEnum = false;
3773
3774 return GL_INVALID_ENUM;
3775 }
3776
3777 if(mInvalidValue)
3778 {
3779 mInvalidValue = false;
3780
3781 return GL_INVALID_VALUE;
3782 }
3783
3784 if(mInvalidOperation)
3785 {
3786 mInvalidOperation = false;
3787
3788 return GL_INVALID_OPERATION;
3789 }
3790
3791 if(mOutOfMemory)
3792 {
3793 mOutOfMemory = false;
3794
3795 return GL_OUT_OF_MEMORY;
3796 }
3797
3798 if(mInvalidFramebufferOperation)
3799 {
3800 mInvalidFramebufferOperation = false;
3801
3802 return GL_INVALID_FRAMEBUFFER_OPERATION;
3803 }
3804
3805 return GL_NO_ERROR;
3806 }
3807
getSupportedMultisampleCount(int requested)3808 int Context::getSupportedMultisampleCount(int requested)
3809 {
3810 int supported = 0;
3811
3812 for(int i = NUM_MULTISAMPLE_COUNTS - 1; i >= 0; i--)
3813 {
3814 if(supported >= requested)
3815 {
3816 return supported;
3817 }
3818
3819 supported = multisampleCount[i];
3820 }
3821
3822 return supported;
3823 }
3824
detachBuffer(GLuint buffer)3825 void Context::detachBuffer(GLuint buffer)
3826 {
3827 // [OpenGL ES 2.0.24] section 2.9 page 22:
3828 // If a buffer object is deleted while it is bound, all bindings to that object in the current context
3829 // (i.e. in the thread that called Delete-Buffers) are reset to zero.
3830
3831 if(mState.copyReadBuffer.name() == buffer)
3832 {
3833 mState.copyReadBuffer = nullptr;
3834 }
3835
3836 if(mState.copyWriteBuffer.name() == buffer)
3837 {
3838 mState.copyWriteBuffer = nullptr;
3839 }
3840
3841 if(mState.pixelPackBuffer.name() == buffer)
3842 {
3843 mState.pixelPackBuffer = nullptr;
3844 }
3845
3846 if(mState.pixelUnpackBuffer.name() == buffer)
3847 {
3848 mState.pixelUnpackBuffer = nullptr;
3849 }
3850
3851 if(mState.genericUniformBuffer.name() == buffer)
3852 {
3853 mState.genericUniformBuffer = nullptr;
3854 }
3855 if (mState.genericTransformFeedbackBuffer.name() == buffer)
3856 {
3857 mState.genericTransformFeedbackBuffer = nullptr;
3858 }
3859
3860 if(getArrayBufferName() == buffer)
3861 {
3862 mState.arrayBuffer = nullptr;
3863 }
3864
3865 // Only detach from the current transform feedback
3866 TransformFeedback* currentTransformFeedback = getTransformFeedback();
3867 if(currentTransformFeedback)
3868 {
3869 currentTransformFeedback->detachBuffer(buffer);
3870 }
3871
3872 // Only detach from the current vertex array
3873 VertexArray* currentVertexArray = getCurrentVertexArray();
3874 if(currentVertexArray)
3875 {
3876 currentVertexArray->detachBuffer(buffer);
3877 }
3878
3879 for(int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
3880 {
3881 if(mState.vertexAttribute[attribute].mBoundBuffer.name() == buffer)
3882 {
3883 mState.vertexAttribute[attribute].mBoundBuffer = nullptr;
3884 }
3885 }
3886 }
3887
detachTexture(GLuint texture)3888 void Context::detachTexture(GLuint texture)
3889 {
3890 // [OpenGL ES 2.0.24] section 3.8 page 84:
3891 // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
3892 // rebound to texture object zero
3893
3894 for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
3895 {
3896 for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
3897 {
3898 if(mState.samplerTexture[type][sampler].name() == texture)
3899 {
3900 mState.samplerTexture[type][sampler] = nullptr;
3901 }
3902 }
3903 }
3904
3905 // [OpenGL ES 2.0.24] section 4.4 page 112:
3906 // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
3907 // as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this
3908 // image was attached in the currently bound framebuffer.
3909
3910 Framebuffer *readFramebuffer = getReadFramebuffer();
3911 Framebuffer *drawFramebuffer = getDrawFramebuffer();
3912
3913 if(readFramebuffer)
3914 {
3915 readFramebuffer->detachTexture(texture);
3916 }
3917
3918 if(drawFramebuffer && drawFramebuffer != readFramebuffer)
3919 {
3920 drawFramebuffer->detachTexture(texture);
3921 }
3922 }
3923
detachFramebuffer(GLuint framebuffer)3924 void Context::detachFramebuffer(GLuint framebuffer)
3925 {
3926 // [OpenGL ES 2.0.24] section 4.4 page 107:
3927 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
3928 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
3929
3930 if(mState.readFramebuffer == framebuffer)
3931 {
3932 bindReadFramebuffer(0);
3933 }
3934
3935 if(mState.drawFramebuffer == framebuffer)
3936 {
3937 bindDrawFramebuffer(0);
3938 }
3939 }
3940
detachRenderbuffer(GLuint renderbuffer)3941 void Context::detachRenderbuffer(GLuint renderbuffer)
3942 {
3943 // [OpenGL ES 2.0.24] section 4.4 page 109:
3944 // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
3945 // had been executed with the target RENDERBUFFER and name of zero.
3946
3947 if(mState.renderbuffer.name() == renderbuffer)
3948 {
3949 bindRenderbuffer(0);
3950 }
3951
3952 // [OpenGL ES 2.0.24] section 4.4 page 111:
3953 // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
3954 // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
3955 // point to which this image was attached in the currently bound framebuffer.
3956
3957 Framebuffer *readFramebuffer = getReadFramebuffer();
3958 Framebuffer *drawFramebuffer = getDrawFramebuffer();
3959
3960 if(readFramebuffer)
3961 {
3962 readFramebuffer->detachRenderbuffer(renderbuffer);
3963 }
3964
3965 if(drawFramebuffer && drawFramebuffer != readFramebuffer)
3966 {
3967 drawFramebuffer->detachRenderbuffer(renderbuffer);
3968 }
3969 }
3970
detachSampler(GLuint sampler)3971 void Context::detachSampler(GLuint sampler)
3972 {
3973 // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
3974 // If a sampler object that is currently bound to one or more texture units is
3975 // deleted, it is as though BindSampler is called once for each texture unit to
3976 // which the sampler is bound, with unit set to the texture unit and sampler set to zero.
3977 for(size_t textureUnit = 0; textureUnit < MAX_COMBINED_TEXTURE_IMAGE_UNITS; ++textureUnit)
3978 {
3979 gl::BindingPointer<Sampler> &samplerBinding = mState.sampler[textureUnit];
3980 if(samplerBinding.name() == sampler)
3981 {
3982 samplerBinding = nullptr;
3983 }
3984 }
3985 }
3986
cullSkipsDraw(GLenum drawMode)3987 bool Context::cullSkipsDraw(GLenum drawMode)
3988 {
3989 return mState.cullFaceEnabled && mState.cullMode == GL_FRONT_AND_BACK && isTriangleMode(drawMode);
3990 }
3991
isTriangleMode(GLenum drawMode)3992 bool Context::isTriangleMode(GLenum drawMode)
3993 {
3994 switch(drawMode)
3995 {
3996 case GL_TRIANGLES:
3997 case GL_TRIANGLE_FAN:
3998 case GL_TRIANGLE_STRIP:
3999 return true;
4000 case GL_POINTS:
4001 case GL_LINES:
4002 case GL_LINE_LOOP:
4003 case GL_LINE_STRIP:
4004 return false;
4005 default: UNREACHABLE(drawMode);
4006 }
4007
4008 return false;
4009 }
4010
setVertexAttrib(GLuint index,const GLfloat * values)4011 void Context::setVertexAttrib(GLuint index, const GLfloat *values)
4012 {
4013 ASSERT(index < MAX_VERTEX_ATTRIBS);
4014
4015 mState.vertexAttribute[index].setCurrentValue(values);
4016
4017 mVertexDataManager->dirtyCurrentValue(index);
4018 }
4019
setVertexAttrib(GLuint index,const GLint * values)4020 void Context::setVertexAttrib(GLuint index, const GLint *values)
4021 {
4022 ASSERT(index < MAX_VERTEX_ATTRIBS);
4023
4024 mState.vertexAttribute[index].setCurrentValue(values);
4025
4026 mVertexDataManager->dirtyCurrentValue(index);
4027 }
4028
setVertexAttrib(GLuint index,const GLuint * values)4029 void Context::setVertexAttrib(GLuint index, const GLuint *values)
4030 {
4031 ASSERT(index < MAX_VERTEX_ATTRIBS);
4032
4033 mState.vertexAttribute[index].setCurrentValue(values);
4034
4035 mVertexDataManager->dirtyCurrentValue(index);
4036 }
4037
blitFramebuffer(GLint srcX0,GLint srcY0,GLint srcX1,GLint srcY1,GLint dstX0,GLint dstY0,GLint dstX1,GLint dstY1,GLbitfield mask,bool filter,bool allowPartialDepthStencilBlit)4038 void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
4039 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
4040 GLbitfield mask, bool filter, bool allowPartialDepthStencilBlit)
4041 {
4042 Framebuffer *readFramebuffer = getReadFramebuffer();
4043 Framebuffer *drawFramebuffer = getDrawFramebuffer();
4044
4045 int readBufferWidth, readBufferHeight, readBufferSamples;
4046 int drawBufferWidth, drawBufferHeight, drawBufferSamples;
4047
4048 if(!readFramebuffer || (readFramebuffer->completeness(readBufferWidth, readBufferHeight, readBufferSamples) != GL_FRAMEBUFFER_COMPLETE) ||
4049 !drawFramebuffer || (drawFramebuffer->completeness(drawBufferWidth, drawBufferHeight, drawBufferSamples) != GL_FRAMEBUFFER_COMPLETE))
4050 {
4051 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
4052 }
4053
4054 if(drawBufferSamples > 1)
4055 {
4056 return error(GL_INVALID_OPERATION);
4057 }
4058
4059 sw::SliceRect sourceRect;
4060 sw::SliceRect destRect;
4061 bool flipX = (srcX0 < srcX1) ^ (dstX0 < dstX1);
4062 bool flipY = (srcY0 < srcY1) ^ (dstY0 < dstY1);
4063
4064 if(srcX0 < srcX1)
4065 {
4066 sourceRect.x0 = srcX0;
4067 sourceRect.x1 = srcX1;
4068 }
4069 else
4070 {
4071 sourceRect.x0 = srcX1;
4072 sourceRect.x1 = srcX0;
4073 }
4074
4075 if(dstX0 < dstX1)
4076 {
4077 destRect.x0 = dstX0;
4078 destRect.x1 = dstX1;
4079 }
4080 else
4081 {
4082 destRect.x0 = dstX1;
4083 destRect.x1 = dstX0;
4084 }
4085
4086 if(srcY0 < srcY1)
4087 {
4088 sourceRect.y0 = srcY0;
4089 sourceRect.y1 = srcY1;
4090 }
4091 else
4092 {
4093 sourceRect.y0 = srcY1;
4094 sourceRect.y1 = srcY0;
4095 }
4096
4097 if(dstY0 < dstY1)
4098 {
4099 destRect.y0 = dstY0;
4100 destRect.y1 = dstY1;
4101 }
4102 else
4103 {
4104 destRect.y0 = dstY1;
4105 destRect.y1 = dstY0;
4106 }
4107
4108 sw::RectF sourceScissoredRect(static_cast<float>(sourceRect.x0), static_cast<float>(sourceRect.y0),
4109 static_cast<float>(sourceRect.x1), static_cast<float>(sourceRect.y1));
4110 sw::Rect destScissoredRect = destRect;
4111
4112 if(mState.scissorTestEnabled) // Only write to parts of the destination framebuffer which pass the scissor test
4113 {
4114 sw::Rect scissorRect(mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight);
4115 if (!Device::ClipDstRect(sourceScissoredRect, destScissoredRect, scissorRect, flipX, flipY))
4116 {
4117 // Failed to clip, blitting can't happen.
4118 return error(GL_INVALID_OPERATION);
4119 }
4120 }
4121
4122 sw::SliceRectF sourceTrimmedRect = sourceScissoredRect;
4123 sw::SliceRect destTrimmedRect = destScissoredRect;
4124
4125 // The source & destination rectangles also may need to be trimmed if
4126 // they fall out of the bounds of the actual draw and read surfaces.
4127 sw::Rect sourceTrimRect(0, 0, readBufferWidth, readBufferHeight);
4128 if (!Device::ClipSrcRect(sourceTrimmedRect, destTrimmedRect, sourceTrimRect, flipX, flipY))
4129 {
4130 // Failed to clip, blitting can't happen.
4131 return error(GL_INVALID_OPERATION);
4132 }
4133
4134 sw::Rect destTrimRect(0, 0, drawBufferWidth, drawBufferHeight);
4135 if (!Device::ClipDstRect(sourceTrimmedRect, destTrimmedRect, destTrimRect, flipX, flipY))
4136 {
4137 // Failed to clip, blitting can't happen.
4138 return error(GL_INVALID_OPERATION);
4139 }
4140
4141 bool partialBufferCopy = false;
4142
4143 if(sourceTrimmedRect.y1 - sourceTrimmedRect.y0 < readBufferHeight ||
4144 sourceTrimmedRect.x1 - sourceTrimmedRect.x0 < readBufferWidth ||
4145 destTrimmedRect.y1 - destTrimmedRect.y0 < drawBufferHeight ||
4146 destTrimmedRect.x1 - destTrimmedRect.x0 < drawBufferWidth ||
4147 sourceTrimmedRect.y0 != 0 || destTrimmedRect.y0 != 0 || sourceTrimmedRect.x0 != 0 || destTrimmedRect.x0 != 0)
4148 {
4149 partialBufferCopy = true;
4150 }
4151
4152 bool sameBounds = (srcX0 == dstX0 && srcY0 == dstY0 && srcX1 == dstX1 && srcY1 == dstY1);
4153 bool blitRenderTarget = false;
4154 bool blitDepth = false;
4155 bool blitStencil = false;
4156
4157 if(mask & GL_COLOR_BUFFER_BIT)
4158 {
4159 GLenum readColorbufferType = readFramebuffer->getReadBufferType();
4160 GLenum drawColorbufferType = drawFramebuffer->getColorbufferType(0);
4161 const bool validReadType = readColorbufferType == GL_TEXTURE_2D || readColorbufferType == GL_TEXTURE_RECTANGLE_ARB || readColorbufferType == GL_TEXTURE_2D_ARRAY || readColorbufferType == GL_TEXTURE_3D || Framebuffer::IsRenderbuffer(readColorbufferType);
4162 const bool validDrawType = drawColorbufferType == GL_TEXTURE_2D || drawColorbufferType == GL_TEXTURE_RECTANGLE_ARB || readColorbufferType == GL_TEXTURE_2D_ARRAY || readColorbufferType == GL_TEXTURE_3D || Framebuffer::IsRenderbuffer(drawColorbufferType);
4163 if(!validReadType || !validDrawType)
4164 {
4165 return error(GL_INVALID_OPERATION);
4166 }
4167
4168 if(partialBufferCopy && readBufferSamples > 1 && !sameBounds)
4169 {
4170 return error(GL_INVALID_OPERATION);
4171 }
4172
4173 // The GL ES 3.0.2 spec (pg 193) states that:
4174 // 1) If the read buffer is fixed point format, the draw buffer must be as well
4175 // 2) If the read buffer is an unsigned integer format, the draw buffer must be
4176 // as well
4177 // 3) If the read buffer is a signed integer format, the draw buffer must be as
4178 // well
4179 es2::Renderbuffer *readRenderbuffer = readFramebuffer->getReadColorbuffer();
4180 es2::Renderbuffer *drawRenderbuffer = drawFramebuffer->getColorbuffer(0);
4181 GLint readFormat = readRenderbuffer->getFormat();
4182 GLint drawFormat = drawRenderbuffer->getFormat();
4183 GLenum readComponentType = GetComponentType(readFormat, GL_COLOR_ATTACHMENT0);
4184 GLenum drawComponentType = GetComponentType(drawFormat, GL_COLOR_ATTACHMENT0);
4185 bool readFixedPoint = ((readComponentType == GL_UNSIGNED_NORMALIZED) ||
4186 (readComponentType == GL_SIGNED_NORMALIZED));
4187 bool drawFixedPoint = ((drawComponentType == GL_UNSIGNED_NORMALIZED) ||
4188 (drawComponentType == GL_SIGNED_NORMALIZED));
4189 bool readFixedOrFloat = (readFixedPoint || (readComponentType == GL_FLOAT));
4190 bool drawFixedOrFloat = (drawFixedPoint || (drawComponentType == GL_FLOAT));
4191
4192 if(readFixedOrFloat != drawFixedOrFloat)
4193 {
4194 return error(GL_INVALID_OPERATION);
4195 }
4196
4197 if((readComponentType == GL_UNSIGNED_INT) && (drawComponentType != GL_UNSIGNED_INT))
4198 {
4199 return error(GL_INVALID_OPERATION);
4200 }
4201
4202 if((readComponentType == GL_INT) && (drawComponentType != GL_INT))
4203 {
4204 return error(GL_INVALID_OPERATION);
4205 }
4206
4207 // Cannot filter integer data
4208 if(((readComponentType == GL_UNSIGNED_INT) || (readComponentType == GL_INT)) && filter)
4209 {
4210 return error(GL_INVALID_OPERATION);
4211 }
4212
4213 if((readRenderbuffer->getSamples() > 0) && (readFormat != drawFormat))
4214 {
4215 // RGBA8 and BGRA8 should be interchangeable here
4216 if(!(((readFormat == GL_RGBA8) && (drawFormat == GL_BGRA8_EXT)) ||
4217 ((readFormat == GL_BGRA8_EXT) && (drawFormat == GL_RGBA8))))
4218 {
4219 return error(GL_INVALID_OPERATION);
4220 }
4221 }
4222
4223 blitRenderTarget = true;
4224 }
4225
4226 if(mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
4227 {
4228 Renderbuffer *readDSBuffer = nullptr;
4229 Renderbuffer *drawDSBuffer = nullptr;
4230
4231 if(mask & GL_DEPTH_BUFFER_BIT)
4232 {
4233 if(readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())
4234 {
4235 GLenum readDepthBufferType = readFramebuffer->getDepthbufferType();
4236 GLenum drawDepthBufferType = drawFramebuffer->getDepthbufferType();
4237 if((readDepthBufferType != drawDepthBufferType) &&
4238 !(Framebuffer::IsRenderbuffer(readDepthBufferType) && Framebuffer::IsRenderbuffer(drawDepthBufferType)))
4239 {
4240 return error(GL_INVALID_OPERATION);
4241 }
4242
4243 blitDepth = true;
4244 readDSBuffer = readFramebuffer->getDepthbuffer();
4245 drawDSBuffer = drawFramebuffer->getDepthbuffer();
4246
4247 if(readDSBuffer->getFormat() != drawDSBuffer->getFormat())
4248 {
4249 return error(GL_INVALID_OPERATION);
4250 }
4251 }
4252 }
4253
4254 if(mask & GL_STENCIL_BUFFER_BIT)
4255 {
4256 if(readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())
4257 {
4258 GLenum readStencilBufferType = readFramebuffer->getStencilbufferType();
4259 GLenum drawStencilBufferType = drawFramebuffer->getStencilbufferType();
4260 if((readStencilBufferType != drawStencilBufferType) &&
4261 !(Framebuffer::IsRenderbuffer(readStencilBufferType) && Framebuffer::IsRenderbuffer(drawStencilBufferType)))
4262 {
4263 return error(GL_INVALID_OPERATION);
4264 }
4265
4266 blitStencil = true;
4267 readDSBuffer = readFramebuffer->getStencilbuffer();
4268 drawDSBuffer = drawFramebuffer->getStencilbuffer();
4269
4270 if(readDSBuffer->getFormat() != drawDSBuffer->getFormat())
4271 {
4272 return error(GL_INVALID_OPERATION);
4273 }
4274 }
4275 }
4276
4277 if(partialBufferCopy && !allowPartialDepthStencilBlit)
4278 {
4279 ERR("Only whole-buffer depth and stencil blits are supported by ANGLE_framebuffer_blit.");
4280 return error(GL_INVALID_OPERATION); // Only whole-buffer copies are permitted
4281 }
4282
4283 // OpenGL ES 3.0.4 spec, p.199:
4284 // ...an INVALID_OPERATION error is generated if the formats of the read
4285 // and draw framebuffers are not identical or if the source and destination
4286 // rectangles are not defined with the same(X0, Y 0) and (X1, Y 1) bounds.
4287 // If SAMPLE_BUFFERS for the draw framebuffer is greater than zero, an
4288 // INVALID_OPERATION error is generated.
4289 if((drawDSBuffer && drawDSBuffer->getSamples() > 1) ||
4290 ((readDSBuffer && readDSBuffer->getSamples() > 1) &&
4291 (!sameBounds || (drawDSBuffer->getFormat() != readDSBuffer->getFormat()))))
4292 {
4293 return error(GL_INVALID_OPERATION);
4294 }
4295 }
4296
4297 if(blitRenderTarget || blitDepth || blitStencil)
4298 {
4299 if(flipX)
4300 {
4301 swap(destTrimmedRect.x0, destTrimmedRect.x1);
4302 }
4303 if(flipY)
4304 {
4305 swap(destTrimmedRect.y0, destTrimmedRect.y1);
4306 }
4307
4308 if(blitRenderTarget)
4309 {
4310 egl::Image *readRenderTarget = readFramebuffer->getReadRenderTarget();
4311 egl::Image *drawRenderTarget = drawFramebuffer->getRenderTarget(0);
4312
4313 bool success = device->stretchRect(readRenderTarget, &sourceTrimmedRect, drawRenderTarget, &destTrimmedRect, (filter ? Device::USE_FILTER : 0) | Device::COLOR_BUFFER);
4314
4315 readRenderTarget->release();
4316 drawRenderTarget->release();
4317
4318 if(!success)
4319 {
4320 ERR("BlitFramebuffer failed.");
4321 return;
4322 }
4323 }
4324
4325 if(blitDepth)
4326 {
4327 egl::Image *readRenderTarget = readFramebuffer->getDepthBuffer();
4328 egl::Image *drawRenderTarget = drawFramebuffer->getDepthBuffer();
4329
4330 bool success = device->stretchRect(readRenderTarget, &sourceTrimmedRect, drawRenderTarget, &destTrimmedRect, (filter ? Device::USE_FILTER : 0) | Device::DEPTH_BUFFER);
4331
4332 readRenderTarget->release();
4333 drawRenderTarget->release();
4334
4335 if(!success)
4336 {
4337 ERR("BlitFramebuffer failed.");
4338 return;
4339 }
4340 }
4341
4342 if(blitStencil)
4343 {
4344 egl::Image *readRenderTarget = readFramebuffer->getStencilBuffer();
4345 egl::Image *drawRenderTarget = drawFramebuffer->getStencilBuffer();
4346
4347 bool success = device->stretchRect(readRenderTarget, &sourceTrimmedRect, drawRenderTarget, &destTrimmedRect, (filter ? Device::USE_FILTER : 0) | Device::STENCIL_BUFFER);
4348
4349 readRenderTarget->release();
4350 drawRenderTarget->release();
4351
4352 if(!success)
4353 {
4354 ERR("BlitFramebuffer failed.");
4355 return;
4356 }
4357 }
4358 }
4359 }
4360
bindTexImage(gl::Surface * surface)4361 void Context::bindTexImage(gl::Surface *surface)
4362 {
4363 bool isRect = (surface->getTextureTarget() == EGL_TEXTURE_RECTANGLE_ANGLE);
4364 es2::Texture2D *textureObject = isRect ? getTexture2DRect() : getTexture2D();
4365
4366 if(textureObject)
4367 {
4368 textureObject->bindTexImage(surface);
4369 }
4370 }
4371
validateSharedImage(EGLenum target,GLuint name,GLuint textureLevel)4372 EGLenum Context::validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel)
4373 {
4374 GLenum textureTarget = GL_NONE;
4375
4376 switch(target)
4377 {
4378 case EGL_GL_TEXTURE_2D_KHR: textureTarget = GL_TEXTURE_2D; break;
4379 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X; break;
4380 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_X; break;
4381 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_Y; break;
4382 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y; break;
4383 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_Z; break;
4384 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; break;
4385 case EGL_GL_RENDERBUFFER_KHR:
4386 break;
4387 default:
4388 return EGL_BAD_PARAMETER;
4389 }
4390
4391 if(textureLevel >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
4392 {
4393 return EGL_BAD_MATCH;
4394 }
4395
4396 if(textureTarget != GL_NONE)
4397 {
4398 es2::Texture *texture = getTexture(name);
4399
4400 if(!texture)
4401 {
4402 return EGL_BAD_PARAMETER;
4403 }
4404
4405 if (texture->getTarget() != GL_TEXTURE_CUBE_MAP && texture->getTarget() != textureTarget)
4406 {
4407 return EGL_BAD_PARAMETER;
4408 }
4409
4410 if (texture->getTarget() == GL_TEXTURE_CUBE_MAP && !IsCubemapTextureTarget(textureTarget))
4411 {
4412 return EGL_BAD_PARAMETER;
4413 }
4414
4415 if(texture->isShared(textureTarget, textureLevel)) // Bound to an EGLSurface or already an EGLImage sibling
4416 {
4417 return EGL_BAD_ACCESS;
4418 }
4419
4420 if(textureLevel != 0 && !texture->isSamplerComplete(nullptr))
4421 {
4422 return EGL_BAD_PARAMETER;
4423 }
4424
4425 if(textureLevel == 0 && !texture->isSamplerComplete(nullptr) && texture->hasNonBaseLevels())
4426 {
4427 return EGL_BAD_PARAMETER;
4428 }
4429 }
4430 else if(target == EGL_GL_RENDERBUFFER_KHR)
4431 {
4432 es2::Renderbuffer *renderbuffer = getRenderbuffer(name);
4433
4434 if(!renderbuffer)
4435 {
4436 return EGL_BAD_PARAMETER;
4437 }
4438
4439 if(renderbuffer->isShared()) // Already an EGLImage sibling
4440 {
4441 return EGL_BAD_ACCESS;
4442 }
4443 }
4444 else UNREACHABLE(target);
4445
4446 return EGL_SUCCESS;
4447 }
4448
createSharedImage(EGLenum target,GLuint name,GLuint textureLevel)4449 egl::Image *Context::createSharedImage(EGLenum target, GLuint name, GLuint textureLevel)
4450 {
4451 GLenum textureTarget = GL_NONE;
4452
4453 switch(target)
4454 {
4455 case EGL_GL_TEXTURE_2D_KHR: textureTarget = GL_TEXTURE_2D; break;
4456 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X; break;
4457 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_X; break;
4458 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_Y; break;
4459 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y; break;
4460 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_Z; break;
4461 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; break;
4462 }
4463
4464 if(textureTarget != GL_NONE)
4465 {
4466 es2::Texture *texture = getTexture(name);
4467
4468 return texture->createSharedImage(textureTarget, textureLevel);
4469 }
4470 else if(target == EGL_GL_RENDERBUFFER_KHR)
4471 {
4472 es2::Renderbuffer *renderbuffer = getRenderbuffer(name);
4473
4474 return renderbuffer->createSharedImage();
4475 }
4476 else UNREACHABLE(target);
4477
4478 return nullptr;
4479 }
4480
getSharedImage(GLeglImageOES image)4481 egl::Image *Context::getSharedImage(GLeglImageOES image)
4482 {
4483 return display->getSharedImage(image);
4484 }
4485
getDevice()4486 Device *Context::getDevice()
4487 {
4488 return device;
4489 }
4490
getExtensions(GLuint index,GLuint * numExt) const4491 const GLubyte *Context::getExtensions(GLuint index, GLuint *numExt) const
4492 {
4493 // Keep list sorted in following order:
4494 // OES extensions
4495 // EXT extensions
4496 // Vendor extensions
4497 static const char *extensions[] =
4498 {
4499 "GL_OES_compressed_ETC1_RGB8_texture",
4500 "GL_OES_depth24",
4501 "GL_OES_depth32",
4502 "GL_OES_depth_texture",
4503 "GL_OES_depth_texture_cube_map",
4504 "GL_OES_EGL_image",
4505 "GL_OES_EGL_image_external",
4506 "GL_OES_EGL_image_external_essl3", // client version is always 3, so this is fine
4507 "GL_OES_EGL_sync",
4508 "GL_OES_element_index_uint",
4509 "GL_OES_fbo_render_mipmap",
4510 "GL_OES_framebuffer_object",
4511 "GL_OES_packed_depth_stencil",
4512 "GL_OES_rgb8_rgba8",
4513 "GL_OES_standard_derivatives",
4514 "GL_OES_surfaceless_context",
4515 "GL_OES_texture_float",
4516 "GL_OES_texture_float_linear",
4517 "GL_OES_texture_half_float",
4518 "GL_OES_texture_half_float_linear",
4519 "GL_OES_texture_npot",
4520 "GL_OES_texture_3D",
4521 "GL_OES_vertex_array_object",
4522 "GL_OES_vertex_half_float",
4523 "GL_EXT_blend_minmax",
4524 "GL_EXT_color_buffer_float", // OpenGL ES 3.0 specific.
4525 "GL_EXT_color_buffer_half_float",
4526 "GL_EXT_draw_buffers",
4527 "GL_EXT_float_blend",
4528 "GL_EXT_instanced_arrays",
4529 "GL_EXT_occlusion_query_boolean",
4530 "GL_EXT_read_format_bgra",
4531 "GL_EXT_texture_compression_dxt1",
4532 "GL_EXT_texture_filter_anisotropic",
4533 "GL_EXT_texture_format_BGRA8888",
4534 "GL_EXT_texture_rg",
4535 "GL_ARB_texture_rectangle",
4536 "GL_ANGLE_framebuffer_blit",
4537 "GL_ANGLE_framebuffer_multisample",
4538 "GL_ANGLE_instanced_arrays",
4539 "GL_ANGLE_texture_compression_dxt3",
4540 "GL_ANGLE_texture_compression_dxt5",
4541 // "GL_APPLE_texture_format_BGRA8888", // b/147536183
4542 "GL_CHROMIUM_color_buffer_float_rgba", // A subset of EXT_color_buffer_float on top of OpenGL ES 2.0
4543 "GL_CHROMIUM_texture_filtering_hint",
4544 "GL_NV_depth_buffer_float2",
4545 "GL_NV_fence",
4546 // "GL_NV_framebuffer_blit", // b/147536183
4547 "GL_NV_read_depth",
4548 "GL_NV_read_stencil",
4549 };
4550
4551 GLuint numExtensions = sizeof(extensions) / sizeof(extensions[0]);
4552
4553 if(numExt)
4554 {
4555 *numExt = numExtensions;
4556
4557 return nullptr;
4558 }
4559
4560 if(index == GL_INVALID_INDEX)
4561 {
4562 static std::string extensionsCat;
4563
4564 if(extensionsCat.empty() && (numExtensions > 0))
4565 {
4566 for(const char *extension : extensions)
4567 {
4568 extensionsCat += std::string(extension) + " ";
4569 }
4570 }
4571
4572 return (const GLubyte*)extensionsCat.c_str();
4573 }
4574
4575 if(index >= numExtensions)
4576 {
4577 return nullptr;
4578 }
4579
4580 return (const GLubyte*)extensions[index];
4581 }
4582
4583 }
4584
es2CreateContext(egl::Display * display,const egl::Context * shareContext,const egl::Config * config)4585 NO_SANITIZE_FUNCTION egl::Context *es2CreateContext(egl::Display *display, const egl::Context *shareContext, const egl::Config *config)
4586 {
4587 return new es2::Context(display, static_cast<const es2::Context*>(shareContext), config);
4588 }
4589