• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "precompiled.h"
2 //
3 // Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style license that can be
5 // found in the LICENSE file.
6 //
7 
8 // Context.cpp: Implements the gl::Context class, managing all GL state and performing
9 // rendering operations. It is the GLES2 specific implementation of EGLContext.
10 
11 #include "libGLESv2/Context.h"
12 
13 #include "libGLESv2/main.h"
14 #include "libGLESv2/utilities.h"
15 #include "libGLESv2/Buffer.h"
16 #include "libGLESv2/Fence.h"
17 #include "libGLESv2/Framebuffer.h"
18 #include "libGLESv2/Renderbuffer.h"
19 #include "libGLESv2/Program.h"
20 #include "libGLESv2/ProgramBinary.h"
21 #include "libGLESv2/Query.h"
22 #include "libGLESv2/Texture.h"
23 #include "libGLESv2/ResourceManager.h"
24 #include "libGLESv2/renderer/IndexDataManager.h"
25 #include "libGLESv2/renderer/RenderTarget.h"
26 #include "libGLESv2/renderer/Renderer.h"
27 
28 #include "libEGL/Surface.h"
29 
30 #undef near
31 #undef far
32 
33 namespace gl
34 {
makeStaticString(const std::string & str)35 static const char* makeStaticString(const std::string& str)
36 {
37     static std::set<std::string> strings;
38     std::set<std::string>::iterator it = strings.find(str);
39     if (it != strings.end())
40       return it->c_str();
41 
42     return strings.insert(str).first->c_str();
43 }
44 
Context(const gl::Context * shareContext,rx::Renderer * renderer,bool notifyResets,bool robustAccess)45 Context::Context(const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess) : mRenderer(renderer)
46 {
47     ASSERT(robustAccess == false);   // Unimplemented
48 
49     mFenceHandleAllocator.setBaseHandle(0);
50 
51     setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
52 
53     mState.depthClearValue = 1.0f;
54     mState.stencilClearValue = 0;
55 
56     mState.rasterizer.cullFace = false;
57     mState.rasterizer.cullMode = GL_BACK;
58     mState.rasterizer.frontFace = GL_CCW;
59     mState.rasterizer.polygonOffsetFill = false;
60     mState.rasterizer.polygonOffsetFactor = 0.0f;
61     mState.rasterizer.polygonOffsetUnits = 0.0f;
62     mState.rasterizer.pointDrawMode = false;
63     mState.rasterizer.multiSample = false;
64     mState.scissorTest = false;
65     mState.scissor.x = 0;
66     mState.scissor.y = 0;
67     mState.scissor.width = 0;
68     mState.scissor.height = 0;
69 
70     mState.blend.blend = false;
71     mState.blend.sourceBlendRGB = GL_ONE;
72     mState.blend.sourceBlendAlpha = GL_ONE;
73     mState.blend.destBlendRGB = GL_ZERO;
74     mState.blend.destBlendAlpha = GL_ZERO;
75     mState.blend.blendEquationRGB = GL_FUNC_ADD;
76     mState.blend.blendEquationAlpha = GL_FUNC_ADD;
77     mState.blend.sampleAlphaToCoverage = false;
78     mState.blend.dither = true;
79 
80     mState.blendColor.red = 0;
81     mState.blendColor.green = 0;
82     mState.blendColor.blue = 0;
83     mState.blendColor.alpha = 0;
84 
85     mState.depthStencil.depthTest = false;
86     mState.depthStencil.depthFunc = GL_LESS;
87     mState.depthStencil.depthMask = true;
88     mState.depthStencil.stencilTest = false;
89     mState.depthStencil.stencilFunc = GL_ALWAYS;
90     mState.depthStencil.stencilMask = -1;
91     mState.depthStencil.stencilWritemask = -1;
92     mState.depthStencil.stencilBackFunc = GL_ALWAYS;
93     mState.depthStencil.stencilBackMask = - 1;
94     mState.depthStencil.stencilBackWritemask = -1;
95     mState.depthStencil.stencilFail = GL_KEEP;
96     mState.depthStencil.stencilPassDepthFail = GL_KEEP;
97     mState.depthStencil.stencilPassDepthPass = GL_KEEP;
98     mState.depthStencil.stencilBackFail = GL_KEEP;
99     mState.depthStencil.stencilBackPassDepthFail = GL_KEEP;
100     mState.depthStencil.stencilBackPassDepthPass = GL_KEEP;
101 
102     mState.stencilRef = 0;
103     mState.stencilBackRef = 0;
104 
105     mState.sampleCoverage = false;
106     mState.sampleCoverageValue = 1.0f;
107     mState.sampleCoverageInvert = false;
108     mState.generateMipmapHint = GL_DONT_CARE;
109     mState.fragmentShaderDerivativeHint = GL_DONT_CARE;
110 
111     mState.lineWidth = 1.0f;
112 
113     mState.viewport.x = 0;
114     mState.viewport.y = 0;
115     mState.viewport.width = 0;
116     mState.viewport.height = 0;
117     mState.zNear = 0.0f;
118     mState.zFar = 1.0f;
119 
120     mState.blend.colorMaskRed = true;
121     mState.blend.colorMaskGreen = true;
122     mState.blend.colorMaskBlue = true;
123     mState.blend.colorMaskAlpha = true;
124 
125     if (shareContext != NULL)
126     {
127         mResourceManager = shareContext->mResourceManager;
128         mResourceManager->addRef();
129     }
130     else
131     {
132         mResourceManager = new ResourceManager(mRenderer);
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.set(new Texture2D(mRenderer, 0));
142     mTextureCubeMapZero.set(new TextureCubeMap(mRenderer, 0));
143 
144     mState.activeSampler = 0;
145     bindArrayBuffer(0);
146     bindElementArrayBuffer(0);
147     bindTextureCubeMap(0);
148     bindTexture2D(0);
149     bindReadFramebuffer(0);
150     bindDrawFramebuffer(0);
151     bindRenderbuffer(0);
152 
153     mState.currentProgram = 0;
154     mCurrentProgramBinary.set(NULL);
155 
156     mState.packAlignment = 4;
157     mState.unpackAlignment = 4;
158     mState.packReverseRowOrder = false;
159 
160     mExtensionString = NULL;
161     mRendererString = NULL;
162 
163     mInvalidEnum = false;
164     mInvalidValue = false;
165     mInvalidOperation = false;
166     mOutOfMemory = false;
167     mInvalidFramebufferOperation = false;
168 
169     mHasBeenCurrent = false;
170     mContextLost = false;
171     mResetStatus = GL_NO_ERROR;
172     mResetStrategy = (notifyResets ? GL_LOSE_CONTEXT_ON_RESET_EXT : GL_NO_RESET_NOTIFICATION_EXT);
173     mRobustAccess = robustAccess;
174 
175     mSupportsBGRATextures = false;
176     mSupportsDXT1Textures = false;
177     mSupportsDXT3Textures = false;
178     mSupportsDXT5Textures = false;
179     mSupportsEventQueries = false;
180     mSupportsOcclusionQueries = false;
181     mNumCompressedTextureFormats = 0;
182 }
183 
~Context()184 Context::~Context()
185 {
186     if (mState.currentProgram != 0)
187     {
188         Program *programObject = mResourceManager->getProgram(mState.currentProgram);
189         if (programObject)
190         {
191             programObject->release();
192         }
193         mState.currentProgram = 0;
194     }
195     mCurrentProgramBinary.set(NULL);
196 
197     while (!mFramebufferMap.empty())
198     {
199         deleteFramebuffer(mFramebufferMap.begin()->first);
200     }
201 
202     while (!mFenceMap.empty())
203     {
204         deleteFence(mFenceMap.begin()->first);
205     }
206 
207     while (!mQueryMap.empty())
208     {
209         deleteQuery(mQueryMap.begin()->first);
210     }
211 
212     for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
213     {
214         for (int sampler = 0; sampler < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
215         {
216             mState.samplerTexture[type][sampler].set(NULL);
217         }
218     }
219 
220     for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
221     {
222         mIncompleteTextures[type].set(NULL);
223     }
224 
225     for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
226     {
227         mState.vertexAttribute[i].mBoundBuffer.set(NULL);
228     }
229 
230     for (int i = 0; i < QUERY_TYPE_COUNT; i++)
231     {
232         mState.activeQuery[i].set(NULL);
233     }
234 
235     mState.arrayBuffer.set(NULL);
236     mState.elementArrayBuffer.set(NULL);
237     mState.renderbuffer.set(NULL);
238 
239     mTexture2DZero.set(NULL);
240     mTextureCubeMapZero.set(NULL);
241 
242     mResourceManager->release();
243 }
244 
makeCurrent(egl::Surface * surface)245 void Context::makeCurrent(egl::Surface *surface)
246 {
247     if (!mHasBeenCurrent)
248     {
249         mMajorShaderModel = mRenderer->getMajorShaderModel();
250         mMaximumPointSize = mRenderer->getMaxPointSize();
251         mSupportsVertexTexture = mRenderer->getVertexTextureSupport();
252         mSupportsNonPower2Texture = mRenderer->getNonPower2TextureSupport();
253         mSupportsInstancing = mRenderer->getInstancingSupport();
254 
255         mMaxViewportDimension = mRenderer->getMaxViewportDimension();
256         mMaxTextureDimension = std::min(std::min(mRenderer->getMaxTextureWidth(), mRenderer->getMaxTextureHeight()),
257                                         (int)gl::IMPLEMENTATION_MAX_TEXTURE_SIZE);
258         mMaxCubeTextureDimension = std::min(mMaxTextureDimension, (int)gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE);
259         mMaxRenderbufferDimension = mMaxTextureDimension;
260         mMaxTextureLevel = log2(mMaxTextureDimension) + 1;
261         mMaxTextureAnisotropy = mRenderer->getTextureMaxAnisotropy();
262         TRACE("MaxTextureDimension=%d, MaxCubeTextureDimension=%d, MaxRenderbufferDimension=%d, MaxTextureLevel=%d, MaxTextureAnisotropy=%f",
263               mMaxTextureDimension, mMaxCubeTextureDimension, mMaxRenderbufferDimension, mMaxTextureLevel, mMaxTextureAnisotropy);
264 
265         mSupportsEventQueries = mRenderer->getEventQuerySupport();
266         mSupportsOcclusionQueries = mRenderer->getOcclusionQuerySupport();
267         mSupportsBGRATextures = mRenderer->getBGRATextureSupport();
268         mSupportsDXT1Textures = mRenderer->getDXT1TextureSupport();
269         mSupportsDXT3Textures = mRenderer->getDXT3TextureSupport();
270         mSupportsDXT5Textures = mRenderer->getDXT5TextureSupport();
271         mSupportsFloat32Textures = mRenderer->getFloat32TextureSupport(&mSupportsFloat32LinearFilter, &mSupportsFloat32RenderableTextures);
272         mSupportsFloat16Textures = mRenderer->getFloat16TextureSupport(&mSupportsFloat16LinearFilter, &mSupportsFloat16RenderableTextures);
273         mSupportsLuminanceTextures = mRenderer->getLuminanceTextureSupport();
274         mSupportsLuminanceAlphaTextures = mRenderer->getLuminanceAlphaTextureSupport();
275         mSupportsDepthTextures = mRenderer->getDepthTextureSupport();
276         mSupportsTextureFilterAnisotropy = mRenderer->getTextureFilterAnisotropySupport();
277         mSupports32bitIndices = mRenderer->get32BitIndexSupport();
278 
279         mNumCompressedTextureFormats = 0;
280         if (supportsDXT1Textures())
281         {
282             mNumCompressedTextureFormats += 2;
283         }
284         if (supportsDXT3Textures())
285         {
286             mNumCompressedTextureFormats += 1;
287         }
288         if (supportsDXT5Textures())
289         {
290             mNumCompressedTextureFormats += 1;
291         }
292 
293         initExtensionString();
294         initRendererString();
295 
296         mState.viewport.x = 0;
297         mState.viewport.y = 0;
298         mState.viewport.width = surface->getWidth();
299         mState.viewport.height = surface->getHeight();
300 
301         mState.scissor.x = 0;
302         mState.scissor.y = 0;
303         mState.scissor.width = surface->getWidth();
304         mState.scissor.height = surface->getHeight();
305 
306         mHasBeenCurrent = true;
307     }
308 
309     // Wrap the existing swapchain resources into GL objects and assign them to the '0' names
310     rx::SwapChain *swapchain = surface->getSwapChain();
311 
312     Colorbuffer *colorbufferZero = new Colorbuffer(mRenderer, swapchain);
313     DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(mRenderer, swapchain);
314     Framebuffer *framebufferZero = new DefaultFramebuffer(mRenderer, colorbufferZero, depthStencilbufferZero);
315 
316     setFramebufferZero(framebufferZero);
317 }
318 
319 // NOTE: this function should not assume that this context is current!
markContextLost()320 void Context::markContextLost()
321 {
322     if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
323         mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
324     mContextLost = true;
325 }
326 
isContextLost()327 bool Context::isContextLost()
328 {
329     return mContextLost;
330 }
331 
setClearColor(float red,float green,float blue,float alpha)332 void Context::setClearColor(float red, float green, float blue, float alpha)
333 {
334     mState.colorClearValue.red = red;
335     mState.colorClearValue.green = green;
336     mState.colorClearValue.blue = blue;
337     mState.colorClearValue.alpha = alpha;
338 }
339 
setClearDepth(float depth)340 void Context::setClearDepth(float depth)
341 {
342     mState.depthClearValue = depth;
343 }
344 
setClearStencil(int stencil)345 void Context::setClearStencil(int stencil)
346 {
347     mState.stencilClearValue = stencil;
348 }
349 
setCullFace(bool enabled)350 void Context::setCullFace(bool enabled)
351 {
352     mState.rasterizer.cullFace = enabled;
353 }
354 
isCullFaceEnabled() const355 bool Context::isCullFaceEnabled() const
356 {
357     return mState.rasterizer.cullFace;
358 }
359 
setCullMode(GLenum mode)360 void Context::setCullMode(GLenum mode)
361 {
362     mState.rasterizer.cullMode = mode;
363 }
364 
setFrontFace(GLenum front)365 void Context::setFrontFace(GLenum front)
366 {
367     mState.rasterizer.frontFace = front;
368 }
369 
setDepthTest(bool enabled)370 void Context::setDepthTest(bool enabled)
371 {
372     mState.depthStencil.depthTest = enabled;
373 }
374 
isDepthTestEnabled() const375 bool Context::isDepthTestEnabled() const
376 {
377     return mState.depthStencil.depthTest;
378 }
379 
setDepthFunc(GLenum depthFunc)380 void Context::setDepthFunc(GLenum depthFunc)
381 {
382      mState.depthStencil.depthFunc = depthFunc;
383 }
384 
setDepthRange(float zNear,float zFar)385 void Context::setDepthRange(float zNear, float zFar)
386 {
387     mState.zNear = zNear;
388     mState.zFar = zFar;
389 }
390 
setBlend(bool enabled)391 void Context::setBlend(bool enabled)
392 {
393     mState.blend.blend = enabled;
394 }
395 
isBlendEnabled() const396 bool Context::isBlendEnabled() const
397 {
398     return mState.blend.blend;
399 }
400 
setBlendFactors(GLenum sourceRGB,GLenum destRGB,GLenum sourceAlpha,GLenum destAlpha)401 void Context::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
402 {
403     mState.blend.sourceBlendRGB = sourceRGB;
404     mState.blend.destBlendRGB = destRGB;
405     mState.blend.sourceBlendAlpha = sourceAlpha;
406     mState.blend.destBlendAlpha = destAlpha;
407 }
408 
setBlendColor(float red,float green,float blue,float alpha)409 void Context::setBlendColor(float red, float green, float blue, float alpha)
410 {
411     mState.blendColor.red = red;
412     mState.blendColor.green = green;
413     mState.blendColor.blue = blue;
414     mState.blendColor.alpha = alpha;
415 }
416 
setBlendEquation(GLenum rgbEquation,GLenum alphaEquation)417 void Context::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
418 {
419     mState.blend.blendEquationRGB = rgbEquation;
420     mState.blend.blendEquationAlpha = alphaEquation;
421 }
422 
setStencilTest(bool enabled)423 void Context::setStencilTest(bool enabled)
424 {
425     mState.depthStencil.stencilTest = enabled;
426 }
427 
isStencilTestEnabled() const428 bool Context::isStencilTestEnabled() const
429 {
430     return mState.depthStencil.stencilTest;
431 }
432 
setStencilParams(GLenum stencilFunc,GLint stencilRef,GLuint stencilMask)433 void Context::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
434 {
435     mState.depthStencil.stencilFunc = stencilFunc;
436     mState.stencilRef = (stencilRef > 0) ? stencilRef : 0;
437     mState.depthStencil.stencilMask = stencilMask;
438 }
439 
setStencilBackParams(GLenum stencilBackFunc,GLint stencilBackRef,GLuint stencilBackMask)440 void Context::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
441 {
442     mState.depthStencil.stencilBackFunc = stencilBackFunc;
443     mState.stencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
444     mState.depthStencil.stencilBackMask = stencilBackMask;
445 }
446 
setStencilWritemask(GLuint stencilWritemask)447 void Context::setStencilWritemask(GLuint stencilWritemask)
448 {
449     mState.depthStencil.stencilWritemask = stencilWritemask;
450 }
451 
setStencilBackWritemask(GLuint stencilBackWritemask)452 void Context::setStencilBackWritemask(GLuint stencilBackWritemask)
453 {
454     mState.depthStencil.stencilBackWritemask = stencilBackWritemask;
455 }
456 
setStencilOperations(GLenum stencilFail,GLenum stencilPassDepthFail,GLenum stencilPassDepthPass)457 void Context::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
458 {
459     mState.depthStencil.stencilFail = stencilFail;
460     mState.depthStencil.stencilPassDepthFail = stencilPassDepthFail;
461     mState.depthStencil.stencilPassDepthPass = stencilPassDepthPass;
462 }
463 
setStencilBackOperations(GLenum stencilBackFail,GLenum stencilBackPassDepthFail,GLenum stencilBackPassDepthPass)464 void Context::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
465 {
466     mState.depthStencil.stencilBackFail = stencilBackFail;
467     mState.depthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
468     mState.depthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
469 }
470 
setPolygonOffsetFill(bool enabled)471 void Context::setPolygonOffsetFill(bool enabled)
472 {
473      mState.rasterizer.polygonOffsetFill = enabled;
474 }
475 
isPolygonOffsetFillEnabled() const476 bool Context::isPolygonOffsetFillEnabled() const
477 {
478     return mState.rasterizer.polygonOffsetFill;
479 }
480 
setPolygonOffsetParams(GLfloat factor,GLfloat units)481 void Context::setPolygonOffsetParams(GLfloat factor, GLfloat units)
482 {
483     // An application can pass NaN values here, so handle this gracefully
484     mState.rasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor;
485     mState.rasterizer.polygonOffsetUnits = units != units ? 0.0f : units;
486 }
487 
setSampleAlphaToCoverage(bool enabled)488 void Context::setSampleAlphaToCoverage(bool enabled)
489 {
490     mState.blend.sampleAlphaToCoverage = enabled;
491 }
492 
isSampleAlphaToCoverageEnabled() const493 bool Context::isSampleAlphaToCoverageEnabled() const
494 {
495     return mState.blend.sampleAlphaToCoverage;
496 }
497 
setSampleCoverage(bool enabled)498 void Context::setSampleCoverage(bool enabled)
499 {
500     mState.sampleCoverage = enabled;
501 }
502 
isSampleCoverageEnabled() const503 bool Context::isSampleCoverageEnabled() const
504 {
505     return mState.sampleCoverage;
506 }
507 
setSampleCoverageParams(GLclampf value,bool invert)508 void Context::setSampleCoverageParams(GLclampf value, bool invert)
509 {
510     mState.sampleCoverageValue = value;
511     mState.sampleCoverageInvert = invert;
512 }
513 
setScissorTest(bool enabled)514 void Context::setScissorTest(bool enabled)
515 {
516     mState.scissorTest = enabled;
517 }
518 
isScissorTestEnabled() const519 bool Context::isScissorTestEnabled() const
520 {
521     return mState.scissorTest;
522 }
523 
setDither(bool enabled)524 void Context::setDither(bool enabled)
525 {
526     mState.blend.dither = enabled;
527 }
528 
isDitherEnabled() const529 bool Context::isDitherEnabled() const
530 {
531     return mState.blend.dither;
532 }
533 
setLineWidth(GLfloat width)534 void Context::setLineWidth(GLfloat width)
535 {
536     mState.lineWidth = width;
537 }
538 
setGenerateMipmapHint(GLenum hint)539 void Context::setGenerateMipmapHint(GLenum hint)
540 {
541     mState.generateMipmapHint = hint;
542 }
543 
setFragmentShaderDerivativeHint(GLenum hint)544 void Context::setFragmentShaderDerivativeHint(GLenum hint)
545 {
546     mState.fragmentShaderDerivativeHint = hint;
547     // TODO: Propagate the hint to shader translator so we can write
548     // ddx, ddx_coarse, or ddx_fine depending on the hint.
549     // Ignore for now. It is valid for implementations to ignore hint.
550 }
551 
setViewportParams(GLint x,GLint y,GLsizei width,GLsizei height)552 void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
553 {
554     mState.viewport.x = x;
555     mState.viewport.y = y;
556     mState.viewport.width = width;
557     mState.viewport.height = height;
558 }
559 
setScissorParams(GLint x,GLint y,GLsizei width,GLsizei height)560 void Context::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
561 {
562     mState.scissor.x = x;
563     mState.scissor.y = y;
564     mState.scissor.width = width;
565     mState.scissor.height = height;
566 }
567 
setColorMask(bool red,bool green,bool blue,bool alpha)568 void Context::setColorMask(bool red, bool green, bool blue, bool alpha)
569 {
570     mState.blend.colorMaskRed = red;
571     mState.blend.colorMaskGreen = green;
572     mState.blend.colorMaskBlue = blue;
573     mState.blend.colorMaskAlpha = alpha;
574 }
575 
setDepthMask(bool mask)576 void Context::setDepthMask(bool mask)
577 {
578     mState.depthStencil.depthMask = mask;
579 }
580 
setActiveSampler(unsigned int active)581 void Context::setActiveSampler(unsigned int active)
582 {
583     mState.activeSampler = active;
584 }
585 
getReadFramebufferHandle() const586 GLuint Context::getReadFramebufferHandle() const
587 {
588     return mState.readFramebuffer;
589 }
590 
getDrawFramebufferHandle() const591 GLuint Context::getDrawFramebufferHandle() const
592 {
593     return mState.drawFramebuffer;
594 }
595 
getRenderbufferHandle() const596 GLuint Context::getRenderbufferHandle() const
597 {
598     return mState.renderbuffer.id();
599 }
600 
getArrayBufferHandle() const601 GLuint Context::getArrayBufferHandle() const
602 {
603     return mState.arrayBuffer.id();
604 }
605 
getActiveQuery(GLenum target) const606 GLuint Context::getActiveQuery(GLenum target) const
607 {
608     Query *queryObject = NULL;
609 
610     switch (target)
611     {
612       case GL_ANY_SAMPLES_PASSED_EXT:
613         queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED].get();
614         break;
615       case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
616         queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE].get();
617         break;
618       default:
619         ASSERT(false);
620     }
621 
622     if (queryObject)
623     {
624         return queryObject->id();
625     }
626     else
627     {
628         return 0;
629     }
630 }
631 
setEnableVertexAttribArray(unsigned int attribNum,bool enabled)632 void Context::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
633 {
634     mState.vertexAttribute[attribNum].mArrayEnabled = enabled;
635 }
636 
getVertexAttribState(unsigned int attribNum)637 const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum)
638 {
639     return mState.vertexAttribute[attribNum];
640 }
641 
setVertexAttribState(unsigned int attribNum,Buffer * boundBuffer,GLint size,GLenum type,bool normalized,GLsizei stride,const void * pointer)642 void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
643                                    GLsizei stride, const void *pointer)
644 {
645     mState.vertexAttribute[attribNum].mBoundBuffer.set(boundBuffer);
646     mState.vertexAttribute[attribNum].mSize = size;
647     mState.vertexAttribute[attribNum].mType = type;
648     mState.vertexAttribute[attribNum].mNormalized = normalized;
649     mState.vertexAttribute[attribNum].mStride = stride;
650     mState.vertexAttribute[attribNum].mPointer = pointer;
651 }
652 
getVertexAttribPointer(unsigned int attribNum) const653 const void *Context::getVertexAttribPointer(unsigned int attribNum) const
654 {
655     return mState.vertexAttribute[attribNum].mPointer;
656 }
657 
setPackAlignment(GLint alignment)658 void Context::setPackAlignment(GLint alignment)
659 {
660     mState.packAlignment = alignment;
661 }
662 
getPackAlignment() const663 GLint Context::getPackAlignment() const
664 {
665     return mState.packAlignment;
666 }
667 
setUnpackAlignment(GLint alignment)668 void Context::setUnpackAlignment(GLint alignment)
669 {
670     mState.unpackAlignment = alignment;
671 }
672 
getUnpackAlignment() const673 GLint Context::getUnpackAlignment() const
674 {
675     return mState.unpackAlignment;
676 }
677 
setPackReverseRowOrder(bool reverseRowOrder)678 void Context::setPackReverseRowOrder(bool reverseRowOrder)
679 {
680     mState.packReverseRowOrder = reverseRowOrder;
681 }
682 
getPackReverseRowOrder() const683 bool Context::getPackReverseRowOrder() const
684 {
685     return mState.packReverseRowOrder;
686 }
687 
createBuffer()688 GLuint Context::createBuffer()
689 {
690     return mResourceManager->createBuffer();
691 }
692 
createProgram()693 GLuint Context::createProgram()
694 {
695     return mResourceManager->createProgram();
696 }
697 
createShader(GLenum type)698 GLuint Context::createShader(GLenum type)
699 {
700     return mResourceManager->createShader(type);
701 }
702 
createTexture()703 GLuint Context::createTexture()
704 {
705     return mResourceManager->createTexture();
706 }
707 
createRenderbuffer()708 GLuint Context::createRenderbuffer()
709 {
710     return mResourceManager->createRenderbuffer();
711 }
712 
713 // Returns an unused framebuffer name
createFramebuffer()714 GLuint Context::createFramebuffer()
715 {
716     GLuint handle = mFramebufferHandleAllocator.allocate();
717 
718     mFramebufferMap[handle] = NULL;
719 
720     return handle;
721 }
722 
createFence()723 GLuint Context::createFence()
724 {
725     GLuint handle = mFenceHandleAllocator.allocate();
726 
727     mFenceMap[handle] = new Fence(mRenderer);
728 
729     return handle;
730 }
731 
732 // Returns an unused query name
createQuery()733 GLuint Context::createQuery()
734 {
735     GLuint handle = mQueryHandleAllocator.allocate();
736 
737     mQueryMap[handle] = NULL;
738 
739     return handle;
740 }
741 
deleteBuffer(GLuint buffer)742 void Context::deleteBuffer(GLuint buffer)
743 {
744     if (mResourceManager->getBuffer(buffer))
745     {
746         detachBuffer(buffer);
747     }
748 
749     mResourceManager->deleteBuffer(buffer);
750 }
751 
deleteShader(GLuint shader)752 void Context::deleteShader(GLuint shader)
753 {
754     mResourceManager->deleteShader(shader);
755 }
756 
deleteProgram(GLuint program)757 void Context::deleteProgram(GLuint program)
758 {
759     mResourceManager->deleteProgram(program);
760 }
761 
deleteTexture(GLuint texture)762 void Context::deleteTexture(GLuint texture)
763 {
764     if (mResourceManager->getTexture(texture))
765     {
766         detachTexture(texture);
767     }
768 
769     mResourceManager->deleteTexture(texture);
770 }
771 
deleteRenderbuffer(GLuint renderbuffer)772 void Context::deleteRenderbuffer(GLuint renderbuffer)
773 {
774     if (mResourceManager->getRenderbuffer(renderbuffer))
775     {
776         detachRenderbuffer(renderbuffer);
777     }
778 
779     mResourceManager->deleteRenderbuffer(renderbuffer);
780 }
781 
deleteFramebuffer(GLuint framebuffer)782 void Context::deleteFramebuffer(GLuint framebuffer)
783 {
784     FramebufferMap::iterator framebufferObject = mFramebufferMap.find(framebuffer);
785 
786     if (framebufferObject != mFramebufferMap.end())
787     {
788         detachFramebuffer(framebuffer);
789 
790         mFramebufferHandleAllocator.release(framebufferObject->first);
791         delete framebufferObject->second;
792         mFramebufferMap.erase(framebufferObject);
793     }
794 }
795 
deleteFence(GLuint fence)796 void Context::deleteFence(GLuint fence)
797 {
798     FenceMap::iterator fenceObject = mFenceMap.find(fence);
799 
800     if (fenceObject != mFenceMap.end())
801     {
802         mFenceHandleAllocator.release(fenceObject->first);
803         delete fenceObject->second;
804         mFenceMap.erase(fenceObject);
805     }
806 }
807 
deleteQuery(GLuint query)808 void Context::deleteQuery(GLuint query)
809 {
810     QueryMap::iterator queryObject = mQueryMap.find(query);
811     if (queryObject != mQueryMap.end())
812     {
813         mQueryHandleAllocator.release(queryObject->first);
814         if (queryObject->second)
815         {
816             queryObject->second->release();
817         }
818         mQueryMap.erase(queryObject);
819     }
820 }
821 
getBuffer(GLuint handle)822 Buffer *Context::getBuffer(GLuint handle)
823 {
824     return mResourceManager->getBuffer(handle);
825 }
826 
getShader(GLuint handle)827 Shader *Context::getShader(GLuint handle)
828 {
829     return mResourceManager->getShader(handle);
830 }
831 
getProgram(GLuint handle)832 Program *Context::getProgram(GLuint handle)
833 {
834     return mResourceManager->getProgram(handle);
835 }
836 
getTexture(GLuint handle)837 Texture *Context::getTexture(GLuint handle)
838 {
839     return mResourceManager->getTexture(handle);
840 }
841 
getRenderbuffer(GLuint handle)842 Renderbuffer *Context::getRenderbuffer(GLuint handle)
843 {
844     return mResourceManager->getRenderbuffer(handle);
845 }
846 
getReadFramebuffer()847 Framebuffer *Context::getReadFramebuffer()
848 {
849     return getFramebuffer(mState.readFramebuffer);
850 }
851 
getDrawFramebuffer()852 Framebuffer *Context::getDrawFramebuffer()
853 {
854     return mBoundDrawFramebuffer;
855 }
856 
bindArrayBuffer(unsigned int buffer)857 void Context::bindArrayBuffer(unsigned int buffer)
858 {
859     mResourceManager->checkBufferAllocation(buffer);
860 
861     mState.arrayBuffer.set(getBuffer(buffer));
862 }
863 
bindElementArrayBuffer(unsigned int buffer)864 void Context::bindElementArrayBuffer(unsigned int buffer)
865 {
866     mResourceManager->checkBufferAllocation(buffer);
867 
868     mState.elementArrayBuffer.set(getBuffer(buffer));
869 }
870 
bindTexture2D(GLuint texture)871 void Context::bindTexture2D(GLuint texture)
872 {
873     mResourceManager->checkTextureAllocation(texture, TEXTURE_2D);
874 
875     mState.samplerTexture[TEXTURE_2D][mState.activeSampler].set(getTexture(texture));
876 }
877 
bindTextureCubeMap(GLuint texture)878 void Context::bindTextureCubeMap(GLuint texture)
879 {
880     mResourceManager->checkTextureAllocation(texture, TEXTURE_CUBE);
881 
882     mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].set(getTexture(texture));
883 }
884 
bindReadFramebuffer(GLuint framebuffer)885 void Context::bindReadFramebuffer(GLuint framebuffer)
886 {
887     if (!getFramebuffer(framebuffer))
888     {
889         mFramebufferMap[framebuffer] = new Framebuffer(mRenderer);
890     }
891 
892     mState.readFramebuffer = framebuffer;
893 }
894 
bindDrawFramebuffer(GLuint framebuffer)895 void Context::bindDrawFramebuffer(GLuint framebuffer)
896 {
897     if (!getFramebuffer(framebuffer))
898     {
899         mFramebufferMap[framebuffer] = new Framebuffer(mRenderer);
900     }
901 
902     mState.drawFramebuffer = framebuffer;
903 
904     mBoundDrawFramebuffer = getFramebuffer(framebuffer);
905 }
906 
bindRenderbuffer(GLuint renderbuffer)907 void Context::bindRenderbuffer(GLuint renderbuffer)
908 {
909     mResourceManager->checkRenderbufferAllocation(renderbuffer);
910 
911     mState.renderbuffer.set(getRenderbuffer(renderbuffer));
912 }
913 
useProgram(GLuint program)914 void Context::useProgram(GLuint program)
915 {
916     GLuint priorProgram = mState.currentProgram;
917     mState.currentProgram = program;               // Must switch before trying to delete, otherwise it only gets flagged.
918 
919     if (priorProgram != program)
920     {
921         Program *newProgram = mResourceManager->getProgram(program);
922         Program *oldProgram = mResourceManager->getProgram(priorProgram);
923         mCurrentProgramBinary.set(NULL);
924 
925         if (newProgram)
926         {
927             newProgram->addRef();
928             mCurrentProgramBinary.set(newProgram->getProgramBinary());
929         }
930 
931         if (oldProgram)
932         {
933             oldProgram->release();
934         }
935     }
936 }
937 
linkProgram(GLuint program)938 void Context::linkProgram(GLuint program)
939 {
940     Program *programObject = mResourceManager->getProgram(program);
941 
942     bool linked = programObject->link();
943 
944     // if the current program was relinked successfully we
945     // need to install the new executables
946     if (linked && program == mState.currentProgram)
947     {
948         mCurrentProgramBinary.set(programObject->getProgramBinary());
949     }
950 }
951 
setProgramBinary(GLuint program,const void * binary,GLint length)952 void Context::setProgramBinary(GLuint program, const void *binary, GLint length)
953 {
954     Program *programObject = mResourceManager->getProgram(program);
955 
956     bool loaded = programObject->setProgramBinary(binary, length);
957 
958     // if the current program was reloaded successfully we
959     // need to install the new executables
960     if (loaded && program == mState.currentProgram)
961     {
962         mCurrentProgramBinary.set(programObject->getProgramBinary());
963     }
964 
965 }
966 
beginQuery(GLenum target,GLuint query)967 void Context::beginQuery(GLenum target, GLuint query)
968 {
969     // From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id>
970     // of zero, if the active query object name for <target> is non-zero (for the
971     // targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if
972     // the active query for either target is non-zero), if <id> is the name of an
973     // existing query object whose type does not match <target>, or if <id> is the
974     // active query object name for any query type, the error INVALID_OPERATION is
975     // generated.
976 
977     // Ensure no other queries are active
978     // NOTE: If other queries than occlusion are supported, we will need to check
979     // separately that:
980     //    a) The query ID passed is not the current active query for any target/type
981     //    b) There are no active queries for the requested target (and in the case
982     //       of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
983     //       no query may be active for either if glBeginQuery targets either.
984     for (int i = 0; i < QUERY_TYPE_COUNT; i++)
985     {
986         if (mState.activeQuery[i].get() != NULL)
987         {
988             return gl::error(GL_INVALID_OPERATION);
989         }
990     }
991 
992     QueryType qType;
993     switch (target)
994     {
995       case GL_ANY_SAMPLES_PASSED_EXT:
996         qType = QUERY_ANY_SAMPLES_PASSED;
997         break;
998       case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
999         qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE;
1000         break;
1001       default:
1002         ASSERT(false);
1003         return;
1004     }
1005 
1006     Query *queryObject = getQuery(query, true, target);
1007 
1008     // check that name was obtained with glGenQueries
1009     if (!queryObject)
1010     {
1011         return gl::error(GL_INVALID_OPERATION);
1012     }
1013 
1014     // check for type mismatch
1015     if (queryObject->getType() != target)
1016     {
1017         return gl::error(GL_INVALID_OPERATION);
1018     }
1019 
1020     // set query as active for specified target
1021     mState.activeQuery[qType].set(queryObject);
1022 
1023     // begin query
1024     queryObject->begin();
1025 }
1026 
endQuery(GLenum target)1027 void Context::endQuery(GLenum target)
1028 {
1029     QueryType qType;
1030 
1031     switch (target)
1032     {
1033       case GL_ANY_SAMPLES_PASSED_EXT:
1034         qType = QUERY_ANY_SAMPLES_PASSED;
1035         break;
1036       case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
1037         qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE;
1038         break;
1039       default:
1040         ASSERT(false);
1041         return;
1042     }
1043 
1044     Query *queryObject = mState.activeQuery[qType].get();
1045 
1046     if (queryObject == NULL)
1047     {
1048         return gl::error(GL_INVALID_OPERATION);
1049     }
1050 
1051     queryObject->end();
1052 
1053     mState.activeQuery[qType].set(NULL);
1054 }
1055 
setFramebufferZero(Framebuffer * buffer)1056 void Context::setFramebufferZero(Framebuffer *buffer)
1057 {
1058     delete mFramebufferMap[0];
1059     mFramebufferMap[0] = buffer;
1060     if (mState.drawFramebuffer == 0)
1061     {
1062         mBoundDrawFramebuffer = buffer;
1063     }
1064 }
1065 
setRenderbufferStorage(GLsizei width,GLsizei height,GLenum internalformat,GLsizei samples)1066 void Context::setRenderbufferStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples)
1067 {
1068     RenderbufferStorage *renderbuffer = NULL;
1069     switch (internalformat)
1070     {
1071       case GL_DEPTH_COMPONENT16:
1072         renderbuffer = new gl::Depthbuffer(mRenderer, width, height, samples);
1073         break;
1074       case GL_RGBA4:
1075       case GL_RGB5_A1:
1076       case GL_RGB565:
1077       case GL_RGB8_OES:
1078       case GL_RGBA8_OES:
1079         renderbuffer = new gl::Colorbuffer(mRenderer,width, height, internalformat, samples);
1080         break;
1081       case GL_STENCIL_INDEX8:
1082         renderbuffer = new gl::Stencilbuffer(mRenderer, width, height, samples);
1083         break;
1084       case GL_DEPTH24_STENCIL8_OES:
1085         renderbuffer = new gl::DepthStencilbuffer(mRenderer, width, height, samples);
1086         break;
1087       default:
1088         UNREACHABLE(); return;
1089     }
1090 
1091     Renderbuffer *renderbufferObject = mState.renderbuffer.get();
1092     renderbufferObject->setStorage(renderbuffer);
1093 }
1094 
getFramebuffer(unsigned int handle)1095 Framebuffer *Context::getFramebuffer(unsigned int handle)
1096 {
1097     FramebufferMap::iterator framebuffer = mFramebufferMap.find(handle);
1098 
1099     if (framebuffer == mFramebufferMap.end())
1100     {
1101         return NULL;
1102     }
1103     else
1104     {
1105         return framebuffer->second;
1106     }
1107 }
1108 
getFence(unsigned int handle)1109 Fence *Context::getFence(unsigned int handle)
1110 {
1111     FenceMap::iterator fence = mFenceMap.find(handle);
1112 
1113     if (fence == mFenceMap.end())
1114     {
1115         return NULL;
1116     }
1117     else
1118     {
1119         return fence->second;
1120     }
1121 }
1122 
getQuery(unsigned int handle,bool create,GLenum type)1123 Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1124 {
1125     QueryMap::iterator query = mQueryMap.find(handle);
1126 
1127     if (query == mQueryMap.end())
1128     {
1129         return NULL;
1130     }
1131     else
1132     {
1133         if (!query->second && create)
1134         {
1135             query->second = new Query(mRenderer, type, handle);
1136             query->second->addRef();
1137         }
1138         return query->second;
1139     }
1140 }
1141 
getArrayBuffer()1142 Buffer *Context::getArrayBuffer()
1143 {
1144     return mState.arrayBuffer.get();
1145 }
1146 
getElementArrayBuffer()1147 Buffer *Context::getElementArrayBuffer()
1148 {
1149     return mState.elementArrayBuffer.get();
1150 }
1151 
getCurrentProgramBinary()1152 ProgramBinary *Context::getCurrentProgramBinary()
1153 {
1154     return mCurrentProgramBinary.get();
1155 }
1156 
getTexture2D()1157 Texture2D *Context::getTexture2D()
1158 {
1159     return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D));
1160 }
1161 
getTextureCubeMap()1162 TextureCubeMap *Context::getTextureCubeMap()
1163 {
1164     return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, TEXTURE_CUBE));
1165 }
1166 
getSamplerTexture(unsigned int sampler,TextureType type)1167 Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type)
1168 {
1169     GLuint texid = mState.samplerTexture[type][sampler].id();
1170 
1171     if (texid == 0)   // Special case: 0 refers to different initial textures based on the target
1172     {
1173         switch (type)
1174         {
1175           default: UNREACHABLE();
1176           case TEXTURE_2D: return mTexture2DZero.get();
1177           case TEXTURE_CUBE: return mTextureCubeMapZero.get();
1178         }
1179     }
1180 
1181     return mState.samplerTexture[type][sampler].get();
1182 }
1183 
getBooleanv(GLenum pname,GLboolean * params)1184 bool Context::getBooleanv(GLenum pname, GLboolean *params)
1185 {
1186     switch (pname)
1187     {
1188       case GL_SHADER_COMPILER:           *params = GL_TRUE;                             break;
1189       case GL_SAMPLE_COVERAGE_INVERT:    *params = mState.sampleCoverageInvert;         break;
1190       case GL_DEPTH_WRITEMASK:           *params = mState.depthStencil.depthMask;       break;
1191       case GL_COLOR_WRITEMASK:
1192         params[0] = mState.blend.colorMaskRed;
1193         params[1] = mState.blend.colorMaskGreen;
1194         params[2] = mState.blend.colorMaskBlue;
1195         params[3] = mState.blend.colorMaskAlpha;
1196         break;
1197       case GL_CULL_FACE:                 *params = mState.rasterizer.cullFace;          break;
1198       case GL_POLYGON_OFFSET_FILL:       *params = mState.rasterizer.polygonOffsetFill; break;
1199       case GL_SAMPLE_ALPHA_TO_COVERAGE:  *params = mState.blend.sampleAlphaToCoverage;  break;
1200       case GL_SAMPLE_COVERAGE:           *params = mState.sampleCoverage;               break;
1201       case GL_SCISSOR_TEST:              *params = mState.scissorTest;                  break;
1202       case GL_STENCIL_TEST:              *params = mState.depthStencil.stencilTest;     break;
1203       case GL_DEPTH_TEST:                *params = mState.depthStencil.depthTest;       break;
1204       case GL_BLEND:                     *params = mState.blend.blend;                  break;
1205       case GL_DITHER:                    *params = mState.blend.dither;                 break;
1206       case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE;  break;
1207       default:
1208         return false;
1209     }
1210 
1211     return true;
1212 }
1213 
getFloatv(GLenum pname,GLfloat * params)1214 bool Context::getFloatv(GLenum pname, GLfloat *params)
1215 {
1216     // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
1217     // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1218     // GetIntegerv as its native query function. As it would require conversion in any
1219     // case, this should make no difference to the calling application.
1220     switch (pname)
1221     {
1222       case GL_LINE_WIDTH:               *params = mState.lineWidth;                         break;
1223       case GL_SAMPLE_COVERAGE_VALUE:    *params = mState.sampleCoverageValue;               break;
1224       case GL_DEPTH_CLEAR_VALUE:        *params = mState.depthClearValue;                   break;
1225       case GL_POLYGON_OFFSET_FACTOR:    *params = mState.rasterizer.polygonOffsetFactor;    break;
1226       case GL_POLYGON_OFFSET_UNITS:     *params = mState.rasterizer.polygonOffsetUnits;     break;
1227       case GL_ALIASED_LINE_WIDTH_RANGE:
1228         params[0] = gl::ALIASED_LINE_WIDTH_RANGE_MIN;
1229         params[1] = gl::ALIASED_LINE_WIDTH_RANGE_MAX;
1230         break;
1231       case GL_ALIASED_POINT_SIZE_RANGE:
1232         params[0] = gl::ALIASED_POINT_SIZE_RANGE_MIN;
1233         params[1] = getMaximumPointSize();
1234         break;
1235       case GL_DEPTH_RANGE:
1236         params[0] = mState.zNear;
1237         params[1] = mState.zFar;
1238         break;
1239       case GL_COLOR_CLEAR_VALUE:
1240         params[0] = mState.colorClearValue.red;
1241         params[1] = mState.colorClearValue.green;
1242         params[2] = mState.colorClearValue.blue;
1243         params[3] = mState.colorClearValue.alpha;
1244         break;
1245       case GL_BLEND_COLOR:
1246         params[0] = mState.blendColor.red;
1247         params[1] = mState.blendColor.green;
1248         params[2] = mState.blendColor.blue;
1249         params[3] = mState.blendColor.alpha;
1250         break;
1251       case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1252         if (!supportsTextureFilterAnisotropy())
1253         {
1254             return false;
1255         }
1256         *params = mMaxTextureAnisotropy;
1257         break;
1258       default:
1259         return false;
1260     }
1261 
1262     return true;
1263 }
1264 
getIntegerv(GLenum pname,GLint * params)1265 bool Context::getIntegerv(GLenum pname, GLint *params)
1266 {
1267     if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1268     {
1269         unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT);
1270 
1271         if (colorAttachment >= mRenderer->getMaxRenderTargets())
1272         {
1273             // return true to stop further operation in the parent call
1274             return gl::error(GL_INVALID_OPERATION, true);
1275         }
1276 
1277         Framebuffer *framebuffer = getDrawFramebuffer();
1278 
1279         *params = framebuffer->getDrawBufferState(colorAttachment);
1280         return true;
1281     }
1282 
1283     // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
1284     // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1285     // GetIntegerv as its native query function. As it would require conversion in any
1286     // case, this should make no difference to the calling application. You may find it in
1287     // Context::getFloatv.
1288     switch (pname)
1289     {
1290       case GL_MAX_VERTEX_ATTRIBS:               *params = gl::MAX_VERTEX_ATTRIBS;               break;
1291       case GL_MAX_VERTEX_UNIFORM_VECTORS:       *params = mRenderer->getMaxVertexUniformVectors(); break;
1292       case GL_MAX_VARYING_VECTORS:              *params = mRenderer->getMaxVaryingVectors();    break;
1293       case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mRenderer->getMaxCombinedTextureImageUnits(); break;
1294       case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:   *params = mRenderer->getMaxVertexTextureImageUnits(); break;
1295       case GL_MAX_TEXTURE_IMAGE_UNITS:          *params = gl::MAX_TEXTURE_IMAGE_UNITS;          break;
1296       case GL_MAX_FRAGMENT_UNIFORM_VECTORS:     *params = mRenderer->getMaxFragmentUniformVectors(); break;
1297       case GL_MAX_RENDERBUFFER_SIZE:            *params = getMaximumRenderbufferDimension();    break;
1298       case GL_MAX_COLOR_ATTACHMENTS_EXT:        *params = mRenderer->getMaxRenderTargets();     break;
1299       case GL_MAX_DRAW_BUFFERS_EXT:             *params = mRenderer->getMaxRenderTargets();     break;
1300       case GL_NUM_SHADER_BINARY_FORMATS:        *params = 0;                                    break;
1301       case GL_SHADER_BINARY_FORMATS:      /* no shader binary formats are supported */          break;
1302       case GL_ARRAY_BUFFER_BINDING:             *params = mState.arrayBuffer.id();              break;
1303       case GL_ELEMENT_ARRAY_BUFFER_BINDING:     *params = mState.elementArrayBuffer.id();       break;
1304       //case GL_FRAMEBUFFER_BINDING:            // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1305       case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE:   *params = mState.drawFramebuffer;               break;
1306       case GL_READ_FRAMEBUFFER_BINDING_ANGLE:   *params = mState.readFramebuffer;               break;
1307       case GL_RENDERBUFFER_BINDING:             *params = mState.renderbuffer.id();             break;
1308       case GL_CURRENT_PROGRAM:                  *params = mState.currentProgram;                break;
1309       case GL_PACK_ALIGNMENT:                   *params = mState.packAlignment;                 break;
1310       case GL_PACK_REVERSE_ROW_ORDER_ANGLE:     *params = mState.packReverseRowOrder;           break;
1311       case GL_UNPACK_ALIGNMENT:                 *params = mState.unpackAlignment;               break;
1312       case GL_GENERATE_MIPMAP_HINT:             *params = mState.generateMipmapHint;            break;
1313       case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mState.fragmentShaderDerivativeHint; break;
1314       case GL_ACTIVE_TEXTURE:                   *params = (mState.activeSampler + GL_TEXTURE0); break;
1315       case GL_STENCIL_FUNC:                     *params = mState.depthStencil.stencilFunc;             break;
1316       case GL_STENCIL_REF:                      *params = mState.stencilRef;                           break;
1317       case GL_STENCIL_VALUE_MASK:               *params = mState.depthStencil.stencilMask;             break;
1318       case GL_STENCIL_BACK_FUNC:                *params = mState.depthStencil.stencilBackFunc;         break;
1319       case GL_STENCIL_BACK_REF:                 *params = mState.stencilBackRef;                       break;
1320       case GL_STENCIL_BACK_VALUE_MASK:          *params = mState.depthStencil.stencilBackMask;         break;
1321       case GL_STENCIL_FAIL:                     *params = mState.depthStencil.stencilFail;             break;
1322       case GL_STENCIL_PASS_DEPTH_FAIL:          *params = mState.depthStencil.stencilPassDepthFail;    break;
1323       case GL_STENCIL_PASS_DEPTH_PASS:          *params = mState.depthStencil.stencilPassDepthPass;    break;
1324       case GL_STENCIL_BACK_FAIL:                *params = mState.depthStencil.stencilBackFail;         break;
1325       case GL_STENCIL_BACK_PASS_DEPTH_FAIL:     *params = mState.depthStencil.stencilBackPassDepthFail; break;
1326       case GL_STENCIL_BACK_PASS_DEPTH_PASS:     *params = mState.depthStencil.stencilBackPassDepthPass; break;
1327       case GL_DEPTH_FUNC:                       *params = mState.depthStencil.depthFunc;               break;
1328       case GL_BLEND_SRC_RGB:                    *params = mState.blend.sourceBlendRGB;                 break;
1329       case GL_BLEND_SRC_ALPHA:                  *params = mState.blend.sourceBlendAlpha;               break;
1330       case GL_BLEND_DST_RGB:                    *params = mState.blend.destBlendRGB;                   break;
1331       case GL_BLEND_DST_ALPHA:                  *params = mState.blend.destBlendAlpha;                 break;
1332       case GL_BLEND_EQUATION_RGB:               *params = mState.blend.blendEquationRGB;               break;
1333       case GL_BLEND_EQUATION_ALPHA:             *params = mState.blend.blendEquationAlpha;             break;
1334       case GL_STENCIL_WRITEMASK:                *params = mState.depthStencil.stencilWritemask;        break;
1335       case GL_STENCIL_BACK_WRITEMASK:           *params = mState.depthStencil.stencilBackWritemask;    break;
1336       case GL_STENCIL_CLEAR_VALUE:              *params = mState.stencilClearValue;             break;
1337       case GL_SUBPIXEL_BITS:                    *params = 4;                                    break;
1338       case GL_MAX_TEXTURE_SIZE:                 *params = getMaximumTextureDimension();         break;
1339       case GL_MAX_CUBE_MAP_TEXTURE_SIZE:        *params = getMaximumCubeTextureDimension();     break;
1340       case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1341         params[0] = mNumCompressedTextureFormats;
1342         break;
1343       case GL_MAX_SAMPLES_ANGLE:
1344         {
1345             GLsizei maxSamples = getMaxSupportedSamples();
1346             if (maxSamples != 0)
1347             {
1348                 *params = maxSamples;
1349             }
1350             else
1351             {
1352                 return false;
1353             }
1354 
1355             break;
1356         }
1357       case GL_SAMPLE_BUFFERS:
1358       case GL_SAMPLES:
1359         {
1360             gl::Framebuffer *framebuffer = getDrawFramebuffer();
1361             if (framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE)
1362             {
1363                 switch (pname)
1364                 {
1365                   case GL_SAMPLE_BUFFERS:
1366                     if (framebuffer->getSamples() != 0)
1367                     {
1368                         *params = 1;
1369                     }
1370                     else
1371                     {
1372                         *params = 0;
1373                     }
1374                     break;
1375                   case GL_SAMPLES:
1376                     *params = framebuffer->getSamples();
1377                     break;
1378                 }
1379             }
1380             else
1381             {
1382                 *params = 0;
1383             }
1384         }
1385         break;
1386       case GL_IMPLEMENTATION_COLOR_READ_TYPE:
1387       case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
1388         {
1389             GLenum format, type;
1390             if (getCurrentReadFormatType(&format, &type))
1391             {
1392                 if (pname == GL_IMPLEMENTATION_COLOR_READ_FORMAT)
1393                     *params = format;
1394                 else
1395                     *params = type;
1396             }
1397         }
1398         break;
1399       case GL_MAX_VIEWPORT_DIMS:
1400         {
1401             params[0] = mMaxViewportDimension;
1402             params[1] = mMaxViewportDimension;
1403         }
1404         break;
1405       case GL_COMPRESSED_TEXTURE_FORMATS:
1406         {
1407             if (supportsDXT1Textures())
1408             {
1409                 *params++ = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
1410                 *params++ = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
1411             }
1412             if (supportsDXT3Textures())
1413             {
1414                 *params++ = GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE;
1415             }
1416             if (supportsDXT5Textures())
1417             {
1418                 *params++ = GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE;
1419             }
1420         }
1421         break;
1422       case GL_VIEWPORT:
1423         params[0] = mState.viewport.x;
1424         params[1] = mState.viewport.y;
1425         params[2] = mState.viewport.width;
1426         params[3] = mState.viewport.height;
1427         break;
1428       case GL_SCISSOR_BOX:
1429         params[0] = mState.scissor.x;
1430         params[1] = mState.scissor.y;
1431         params[2] = mState.scissor.width;
1432         params[3] = mState.scissor.height;
1433         break;
1434       case GL_CULL_FACE_MODE:                   *params = mState.rasterizer.cullMode;   break;
1435       case GL_FRONT_FACE:                       *params = mState.rasterizer.frontFace;  break;
1436       case GL_RED_BITS:
1437       case GL_GREEN_BITS:
1438       case GL_BLUE_BITS:
1439       case GL_ALPHA_BITS:
1440         {
1441             gl::Framebuffer *framebuffer = getDrawFramebuffer();
1442             gl::Renderbuffer *colorbuffer = framebuffer->getFirstColorbuffer();
1443 
1444             if (colorbuffer)
1445             {
1446                 switch (pname)
1447                 {
1448                   case GL_RED_BITS:   *params = colorbuffer->getRedSize();      break;
1449                   case GL_GREEN_BITS: *params = colorbuffer->getGreenSize();    break;
1450                   case GL_BLUE_BITS:  *params = colorbuffer->getBlueSize();     break;
1451                   case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize();    break;
1452                 }
1453             }
1454             else
1455             {
1456                 *params = 0;
1457             }
1458         }
1459         break;
1460       case GL_DEPTH_BITS:
1461         {
1462             gl::Framebuffer *framebuffer = getDrawFramebuffer();
1463             gl::Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
1464 
1465             if (depthbuffer)
1466             {
1467                 *params = depthbuffer->getDepthSize();
1468             }
1469             else
1470             {
1471                 *params = 0;
1472             }
1473         }
1474         break;
1475       case GL_STENCIL_BITS:
1476         {
1477             gl::Framebuffer *framebuffer = getDrawFramebuffer();
1478             gl::Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
1479 
1480             if (stencilbuffer)
1481             {
1482                 *params = stencilbuffer->getStencilSize();
1483             }
1484             else
1485             {
1486                 *params = 0;
1487             }
1488         }
1489         break;
1490       case GL_TEXTURE_BINDING_2D:
1491         {
1492             if (mState.activeSampler > mRenderer->getMaxCombinedTextureImageUnits() - 1)
1493             {
1494                 gl::error(GL_INVALID_OPERATION);
1495                 return false;
1496             }
1497 
1498             *params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].id();
1499         }
1500         break;
1501       case GL_TEXTURE_BINDING_CUBE_MAP:
1502         {
1503             if (mState.activeSampler > mRenderer->getMaxCombinedTextureImageUnits() - 1)
1504             {
1505                 gl::error(GL_INVALID_OPERATION);
1506                 return false;
1507             }
1508 
1509             *params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].id();
1510         }
1511         break;
1512       case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1513         *params = mResetStrategy;
1514         break;
1515       case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
1516         *params = 1;
1517         break;
1518       case GL_PROGRAM_BINARY_FORMATS_OES:
1519         *params = GL_PROGRAM_BINARY_ANGLE;
1520         break;
1521       default:
1522         return false;
1523     }
1524 
1525     return true;
1526 }
1527 
getQueryParameterInfo(GLenum pname,GLenum * type,unsigned int * numParams)1528 bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams)
1529 {
1530     if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1531     {
1532         *type = GL_INT;
1533         *numParams = 1;
1534         return true;
1535     }
1536 
1537     // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
1538     // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
1539     // to the fact that it is stored internally as a float, and so would require conversion
1540     // if returned from Context::getIntegerv. Since this conversion is already implemented
1541     // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
1542     // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
1543     // application.
1544     switch (pname)
1545     {
1546       case GL_COMPRESSED_TEXTURE_FORMATS:
1547         {
1548             *type = GL_INT;
1549             *numParams = mNumCompressedTextureFormats;
1550         }
1551         break;
1552       case GL_SHADER_BINARY_FORMATS:
1553         {
1554             *type = GL_INT;
1555             *numParams = 0;
1556         }
1557         break;
1558       case GL_MAX_VERTEX_ATTRIBS:
1559       case GL_MAX_VERTEX_UNIFORM_VECTORS:
1560       case GL_MAX_VARYING_VECTORS:
1561       case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1562       case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1563       case GL_MAX_TEXTURE_IMAGE_UNITS:
1564       case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1565       case GL_MAX_RENDERBUFFER_SIZE:
1566       case GL_MAX_COLOR_ATTACHMENTS_EXT:
1567       case GL_MAX_DRAW_BUFFERS_EXT:
1568       case GL_NUM_SHADER_BINARY_FORMATS:
1569       case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1570       case GL_ARRAY_BUFFER_BINDING:
1571       case GL_FRAMEBUFFER_BINDING:
1572       case GL_RENDERBUFFER_BINDING:
1573       case GL_CURRENT_PROGRAM:
1574       case GL_PACK_ALIGNMENT:
1575       case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
1576       case GL_UNPACK_ALIGNMENT:
1577       case GL_GENERATE_MIPMAP_HINT:
1578       case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
1579       case GL_RED_BITS:
1580       case GL_GREEN_BITS:
1581       case GL_BLUE_BITS:
1582       case GL_ALPHA_BITS:
1583       case GL_DEPTH_BITS:
1584       case GL_STENCIL_BITS:
1585       case GL_ELEMENT_ARRAY_BUFFER_BINDING:
1586       case GL_CULL_FACE_MODE:
1587       case GL_FRONT_FACE:
1588       case GL_ACTIVE_TEXTURE:
1589       case GL_STENCIL_FUNC:
1590       case GL_STENCIL_VALUE_MASK:
1591       case GL_STENCIL_REF:
1592       case GL_STENCIL_FAIL:
1593       case GL_STENCIL_PASS_DEPTH_FAIL:
1594       case GL_STENCIL_PASS_DEPTH_PASS:
1595       case GL_STENCIL_BACK_FUNC:
1596       case GL_STENCIL_BACK_VALUE_MASK:
1597       case GL_STENCIL_BACK_REF:
1598       case GL_STENCIL_BACK_FAIL:
1599       case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
1600       case GL_STENCIL_BACK_PASS_DEPTH_PASS:
1601       case GL_DEPTH_FUNC:
1602       case GL_BLEND_SRC_RGB:
1603       case GL_BLEND_SRC_ALPHA:
1604       case GL_BLEND_DST_RGB:
1605       case GL_BLEND_DST_ALPHA:
1606       case GL_BLEND_EQUATION_RGB:
1607       case GL_BLEND_EQUATION_ALPHA:
1608       case GL_STENCIL_WRITEMASK:
1609       case GL_STENCIL_BACK_WRITEMASK:
1610       case GL_STENCIL_CLEAR_VALUE:
1611       case GL_SUBPIXEL_BITS:
1612       case GL_MAX_TEXTURE_SIZE:
1613       case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1614       case GL_SAMPLE_BUFFERS:
1615       case GL_SAMPLES:
1616       case GL_IMPLEMENTATION_COLOR_READ_TYPE:
1617       case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
1618       case GL_TEXTURE_BINDING_2D:
1619       case GL_TEXTURE_BINDING_CUBE_MAP:
1620       case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1621       case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
1622       case GL_PROGRAM_BINARY_FORMATS_OES:
1623         {
1624             *type = GL_INT;
1625             *numParams = 1;
1626         }
1627         break;
1628       case GL_MAX_SAMPLES_ANGLE:
1629         {
1630             if (getMaxSupportedSamples() != 0)
1631             {
1632                 *type = GL_INT;
1633                 *numParams = 1;
1634             }
1635             else
1636             {
1637                 return false;
1638             }
1639         }
1640         break;
1641       case GL_MAX_VIEWPORT_DIMS:
1642         {
1643             *type = GL_INT;
1644             *numParams = 2;
1645         }
1646         break;
1647       case GL_VIEWPORT:
1648       case GL_SCISSOR_BOX:
1649         {
1650             *type = GL_INT;
1651             *numParams = 4;
1652         }
1653         break;
1654       case GL_SHADER_COMPILER:
1655       case GL_SAMPLE_COVERAGE_INVERT:
1656       case GL_DEPTH_WRITEMASK:
1657       case GL_CULL_FACE:                // CULL_FACE through DITHER are natural to IsEnabled,
1658       case GL_POLYGON_OFFSET_FILL:      // but can be retrieved through the Get{Type}v queries.
1659       case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
1660       case GL_SAMPLE_COVERAGE:
1661       case GL_SCISSOR_TEST:
1662       case GL_STENCIL_TEST:
1663       case GL_DEPTH_TEST:
1664       case GL_BLEND:
1665       case GL_DITHER:
1666       case GL_CONTEXT_ROBUST_ACCESS_EXT:
1667         {
1668             *type = GL_BOOL;
1669             *numParams = 1;
1670         }
1671         break;
1672       case GL_COLOR_WRITEMASK:
1673         {
1674             *type = GL_BOOL;
1675             *numParams = 4;
1676         }
1677         break;
1678       case GL_POLYGON_OFFSET_FACTOR:
1679       case GL_POLYGON_OFFSET_UNITS:
1680       case GL_SAMPLE_COVERAGE_VALUE:
1681       case GL_DEPTH_CLEAR_VALUE:
1682       case GL_LINE_WIDTH:
1683         {
1684             *type = GL_FLOAT;
1685             *numParams = 1;
1686         }
1687         break;
1688       case GL_ALIASED_LINE_WIDTH_RANGE:
1689       case GL_ALIASED_POINT_SIZE_RANGE:
1690       case GL_DEPTH_RANGE:
1691         {
1692             *type = GL_FLOAT;
1693             *numParams = 2;
1694         }
1695         break;
1696       case GL_COLOR_CLEAR_VALUE:
1697       case GL_BLEND_COLOR:
1698         {
1699             *type = GL_FLOAT;
1700             *numParams = 4;
1701         }
1702         break;
1703       case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1704         if (!supportsTextureFilterAnisotropy())
1705         {
1706             return false;
1707         }
1708         *type = GL_FLOAT;
1709         *numParams = 1;
1710         break;
1711       default:
1712         return false;
1713     }
1714 
1715     return true;
1716 }
1717 
1718 // Applies the render target surface, depth stencil surface, viewport rectangle and
1719 // scissor rectangle to the renderer
applyRenderTarget(GLenum drawMode,bool ignoreViewport)1720 bool Context::applyRenderTarget(GLenum drawMode, bool ignoreViewport)
1721 {
1722     Framebuffer *framebufferObject = getDrawFramebuffer();
1723 
1724     if (!framebufferObject || framebufferObject->completeness() != GL_FRAMEBUFFER_COMPLETE)
1725     {
1726         return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
1727     }
1728 
1729     mRenderer->applyRenderTarget(framebufferObject);
1730 
1731     if (!mRenderer->setViewport(mState.viewport, mState.zNear, mState.zFar, drawMode, mState.rasterizer.frontFace,
1732                                 ignoreViewport))
1733     {
1734         return false;
1735     }
1736 
1737     mRenderer->setScissorRectangle(mState.scissor, mState.scissorTest);
1738 
1739     return true;
1740 }
1741 
1742 // Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) to the Direct3D 9 device
applyState(GLenum drawMode)1743 void Context::applyState(GLenum drawMode)
1744 {
1745     Framebuffer *framebufferObject = getDrawFramebuffer();
1746     int samples = framebufferObject->getSamples();
1747 
1748     mState.rasterizer.pointDrawMode = (drawMode == GL_POINTS);
1749     mState.rasterizer.multiSample = (samples != 0);
1750     mRenderer->setRasterizerState(mState.rasterizer);
1751 
1752     unsigned int mask = 0;
1753     if (mState.sampleCoverage)
1754     {
1755         if (mState.sampleCoverageValue != 0)
1756         {
1757 
1758             float threshold = 0.5f;
1759 
1760             for (int i = 0; i < samples; ++i)
1761             {
1762                 mask <<= 1;
1763 
1764                 if ((i + 1) * mState.sampleCoverageValue >= threshold)
1765                 {
1766                     threshold += 1.0f;
1767                     mask |= 1;
1768                 }
1769             }
1770         }
1771 
1772         if (mState.sampleCoverageInvert)
1773         {
1774             mask = ~mask;
1775         }
1776     }
1777     else
1778     {
1779         mask = 0xFFFFFFFF;
1780     }
1781     mRenderer->setBlendState(mState.blend, mState.blendColor, mask);
1782 
1783     mRenderer->setDepthStencilState(mState.depthStencil, mState.stencilRef, mState.stencilBackRef,
1784                                     mState.rasterizer.frontFace == GL_CCW);
1785 }
1786 
1787 // Applies the shaders and shader constants to the Direct3D 9 device
applyShaders()1788 void Context::applyShaders()
1789 {
1790     ProgramBinary *programBinary = getCurrentProgramBinary();
1791 
1792     mRenderer->applyShaders(programBinary);
1793 
1794     programBinary->applyUniforms();
1795 }
1796 
1797 // Applies the textures and sampler states to the Direct3D 9 device
applyTextures()1798 void Context::applyTextures()
1799 {
1800     applyTextures(SAMPLER_PIXEL);
1801 
1802     if (mSupportsVertexTexture)
1803     {
1804         applyTextures(SAMPLER_VERTEX);
1805     }
1806 }
1807 
1808 // For each Direct3D 9 sampler of either the pixel or vertex stage,
1809 // looks up the corresponding OpenGL texture image unit and texture type,
1810 // and sets the texture and its addressing/filtering state (or NULL when inactive).
applyTextures(SamplerType type)1811 void Context::applyTextures(SamplerType type)
1812 {
1813     ProgramBinary *programBinary = getCurrentProgramBinary();
1814 
1815     FramebufferTextureSerialSet boundFramebufferTextures = getBoundFramebufferTextureSerials();
1816 
1817     // Range of Direct3D samplers of given sampler type
1818     int samplerCount = (type == SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : mRenderer->getMaxVertexTextureImageUnits();
1819     int samplerRange = programBinary->getUsedSamplerRange(type);
1820 
1821     for (int samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++)
1822     {
1823         int textureUnit = programBinary->getSamplerMapping(type, samplerIndex);   // OpenGL texture image unit index
1824 
1825         if (textureUnit != -1)
1826         {
1827             TextureType textureType = programBinary->getSamplerTextureType(type, samplerIndex);
1828             Texture *texture = getSamplerTexture(textureUnit, textureType);
1829 
1830             if (texture->isSamplerComplete() &&
1831                 boundFramebufferTextures.find(texture->getTextureSerial()) == boundFramebufferTextures.end())
1832             {
1833                 SamplerState samplerState;
1834                 texture->getSamplerState(&samplerState);
1835                 mRenderer->setSamplerState(type, samplerIndex, samplerState);
1836 
1837                 mRenderer->setTexture(type, samplerIndex, texture);
1838 
1839                 texture->resetDirty();
1840             }
1841             else
1842             {
1843                 mRenderer->setTexture(type, samplerIndex, getIncompleteTexture(textureType));
1844             }
1845         }
1846         else
1847         {
1848             mRenderer->setTexture(type, samplerIndex, NULL);
1849         }
1850     }
1851 
1852     for (int samplerIndex = samplerRange; samplerIndex < samplerCount; samplerIndex++)
1853     {
1854         mRenderer->setTexture(type, samplerIndex, NULL);
1855     }
1856 }
1857 
readPixels(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei * bufSize,void * pixels)1858 void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
1859                          GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
1860 {
1861     Framebuffer *framebuffer = getReadFramebuffer();
1862 
1863     if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1864     {
1865         return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION);
1866     }
1867 
1868     if (getReadFramebufferHandle() != 0 && framebuffer->getSamples() != 0)
1869     {
1870         return gl::error(GL_INVALID_OPERATION);
1871     }
1872 
1873     GLsizei outputPitch = ComputePitch(width, ConvertSizedInternalFormat(format, type), getPackAlignment());
1874     // sized query sanity check
1875     if (bufSize)
1876     {
1877         int requiredSize = outputPitch * height;
1878         if (requiredSize > *bufSize)
1879         {
1880             return gl::error(GL_INVALID_OPERATION);
1881         }
1882     }
1883 
1884     mRenderer->readPixels(framebuffer, x, y, width, height, format, type, outputPitch, getPackReverseRowOrder(), getPackAlignment(), pixels);
1885 }
1886 
clear(GLbitfield mask)1887 void Context::clear(GLbitfield mask)
1888 {
1889     Framebuffer *framebufferObject = getDrawFramebuffer();
1890 
1891     if (!framebufferObject || framebufferObject->completeness() != GL_FRAMEBUFFER_COMPLETE)
1892     {
1893         return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION);
1894     }
1895 
1896     DWORD flags = 0;
1897     GLbitfield finalMask = 0;
1898 
1899     if (mask & GL_COLOR_BUFFER_BIT)
1900     {
1901         mask &= ~GL_COLOR_BUFFER_BIT;
1902 
1903         if (framebufferObject->hasEnabledColorAttachment())
1904         {
1905             finalMask |= GL_COLOR_BUFFER_BIT;
1906         }
1907     }
1908 
1909     if (mask & GL_DEPTH_BUFFER_BIT)
1910     {
1911         mask &= ~GL_DEPTH_BUFFER_BIT;
1912         if (mState.depthStencil.depthMask && framebufferObject->getDepthbufferType() != GL_NONE)
1913         {
1914             finalMask |= GL_DEPTH_BUFFER_BIT;
1915         }
1916     }
1917 
1918     if (mask & GL_STENCIL_BUFFER_BIT)
1919     {
1920         mask &= ~GL_STENCIL_BUFFER_BIT;
1921         if (framebufferObject->getStencilbufferType() != GL_NONE)
1922         {
1923             rx::RenderTarget *depthStencil = framebufferObject->getStencilbuffer()->getDepthStencil();
1924             if (!depthStencil)
1925             {
1926                 ERR("Depth stencil pointer unexpectedly null.");
1927                 return;
1928             }
1929 
1930             if (GetStencilSize(depthStencil->getActualFormat()) > 0)
1931             {
1932                 finalMask |= GL_STENCIL_BUFFER_BIT;
1933             }
1934         }
1935     }
1936 
1937     if (mask != 0)
1938     {
1939         return gl::error(GL_INVALID_VALUE);
1940     }
1941 
1942     if (!applyRenderTarget(GL_TRIANGLES, true))   // Clips the clear to the scissor rectangle but not the viewport
1943     {
1944         return;
1945     }
1946 
1947     ClearParameters clearParams;
1948     clearParams.mask = finalMask;
1949     clearParams.colorClearValue = mState.colorClearValue;
1950     clearParams.colorMaskRed = mState.blend.colorMaskRed;
1951     clearParams.colorMaskGreen = mState.blend.colorMaskGreen;
1952     clearParams.colorMaskBlue = mState.blend.colorMaskBlue;
1953     clearParams.colorMaskAlpha = mState.blend.colorMaskAlpha;
1954     clearParams.depthClearValue = mState.depthClearValue;
1955     clearParams.stencilClearValue = mState.stencilClearValue;
1956     clearParams.stencilWriteMask = mState.depthStencil.stencilWritemask;
1957 
1958     mRenderer->clear(clearParams, framebufferObject);
1959 }
1960 
drawArrays(GLenum mode,GLint first,GLsizei count,GLsizei instances)1961 void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances)
1962 {
1963     if (!mState.currentProgram)
1964     {
1965         return gl::error(GL_INVALID_OPERATION);
1966     }
1967 
1968     if (!mRenderer->applyPrimitiveType(mode, count))
1969     {
1970         return;
1971     }
1972 
1973     if (!applyRenderTarget(mode, false))
1974     {
1975         return;
1976     }
1977 
1978     applyState(mode);
1979 
1980     ProgramBinary *programBinary = getCurrentProgramBinary();
1981 
1982     GLenum err = mRenderer->applyVertexBuffer(programBinary, mState.vertexAttribute, first, count, instances);
1983     if (err != GL_NO_ERROR)
1984     {
1985         return gl::error(err);
1986     }
1987 
1988     applyShaders();
1989     applyTextures();
1990 
1991     if (!programBinary->validateSamplers(NULL))
1992     {
1993         return gl::error(GL_INVALID_OPERATION);
1994     }
1995 
1996     if (!skipDraw(mode))
1997     {
1998         mRenderer->drawArrays(mode, count, instances);
1999     }
2000 }
2001 
drawElements(GLenum mode,GLsizei count,GLenum type,const GLvoid * indices,GLsizei instances)2002 void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instances)
2003 {
2004     if (!mState.currentProgram)
2005     {
2006         return gl::error(GL_INVALID_OPERATION);
2007     }
2008 
2009     if (!indices && !mState.elementArrayBuffer)
2010     {
2011         return gl::error(GL_INVALID_OPERATION);
2012     }
2013 
2014     if (!mRenderer->applyPrimitiveType(mode, count))
2015     {
2016         return;
2017     }
2018 
2019     if (!applyRenderTarget(mode, false))
2020     {
2021         return;
2022     }
2023 
2024     applyState(mode);
2025 
2026     rx::TranslatedIndexData indexInfo;
2027     GLenum err = mRenderer->applyIndexBuffer(indices, mState.elementArrayBuffer.get(), count, mode, type, &indexInfo);
2028     if (err != GL_NO_ERROR)
2029     {
2030         return gl::error(err);
2031     }
2032 
2033     ProgramBinary *programBinary = getCurrentProgramBinary();
2034 
2035     GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
2036     err = mRenderer->applyVertexBuffer(programBinary, mState.vertexAttribute, indexInfo.minIndex, vertexCount, instances);
2037     if (err != GL_NO_ERROR)
2038     {
2039         return gl::error(err);
2040     }
2041 
2042     applyShaders();
2043     applyTextures();
2044 
2045     if (!programBinary->validateSamplers(NULL))
2046     {
2047         return gl::error(GL_INVALID_OPERATION);
2048     }
2049 
2050     if (!skipDraw(mode))
2051     {
2052         mRenderer->drawElements(mode, count, type, indices, mState.elementArrayBuffer.get(), indexInfo, instances);
2053     }
2054 }
2055 
2056 // Implements glFlush when block is false, glFinish when block is true
sync(bool block)2057 void Context::sync(bool block)
2058 {
2059     mRenderer->sync(block);
2060 }
2061 
recordInvalidEnum()2062 void Context::recordInvalidEnum()
2063 {
2064     mInvalidEnum = true;
2065 }
2066 
recordInvalidValue()2067 void Context::recordInvalidValue()
2068 {
2069     mInvalidValue = true;
2070 }
2071 
recordInvalidOperation()2072 void Context::recordInvalidOperation()
2073 {
2074     mInvalidOperation = true;
2075 }
2076 
recordOutOfMemory()2077 void Context::recordOutOfMemory()
2078 {
2079     mOutOfMemory = true;
2080 }
2081 
recordInvalidFramebufferOperation()2082 void Context::recordInvalidFramebufferOperation()
2083 {
2084     mInvalidFramebufferOperation = true;
2085 }
2086 
2087 // Get one of the recorded errors and clear its flag, if any.
2088 // [OpenGL ES 2.0.24] section 2.5 page 13.
getError()2089 GLenum Context::getError()
2090 {
2091     if (mInvalidEnum)
2092     {
2093         mInvalidEnum = false;
2094 
2095         return GL_INVALID_ENUM;
2096     }
2097 
2098     if (mInvalidValue)
2099     {
2100         mInvalidValue = false;
2101 
2102         return GL_INVALID_VALUE;
2103     }
2104 
2105     if (mInvalidOperation)
2106     {
2107         mInvalidOperation = false;
2108 
2109         return GL_INVALID_OPERATION;
2110     }
2111 
2112     if (mOutOfMemory)
2113     {
2114         mOutOfMemory = false;
2115 
2116         return GL_OUT_OF_MEMORY;
2117     }
2118 
2119     if (mInvalidFramebufferOperation)
2120     {
2121         mInvalidFramebufferOperation = false;
2122 
2123         return GL_INVALID_FRAMEBUFFER_OPERATION;
2124     }
2125 
2126     return GL_NO_ERROR;
2127 }
2128 
getResetStatus()2129 GLenum Context::getResetStatus()
2130 {
2131     if (mResetStatus == GL_NO_ERROR && !mContextLost)
2132     {
2133         // mResetStatus will be set by the markContextLost callback
2134         // in the case a notification is sent
2135         mRenderer->testDeviceLost(true);
2136     }
2137 
2138     GLenum status = mResetStatus;
2139 
2140     if (mResetStatus != GL_NO_ERROR)
2141     {
2142         ASSERT(mContextLost);
2143 
2144         if (mRenderer->testDeviceResettable())
2145         {
2146             mResetStatus = GL_NO_ERROR;
2147         }
2148     }
2149 
2150     return status;
2151 }
2152 
isResetNotificationEnabled()2153 bool Context::isResetNotificationEnabled()
2154 {
2155     return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2156 }
2157 
getMajorShaderModel() const2158 int Context::getMajorShaderModel() const
2159 {
2160     return mMajorShaderModel;
2161 }
2162 
getMaximumPointSize() const2163 float Context::getMaximumPointSize() const
2164 {
2165     return mMaximumPointSize;
2166 }
2167 
getMaximumCombinedTextureImageUnits() const2168 unsigned int Context::getMaximumCombinedTextureImageUnits() const
2169 {
2170     return mRenderer->getMaxCombinedTextureImageUnits();
2171 }
2172 
getMaxSupportedSamples() const2173 int Context::getMaxSupportedSamples() const
2174 {
2175     return mRenderer->getMaxSupportedSamples();
2176 }
2177 
getMaximumRenderTargets() const2178 unsigned int Context::getMaximumRenderTargets() const
2179 {
2180     return mRenderer->getMaxRenderTargets();
2181 }
2182 
supportsEventQueries() const2183 bool Context::supportsEventQueries() const
2184 {
2185     return mSupportsEventQueries;
2186 }
2187 
supportsOcclusionQueries() const2188 bool Context::supportsOcclusionQueries() const
2189 {
2190     return mSupportsOcclusionQueries;
2191 }
2192 
supportsBGRATextures() const2193 bool Context::supportsBGRATextures() const
2194 {
2195     return mSupportsBGRATextures;
2196 }
2197 
supportsDXT1Textures() const2198 bool Context::supportsDXT1Textures() const
2199 {
2200     return mSupportsDXT1Textures;
2201 }
2202 
supportsDXT3Textures() const2203 bool Context::supportsDXT3Textures() const
2204 {
2205     return mSupportsDXT3Textures;
2206 }
2207 
supportsDXT5Textures() const2208 bool Context::supportsDXT5Textures() const
2209 {
2210     return mSupportsDXT5Textures;
2211 }
2212 
supportsFloat32Textures() const2213 bool Context::supportsFloat32Textures() const
2214 {
2215     return mSupportsFloat32Textures;
2216 }
2217 
supportsFloat32LinearFilter() const2218 bool Context::supportsFloat32LinearFilter() const
2219 {
2220     return mSupportsFloat32LinearFilter;
2221 }
2222 
supportsFloat32RenderableTextures() const2223 bool Context::supportsFloat32RenderableTextures() const
2224 {
2225     return mSupportsFloat32RenderableTextures;
2226 }
2227 
supportsFloat16Textures() const2228 bool Context::supportsFloat16Textures() const
2229 {
2230     return mSupportsFloat16Textures;
2231 }
2232 
supportsFloat16LinearFilter() const2233 bool Context::supportsFloat16LinearFilter() const
2234 {
2235     return mSupportsFloat16LinearFilter;
2236 }
2237 
supportsFloat16RenderableTextures() const2238 bool Context::supportsFloat16RenderableTextures() const
2239 {
2240     return mSupportsFloat16RenderableTextures;
2241 }
2242 
getMaximumRenderbufferDimension() const2243 int Context::getMaximumRenderbufferDimension() const
2244 {
2245     return mMaxRenderbufferDimension;
2246 }
2247 
getMaximumTextureDimension() const2248 int Context::getMaximumTextureDimension() const
2249 {
2250     return mMaxTextureDimension;
2251 }
2252 
getMaximumCubeTextureDimension() const2253 int Context::getMaximumCubeTextureDimension() const
2254 {
2255     return mMaxCubeTextureDimension;
2256 }
2257 
getMaximumTextureLevel() const2258 int Context::getMaximumTextureLevel() const
2259 {
2260     return mMaxTextureLevel;
2261 }
2262 
supportsLuminanceTextures() const2263 bool Context::supportsLuminanceTextures() const
2264 {
2265     return mSupportsLuminanceTextures;
2266 }
2267 
supportsLuminanceAlphaTextures() const2268 bool Context::supportsLuminanceAlphaTextures() const
2269 {
2270     return mSupportsLuminanceAlphaTextures;
2271 }
2272 
supportsDepthTextures() const2273 bool Context::supportsDepthTextures() const
2274 {
2275     return mSupportsDepthTextures;
2276 }
2277 
supports32bitIndices() const2278 bool Context::supports32bitIndices() const
2279 {
2280     return mSupports32bitIndices;
2281 }
2282 
supportsNonPower2Texture() const2283 bool Context::supportsNonPower2Texture() const
2284 {
2285     return mSupportsNonPower2Texture;
2286 }
2287 
supportsInstancing() const2288 bool Context::supportsInstancing() const
2289 {
2290     return mSupportsInstancing;
2291 }
2292 
supportsTextureFilterAnisotropy() const2293 bool Context::supportsTextureFilterAnisotropy() const
2294 {
2295     return mSupportsTextureFilterAnisotropy;
2296 }
2297 
getTextureMaxAnisotropy() const2298 float Context::getTextureMaxAnisotropy() const
2299 {
2300     return mMaxTextureAnisotropy;
2301 }
2302 
getCurrentReadFormatType(GLenum * format,GLenum * type)2303 bool Context::getCurrentReadFormatType(GLenum *format, GLenum *type)
2304 {
2305     Framebuffer *framebuffer = getReadFramebuffer();
2306     if (!framebuffer || framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
2307     {
2308         return gl::error(GL_INVALID_OPERATION, false);
2309     }
2310 
2311     Renderbuffer *renderbuffer = framebuffer->getReadColorbuffer();
2312     if (!renderbuffer)
2313     {
2314         return gl::error(GL_INVALID_OPERATION, false);
2315     }
2316 
2317     *format = gl::ExtractFormat(renderbuffer->getActualFormat());
2318     *type = gl::ExtractType(renderbuffer->getActualFormat());
2319 
2320     return true;
2321 }
2322 
detachBuffer(GLuint buffer)2323 void Context::detachBuffer(GLuint buffer)
2324 {
2325     // [OpenGL ES 2.0.24] section 2.9 page 22:
2326     // If a buffer object is deleted while it is bound, all bindings to that object in the current context
2327     // (i.e. in the thread that called Delete-Buffers) are reset to zero.
2328 
2329     if (mState.arrayBuffer.id() == buffer)
2330     {
2331         mState.arrayBuffer.set(NULL);
2332     }
2333 
2334     if (mState.elementArrayBuffer.id() == buffer)
2335     {
2336         mState.elementArrayBuffer.set(NULL);
2337     }
2338 
2339     for (int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
2340     {
2341         if (mState.vertexAttribute[attribute].mBoundBuffer.id() == buffer)
2342         {
2343             mState.vertexAttribute[attribute].mBoundBuffer.set(NULL);
2344         }
2345     }
2346 }
2347 
detachTexture(GLuint texture)2348 void Context::detachTexture(GLuint texture)
2349 {
2350     // [OpenGL ES 2.0.24] section 3.8 page 84:
2351     // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
2352     // rebound to texture object zero
2353 
2354     for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
2355     {
2356         for (int sampler = 0; sampler < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
2357         {
2358             if (mState.samplerTexture[type][sampler].id() == texture)
2359             {
2360                 mState.samplerTexture[type][sampler].set(NULL);
2361             }
2362         }
2363     }
2364 
2365     // [OpenGL ES 2.0.24] section 4.4 page 112:
2366     // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
2367     // as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this
2368     // image was attached in the currently bound framebuffer.
2369 
2370     Framebuffer *readFramebuffer = getReadFramebuffer();
2371     Framebuffer *drawFramebuffer = getDrawFramebuffer();
2372 
2373     if (readFramebuffer)
2374     {
2375         readFramebuffer->detachTexture(texture);
2376     }
2377 
2378     if (drawFramebuffer && drawFramebuffer != readFramebuffer)
2379     {
2380         drawFramebuffer->detachTexture(texture);
2381     }
2382 }
2383 
detachFramebuffer(GLuint framebuffer)2384 void Context::detachFramebuffer(GLuint framebuffer)
2385 {
2386     // [OpenGL ES 2.0.24] section 4.4 page 107:
2387     // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2388     // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2389 
2390     if (mState.readFramebuffer == framebuffer)
2391     {
2392         bindReadFramebuffer(0);
2393     }
2394 
2395     if (mState.drawFramebuffer == framebuffer)
2396     {
2397         bindDrawFramebuffer(0);
2398     }
2399 }
2400 
detachRenderbuffer(GLuint renderbuffer)2401 void Context::detachRenderbuffer(GLuint renderbuffer)
2402 {
2403     // [OpenGL ES 2.0.24] section 4.4 page 109:
2404     // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
2405     // had been executed with the target RENDERBUFFER and name of zero.
2406 
2407     if (mState.renderbuffer.id() == renderbuffer)
2408     {
2409         bindRenderbuffer(0);
2410     }
2411 
2412     // [OpenGL ES 2.0.24] section 4.4 page 111:
2413     // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
2414     // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
2415     // point to which this image was attached in the currently bound framebuffer.
2416 
2417     Framebuffer *readFramebuffer = getReadFramebuffer();
2418     Framebuffer *drawFramebuffer = getDrawFramebuffer();
2419 
2420     if (readFramebuffer)
2421     {
2422         readFramebuffer->detachRenderbuffer(renderbuffer);
2423     }
2424 
2425     if (drawFramebuffer && drawFramebuffer != readFramebuffer)
2426     {
2427         drawFramebuffer->detachRenderbuffer(renderbuffer);
2428     }
2429 }
2430 
getIncompleteTexture(TextureType type)2431 Texture *Context::getIncompleteTexture(TextureType type)
2432 {
2433     Texture *t = mIncompleteTextures[type].get();
2434 
2435     if (t == NULL)
2436     {
2437         static const GLubyte color[] = { 0, 0, 0, 255 };
2438 
2439         switch (type)
2440         {
2441           default:
2442             UNREACHABLE();
2443             // default falls through to TEXTURE_2D
2444 
2445           case TEXTURE_2D:
2446             {
2447                 Texture2D *incomplete2d = new Texture2D(mRenderer, Texture::INCOMPLETE_TEXTURE_ID);
2448                 incomplete2d->setImage(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
2449                 t = incomplete2d;
2450             }
2451             break;
2452 
2453           case TEXTURE_CUBE:
2454             {
2455               TextureCubeMap *incompleteCube = new TextureCubeMap(mRenderer, Texture::INCOMPLETE_TEXTURE_ID);
2456 
2457               incompleteCube->setImagePosX(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
2458               incompleteCube->setImageNegX(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
2459               incompleteCube->setImagePosY(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
2460               incompleteCube->setImageNegY(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
2461               incompleteCube->setImagePosZ(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
2462               incompleteCube->setImageNegZ(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
2463 
2464               t = incompleteCube;
2465             }
2466             break;
2467         }
2468 
2469         mIncompleteTextures[type].set(t);
2470     }
2471 
2472     return t;
2473 }
2474 
skipDraw(GLenum drawMode)2475 bool Context::skipDraw(GLenum drawMode)
2476 {
2477     if (drawMode == GL_POINTS)
2478     {
2479         // ProgramBinary assumes non-point rendering if gl_PointSize isn't written,
2480         // which affects varying interpolation. Since the value of gl_PointSize is
2481         // undefined when not written, just skip drawing to avoid unexpected results.
2482         if (!getCurrentProgramBinary()->usesPointSize())
2483         {
2484             // This is stictly speaking not an error, but developers should be
2485             // notified of risking undefined behavior.
2486             ERR("Point rendering without writing to gl_PointSize.");
2487 
2488             return true;
2489         }
2490     }
2491     else if (IsTriangleMode(drawMode))
2492     {
2493         if (mState.rasterizer.cullFace && mState.rasterizer.cullMode == GL_FRONT_AND_BACK)
2494         {
2495             return true;
2496         }
2497     }
2498 
2499     return false;
2500 }
2501 
setVertexAttrib(GLuint index,const GLfloat * values)2502 void Context::setVertexAttrib(GLuint index, const GLfloat *values)
2503 {
2504     ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
2505 
2506     mState.vertexAttribute[index].mCurrentValue[0] = values[0];
2507     mState.vertexAttribute[index].mCurrentValue[1] = values[1];
2508     mState.vertexAttribute[index].mCurrentValue[2] = values[2];
2509     mState.vertexAttribute[index].mCurrentValue[3] = values[3];
2510 }
2511 
setVertexAttribDivisor(GLuint index,GLuint divisor)2512 void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2513 {
2514     ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
2515 
2516     mState.vertexAttribute[index].mDivisor = divisor;
2517 }
2518 
2519 // keep list sorted in following order
2520 // OES extensions
2521 // EXT extensions
2522 // Vendor extensions
initExtensionString()2523 void Context::initExtensionString()
2524 {
2525     std::string extensionString = "";
2526 
2527     // OES extensions
2528     if (supports32bitIndices())
2529     {
2530         extensionString += "GL_OES_element_index_uint ";
2531     }
2532 
2533     extensionString += "GL_OES_packed_depth_stencil ";
2534     extensionString += "GL_OES_get_program_binary ";
2535     extensionString += "GL_OES_rgb8_rgba8 ";
2536     if (mRenderer->getDerivativeInstructionSupport())
2537     {
2538         extensionString += "GL_OES_standard_derivatives ";
2539     }
2540 
2541     if (supportsFloat16Textures())
2542     {
2543         extensionString += "GL_OES_texture_half_float ";
2544     }
2545     if (supportsFloat16LinearFilter())
2546     {
2547         extensionString += "GL_OES_texture_half_float_linear ";
2548     }
2549     if (supportsFloat32Textures())
2550     {
2551         extensionString += "GL_OES_texture_float ";
2552     }
2553     if (supportsFloat32LinearFilter())
2554     {
2555         extensionString += "GL_OES_texture_float_linear ";
2556     }
2557 
2558     if (supportsNonPower2Texture())
2559     {
2560         extensionString += "GL_OES_texture_npot ";
2561     }
2562 
2563     // Multi-vendor (EXT) extensions
2564     if (supportsOcclusionQueries())
2565     {
2566         extensionString += "GL_EXT_occlusion_query_boolean ";
2567     }
2568 
2569     extensionString += "GL_EXT_read_format_bgra ";
2570     extensionString += "GL_EXT_robustness ";
2571 
2572     if (supportsDXT1Textures())
2573     {
2574         extensionString += "GL_EXT_texture_compression_dxt1 ";
2575     }
2576 
2577     if (supportsTextureFilterAnisotropy())
2578     {
2579         extensionString += "GL_EXT_texture_filter_anisotropic ";
2580     }
2581 
2582     if (supportsBGRATextures())
2583     {
2584         extensionString += "GL_EXT_texture_format_BGRA8888 ";
2585     }
2586 
2587     if (mRenderer->getMaxRenderTargets() > 1)
2588     {
2589         extensionString += "GL_EXT_draw_buffers ";
2590     }
2591 
2592     extensionString += "GL_EXT_texture_storage ";
2593     extensionString += "GL_EXT_frag_depth ";
2594 
2595     // ANGLE-specific extensions
2596     if (supportsDepthTextures())
2597     {
2598         extensionString += "GL_ANGLE_depth_texture ";
2599     }
2600 
2601     extensionString += "GL_ANGLE_framebuffer_blit ";
2602     if (getMaxSupportedSamples() != 0)
2603     {
2604         extensionString += "GL_ANGLE_framebuffer_multisample ";
2605     }
2606 
2607     if (supportsInstancing())
2608     {
2609         extensionString += "GL_ANGLE_instanced_arrays ";
2610     }
2611 
2612     extensionString += "GL_ANGLE_pack_reverse_row_order ";
2613 
2614     if (supportsDXT3Textures())
2615     {
2616         extensionString += "GL_ANGLE_texture_compression_dxt3 ";
2617     }
2618     if (supportsDXT5Textures())
2619     {
2620         extensionString += "GL_ANGLE_texture_compression_dxt5 ";
2621     }
2622 
2623     extensionString += "GL_ANGLE_texture_usage ";
2624     extensionString += "GL_ANGLE_translated_shader_source ";
2625 
2626     // Other vendor-specific extensions
2627     if (supportsEventQueries())
2628     {
2629         extensionString += "GL_NV_fence ";
2630     }
2631 
2632     std::string::size_type end = extensionString.find_last_not_of(' ');
2633     if (end != std::string::npos)
2634     {
2635         extensionString.resize(end+1);
2636     }
2637 
2638     mExtensionString = makeStaticString(extensionString);
2639 }
2640 
getExtensionString() const2641 const char *Context::getExtensionString() const
2642 {
2643     return mExtensionString;
2644 }
2645 
initRendererString()2646 void Context::initRendererString()
2647 {
2648     std::ostringstream rendererString;
2649     rendererString << "ANGLE (";
2650     rendererString << mRenderer->getRendererDescription();
2651     rendererString << ")";
2652 
2653     mRendererString = makeStaticString(rendererString.str());
2654 }
2655 
getRendererString() const2656 const char *Context::getRendererString() const
2657 {
2658     return mRendererString;
2659 }
2660 
getBoundFramebufferTextureSerials()2661 Context::FramebufferTextureSerialSet Context::getBoundFramebufferTextureSerials()
2662 {
2663     FramebufferTextureSerialSet set;
2664 
2665     Framebuffer *drawFramebuffer = getDrawFramebuffer();
2666     for (unsigned int i = 0; i < IMPLEMENTATION_MAX_DRAW_BUFFERS; i++)
2667     {
2668         Renderbuffer *renderBuffer = drawFramebuffer->getColorbuffer(i);
2669         if (renderBuffer && renderBuffer->getTextureSerial() != 0)
2670         {
2671             set.insert(renderBuffer->getTextureSerial());
2672         }
2673     }
2674 
2675     Renderbuffer *depthStencilBuffer = drawFramebuffer->getDepthOrStencilbuffer();
2676     if (depthStencilBuffer && depthStencilBuffer->getTextureSerial() != 0)
2677     {
2678         set.insert(depthStencilBuffer->getTextureSerial());
2679     }
2680 
2681     return set;
2682 }
2683 
blitFramebuffer(GLint srcX0,GLint srcY0,GLint srcX1,GLint srcY1,GLint dstX0,GLint dstY0,GLint dstX1,GLint dstY1,GLbitfield mask)2684 void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
2685                               GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
2686                               GLbitfield mask)
2687 {
2688     Framebuffer *readFramebuffer = getReadFramebuffer();
2689     Framebuffer *drawFramebuffer = getDrawFramebuffer();
2690 
2691     if (!readFramebuffer || readFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE ||
2692         !drawFramebuffer || drawFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
2693     {
2694         return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION);
2695     }
2696 
2697     if (drawFramebuffer->getSamples() != 0)
2698     {
2699         return gl::error(GL_INVALID_OPERATION);
2700     }
2701 
2702     Renderbuffer *readColorBuffer = readFramebuffer->getReadColorbuffer();
2703     Renderbuffer *drawColorBuffer = drawFramebuffer->getFirstColorbuffer();
2704 
2705     if (drawColorBuffer == NULL)
2706     {
2707         ERR("Draw buffers formats don't match, which is not supported in this implementation of BlitFramebufferANGLE");
2708         return gl::error(GL_INVALID_OPERATION);
2709     }
2710 
2711     int readBufferWidth = readColorBuffer->getWidth();
2712     int readBufferHeight = readColorBuffer->getHeight();
2713     int drawBufferWidth = drawColorBuffer->getWidth();
2714     int drawBufferHeight = drawColorBuffer->getHeight();
2715 
2716     Rectangle sourceRect;
2717     Rectangle destRect;
2718 
2719     if (srcX0 < srcX1)
2720     {
2721         sourceRect.x = srcX0;
2722         destRect.x = dstX0;
2723         sourceRect.width = srcX1 - srcX0;
2724         destRect.width = dstX1 - dstX0;
2725     }
2726     else
2727     {
2728         sourceRect.x = srcX1;
2729         destRect.x = dstX1;
2730         sourceRect.width = srcX0 - srcX1;
2731         destRect.width = dstX0 - dstX1;
2732     }
2733 
2734     if (srcY0 < srcY1)
2735     {
2736         sourceRect.height = srcY1 - srcY0;
2737         destRect.height = dstY1 - dstY0;
2738         sourceRect.y = srcY0;
2739         destRect.y = dstY0;
2740     }
2741     else
2742     {
2743         sourceRect.height = srcY0 - srcY1;
2744         destRect.height = dstY0 - srcY1;
2745         sourceRect.y = srcY1;
2746         destRect.y = dstY1;
2747     }
2748 
2749     Rectangle sourceScissoredRect = sourceRect;
2750     Rectangle destScissoredRect = destRect;
2751 
2752     if (mState.scissorTest)
2753     {
2754         // Only write to parts of the destination framebuffer which pass the scissor test.
2755         if (destRect.x < mState.scissor.x)
2756         {
2757             int xDiff = mState.scissor.x - destRect.x;
2758             destScissoredRect.x = mState.scissor.x;
2759             destScissoredRect.width -= xDiff;
2760             sourceScissoredRect.x += xDiff;
2761             sourceScissoredRect.width -= xDiff;
2762 
2763         }
2764 
2765         if (destRect.x + destRect.width > mState.scissor.x + mState.scissor.width)
2766         {
2767             int xDiff = (destRect.x + destRect.width) - (mState.scissor.x + mState.scissor.width);
2768             destScissoredRect.width -= xDiff;
2769             sourceScissoredRect.width -= xDiff;
2770         }
2771 
2772         if (destRect.y < mState.scissor.y)
2773         {
2774             int yDiff = mState.scissor.y - destRect.y;
2775             destScissoredRect.y = mState.scissor.y;
2776             destScissoredRect.height -= yDiff;
2777             sourceScissoredRect.y += yDiff;
2778             sourceScissoredRect.height -= yDiff;
2779         }
2780 
2781         if (destRect.y + destRect.height > mState.scissor.y + mState.scissor.height)
2782         {
2783             int yDiff = (destRect.y + destRect.height) - (mState.scissor.y + mState.scissor.height);
2784             destScissoredRect.height  -= yDiff;
2785             sourceScissoredRect.height -= yDiff;
2786         }
2787     }
2788 
2789     bool blitRenderTarget = false;
2790     bool blitDepthStencil = false;
2791 
2792     Rectangle sourceTrimmedRect = sourceScissoredRect;
2793     Rectangle destTrimmedRect = destScissoredRect;
2794 
2795     // The source & destination rectangles also may need to be trimmed if they fall out of the bounds of
2796     // the actual draw and read surfaces.
2797     if (sourceTrimmedRect.x < 0)
2798     {
2799         int xDiff = 0 - sourceTrimmedRect.x;
2800         sourceTrimmedRect.x = 0;
2801         sourceTrimmedRect.width -= xDiff;
2802         destTrimmedRect.x += xDiff;
2803         destTrimmedRect.width -= xDiff;
2804     }
2805 
2806     if (sourceTrimmedRect.x + sourceTrimmedRect.width > readBufferWidth)
2807     {
2808         int xDiff = (sourceTrimmedRect.x + sourceTrimmedRect.width) - readBufferWidth;
2809         sourceTrimmedRect.width -= xDiff;
2810         destTrimmedRect.width -= xDiff;
2811     }
2812 
2813     if (sourceTrimmedRect.y < 0)
2814     {
2815         int yDiff = 0 - sourceTrimmedRect.y;
2816         sourceTrimmedRect.y = 0;
2817         sourceTrimmedRect.height -= yDiff;
2818         destTrimmedRect.y += yDiff;
2819         destTrimmedRect.height -= yDiff;
2820     }
2821 
2822     if (sourceTrimmedRect.y + sourceTrimmedRect.height > readBufferHeight)
2823     {
2824         int yDiff = (sourceTrimmedRect.y + sourceTrimmedRect.height) - readBufferHeight;
2825         sourceTrimmedRect.height -= yDiff;
2826         destTrimmedRect.height -= yDiff;
2827     }
2828 
2829     if (destTrimmedRect.x < 0)
2830     {
2831         int xDiff = 0 - destTrimmedRect.x;
2832         destTrimmedRect.x = 0;
2833         destTrimmedRect.width -= xDiff;
2834         sourceTrimmedRect.x += xDiff;
2835         sourceTrimmedRect.width -= xDiff;
2836     }
2837 
2838     if (destTrimmedRect.x + destTrimmedRect.width > drawBufferWidth)
2839     {
2840         int xDiff = (destTrimmedRect.x + destTrimmedRect.width) - drawBufferWidth;
2841         destTrimmedRect.width -= xDiff;
2842         sourceTrimmedRect.width -= xDiff;
2843     }
2844 
2845     if (destTrimmedRect.y < 0)
2846     {
2847         int yDiff = 0 - destTrimmedRect.y;
2848         destTrimmedRect.y = 0;
2849         destTrimmedRect.height -= yDiff;
2850         sourceTrimmedRect.y += yDiff;
2851         sourceTrimmedRect.height -= yDiff;
2852     }
2853 
2854     if (destTrimmedRect.y + destTrimmedRect.height > drawBufferHeight)
2855     {
2856         int yDiff = (destTrimmedRect.y + destTrimmedRect.height) - drawBufferHeight;
2857         destTrimmedRect.height -= yDiff;
2858         sourceTrimmedRect.height -= yDiff;
2859     }
2860 
2861     bool partialBufferCopy = false;
2862     if (sourceTrimmedRect.height < readBufferHeight ||
2863         sourceTrimmedRect.width < readBufferWidth ||
2864         destTrimmedRect.height < drawBufferHeight ||
2865         destTrimmedRect.width < drawBufferWidth ||
2866         sourceTrimmedRect.y != 0 || destTrimmedRect.y != 0 || sourceTrimmedRect.x != 0 || destTrimmedRect.x != 0)
2867     {
2868         partialBufferCopy = true;
2869     }
2870 
2871     if (mask & GL_COLOR_BUFFER_BIT)
2872     {
2873         const GLenum readColorbufferType = readFramebuffer->getReadColorbufferType();
2874         const bool validReadType = (readColorbufferType == GL_TEXTURE_2D) || (readColorbufferType == GL_RENDERBUFFER);
2875         bool validDrawType = true;
2876         bool validDrawFormat = true;
2877 
2878         for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
2879         {
2880             if (drawFramebuffer->isEnabledColorAttachment(colorAttachment))
2881             {
2882                 if (drawFramebuffer->getColorbufferType(colorAttachment) != GL_TEXTURE_2D &&
2883                     drawFramebuffer->getColorbufferType(colorAttachment) != GL_RENDERBUFFER)
2884                 {
2885                     validDrawType = false;
2886                 }
2887 
2888                 if (drawFramebuffer->getColorbuffer(colorAttachment)->getActualFormat() != readColorBuffer->getActualFormat())
2889                 {
2890                     validDrawFormat = false;
2891                 }
2892             }
2893         }
2894 
2895         if (!validReadType || !validDrawType || !validDrawFormat)
2896         {
2897             ERR("Color buffer format conversion in BlitFramebufferANGLE not supported by this implementation");
2898             return gl::error(GL_INVALID_OPERATION);
2899         }
2900 
2901         if (partialBufferCopy && readFramebuffer->getSamples() != 0)
2902         {
2903             return gl::error(GL_INVALID_OPERATION);
2904         }
2905 
2906         blitRenderTarget = true;
2907 
2908     }
2909 
2910     if (mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
2911     {
2912         Renderbuffer *readDSBuffer = NULL;
2913         Renderbuffer *drawDSBuffer = NULL;
2914 
2915         // We support OES_packed_depth_stencil, and do not support a separately attached depth and stencil buffer, so if we have
2916         // both a depth and stencil buffer, it will be the same buffer.
2917 
2918         if (mask & GL_DEPTH_BUFFER_BIT)
2919         {
2920             if (readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())
2921             {
2922                 if (readFramebuffer->getDepthbufferType() != drawFramebuffer->getDepthbufferType() ||
2923                     readFramebuffer->getDepthbuffer()->getActualFormat() != drawFramebuffer->getDepthbuffer()->getActualFormat())
2924                 {
2925                     return gl::error(GL_INVALID_OPERATION);
2926                 }
2927 
2928                 blitDepthStencil = true;
2929                 readDSBuffer = readFramebuffer->getDepthbuffer();
2930                 drawDSBuffer = drawFramebuffer->getDepthbuffer();
2931             }
2932         }
2933 
2934         if (mask & GL_STENCIL_BUFFER_BIT)
2935         {
2936             if (readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())
2937             {
2938                 if (readFramebuffer->getStencilbufferType() != drawFramebuffer->getStencilbufferType() ||
2939                     readFramebuffer->getStencilbuffer()->getActualFormat() != drawFramebuffer->getStencilbuffer()->getActualFormat())
2940                 {
2941                     return gl::error(GL_INVALID_OPERATION);
2942                 }
2943 
2944                 blitDepthStencil = true;
2945                 readDSBuffer = readFramebuffer->getStencilbuffer();
2946                 drawDSBuffer = drawFramebuffer->getStencilbuffer();
2947             }
2948         }
2949 
2950         if (partialBufferCopy)
2951         {
2952             ERR("Only whole-buffer depth and stencil blits are supported by this implementation.");
2953             return gl::error(GL_INVALID_OPERATION); // only whole-buffer copies are permitted
2954         }
2955 
2956         if ((drawDSBuffer && drawDSBuffer->getSamples() != 0) ||
2957             (readDSBuffer && readDSBuffer->getSamples() != 0))
2958         {
2959             return gl::error(GL_INVALID_OPERATION);
2960         }
2961     }
2962 
2963     if (blitRenderTarget || blitDepthStencil)
2964     {
2965         mRenderer->blitRect(readFramebuffer, sourceTrimmedRect, drawFramebuffer, destTrimmedRect, blitRenderTarget, blitDepthStencil);
2966     }
2967 }
2968 
2969 }
2970 
2971 extern "C"
2972 {
glCreateContext(const gl::Context * shareContext,rx::Renderer * renderer,bool notifyResets,bool robustAccess)2973 gl::Context *glCreateContext(const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess)
2974 {
2975     return new gl::Context(shareContext, renderer, notifyResets, robustAccess);
2976 }
2977 
glDestroyContext(gl::Context * context)2978 void glDestroyContext(gl::Context *context)
2979 {
2980     delete context;
2981 
2982     if (context == gl::getContext())
2983     {
2984         gl::makeCurrent(NULL, NULL, NULL);
2985     }
2986 }
2987 
glMakeCurrent(gl::Context * context,egl::Display * display,egl::Surface * surface)2988 void glMakeCurrent(gl::Context *context, egl::Display *display, egl::Surface *surface)
2989 {
2990     gl::makeCurrent(context, display, surface);
2991 }
2992 
glGetCurrentContext()2993 gl::Context *glGetCurrentContext()
2994 {
2995     return gl::getContext();
2996 }
2997 
2998 }
2999