blob: bd9508a0de141801bd08fdb8803f9c9e89ea10a1 [file] [log] [blame]
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001//
Geoff Langeeba6e12014-02-03 13:12:30 -05002// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// Context.cpp: Implements the gl::Context class, managing all GL state and performing
8// rendering operations. It is the GLES2 specific implementation of EGLContext.
9
Geoff Lang2b5420c2014-11-19 14:20:15 -050010#include "libANGLE/Context.h"
apatrick@chromium.org144f2802012-07-12 01:42:34 +000011
Jamie Madill231c7f52017-04-26 13:45:37 -040012#include <string.h>
Jamie Madillb9293972015-02-19 11:07:54 -050013#include <iterator>
14#include <sstream>
Sami Väisänend59ca052016-06-21 16:10:00 +030015#include <vector>
Jamie Madillb9293972015-02-19 11:07:54 -050016
Sami Väisänene45e53b2016-05-25 10:36:04 +030017#include "common/matrix_utils.h"
Geoff Lang0b7eef72014-06-12 14:10:47 -040018#include "common/platform.h"
Jamie Madillb9293972015-02-19 11:07:54 -050019#include "common/utilities.h"
Geoff Langc339c4e2016-11-29 10:37:36 -050020#include "common/version.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050021#include "libANGLE/Buffer.h"
Jamie Madillb9293972015-02-19 11:07:54 -050022#include "libANGLE/Compiler.h"
Jamie Madill948bbe52017-06-01 13:10:42 -040023#include "libANGLE/Display.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050024#include "libANGLE/Fence.h"
25#include "libANGLE/Framebuffer.h"
26#include "libANGLE/FramebufferAttachment.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030027#include "libANGLE/Path.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050028#include "libANGLE/Program.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050029#include "libANGLE/Query.h"
Jamie Madillb9293972015-02-19 11:07:54 -050030#include "libANGLE/Renderbuffer.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050031#include "libANGLE/ResourceManager.h"
32#include "libANGLE/Sampler.h"
Jamie Madill9dd0cf02014-11-24 11:38:51 -050033#include "libANGLE/Surface.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050034#include "libANGLE/Texture.h"
35#include "libANGLE/TransformFeedback.h"
36#include "libANGLE/VertexArray.h"
Kenneth Russellf2f6f652016-10-05 19:53:23 -070037#include "libANGLE/Workarounds.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040038#include "libANGLE/formatutils.h"
Martin Radev66fb8202016-07-28 11:45:20 +030039#include "libANGLE/queryconversions.h"
Geoff Langc1984ed2016-10-07 12:41:00 -040040#include "libANGLE/queryutils.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040041#include "libANGLE/renderer/ContextImpl.h"
42#include "libANGLE/renderer/EGLImplFactory.h"
43#include "libANGLE/validationES.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000044
Geoff Langf6db0982015-08-25 13:04:00 -040045namespace
46{
47
Ian Ewell3ffd78b2016-01-22 16:09:42 -050048template <typename T>
Geoff Lang4ddf5af2016-12-01 14:30:44 -050049std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
Sami Väisänend59ca052016-06-21 16:10:00 +030050 GLsizei numPaths,
51 const void *paths,
52 GLuint pathBase)
53{
54 std::vector<gl::Path *> ret;
55 ret.reserve(numPaths);
56
57 const auto *nameArray = static_cast<const T *>(paths);
58
59 for (GLsizei i = 0; i < numPaths; ++i)
60 {
61 const GLuint pathName = nameArray[i] + pathBase;
62
63 ret.push_back(resourceManager.getPath(pathName));
64 }
65
66 return ret;
67}
68
Geoff Lang4ddf5af2016-12-01 14:30:44 -050069std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
Sami Väisänend59ca052016-06-21 16:10:00 +030070 GLsizei numPaths,
71 GLenum pathNameType,
72 const void *paths,
73 GLuint pathBase)
74{
75 switch (pathNameType)
76 {
77 case GL_UNSIGNED_BYTE:
78 return GatherPaths<GLubyte>(resourceManager, numPaths, paths, pathBase);
79
80 case GL_BYTE:
81 return GatherPaths<GLbyte>(resourceManager, numPaths, paths, pathBase);
82
83 case GL_UNSIGNED_SHORT:
84 return GatherPaths<GLushort>(resourceManager, numPaths, paths, pathBase);
85
86 case GL_SHORT:
87 return GatherPaths<GLshort>(resourceManager, numPaths, paths, pathBase);
88
89 case GL_UNSIGNED_INT:
90 return GatherPaths<GLuint>(resourceManager, numPaths, paths, pathBase);
91
92 case GL_INT:
93 return GatherPaths<GLint>(resourceManager, numPaths, paths, pathBase);
94 }
95
96 UNREACHABLE();
97 return std::vector<gl::Path *>();
98}
99
100template <typename T>
Geoff Lang2186c382016-10-14 10:54:54 -0400101gl::Error GetQueryObjectParameter(gl::Query *query, GLenum pname, T *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500102{
Geoff Lang2186c382016-10-14 10:54:54 -0400103 ASSERT(query != nullptr);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500104
105 switch (pname)
106 {
107 case GL_QUERY_RESULT_EXT:
Geoff Lang2186c382016-10-14 10:54:54 -0400108 return query->getResult(params);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500109 case GL_QUERY_RESULT_AVAILABLE_EXT:
110 {
111 bool available;
Geoff Lang2186c382016-10-14 10:54:54 -0400112 gl::Error error = query->isResultAvailable(&available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500113 if (!error.isError())
114 {
Geoff Lang2186c382016-10-14 10:54:54 -0400115 *params = gl::ConvertFromGLboolean<T>(available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500116 }
117 return error;
118 }
119 default:
120 UNREACHABLE();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500121 return gl::InternalError() << "Unreachable Error";
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500122 }
123}
124
Geoff Langf6db0982015-08-25 13:04:00 -0400125void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback)
126{
Geoff Lang1a683462015-09-29 15:09:59 -0400127 if (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
Geoff Langf6db0982015-08-25 13:04:00 -0400128 {
129 for (size_t tfBufferIndex = 0; tfBufferIndex < transformFeedback->getIndexedBufferCount();
130 tfBufferIndex++)
131 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400132 const gl::OffsetBindingPointer<gl::Buffer> &buffer =
Geoff Langf6db0982015-08-25 13:04:00 -0400133 transformFeedback->getIndexedBuffer(tfBufferIndex);
134 if (buffer.get() != nullptr)
135 {
136 buffer->onTransformFeedback();
137 }
138 }
139 }
140}
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500141
142// Attribute map queries.
Martin Radev1be913c2016-07-11 17:59:16 +0300143EGLint GetClientMajorVersion(const egl::AttributeMap &attribs)
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500144{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400145 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1));
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500146}
147
Martin Radev1be913c2016-07-11 17:59:16 +0300148EGLint GetClientMinorVersion(const egl::AttributeMap &attribs)
149{
150 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_MINOR_VERSION, 0));
151}
152
Geoff Langeb66a6e2016-10-31 13:06:12 -0400153gl::Version GetClientVersion(const egl::AttributeMap &attribs)
154{
155 return gl::Version(GetClientMajorVersion(attribs), GetClientMinorVersion(attribs));
156}
157
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500158GLenum GetResetStrategy(const egl::AttributeMap &attribs)
159{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400160 EGLAttrib attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
161 EGL_NO_RESET_NOTIFICATION_EXT);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500162 switch (attrib)
163 {
164 case EGL_NO_RESET_NOTIFICATION:
165 return GL_NO_RESET_NOTIFICATION_EXT;
166 case EGL_LOSE_CONTEXT_ON_RESET:
167 return GL_LOSE_CONTEXT_ON_RESET_EXT;
168 default:
169 UNREACHABLE();
170 return GL_NONE;
171 }
172}
173
174bool GetRobustAccess(const egl::AttributeMap &attribs)
175{
Geoff Lang077f20a2016-11-01 10:08:02 -0400176 return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE) ||
177 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) !=
178 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500179}
180
181bool GetDebug(const egl::AttributeMap &attribs)
182{
Geoff Lang077f20a2016-11-01 10:08:02 -0400183 return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE) ||
184 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR) != 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500185}
186
187bool GetNoError(const egl::AttributeMap &attribs)
188{
189 return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
190}
191
Geoff Langc287ea62016-09-16 14:46:51 -0400192bool GetWebGLContext(const egl::AttributeMap &attribs)
193{
194 return (attribs.get(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE, EGL_FALSE) == EGL_TRUE);
195}
196
Geoff Langf41a7152016-09-19 15:11:17 -0400197bool GetBindGeneratesResource(const egl::AttributeMap &attribs)
198{
199 return (attribs.get(EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE) == EGL_TRUE);
200}
201
Geoff Langfeb8c682017-02-13 16:07:35 -0500202bool GetClientArraysEnabled(const egl::AttributeMap &attribs)
203{
204 return (attribs.get(EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE, EGL_TRUE) == EGL_TRUE);
205}
206
Martin Radev9d901792016-07-15 15:58:58 +0300207std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
208{
209 std::string labelName;
210 if (label != nullptr)
211 {
212 size_t labelLength = length < 0 ? strlen(label) : length;
213 labelName = std::string(label, labelLength);
214 }
215 return labelName;
216}
217
218void GetObjectLabelBase(const std::string &objectLabel,
219 GLsizei bufSize,
220 GLsizei *length,
221 GLchar *label)
222{
223 size_t writeLength = objectLabel.length();
224 if (label != nullptr && bufSize > 0)
225 {
226 writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
227 std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
228 label[writeLength] = '\0';
229 }
230
231 if (length != nullptr)
232 {
233 *length = static_cast<GLsizei>(writeLength);
234 }
235}
236
Geoff Langf6db0982015-08-25 13:04:00 -0400237} // anonymous namespace
238
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000239namespace gl
240{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000241
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400242Context::Context(rx::EGLImplFactory *implFactory,
243 const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400244 const Context *shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500245 TextureManager *shareTextures,
Jamie Madill32447362017-06-28 14:53:52 -0400246 MemoryProgramCache *memoryProgramCache,
Corentin Wallezc295e512017-01-27 17:47:50 -0500247 const egl::AttributeMap &attribs,
Jamie Madill948bbe52017-06-01 13:10:42 -0400248 const egl::DisplayExtensions &displayExtensions,
249 bool robustResourceInit)
Martin Radev1be913c2016-07-11 17:59:16 +0300250
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500251 : ValidationContext(shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500252 shareTextures,
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500253 GetClientVersion(attribs),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700254 &mGLState,
Jamie Madillf25855c2015-11-03 11:06:18 -0500255 mCaps,
256 mTextureCaps,
257 mExtensions,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500258 mLimitations,
259 GetNoError(attribs)),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700260 mImplementation(implFactory->createContext(mState)),
Jamie Madill2f348d22017-06-05 10:50:59 -0400261 mCompiler(),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400262 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500263 mClientType(EGL_OPENGL_ES_API),
264 mHasBeenCurrent(false),
265 mContextLost(false),
266 mResetStatus(GL_NO_ERROR),
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700267 mContextLostForced(false),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500268 mResetStrategy(GetResetStrategy(attribs)),
269 mRobustAccess(GetRobustAccess(attribs)),
Jamie Madill61e16b42017-06-19 11:13:23 -0400270 mCurrentSurface(static_cast<egl::Surface *>(EGL_NO_SURFACE)),
271 mCurrentDisplay(static_cast<egl::Display *>(EGL_NO_DISPLAY)),
Jamie Madill4e0e6f82017-02-17 11:06:03 -0500272 mSurfacelessFramebuffer(nullptr),
Jamie Madille14951e2017-03-09 18:55:16 -0500273 mWebGLContext(GetWebGLContext(attribs)),
Jamie Madill32447362017-06-28 14:53:52 -0400274 mMemoryProgramCache(memoryProgramCache),
Jamie Madille14951e2017-03-09 18:55:16 -0500275 mScratchBuffer(1000u)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000276{
Geoff Lang077f20a2016-11-01 10:08:02 -0400277 if (mRobustAccess)
278 {
279 UNIMPLEMENTED();
280 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000281
Jamie Madill4e0e6f82017-02-17 11:06:03 -0500282 initCaps(displayExtensions);
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700283 initWorkarounds();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400284
Jamie Madill4928b7c2017-06-20 12:57:39 -0400285 mGLState.initialize(this, GetDebug(attribs), GetBindGeneratesResource(attribs),
286 GetClientArraysEnabled(attribs), robustResourceInit);
Régis Fénéon83107972015-02-05 12:57:44 +0100287
Shannon Woods53a94a82014-06-24 15:20:36 -0400288 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400289
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000290 // [OpenGL ES 2.0.24] section 3.7 page 83:
291 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
292 // and cube map texture state vectors respectively associated with them.
293 // In order that access to these initial textures not be lost, they are treated as texture
294 // objects all of whose names are 0.
295
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400296 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400297 mZeroTextures[GL_TEXTURE_2D].set(this, zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500298
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400299 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400300 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(this, zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400301
Geoff Langeb66a6e2016-10-31 13:06:12 -0400302 if (getClientVersion() >= Version(3, 0))
Geoff Lang76b10c92014-09-05 16:28:14 -0400303 {
304 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400305 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400306 mZeroTextures[GL_TEXTURE_3D].set(this, zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400307
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400308 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400309 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(this, zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400310 }
Geoff Lang3b573612016-10-31 14:08:10 -0400311 if (getClientVersion() >= Version(3, 1))
312 {
313 Texture *zeroTexture2DMultisample =
314 new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_MULTISAMPLE);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400315 mZeroTextures[GL_TEXTURE_2D_MULTISAMPLE].set(this, zeroTexture2DMultisample);
Jiajia Qin6eafb042016-12-27 17:04:07 +0800316
317 bindGenericAtomicCounterBuffer(0);
318 for (unsigned int i = 0; i < mCaps.maxAtomicCounterBufferBindings; i++)
319 {
320 bindIndexedAtomicCounterBuffer(0, i, 0, 0);
321 }
Jiajia Qinf546e7d2017-03-27 14:12:59 +0800322
323 bindGenericShaderStorageBuffer(0);
324 for (unsigned int i = 0; i < mCaps.maxShaderStorageBufferBindings; i++)
325 {
326 bindIndexedShaderStorageBuffer(0, i, 0, 0);
327 }
Geoff Lang3b573612016-10-31 14:08:10 -0400328 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000329
Ian Ewellbda75592016-04-18 17:25:54 -0400330 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
331 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400332 Texture *zeroTextureExternal =
333 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400334 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(this, zeroTextureExternal);
Ian Ewellbda75592016-04-18 17:25:54 -0400335 }
336
Jamie Madill4928b7c2017-06-20 12:57:39 -0400337 mGLState.initializeZeroTextures(this, mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500338
Jamie Madill57a89722013-07-02 11:57:03 -0400339 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000340 bindArrayBuffer(0);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800341 bindDrawIndirectBuffer(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000342 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400343
Jamie Madill01a80ee2016-11-07 12:06:18 -0500344 bindRenderbuffer(GL_RENDERBUFFER, 0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000345
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000346 bindGenericUniformBuffer(0);
Geoff Lang4dc3af02016-11-18 14:09:27 -0500347 for (unsigned int i = 0; i < mCaps.maxUniformBufferBindings; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000348 {
349 bindIndexedUniformBuffer(0, i, 0, -1);
350 }
351
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000352 bindCopyReadBuffer(0);
353 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000354 bindPixelPackBuffer(0);
355 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000356
Geoff Langeb66a6e2016-10-31 13:06:12 -0400357 if (getClientVersion() >= Version(3, 0))
Geoff Lang1a683462015-09-29 15:09:59 -0400358 {
359 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
360 // In the initial state, a default transform feedback object is bound and treated as
361 // a transform feedback object with a name of zero. That object is bound any time
362 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400363 bindTransformFeedback(0);
364 }
Geoff Langc8058452014-02-03 12:04:11 -0500365
Jamie Madillad9f24e2016-02-12 09:27:24 -0500366 // Initialize dirty bit masks
367 // TODO(jmadill): additional ES3 state
368 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
369 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
370 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
371 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
372 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
373 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400374 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500375 // No dirty objects.
376
377 // Readpixels uses the pack state and read FBO
378 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
379 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
380 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
381 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
382 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400383 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500384 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
385
386 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
387 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
388 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
389 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
390 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
391 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
392 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
393 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
394 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
395 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
396 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
397 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
398
399 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
400 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700401 mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500402 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
403 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400404
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400405 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000406}
407
Jamie Madill4928b7c2017-06-20 12:57:39 -0400408egl::Error Context::onDestroy(const egl::Display *display)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000409{
Corentin Wallez80b24112015-08-25 16:41:57 -0400410 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000411 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400412 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000413 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400414 mFenceNVMap.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000415
Corentin Wallez80b24112015-08-25 16:41:57 -0400416 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000417 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400418 if (query.second != nullptr)
419 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400420 query.second->release(this);
Geoff Langf0aa8422015-09-29 15:08:34 -0400421 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000422 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400423 mQueryMap.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000424
Corentin Wallez80b24112015-08-25 16:41:57 -0400425 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400426 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400427 if (vertexArray.second)
428 {
429 vertexArray.second->onDestroy(this);
430 }
Jamie Madill57a89722013-07-02 11:57:03 -0400431 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400432 mVertexArrayMap.clear();
Jamie Madill57a89722013-07-02 11:57:03 -0400433
Corentin Wallez80b24112015-08-25 16:41:57 -0400434 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500435 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500436 if (transformFeedback.second != nullptr)
437 {
Jamie Madill6c1f6712017-02-14 19:08:04 -0500438 transformFeedback.second->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500439 }
Geoff Langc8058452014-02-03 12:04:11 -0500440 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400441 mTransformFeedbackMap.clear();
Geoff Langc8058452014-02-03 12:04:11 -0500442
Jamie Madilldedd7b92014-11-05 16:30:36 -0500443 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400444 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400445 zeroTexture.second->onDestroy(this);
446 zeroTexture.second.set(this, nullptr);
Geoff Lang76b10c92014-09-05 16:28:14 -0400447 }
448 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000449
Corentin Wallezccab69d2017-01-27 16:57:15 -0500450 SafeDelete(mSurfacelessFramebuffer);
451
Jamie Madill4928b7c2017-06-20 12:57:39 -0400452 ANGLE_TRY(releaseSurface(display));
Jamie Madill2f348d22017-06-05 10:50:59 -0400453 releaseShaderCompiler();
Jamie Madill6c1f6712017-02-14 19:08:04 -0500454
Jamie Madill4928b7c2017-06-20 12:57:39 -0400455 mGLState.reset(this);
456
Jamie Madill6c1f6712017-02-14 19:08:04 -0500457 mState.mBuffers->release(this);
458 mState.mShaderPrograms->release(this);
459 mState.mTextures->release(this);
460 mState.mRenderbuffers->release(this);
461 mState.mSamplers->release(this);
462 mState.mFenceSyncs->release(this);
463 mState.mPaths->release(this);
464 mState.mFramebuffers->release(this);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400465
466 return egl::NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000467}
468
Jamie Madill70ee0f62017-02-06 16:04:20 -0500469Context::~Context()
470{
471}
472
Jamie Madill4928b7c2017-06-20 12:57:39 -0400473egl::Error Context::makeCurrent(egl::Display *display, egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000474{
Jamie Madill61e16b42017-06-19 11:13:23 -0400475 mCurrentDisplay = display;
476
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000477 if (!mHasBeenCurrent)
478 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000479 initRendererString();
Geoff Langc339c4e2016-11-29 10:37:36 -0500480 initVersionStrings();
Geoff Langcec35902014-04-16 10:52:36 -0400481 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000482
Corentin Wallezc295e512017-01-27 17:47:50 -0500483 int width = 0;
484 int height = 0;
485 if (surface != nullptr)
486 {
487 width = surface->getWidth();
488 height = surface->getHeight();
489 }
490
491 mGLState.setViewportParams(0, 0, width, height);
492 mGLState.setScissorParams(0, 0, width, height);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000493
494 mHasBeenCurrent = true;
495 }
496
Jamie Madill1b94d432015-08-07 13:23:23 -0400497 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700498 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400499
Jamie Madill4928b7c2017-06-20 12:57:39 -0400500 ANGLE_TRY(releaseSurface(display));
Corentin Wallezccab69d2017-01-27 16:57:15 -0500501
502 Framebuffer *newDefault = nullptr;
503 if (surface != nullptr)
504 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400505 ANGLE_TRY(surface->setIsCurrent(this, true));
Corentin Wallezccab69d2017-01-27 16:57:15 -0500506 mCurrentSurface = surface;
507 newDefault = surface->getDefaultFramebuffer();
508 }
509 else
510 {
511 if (mSurfacelessFramebuffer == nullptr)
512 {
513 mSurfacelessFramebuffer = new Framebuffer(mImplementation.get());
514 }
515
516 newDefault = mSurfacelessFramebuffer;
517 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000518
Corentin Wallez37c39792015-08-20 14:19:46 -0400519 // Update default framebuffer, the binding of the previous default
520 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400521 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700522 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400523 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700524 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400525 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700526 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400527 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700528 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400529 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500530 mState.mFramebuffers->setDefaultFramebuffer(newDefault);
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400531 }
Ian Ewell292f0052016-02-04 10:37:32 -0500532
533 // Notify the renderer of a context switch
Jamie Madill4928b7c2017-06-20 12:57:39 -0400534 mImplementation->onMakeCurrent(this);
535 return egl::NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000536}
537
Jamie Madill4928b7c2017-06-20 12:57:39 -0400538egl::Error Context::releaseSurface(const egl::Display *display)
Jamie Madill77a72f62015-04-14 11:18:32 -0400539{
Corentin Wallez37c39792015-08-20 14:19:46 -0400540 // Remove the default framebuffer
Corentin Wallezc295e512017-01-27 17:47:50 -0500541 Framebuffer *currentDefault = nullptr;
542 if (mCurrentSurface != nullptr)
Corentin Wallez51706ea2015-08-07 14:39:22 -0400543 {
Corentin Wallezc295e512017-01-27 17:47:50 -0500544 currentDefault = mCurrentSurface->getDefaultFramebuffer();
545 }
546 else if (mSurfacelessFramebuffer != nullptr)
547 {
548 currentDefault = mSurfacelessFramebuffer;
Corentin Wallez51706ea2015-08-07 14:39:22 -0400549 }
550
Corentin Wallezc295e512017-01-27 17:47:50 -0500551 if (mGLState.getReadFramebuffer() == currentDefault)
552 {
553 mGLState.setReadFramebufferBinding(nullptr);
554 }
555 if (mGLState.getDrawFramebuffer() == currentDefault)
556 {
557 mGLState.setDrawFramebufferBinding(nullptr);
558 }
559 mState.mFramebuffers->setDefaultFramebuffer(nullptr);
560
561 if (mCurrentSurface)
562 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400563 ANGLE_TRY(mCurrentSurface->setIsCurrent(this, false));
Corentin Wallezc295e512017-01-27 17:47:50 -0500564 mCurrentSurface = nullptr;
565 }
Jamie Madill4928b7c2017-06-20 12:57:39 -0400566
567 return egl::NoError();
Jamie Madill77a72f62015-04-14 11:18:32 -0400568}
569
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000570GLuint Context::createBuffer()
571{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500572 return mState.mBuffers->createBuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000573}
574
575GLuint Context::createProgram()
576{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500577 return mState.mShaderPrograms->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000578}
579
580GLuint Context::createShader(GLenum type)
581{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500582 return mState.mShaderPrograms->createShader(mImplementation.get(), mLimitations, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000583}
584
585GLuint Context::createTexture()
586{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500587 return mState.mTextures->createTexture();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000588}
589
590GLuint Context::createRenderbuffer()
591{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500592 return mState.mRenderbuffers->createRenderbuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000593}
594
Geoff Lang882033e2014-09-30 11:26:07 -0400595GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400596{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500597 GLuint handle = mState.mFenceSyncs->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400598
Cooper Partind8e62a32015-01-29 15:21:25 -0800599 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400600}
601
Sami Väisänene45e53b2016-05-25 10:36:04 +0300602GLuint Context::createPaths(GLsizei range)
603{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500604 auto resultOrError = mState.mPaths->createPaths(mImplementation.get(), range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300605 if (resultOrError.isError())
606 {
607 handleError(resultOrError.getError());
608 return 0;
609 }
610 return resultOrError.getResult();
611}
612
Jamie Madill57a89722013-07-02 11:57:03 -0400613GLuint Context::createVertexArray()
614{
Jamie Madill96a483b2017-06-27 16:49:21 -0400615 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
616 mVertexArrayMap.assign(vertexArray, nullptr);
Geoff Lang36167ab2015-12-07 10:27:14 -0500617 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400618}
619
Jamie Madilldc356042013-07-19 16:36:57 -0400620GLuint Context::createSampler()
621{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500622 return mState.mSamplers->createSampler();
Jamie Madilldc356042013-07-19 16:36:57 -0400623}
624
Geoff Langc8058452014-02-03 12:04:11 -0500625GLuint Context::createTransformFeedback()
626{
Jamie Madill96a483b2017-06-27 16:49:21 -0400627 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
628 mTransformFeedbackMap.assign(transformFeedback, nullptr);
Geoff Lang36167ab2015-12-07 10:27:14 -0500629 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500630}
631
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000632// Returns an unused framebuffer name
633GLuint Context::createFramebuffer()
634{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500635 return mState.mFramebuffers->createFramebuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000636}
637
Jamie Madill33dc8432013-07-26 11:55:05 -0400638GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000639{
Jamie Madill33dc8432013-07-26 11:55:05 -0400640 GLuint handle = mFenceNVHandleAllocator.allocate();
Jamie Madill96a483b2017-06-27 16:49:21 -0400641 mFenceNVMap.assign(handle, new FenceNV(mImplementation->createFenceNV()));
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000642 return handle;
643}
644
645// Returns an unused query name
646GLuint Context::createQuery()
647{
648 GLuint handle = mQueryHandleAllocator.allocate();
Jamie Madill96a483b2017-06-27 16:49:21 -0400649 mQueryMap.assign(handle, nullptr);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000650 return handle;
651}
652
653void Context::deleteBuffer(GLuint buffer)
654{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500655 if (mState.mBuffers->getBuffer(buffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000656 {
657 detachBuffer(buffer);
658 }
Jamie Madill893ab082014-05-16 16:56:10 -0400659
Jamie Madill6c1f6712017-02-14 19:08:04 -0500660 mState.mBuffers->deleteObject(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000661}
662
663void Context::deleteShader(GLuint shader)
664{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500665 mState.mShaderPrograms->deleteShader(this, shader);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000666}
667
668void Context::deleteProgram(GLuint program)
669{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500670 mState.mShaderPrograms->deleteProgram(this, program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000671}
672
673void Context::deleteTexture(GLuint texture)
674{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500675 if (mState.mTextures->getTexture(texture))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000676 {
677 detachTexture(texture);
678 }
679
Jamie Madill6c1f6712017-02-14 19:08:04 -0500680 mState.mTextures->deleteObject(this, texture);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000681}
682
683void Context::deleteRenderbuffer(GLuint renderbuffer)
684{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500685 if (mState.mRenderbuffers->getRenderbuffer(renderbuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000686 {
687 detachRenderbuffer(renderbuffer);
688 }
Jamie Madill893ab082014-05-16 16:56:10 -0400689
Jamie Madill6c1f6712017-02-14 19:08:04 -0500690 mState.mRenderbuffers->deleteObject(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000691}
692
Jamie Madillcd055f82013-07-26 11:55:15 -0400693void Context::deleteFenceSync(GLsync fenceSync)
694{
695 // The spec specifies the underlying Fence object is not deleted until all current
696 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
697 // and since our API is currently designed for being called from a single thread, we can delete
698 // the fence immediately.
Jamie Madill6c1f6712017-02-14 19:08:04 -0500699 mState.mFenceSyncs->deleteObject(this,
700 static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400701}
702
Sami Väisänene45e53b2016-05-25 10:36:04 +0300703void Context::deletePaths(GLuint first, GLsizei range)
704{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500705 mState.mPaths->deletePaths(first, range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300706}
707
708bool Context::hasPathData(GLuint path) const
709{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500710 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300711 if (pathObj == nullptr)
712 return false;
713
714 return pathObj->hasPathData();
715}
716
717bool Context::hasPath(GLuint path) const
718{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500719 return mState.mPaths->hasPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300720}
721
722void Context::setPathCommands(GLuint path,
723 GLsizei numCommands,
724 const GLubyte *commands,
725 GLsizei numCoords,
726 GLenum coordType,
727 const void *coords)
728{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500729 auto *pathObject = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300730
731 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
732}
733
734void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
735{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500736 auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300737
738 switch (pname)
739 {
740 case GL_PATH_STROKE_WIDTH_CHROMIUM:
741 pathObj->setStrokeWidth(value);
742 break;
743 case GL_PATH_END_CAPS_CHROMIUM:
744 pathObj->setEndCaps(static_cast<GLenum>(value));
745 break;
746 case GL_PATH_JOIN_STYLE_CHROMIUM:
747 pathObj->setJoinStyle(static_cast<GLenum>(value));
748 break;
749 case GL_PATH_MITER_LIMIT_CHROMIUM:
750 pathObj->setMiterLimit(value);
751 break;
752 case GL_PATH_STROKE_BOUND_CHROMIUM:
753 pathObj->setStrokeBound(value);
754 break;
755 default:
756 UNREACHABLE();
757 break;
758 }
759}
760
761void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
762{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500763 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300764
765 switch (pname)
766 {
767 case GL_PATH_STROKE_WIDTH_CHROMIUM:
768 *value = pathObj->getStrokeWidth();
769 break;
770 case GL_PATH_END_CAPS_CHROMIUM:
771 *value = static_cast<GLfloat>(pathObj->getEndCaps());
772 break;
773 case GL_PATH_JOIN_STYLE_CHROMIUM:
774 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
775 break;
776 case GL_PATH_MITER_LIMIT_CHROMIUM:
777 *value = pathObj->getMiterLimit();
778 break;
779 case GL_PATH_STROKE_BOUND_CHROMIUM:
780 *value = pathObj->getStrokeBound();
781 break;
782 default:
783 UNREACHABLE();
784 break;
785 }
786}
787
788void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
789{
790 mGLState.setPathStencilFunc(func, ref, mask);
791}
792
Jamie Madill57a89722013-07-02 11:57:03 -0400793void Context::deleteVertexArray(GLuint vertexArray)
794{
Jamie Madill96a483b2017-06-27 16:49:21 -0400795 VertexArray *vertexArrayObject = nullptr;
796 if (mVertexArrayMap.erase(vertexArray, &vertexArrayObject))
Geoff Lang50b3fe82015-12-08 14:49:12 +0000797 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500798 if (vertexArrayObject != nullptr)
799 {
800 detachVertexArray(vertexArray);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400801 vertexArrayObject->onDestroy(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500802 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000803
Geoff Lang36167ab2015-12-07 10:27:14 -0500804 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400805 }
806}
807
Jamie Madilldc356042013-07-19 16:36:57 -0400808void Context::deleteSampler(GLuint sampler)
809{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500810 if (mState.mSamplers->getSampler(sampler))
Jamie Madilldc356042013-07-19 16:36:57 -0400811 {
812 detachSampler(sampler);
813 }
814
Jamie Madill6c1f6712017-02-14 19:08:04 -0500815 mState.mSamplers->deleteObject(this, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400816}
817
Geoff Langc8058452014-02-03 12:04:11 -0500818void Context::deleteTransformFeedback(GLuint transformFeedback)
819{
Geoff Lang6e60d6b2017-04-12 12:59:04 -0400820 if (transformFeedback == 0)
821 {
822 return;
823 }
824
Jamie Madill96a483b2017-06-27 16:49:21 -0400825 TransformFeedback *transformFeedbackObject = nullptr;
826 if (mTransformFeedbackMap.erase(transformFeedback, &transformFeedbackObject))
Geoff Langc8058452014-02-03 12:04:11 -0500827 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500828 if (transformFeedbackObject != nullptr)
829 {
830 detachTransformFeedback(transformFeedback);
Jamie Madill6c1f6712017-02-14 19:08:04 -0500831 transformFeedbackObject->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500832 }
833
Geoff Lang36167ab2015-12-07 10:27:14 -0500834 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500835 }
836}
837
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000838void Context::deleteFramebuffer(GLuint framebuffer)
839{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500840 if (mState.mFramebuffers->getFramebuffer(framebuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000841 {
842 detachFramebuffer(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000843 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500844
Jamie Madill6c1f6712017-02-14 19:08:04 -0500845 mState.mFramebuffers->deleteObject(this, framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000846}
847
Jamie Madill33dc8432013-07-26 11:55:05 -0400848void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000849{
Jamie Madill96a483b2017-06-27 16:49:21 -0400850 FenceNV *fenceObject = nullptr;
851 if (mFenceNVMap.erase(fence, &fenceObject))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000852 {
Jamie Madill96a483b2017-06-27 16:49:21 -0400853 mFenceNVHandleAllocator.release(fence);
854 delete fenceObject;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000855 }
856}
857
858void Context::deleteQuery(GLuint query)
859{
Jamie Madill96a483b2017-06-27 16:49:21 -0400860 Query *queryObject = nullptr;
861 if (mQueryMap.erase(query, &queryObject))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000862 {
Jamie Madill96a483b2017-06-27 16:49:21 -0400863 mQueryHandleAllocator.release(query);
864 if (queryObject)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000865 {
Jamie Madill96a483b2017-06-27 16:49:21 -0400866 queryObject->release(this);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000867 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000868 }
869}
870
Geoff Lang70d0f492015-12-10 17:45:46 -0500871Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000872{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500873 return mState.mBuffers->getBuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000874}
875
Jamie Madill570f7c82014-07-03 10:38:54 -0400876Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000877{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500878 return mState.mTextures->getTexture(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000879}
880
Geoff Lang70d0f492015-12-10 17:45:46 -0500881Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000882{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500883 return mState.mRenderbuffers->getRenderbuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000884}
885
Jamie Madillcd055f82013-07-26 11:55:15 -0400886FenceSync *Context::getFenceSync(GLsync handle) const
887{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500888 return mState.mFenceSyncs->getFenceSync(
889 static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400890}
891
Jamie Madill57a89722013-07-02 11:57:03 -0400892VertexArray *Context::getVertexArray(GLuint handle) const
893{
Jamie Madill96a483b2017-06-27 16:49:21 -0400894 return mVertexArrayMap.query(handle);
Jamie Madill57a89722013-07-02 11:57:03 -0400895}
896
Jamie Madilldc356042013-07-19 16:36:57 -0400897Sampler *Context::getSampler(GLuint handle) const
898{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500899 return mState.mSamplers->getSampler(handle);
Jamie Madilldc356042013-07-19 16:36:57 -0400900}
901
Geoff Langc8058452014-02-03 12:04:11 -0500902TransformFeedback *Context::getTransformFeedback(GLuint handle) const
903{
Jamie Madill96a483b2017-06-27 16:49:21 -0400904 return mTransformFeedbackMap.query(handle);
Geoff Langc8058452014-02-03 12:04:11 -0500905}
906
Geoff Lang70d0f492015-12-10 17:45:46 -0500907LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
908{
909 switch (identifier)
910 {
911 case GL_BUFFER:
912 return getBuffer(name);
913 case GL_SHADER:
914 return getShader(name);
915 case GL_PROGRAM:
916 return getProgram(name);
917 case GL_VERTEX_ARRAY:
918 return getVertexArray(name);
919 case GL_QUERY:
920 return getQuery(name);
921 case GL_TRANSFORM_FEEDBACK:
922 return getTransformFeedback(name);
923 case GL_SAMPLER:
924 return getSampler(name);
925 case GL_TEXTURE:
926 return getTexture(name);
927 case GL_RENDERBUFFER:
928 return getRenderbuffer(name);
929 case GL_FRAMEBUFFER:
930 return getFramebuffer(name);
931 default:
932 UNREACHABLE();
933 return nullptr;
934 }
935}
936
937LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
938{
939 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
940}
941
Martin Radev9d901792016-07-15 15:58:58 +0300942void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
943{
944 LabeledObject *object = getLabeledObject(identifier, name);
945 ASSERT(object != nullptr);
946
947 std::string labelName = GetObjectLabelFromPointer(length, label);
948 object->setLabel(labelName);
949}
950
951void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
952{
953 LabeledObject *object = getLabeledObjectFromPtr(ptr);
954 ASSERT(object != nullptr);
955
956 std::string labelName = GetObjectLabelFromPointer(length, label);
957 object->setLabel(labelName);
958}
959
960void Context::getObjectLabel(GLenum identifier,
961 GLuint name,
962 GLsizei bufSize,
963 GLsizei *length,
964 GLchar *label) const
965{
966 LabeledObject *object = getLabeledObject(identifier, name);
967 ASSERT(object != nullptr);
968
969 const std::string &objectLabel = object->getLabel();
970 GetObjectLabelBase(objectLabel, bufSize, length, label);
971}
972
973void Context::getObjectPtrLabel(const void *ptr,
974 GLsizei bufSize,
975 GLsizei *length,
976 GLchar *label) const
977{
978 LabeledObject *object = getLabeledObjectFromPtr(ptr);
979 ASSERT(object != nullptr);
980
981 const std::string &objectLabel = object->getLabel();
982 GetObjectLabelBase(objectLabel, bufSize, length, label);
983}
984
Jamie Madilldc356042013-07-19 16:36:57 -0400985bool Context::isSampler(GLuint samplerName) const
986{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500987 return mState.mSamplers->isSampler(samplerName);
Jamie Madilldc356042013-07-19 16:36:57 -0400988}
989
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500990void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000991{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500992 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400993 mGLState.setArrayBufferBinding(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000994}
995
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800996void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
997{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500998 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400999 mGLState.setDrawIndirectBufferBinding(this, buffer);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08001000}
1001
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001002void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001003{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001004 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001005 mGLState.setElementArrayBuffer(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001006}
1007
Jamie Madilldedd7b92014-11-05 16:30:36 -05001008void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001009{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001010 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001011
Jamie Madilldedd7b92014-11-05 16:30:36 -05001012 if (handle == 0)
1013 {
1014 texture = mZeroTextures[target].get();
1015 }
1016 else
1017 {
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001018 texture = mState.mTextures->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -05001019 }
1020
1021 ASSERT(texture);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001022 mGLState.setSamplerTexture(this, target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +00001023}
1024
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001025void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001026{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001027 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
1028 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001029 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001030}
1031
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001032void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001033{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001034 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
1035 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001036 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001037}
1038
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001039void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -04001040{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001041 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001042 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -04001043}
1044
Shao80957d92017-02-20 21:25:59 +08001045void Context::bindVertexBuffer(GLuint bindingIndex,
1046 GLuint bufferHandle,
1047 GLintptr offset,
1048 GLsizei stride)
1049{
1050 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001051 mGLState.bindVertexBuffer(this, bindingIndex, buffer, offset, stride);
Shao80957d92017-02-20 21:25:59 +08001052}
1053
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001054void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -04001055{
Geoff Lang76b10c92014-09-05 16:28:14 -04001056 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -04001057 Sampler *sampler =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001058 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001059 mGLState.setSamplerBinding(this, textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001060}
1061
Xinghua Cao65ec0b22017-03-28 16:10:52 +08001062void Context::bindImageTexture(GLuint unit,
1063 GLuint texture,
1064 GLint level,
1065 GLboolean layered,
1066 GLint layer,
1067 GLenum access,
1068 GLenum format)
1069{
1070 Texture *tex = mState.mTextures->getTexture(texture);
1071 mGLState.setImageUnit(this, unit, tex, level, layered, layer, access, format);
1072}
1073
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001074void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001075{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001076 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001077 mGLState.setGenericUniformBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001078}
1079
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001080void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1081 GLuint index,
1082 GLintptr offset,
1083 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001084{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001085 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001086 mGLState.setIndexedUniformBufferBinding(this, index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001087}
1088
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001089void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001090{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001091 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001092 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001093}
1094
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001095void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1096 GLuint index,
1097 GLintptr offset,
1098 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001099{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001100 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001101 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(this, index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001102}
1103
Jiajia Qin6eafb042016-12-27 17:04:07 +08001104void Context::bindGenericAtomicCounterBuffer(GLuint bufferHandle)
1105{
1106 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001107 mGLState.setGenericAtomicCounterBufferBinding(this, buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08001108}
1109
1110void Context::bindIndexedAtomicCounterBuffer(GLuint bufferHandle,
1111 GLuint index,
1112 GLintptr offset,
1113 GLsizeiptr size)
1114{
1115 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001116 mGLState.setIndexedAtomicCounterBufferBinding(this, index, buffer, offset, size);
Jiajia Qin6eafb042016-12-27 17:04:07 +08001117}
1118
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001119void Context::bindGenericShaderStorageBuffer(GLuint bufferHandle)
1120{
1121 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001122 mGLState.setGenericShaderStorageBufferBinding(this, buffer);
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001123}
1124
1125void Context::bindIndexedShaderStorageBuffer(GLuint bufferHandle,
1126 GLuint index,
1127 GLintptr offset,
1128 GLsizeiptr size)
1129{
1130 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001131 mGLState.setIndexedShaderStorageBufferBinding(this, index, buffer, offset, size);
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001132}
1133
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001134void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001135{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001136 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001137 mGLState.setCopyReadBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001138}
1139
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001140void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001141{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001142 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001143 mGLState.setCopyWriteBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001144}
1145
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001146void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001147{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001148 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001149 mGLState.setPixelPackBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001150}
1151
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001152void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001153{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001154 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001155 mGLState.setPixelUnpackBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001156}
1157
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001158void Context::useProgram(GLuint program)
1159{
Jamie Madill6c1f6712017-02-14 19:08:04 -05001160 mGLState.setProgram(this, getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001161}
1162
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001163void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001164{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001165 TransformFeedback *transformFeedback =
1166 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001167 mGLState.setTransformFeedbackBinding(this, transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001168}
1169
Geoff Lang5aad9672014-09-08 11:10:42 -04001170Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001171{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001172 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001173 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001174
Geoff Lang5aad9672014-09-08 11:10:42 -04001175 // begin query
1176 Error error = queryObject->begin();
1177 if (error.isError())
1178 {
1179 return error;
1180 }
1181
1182 // set query as active for specified target only if begin succeeded
Jamie Madill4928b7c2017-06-20 12:57:39 -04001183 mGLState.setActiveQuery(this, target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001184
He Yunchaoacd18982017-01-04 10:46:42 +08001185 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001186}
1187
Geoff Lang5aad9672014-09-08 11:10:42 -04001188Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001189{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001190 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001191 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001192
Geoff Lang5aad9672014-09-08 11:10:42 -04001193 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001194
Geoff Lang5aad9672014-09-08 11:10:42 -04001195 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madill4928b7c2017-06-20 12:57:39 -04001196 mGLState.setActiveQuery(this, target, nullptr);
Geoff Lang5aad9672014-09-08 11:10:42 -04001197
1198 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001199}
1200
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001201Error Context::queryCounter(GLuint id, GLenum target)
1202{
1203 ASSERT(target == GL_TIMESTAMP_EXT);
1204
1205 Query *queryObject = getQuery(id, true, target);
1206 ASSERT(queryObject);
1207
1208 return queryObject->queryCounter();
1209}
1210
1211void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1212{
1213 switch (pname)
1214 {
1215 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001216 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001217 break;
1218 case GL_QUERY_COUNTER_BITS_EXT:
1219 switch (target)
1220 {
1221 case GL_TIME_ELAPSED_EXT:
1222 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1223 break;
1224 case GL_TIMESTAMP_EXT:
1225 params[0] = getExtensions().queryCounterBitsTimestamp;
1226 break;
1227 default:
1228 UNREACHABLE();
1229 params[0] = 0;
1230 break;
1231 }
1232 break;
1233 default:
1234 UNREACHABLE();
1235 return;
1236 }
1237}
1238
Geoff Lang2186c382016-10-14 10:54:54 -04001239void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001240{
Geoff Lang2186c382016-10-14 10:54:54 -04001241 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001242}
1243
Geoff Lang2186c382016-10-14 10:54:54 -04001244void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001245{
Geoff Lang2186c382016-10-14 10:54:54 -04001246 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001247}
1248
Geoff Lang2186c382016-10-14 10:54:54 -04001249void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001250{
Geoff Lang2186c382016-10-14 10:54:54 -04001251 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001252}
1253
Geoff Lang2186c382016-10-14 10:54:54 -04001254void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001255{
Geoff Lang2186c382016-10-14 10:54:54 -04001256 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001257}
1258
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001259Framebuffer *Context::getFramebuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001260{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001261 return mState.mFramebuffers->getFramebuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001262}
1263
Jamie Madill2f348d22017-06-05 10:50:59 -04001264FenceNV *Context::getFenceNV(GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001265{
Jamie Madill96a483b2017-06-27 16:49:21 -04001266 return mFenceNVMap.query(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001267}
1268
Jamie Madill2f348d22017-06-05 10:50:59 -04001269Query *Context::getQuery(GLuint handle, bool create, GLenum type)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001270{
Jamie Madill96a483b2017-06-27 16:49:21 -04001271 if (!mQueryMap.contains(handle))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001272 {
Yunchao Hef81ce4a2017-04-24 10:49:17 +08001273 return nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001274 }
Jamie Madill96a483b2017-06-27 16:49:21 -04001275
1276 Query *query = mQueryMap.query(handle);
1277 if (!query && create)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001278 {
Jamie Madill96a483b2017-06-27 16:49:21 -04001279 query = new Query(mImplementation->createQuery(type), handle);
1280 query->addRef();
1281 mQueryMap.assign(handle, query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001282 }
Jamie Madill96a483b2017-06-27 16:49:21 -04001283 return query;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001284}
1285
Geoff Lang70d0f492015-12-10 17:45:46 -05001286Query *Context::getQuery(GLuint handle) const
1287{
Jamie Madill96a483b2017-06-27 16:49:21 -04001288 return mQueryMap.query(handle);
Geoff Lang70d0f492015-12-10 17:45:46 -05001289}
1290
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001291Texture *Context::getTargetTexture(GLenum target) const
1292{
Ian Ewellbda75592016-04-18 17:25:54 -04001293 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001294 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001295}
1296
Geoff Lang76b10c92014-09-05 16:28:14 -04001297Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001298{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001299 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001300}
1301
Geoff Lang492a7e42014-11-05 13:27:06 -05001302Compiler *Context::getCompiler() const
1303{
Jamie Madill2f348d22017-06-05 10:50:59 -04001304 if (mCompiler.get() == nullptr)
1305 {
Jamie Madill4928b7c2017-06-20 12:57:39 -04001306 mCompiler.set(this, new Compiler(mImplementation.get(), mState));
Jamie Madill2f348d22017-06-05 10:50:59 -04001307 }
1308 return mCompiler.get();
Geoff Lang492a7e42014-11-05 13:27:06 -05001309}
1310
Jamie Madillc1d770e2017-04-13 17:31:24 -04001311void Context::getBooleanvImpl(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001312{
1313 switch (pname)
1314 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001315 case GL_SHADER_COMPILER:
1316 *params = GL_TRUE;
1317 break;
1318 case GL_CONTEXT_ROBUST_ACCESS_EXT:
1319 *params = mRobustAccess ? GL_TRUE : GL_FALSE;
1320 break;
1321 default:
1322 mGLState.getBooleanv(pname, params);
1323 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001324 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001325}
1326
Jamie Madillc1d770e2017-04-13 17:31:24 -04001327void Context::getFloatvImpl(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001328{
Shannon Woods53a94a82014-06-24 15:20:36 -04001329 // Queries about context capabilities and maximums are answered by Context.
1330 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001331 switch (pname)
1332 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001333 case GL_ALIASED_LINE_WIDTH_RANGE:
1334 params[0] = mCaps.minAliasedLineWidth;
1335 params[1] = mCaps.maxAliasedLineWidth;
1336 break;
1337 case GL_ALIASED_POINT_SIZE_RANGE:
1338 params[0] = mCaps.minAliasedPointSize;
1339 params[1] = mCaps.maxAliasedPointSize;
1340 break;
1341 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1342 ASSERT(mExtensions.textureFilterAnisotropic);
1343 *params = mExtensions.maxTextureAnisotropy;
1344 break;
1345 case GL_MAX_TEXTURE_LOD_BIAS:
1346 *params = mCaps.maxLODBias;
1347 break;
1348
1349 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1350 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1351 {
1352 ASSERT(mExtensions.pathRendering);
1353 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1354 memcpy(params, m, 16 * sizeof(GLfloat));
1355 }
Geoff Lange6d4e122015-06-29 13:33:55 -04001356 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001357
Jamie Madill231c7f52017-04-26 13:45:37 -04001358 default:
1359 mGLState.getFloatv(pname, params);
1360 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001361 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001362}
1363
Jamie Madillc1d770e2017-04-13 17:31:24 -04001364void Context::getIntegervImpl(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001365{
Shannon Woods53a94a82014-06-24 15:20:36 -04001366 // Queries about context capabilities and maximums are answered by Context.
1367 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001368
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001369 switch (pname)
1370 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001371 case GL_MAX_VERTEX_ATTRIBS:
1372 *params = mCaps.maxVertexAttributes;
1373 break;
1374 case GL_MAX_VERTEX_UNIFORM_VECTORS:
1375 *params = mCaps.maxVertexUniformVectors;
1376 break;
1377 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
1378 *params = mCaps.maxVertexUniformComponents;
1379 break;
1380 case GL_MAX_VARYING_VECTORS:
1381 *params = mCaps.maxVaryingVectors;
1382 break;
1383 case GL_MAX_VARYING_COMPONENTS:
1384 *params = mCaps.maxVertexOutputComponents;
1385 break;
1386 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1387 *params = mCaps.maxCombinedTextureImageUnits;
1388 break;
1389 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1390 *params = mCaps.maxVertexTextureImageUnits;
1391 break;
1392 case GL_MAX_TEXTURE_IMAGE_UNITS:
1393 *params = mCaps.maxTextureImageUnits;
1394 break;
1395 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1396 *params = mCaps.maxFragmentUniformVectors;
1397 break;
1398 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
1399 *params = mCaps.maxFragmentUniformComponents;
1400 break;
1401 case GL_MAX_RENDERBUFFER_SIZE:
1402 *params = mCaps.maxRenderbufferSize;
1403 break;
1404 case GL_MAX_COLOR_ATTACHMENTS_EXT:
1405 *params = mCaps.maxColorAttachments;
1406 break;
1407 case GL_MAX_DRAW_BUFFERS_EXT:
1408 *params = mCaps.maxDrawBuffers;
1409 break;
1410 // case GL_FRAMEBUFFER_BINDING: // now equivalent to
1411 // GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1412 case GL_SUBPIXEL_BITS:
1413 *params = 4;
1414 break;
1415 case GL_MAX_TEXTURE_SIZE:
1416 *params = mCaps.max2DTextureSize;
1417 break;
1418 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1419 *params = mCaps.maxCubeMapTextureSize;
1420 break;
1421 case GL_MAX_3D_TEXTURE_SIZE:
1422 *params = mCaps.max3DTextureSize;
1423 break;
1424 case GL_MAX_ARRAY_TEXTURE_LAYERS:
1425 *params = mCaps.maxArrayTextureLayers;
1426 break;
1427 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
1428 *params = mCaps.uniformBufferOffsetAlignment;
1429 break;
1430 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
1431 *params = mCaps.maxUniformBufferBindings;
1432 break;
1433 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
1434 *params = mCaps.maxVertexUniformBlocks;
1435 break;
1436 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
1437 *params = mCaps.maxFragmentUniformBlocks;
1438 break;
1439 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
1440 *params = mCaps.maxCombinedTextureImageUnits;
1441 break;
1442 case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
1443 *params = mCaps.maxVertexOutputComponents;
1444 break;
1445 case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
1446 *params = mCaps.maxFragmentInputComponents;
1447 break;
1448 case GL_MIN_PROGRAM_TEXEL_OFFSET:
1449 *params = mCaps.minProgramTexelOffset;
1450 break;
1451 case GL_MAX_PROGRAM_TEXEL_OFFSET:
1452 *params = mCaps.maxProgramTexelOffset;
1453 break;
1454 case GL_MAJOR_VERSION:
1455 *params = getClientVersion().major;
1456 break;
1457 case GL_MINOR_VERSION:
1458 *params = getClientVersion().minor;
1459 break;
1460 case GL_MAX_ELEMENTS_INDICES:
1461 *params = mCaps.maxElementsIndices;
1462 break;
1463 case GL_MAX_ELEMENTS_VERTICES:
1464 *params = mCaps.maxElementsVertices;
1465 break;
1466 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
1467 *params = mCaps.maxTransformFeedbackInterleavedComponents;
1468 break;
1469 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
1470 *params = mCaps.maxTransformFeedbackSeparateAttributes;
1471 break;
1472 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
1473 *params = mCaps.maxTransformFeedbackSeparateComponents;
1474 break;
1475 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1476 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1477 break;
1478 case GL_MAX_SAMPLES_ANGLE:
1479 *params = mCaps.maxSamples;
1480 break;
1481 case GL_MAX_VIEWPORT_DIMS:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001482 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001483 params[0] = mCaps.maxViewportWidth;
1484 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001485 }
1486 break;
Jamie Madill231c7f52017-04-26 13:45:37 -04001487 case GL_COMPRESSED_TEXTURE_FORMATS:
1488 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(),
1489 params);
1490 break;
1491 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1492 *params = mResetStrategy;
1493 break;
1494 case GL_NUM_SHADER_BINARY_FORMATS:
1495 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
1496 break;
1497 case GL_SHADER_BINARY_FORMATS:
1498 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1499 break;
1500 case GL_NUM_PROGRAM_BINARY_FORMATS:
1501 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
1502 break;
1503 case GL_PROGRAM_BINARY_FORMATS:
1504 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
1505 break;
1506 case GL_NUM_EXTENSIONS:
1507 *params = static_cast<GLint>(mExtensionStrings.size());
1508 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001509
Jamie Madill231c7f52017-04-26 13:45:37 -04001510 // GL_KHR_debug
1511 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1512 *params = mExtensions.maxDebugMessageLength;
1513 break;
1514 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1515 *params = mExtensions.maxDebugLoggedMessages;
1516 break;
1517 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1518 *params = mExtensions.maxDebugGroupStackDepth;
1519 break;
1520 case GL_MAX_LABEL_LENGTH:
1521 *params = mExtensions.maxLabelLength;
1522 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001523
Jamie Madill231c7f52017-04-26 13:45:37 -04001524 // GL_EXT_disjoint_timer_query
1525 case GL_GPU_DISJOINT_EXT:
1526 *params = mImplementation->getGPUDisjoint();
1527 break;
1528 case GL_MAX_FRAMEBUFFER_WIDTH:
1529 *params = mCaps.maxFramebufferWidth;
1530 break;
1531 case GL_MAX_FRAMEBUFFER_HEIGHT:
1532 *params = mCaps.maxFramebufferHeight;
1533 break;
1534 case GL_MAX_FRAMEBUFFER_SAMPLES:
1535 *params = mCaps.maxFramebufferSamples;
1536 break;
1537 case GL_MAX_SAMPLE_MASK_WORDS:
1538 *params = mCaps.maxSampleMaskWords;
1539 break;
1540 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1541 *params = mCaps.maxColorTextureSamples;
1542 break;
1543 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1544 *params = mCaps.maxDepthTextureSamples;
1545 break;
1546 case GL_MAX_INTEGER_SAMPLES:
1547 *params = mCaps.maxIntegerSamples;
1548 break;
1549 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1550 *params = mCaps.maxVertexAttribRelativeOffset;
1551 break;
1552 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1553 *params = mCaps.maxVertexAttribBindings;
1554 break;
1555 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1556 *params = mCaps.maxVertexAttribStride;
1557 break;
1558 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1559 *params = mCaps.maxVertexAtomicCounterBuffers;
1560 break;
1561 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1562 *params = mCaps.maxVertexAtomicCounters;
1563 break;
1564 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1565 *params = mCaps.maxVertexImageUniforms;
1566 break;
1567 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1568 *params = mCaps.maxVertexShaderStorageBlocks;
1569 break;
1570 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1571 *params = mCaps.maxFragmentAtomicCounterBuffers;
1572 break;
1573 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1574 *params = mCaps.maxFragmentAtomicCounters;
1575 break;
1576 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1577 *params = mCaps.maxFragmentImageUniforms;
1578 break;
1579 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1580 *params = mCaps.maxFragmentShaderStorageBlocks;
1581 break;
1582 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1583 *params = mCaps.minProgramTextureGatherOffset;
1584 break;
1585 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1586 *params = mCaps.maxProgramTextureGatherOffset;
1587 break;
1588 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1589 *params = mCaps.maxComputeWorkGroupInvocations;
1590 break;
1591 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1592 *params = mCaps.maxComputeUniformBlocks;
1593 break;
1594 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1595 *params = mCaps.maxComputeTextureImageUnits;
1596 break;
1597 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1598 *params = mCaps.maxComputeSharedMemorySize;
1599 break;
1600 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1601 *params = mCaps.maxComputeUniformComponents;
1602 break;
1603 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1604 *params = mCaps.maxComputeAtomicCounterBuffers;
1605 break;
1606 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1607 *params = mCaps.maxComputeAtomicCounters;
1608 break;
1609 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1610 *params = mCaps.maxComputeImageUniforms;
1611 break;
1612 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1613 *params = mCaps.maxCombinedComputeUniformComponents;
1614 break;
1615 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1616 *params = mCaps.maxComputeShaderStorageBlocks;
1617 break;
1618 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1619 *params = mCaps.maxCombinedShaderOutputResources;
1620 break;
1621 case GL_MAX_UNIFORM_LOCATIONS:
1622 *params = mCaps.maxUniformLocations;
1623 break;
1624 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1625 *params = mCaps.maxAtomicCounterBufferBindings;
1626 break;
1627 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1628 *params = mCaps.maxAtomicCounterBufferSize;
1629 break;
1630 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1631 *params = mCaps.maxCombinedAtomicCounterBuffers;
1632 break;
1633 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1634 *params = mCaps.maxCombinedAtomicCounters;
1635 break;
1636 case GL_MAX_IMAGE_UNITS:
1637 *params = mCaps.maxImageUnits;
1638 break;
1639 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1640 *params = mCaps.maxCombinedImageUniforms;
1641 break;
1642 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1643 *params = mCaps.maxShaderStorageBufferBindings;
1644 break;
1645 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1646 *params = mCaps.maxCombinedShaderStorageBlocks;
1647 break;
1648 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1649 *params = mCaps.shaderStorageBufferOffsetAlignment;
1650 break;
1651 default:
1652 mGLState.getIntegerv(this, pname, params);
1653 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001654 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001655}
1656
Jamie Madill893ab082014-05-16 16:56:10 -04001657void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001658{
Shannon Woods53a94a82014-06-24 15:20:36 -04001659 // Queries about context capabilities and maximums are answered by Context.
1660 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001661 switch (pname)
1662 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001663 case GL_MAX_ELEMENT_INDEX:
1664 *params = mCaps.maxElementIndex;
1665 break;
1666 case GL_MAX_UNIFORM_BLOCK_SIZE:
1667 *params = mCaps.maxUniformBlockSize;
1668 break;
1669 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
1670 *params = mCaps.maxCombinedVertexUniformComponents;
1671 break;
1672 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
1673 *params = mCaps.maxCombinedFragmentUniformComponents;
1674 break;
1675 case GL_MAX_SERVER_WAIT_TIMEOUT:
1676 *params = mCaps.maxServerWaitTimeout;
1677 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001678
Jamie Madill231c7f52017-04-26 13:45:37 -04001679 // GL_EXT_disjoint_timer_query
1680 case GL_TIMESTAMP_EXT:
1681 *params = mImplementation->getTimestamp();
1682 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001683
Jamie Madill231c7f52017-04-26 13:45:37 -04001684 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1685 *params = mCaps.maxShaderStorageBlockSize;
1686 break;
1687 default:
1688 UNREACHABLE();
1689 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001690 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001691}
1692
Geoff Lang70d0f492015-12-10 17:45:46 -05001693void Context::getPointerv(GLenum pname, void **params) const
1694{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001695 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001696}
1697
Martin Radev66fb8202016-07-28 11:45:20 +03001698void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001699{
Shannon Woods53a94a82014-06-24 15:20:36 -04001700 // Queries about context capabilities and maximums are answered by Context.
1701 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001702
1703 GLenum nativeType;
1704 unsigned int numParams;
1705 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1706 ASSERT(queryStatus);
1707
1708 if (nativeType == GL_INT)
1709 {
1710 switch (target)
1711 {
1712 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1713 ASSERT(index < 3u);
1714 *data = mCaps.maxComputeWorkGroupCount[index];
1715 break;
1716 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1717 ASSERT(index < 3u);
1718 *data = mCaps.maxComputeWorkGroupSize[index];
1719 break;
1720 default:
1721 mGLState.getIntegeri_v(target, index, data);
1722 }
1723 }
1724 else
1725 {
1726 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1727 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001728}
1729
Martin Radev66fb8202016-07-28 11:45:20 +03001730void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001731{
Shannon Woods53a94a82014-06-24 15:20:36 -04001732 // Queries about context capabilities and maximums are answered by Context.
1733 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001734
1735 GLenum nativeType;
1736 unsigned int numParams;
1737 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1738 ASSERT(queryStatus);
1739
1740 if (nativeType == GL_INT_64_ANGLEX)
1741 {
1742 mGLState.getInteger64i_v(target, index, data);
1743 }
1744 else
1745 {
1746 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1747 }
1748}
1749
1750void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1751{
1752 // Queries about context capabilities and maximums are answered by Context.
1753 // Queries about current GL state values are answered by State.
1754
1755 GLenum nativeType;
1756 unsigned int numParams;
1757 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1758 ASSERT(queryStatus);
1759
1760 if (nativeType == GL_BOOL)
1761 {
1762 mGLState.getBooleani_v(target, index, data);
1763 }
1764 else
1765 {
1766 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1767 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001768}
1769
He Yunchao010e4db2017-03-03 14:22:06 +08001770void Context::getBufferParameteriv(GLenum target, GLenum pname, GLint *params)
1771{
1772 Buffer *buffer = mGLState.getTargetBuffer(target);
1773 QueryBufferParameteriv(buffer, pname, params);
1774}
1775
1776void Context::getFramebufferAttachmentParameteriv(GLenum target,
1777 GLenum attachment,
1778 GLenum pname,
1779 GLint *params)
1780{
1781 const Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
1782 QueryFramebufferAttachmentParameteriv(framebuffer, attachment, pname, params);
1783}
1784
1785void Context::getRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
1786{
1787 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
1788 QueryRenderbufferiv(this, renderbuffer, pname, params);
1789}
1790
1791void Context::getTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
1792{
1793 Texture *texture = getTargetTexture(target);
1794 QueryTexParameterfv(texture, pname, params);
1795}
1796
1797void Context::getTexParameteriv(GLenum target, GLenum pname, GLint *params)
1798{
1799 Texture *texture = getTargetTexture(target);
1800 QueryTexParameteriv(texture, pname, params);
1801}
1802void Context::texParameterf(GLenum target, GLenum pname, GLfloat param)
1803{
1804 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001805 SetTexParameterf(this, texture, pname, param);
He Yunchao010e4db2017-03-03 14:22:06 +08001806}
1807
1808void Context::texParameterfv(GLenum target, GLenum pname, const GLfloat *params)
1809{
1810 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001811 SetTexParameterfv(this, texture, pname, params);
He Yunchao010e4db2017-03-03 14:22:06 +08001812}
1813
1814void Context::texParameteri(GLenum target, GLenum pname, GLint param)
1815{
1816 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001817 SetTexParameteri(this, texture, pname, param);
He Yunchao010e4db2017-03-03 14:22:06 +08001818}
1819
1820void Context::texParameteriv(GLenum target, GLenum pname, const GLint *params)
1821{
1822 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001823 SetTexParameteriv(this, texture, pname, params);
He Yunchao010e4db2017-03-03 14:22:06 +08001824}
1825
Jamie Madill675fe712016-12-19 13:07:54 -05001826void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001827{
Jamie Madill1b94d432015-08-07 13:23:23 -04001828 syncRendererState();
Jamie Madillc564c072017-06-01 12:45:42 -04001829 auto error = mImplementation->drawArrays(this, mode, first, count);
Jamie Madill675fe712016-12-19 13:07:54 -05001830 handleError(error);
1831 if (!error.isError())
1832 {
1833 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1834 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001835}
1836
Jamie Madill675fe712016-12-19 13:07:54 -05001837void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Geoff Langf6db0982015-08-25 13:04:00 -04001838{
1839 syncRendererState();
Jamie Madillc564c072017-06-01 12:45:42 -04001840 auto error = mImplementation->drawArraysInstanced(this, mode, first, count, instanceCount);
Jamie Madill675fe712016-12-19 13:07:54 -05001841 handleError(error);
1842 if (!error.isError())
1843 {
1844 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1845 }
Geoff Langf6db0982015-08-25 13:04:00 -04001846}
1847
Jamie Madill876429b2017-04-20 15:46:24 -04001848void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001849{
Jamie Madill1b94d432015-08-07 13:23:23 -04001850 syncRendererState();
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001851 const IndexRange &indexRange = getParams<HasIndexRange>().getIndexRange().value();
Jamie Madillc564c072017-06-01 12:45:42 -04001852 handleError(mImplementation->drawElements(this, mode, count, type, indices, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001853}
1854
Jamie Madill675fe712016-12-19 13:07:54 -05001855void Context::drawElementsInstanced(GLenum mode,
1856 GLsizei count,
1857 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001858 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001859 GLsizei instances)
Geoff Langf6db0982015-08-25 13:04:00 -04001860{
1861 syncRendererState();
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001862 const IndexRange &indexRange = getParams<HasIndexRange>().getIndexRange().value();
Jamie Madillc564c072017-06-01 12:45:42 -04001863 handleError(mImplementation->drawElementsInstanced(this, mode, count, type, indices, instances,
1864 indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001865}
1866
Jamie Madill675fe712016-12-19 13:07:54 -05001867void Context::drawRangeElements(GLenum mode,
1868 GLuint start,
1869 GLuint end,
1870 GLsizei count,
1871 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001872 const void *indices)
Geoff Langf6db0982015-08-25 13:04:00 -04001873{
1874 syncRendererState();
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001875 const IndexRange &indexRange = getParams<HasIndexRange>().getIndexRange().value();
Jamie Madillc564c072017-06-01 12:45:42 -04001876 handleError(mImplementation->drawRangeElements(this, mode, start, end, count, type, indices,
1877 indexRange));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001878}
1879
Jamie Madill876429b2017-04-20 15:46:24 -04001880void Context::drawArraysIndirect(GLenum mode, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001881{
1882 syncRendererState();
Jamie Madillc564c072017-06-01 12:45:42 -04001883 handleError(mImplementation->drawArraysIndirect(this, mode, indirect));
Jiajia Qind9671222016-11-29 16:30:31 +08001884}
1885
Jamie Madill876429b2017-04-20 15:46:24 -04001886void Context::drawElementsIndirect(GLenum mode, GLenum type, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001887{
1888 syncRendererState();
Jamie Madillc564c072017-06-01 12:45:42 -04001889 handleError(mImplementation->drawElementsIndirect(this, mode, type, indirect));
Jiajia Qind9671222016-11-29 16:30:31 +08001890}
1891
Jamie Madill675fe712016-12-19 13:07:54 -05001892void Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001893{
Jamie Madill675fe712016-12-19 13:07:54 -05001894 handleError(mImplementation->flush());
Geoff Lang129753a2015-01-09 16:52:09 -05001895}
1896
Jamie Madill675fe712016-12-19 13:07:54 -05001897void Context::finish()
Geoff Lang129753a2015-01-09 16:52:09 -05001898{
Jamie Madill675fe712016-12-19 13:07:54 -05001899 handleError(mImplementation->finish());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001900}
1901
Austin Kinross6ee1e782015-05-29 17:05:37 -07001902void Context::insertEventMarker(GLsizei length, const char *marker)
1903{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001904 ASSERT(mImplementation);
1905 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001906}
1907
1908void Context::pushGroupMarker(GLsizei length, const char *marker)
1909{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001910 ASSERT(mImplementation);
1911 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001912}
1913
1914void Context::popGroupMarker()
1915{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001916 ASSERT(mImplementation);
1917 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001918}
1919
Geoff Langd8605522016-04-13 10:19:12 -04001920void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1921{
1922 Program *programObject = getProgram(program);
1923 ASSERT(programObject);
1924
1925 programObject->bindUniformLocation(location, name);
1926}
1927
Sami Väisänena797e062016-05-12 15:23:40 +03001928void Context::setCoverageModulation(GLenum components)
1929{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001930 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001931}
1932
Sami Väisänene45e53b2016-05-25 10:36:04 +03001933void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1934{
1935 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1936}
1937
1938void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1939{
1940 GLfloat I[16];
1941 angle::Matrix<GLfloat>::setToIdentity(I);
1942
1943 mGLState.loadPathRenderingMatrix(matrixMode, I);
1944}
1945
1946void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1947{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001948 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001949 if (!pathObj)
1950 return;
1951
1952 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1953 syncRendererState();
1954
1955 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1956}
1957
1958void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1959{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001960 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001961 if (!pathObj)
1962 return;
1963
1964 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1965 syncRendererState();
1966
1967 mImplementation->stencilStrokePath(pathObj, reference, mask);
1968}
1969
1970void Context::coverFillPath(GLuint path, GLenum coverMode)
1971{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001972 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001973 if (!pathObj)
1974 return;
1975
1976 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1977 syncRendererState();
1978
1979 mImplementation->coverFillPath(pathObj, coverMode);
1980}
1981
1982void Context::coverStrokePath(GLuint path, GLenum coverMode)
1983{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001984 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001985 if (!pathObj)
1986 return;
1987
1988 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1989 syncRendererState();
1990
1991 mImplementation->coverStrokePath(pathObj, coverMode);
1992}
1993
1994void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1995{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001996 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001997 if (!pathObj)
1998 return;
1999
2000 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2001 syncRendererState();
2002
2003 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
2004}
2005
2006void Context::stencilThenCoverStrokePath(GLuint path,
2007 GLint reference,
2008 GLuint mask,
2009 GLenum coverMode)
2010{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002011 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03002012 if (!pathObj)
2013 return;
2014
2015 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2016 syncRendererState();
2017
2018 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
2019}
2020
Sami Väisänend59ca052016-06-21 16:10:00 +03002021void Context::coverFillPathInstanced(GLsizei numPaths,
2022 GLenum pathNameType,
2023 const void *paths,
2024 GLuint pathBase,
2025 GLenum coverMode,
2026 GLenum transformType,
2027 const GLfloat *transformValues)
2028{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002029 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002030
2031 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2032 syncRendererState();
2033
2034 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
2035}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002036
Sami Väisänend59ca052016-06-21 16:10:00 +03002037void Context::coverStrokePathInstanced(GLsizei numPaths,
2038 GLenum pathNameType,
2039 const void *paths,
2040 GLuint pathBase,
2041 GLenum coverMode,
2042 GLenum transformType,
2043 const GLfloat *transformValues)
2044{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002045 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002046
2047 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2048 syncRendererState();
2049
2050 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
2051 transformValues);
2052}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002053
Sami Väisänend59ca052016-06-21 16:10:00 +03002054void Context::stencilFillPathInstanced(GLsizei numPaths,
2055 GLenum pathNameType,
2056 const void *paths,
2057 GLuint pathBase,
2058 GLenum fillMode,
2059 GLuint mask,
2060 GLenum transformType,
2061 const GLfloat *transformValues)
2062{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002063 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002064
2065 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2066 syncRendererState();
2067
2068 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
2069 transformValues);
2070}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002071
Sami Väisänend59ca052016-06-21 16:10:00 +03002072void Context::stencilStrokePathInstanced(GLsizei numPaths,
2073 GLenum pathNameType,
2074 const void *paths,
2075 GLuint pathBase,
2076 GLint reference,
2077 GLuint mask,
2078 GLenum transformType,
2079 const GLfloat *transformValues)
2080{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002081 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002082
2083 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2084 syncRendererState();
2085
2086 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
2087 transformValues);
2088}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002089
Sami Väisänend59ca052016-06-21 16:10:00 +03002090void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
2091 GLenum pathNameType,
2092 const void *paths,
2093 GLuint pathBase,
2094 GLenum fillMode,
2095 GLuint mask,
2096 GLenum coverMode,
2097 GLenum transformType,
2098 const GLfloat *transformValues)
2099{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002100 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002101
2102 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2103 syncRendererState();
2104
2105 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
2106 transformType, transformValues);
2107}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002108
Sami Väisänend59ca052016-06-21 16:10:00 +03002109void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
2110 GLenum pathNameType,
2111 const void *paths,
2112 GLuint pathBase,
2113 GLint reference,
2114 GLuint mask,
2115 GLenum coverMode,
2116 GLenum transformType,
2117 const GLfloat *transformValues)
2118{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002119 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002120
2121 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2122 syncRendererState();
2123
2124 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
2125 transformType, transformValues);
2126}
2127
Sami Väisänen46eaa942016-06-29 10:26:37 +03002128void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
2129{
2130 auto *programObject = getProgram(program);
2131
2132 programObject->bindFragmentInputLocation(location, name);
2133}
2134
2135void Context::programPathFragmentInputGen(GLuint program,
2136 GLint location,
2137 GLenum genMode,
2138 GLint components,
2139 const GLfloat *coeffs)
2140{
2141 auto *programObject = getProgram(program);
2142
Jamie Madillbd044ed2017-06-05 12:59:21 -04002143 programObject->pathFragmentInputGen(this, location, genMode, components, coeffs);
Sami Väisänen46eaa942016-06-29 10:26:37 +03002144}
2145
jchen1015015f72017-03-16 13:54:21 +08002146GLuint Context::getProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name)
2147{
jchen10fd7c3b52017-03-21 15:36:03 +08002148 const auto *programObject = getProgram(program);
jchen1015015f72017-03-16 13:54:21 +08002149 return QueryProgramResourceIndex(programObject, programInterface, name);
2150}
2151
jchen10fd7c3b52017-03-21 15:36:03 +08002152void Context::getProgramResourceName(GLuint program,
2153 GLenum programInterface,
2154 GLuint index,
2155 GLsizei bufSize,
2156 GLsizei *length,
2157 GLchar *name)
2158{
2159 const auto *programObject = getProgram(program);
2160 QueryProgramResourceName(programObject, programInterface, index, bufSize, length, name);
2161}
2162
Jamie Madill437fa652016-05-03 15:13:24 -04002163void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002164{
Geoff Langda5777c2014-07-11 09:52:58 -04002165 if (error.isError())
2166 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002167 GLenum code = error.getCode();
2168 mErrors.insert(code);
2169 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
2170 {
2171 markContextLost();
2172 }
Geoff Lang70d0f492015-12-10 17:45:46 -05002173
2174 if (!error.getMessage().empty())
2175 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002176 auto *debug = &mGLState.getDebug();
2177 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
2178 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05002179 }
Geoff Langda5777c2014-07-11 09:52:58 -04002180 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002181}
2182
2183// Get one of the recorded errors and clear its flag, if any.
2184// [OpenGL ES 2.0.24] section 2.5 page 13.
2185GLenum Context::getError()
2186{
Geoff Langda5777c2014-07-11 09:52:58 -04002187 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002188 {
Geoff Langda5777c2014-07-11 09:52:58 -04002189 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002190 }
Geoff Langda5777c2014-07-11 09:52:58 -04002191 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002192 {
Geoff Langda5777c2014-07-11 09:52:58 -04002193 GLenum error = *mErrors.begin();
2194 mErrors.erase(mErrors.begin());
2195 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002196 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002197}
2198
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002199// NOTE: this function should not assume that this context is current!
2200void Context::markContextLost()
2201{
2202 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002203 {
Jamie Madill231c7f52017-04-26 13:45:37 -04002204 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002205 mContextLostForced = true;
2206 }
Jamie Madill231c7f52017-04-26 13:45:37 -04002207 mContextLost = true;
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002208}
2209
2210bool Context::isContextLost()
2211{
2212 return mContextLost;
2213}
2214
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002215GLenum Context::getResetStatus()
2216{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002217 // Even if the application doesn't want to know about resets, we want to know
2218 // as it will allow us to skip all the calls.
2219 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002220 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002221 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002222 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002223 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002224 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002225
2226 // EXT_robustness, section 2.6: If the reset notification behavior is
2227 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2228 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2229 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002230 }
2231
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002232 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2233 // status should be returned at least once, and GL_NO_ERROR should be returned
2234 // once the device has finished resetting.
2235 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002236 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002237 ASSERT(mResetStatus == GL_NO_ERROR);
2238 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002239
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002240 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002241 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002242 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002243 }
2244 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002245 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002246 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002247 // If markContextLost was used to mark the context lost then
2248 // assume that is not recoverable, and continue to report the
2249 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002250 mResetStatus = mImplementation->getResetStatus();
2251 }
Jamie Madill893ab082014-05-16 16:56:10 -04002252
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002253 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002254}
2255
2256bool Context::isResetNotificationEnabled()
2257{
2258 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2259}
2260
Corentin Walleze3b10e82015-05-20 11:06:25 -04002261const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002262{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002263 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002264}
2265
2266EGLenum Context::getClientType() const
2267{
2268 return mClientType;
2269}
2270
2271EGLenum Context::getRenderBuffer() const
2272{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002273 const Framebuffer *framebuffer = mState.mFramebuffers->getFramebuffer(0);
2274 if (framebuffer == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -04002275 {
2276 return EGL_NONE;
2277 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002278
2279 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2280 ASSERT(backAttachment != nullptr);
2281 return backAttachment->getSurface()->getRenderBuffer();
Régis Fénéon83107972015-02-05 12:57:44 +01002282}
2283
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002284VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002285{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002286 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002287 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2288 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002289 {
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002290 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle,
2291 mCaps.maxVertexAttributes, mCaps.maxVertexAttribBindings);
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002292
Jamie Madill96a483b2017-06-27 16:49:21 -04002293 mVertexArrayMap.assign(vertexArrayHandle, vertexArray);
Geoff Lang36167ab2015-12-07 10:27:14 -05002294 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002295
2296 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002297}
2298
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002299TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002300{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002301 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002302 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2303 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002304 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002305 transformFeedback =
2306 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002307 transformFeedback->addRef();
Jamie Madill96a483b2017-06-27 16:49:21 -04002308 mTransformFeedbackMap.assign(transformFeedbackHandle, transformFeedback);
Geoff Lang36167ab2015-12-07 10:27:14 -05002309 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002310
2311 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002312}
2313
2314bool Context::isVertexArrayGenerated(GLuint vertexArray)
2315{
Jamie Madill96a483b2017-06-27 16:49:21 -04002316 ASSERT(mVertexArrayMap.contains(0));
2317 return mVertexArrayMap.contains(vertexArray);
Geoff Lang36167ab2015-12-07 10:27:14 -05002318}
2319
2320bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2321{
Jamie Madill96a483b2017-06-27 16:49:21 -04002322 ASSERT(mTransformFeedbackMap.contains(0));
2323 return mTransformFeedbackMap.contains(transformFeedback);
Geoff Lang36167ab2015-12-07 10:27:14 -05002324}
2325
Shannon Woods53a94a82014-06-24 15:20:36 -04002326void Context::detachTexture(GLuint texture)
2327{
2328 // Simple pass-through to State's detachTexture method, as textures do not require
2329 // allocation map management either here or in the resource manager at detach time.
2330 // Zero textures are held by the Context, and we don't attempt to request them from
2331 // the State.
Jamie Madilla02315b2017-02-23 14:14:47 -05002332 mGLState.detachTexture(this, mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002333}
2334
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002335void Context::detachBuffer(GLuint buffer)
2336{
Yuly Novikov5807a532015-12-03 13:01:22 -05002337 // Simple pass-through to State's detachBuffer method, since
2338 // only buffer attachments to container objects that are bound to the current context
2339 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002340
Yuly Novikov5807a532015-12-03 13:01:22 -05002341 // [OpenGL ES 3.2] section 5.1.2 page 45:
2342 // Attachments to unbound container objects, such as
2343 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2344 // are not affected and continue to act as references on the deleted object
Jamie Madill4928b7c2017-06-20 12:57:39 -04002345 mGLState.detachBuffer(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002346}
2347
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002348void Context::detachFramebuffer(GLuint framebuffer)
2349{
Shannon Woods53a94a82014-06-24 15:20:36 -04002350 // Framebuffer detachment is handled by Context, because 0 is a valid
2351 // Framebuffer object, and a pointer to it must be passed from Context
2352 // to State at binding time.
2353
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002354 // [OpenGL ES 2.0.24] section 4.4 page 107:
Jamie Madill231c7f52017-04-26 13:45:37 -04002355 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as
2356 // though BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of
2357 // zero.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002358
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002359 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002360 {
2361 bindReadFramebuffer(0);
2362 }
2363
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002364 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002365 {
2366 bindDrawFramebuffer(0);
2367 }
2368}
2369
2370void Context::detachRenderbuffer(GLuint renderbuffer)
2371{
Jamie Madilla02315b2017-02-23 14:14:47 -05002372 mGLState.detachRenderbuffer(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002373}
2374
Jamie Madill57a89722013-07-02 11:57:03 -04002375void Context::detachVertexArray(GLuint vertexArray)
2376{
Jamie Madill77a72f62015-04-14 11:18:32 -04002377 // Vertex array detachment is handled by Context, because 0 is a valid
2378 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002379 // binding time.
2380
Jamie Madill57a89722013-07-02 11:57:03 -04002381 // [OpenGL ES 3.0.2] section 2.10 page 43:
2382 // If a vertex array object that is currently bound is deleted, the binding
2383 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002384 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002385 {
2386 bindVertexArray(0);
2387 }
2388}
2389
Geoff Langc8058452014-02-03 12:04:11 -05002390void Context::detachTransformFeedback(GLuint transformFeedback)
2391{
Corentin Walleza2257da2016-04-19 16:43:12 -04002392 // Transform feedback detachment is handled by Context, because 0 is a valid
2393 // transform feedback, and a pointer to it must be passed from Context to State at
2394 // binding time.
2395
2396 // The OpenGL specification doesn't mention what should happen when the currently bound
2397 // transform feedback object is deleted. Since it is a container object, we treat it like
2398 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madill4928b7c2017-06-20 12:57:39 -04002399 if (mGLState.removeTransformFeedbackBinding(this, transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002400 {
2401 bindTransformFeedback(0);
2402 }
Geoff Langc8058452014-02-03 12:04:11 -05002403}
2404
Jamie Madilldc356042013-07-19 16:36:57 -04002405void Context::detachSampler(GLuint sampler)
2406{
Jamie Madill4928b7c2017-06-20 12:57:39 -04002407 mGLState.detachSampler(this, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002408}
2409
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002410void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2411{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002412 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002413}
2414
Jamie Madille29d1672013-07-19 16:36:57 -04002415void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2416{
Geoff Langc1984ed2016-10-07 12:41:00 -04002417 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002418 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002419 SetSamplerParameteri(samplerObject, pname, param);
2420}
Jamie Madille29d1672013-07-19 16:36:57 -04002421
Geoff Langc1984ed2016-10-07 12:41:00 -04002422void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2423{
2424 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002425 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002426 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002427}
2428
2429void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2430{
Geoff Langc1984ed2016-10-07 12:41:00 -04002431 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002432 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002433 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002434}
2435
Geoff Langc1984ed2016-10-07 12:41:00 -04002436void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002437{
Geoff Langc1984ed2016-10-07 12:41:00 -04002438 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002439 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002440 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002441}
2442
Geoff Langc1984ed2016-10-07 12:41:00 -04002443void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002444{
Geoff Langc1984ed2016-10-07 12:41:00 -04002445 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002446 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002447 QuerySamplerParameteriv(samplerObject, pname, params);
2448}
Jamie Madill9675b802013-07-19 16:36:59 -04002449
Geoff Langc1984ed2016-10-07 12:41:00 -04002450void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2451{
2452 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002453 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002454 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002455}
2456
Olli Etuahof0fee072016-03-30 15:11:58 +03002457void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2458{
2459 gl::Program *programObject = getProgram(program);
Yunchao He61afff12017-03-14 15:34:03 +08002460 SetProgramParameteri(programObject, pname, value);
Olli Etuahof0fee072016-03-30 15:11:58 +03002461}
2462
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002463void Context::initRendererString()
2464{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002465 std::ostringstream rendererString;
2466 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002467 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002468 rendererString << ")";
2469
Geoff Langcec35902014-04-16 10:52:36 -04002470 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002471}
2472
Geoff Langc339c4e2016-11-29 10:37:36 -05002473void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002474{
Geoff Langc339c4e2016-11-29 10:37:36 -05002475 const Version &clientVersion = getClientVersion();
2476
2477 std::ostringstream versionString;
2478 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2479 << ANGLE_VERSION_STRING << ")";
2480 mVersionString = MakeStaticString(versionString.str());
2481
2482 std::ostringstream shadingLanguageVersionString;
2483 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2484 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2485 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2486 << ")";
2487 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002488}
2489
Geoff Langcec35902014-04-16 10:52:36 -04002490void Context::initExtensionStrings()
2491{
Geoff Langc339c4e2016-11-29 10:37:36 -05002492 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2493 std::ostringstream combinedStringStream;
2494 std::copy(strings.begin(), strings.end(),
2495 std::ostream_iterator<const char *>(combinedStringStream, " "));
2496 return MakeStaticString(combinedStringStream.str());
2497 };
2498
2499 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002500 for (const auto &extensionString : mExtensions.getStrings())
2501 {
2502 mExtensionStrings.push_back(MakeStaticString(extensionString));
2503 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002504 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002505
Bryan Bernhart58806562017-01-05 13:09:31 -08002506 const gl::Extensions &nativeExtensions = mImplementation->getNativeExtensions();
2507
Geoff Langc339c4e2016-11-29 10:37:36 -05002508 mRequestableExtensionStrings.clear();
2509 for (const auto &extensionInfo : GetExtensionInfoMap())
2510 {
2511 if (extensionInfo.second.Requestable &&
Bryan Bernhart58806562017-01-05 13:09:31 -08002512 !(mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
2513 nativeExtensions.*(extensionInfo.second.ExtensionsMember))
Geoff Langc339c4e2016-11-29 10:37:36 -05002514 {
2515 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2516 }
2517 }
2518 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002519}
2520
Geoff Langc339c4e2016-11-29 10:37:36 -05002521const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002522{
Geoff Langc339c4e2016-11-29 10:37:36 -05002523 switch (name)
2524 {
2525 case GL_VENDOR:
2526 return reinterpret_cast<const GLubyte *>("Google Inc.");
2527
2528 case GL_RENDERER:
2529 return reinterpret_cast<const GLubyte *>(mRendererString);
2530
2531 case GL_VERSION:
2532 return reinterpret_cast<const GLubyte *>(mVersionString);
2533
2534 case GL_SHADING_LANGUAGE_VERSION:
2535 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2536
2537 case GL_EXTENSIONS:
2538 return reinterpret_cast<const GLubyte *>(mExtensionString);
2539
2540 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2541 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2542
2543 default:
2544 UNREACHABLE();
2545 return nullptr;
2546 }
Geoff Langcec35902014-04-16 10:52:36 -04002547}
2548
Geoff Langc339c4e2016-11-29 10:37:36 -05002549const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002550{
Geoff Langc339c4e2016-11-29 10:37:36 -05002551 switch (name)
2552 {
2553 case GL_EXTENSIONS:
2554 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2555
2556 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2557 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2558
2559 default:
2560 UNREACHABLE();
2561 return nullptr;
2562 }
Geoff Langcec35902014-04-16 10:52:36 -04002563}
2564
2565size_t Context::getExtensionStringCount() const
2566{
2567 return mExtensionStrings.size();
2568}
2569
Geoff Langc339c4e2016-11-29 10:37:36 -05002570void Context::requestExtension(const char *name)
2571{
2572 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2573 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2574 const auto &extension = extensionInfos.at(name);
2575 ASSERT(extension.Requestable);
2576
2577 if (mExtensions.*(extension.ExtensionsMember))
2578 {
2579 // Extension already enabled
2580 return;
2581 }
2582
2583 mExtensions.*(extension.ExtensionsMember) = true;
2584 updateCaps();
2585 initExtensionStrings();
Bryan Bernhart58806562017-01-05 13:09:31 -08002586
Jamie Madill2f348d22017-06-05 10:50:59 -04002587 // Release the shader compiler so it will be re-created with the requested extensions enabled.
2588 releaseShaderCompiler();
Geoff Lang9aded172017-04-05 11:07:56 -04002589
2590 // Invalidate all cached completenesses for textures and framebuffer. Some extensions make new
2591 // formats renderable or sampleable.
2592 mState.mTextures->invalidateTextureComplenessCache();
2593 for (auto &zeroTexture : mZeroTextures)
2594 {
2595 zeroTexture.second->invalidateCompletenessCache();
2596 }
2597
2598 mState.mFramebuffers->invalidateFramebufferComplenessCache();
Geoff Langc339c4e2016-11-29 10:37:36 -05002599}
2600
2601size_t Context::getRequestableExtensionStringCount() const
2602{
2603 return mRequestableExtensionStrings.size();
2604}
2605
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002606void Context::beginTransformFeedback(GLenum primitiveMode)
2607{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002608 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002609 ASSERT(transformFeedback != nullptr);
2610 ASSERT(!transformFeedback->isPaused());
2611
Jamie Madill6c1f6712017-02-14 19:08:04 -05002612 transformFeedback->begin(this, primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002613}
2614
2615bool Context::hasActiveTransformFeedback(GLuint program) const
2616{
2617 for (auto pair : mTransformFeedbackMap)
2618 {
2619 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2620 {
2621 return true;
2622 }
2623 }
2624 return false;
2625}
2626
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002627void Context::initCaps(const egl::DisplayExtensions &displayExtensions)
Geoff Lang493daf52014-07-03 13:38:44 -04002628{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002629 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002630
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002631 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002632
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002633 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002634
Geoff Langeb66a6e2016-10-31 13:06:12 -04002635 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002636 {
2637 // Disable ES3+ extensions
Jamie Madill231c7f52017-04-26 13:45:37 -04002638 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002639 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002640 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002641 }
2642
Geoff Langeb66a6e2016-10-31 13:06:12 -04002643 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002644 {
2645 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
Jamie Madill231c7f52017-04-26 13:45:37 -04002646 // mExtensions.sRGB = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002647 }
2648
Jamie Madill00ed7a12016-05-19 13:13:38 -04002649 // Some extensions are always available because they are implemented in the GL layer.
Jamie Madill231c7f52017-04-26 13:45:37 -04002650 mExtensions.bindUniformLocation = true;
2651 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002652 mExtensions.bindGeneratesResource = true;
Geoff Langfeb8c682017-02-13 16:07:35 -05002653 mExtensions.clientArrays = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002654 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002655
2656 // Enable the no error extension if the context was created with the flag.
2657 mExtensions.noError = mSkipValidation;
2658
Corentin Wallezccab69d2017-01-27 16:57:15 -05002659 // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
Corentin Wallezc295e512017-01-27 17:47:50 -05002660 mExtensions.surfacelessContext = displayExtensions.surfacelessContext;
Corentin Wallezccab69d2017-01-27 16:57:15 -05002661
Geoff Lang70d0f492015-12-10 17:45:46 -05002662 // Explicitly enable GL_KHR_debug
2663 mExtensions.debug = true;
2664 mExtensions.maxDebugMessageLength = 1024;
2665 mExtensions.maxDebugLoggedMessages = 1024;
2666 mExtensions.maxDebugGroupStackDepth = 1024;
2667 mExtensions.maxLabelLength = 1024;
2668
Geoff Langff5b2d52016-09-07 11:32:23 -04002669 // Explicitly enable GL_ANGLE_robust_client_memory
2670 mExtensions.robustClientMemory = true;
2671
Jamie Madille08a1d32017-03-07 17:24:06 -05002672 // Determine robust resource init availability from EGL.
2673 mExtensions.robustResourceInitialization =
Jamie Madill948bbe52017-06-01 13:10:42 -04002674 egl::Display::GetClientExtensions().displayRobustResourceInitialization;
Jamie Madille08a1d32017-03-07 17:24:06 -05002675
Geoff Lang301d1612014-07-09 10:34:37 -04002676 // Apply implementation limits
2677 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002678 mCaps.maxVertexAttribBindings =
2679 getClientVersion() < ES_3_1
2680 ? mCaps.maxVertexAttributes
2681 : std::min<GLuint>(mCaps.maxVertexAttribBindings, MAX_VERTEX_ATTRIB_BINDINGS);
2682
Jamie Madill231c7f52017-04-26 13:45:37 -04002683 mCaps.maxVertexUniformBlocks = std::min<GLuint>(
2684 mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2685 mCaps.maxVertexOutputComponents =
2686 std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang301d1612014-07-09 10:34:37 -04002687
Jamie Madill231c7f52017-04-26 13:45:37 -04002688 mCaps.maxFragmentInputComponents =
2689 std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002690
Geoff Langc287ea62016-09-16 14:46:51 -04002691 // WebGL compatibility
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002692 mExtensions.webglCompatibility = mWebGLContext;
Geoff Langc287ea62016-09-16 14:46:51 -04002693 for (const auto &extensionInfo : GetExtensionInfoMap())
2694 {
2695 // If this context is for WebGL, disable all enableable extensions
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002696 if (mWebGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002697 {
2698 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2699 }
2700 }
2701
2702 // Generate texture caps
2703 updateCaps();
2704}
2705
2706void Context::updateCaps()
2707{
Geoff Lang900013c2014-07-07 11:32:19 -04002708 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002709 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002710
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002711 for (auto capsIt : mImplementation->getNativeTextureCaps())
Geoff Lang493daf52014-07-03 13:38:44 -04002712 {
Geoff Langca271392017-04-05 12:30:00 -04002713 GLenum sizedInternalFormat = capsIt.first;
Jamie Madill231c7f52017-04-26 13:45:37 -04002714 TextureCaps formatCaps = capsIt.second;
Geoff Lang493daf52014-07-03 13:38:44 -04002715
Geoff Langca271392017-04-05 12:30:00 -04002716 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002717
Geoff Lang0d8b7242015-09-09 14:56:53 -04002718 // Update the format caps based on the client version and extensions.
2719 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2720 // ES3.
2721 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002722 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002723 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002724 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002725 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002726 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002727
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002728 // OpenGL ES does not support multisampling with non-rendererable formats
2729 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
Olli Etuaho50c562d2017-06-06 14:43:30 +03002730 if (!formatCaps.renderable ||
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002731 (getClientVersion() < ES_3_1 &&
2732 (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
Geoff Lang493daf52014-07-03 13:38:44 -04002733 {
Geoff Langd87878e2014-09-19 15:42:59 -04002734 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002735 }
Olli Etuaho50c562d2017-06-06 14:43:30 +03002736 else
2737 {
2738 // We may have limited the max samples for some required renderbuffer formats due to
2739 // non-conformant formats. In this case MAX_SAMPLES needs to be lowered accordingly.
2740 GLuint formatMaxSamples = formatCaps.getMaxSamples();
2741
2742 // GLES 3.0.5 section 4.4.2.2: "Implementations must support creation of renderbuffers
2743 // in these required formats with up to the value of MAX_SAMPLES multisamples, with the
2744 // exception of signed and unsigned integer formats."
2745 if (formatInfo.componentType != GL_INT && formatInfo.componentType != GL_UNSIGNED_INT &&
2746 formatInfo.isRequiredRenderbufferFormat(getClientVersion()))
2747 {
2748 ASSERT(getClientVersion() < ES_3_0 || formatMaxSamples >= 4);
2749 mCaps.maxSamples = std::min(mCaps.maxSamples, formatMaxSamples);
2750 }
2751
2752 // Handle GLES 3.1 MAX_*_SAMPLES values similarly to MAX_SAMPLES.
2753 if (getClientVersion() >= ES_3_1)
2754 {
2755 // GLES 3.1 section 9.2.5: "Implementations must support creation of renderbuffers
2756 // in these required formats with up to the value of MAX_SAMPLES multisamples, with
2757 // the exception that the signed and unsigned integer formats are required only to
2758 // support creation of renderbuffers with up to the value of MAX_INTEGER_SAMPLES
2759 // multisamples, which must be at least one."
2760 if (formatInfo.componentType == GL_INT ||
2761 formatInfo.componentType == GL_UNSIGNED_INT)
2762 {
2763 mCaps.maxIntegerSamples = std::min(mCaps.maxIntegerSamples, formatMaxSamples);
2764 }
2765
2766 // GLES 3.1 section 19.3.1.
2767 if (formatCaps.texturable)
2768 {
2769 if (formatInfo.depthBits > 0)
2770 {
2771 mCaps.maxDepthTextureSamples =
2772 std::min(mCaps.maxDepthTextureSamples, formatMaxSamples);
2773 }
2774 else if (formatInfo.redBits > 0)
2775 {
2776 mCaps.maxColorTextureSamples =
2777 std::min(mCaps.maxColorTextureSamples, formatMaxSamples);
2778 }
2779 }
2780 }
2781 }
Geoff Langd87878e2014-09-19 15:42:59 -04002782
2783 if (formatCaps.texturable && formatInfo.compressed)
2784 {
Geoff Langca271392017-04-05 12:30:00 -04002785 mCaps.compressedTextureFormats.push_back(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002786 }
2787
Geoff Langca271392017-04-05 12:30:00 -04002788 mTextureCaps.insert(sizedInternalFormat, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002789 }
Jamie Madill32447362017-06-28 14:53:52 -04002790
2791 // If program binary is disabled, blank out the memory cache pointer.
2792 if (!mImplementation->getNativeExtensions().getProgramBinary)
2793 {
2794 mMemoryProgramCache = nullptr;
2795 }
Geoff Lang493daf52014-07-03 13:38:44 -04002796}
2797
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002798void Context::initWorkarounds()
2799{
Jamie Madill761b02c2017-06-23 16:27:06 -04002800 // Apply back-end workarounds.
2801 mImplementation->applyNativeWorkarounds(&mWorkarounds);
2802
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002803 // Lose the context upon out of memory error if the application is
2804 // expecting to watch for those events.
2805 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2806}
2807
Jamie Madill1b94d432015-08-07 13:23:23 -04002808void Context::syncRendererState()
2809{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002810 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
Jamie Madillfe548342017-06-19 11:13:24 -04002811 mImplementation->syncState(this, dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002812 mGLState.clearDirtyBits();
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002813 mGLState.syncDirtyObjects(this);
Jamie Madill1b94d432015-08-07 13:23:23 -04002814}
2815
Jamie Madillad9f24e2016-02-12 09:27:24 -05002816void Context::syncRendererState(const State::DirtyBits &bitMask,
2817 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002818{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002819 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
Jamie Madillfe548342017-06-19 11:13:24 -04002820 mImplementation->syncState(this, dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002821 mGLState.clearDirtyBits(dirtyBits);
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002822 mGLState.syncDirtyObjects(this, objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002823}
Jamie Madillc29968b2016-01-20 11:17:23 -05002824
2825void Context::blitFramebuffer(GLint srcX0,
2826 GLint srcY0,
2827 GLint srcX1,
2828 GLint srcY1,
2829 GLint dstX0,
2830 GLint dstY0,
2831 GLint dstX1,
2832 GLint dstY1,
2833 GLbitfield mask,
2834 GLenum filter)
2835{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002836 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002837 ASSERT(drawFramebuffer);
2838
2839 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2840 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2841
Jamie Madillad9f24e2016-02-12 09:27:24 -05002842 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002843
Jamie Madillc564c072017-06-01 12:45:42 -04002844 handleError(drawFramebuffer->blit(this, srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002845}
Jamie Madillc29968b2016-01-20 11:17:23 -05002846
2847void Context::clear(GLbitfield mask)
2848{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002849 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002850 handleError(mGLState.getDrawFramebuffer()->clear(this, mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002851}
2852
2853void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2854{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002855 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002856 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002857}
2858
2859void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2860{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002861 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002862 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002863}
2864
2865void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2866{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002867 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002868 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002869}
2870
2871void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2872{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002873 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002874 ASSERT(framebufferObject);
2875
2876 // If a buffer is not present, the clear has no effect
2877 if (framebufferObject->getDepthbuffer() == nullptr &&
2878 framebufferObject->getStencilbuffer() == nullptr)
2879 {
2880 return;
2881 }
2882
Jamie Madillad9f24e2016-02-12 09:27:24 -05002883 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002884 handleError(framebufferObject->clearBufferfi(this, buffer, drawbuffer, depth, stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002885}
2886
2887void Context::readPixels(GLint x,
2888 GLint y,
2889 GLsizei width,
2890 GLsizei height,
2891 GLenum format,
2892 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002893 void *pixels)
Jamie Madillc29968b2016-01-20 11:17:23 -05002894{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002895 if (width == 0 || height == 0)
2896 {
2897 return;
2898 }
2899
Jamie Madillad9f24e2016-02-12 09:27:24 -05002900 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002901
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002902 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002903 ASSERT(framebufferObject);
2904
2905 Rectangle area(x, y, width, height);
Jamie Madillc564c072017-06-01 12:45:42 -04002906 handleError(framebufferObject->readPixels(this, area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002907}
2908
2909void Context::copyTexImage2D(GLenum target,
2910 GLint level,
2911 GLenum internalformat,
2912 GLint x,
2913 GLint y,
2914 GLsizei width,
2915 GLsizei height,
2916 GLint border)
2917{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002918 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002919 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002920
Jamie Madillc29968b2016-01-20 11:17:23 -05002921 Rectangle sourceArea(x, y, width, height);
2922
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002923 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002924 Texture *texture =
2925 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002926 handleError(texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002927}
2928
2929void Context::copyTexSubImage2D(GLenum target,
2930 GLint level,
2931 GLint xoffset,
2932 GLint yoffset,
2933 GLint x,
2934 GLint y,
2935 GLsizei width,
2936 GLsizei height)
2937{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002938 if (width == 0 || height == 0)
2939 {
2940 return;
2941 }
2942
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002943 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002944 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002945
Jamie Madillc29968b2016-01-20 11:17:23 -05002946 Offset destOffset(xoffset, yoffset, 0);
2947 Rectangle sourceArea(x, y, width, height);
2948
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002949 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002950 Texture *texture =
2951 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002952 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002953}
2954
2955void Context::copyTexSubImage3D(GLenum target,
2956 GLint level,
2957 GLint xoffset,
2958 GLint yoffset,
2959 GLint zoffset,
2960 GLint x,
2961 GLint y,
2962 GLsizei width,
2963 GLsizei height)
2964{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002965 if (width == 0 || height == 0)
2966 {
2967 return;
2968 }
2969
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002970 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002971 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002972
Jamie Madillc29968b2016-01-20 11:17:23 -05002973 Offset destOffset(xoffset, yoffset, zoffset);
2974 Rectangle sourceArea(x, y, width, height);
2975
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002976 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002977 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002978 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002979}
2980
2981void Context::framebufferTexture2D(GLenum target,
2982 GLenum attachment,
2983 GLenum textarget,
2984 GLuint texture,
2985 GLint level)
2986{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002987 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002988 ASSERT(framebuffer);
2989
2990 if (texture != 0)
2991 {
2992 Texture *textureObj = getTexture(texture);
2993
2994 ImageIndex index = ImageIndex::MakeInvalid();
2995
2996 if (textarget == GL_TEXTURE_2D)
2997 {
2998 index = ImageIndex::Make2D(level);
2999 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08003000 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
3001 {
3002 ASSERT(level == 0);
3003 index = ImageIndex::Make2DMultisample();
3004 }
Jamie Madillc29968b2016-01-20 11:17:23 -05003005 else
3006 {
3007 ASSERT(IsCubeMapTextureTarget(textarget));
3008 index = ImageIndex::MakeCube(textarget, level);
3009 }
3010
Jamie Madilla02315b2017-02-23 14:14:47 -05003011 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
Jamie Madillc29968b2016-01-20 11:17:23 -05003012 }
3013 else
3014 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003015 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003016 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003017
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003018 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003019}
3020
3021void Context::framebufferRenderbuffer(GLenum target,
3022 GLenum attachment,
3023 GLenum renderbuffertarget,
3024 GLuint renderbuffer)
3025{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003026 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003027 ASSERT(framebuffer);
3028
3029 if (renderbuffer != 0)
3030 {
3031 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
Jamie Madilla02315b2017-02-23 14:14:47 -05003032
3033 framebuffer->setAttachment(this, GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
Jamie Madillc29968b2016-01-20 11:17:23 -05003034 renderbufferObject);
3035 }
3036 else
3037 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003038 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003039 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003040
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003041 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003042}
3043
3044void Context::framebufferTextureLayer(GLenum target,
3045 GLenum attachment,
3046 GLuint texture,
3047 GLint level,
3048 GLint layer)
3049{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003050 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003051 ASSERT(framebuffer);
3052
3053 if (texture != 0)
3054 {
3055 Texture *textureObject = getTexture(texture);
3056
3057 ImageIndex index = ImageIndex::MakeInvalid();
3058
3059 if (textureObject->getTarget() == GL_TEXTURE_3D)
3060 {
3061 index = ImageIndex::Make3D(level, layer);
3062 }
3063 else
3064 {
3065 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
3066 index = ImageIndex::Make2DArray(level, layer);
3067 }
3068
Jamie Madilla02315b2017-02-23 14:14:47 -05003069 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObject);
Jamie Madillc29968b2016-01-20 11:17:23 -05003070 }
3071 else
3072 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003073 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003074 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003075
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003076 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003077}
3078
3079void Context::drawBuffers(GLsizei n, const GLenum *bufs)
3080{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003081 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003082 ASSERT(framebuffer);
3083 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003084 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003085}
3086
3087void Context::readBuffer(GLenum mode)
3088{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003089 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003090 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003091 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003092}
3093
3094void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
3095{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003096 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003097 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003098
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003099 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003100 ASSERT(framebuffer);
3101
3102 // The specification isn't clear what should be done when the framebuffer isn't complete.
3103 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill4928b7c2017-06-20 12:57:39 -04003104 handleError(framebuffer->discard(this, numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003105}
3106
3107void Context::invalidateFramebuffer(GLenum target,
3108 GLsizei numAttachments,
3109 const GLenum *attachments)
3110{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003111 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003112 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003113
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003114 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003115 ASSERT(framebuffer);
3116
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003117 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003118 {
Jamie Madill437fa652016-05-03 15:13:24 -04003119 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003120 }
Jamie Madill437fa652016-05-03 15:13:24 -04003121
Jamie Madill4928b7c2017-06-20 12:57:39 -04003122 handleError(framebuffer->invalidate(this, numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003123}
3124
3125void Context::invalidateSubFramebuffer(GLenum target,
3126 GLsizei numAttachments,
3127 const GLenum *attachments,
3128 GLint x,
3129 GLint y,
3130 GLsizei width,
3131 GLsizei height)
3132{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003133 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003134 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003135
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003136 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003137 ASSERT(framebuffer);
3138
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003139 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003140 {
Jamie Madill437fa652016-05-03 15:13:24 -04003141 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003142 }
Jamie Madill437fa652016-05-03 15:13:24 -04003143
3144 Rectangle area(x, y, width, height);
Jamie Madill4928b7c2017-06-20 12:57:39 -04003145 handleError(framebuffer->invalidateSub(this, numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05003146}
3147
Jamie Madill73a84962016-02-12 09:27:23 -05003148void Context::texImage2D(GLenum target,
3149 GLint level,
3150 GLint internalformat,
3151 GLsizei width,
3152 GLsizei height,
3153 GLint border,
3154 GLenum format,
3155 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003156 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003157{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003158 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003159
3160 Extents size(width, height, 1);
3161 Texture *texture =
3162 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003163 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3164 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003165}
3166
3167void Context::texImage3D(GLenum target,
3168 GLint level,
3169 GLint internalformat,
3170 GLsizei width,
3171 GLsizei height,
3172 GLsizei depth,
3173 GLint border,
3174 GLenum format,
3175 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003176 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003177{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003178 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003179
3180 Extents size(width, height, depth);
3181 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003182 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3183 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003184}
3185
3186void Context::texSubImage2D(GLenum target,
3187 GLint level,
3188 GLint xoffset,
3189 GLint yoffset,
3190 GLsizei width,
3191 GLsizei height,
3192 GLenum format,
3193 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003194 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003195{
3196 // Zero sized uploads are valid but no-ops
3197 if (width == 0 || height == 0)
3198 {
3199 return;
3200 }
3201
Jamie Madillad9f24e2016-02-12 09:27:24 -05003202 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003203
3204 Box area(xoffset, yoffset, 0, width, height, 1);
3205 Texture *texture =
3206 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003207 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3208 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003209}
3210
3211void Context::texSubImage3D(GLenum target,
3212 GLint level,
3213 GLint xoffset,
3214 GLint yoffset,
3215 GLint zoffset,
3216 GLsizei width,
3217 GLsizei height,
3218 GLsizei depth,
3219 GLenum format,
3220 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003221 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003222{
3223 // Zero sized uploads are valid but no-ops
3224 if (width == 0 || height == 0 || depth == 0)
3225 {
3226 return;
3227 }
3228
Jamie Madillad9f24e2016-02-12 09:27:24 -05003229 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003230
3231 Box area(xoffset, yoffset, zoffset, width, height, depth);
3232 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003233 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3234 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003235}
3236
3237void Context::compressedTexImage2D(GLenum target,
3238 GLint level,
3239 GLenum internalformat,
3240 GLsizei width,
3241 GLsizei height,
3242 GLint border,
3243 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003244 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003245{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003246 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003247
3248 Extents size(width, height, 1);
3249 Texture *texture =
3250 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003251 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003252 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003253 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003254}
3255
3256void Context::compressedTexImage3D(GLenum target,
3257 GLint level,
3258 GLenum internalformat,
3259 GLsizei width,
3260 GLsizei height,
3261 GLsizei depth,
3262 GLint border,
3263 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003264 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003265{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003266 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003267
3268 Extents size(width, height, depth);
3269 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003270 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003271 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003272 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003273}
3274
3275void Context::compressedTexSubImage2D(GLenum target,
3276 GLint level,
3277 GLint xoffset,
3278 GLint yoffset,
3279 GLsizei width,
3280 GLsizei height,
3281 GLenum format,
3282 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003283 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003284{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003285 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003286
3287 Box area(xoffset, yoffset, 0, width, height, 1);
3288 Texture *texture =
3289 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003290 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003291 format, imageSize,
3292 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003293}
3294
3295void Context::compressedTexSubImage3D(GLenum target,
3296 GLint level,
3297 GLint xoffset,
3298 GLint yoffset,
3299 GLint zoffset,
3300 GLsizei width,
3301 GLsizei height,
3302 GLsizei depth,
3303 GLenum format,
3304 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003305 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003306{
3307 // Zero sized uploads are valid but no-ops
3308 if (width == 0 || height == 0)
3309 {
3310 return;
3311 }
3312
Jamie Madillad9f24e2016-02-12 09:27:24 -05003313 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003314
3315 Box area(xoffset, yoffset, zoffset, width, height, depth);
3316 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003317 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003318 format, imageSize,
3319 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003320}
3321
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003322void Context::generateMipmap(GLenum target)
3323{
3324 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003325 handleError(texture->generateMipmap(this));
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003326}
3327
Geoff Lang97073d12016-04-20 10:42:34 -07003328void Context::copyTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003329 GLint sourceLevel,
3330 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003331 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003332 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003333 GLint internalFormat,
3334 GLenum destType,
3335 GLboolean unpackFlipY,
3336 GLboolean unpackPremultiplyAlpha,
3337 GLboolean unpackUnmultiplyAlpha)
3338{
3339 syncStateForTexImage();
3340
3341 gl::Texture *sourceTexture = getTexture(sourceId);
3342 gl::Texture *destTexture = getTexture(destId);
Geoff Langfc72a072017-03-24 14:52:39 -04003343 handleError(destTexture->copyTexture(
3344 this, destTarget, destLevel, internalFormat, destType, sourceLevel, unpackFlipY == GL_TRUE,
3345 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003346}
3347
3348void Context::copySubTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003349 GLint sourceLevel,
3350 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003351 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003352 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003353 GLint xoffset,
3354 GLint yoffset,
3355 GLint x,
3356 GLint y,
3357 GLsizei width,
3358 GLsizei height,
3359 GLboolean unpackFlipY,
3360 GLboolean unpackPremultiplyAlpha,
3361 GLboolean unpackUnmultiplyAlpha)
3362{
3363 // Zero sized copies are valid but no-ops
3364 if (width == 0 || height == 0)
3365 {
3366 return;
3367 }
3368
3369 syncStateForTexImage();
3370
3371 gl::Texture *sourceTexture = getTexture(sourceId);
3372 gl::Texture *destTexture = getTexture(destId);
3373 Offset offset(xoffset, yoffset, 0);
3374 Rectangle area(x, y, width, height);
Geoff Langfc72a072017-03-24 14:52:39 -04003375 handleError(destTexture->copySubTexture(
3376 this, destTarget, destLevel, offset, sourceLevel, area, unpackFlipY == GL_TRUE,
3377 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003378}
3379
Geoff Lang47110bf2016-04-20 11:13:22 -07003380void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3381{
3382 syncStateForTexImage();
3383
3384 gl::Texture *sourceTexture = getTexture(sourceId);
3385 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003386 handleError(destTexture->copyCompressedTexture(this, sourceTexture));
Geoff Lang47110bf2016-04-20 11:13:22 -07003387}
3388
Geoff Lang496c02d2016-10-20 11:38:11 -07003389void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003390{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003391 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003392 ASSERT(buffer);
3393
Geoff Lang496c02d2016-10-20 11:38:11 -07003394 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003395}
3396
Jamie Madill876429b2017-04-20 15:46:24 -04003397void *Context::mapBuffer(GLenum target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003398{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003399 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003400 ASSERT(buffer);
3401
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003402 Error error = buffer->map(this, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003403 if (error.isError())
3404 {
Jamie Madill437fa652016-05-03 15:13:24 -04003405 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003406 return nullptr;
3407 }
3408
3409 return buffer->getMapPointer();
3410}
3411
3412GLboolean Context::unmapBuffer(GLenum target)
3413{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003414 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003415 ASSERT(buffer);
3416
3417 GLboolean result;
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003418 Error error = buffer->unmap(this, &result);
Olli Etuaho4f667482016-03-30 15:56:35 +03003419 if (error.isError())
3420 {
Jamie Madill437fa652016-05-03 15:13:24 -04003421 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003422 return GL_FALSE;
3423 }
3424
3425 return result;
3426}
3427
Jamie Madill876429b2017-04-20 15:46:24 -04003428void *Context::mapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003429{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003430 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003431 ASSERT(buffer);
3432
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003433 Error error = buffer->mapRange(this, offset, length, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003434 if (error.isError())
3435 {
Jamie Madill437fa652016-05-03 15:13:24 -04003436 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003437 return nullptr;
3438 }
3439
3440 return buffer->getMapPointer();
3441}
3442
3443void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3444{
3445 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3446}
3447
Jamie Madillad9f24e2016-02-12 09:27:24 -05003448void Context::syncStateForReadPixels()
3449{
3450 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3451}
3452
3453void Context::syncStateForTexImage()
3454{
3455 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3456}
3457
3458void Context::syncStateForClear()
3459{
3460 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3461}
3462
3463void Context::syncStateForBlit()
3464{
3465 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3466}
3467
Jamie Madillc20ab272016-06-09 07:20:46 -07003468void Context::activeTexture(GLenum texture)
3469{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003470 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003471}
3472
Jamie Madill876429b2017-04-20 15:46:24 -04003473void Context::blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003474{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003475 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003476}
3477
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003478void Context::blendEquation(GLenum mode)
3479{
3480 mGLState.setBlendEquation(mode, mode);
3481}
3482
Jamie Madillc20ab272016-06-09 07:20:46 -07003483void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3484{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003485 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003486}
3487
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003488void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3489{
3490 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3491}
3492
Jamie Madillc20ab272016-06-09 07:20:46 -07003493void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3494{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003495 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003496}
3497
Jamie Madill876429b2017-04-20 15:46:24 -04003498void Context::clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003499{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003500 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003501}
3502
Jamie Madill876429b2017-04-20 15:46:24 -04003503void Context::clearDepthf(GLfloat depth)
Jamie Madillc20ab272016-06-09 07:20:46 -07003504{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003505 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003506}
3507
3508void Context::clearStencil(GLint s)
3509{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003510 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003511}
3512
3513void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3514{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003515 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003516}
3517
3518void Context::cullFace(GLenum mode)
3519{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003520 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003521}
3522
3523void Context::depthFunc(GLenum func)
3524{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003525 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003526}
3527
3528void Context::depthMask(GLboolean flag)
3529{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003530 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003531}
3532
Jamie Madill876429b2017-04-20 15:46:24 -04003533void Context::depthRangef(GLfloat zNear, GLfloat zFar)
Jamie Madillc20ab272016-06-09 07:20:46 -07003534{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003535 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003536}
3537
3538void Context::disable(GLenum cap)
3539{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003540 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003541}
3542
3543void Context::disableVertexAttribArray(GLuint index)
3544{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003545 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003546}
3547
3548void Context::enable(GLenum cap)
3549{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003550 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003551}
3552
3553void Context::enableVertexAttribArray(GLuint index)
3554{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003555 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003556}
3557
3558void Context::frontFace(GLenum mode)
3559{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003560 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003561}
3562
3563void Context::hint(GLenum target, GLenum mode)
3564{
3565 switch (target)
3566 {
3567 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003568 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003569 break;
3570
3571 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003572 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003573 break;
3574
3575 default:
3576 UNREACHABLE();
3577 return;
3578 }
3579}
3580
3581void Context::lineWidth(GLfloat width)
3582{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003583 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003584}
3585
3586void Context::pixelStorei(GLenum pname, GLint param)
3587{
3588 switch (pname)
3589 {
3590 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003591 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003592 break;
3593
3594 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003595 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003596 break;
3597
3598 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003599 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003600 break;
3601
3602 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003603 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003604 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003605 break;
3606
3607 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003608 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003609 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003610 break;
3611
3612 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003613 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003614 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003615 break;
3616
3617 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003618 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003619 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003620 break;
3621
3622 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003623 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003624 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003625 break;
3626
3627 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003628 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003629 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003630 break;
3631
3632 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003633 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003634 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003635 break;
3636
3637 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003638 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003639 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003640 break;
3641
3642 default:
3643 UNREACHABLE();
3644 return;
3645 }
3646}
3647
3648void Context::polygonOffset(GLfloat factor, GLfloat units)
3649{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003650 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003651}
3652
Jamie Madill876429b2017-04-20 15:46:24 -04003653void Context::sampleCoverage(GLfloat value, GLboolean invert)
Jamie Madillc20ab272016-06-09 07:20:46 -07003654{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003655 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003656}
3657
3658void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3659{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003660 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003661}
3662
3663void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3664{
3665 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3666 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003667 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003668 }
3669
3670 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3671 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003672 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003673 }
3674}
3675
3676void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3677{
3678 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3679 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003680 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003681 }
3682
3683 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3684 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003685 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003686 }
3687}
3688
3689void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3690{
3691 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3692 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003693 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003694 }
3695
3696 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3697 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003698 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003699 }
3700}
3701
3702void Context::vertexAttrib1f(GLuint index, GLfloat x)
3703{
3704 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003705 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003706}
3707
3708void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3709{
3710 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003711 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003712}
3713
3714void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3715{
3716 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003717 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003718}
3719
3720void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3721{
3722 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003723 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003724}
3725
3726void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3727{
3728 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003729 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003730}
3731
3732void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3733{
3734 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003735 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003736}
3737
3738void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3739{
3740 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003741 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003742}
3743
3744void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3745{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003746 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003747}
3748
3749void Context::vertexAttribPointer(GLuint index,
3750 GLint size,
3751 GLenum type,
3752 GLboolean normalized,
3753 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003754 const void *ptr)
Jamie Madillc20ab272016-06-09 07:20:46 -07003755{
Jamie Madill4928b7c2017-06-20 12:57:39 -04003756 mGLState.setVertexAttribState(this, index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size,
3757 type, normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003758}
3759
Shao80957d92017-02-20 21:25:59 +08003760void Context::vertexAttribFormat(GLuint attribIndex,
3761 GLint size,
3762 GLenum type,
3763 GLboolean normalized,
3764 GLuint relativeOffset)
3765{
3766 mGLState.setVertexAttribFormat(attribIndex, size, type, normalized == GL_TRUE, false,
3767 relativeOffset);
3768}
3769
3770void Context::vertexAttribIFormat(GLuint attribIndex,
3771 GLint size,
3772 GLenum type,
3773 GLuint relativeOffset)
3774{
3775 mGLState.setVertexAttribFormat(attribIndex, size, type, false, true, relativeOffset);
3776}
3777
3778void Context::vertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
3779{
3780 mGLState.setVertexAttribBinding(attribIndex, bindingIndex);
3781}
3782
3783void Context::setVertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
3784{
3785 mGLState.setVertexBindingDivisor(bindingIndex, divisor);
3786}
3787
Jamie Madillc20ab272016-06-09 07:20:46 -07003788void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3789{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003790 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003791}
3792
3793void Context::vertexAttribIPointer(GLuint index,
3794 GLint size,
3795 GLenum type,
3796 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003797 const void *pointer)
Jamie Madillc20ab272016-06-09 07:20:46 -07003798{
Jamie Madill4928b7c2017-06-20 12:57:39 -04003799 mGLState.setVertexAttribState(this, index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size,
3800 type, false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003801}
3802
3803void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3804{
3805 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003806 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003807}
3808
3809void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3810{
3811 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003812 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003813}
3814
3815void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3816{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003817 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003818}
3819
3820void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3821{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003822 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003823}
3824
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003825void Context::getVertexAttribiv(GLuint index, GLenum pname, GLint *params)
3826{
3827 const VertexAttribCurrentValueData &currentValues =
3828 getGLState().getVertexAttribCurrentValue(index);
3829 const VertexArray *vao = getGLState().getVertexArray();
3830 QueryVertexAttribiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3831 currentValues, pname, params);
3832}
3833
3834void Context::getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
3835{
3836 const VertexAttribCurrentValueData &currentValues =
3837 getGLState().getVertexAttribCurrentValue(index);
3838 const VertexArray *vao = getGLState().getVertexArray();
3839 QueryVertexAttribfv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3840 currentValues, pname, params);
3841}
3842
3843void Context::getVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
3844{
3845 const VertexAttribCurrentValueData &currentValues =
3846 getGLState().getVertexAttribCurrentValue(index);
3847 const VertexArray *vao = getGLState().getVertexArray();
3848 QueryVertexAttribIiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3849 currentValues, pname, params);
3850}
3851
3852void Context::getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
3853{
3854 const VertexAttribCurrentValueData &currentValues =
3855 getGLState().getVertexAttribCurrentValue(index);
3856 const VertexArray *vao = getGLState().getVertexArray();
3857 QueryVertexAttribIuiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3858 currentValues, pname, params);
3859}
3860
Jamie Madill876429b2017-04-20 15:46:24 -04003861void Context::getVertexAttribPointerv(GLuint index, GLenum pname, void **pointer)
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003862{
3863 const VertexAttribute &attrib = getGLState().getVertexArray()->getVertexAttribute(index);
3864 QueryVertexAttribPointerv(attrib, pname, pointer);
3865}
3866
Jamie Madillc20ab272016-06-09 07:20:46 -07003867void Context::debugMessageControl(GLenum source,
3868 GLenum type,
3869 GLenum severity,
3870 GLsizei count,
3871 const GLuint *ids,
3872 GLboolean enabled)
3873{
3874 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003875 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3876 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003877}
3878
3879void Context::debugMessageInsert(GLenum source,
3880 GLenum type,
3881 GLuint id,
3882 GLenum severity,
3883 GLsizei length,
3884 const GLchar *buf)
3885{
3886 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003887 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003888}
3889
3890void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3891{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003892 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003893}
3894
3895GLuint Context::getDebugMessageLog(GLuint count,
3896 GLsizei bufSize,
3897 GLenum *sources,
3898 GLenum *types,
3899 GLuint *ids,
3900 GLenum *severities,
3901 GLsizei *lengths,
3902 GLchar *messageLog)
3903{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003904 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3905 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003906}
3907
3908void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3909{
3910 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003911 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003912}
3913
3914void Context::popDebugGroup()
3915{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003916 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003917}
3918
Jamie Madill876429b2017-04-20 15:46:24 -04003919void Context::bufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage)
Jamie Madill29639852016-09-02 15:00:09 -04003920{
3921 Buffer *buffer = mGLState.getTargetBuffer(target);
3922 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003923 handleError(buffer->bufferData(this, target, data, size, usage));
Jamie Madill29639852016-09-02 15:00:09 -04003924}
3925
Jamie Madill876429b2017-04-20 15:46:24 -04003926void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04003927{
3928 if (data == nullptr)
3929 {
3930 return;
3931 }
3932
3933 Buffer *buffer = mGLState.getTargetBuffer(target);
3934 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003935 handleError(buffer->bufferSubData(this, target, data, size, offset));
Jamie Madill29639852016-09-02 15:00:09 -04003936}
3937
Jamie Madillef300b12016-10-07 15:12:09 -04003938void Context::attachShader(GLuint program, GLuint shader)
3939{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003940 auto programObject = mState.mShaderPrograms->getProgram(program);
3941 auto shaderObject = mState.mShaderPrograms->getShader(shader);
Jamie Madillef300b12016-10-07 15:12:09 -04003942 ASSERT(programObject && shaderObject);
3943 programObject->attachShader(shaderObject);
3944}
3945
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003946const Workarounds &Context::getWorkarounds() const
3947{
3948 return mWorkarounds;
3949}
3950
Jamie Madillb0817d12016-11-01 15:48:31 -04003951void Context::copyBufferSubData(GLenum readTarget,
3952 GLenum writeTarget,
3953 GLintptr readOffset,
3954 GLintptr writeOffset,
3955 GLsizeiptr size)
3956{
3957 // if size is zero, the copy is a successful no-op
3958 if (size == 0)
3959 {
3960 return;
3961 }
3962
3963 // TODO(jmadill): cache these.
3964 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3965 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3966
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003967 handleError(writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size));
Jamie Madillb0817d12016-11-01 15:48:31 -04003968}
3969
Jamie Madill01a80ee2016-11-07 12:06:18 -05003970void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3971{
3972 Program *programObject = getProgram(program);
3973 // TODO(jmadill): Re-use this from the validation if possible.
3974 ASSERT(programObject);
3975 programObject->bindAttributeLocation(index, name);
3976}
3977
3978void Context::bindBuffer(GLenum target, GLuint buffer)
3979{
3980 switch (target)
3981 {
3982 case GL_ARRAY_BUFFER:
3983 bindArrayBuffer(buffer);
3984 break;
3985 case GL_ELEMENT_ARRAY_BUFFER:
3986 bindElementArrayBuffer(buffer);
3987 break;
3988 case GL_COPY_READ_BUFFER:
3989 bindCopyReadBuffer(buffer);
3990 break;
3991 case GL_COPY_WRITE_BUFFER:
3992 bindCopyWriteBuffer(buffer);
3993 break;
3994 case GL_PIXEL_PACK_BUFFER:
3995 bindPixelPackBuffer(buffer);
3996 break;
3997 case GL_PIXEL_UNPACK_BUFFER:
3998 bindPixelUnpackBuffer(buffer);
3999 break;
4000 case GL_UNIFORM_BUFFER:
4001 bindGenericUniformBuffer(buffer);
4002 break;
4003 case GL_TRANSFORM_FEEDBACK_BUFFER:
4004 bindGenericTransformFeedbackBuffer(buffer);
4005 break;
Geoff Lang3b573612016-10-31 14:08:10 -04004006 case GL_ATOMIC_COUNTER_BUFFER:
Jiajia Qin6eafb042016-12-27 17:04:07 +08004007 bindGenericAtomicCounterBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004008 break;
4009 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08004010 bindGenericShaderStorageBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004011 break;
4012 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08004013 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004014 break;
4015 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05004016 if (buffer != 0)
4017 {
4018 // Binding buffers to this binding point is not implemented yet.
4019 UNIMPLEMENTED();
4020 }
Geoff Lang3b573612016-10-31 14:08:10 -04004021 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05004022
4023 default:
4024 UNREACHABLE();
4025 break;
4026 }
4027}
4028
Jiajia Qin6eafb042016-12-27 17:04:07 +08004029void Context::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
4030{
4031 bindBufferRange(target, index, buffer, 0, 0);
4032}
4033
4034void Context::bindBufferRange(GLenum target,
4035 GLuint index,
4036 GLuint buffer,
4037 GLintptr offset,
4038 GLsizeiptr size)
4039{
4040 switch (target)
4041 {
4042 case GL_TRANSFORM_FEEDBACK_BUFFER:
4043 bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
4044 bindGenericTransformFeedbackBuffer(buffer);
4045 break;
4046 case GL_UNIFORM_BUFFER:
4047 bindIndexedUniformBuffer(buffer, index, offset, size);
4048 bindGenericUniformBuffer(buffer);
4049 break;
4050 case GL_ATOMIC_COUNTER_BUFFER:
4051 bindIndexedAtomicCounterBuffer(buffer, index, offset, size);
4052 bindGenericAtomicCounterBuffer(buffer);
4053 break;
4054 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08004055 bindIndexedShaderStorageBuffer(buffer, index, offset, size);
4056 bindGenericShaderStorageBuffer(buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08004057 break;
4058 default:
4059 UNREACHABLE();
4060 break;
4061 }
4062}
4063
Jamie Madill01a80ee2016-11-07 12:06:18 -05004064void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
4065{
4066 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4067 {
4068 bindReadFramebuffer(framebuffer);
4069 }
4070
4071 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4072 {
4073 bindDrawFramebuffer(framebuffer);
4074 }
4075}
4076
4077void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
4078{
4079 ASSERT(target == GL_RENDERBUFFER);
4080 Renderbuffer *object =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05004081 mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
Jamie Madill4928b7c2017-06-20 12:57:39 -04004082 mGLState.setRenderbufferBinding(this, object);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004083}
4084
JiangYizhoubddc46b2016-12-09 09:50:51 +08004085void Context::texStorage2DMultisample(GLenum target,
4086 GLsizei samples,
4087 GLenum internalformat,
4088 GLsizei width,
4089 GLsizei height,
4090 GLboolean fixedsamplelocations)
4091{
4092 Extents size(width, height, 1);
4093 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05004094 handleError(texture->setStorageMultisample(this, target, samples, internalformat, size,
JiangYizhoubddc46b2016-12-09 09:50:51 +08004095 fixedsamplelocations));
4096}
4097
4098void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
4099{
Jamie Madilldd43e6c2017-03-24 14:18:49 -04004100 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
JiangYizhoubddc46b2016-12-09 09:50:51 +08004101 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
4102
4103 switch (pname)
4104 {
4105 case GL_SAMPLE_POSITION:
4106 handleError(framebuffer->getSamplePosition(index, val));
4107 break;
4108 default:
4109 UNREACHABLE();
4110 }
4111}
4112
Jamie Madille8fb6402017-02-14 17:56:40 -05004113void Context::renderbufferStorage(GLenum target,
4114 GLenum internalformat,
4115 GLsizei width,
4116 GLsizei height)
4117{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004118 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4119 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
4120
Jamie Madille8fb6402017-02-14 17:56:40 -05004121 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4928b7c2017-06-20 12:57:39 -04004122 handleError(renderbuffer->setStorage(this, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004123}
4124
4125void Context::renderbufferStorageMultisample(GLenum target,
4126 GLsizei samples,
4127 GLenum internalformat,
4128 GLsizei width,
4129 GLsizei height)
4130{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004131 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4132 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
Jamie Madille8fb6402017-02-14 17:56:40 -05004133
4134 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004135 handleError(
Jamie Madill4928b7c2017-06-20 12:57:39 -04004136 renderbuffer->setStorageMultisample(this, samples, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004137}
4138
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004139void Context::getSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)
4140{
4141 const FenceSync *syncObject = getFenceSync(sync);
Geoff Lang82483b92017-04-11 15:33:00 -04004142 handleError(QuerySynciv(syncObject, pname, bufSize, length, values));
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004143}
4144
JiangYizhoue18e6392017-02-20 10:32:23 +08004145void Context::getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
4146{
4147 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4148 QueryFramebufferParameteriv(framebuffer, pname, params);
4149}
4150
4151void Context::setFramebufferParameteri(GLenum target, GLenum pname, GLint param)
4152{
4153 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4154 SetFramebufferParameteri(framebuffer, pname, param);
4155}
4156
Jamie Madille14951e2017-03-09 18:55:16 -05004157Error Context::getScratchBuffer(size_t requestedSize, angle::MemoryBuffer **scratchBufferOut) const
4158{
4159 if (!mScratchBuffer.get(requestedSize, scratchBufferOut))
4160 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004161 return OutOfMemory() << "Failed to allocate internal buffer.";
Jamie Madille14951e2017-03-09 18:55:16 -05004162 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004163 return NoError();
Jamie Madille14951e2017-03-09 18:55:16 -05004164}
4165
Xinghua Cao2b396592017-03-29 15:36:04 +08004166void Context::dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ)
4167{
4168 if (numGroupsX == 0u || numGroupsY == 0u || numGroupsZ == 0u)
4169 {
4170 return;
4171 }
4172
Jamie Madillfe548342017-06-19 11:13:24 -04004173 mImplementation->dispatchCompute(this, numGroupsX, numGroupsY, numGroupsZ);
Xinghua Cao2b396592017-03-29 15:36:04 +08004174}
4175
JiangYizhou165361c2017-06-07 14:56:57 +08004176void Context::texStorage2D(GLenum target,
4177 GLsizei levels,
4178 GLenum internalFormat,
4179 GLsizei width,
4180 GLsizei height)
4181{
4182 Extents size(width, height, 1);
4183 Texture *texture = getTargetTexture(target);
4184 handleError(texture->setStorage(this, target, levels, internalFormat, size));
4185}
4186
4187void Context::texStorage3D(GLenum target,
4188 GLsizei levels,
4189 GLenum internalFormat,
4190 GLsizei width,
4191 GLsizei height,
4192 GLsizei depth)
4193{
4194 Extents size(width, height, depth);
4195 Texture *texture = getTargetTexture(target);
4196 handleError(texture->setStorage(this, target, levels, internalFormat, size));
4197}
4198
Jamie Madillc1d770e2017-04-13 17:31:24 -04004199GLenum Context::checkFramebufferStatus(GLenum target)
4200{
4201 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4202 ASSERT(framebuffer);
4203
4204 return framebuffer->checkStatus(this);
4205}
4206
4207void Context::compileShader(GLuint shader)
4208{
4209 Shader *shaderObject = GetValidShader(this, shader);
4210 if (!shaderObject)
4211 {
4212 return;
4213 }
4214 shaderObject->compile(this);
4215}
4216
4217void Context::deleteBuffers(GLsizei n, const GLuint *buffers)
4218{
4219 for (int i = 0; i < n; i++)
4220 {
4221 deleteBuffer(buffers[i]);
4222 }
4223}
4224
4225void Context::deleteFramebuffers(GLsizei n, const GLuint *framebuffers)
4226{
4227 for (int i = 0; i < n; i++)
4228 {
4229 if (framebuffers[i] != 0)
4230 {
4231 deleteFramebuffer(framebuffers[i]);
4232 }
4233 }
4234}
4235
4236void Context::deleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)
4237{
4238 for (int i = 0; i < n; i++)
4239 {
4240 deleteRenderbuffer(renderbuffers[i]);
4241 }
4242}
4243
4244void Context::deleteTextures(GLsizei n, const GLuint *textures)
4245{
4246 for (int i = 0; i < n; i++)
4247 {
4248 if (textures[i] != 0)
4249 {
4250 deleteTexture(textures[i]);
4251 }
4252 }
4253}
4254
4255void Context::detachShader(GLuint program, GLuint shader)
4256{
4257 Program *programObject = getProgram(program);
4258 ASSERT(programObject);
4259
4260 Shader *shaderObject = getShader(shader);
4261 ASSERT(shaderObject);
4262
4263 programObject->detachShader(this, shaderObject);
4264}
4265
4266void Context::genBuffers(GLsizei n, GLuint *buffers)
4267{
4268 for (int i = 0; i < n; i++)
4269 {
4270 buffers[i] = createBuffer();
4271 }
4272}
4273
4274void Context::genFramebuffers(GLsizei n, GLuint *framebuffers)
4275{
4276 for (int i = 0; i < n; i++)
4277 {
4278 framebuffers[i] = createFramebuffer();
4279 }
4280}
4281
4282void Context::genRenderbuffers(GLsizei n, GLuint *renderbuffers)
4283{
4284 for (int i = 0; i < n; i++)
4285 {
4286 renderbuffers[i] = createRenderbuffer();
4287 }
4288}
4289
4290void Context::genTextures(GLsizei n, GLuint *textures)
4291{
4292 for (int i = 0; i < n; i++)
4293 {
4294 textures[i] = createTexture();
4295 }
4296}
4297
4298void Context::getActiveAttrib(GLuint program,
4299 GLuint index,
4300 GLsizei bufsize,
4301 GLsizei *length,
4302 GLint *size,
4303 GLenum *type,
4304 GLchar *name)
4305{
4306 Program *programObject = getProgram(program);
4307 ASSERT(programObject);
4308 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
4309}
4310
4311void Context::getActiveUniform(GLuint program,
4312 GLuint index,
4313 GLsizei bufsize,
4314 GLsizei *length,
4315 GLint *size,
4316 GLenum *type,
4317 GLchar *name)
4318{
4319 Program *programObject = getProgram(program);
4320 ASSERT(programObject);
4321 programObject->getActiveUniform(index, bufsize, length, size, type, name);
4322}
4323
4324void Context::getAttachedShaders(GLuint program, GLsizei maxcount, GLsizei *count, GLuint *shaders)
4325{
4326 Program *programObject = getProgram(program);
4327 ASSERT(programObject);
4328 programObject->getAttachedShaders(maxcount, count, shaders);
4329}
4330
4331GLint Context::getAttribLocation(GLuint program, const GLchar *name)
4332{
4333 Program *programObject = getProgram(program);
4334 ASSERT(programObject);
4335 return programObject->getAttributeLocation(name);
4336}
4337
4338void Context::getBooleanv(GLenum pname, GLboolean *params)
4339{
4340 GLenum nativeType;
4341 unsigned int numParams = 0;
4342 getQueryParameterInfo(pname, &nativeType, &numParams);
4343
4344 if (nativeType == GL_BOOL)
4345 {
4346 getBooleanvImpl(pname, params);
4347 }
4348 else
4349 {
4350 CastStateValues(this, nativeType, pname, numParams, params);
4351 }
4352}
4353
4354void Context::getFloatv(GLenum pname, GLfloat *params)
4355{
4356 GLenum nativeType;
4357 unsigned int numParams = 0;
4358 getQueryParameterInfo(pname, &nativeType, &numParams);
4359
4360 if (nativeType == GL_FLOAT)
4361 {
4362 getFloatvImpl(pname, params);
4363 }
4364 else
4365 {
4366 CastStateValues(this, nativeType, pname, numParams, params);
4367 }
4368}
4369
4370void Context::getIntegerv(GLenum pname, GLint *params)
4371{
4372 GLenum nativeType;
4373 unsigned int numParams = 0;
4374 getQueryParameterInfo(pname, &nativeType, &numParams);
4375
4376 if (nativeType == GL_INT)
4377 {
4378 getIntegervImpl(pname, params);
4379 }
4380 else
4381 {
4382 CastStateValues(this, nativeType, pname, numParams, params);
4383 }
4384}
4385
4386void Context::getProgramiv(GLuint program, GLenum pname, GLint *params)
4387{
4388 Program *programObject = getProgram(program);
4389 ASSERT(programObject);
Jamie Madillffe00c02017-06-27 16:26:55 -04004390 QueryProgramiv(this, programObject, pname, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004391}
4392
Jamie Madillbe849e42017-05-02 15:49:00 -04004393void Context::getProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei *length, GLchar *infolog)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004394{
4395 Program *programObject = getProgram(program);
4396 ASSERT(programObject);
4397 programObject->getInfoLog(bufsize, length, infolog);
4398}
4399
4400void Context::getShaderiv(GLuint shader, GLenum pname, GLint *params)
4401{
4402 Shader *shaderObject = getShader(shader);
4403 ASSERT(shaderObject);
Jamie Madillbd044ed2017-06-05 12:59:21 -04004404 QueryShaderiv(this, shaderObject, pname, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004405}
4406
4407void Context::getShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *infolog)
4408{
4409 Shader *shaderObject = getShader(shader);
4410 ASSERT(shaderObject);
Jamie Madillbd044ed2017-06-05 12:59:21 -04004411 shaderObject->getInfoLog(this, bufsize, length, infolog);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004412}
4413
4414void Context::getShaderPrecisionFormat(GLenum shadertype,
4415 GLenum precisiontype,
4416 GLint *range,
4417 GLint *precision)
4418{
4419 // TODO(jmadill): Compute shaders.
4420
4421 switch (shadertype)
4422 {
4423 case GL_VERTEX_SHADER:
4424 switch (precisiontype)
4425 {
4426 case GL_LOW_FLOAT:
4427 mCaps.vertexLowpFloat.get(range, precision);
4428 break;
4429 case GL_MEDIUM_FLOAT:
4430 mCaps.vertexMediumpFloat.get(range, precision);
4431 break;
4432 case GL_HIGH_FLOAT:
4433 mCaps.vertexHighpFloat.get(range, precision);
4434 break;
4435
4436 case GL_LOW_INT:
4437 mCaps.vertexLowpInt.get(range, precision);
4438 break;
4439 case GL_MEDIUM_INT:
4440 mCaps.vertexMediumpInt.get(range, precision);
4441 break;
4442 case GL_HIGH_INT:
4443 mCaps.vertexHighpInt.get(range, precision);
4444 break;
4445
4446 default:
4447 UNREACHABLE();
4448 return;
4449 }
4450 break;
4451
4452 case GL_FRAGMENT_SHADER:
4453 switch (precisiontype)
4454 {
4455 case GL_LOW_FLOAT:
4456 mCaps.fragmentLowpFloat.get(range, precision);
4457 break;
4458 case GL_MEDIUM_FLOAT:
4459 mCaps.fragmentMediumpFloat.get(range, precision);
4460 break;
4461 case GL_HIGH_FLOAT:
4462 mCaps.fragmentHighpFloat.get(range, precision);
4463 break;
4464
4465 case GL_LOW_INT:
4466 mCaps.fragmentLowpInt.get(range, precision);
4467 break;
4468 case GL_MEDIUM_INT:
4469 mCaps.fragmentMediumpInt.get(range, precision);
4470 break;
4471 case GL_HIGH_INT:
4472 mCaps.fragmentHighpInt.get(range, precision);
4473 break;
4474
4475 default:
4476 UNREACHABLE();
4477 return;
4478 }
4479 break;
4480
4481 default:
4482 UNREACHABLE();
4483 return;
4484 }
4485}
4486
4487void Context::getShaderSource(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source)
4488{
4489 Shader *shaderObject = getShader(shader);
4490 ASSERT(shaderObject);
4491 shaderObject->getSource(bufsize, length, source);
4492}
4493
4494void Context::getUniformfv(GLuint program, GLint location, GLfloat *params)
4495{
4496 Program *programObject = getProgram(program);
4497 ASSERT(programObject);
4498 programObject->getUniformfv(location, params);
4499}
4500
4501void Context::getUniformiv(GLuint program, GLint location, GLint *params)
4502{
4503 Program *programObject = getProgram(program);
4504 ASSERT(programObject);
4505 programObject->getUniformiv(location, params);
4506}
4507
4508GLint Context::getUniformLocation(GLuint program, const GLchar *name)
4509{
4510 Program *programObject = getProgram(program);
4511 ASSERT(programObject);
4512 return programObject->getUniformLocation(name);
4513}
4514
4515GLboolean Context::isBuffer(GLuint buffer)
4516{
4517 if (buffer == 0)
4518 {
4519 return GL_FALSE;
4520 }
4521
4522 return (getBuffer(buffer) ? GL_TRUE : GL_FALSE);
4523}
4524
4525GLboolean Context::isEnabled(GLenum cap)
4526{
4527 return mGLState.getEnableFeature(cap);
4528}
4529
4530GLboolean Context::isFramebuffer(GLuint framebuffer)
4531{
4532 if (framebuffer == 0)
4533 {
4534 return GL_FALSE;
4535 }
4536
4537 return (getFramebuffer(framebuffer) ? GL_TRUE : GL_FALSE);
4538}
4539
4540GLboolean Context::isProgram(GLuint program)
4541{
4542 if (program == 0)
4543 {
4544 return GL_FALSE;
4545 }
4546
4547 return (getProgram(program) ? GL_TRUE : GL_FALSE);
4548}
4549
4550GLboolean Context::isRenderbuffer(GLuint renderbuffer)
4551{
4552 if (renderbuffer == 0)
4553 {
4554 return GL_FALSE;
4555 }
4556
4557 return (getRenderbuffer(renderbuffer) ? GL_TRUE : GL_FALSE);
4558}
4559
4560GLboolean Context::isShader(GLuint shader)
4561{
4562 if (shader == 0)
4563 {
4564 return GL_FALSE;
4565 }
4566
4567 return (getShader(shader) ? GL_TRUE : GL_FALSE);
4568}
4569
4570GLboolean Context::isTexture(GLuint texture)
4571{
4572 if (texture == 0)
4573 {
4574 return GL_FALSE;
4575 }
4576
4577 return (getTexture(texture) ? GL_TRUE : GL_FALSE);
4578}
4579
4580void Context::linkProgram(GLuint program)
4581{
4582 Program *programObject = getProgram(program);
4583 ASSERT(programObject);
4584 handleError(programObject->link(this));
4585}
4586
4587void Context::releaseShaderCompiler()
4588{
Jamie Madill4928b7c2017-06-20 12:57:39 -04004589 mCompiler.set(this, nullptr);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004590}
4591
4592void Context::shaderBinary(GLsizei n,
4593 const GLuint *shaders,
4594 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04004595 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004596 GLsizei length)
4597{
4598 // No binary shader formats are supported.
4599 UNIMPLEMENTED();
4600}
4601
4602void Context::shaderSource(GLuint shader,
4603 GLsizei count,
4604 const GLchar *const *string,
4605 const GLint *length)
4606{
4607 Shader *shaderObject = getShader(shader);
4608 ASSERT(shaderObject);
4609 shaderObject->setSource(count, string, length);
4610}
4611
4612void Context::stencilFunc(GLenum func, GLint ref, GLuint mask)
4613{
4614 stencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
4615}
4616
4617void Context::stencilMask(GLuint mask)
4618{
4619 stencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4620}
4621
4622void Context::stencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4623{
4624 stencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4625}
4626
4627void Context::uniform1f(GLint location, GLfloat x)
4628{
4629 Program *program = mGLState.getProgram();
4630 program->setUniform1fv(location, 1, &x);
4631}
4632
4633void Context::uniform1fv(GLint location, GLsizei count, const GLfloat *v)
4634{
4635 Program *program = mGLState.getProgram();
4636 program->setUniform1fv(location, count, v);
4637}
4638
4639void Context::uniform1i(GLint location, GLint x)
4640{
4641 Program *program = mGLState.getProgram();
4642 program->setUniform1iv(location, 1, &x);
4643}
4644
4645void Context::uniform1iv(GLint location, GLsizei count, const GLint *v)
4646{
4647 Program *program = mGLState.getProgram();
4648 program->setUniform1iv(location, count, v);
4649}
4650
4651void Context::uniform2f(GLint location, GLfloat x, GLfloat y)
4652{
4653 GLfloat xy[2] = {x, y};
4654 Program *program = mGLState.getProgram();
4655 program->setUniform2fv(location, 1, xy);
4656}
4657
4658void Context::uniform2fv(GLint location, GLsizei count, const GLfloat *v)
4659{
4660 Program *program = mGLState.getProgram();
4661 program->setUniform2fv(location, count, v);
4662}
4663
4664void Context::uniform2i(GLint location, GLint x, GLint y)
4665{
4666 GLint xy[2] = {x, y};
4667 Program *program = mGLState.getProgram();
4668 program->setUniform2iv(location, 1, xy);
4669}
4670
4671void Context::uniform2iv(GLint location, GLsizei count, const GLint *v)
4672{
4673 Program *program = mGLState.getProgram();
4674 program->setUniform2iv(location, count, v);
4675}
4676
4677void Context::uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4678{
4679 GLfloat xyz[3] = {x, y, z};
4680 Program *program = mGLState.getProgram();
4681 program->setUniform3fv(location, 1, xyz);
4682}
4683
4684void Context::uniform3fv(GLint location, GLsizei count, const GLfloat *v)
4685{
4686 Program *program = mGLState.getProgram();
4687 program->setUniform3fv(location, count, v);
4688}
4689
4690void Context::uniform3i(GLint location, GLint x, GLint y, GLint z)
4691{
4692 GLint xyz[3] = {x, y, z};
4693 Program *program = mGLState.getProgram();
4694 program->setUniform3iv(location, 1, xyz);
4695}
4696
4697void Context::uniform3iv(GLint location, GLsizei count, const GLint *v)
4698{
4699 Program *program = mGLState.getProgram();
4700 program->setUniform3iv(location, count, v);
4701}
4702
4703void Context::uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4704{
4705 GLfloat xyzw[4] = {x, y, z, w};
4706 Program *program = mGLState.getProgram();
4707 program->setUniform4fv(location, 1, xyzw);
4708}
4709
4710void Context::uniform4fv(GLint location, GLsizei count, const GLfloat *v)
4711{
4712 Program *program = mGLState.getProgram();
4713 program->setUniform4fv(location, count, v);
4714}
4715
4716void Context::uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4717{
4718 GLint xyzw[4] = {x, y, z, w};
4719 Program *program = mGLState.getProgram();
4720 program->setUniform4iv(location, 1, xyzw);
4721}
4722
4723void Context::uniform4iv(GLint location, GLsizei count, const GLint *v)
4724{
4725 Program *program = mGLState.getProgram();
4726 program->setUniform4iv(location, count, v);
4727}
4728
4729void Context::uniformMatrix2fv(GLint location,
4730 GLsizei count,
4731 GLboolean transpose,
4732 const GLfloat *value)
4733{
4734 Program *program = mGLState.getProgram();
4735 program->setUniformMatrix2fv(location, count, transpose, value);
4736}
4737
4738void Context::uniformMatrix3fv(GLint location,
4739 GLsizei count,
4740 GLboolean transpose,
4741 const GLfloat *value)
4742{
4743 Program *program = mGLState.getProgram();
4744 program->setUniformMatrix3fv(location, count, transpose, value);
4745}
4746
4747void Context::uniformMatrix4fv(GLint location,
4748 GLsizei count,
4749 GLboolean transpose,
4750 const GLfloat *value)
4751{
4752 Program *program = mGLState.getProgram();
4753 program->setUniformMatrix4fv(location, count, transpose, value);
4754}
4755
4756void Context::validateProgram(GLuint program)
4757{
4758 Program *programObject = getProgram(program);
4759 ASSERT(programObject);
4760 programObject->validate(mCaps);
4761}
4762
Jamie Madilld04908b2017-06-09 14:15:35 -04004763void Context::getProgramBinary(GLuint program,
4764 GLsizei bufSize,
4765 GLsizei *length,
4766 GLenum *binaryFormat,
4767 void *binary)
4768{
4769 Program *programObject = getProgram(program);
4770 ASSERT(programObject != nullptr);
4771
4772 handleError(programObject->saveBinary(this, binaryFormat, binary, bufSize, length));
4773}
4774
4775void Context::programBinary(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length)
4776{
4777 Program *programObject = getProgram(program);
4778 ASSERT(programObject != nullptr);
4779
4780 handleError(programObject->loadBinary(this, binaryFormat, binary, length));
4781}
4782
Jamie Madillc29968b2016-01-20 11:17:23 -05004783} // namespace gl