blob: eb38902fe2d0837cb4ce89440b9e5145a330a35a [file] [log] [blame]
shannon.woods@transgaming.combdf2d802013-02-28 23:16:20 +00001#include "precompiled.h"
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002//
daniel@transgaming.comb37cd2d2013-01-11 04:10:31 +00003// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00004// 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
apatrick@chromium.org144f2802012-07-12 01:42:34 +000013#include "libGLESv2/main.h"
shannonwoods@chromium.orga2ecfcc2013-05-30 00:11:59 +000014#include "common/utilities.h"
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +000015#include "libGLESv2/formatutils.h"
apatrick@chromium.org144f2802012-07-12 01:42:34 +000016#include "libGLESv2/Buffer.h"
17#include "libGLESv2/Fence.h"
daniel@transgaming.com29ab9522012-08-27 16:25:37 +000018#include "libGLESv2/Framebuffer.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000019#include "libGLESv2/Renderbuffer.h"
apatrick@chromium.org144f2802012-07-12 01:42:34 +000020#include "libGLESv2/Program.h"
21#include "libGLESv2/ProgramBinary.h"
22#include "libGLESv2/Query.h"
apatrick@chromium.org144f2802012-07-12 01:42:34 +000023#include "libGLESv2/Texture.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000024#include "libGLESv2/ResourceManager.h"
shannon.woods@transgaming.com938ac8d2013-02-28 23:03:06 +000025#include "libGLESv2/renderer/IndexDataManager.h"
shannon.woods@transgaming.comd2811d62013-02-28 23:11:19 +000026#include "libGLESv2/renderer/RenderTarget.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000027#include "libGLESv2/renderer/Renderer.h"
Jamie Madill57a89722013-07-02 11:57:03 -040028#include "libGLESv2/VertexArray.h"
Jamie Madilldc356042013-07-19 16:36:57 -040029#include "libGLESv2/Sampler.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000030
31#include "libEGL/Surface.h"
apatrick@chromium.org144f2802012-07-12 01:42:34 +000032
33#undef near
34#undef far
35
36namespace gl
37{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +000038static const char* makeStaticString(const std::string& str)
39{
40 static std::set<std::string> strings;
41 std::set<std::string>::iterator it = strings.find(str);
42 if (it != strings.end())
43 return it->c_str();
44
45 return strings.insert(str).first->c_str();
46}
47
shannon.woods%transgaming.com@gtempaccount.comdaea4b42013-04-13 03:28:54 +000048Context::Context(int clientVersion, const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess) : mRenderer(renderer)
apatrick@chromium.org144f2802012-07-12 01:42:34 +000049{
50 ASSERT(robustAccess == false); // Unimplemented
51
Jamie Madill33dc8432013-07-26 11:55:05 -040052 mFenceNVHandleAllocator.setBaseHandle(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +000053
54 setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
55
shannon.woods%transgaming.com@gtempaccount.comdaea4b42013-04-13 03:28:54 +000056 mClientVersion = clientVersion;
57
apatrick@chromium.org144f2802012-07-12 01:42:34 +000058 mState.depthClearValue = 1.0f;
59 mState.stencilClearValue = 0;
60
daniel@transgaming.comf39967e2012-11-28 19:35:56 +000061 mState.rasterizer.cullFace = false;
62 mState.rasterizer.cullMode = GL_BACK;
63 mState.rasterizer.frontFace = GL_CCW;
64 mState.rasterizer.polygonOffsetFill = false;
65 mState.rasterizer.polygonOffsetFactor = 0.0f;
66 mState.rasterizer.polygonOffsetUnits = 0.0f;
shannon.woods@transgaming.comdd2524c2013-02-28 23:04:33 +000067 mState.rasterizer.pointDrawMode = false;
Nicolas Capensfd396552013-06-18 21:41:30 -040068 mState.rasterizer.multiSample = false;
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +000069 mState.scissorTest = false;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +000070 mState.scissor.x = 0;
71 mState.scissor.y = 0;
72 mState.scissor.width = 0;
73 mState.scissor.height = 0;
74
75 mState.blend.blend = false;
76 mState.blend.sourceBlendRGB = GL_ONE;
77 mState.blend.sourceBlendAlpha = GL_ONE;
78 mState.blend.destBlendRGB = GL_ZERO;
79 mState.blend.destBlendAlpha = GL_ZERO;
80 mState.blend.blendEquationRGB = GL_FUNC_ADD;
81 mState.blend.blendEquationAlpha = GL_FUNC_ADD;
82 mState.blend.sampleAlphaToCoverage = false;
83 mState.blend.dither = true;
84
apatrick@chromium.org144f2802012-07-12 01:42:34 +000085 mState.blendColor.red = 0;
86 mState.blendColor.green = 0;
87 mState.blendColor.blue = 0;
88 mState.blendColor.alpha = 0;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +000089
90 mState.depthStencil.depthTest = false;
91 mState.depthStencil.depthFunc = GL_LESS;
92 mState.depthStencil.depthMask = true;
93 mState.depthStencil.stencilTest = false;
94 mState.depthStencil.stencilFunc = GL_ALWAYS;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +000095 mState.depthStencil.stencilMask = -1;
96 mState.depthStencil.stencilWritemask = -1;
97 mState.depthStencil.stencilBackFunc = GL_ALWAYS;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +000098 mState.depthStencil.stencilBackMask = - 1;
99 mState.depthStencil.stencilBackWritemask = -1;
100 mState.depthStencil.stencilFail = GL_KEEP;
101 mState.depthStencil.stencilPassDepthFail = GL_KEEP;
102 mState.depthStencil.stencilPassDepthPass = GL_KEEP;
103 mState.depthStencil.stencilBackFail = GL_KEEP;
104 mState.depthStencil.stencilBackPassDepthFail = GL_KEEP;
105 mState.depthStencil.stencilBackPassDepthPass = GL_KEEP;
106
daniel@transgaming.com08c331d2012-11-28 19:38:39 +0000107 mState.stencilRef = 0;
108 mState.stencilBackRef = 0;
109
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000110 mState.sampleCoverage = false;
111 mState.sampleCoverageValue = 1.0f;
112 mState.sampleCoverageInvert = false;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000113 mState.generateMipmapHint = GL_DONT_CARE;
114 mState.fragmentShaderDerivativeHint = GL_DONT_CARE;
115
116 mState.lineWidth = 1.0f;
117
daniel@transgaming.com3884e2c2012-11-28 19:41:00 +0000118 mState.viewport.x = 0;
119 mState.viewport.y = 0;
120 mState.viewport.width = 0;
121 mState.viewport.height = 0;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000122 mState.zNear = 0.0f;
123 mState.zFar = 1.0f;
124
daniel@transgaming.comf39967e2012-11-28 19:35:56 +0000125 mState.blend.colorMaskRed = true;
126 mState.blend.colorMaskGreen = true;
127 mState.blend.colorMaskBlue = true;
128 mState.blend.colorMaskAlpha = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000129
Geoff Lang7dca1862013-07-30 16:30:46 -0400130 const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f };
131 for (int attribIndex = 0; attribIndex < MAX_VERTEX_ATTRIBS; attribIndex++)
132 {
133 mState.vertexAttribCurrentValues[attribIndex].setFloatValues(defaultFloatValues);
134 }
135
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000136 if (shareContext != NULL)
137 {
138 mResourceManager = shareContext->mResourceManager;
139 mResourceManager->addRef();
140 }
141 else
142 {
daniel@transgaming.com370482e2012-11-28 19:32:13 +0000143 mResourceManager = new ResourceManager(mRenderer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000144 }
145
146 // [OpenGL ES 2.0.24] section 3.7 page 83:
147 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
148 // and cube map texture state vectors respectively associated with them.
149 // In order that access to these initial textures not be lost, they are treated as texture
150 // objects all of whose names are 0.
151
daniel@transgaming.com370482e2012-11-28 19:32:13 +0000152 mTexture2DZero.set(new Texture2D(mRenderer, 0));
153 mTextureCubeMapZero.set(new TextureCubeMap(mRenderer, 0));
shannon.woods%transgaming.com@gtempaccount.comc416e1c2013-04-13 03:45:05 +0000154 mTexture3DZero.set(new Texture3D(mRenderer, 0));
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000155 mTexture2DArrayZero.set(new Texture2DArray(mRenderer, 0));
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000156
Jamie Madilldc356042013-07-19 16:36:57 -0400157 for (unsigned int textureUnit = 0; textureUnit < ArraySize(mState.samplers); textureUnit++)
158 {
159 mState.samplers[textureUnit] = 0;
160 }
161
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000162 mState.activeSampler = 0;
Jamie Madill57a89722013-07-02 11:57:03 -0400163 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000164 bindArrayBuffer(0);
165 bindElementArrayBuffer(0);
166 bindTextureCubeMap(0);
167 bindTexture2D(0);
168 bindReadFramebuffer(0);
169 bindDrawFramebuffer(0);
170 bindRenderbuffer(0);
171
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000172 bindGenericUniformBuffer(0);
173 for (int i = 0; i < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS; i++)
174 {
175 bindIndexedUniformBuffer(0, i, 0, -1);
176 }
177
178 bindGenericTransformFeedbackBuffer(0);
179 for (int i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
180 {
181 bindIndexedTransformFeedbackBuffer(0, i, 0, -1);
182 }
183
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000184 bindCopyReadBuffer(0);
185 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000186 bindPixelPackBuffer(0);
187 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000188
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000189 mState.currentProgram = 0;
daniel@transgaming.com989c1c82012-07-24 18:40:38 +0000190 mCurrentProgramBinary.set(NULL);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000191
192 mState.packAlignment = 4;
193 mState.unpackAlignment = 4;
194 mState.packReverseRowOrder = false;
195
shannonwoods@chromium.org302df742013-05-30 00:05:54 +0000196 mCombinedExtensionsString = NULL;
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000197 mRendererString = NULL;
198
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000199 mInvalidEnum = false;
200 mInvalidValue = false;
201 mInvalidOperation = false;
202 mOutOfMemory = false;
203 mInvalidFramebufferOperation = false;
204
205 mHasBeenCurrent = false;
206 mContextLost = false;
207 mResetStatus = GL_NO_ERROR;
208 mResetStrategy = (notifyResets ? GL_LOSE_CONTEXT_ON_RESET_EXT : GL_NO_RESET_NOTIFICATION_EXT);
209 mRobustAccess = robustAccess;
210
shannon.woods@transgaming.combec04bf2013-01-25 21:53:52 +0000211 mSupportsBGRATextures = false;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000212 mSupportsDXT1Textures = false;
213 mSupportsDXT3Textures = false;
214 mSupportsDXT5Textures = false;
215 mSupportsEventQueries = false;
216 mSupportsOcclusionQueries = false;
217 mNumCompressedTextureFormats = 0;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000218}
219
220Context::~Context()
221{
222 if (mState.currentProgram != 0)
223 {
224 Program *programObject = mResourceManager->getProgram(mState.currentProgram);
225 if (programObject)
226 {
227 programObject->release();
228 }
229 mState.currentProgram = 0;
230 }
daniel@transgaming.com989c1c82012-07-24 18:40:38 +0000231 mCurrentProgramBinary.set(NULL);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000232
233 while (!mFramebufferMap.empty())
234 {
235 deleteFramebuffer(mFramebufferMap.begin()->first);
236 }
237
Jamie Madill33dc8432013-07-26 11:55:05 -0400238 while (!mFenceNVMap.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000239 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400240 deleteFenceNV(mFenceNVMap.begin()->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000241 }
242
243 while (!mQueryMap.empty())
244 {
245 deleteQuery(mQueryMap.begin()->first);
246 }
247
Jamie Madill57a89722013-07-02 11:57:03 -0400248 while (!mVertexArrayMap.empty())
249 {
250 deleteVertexArray(mVertexArrayMap.begin()->first);
251 }
252
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000253 for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
254 {
shannon.woods@transgaming.com233fe952013-01-25 21:51:57 +0000255 for (int sampler = 0; sampler < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000256 {
257 mState.samplerTexture[type][sampler].set(NULL);
258 }
259 }
260
261 for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
262 {
263 mIncompleteTextures[type].set(NULL);
264 }
265
Jamie Madilla857c362013-07-02 11:57:02 -0400266 const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f };
267 for (int attribIndex = 0; attribIndex < MAX_VERTEX_ATTRIBS; attribIndex++)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000268 {
Jamie Madilla857c362013-07-02 11:57:02 -0400269 mState.vertexAttribCurrentValues[attribIndex].setFloatValues(defaultFloatValues);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000270 }
271
272 for (int i = 0; i < QUERY_TYPE_COUNT; i++)
273 {
274 mState.activeQuery[i].set(NULL);
275 }
276
277 mState.arrayBuffer.set(NULL);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000278 mState.renderbuffer.set(NULL);
279
280 mTexture2DZero.set(NULL);
281 mTextureCubeMapZero.set(NULL);
shannon.woods%transgaming.com@gtempaccount.comc416e1c2013-04-13 03:45:05 +0000282 mTexture3DZero.set(NULL);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000283 mTexture2DArrayZero.set(NULL);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000284
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000285 mState.genericUniformBuffer.set(NULL);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000286 for (int i = 0; i < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS; i++)
287 {
288 mState.uniformBuffers[i].set(NULL);
289 }
290
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000291 mState.genericTransformFeedbackBuffer.set(NULL);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000292 for (int i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
293 {
294 mState.transformFeedbackBuffers[i].set(NULL);
295 }
296
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000297 mState.copyReadBuffer.set(NULL);
298 mState.copyWriteBuffer.set(NULL);
299
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000300 mState.pixelPackBuffer.set(NULL);
301 mState.pixelUnpackBuffer.set(NULL);
302
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000303 mResourceManager->release();
304}
305
daniel@transgaming.comad629872012-11-28 19:32:06 +0000306void Context::makeCurrent(egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000307{
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000308 if (!mHasBeenCurrent)
309 {
daniel@transgaming.com9549bea2012-11-28 20:57:23 +0000310 mMajorShaderModel = mRenderer->getMajorShaderModel();
daniel@transgaming.com5f4c1362012-10-31 18:29:00 +0000311 mMaximumPointSize = mRenderer->getMaxPointSize();
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000312 mSupportsVertexTexture = mRenderer->getVertexTextureSupport();
313 mSupportsNonPower2Texture = mRenderer->getNonPower2TextureSupport();
314 mSupportsInstancing = mRenderer->getInstancingSupport();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000315
shannon.woods@transgaming.com8ce2f8f2013-02-28 23:07:10 +0000316 mMaxViewportDimension = mRenderer->getMaxViewportDimension();
shannon.woods%transgaming.com@gtempaccount.comc1fdf6b2013-04-13 03:44:41 +0000317 mMax2DTextureDimension = std::min(std::min(mRenderer->getMaxTextureWidth(), mRenderer->getMaxTextureHeight()),
318 (int)gl::IMPLEMENTATION_MAX_2D_TEXTURE_SIZE);
319 mMaxCubeTextureDimension = std::min(mMax2DTextureDimension, (int)gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE);
320 mMax3DTextureDimension = std::min(std::min(mMax2DTextureDimension, mRenderer->getMaxTextureDepth()),
321 (int)gl::IMPLEMENTATION_MAX_3D_TEXTURE_SIZE);
shannon.woods%transgaming.com@gtempaccount.coma98a8112013-04-13 03:45:57 +0000322 mMax2DArrayTextureLayers = mRenderer->getMaxTextureArrayLayers();
shannon.woods%transgaming.com@gtempaccount.comc1fdf6b2013-04-13 03:44:41 +0000323 mMaxRenderbufferDimension = mMax2DTextureDimension;
324 mMaxTextureLevel = log2(mMax2DTextureDimension) + 1;
daniel@transgaming.comba0570e2012-10-31 18:07:39 +0000325 mMaxTextureAnisotropy = mRenderer->getTextureMaxAnisotropy();
shannon.woods%transgaming.com@gtempaccount.coma98a8112013-04-13 03:45:57 +0000326 TRACE("Max2DTextureDimension=%d, MaxCubeTextureDimension=%d, Max3DTextureDimension=%d, Max2DArrayTextureLayers = %d, "
327 "MaxRenderbufferDimension=%d, MaxTextureLevel=%d, MaxTextureAnisotropy=%f",
328 mMax2DTextureDimension, mMaxCubeTextureDimension, mMax3DTextureDimension, mMax2DArrayTextureLayers,
shannon.woods%transgaming.com@gtempaccount.comc1fdf6b2013-04-13 03:44:41 +0000329 mMaxRenderbufferDimension, mMaxTextureLevel, mMaxTextureAnisotropy);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000330
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000331 mSupportsEventQueries = mRenderer->getEventQuerySupport();
332 mSupportsOcclusionQueries = mRenderer->getOcclusionQuerySupport();
shannon.woods@transgaming.combec04bf2013-01-25 21:53:52 +0000333 mSupportsBGRATextures = mRenderer->getBGRATextureSupport();
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000334 mSupportsDXT1Textures = mRenderer->getDXT1TextureSupport();
335 mSupportsDXT3Textures = mRenderer->getDXT3TextureSupport();
336 mSupportsDXT5Textures = mRenderer->getDXT5TextureSupport();
shannonwoods@chromium.org89200d92013-05-30 00:07:50 +0000337 mSupportsFloat32Textures = mRenderer->getFloat32TextureSupport();
338 mSupportsFloat32LinearFilter = mRenderer->getFloat32TextureFilteringSupport();
339 mSupportsFloat32RenderableTextures = mRenderer->getFloat32TextureRenderingSupport();
340 mSupportsFloat16Textures = mRenderer->getFloat16TextureSupport();
341 mSupportsFloat16LinearFilter = mRenderer->getFloat16TextureFilteringSupport();
342 mSupportsFloat16RenderableTextures = mRenderer->getFloat16TextureRenderingSupport();
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000343 mSupportsLuminanceTextures = mRenderer->getLuminanceTextureSupport();
344 mSupportsLuminanceAlphaTextures = mRenderer->getLuminanceAlphaTextureSupport();
345 mSupportsDepthTextures = mRenderer->getDepthTextureSupport();
daniel@transgaming.comba0570e2012-10-31 18:07:39 +0000346 mSupportsTextureFilterAnisotropy = mRenderer->getTextureFilterAnisotropySupport();
daniel@transgaming.com5f4c1362012-10-31 18:29:00 +0000347 mSupports32bitIndices = mRenderer->get32BitIndexSupport();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000348
349 mNumCompressedTextureFormats = 0;
350 if (supportsDXT1Textures())
351 {
352 mNumCompressedTextureFormats += 2;
353 }
354 if (supportsDXT3Textures())
355 {
356 mNumCompressedTextureFormats += 1;
357 }
358 if (supportsDXT5Textures())
359 {
360 mNumCompressedTextureFormats += 1;
361 }
362
363 initExtensionString();
364 initRendererString();
365
daniel@transgaming.com3884e2c2012-11-28 19:41:00 +0000366 mState.viewport.x = 0;
367 mState.viewport.y = 0;
368 mState.viewport.width = surface->getWidth();
369 mState.viewport.height = surface->getHeight();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000370
daniel@transgaming.comf39967e2012-11-28 19:35:56 +0000371 mState.scissor.x = 0;
372 mState.scissor.y = 0;
373 mState.scissor.width = surface->getWidth();
374 mState.scissor.height = surface->getHeight();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000375
376 mHasBeenCurrent = true;
377 }
378
daniel@transgaming.com024786d2012-10-31 18:42:55 +0000379 // Wrap the existing swapchain resources into GL objects and assign them to the '0' names
daniel@transgaming.com76d3e6e2012-10-31 19:55:33 +0000380 rx::SwapChain *swapchain = surface->getSwapChain();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000381
daniel@transgaming.com70062c92012-11-28 19:32:30 +0000382 Colorbuffer *colorbufferZero = new Colorbuffer(mRenderer, swapchain);
383 DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(mRenderer, swapchain);
daniel@transgaming.com16418b12012-11-28 19:32:22 +0000384 Framebuffer *framebufferZero = new DefaultFramebuffer(mRenderer, colorbufferZero, depthStencilbufferZero);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000385
386 setFramebufferZero(framebufferZero);
shannon.woods%transgaming.com@gtempaccount.com785f1962013-04-13 03:34:45 +0000387
388 // Store the current client version in the renderer
389 mRenderer->setCurrentClientVersion(mClientVersion);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000390}
391
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +0000392// NOTE: this function should not assume that this context is current!
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000393void Context::markContextLost()
394{
395 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
396 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
397 mContextLost = true;
398}
399
400bool Context::isContextLost()
401{
402 return mContextLost;
403}
404
405void Context::setClearColor(float red, float green, float blue, float alpha)
406{
407 mState.colorClearValue.red = red;
408 mState.colorClearValue.green = green;
409 mState.colorClearValue.blue = blue;
410 mState.colorClearValue.alpha = alpha;
411}
412
413void Context::setClearDepth(float depth)
414{
415 mState.depthClearValue = depth;
416}
417
418void Context::setClearStencil(int stencil)
419{
420 mState.stencilClearValue = stencil;
421}
422
423void Context::setCullFace(bool enabled)
424{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000425 mState.rasterizer.cullFace = enabled;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000426}
427
428bool Context::isCullFaceEnabled() const
429{
daniel@transgaming.comf39967e2012-11-28 19:35:56 +0000430 return mState.rasterizer.cullFace;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000431}
432
433void Context::setCullMode(GLenum mode)
434{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000435 mState.rasterizer.cullMode = mode;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000436}
437
438void Context::setFrontFace(GLenum front)
439{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000440 mState.rasterizer.frontFace = front;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000441}
442
443void Context::setDepthTest(bool enabled)
444{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000445 mState.depthStencil.depthTest = enabled;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000446}
447
448bool Context::isDepthTestEnabled() const
449{
daniel@transgaming.comf39967e2012-11-28 19:35:56 +0000450 return mState.depthStencil.depthTest;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000451}
452
453void Context::setDepthFunc(GLenum depthFunc)
454{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000455 mState.depthStencil.depthFunc = depthFunc;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000456}
457
458void Context::setDepthRange(float zNear, float zFar)
459{
460 mState.zNear = zNear;
461 mState.zFar = zFar;
462}
463
464void Context::setBlend(bool enabled)
465{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000466 mState.blend.blend = enabled;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000467}
468
469bool Context::isBlendEnabled() const
470{
daniel@transgaming.comf39967e2012-11-28 19:35:56 +0000471 return mState.blend.blend;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000472}
473
474void Context::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
475{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000476 mState.blend.sourceBlendRGB = sourceRGB;
477 mState.blend.destBlendRGB = destRGB;
478 mState.blend.sourceBlendAlpha = sourceAlpha;
479 mState.blend.destBlendAlpha = destAlpha;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000480}
481
482void Context::setBlendColor(float red, float green, float blue, float alpha)
483{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000484 mState.blendColor.red = red;
485 mState.blendColor.green = green;
486 mState.blendColor.blue = blue;
487 mState.blendColor.alpha = alpha;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000488}
489
490void Context::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
491{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000492 mState.blend.blendEquationRGB = rgbEquation;
493 mState.blend.blendEquationAlpha = alphaEquation;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000494}
495
496void Context::setStencilTest(bool enabled)
497{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000498 mState.depthStencil.stencilTest = enabled;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000499}
500
501bool Context::isStencilTestEnabled() const
502{
daniel@transgaming.comf39967e2012-11-28 19:35:56 +0000503 return mState.depthStencil.stencilTest;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000504}
505
506void Context::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
507{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000508 mState.depthStencil.stencilFunc = stencilFunc;
daniel@transgaming.com08c331d2012-11-28 19:38:39 +0000509 mState.stencilRef = (stencilRef > 0) ? stencilRef : 0;
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000510 mState.depthStencil.stencilMask = stencilMask;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000511}
512
513void Context::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
514{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000515 mState.depthStencil.stencilBackFunc = stencilBackFunc;
daniel@transgaming.com08c331d2012-11-28 19:38:39 +0000516 mState.stencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000517 mState.depthStencil.stencilBackMask = stencilBackMask;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000518}
519
520void Context::setStencilWritemask(GLuint stencilWritemask)
521{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000522 mState.depthStencil.stencilWritemask = stencilWritemask;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000523}
524
525void Context::setStencilBackWritemask(GLuint stencilBackWritemask)
526{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000527 mState.depthStencil.stencilBackWritemask = stencilBackWritemask;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000528}
529
530void Context::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
531{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000532 mState.depthStencil.stencilFail = stencilFail;
533 mState.depthStencil.stencilPassDepthFail = stencilPassDepthFail;
534 mState.depthStencil.stencilPassDepthPass = stencilPassDepthPass;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000535}
536
537void Context::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
538{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000539 mState.depthStencil.stencilBackFail = stencilBackFail;
540 mState.depthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
541 mState.depthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000542}
543
544void Context::setPolygonOffsetFill(bool enabled)
545{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000546 mState.rasterizer.polygonOffsetFill = enabled;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000547}
548
549bool Context::isPolygonOffsetFillEnabled() const
550{
daniel@transgaming.comf39967e2012-11-28 19:35:56 +0000551 return mState.rasterizer.polygonOffsetFill;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000552}
553
554void Context::setPolygonOffsetParams(GLfloat factor, GLfloat units)
555{
shannon.woods@transgaming.com31c4f232013-02-28 23:14:18 +0000556 // An application can pass NaN values here, so handle this gracefully
557 mState.rasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor;
558 mState.rasterizer.polygonOffsetUnits = units != units ? 0.0f : units;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000559}
560
561void Context::setSampleAlphaToCoverage(bool enabled)
562{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000563 mState.blend.sampleAlphaToCoverage = enabled;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000564}
565
566bool Context::isSampleAlphaToCoverageEnabled() const
567{
daniel@transgaming.comf39967e2012-11-28 19:35:56 +0000568 return mState.blend.sampleAlphaToCoverage;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000569}
570
571void Context::setSampleCoverage(bool enabled)
572{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000573 mState.sampleCoverage = enabled;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000574}
575
576bool Context::isSampleCoverageEnabled() const
577{
578 return mState.sampleCoverage;
579}
580
581void Context::setSampleCoverageParams(GLclampf value, bool invert)
582{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000583 mState.sampleCoverageValue = value;
584 mState.sampleCoverageInvert = invert;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000585}
586
587void Context::setScissorTest(bool enabled)
588{
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +0000589 mState.scissorTest = enabled;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000590}
591
592bool Context::isScissorTestEnabled() const
593{
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +0000594 return mState.scissorTest;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000595}
596
597void Context::setDither(bool enabled)
598{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000599 mState.blend.dither = enabled;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000600}
601
602bool Context::isDitherEnabled() const
603{
daniel@transgaming.comf39967e2012-11-28 19:35:56 +0000604 return mState.blend.dither;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000605}
606
607void Context::setLineWidth(GLfloat width)
608{
609 mState.lineWidth = width;
610}
611
612void Context::setGenerateMipmapHint(GLenum hint)
613{
614 mState.generateMipmapHint = hint;
615}
616
617void Context::setFragmentShaderDerivativeHint(GLenum hint)
618{
619 mState.fragmentShaderDerivativeHint = hint;
620 // TODO: Propagate the hint to shader translator so we can write
621 // ddx, ddx_coarse, or ddx_fine depending on the hint.
622 // Ignore for now. It is valid for implementations to ignore hint.
623}
624
625void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
626{
daniel@transgaming.com3884e2c2012-11-28 19:41:00 +0000627 mState.viewport.x = x;
628 mState.viewport.y = y;
629 mState.viewport.width = width;
630 mState.viewport.height = height;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000631}
632
633void Context::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
634{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000635 mState.scissor.x = x;
636 mState.scissor.y = y;
637 mState.scissor.width = width;
638 mState.scissor.height = height;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000639}
640
Geoff Langc8325162013-08-09 13:26:56 -0400641void Context::getScissorParams(GLint *x, GLint *y, GLsizei *width, GLsizei *height)
642{
643 *x = mState.scissor.x;
644 *y = mState.scissor.y;
645 *width = mState.scissor.width;
646 *height = mState.scissor.height;
647}
648
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000649void Context::setColorMask(bool red, bool green, bool blue, bool alpha)
650{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000651 mState.blend.colorMaskRed = red;
652 mState.blend.colorMaskGreen = green;
653 mState.blend.colorMaskBlue = blue;
654 mState.blend.colorMaskAlpha = alpha;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000655}
656
657void Context::setDepthMask(bool mask)
658{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000659 mState.depthStencil.depthMask = mask;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000660}
661
662void Context::setActiveSampler(unsigned int active)
663{
664 mState.activeSampler = active;
665}
666
667GLuint Context::getReadFramebufferHandle() const
668{
669 return mState.readFramebuffer;
670}
671
672GLuint Context::getDrawFramebufferHandle() const
673{
674 return mState.drawFramebuffer;
675}
676
677GLuint Context::getRenderbufferHandle() const
678{
679 return mState.renderbuffer.id();
680}
681
Jamie Madilld8db8662013-07-02 11:57:04 -0400682GLuint Context::getVertexArrayHandle() const
683{
684 return mState.vertexArray;
685}
686
Jamie Madilldc356042013-07-19 16:36:57 -0400687GLuint Context::getSamplerHandle(GLuint textureUnit) const
688{
689 ASSERT(textureUnit < ArraySize(mState.samplers));
690 return mState.samplers[textureUnit];
691}
692
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000693GLuint Context::getArrayBufferHandle() const
694{
695 return mState.arrayBuffer.id();
696}
697
698GLuint Context::getActiveQuery(GLenum target) const
699{
700 Query *queryObject = NULL;
701
702 switch (target)
703 {
704 case GL_ANY_SAMPLES_PASSED_EXT:
705 queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED].get();
706 break;
707 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
708 queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE].get();
709 break;
710 default:
711 ASSERT(false);
712 }
713
714 if (queryObject)
715 {
716 return queryObject->id();
717 }
718 else
719 {
720 return 0;
721 }
722}
723
724void Context::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
725{
Jamie Madill57a89722013-07-02 11:57:03 -0400726 getCurrentVertexArray()->enableAttribute(attribNum, enabled);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000727}
728
Jamie Madilla857c362013-07-02 11:57:02 -0400729const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000730{
Jamie Madill57a89722013-07-02 11:57:03 -0400731 return getCurrentVertexArray()->getVertexAttribute(attribNum);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000732}
733
Jamie Madilla857c362013-07-02 11:57:02 -0400734const VertexAttribCurrentValueData &Context::getVertexAttribCurrentValue(unsigned int attribNum) const
735{
736 ASSERT(attribNum < MAX_VERTEX_ATTRIBS);
737 return mState.vertexAttribCurrentValues[attribNum];
738}
739
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000740void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
shannon.woods%transgaming.com@gtempaccount.com8de4e6a2013-04-13 03:37:44 +0000741 bool pureInteger, GLsizei stride, const void *pointer)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000742{
Jamie Madill57a89722013-07-02 11:57:03 -0400743 getCurrentVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, pureInteger, stride, pointer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000744}
745
746const void *Context::getVertexAttribPointer(unsigned int attribNum) const
747{
Jamie Madill57a89722013-07-02 11:57:03 -0400748 return getCurrentVertexArray()->getVertexAttribute(attribNum).mPointer;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000749}
750
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000751void Context::setPackAlignment(GLint alignment)
752{
753 mState.packAlignment = alignment;
754}
755
756GLint Context::getPackAlignment() const
757{
758 return mState.packAlignment;
759}
760
761void Context::setUnpackAlignment(GLint alignment)
762{
763 mState.unpackAlignment = alignment;
764}
765
766GLint Context::getUnpackAlignment() const
767{
768 return mState.unpackAlignment;
769}
770
771void Context::setPackReverseRowOrder(bool reverseRowOrder)
772{
773 mState.packReverseRowOrder = reverseRowOrder;
774}
775
776bool Context::getPackReverseRowOrder() const
777{
778 return mState.packReverseRowOrder;
779}
780
781GLuint Context::createBuffer()
782{
783 return mResourceManager->createBuffer();
784}
785
786GLuint Context::createProgram()
787{
788 return mResourceManager->createProgram();
789}
790
791GLuint Context::createShader(GLenum type)
792{
793 return mResourceManager->createShader(type);
794}
795
796GLuint Context::createTexture()
797{
798 return mResourceManager->createTexture();
799}
800
801GLuint Context::createRenderbuffer()
802{
803 return mResourceManager->createRenderbuffer();
804}
805
Jamie Madillcd055f82013-07-26 11:55:15 -0400806GLsync Context::createFenceSync(GLenum condition)
807{
808 GLuint handle = mResourceManager->createFenceSync();
809
810 gl::FenceSync *fenceSync = mResourceManager->getFenceSync(handle);
811 ASSERT(fenceSync);
812
813 fenceSync->set(condition);
814
815 return reinterpret_cast<GLsync>(handle);
816}
817
Jamie Madill57a89722013-07-02 11:57:03 -0400818GLuint Context::createVertexArray()
819{
820 GLuint handle = mVertexArrayHandleAllocator.allocate();
821
Jamie Madilld1028542013-07-02 11:57:04 -0400822 // Although the spec states VAO state is not initialized until the object is bound,
823 // we create it immediately. The resulting behaviour is transparent to the application,
824 // since it's not currently possible to access the state until the object is bound.
Jamie Madill57a89722013-07-02 11:57:03 -0400825 mVertexArrayMap[handle] = new VertexArray(mRenderer, handle);
826
827 return handle;
828}
829
Jamie Madilldc356042013-07-19 16:36:57 -0400830GLuint Context::createSampler()
831{
832 return mResourceManager->createSampler();
833}
834
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000835// Returns an unused framebuffer name
836GLuint Context::createFramebuffer()
837{
838 GLuint handle = mFramebufferHandleAllocator.allocate();
839
840 mFramebufferMap[handle] = NULL;
841
842 return handle;
843}
844
Jamie Madill33dc8432013-07-26 11:55:05 -0400845GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000846{
Jamie Madill33dc8432013-07-26 11:55:05 -0400847 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000848
Jamie Madill33dc8432013-07-26 11:55:05 -0400849 mFenceNVMap[handle] = new FenceNV(mRenderer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000850
851 return handle;
852}
853
854// Returns an unused query name
855GLuint Context::createQuery()
856{
857 GLuint handle = mQueryHandleAllocator.allocate();
858
859 mQueryMap[handle] = NULL;
860
861 return handle;
862}
863
864void Context::deleteBuffer(GLuint buffer)
865{
866 if (mResourceManager->getBuffer(buffer))
867 {
868 detachBuffer(buffer);
869 }
870
871 mResourceManager->deleteBuffer(buffer);
872}
873
874void Context::deleteShader(GLuint shader)
875{
876 mResourceManager->deleteShader(shader);
877}
878
879void Context::deleteProgram(GLuint program)
880{
881 mResourceManager->deleteProgram(program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000882}
883
884void Context::deleteTexture(GLuint texture)
885{
886 if (mResourceManager->getTexture(texture))
887 {
888 detachTexture(texture);
889 }
890
891 mResourceManager->deleteTexture(texture);
892}
893
894void Context::deleteRenderbuffer(GLuint renderbuffer)
895{
896 if (mResourceManager->getRenderbuffer(renderbuffer))
897 {
898 detachRenderbuffer(renderbuffer);
899 }
900
901 mResourceManager->deleteRenderbuffer(renderbuffer);
902}
903
Jamie Madillcd055f82013-07-26 11:55:15 -0400904void Context::deleteFenceSync(GLsync fenceSync)
905{
906 // The spec specifies the underlying Fence object is not deleted until all current
907 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
908 // and since our API is currently designed for being called from a single thread, we can delete
909 // the fence immediately.
910 mResourceManager->deleteFenceSync(reinterpret_cast<GLuint>(fenceSync));
911}
912
Jamie Madill57a89722013-07-02 11:57:03 -0400913void Context::deleteVertexArray(GLuint vertexArray)
914{
915 auto vertexArrayObject = mVertexArrayMap.find(vertexArray);
916
917 if (vertexArrayObject != mVertexArrayMap.end())
918 {
919 detachVertexArray(vertexArray);
920
921 mVertexArrayHandleAllocator.release(vertexArrayObject->first);
922 delete vertexArrayObject->second;
923 mVertexArrayMap.erase(vertexArrayObject);
924 }
925}
926
Jamie Madilldc356042013-07-19 16:36:57 -0400927void Context::deleteSampler(GLuint sampler)
928{
929 if (mResourceManager->getSampler(sampler))
930 {
931 detachSampler(sampler);
932 }
933
934 mResourceManager->deleteSampler(sampler);
935}
936
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000937void Context::deleteFramebuffer(GLuint framebuffer)
938{
939 FramebufferMap::iterator framebufferObject = mFramebufferMap.find(framebuffer);
940
941 if (framebufferObject != mFramebufferMap.end())
942 {
943 detachFramebuffer(framebuffer);
944
945 mFramebufferHandleAllocator.release(framebufferObject->first);
946 delete framebufferObject->second;
947 mFramebufferMap.erase(framebufferObject);
948 }
949}
950
Jamie Madill33dc8432013-07-26 11:55:05 -0400951void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000952{
Jamie Madill33dc8432013-07-26 11:55:05 -0400953 FenceNVMap::iterator fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000954
Jamie Madill33dc8432013-07-26 11:55:05 -0400955 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000956 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400957 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000958 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400959 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000960 }
961}
962
963void Context::deleteQuery(GLuint query)
964{
965 QueryMap::iterator queryObject = mQueryMap.find(query);
966 if (queryObject != mQueryMap.end())
967 {
968 mQueryHandleAllocator.release(queryObject->first);
969 if (queryObject->second)
970 {
971 queryObject->second->release();
972 }
973 mQueryMap.erase(queryObject);
974 }
975}
976
977Buffer *Context::getBuffer(GLuint handle)
978{
979 return mResourceManager->getBuffer(handle);
980}
981
982Shader *Context::getShader(GLuint handle)
983{
984 return mResourceManager->getShader(handle);
985}
986
987Program *Context::getProgram(GLuint handle)
988{
989 return mResourceManager->getProgram(handle);
990}
991
992Texture *Context::getTexture(GLuint handle)
993{
994 return mResourceManager->getTexture(handle);
995}
996
997Renderbuffer *Context::getRenderbuffer(GLuint handle)
998{
999 return mResourceManager->getRenderbuffer(handle);
1000}
1001
Jamie Madillcd055f82013-07-26 11:55:15 -04001002FenceSync *Context::getFenceSync(GLsync handle) const
1003{
1004 return mResourceManager->getFenceSync(reinterpret_cast<GLuint>(handle));
1005}
1006
Jamie Madill57a89722013-07-02 11:57:03 -04001007VertexArray *Context::getVertexArray(GLuint handle) const
1008{
1009 auto vertexArray = mVertexArrayMap.find(handle);
1010
1011 if (vertexArray == mVertexArrayMap.end())
1012 {
1013 return NULL;
1014 }
1015 else
1016 {
1017 return vertexArray->second;
1018 }
1019}
1020
Jamie Madilldc356042013-07-19 16:36:57 -04001021Sampler *Context::getSampler(GLuint handle) const
1022{
1023 return mResourceManager->getSampler(handle);
1024}
1025
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001026Framebuffer *Context::getReadFramebuffer()
1027{
1028 return getFramebuffer(mState.readFramebuffer);
1029}
1030
1031Framebuffer *Context::getDrawFramebuffer()
1032{
1033 return mBoundDrawFramebuffer;
1034}
1035
Jamie Madill57a89722013-07-02 11:57:03 -04001036VertexArray *Context::getCurrentVertexArray() const
1037{
1038 VertexArray *vao = getVertexArray(mState.vertexArray);
1039 ASSERT(vao != NULL);
1040 return vao;
1041}
1042
Jamie Madilldc356042013-07-19 16:36:57 -04001043bool Context::isSampler(GLuint samplerName) const
1044{
1045 return mResourceManager->isSampler(samplerName);
1046}
1047
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001048void Context::bindArrayBuffer(unsigned int buffer)
1049{
1050 mResourceManager->checkBufferAllocation(buffer);
1051
1052 mState.arrayBuffer.set(getBuffer(buffer));
1053}
1054
1055void Context::bindElementArrayBuffer(unsigned int buffer)
1056{
1057 mResourceManager->checkBufferAllocation(buffer);
1058
Jamie Madill57a89722013-07-02 11:57:03 -04001059 getCurrentVertexArray()->setElementArrayBuffer(getBuffer(buffer));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001060}
1061
1062void Context::bindTexture2D(GLuint texture)
1063{
1064 mResourceManager->checkTextureAllocation(texture, TEXTURE_2D);
1065
1066 mState.samplerTexture[TEXTURE_2D][mState.activeSampler].set(getTexture(texture));
1067}
1068
1069void Context::bindTextureCubeMap(GLuint texture)
1070{
1071 mResourceManager->checkTextureAllocation(texture, TEXTURE_CUBE);
1072
1073 mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].set(getTexture(texture));
1074}
1075
shannon.woods%transgaming.com@gtempaccount.comc416e1c2013-04-13 03:45:05 +00001076void Context::bindTexture3D(GLuint texture)
1077{
1078 mResourceManager->checkTextureAllocation(texture, TEXTURE_3D);
1079
1080 mState.samplerTexture[TEXTURE_3D][mState.activeSampler].set(getTexture(texture));
1081}
1082
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +00001083void Context::bindTexture2DArray(GLuint texture)
1084{
1085 mResourceManager->checkTextureAllocation(texture, TEXTURE_2D_ARRAY);
1086
1087 mState.samplerTexture[TEXTURE_2D_ARRAY][mState.activeSampler].set(getTexture(texture));
1088}
1089
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001090void Context::bindReadFramebuffer(GLuint framebuffer)
1091{
1092 if (!getFramebuffer(framebuffer))
1093 {
daniel@transgaming.com16418b12012-11-28 19:32:22 +00001094 mFramebufferMap[framebuffer] = new Framebuffer(mRenderer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001095 }
1096
1097 mState.readFramebuffer = framebuffer;
1098}
1099
1100void Context::bindDrawFramebuffer(GLuint framebuffer)
1101{
1102 if (!getFramebuffer(framebuffer))
1103 {
daniel@transgaming.com16418b12012-11-28 19:32:22 +00001104 mFramebufferMap[framebuffer] = new Framebuffer(mRenderer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001105 }
1106
1107 mState.drawFramebuffer = framebuffer;
1108
1109 mBoundDrawFramebuffer = getFramebuffer(framebuffer);
1110}
1111
1112void Context::bindRenderbuffer(GLuint renderbuffer)
1113{
1114 mResourceManager->checkRenderbufferAllocation(renderbuffer);
1115
1116 mState.renderbuffer.set(getRenderbuffer(renderbuffer));
1117}
1118
Jamie Madill57a89722013-07-02 11:57:03 -04001119void Context::bindVertexArray(GLuint vertexArray)
1120{
1121 if (!getVertexArray(vertexArray))
1122 {
1123 mVertexArrayMap[vertexArray] = new VertexArray(mRenderer, vertexArray);
1124 }
1125
1126 mState.vertexArray = vertexArray;
1127}
1128
Jamie Madilldc356042013-07-19 16:36:57 -04001129void Context::bindSampler(GLuint textureUnit, GLuint sampler)
1130{
1131 ASSERT(textureUnit < ArraySize(mState.samplers));
1132 mResourceManager->checkSamplerAllocation(sampler);
1133
1134 mState.samplers[textureUnit] = sampler;
1135}
1136
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001137void Context::bindGenericUniformBuffer(GLuint buffer)
1138{
1139 mResourceManager->checkBufferAllocation(buffer);
1140
1141 mState.genericUniformBuffer.set(getBuffer(buffer));
1142}
1143
1144void Context::bindIndexedUniformBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001145{
1146 mResourceManager->checkBufferAllocation(buffer);
1147
1148 mState.uniformBuffers[index].set(getBuffer(buffer), offset, size);
1149}
1150
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001151void Context::bindGenericTransformFeedbackBuffer(GLuint buffer)
1152{
1153 mResourceManager->checkBufferAllocation(buffer);
1154
1155 mState.genericTransformFeedbackBuffer.set(getBuffer(buffer));
1156}
1157
1158void Context::bindIndexedTransformFeedbackBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001159{
1160 mResourceManager->checkBufferAllocation(buffer);
1161
1162 mState.transformFeedbackBuffers[index].set(getBuffer(buffer), offset, size);
1163}
1164
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001165void Context::bindCopyReadBuffer(GLuint buffer)
1166{
1167 mResourceManager->checkBufferAllocation(buffer);
1168
1169 mState.copyReadBuffer.set(getBuffer(buffer));
1170}
1171
1172void Context::bindCopyWriteBuffer(GLuint buffer)
1173{
1174 mResourceManager->checkBufferAllocation(buffer);
1175
1176 mState.copyWriteBuffer.set(getBuffer(buffer));
1177}
1178
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001179void Context::bindPixelPackBuffer(GLuint buffer)
1180{
1181 mResourceManager->checkBufferAllocation(buffer);
1182
1183 mState.pixelPackBuffer.set(getBuffer(buffer));
1184}
1185
1186void Context::bindPixelUnpackBuffer(GLuint buffer)
1187{
1188 mResourceManager->checkBufferAllocation(buffer);
1189
1190 mState.pixelUnpackBuffer.set(getBuffer(buffer));
1191}
1192
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001193void Context::useProgram(GLuint program)
1194{
1195 GLuint priorProgram = mState.currentProgram;
1196 mState.currentProgram = program; // Must switch before trying to delete, otherwise it only gets flagged.
1197
1198 if (priorProgram != program)
1199 {
1200 Program *newProgram = mResourceManager->getProgram(program);
1201 Program *oldProgram = mResourceManager->getProgram(priorProgram);
daniel@transgaming.com989c1c82012-07-24 18:40:38 +00001202 mCurrentProgramBinary.set(NULL);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001203
1204 if (newProgram)
1205 {
1206 newProgram->addRef();
daniel@transgaming.com989c1c82012-07-24 18:40:38 +00001207 mCurrentProgramBinary.set(newProgram->getProgramBinary());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001208 }
1209
1210 if (oldProgram)
1211 {
1212 oldProgram->release();
1213 }
1214 }
1215}
1216
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001217void Context::linkProgram(GLuint program)
1218{
1219 Program *programObject = mResourceManager->getProgram(program);
1220
daniel@transgaming.com12394cf2012-07-24 18:37:59 +00001221 bool linked = programObject->link();
1222
1223 // if the current program was relinked successfully we
1224 // need to install the new executables
1225 if (linked && program == mState.currentProgram)
1226 {
daniel@transgaming.com989c1c82012-07-24 18:40:38 +00001227 mCurrentProgramBinary.set(programObject->getProgramBinary());
daniel@transgaming.com12394cf2012-07-24 18:37:59 +00001228 }
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001229}
1230
1231void Context::setProgramBinary(GLuint program, const void *binary, GLint length)
1232{
1233 Program *programObject = mResourceManager->getProgram(program);
1234
daniel@transgaming.com12394cf2012-07-24 18:37:59 +00001235 bool loaded = programObject->setProgramBinary(binary, length);
1236
1237 // if the current program was reloaded successfully we
1238 // need to install the new executables
1239 if (loaded && program == mState.currentProgram)
1240 {
daniel@transgaming.com989c1c82012-07-24 18:40:38 +00001241 mCurrentProgramBinary.set(programObject->getProgramBinary());
daniel@transgaming.com12394cf2012-07-24 18:37:59 +00001242 }
1243
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001244}
1245
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001246void Context::beginQuery(GLenum target, GLuint query)
1247{
1248 // From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id>
1249 // of zero, if the active query object name for <target> is non-zero (for the
1250 // targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if
1251 // the active query for either target is non-zero), if <id> is the name of an
1252 // existing query object whose type does not match <target>, or if <id> is the
1253 // active query object name for any query type, the error INVALID_OPERATION is
1254 // generated.
1255
1256 // Ensure no other queries are active
1257 // NOTE: If other queries than occlusion are supported, we will need to check
1258 // separately that:
1259 // a) The query ID passed is not the current active query for any target/type
1260 // b) There are no active queries for the requested target (and in the case
1261 // of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
1262 // no query may be active for either if glBeginQuery targets either.
1263 for (int i = 0; i < QUERY_TYPE_COUNT; i++)
1264 {
1265 if (mState.activeQuery[i].get() != NULL)
1266 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +00001267 return gl::error(GL_INVALID_OPERATION);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001268 }
1269 }
1270
1271 QueryType qType;
1272 switch (target)
1273 {
1274 case GL_ANY_SAMPLES_PASSED_EXT:
1275 qType = QUERY_ANY_SAMPLES_PASSED;
1276 break;
1277 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
1278 qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE;
1279 break;
1280 default:
1281 ASSERT(false);
1282 return;
1283 }
1284
1285 Query *queryObject = getQuery(query, true, target);
1286
1287 // check that name was obtained with glGenQueries
1288 if (!queryObject)
1289 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +00001290 return gl::error(GL_INVALID_OPERATION);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001291 }
1292
1293 // check for type mismatch
1294 if (queryObject->getType() != target)
1295 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +00001296 return gl::error(GL_INVALID_OPERATION);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001297 }
1298
1299 // set query as active for specified target
1300 mState.activeQuery[qType].set(queryObject);
1301
1302 // begin query
1303 queryObject->begin();
1304}
1305
1306void Context::endQuery(GLenum target)
1307{
1308 QueryType qType;
1309
1310 switch (target)
1311 {
1312 case GL_ANY_SAMPLES_PASSED_EXT:
1313 qType = QUERY_ANY_SAMPLES_PASSED;
1314 break;
1315 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
1316 qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE;
1317 break;
1318 default:
1319 ASSERT(false);
1320 return;
1321 }
1322
1323 Query *queryObject = mState.activeQuery[qType].get();
1324
1325 if (queryObject == NULL)
1326 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +00001327 return gl::error(GL_INVALID_OPERATION);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001328 }
1329
1330 queryObject->end();
1331
1332 mState.activeQuery[qType].set(NULL);
1333}
1334
1335void Context::setFramebufferZero(Framebuffer *buffer)
1336{
1337 delete mFramebufferMap[0];
1338 mFramebufferMap[0] = buffer;
1339 if (mState.drawFramebuffer == 0)
1340 {
1341 mBoundDrawFramebuffer = buffer;
1342 }
1343}
1344
daniel@transgaming.com70062c92012-11-28 19:32:30 +00001345void Context::setRenderbufferStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001346{
Geoff Lang2e1dcd52013-05-29 10:34:08 -04001347 const bool color = gl::IsColorRenderingSupported(internalformat, this);
1348 const bool depth = gl::IsDepthRenderingSupported(internalformat, this);
1349 const bool stencil = gl::IsStencilRenderingSupported(internalformat, this);
1350
daniel@transgaming.com70062c92012-11-28 19:32:30 +00001351 RenderbufferStorage *renderbuffer = NULL;
Geoff Lang2e1dcd52013-05-29 10:34:08 -04001352
1353 if (color)
daniel@transgaming.com70062c92012-11-28 19:32:30 +00001354 {
daniel@transgaming.com70062c92012-11-28 19:32:30 +00001355 renderbuffer = new gl::Colorbuffer(mRenderer,width, height, internalformat, samples);
Geoff Lang2e1dcd52013-05-29 10:34:08 -04001356 }
1357 else if (depth && stencil)
1358 {
daniel@transgaming.com70062c92012-11-28 19:32:30 +00001359 renderbuffer = new gl::DepthStencilbuffer(mRenderer, width, height, samples);
Geoff Lang2e1dcd52013-05-29 10:34:08 -04001360 }
1361 else if (depth)
1362 {
1363 renderbuffer = new gl::Depthbuffer(mRenderer, width, height, samples);
1364 }
1365 else if (stencil)
1366 {
1367 renderbuffer = new gl::Stencilbuffer(mRenderer, width, height, samples);
1368 }
1369 else
1370 {
1371 UNREACHABLE();
1372 return;
daniel@transgaming.com70062c92012-11-28 19:32:30 +00001373 }
1374
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001375 Renderbuffer *renderbufferObject = mState.renderbuffer.get();
1376 renderbufferObject->setStorage(renderbuffer);
1377}
1378
1379Framebuffer *Context::getFramebuffer(unsigned int handle)
1380{
1381 FramebufferMap::iterator framebuffer = mFramebufferMap.find(handle);
1382
1383 if (framebuffer == mFramebufferMap.end())
1384 {
1385 return NULL;
1386 }
1387 else
1388 {
1389 return framebuffer->second;
1390 }
1391}
1392
Jamie Madill33dc8432013-07-26 11:55:05 -04001393FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001394{
Jamie Madill33dc8432013-07-26 11:55:05 -04001395 FenceNVMap::iterator fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001396
Jamie Madill33dc8432013-07-26 11:55:05 -04001397 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001398 {
1399 return NULL;
1400 }
1401 else
1402 {
1403 return fence->second;
1404 }
1405}
1406
1407Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1408{
1409 QueryMap::iterator query = mQueryMap.find(handle);
1410
1411 if (query == mQueryMap.end())
1412 {
1413 return NULL;
1414 }
1415 else
1416 {
1417 if (!query->second && create)
1418 {
shannon.woods@transgaming.comb32e1982013-02-28 23:02:59 +00001419 query->second = new Query(mRenderer, type, handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001420 query->second->addRef();
1421 }
1422 return query->second;
1423 }
1424}
1425
1426Buffer *Context::getArrayBuffer()
1427{
1428 return mState.arrayBuffer.get();
1429}
1430
1431Buffer *Context::getElementArrayBuffer()
1432{
Jamie Madill57a89722013-07-02 11:57:03 -04001433 return getCurrentVertexArray()->getElementArrayBuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001434}
1435
daniel@transgaming.com62a28462012-07-24 18:33:59 +00001436ProgramBinary *Context::getCurrentProgramBinary()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001437{
daniel@transgaming.com989c1c82012-07-24 18:40:38 +00001438 return mCurrentProgramBinary.get();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001439}
1440
1441Texture2D *Context::getTexture2D()
1442{
1443 return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D));
1444}
1445
1446TextureCubeMap *Context::getTextureCubeMap()
1447{
1448 return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, TEXTURE_CUBE));
1449}
1450
shannon.woods%transgaming.com@gtempaccount.comc416e1c2013-04-13 03:45:05 +00001451Texture3D *Context::getTexture3D()
1452{
1453 return static_cast<Texture3D*>(getSamplerTexture(mState.activeSampler, TEXTURE_3D));
1454}
1455
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +00001456Texture2DArray *Context::getTexture2DArray()
1457{
1458 return static_cast<Texture2DArray*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D_ARRAY));
1459}
1460
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001461Buffer *Context::getGenericUniformBuffer()
1462{
1463 return mState.genericUniformBuffer.get();
1464}
1465
1466Buffer *Context::getGenericTransformFeedbackBuffer()
1467{
1468 return mState.genericTransformFeedbackBuffer.get();
1469}
1470
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001471Buffer *Context::getCopyReadBuffer()
1472{
1473 return mState.copyReadBuffer.get();
1474}
1475
1476Buffer *Context::getCopyWriteBuffer()
1477{
1478 return mState.copyWriteBuffer.get();
1479}
1480
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001481Buffer *Context::getPixelPackBuffer()
1482{
1483 return mState.pixelPackBuffer.get();
1484}
1485
1486Buffer *Context::getPixelUnpackBuffer()
1487{
1488 return mState.pixelUnpackBuffer.get();
1489}
1490
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001491Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type)
1492{
1493 GLuint texid = mState.samplerTexture[type][sampler].id();
1494
1495 if (texid == 0) // Special case: 0 refers to different initial textures based on the target
1496 {
1497 switch (type)
1498 {
1499 default: UNREACHABLE();
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +00001500 case TEXTURE_2D: return mTexture2DZero.get();
1501 case TEXTURE_CUBE: return mTextureCubeMapZero.get();
1502 case TEXTURE_3D: return mTexture3DZero.get();
1503 case TEXTURE_2D_ARRAY: return mTexture2DArrayZero.get();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001504 }
1505 }
1506
1507 return mState.samplerTexture[type][sampler].get();
1508}
1509
1510bool Context::getBooleanv(GLenum pname, GLboolean *params)
1511{
1512 switch (pname)
1513 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001514 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
1515 case GL_SAMPLE_COVERAGE_INVERT: *params = mState.sampleCoverageInvert; break;
1516 case GL_DEPTH_WRITEMASK: *params = mState.depthStencil.depthMask; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001517 case GL_COLOR_WRITEMASK:
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001518 params[0] = mState.blend.colorMaskRed;
1519 params[1] = mState.blend.colorMaskGreen;
1520 params[2] = mState.blend.colorMaskBlue;
1521 params[3] = mState.blend.colorMaskAlpha;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001522 break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001523 case GL_CULL_FACE: *params = mState.rasterizer.cullFace; break;
1524 case GL_POLYGON_OFFSET_FILL: *params = mState.rasterizer.polygonOffsetFill; break;
1525 case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.blend.sampleAlphaToCoverage; break;
1526 case GL_SAMPLE_COVERAGE: *params = mState.sampleCoverage; break;
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +00001527 case GL_SCISSOR_TEST: *params = mState.scissorTest; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001528 case GL_STENCIL_TEST: *params = mState.depthStencil.stencilTest; break;
1529 case GL_DEPTH_TEST: *params = mState.depthStencil.depthTest; break;
1530 case GL_BLEND: *params = mState.blend.blend; break;
1531 case GL_DITHER: *params = mState.blend.dither; break;
1532 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
shannonwoods@chromium.orgabf14cc2013-05-30 00:20:58 +00001533 case GL_TRANSFORM_FEEDBACK_ACTIVE: *params = GL_FALSE; UNIMPLEMENTED(); break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001534 default:
1535 return false;
1536 }
1537
1538 return true;
1539}
1540
1541bool Context::getFloatv(GLenum pname, GLfloat *params)
1542{
1543 // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
1544 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1545 // GetIntegerv as its native query function. As it would require conversion in any
1546 // case, this should make no difference to the calling application.
1547 switch (pname)
1548 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001549 case GL_LINE_WIDTH: *params = mState.lineWidth; break;
1550 case GL_SAMPLE_COVERAGE_VALUE: *params = mState.sampleCoverageValue; break;
1551 case GL_DEPTH_CLEAR_VALUE: *params = mState.depthClearValue; break;
1552 case GL_POLYGON_OFFSET_FACTOR: *params = mState.rasterizer.polygonOffsetFactor; break;
1553 case GL_POLYGON_OFFSET_UNITS: *params = mState.rasterizer.polygonOffsetUnits; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001554 case GL_ALIASED_LINE_WIDTH_RANGE:
1555 params[0] = gl::ALIASED_LINE_WIDTH_RANGE_MIN;
1556 params[1] = gl::ALIASED_LINE_WIDTH_RANGE_MAX;
1557 break;
1558 case GL_ALIASED_POINT_SIZE_RANGE:
1559 params[0] = gl::ALIASED_POINT_SIZE_RANGE_MIN;
1560 params[1] = getMaximumPointSize();
1561 break;
1562 case GL_DEPTH_RANGE:
1563 params[0] = mState.zNear;
1564 params[1] = mState.zFar;
1565 break;
1566 case GL_COLOR_CLEAR_VALUE:
1567 params[0] = mState.colorClearValue.red;
1568 params[1] = mState.colorClearValue.green;
1569 params[2] = mState.colorClearValue.blue;
1570 params[3] = mState.colorClearValue.alpha;
1571 break;
1572 case GL_BLEND_COLOR:
1573 params[0] = mState.blendColor.red;
1574 params[1] = mState.blendColor.green;
1575 params[2] = mState.blendColor.blue;
1576 params[3] = mState.blendColor.alpha;
1577 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001578 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1579 if (!supportsTextureFilterAnisotropy())
1580 {
1581 return false;
1582 }
1583 *params = mMaxTextureAnisotropy;
1584 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001585 default:
1586 return false;
1587 }
1588
1589 return true;
1590}
1591
1592bool Context::getIntegerv(GLenum pname, GLint *params)
1593{
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001594 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1595 {
1596 unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT);
1597
1598 if (colorAttachment >= mRenderer->getMaxRenderTargets())
1599 {
1600 // return true to stop further operation in the parent call
1601 return gl::error(GL_INVALID_OPERATION, true);
1602 }
1603
1604 Framebuffer *framebuffer = getDrawFramebuffer();
1605
1606 *params = framebuffer->getDrawBufferState(colorAttachment);
1607 return true;
1608 }
1609
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001610 // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
1611 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1612 // GetIntegerv as its native query function. As it would require conversion in any
1613 // case, this should make no difference to the calling application. You may find it in
1614 // Context::getFloatv.
1615 switch (pname)
1616 {
Jamie Madill1caff072013-07-19 16:36:56 -04001617 case GL_MAX_VERTEX_ATTRIBS: *params = gl::MAX_VERTEX_ATTRIBS; break;
1618 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mRenderer->getMaxVertexUniformVectors(); break;
1619 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mRenderer->getMaxVertexUniformVectors() * 4; break;
1620 case GL_MAX_VARYING_VECTORS: *params = mRenderer->getMaxVaryingVectors(); break;
1621 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mRenderer->getMaxCombinedTextureImageUnits(); break;
1622 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mRenderer->getMaxVertexTextureImageUnits(); break;
1623 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = gl::MAX_TEXTURE_IMAGE_UNITS; break;
1624 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mRenderer->getMaxFragmentUniformVectors(); break;
1625 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mRenderer->getMaxFragmentUniformVectors() * 4; break;
1626 case GL_MAX_RENDERBUFFER_SIZE: *params = getMaximumRenderbufferDimension(); break;
1627 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mRenderer->getMaxRenderTargets(); break;
1628 case GL_MAX_DRAW_BUFFERS_EXT: *params = mRenderer->getMaxRenderTargets(); break;
1629 case GL_NUM_SHADER_BINARY_FORMATS: *params = 0; break;
1630 case GL_SHADER_BINARY_FORMATS: /* no shader binary formats are supported */ break;
1631 case GL_ARRAY_BUFFER_BINDING: *params = mState.arrayBuffer.id(); break;
1632 case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = getCurrentVertexArray()->getElementArrayBufferId(); break;
1633 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1634 case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE: *params = mState.drawFramebuffer; break;
1635 case GL_READ_FRAMEBUFFER_BINDING_ANGLE: *params = mState.readFramebuffer; break;
1636 case GL_RENDERBUFFER_BINDING: *params = mState.renderbuffer.id(); break;
1637 case GL_VERTEX_ARRAY_BINDING: *params = mState.vertexArray; break;
1638 case GL_CURRENT_PROGRAM: *params = mState.currentProgram; break;
1639 case GL_PACK_ALIGNMENT: *params = mState.packAlignment; break;
1640 case GL_PACK_REVERSE_ROW_ORDER_ANGLE: *params = mState.packReverseRowOrder; break;
1641 case GL_UNPACK_ALIGNMENT: *params = mState.unpackAlignment; break;
1642 case GL_GENERATE_MIPMAP_HINT: *params = mState.generateMipmapHint; break;
1643 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mState.fragmentShaderDerivativeHint; break;
1644 case GL_ACTIVE_TEXTURE: *params = (mState.activeSampler + GL_TEXTURE0); break;
1645 case GL_STENCIL_FUNC: *params = mState.depthStencil.stencilFunc; break;
1646 case GL_STENCIL_REF: *params = mState.stencilRef; break;
1647 case GL_STENCIL_VALUE_MASK: *params = mState.depthStencil.stencilMask; break;
1648 case GL_STENCIL_BACK_FUNC: *params = mState.depthStencil.stencilBackFunc; break;
1649 case GL_STENCIL_BACK_REF: *params = mState.stencilBackRef; break;
1650 case GL_STENCIL_BACK_VALUE_MASK: *params = mState.depthStencil.stencilBackMask; break;
1651 case GL_STENCIL_FAIL: *params = mState.depthStencil.stencilFail; break;
1652 case GL_STENCIL_PASS_DEPTH_FAIL: *params = mState.depthStencil.stencilPassDepthFail; break;
1653 case GL_STENCIL_PASS_DEPTH_PASS: *params = mState.depthStencil.stencilPassDepthPass; break;
1654 case GL_STENCIL_BACK_FAIL: *params = mState.depthStencil.stencilBackFail; break;
1655 case GL_STENCIL_BACK_PASS_DEPTH_FAIL: *params = mState.depthStencil.stencilBackPassDepthFail; break;
1656 case GL_STENCIL_BACK_PASS_DEPTH_PASS: *params = mState.depthStencil.stencilBackPassDepthPass; break;
1657 case GL_DEPTH_FUNC: *params = mState.depthStencil.depthFunc; break;
1658 case GL_BLEND_SRC_RGB: *params = mState.blend.sourceBlendRGB; break;
1659 case GL_BLEND_SRC_ALPHA: *params = mState.blend.sourceBlendAlpha; break;
1660 case GL_BLEND_DST_RGB: *params = mState.blend.destBlendRGB; break;
1661 case GL_BLEND_DST_ALPHA: *params = mState.blend.destBlendAlpha; break;
1662 case GL_BLEND_EQUATION_RGB: *params = mState.blend.blendEquationRGB; break;
1663 case GL_BLEND_EQUATION_ALPHA: *params = mState.blend.blendEquationAlpha; break;
1664 case GL_STENCIL_WRITEMASK: *params = mState.depthStencil.stencilWritemask; break;
1665 case GL_STENCIL_BACK_WRITEMASK: *params = mState.depthStencil.stencilBackWritemask; break;
1666 case GL_STENCIL_CLEAR_VALUE: *params = mState.stencilClearValue; break;
1667 case GL_SUBPIXEL_BITS: *params = 4; break;
1668 case GL_MAX_TEXTURE_SIZE: *params = getMaximum2DTextureDimension(); break;
1669 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = getMaximumCubeTextureDimension(); break;
1670 case GL_MAX_3D_TEXTURE_SIZE: *params = getMaximum3DTextureDimension(); break;
1671 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = getMaximum2DArrayTextureLayers(); break;
1672 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = getUniformBufferOffsetAlignment(); break;
1673 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = getMaximumCombinedUniformBufferBindings(); break;
1674 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mRenderer->getMaxVertexShaderUniformBuffers(); break;
1675 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mRenderer->getMaxFragmentShaderUniformBuffers(); break;
1676 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = getMaximumCombinedUniformBufferBindings(); break;
1677 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = 0; UNIMPLEMENTED(); break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001678 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1679 params[0] = mNumCompressedTextureFormats;
1680 break;
1681 case GL_MAX_SAMPLES_ANGLE:
1682 {
1683 GLsizei maxSamples = getMaxSupportedSamples();
1684 if (maxSamples != 0)
1685 {
1686 *params = maxSamples;
1687 }
1688 else
1689 {
1690 return false;
1691 }
1692
1693 break;
1694 }
1695 case GL_SAMPLE_BUFFERS:
1696 case GL_SAMPLES:
1697 {
1698 gl::Framebuffer *framebuffer = getDrawFramebuffer();
1699 if (framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE)
1700 {
1701 switch (pname)
1702 {
1703 case GL_SAMPLE_BUFFERS:
1704 if (framebuffer->getSamples() != 0)
1705 {
1706 *params = 1;
1707 }
1708 else
1709 {
1710 *params = 0;
1711 }
1712 break;
1713 case GL_SAMPLES:
1714 *params = framebuffer->getSamples();
1715 break;
1716 }
1717 }
1718 else
1719 {
1720 *params = 0;
1721 }
1722 }
1723 break;
daniel@transgaming.com42944b02012-09-27 17:45:57 +00001724 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
1725 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
1726 {
shannonwoods@chromium.org44a4f982013-05-30 00:13:49 +00001727 GLint internalFormat;
daniel@transgaming.com42944b02012-09-27 17:45:57 +00001728 GLenum format, type;
shannonwoods@chromium.org44a4f982013-05-30 00:13:49 +00001729 if (getCurrentReadFormatType(&internalFormat, &format, &type))
daniel@transgaming.com42944b02012-09-27 17:45:57 +00001730 {
1731 if (pname == GL_IMPLEMENTATION_COLOR_READ_FORMAT)
1732 *params = format;
1733 else
1734 *params = type;
1735 }
1736 }
1737 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001738 case GL_MAX_VIEWPORT_DIMS:
1739 {
shannon.woods@transgaming.com8ce2f8f2013-02-28 23:07:10 +00001740 params[0] = mMaxViewportDimension;
1741 params[1] = mMaxViewportDimension;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001742 }
1743 break;
1744 case GL_COMPRESSED_TEXTURE_FORMATS:
1745 {
1746 if (supportsDXT1Textures())
1747 {
1748 *params++ = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
1749 *params++ = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
1750 }
1751 if (supportsDXT3Textures())
1752 {
1753 *params++ = GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE;
1754 }
1755 if (supportsDXT5Textures())
1756 {
1757 *params++ = GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE;
1758 }
1759 }
1760 break;
1761 case GL_VIEWPORT:
daniel@transgaming.com3884e2c2012-11-28 19:41:00 +00001762 params[0] = mState.viewport.x;
1763 params[1] = mState.viewport.y;
1764 params[2] = mState.viewport.width;
1765 params[3] = mState.viewport.height;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001766 break;
1767 case GL_SCISSOR_BOX:
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001768 params[0] = mState.scissor.x;
1769 params[1] = mState.scissor.y;
1770 params[2] = mState.scissor.width;
1771 params[3] = mState.scissor.height;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001772 break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001773 case GL_CULL_FACE_MODE: *params = mState.rasterizer.cullMode; break;
1774 case GL_FRONT_FACE: *params = mState.rasterizer.frontFace; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001775 case GL_RED_BITS:
1776 case GL_GREEN_BITS:
1777 case GL_BLUE_BITS:
1778 case GL_ALPHA_BITS:
1779 {
1780 gl::Framebuffer *framebuffer = getDrawFramebuffer();
shannon.woods%transgaming.com@gtempaccount.com882434c2013-04-13 03:34:14 +00001781 gl::Renderbuffer *colorbuffer = framebuffer->getFirstColorbuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001782
1783 if (colorbuffer)
1784 {
1785 switch (pname)
1786 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001787 case GL_RED_BITS: *params = colorbuffer->getRedSize(); break;
1788 case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
1789 case GL_BLUE_BITS: *params = colorbuffer->getBlueSize(); break;
1790 case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001791 }
1792 }
1793 else
1794 {
1795 *params = 0;
1796 }
1797 }
1798 break;
1799 case GL_DEPTH_BITS:
1800 {
1801 gl::Framebuffer *framebuffer = getDrawFramebuffer();
1802 gl::Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
1803
1804 if (depthbuffer)
1805 {
1806 *params = depthbuffer->getDepthSize();
1807 }
1808 else
1809 {
1810 *params = 0;
1811 }
1812 }
1813 break;
1814 case GL_STENCIL_BITS:
1815 {
1816 gl::Framebuffer *framebuffer = getDrawFramebuffer();
1817 gl::Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
1818
1819 if (stencilbuffer)
1820 {
1821 *params = stencilbuffer->getStencilSize();
1822 }
1823 else
1824 {
1825 *params = 0;
1826 }
1827 }
1828 break;
1829 case GL_TEXTURE_BINDING_2D:
1830 {
shannon.woods@transgaming.com76cd88c2013-01-25 21:54:36 +00001831 if (mState.activeSampler > mRenderer->getMaxCombinedTextureImageUnits() - 1)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001832 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +00001833 gl::error(GL_INVALID_OPERATION);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001834 return false;
1835 }
1836
1837 *params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].id();
1838 }
1839 break;
1840 case GL_TEXTURE_BINDING_CUBE_MAP:
1841 {
shannon.woods@transgaming.com76cd88c2013-01-25 21:54:36 +00001842 if (mState.activeSampler > mRenderer->getMaxCombinedTextureImageUnits() - 1)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001843 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +00001844 gl::error(GL_INVALID_OPERATION);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001845 return false;
1846 }
1847
1848 *params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].id();
1849 }
1850 break;
shannon.woods%transgaming.com@gtempaccount.comc416e1c2013-04-13 03:45:05 +00001851 case GL_TEXTURE_BINDING_3D:
1852 {
1853 if (mState.activeSampler > mRenderer->getMaxCombinedTextureImageUnits() - 1)
1854 {
1855 gl::error(GL_INVALID_OPERATION);
1856 return false;
1857 }
1858
1859 *params = mState.samplerTexture[TEXTURE_3D][mState.activeSampler].id();
1860 }
1861 break;
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +00001862 case GL_TEXTURE_BINDING_2D_ARRAY:
1863 {
1864 if (mState.activeSampler > mRenderer->getMaxCombinedTextureImageUnits() - 1)
1865 {
1866 gl::error(GL_INVALID_OPERATION);
1867 return false;
1868 }
1869
1870 *params = mState.samplerTexture[TEXTURE_2D_ARRAY][mState.activeSampler].id();
1871 }
1872 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001873 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1874 *params = mResetStrategy;
1875 break;
1876 case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
1877 *params = 1;
1878 break;
1879 case GL_PROGRAM_BINARY_FORMATS_OES:
1880 *params = GL_PROGRAM_BINARY_ANGLE;
1881 break;
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001882 case GL_UNIFORM_BUFFER_BINDING:
1883 *params = mState.genericUniformBuffer.id();
1884 break;
1885 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
1886 *params = mState.genericTransformFeedbackBuffer.id();
1887 break;
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001888 case GL_COPY_READ_BUFFER_BINDING:
1889 *params = mState.copyReadBuffer.id();
1890 break;
1891 case GL_COPY_WRITE_BUFFER_BINDING:
1892 *params = mState.copyWriteBuffer.id();
1893 break;
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001894 case GL_PIXEL_PACK_BUFFER_BINDING:
1895 *params = mState.pixelPackBuffer.id();
1896 break;
1897 case GL_PIXEL_UNPACK_BUFFER_BINDING:
1898 *params = mState.pixelUnpackBuffer.id();
1899 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001900 case GL_NUM_EXTENSIONS:
1901 *params = static_cast<GLint>(getNumExtensions());
1902 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001903 default:
1904 return false;
1905 }
1906
1907 return true;
1908}
1909
Jamie Madill0fda9862013-07-19 16:36:55 -04001910bool Context::getInteger64v(GLenum pname, GLint64 *params)
1911{
1912 switch (pname)
1913 {
1914 case GL_MAX_ELEMENT_INDEX:
1915 *params = static_cast<GLint64>(std::numeric_limits<unsigned int>::max());
1916 break;
1917 case GL_MAX_UNIFORM_BLOCK_SIZE:
1918 *params = static_cast<GLint64>(mRenderer->getMaxUniformBufferSize());
1919 break;
1920 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
1921 {
1922 GLint64 uniformBufferComponents = static_cast<GLint64>(mRenderer->getMaxVertexShaderUniformBuffers()) * static_cast<GLint64>(mRenderer->getMaxUniformBufferSize() / 4);
1923 GLint64 defaultBufferComponents = static_cast<GLint64>(mRenderer->getMaxVertexUniformVectors() * 4);
1924 *params = uniformBufferComponents + defaultBufferComponents;
1925 }
1926 break;
1927 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
1928 {
1929 GLint64 uniformBufferComponents = static_cast<GLint64>(mRenderer->getMaxFragmentShaderUniformBuffers()) * static_cast<GLint64>(mRenderer->getMaxUniformBufferSize() / 4);
1930 GLint64 defaultBufferComponents = static_cast<GLint64>(mRenderer->getMaxVertexUniformVectors() * 4);
1931 *params = uniformBufferComponents + defaultBufferComponents;
1932 }
1933 break;
1934 case GL_MAX_SERVER_WAIT_TIMEOUT:
Jamie Madill5215e1a2013-07-26 11:55:19 -04001935 // We do not wait for server fence objects internally, so report a max timeout of zero.
1936 *params = 0;
Jamie Madill0fda9862013-07-19 16:36:55 -04001937 break;
1938 default:
1939 return false;
1940 }
1941
1942 return true;
1943}
1944
Shannon Woods1b2fb852013-08-19 14:28:48 -04001945bool Context::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
1946{
1947 switch (target)
1948 {
1949 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
1950 if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS)
1951 {
1952 *data = mState.transformFeedbackBuffers[index].id();
1953 }
1954 break;
1955 case GL_UNIFORM_BUFFER_BINDING:
1956 if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS)
1957 {
1958 *data = mState.uniformBuffers[index].id();
1959 }
1960 break;
1961 default:
1962 return false;
1963 }
1964
1965 return true;
1966}
1967
1968bool Context::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
1969{
1970 switch (target)
1971 {
1972 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
1973 if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS)
1974 {
1975 *data = mState.transformFeedbackBuffers[index].getOffset();
1976 }
1977 break;
1978 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
1979 if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS)
1980 {
1981 *data = mState.transformFeedbackBuffers[index].getSize();
1982 }
1983 break;
1984 case GL_UNIFORM_BUFFER_START:
1985 if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS)
1986 {
1987 *data = mState.uniformBuffers[index].getOffset();
1988 }
1989 break;
1990 case GL_UNIFORM_BUFFER_SIZE:
1991 if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS)
1992 {
1993 *data = mState.uniformBuffers[index].getSize();
1994 }
1995 break;
1996 default:
1997 return false;
1998 }
1999
2000 return true;
2001}
2002
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002003bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams)
2004{
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00002005 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
2006 {
2007 *type = GL_INT;
2008 *numParams = 1;
2009 return true;
2010 }
2011
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002012 // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
2013 // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
2014 // to the fact that it is stored internally as a float, and so would require conversion
2015 // if returned from Context::getIntegerv. Since this conversion is already implemented
2016 // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
2017 // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
2018 // application.
2019 switch (pname)
2020 {
2021 case GL_COMPRESSED_TEXTURE_FORMATS:
2022 {
2023 *type = GL_INT;
2024 *numParams = mNumCompressedTextureFormats;
2025 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00002026 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002027 case GL_SHADER_BINARY_FORMATS:
2028 {
2029 *type = GL_INT;
2030 *numParams = 0;
2031 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00002032 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002033 case GL_MAX_VERTEX_ATTRIBS:
2034 case GL_MAX_VERTEX_UNIFORM_VECTORS:
2035 case GL_MAX_VARYING_VECTORS:
2036 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
2037 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
2038 case GL_MAX_TEXTURE_IMAGE_UNITS:
2039 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
2040 case GL_MAX_RENDERBUFFER_SIZE:
shannon.woods%transgaming.com@gtempaccount.com9790c472013-04-13 03:28:23 +00002041 case GL_MAX_COLOR_ATTACHMENTS_EXT:
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00002042 case GL_MAX_DRAW_BUFFERS_EXT:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002043 case GL_NUM_SHADER_BINARY_FORMATS:
2044 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
2045 case GL_ARRAY_BUFFER_BINDING:
2046 case GL_FRAMEBUFFER_BINDING:
2047 case GL_RENDERBUFFER_BINDING:
2048 case GL_CURRENT_PROGRAM:
2049 case GL_PACK_ALIGNMENT:
2050 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
2051 case GL_UNPACK_ALIGNMENT:
2052 case GL_GENERATE_MIPMAP_HINT:
2053 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
2054 case GL_RED_BITS:
2055 case GL_GREEN_BITS:
2056 case GL_BLUE_BITS:
2057 case GL_ALPHA_BITS:
2058 case GL_DEPTH_BITS:
2059 case GL_STENCIL_BITS:
2060 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
2061 case GL_CULL_FACE_MODE:
2062 case GL_FRONT_FACE:
2063 case GL_ACTIVE_TEXTURE:
2064 case GL_STENCIL_FUNC:
2065 case GL_STENCIL_VALUE_MASK:
2066 case GL_STENCIL_REF:
2067 case GL_STENCIL_FAIL:
2068 case GL_STENCIL_PASS_DEPTH_FAIL:
2069 case GL_STENCIL_PASS_DEPTH_PASS:
2070 case GL_STENCIL_BACK_FUNC:
2071 case GL_STENCIL_BACK_VALUE_MASK:
2072 case GL_STENCIL_BACK_REF:
2073 case GL_STENCIL_BACK_FAIL:
2074 case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
2075 case GL_STENCIL_BACK_PASS_DEPTH_PASS:
2076 case GL_DEPTH_FUNC:
2077 case GL_BLEND_SRC_RGB:
2078 case GL_BLEND_SRC_ALPHA:
2079 case GL_BLEND_DST_RGB:
2080 case GL_BLEND_DST_ALPHA:
2081 case GL_BLEND_EQUATION_RGB:
2082 case GL_BLEND_EQUATION_ALPHA:
2083 case GL_STENCIL_WRITEMASK:
2084 case GL_STENCIL_BACK_WRITEMASK:
2085 case GL_STENCIL_CLEAR_VALUE:
2086 case GL_SUBPIXEL_BITS:
2087 case GL_MAX_TEXTURE_SIZE:
2088 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
2089 case GL_SAMPLE_BUFFERS:
2090 case GL_SAMPLES:
2091 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
2092 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
2093 case GL_TEXTURE_BINDING_2D:
2094 case GL_TEXTURE_BINDING_CUBE_MAP:
2095 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
2096 case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
2097 case GL_PROGRAM_BINARY_FORMATS_OES:
2098 {
2099 *type = GL_INT;
2100 *numParams = 1;
2101 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00002102 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002103 case GL_MAX_SAMPLES_ANGLE:
2104 {
2105 if (getMaxSupportedSamples() != 0)
2106 {
2107 *type = GL_INT;
2108 *numParams = 1;
2109 }
2110 else
2111 {
2112 return false;
2113 }
2114 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00002115 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002116 case GL_MAX_VIEWPORT_DIMS:
2117 {
2118 *type = GL_INT;
2119 *numParams = 2;
2120 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00002121 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002122 case GL_VIEWPORT:
2123 case GL_SCISSOR_BOX:
2124 {
2125 *type = GL_INT;
2126 *numParams = 4;
2127 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00002128 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002129 case GL_SHADER_COMPILER:
2130 case GL_SAMPLE_COVERAGE_INVERT:
2131 case GL_DEPTH_WRITEMASK:
2132 case GL_CULL_FACE: // CULL_FACE through DITHER are natural to IsEnabled,
2133 case GL_POLYGON_OFFSET_FILL: // but can be retrieved through the Get{Type}v queries.
2134 case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
2135 case GL_SAMPLE_COVERAGE:
2136 case GL_SCISSOR_TEST:
2137 case GL_STENCIL_TEST:
2138 case GL_DEPTH_TEST:
2139 case GL_BLEND:
2140 case GL_DITHER:
2141 case GL_CONTEXT_ROBUST_ACCESS_EXT:
2142 {
2143 *type = GL_BOOL;
2144 *numParams = 1;
2145 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00002146 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002147 case GL_COLOR_WRITEMASK:
2148 {
2149 *type = GL_BOOL;
2150 *numParams = 4;
2151 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00002152 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002153 case GL_POLYGON_OFFSET_FACTOR:
2154 case GL_POLYGON_OFFSET_UNITS:
2155 case GL_SAMPLE_COVERAGE_VALUE:
2156 case GL_DEPTH_CLEAR_VALUE:
2157 case GL_LINE_WIDTH:
2158 {
2159 *type = GL_FLOAT;
2160 *numParams = 1;
2161 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00002162 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002163 case GL_ALIASED_LINE_WIDTH_RANGE:
2164 case GL_ALIASED_POINT_SIZE_RANGE:
2165 case GL_DEPTH_RANGE:
2166 {
2167 *type = GL_FLOAT;
2168 *numParams = 2;
2169 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00002170 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002171 case GL_COLOR_CLEAR_VALUE:
2172 case GL_BLEND_COLOR:
2173 {
2174 *type = GL_FLOAT;
2175 *numParams = 4;
2176 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00002177 return true;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00002178 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
2179 if (!supportsTextureFilterAnisotropy())
2180 {
2181 return false;
2182 }
2183 *type = GL_FLOAT;
2184 *numParams = 1;
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00002185 return true;
2186 }
2187
2188 if (mClientVersion < 3)
2189 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002190 return false;
2191 }
2192
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00002193 // Check for ES3.0+ parameter names
2194 switch (pname)
2195 {
shannonwoods@chromium.org97c3d502013-05-30 00:04:34 +00002196 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
2197 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00002198 case GL_UNIFORM_BUFFER_BINDING:
2199 case GL_TRANSFORM_FEEDBACK_BINDING:
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00002200 case GL_COPY_READ_BUFFER_BINDING:
2201 case GL_COPY_WRITE_BUFFER_BINDING:
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00002202 case GL_PIXEL_PACK_BUFFER_BINDING:
2203 case GL_PIXEL_UNPACK_BUFFER_BINDING:
shannon.woods%transgaming.com@gtempaccount.comc416e1c2013-04-13 03:45:05 +00002204 case GL_TEXTURE_BINDING_3D:
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +00002205 case GL_TEXTURE_BINDING_2D_ARRAY:
shannon.woods%transgaming.com@gtempaccount.comc1fdf6b2013-04-13 03:44:41 +00002206 case GL_MAX_3D_TEXTURE_SIZE:
shannon.woods%transgaming.com@gtempaccount.coma98a8112013-04-13 03:45:57 +00002207 case GL_MAX_ARRAY_TEXTURE_LAYERS:
shannonwoods@chromium.orgf2d76f82013-05-30 00:06:32 +00002208 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
2209 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
2210 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
Jamie Madillefb3bd12013-07-02 11:57:05 -04002211 case GL_VERTEX_ARRAY_BINDING:
Jamie Madill38850df2013-07-19 16:36:55 -04002212 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
2213 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang23c81692013-08-12 10:46:58 -04002214 case GL_NUM_EXTENSIONS:
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00002215 {
2216 *type = GL_INT;
2217 *numParams = 1;
2218 }
2219 return true;
Jamie Madill0fda9862013-07-19 16:36:55 -04002220
2221 case GL_MAX_ELEMENT_INDEX:
2222 case GL_MAX_UNIFORM_BLOCK_SIZE:
2223 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
2224 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
2225 case GL_MAX_SERVER_WAIT_TIMEOUT:
2226 {
2227 *type = GL_INT_64_ANGLEX;
2228 *numParams = 1;
2229 }
2230 return true;
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00002231 }
2232
2233 return false;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002234}
2235
Shannon Woods1b2fb852013-08-19 14:28:48 -04002236bool Context::getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams)
2237{
2238 if (mClientVersion < 3)
2239 {
2240 return false;
2241 }
2242
2243 switch (target)
2244 {
2245 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
2246 case GL_UNIFORM_BUFFER_BINDING:
2247 {
2248 *type = GL_INT;
2249 *numParams = 1;
2250 }
2251 return true;
2252 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
2253 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
2254 case GL_UNIFORM_BUFFER_START:
2255 case GL_UNIFORM_BUFFER_SIZE:
2256 {
2257 *type = GL_INT_64_ANGLEX;
2258 *numParams = 1;
2259 }
2260 }
2261
2262 return false;
2263}
2264
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002265// Applies the render target surface, depth stencil surface, viewport rectangle and
daniel@transgaming.com12985182012-12-20 20:56:31 +00002266// scissor rectangle to the renderer
2267bool Context::applyRenderTarget(GLenum drawMode, bool ignoreViewport)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002268{
2269 Framebuffer *framebufferObject = getDrawFramebuffer();
2270
2271 if (!framebufferObject || framebufferObject->completeness() != GL_FRAMEBUFFER_COMPLETE)
2272 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +00002273 return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002274 }
2275
daniel@transgaming.com8a8b24c2012-11-28 19:36:26 +00002276 mRenderer->applyRenderTarget(framebufferObject);
2277
daniel@transgaming.com12985182012-12-20 20:56:31 +00002278 if (!mRenderer->setViewport(mState.viewport, mState.zNear, mState.zFar, drawMode, mState.rasterizer.frontFace,
shannon.woods@transgaming.com0b236e22013-01-25 21:57:07 +00002279 ignoreViewport))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002280 {
daniel@transgaming.com3ca082c2012-11-28 19:41:07 +00002281 return false;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002282 }
2283
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +00002284 mRenderer->setScissorRectangle(mState.scissor, mState.scissorTest);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002285
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002286 return true;
2287}
2288
2289// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) to the Direct3D 9 device
2290void Context::applyState(GLenum drawMode)
2291{
Nicolas Capensfd396552013-06-18 21:41:30 -04002292 Framebuffer *framebufferObject = getDrawFramebuffer();
2293 int samples = framebufferObject->getSamples();
2294
shannon.woods@transgaming.comdd2524c2013-02-28 23:04:33 +00002295 mState.rasterizer.pointDrawMode = (drawMode == GL_POINTS);
Nicolas Capensfd396552013-06-18 21:41:30 -04002296 mState.rasterizer.multiSample = (samples != 0);
shannon.woods@transgaming.comdd2524c2013-02-28 23:04:33 +00002297 mRenderer->setRasterizerState(mState.rasterizer);
daniel@transgaming.com2e258642012-11-28 19:36:18 +00002298
2299 unsigned int mask = 0;
2300 if (mState.sampleCoverage)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002301 {
daniel@transgaming.com2e258642012-11-28 19:36:18 +00002302 if (mState.sampleCoverageValue != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002303 {
Nicolas Capensfd396552013-06-18 21:41:30 -04002304
daniel@transgaming.com2e258642012-11-28 19:36:18 +00002305 float threshold = 0.5f;
2306
Nicolas Capensfd396552013-06-18 21:41:30 -04002307 for (int i = 0; i < samples; ++i)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002308 {
daniel@transgaming.com2e258642012-11-28 19:36:18 +00002309 mask <<= 1;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002310
daniel@transgaming.com2e258642012-11-28 19:36:18 +00002311 if ((i + 1) * mState.sampleCoverageValue >= threshold)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002312 {
daniel@transgaming.com2e258642012-11-28 19:36:18 +00002313 threshold += 1.0f;
2314 mask |= 1;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002315 }
2316 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002317 }
daniel@transgaming.com2e258642012-11-28 19:36:18 +00002318
2319 if (mState.sampleCoverageInvert)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002320 {
daniel@transgaming.com2e258642012-11-28 19:36:18 +00002321 mask = ~mask;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002322 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002323 }
daniel@transgaming.com2e258642012-11-28 19:36:18 +00002324 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002325 {
daniel@transgaming.com2e258642012-11-28 19:36:18 +00002326 mask = 0xFFFFFFFF;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002327 }
daniel@transgaming.com2e258642012-11-28 19:36:18 +00002328 mRenderer->setBlendState(mState.blend, mState.blendColor, mask);
2329
daniel@transgaming.com08c331d2012-11-28 19:38:39 +00002330 mRenderer->setDepthStencilState(mState.depthStencil, mState.stencilRef, mState.stencilBackRef,
daniel@transgaming.com3a0ef482012-11-28 21:01:20 +00002331 mState.rasterizer.frontFace == GL_CCW);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002332}
2333
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002334// Applies the shaders and shader constants to the Direct3D 9 device
2335void Context::applyShaders()
2336{
daniel@transgaming.com62a28462012-07-24 18:33:59 +00002337 ProgramBinary *programBinary = getCurrentProgramBinary();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002338
daniel@transgaming.come4991412012-12-20 20:55:34 +00002339 mRenderer->applyShaders(programBinary);
daniel@transgaming.com5fbf1772012-11-28 20:54:43 +00002340
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002341 programBinary->applyUniforms();
2342}
2343
2344// Applies the textures and sampler states to the Direct3D 9 device
2345void Context::applyTextures()
2346{
2347 applyTextures(SAMPLER_PIXEL);
2348
2349 if (mSupportsVertexTexture)
2350 {
2351 applyTextures(SAMPLER_VERTEX);
2352 }
2353}
2354
2355// For each Direct3D 9 sampler of either the pixel or vertex stage,
2356// looks up the corresponding OpenGL texture image unit and texture type,
2357// and sets the texture and its addressing/filtering state (or NULL when inactive).
2358void Context::applyTextures(SamplerType type)
2359{
daniel@transgaming.com62a28462012-07-24 18:33:59 +00002360 ProgramBinary *programBinary = getCurrentProgramBinary();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002361
shannon.woods@transgaming.com233fe952013-01-25 21:51:57 +00002362 // Range of Direct3D samplers of given sampler type
2363 int samplerCount = (type == SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : mRenderer->getMaxVertexTextureImageUnits();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002364 int samplerRange = programBinary->getUsedSamplerRange(type);
2365
2366 for (int samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++)
2367 {
2368 int textureUnit = programBinary->getSamplerMapping(type, samplerIndex); // OpenGL texture image unit index
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002369
2370 if (textureUnit != -1)
2371 {
2372 TextureType textureType = programBinary->getSamplerTextureType(type, samplerIndex);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002373 Texture *texture = getSamplerTexture(textureUnit, textureType);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002374
Jamie Madillf8989902013-07-19 16:36:58 -04002375 SamplerState samplerState;
2376 texture->getSamplerState(&samplerState);
2377
Jamie Madilla85f6f12013-07-19 16:36:59 -04002378 if (mState.samplers[textureUnit] != 0)
2379 {
2380 Sampler *samplerObject = getSampler(mState.samplers[textureUnit]);
2381 samplerObject->getState(&samplerState);
2382 }
2383
Jamie Madillf8989902013-07-19 16:36:58 -04002384 if (texture->isSamplerComplete(samplerState))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002385 {
daniel@transgaming.come33c8bf2013-01-11 04:11:33 +00002386 mRenderer->setSamplerState(type, samplerIndex, samplerState);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002387
daniel@transgaming.come33c8bf2013-01-11 04:11:33 +00002388 mRenderer->setTexture(type, samplerIndex, texture);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002389
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002390 texture->resetDirty();
2391 }
daniel@transgaming.come33c8bf2013-01-11 04:11:33 +00002392 else
2393 {
2394 mRenderer->setTexture(type, samplerIndex, getIncompleteTexture(textureType));
2395 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002396 }
2397 else
2398 {
daniel@transgaming.come33c8bf2013-01-11 04:11:33 +00002399 mRenderer->setTexture(type, samplerIndex, NULL);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002400 }
2401 }
2402
2403 for (int samplerIndex = samplerRange; samplerIndex < samplerCount; samplerIndex++)
2404 {
daniel@transgaming.come33c8bf2013-01-11 04:11:33 +00002405 mRenderer->setTexture(type, samplerIndex, NULL);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002406 }
2407}
2408
shannonwoods@chromium.org1bddfb92013-05-30 00:11:29 +00002409bool Context::applyUniformBuffers()
2410{
2411 Program *programObject = getProgram(mState.currentProgram);
2412 ProgramBinary *programBinary = programObject->getProgramBinary();
2413
2414 std::vector<gl::Buffer*> boundBuffers;
2415
2416 for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < programBinary->getActiveUniformBlockCount(); uniformBlockIndex++)
2417 {
2418 GLuint blockBinding = programObject->getUniformBlockBinding(uniformBlockIndex);
2419 const OffsetBindingPointer<Buffer>& boundBuffer = mState.uniformBuffers[blockBinding];
2420 if (boundBuffer.id() == 0)
2421 {
2422 // undefined behaviour
2423 return false;
2424 }
2425 else
2426 {
2427 gl::Buffer *uniformBuffer = boundBuffer.get();
2428 ASSERT(uniformBuffer);
2429 boundBuffers.push_back(uniformBuffer);
2430 }
2431 }
2432
2433 return programBinary->applyUniformBuffers(boundBuffers);
2434}
2435
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002436
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002437
2438void Context::clear(GLbitfield mask)
2439{
Geoff Langda507fe2013-08-20 12:01:42 -04002440 ClearParameters clearParams = { 0 };
Geoff Langda507fe2013-08-20 12:01:42 -04002441 for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
2442 {
2443 clearParams.clearColor[i] = false;
2444 }
2445 clearParams.colorFClearValue = mState.colorClearValue;
2446 clearParams.colorClearType = GL_FLOAT;
2447 clearParams.colorMaskRed = mState.blend.colorMaskRed;
2448 clearParams.colorMaskGreen = mState.blend.colorMaskGreen;
2449 clearParams.colorMaskBlue = mState.blend.colorMaskBlue;
2450 clearParams.colorMaskAlpha = mState.blend.colorMaskAlpha;
2451 clearParams.clearDepth = false;
2452 clearParams.depthClearValue = mState.depthClearValue;
2453 clearParams.clearStencil = false;
2454 clearParams.stencilClearValue = mState.stencilClearValue;
2455 clearParams.stencilWriteMask = mState.depthStencil.stencilWritemask;
2456 clearParams.scissorEnabled = mState.scissorTest;
2457 clearParams.scissor = mState.scissor;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002458
Geoff Lang0b833232013-08-21 10:13:29 -04002459 Framebuffer *framebufferObject = getDrawFramebuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002460 if (mask & GL_COLOR_BUFFER_BIT)
2461 {
shannon.woods%transgaming.com@gtempaccount.comdae24092013-04-13 03:31:31 +00002462 if (framebufferObject->hasEnabledColorAttachment())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002463 {
Geoff Langda507fe2013-08-20 12:01:42 -04002464 for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
2465 {
2466 clearParams.clearColor[i] = true;
2467 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002468 }
2469 }
2470
2471 if (mask & GL_DEPTH_BUFFER_BIT)
2472 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00002473 if (mState.depthStencil.depthMask && framebufferObject->getDepthbufferType() != GL_NONE)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002474 {
Geoff Langda507fe2013-08-20 12:01:42 -04002475 clearParams.clearDepth = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002476 }
2477 }
2478
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002479 if (mask & GL_STENCIL_BUFFER_BIT)
2480 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002481 if (framebufferObject->getStencilbufferType() != GL_NONE)
2482 {
daniel@transgaming.comd62d7142012-11-28 19:40:28 +00002483 rx::RenderTarget *depthStencil = framebufferObject->getStencilbuffer()->getDepthStencil();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002484 if (!depthStencil)
2485 {
2486 ERR("Depth stencil pointer unexpectedly null.");
2487 return;
2488 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002489
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +00002490 if (gl::GetStencilBits(depthStencil->getActualFormat(), mClientVersion) > 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002491 {
Geoff Langda507fe2013-08-20 12:01:42 -04002492 clearParams.clearStencil = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002493 }
2494 }
2495 }
2496
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002497
daniel@transgaming.com12985182012-12-20 20:56:31 +00002498 if (!applyRenderTarget(GL_TRIANGLES, true)) // Clips the clear to the scissor rectangle but not the viewport
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002499 {
2500 return;
2501 }
2502
daniel@transgaming.com084a2572012-11-28 20:55:17 +00002503 mRenderer->clear(clearParams, framebufferObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002504}
2505
Geoff Lang42359ca2013-08-21 13:25:17 -04002506void Context::clearBufferfv(GLenum buffer, int drawbuffer, const float *values)
2507{
2508 // glClearBufferfv can be called to clear the color buffer or depth buffer
2509
2510 ClearParameters clearParams = { 0 };
2511
2512 if (buffer == GL_COLOR)
2513 {
2514 for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
2515 {
2516 clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
2517 }
2518 clearParams.colorFClearValue = ColorF(values[0], values[1], values[2], values[3]);
2519 clearParams.colorClearType = GL_FLOAT;
2520 }
2521 else
2522 {
2523 for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
2524 {
2525 clearParams.clearColor[i] = false;
2526 }
2527 clearParams.colorFClearValue = mState.colorClearValue;
2528 clearParams.colorClearType = GL_FLOAT;
2529 }
2530
2531 clearParams.colorMaskRed = mState.blend.colorMaskRed;
2532 clearParams.colorMaskGreen = mState.blend.colorMaskGreen;
2533 clearParams.colorMaskBlue = mState.blend.colorMaskBlue;
2534 clearParams.colorMaskAlpha = mState.blend.colorMaskAlpha;
2535
2536 if (buffer == GL_DEPTH)
2537 {
2538 clearParams.clearDepth = true;
2539 clearParams.depthClearValue = values[0];
2540 }
2541 else
2542 {
2543 clearParams.clearDepth = false;
2544 clearParams.depthClearValue = mState.depthClearValue;
2545 }
2546
2547 clearParams.clearStencil = false;
2548 clearParams.stencilClearValue = mState.stencilClearValue;
2549 clearParams.stencilWriteMask = mState.depthStencil.stencilWritemask;
2550 clearParams.scissorEnabled = mState.scissorTest;
2551 clearParams.scissor = mState.scissor;
2552
2553 if (!applyRenderTarget(GL_TRIANGLES, true)) // Clips the clear to the scissor rectangle but not the viewport
2554 {
2555 return;
2556 }
2557
2558 mRenderer->clear(clearParams, getDrawFramebuffer());
2559}
2560
2561void Context::clearBufferuiv(GLenum buffer, int drawbuffer, const unsigned int *values)
2562{
2563 // glClearBufferuv can only be called to clear a color buffer
2564
2565 ClearParameters clearParams = { 0 };
2566 for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
2567 {
2568 clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
2569 }
2570 clearParams.colorUIClearValue = ColorUI(values[0], values[1], values[2], values[3]);
2571 clearParams.colorClearType = GL_UNSIGNED_INT;
2572 clearParams.colorMaskRed = mState.blend.colorMaskRed;
2573 clearParams.colorMaskGreen = mState.blend.colorMaskGreen;
2574 clearParams.colorMaskBlue = mState.blend.colorMaskBlue;
2575 clearParams.colorMaskAlpha = mState.blend.colorMaskAlpha;
2576 clearParams.clearDepth = false;
2577 clearParams.depthClearValue = mState.depthClearValue;
2578 clearParams.clearStencil = false;
2579 clearParams.stencilClearValue = mState.stencilClearValue;
2580 clearParams.stencilWriteMask = mState.depthStencil.stencilWritemask;
2581 clearParams.scissorEnabled = mState.scissorTest;
2582 clearParams.scissor = mState.scissor;
2583
2584 if (!applyRenderTarget(GL_TRIANGLES, true)) // Clips the clear to the scissor rectangle but not the viewport
2585 {
2586 return;
2587 }
2588
2589 mRenderer->clear(clearParams, getDrawFramebuffer());
2590}
2591
2592void Context::clearBufferiv(GLenum buffer, int drawbuffer, const int *values)
2593{
2594 // glClearBufferfv can be called to clear the color buffer or stencil buffer
2595
2596 ClearParameters clearParams = { 0 };
2597
2598 if (buffer == GL_COLOR)
2599 {
2600 for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
2601 {
2602 clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
2603 }
2604 clearParams.colorIClearValue = ColorI(values[0], values[1], values[2], values[3]);
2605 clearParams.colorClearType = GL_INT;
2606 }
2607 else
2608 {
2609 for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
2610 {
2611 clearParams.clearColor[i] = false;
2612 }
2613 clearParams.colorFClearValue = mState.colorClearValue;
2614 clearParams.colorClearType = GL_FLOAT;
2615 }
2616
2617 clearParams.colorMaskRed = mState.blend.colorMaskRed;
2618 clearParams.colorMaskGreen = mState.blend.colorMaskGreen;
2619 clearParams.colorMaskBlue = mState.blend.colorMaskBlue;
2620 clearParams.colorMaskAlpha = mState.blend.colorMaskAlpha;
2621
2622 clearParams.clearDepth = false;
2623 clearParams.depthClearValue = mState.depthClearValue;
2624
2625 if (buffer == GL_STENCIL)
2626 {
2627 clearParams.clearStencil = true;
2628 clearParams.stencilClearValue = values[1];
2629 }
2630 else
2631 {
2632 clearParams.clearStencil = false;
2633 clearParams.stencilClearValue = mState.stencilClearValue;
2634 }
2635 clearParams.stencilWriteMask = mState.depthStencil.stencilWritemask;
2636
2637 clearParams.scissorEnabled = mState.scissorTest;
2638 clearParams.scissor = mState.scissor;
2639
2640 if (!applyRenderTarget(GL_TRIANGLES, true)) // Clips the clear to the scissor rectangle but not the viewport
2641 {
2642 return;
2643 }
2644
2645 mRenderer->clear(clearParams, getDrawFramebuffer());
2646}
2647
2648void Context::clearBufferfi(GLenum buffer, int drawbuffer, float depth, int stencil)
2649{
2650 // glClearBufferfi can only be called to clear a depth stencil buffer
2651
2652 ClearParameters clearParams = { 0 };
2653 for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
2654 {
2655 clearParams.clearColor[i] = false;
2656 }
2657 clearParams.colorFClearValue = mState.colorClearValue;
2658 clearParams.colorClearType = GL_FLOAT;
2659 clearParams.colorMaskRed = mState.blend.colorMaskRed;
2660 clearParams.colorMaskGreen = mState.blend.colorMaskGreen;
2661 clearParams.colorMaskBlue = mState.blend.colorMaskBlue;
2662 clearParams.colorMaskAlpha = mState.blend.colorMaskAlpha;
2663 clearParams.clearDepth = true;
2664 clearParams.depthClearValue = depth;
2665 clearParams.clearStencil = true;
2666 clearParams.stencilClearValue = stencil;
2667 clearParams.stencilWriteMask = mState.depthStencil.stencilWritemask;
2668 clearParams.scissorEnabled = mState.scissorTest;
2669 clearParams.scissor = mState.scissor;
2670
2671 if (!applyRenderTarget(GL_TRIANGLES, true)) // Clips the clear to the scissor rectangle but not the viewport
2672 {
2673 return;
2674 }
2675
2676 mRenderer->clear(clearParams, getDrawFramebuffer());
2677}
2678
2679void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
2680 GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
2681{
2682 Framebuffer *framebuffer = getReadFramebuffer();
2683
2684 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
2685 {
2686 return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION);
2687 }
2688
2689 if (getReadFramebufferHandle() != 0 && framebuffer->getSamples() != 0)
2690 {
2691 return gl::error(GL_INVALID_OPERATION);
2692 }
2693
2694 GLint sizedInternalFormat = IsSizedInternalFormat(format, mClientVersion) ? format
2695 : GetSizedInternalFormat(format, type, mClientVersion);
2696
2697 GLsizei outputPitch = GetRowPitch(sizedInternalFormat, type, mClientVersion, width, getPackAlignment());
2698 // sized query sanity check
2699 if (bufSize)
2700 {
2701 int requiredSize = outputPitch * height;
2702 if (requiredSize > *bufSize)
2703 {
2704 return gl::error(GL_INVALID_OPERATION);
2705 }
2706 }
2707
2708 mRenderer->readPixels(framebuffer, x, y, width, height, format, type, outputPitch, getPackReverseRowOrder(), getPackAlignment(), pixels);
2709}
2710
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002711void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances)
2712{
2713 if (!mState.currentProgram)
2714 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +00002715 return gl::error(GL_INVALID_OPERATION);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002716 }
2717
daniel@transgaming.com91207b72012-11-28 20:56:43 +00002718 if (!mRenderer->applyPrimitiveType(mode, count))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002719 {
2720 return;
2721 }
2722
daniel@transgaming.com12985182012-12-20 20:56:31 +00002723 if (!applyRenderTarget(mode, false))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002724 {
2725 return;
2726 }
2727
2728 applyState(mode);
2729
daniel@transgaming.com92025f52012-11-28 20:52:54 +00002730 ProgramBinary *programBinary = getCurrentProgramBinary();
2731
Jamie Madill57a89722013-07-02 11:57:03 -04002732 GLenum err = mRenderer->applyVertexBuffer(programBinary, getCurrentVertexArray()->getVertexAttributes(), mState.vertexAttribCurrentValues, first, count, instances);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002733 if (err != GL_NO_ERROR)
2734 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +00002735 return gl::error(err);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002736 }
2737
2738 applyShaders();
2739 applyTextures();
2740
shannonwoods@chromium.org1bddfb92013-05-30 00:11:29 +00002741 if (!applyUniformBuffers())
2742 {
2743 return;
2744 }
2745
daniel@transgaming.com92025f52012-11-28 20:52:54 +00002746 if (!programBinary->validateSamplers(NULL))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002747 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +00002748 return gl::error(GL_INVALID_OPERATION);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002749 }
2750
daniel@transgaming.com087e5782012-09-17 21:28:47 +00002751 if (!skipDraw(mode))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002752 {
daniel@transgaming.com91207b72012-11-28 20:56:43 +00002753 mRenderer->drawArrays(mode, count, instances);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002754 }
2755}
2756
2757void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instances)
2758{
2759 if (!mState.currentProgram)
2760 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +00002761 return gl::error(GL_INVALID_OPERATION);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002762 }
2763
Jamie Madill57a89722013-07-02 11:57:03 -04002764 VertexArray *vao = getCurrentVertexArray();
2765 if (!indices && !vao->getElementArrayBuffer())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002766 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +00002767 return gl::error(GL_INVALID_OPERATION);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002768 }
daniel@transgaming.com91207b72012-11-28 20:56:43 +00002769
2770 if (!mRenderer->applyPrimitiveType(mode, count))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002771 {
2772 return;
2773 }
2774
daniel@transgaming.com12985182012-12-20 20:56:31 +00002775 if (!applyRenderTarget(mode, false))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002776 {
2777 return;
2778 }
2779
2780 applyState(mode);
2781
daniel@transgaming.com31240482012-11-28 21:06:41 +00002782 rx::TranslatedIndexData indexInfo;
Jamie Madill57a89722013-07-02 11:57:03 -04002783 GLenum err = mRenderer->applyIndexBuffer(indices, vao->getElementArrayBuffer(), count, mode, type, &indexInfo);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002784 if (err != GL_NO_ERROR)
2785 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +00002786 return gl::error(err);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002787 }
2788
daniel@transgaming.com92025f52012-11-28 20:52:54 +00002789 ProgramBinary *programBinary = getCurrentProgramBinary();
2790
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002791 GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
Jamie Madill57a89722013-07-02 11:57:03 -04002792 err = mRenderer->applyVertexBuffer(programBinary, vao->getVertexAttributes(), mState.vertexAttribCurrentValues, indexInfo.minIndex, vertexCount, instances);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002793 if (err != GL_NO_ERROR)
2794 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +00002795 return gl::error(err);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002796 }
2797
2798 applyShaders();
2799 applyTextures();
2800
shannonwoods@chromium.org1bddfb92013-05-30 00:11:29 +00002801 if (!applyUniformBuffers())
2802 {
2803 return;
2804 }
2805
daniel@transgaming.com92025f52012-11-28 20:52:54 +00002806 if (!programBinary->validateSamplers(NULL))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002807 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +00002808 return gl::error(GL_INVALID_OPERATION);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002809 }
2810
daniel@transgaming.com087e5782012-09-17 21:28:47 +00002811 if (!skipDraw(mode))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002812 {
Jamie Madill57a89722013-07-02 11:57:03 -04002813 mRenderer->drawElements(mode, count, type, indices, vao->getElementArrayBuffer(), indexInfo, instances);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002814 }
2815}
2816
2817// Implements glFlush when block is false, glFinish when block is true
2818void Context::sync(bool block)
2819{
daniel@transgaming.comef21ab22012-10-31 17:52:47 +00002820 mRenderer->sync(block);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002821}
2822
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002823void Context::recordInvalidEnum()
2824{
2825 mInvalidEnum = true;
2826}
2827
2828void Context::recordInvalidValue()
2829{
2830 mInvalidValue = true;
2831}
2832
2833void Context::recordInvalidOperation()
2834{
2835 mInvalidOperation = true;
2836}
2837
2838void Context::recordOutOfMemory()
2839{
2840 mOutOfMemory = true;
2841}
2842
2843void Context::recordInvalidFramebufferOperation()
2844{
2845 mInvalidFramebufferOperation = true;
2846}
2847
2848// Get one of the recorded errors and clear its flag, if any.
2849// [OpenGL ES 2.0.24] section 2.5 page 13.
2850GLenum Context::getError()
2851{
2852 if (mInvalidEnum)
2853 {
2854 mInvalidEnum = false;
2855
2856 return GL_INVALID_ENUM;
2857 }
2858
2859 if (mInvalidValue)
2860 {
2861 mInvalidValue = false;
2862
2863 return GL_INVALID_VALUE;
2864 }
2865
2866 if (mInvalidOperation)
2867 {
2868 mInvalidOperation = false;
2869
2870 return GL_INVALID_OPERATION;
2871 }
2872
2873 if (mOutOfMemory)
2874 {
2875 mOutOfMemory = false;
2876
2877 return GL_OUT_OF_MEMORY;
2878 }
2879
2880 if (mInvalidFramebufferOperation)
2881 {
2882 mInvalidFramebufferOperation = false;
2883
2884 return GL_INVALID_FRAMEBUFFER_OPERATION;
2885 }
2886
2887 return GL_NO_ERROR;
2888}
2889
2890GLenum Context::getResetStatus()
2891{
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002892 if (mResetStatus == GL_NO_ERROR && !mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002893 {
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +00002894 // mResetStatus will be set by the markContextLost callback
2895 // in the case a notification is sent
2896 mRenderer->testDeviceLost(true);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002897 }
2898
2899 GLenum status = mResetStatus;
2900
2901 if (mResetStatus != GL_NO_ERROR)
2902 {
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002903 ASSERT(mContextLost);
2904
daniel@transgaming.com621ce052012-10-31 17:52:29 +00002905 if (mRenderer->testDeviceResettable())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002906 {
2907 mResetStatus = GL_NO_ERROR;
2908 }
2909 }
2910
2911 return status;
2912}
2913
2914bool Context::isResetNotificationEnabled()
2915{
2916 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2917}
2918
shannon.woods%transgaming.com@gtempaccount.comdaea4b42013-04-13 03:28:54 +00002919int Context::getClientVersion() const
2920{
2921 return mClientVersion;
2922}
2923
daniel@transgaming.com9549bea2012-11-28 20:57:23 +00002924int Context::getMajorShaderModel() const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002925{
daniel@transgaming.com9549bea2012-11-28 20:57:23 +00002926 return mMajorShaderModel;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002927}
2928
2929float Context::getMaximumPointSize() const
2930{
shannon.woods@transgaming.combd8c10c2013-01-25 21:15:03 +00002931 return mMaximumPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002932}
2933
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002934unsigned int Context::getMaximumCombinedTextureImageUnits() const
2935{
shannon.woods@transgaming.com76cd88c2013-01-25 21:54:36 +00002936 return mRenderer->getMaxCombinedTextureImageUnits();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002937}
2938
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00002939unsigned int Context::getMaximumCombinedUniformBufferBindings() const
2940{
2941 return mRenderer->getMaxVertexShaderUniformBuffers() +
2942 mRenderer->getMaxFragmentShaderUniformBuffers();
2943}
2944
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002945int Context::getMaxSupportedSamples() const
2946{
daniel@transgaming.comb7833982012-10-31 18:31:46 +00002947 return mRenderer->getMaxSupportedSamples();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002948}
2949
Geoff Lang0e120e32013-05-29 10:23:55 -04002950GLsizei Context::getMaxSupportedFormatSamples(GLint internalFormat) const
2951{
2952 return mRenderer->getMaxSupportedFormatSamples(internalFormat);
2953}
2954
Shannon Woods52f1e7e2013-07-08 10:32:17 -04002955GLsizei Context::getNumSampleCounts(GLint internalFormat) const
2956{
2957 return mRenderer->getNumSampleCounts(internalFormat);
2958}
2959
2960void Context::getSampleCounts(GLint internalFormat, GLsizei bufSize, GLint *params) const
2961{
2962 mRenderer->getSampleCounts(internalFormat, bufSize, params);
2963}
2964
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00002965unsigned int Context::getMaxTransformFeedbackBufferBindings() const
2966{
2967 return mRenderer->getMaxTransformFeedbackBuffers();
2968}
2969
shannonwoods@chromium.org97c3d502013-05-30 00:04:34 +00002970GLintptr Context::getUniformBufferOffsetAlignment() const
2971{
2972 // setting a large alignment forces uniform buffers to bind with zero offset
2973 return static_cast<GLintptr>(std::numeric_limits<GLint>::max());
2974}
2975
shannon.woods%transgaming.com@gtempaccount.com89ae1132013-04-13 03:28:43 +00002976unsigned int Context::getMaximumRenderTargets() const
2977{
2978 return mRenderer->getMaxRenderTargets();
2979}
2980
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002981bool Context::supportsEventQueries() const
2982{
2983 return mSupportsEventQueries;
2984}
2985
2986bool Context::supportsOcclusionQueries() const
2987{
2988 return mSupportsOcclusionQueries;
2989}
2990
shannon.woods@transgaming.combec04bf2013-01-25 21:53:52 +00002991bool Context::supportsBGRATextures() const
2992{
2993 return mSupportsBGRATextures;
2994}
2995
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002996bool Context::supportsDXT1Textures() const
2997{
2998 return mSupportsDXT1Textures;
2999}
3000
3001bool Context::supportsDXT3Textures() const
3002{
3003 return mSupportsDXT3Textures;
3004}
3005
3006bool Context::supportsDXT5Textures() const
3007{
3008 return mSupportsDXT5Textures;
3009}
3010
3011bool Context::supportsFloat32Textures() const
3012{
3013 return mSupportsFloat32Textures;
3014}
3015
3016bool Context::supportsFloat32LinearFilter() const
3017{
3018 return mSupportsFloat32LinearFilter;
3019}
3020
3021bool Context::supportsFloat32RenderableTextures() const
3022{
3023 return mSupportsFloat32RenderableTextures;
3024}
3025
3026bool Context::supportsFloat16Textures() const
3027{
3028 return mSupportsFloat16Textures;
3029}
3030
3031bool Context::supportsFloat16LinearFilter() const
3032{
3033 return mSupportsFloat16LinearFilter;
3034}
3035
3036bool Context::supportsFloat16RenderableTextures() const
3037{
3038 return mSupportsFloat16RenderableTextures;
3039}
3040
3041int Context::getMaximumRenderbufferDimension() const
3042{
3043 return mMaxRenderbufferDimension;
3044}
3045
shannon.woods%transgaming.com@gtempaccount.comc1fdf6b2013-04-13 03:44:41 +00003046int Context::getMaximum2DTextureDimension() const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003047{
shannon.woods%transgaming.com@gtempaccount.comc1fdf6b2013-04-13 03:44:41 +00003048 return mMax2DTextureDimension;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003049}
3050
3051int Context::getMaximumCubeTextureDimension() const
3052{
3053 return mMaxCubeTextureDimension;
3054}
3055
shannon.woods%transgaming.com@gtempaccount.comc1fdf6b2013-04-13 03:44:41 +00003056int Context::getMaximum3DTextureDimension() const
3057{
3058 return mMax3DTextureDimension;
3059}
3060
shannon.woods%transgaming.com@gtempaccount.coma98a8112013-04-13 03:45:57 +00003061int Context::getMaximum2DArrayTextureLayers() const
3062{
3063 return mMax2DArrayTextureLayers;
3064}
3065
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003066int Context::getMaximumTextureLevel() const
3067{
3068 return mMaxTextureLevel;
3069}
3070
3071bool Context::supportsLuminanceTextures() const
3072{
3073 return mSupportsLuminanceTextures;
3074}
3075
3076bool Context::supportsLuminanceAlphaTextures() const
3077{
3078 return mSupportsLuminanceAlphaTextures;
3079}
3080
3081bool Context::supportsDepthTextures() const
3082{
3083 return mSupportsDepthTextures;
3084}
3085
3086bool Context::supports32bitIndices() const
3087{
3088 return mSupports32bitIndices;
3089}
3090
3091bool Context::supportsNonPower2Texture() const
3092{
3093 return mSupportsNonPower2Texture;
3094}
3095
3096bool Context::supportsInstancing() const
3097{
3098 return mSupportsInstancing;
3099}
3100
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00003101bool Context::supportsTextureFilterAnisotropy() const
3102{
3103 return mSupportsTextureFilterAnisotropy;
3104}
3105
3106float Context::getTextureMaxAnisotropy() const
3107{
3108 return mMaxTextureAnisotropy;
3109}
3110
shannonwoods@chromium.org44a4f982013-05-30 00:13:49 +00003111bool Context::getCurrentReadFormatType(GLint *internalFormat, GLenum *format, GLenum *type)
daniel@transgaming.com42944b02012-09-27 17:45:57 +00003112{
3113 Framebuffer *framebuffer = getReadFramebuffer();
3114 if (!framebuffer || framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
3115 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +00003116 return gl::error(GL_INVALID_OPERATION, false);
daniel@transgaming.com42944b02012-09-27 17:45:57 +00003117 }
3118
shannon.woods%transgaming.com@gtempaccount.com89ae1132013-04-13 03:28:43 +00003119 Renderbuffer *renderbuffer = framebuffer->getReadColorbuffer();
daniel@transgaming.com42944b02012-09-27 17:45:57 +00003120 if (!renderbuffer)
3121 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +00003122 return gl::error(GL_INVALID_OPERATION, false);
daniel@transgaming.com42944b02012-09-27 17:45:57 +00003123 }
3124
shannonwoods@chromium.org44a4f982013-05-30 00:13:49 +00003125 *internalFormat = renderbuffer->getActualFormat();
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +00003126 *format = gl::GetFormat(renderbuffer->getActualFormat(), mClientVersion);
3127 *type = gl::GetType(renderbuffer->getActualFormat(), mClientVersion);
daniel@transgaming.com42944b02012-09-27 17:45:57 +00003128
3129 return true;
3130}
3131
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003132void Context::detachBuffer(GLuint buffer)
3133{
3134 // [OpenGL ES 2.0.24] section 2.9 page 22:
3135 // If a buffer object is deleted while it is bound, all bindings to that object in the current context
3136 // (i.e. in the thread that called Delete-Buffers) are reset to zero.
3137
3138 if (mState.arrayBuffer.id() == buffer)
3139 {
3140 mState.arrayBuffer.set(NULL);
3141 }
3142
Jamie Madill57a89722013-07-02 11:57:03 -04003143 // mark as freed among the vertex array objects
3144 for (auto vaoIt = mVertexArrayMap.begin(); vaoIt != mVertexArrayMap.end(); vaoIt++)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003145 {
Jamie Madill57a89722013-07-02 11:57:03 -04003146 vaoIt->second->detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003147 }
3148}
3149
3150void Context::detachTexture(GLuint texture)
3151{
3152 // [OpenGL ES 2.0.24] section 3.8 page 84:
3153 // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
3154 // rebound to texture object zero
3155
3156 for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
3157 {
shannon.woods@transgaming.com233fe952013-01-25 21:51:57 +00003158 for (int sampler = 0; sampler < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003159 {
3160 if (mState.samplerTexture[type][sampler].id() == texture)
3161 {
3162 mState.samplerTexture[type][sampler].set(NULL);
3163 }
3164 }
3165 }
3166
3167 // [OpenGL ES 2.0.24] section 4.4 page 112:
3168 // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
3169 // as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this
3170 // image was attached in the currently bound framebuffer.
3171
3172 Framebuffer *readFramebuffer = getReadFramebuffer();
3173 Framebuffer *drawFramebuffer = getDrawFramebuffer();
3174
3175 if (readFramebuffer)
3176 {
3177 readFramebuffer->detachTexture(texture);
3178 }
3179
3180 if (drawFramebuffer && drawFramebuffer != readFramebuffer)
3181 {
3182 drawFramebuffer->detachTexture(texture);
3183 }
3184}
3185
3186void Context::detachFramebuffer(GLuint framebuffer)
3187{
3188 // [OpenGL ES 2.0.24] section 4.4 page 107:
3189 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
3190 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
3191
3192 if (mState.readFramebuffer == framebuffer)
3193 {
3194 bindReadFramebuffer(0);
3195 }
3196
3197 if (mState.drawFramebuffer == framebuffer)
3198 {
3199 bindDrawFramebuffer(0);
3200 }
3201}
3202
3203void Context::detachRenderbuffer(GLuint renderbuffer)
3204{
3205 // [OpenGL ES 2.0.24] section 4.4 page 109:
3206 // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
3207 // had been executed with the target RENDERBUFFER and name of zero.
3208
3209 if (mState.renderbuffer.id() == renderbuffer)
3210 {
3211 bindRenderbuffer(0);
3212 }
3213
3214 // [OpenGL ES 2.0.24] section 4.4 page 111:
3215 // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
3216 // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
3217 // point to which this image was attached in the currently bound framebuffer.
3218
3219 Framebuffer *readFramebuffer = getReadFramebuffer();
3220 Framebuffer *drawFramebuffer = getDrawFramebuffer();
3221
3222 if (readFramebuffer)
3223 {
3224 readFramebuffer->detachRenderbuffer(renderbuffer);
3225 }
3226
3227 if (drawFramebuffer && drawFramebuffer != readFramebuffer)
3228 {
3229 drawFramebuffer->detachRenderbuffer(renderbuffer);
3230 }
3231}
3232
Jamie Madill57a89722013-07-02 11:57:03 -04003233void Context::detachVertexArray(GLuint vertexArray)
3234{
3235 // [OpenGL ES 3.0.2] section 2.10 page 43:
3236 // If a vertex array object that is currently bound is deleted, the binding
3237 // for that object reverts to zero and the default vertex array becomes current.
3238 if (mState.vertexArray == vertexArray)
3239 {
3240 bindVertexArray(0);
3241 }
3242}
3243
Jamie Madilldc356042013-07-19 16:36:57 -04003244void Context::detachSampler(GLuint sampler)
3245{
3246 // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
3247 // If a sampler object that is currently bound to one or more texture units is
3248 // deleted, it is as though BindSampler is called once for each texture unit to
3249 // which the sampler is bound, with unit set to the texture unit and sampler set to zero.
3250 for (unsigned int textureUnit = 0; textureUnit < ArraySize(mState.samplers); textureUnit++)
3251 {
3252 if (mState.samplers[textureUnit] == sampler)
3253 {
3254 mState.samplers[textureUnit] = 0;
3255 }
3256 }
3257}
3258
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003259Texture *Context::getIncompleteTexture(TextureType type)
3260{
3261 Texture *t = mIncompleteTextures[type].get();
3262
3263 if (t == NULL)
3264 {
3265 static const GLubyte color[] = { 0, 0, 0, 255 };
3266
3267 switch (type)
3268 {
3269 default:
3270 UNREACHABLE();
3271 // default falls through to TEXTURE_2D
3272
3273 case TEXTURE_2D:
3274 {
daniel@transgaming.com370482e2012-11-28 19:32:13 +00003275 Texture2D *incomplete2d = new Texture2D(mRenderer, Texture::INCOMPLETE_TEXTURE_ID);
shannonwoods@chromium.org4ad58e02013-05-30 00:08:11 +00003276 incomplete2d->setImage(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003277 t = incomplete2d;
3278 }
3279 break;
3280
3281 case TEXTURE_CUBE:
3282 {
daniel@transgaming.com370482e2012-11-28 19:32:13 +00003283 TextureCubeMap *incompleteCube = new TextureCubeMap(mRenderer, Texture::INCOMPLETE_TEXTURE_ID);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003284
shannonwoods@chromium.org4ad58e02013-05-30 00:08:11 +00003285 incompleteCube->setImagePosX(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
3286 incompleteCube->setImageNegX(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
3287 incompleteCube->setImagePosY(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
3288 incompleteCube->setImageNegY(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
3289 incompleteCube->setImagePosZ(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
3290 incompleteCube->setImageNegZ(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003291
3292 t = incompleteCube;
3293 }
3294 break;
shannonwoods@chromium.org18029cd2013-05-30 00:14:06 +00003295
3296 case TEXTURE_3D:
3297 {
3298 Texture3D *incomplete3d = new Texture3D(mRenderer, Texture::INCOMPLETE_TEXTURE_ID);
3299 incomplete3d->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
3300
3301 t = incomplete3d;
3302 }
3303 break;
3304
3305 case TEXTURE_2D_ARRAY:
3306 {
3307 Texture2DArray *incomplete2darray = new Texture2DArray(mRenderer, Texture::INCOMPLETE_TEXTURE_ID);
3308 incomplete2darray->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
3309
3310 t = incomplete2darray;
3311 }
3312 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003313 }
3314
3315 mIncompleteTextures[type].set(t);
3316 }
3317
3318 return t;
3319}
3320
daniel@transgaming.com087e5782012-09-17 21:28:47 +00003321bool Context::skipDraw(GLenum drawMode)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003322{
daniel@transgaming.com087e5782012-09-17 21:28:47 +00003323 if (drawMode == GL_POINTS)
3324 {
3325 // ProgramBinary assumes non-point rendering if gl_PointSize isn't written,
3326 // which affects varying interpolation. Since the value of gl_PointSize is
3327 // undefined when not written, just skip drawing to avoid unexpected results.
3328 if (!getCurrentProgramBinary()->usesPointSize())
3329 {
3330 // This is stictly speaking not an error, but developers should be
3331 // notified of risking undefined behavior.
3332 ERR("Point rendering without writing to gl_PointSize.");
3333
3334 return true;
3335 }
3336 }
daniel@transgaming.com97c852b2012-12-20 20:56:23 +00003337 else if (IsTriangleMode(drawMode))
daniel@transgaming.com087e5782012-09-17 21:28:47 +00003338 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00003339 if (mState.rasterizer.cullFace && mState.rasterizer.cullMode == GL_FRONT_AND_BACK)
daniel@transgaming.com087e5782012-09-17 21:28:47 +00003340 {
3341 return true;
3342 }
3343 }
3344
3345 return false;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003346}
3347
shannon.woods%transgaming.com@gtempaccount.coma8885862013-04-13 03:37:53 +00003348void Context::setVertexAttribf(GLuint index, const GLfloat values[4])
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003349{
3350 ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
Jamie Madilla857c362013-07-02 11:57:02 -04003351 mState.vertexAttribCurrentValues[index].setFloatValues(values);
shannon.woods%transgaming.com@gtempaccount.coma8885862013-04-13 03:37:53 +00003352}
3353
3354void Context::setVertexAttribu(GLuint index, const GLuint values[4])
3355{
3356 ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
Jamie Madilla857c362013-07-02 11:57:02 -04003357 mState.vertexAttribCurrentValues[index].setUnsignedIntValues(values);
shannon.woods%transgaming.com@gtempaccount.coma8885862013-04-13 03:37:53 +00003358}
3359
3360void Context::setVertexAttribi(GLuint index, const GLint values[4])
3361{
3362 ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
Jamie Madilla857c362013-07-02 11:57:02 -04003363 mState.vertexAttribCurrentValues[index].setIntValues(values);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003364}
3365
3366void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
3367{
Jamie Madill57a89722013-07-02 11:57:03 -04003368 getCurrentVertexArray()->setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003369}
3370
Jamie Madille29d1672013-07-19 16:36:57 -04003371void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
3372{
3373 mResourceManager->checkSamplerAllocation(sampler);
3374
3375 Sampler *samplerObject = getSampler(sampler);
3376 ASSERT(samplerObject);
3377
3378 switch (pname)
3379 {
3380 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(static_cast<GLenum>(param)); break;
3381 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(static_cast<GLenum>(param)); break;
3382 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(static_cast<GLenum>(param)); break;
3383 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(static_cast<GLenum>(param)); break;
3384 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(static_cast<GLenum>(param)); break;
3385 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(static_cast<GLfloat>(param)); break;
3386 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(static_cast<GLfloat>(param)); break;
3387 case GL_TEXTURE_COMPARE_MODE: samplerObject->setComparisonMode(static_cast<GLenum>(param)); break;
3388 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setComparisonFunc(static_cast<GLenum>(param)); break;
3389 default: UNREACHABLE(); break;
3390 }
3391}
3392
3393void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
3394{
3395 mResourceManager->checkSamplerAllocation(sampler);
3396
3397 Sampler *samplerObject = getSampler(sampler);
3398 ASSERT(samplerObject);
3399
3400 switch (pname)
3401 {
Jamie Madill9675b802013-07-19 16:36:59 -04003402 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(uiround<GLenum>(param)); break;
3403 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(uiround<GLenum>(param)); break;
3404 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(uiround<GLenum>(param)); break;
3405 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(uiround<GLenum>(param)); break;
3406 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(uiround<GLenum>(param)); break;
Jamie Madille29d1672013-07-19 16:36:57 -04003407 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(param); break;
3408 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(param); break;
Jamie Madill9675b802013-07-19 16:36:59 -04003409 case GL_TEXTURE_COMPARE_MODE: samplerObject->setComparisonMode(uiround<GLenum>(param)); break;
3410 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setComparisonFunc(uiround<GLenum>(param)); break;
Jamie Madille29d1672013-07-19 16:36:57 -04003411 default: UNREACHABLE(); break;
3412 }
3413}
3414
Jamie Madill9675b802013-07-19 16:36:59 -04003415GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname)
3416{
3417 mResourceManager->checkSamplerAllocation(sampler);
3418
3419 Sampler *samplerObject = getSampler(sampler);
3420 ASSERT(samplerObject);
3421
3422 switch (pname)
3423 {
3424 case GL_TEXTURE_MIN_FILTER: return static_cast<GLint>(samplerObject->getMinFilter());
3425 case GL_TEXTURE_MAG_FILTER: return static_cast<GLint>(samplerObject->getMagFilter());
3426 case GL_TEXTURE_WRAP_S: return static_cast<GLint>(samplerObject->getWrapS());
3427 case GL_TEXTURE_WRAP_T: return static_cast<GLint>(samplerObject->getWrapT());
3428 case GL_TEXTURE_WRAP_R: return static_cast<GLint>(samplerObject->getWrapR());
3429 case GL_TEXTURE_MIN_LOD: return uiround<GLint>(samplerObject->getMinLod());
3430 case GL_TEXTURE_MAX_LOD: return uiround<GLint>(samplerObject->getMaxLod());
3431 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLint>(samplerObject->getComparisonMode());
3432 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLint>(samplerObject->getComparisonFunc());
3433 default: UNREACHABLE(); return 0;
3434 }
3435}
3436
3437GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname)
3438{
3439 mResourceManager->checkSamplerAllocation(sampler);
3440
3441 Sampler *samplerObject = getSampler(sampler);
3442 ASSERT(samplerObject);
3443
3444 switch (pname)
3445 {
3446 case GL_TEXTURE_MIN_FILTER: return static_cast<GLfloat>(samplerObject->getMinFilter());
3447 case GL_TEXTURE_MAG_FILTER: return static_cast<GLfloat>(samplerObject->getMagFilter());
3448 case GL_TEXTURE_WRAP_S: return static_cast<GLfloat>(samplerObject->getWrapS());
3449 case GL_TEXTURE_WRAP_T: return static_cast<GLfloat>(samplerObject->getWrapT());
3450 case GL_TEXTURE_WRAP_R: return static_cast<GLfloat>(samplerObject->getWrapR());
3451 case GL_TEXTURE_MIN_LOD: return samplerObject->getMinLod();
3452 case GL_TEXTURE_MAX_LOD: return samplerObject->getMaxLod();
3453 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLfloat>(samplerObject->getComparisonMode());
3454 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLfloat>(samplerObject->getComparisonFunc());
3455 default: UNREACHABLE(); return 0;
3456 }
3457}
3458
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003459// keep list sorted in following order
3460// OES extensions
3461// EXT extensions
3462// Vendor extensions
3463void Context::initExtensionString()
3464{
shannonwoods@chromium.org302df742013-05-30 00:05:54 +00003465 // Do not report extension in GLES 3 contexts for now
3466 if (mClientVersion == 2)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003467 {
shannonwoods@chromium.org302df742013-05-30 00:05:54 +00003468 // OES extensions
3469 if (supports32bitIndices())
3470 {
3471 mExtensionStringList.push_back("GL_OES_element_index_uint");
3472 }
3473
3474 mExtensionStringList.push_back("GL_OES_packed_depth_stencil");
3475 mExtensionStringList.push_back("GL_OES_get_program_binary");
3476 mExtensionStringList.push_back("GL_OES_rgb8_rgba8");
3477 if (mRenderer->getDerivativeInstructionSupport())
3478 {
3479 mExtensionStringList.push_back("GL_OES_standard_derivatives");
3480 }
3481
3482 if (supportsFloat16Textures())
3483 {
3484 mExtensionStringList.push_back("GL_OES_texture_half_float");
3485 }
3486 if (supportsFloat16LinearFilter())
3487 {
3488 mExtensionStringList.push_back("GL_OES_texture_half_float_linear");
3489 }
3490 if (supportsFloat32Textures())
3491 {
3492 mExtensionStringList.push_back("GL_OES_texture_float");
3493 }
3494 if (supportsFloat32LinearFilter())
3495 {
3496 mExtensionStringList.push_back("GL_OES_texture_float_linear");
3497 }
3498
3499 if (supportsNonPower2Texture())
3500 {
3501 mExtensionStringList.push_back("GL_OES_texture_npot");
3502 }
3503
3504 // Multi-vendor (EXT) extensions
3505 if (supportsOcclusionQueries())
3506 {
3507 mExtensionStringList.push_back("GL_EXT_occlusion_query_boolean");
3508 }
3509
3510 mExtensionStringList.push_back("GL_EXT_read_format_bgra");
3511 mExtensionStringList.push_back("GL_EXT_robustness");
3512
3513 if (supportsDXT1Textures())
3514 {
3515 mExtensionStringList.push_back("GL_EXT_texture_compression_dxt1");
3516 }
3517
3518 if (supportsTextureFilterAnisotropy())
3519 {
3520 mExtensionStringList.push_back("GL_EXT_texture_filter_anisotropic");
3521 }
3522
3523 if (supportsBGRATextures())
3524 {
3525 mExtensionStringList.push_back("GL_EXT_texture_format_BGRA8888");
3526 }
3527
3528 if (mRenderer->getMaxRenderTargets() > 1)
3529 {
3530 mExtensionStringList.push_back("GL_EXT_draw_buffers");
3531 }
3532
3533 mExtensionStringList.push_back("GL_EXT_texture_storage");
Jamie Madill2aeb26a2013-07-08 14:02:55 -04003534 mExtensionStringList.push_back("GL_EXT_frag_depth");
shannonwoods@chromium.org302df742013-05-30 00:05:54 +00003535
3536 // ANGLE-specific extensions
3537 if (supportsDepthTextures())
3538 {
3539 mExtensionStringList.push_back("GL_ANGLE_depth_texture");
3540 }
3541
3542 mExtensionStringList.push_back("GL_ANGLE_framebuffer_blit");
3543 if (getMaxSupportedSamples() != 0)
3544 {
3545 mExtensionStringList.push_back("GL_ANGLE_framebuffer_multisample");
3546 }
3547
3548 if (supportsInstancing())
3549 {
3550 mExtensionStringList.push_back("GL_ANGLE_instanced_arrays");
3551 }
3552
3553 mExtensionStringList.push_back("GL_ANGLE_pack_reverse_row_order");
3554
3555 if (supportsDXT3Textures())
3556 {
3557 mExtensionStringList.push_back("GL_ANGLE_texture_compression_dxt3");
3558 }
3559 if (supportsDXT5Textures())
3560 {
3561 mExtensionStringList.push_back("GL_ANGLE_texture_compression_dxt5");
3562 }
3563
3564 mExtensionStringList.push_back("GL_ANGLE_texture_usage");
3565 mExtensionStringList.push_back("GL_ANGLE_translated_shader_source");
3566
3567 // Other vendor-specific extensions
3568 if (supportsEventQueries())
3569 {
3570 mExtensionStringList.push_back("GL_NV_fence");
3571 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003572 }
3573
shannonwoods@chromium.org302df742013-05-30 00:05:54 +00003574 // Join the extension strings to one long string for use with GetString
3575 std::stringstream strstr;
3576 for (unsigned int extensionIndex = 0; extensionIndex < mExtensionStringList.size(); extensionIndex++)
daniel@transgaming.com7629bb62013-01-11 04:12:28 +00003577 {
shannonwoods@chromium.org302df742013-05-30 00:05:54 +00003578 strstr << mExtensionStringList[extensionIndex];
3579 strstr << " ";
daniel@transgaming.com7629bb62013-01-11 04:12:28 +00003580 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003581
shannonwoods@chromium.org302df742013-05-30 00:05:54 +00003582 mCombinedExtensionsString = makeStaticString(strstr.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003583}
3584
shannonwoods@chromium.org302df742013-05-30 00:05:54 +00003585const char *Context::getCombinedExtensionsString() const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003586{
shannonwoods@chromium.org302df742013-05-30 00:05:54 +00003587 return mCombinedExtensionsString;
3588}
3589
3590const char *Context::getExtensionString(const GLuint index) const
3591{
3592 ASSERT(index < mExtensionStringList.size());
3593 return mExtensionStringList[index].c_str();
3594}
3595
3596unsigned int Context::getNumExtensions() const
3597{
3598 return mExtensionStringList.size();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003599}
3600
3601void Context::initRendererString()
3602{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00003603 std::ostringstream rendererString;
3604 rendererString << "ANGLE (";
3605 rendererString << mRenderer->getRendererDescription();
3606 rendererString << ")";
3607
3608 mRendererString = makeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003609}
3610
3611const char *Context::getRendererString() const
3612{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00003613 return mRendererString;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003614}
3615
Geoff Lang758d5b22013-06-11 11:42:50 -04003616void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
3617 GLbitfield mask, GLenum filter)
3618{
3619 Framebuffer *readFramebuffer = getReadFramebuffer();
3620 Framebuffer *drawFramebuffer = getDrawFramebuffer();
3621
3622 bool blitRenderTarget = false;
Geoff Lang685806d2013-06-12 11:16:36 -04003623 bool blitDepth = false;
3624 bool blitStencil = false;
Geoff Lang758d5b22013-06-11 11:42:50 -04003625 if ((mask & GL_COLOR_BUFFER_BIT) && readFramebuffer->getReadColorbuffer() && drawFramebuffer->getFirstColorbuffer())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003626 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003627 blitRenderTarget = true;
Geoff Lang758d5b22013-06-11 11:42:50 -04003628 }
3629 if ((mask & GL_STENCIL_BUFFER_BIT) && readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())
3630 {
Geoff Lang685806d2013-06-12 11:16:36 -04003631 blitStencil = true;
Geoff Lang758d5b22013-06-11 11:42:50 -04003632 }
3633 if ((mask & GL_DEPTH_BUFFER_BIT) && readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())
3634 {
Geoff Lang685806d2013-06-12 11:16:36 -04003635 blitDepth = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003636 }
3637
Geoff Lang125deab2013-08-09 13:34:16 -04003638 gl::Rectangle srcRect(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
3639 gl::Rectangle dstRect(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
Geoff Lang685806d2013-06-12 11:16:36 -04003640 if (blitRenderTarget || blitDepth || blitStencil)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003641 {
Geoff Lang125deab2013-08-09 13:34:16 -04003642 const gl::Rectangle *scissor = mState.scissorTest ? &mState.scissor : NULL;
3643 mRenderer->blitRect(readFramebuffer, srcRect, drawFramebuffer, dstRect, scissor,
Geoff Lang685806d2013-06-12 11:16:36 -04003644 blitRenderTarget, blitDepth, blitStencil, filter);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003645 }
3646}
3647
shannonwoods@chromium.orgd63ef892013-05-30 00:10:56 +00003648void Context::invalidateFrameBuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments,
3649 GLint x, GLint y, GLsizei width, GLsizei height)
3650{
3651 Framebuffer *frameBuffer = NULL;
3652 switch (target)
3653 {
3654 case GL_FRAMEBUFFER:
3655 case GL_DRAW_FRAMEBUFFER:
3656 frameBuffer = getDrawFramebuffer();
3657 break;
3658 case GL_READ_FRAMEBUFFER:
3659 frameBuffer = getReadFramebuffer();
3660 break;
3661 default:
3662 UNREACHABLE();
3663 }
3664
3665 if (frameBuffer && frameBuffer->completeness() == GL_FRAMEBUFFER_COMPLETE)
3666 {
3667 for (int i = 0; i < numAttachments; ++i)
3668 {
3669 rx::RenderTarget *renderTarget = NULL;
3670
3671 if (attachments[i] >= GL_COLOR_ATTACHMENT0 && attachments[i] <= GL_COLOR_ATTACHMENT15)
3672 {
3673 gl::Renderbuffer *renderBuffer = frameBuffer->getColorbuffer(attachments[i] - GL_COLOR_ATTACHMENT0);
3674 if (renderBuffer)
3675 {
3676 renderTarget = renderBuffer->getRenderTarget();
3677 }
3678 }
3679 else if (attachments[i] == GL_COLOR)
3680 {
3681 gl::Renderbuffer *renderBuffer = frameBuffer->getColorbuffer(0);
3682 if (renderBuffer)
3683 {
3684 renderTarget = renderBuffer->getRenderTarget();
3685 }
3686 }
3687 else
3688 {
3689 gl::Renderbuffer *renderBuffer = NULL;
3690 switch (attachments[i])
3691 {
3692 case GL_DEPTH_ATTACHMENT:
3693 case GL_DEPTH:
3694 renderBuffer = frameBuffer->getDepthbuffer();
3695 break;
3696 case GL_STENCIL_ATTACHMENT:
3697 case GL_STENCIL:
3698 renderBuffer = frameBuffer->getStencilbuffer();
3699 break;
3700 case GL_DEPTH_STENCIL_ATTACHMENT:
3701 renderBuffer = frameBuffer->getDepthOrStencilbuffer();
3702 break;
3703 default:
3704 UNREACHABLE();
3705 }
3706
3707 if (renderBuffer)
3708 {
3709 renderTarget = renderBuffer->getDepthStencil();
3710 }
3711 }
3712
3713 if (renderTarget)
3714 {
3715 renderTarget->invalidate(x, y, width, height);
3716 }
3717 }
3718 }
3719}
3720
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003721}
3722
3723extern "C"
3724{
shannon.woods%transgaming.com@gtempaccount.comdaea4b42013-04-13 03:28:54 +00003725gl::Context *glCreateContext(int clientVersion, const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003726{
shannon.woods%transgaming.com@gtempaccount.comdaea4b42013-04-13 03:28:54 +00003727 return new gl::Context(clientVersion, shareContext, renderer, notifyResets, robustAccess);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003728}
3729
3730void glDestroyContext(gl::Context *context)
3731{
3732 delete context;
3733
3734 if (context == gl::getContext())
3735 {
3736 gl::makeCurrent(NULL, NULL, NULL);
3737 }
3738}
3739
3740void glMakeCurrent(gl::Context *context, egl::Display *display, egl::Surface *surface)
3741{
3742 gl::makeCurrent(context, display, surface);
3743}
3744
3745gl::Context *glGetCurrentContext()
3746{
3747 return gl::getContext();
3748}
daniel@transgaming.com621ce052012-10-31 17:52:29 +00003749
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003750}