blob: 1c7520bb4fd017b0c30768076da18433c5c10301 [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
Jiawei Shaodb342272017-09-27 10:21:45 +08002701 mCaps.maxSampleMaskWords = std::min<GLuint>(mCaps.maxSampleMaskWords, MAX_SAMPLE_MASK_WORDS);
2702
Geoff Langc287ea62016-09-16 14:46:51 -04002703 // WebGL compatibility
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002704 mExtensions.webglCompatibility = mWebGLContext;
Geoff Langc287ea62016-09-16 14:46:51 -04002705 for (const auto &extensionInfo : GetExtensionInfoMap())
2706 {
2707 // If this context is for WebGL, disable all enableable extensions
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002708 if (mWebGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002709 {
2710 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2711 }
2712 }
2713
2714 // Generate texture caps
2715 updateCaps();
2716}
2717
2718void Context::updateCaps()
2719{
Geoff Lang900013c2014-07-07 11:32:19 -04002720 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002721 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002722
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002723 for (auto capsIt : mImplementation->getNativeTextureCaps())
Geoff Lang493daf52014-07-03 13:38:44 -04002724 {
Geoff Langca271392017-04-05 12:30:00 -04002725 GLenum sizedInternalFormat = capsIt.first;
Jamie Madill231c7f52017-04-26 13:45:37 -04002726 TextureCaps formatCaps = capsIt.second;
Geoff Lang493daf52014-07-03 13:38:44 -04002727
Geoff Langca271392017-04-05 12:30:00 -04002728 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002729
Geoff Lang0d8b7242015-09-09 14:56:53 -04002730 // Update the format caps based on the client version and extensions.
2731 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2732 // ES3.
2733 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002734 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002735 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002736 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002737 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002738 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002739
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002740 // OpenGL ES does not support multisampling with non-rendererable formats
2741 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
Olli Etuaho50c562d2017-06-06 14:43:30 +03002742 if (!formatCaps.renderable ||
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002743 (getClientVersion() < ES_3_1 &&
2744 (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
Geoff Lang493daf52014-07-03 13:38:44 -04002745 {
Geoff Langd87878e2014-09-19 15:42:59 -04002746 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002747 }
Olli Etuaho50c562d2017-06-06 14:43:30 +03002748 else
2749 {
2750 // We may have limited the max samples for some required renderbuffer formats due to
2751 // non-conformant formats. In this case MAX_SAMPLES needs to be lowered accordingly.
2752 GLuint formatMaxSamples = formatCaps.getMaxSamples();
2753
2754 // GLES 3.0.5 section 4.4.2.2: "Implementations must support creation of renderbuffers
2755 // in these required formats with up to the value of MAX_SAMPLES multisamples, with the
2756 // exception of signed and unsigned integer formats."
2757 if (formatInfo.componentType != GL_INT && formatInfo.componentType != GL_UNSIGNED_INT &&
2758 formatInfo.isRequiredRenderbufferFormat(getClientVersion()))
2759 {
2760 ASSERT(getClientVersion() < ES_3_0 || formatMaxSamples >= 4);
2761 mCaps.maxSamples = std::min(mCaps.maxSamples, formatMaxSamples);
2762 }
2763
2764 // Handle GLES 3.1 MAX_*_SAMPLES values similarly to MAX_SAMPLES.
2765 if (getClientVersion() >= ES_3_1)
2766 {
2767 // GLES 3.1 section 9.2.5: "Implementations must support creation of renderbuffers
2768 // in these required formats with up to the value of MAX_SAMPLES multisamples, with
2769 // the exception that the signed and unsigned integer formats are required only to
2770 // support creation of renderbuffers with up to the value of MAX_INTEGER_SAMPLES
2771 // multisamples, which must be at least one."
2772 if (formatInfo.componentType == GL_INT ||
2773 formatInfo.componentType == GL_UNSIGNED_INT)
2774 {
2775 mCaps.maxIntegerSamples = std::min(mCaps.maxIntegerSamples, formatMaxSamples);
2776 }
2777
2778 // GLES 3.1 section 19.3.1.
2779 if (formatCaps.texturable)
2780 {
2781 if (formatInfo.depthBits > 0)
2782 {
2783 mCaps.maxDepthTextureSamples =
2784 std::min(mCaps.maxDepthTextureSamples, formatMaxSamples);
2785 }
2786 else if (formatInfo.redBits > 0)
2787 {
2788 mCaps.maxColorTextureSamples =
2789 std::min(mCaps.maxColorTextureSamples, formatMaxSamples);
2790 }
2791 }
2792 }
2793 }
Geoff Langd87878e2014-09-19 15:42:59 -04002794
2795 if (formatCaps.texturable && formatInfo.compressed)
2796 {
Geoff Langca271392017-04-05 12:30:00 -04002797 mCaps.compressedTextureFormats.push_back(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002798 }
2799
Geoff Langca271392017-04-05 12:30:00 -04002800 mTextureCaps.insert(sizedInternalFormat, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002801 }
Jamie Madill32447362017-06-28 14:53:52 -04002802
2803 // If program binary is disabled, blank out the memory cache pointer.
2804 if (!mImplementation->getNativeExtensions().getProgramBinary)
2805 {
2806 mMemoryProgramCache = nullptr;
2807 }
Geoff Lang493daf52014-07-03 13:38:44 -04002808}
2809
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002810void Context::initWorkarounds()
2811{
Jamie Madill761b02c2017-06-23 16:27:06 -04002812 // Apply back-end workarounds.
2813 mImplementation->applyNativeWorkarounds(&mWorkarounds);
2814
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002815 // Lose the context upon out of memory error if the application is
2816 // expecting to watch for those events.
2817 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2818}
2819
Jamie Madill1b94d432015-08-07 13:23:23 -04002820void Context::syncRendererState()
2821{
Jamie Madill7d1f5c62017-09-02 15:32:15 -04002822 mGLState.syncDirtyObjects(this);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002823 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
Jamie Madillfe548342017-06-19 11:13:24 -04002824 mImplementation->syncState(this, dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002825 mGLState.clearDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -04002826}
2827
Jamie Madillad9f24e2016-02-12 09:27:24 -05002828void Context::syncRendererState(const State::DirtyBits &bitMask,
2829 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002830{
Jamie Madill7d1f5c62017-09-02 15:32:15 -04002831 mGLState.syncDirtyObjects(this, objectMask);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002832 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
Jamie Madillfe548342017-06-19 11:13:24 -04002833 mImplementation->syncState(this, dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002834 mGLState.clearDirtyBits(dirtyBits);
Jamie Madill1b94d432015-08-07 13:23:23 -04002835}
Jamie Madillc29968b2016-01-20 11:17:23 -05002836
2837void Context::blitFramebuffer(GLint srcX0,
2838 GLint srcY0,
2839 GLint srcX1,
2840 GLint srcY1,
2841 GLint dstX0,
2842 GLint dstY0,
2843 GLint dstX1,
2844 GLint dstY1,
2845 GLbitfield mask,
2846 GLenum filter)
2847{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002848 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002849 ASSERT(drawFramebuffer);
2850
2851 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2852 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2853
Jamie Madillad9f24e2016-02-12 09:27:24 -05002854 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002855
Jamie Madillc564c072017-06-01 12:45:42 -04002856 handleError(drawFramebuffer->blit(this, srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002857}
Jamie Madillc29968b2016-01-20 11:17:23 -05002858
2859void Context::clear(GLbitfield mask)
2860{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002861 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002862 handleError(mGLState.getDrawFramebuffer()->clear(this, mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002863}
2864
2865void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2866{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002867 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002868 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002869}
2870
2871void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2872{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002873 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002874 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002875}
2876
2877void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2878{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002879 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002880 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002881}
2882
2883void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2884{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002885 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002886 ASSERT(framebufferObject);
2887
2888 // If a buffer is not present, the clear has no effect
2889 if (framebufferObject->getDepthbuffer() == nullptr &&
2890 framebufferObject->getStencilbuffer() == nullptr)
2891 {
2892 return;
2893 }
2894
Jamie Madillad9f24e2016-02-12 09:27:24 -05002895 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002896 handleError(framebufferObject->clearBufferfi(this, buffer, drawbuffer, depth, stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002897}
2898
2899void Context::readPixels(GLint x,
2900 GLint y,
2901 GLsizei width,
2902 GLsizei height,
2903 GLenum format,
2904 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002905 void *pixels)
Jamie Madillc29968b2016-01-20 11:17:23 -05002906{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002907 if (width == 0 || height == 0)
2908 {
2909 return;
2910 }
2911
Jamie Madillad9f24e2016-02-12 09:27:24 -05002912 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002913
Jamie Madillb6664922017-07-25 12:55:04 -04002914 Framebuffer *readFBO = mGLState.getReadFramebuffer();
2915 ASSERT(readFBO);
Jamie Madillc29968b2016-01-20 11:17:23 -05002916
2917 Rectangle area(x, y, width, height);
Jamie Madillb6664922017-07-25 12:55:04 -04002918 handleError(readFBO->readPixels(this, area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002919}
2920
2921void Context::copyTexImage2D(GLenum target,
2922 GLint level,
2923 GLenum internalformat,
2924 GLint x,
2925 GLint y,
2926 GLsizei width,
2927 GLsizei height,
2928 GLint border)
2929{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002930 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002931 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002932
Jamie Madillc29968b2016-01-20 11:17:23 -05002933 Rectangle sourceArea(x, y, width, height);
2934
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002935 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002936 Texture *texture =
2937 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002938 handleError(texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002939}
2940
2941void Context::copyTexSubImage2D(GLenum target,
2942 GLint level,
2943 GLint xoffset,
2944 GLint yoffset,
2945 GLint x,
2946 GLint y,
2947 GLsizei width,
2948 GLsizei height)
2949{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002950 if (width == 0 || height == 0)
2951 {
2952 return;
2953 }
2954
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002955 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002956 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002957
Jamie Madillc29968b2016-01-20 11:17:23 -05002958 Offset destOffset(xoffset, yoffset, 0);
2959 Rectangle sourceArea(x, y, width, height);
2960
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002961 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002962 Texture *texture =
2963 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002964 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002965}
2966
2967void Context::copyTexSubImage3D(GLenum target,
2968 GLint level,
2969 GLint xoffset,
2970 GLint yoffset,
2971 GLint zoffset,
2972 GLint x,
2973 GLint y,
2974 GLsizei width,
2975 GLsizei height)
2976{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002977 if (width == 0 || height == 0)
2978 {
2979 return;
2980 }
2981
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002982 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002983 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002984
Jamie Madillc29968b2016-01-20 11:17:23 -05002985 Offset destOffset(xoffset, yoffset, zoffset);
2986 Rectangle sourceArea(x, y, width, height);
2987
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002988 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002989 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002990 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002991}
2992
2993void Context::framebufferTexture2D(GLenum target,
2994 GLenum attachment,
2995 GLenum textarget,
2996 GLuint texture,
2997 GLint level)
2998{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002999 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003000 ASSERT(framebuffer);
3001
3002 if (texture != 0)
3003 {
3004 Texture *textureObj = getTexture(texture);
3005
3006 ImageIndex index = ImageIndex::MakeInvalid();
3007
3008 if (textarget == GL_TEXTURE_2D)
3009 {
3010 index = ImageIndex::Make2D(level);
3011 }
Corentin Wallez13c0dd42017-07-04 18:27:01 -04003012 else if (textarget == GL_TEXTURE_RECTANGLE_ANGLE)
3013 {
3014 index = ImageIndex::MakeRectangle(level);
3015 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08003016 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
3017 {
3018 ASSERT(level == 0);
3019 index = ImageIndex::Make2DMultisample();
3020 }
Jamie Madillc29968b2016-01-20 11:17:23 -05003021 else
3022 {
3023 ASSERT(IsCubeMapTextureTarget(textarget));
3024 index = ImageIndex::MakeCube(textarget, level);
3025 }
3026
Jamie Madilla02315b2017-02-23 14:14:47 -05003027 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
Jamie Madillc29968b2016-01-20 11:17:23 -05003028 }
3029 else
3030 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003031 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003032 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003033
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003034 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003035}
3036
3037void Context::framebufferRenderbuffer(GLenum target,
3038 GLenum attachment,
3039 GLenum renderbuffertarget,
3040 GLuint renderbuffer)
3041{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003042 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003043 ASSERT(framebuffer);
3044
3045 if (renderbuffer != 0)
3046 {
3047 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
Jamie Madilla02315b2017-02-23 14:14:47 -05003048
3049 framebuffer->setAttachment(this, GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
Jamie Madillc29968b2016-01-20 11:17:23 -05003050 renderbufferObject);
3051 }
3052 else
3053 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003054 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003055 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003056
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003057 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003058}
3059
3060void Context::framebufferTextureLayer(GLenum target,
3061 GLenum attachment,
3062 GLuint texture,
3063 GLint level,
3064 GLint layer)
3065{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003066 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003067 ASSERT(framebuffer);
3068
3069 if (texture != 0)
3070 {
3071 Texture *textureObject = getTexture(texture);
3072
3073 ImageIndex index = ImageIndex::MakeInvalid();
3074
3075 if (textureObject->getTarget() == GL_TEXTURE_3D)
3076 {
3077 index = ImageIndex::Make3D(level, layer);
3078 }
3079 else
3080 {
3081 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
3082 index = ImageIndex::Make2DArray(level, layer);
3083 }
3084
Jamie Madilla02315b2017-02-23 14:14:47 -05003085 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObject);
Jamie Madillc29968b2016-01-20 11:17:23 -05003086 }
3087 else
3088 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003089 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003090 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003091
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003092 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003093}
3094
Martin Radev137032d2017-07-13 10:11:12 +03003095void Context::framebufferTextureMultiviewLayeredANGLE(GLenum target,
3096 GLenum attachment,
3097 GLuint texture,
3098 GLint level,
3099 GLint baseViewIndex,
3100 GLsizei numViews)
3101{
Martin Radev82ef7742017-08-08 17:44:58 +03003102 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
3103 ASSERT(framebuffer);
3104
3105 if (texture != 0)
3106 {
3107 Texture *textureObj = getTexture(texture);
3108
Martin Radev18b75ba2017-08-15 15:50:40 +03003109 ImageIndex index = ImageIndex::Make2DArrayRange(level, baseViewIndex, numViews);
Martin Radev82ef7742017-08-08 17:44:58 +03003110 framebuffer->setAttachmentMultiviewLayered(this, GL_TEXTURE, attachment, index, textureObj,
3111 numViews, baseViewIndex);
3112 }
3113 else
3114 {
3115 framebuffer->resetAttachment(this, attachment);
3116 }
3117
3118 mGLState.setObjectDirty(target);
Martin Radev137032d2017-07-13 10:11:12 +03003119}
3120
3121void Context::framebufferTextureMultiviewSideBySideANGLE(GLenum target,
3122 GLenum attachment,
3123 GLuint texture,
3124 GLint level,
3125 GLsizei numViews,
3126 const GLint *viewportOffsets)
3127{
Martin Radev5dae57b2017-07-14 16:15:55 +03003128 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
3129 ASSERT(framebuffer);
3130
3131 if (texture != 0)
3132 {
3133 Texture *textureObj = getTexture(texture);
3134
3135 ImageIndex index = ImageIndex::Make2D(level);
3136 framebuffer->setAttachmentMultiviewSideBySide(this, GL_TEXTURE, attachment, index,
3137 textureObj, numViews, viewportOffsets);
3138 }
3139 else
3140 {
3141 framebuffer->resetAttachment(this, attachment);
3142 }
3143
3144 mGLState.setObjectDirty(target);
Martin Radev137032d2017-07-13 10:11:12 +03003145}
3146
Jamie Madillc29968b2016-01-20 11:17:23 -05003147void Context::drawBuffers(GLsizei n, const GLenum *bufs)
3148{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003149 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003150 ASSERT(framebuffer);
3151 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003152 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003153}
3154
3155void Context::readBuffer(GLenum mode)
3156{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003157 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003158 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003159 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003160}
3161
3162void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
3163{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003164 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003165 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003166
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003167 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003168 ASSERT(framebuffer);
3169
3170 // The specification isn't clear what should be done when the framebuffer isn't complete.
3171 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill4928b7c2017-06-20 12:57:39 -04003172 handleError(framebuffer->discard(this, numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003173}
3174
3175void Context::invalidateFramebuffer(GLenum target,
3176 GLsizei numAttachments,
3177 const GLenum *attachments)
3178{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003179 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003180 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003181
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003182 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003183 ASSERT(framebuffer);
3184
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003185 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003186 {
Jamie Madill437fa652016-05-03 15:13:24 -04003187 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003188 }
Jamie Madill437fa652016-05-03 15:13:24 -04003189
Jamie Madill4928b7c2017-06-20 12:57:39 -04003190 handleError(framebuffer->invalidate(this, numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003191}
3192
3193void Context::invalidateSubFramebuffer(GLenum target,
3194 GLsizei numAttachments,
3195 const GLenum *attachments,
3196 GLint x,
3197 GLint y,
3198 GLsizei width,
3199 GLsizei height)
3200{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003201 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003202 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003203
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003204 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003205 ASSERT(framebuffer);
3206
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003207 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003208 {
Jamie Madill437fa652016-05-03 15:13:24 -04003209 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003210 }
Jamie Madill437fa652016-05-03 15:13:24 -04003211
3212 Rectangle area(x, y, width, height);
Jamie Madill4928b7c2017-06-20 12:57:39 -04003213 handleError(framebuffer->invalidateSub(this, numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05003214}
3215
Jamie Madill73a84962016-02-12 09:27:23 -05003216void Context::texImage2D(GLenum target,
3217 GLint level,
3218 GLint internalformat,
3219 GLsizei width,
3220 GLsizei height,
3221 GLint border,
3222 GLenum format,
3223 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003224 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003225{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003226 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003227
3228 Extents size(width, height, 1);
3229 Texture *texture =
3230 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003231 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3232 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003233}
3234
3235void Context::texImage3D(GLenum target,
3236 GLint level,
3237 GLint internalformat,
3238 GLsizei width,
3239 GLsizei height,
3240 GLsizei depth,
3241 GLint border,
3242 GLenum format,
3243 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003244 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003245{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003246 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003247
3248 Extents size(width, height, depth);
3249 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003250 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3251 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003252}
3253
3254void Context::texSubImage2D(GLenum target,
3255 GLint level,
3256 GLint xoffset,
3257 GLint yoffset,
3258 GLsizei width,
3259 GLsizei height,
3260 GLenum format,
3261 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003262 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003263{
3264 // Zero sized uploads are valid but no-ops
3265 if (width == 0 || height == 0)
3266 {
3267 return;
3268 }
3269
Jamie Madillad9f24e2016-02-12 09:27:24 -05003270 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003271
3272 Box area(xoffset, yoffset, 0, width, height, 1);
3273 Texture *texture =
3274 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003275 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3276 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003277}
3278
3279void Context::texSubImage3D(GLenum target,
3280 GLint level,
3281 GLint xoffset,
3282 GLint yoffset,
3283 GLint zoffset,
3284 GLsizei width,
3285 GLsizei height,
3286 GLsizei depth,
3287 GLenum format,
3288 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003289 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003290{
3291 // Zero sized uploads are valid but no-ops
3292 if (width == 0 || height == 0 || depth == 0)
3293 {
3294 return;
3295 }
3296
Jamie Madillad9f24e2016-02-12 09:27:24 -05003297 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003298
3299 Box area(xoffset, yoffset, zoffset, width, height, depth);
3300 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003301 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3302 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003303}
3304
3305void Context::compressedTexImage2D(GLenum target,
3306 GLint level,
3307 GLenum internalformat,
3308 GLsizei width,
3309 GLsizei height,
3310 GLint border,
3311 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003312 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003313{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003314 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003315
3316 Extents size(width, height, 1);
3317 Texture *texture =
3318 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003319 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003320 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003321 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003322}
3323
3324void Context::compressedTexImage3D(GLenum target,
3325 GLint level,
3326 GLenum internalformat,
3327 GLsizei width,
3328 GLsizei height,
3329 GLsizei depth,
3330 GLint border,
3331 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003332 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003333{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003334 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003335
3336 Extents size(width, height, depth);
3337 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003338 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003339 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003340 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003341}
3342
3343void Context::compressedTexSubImage2D(GLenum target,
3344 GLint level,
3345 GLint xoffset,
3346 GLint yoffset,
3347 GLsizei width,
3348 GLsizei height,
3349 GLenum format,
3350 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003351 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003352{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003353 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003354
3355 Box area(xoffset, yoffset, 0, width, height, 1);
3356 Texture *texture =
3357 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003358 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003359 format, imageSize,
3360 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003361}
3362
3363void Context::compressedTexSubImage3D(GLenum target,
3364 GLint level,
3365 GLint xoffset,
3366 GLint yoffset,
3367 GLint zoffset,
3368 GLsizei width,
3369 GLsizei height,
3370 GLsizei depth,
3371 GLenum format,
3372 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003373 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003374{
3375 // Zero sized uploads are valid but no-ops
3376 if (width == 0 || height == 0)
3377 {
3378 return;
3379 }
3380
Jamie Madillad9f24e2016-02-12 09:27:24 -05003381 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003382
3383 Box area(xoffset, yoffset, zoffset, width, height, depth);
3384 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003385 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003386 format, imageSize,
3387 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003388}
3389
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003390void Context::generateMipmap(GLenum target)
3391{
3392 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003393 handleError(texture->generateMipmap(this));
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003394}
3395
Geoff Lang97073d12016-04-20 10:42:34 -07003396void Context::copyTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003397 GLint sourceLevel,
3398 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003399 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003400 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003401 GLint internalFormat,
3402 GLenum destType,
3403 GLboolean unpackFlipY,
3404 GLboolean unpackPremultiplyAlpha,
3405 GLboolean unpackUnmultiplyAlpha)
3406{
3407 syncStateForTexImage();
3408
3409 gl::Texture *sourceTexture = getTexture(sourceId);
3410 gl::Texture *destTexture = getTexture(destId);
Geoff Langfc72a072017-03-24 14:52:39 -04003411 handleError(destTexture->copyTexture(
3412 this, destTarget, destLevel, internalFormat, destType, sourceLevel, unpackFlipY == GL_TRUE,
3413 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003414}
3415
3416void Context::copySubTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003417 GLint sourceLevel,
3418 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003419 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003420 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003421 GLint xoffset,
3422 GLint yoffset,
3423 GLint x,
3424 GLint y,
3425 GLsizei width,
3426 GLsizei height,
3427 GLboolean unpackFlipY,
3428 GLboolean unpackPremultiplyAlpha,
3429 GLboolean unpackUnmultiplyAlpha)
3430{
3431 // Zero sized copies are valid but no-ops
3432 if (width == 0 || height == 0)
3433 {
3434 return;
3435 }
3436
3437 syncStateForTexImage();
3438
3439 gl::Texture *sourceTexture = getTexture(sourceId);
3440 gl::Texture *destTexture = getTexture(destId);
3441 Offset offset(xoffset, yoffset, 0);
3442 Rectangle area(x, y, width, height);
Geoff Langfc72a072017-03-24 14:52:39 -04003443 handleError(destTexture->copySubTexture(
3444 this, destTarget, destLevel, offset, sourceLevel, area, unpackFlipY == GL_TRUE,
3445 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003446}
3447
Geoff Lang47110bf2016-04-20 11:13:22 -07003448void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3449{
3450 syncStateForTexImage();
3451
3452 gl::Texture *sourceTexture = getTexture(sourceId);
3453 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003454 handleError(destTexture->copyCompressedTexture(this, sourceTexture));
Geoff Lang47110bf2016-04-20 11:13:22 -07003455}
3456
Geoff Lang496c02d2016-10-20 11:38:11 -07003457void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003458{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003459 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003460 ASSERT(buffer);
3461
Geoff Lang496c02d2016-10-20 11:38:11 -07003462 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003463}
3464
Jamie Madill876429b2017-04-20 15:46:24 -04003465void *Context::mapBuffer(GLenum target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003466{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003467 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003468 ASSERT(buffer);
3469
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003470 Error error = buffer->map(this, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003471 if (error.isError())
3472 {
Jamie Madill437fa652016-05-03 15:13:24 -04003473 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003474 return nullptr;
3475 }
3476
3477 return buffer->getMapPointer();
3478}
3479
3480GLboolean Context::unmapBuffer(GLenum target)
3481{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003482 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003483 ASSERT(buffer);
3484
3485 GLboolean result;
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003486 Error error = buffer->unmap(this, &result);
Olli Etuaho4f667482016-03-30 15:56:35 +03003487 if (error.isError())
3488 {
Jamie Madill437fa652016-05-03 15:13:24 -04003489 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003490 return GL_FALSE;
3491 }
3492
3493 return result;
3494}
3495
Jamie Madill876429b2017-04-20 15:46:24 -04003496void *Context::mapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003497{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003498 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003499 ASSERT(buffer);
3500
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003501 Error error = buffer->mapRange(this, offset, length, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003502 if (error.isError())
3503 {
Jamie Madill437fa652016-05-03 15:13:24 -04003504 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003505 return nullptr;
3506 }
3507
3508 return buffer->getMapPointer();
3509}
3510
3511void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3512{
3513 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3514}
3515
Jamie Madillad9f24e2016-02-12 09:27:24 -05003516void Context::syncStateForReadPixels()
3517{
3518 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3519}
3520
3521void Context::syncStateForTexImage()
3522{
3523 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3524}
3525
3526void Context::syncStateForClear()
3527{
3528 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3529}
3530
3531void Context::syncStateForBlit()
3532{
3533 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3534}
3535
Jamie Madillc20ab272016-06-09 07:20:46 -07003536void Context::activeTexture(GLenum texture)
3537{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003538 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003539}
3540
Jamie Madill876429b2017-04-20 15:46:24 -04003541void Context::blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003542{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003543 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003544}
3545
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003546void Context::blendEquation(GLenum mode)
3547{
3548 mGLState.setBlendEquation(mode, mode);
3549}
3550
Jamie Madillc20ab272016-06-09 07:20:46 -07003551void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3552{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003553 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003554}
3555
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003556void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3557{
3558 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3559}
3560
Jamie Madillc20ab272016-06-09 07:20:46 -07003561void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3562{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003563 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003564}
3565
Jamie Madill876429b2017-04-20 15:46:24 -04003566void Context::clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003567{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003568 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003569}
3570
Jamie Madill876429b2017-04-20 15:46:24 -04003571void Context::clearDepthf(GLfloat depth)
Jamie Madillc20ab272016-06-09 07:20:46 -07003572{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003573 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003574}
3575
3576void Context::clearStencil(GLint s)
3577{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003578 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003579}
3580
3581void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3582{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003583 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003584}
3585
3586void Context::cullFace(GLenum mode)
3587{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003588 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003589}
3590
3591void Context::depthFunc(GLenum func)
3592{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003593 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003594}
3595
3596void Context::depthMask(GLboolean flag)
3597{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003598 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003599}
3600
Jamie Madill876429b2017-04-20 15:46:24 -04003601void Context::depthRangef(GLfloat zNear, GLfloat zFar)
Jamie Madillc20ab272016-06-09 07:20:46 -07003602{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003603 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003604}
3605
3606void Context::disable(GLenum cap)
3607{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003608 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003609}
3610
3611void Context::disableVertexAttribArray(GLuint index)
3612{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003613 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003614}
3615
3616void Context::enable(GLenum cap)
3617{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003618 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003619}
3620
3621void Context::enableVertexAttribArray(GLuint index)
3622{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003623 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003624}
3625
3626void Context::frontFace(GLenum mode)
3627{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003628 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003629}
3630
3631void Context::hint(GLenum target, GLenum mode)
3632{
3633 switch (target)
3634 {
3635 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003636 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003637 break;
3638
3639 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003640 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003641 break;
3642
3643 default:
3644 UNREACHABLE();
3645 return;
3646 }
3647}
3648
3649void Context::lineWidth(GLfloat width)
3650{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003651 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003652}
3653
3654void Context::pixelStorei(GLenum pname, GLint param)
3655{
3656 switch (pname)
3657 {
3658 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003659 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003660 break;
3661
3662 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003663 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003664 break;
3665
3666 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003667 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003668 break;
3669
3670 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003671 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003672 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003673 break;
3674
3675 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003676 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003677 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003678 break;
3679
3680 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003681 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003682 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003683 break;
3684
3685 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003686 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003687 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003688 break;
3689
3690 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003691 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003692 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003693 break;
3694
3695 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003696 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003697 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003698 break;
3699
3700 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003701 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003702 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003703 break;
3704
3705 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003706 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003707 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003708 break;
3709
3710 default:
3711 UNREACHABLE();
3712 return;
3713 }
3714}
3715
3716void Context::polygonOffset(GLfloat factor, GLfloat units)
3717{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003718 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003719}
3720
Jamie Madill876429b2017-04-20 15:46:24 -04003721void Context::sampleCoverage(GLfloat value, GLboolean invert)
Jamie Madillc20ab272016-06-09 07:20:46 -07003722{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003723 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003724}
3725
Jiawei Shaodb342272017-09-27 10:21:45 +08003726void Context::sampleMaski(GLuint maskNumber, GLbitfield mask)
3727{
3728 mGLState.setSampleMaskParams(maskNumber, mask);
3729}
3730
Jamie Madillc20ab272016-06-09 07:20:46 -07003731void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3732{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003733 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003734}
3735
3736void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3737{
3738 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3739 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003740 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003741 }
3742
3743 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3744 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003745 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003746 }
3747}
3748
3749void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3750{
3751 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3752 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003753 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003754 }
3755
3756 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3757 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003758 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003759 }
3760}
3761
3762void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3763{
3764 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3765 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003766 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003767 }
3768
3769 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3770 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003771 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003772 }
3773}
3774
3775void Context::vertexAttrib1f(GLuint index, GLfloat x)
3776{
3777 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003778 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003779}
3780
3781void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3782{
3783 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003784 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003785}
3786
3787void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3788{
3789 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003790 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003791}
3792
3793void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3794{
3795 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003796 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003797}
3798
3799void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3800{
3801 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003802 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003803}
3804
3805void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3806{
3807 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003808 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003809}
3810
3811void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3812{
3813 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003814 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003815}
3816
3817void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3818{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003819 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003820}
3821
3822void Context::vertexAttribPointer(GLuint index,
3823 GLint size,
3824 GLenum type,
3825 GLboolean normalized,
3826 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003827 const void *ptr)
Jamie Madillc20ab272016-06-09 07:20:46 -07003828{
Shaodde78e82017-05-22 14:13:27 +08003829 mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size,
3830 type, normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003831}
3832
Shao80957d92017-02-20 21:25:59 +08003833void Context::vertexAttribFormat(GLuint attribIndex,
3834 GLint size,
3835 GLenum type,
3836 GLboolean normalized,
3837 GLuint relativeOffset)
3838{
3839 mGLState.setVertexAttribFormat(attribIndex, size, type, normalized == GL_TRUE, false,
3840 relativeOffset);
3841}
3842
3843void Context::vertexAttribIFormat(GLuint attribIndex,
3844 GLint size,
3845 GLenum type,
3846 GLuint relativeOffset)
3847{
3848 mGLState.setVertexAttribFormat(attribIndex, size, type, false, true, relativeOffset);
3849}
3850
3851void Context::vertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
3852{
Shaodde78e82017-05-22 14:13:27 +08003853 mGLState.setVertexAttribBinding(this, attribIndex, bindingIndex);
Shao80957d92017-02-20 21:25:59 +08003854}
3855
3856void Context::setVertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
3857{
3858 mGLState.setVertexBindingDivisor(bindingIndex, divisor);
3859}
3860
Jamie Madillc20ab272016-06-09 07:20:46 -07003861void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3862{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003863 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003864}
3865
3866void Context::vertexAttribIPointer(GLuint index,
3867 GLint size,
3868 GLenum type,
3869 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003870 const void *pointer)
Jamie Madillc20ab272016-06-09 07:20:46 -07003871{
Shaodde78e82017-05-22 14:13:27 +08003872 mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size,
3873 type, false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003874}
3875
3876void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3877{
3878 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003879 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003880}
3881
3882void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3883{
3884 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003885 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003886}
3887
3888void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3889{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003890 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003891}
3892
3893void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3894{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003895 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003896}
3897
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003898void Context::getVertexAttribiv(GLuint index, GLenum pname, GLint *params)
3899{
3900 const VertexAttribCurrentValueData &currentValues =
3901 getGLState().getVertexAttribCurrentValue(index);
3902 const VertexArray *vao = getGLState().getVertexArray();
3903 QueryVertexAttribiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3904 currentValues, pname, params);
3905}
3906
3907void Context::getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
3908{
3909 const VertexAttribCurrentValueData &currentValues =
3910 getGLState().getVertexAttribCurrentValue(index);
3911 const VertexArray *vao = getGLState().getVertexArray();
3912 QueryVertexAttribfv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3913 currentValues, pname, params);
3914}
3915
3916void Context::getVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
3917{
3918 const VertexAttribCurrentValueData &currentValues =
3919 getGLState().getVertexAttribCurrentValue(index);
3920 const VertexArray *vao = getGLState().getVertexArray();
3921 QueryVertexAttribIiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3922 currentValues, pname, params);
3923}
3924
3925void Context::getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
3926{
3927 const VertexAttribCurrentValueData &currentValues =
3928 getGLState().getVertexAttribCurrentValue(index);
3929 const VertexArray *vao = getGLState().getVertexArray();
3930 QueryVertexAttribIuiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3931 currentValues, pname, params);
3932}
3933
Jamie Madill876429b2017-04-20 15:46:24 -04003934void Context::getVertexAttribPointerv(GLuint index, GLenum pname, void **pointer)
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003935{
3936 const VertexAttribute &attrib = getGLState().getVertexArray()->getVertexAttribute(index);
3937 QueryVertexAttribPointerv(attrib, pname, pointer);
3938}
3939
Jamie Madillc20ab272016-06-09 07:20:46 -07003940void Context::debugMessageControl(GLenum source,
3941 GLenum type,
3942 GLenum severity,
3943 GLsizei count,
3944 const GLuint *ids,
3945 GLboolean enabled)
3946{
3947 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003948 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3949 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003950}
3951
3952void Context::debugMessageInsert(GLenum source,
3953 GLenum type,
3954 GLuint id,
3955 GLenum severity,
3956 GLsizei length,
3957 const GLchar *buf)
3958{
3959 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003960 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003961}
3962
3963void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3964{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003965 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003966}
3967
3968GLuint Context::getDebugMessageLog(GLuint count,
3969 GLsizei bufSize,
3970 GLenum *sources,
3971 GLenum *types,
3972 GLuint *ids,
3973 GLenum *severities,
3974 GLsizei *lengths,
3975 GLchar *messageLog)
3976{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003977 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3978 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003979}
3980
3981void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3982{
3983 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003984 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003985}
3986
3987void Context::popDebugGroup()
3988{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003989 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003990}
3991
Jamie Madill876429b2017-04-20 15:46:24 -04003992void Context::bufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage)
Jamie Madill29639852016-09-02 15:00:09 -04003993{
3994 Buffer *buffer = mGLState.getTargetBuffer(target);
3995 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003996 handleError(buffer->bufferData(this, target, data, size, usage));
Jamie Madill29639852016-09-02 15:00:09 -04003997}
3998
Jamie Madill876429b2017-04-20 15:46:24 -04003999void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004000{
4001 if (data == nullptr)
4002 {
4003 return;
4004 }
4005
4006 Buffer *buffer = mGLState.getTargetBuffer(target);
4007 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08004008 handleError(buffer->bufferSubData(this, target, data, size, offset));
Jamie Madill29639852016-09-02 15:00:09 -04004009}
4010
Jamie Madillef300b12016-10-07 15:12:09 -04004011void Context::attachShader(GLuint program, GLuint shader)
4012{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05004013 auto programObject = mState.mShaderPrograms->getProgram(program);
4014 auto shaderObject = mState.mShaderPrograms->getShader(shader);
Jamie Madillef300b12016-10-07 15:12:09 -04004015 ASSERT(programObject && shaderObject);
4016 programObject->attachShader(shaderObject);
4017}
4018
Kenneth Russellf2f6f652016-10-05 19:53:23 -07004019const Workarounds &Context::getWorkarounds() const
4020{
4021 return mWorkarounds;
4022}
4023
Jamie Madillb0817d12016-11-01 15:48:31 -04004024void Context::copyBufferSubData(GLenum readTarget,
4025 GLenum writeTarget,
4026 GLintptr readOffset,
4027 GLintptr writeOffset,
4028 GLsizeiptr size)
4029{
4030 // if size is zero, the copy is a successful no-op
4031 if (size == 0)
4032 {
4033 return;
4034 }
4035
4036 // TODO(jmadill): cache these.
4037 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
4038 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
4039
Jamie Madill5f56ddb2017-01-13 17:29:55 -05004040 handleError(writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size));
Jamie Madillb0817d12016-11-01 15:48:31 -04004041}
4042
Jamie Madill01a80ee2016-11-07 12:06:18 -05004043void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
4044{
4045 Program *programObject = getProgram(program);
4046 // TODO(jmadill): Re-use this from the validation if possible.
4047 ASSERT(programObject);
4048 programObject->bindAttributeLocation(index, name);
4049}
4050
4051void Context::bindBuffer(GLenum target, GLuint buffer)
4052{
4053 switch (target)
4054 {
4055 case GL_ARRAY_BUFFER:
4056 bindArrayBuffer(buffer);
4057 break;
4058 case GL_ELEMENT_ARRAY_BUFFER:
4059 bindElementArrayBuffer(buffer);
4060 break;
4061 case GL_COPY_READ_BUFFER:
4062 bindCopyReadBuffer(buffer);
4063 break;
4064 case GL_COPY_WRITE_BUFFER:
4065 bindCopyWriteBuffer(buffer);
4066 break;
4067 case GL_PIXEL_PACK_BUFFER:
4068 bindPixelPackBuffer(buffer);
4069 break;
4070 case GL_PIXEL_UNPACK_BUFFER:
4071 bindPixelUnpackBuffer(buffer);
4072 break;
4073 case GL_UNIFORM_BUFFER:
4074 bindGenericUniformBuffer(buffer);
4075 break;
4076 case GL_TRANSFORM_FEEDBACK_BUFFER:
4077 bindGenericTransformFeedbackBuffer(buffer);
4078 break;
Geoff Lang3b573612016-10-31 14:08:10 -04004079 case GL_ATOMIC_COUNTER_BUFFER:
Jiajia Qin6eafb042016-12-27 17:04:07 +08004080 bindGenericAtomicCounterBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004081 break;
4082 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08004083 bindGenericShaderStorageBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004084 break;
4085 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08004086 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004087 break;
4088 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05004089 if (buffer != 0)
4090 {
4091 // Binding buffers to this binding point is not implemented yet.
4092 UNIMPLEMENTED();
4093 }
Geoff Lang3b573612016-10-31 14:08:10 -04004094 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05004095
4096 default:
4097 UNREACHABLE();
4098 break;
4099 }
4100}
4101
Jiajia Qin6eafb042016-12-27 17:04:07 +08004102void Context::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
4103{
4104 bindBufferRange(target, index, buffer, 0, 0);
4105}
4106
4107void Context::bindBufferRange(GLenum target,
4108 GLuint index,
4109 GLuint buffer,
4110 GLintptr offset,
4111 GLsizeiptr size)
4112{
4113 switch (target)
4114 {
4115 case GL_TRANSFORM_FEEDBACK_BUFFER:
4116 bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
4117 bindGenericTransformFeedbackBuffer(buffer);
4118 break;
4119 case GL_UNIFORM_BUFFER:
4120 bindIndexedUniformBuffer(buffer, index, offset, size);
4121 bindGenericUniformBuffer(buffer);
4122 break;
4123 case GL_ATOMIC_COUNTER_BUFFER:
4124 bindIndexedAtomicCounterBuffer(buffer, index, offset, size);
4125 bindGenericAtomicCounterBuffer(buffer);
4126 break;
4127 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08004128 bindIndexedShaderStorageBuffer(buffer, index, offset, size);
4129 bindGenericShaderStorageBuffer(buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08004130 break;
4131 default:
4132 UNREACHABLE();
4133 break;
4134 }
4135}
4136
Jamie Madill01a80ee2016-11-07 12:06:18 -05004137void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
4138{
4139 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4140 {
4141 bindReadFramebuffer(framebuffer);
4142 }
4143
4144 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4145 {
4146 bindDrawFramebuffer(framebuffer);
4147 }
4148}
4149
4150void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
4151{
4152 ASSERT(target == GL_RENDERBUFFER);
4153 Renderbuffer *object =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05004154 mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
Jamie Madill4928b7c2017-06-20 12:57:39 -04004155 mGLState.setRenderbufferBinding(this, object);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004156}
4157
JiangYizhoubddc46b2016-12-09 09:50:51 +08004158void Context::texStorage2DMultisample(GLenum target,
4159 GLsizei samples,
4160 GLenum internalformat,
4161 GLsizei width,
4162 GLsizei height,
4163 GLboolean fixedsamplelocations)
4164{
4165 Extents size(width, height, 1);
4166 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05004167 handleError(texture->setStorageMultisample(this, target, samples, internalformat, size,
JiangYizhoubddc46b2016-12-09 09:50:51 +08004168 fixedsamplelocations));
4169}
4170
4171void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
4172{
JiangYizhou5b03f472017-01-09 10:22:53 +08004173 // According to spec 3.1 Table 20.49: Framebuffer Dependent Values,
4174 // the sample position should be queried by DRAW_FRAMEBUFFER.
4175 mGLState.syncDirtyObject(this, GL_DRAW_FRAMEBUFFER);
4176 const Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
JiangYizhoubddc46b2016-12-09 09:50:51 +08004177
4178 switch (pname)
4179 {
4180 case GL_SAMPLE_POSITION:
4181 handleError(framebuffer->getSamplePosition(index, val));
4182 break;
4183 default:
4184 UNREACHABLE();
4185 }
4186}
4187
Jamie Madille8fb6402017-02-14 17:56:40 -05004188void Context::renderbufferStorage(GLenum target,
4189 GLenum internalformat,
4190 GLsizei width,
4191 GLsizei height)
4192{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004193 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4194 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
4195
Jamie Madille8fb6402017-02-14 17:56:40 -05004196 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4928b7c2017-06-20 12:57:39 -04004197 handleError(renderbuffer->setStorage(this, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004198}
4199
4200void Context::renderbufferStorageMultisample(GLenum target,
4201 GLsizei samples,
4202 GLenum internalformat,
4203 GLsizei width,
4204 GLsizei height)
4205{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004206 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4207 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
Jamie Madille8fb6402017-02-14 17:56:40 -05004208
4209 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004210 handleError(
Jamie Madill4928b7c2017-06-20 12:57:39 -04004211 renderbuffer->setStorageMultisample(this, samples, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004212}
4213
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004214void Context::getSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)
4215{
Jamie Madill70b5bb02017-08-28 13:32:37 -04004216 const Sync *syncObject = getSync(sync);
Geoff Lang82483b92017-04-11 15:33:00 -04004217 handleError(QuerySynciv(syncObject, pname, bufSize, length, values));
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004218}
4219
JiangYizhoue18e6392017-02-20 10:32:23 +08004220void Context::getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
4221{
4222 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4223 QueryFramebufferParameteriv(framebuffer, pname, params);
4224}
4225
4226void Context::setFramebufferParameteri(GLenum target, GLenum pname, GLint param)
4227{
4228 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4229 SetFramebufferParameteri(framebuffer, pname, param);
4230}
4231
Jamie Madillb3f26b92017-07-19 15:07:41 -04004232Error Context::getScratchBuffer(size_t requstedSizeBytes,
4233 angle::MemoryBuffer **scratchBufferOut) const
Jamie Madille14951e2017-03-09 18:55:16 -05004234{
Jamie Madillb3f26b92017-07-19 15:07:41 -04004235 if (!mScratchBuffer.get(requstedSizeBytes, scratchBufferOut))
4236 {
4237 return OutOfMemory() << "Failed to allocate internal buffer.";
4238 }
4239 return NoError();
4240}
4241
4242Error Context::getZeroFilledBuffer(size_t requstedSizeBytes,
4243 angle::MemoryBuffer **zeroBufferOut) const
4244{
4245 if (!mZeroFilledBuffer.getInitialized(requstedSizeBytes, zeroBufferOut, 0))
Jamie Madille14951e2017-03-09 18:55:16 -05004246 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004247 return OutOfMemory() << "Failed to allocate internal buffer.";
Jamie Madille14951e2017-03-09 18:55:16 -05004248 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004249 return NoError();
Jamie Madille14951e2017-03-09 18:55:16 -05004250}
4251
Xinghua Cao2b396592017-03-29 15:36:04 +08004252void Context::dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ)
4253{
4254 if (numGroupsX == 0u || numGroupsY == 0u || numGroupsZ == 0u)
4255 {
4256 return;
4257 }
4258
Jamie Madill71c88b32017-09-14 22:20:29 -04004259 handleError(mImplementation->dispatchCompute(this, numGroupsX, numGroupsY, numGroupsZ));
Xinghua Cao2b396592017-03-29 15:36:04 +08004260}
4261
JiangYizhou165361c2017-06-07 14:56:57 +08004262void Context::texStorage2D(GLenum target,
4263 GLsizei levels,
4264 GLenum internalFormat,
4265 GLsizei width,
4266 GLsizei height)
4267{
4268 Extents size(width, height, 1);
4269 Texture *texture = getTargetTexture(target);
4270 handleError(texture->setStorage(this, target, levels, internalFormat, size));
4271}
4272
4273void Context::texStorage3D(GLenum target,
4274 GLsizei levels,
4275 GLenum internalFormat,
4276 GLsizei width,
4277 GLsizei height,
4278 GLsizei depth)
4279{
4280 Extents size(width, height, depth);
4281 Texture *texture = getTargetTexture(target);
4282 handleError(texture->setStorage(this, target, levels, internalFormat, size));
4283}
4284
Jamie Madillc1d770e2017-04-13 17:31:24 -04004285GLenum Context::checkFramebufferStatus(GLenum target)
4286{
4287 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4288 ASSERT(framebuffer);
4289
4290 return framebuffer->checkStatus(this);
4291}
4292
4293void Context::compileShader(GLuint shader)
4294{
4295 Shader *shaderObject = GetValidShader(this, shader);
4296 if (!shaderObject)
4297 {
4298 return;
4299 }
4300 shaderObject->compile(this);
4301}
4302
4303void Context::deleteBuffers(GLsizei n, const GLuint *buffers)
4304{
4305 for (int i = 0; i < n; i++)
4306 {
4307 deleteBuffer(buffers[i]);
4308 }
4309}
4310
4311void Context::deleteFramebuffers(GLsizei n, const GLuint *framebuffers)
4312{
4313 for (int i = 0; i < n; i++)
4314 {
4315 if (framebuffers[i] != 0)
4316 {
4317 deleteFramebuffer(framebuffers[i]);
4318 }
4319 }
4320}
4321
4322void Context::deleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)
4323{
4324 for (int i = 0; i < n; i++)
4325 {
4326 deleteRenderbuffer(renderbuffers[i]);
4327 }
4328}
4329
4330void Context::deleteTextures(GLsizei n, const GLuint *textures)
4331{
4332 for (int i = 0; i < n; i++)
4333 {
4334 if (textures[i] != 0)
4335 {
4336 deleteTexture(textures[i]);
4337 }
4338 }
4339}
4340
4341void Context::detachShader(GLuint program, GLuint shader)
4342{
4343 Program *programObject = getProgram(program);
4344 ASSERT(programObject);
4345
4346 Shader *shaderObject = getShader(shader);
4347 ASSERT(shaderObject);
4348
4349 programObject->detachShader(this, shaderObject);
4350}
4351
4352void Context::genBuffers(GLsizei n, GLuint *buffers)
4353{
4354 for (int i = 0; i < n; i++)
4355 {
4356 buffers[i] = createBuffer();
4357 }
4358}
4359
4360void Context::genFramebuffers(GLsizei n, GLuint *framebuffers)
4361{
4362 for (int i = 0; i < n; i++)
4363 {
4364 framebuffers[i] = createFramebuffer();
4365 }
4366}
4367
4368void Context::genRenderbuffers(GLsizei n, GLuint *renderbuffers)
4369{
4370 for (int i = 0; i < n; i++)
4371 {
4372 renderbuffers[i] = createRenderbuffer();
4373 }
4374}
4375
4376void Context::genTextures(GLsizei n, GLuint *textures)
4377{
4378 for (int i = 0; i < n; i++)
4379 {
4380 textures[i] = createTexture();
4381 }
4382}
4383
4384void Context::getActiveAttrib(GLuint program,
4385 GLuint index,
4386 GLsizei bufsize,
4387 GLsizei *length,
4388 GLint *size,
4389 GLenum *type,
4390 GLchar *name)
4391{
4392 Program *programObject = getProgram(program);
4393 ASSERT(programObject);
4394 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
4395}
4396
4397void Context::getActiveUniform(GLuint program,
4398 GLuint index,
4399 GLsizei bufsize,
4400 GLsizei *length,
4401 GLint *size,
4402 GLenum *type,
4403 GLchar *name)
4404{
4405 Program *programObject = getProgram(program);
4406 ASSERT(programObject);
4407 programObject->getActiveUniform(index, bufsize, length, size, type, name);
4408}
4409
4410void Context::getAttachedShaders(GLuint program, GLsizei maxcount, GLsizei *count, GLuint *shaders)
4411{
4412 Program *programObject = getProgram(program);
4413 ASSERT(programObject);
4414 programObject->getAttachedShaders(maxcount, count, shaders);
4415}
4416
4417GLint Context::getAttribLocation(GLuint program, const GLchar *name)
4418{
4419 Program *programObject = getProgram(program);
4420 ASSERT(programObject);
4421 return programObject->getAttributeLocation(name);
4422}
4423
4424void Context::getBooleanv(GLenum pname, GLboolean *params)
4425{
4426 GLenum nativeType;
4427 unsigned int numParams = 0;
4428 getQueryParameterInfo(pname, &nativeType, &numParams);
4429
4430 if (nativeType == GL_BOOL)
4431 {
4432 getBooleanvImpl(pname, params);
4433 }
4434 else
4435 {
4436 CastStateValues(this, nativeType, pname, numParams, params);
4437 }
4438}
4439
4440void Context::getFloatv(GLenum pname, GLfloat *params)
4441{
4442 GLenum nativeType;
4443 unsigned int numParams = 0;
4444 getQueryParameterInfo(pname, &nativeType, &numParams);
4445
4446 if (nativeType == GL_FLOAT)
4447 {
4448 getFloatvImpl(pname, params);
4449 }
4450 else
4451 {
4452 CastStateValues(this, nativeType, pname, numParams, params);
4453 }
4454}
4455
4456void Context::getIntegerv(GLenum pname, GLint *params)
4457{
4458 GLenum nativeType;
4459 unsigned int numParams = 0;
4460 getQueryParameterInfo(pname, &nativeType, &numParams);
4461
4462 if (nativeType == GL_INT)
4463 {
4464 getIntegervImpl(pname, params);
4465 }
4466 else
4467 {
4468 CastStateValues(this, nativeType, pname, numParams, params);
4469 }
4470}
4471
4472void Context::getProgramiv(GLuint program, GLenum pname, GLint *params)
4473{
4474 Program *programObject = getProgram(program);
4475 ASSERT(programObject);
Jamie Madillffe00c02017-06-27 16:26:55 -04004476 QueryProgramiv(this, programObject, pname, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004477}
4478
Jamie Madillbe849e42017-05-02 15:49:00 -04004479void Context::getProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei *length, GLchar *infolog)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004480{
4481 Program *programObject = getProgram(program);
4482 ASSERT(programObject);
4483 programObject->getInfoLog(bufsize, length, infolog);
4484}
4485
4486void Context::getShaderiv(GLuint shader, GLenum pname, GLint *params)
4487{
4488 Shader *shaderObject = getShader(shader);
4489 ASSERT(shaderObject);
Jamie Madillbd044ed2017-06-05 12:59:21 -04004490 QueryShaderiv(this, shaderObject, pname, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004491}
4492
4493void Context::getShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *infolog)
4494{
4495 Shader *shaderObject = getShader(shader);
4496 ASSERT(shaderObject);
Jamie Madillbd044ed2017-06-05 12:59:21 -04004497 shaderObject->getInfoLog(this, bufsize, length, infolog);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004498}
4499
4500void Context::getShaderPrecisionFormat(GLenum shadertype,
4501 GLenum precisiontype,
4502 GLint *range,
4503 GLint *precision)
4504{
4505 // TODO(jmadill): Compute shaders.
4506
4507 switch (shadertype)
4508 {
4509 case GL_VERTEX_SHADER:
4510 switch (precisiontype)
4511 {
4512 case GL_LOW_FLOAT:
4513 mCaps.vertexLowpFloat.get(range, precision);
4514 break;
4515 case GL_MEDIUM_FLOAT:
4516 mCaps.vertexMediumpFloat.get(range, precision);
4517 break;
4518 case GL_HIGH_FLOAT:
4519 mCaps.vertexHighpFloat.get(range, precision);
4520 break;
4521
4522 case GL_LOW_INT:
4523 mCaps.vertexLowpInt.get(range, precision);
4524 break;
4525 case GL_MEDIUM_INT:
4526 mCaps.vertexMediumpInt.get(range, precision);
4527 break;
4528 case GL_HIGH_INT:
4529 mCaps.vertexHighpInt.get(range, precision);
4530 break;
4531
4532 default:
4533 UNREACHABLE();
4534 return;
4535 }
4536 break;
4537
4538 case GL_FRAGMENT_SHADER:
4539 switch (precisiontype)
4540 {
4541 case GL_LOW_FLOAT:
4542 mCaps.fragmentLowpFloat.get(range, precision);
4543 break;
4544 case GL_MEDIUM_FLOAT:
4545 mCaps.fragmentMediumpFloat.get(range, precision);
4546 break;
4547 case GL_HIGH_FLOAT:
4548 mCaps.fragmentHighpFloat.get(range, precision);
4549 break;
4550
4551 case GL_LOW_INT:
4552 mCaps.fragmentLowpInt.get(range, precision);
4553 break;
4554 case GL_MEDIUM_INT:
4555 mCaps.fragmentMediumpInt.get(range, precision);
4556 break;
4557 case GL_HIGH_INT:
4558 mCaps.fragmentHighpInt.get(range, precision);
4559 break;
4560
4561 default:
4562 UNREACHABLE();
4563 return;
4564 }
4565 break;
4566
4567 default:
4568 UNREACHABLE();
4569 return;
4570 }
4571}
4572
4573void Context::getShaderSource(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source)
4574{
4575 Shader *shaderObject = getShader(shader);
4576 ASSERT(shaderObject);
4577 shaderObject->getSource(bufsize, length, source);
4578}
4579
4580void Context::getUniformfv(GLuint program, GLint location, GLfloat *params)
4581{
4582 Program *programObject = getProgram(program);
4583 ASSERT(programObject);
Jamie Madill54164b02017-08-28 15:17:37 -04004584 programObject->getUniformfv(this, location, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004585}
4586
4587void Context::getUniformiv(GLuint program, GLint location, GLint *params)
4588{
4589 Program *programObject = getProgram(program);
4590 ASSERT(programObject);
Jamie Madill54164b02017-08-28 15:17:37 -04004591 programObject->getUniformiv(this, location, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004592}
4593
4594GLint Context::getUniformLocation(GLuint program, const GLchar *name)
4595{
4596 Program *programObject = getProgram(program);
4597 ASSERT(programObject);
4598 return programObject->getUniformLocation(name);
4599}
4600
4601GLboolean Context::isBuffer(GLuint buffer)
4602{
4603 if (buffer == 0)
4604 {
4605 return GL_FALSE;
4606 }
4607
4608 return (getBuffer(buffer) ? GL_TRUE : GL_FALSE);
4609}
4610
4611GLboolean Context::isEnabled(GLenum cap)
4612{
4613 return mGLState.getEnableFeature(cap);
4614}
4615
4616GLboolean Context::isFramebuffer(GLuint framebuffer)
4617{
4618 if (framebuffer == 0)
4619 {
4620 return GL_FALSE;
4621 }
4622
4623 return (getFramebuffer(framebuffer) ? GL_TRUE : GL_FALSE);
4624}
4625
4626GLboolean Context::isProgram(GLuint program)
4627{
4628 if (program == 0)
4629 {
4630 return GL_FALSE;
4631 }
4632
4633 return (getProgram(program) ? GL_TRUE : GL_FALSE);
4634}
4635
4636GLboolean Context::isRenderbuffer(GLuint renderbuffer)
4637{
4638 if (renderbuffer == 0)
4639 {
4640 return GL_FALSE;
4641 }
4642
4643 return (getRenderbuffer(renderbuffer) ? GL_TRUE : GL_FALSE);
4644}
4645
4646GLboolean Context::isShader(GLuint shader)
4647{
4648 if (shader == 0)
4649 {
4650 return GL_FALSE;
4651 }
4652
4653 return (getShader(shader) ? GL_TRUE : GL_FALSE);
4654}
4655
4656GLboolean Context::isTexture(GLuint texture)
4657{
4658 if (texture == 0)
4659 {
4660 return GL_FALSE;
4661 }
4662
4663 return (getTexture(texture) ? GL_TRUE : GL_FALSE);
4664}
4665
4666void Context::linkProgram(GLuint program)
4667{
4668 Program *programObject = getProgram(program);
4669 ASSERT(programObject);
4670 handleError(programObject->link(this));
Martin Radev0abb7a22017-08-28 15:34:45 +03004671 mGLState.onProgramExecutableChange(programObject);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004672}
4673
4674void Context::releaseShaderCompiler()
4675{
Jamie Madill4928b7c2017-06-20 12:57:39 -04004676 mCompiler.set(this, nullptr);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004677}
4678
4679void Context::shaderBinary(GLsizei n,
4680 const GLuint *shaders,
4681 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04004682 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004683 GLsizei length)
4684{
4685 // No binary shader formats are supported.
4686 UNIMPLEMENTED();
4687}
4688
4689void Context::shaderSource(GLuint shader,
4690 GLsizei count,
4691 const GLchar *const *string,
4692 const GLint *length)
4693{
4694 Shader *shaderObject = getShader(shader);
4695 ASSERT(shaderObject);
4696 shaderObject->setSource(count, string, length);
4697}
4698
4699void Context::stencilFunc(GLenum func, GLint ref, GLuint mask)
4700{
4701 stencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
4702}
4703
4704void Context::stencilMask(GLuint mask)
4705{
4706 stencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4707}
4708
4709void Context::stencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4710{
4711 stencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4712}
4713
4714void Context::uniform1f(GLint location, GLfloat x)
4715{
4716 Program *program = mGLState.getProgram();
4717 program->setUniform1fv(location, 1, &x);
4718}
4719
4720void Context::uniform1fv(GLint location, GLsizei count, const GLfloat *v)
4721{
4722 Program *program = mGLState.getProgram();
4723 program->setUniform1fv(location, count, v);
4724}
4725
4726void Context::uniform1i(GLint location, GLint x)
4727{
4728 Program *program = mGLState.getProgram();
Jamie Madill81c2e252017-09-09 23:32:46 -04004729 if (program->setUniform1iv(location, 1, &x) == Program::SetUniformResult::SamplerChanged)
4730 {
4731 mGLState.setObjectDirty(GL_PROGRAM);
4732 }
Jamie Madillc1d770e2017-04-13 17:31:24 -04004733}
4734
4735void Context::uniform1iv(GLint location, GLsizei count, const GLint *v)
4736{
4737 Program *program = mGLState.getProgram();
Jamie Madill81c2e252017-09-09 23:32:46 -04004738 if (program->setUniform1iv(location, count, v) == Program::SetUniformResult::SamplerChanged)
4739 {
4740 mGLState.setObjectDirty(GL_PROGRAM);
4741 }
Jamie Madillc1d770e2017-04-13 17:31:24 -04004742}
4743
4744void Context::uniform2f(GLint location, GLfloat x, GLfloat y)
4745{
4746 GLfloat xy[2] = {x, y};
4747 Program *program = mGLState.getProgram();
4748 program->setUniform2fv(location, 1, xy);
4749}
4750
4751void Context::uniform2fv(GLint location, GLsizei count, const GLfloat *v)
4752{
4753 Program *program = mGLState.getProgram();
4754 program->setUniform2fv(location, count, v);
4755}
4756
4757void Context::uniform2i(GLint location, GLint x, GLint y)
4758{
4759 GLint xy[2] = {x, y};
4760 Program *program = mGLState.getProgram();
4761 program->setUniform2iv(location, 1, xy);
4762}
4763
4764void Context::uniform2iv(GLint location, GLsizei count, const GLint *v)
4765{
4766 Program *program = mGLState.getProgram();
4767 program->setUniform2iv(location, count, v);
4768}
4769
4770void Context::uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4771{
4772 GLfloat xyz[3] = {x, y, z};
4773 Program *program = mGLState.getProgram();
4774 program->setUniform3fv(location, 1, xyz);
4775}
4776
4777void Context::uniform3fv(GLint location, GLsizei count, const GLfloat *v)
4778{
4779 Program *program = mGLState.getProgram();
4780 program->setUniform3fv(location, count, v);
4781}
4782
4783void Context::uniform3i(GLint location, GLint x, GLint y, GLint z)
4784{
4785 GLint xyz[3] = {x, y, z};
4786 Program *program = mGLState.getProgram();
4787 program->setUniform3iv(location, 1, xyz);
4788}
4789
4790void Context::uniform3iv(GLint location, GLsizei count, const GLint *v)
4791{
4792 Program *program = mGLState.getProgram();
4793 program->setUniform3iv(location, count, v);
4794}
4795
4796void Context::uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4797{
4798 GLfloat xyzw[4] = {x, y, z, w};
4799 Program *program = mGLState.getProgram();
4800 program->setUniform4fv(location, 1, xyzw);
4801}
4802
4803void Context::uniform4fv(GLint location, GLsizei count, const GLfloat *v)
4804{
4805 Program *program = mGLState.getProgram();
4806 program->setUniform4fv(location, count, v);
4807}
4808
4809void Context::uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4810{
4811 GLint xyzw[4] = {x, y, z, w};
4812 Program *program = mGLState.getProgram();
4813 program->setUniform4iv(location, 1, xyzw);
4814}
4815
4816void Context::uniform4iv(GLint location, GLsizei count, const GLint *v)
4817{
4818 Program *program = mGLState.getProgram();
4819 program->setUniform4iv(location, count, v);
4820}
4821
4822void Context::uniformMatrix2fv(GLint location,
4823 GLsizei count,
4824 GLboolean transpose,
4825 const GLfloat *value)
4826{
4827 Program *program = mGLState.getProgram();
4828 program->setUniformMatrix2fv(location, count, transpose, value);
4829}
4830
4831void Context::uniformMatrix3fv(GLint location,
4832 GLsizei count,
4833 GLboolean transpose,
4834 const GLfloat *value)
4835{
4836 Program *program = mGLState.getProgram();
4837 program->setUniformMatrix3fv(location, count, transpose, value);
4838}
4839
4840void Context::uniformMatrix4fv(GLint location,
4841 GLsizei count,
4842 GLboolean transpose,
4843 const GLfloat *value)
4844{
4845 Program *program = mGLState.getProgram();
4846 program->setUniformMatrix4fv(location, count, transpose, value);
4847}
4848
4849void Context::validateProgram(GLuint program)
4850{
4851 Program *programObject = getProgram(program);
4852 ASSERT(programObject);
4853 programObject->validate(mCaps);
4854}
4855
Jamie Madilld04908b2017-06-09 14:15:35 -04004856void Context::getProgramBinary(GLuint program,
4857 GLsizei bufSize,
4858 GLsizei *length,
4859 GLenum *binaryFormat,
4860 void *binary)
4861{
4862 Program *programObject = getProgram(program);
4863 ASSERT(programObject != nullptr);
4864
4865 handleError(programObject->saveBinary(this, binaryFormat, binary, bufSize, length));
4866}
4867
4868void Context::programBinary(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length)
4869{
4870 Program *programObject = getProgram(program);
4871 ASSERT(programObject != nullptr);
Jamie Madillb6664922017-07-25 12:55:04 -04004872
Jamie Madilld04908b2017-06-09 14:15:35 -04004873 handleError(programObject->loadBinary(this, binaryFormat, binary, length));
4874}
4875
Jamie Madillff325f12017-08-26 15:06:05 -04004876void Context::uniform1ui(GLint location, GLuint v0)
4877{
4878 Program *program = mGLState.getProgram();
4879 program->setUniform1uiv(location, 1, &v0);
4880}
4881
4882void Context::uniform2ui(GLint location, GLuint v0, GLuint v1)
4883{
4884 Program *program = mGLState.getProgram();
4885 const GLuint xy[] = {v0, v1};
4886 program->setUniform2uiv(location, 1, xy);
4887}
4888
4889void Context::uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
4890{
4891 Program *program = mGLState.getProgram();
4892 const GLuint xyz[] = {v0, v1, v2};
4893 program->setUniform3uiv(location, 1, xyz);
4894}
4895
4896void Context::uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
4897{
4898 Program *program = mGLState.getProgram();
4899 const GLuint xyzw[] = {v0, v1, v2, v3};
4900 program->setUniform4uiv(location, 1, xyzw);
4901}
4902
4903void Context::uniform1uiv(GLint location, GLsizei count, const GLuint *value)
4904{
4905 Program *program = mGLState.getProgram();
4906 program->setUniform1uiv(location, count, value);
4907}
4908void Context::uniform2uiv(GLint location, GLsizei count, const GLuint *value)
4909{
4910 Program *program = mGLState.getProgram();
4911 program->setUniform2uiv(location, count, value);
4912}
4913
4914void Context::uniform3uiv(GLint location, GLsizei count, const GLuint *value)
4915{
4916 Program *program = mGLState.getProgram();
4917 program->setUniform3uiv(location, count, value);
4918}
4919
4920void Context::uniform4uiv(GLint location, GLsizei count, const GLuint *value)
4921{
4922 Program *program = mGLState.getProgram();
4923 program->setUniform4uiv(location, count, value);
4924}
4925
Jamie Madillf0e04492017-08-26 15:28:42 -04004926void Context::genQueries(GLsizei n, GLuint *ids)
4927{
4928 for (GLsizei i = 0; i < n; i++)
4929 {
4930 GLuint handle = mQueryHandleAllocator.allocate();
4931 mQueryMap.assign(handle, nullptr);
4932 ids[i] = handle;
4933 }
4934}
4935
4936void Context::deleteQueries(GLsizei n, const GLuint *ids)
4937{
4938 for (int i = 0; i < n; i++)
4939 {
4940 GLuint query = ids[i];
4941
4942 Query *queryObject = nullptr;
4943 if (mQueryMap.erase(query, &queryObject))
4944 {
4945 mQueryHandleAllocator.release(query);
4946 if (queryObject)
4947 {
4948 queryObject->release(this);
4949 }
4950 }
4951 }
4952}
4953
4954GLboolean Context::isQuery(GLuint id)
4955{
4956 return (getQuery(id, false, GL_NONE) != nullptr) ? GL_TRUE : GL_FALSE;
4957}
4958
Jamie Madillc8c95812017-08-26 18:40:09 -04004959void Context::uniformMatrix2x3fv(GLint location,
4960 GLsizei count,
4961 GLboolean transpose,
4962 const GLfloat *value)
4963{
4964 Program *program = mGLState.getProgram();
4965 program->setUniformMatrix2x3fv(location, count, transpose, value);
4966}
4967
4968void Context::uniformMatrix3x2fv(GLint location,
4969 GLsizei count,
4970 GLboolean transpose,
4971 const GLfloat *value)
4972{
4973 Program *program = mGLState.getProgram();
4974 program->setUniformMatrix3x2fv(location, count, transpose, value);
4975}
4976
4977void Context::uniformMatrix2x4fv(GLint location,
4978 GLsizei count,
4979 GLboolean transpose,
4980 const GLfloat *value)
4981{
4982 Program *program = mGLState.getProgram();
4983 program->setUniformMatrix2x4fv(location, count, transpose, value);
4984}
4985
4986void Context::uniformMatrix4x2fv(GLint location,
4987 GLsizei count,
4988 GLboolean transpose,
4989 const GLfloat *value)
4990{
4991 Program *program = mGLState.getProgram();
4992 program->setUniformMatrix4x2fv(location, count, transpose, value);
4993}
4994
4995void Context::uniformMatrix3x4fv(GLint location,
4996 GLsizei count,
4997 GLboolean transpose,
4998 const GLfloat *value)
4999{
5000 Program *program = mGLState.getProgram();
5001 program->setUniformMatrix3x4fv(location, count, transpose, value);
5002}
5003
5004void Context::uniformMatrix4x3fv(GLint location,
5005 GLsizei count,
5006 GLboolean transpose,
5007 const GLfloat *value)
5008{
5009 Program *program = mGLState.getProgram();
5010 program->setUniformMatrix4x3fv(location, count, transpose, value);
5011}
5012
Jamie Madilld7576732017-08-26 18:49:50 -04005013void Context::deleteVertexArrays(GLsizei n, const GLuint *arrays)
5014{
5015 for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
5016 {
5017 GLuint vertexArray = arrays[arrayIndex];
5018
5019 if (arrays[arrayIndex] != 0)
5020 {
5021 VertexArray *vertexArrayObject = nullptr;
5022 if (mVertexArrayMap.erase(vertexArray, &vertexArrayObject))
5023 {
5024 if (vertexArrayObject != nullptr)
5025 {
5026 detachVertexArray(vertexArray);
5027 vertexArrayObject->onDestroy(this);
5028 }
5029
5030 mVertexArrayHandleAllocator.release(vertexArray);
5031 }
5032 }
5033 }
5034}
5035
5036void Context::genVertexArrays(GLsizei n, GLuint *arrays)
5037{
5038 for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
5039 {
5040 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
5041 mVertexArrayMap.assign(vertexArray, nullptr);
5042 arrays[arrayIndex] = vertexArray;
5043 }
5044}
5045
5046bool Context::isVertexArray(GLuint array)
5047{
5048 if (array == 0)
5049 {
5050 return GL_FALSE;
5051 }
5052
5053 VertexArray *vao = getVertexArray(array);
5054 return (vao != nullptr ? GL_TRUE : GL_FALSE);
5055}
5056
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04005057void Context::endTransformFeedback()
5058{
5059 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
5060 transformFeedback->end(this);
5061}
5062
5063void Context::transformFeedbackVaryings(GLuint program,
5064 GLsizei count,
5065 const GLchar *const *varyings,
5066 GLenum bufferMode)
5067{
5068 Program *programObject = getProgram(program);
5069 ASSERT(programObject);
5070 programObject->setTransformFeedbackVaryings(count, varyings, bufferMode);
5071}
5072
5073void Context::getTransformFeedbackVarying(GLuint program,
5074 GLuint index,
5075 GLsizei bufSize,
5076 GLsizei *length,
5077 GLsizei *size,
5078 GLenum *type,
5079 GLchar *name)
5080{
5081 Program *programObject = getProgram(program);
5082 ASSERT(programObject);
5083 programObject->getTransformFeedbackVarying(index, bufSize, length, size, type, name);
5084}
5085
5086void Context::deleteTransformFeedbacks(GLsizei n, const GLuint *ids)
5087{
5088 for (int i = 0; i < n; i++)
5089 {
5090 GLuint transformFeedback = ids[i];
5091 if (transformFeedback == 0)
5092 {
5093 continue;
5094 }
5095
5096 TransformFeedback *transformFeedbackObject = nullptr;
5097 if (mTransformFeedbackMap.erase(transformFeedback, &transformFeedbackObject))
5098 {
5099 if (transformFeedbackObject != nullptr)
5100 {
5101 detachTransformFeedback(transformFeedback);
5102 transformFeedbackObject->release(this);
5103 }
5104
5105 mTransformFeedbackHandleAllocator.release(transformFeedback);
5106 }
5107 }
5108}
5109
5110void Context::genTransformFeedbacks(GLsizei n, GLuint *ids)
5111{
5112 for (int i = 0; i < n; i++)
5113 {
5114 GLuint transformFeedback = mTransformFeedbackHandleAllocator.allocate();
5115 mTransformFeedbackMap.assign(transformFeedback, nullptr);
5116 ids[i] = transformFeedback;
5117 }
5118}
5119
5120bool Context::isTransformFeedback(GLuint id)
5121{
5122 if (id == 0)
5123 {
5124 // The 3.0.4 spec [section 6.1.11] states that if ID is zero, IsTransformFeedback
5125 // returns FALSE
5126 return GL_FALSE;
5127 }
5128
5129 const TransformFeedback *transformFeedback = getTransformFeedback(id);
5130 return ((transformFeedback != nullptr) ? GL_TRUE : GL_FALSE);
5131}
5132
5133void Context::pauseTransformFeedback()
5134{
5135 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
5136 transformFeedback->pause();
5137}
5138
5139void Context::resumeTransformFeedback()
5140{
5141 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
5142 transformFeedback->resume();
5143}
5144
Jamie Madill12e957f2017-08-26 21:42:26 -04005145void Context::getUniformuiv(GLuint program, GLint location, GLuint *params)
5146{
5147 const Program *programObject = getProgram(program);
Jamie Madill54164b02017-08-28 15:17:37 -04005148 programObject->getUniformuiv(this, location, params);
Jamie Madill12e957f2017-08-26 21:42:26 -04005149}
5150
5151GLint Context::getFragDataLocation(GLuint program, const GLchar *name)
5152{
5153 const Program *programObject = getProgram(program);
5154 return programObject->getFragDataLocation(name);
5155}
5156
5157void Context::getUniformIndices(GLuint program,
5158 GLsizei uniformCount,
5159 const GLchar *const *uniformNames,
5160 GLuint *uniformIndices)
5161{
5162 const Program *programObject = getProgram(program);
5163 if (!programObject->isLinked())
5164 {
5165 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
5166 {
5167 uniformIndices[uniformId] = GL_INVALID_INDEX;
5168 }
5169 }
5170 else
5171 {
5172 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
5173 {
5174 uniformIndices[uniformId] = programObject->getUniformIndex(uniformNames[uniformId]);
5175 }
5176 }
5177}
5178
5179void Context::getActiveUniformsiv(GLuint program,
5180 GLsizei uniformCount,
5181 const GLuint *uniformIndices,
5182 GLenum pname,
5183 GLint *params)
5184{
5185 const Program *programObject = getProgram(program);
5186 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
5187 {
5188 const GLuint index = uniformIndices[uniformId];
5189 params[uniformId] = programObject->getActiveUniformi(index, pname);
5190 }
5191}
5192
5193GLuint Context::getUniformBlockIndex(GLuint program, const GLchar *uniformBlockName)
5194{
5195 const Program *programObject = getProgram(program);
5196 return programObject->getUniformBlockIndex(uniformBlockName);
5197}
5198
5199void Context::getActiveUniformBlockiv(GLuint program,
5200 GLuint uniformBlockIndex,
5201 GLenum pname,
5202 GLint *params)
5203{
5204 const Program *programObject = getProgram(program);
5205 QueryActiveUniformBlockiv(programObject, uniformBlockIndex, pname, params);
5206}
5207
5208void Context::getActiveUniformBlockName(GLuint program,
5209 GLuint uniformBlockIndex,
5210 GLsizei bufSize,
5211 GLsizei *length,
5212 GLchar *uniformBlockName)
5213{
5214 const Program *programObject = getProgram(program);
5215 programObject->getActiveUniformBlockName(uniformBlockIndex, bufSize, length, uniformBlockName);
5216}
5217
5218void Context::uniformBlockBinding(GLuint program,
5219 GLuint uniformBlockIndex,
5220 GLuint uniformBlockBinding)
5221{
5222 Program *programObject = getProgram(program);
5223 programObject->bindUniformBlock(uniformBlockIndex, uniformBlockBinding);
5224}
5225
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005226GLsync Context::fenceSync(GLenum condition, GLbitfield flags)
5227{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005228 GLuint handle = mState.mSyncs->createSync(mImplementation.get());
5229 GLsync syncHandle = reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005230
Jamie Madill70b5bb02017-08-28 13:32:37 -04005231 Sync *syncObject = getSync(syncHandle);
5232 Error error = syncObject->set(condition, flags);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005233 if (error.isError())
5234 {
Jamie Madill70b5bb02017-08-28 13:32:37 -04005235 deleteSync(syncHandle);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005236 handleError(error);
5237 return nullptr;
5238 }
5239
Jamie Madill70b5bb02017-08-28 13:32:37 -04005240 return syncHandle;
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005241}
5242
5243GLboolean Context::isSync(GLsync sync)
5244{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005245 return (getSync(sync) != nullptr);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005246}
5247
5248GLenum Context::clientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
5249{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005250 Sync *syncObject = getSync(sync);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005251
5252 GLenum result = GL_WAIT_FAILED;
5253 handleError(syncObject->clientWait(flags, timeout, &result));
5254 return result;
5255}
5256
5257void Context::waitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
5258{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005259 Sync *syncObject = getSync(sync);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005260 handleError(syncObject->serverWait(flags, timeout));
5261}
5262
5263void Context::getInteger64v(GLenum pname, GLint64 *params)
5264{
5265 GLenum nativeType = GL_NONE;
5266 unsigned int numParams = 0;
5267 getQueryParameterInfo(pname, &nativeType, &numParams);
5268
5269 if (nativeType == GL_INT_64_ANGLEX)
5270 {
5271 getInteger64vImpl(pname, params);
5272 }
5273 else
5274 {
5275 CastStateValues(this, nativeType, pname, numParams, params);
5276 }
5277}
5278
Jamie Madill3ef140a2017-08-26 23:11:21 -04005279void Context::getBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params)
5280{
5281 Buffer *buffer = mGLState.getTargetBuffer(target);
5282 QueryBufferParameteri64v(buffer, pname, params);
5283}
5284
5285void Context::genSamplers(GLsizei count, GLuint *samplers)
5286{
5287 for (int i = 0; i < count; i++)
5288 {
5289 samplers[i] = mState.mSamplers->createSampler();
5290 }
5291}
5292
5293void Context::deleteSamplers(GLsizei count, const GLuint *samplers)
5294{
5295 for (int i = 0; i < count; i++)
5296 {
5297 GLuint sampler = samplers[i];
5298
5299 if (mState.mSamplers->getSampler(sampler))
5300 {
5301 detachSampler(sampler);
5302 }
5303
5304 mState.mSamplers->deleteObject(this, sampler);
5305 }
5306}
5307
5308void Context::getInternalformativ(GLenum target,
5309 GLenum internalformat,
5310 GLenum pname,
5311 GLsizei bufSize,
5312 GLint *params)
5313{
5314 const TextureCaps &formatCaps = mTextureCaps.get(internalformat);
5315 QueryInternalFormativ(formatCaps, pname, bufSize, params);
5316}
5317
Jamie Madill81c2e252017-09-09 23:32:46 -04005318void Context::programUniform1iv(GLuint program, GLint location, GLsizei count, const GLint *value)
5319{
5320 Program *programObject = getProgram(program);
5321 ASSERT(programObject);
5322 if (programObject->setUniform1iv(location, count, value) ==
5323 Program::SetUniformResult::SamplerChanged)
5324 {
5325 mGLState.setObjectDirty(GL_PROGRAM);
5326 }
5327}
5328
5329void Context::onTextureChange(const Texture *texture)
5330{
5331 // Conservatively assume all textures are dirty.
5332 // TODO(jmadill): More fine-grained update.
5333 mGLState.setObjectDirty(GL_TEXTURE);
5334}
5335
Yunchao Hea336b902017-08-02 16:05:21 +08005336void Context::genProgramPipelines(GLsizei count, GLuint *pipelines)
5337{
5338 for (int i = 0; i < count; i++)
5339 {
5340 pipelines[i] = createProgramPipeline();
5341 }
5342}
5343
5344void Context::deleteProgramPipelines(GLsizei count, const GLuint *pipelines)
5345{
5346 for (int i = 0; i < count; i++)
5347 {
5348 if (pipelines[i] != 0)
5349 {
5350 deleteProgramPipeline(pipelines[i]);
5351 }
5352 }
5353}
5354
5355GLboolean Context::isProgramPipeline(GLuint pipeline)
5356{
5357 if (pipeline == 0)
5358 {
5359 return GL_FALSE;
5360 }
5361
5362 return (getProgramPipeline(pipeline) ? GL_TRUE : GL_FALSE);
5363}
5364
Jamie Madillc29968b2016-01-20 11:17:23 -05005365} // namespace gl