blob: 74ff87505e75b8b68436b7634d3ee53083af2300 [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"
Yunchao Hea336b902017-08-02 16:05:21 +080029#include "libANGLE/ProgramPipeline.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050030#include "libANGLE/Query.h"
Jamie Madillb9293972015-02-19 11:07:54 -050031#include "libANGLE/Renderbuffer.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050032#include "libANGLE/ResourceManager.h"
33#include "libANGLE/Sampler.h"
Jamie Madill9dd0cf02014-11-24 11:38:51 -050034#include "libANGLE/Surface.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050035#include "libANGLE/Texture.h"
36#include "libANGLE/TransformFeedback.h"
37#include "libANGLE/VertexArray.h"
Kenneth Russellf2f6f652016-10-05 19:53:23 -070038#include "libANGLE/Workarounds.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040039#include "libANGLE/formatutils.h"
Martin Radev66fb8202016-07-28 11:45:20 +030040#include "libANGLE/queryconversions.h"
Geoff Langc1984ed2016-10-07 12:41:00 -040041#include "libANGLE/queryutils.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040042#include "libANGLE/renderer/ContextImpl.h"
43#include "libANGLE/renderer/EGLImplFactory.h"
44#include "libANGLE/validationES.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000045
Geoff Langf6db0982015-08-25 13:04:00 -040046namespace
47{
48
Jamie Madillb6664922017-07-25 12:55:04 -040049#define ANGLE_HANDLE_ERR(X) \
50 handleError(X); \
51 return;
52#define ANGLE_CONTEXT_TRY(EXPR) ANGLE_TRY_TEMPLATE(EXPR, ANGLE_HANDLE_ERR);
53
Ian Ewell3ffd78b2016-01-22 16:09:42 -050054template <typename T>
Geoff Lang4ddf5af2016-12-01 14:30:44 -050055std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
Sami Väisänend59ca052016-06-21 16:10:00 +030056 GLsizei numPaths,
57 const void *paths,
58 GLuint pathBase)
59{
60 std::vector<gl::Path *> ret;
61 ret.reserve(numPaths);
62
63 const auto *nameArray = static_cast<const T *>(paths);
64
65 for (GLsizei i = 0; i < numPaths; ++i)
66 {
67 const GLuint pathName = nameArray[i] + pathBase;
68
69 ret.push_back(resourceManager.getPath(pathName));
70 }
71
72 return ret;
73}
74
Geoff Lang4ddf5af2016-12-01 14:30:44 -050075std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
Sami Väisänend59ca052016-06-21 16:10:00 +030076 GLsizei numPaths,
77 GLenum pathNameType,
78 const void *paths,
79 GLuint pathBase)
80{
81 switch (pathNameType)
82 {
83 case GL_UNSIGNED_BYTE:
84 return GatherPaths<GLubyte>(resourceManager, numPaths, paths, pathBase);
85
86 case GL_BYTE:
87 return GatherPaths<GLbyte>(resourceManager, numPaths, paths, pathBase);
88
89 case GL_UNSIGNED_SHORT:
90 return GatherPaths<GLushort>(resourceManager, numPaths, paths, pathBase);
91
92 case GL_SHORT:
93 return GatherPaths<GLshort>(resourceManager, numPaths, paths, pathBase);
94
95 case GL_UNSIGNED_INT:
96 return GatherPaths<GLuint>(resourceManager, numPaths, paths, pathBase);
97
98 case GL_INT:
99 return GatherPaths<GLint>(resourceManager, numPaths, paths, pathBase);
100 }
101
102 UNREACHABLE();
103 return std::vector<gl::Path *>();
104}
105
106template <typename T>
Geoff Lang2186c382016-10-14 10:54:54 -0400107gl::Error GetQueryObjectParameter(gl::Query *query, GLenum pname, T *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500108{
Geoff Lang2186c382016-10-14 10:54:54 -0400109 ASSERT(query != nullptr);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500110
111 switch (pname)
112 {
113 case GL_QUERY_RESULT_EXT:
Geoff Lang2186c382016-10-14 10:54:54 -0400114 return query->getResult(params);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500115 case GL_QUERY_RESULT_AVAILABLE_EXT:
116 {
117 bool available;
Geoff Lang2186c382016-10-14 10:54:54 -0400118 gl::Error error = query->isResultAvailable(&available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500119 if (!error.isError())
120 {
Geoff Lang2186c382016-10-14 10:54:54 -0400121 *params = gl::ConvertFromGLboolean<T>(available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500122 }
123 return error;
124 }
125 default:
126 UNREACHABLE();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500127 return gl::InternalError() << "Unreachable Error";
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500128 }
129}
130
Geoff Langf6db0982015-08-25 13:04:00 -0400131void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback)
132{
Geoff Lang1a683462015-09-29 15:09:59 -0400133 if (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
Geoff Langf6db0982015-08-25 13:04:00 -0400134 {
135 for (size_t tfBufferIndex = 0; tfBufferIndex < transformFeedback->getIndexedBufferCount();
136 tfBufferIndex++)
137 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400138 const gl::OffsetBindingPointer<gl::Buffer> &buffer =
Geoff Langf6db0982015-08-25 13:04:00 -0400139 transformFeedback->getIndexedBuffer(tfBufferIndex);
140 if (buffer.get() != nullptr)
141 {
142 buffer->onTransformFeedback();
143 }
144 }
145 }
146}
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500147
148// Attribute map queries.
Martin Radev1be913c2016-07-11 17:59:16 +0300149EGLint GetClientMajorVersion(const egl::AttributeMap &attribs)
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500150{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400151 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1));
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500152}
153
Martin Radev1be913c2016-07-11 17:59:16 +0300154EGLint GetClientMinorVersion(const egl::AttributeMap &attribs)
155{
156 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_MINOR_VERSION, 0));
157}
158
Geoff Langeb66a6e2016-10-31 13:06:12 -0400159gl::Version GetClientVersion(const egl::AttributeMap &attribs)
160{
161 return gl::Version(GetClientMajorVersion(attribs), GetClientMinorVersion(attribs));
162}
163
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500164GLenum GetResetStrategy(const egl::AttributeMap &attribs)
165{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400166 EGLAttrib attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
167 EGL_NO_RESET_NOTIFICATION_EXT);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500168 switch (attrib)
169 {
170 case EGL_NO_RESET_NOTIFICATION:
171 return GL_NO_RESET_NOTIFICATION_EXT;
172 case EGL_LOSE_CONTEXT_ON_RESET:
173 return GL_LOSE_CONTEXT_ON_RESET_EXT;
174 default:
175 UNREACHABLE();
176 return GL_NONE;
177 }
178}
179
180bool GetRobustAccess(const egl::AttributeMap &attribs)
181{
Geoff Lang077f20a2016-11-01 10:08:02 -0400182 return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE) ||
183 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) !=
184 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500185}
186
187bool GetDebug(const egl::AttributeMap &attribs)
188{
Geoff Lang077f20a2016-11-01 10:08:02 -0400189 return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE) ||
190 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR) != 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500191}
192
193bool GetNoError(const egl::AttributeMap &attribs)
194{
195 return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
196}
197
Geoff Langc287ea62016-09-16 14:46:51 -0400198bool GetWebGLContext(const egl::AttributeMap &attribs)
199{
200 return (attribs.get(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE, EGL_FALSE) == EGL_TRUE);
201}
202
Geoff Langf41a7152016-09-19 15:11:17 -0400203bool GetBindGeneratesResource(const egl::AttributeMap &attribs)
204{
205 return (attribs.get(EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE) == EGL_TRUE);
206}
207
Geoff Langfeb8c682017-02-13 16:07:35 -0500208bool GetClientArraysEnabled(const egl::AttributeMap &attribs)
209{
210 return (attribs.get(EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE, EGL_TRUE) == EGL_TRUE);
211}
212
Martin Radev9d901792016-07-15 15:58:58 +0300213std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
214{
215 std::string labelName;
216 if (label != nullptr)
217 {
218 size_t labelLength = length < 0 ? strlen(label) : length;
219 labelName = std::string(label, labelLength);
220 }
221 return labelName;
222}
223
224void GetObjectLabelBase(const std::string &objectLabel,
225 GLsizei bufSize,
226 GLsizei *length,
227 GLchar *label)
228{
229 size_t writeLength = objectLabel.length();
230 if (label != nullptr && bufSize > 0)
231 {
232 writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
233 std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
234 label[writeLength] = '\0';
235 }
236
237 if (length != nullptr)
238 {
239 *length = static_cast<GLsizei>(writeLength);
240 }
241}
242
Jamie Madill0f80ed82017-09-19 00:24:56 -0400243template <typename CapT, typename MaxT>
244void LimitCap(CapT *cap, MaxT maximum)
245{
246 *cap = std::min(*cap, static_cast<CapT>(maximum));
247}
248
Geoff Langf6db0982015-08-25 13:04:00 -0400249} // anonymous namespace
250
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000251namespace gl
252{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000253
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400254Context::Context(rx::EGLImplFactory *implFactory,
255 const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400256 const Context *shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500257 TextureManager *shareTextures,
Jamie Madill32447362017-06-28 14:53:52 -0400258 MemoryProgramCache *memoryProgramCache,
Corentin Wallezc295e512017-01-27 17:47:50 -0500259 const egl::AttributeMap &attribs,
Jamie Madill948bbe52017-06-01 13:10:42 -0400260 const egl::DisplayExtensions &displayExtensions,
261 bool robustResourceInit)
Martin Radev1be913c2016-07-11 17:59:16 +0300262
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500263 : ValidationContext(shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500264 shareTextures,
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500265 GetClientVersion(attribs),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700266 &mGLState,
Jamie Madillf25855c2015-11-03 11:06:18 -0500267 mCaps,
268 mTextureCaps,
269 mExtensions,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500270 mLimitations,
271 GetNoError(attribs)),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700272 mImplementation(implFactory->createContext(mState)),
Jamie Madill2f348d22017-06-05 10:50:59 -0400273 mCompiler(),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400274 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500275 mClientType(EGL_OPENGL_ES_API),
276 mHasBeenCurrent(false),
277 mContextLost(false),
278 mResetStatus(GL_NO_ERROR),
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700279 mContextLostForced(false),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500280 mResetStrategy(GetResetStrategy(attribs)),
281 mRobustAccess(GetRobustAccess(attribs)),
Jamie Madill61e16b42017-06-19 11:13:23 -0400282 mCurrentSurface(static_cast<egl::Surface *>(EGL_NO_SURFACE)),
283 mCurrentDisplay(static_cast<egl::Display *>(EGL_NO_DISPLAY)),
Jamie Madill4e0e6f82017-02-17 11:06:03 -0500284 mSurfacelessFramebuffer(nullptr),
Jamie Madille14951e2017-03-09 18:55:16 -0500285 mWebGLContext(GetWebGLContext(attribs)),
Jamie Madill32447362017-06-28 14:53:52 -0400286 mMemoryProgramCache(memoryProgramCache),
Jamie Madillb3f26b92017-07-19 15:07:41 -0400287 mScratchBuffer(1000u),
288 mZeroFilledBuffer(1000u)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000289{
Jamie Madill14bbb3f2017-09-12 15:23:01 -0400290 mImplementation->setMemoryProgramCache(memoryProgramCache);
291
Jamie Madill4e0e6f82017-02-17 11:06:03 -0500292 initCaps(displayExtensions);
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700293 initWorkarounds();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400294
Jamie Madill4928b7c2017-06-20 12:57:39 -0400295 mGLState.initialize(this, GetDebug(attribs), GetBindGeneratesResource(attribs),
Jamie Madillc43be722017-07-13 16:22:14 -0400296 GetClientArraysEnabled(attribs), robustResourceInit,
297 mMemoryProgramCache != nullptr);
Régis Fénéon83107972015-02-05 12:57:44 +0100298
Shannon Woods53a94a82014-06-24 15:20:36 -0400299 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400300
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000301 // [OpenGL ES 2.0.24] section 3.7 page 83:
302 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
303 // and cube map texture state vectors respectively associated with them.
304 // In order that access to these initial textures not be lost, they are treated as texture
305 // objects all of whose names are 0.
306
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400307 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400308 mZeroTextures[GL_TEXTURE_2D].set(this, zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500309
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400310 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400311 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(this, zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400312
Geoff Langeb66a6e2016-10-31 13:06:12 -0400313 if (getClientVersion() >= Version(3, 0))
Geoff Lang76b10c92014-09-05 16:28:14 -0400314 {
315 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400316 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400317 mZeroTextures[GL_TEXTURE_3D].set(this, zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400318
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400319 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400320 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(this, zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400321 }
Geoff Lang3b573612016-10-31 14:08:10 -0400322 if (getClientVersion() >= Version(3, 1))
323 {
324 Texture *zeroTexture2DMultisample =
325 new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_MULTISAMPLE);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400326 mZeroTextures[GL_TEXTURE_2D_MULTISAMPLE].set(this, zeroTexture2DMultisample);
Jiajia Qin6eafb042016-12-27 17:04:07 +0800327
328 bindGenericAtomicCounterBuffer(0);
329 for (unsigned int i = 0; i < mCaps.maxAtomicCounterBufferBindings; i++)
330 {
331 bindIndexedAtomicCounterBuffer(0, i, 0, 0);
332 }
Jiajia Qinf546e7d2017-03-27 14:12:59 +0800333
334 bindGenericShaderStorageBuffer(0);
335 for (unsigned int i = 0; i < mCaps.maxShaderStorageBufferBindings; i++)
336 {
337 bindIndexedShaderStorageBuffer(0, i, 0, 0);
338 }
Geoff Lang3b573612016-10-31 14:08:10 -0400339 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000340
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400341 if (mExtensions.textureRectangle)
342 {
343 Texture *zeroTextureRectangle =
344 new Texture(mImplementation.get(), 0, GL_TEXTURE_RECTANGLE_ANGLE);
345 mZeroTextures[GL_TEXTURE_RECTANGLE_ANGLE].set(this, zeroTextureRectangle);
346 }
347
Ian Ewellbda75592016-04-18 17:25:54 -0400348 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
349 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400350 Texture *zeroTextureExternal =
351 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400352 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(this, zeroTextureExternal);
Ian Ewellbda75592016-04-18 17:25:54 -0400353 }
354
Jamie Madill4928b7c2017-06-20 12:57:39 -0400355 mGLState.initializeZeroTextures(this, mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500356
Jamie Madill57a89722013-07-02 11:57:03 -0400357 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000358 bindArrayBuffer(0);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800359 bindDrawIndirectBuffer(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000360 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400361
Jamie Madill01a80ee2016-11-07 12:06:18 -0500362 bindRenderbuffer(GL_RENDERBUFFER, 0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000363
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000364 bindGenericUniformBuffer(0);
Geoff Lang4dc3af02016-11-18 14:09:27 -0500365 for (unsigned int i = 0; i < mCaps.maxUniformBufferBindings; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000366 {
367 bindIndexedUniformBuffer(0, i, 0, -1);
368 }
369
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000370 bindCopyReadBuffer(0);
371 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000372 bindPixelPackBuffer(0);
373 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000374
Geoff Langeb66a6e2016-10-31 13:06:12 -0400375 if (getClientVersion() >= Version(3, 0))
Geoff Lang1a683462015-09-29 15:09:59 -0400376 {
377 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
378 // In the initial state, a default transform feedback object is bound and treated as
379 // a transform feedback object with a name of zero. That object is bound any time
380 // BindTransformFeedback is called with id of zero
Jamie Madillf0dcb8b2017-08-26 19:05:13 -0400381 bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
Geoff Lang1a683462015-09-29 15:09:59 -0400382 }
Geoff Langc8058452014-02-03 12:04:11 -0500383
Jamie Madillad9f24e2016-02-12 09:27:24 -0500384 // Initialize dirty bit masks
385 // TODO(jmadill): additional ES3 state
386 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
387 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
388 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
389 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
390 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
391 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400392 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500393 // No dirty objects.
394
395 // Readpixels uses the pack state and read FBO
396 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
397 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
398 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
399 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
400 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400401 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500402 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
403
404 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
405 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
406 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
407 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
408 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
409 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
410 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
411 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
412 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
413 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
414 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
415 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
416
417 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
418 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700419 mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500420 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
421 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400422
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400423 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000424}
425
Jamie Madill4928b7c2017-06-20 12:57:39 -0400426egl::Error Context::onDestroy(const egl::Display *display)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000427{
Corentin Wallez80b24112015-08-25 16:41:57 -0400428 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000429 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400430 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000431 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400432 mFenceNVMap.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000433
Corentin Wallez80b24112015-08-25 16:41:57 -0400434 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000435 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400436 if (query.second != nullptr)
437 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400438 query.second->release(this);
Geoff Langf0aa8422015-09-29 15:08:34 -0400439 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000440 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400441 mQueryMap.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000442
Corentin Wallez80b24112015-08-25 16:41:57 -0400443 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400444 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400445 if (vertexArray.second)
446 {
447 vertexArray.second->onDestroy(this);
448 }
Jamie Madill57a89722013-07-02 11:57:03 -0400449 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400450 mVertexArrayMap.clear();
Jamie Madill57a89722013-07-02 11:57:03 -0400451
Corentin Wallez80b24112015-08-25 16:41:57 -0400452 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500453 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500454 if (transformFeedback.second != nullptr)
455 {
Jamie Madill6c1f6712017-02-14 19:08:04 -0500456 transformFeedback.second->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500457 }
Geoff Langc8058452014-02-03 12:04:11 -0500458 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400459 mTransformFeedbackMap.clear();
Geoff Langc8058452014-02-03 12:04:11 -0500460
Jamie Madilldedd7b92014-11-05 16:30:36 -0500461 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400462 {
Jamie Madill71c88b32017-09-14 22:20:29 -0400463 ANGLE_TRY(zeroTexture.second->onDestroy(this));
Jamie Madill4928b7c2017-06-20 12:57:39 -0400464 zeroTexture.second.set(this, nullptr);
Geoff Lang76b10c92014-09-05 16:28:14 -0400465 }
466 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000467
Corentin Wallezccab69d2017-01-27 16:57:15 -0500468 SafeDelete(mSurfacelessFramebuffer);
469
Jamie Madill4928b7c2017-06-20 12:57:39 -0400470 ANGLE_TRY(releaseSurface(display));
Jamie Madill2f348d22017-06-05 10:50:59 -0400471 releaseShaderCompiler();
Jamie Madill6c1f6712017-02-14 19:08:04 -0500472
Jamie Madill4928b7c2017-06-20 12:57:39 -0400473 mGLState.reset(this);
474
Jamie Madill6c1f6712017-02-14 19:08:04 -0500475 mState.mBuffers->release(this);
476 mState.mShaderPrograms->release(this);
477 mState.mTextures->release(this);
478 mState.mRenderbuffers->release(this);
479 mState.mSamplers->release(this);
Jamie Madill70b5bb02017-08-28 13:32:37 -0400480 mState.mSyncs->release(this);
Jamie Madill6c1f6712017-02-14 19:08:04 -0500481 mState.mPaths->release(this);
482 mState.mFramebuffers->release(this);
Yunchao Hea336b902017-08-02 16:05:21 +0800483 mState.mPipelines->release(this);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400484
485 return egl::NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000486}
487
Jamie Madill70ee0f62017-02-06 16:04:20 -0500488Context::~Context()
489{
490}
491
Jamie Madill4928b7c2017-06-20 12:57:39 -0400492egl::Error Context::makeCurrent(egl::Display *display, egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000493{
Jamie Madill61e16b42017-06-19 11:13:23 -0400494 mCurrentDisplay = display;
495
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000496 if (!mHasBeenCurrent)
497 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000498 initRendererString();
Geoff Langc339c4e2016-11-29 10:37:36 -0500499 initVersionStrings();
Geoff Langcec35902014-04-16 10:52:36 -0400500 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000501
Corentin Wallezc295e512017-01-27 17:47:50 -0500502 int width = 0;
503 int height = 0;
504 if (surface != nullptr)
505 {
506 width = surface->getWidth();
507 height = surface->getHeight();
508 }
509
510 mGLState.setViewportParams(0, 0, width, height);
511 mGLState.setScissorParams(0, 0, width, height);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000512
513 mHasBeenCurrent = true;
514 }
515
Jamie Madill1b94d432015-08-07 13:23:23 -0400516 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700517 mGLState.setAllDirtyBits();
Jamie Madill81c2e252017-09-09 23:32:46 -0400518 mGLState.setAllDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -0400519
Jamie Madill4928b7c2017-06-20 12:57:39 -0400520 ANGLE_TRY(releaseSurface(display));
Corentin Wallezccab69d2017-01-27 16:57:15 -0500521
522 Framebuffer *newDefault = nullptr;
523 if (surface != nullptr)
524 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400525 ANGLE_TRY(surface->setIsCurrent(this, true));
Corentin Wallezccab69d2017-01-27 16:57:15 -0500526 mCurrentSurface = surface;
527 newDefault = surface->getDefaultFramebuffer();
528 }
529 else
530 {
531 if (mSurfacelessFramebuffer == nullptr)
532 {
533 mSurfacelessFramebuffer = new Framebuffer(mImplementation.get());
534 }
535
536 newDefault = mSurfacelessFramebuffer;
537 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000538
Corentin Wallez37c39792015-08-20 14:19:46 -0400539 // Update default framebuffer, the binding of the previous default
540 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400541 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700542 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400543 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700544 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400545 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700546 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400547 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700548 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400549 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500550 mState.mFramebuffers->setDefaultFramebuffer(newDefault);
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400551 }
Ian Ewell292f0052016-02-04 10:37:32 -0500552
553 // Notify the renderer of a context switch
Jamie Madill4928b7c2017-06-20 12:57:39 -0400554 mImplementation->onMakeCurrent(this);
555 return egl::NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000556}
557
Jamie Madill4928b7c2017-06-20 12:57:39 -0400558egl::Error Context::releaseSurface(const egl::Display *display)
Jamie Madill77a72f62015-04-14 11:18:32 -0400559{
Corentin Wallez37c39792015-08-20 14:19:46 -0400560 // Remove the default framebuffer
Corentin Wallezc295e512017-01-27 17:47:50 -0500561 Framebuffer *currentDefault = nullptr;
562 if (mCurrentSurface != nullptr)
Corentin Wallez51706ea2015-08-07 14:39:22 -0400563 {
Corentin Wallezc295e512017-01-27 17:47:50 -0500564 currentDefault = mCurrentSurface->getDefaultFramebuffer();
565 }
566 else if (mSurfacelessFramebuffer != nullptr)
567 {
568 currentDefault = mSurfacelessFramebuffer;
Corentin Wallez51706ea2015-08-07 14:39:22 -0400569 }
570
Corentin Wallezc295e512017-01-27 17:47:50 -0500571 if (mGLState.getReadFramebuffer() == currentDefault)
572 {
573 mGLState.setReadFramebufferBinding(nullptr);
574 }
575 if (mGLState.getDrawFramebuffer() == currentDefault)
576 {
577 mGLState.setDrawFramebufferBinding(nullptr);
578 }
579 mState.mFramebuffers->setDefaultFramebuffer(nullptr);
580
581 if (mCurrentSurface)
582 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400583 ANGLE_TRY(mCurrentSurface->setIsCurrent(this, false));
Corentin Wallezc295e512017-01-27 17:47:50 -0500584 mCurrentSurface = nullptr;
585 }
Jamie Madill4928b7c2017-06-20 12:57:39 -0400586
587 return egl::NoError();
Jamie Madill77a72f62015-04-14 11:18:32 -0400588}
589
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000590GLuint Context::createBuffer()
591{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500592 return mState.mBuffers->createBuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000593}
594
595GLuint Context::createProgram()
596{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500597 return mState.mShaderPrograms->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000598}
599
600GLuint Context::createShader(GLenum type)
601{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500602 return mState.mShaderPrograms->createShader(mImplementation.get(), mLimitations, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000603}
604
605GLuint Context::createTexture()
606{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500607 return mState.mTextures->createTexture();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000608}
609
610GLuint Context::createRenderbuffer()
611{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500612 return mState.mRenderbuffers->createRenderbuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000613}
614
Sami Väisänene45e53b2016-05-25 10:36:04 +0300615GLuint Context::createPaths(GLsizei range)
616{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500617 auto resultOrError = mState.mPaths->createPaths(mImplementation.get(), range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300618 if (resultOrError.isError())
619 {
620 handleError(resultOrError.getError());
621 return 0;
622 }
623 return resultOrError.getResult();
624}
625
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000626// Returns an unused framebuffer name
627GLuint Context::createFramebuffer()
628{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500629 return mState.mFramebuffers->createFramebuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000630}
631
Jamie Madill33dc8432013-07-26 11:55:05 -0400632GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000633{
Jamie Madill33dc8432013-07-26 11:55:05 -0400634 GLuint handle = mFenceNVHandleAllocator.allocate();
Jamie Madill96a483b2017-06-27 16:49:21 -0400635 mFenceNVMap.assign(handle, new FenceNV(mImplementation->createFenceNV()));
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000636 return handle;
637}
638
Yunchao Hea336b902017-08-02 16:05:21 +0800639GLuint Context::createProgramPipeline()
640{
641 return mState.mPipelines->createProgramPipeline();
642}
643
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000644void Context::deleteBuffer(GLuint buffer)
645{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500646 if (mState.mBuffers->getBuffer(buffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000647 {
648 detachBuffer(buffer);
649 }
Jamie Madill893ab082014-05-16 16:56:10 -0400650
Jamie Madill6c1f6712017-02-14 19:08:04 -0500651 mState.mBuffers->deleteObject(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000652}
653
654void Context::deleteShader(GLuint shader)
655{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500656 mState.mShaderPrograms->deleteShader(this, shader);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000657}
658
659void Context::deleteProgram(GLuint program)
660{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500661 mState.mShaderPrograms->deleteProgram(this, program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000662}
663
664void Context::deleteTexture(GLuint texture)
665{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500666 if (mState.mTextures->getTexture(texture))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000667 {
668 detachTexture(texture);
669 }
670
Jamie Madill6c1f6712017-02-14 19:08:04 -0500671 mState.mTextures->deleteObject(this, texture);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000672}
673
674void Context::deleteRenderbuffer(GLuint renderbuffer)
675{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500676 if (mState.mRenderbuffers->getRenderbuffer(renderbuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000677 {
678 detachRenderbuffer(renderbuffer);
679 }
Jamie Madill893ab082014-05-16 16:56:10 -0400680
Jamie Madill6c1f6712017-02-14 19:08:04 -0500681 mState.mRenderbuffers->deleteObject(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000682}
683
Jamie Madill7f0c5a42017-08-26 22:43:26 -0400684void Context::deleteSync(GLsync sync)
Jamie Madillcd055f82013-07-26 11:55:15 -0400685{
686 // The spec specifies the underlying Fence object is not deleted until all current
687 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
688 // and since our API is currently designed for being called from a single thread, we can delete
689 // the fence immediately.
Jamie Madill70b5bb02017-08-28 13:32:37 -0400690 mState.mSyncs->deleteObject(this, static_cast<GLuint>(reinterpret_cast<uintptr_t>(sync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400691}
692
Yunchao Hea336b902017-08-02 16:05:21 +0800693void Context::deleteProgramPipeline(GLuint pipeline)
694{
695 if (mState.mPipelines->getProgramPipeline(pipeline))
696 {
697 detachProgramPipeline(pipeline);
698 }
699
700 mState.mPipelines->deleteObject(this, pipeline);
701}
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
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000793void Context::deleteFramebuffer(GLuint framebuffer)
794{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500795 if (mState.mFramebuffers->getFramebuffer(framebuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000796 {
797 detachFramebuffer(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000798 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500799
Jamie Madill6c1f6712017-02-14 19:08:04 -0500800 mState.mFramebuffers->deleteObject(this, framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000801}
802
Jamie Madill33dc8432013-07-26 11:55:05 -0400803void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000804{
Jamie Madill96a483b2017-06-27 16:49:21 -0400805 FenceNV *fenceObject = nullptr;
806 if (mFenceNVMap.erase(fence, &fenceObject))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000807 {
Jamie Madill96a483b2017-06-27 16:49:21 -0400808 mFenceNVHandleAllocator.release(fence);
809 delete fenceObject;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000810 }
811}
812
Geoff Lang70d0f492015-12-10 17:45:46 -0500813Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000814{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500815 return mState.mBuffers->getBuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000816}
817
Jamie Madill570f7c82014-07-03 10:38:54 -0400818Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000819{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500820 return mState.mTextures->getTexture(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000821}
822
Geoff Lang70d0f492015-12-10 17:45:46 -0500823Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000824{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500825 return mState.mRenderbuffers->getRenderbuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000826}
827
Jamie Madill70b5bb02017-08-28 13:32:37 -0400828Sync *Context::getSync(GLsync handle) const
Jamie Madillcd055f82013-07-26 11:55:15 -0400829{
Jamie Madill70b5bb02017-08-28 13:32:37 -0400830 return mState.mSyncs->getSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400831}
832
Jamie Madill57a89722013-07-02 11:57:03 -0400833VertexArray *Context::getVertexArray(GLuint handle) const
834{
Jamie Madill96a483b2017-06-27 16:49:21 -0400835 return mVertexArrayMap.query(handle);
Jamie Madill57a89722013-07-02 11:57:03 -0400836}
837
Jamie Madilldc356042013-07-19 16:36:57 -0400838Sampler *Context::getSampler(GLuint handle) const
839{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500840 return mState.mSamplers->getSampler(handle);
Jamie Madilldc356042013-07-19 16:36:57 -0400841}
842
Geoff Langc8058452014-02-03 12:04:11 -0500843TransformFeedback *Context::getTransformFeedback(GLuint handle) const
844{
Jamie Madill96a483b2017-06-27 16:49:21 -0400845 return mTransformFeedbackMap.query(handle);
Geoff Langc8058452014-02-03 12:04:11 -0500846}
847
Yunchao Hea336b902017-08-02 16:05:21 +0800848ProgramPipeline *Context::getProgramPipeline(GLuint handle) const
849{
850 return mState.mPipelines->getProgramPipeline(handle);
851}
852
Geoff Lang70d0f492015-12-10 17:45:46 -0500853LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
854{
855 switch (identifier)
856 {
857 case GL_BUFFER:
858 return getBuffer(name);
859 case GL_SHADER:
860 return getShader(name);
861 case GL_PROGRAM:
862 return getProgram(name);
863 case GL_VERTEX_ARRAY:
864 return getVertexArray(name);
865 case GL_QUERY:
866 return getQuery(name);
867 case GL_TRANSFORM_FEEDBACK:
868 return getTransformFeedback(name);
869 case GL_SAMPLER:
870 return getSampler(name);
871 case GL_TEXTURE:
872 return getTexture(name);
873 case GL_RENDERBUFFER:
874 return getRenderbuffer(name);
875 case GL_FRAMEBUFFER:
876 return getFramebuffer(name);
877 default:
878 UNREACHABLE();
879 return nullptr;
880 }
881}
882
883LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
884{
Jamie Madill70b5bb02017-08-28 13:32:37 -0400885 return getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
Geoff Lang70d0f492015-12-10 17:45:46 -0500886}
887
Martin Radev9d901792016-07-15 15:58:58 +0300888void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
889{
890 LabeledObject *object = getLabeledObject(identifier, name);
891 ASSERT(object != nullptr);
892
893 std::string labelName = GetObjectLabelFromPointer(length, label);
894 object->setLabel(labelName);
Jamie Madill8693bdb2017-09-02 15:32:14 -0400895
896 // TODO(jmadill): Determine if the object is dirty based on 'name'. Conservatively assume the
897 // specified object is active until we do this.
898 mGLState.setObjectDirty(identifier);
Martin Radev9d901792016-07-15 15:58:58 +0300899}
900
901void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
902{
903 LabeledObject *object = getLabeledObjectFromPtr(ptr);
904 ASSERT(object != nullptr);
905
906 std::string labelName = GetObjectLabelFromPointer(length, label);
907 object->setLabel(labelName);
908}
909
910void Context::getObjectLabel(GLenum identifier,
911 GLuint name,
912 GLsizei bufSize,
913 GLsizei *length,
914 GLchar *label) const
915{
916 LabeledObject *object = getLabeledObject(identifier, name);
917 ASSERT(object != nullptr);
918
919 const std::string &objectLabel = object->getLabel();
920 GetObjectLabelBase(objectLabel, bufSize, length, label);
921}
922
923void Context::getObjectPtrLabel(const void *ptr,
924 GLsizei bufSize,
925 GLsizei *length,
926 GLchar *label) const
927{
928 LabeledObject *object = getLabeledObjectFromPtr(ptr);
929 ASSERT(object != nullptr);
930
931 const std::string &objectLabel = object->getLabel();
932 GetObjectLabelBase(objectLabel, bufSize, length, label);
933}
934
Jamie Madilldc356042013-07-19 16:36:57 -0400935bool Context::isSampler(GLuint samplerName) const
936{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500937 return mState.mSamplers->isSampler(samplerName);
Jamie Madilldc356042013-07-19 16:36:57 -0400938}
939
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500940void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000941{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500942 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400943 mGLState.setArrayBufferBinding(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000944}
945
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800946void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
947{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500948 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400949 mGLState.setDrawIndirectBufferBinding(this, buffer);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800950}
951
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500952void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000953{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500954 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400955 mGLState.setElementArrayBuffer(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000956}
957
Jamie Madilldedd7b92014-11-05 16:30:36 -0500958void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000959{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500960 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000961
Jamie Madilldedd7b92014-11-05 16:30:36 -0500962 if (handle == 0)
963 {
964 texture = mZeroTextures[target].get();
965 }
966 else
967 {
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500968 texture = mState.mTextures->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500969 }
970
971 ASSERT(texture);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400972 mGLState.setSamplerTexture(this, target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000973}
974
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500975void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000976{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500977 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
978 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700979 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000980}
981
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500982void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000983{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500984 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
985 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700986 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000987}
988
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500989void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -0400990{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500991 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700992 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400993}
994
Shao80957d92017-02-20 21:25:59 +0800995void Context::bindVertexBuffer(GLuint bindingIndex,
996 GLuint bufferHandle,
997 GLintptr offset,
998 GLsizei stride)
999{
1000 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001001 mGLState.bindVertexBuffer(this, bindingIndex, buffer, offset, stride);
Shao80957d92017-02-20 21:25:59 +08001002}
1003
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001004void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -04001005{
Geoff Lang76b10c92014-09-05 16:28:14 -04001006 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -04001007 Sampler *sampler =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001008 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001009 mGLState.setSamplerBinding(this, textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001010}
1011
Xinghua Cao65ec0b22017-03-28 16:10:52 +08001012void Context::bindImageTexture(GLuint unit,
1013 GLuint texture,
1014 GLint level,
1015 GLboolean layered,
1016 GLint layer,
1017 GLenum access,
1018 GLenum format)
1019{
1020 Texture *tex = mState.mTextures->getTexture(texture);
1021 mGLState.setImageUnit(this, unit, tex, level, layered, layer, access, format);
1022}
1023
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001024void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001025{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001026 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001027 mGLState.setGenericUniformBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001028}
1029
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001030void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1031 GLuint index,
1032 GLintptr offset,
1033 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001034{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001035 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001036 mGLState.setIndexedUniformBufferBinding(this, index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001037}
1038
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001039void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001040{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001041 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001042 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001043}
1044
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001045void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1046 GLuint index,
1047 GLintptr offset,
1048 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001049{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001050 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001051 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(this, index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001052}
1053
Jiajia Qin6eafb042016-12-27 17:04:07 +08001054void Context::bindGenericAtomicCounterBuffer(GLuint bufferHandle)
1055{
1056 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001057 mGLState.setGenericAtomicCounterBufferBinding(this, buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08001058}
1059
1060void Context::bindIndexedAtomicCounterBuffer(GLuint bufferHandle,
1061 GLuint index,
1062 GLintptr offset,
1063 GLsizeiptr size)
1064{
1065 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001066 mGLState.setIndexedAtomicCounterBufferBinding(this, index, buffer, offset, size);
Jiajia Qin6eafb042016-12-27 17:04:07 +08001067}
1068
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001069void Context::bindGenericShaderStorageBuffer(GLuint bufferHandle)
1070{
1071 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001072 mGLState.setGenericShaderStorageBufferBinding(this, buffer);
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001073}
1074
1075void Context::bindIndexedShaderStorageBuffer(GLuint bufferHandle,
1076 GLuint index,
1077 GLintptr offset,
1078 GLsizeiptr size)
1079{
1080 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001081 mGLState.setIndexedShaderStorageBufferBinding(this, index, buffer, offset, size);
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001082}
1083
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001084void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001085{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001086 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001087 mGLState.setCopyReadBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001088}
1089
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001090void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001091{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001092 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001093 mGLState.setCopyWriteBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001094}
1095
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001096void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001097{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001098 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001099 mGLState.setPixelPackBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001100}
1101
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001102void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001103{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001104 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001105 mGLState.setPixelUnpackBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001106}
1107
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001108void Context::useProgram(GLuint program)
1109{
Jamie Madill6c1f6712017-02-14 19:08:04 -05001110 mGLState.setProgram(this, getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001111}
1112
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04001113void Context::bindTransformFeedback(GLenum target, GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001114{
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04001115 ASSERT(target == GL_TRANSFORM_FEEDBACK);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001116 TransformFeedback *transformFeedback =
1117 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001118 mGLState.setTransformFeedbackBinding(this, transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001119}
1120
Yunchao Hea336b902017-08-02 16:05:21 +08001121void Context::bindProgramPipeline(GLuint pipelineHandle)
1122{
1123 ProgramPipeline *pipeline =
1124 mState.mPipelines->checkProgramPipelineAllocation(mImplementation.get(), pipelineHandle);
1125 mGLState.setProgramPipelineBinding(this, pipeline);
1126}
1127
Jamie Madillf0e04492017-08-26 15:28:42 -04001128void Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001129{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001130 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001131 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001132
Geoff Lang5aad9672014-09-08 11:10:42 -04001133 // begin query
Jamie Madillf0e04492017-08-26 15:28:42 -04001134 ANGLE_CONTEXT_TRY(queryObject->begin());
Geoff Lang5aad9672014-09-08 11:10:42 -04001135
1136 // set query as active for specified target only if begin succeeded
Jamie Madill4928b7c2017-06-20 12:57:39 -04001137 mGLState.setActiveQuery(this, target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001138}
1139
Jamie Madillf0e04492017-08-26 15:28:42 -04001140void Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001141{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001142 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001143 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001144
Jamie Madillf0e04492017-08-26 15:28:42 -04001145 handleError(queryObject->end());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001146
Geoff Lang5aad9672014-09-08 11:10:42 -04001147 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madill4928b7c2017-06-20 12:57:39 -04001148 mGLState.setActiveQuery(this, target, nullptr);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001149}
1150
Jamie Madillf0e04492017-08-26 15:28:42 -04001151void Context::queryCounter(GLuint id, GLenum target)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001152{
1153 ASSERT(target == GL_TIMESTAMP_EXT);
1154
1155 Query *queryObject = getQuery(id, true, target);
1156 ASSERT(queryObject);
1157
Jamie Madillf0e04492017-08-26 15:28:42 -04001158 handleError(queryObject->queryCounter());
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001159}
1160
1161void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1162{
1163 switch (pname)
1164 {
1165 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001166 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001167 break;
1168 case GL_QUERY_COUNTER_BITS_EXT:
1169 switch (target)
1170 {
1171 case GL_TIME_ELAPSED_EXT:
1172 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1173 break;
1174 case GL_TIMESTAMP_EXT:
1175 params[0] = getExtensions().queryCounterBitsTimestamp;
1176 break;
1177 default:
1178 UNREACHABLE();
1179 params[0] = 0;
1180 break;
1181 }
1182 break;
1183 default:
1184 UNREACHABLE();
1185 return;
1186 }
1187}
1188
Geoff Lang2186c382016-10-14 10:54:54 -04001189void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001190{
Geoff Lang2186c382016-10-14 10:54:54 -04001191 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001192}
1193
Geoff Lang2186c382016-10-14 10:54:54 -04001194void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001195{
Geoff Lang2186c382016-10-14 10:54:54 -04001196 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001197}
1198
Geoff Lang2186c382016-10-14 10:54:54 -04001199void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001200{
Geoff Lang2186c382016-10-14 10:54:54 -04001201 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001202}
1203
Geoff Lang2186c382016-10-14 10:54:54 -04001204void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001205{
Geoff Lang2186c382016-10-14 10:54:54 -04001206 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001207}
1208
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001209Framebuffer *Context::getFramebuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001210{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001211 return mState.mFramebuffers->getFramebuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001212}
1213
Jamie Madill2f348d22017-06-05 10:50:59 -04001214FenceNV *Context::getFenceNV(GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001215{
Jamie Madill96a483b2017-06-27 16:49:21 -04001216 return mFenceNVMap.query(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001217}
1218
Jamie Madill2f348d22017-06-05 10:50:59 -04001219Query *Context::getQuery(GLuint handle, bool create, GLenum type)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001220{
Jamie Madill96a483b2017-06-27 16:49:21 -04001221 if (!mQueryMap.contains(handle))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001222 {
Yunchao Hef81ce4a2017-04-24 10:49:17 +08001223 return nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001224 }
Jamie Madill96a483b2017-06-27 16:49:21 -04001225
1226 Query *query = mQueryMap.query(handle);
1227 if (!query && create)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001228 {
Jamie Madill96a483b2017-06-27 16:49:21 -04001229 query = new Query(mImplementation->createQuery(type), handle);
1230 query->addRef();
1231 mQueryMap.assign(handle, query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001232 }
Jamie Madill96a483b2017-06-27 16:49:21 -04001233 return query;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001234}
1235
Geoff Lang70d0f492015-12-10 17:45:46 -05001236Query *Context::getQuery(GLuint handle) const
1237{
Jamie Madill96a483b2017-06-27 16:49:21 -04001238 return mQueryMap.query(handle);
Geoff Lang70d0f492015-12-10 17:45:46 -05001239}
1240
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001241Texture *Context::getTargetTexture(GLenum target) const
1242{
Ian Ewellbda75592016-04-18 17:25:54 -04001243 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001244 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001245}
1246
Geoff Lang76b10c92014-09-05 16:28:14 -04001247Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001248{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001249 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001250}
1251
Geoff Lang492a7e42014-11-05 13:27:06 -05001252Compiler *Context::getCompiler() const
1253{
Jamie Madill2f348d22017-06-05 10:50:59 -04001254 if (mCompiler.get() == nullptr)
1255 {
Jamie Madill4928b7c2017-06-20 12:57:39 -04001256 mCompiler.set(this, new Compiler(mImplementation.get(), mState));
Jamie Madill2f348d22017-06-05 10:50:59 -04001257 }
1258 return mCompiler.get();
Geoff Lang492a7e42014-11-05 13:27:06 -05001259}
1260
Jamie Madillc1d770e2017-04-13 17:31:24 -04001261void Context::getBooleanvImpl(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001262{
1263 switch (pname)
1264 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001265 case GL_SHADER_COMPILER:
1266 *params = GL_TRUE;
1267 break;
1268 case GL_CONTEXT_ROBUST_ACCESS_EXT:
1269 *params = mRobustAccess ? GL_TRUE : GL_FALSE;
1270 break;
1271 default:
1272 mGLState.getBooleanv(pname, params);
1273 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001274 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001275}
1276
Jamie Madillc1d770e2017-04-13 17:31:24 -04001277void Context::getFloatvImpl(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001278{
Shannon Woods53a94a82014-06-24 15:20:36 -04001279 // Queries about context capabilities and maximums are answered by Context.
1280 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001281 switch (pname)
1282 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001283 case GL_ALIASED_LINE_WIDTH_RANGE:
1284 params[0] = mCaps.minAliasedLineWidth;
1285 params[1] = mCaps.maxAliasedLineWidth;
1286 break;
1287 case GL_ALIASED_POINT_SIZE_RANGE:
1288 params[0] = mCaps.minAliasedPointSize;
1289 params[1] = mCaps.maxAliasedPointSize;
1290 break;
1291 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1292 ASSERT(mExtensions.textureFilterAnisotropic);
1293 *params = mExtensions.maxTextureAnisotropy;
1294 break;
1295 case GL_MAX_TEXTURE_LOD_BIAS:
1296 *params = mCaps.maxLODBias;
1297 break;
1298
1299 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1300 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1301 {
1302 ASSERT(mExtensions.pathRendering);
1303 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1304 memcpy(params, m, 16 * sizeof(GLfloat));
1305 }
Geoff Lange6d4e122015-06-29 13:33:55 -04001306 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001307
Jamie Madill231c7f52017-04-26 13:45:37 -04001308 default:
1309 mGLState.getFloatv(pname, params);
1310 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001311 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001312}
1313
Jamie Madillc1d770e2017-04-13 17:31:24 -04001314void Context::getIntegervImpl(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001315{
Shannon Woods53a94a82014-06-24 15:20:36 -04001316 // Queries about context capabilities and maximums are answered by Context.
1317 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001318
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001319 switch (pname)
1320 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001321 case GL_MAX_VERTEX_ATTRIBS:
1322 *params = mCaps.maxVertexAttributes;
1323 break;
1324 case GL_MAX_VERTEX_UNIFORM_VECTORS:
1325 *params = mCaps.maxVertexUniformVectors;
1326 break;
1327 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
1328 *params = mCaps.maxVertexUniformComponents;
1329 break;
1330 case GL_MAX_VARYING_VECTORS:
1331 *params = mCaps.maxVaryingVectors;
1332 break;
1333 case GL_MAX_VARYING_COMPONENTS:
1334 *params = mCaps.maxVertexOutputComponents;
1335 break;
1336 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1337 *params = mCaps.maxCombinedTextureImageUnits;
1338 break;
1339 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1340 *params = mCaps.maxVertexTextureImageUnits;
1341 break;
1342 case GL_MAX_TEXTURE_IMAGE_UNITS:
1343 *params = mCaps.maxTextureImageUnits;
1344 break;
1345 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1346 *params = mCaps.maxFragmentUniformVectors;
1347 break;
1348 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
1349 *params = mCaps.maxFragmentUniformComponents;
1350 break;
1351 case GL_MAX_RENDERBUFFER_SIZE:
1352 *params = mCaps.maxRenderbufferSize;
1353 break;
1354 case GL_MAX_COLOR_ATTACHMENTS_EXT:
1355 *params = mCaps.maxColorAttachments;
1356 break;
1357 case GL_MAX_DRAW_BUFFERS_EXT:
1358 *params = mCaps.maxDrawBuffers;
1359 break;
1360 // case GL_FRAMEBUFFER_BINDING: // now equivalent to
1361 // GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1362 case GL_SUBPIXEL_BITS:
1363 *params = 4;
1364 break;
1365 case GL_MAX_TEXTURE_SIZE:
1366 *params = mCaps.max2DTextureSize;
1367 break;
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001368 case GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE:
1369 *params = mCaps.maxRectangleTextureSize;
1370 break;
Jamie Madill231c7f52017-04-26 13:45:37 -04001371 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1372 *params = mCaps.maxCubeMapTextureSize;
1373 break;
1374 case GL_MAX_3D_TEXTURE_SIZE:
1375 *params = mCaps.max3DTextureSize;
1376 break;
1377 case GL_MAX_ARRAY_TEXTURE_LAYERS:
1378 *params = mCaps.maxArrayTextureLayers;
1379 break;
1380 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
1381 *params = mCaps.uniformBufferOffsetAlignment;
1382 break;
1383 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
1384 *params = mCaps.maxUniformBufferBindings;
1385 break;
1386 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
1387 *params = mCaps.maxVertexUniformBlocks;
1388 break;
1389 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
1390 *params = mCaps.maxFragmentUniformBlocks;
1391 break;
1392 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
1393 *params = mCaps.maxCombinedTextureImageUnits;
1394 break;
1395 case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
1396 *params = mCaps.maxVertexOutputComponents;
1397 break;
1398 case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
1399 *params = mCaps.maxFragmentInputComponents;
1400 break;
1401 case GL_MIN_PROGRAM_TEXEL_OFFSET:
1402 *params = mCaps.minProgramTexelOffset;
1403 break;
1404 case GL_MAX_PROGRAM_TEXEL_OFFSET:
1405 *params = mCaps.maxProgramTexelOffset;
1406 break;
1407 case GL_MAJOR_VERSION:
1408 *params = getClientVersion().major;
1409 break;
1410 case GL_MINOR_VERSION:
1411 *params = getClientVersion().minor;
1412 break;
1413 case GL_MAX_ELEMENTS_INDICES:
1414 *params = mCaps.maxElementsIndices;
1415 break;
1416 case GL_MAX_ELEMENTS_VERTICES:
1417 *params = mCaps.maxElementsVertices;
1418 break;
1419 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
1420 *params = mCaps.maxTransformFeedbackInterleavedComponents;
1421 break;
1422 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
1423 *params = mCaps.maxTransformFeedbackSeparateAttributes;
1424 break;
1425 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
1426 *params = mCaps.maxTransformFeedbackSeparateComponents;
1427 break;
1428 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1429 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1430 break;
1431 case GL_MAX_SAMPLES_ANGLE:
1432 *params = mCaps.maxSamples;
1433 break;
1434 case GL_MAX_VIEWPORT_DIMS:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001435 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001436 params[0] = mCaps.maxViewportWidth;
1437 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001438 }
1439 break;
Jamie Madill231c7f52017-04-26 13:45:37 -04001440 case GL_COMPRESSED_TEXTURE_FORMATS:
1441 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(),
1442 params);
1443 break;
1444 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1445 *params = mResetStrategy;
1446 break;
1447 case GL_NUM_SHADER_BINARY_FORMATS:
1448 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
1449 break;
1450 case GL_SHADER_BINARY_FORMATS:
1451 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1452 break;
1453 case GL_NUM_PROGRAM_BINARY_FORMATS:
1454 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
1455 break;
1456 case GL_PROGRAM_BINARY_FORMATS:
1457 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
1458 break;
1459 case GL_NUM_EXTENSIONS:
1460 *params = static_cast<GLint>(mExtensionStrings.size());
1461 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001462
Jamie Madill231c7f52017-04-26 13:45:37 -04001463 // GL_KHR_debug
1464 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1465 *params = mExtensions.maxDebugMessageLength;
1466 break;
1467 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1468 *params = mExtensions.maxDebugLoggedMessages;
1469 break;
1470 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1471 *params = mExtensions.maxDebugGroupStackDepth;
1472 break;
1473 case GL_MAX_LABEL_LENGTH:
1474 *params = mExtensions.maxLabelLength;
1475 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001476
Martin Radeve5285d22017-07-14 16:23:53 +03001477 // GL_ANGLE_multiview
1478 case GL_MAX_VIEWS_ANGLE:
1479 *params = mExtensions.maxViews;
1480 break;
1481
Jamie Madill231c7f52017-04-26 13:45:37 -04001482 // GL_EXT_disjoint_timer_query
1483 case GL_GPU_DISJOINT_EXT:
1484 *params = mImplementation->getGPUDisjoint();
1485 break;
1486 case GL_MAX_FRAMEBUFFER_WIDTH:
1487 *params = mCaps.maxFramebufferWidth;
1488 break;
1489 case GL_MAX_FRAMEBUFFER_HEIGHT:
1490 *params = mCaps.maxFramebufferHeight;
1491 break;
1492 case GL_MAX_FRAMEBUFFER_SAMPLES:
1493 *params = mCaps.maxFramebufferSamples;
1494 break;
1495 case GL_MAX_SAMPLE_MASK_WORDS:
1496 *params = mCaps.maxSampleMaskWords;
1497 break;
1498 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1499 *params = mCaps.maxColorTextureSamples;
1500 break;
1501 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1502 *params = mCaps.maxDepthTextureSamples;
1503 break;
1504 case GL_MAX_INTEGER_SAMPLES:
1505 *params = mCaps.maxIntegerSamples;
1506 break;
1507 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1508 *params = mCaps.maxVertexAttribRelativeOffset;
1509 break;
1510 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1511 *params = mCaps.maxVertexAttribBindings;
1512 break;
1513 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1514 *params = mCaps.maxVertexAttribStride;
1515 break;
1516 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1517 *params = mCaps.maxVertexAtomicCounterBuffers;
1518 break;
1519 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1520 *params = mCaps.maxVertexAtomicCounters;
1521 break;
1522 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1523 *params = mCaps.maxVertexImageUniforms;
1524 break;
1525 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1526 *params = mCaps.maxVertexShaderStorageBlocks;
1527 break;
1528 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1529 *params = mCaps.maxFragmentAtomicCounterBuffers;
1530 break;
1531 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1532 *params = mCaps.maxFragmentAtomicCounters;
1533 break;
1534 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1535 *params = mCaps.maxFragmentImageUniforms;
1536 break;
1537 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1538 *params = mCaps.maxFragmentShaderStorageBlocks;
1539 break;
1540 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1541 *params = mCaps.minProgramTextureGatherOffset;
1542 break;
1543 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1544 *params = mCaps.maxProgramTextureGatherOffset;
1545 break;
1546 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1547 *params = mCaps.maxComputeWorkGroupInvocations;
1548 break;
1549 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1550 *params = mCaps.maxComputeUniformBlocks;
1551 break;
1552 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1553 *params = mCaps.maxComputeTextureImageUnits;
1554 break;
1555 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1556 *params = mCaps.maxComputeSharedMemorySize;
1557 break;
1558 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1559 *params = mCaps.maxComputeUniformComponents;
1560 break;
1561 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1562 *params = mCaps.maxComputeAtomicCounterBuffers;
1563 break;
1564 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1565 *params = mCaps.maxComputeAtomicCounters;
1566 break;
1567 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1568 *params = mCaps.maxComputeImageUniforms;
1569 break;
1570 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1571 *params = mCaps.maxCombinedComputeUniformComponents;
1572 break;
1573 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1574 *params = mCaps.maxComputeShaderStorageBlocks;
1575 break;
1576 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1577 *params = mCaps.maxCombinedShaderOutputResources;
1578 break;
1579 case GL_MAX_UNIFORM_LOCATIONS:
1580 *params = mCaps.maxUniformLocations;
1581 break;
1582 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1583 *params = mCaps.maxAtomicCounterBufferBindings;
1584 break;
1585 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1586 *params = mCaps.maxAtomicCounterBufferSize;
1587 break;
1588 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1589 *params = mCaps.maxCombinedAtomicCounterBuffers;
1590 break;
1591 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1592 *params = mCaps.maxCombinedAtomicCounters;
1593 break;
1594 case GL_MAX_IMAGE_UNITS:
1595 *params = mCaps.maxImageUnits;
1596 break;
1597 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1598 *params = mCaps.maxCombinedImageUniforms;
1599 break;
1600 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1601 *params = mCaps.maxShaderStorageBufferBindings;
1602 break;
1603 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1604 *params = mCaps.maxCombinedShaderStorageBlocks;
1605 break;
1606 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1607 *params = mCaps.shaderStorageBufferOffsetAlignment;
1608 break;
1609 default:
1610 mGLState.getIntegerv(this, pname, params);
1611 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001612 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001613}
1614
Jamie Madill7f0c5a42017-08-26 22:43:26 -04001615void Context::getInteger64vImpl(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001616{
Shannon Woods53a94a82014-06-24 15:20:36 -04001617 // Queries about context capabilities and maximums are answered by Context.
1618 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001619 switch (pname)
1620 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001621 case GL_MAX_ELEMENT_INDEX:
1622 *params = mCaps.maxElementIndex;
1623 break;
1624 case GL_MAX_UNIFORM_BLOCK_SIZE:
1625 *params = mCaps.maxUniformBlockSize;
1626 break;
1627 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
1628 *params = mCaps.maxCombinedVertexUniformComponents;
1629 break;
1630 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
1631 *params = mCaps.maxCombinedFragmentUniformComponents;
1632 break;
1633 case GL_MAX_SERVER_WAIT_TIMEOUT:
1634 *params = mCaps.maxServerWaitTimeout;
1635 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001636
Jamie Madill231c7f52017-04-26 13:45:37 -04001637 // GL_EXT_disjoint_timer_query
1638 case GL_TIMESTAMP_EXT:
1639 *params = mImplementation->getTimestamp();
1640 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001641
Jamie Madill231c7f52017-04-26 13:45:37 -04001642 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1643 *params = mCaps.maxShaderStorageBlockSize;
1644 break;
1645 default:
1646 UNREACHABLE();
1647 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001648 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001649}
1650
Geoff Lang70d0f492015-12-10 17:45:46 -05001651void Context::getPointerv(GLenum pname, void **params) const
1652{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001653 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001654}
1655
Martin Radev66fb8202016-07-28 11:45:20 +03001656void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001657{
Shannon Woods53a94a82014-06-24 15:20:36 -04001658 // Queries about context capabilities and maximums are answered by Context.
1659 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001660
1661 GLenum nativeType;
1662 unsigned int numParams;
1663 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1664 ASSERT(queryStatus);
1665
1666 if (nativeType == GL_INT)
1667 {
1668 switch (target)
1669 {
1670 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1671 ASSERT(index < 3u);
1672 *data = mCaps.maxComputeWorkGroupCount[index];
1673 break;
1674 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1675 ASSERT(index < 3u);
1676 *data = mCaps.maxComputeWorkGroupSize[index];
1677 break;
1678 default:
1679 mGLState.getIntegeri_v(target, index, data);
1680 }
1681 }
1682 else
1683 {
1684 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1685 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001686}
1687
Martin Radev66fb8202016-07-28 11:45:20 +03001688void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001689{
Shannon Woods53a94a82014-06-24 15:20:36 -04001690 // Queries about context capabilities and maximums are answered by Context.
1691 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001692
1693 GLenum nativeType;
1694 unsigned int numParams;
1695 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1696 ASSERT(queryStatus);
1697
1698 if (nativeType == GL_INT_64_ANGLEX)
1699 {
1700 mGLState.getInteger64i_v(target, index, data);
1701 }
1702 else
1703 {
1704 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1705 }
1706}
1707
1708void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1709{
1710 // Queries about context capabilities and maximums are answered by Context.
1711 // Queries about current GL state values are answered by State.
1712
1713 GLenum nativeType;
1714 unsigned int numParams;
1715 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1716 ASSERT(queryStatus);
1717
1718 if (nativeType == GL_BOOL)
1719 {
1720 mGLState.getBooleani_v(target, index, data);
1721 }
1722 else
1723 {
1724 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1725 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001726}
1727
He Yunchao010e4db2017-03-03 14:22:06 +08001728void Context::getBufferParameteriv(GLenum target, GLenum pname, GLint *params)
1729{
1730 Buffer *buffer = mGLState.getTargetBuffer(target);
1731 QueryBufferParameteriv(buffer, pname, params);
1732}
1733
1734void Context::getFramebufferAttachmentParameteriv(GLenum target,
1735 GLenum attachment,
1736 GLenum pname,
1737 GLint *params)
1738{
1739 const Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
1740 QueryFramebufferAttachmentParameteriv(framebuffer, attachment, pname, params);
1741}
1742
1743void Context::getRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
1744{
1745 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
1746 QueryRenderbufferiv(this, renderbuffer, pname, params);
1747}
1748
1749void Context::getTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
1750{
1751 Texture *texture = getTargetTexture(target);
1752 QueryTexParameterfv(texture, pname, params);
1753}
1754
1755void Context::getTexParameteriv(GLenum target, GLenum pname, GLint *params)
1756{
1757 Texture *texture = getTargetTexture(target);
1758 QueryTexParameteriv(texture, pname, params);
1759}
1760void Context::texParameterf(GLenum target, GLenum pname, GLfloat param)
1761{
1762 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001763 SetTexParameterf(this, texture, pname, param);
Jamie Madill81c2e252017-09-09 23:32:46 -04001764 onTextureChange(texture);
He Yunchao010e4db2017-03-03 14:22:06 +08001765}
1766
1767void Context::texParameterfv(GLenum target, GLenum pname, const GLfloat *params)
1768{
1769 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001770 SetTexParameterfv(this, texture, pname, params);
Jamie Madill81c2e252017-09-09 23:32:46 -04001771 onTextureChange(texture);
He Yunchao010e4db2017-03-03 14:22:06 +08001772}
1773
1774void Context::texParameteri(GLenum target, GLenum pname, GLint param)
1775{
1776 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001777 SetTexParameteri(this, texture, pname, param);
Jamie Madill81c2e252017-09-09 23:32:46 -04001778 onTextureChange(texture);
He Yunchao010e4db2017-03-03 14:22:06 +08001779}
1780
1781void Context::texParameteriv(GLenum target, GLenum pname, const GLint *params)
1782{
1783 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001784 SetTexParameteriv(this, texture, pname, params);
Jamie Madill81c2e252017-09-09 23:32:46 -04001785 onTextureChange(texture);
He Yunchao010e4db2017-03-03 14:22:06 +08001786}
1787
Jamie Madill675fe712016-12-19 13:07:54 -05001788void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001789{
Jamie Madill14bbb3f2017-09-12 15:23:01 -04001790 syncRendererState();
Jamie Madillb6664922017-07-25 12:55:04 -04001791 ANGLE_CONTEXT_TRY(mImplementation->drawArrays(this, mode, first, count));
1792 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001793}
1794
Jamie Madill675fe712016-12-19 13:07:54 -05001795void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Geoff Langf6db0982015-08-25 13:04:00 -04001796{
Jamie Madill14bbb3f2017-09-12 15:23:01 -04001797 syncRendererState();
Jamie Madillb6664922017-07-25 12:55:04 -04001798 ANGLE_CONTEXT_TRY(
1799 mImplementation->drawArraysInstanced(this, mode, first, count, instanceCount));
1800 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Langf6db0982015-08-25 13:04:00 -04001801}
1802
Jamie Madill876429b2017-04-20 15:46:24 -04001803void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001804{
Jamie Madill14bbb3f2017-09-12 15:23:01 -04001805 syncRendererState();
Jamie Madillb6664922017-07-25 12:55:04 -04001806 ANGLE_CONTEXT_TRY(mImplementation->drawElements(this, mode, count, type, indices));
Geoff Langf6db0982015-08-25 13:04:00 -04001807}
1808
Jamie Madill675fe712016-12-19 13:07:54 -05001809void Context::drawElementsInstanced(GLenum mode,
1810 GLsizei count,
1811 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001812 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001813 GLsizei instances)
Geoff Langf6db0982015-08-25 13:04:00 -04001814{
Jamie Madill14bbb3f2017-09-12 15:23:01 -04001815 syncRendererState();
Jamie Madillb6664922017-07-25 12:55:04 -04001816 ANGLE_CONTEXT_TRY(
Qin Jiajia1da00652017-06-20 17:16:25 +08001817 mImplementation->drawElementsInstanced(this, mode, count, type, indices, instances));
Geoff Langf6db0982015-08-25 13:04:00 -04001818}
1819
Jamie Madill675fe712016-12-19 13:07:54 -05001820void Context::drawRangeElements(GLenum mode,
1821 GLuint start,
1822 GLuint end,
1823 GLsizei count,
1824 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001825 const void *indices)
Geoff Langf6db0982015-08-25 13:04:00 -04001826{
Jamie Madill14bbb3f2017-09-12 15:23:01 -04001827 syncRendererState();
Jamie Madillb6664922017-07-25 12:55:04 -04001828 ANGLE_CONTEXT_TRY(
1829 mImplementation->drawRangeElements(this, mode, start, end, count, type, indices));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001830}
1831
Jamie Madill876429b2017-04-20 15:46:24 -04001832void Context::drawArraysIndirect(GLenum mode, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001833{
Jamie Madill14bbb3f2017-09-12 15:23:01 -04001834 syncRendererState();
Jamie Madillb6664922017-07-25 12:55:04 -04001835 ANGLE_CONTEXT_TRY(mImplementation->drawArraysIndirect(this, mode, indirect));
Jiajia Qind9671222016-11-29 16:30:31 +08001836}
1837
Jamie Madill876429b2017-04-20 15:46:24 -04001838void Context::drawElementsIndirect(GLenum mode, GLenum type, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001839{
Jamie Madill14bbb3f2017-09-12 15:23:01 -04001840 syncRendererState();
Jamie Madillb6664922017-07-25 12:55:04 -04001841 ANGLE_CONTEXT_TRY(mImplementation->drawElementsIndirect(this, mode, type, indirect));
Jiajia Qind9671222016-11-29 16:30:31 +08001842}
1843
Jamie Madill675fe712016-12-19 13:07:54 -05001844void Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001845{
Jamie Madill675fe712016-12-19 13:07:54 -05001846 handleError(mImplementation->flush());
Geoff Lang129753a2015-01-09 16:52:09 -05001847}
1848
Jamie Madill675fe712016-12-19 13:07:54 -05001849void Context::finish()
Geoff Lang129753a2015-01-09 16:52:09 -05001850{
Jamie Madill675fe712016-12-19 13:07:54 -05001851 handleError(mImplementation->finish());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001852}
1853
Austin Kinross6ee1e782015-05-29 17:05:37 -07001854void Context::insertEventMarker(GLsizei length, const char *marker)
1855{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001856 ASSERT(mImplementation);
1857 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001858}
1859
1860void Context::pushGroupMarker(GLsizei length, const char *marker)
1861{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001862 ASSERT(mImplementation);
1863 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001864}
1865
1866void Context::popGroupMarker()
1867{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001868 ASSERT(mImplementation);
1869 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001870}
1871
Geoff Langd8605522016-04-13 10:19:12 -04001872void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1873{
1874 Program *programObject = getProgram(program);
1875 ASSERT(programObject);
1876
1877 programObject->bindUniformLocation(location, name);
1878}
1879
Sami Väisänena797e062016-05-12 15:23:40 +03001880void Context::setCoverageModulation(GLenum components)
1881{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001882 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001883}
1884
Sami Väisänene45e53b2016-05-25 10:36:04 +03001885void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1886{
1887 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1888}
1889
1890void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1891{
1892 GLfloat I[16];
1893 angle::Matrix<GLfloat>::setToIdentity(I);
1894
1895 mGLState.loadPathRenderingMatrix(matrixMode, I);
1896}
1897
1898void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1899{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001900 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001901 if (!pathObj)
1902 return;
1903
1904 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1905 syncRendererState();
1906
1907 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1908}
1909
1910void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1911{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001912 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001913 if (!pathObj)
1914 return;
1915
1916 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1917 syncRendererState();
1918
1919 mImplementation->stencilStrokePath(pathObj, reference, mask);
1920}
1921
1922void Context::coverFillPath(GLuint path, GLenum coverMode)
1923{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001924 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001925 if (!pathObj)
1926 return;
1927
1928 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1929 syncRendererState();
1930
1931 mImplementation->coverFillPath(pathObj, coverMode);
1932}
1933
1934void Context::coverStrokePath(GLuint path, GLenum coverMode)
1935{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001936 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001937 if (!pathObj)
1938 return;
1939
1940 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1941 syncRendererState();
1942
1943 mImplementation->coverStrokePath(pathObj, coverMode);
1944}
1945
1946void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
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->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1956}
1957
1958void Context::stencilThenCoverStrokePath(GLuint path,
1959 GLint reference,
1960 GLuint mask,
1961 GLenum coverMode)
1962{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001963 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001964 if (!pathObj)
1965 return;
1966
1967 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1968 syncRendererState();
1969
1970 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1971}
1972
Sami Väisänend59ca052016-06-21 16:10:00 +03001973void Context::coverFillPathInstanced(GLsizei numPaths,
1974 GLenum pathNameType,
1975 const void *paths,
1976 GLuint pathBase,
1977 GLenum coverMode,
1978 GLenum transformType,
1979 const GLfloat *transformValues)
1980{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001981 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001982
1983 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1984 syncRendererState();
1985
1986 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1987}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001988
Sami Väisänend59ca052016-06-21 16:10:00 +03001989void Context::coverStrokePathInstanced(GLsizei numPaths,
1990 GLenum pathNameType,
1991 const void *paths,
1992 GLuint pathBase,
1993 GLenum coverMode,
1994 GLenum transformType,
1995 const GLfloat *transformValues)
1996{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001997 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001998
1999 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2000 syncRendererState();
2001
2002 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
2003 transformValues);
2004}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002005
Sami Väisänend59ca052016-06-21 16:10:00 +03002006void Context::stencilFillPathInstanced(GLsizei numPaths,
2007 GLenum pathNameType,
2008 const void *paths,
2009 GLuint pathBase,
2010 GLenum fillMode,
2011 GLuint mask,
2012 GLenum transformType,
2013 const GLfloat *transformValues)
2014{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002015 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002016
2017 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2018 syncRendererState();
2019
2020 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
2021 transformValues);
2022}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002023
Sami Väisänend59ca052016-06-21 16:10:00 +03002024void Context::stencilStrokePathInstanced(GLsizei numPaths,
2025 GLenum pathNameType,
2026 const void *paths,
2027 GLuint pathBase,
2028 GLint reference,
2029 GLuint mask,
2030 GLenum transformType,
2031 const GLfloat *transformValues)
2032{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002033 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002034
2035 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2036 syncRendererState();
2037
2038 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
2039 transformValues);
2040}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002041
Sami Väisänend59ca052016-06-21 16:10:00 +03002042void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
2043 GLenum pathNameType,
2044 const void *paths,
2045 GLuint pathBase,
2046 GLenum fillMode,
2047 GLuint mask,
2048 GLenum coverMode,
2049 GLenum transformType,
2050 const GLfloat *transformValues)
2051{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002052 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002053
2054 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2055 syncRendererState();
2056
2057 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
2058 transformType, transformValues);
2059}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002060
Sami Väisänend59ca052016-06-21 16:10:00 +03002061void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
2062 GLenum pathNameType,
2063 const void *paths,
2064 GLuint pathBase,
2065 GLint reference,
2066 GLuint mask,
2067 GLenum coverMode,
2068 GLenum transformType,
2069 const GLfloat *transformValues)
2070{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002071 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002072
2073 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2074 syncRendererState();
2075
2076 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
2077 transformType, transformValues);
2078}
2079
Sami Väisänen46eaa942016-06-29 10:26:37 +03002080void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
2081{
2082 auto *programObject = getProgram(program);
2083
2084 programObject->bindFragmentInputLocation(location, name);
2085}
2086
2087void Context::programPathFragmentInputGen(GLuint program,
2088 GLint location,
2089 GLenum genMode,
2090 GLint components,
2091 const GLfloat *coeffs)
2092{
2093 auto *programObject = getProgram(program);
2094
Jamie Madillbd044ed2017-06-05 12:59:21 -04002095 programObject->pathFragmentInputGen(this, location, genMode, components, coeffs);
Sami Väisänen46eaa942016-06-29 10:26:37 +03002096}
2097
jchen1015015f72017-03-16 13:54:21 +08002098GLuint Context::getProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name)
2099{
jchen10fd7c3b52017-03-21 15:36:03 +08002100 const auto *programObject = getProgram(program);
jchen1015015f72017-03-16 13:54:21 +08002101 return QueryProgramResourceIndex(programObject, programInterface, name);
2102}
2103
jchen10fd7c3b52017-03-21 15:36:03 +08002104void Context::getProgramResourceName(GLuint program,
2105 GLenum programInterface,
2106 GLuint index,
2107 GLsizei bufSize,
2108 GLsizei *length,
2109 GLchar *name)
2110{
2111 const auto *programObject = getProgram(program);
2112 QueryProgramResourceName(programObject, programInterface, index, bufSize, length, name);
2113}
2114
jchen10191381f2017-04-11 13:59:04 +08002115GLint Context::getProgramResourceLocation(GLuint program,
2116 GLenum programInterface,
2117 const GLchar *name)
2118{
2119 const auto *programObject = getProgram(program);
2120 return QueryProgramResourceLocation(programObject, programInterface, name);
2121}
2122
jchen10880683b2017-04-12 16:21:55 +08002123void Context::getProgramResourceiv(GLuint program,
2124 GLenum programInterface,
2125 GLuint index,
2126 GLsizei propCount,
2127 const GLenum *props,
2128 GLsizei bufSize,
2129 GLsizei *length,
2130 GLint *params)
2131{
2132 const auto *programObject = getProgram(program);
2133 QueryProgramResourceiv(programObject, programInterface, index, propCount, props, bufSize,
2134 length, params);
2135}
2136
jchen10d9cd7b72017-08-30 15:04:25 +08002137void Context::getProgramInterfaceiv(GLuint program,
2138 GLenum programInterface,
2139 GLenum pname,
2140 GLint *params)
2141{
2142 const auto *programObject = getProgram(program);
2143 QueryProgramInterfaceiv(programObject, programInterface, pname, params);
2144}
2145
Jamie Madill71c88b32017-09-14 22:20:29 -04002146void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002147{
Geoff Langda5777c2014-07-11 09:52:58 -04002148 if (error.isError())
2149 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002150 GLenum code = error.getCode();
2151 mErrors.insert(code);
2152 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
2153 {
2154 markContextLost();
2155 }
Geoff Lang70d0f492015-12-10 17:45:46 -05002156
2157 if (!error.getMessage().empty())
2158 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002159 auto *debug = &mGLState.getDebug();
2160 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
2161 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05002162 }
Geoff Langda5777c2014-07-11 09:52:58 -04002163 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002164}
2165
2166// Get one of the recorded errors and clear its flag, if any.
2167// [OpenGL ES 2.0.24] section 2.5 page 13.
2168GLenum Context::getError()
2169{
Geoff Langda5777c2014-07-11 09:52:58 -04002170 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002171 {
Geoff Langda5777c2014-07-11 09:52:58 -04002172 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002173 }
Geoff Langda5777c2014-07-11 09:52:58 -04002174 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002175 {
Geoff Langda5777c2014-07-11 09:52:58 -04002176 GLenum error = *mErrors.begin();
2177 mErrors.erase(mErrors.begin());
2178 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002179 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002180}
2181
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002182// NOTE: this function should not assume that this context is current!
2183void Context::markContextLost()
2184{
2185 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002186 {
Jamie Madill231c7f52017-04-26 13:45:37 -04002187 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002188 mContextLostForced = true;
2189 }
Jamie Madill231c7f52017-04-26 13:45:37 -04002190 mContextLost = true;
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002191}
2192
2193bool Context::isContextLost()
2194{
2195 return mContextLost;
2196}
2197
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002198GLenum Context::getResetStatus()
2199{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002200 // Even if the application doesn't want to know about resets, we want to know
2201 // as it will allow us to skip all the calls.
2202 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002203 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002204 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002205 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002206 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002207 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002208
2209 // EXT_robustness, section 2.6: If the reset notification behavior is
2210 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2211 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2212 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002213 }
2214
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002215 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2216 // status should be returned at least once, and GL_NO_ERROR should be returned
2217 // once the device has finished resetting.
2218 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002219 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002220 ASSERT(mResetStatus == GL_NO_ERROR);
2221 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002222
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002223 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002224 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002225 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002226 }
2227 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002228 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002229 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002230 // If markContextLost was used to mark the context lost then
2231 // assume that is not recoverable, and continue to report the
2232 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002233 mResetStatus = mImplementation->getResetStatus();
2234 }
Jamie Madill893ab082014-05-16 16:56:10 -04002235
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002236 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002237}
2238
2239bool Context::isResetNotificationEnabled()
2240{
2241 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2242}
2243
Corentin Walleze3b10e82015-05-20 11:06:25 -04002244const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002245{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002246 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002247}
2248
2249EGLenum Context::getClientType() const
2250{
2251 return mClientType;
2252}
2253
2254EGLenum Context::getRenderBuffer() const
2255{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002256 const Framebuffer *framebuffer = mState.mFramebuffers->getFramebuffer(0);
2257 if (framebuffer == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -04002258 {
2259 return EGL_NONE;
2260 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002261
2262 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2263 ASSERT(backAttachment != nullptr);
2264 return backAttachment->getSurface()->getRenderBuffer();
Régis Fénéon83107972015-02-05 12:57:44 +01002265}
2266
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002267VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002268{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002269 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002270 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2271 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002272 {
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002273 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle,
2274 mCaps.maxVertexAttributes, mCaps.maxVertexAttribBindings);
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002275
Jamie Madill96a483b2017-06-27 16:49:21 -04002276 mVertexArrayMap.assign(vertexArrayHandle, vertexArray);
Geoff Lang36167ab2015-12-07 10:27:14 -05002277 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002278
2279 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002280}
2281
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002282TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002283{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002284 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002285 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2286 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002287 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002288 transformFeedback =
2289 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002290 transformFeedback->addRef();
Jamie Madill96a483b2017-06-27 16:49:21 -04002291 mTransformFeedbackMap.assign(transformFeedbackHandle, transformFeedback);
Geoff Lang36167ab2015-12-07 10:27:14 -05002292 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002293
2294 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002295}
2296
2297bool Context::isVertexArrayGenerated(GLuint vertexArray)
2298{
Jamie Madill96a483b2017-06-27 16:49:21 -04002299 ASSERT(mVertexArrayMap.contains(0));
2300 return mVertexArrayMap.contains(vertexArray);
Geoff Lang36167ab2015-12-07 10:27:14 -05002301}
2302
2303bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2304{
Jamie Madill96a483b2017-06-27 16:49:21 -04002305 ASSERT(mTransformFeedbackMap.contains(0));
2306 return mTransformFeedbackMap.contains(transformFeedback);
Geoff Lang36167ab2015-12-07 10:27:14 -05002307}
2308
Shannon Woods53a94a82014-06-24 15:20:36 -04002309void Context::detachTexture(GLuint texture)
2310{
2311 // Simple pass-through to State's detachTexture method, as textures do not require
2312 // allocation map management either here or in the resource manager at detach time.
2313 // Zero textures are held by the Context, and we don't attempt to request them from
2314 // the State.
Jamie Madilla02315b2017-02-23 14:14:47 -05002315 mGLState.detachTexture(this, mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002316}
2317
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002318void Context::detachBuffer(GLuint buffer)
2319{
Yuly Novikov5807a532015-12-03 13:01:22 -05002320 // Simple pass-through to State's detachBuffer method, since
2321 // only buffer attachments to container objects that are bound to the current context
2322 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002323
Yuly Novikov5807a532015-12-03 13:01:22 -05002324 // [OpenGL ES 3.2] section 5.1.2 page 45:
2325 // Attachments to unbound container objects, such as
2326 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2327 // are not affected and continue to act as references on the deleted object
Jamie Madill4928b7c2017-06-20 12:57:39 -04002328 mGLState.detachBuffer(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002329}
2330
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002331void Context::detachFramebuffer(GLuint framebuffer)
2332{
Shannon Woods53a94a82014-06-24 15:20:36 -04002333 // Framebuffer detachment is handled by Context, because 0 is a valid
2334 // Framebuffer object, and a pointer to it must be passed from Context
2335 // to State at binding time.
2336
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002337 // [OpenGL ES 2.0.24] section 4.4 page 107:
Jamie Madill231c7f52017-04-26 13:45:37 -04002338 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as
2339 // though BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of
2340 // zero.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002341
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002342 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002343 {
2344 bindReadFramebuffer(0);
2345 }
2346
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002347 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002348 {
2349 bindDrawFramebuffer(0);
2350 }
2351}
2352
2353void Context::detachRenderbuffer(GLuint renderbuffer)
2354{
Jamie Madilla02315b2017-02-23 14:14:47 -05002355 mGLState.detachRenderbuffer(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002356}
2357
Jamie Madill57a89722013-07-02 11:57:03 -04002358void Context::detachVertexArray(GLuint vertexArray)
2359{
Jamie Madill77a72f62015-04-14 11:18:32 -04002360 // Vertex array detachment is handled by Context, because 0 is a valid
2361 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002362 // binding time.
2363
Jamie Madill57a89722013-07-02 11:57:03 -04002364 // [OpenGL ES 3.0.2] section 2.10 page 43:
2365 // If a vertex array object that is currently bound is deleted, the binding
2366 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002367 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002368 {
2369 bindVertexArray(0);
2370 }
2371}
2372
Geoff Langc8058452014-02-03 12:04:11 -05002373void Context::detachTransformFeedback(GLuint transformFeedback)
2374{
Corentin Walleza2257da2016-04-19 16:43:12 -04002375 // Transform feedback detachment is handled by Context, because 0 is a valid
2376 // transform feedback, and a pointer to it must be passed from Context to State at
2377 // binding time.
2378
2379 // The OpenGL specification doesn't mention what should happen when the currently bound
2380 // transform feedback object is deleted. Since it is a container object, we treat it like
2381 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madill4928b7c2017-06-20 12:57:39 -04002382 if (mGLState.removeTransformFeedbackBinding(this, transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002383 {
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04002384 bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
Corentin Walleza2257da2016-04-19 16:43:12 -04002385 }
Geoff Langc8058452014-02-03 12:04:11 -05002386}
2387
Jamie Madilldc356042013-07-19 16:36:57 -04002388void Context::detachSampler(GLuint sampler)
2389{
Jamie Madill4928b7c2017-06-20 12:57:39 -04002390 mGLState.detachSampler(this, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002391}
2392
Yunchao Hea336b902017-08-02 16:05:21 +08002393void Context::detachProgramPipeline(GLuint pipeline)
2394{
2395 mGLState.detachProgramPipeline(this, pipeline);
2396}
2397
Jamie Madill3ef140a2017-08-26 23:11:21 -04002398void Context::vertexAttribDivisor(GLuint index, GLuint divisor)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002399{
Shaodde78e82017-05-22 14:13:27 +08002400 mGLState.setVertexAttribDivisor(this, index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002401}
2402
Jamie Madille29d1672013-07-19 16:36:57 -04002403void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2404{
Geoff Langc1984ed2016-10-07 12:41:00 -04002405 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002406 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002407 SetSamplerParameteri(samplerObject, pname, param);
Jamie Madill06ef36b2017-09-09 23:32:46 -04002408 mGLState.setObjectDirty(GL_SAMPLER);
Geoff Langc1984ed2016-10-07 12:41:00 -04002409}
Jamie Madille29d1672013-07-19 16:36:57 -04002410
Geoff Langc1984ed2016-10-07 12:41:00 -04002411void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2412{
2413 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002414 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002415 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madill06ef36b2017-09-09 23:32:46 -04002416 mGLState.setObjectDirty(GL_SAMPLER);
Jamie Madille29d1672013-07-19 16:36:57 -04002417}
2418
2419void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2420{
Geoff Langc1984ed2016-10-07 12:41:00 -04002421 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002422 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002423 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madill06ef36b2017-09-09 23:32:46 -04002424 mGLState.setObjectDirty(GL_SAMPLER);
Jamie Madille29d1672013-07-19 16:36:57 -04002425}
2426
Geoff Langc1984ed2016-10-07 12:41:00 -04002427void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002428{
Geoff Langc1984ed2016-10-07 12:41:00 -04002429 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002430 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002431 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill06ef36b2017-09-09 23:32:46 -04002432 mGLState.setObjectDirty(GL_SAMPLER);
Jamie Madill9675b802013-07-19 16:36:59 -04002433}
2434
Geoff Langc1984ed2016-10-07 12:41:00 -04002435void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002436{
Geoff Langc1984ed2016-10-07 12:41:00 -04002437 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002438 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002439 QuerySamplerParameteriv(samplerObject, pname, params);
Jamie Madill06ef36b2017-09-09 23:32:46 -04002440 mGLState.setObjectDirty(GL_SAMPLER);
Geoff Langc1984ed2016-10-07 12:41:00 -04002441}
Jamie Madill9675b802013-07-19 16:36:59 -04002442
Geoff Langc1984ed2016-10-07 12:41:00 -04002443void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2444{
2445 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 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill06ef36b2017-09-09 23:32:46 -04002448 mGLState.setObjectDirty(GL_SAMPLER);
Jamie Madill9675b802013-07-19 16:36:59 -04002449}
2450
Olli Etuahof0fee072016-03-30 15:11:58 +03002451void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2452{
2453 gl::Program *programObject = getProgram(program);
Yunchao He61afff12017-03-14 15:34:03 +08002454 SetProgramParameteri(programObject, pname, value);
Olli Etuahof0fee072016-03-30 15:11:58 +03002455}
2456
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002457void Context::initRendererString()
2458{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002459 std::ostringstream rendererString;
2460 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002461 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002462 rendererString << ")";
2463
Geoff Langcec35902014-04-16 10:52:36 -04002464 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002465}
2466
Geoff Langc339c4e2016-11-29 10:37:36 -05002467void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002468{
Geoff Langc339c4e2016-11-29 10:37:36 -05002469 const Version &clientVersion = getClientVersion();
2470
2471 std::ostringstream versionString;
2472 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2473 << ANGLE_VERSION_STRING << ")";
2474 mVersionString = MakeStaticString(versionString.str());
2475
2476 std::ostringstream shadingLanguageVersionString;
2477 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2478 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2479 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2480 << ")";
2481 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002482}
2483
Geoff Langcec35902014-04-16 10:52:36 -04002484void Context::initExtensionStrings()
2485{
Geoff Langc339c4e2016-11-29 10:37:36 -05002486 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2487 std::ostringstream combinedStringStream;
2488 std::copy(strings.begin(), strings.end(),
2489 std::ostream_iterator<const char *>(combinedStringStream, " "));
2490 return MakeStaticString(combinedStringStream.str());
2491 };
2492
2493 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002494 for (const auto &extensionString : mExtensions.getStrings())
2495 {
2496 mExtensionStrings.push_back(MakeStaticString(extensionString));
2497 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002498 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002499
Bryan Bernhart58806562017-01-05 13:09:31 -08002500 const gl::Extensions &nativeExtensions = mImplementation->getNativeExtensions();
2501
Geoff Langc339c4e2016-11-29 10:37:36 -05002502 mRequestableExtensionStrings.clear();
2503 for (const auto &extensionInfo : GetExtensionInfoMap())
2504 {
2505 if (extensionInfo.second.Requestable &&
Bryan Bernhart58806562017-01-05 13:09:31 -08002506 !(mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
2507 nativeExtensions.*(extensionInfo.second.ExtensionsMember))
Geoff Langc339c4e2016-11-29 10:37:36 -05002508 {
2509 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2510 }
2511 }
2512 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002513}
2514
Geoff Langc339c4e2016-11-29 10:37:36 -05002515const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002516{
Geoff Langc339c4e2016-11-29 10:37:36 -05002517 switch (name)
2518 {
2519 case GL_VENDOR:
2520 return reinterpret_cast<const GLubyte *>("Google Inc.");
2521
2522 case GL_RENDERER:
2523 return reinterpret_cast<const GLubyte *>(mRendererString);
2524
2525 case GL_VERSION:
2526 return reinterpret_cast<const GLubyte *>(mVersionString);
2527
2528 case GL_SHADING_LANGUAGE_VERSION:
2529 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2530
2531 case GL_EXTENSIONS:
2532 return reinterpret_cast<const GLubyte *>(mExtensionString);
2533
2534 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2535 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2536
2537 default:
2538 UNREACHABLE();
2539 return nullptr;
2540 }
Geoff Langcec35902014-04-16 10:52:36 -04002541}
2542
Geoff Langc339c4e2016-11-29 10:37:36 -05002543const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002544{
Geoff Langc339c4e2016-11-29 10:37:36 -05002545 switch (name)
2546 {
2547 case GL_EXTENSIONS:
2548 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2549
2550 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2551 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2552
2553 default:
2554 UNREACHABLE();
2555 return nullptr;
2556 }
Geoff Langcec35902014-04-16 10:52:36 -04002557}
2558
2559size_t Context::getExtensionStringCount() const
2560{
2561 return mExtensionStrings.size();
2562}
2563
Geoff Langc339c4e2016-11-29 10:37:36 -05002564void Context::requestExtension(const char *name)
2565{
2566 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2567 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2568 const auto &extension = extensionInfos.at(name);
2569 ASSERT(extension.Requestable);
2570
2571 if (mExtensions.*(extension.ExtensionsMember))
2572 {
2573 // Extension already enabled
2574 return;
2575 }
2576
2577 mExtensions.*(extension.ExtensionsMember) = true;
2578 updateCaps();
2579 initExtensionStrings();
Bryan Bernhart58806562017-01-05 13:09:31 -08002580
Jamie Madill2f348d22017-06-05 10:50:59 -04002581 // Release the shader compiler so it will be re-created with the requested extensions enabled.
2582 releaseShaderCompiler();
Geoff Lang9aded172017-04-05 11:07:56 -04002583
Jamie Madill81c2e252017-09-09 23:32:46 -04002584 // Invalidate all textures and framebuffer. Some extensions make new formats renderable or
2585 // sampleable.
2586 mState.mTextures->signalAllTexturesDirty();
Geoff Lang9aded172017-04-05 11:07:56 -04002587 for (auto &zeroTexture : mZeroTextures)
2588 {
Jamie Madill81c2e252017-09-09 23:32:46 -04002589 zeroTexture.second->signalDirty();
Geoff Lang9aded172017-04-05 11:07:56 -04002590 }
2591
2592 mState.mFramebuffers->invalidateFramebufferComplenessCache();
Geoff Langc339c4e2016-11-29 10:37:36 -05002593}
2594
2595size_t Context::getRequestableExtensionStringCount() const
2596{
2597 return mRequestableExtensionStrings.size();
2598}
2599
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002600void Context::beginTransformFeedback(GLenum primitiveMode)
2601{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002602 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002603 ASSERT(transformFeedback != nullptr);
2604 ASSERT(!transformFeedback->isPaused());
2605
Jamie Madill6c1f6712017-02-14 19:08:04 -05002606 transformFeedback->begin(this, primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002607}
2608
2609bool Context::hasActiveTransformFeedback(GLuint program) const
2610{
2611 for (auto pair : mTransformFeedbackMap)
2612 {
2613 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2614 {
2615 return true;
2616 }
2617 }
2618 return false;
2619}
2620
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002621void Context::initCaps(const egl::DisplayExtensions &displayExtensions)
Geoff Lang493daf52014-07-03 13:38:44 -04002622{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002623 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002624
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002625 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002626
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002627 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002628
Geoff Langeb66a6e2016-10-31 13:06:12 -04002629 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002630 {
2631 // Disable ES3+ extensions
Jamie Madill231c7f52017-04-26 13:45:37 -04002632 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002633 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002634 mExtensions.textureNorm16 = false;
Martin Radev137032d2017-07-13 10:11:12 +03002635 mExtensions.multiview = false;
2636 mExtensions.maxViews = 1u;
Geoff Lang493daf52014-07-03 13:38:44 -04002637 }
2638
Geoff Langeb66a6e2016-10-31 13:06:12 -04002639 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002640 {
2641 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
Jamie Madill231c7f52017-04-26 13:45:37 -04002642 // mExtensions.sRGB = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002643 }
2644
Jamie Madill00ed7a12016-05-19 13:13:38 -04002645 // Some extensions are always available because they are implemented in the GL layer.
Jamie Madill231c7f52017-04-26 13:45:37 -04002646 mExtensions.bindUniformLocation = true;
2647 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002648 mExtensions.bindGeneratesResource = true;
Geoff Langfeb8c682017-02-13 16:07:35 -05002649 mExtensions.clientArrays = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002650 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002651
2652 // Enable the no error extension if the context was created with the flag.
2653 mExtensions.noError = mSkipValidation;
2654
Corentin Wallezccab69d2017-01-27 16:57:15 -05002655 // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
Corentin Wallezc295e512017-01-27 17:47:50 -05002656 mExtensions.surfacelessContext = displayExtensions.surfacelessContext;
Corentin Wallezccab69d2017-01-27 16:57:15 -05002657
Geoff Lang70d0f492015-12-10 17:45:46 -05002658 // Explicitly enable GL_KHR_debug
2659 mExtensions.debug = true;
2660 mExtensions.maxDebugMessageLength = 1024;
2661 mExtensions.maxDebugLoggedMessages = 1024;
2662 mExtensions.maxDebugGroupStackDepth = 1024;
2663 mExtensions.maxLabelLength = 1024;
2664
Geoff Langff5b2d52016-09-07 11:32:23 -04002665 // Explicitly enable GL_ANGLE_robust_client_memory
2666 mExtensions.robustClientMemory = true;
2667
Jamie Madille08a1d32017-03-07 17:24:06 -05002668 // Determine robust resource init availability from EGL.
2669 mExtensions.robustResourceInitialization =
Jamie Madill948bbe52017-06-01 13:10:42 -04002670 egl::Display::GetClientExtensions().displayRobustResourceInitialization;
Jamie Madille08a1d32017-03-07 17:24:06 -05002671
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08002672 // mExtensions.robustBufferAccessBehavior is true only if robust access is true and the backend
2673 // supports it.
2674 mExtensions.robustBufferAccessBehavior =
2675 mRobustAccess && mExtensions.robustBufferAccessBehavior;
2676
Jamie Madillc43be722017-07-13 16:22:14 -04002677 // Enable the cache control query unconditionally.
2678 mExtensions.programCacheControl = true;
2679
Geoff Lang301d1612014-07-09 10:34:37 -04002680 // Apply implementation limits
Jamie Madill0f80ed82017-09-19 00:24:56 -04002681 LimitCap(&mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002682
Jamie Madill0f80ed82017-09-19 00:24:56 -04002683 if (getClientVersion() < ES_3_1)
2684 {
2685 mCaps.maxVertexAttribBindings = mCaps.maxVertexAttributes;
2686 }
2687 else
2688 {
2689 LimitCap(&mCaps.maxVertexAttribBindings, MAX_VERTEX_ATTRIB_BINDINGS);
2690 }
Geoff Lang301d1612014-07-09 10:34:37 -04002691
Jamie Madill0f80ed82017-09-19 00:24:56 -04002692 LimitCap(&mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2693 LimitCap(&mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2694 LimitCap(&mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2695
2696 // Limit textures as well, so we can use fast bitsets with texture bindings.
2697 LimitCap(&mCaps.maxCombinedTextureImageUnits, IMPLEMENTATION_MAX_ACTIVE_TEXTURES);
2698 LimitCap(&mCaps.maxVertexTextureImageUnits, IMPLEMENTATION_MAX_ACTIVE_TEXTURES / 2);
2699 LimitCap(&mCaps.maxTextureImageUnits, IMPLEMENTATION_MAX_ACTIVE_TEXTURES / 2);
Geoff Lang3a61c322014-07-10 13:01:54 -04002700
Geoff Langc287ea62016-09-16 14:46:51 -04002701 // WebGL compatibility
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002702 mExtensions.webglCompatibility = mWebGLContext;
Geoff Langc287ea62016-09-16 14:46:51 -04002703 for (const auto &extensionInfo : GetExtensionInfoMap())
2704 {
2705 // If this context is for WebGL, disable all enableable extensions
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002706 if (mWebGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002707 {
2708 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2709 }
2710 }
2711
2712 // Generate texture caps
2713 updateCaps();
2714}
2715
2716void Context::updateCaps()
2717{
Geoff Lang900013c2014-07-07 11:32:19 -04002718 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002719 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002720
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002721 for (auto capsIt : mImplementation->getNativeTextureCaps())
Geoff Lang493daf52014-07-03 13:38:44 -04002722 {
Geoff Langca271392017-04-05 12:30:00 -04002723 GLenum sizedInternalFormat = capsIt.first;
Jamie Madill231c7f52017-04-26 13:45:37 -04002724 TextureCaps formatCaps = capsIt.second;
Geoff Lang493daf52014-07-03 13:38:44 -04002725
Geoff Langca271392017-04-05 12:30:00 -04002726 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002727
Geoff Lang0d8b7242015-09-09 14:56:53 -04002728 // Update the format caps based on the client version and extensions.
2729 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2730 // ES3.
2731 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002732 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002733 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002734 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002735 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002736 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002737
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002738 // OpenGL ES does not support multisampling with non-rendererable formats
2739 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
Olli Etuaho50c562d2017-06-06 14:43:30 +03002740 if (!formatCaps.renderable ||
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002741 (getClientVersion() < ES_3_1 &&
2742 (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
Geoff Lang493daf52014-07-03 13:38:44 -04002743 {
Geoff Langd87878e2014-09-19 15:42:59 -04002744 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002745 }
Olli Etuaho50c562d2017-06-06 14:43:30 +03002746 else
2747 {
2748 // We may have limited the max samples for some required renderbuffer formats due to
2749 // non-conformant formats. In this case MAX_SAMPLES needs to be lowered accordingly.
2750 GLuint formatMaxSamples = formatCaps.getMaxSamples();
2751
2752 // GLES 3.0.5 section 4.4.2.2: "Implementations must support creation of renderbuffers
2753 // in these required formats with up to the value of MAX_SAMPLES multisamples, with the
2754 // exception of signed and unsigned integer formats."
2755 if (formatInfo.componentType != GL_INT && formatInfo.componentType != GL_UNSIGNED_INT &&
2756 formatInfo.isRequiredRenderbufferFormat(getClientVersion()))
2757 {
2758 ASSERT(getClientVersion() < ES_3_0 || formatMaxSamples >= 4);
2759 mCaps.maxSamples = std::min(mCaps.maxSamples, formatMaxSamples);
2760 }
2761
2762 // Handle GLES 3.1 MAX_*_SAMPLES values similarly to MAX_SAMPLES.
2763 if (getClientVersion() >= ES_3_1)
2764 {
2765 // GLES 3.1 section 9.2.5: "Implementations must support creation of renderbuffers
2766 // in these required formats with up to the value of MAX_SAMPLES multisamples, with
2767 // the exception that the signed and unsigned integer formats are required only to
2768 // support creation of renderbuffers with up to the value of MAX_INTEGER_SAMPLES
2769 // multisamples, which must be at least one."
2770 if (formatInfo.componentType == GL_INT ||
2771 formatInfo.componentType == GL_UNSIGNED_INT)
2772 {
2773 mCaps.maxIntegerSamples = std::min(mCaps.maxIntegerSamples, formatMaxSamples);
2774 }
2775
2776 // GLES 3.1 section 19.3.1.
2777 if (formatCaps.texturable)
2778 {
2779 if (formatInfo.depthBits > 0)
2780 {
2781 mCaps.maxDepthTextureSamples =
2782 std::min(mCaps.maxDepthTextureSamples, formatMaxSamples);
2783 }
2784 else if (formatInfo.redBits > 0)
2785 {
2786 mCaps.maxColorTextureSamples =
2787 std::min(mCaps.maxColorTextureSamples, formatMaxSamples);
2788 }
2789 }
2790 }
2791 }
Geoff Langd87878e2014-09-19 15:42:59 -04002792
2793 if (formatCaps.texturable && formatInfo.compressed)
2794 {
Geoff Langca271392017-04-05 12:30:00 -04002795 mCaps.compressedTextureFormats.push_back(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002796 }
2797
Geoff Langca271392017-04-05 12:30:00 -04002798 mTextureCaps.insert(sizedInternalFormat, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002799 }
Jamie Madill32447362017-06-28 14:53:52 -04002800
2801 // If program binary is disabled, blank out the memory cache pointer.
2802 if (!mImplementation->getNativeExtensions().getProgramBinary)
2803 {
2804 mMemoryProgramCache = nullptr;
2805 }
Geoff Lang493daf52014-07-03 13:38:44 -04002806}
2807
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002808void Context::initWorkarounds()
2809{
Jamie Madill761b02c2017-06-23 16:27:06 -04002810 // Apply back-end workarounds.
2811 mImplementation->applyNativeWorkarounds(&mWorkarounds);
2812
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002813 // Lose the context upon out of memory error if the application is
2814 // expecting to watch for those events.
2815 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2816}
2817
Jamie Madill1b94d432015-08-07 13:23:23 -04002818void Context::syncRendererState()
2819{
Jamie Madill7d1f5c62017-09-02 15:32:15 -04002820 mGLState.syncDirtyObjects(this);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002821 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
Jamie Madillfe548342017-06-19 11:13:24 -04002822 mImplementation->syncState(this, dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002823 mGLState.clearDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -04002824}
2825
Jamie Madillad9f24e2016-02-12 09:27:24 -05002826void Context::syncRendererState(const State::DirtyBits &bitMask,
2827 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002828{
Jamie Madill7d1f5c62017-09-02 15:32:15 -04002829 mGLState.syncDirtyObjects(this, objectMask);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002830 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
Jamie Madillfe548342017-06-19 11:13:24 -04002831 mImplementation->syncState(this, dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002832 mGLState.clearDirtyBits(dirtyBits);
Jamie Madill1b94d432015-08-07 13:23:23 -04002833}
Jamie Madillc29968b2016-01-20 11:17:23 -05002834
2835void Context::blitFramebuffer(GLint srcX0,
2836 GLint srcY0,
2837 GLint srcX1,
2838 GLint srcY1,
2839 GLint dstX0,
2840 GLint dstY0,
2841 GLint dstX1,
2842 GLint dstY1,
2843 GLbitfield mask,
2844 GLenum filter)
2845{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002846 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002847 ASSERT(drawFramebuffer);
2848
2849 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2850 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2851
Jamie Madillad9f24e2016-02-12 09:27:24 -05002852 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002853
Jamie Madillc564c072017-06-01 12:45:42 -04002854 handleError(drawFramebuffer->blit(this, srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002855}
Jamie Madillc29968b2016-01-20 11:17:23 -05002856
2857void Context::clear(GLbitfield mask)
2858{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002859 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002860 handleError(mGLState.getDrawFramebuffer()->clear(this, mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002861}
2862
2863void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2864{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002865 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002866 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002867}
2868
2869void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2870{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002871 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002872 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002873}
2874
2875void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2876{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002877 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002878 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002879}
2880
2881void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2882{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002883 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002884 ASSERT(framebufferObject);
2885
2886 // If a buffer is not present, the clear has no effect
2887 if (framebufferObject->getDepthbuffer() == nullptr &&
2888 framebufferObject->getStencilbuffer() == nullptr)
2889 {
2890 return;
2891 }
2892
Jamie Madillad9f24e2016-02-12 09:27:24 -05002893 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002894 handleError(framebufferObject->clearBufferfi(this, buffer, drawbuffer, depth, stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002895}
2896
2897void Context::readPixels(GLint x,
2898 GLint y,
2899 GLsizei width,
2900 GLsizei height,
2901 GLenum format,
2902 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002903 void *pixels)
Jamie Madillc29968b2016-01-20 11:17:23 -05002904{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002905 if (width == 0 || height == 0)
2906 {
2907 return;
2908 }
2909
Jamie Madillad9f24e2016-02-12 09:27:24 -05002910 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002911
Jamie Madillb6664922017-07-25 12:55:04 -04002912 Framebuffer *readFBO = mGLState.getReadFramebuffer();
2913 ASSERT(readFBO);
Jamie Madillc29968b2016-01-20 11:17:23 -05002914
2915 Rectangle area(x, y, width, height);
Jamie Madillb6664922017-07-25 12:55:04 -04002916 handleError(readFBO->readPixels(this, area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002917}
2918
2919void Context::copyTexImage2D(GLenum target,
2920 GLint level,
2921 GLenum internalformat,
2922 GLint x,
2923 GLint y,
2924 GLsizei width,
2925 GLsizei height,
2926 GLint border)
2927{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002928 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002929 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002930
Jamie Madillc29968b2016-01-20 11:17:23 -05002931 Rectangle sourceArea(x, y, width, height);
2932
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002933 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002934 Texture *texture =
2935 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002936 handleError(texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002937}
2938
2939void Context::copyTexSubImage2D(GLenum target,
2940 GLint level,
2941 GLint xoffset,
2942 GLint yoffset,
2943 GLint x,
2944 GLint y,
2945 GLsizei width,
2946 GLsizei height)
2947{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002948 if (width == 0 || height == 0)
2949 {
2950 return;
2951 }
2952
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002953 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002954 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002955
Jamie Madillc29968b2016-01-20 11:17:23 -05002956 Offset destOffset(xoffset, yoffset, 0);
2957 Rectangle sourceArea(x, y, width, height);
2958
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002959 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002960 Texture *texture =
2961 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002962 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002963}
2964
2965void Context::copyTexSubImage3D(GLenum target,
2966 GLint level,
2967 GLint xoffset,
2968 GLint yoffset,
2969 GLint zoffset,
2970 GLint x,
2971 GLint y,
2972 GLsizei width,
2973 GLsizei height)
2974{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002975 if (width == 0 || height == 0)
2976 {
2977 return;
2978 }
2979
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002980 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002981 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002982
Jamie Madillc29968b2016-01-20 11:17:23 -05002983 Offset destOffset(xoffset, yoffset, zoffset);
2984 Rectangle sourceArea(x, y, width, height);
2985
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002986 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002987 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002988 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002989}
2990
2991void Context::framebufferTexture2D(GLenum target,
2992 GLenum attachment,
2993 GLenum textarget,
2994 GLuint texture,
2995 GLint level)
2996{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002997 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002998 ASSERT(framebuffer);
2999
3000 if (texture != 0)
3001 {
3002 Texture *textureObj = getTexture(texture);
3003
3004 ImageIndex index = ImageIndex::MakeInvalid();
3005
3006 if (textarget == GL_TEXTURE_2D)
3007 {
3008 index = ImageIndex::Make2D(level);
3009 }
Corentin Wallez13c0dd42017-07-04 18:27:01 -04003010 else if (textarget == GL_TEXTURE_RECTANGLE_ANGLE)
3011 {
3012 index = ImageIndex::MakeRectangle(level);
3013 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08003014 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
3015 {
3016 ASSERT(level == 0);
3017 index = ImageIndex::Make2DMultisample();
3018 }
Jamie Madillc29968b2016-01-20 11:17:23 -05003019 else
3020 {
3021 ASSERT(IsCubeMapTextureTarget(textarget));
3022 index = ImageIndex::MakeCube(textarget, level);
3023 }
3024
Jamie Madilla02315b2017-02-23 14:14:47 -05003025 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
Jamie Madillc29968b2016-01-20 11:17:23 -05003026 }
3027 else
3028 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003029 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003030 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003031
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003032 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003033}
3034
3035void Context::framebufferRenderbuffer(GLenum target,
3036 GLenum attachment,
3037 GLenum renderbuffertarget,
3038 GLuint renderbuffer)
3039{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003040 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003041 ASSERT(framebuffer);
3042
3043 if (renderbuffer != 0)
3044 {
3045 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
Jamie Madilla02315b2017-02-23 14:14:47 -05003046
3047 framebuffer->setAttachment(this, GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
Jamie Madillc29968b2016-01-20 11:17:23 -05003048 renderbufferObject);
3049 }
3050 else
3051 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003052 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003053 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003054
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003055 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003056}
3057
3058void Context::framebufferTextureLayer(GLenum target,
3059 GLenum attachment,
3060 GLuint texture,
3061 GLint level,
3062 GLint layer)
3063{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003064 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003065 ASSERT(framebuffer);
3066
3067 if (texture != 0)
3068 {
3069 Texture *textureObject = getTexture(texture);
3070
3071 ImageIndex index = ImageIndex::MakeInvalid();
3072
3073 if (textureObject->getTarget() == GL_TEXTURE_3D)
3074 {
3075 index = ImageIndex::Make3D(level, layer);
3076 }
3077 else
3078 {
3079 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
3080 index = ImageIndex::Make2DArray(level, layer);
3081 }
3082
Jamie Madilla02315b2017-02-23 14:14:47 -05003083 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObject);
Jamie Madillc29968b2016-01-20 11:17:23 -05003084 }
3085 else
3086 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003087 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003088 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003089
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003090 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003091}
3092
Martin Radev137032d2017-07-13 10:11:12 +03003093void Context::framebufferTextureMultiviewLayeredANGLE(GLenum target,
3094 GLenum attachment,
3095 GLuint texture,
3096 GLint level,
3097 GLint baseViewIndex,
3098 GLsizei numViews)
3099{
Martin Radev82ef7742017-08-08 17:44:58 +03003100 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
3101 ASSERT(framebuffer);
3102
3103 if (texture != 0)
3104 {
3105 Texture *textureObj = getTexture(texture);
3106
Martin Radev18b75ba2017-08-15 15:50:40 +03003107 ImageIndex index = ImageIndex::Make2DArrayRange(level, baseViewIndex, numViews);
Martin Radev82ef7742017-08-08 17:44:58 +03003108 framebuffer->setAttachmentMultiviewLayered(this, GL_TEXTURE, attachment, index, textureObj,
3109 numViews, baseViewIndex);
3110 }
3111 else
3112 {
3113 framebuffer->resetAttachment(this, attachment);
3114 }
3115
3116 mGLState.setObjectDirty(target);
Martin Radev137032d2017-07-13 10:11:12 +03003117}
3118
3119void Context::framebufferTextureMultiviewSideBySideANGLE(GLenum target,
3120 GLenum attachment,
3121 GLuint texture,
3122 GLint level,
3123 GLsizei numViews,
3124 const GLint *viewportOffsets)
3125{
Martin Radev5dae57b2017-07-14 16:15:55 +03003126 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
3127 ASSERT(framebuffer);
3128
3129 if (texture != 0)
3130 {
3131 Texture *textureObj = getTexture(texture);
3132
3133 ImageIndex index = ImageIndex::Make2D(level);
3134 framebuffer->setAttachmentMultiviewSideBySide(this, GL_TEXTURE, attachment, index,
3135 textureObj, numViews, viewportOffsets);
3136 }
3137 else
3138 {
3139 framebuffer->resetAttachment(this, attachment);
3140 }
3141
3142 mGLState.setObjectDirty(target);
Martin Radev137032d2017-07-13 10:11:12 +03003143}
3144
Jamie Madillc29968b2016-01-20 11:17:23 -05003145void Context::drawBuffers(GLsizei n, const GLenum *bufs)
3146{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003147 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003148 ASSERT(framebuffer);
3149 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003150 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003151}
3152
3153void Context::readBuffer(GLenum mode)
3154{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003155 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003156 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003157 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003158}
3159
3160void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
3161{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003162 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003163 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003164
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003165 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003166 ASSERT(framebuffer);
3167
3168 // The specification isn't clear what should be done when the framebuffer isn't complete.
3169 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill4928b7c2017-06-20 12:57:39 -04003170 handleError(framebuffer->discard(this, numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003171}
3172
3173void Context::invalidateFramebuffer(GLenum target,
3174 GLsizei numAttachments,
3175 const GLenum *attachments)
3176{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003177 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003178 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003179
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003180 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003181 ASSERT(framebuffer);
3182
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003183 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003184 {
Jamie Madill437fa652016-05-03 15:13:24 -04003185 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003186 }
Jamie Madill437fa652016-05-03 15:13:24 -04003187
Jamie Madill4928b7c2017-06-20 12:57:39 -04003188 handleError(framebuffer->invalidate(this, numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003189}
3190
3191void Context::invalidateSubFramebuffer(GLenum target,
3192 GLsizei numAttachments,
3193 const GLenum *attachments,
3194 GLint x,
3195 GLint y,
3196 GLsizei width,
3197 GLsizei height)
3198{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003199 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003200 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003201
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003202 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003203 ASSERT(framebuffer);
3204
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003205 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003206 {
Jamie Madill437fa652016-05-03 15:13:24 -04003207 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003208 }
Jamie Madill437fa652016-05-03 15:13:24 -04003209
3210 Rectangle area(x, y, width, height);
Jamie Madill4928b7c2017-06-20 12:57:39 -04003211 handleError(framebuffer->invalidateSub(this, numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05003212}
3213
Jamie Madill73a84962016-02-12 09:27:23 -05003214void Context::texImage2D(GLenum target,
3215 GLint level,
3216 GLint internalformat,
3217 GLsizei width,
3218 GLsizei height,
3219 GLint border,
3220 GLenum format,
3221 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003222 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003223{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003224 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003225
3226 Extents size(width, height, 1);
3227 Texture *texture =
3228 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003229 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3230 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003231}
3232
3233void Context::texImage3D(GLenum target,
3234 GLint level,
3235 GLint internalformat,
3236 GLsizei width,
3237 GLsizei height,
3238 GLsizei depth,
3239 GLint border,
3240 GLenum format,
3241 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003242 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003243{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003244 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003245
3246 Extents size(width, height, depth);
3247 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003248 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3249 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003250}
3251
3252void Context::texSubImage2D(GLenum target,
3253 GLint level,
3254 GLint xoffset,
3255 GLint yoffset,
3256 GLsizei width,
3257 GLsizei height,
3258 GLenum format,
3259 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003260 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003261{
3262 // Zero sized uploads are valid but no-ops
3263 if (width == 0 || height == 0)
3264 {
3265 return;
3266 }
3267
Jamie Madillad9f24e2016-02-12 09:27:24 -05003268 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003269
3270 Box area(xoffset, yoffset, 0, width, height, 1);
3271 Texture *texture =
3272 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003273 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3274 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003275}
3276
3277void Context::texSubImage3D(GLenum target,
3278 GLint level,
3279 GLint xoffset,
3280 GLint yoffset,
3281 GLint zoffset,
3282 GLsizei width,
3283 GLsizei height,
3284 GLsizei depth,
3285 GLenum format,
3286 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003287 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003288{
3289 // Zero sized uploads are valid but no-ops
3290 if (width == 0 || height == 0 || depth == 0)
3291 {
3292 return;
3293 }
3294
Jamie Madillad9f24e2016-02-12 09:27:24 -05003295 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003296
3297 Box area(xoffset, yoffset, zoffset, width, height, depth);
3298 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003299 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3300 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003301}
3302
3303void Context::compressedTexImage2D(GLenum target,
3304 GLint level,
3305 GLenum internalformat,
3306 GLsizei width,
3307 GLsizei height,
3308 GLint border,
3309 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003310 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003311{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003312 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003313
3314 Extents size(width, height, 1);
3315 Texture *texture =
3316 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003317 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003318 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003319 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003320}
3321
3322void Context::compressedTexImage3D(GLenum target,
3323 GLint level,
3324 GLenum internalformat,
3325 GLsizei width,
3326 GLsizei height,
3327 GLsizei depth,
3328 GLint border,
3329 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003330 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003331{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003332 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003333
3334 Extents size(width, height, depth);
3335 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003336 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003337 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003338 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003339}
3340
3341void Context::compressedTexSubImage2D(GLenum target,
3342 GLint level,
3343 GLint xoffset,
3344 GLint yoffset,
3345 GLsizei width,
3346 GLsizei height,
3347 GLenum format,
3348 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003349 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003350{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003351 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003352
3353 Box area(xoffset, yoffset, 0, width, height, 1);
3354 Texture *texture =
3355 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003356 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003357 format, imageSize,
3358 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003359}
3360
3361void Context::compressedTexSubImage3D(GLenum target,
3362 GLint level,
3363 GLint xoffset,
3364 GLint yoffset,
3365 GLint zoffset,
3366 GLsizei width,
3367 GLsizei height,
3368 GLsizei depth,
3369 GLenum format,
3370 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003371 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003372{
3373 // Zero sized uploads are valid but no-ops
3374 if (width == 0 || height == 0)
3375 {
3376 return;
3377 }
3378
Jamie Madillad9f24e2016-02-12 09:27:24 -05003379 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003380
3381 Box area(xoffset, yoffset, zoffset, width, height, depth);
3382 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003383 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003384 format, imageSize,
3385 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003386}
3387
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003388void Context::generateMipmap(GLenum target)
3389{
3390 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003391 handleError(texture->generateMipmap(this));
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003392}
3393
Geoff Lang97073d12016-04-20 10:42:34 -07003394void Context::copyTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003395 GLint sourceLevel,
3396 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003397 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003398 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003399 GLint internalFormat,
3400 GLenum destType,
3401 GLboolean unpackFlipY,
3402 GLboolean unpackPremultiplyAlpha,
3403 GLboolean unpackUnmultiplyAlpha)
3404{
3405 syncStateForTexImage();
3406
3407 gl::Texture *sourceTexture = getTexture(sourceId);
3408 gl::Texture *destTexture = getTexture(destId);
Geoff Langfc72a072017-03-24 14:52:39 -04003409 handleError(destTexture->copyTexture(
3410 this, destTarget, destLevel, internalFormat, destType, sourceLevel, unpackFlipY == GL_TRUE,
3411 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003412}
3413
3414void Context::copySubTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003415 GLint sourceLevel,
3416 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003417 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003418 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003419 GLint xoffset,
3420 GLint yoffset,
3421 GLint x,
3422 GLint y,
3423 GLsizei width,
3424 GLsizei height,
3425 GLboolean unpackFlipY,
3426 GLboolean unpackPremultiplyAlpha,
3427 GLboolean unpackUnmultiplyAlpha)
3428{
3429 // Zero sized copies are valid but no-ops
3430 if (width == 0 || height == 0)
3431 {
3432 return;
3433 }
3434
3435 syncStateForTexImage();
3436
3437 gl::Texture *sourceTexture = getTexture(sourceId);
3438 gl::Texture *destTexture = getTexture(destId);
3439 Offset offset(xoffset, yoffset, 0);
3440 Rectangle area(x, y, width, height);
Geoff Langfc72a072017-03-24 14:52:39 -04003441 handleError(destTexture->copySubTexture(
3442 this, destTarget, destLevel, offset, sourceLevel, area, unpackFlipY == GL_TRUE,
3443 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003444}
3445
Geoff Lang47110bf2016-04-20 11:13:22 -07003446void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3447{
3448 syncStateForTexImage();
3449
3450 gl::Texture *sourceTexture = getTexture(sourceId);
3451 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003452 handleError(destTexture->copyCompressedTexture(this, sourceTexture));
Geoff Lang47110bf2016-04-20 11:13:22 -07003453}
3454
Geoff Lang496c02d2016-10-20 11:38:11 -07003455void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003456{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003457 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003458 ASSERT(buffer);
3459
Geoff Lang496c02d2016-10-20 11:38:11 -07003460 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003461}
3462
Jamie Madill876429b2017-04-20 15:46:24 -04003463void *Context::mapBuffer(GLenum target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003464{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003465 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003466 ASSERT(buffer);
3467
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003468 Error error = buffer->map(this, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003469 if (error.isError())
3470 {
Jamie Madill437fa652016-05-03 15:13:24 -04003471 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003472 return nullptr;
3473 }
3474
3475 return buffer->getMapPointer();
3476}
3477
3478GLboolean Context::unmapBuffer(GLenum target)
3479{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003480 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003481 ASSERT(buffer);
3482
3483 GLboolean result;
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003484 Error error = buffer->unmap(this, &result);
Olli Etuaho4f667482016-03-30 15:56:35 +03003485 if (error.isError())
3486 {
Jamie Madill437fa652016-05-03 15:13:24 -04003487 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003488 return GL_FALSE;
3489 }
3490
3491 return result;
3492}
3493
Jamie Madill876429b2017-04-20 15:46:24 -04003494void *Context::mapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003495{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003496 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003497 ASSERT(buffer);
3498
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003499 Error error = buffer->mapRange(this, offset, length, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003500 if (error.isError())
3501 {
Jamie Madill437fa652016-05-03 15:13:24 -04003502 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003503 return nullptr;
3504 }
3505
3506 return buffer->getMapPointer();
3507}
3508
3509void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3510{
3511 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3512}
3513
Jamie Madillad9f24e2016-02-12 09:27:24 -05003514void Context::syncStateForReadPixels()
3515{
3516 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3517}
3518
3519void Context::syncStateForTexImage()
3520{
3521 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3522}
3523
3524void Context::syncStateForClear()
3525{
3526 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3527}
3528
3529void Context::syncStateForBlit()
3530{
3531 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3532}
3533
Jamie Madillc20ab272016-06-09 07:20:46 -07003534void Context::activeTexture(GLenum texture)
3535{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003536 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003537}
3538
Jamie Madill876429b2017-04-20 15:46:24 -04003539void Context::blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003540{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003541 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003542}
3543
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003544void Context::blendEquation(GLenum mode)
3545{
3546 mGLState.setBlendEquation(mode, mode);
3547}
3548
Jamie Madillc20ab272016-06-09 07:20:46 -07003549void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3550{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003551 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003552}
3553
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003554void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3555{
3556 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3557}
3558
Jamie Madillc20ab272016-06-09 07:20:46 -07003559void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3560{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003561 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003562}
3563
Jamie Madill876429b2017-04-20 15:46:24 -04003564void Context::clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003565{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003566 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003567}
3568
Jamie Madill876429b2017-04-20 15:46:24 -04003569void Context::clearDepthf(GLfloat depth)
Jamie Madillc20ab272016-06-09 07:20:46 -07003570{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003571 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003572}
3573
3574void Context::clearStencil(GLint s)
3575{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003576 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003577}
3578
3579void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3580{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003581 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003582}
3583
3584void Context::cullFace(GLenum mode)
3585{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003586 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003587}
3588
3589void Context::depthFunc(GLenum func)
3590{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003591 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003592}
3593
3594void Context::depthMask(GLboolean flag)
3595{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003596 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003597}
3598
Jamie Madill876429b2017-04-20 15:46:24 -04003599void Context::depthRangef(GLfloat zNear, GLfloat zFar)
Jamie Madillc20ab272016-06-09 07:20:46 -07003600{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003601 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003602}
3603
3604void Context::disable(GLenum cap)
3605{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003606 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003607}
3608
3609void Context::disableVertexAttribArray(GLuint index)
3610{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003611 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003612}
3613
3614void Context::enable(GLenum cap)
3615{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003616 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003617}
3618
3619void Context::enableVertexAttribArray(GLuint index)
3620{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003621 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003622}
3623
3624void Context::frontFace(GLenum mode)
3625{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003626 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003627}
3628
3629void Context::hint(GLenum target, GLenum mode)
3630{
3631 switch (target)
3632 {
3633 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003634 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003635 break;
3636
3637 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003638 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003639 break;
3640
3641 default:
3642 UNREACHABLE();
3643 return;
3644 }
3645}
3646
3647void Context::lineWidth(GLfloat width)
3648{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003649 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003650}
3651
3652void Context::pixelStorei(GLenum pname, GLint param)
3653{
3654 switch (pname)
3655 {
3656 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003657 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003658 break;
3659
3660 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003661 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003662 break;
3663
3664 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003665 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003666 break;
3667
3668 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003669 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003670 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003671 break;
3672
3673 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003674 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003675 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003676 break;
3677
3678 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003679 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003680 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003681 break;
3682
3683 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003684 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003685 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003686 break;
3687
3688 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003689 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003690 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003691 break;
3692
3693 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003694 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003695 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003696 break;
3697
3698 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003699 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003700 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003701 break;
3702
3703 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003704 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003705 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003706 break;
3707
3708 default:
3709 UNREACHABLE();
3710 return;
3711 }
3712}
3713
3714void Context::polygonOffset(GLfloat factor, GLfloat units)
3715{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003716 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003717}
3718
Jamie Madill876429b2017-04-20 15:46:24 -04003719void Context::sampleCoverage(GLfloat value, GLboolean invert)
Jamie Madillc20ab272016-06-09 07:20:46 -07003720{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003721 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003722}
3723
3724void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3725{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003726 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003727}
3728
3729void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3730{
3731 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3732 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003733 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003734 }
3735
3736 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3737 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003738 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003739 }
3740}
3741
3742void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3743{
3744 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3745 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003746 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003747 }
3748
3749 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3750 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003751 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003752 }
3753}
3754
3755void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3756{
3757 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3758 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003759 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003760 }
3761
3762 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3763 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003764 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003765 }
3766}
3767
3768void Context::vertexAttrib1f(GLuint index, GLfloat x)
3769{
3770 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003771 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003772}
3773
3774void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3775{
3776 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003777 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003778}
3779
3780void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3781{
3782 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003783 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003784}
3785
3786void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3787{
3788 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003789 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003790}
3791
3792void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3793{
3794 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003795 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003796}
3797
3798void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3799{
3800 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003801 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003802}
3803
3804void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3805{
3806 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003807 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003808}
3809
3810void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3811{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003812 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003813}
3814
3815void Context::vertexAttribPointer(GLuint index,
3816 GLint size,
3817 GLenum type,
3818 GLboolean normalized,
3819 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003820 const void *ptr)
Jamie Madillc20ab272016-06-09 07:20:46 -07003821{
Shaodde78e82017-05-22 14:13:27 +08003822 mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size,
3823 type, normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003824}
3825
Shao80957d92017-02-20 21:25:59 +08003826void Context::vertexAttribFormat(GLuint attribIndex,
3827 GLint size,
3828 GLenum type,
3829 GLboolean normalized,
3830 GLuint relativeOffset)
3831{
3832 mGLState.setVertexAttribFormat(attribIndex, size, type, normalized == GL_TRUE, false,
3833 relativeOffset);
3834}
3835
3836void Context::vertexAttribIFormat(GLuint attribIndex,
3837 GLint size,
3838 GLenum type,
3839 GLuint relativeOffset)
3840{
3841 mGLState.setVertexAttribFormat(attribIndex, size, type, false, true, relativeOffset);
3842}
3843
3844void Context::vertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
3845{
Shaodde78e82017-05-22 14:13:27 +08003846 mGLState.setVertexAttribBinding(this, attribIndex, bindingIndex);
Shao80957d92017-02-20 21:25:59 +08003847}
3848
3849void Context::setVertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
3850{
3851 mGLState.setVertexBindingDivisor(bindingIndex, divisor);
3852}
3853
Jamie Madillc20ab272016-06-09 07:20:46 -07003854void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3855{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003856 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003857}
3858
3859void Context::vertexAttribIPointer(GLuint index,
3860 GLint size,
3861 GLenum type,
3862 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003863 const void *pointer)
Jamie Madillc20ab272016-06-09 07:20:46 -07003864{
Shaodde78e82017-05-22 14:13:27 +08003865 mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size,
3866 type, false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003867}
3868
3869void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3870{
3871 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003872 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003873}
3874
3875void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3876{
3877 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003878 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003879}
3880
3881void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3882{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003883 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003884}
3885
3886void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3887{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003888 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003889}
3890
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003891void Context::getVertexAttribiv(GLuint index, GLenum pname, GLint *params)
3892{
3893 const VertexAttribCurrentValueData &currentValues =
3894 getGLState().getVertexAttribCurrentValue(index);
3895 const VertexArray *vao = getGLState().getVertexArray();
3896 QueryVertexAttribiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3897 currentValues, pname, params);
3898}
3899
3900void Context::getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
3901{
3902 const VertexAttribCurrentValueData &currentValues =
3903 getGLState().getVertexAttribCurrentValue(index);
3904 const VertexArray *vao = getGLState().getVertexArray();
3905 QueryVertexAttribfv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3906 currentValues, pname, params);
3907}
3908
3909void Context::getVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
3910{
3911 const VertexAttribCurrentValueData &currentValues =
3912 getGLState().getVertexAttribCurrentValue(index);
3913 const VertexArray *vao = getGLState().getVertexArray();
3914 QueryVertexAttribIiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3915 currentValues, pname, params);
3916}
3917
3918void Context::getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
3919{
3920 const VertexAttribCurrentValueData &currentValues =
3921 getGLState().getVertexAttribCurrentValue(index);
3922 const VertexArray *vao = getGLState().getVertexArray();
3923 QueryVertexAttribIuiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3924 currentValues, pname, params);
3925}
3926
Jamie Madill876429b2017-04-20 15:46:24 -04003927void Context::getVertexAttribPointerv(GLuint index, GLenum pname, void **pointer)
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003928{
3929 const VertexAttribute &attrib = getGLState().getVertexArray()->getVertexAttribute(index);
3930 QueryVertexAttribPointerv(attrib, pname, pointer);
3931}
3932
Jamie Madillc20ab272016-06-09 07:20:46 -07003933void Context::debugMessageControl(GLenum source,
3934 GLenum type,
3935 GLenum severity,
3936 GLsizei count,
3937 const GLuint *ids,
3938 GLboolean enabled)
3939{
3940 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003941 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3942 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003943}
3944
3945void Context::debugMessageInsert(GLenum source,
3946 GLenum type,
3947 GLuint id,
3948 GLenum severity,
3949 GLsizei length,
3950 const GLchar *buf)
3951{
3952 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003953 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003954}
3955
3956void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3957{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003958 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003959}
3960
3961GLuint Context::getDebugMessageLog(GLuint count,
3962 GLsizei bufSize,
3963 GLenum *sources,
3964 GLenum *types,
3965 GLuint *ids,
3966 GLenum *severities,
3967 GLsizei *lengths,
3968 GLchar *messageLog)
3969{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003970 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3971 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003972}
3973
3974void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3975{
3976 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003977 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003978}
3979
3980void Context::popDebugGroup()
3981{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003982 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003983}
3984
Jamie Madill876429b2017-04-20 15:46:24 -04003985void Context::bufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage)
Jamie Madill29639852016-09-02 15:00:09 -04003986{
3987 Buffer *buffer = mGLState.getTargetBuffer(target);
3988 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003989 handleError(buffer->bufferData(this, target, data, size, usage));
Jamie Madill29639852016-09-02 15:00:09 -04003990}
3991
Jamie Madill876429b2017-04-20 15:46:24 -04003992void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04003993{
3994 if (data == nullptr)
3995 {
3996 return;
3997 }
3998
3999 Buffer *buffer = mGLState.getTargetBuffer(target);
4000 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08004001 handleError(buffer->bufferSubData(this, target, data, size, offset));
Jamie Madill29639852016-09-02 15:00:09 -04004002}
4003
Jamie Madillef300b12016-10-07 15:12:09 -04004004void Context::attachShader(GLuint program, GLuint shader)
4005{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05004006 auto programObject = mState.mShaderPrograms->getProgram(program);
4007 auto shaderObject = mState.mShaderPrograms->getShader(shader);
Jamie Madillef300b12016-10-07 15:12:09 -04004008 ASSERT(programObject && shaderObject);
4009 programObject->attachShader(shaderObject);
4010}
4011
Kenneth Russellf2f6f652016-10-05 19:53:23 -07004012const Workarounds &Context::getWorkarounds() const
4013{
4014 return mWorkarounds;
4015}
4016
Jamie Madillb0817d12016-11-01 15:48:31 -04004017void Context::copyBufferSubData(GLenum readTarget,
4018 GLenum writeTarget,
4019 GLintptr readOffset,
4020 GLintptr writeOffset,
4021 GLsizeiptr size)
4022{
4023 // if size is zero, the copy is a successful no-op
4024 if (size == 0)
4025 {
4026 return;
4027 }
4028
4029 // TODO(jmadill): cache these.
4030 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
4031 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
4032
Jamie Madill5f56ddb2017-01-13 17:29:55 -05004033 handleError(writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size));
Jamie Madillb0817d12016-11-01 15:48:31 -04004034}
4035
Jamie Madill01a80ee2016-11-07 12:06:18 -05004036void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
4037{
4038 Program *programObject = getProgram(program);
4039 // TODO(jmadill): Re-use this from the validation if possible.
4040 ASSERT(programObject);
4041 programObject->bindAttributeLocation(index, name);
4042}
4043
4044void Context::bindBuffer(GLenum target, GLuint buffer)
4045{
4046 switch (target)
4047 {
4048 case GL_ARRAY_BUFFER:
4049 bindArrayBuffer(buffer);
4050 break;
4051 case GL_ELEMENT_ARRAY_BUFFER:
4052 bindElementArrayBuffer(buffer);
4053 break;
4054 case GL_COPY_READ_BUFFER:
4055 bindCopyReadBuffer(buffer);
4056 break;
4057 case GL_COPY_WRITE_BUFFER:
4058 bindCopyWriteBuffer(buffer);
4059 break;
4060 case GL_PIXEL_PACK_BUFFER:
4061 bindPixelPackBuffer(buffer);
4062 break;
4063 case GL_PIXEL_UNPACK_BUFFER:
4064 bindPixelUnpackBuffer(buffer);
4065 break;
4066 case GL_UNIFORM_BUFFER:
4067 bindGenericUniformBuffer(buffer);
4068 break;
4069 case GL_TRANSFORM_FEEDBACK_BUFFER:
4070 bindGenericTransformFeedbackBuffer(buffer);
4071 break;
Geoff Lang3b573612016-10-31 14:08:10 -04004072 case GL_ATOMIC_COUNTER_BUFFER:
Jiajia Qin6eafb042016-12-27 17:04:07 +08004073 bindGenericAtomicCounterBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004074 break;
4075 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08004076 bindGenericShaderStorageBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004077 break;
4078 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08004079 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004080 break;
4081 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05004082 if (buffer != 0)
4083 {
4084 // Binding buffers to this binding point is not implemented yet.
4085 UNIMPLEMENTED();
4086 }
Geoff Lang3b573612016-10-31 14:08:10 -04004087 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05004088
4089 default:
4090 UNREACHABLE();
4091 break;
4092 }
4093}
4094
Jiajia Qin6eafb042016-12-27 17:04:07 +08004095void Context::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
4096{
4097 bindBufferRange(target, index, buffer, 0, 0);
4098}
4099
4100void Context::bindBufferRange(GLenum target,
4101 GLuint index,
4102 GLuint buffer,
4103 GLintptr offset,
4104 GLsizeiptr size)
4105{
4106 switch (target)
4107 {
4108 case GL_TRANSFORM_FEEDBACK_BUFFER:
4109 bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
4110 bindGenericTransformFeedbackBuffer(buffer);
4111 break;
4112 case GL_UNIFORM_BUFFER:
4113 bindIndexedUniformBuffer(buffer, index, offset, size);
4114 bindGenericUniformBuffer(buffer);
4115 break;
4116 case GL_ATOMIC_COUNTER_BUFFER:
4117 bindIndexedAtomicCounterBuffer(buffer, index, offset, size);
4118 bindGenericAtomicCounterBuffer(buffer);
4119 break;
4120 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08004121 bindIndexedShaderStorageBuffer(buffer, index, offset, size);
4122 bindGenericShaderStorageBuffer(buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08004123 break;
4124 default:
4125 UNREACHABLE();
4126 break;
4127 }
4128}
4129
Jamie Madill01a80ee2016-11-07 12:06:18 -05004130void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
4131{
4132 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4133 {
4134 bindReadFramebuffer(framebuffer);
4135 }
4136
4137 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4138 {
4139 bindDrawFramebuffer(framebuffer);
4140 }
4141}
4142
4143void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
4144{
4145 ASSERT(target == GL_RENDERBUFFER);
4146 Renderbuffer *object =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05004147 mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
Jamie Madill4928b7c2017-06-20 12:57:39 -04004148 mGLState.setRenderbufferBinding(this, object);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004149}
4150
JiangYizhoubddc46b2016-12-09 09:50:51 +08004151void Context::texStorage2DMultisample(GLenum target,
4152 GLsizei samples,
4153 GLenum internalformat,
4154 GLsizei width,
4155 GLsizei height,
4156 GLboolean fixedsamplelocations)
4157{
4158 Extents size(width, height, 1);
4159 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05004160 handleError(texture->setStorageMultisample(this, target, samples, internalformat, size,
JiangYizhoubddc46b2016-12-09 09:50:51 +08004161 fixedsamplelocations));
4162}
4163
4164void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
4165{
JiangYizhou5b03f472017-01-09 10:22:53 +08004166 // According to spec 3.1 Table 20.49: Framebuffer Dependent Values,
4167 // the sample position should be queried by DRAW_FRAMEBUFFER.
4168 mGLState.syncDirtyObject(this, GL_DRAW_FRAMEBUFFER);
4169 const Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
JiangYizhoubddc46b2016-12-09 09:50:51 +08004170
4171 switch (pname)
4172 {
4173 case GL_SAMPLE_POSITION:
4174 handleError(framebuffer->getSamplePosition(index, val));
4175 break;
4176 default:
4177 UNREACHABLE();
4178 }
4179}
4180
Jamie Madille8fb6402017-02-14 17:56:40 -05004181void Context::renderbufferStorage(GLenum target,
4182 GLenum internalformat,
4183 GLsizei width,
4184 GLsizei height)
4185{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004186 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4187 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
4188
Jamie Madille8fb6402017-02-14 17:56:40 -05004189 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4928b7c2017-06-20 12:57:39 -04004190 handleError(renderbuffer->setStorage(this, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004191}
4192
4193void Context::renderbufferStorageMultisample(GLenum target,
4194 GLsizei samples,
4195 GLenum internalformat,
4196 GLsizei width,
4197 GLsizei height)
4198{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004199 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4200 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
Jamie Madille8fb6402017-02-14 17:56:40 -05004201
4202 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004203 handleError(
Jamie Madill4928b7c2017-06-20 12:57:39 -04004204 renderbuffer->setStorageMultisample(this, samples, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004205}
4206
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004207void Context::getSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)
4208{
Jamie Madill70b5bb02017-08-28 13:32:37 -04004209 const Sync *syncObject = getSync(sync);
Geoff Lang82483b92017-04-11 15:33:00 -04004210 handleError(QuerySynciv(syncObject, pname, bufSize, length, values));
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004211}
4212
JiangYizhoue18e6392017-02-20 10:32:23 +08004213void Context::getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
4214{
4215 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4216 QueryFramebufferParameteriv(framebuffer, pname, params);
4217}
4218
4219void Context::setFramebufferParameteri(GLenum target, GLenum pname, GLint param)
4220{
4221 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4222 SetFramebufferParameteri(framebuffer, pname, param);
4223}
4224
Jamie Madillb3f26b92017-07-19 15:07:41 -04004225Error Context::getScratchBuffer(size_t requstedSizeBytes,
4226 angle::MemoryBuffer **scratchBufferOut) const
Jamie Madille14951e2017-03-09 18:55:16 -05004227{
Jamie Madillb3f26b92017-07-19 15:07:41 -04004228 if (!mScratchBuffer.get(requstedSizeBytes, scratchBufferOut))
4229 {
4230 return OutOfMemory() << "Failed to allocate internal buffer.";
4231 }
4232 return NoError();
4233}
4234
4235Error Context::getZeroFilledBuffer(size_t requstedSizeBytes,
4236 angle::MemoryBuffer **zeroBufferOut) const
4237{
4238 if (!mZeroFilledBuffer.getInitialized(requstedSizeBytes, zeroBufferOut, 0))
Jamie Madille14951e2017-03-09 18:55:16 -05004239 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004240 return OutOfMemory() << "Failed to allocate internal buffer.";
Jamie Madille14951e2017-03-09 18:55:16 -05004241 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004242 return NoError();
Jamie Madille14951e2017-03-09 18:55:16 -05004243}
4244
Xinghua Cao2b396592017-03-29 15:36:04 +08004245void Context::dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ)
4246{
4247 if (numGroupsX == 0u || numGroupsY == 0u || numGroupsZ == 0u)
4248 {
4249 return;
4250 }
4251
Jamie Madill71c88b32017-09-14 22:20:29 -04004252 handleError(mImplementation->dispatchCompute(this, numGroupsX, numGroupsY, numGroupsZ));
Xinghua Cao2b396592017-03-29 15:36:04 +08004253}
4254
JiangYizhou165361c2017-06-07 14:56:57 +08004255void Context::texStorage2D(GLenum target,
4256 GLsizei levels,
4257 GLenum internalFormat,
4258 GLsizei width,
4259 GLsizei height)
4260{
4261 Extents size(width, height, 1);
4262 Texture *texture = getTargetTexture(target);
4263 handleError(texture->setStorage(this, target, levels, internalFormat, size));
4264}
4265
4266void Context::texStorage3D(GLenum target,
4267 GLsizei levels,
4268 GLenum internalFormat,
4269 GLsizei width,
4270 GLsizei height,
4271 GLsizei depth)
4272{
4273 Extents size(width, height, depth);
4274 Texture *texture = getTargetTexture(target);
4275 handleError(texture->setStorage(this, target, levels, internalFormat, size));
4276}
4277
Jamie Madillc1d770e2017-04-13 17:31:24 -04004278GLenum Context::checkFramebufferStatus(GLenum target)
4279{
4280 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4281 ASSERT(framebuffer);
4282
4283 return framebuffer->checkStatus(this);
4284}
4285
4286void Context::compileShader(GLuint shader)
4287{
4288 Shader *shaderObject = GetValidShader(this, shader);
4289 if (!shaderObject)
4290 {
4291 return;
4292 }
4293 shaderObject->compile(this);
4294}
4295
4296void Context::deleteBuffers(GLsizei n, const GLuint *buffers)
4297{
4298 for (int i = 0; i < n; i++)
4299 {
4300 deleteBuffer(buffers[i]);
4301 }
4302}
4303
4304void Context::deleteFramebuffers(GLsizei n, const GLuint *framebuffers)
4305{
4306 for (int i = 0; i < n; i++)
4307 {
4308 if (framebuffers[i] != 0)
4309 {
4310 deleteFramebuffer(framebuffers[i]);
4311 }
4312 }
4313}
4314
4315void Context::deleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)
4316{
4317 for (int i = 0; i < n; i++)
4318 {
4319 deleteRenderbuffer(renderbuffers[i]);
4320 }
4321}
4322
4323void Context::deleteTextures(GLsizei n, const GLuint *textures)
4324{
4325 for (int i = 0; i < n; i++)
4326 {
4327 if (textures[i] != 0)
4328 {
4329 deleteTexture(textures[i]);
4330 }
4331 }
4332}
4333
4334void Context::detachShader(GLuint program, GLuint shader)
4335{
4336 Program *programObject = getProgram(program);
4337 ASSERT(programObject);
4338
4339 Shader *shaderObject = getShader(shader);
4340 ASSERT(shaderObject);
4341
4342 programObject->detachShader(this, shaderObject);
4343}
4344
4345void Context::genBuffers(GLsizei n, GLuint *buffers)
4346{
4347 for (int i = 0; i < n; i++)
4348 {
4349 buffers[i] = createBuffer();
4350 }
4351}
4352
4353void Context::genFramebuffers(GLsizei n, GLuint *framebuffers)
4354{
4355 for (int i = 0; i < n; i++)
4356 {
4357 framebuffers[i] = createFramebuffer();
4358 }
4359}
4360
4361void Context::genRenderbuffers(GLsizei n, GLuint *renderbuffers)
4362{
4363 for (int i = 0; i < n; i++)
4364 {
4365 renderbuffers[i] = createRenderbuffer();
4366 }
4367}
4368
4369void Context::genTextures(GLsizei n, GLuint *textures)
4370{
4371 for (int i = 0; i < n; i++)
4372 {
4373 textures[i] = createTexture();
4374 }
4375}
4376
4377void Context::getActiveAttrib(GLuint program,
4378 GLuint index,
4379 GLsizei bufsize,
4380 GLsizei *length,
4381 GLint *size,
4382 GLenum *type,
4383 GLchar *name)
4384{
4385 Program *programObject = getProgram(program);
4386 ASSERT(programObject);
4387 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
4388}
4389
4390void Context::getActiveUniform(GLuint program,
4391 GLuint index,
4392 GLsizei bufsize,
4393 GLsizei *length,
4394 GLint *size,
4395 GLenum *type,
4396 GLchar *name)
4397{
4398 Program *programObject = getProgram(program);
4399 ASSERT(programObject);
4400 programObject->getActiveUniform(index, bufsize, length, size, type, name);
4401}
4402
4403void Context::getAttachedShaders(GLuint program, GLsizei maxcount, GLsizei *count, GLuint *shaders)
4404{
4405 Program *programObject = getProgram(program);
4406 ASSERT(programObject);
4407 programObject->getAttachedShaders(maxcount, count, shaders);
4408}
4409
4410GLint Context::getAttribLocation(GLuint program, const GLchar *name)
4411{
4412 Program *programObject = getProgram(program);
4413 ASSERT(programObject);
4414 return programObject->getAttributeLocation(name);
4415}
4416
4417void Context::getBooleanv(GLenum pname, GLboolean *params)
4418{
4419 GLenum nativeType;
4420 unsigned int numParams = 0;
4421 getQueryParameterInfo(pname, &nativeType, &numParams);
4422
4423 if (nativeType == GL_BOOL)
4424 {
4425 getBooleanvImpl(pname, params);
4426 }
4427 else
4428 {
4429 CastStateValues(this, nativeType, pname, numParams, params);
4430 }
4431}
4432
4433void Context::getFloatv(GLenum pname, GLfloat *params)
4434{
4435 GLenum nativeType;
4436 unsigned int numParams = 0;
4437 getQueryParameterInfo(pname, &nativeType, &numParams);
4438
4439 if (nativeType == GL_FLOAT)
4440 {
4441 getFloatvImpl(pname, params);
4442 }
4443 else
4444 {
4445 CastStateValues(this, nativeType, pname, numParams, params);
4446 }
4447}
4448
4449void Context::getIntegerv(GLenum pname, GLint *params)
4450{
4451 GLenum nativeType;
4452 unsigned int numParams = 0;
4453 getQueryParameterInfo(pname, &nativeType, &numParams);
4454
4455 if (nativeType == GL_INT)
4456 {
4457 getIntegervImpl(pname, params);
4458 }
4459 else
4460 {
4461 CastStateValues(this, nativeType, pname, numParams, params);
4462 }
4463}
4464
4465void Context::getProgramiv(GLuint program, GLenum pname, GLint *params)
4466{
4467 Program *programObject = getProgram(program);
4468 ASSERT(programObject);
Jamie Madillffe00c02017-06-27 16:26:55 -04004469 QueryProgramiv(this, programObject, pname, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004470}
4471
Jamie Madillbe849e42017-05-02 15:49:00 -04004472void Context::getProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei *length, GLchar *infolog)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004473{
4474 Program *programObject = getProgram(program);
4475 ASSERT(programObject);
4476 programObject->getInfoLog(bufsize, length, infolog);
4477}
4478
4479void Context::getShaderiv(GLuint shader, GLenum pname, GLint *params)
4480{
4481 Shader *shaderObject = getShader(shader);
4482 ASSERT(shaderObject);
Jamie Madillbd044ed2017-06-05 12:59:21 -04004483 QueryShaderiv(this, shaderObject, pname, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004484}
4485
4486void Context::getShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *infolog)
4487{
4488 Shader *shaderObject = getShader(shader);
4489 ASSERT(shaderObject);
Jamie Madillbd044ed2017-06-05 12:59:21 -04004490 shaderObject->getInfoLog(this, bufsize, length, infolog);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004491}
4492
4493void Context::getShaderPrecisionFormat(GLenum shadertype,
4494 GLenum precisiontype,
4495 GLint *range,
4496 GLint *precision)
4497{
4498 // TODO(jmadill): Compute shaders.
4499
4500 switch (shadertype)
4501 {
4502 case GL_VERTEX_SHADER:
4503 switch (precisiontype)
4504 {
4505 case GL_LOW_FLOAT:
4506 mCaps.vertexLowpFloat.get(range, precision);
4507 break;
4508 case GL_MEDIUM_FLOAT:
4509 mCaps.vertexMediumpFloat.get(range, precision);
4510 break;
4511 case GL_HIGH_FLOAT:
4512 mCaps.vertexHighpFloat.get(range, precision);
4513 break;
4514
4515 case GL_LOW_INT:
4516 mCaps.vertexLowpInt.get(range, precision);
4517 break;
4518 case GL_MEDIUM_INT:
4519 mCaps.vertexMediumpInt.get(range, precision);
4520 break;
4521 case GL_HIGH_INT:
4522 mCaps.vertexHighpInt.get(range, precision);
4523 break;
4524
4525 default:
4526 UNREACHABLE();
4527 return;
4528 }
4529 break;
4530
4531 case GL_FRAGMENT_SHADER:
4532 switch (precisiontype)
4533 {
4534 case GL_LOW_FLOAT:
4535 mCaps.fragmentLowpFloat.get(range, precision);
4536 break;
4537 case GL_MEDIUM_FLOAT:
4538 mCaps.fragmentMediumpFloat.get(range, precision);
4539 break;
4540 case GL_HIGH_FLOAT:
4541 mCaps.fragmentHighpFloat.get(range, precision);
4542 break;
4543
4544 case GL_LOW_INT:
4545 mCaps.fragmentLowpInt.get(range, precision);
4546 break;
4547 case GL_MEDIUM_INT:
4548 mCaps.fragmentMediumpInt.get(range, precision);
4549 break;
4550 case GL_HIGH_INT:
4551 mCaps.fragmentHighpInt.get(range, precision);
4552 break;
4553
4554 default:
4555 UNREACHABLE();
4556 return;
4557 }
4558 break;
4559
4560 default:
4561 UNREACHABLE();
4562 return;
4563 }
4564}
4565
4566void Context::getShaderSource(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source)
4567{
4568 Shader *shaderObject = getShader(shader);
4569 ASSERT(shaderObject);
4570 shaderObject->getSource(bufsize, length, source);
4571}
4572
4573void Context::getUniformfv(GLuint program, GLint location, GLfloat *params)
4574{
4575 Program *programObject = getProgram(program);
4576 ASSERT(programObject);
Jamie Madill54164b02017-08-28 15:17:37 -04004577 programObject->getUniformfv(this, location, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004578}
4579
4580void Context::getUniformiv(GLuint program, GLint location, GLint *params)
4581{
4582 Program *programObject = getProgram(program);
4583 ASSERT(programObject);
Jamie Madill54164b02017-08-28 15:17:37 -04004584 programObject->getUniformiv(this, location, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004585}
4586
4587GLint Context::getUniformLocation(GLuint program, const GLchar *name)
4588{
4589 Program *programObject = getProgram(program);
4590 ASSERT(programObject);
4591 return programObject->getUniformLocation(name);
4592}
4593
4594GLboolean Context::isBuffer(GLuint buffer)
4595{
4596 if (buffer == 0)
4597 {
4598 return GL_FALSE;
4599 }
4600
4601 return (getBuffer(buffer) ? GL_TRUE : GL_FALSE);
4602}
4603
4604GLboolean Context::isEnabled(GLenum cap)
4605{
4606 return mGLState.getEnableFeature(cap);
4607}
4608
4609GLboolean Context::isFramebuffer(GLuint framebuffer)
4610{
4611 if (framebuffer == 0)
4612 {
4613 return GL_FALSE;
4614 }
4615
4616 return (getFramebuffer(framebuffer) ? GL_TRUE : GL_FALSE);
4617}
4618
4619GLboolean Context::isProgram(GLuint program)
4620{
4621 if (program == 0)
4622 {
4623 return GL_FALSE;
4624 }
4625
4626 return (getProgram(program) ? GL_TRUE : GL_FALSE);
4627}
4628
4629GLboolean Context::isRenderbuffer(GLuint renderbuffer)
4630{
4631 if (renderbuffer == 0)
4632 {
4633 return GL_FALSE;
4634 }
4635
4636 return (getRenderbuffer(renderbuffer) ? GL_TRUE : GL_FALSE);
4637}
4638
4639GLboolean Context::isShader(GLuint shader)
4640{
4641 if (shader == 0)
4642 {
4643 return GL_FALSE;
4644 }
4645
4646 return (getShader(shader) ? GL_TRUE : GL_FALSE);
4647}
4648
4649GLboolean Context::isTexture(GLuint texture)
4650{
4651 if (texture == 0)
4652 {
4653 return GL_FALSE;
4654 }
4655
4656 return (getTexture(texture) ? GL_TRUE : GL_FALSE);
4657}
4658
4659void Context::linkProgram(GLuint program)
4660{
4661 Program *programObject = getProgram(program);
4662 ASSERT(programObject);
4663 handleError(programObject->link(this));
Martin Radev0abb7a22017-08-28 15:34:45 +03004664 mGLState.onProgramExecutableChange(programObject);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004665}
4666
4667void Context::releaseShaderCompiler()
4668{
Jamie Madill4928b7c2017-06-20 12:57:39 -04004669 mCompiler.set(this, nullptr);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004670}
4671
4672void Context::shaderBinary(GLsizei n,
4673 const GLuint *shaders,
4674 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04004675 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004676 GLsizei length)
4677{
4678 // No binary shader formats are supported.
4679 UNIMPLEMENTED();
4680}
4681
4682void Context::shaderSource(GLuint shader,
4683 GLsizei count,
4684 const GLchar *const *string,
4685 const GLint *length)
4686{
4687 Shader *shaderObject = getShader(shader);
4688 ASSERT(shaderObject);
4689 shaderObject->setSource(count, string, length);
4690}
4691
4692void Context::stencilFunc(GLenum func, GLint ref, GLuint mask)
4693{
4694 stencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
4695}
4696
4697void Context::stencilMask(GLuint mask)
4698{
4699 stencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4700}
4701
4702void Context::stencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4703{
4704 stencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4705}
4706
4707void Context::uniform1f(GLint location, GLfloat x)
4708{
4709 Program *program = mGLState.getProgram();
4710 program->setUniform1fv(location, 1, &x);
4711}
4712
4713void Context::uniform1fv(GLint location, GLsizei count, const GLfloat *v)
4714{
4715 Program *program = mGLState.getProgram();
4716 program->setUniform1fv(location, count, v);
4717}
4718
4719void Context::uniform1i(GLint location, GLint x)
4720{
4721 Program *program = mGLState.getProgram();
Jamie Madill81c2e252017-09-09 23:32:46 -04004722 if (program->setUniform1iv(location, 1, &x) == Program::SetUniformResult::SamplerChanged)
4723 {
4724 mGLState.setObjectDirty(GL_PROGRAM);
4725 }
Jamie Madillc1d770e2017-04-13 17:31:24 -04004726}
4727
4728void Context::uniform1iv(GLint location, GLsizei count, const GLint *v)
4729{
4730 Program *program = mGLState.getProgram();
Jamie Madill81c2e252017-09-09 23:32:46 -04004731 if (program->setUniform1iv(location, count, v) == Program::SetUniformResult::SamplerChanged)
4732 {
4733 mGLState.setObjectDirty(GL_PROGRAM);
4734 }
Jamie Madillc1d770e2017-04-13 17:31:24 -04004735}
4736
4737void Context::uniform2f(GLint location, GLfloat x, GLfloat y)
4738{
4739 GLfloat xy[2] = {x, y};
4740 Program *program = mGLState.getProgram();
4741 program->setUniform2fv(location, 1, xy);
4742}
4743
4744void Context::uniform2fv(GLint location, GLsizei count, const GLfloat *v)
4745{
4746 Program *program = mGLState.getProgram();
4747 program->setUniform2fv(location, count, v);
4748}
4749
4750void Context::uniform2i(GLint location, GLint x, GLint y)
4751{
4752 GLint xy[2] = {x, y};
4753 Program *program = mGLState.getProgram();
4754 program->setUniform2iv(location, 1, xy);
4755}
4756
4757void Context::uniform2iv(GLint location, GLsizei count, const GLint *v)
4758{
4759 Program *program = mGLState.getProgram();
4760 program->setUniform2iv(location, count, v);
4761}
4762
4763void Context::uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4764{
4765 GLfloat xyz[3] = {x, y, z};
4766 Program *program = mGLState.getProgram();
4767 program->setUniform3fv(location, 1, xyz);
4768}
4769
4770void Context::uniform3fv(GLint location, GLsizei count, const GLfloat *v)
4771{
4772 Program *program = mGLState.getProgram();
4773 program->setUniform3fv(location, count, v);
4774}
4775
4776void Context::uniform3i(GLint location, GLint x, GLint y, GLint z)
4777{
4778 GLint xyz[3] = {x, y, z};
4779 Program *program = mGLState.getProgram();
4780 program->setUniform3iv(location, 1, xyz);
4781}
4782
4783void Context::uniform3iv(GLint location, GLsizei count, const GLint *v)
4784{
4785 Program *program = mGLState.getProgram();
4786 program->setUniform3iv(location, count, v);
4787}
4788
4789void Context::uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4790{
4791 GLfloat xyzw[4] = {x, y, z, w};
4792 Program *program = mGLState.getProgram();
4793 program->setUniform4fv(location, 1, xyzw);
4794}
4795
4796void Context::uniform4fv(GLint location, GLsizei count, const GLfloat *v)
4797{
4798 Program *program = mGLState.getProgram();
4799 program->setUniform4fv(location, count, v);
4800}
4801
4802void Context::uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4803{
4804 GLint xyzw[4] = {x, y, z, w};
4805 Program *program = mGLState.getProgram();
4806 program->setUniform4iv(location, 1, xyzw);
4807}
4808
4809void Context::uniform4iv(GLint location, GLsizei count, const GLint *v)
4810{
4811 Program *program = mGLState.getProgram();
4812 program->setUniform4iv(location, count, v);
4813}
4814
4815void Context::uniformMatrix2fv(GLint location,
4816 GLsizei count,
4817 GLboolean transpose,
4818 const GLfloat *value)
4819{
4820 Program *program = mGLState.getProgram();
4821 program->setUniformMatrix2fv(location, count, transpose, value);
4822}
4823
4824void Context::uniformMatrix3fv(GLint location,
4825 GLsizei count,
4826 GLboolean transpose,
4827 const GLfloat *value)
4828{
4829 Program *program = mGLState.getProgram();
4830 program->setUniformMatrix3fv(location, count, transpose, value);
4831}
4832
4833void Context::uniformMatrix4fv(GLint location,
4834 GLsizei count,
4835 GLboolean transpose,
4836 const GLfloat *value)
4837{
4838 Program *program = mGLState.getProgram();
4839 program->setUniformMatrix4fv(location, count, transpose, value);
4840}
4841
4842void Context::validateProgram(GLuint program)
4843{
4844 Program *programObject = getProgram(program);
4845 ASSERT(programObject);
4846 programObject->validate(mCaps);
4847}
4848
Jamie Madilld04908b2017-06-09 14:15:35 -04004849void Context::getProgramBinary(GLuint program,
4850 GLsizei bufSize,
4851 GLsizei *length,
4852 GLenum *binaryFormat,
4853 void *binary)
4854{
4855 Program *programObject = getProgram(program);
4856 ASSERT(programObject != nullptr);
4857
4858 handleError(programObject->saveBinary(this, binaryFormat, binary, bufSize, length));
4859}
4860
4861void Context::programBinary(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length)
4862{
4863 Program *programObject = getProgram(program);
4864 ASSERT(programObject != nullptr);
Jamie Madillb6664922017-07-25 12:55:04 -04004865
Jamie Madilld04908b2017-06-09 14:15:35 -04004866 handleError(programObject->loadBinary(this, binaryFormat, binary, length));
4867}
4868
Jamie Madillff325f12017-08-26 15:06:05 -04004869void Context::uniform1ui(GLint location, GLuint v0)
4870{
4871 Program *program = mGLState.getProgram();
4872 program->setUniform1uiv(location, 1, &v0);
4873}
4874
4875void Context::uniform2ui(GLint location, GLuint v0, GLuint v1)
4876{
4877 Program *program = mGLState.getProgram();
4878 const GLuint xy[] = {v0, v1};
4879 program->setUniform2uiv(location, 1, xy);
4880}
4881
4882void Context::uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
4883{
4884 Program *program = mGLState.getProgram();
4885 const GLuint xyz[] = {v0, v1, v2};
4886 program->setUniform3uiv(location, 1, xyz);
4887}
4888
4889void Context::uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
4890{
4891 Program *program = mGLState.getProgram();
4892 const GLuint xyzw[] = {v0, v1, v2, v3};
4893 program->setUniform4uiv(location, 1, xyzw);
4894}
4895
4896void Context::uniform1uiv(GLint location, GLsizei count, const GLuint *value)
4897{
4898 Program *program = mGLState.getProgram();
4899 program->setUniform1uiv(location, count, value);
4900}
4901void Context::uniform2uiv(GLint location, GLsizei count, const GLuint *value)
4902{
4903 Program *program = mGLState.getProgram();
4904 program->setUniform2uiv(location, count, value);
4905}
4906
4907void Context::uniform3uiv(GLint location, GLsizei count, const GLuint *value)
4908{
4909 Program *program = mGLState.getProgram();
4910 program->setUniform3uiv(location, count, value);
4911}
4912
4913void Context::uniform4uiv(GLint location, GLsizei count, const GLuint *value)
4914{
4915 Program *program = mGLState.getProgram();
4916 program->setUniform4uiv(location, count, value);
4917}
4918
Jamie Madillf0e04492017-08-26 15:28:42 -04004919void Context::genQueries(GLsizei n, GLuint *ids)
4920{
4921 for (GLsizei i = 0; i < n; i++)
4922 {
4923 GLuint handle = mQueryHandleAllocator.allocate();
4924 mQueryMap.assign(handle, nullptr);
4925 ids[i] = handle;
4926 }
4927}
4928
4929void Context::deleteQueries(GLsizei n, const GLuint *ids)
4930{
4931 for (int i = 0; i < n; i++)
4932 {
4933 GLuint query = ids[i];
4934
4935 Query *queryObject = nullptr;
4936 if (mQueryMap.erase(query, &queryObject))
4937 {
4938 mQueryHandleAllocator.release(query);
4939 if (queryObject)
4940 {
4941 queryObject->release(this);
4942 }
4943 }
4944 }
4945}
4946
4947GLboolean Context::isQuery(GLuint id)
4948{
4949 return (getQuery(id, false, GL_NONE) != nullptr) ? GL_TRUE : GL_FALSE;
4950}
4951
Jamie Madillc8c95812017-08-26 18:40:09 -04004952void Context::uniformMatrix2x3fv(GLint location,
4953 GLsizei count,
4954 GLboolean transpose,
4955 const GLfloat *value)
4956{
4957 Program *program = mGLState.getProgram();
4958 program->setUniformMatrix2x3fv(location, count, transpose, value);
4959}
4960
4961void Context::uniformMatrix3x2fv(GLint location,
4962 GLsizei count,
4963 GLboolean transpose,
4964 const GLfloat *value)
4965{
4966 Program *program = mGLState.getProgram();
4967 program->setUniformMatrix3x2fv(location, count, transpose, value);
4968}
4969
4970void Context::uniformMatrix2x4fv(GLint location,
4971 GLsizei count,
4972 GLboolean transpose,
4973 const GLfloat *value)
4974{
4975 Program *program = mGLState.getProgram();
4976 program->setUniformMatrix2x4fv(location, count, transpose, value);
4977}
4978
4979void Context::uniformMatrix4x2fv(GLint location,
4980 GLsizei count,
4981 GLboolean transpose,
4982 const GLfloat *value)
4983{
4984 Program *program = mGLState.getProgram();
4985 program->setUniformMatrix4x2fv(location, count, transpose, value);
4986}
4987
4988void Context::uniformMatrix3x4fv(GLint location,
4989 GLsizei count,
4990 GLboolean transpose,
4991 const GLfloat *value)
4992{
4993 Program *program = mGLState.getProgram();
4994 program->setUniformMatrix3x4fv(location, count, transpose, value);
4995}
4996
4997void Context::uniformMatrix4x3fv(GLint location,
4998 GLsizei count,
4999 GLboolean transpose,
5000 const GLfloat *value)
5001{
5002 Program *program = mGLState.getProgram();
5003 program->setUniformMatrix4x3fv(location, count, transpose, value);
5004}
5005
Jamie Madilld7576732017-08-26 18:49:50 -04005006void Context::deleteVertexArrays(GLsizei n, const GLuint *arrays)
5007{
5008 for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
5009 {
5010 GLuint vertexArray = arrays[arrayIndex];
5011
5012 if (arrays[arrayIndex] != 0)
5013 {
5014 VertexArray *vertexArrayObject = nullptr;
5015 if (mVertexArrayMap.erase(vertexArray, &vertexArrayObject))
5016 {
5017 if (vertexArrayObject != nullptr)
5018 {
5019 detachVertexArray(vertexArray);
5020 vertexArrayObject->onDestroy(this);
5021 }
5022
5023 mVertexArrayHandleAllocator.release(vertexArray);
5024 }
5025 }
5026 }
5027}
5028
5029void Context::genVertexArrays(GLsizei n, GLuint *arrays)
5030{
5031 for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
5032 {
5033 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
5034 mVertexArrayMap.assign(vertexArray, nullptr);
5035 arrays[arrayIndex] = vertexArray;
5036 }
5037}
5038
5039bool Context::isVertexArray(GLuint array)
5040{
5041 if (array == 0)
5042 {
5043 return GL_FALSE;
5044 }
5045
5046 VertexArray *vao = getVertexArray(array);
5047 return (vao != nullptr ? GL_TRUE : GL_FALSE);
5048}
5049
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04005050void Context::endTransformFeedback()
5051{
5052 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
5053 transformFeedback->end(this);
5054}
5055
5056void Context::transformFeedbackVaryings(GLuint program,
5057 GLsizei count,
5058 const GLchar *const *varyings,
5059 GLenum bufferMode)
5060{
5061 Program *programObject = getProgram(program);
5062 ASSERT(programObject);
5063 programObject->setTransformFeedbackVaryings(count, varyings, bufferMode);
5064}
5065
5066void Context::getTransformFeedbackVarying(GLuint program,
5067 GLuint index,
5068 GLsizei bufSize,
5069 GLsizei *length,
5070 GLsizei *size,
5071 GLenum *type,
5072 GLchar *name)
5073{
5074 Program *programObject = getProgram(program);
5075 ASSERT(programObject);
5076 programObject->getTransformFeedbackVarying(index, bufSize, length, size, type, name);
5077}
5078
5079void Context::deleteTransformFeedbacks(GLsizei n, const GLuint *ids)
5080{
5081 for (int i = 0; i < n; i++)
5082 {
5083 GLuint transformFeedback = ids[i];
5084 if (transformFeedback == 0)
5085 {
5086 continue;
5087 }
5088
5089 TransformFeedback *transformFeedbackObject = nullptr;
5090 if (mTransformFeedbackMap.erase(transformFeedback, &transformFeedbackObject))
5091 {
5092 if (transformFeedbackObject != nullptr)
5093 {
5094 detachTransformFeedback(transformFeedback);
5095 transformFeedbackObject->release(this);
5096 }
5097
5098 mTransformFeedbackHandleAllocator.release(transformFeedback);
5099 }
5100 }
5101}
5102
5103void Context::genTransformFeedbacks(GLsizei n, GLuint *ids)
5104{
5105 for (int i = 0; i < n; i++)
5106 {
5107 GLuint transformFeedback = mTransformFeedbackHandleAllocator.allocate();
5108 mTransformFeedbackMap.assign(transformFeedback, nullptr);
5109 ids[i] = transformFeedback;
5110 }
5111}
5112
5113bool Context::isTransformFeedback(GLuint id)
5114{
5115 if (id == 0)
5116 {
5117 // The 3.0.4 spec [section 6.1.11] states that if ID is zero, IsTransformFeedback
5118 // returns FALSE
5119 return GL_FALSE;
5120 }
5121
5122 const TransformFeedback *transformFeedback = getTransformFeedback(id);
5123 return ((transformFeedback != nullptr) ? GL_TRUE : GL_FALSE);
5124}
5125
5126void Context::pauseTransformFeedback()
5127{
5128 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
5129 transformFeedback->pause();
5130}
5131
5132void Context::resumeTransformFeedback()
5133{
5134 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
5135 transformFeedback->resume();
5136}
5137
Jamie Madill12e957f2017-08-26 21:42:26 -04005138void Context::getUniformuiv(GLuint program, GLint location, GLuint *params)
5139{
5140 const Program *programObject = getProgram(program);
Jamie Madill54164b02017-08-28 15:17:37 -04005141 programObject->getUniformuiv(this, location, params);
Jamie Madill12e957f2017-08-26 21:42:26 -04005142}
5143
5144GLint Context::getFragDataLocation(GLuint program, const GLchar *name)
5145{
5146 const Program *programObject = getProgram(program);
5147 return programObject->getFragDataLocation(name);
5148}
5149
5150void Context::getUniformIndices(GLuint program,
5151 GLsizei uniformCount,
5152 const GLchar *const *uniformNames,
5153 GLuint *uniformIndices)
5154{
5155 const Program *programObject = getProgram(program);
5156 if (!programObject->isLinked())
5157 {
5158 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
5159 {
5160 uniformIndices[uniformId] = GL_INVALID_INDEX;
5161 }
5162 }
5163 else
5164 {
5165 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
5166 {
5167 uniformIndices[uniformId] = programObject->getUniformIndex(uniformNames[uniformId]);
5168 }
5169 }
5170}
5171
5172void Context::getActiveUniformsiv(GLuint program,
5173 GLsizei uniformCount,
5174 const GLuint *uniformIndices,
5175 GLenum pname,
5176 GLint *params)
5177{
5178 const Program *programObject = getProgram(program);
5179 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
5180 {
5181 const GLuint index = uniformIndices[uniformId];
5182 params[uniformId] = programObject->getActiveUniformi(index, pname);
5183 }
5184}
5185
5186GLuint Context::getUniformBlockIndex(GLuint program, const GLchar *uniformBlockName)
5187{
5188 const Program *programObject = getProgram(program);
5189 return programObject->getUniformBlockIndex(uniformBlockName);
5190}
5191
5192void Context::getActiveUniformBlockiv(GLuint program,
5193 GLuint uniformBlockIndex,
5194 GLenum pname,
5195 GLint *params)
5196{
5197 const Program *programObject = getProgram(program);
5198 QueryActiveUniformBlockiv(programObject, uniformBlockIndex, pname, params);
5199}
5200
5201void Context::getActiveUniformBlockName(GLuint program,
5202 GLuint uniformBlockIndex,
5203 GLsizei bufSize,
5204 GLsizei *length,
5205 GLchar *uniformBlockName)
5206{
5207 const Program *programObject = getProgram(program);
5208 programObject->getActiveUniformBlockName(uniformBlockIndex, bufSize, length, uniformBlockName);
5209}
5210
5211void Context::uniformBlockBinding(GLuint program,
5212 GLuint uniformBlockIndex,
5213 GLuint uniformBlockBinding)
5214{
5215 Program *programObject = getProgram(program);
5216 programObject->bindUniformBlock(uniformBlockIndex, uniformBlockBinding);
5217}
5218
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005219GLsync Context::fenceSync(GLenum condition, GLbitfield flags)
5220{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005221 GLuint handle = mState.mSyncs->createSync(mImplementation.get());
5222 GLsync syncHandle = reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005223
Jamie Madill70b5bb02017-08-28 13:32:37 -04005224 Sync *syncObject = getSync(syncHandle);
5225 Error error = syncObject->set(condition, flags);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005226 if (error.isError())
5227 {
Jamie Madill70b5bb02017-08-28 13:32:37 -04005228 deleteSync(syncHandle);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005229 handleError(error);
5230 return nullptr;
5231 }
5232
Jamie Madill70b5bb02017-08-28 13:32:37 -04005233 return syncHandle;
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005234}
5235
5236GLboolean Context::isSync(GLsync sync)
5237{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005238 return (getSync(sync) != nullptr);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005239}
5240
5241GLenum Context::clientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
5242{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005243 Sync *syncObject = getSync(sync);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005244
5245 GLenum result = GL_WAIT_FAILED;
5246 handleError(syncObject->clientWait(flags, timeout, &result));
5247 return result;
5248}
5249
5250void Context::waitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
5251{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005252 Sync *syncObject = getSync(sync);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005253 handleError(syncObject->serverWait(flags, timeout));
5254}
5255
5256void Context::getInteger64v(GLenum pname, GLint64 *params)
5257{
5258 GLenum nativeType = GL_NONE;
5259 unsigned int numParams = 0;
5260 getQueryParameterInfo(pname, &nativeType, &numParams);
5261
5262 if (nativeType == GL_INT_64_ANGLEX)
5263 {
5264 getInteger64vImpl(pname, params);
5265 }
5266 else
5267 {
5268 CastStateValues(this, nativeType, pname, numParams, params);
5269 }
5270}
5271
Jamie Madill3ef140a2017-08-26 23:11:21 -04005272void Context::getBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params)
5273{
5274 Buffer *buffer = mGLState.getTargetBuffer(target);
5275 QueryBufferParameteri64v(buffer, pname, params);
5276}
5277
5278void Context::genSamplers(GLsizei count, GLuint *samplers)
5279{
5280 for (int i = 0; i < count; i++)
5281 {
5282 samplers[i] = mState.mSamplers->createSampler();
5283 }
5284}
5285
5286void Context::deleteSamplers(GLsizei count, const GLuint *samplers)
5287{
5288 for (int i = 0; i < count; i++)
5289 {
5290 GLuint sampler = samplers[i];
5291
5292 if (mState.mSamplers->getSampler(sampler))
5293 {
5294 detachSampler(sampler);
5295 }
5296
5297 mState.mSamplers->deleteObject(this, sampler);
5298 }
5299}
5300
5301void Context::getInternalformativ(GLenum target,
5302 GLenum internalformat,
5303 GLenum pname,
5304 GLsizei bufSize,
5305 GLint *params)
5306{
5307 const TextureCaps &formatCaps = mTextureCaps.get(internalformat);
5308 QueryInternalFormativ(formatCaps, pname, bufSize, params);
5309}
5310
Jamie Madill81c2e252017-09-09 23:32:46 -04005311void Context::programUniform1iv(GLuint program, GLint location, GLsizei count, const GLint *value)
5312{
5313 Program *programObject = getProgram(program);
5314 ASSERT(programObject);
5315 if (programObject->setUniform1iv(location, count, value) ==
5316 Program::SetUniformResult::SamplerChanged)
5317 {
5318 mGLState.setObjectDirty(GL_PROGRAM);
5319 }
5320}
5321
5322void Context::onTextureChange(const Texture *texture)
5323{
5324 // Conservatively assume all textures are dirty.
5325 // TODO(jmadill): More fine-grained update.
5326 mGLState.setObjectDirty(GL_TEXTURE);
5327}
5328
Yunchao Hea336b902017-08-02 16:05:21 +08005329void Context::genProgramPipelines(GLsizei count, GLuint *pipelines)
5330{
5331 for (int i = 0; i < count; i++)
5332 {
5333 pipelines[i] = createProgramPipeline();
5334 }
5335}
5336
5337void Context::deleteProgramPipelines(GLsizei count, const GLuint *pipelines)
5338{
5339 for (int i = 0; i < count; i++)
5340 {
5341 if (pipelines[i] != 0)
5342 {
5343 deleteProgramPipeline(pipelines[i]);
5344 }
5345 }
5346}
5347
5348GLboolean Context::isProgramPipeline(GLuint pipeline)
5349{
5350 if (pipeline == 0)
5351 {
5352 return GL_FALSE;
5353 }
5354
5355 return (getProgramPipeline(pipeline) ? GL_TRUE : GL_FALSE);
5356}
5357
Jamie Madillc29968b2016-01-20 11:17:23 -05005358} // namespace gl