blob: 52c217632c0c62f294bd36e22617ff67b2163829 [file] [log] [blame]
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001//
Geoff Langeeba6e12014-02-03 13:12:30 -05002// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// Context.cpp: Implements the gl::Context class, managing all GL state and performing
8// rendering operations. It is the GLES2 specific implementation of EGLContext.
9
Geoff Lang2b5420c2014-11-19 14:20:15 -050010#include "libANGLE/Context.h"
apatrick@chromium.org144f2802012-07-12 01:42:34 +000011
Jamie Madill231c7f52017-04-26 13:45:37 -040012#include <string.h>
Jamie Madillb9293972015-02-19 11:07:54 -050013#include <iterator>
14#include <sstream>
Sami Väisänend59ca052016-06-21 16:10:00 +030015#include <vector>
Jamie Madillb9293972015-02-19 11:07:54 -050016
Sami Väisänene45e53b2016-05-25 10:36:04 +030017#include "common/matrix_utils.h"
Geoff Lang0b7eef72014-06-12 14:10:47 -040018#include "common/platform.h"
Jamie Madillb9293972015-02-19 11:07:54 -050019#include "common/utilities.h"
Geoff Langc339c4e2016-11-29 10:37:36 -050020#include "common/version.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050021#include "libANGLE/Buffer.h"
Jamie Madillb9293972015-02-19 11:07:54 -050022#include "libANGLE/Compiler.h"
Jamie Madill948bbe52017-06-01 13:10:42 -040023#include "libANGLE/Display.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050024#include "libANGLE/Fence.h"
25#include "libANGLE/Framebuffer.h"
26#include "libANGLE/FramebufferAttachment.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030027#include "libANGLE/Path.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050028#include "libANGLE/Program.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050029#include "libANGLE/Query.h"
Jamie Madillb9293972015-02-19 11:07:54 -050030#include "libANGLE/Renderbuffer.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050031#include "libANGLE/ResourceManager.h"
32#include "libANGLE/Sampler.h"
Jamie Madill9dd0cf02014-11-24 11:38:51 -050033#include "libANGLE/Surface.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050034#include "libANGLE/Texture.h"
35#include "libANGLE/TransformFeedback.h"
36#include "libANGLE/VertexArray.h"
Kenneth Russellf2f6f652016-10-05 19:53:23 -070037#include "libANGLE/Workarounds.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040038#include "libANGLE/formatutils.h"
Martin Radev66fb8202016-07-28 11:45:20 +030039#include "libANGLE/queryconversions.h"
Geoff Langc1984ed2016-10-07 12:41:00 -040040#include "libANGLE/queryutils.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040041#include "libANGLE/renderer/ContextImpl.h"
42#include "libANGLE/renderer/EGLImplFactory.h"
43#include "libANGLE/validationES.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000044
Geoff Langf6db0982015-08-25 13:04:00 -040045namespace
46{
47
Ian Ewell3ffd78b2016-01-22 16:09:42 -050048template <typename T>
Geoff Lang4ddf5af2016-12-01 14:30:44 -050049std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
Sami Väisänend59ca052016-06-21 16:10:00 +030050 GLsizei numPaths,
51 const void *paths,
52 GLuint pathBase)
53{
54 std::vector<gl::Path *> ret;
55 ret.reserve(numPaths);
56
57 const auto *nameArray = static_cast<const T *>(paths);
58
59 for (GLsizei i = 0; i < numPaths; ++i)
60 {
61 const GLuint pathName = nameArray[i] + pathBase;
62
63 ret.push_back(resourceManager.getPath(pathName));
64 }
65
66 return ret;
67}
68
Geoff Lang4ddf5af2016-12-01 14:30:44 -050069std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
Sami Väisänend59ca052016-06-21 16:10:00 +030070 GLsizei numPaths,
71 GLenum pathNameType,
72 const void *paths,
73 GLuint pathBase)
74{
75 switch (pathNameType)
76 {
77 case GL_UNSIGNED_BYTE:
78 return GatherPaths<GLubyte>(resourceManager, numPaths, paths, pathBase);
79
80 case GL_BYTE:
81 return GatherPaths<GLbyte>(resourceManager, numPaths, paths, pathBase);
82
83 case GL_UNSIGNED_SHORT:
84 return GatherPaths<GLushort>(resourceManager, numPaths, paths, pathBase);
85
86 case GL_SHORT:
87 return GatherPaths<GLshort>(resourceManager, numPaths, paths, pathBase);
88
89 case GL_UNSIGNED_INT:
90 return GatherPaths<GLuint>(resourceManager, numPaths, paths, pathBase);
91
92 case GL_INT:
93 return GatherPaths<GLint>(resourceManager, numPaths, paths, pathBase);
94 }
95
96 UNREACHABLE();
97 return std::vector<gl::Path *>();
98}
99
100template <typename T>
Geoff Lang2186c382016-10-14 10:54:54 -0400101gl::Error GetQueryObjectParameter(gl::Query *query, GLenum pname, T *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500102{
Geoff Lang2186c382016-10-14 10:54:54 -0400103 ASSERT(query != nullptr);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500104
105 switch (pname)
106 {
107 case GL_QUERY_RESULT_EXT:
Geoff Lang2186c382016-10-14 10:54:54 -0400108 return query->getResult(params);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500109 case GL_QUERY_RESULT_AVAILABLE_EXT:
110 {
111 bool available;
Geoff Lang2186c382016-10-14 10:54:54 -0400112 gl::Error error = query->isResultAvailable(&available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500113 if (!error.isError())
114 {
Geoff Lang2186c382016-10-14 10:54:54 -0400115 *params = gl::ConvertFromGLboolean<T>(available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500116 }
117 return error;
118 }
119 default:
120 UNREACHABLE();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500121 return gl::InternalError() << "Unreachable Error";
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500122 }
123}
124
Geoff Langf6db0982015-08-25 13:04:00 -0400125void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback)
126{
Geoff Lang1a683462015-09-29 15:09:59 -0400127 if (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
Geoff Langf6db0982015-08-25 13:04:00 -0400128 {
129 for (size_t tfBufferIndex = 0; tfBufferIndex < transformFeedback->getIndexedBufferCount();
130 tfBufferIndex++)
131 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400132 const gl::OffsetBindingPointer<gl::Buffer> &buffer =
Geoff Langf6db0982015-08-25 13:04:00 -0400133 transformFeedback->getIndexedBuffer(tfBufferIndex);
134 if (buffer.get() != nullptr)
135 {
136 buffer->onTransformFeedback();
137 }
138 }
139 }
140}
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500141
142// Attribute map queries.
Martin Radev1be913c2016-07-11 17:59:16 +0300143EGLint GetClientMajorVersion(const egl::AttributeMap &attribs)
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500144{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400145 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1));
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500146}
147
Martin Radev1be913c2016-07-11 17:59:16 +0300148EGLint GetClientMinorVersion(const egl::AttributeMap &attribs)
149{
150 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_MINOR_VERSION, 0));
151}
152
Geoff Langeb66a6e2016-10-31 13:06:12 -0400153gl::Version GetClientVersion(const egl::AttributeMap &attribs)
154{
155 return gl::Version(GetClientMajorVersion(attribs), GetClientMinorVersion(attribs));
156}
157
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500158GLenum GetResetStrategy(const egl::AttributeMap &attribs)
159{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400160 EGLAttrib attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
161 EGL_NO_RESET_NOTIFICATION_EXT);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500162 switch (attrib)
163 {
164 case EGL_NO_RESET_NOTIFICATION:
165 return GL_NO_RESET_NOTIFICATION_EXT;
166 case EGL_LOSE_CONTEXT_ON_RESET:
167 return GL_LOSE_CONTEXT_ON_RESET_EXT;
168 default:
169 UNREACHABLE();
170 return GL_NONE;
171 }
172}
173
174bool GetRobustAccess(const egl::AttributeMap &attribs)
175{
Geoff Lang077f20a2016-11-01 10:08:02 -0400176 return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE) ||
177 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) !=
178 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500179}
180
181bool GetDebug(const egl::AttributeMap &attribs)
182{
Geoff Lang077f20a2016-11-01 10:08:02 -0400183 return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE) ||
184 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR) != 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500185}
186
187bool GetNoError(const egl::AttributeMap &attribs)
188{
189 return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
190}
191
Geoff Langc287ea62016-09-16 14:46:51 -0400192bool GetWebGLContext(const egl::AttributeMap &attribs)
193{
194 return (attribs.get(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE, EGL_FALSE) == EGL_TRUE);
195}
196
Geoff Langf41a7152016-09-19 15:11:17 -0400197bool GetBindGeneratesResource(const egl::AttributeMap &attribs)
198{
199 return (attribs.get(EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE) == EGL_TRUE);
200}
201
Geoff Langfeb8c682017-02-13 16:07:35 -0500202bool GetClientArraysEnabled(const egl::AttributeMap &attribs)
203{
204 return (attribs.get(EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE, EGL_TRUE) == EGL_TRUE);
205}
206
Martin Radev9d901792016-07-15 15:58:58 +0300207std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
208{
209 std::string labelName;
210 if (label != nullptr)
211 {
212 size_t labelLength = length < 0 ? strlen(label) : length;
213 labelName = std::string(label, labelLength);
214 }
215 return labelName;
216}
217
218void GetObjectLabelBase(const std::string &objectLabel,
219 GLsizei bufSize,
220 GLsizei *length,
221 GLchar *label)
222{
223 size_t writeLength = objectLabel.length();
224 if (label != nullptr && bufSize > 0)
225 {
226 writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
227 std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
228 label[writeLength] = '\0';
229 }
230
231 if (length != nullptr)
232 {
233 *length = static_cast<GLsizei>(writeLength);
234 }
235}
236
Geoff Langf6db0982015-08-25 13:04:00 -0400237} // anonymous namespace
238
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000239namespace gl
240{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000241
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400242Context::Context(rx::EGLImplFactory *implFactory,
243 const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400244 const Context *shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500245 TextureManager *shareTextures,
Jamie Madill32447362017-06-28 14:53:52 -0400246 MemoryProgramCache *memoryProgramCache,
Corentin Wallezc295e512017-01-27 17:47:50 -0500247 const egl::AttributeMap &attribs,
Jamie Madill948bbe52017-06-01 13:10:42 -0400248 const egl::DisplayExtensions &displayExtensions,
249 bool robustResourceInit)
Martin Radev1be913c2016-07-11 17:59:16 +0300250
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500251 : ValidationContext(shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500252 shareTextures,
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500253 GetClientVersion(attribs),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700254 &mGLState,
Jamie Madillf25855c2015-11-03 11:06:18 -0500255 mCaps,
256 mTextureCaps,
257 mExtensions,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500258 mLimitations,
259 GetNoError(attribs)),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700260 mImplementation(implFactory->createContext(mState)),
Jamie Madill2f348d22017-06-05 10:50:59 -0400261 mCompiler(),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400262 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500263 mClientType(EGL_OPENGL_ES_API),
264 mHasBeenCurrent(false),
265 mContextLost(false),
266 mResetStatus(GL_NO_ERROR),
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700267 mContextLostForced(false),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500268 mResetStrategy(GetResetStrategy(attribs)),
269 mRobustAccess(GetRobustAccess(attribs)),
Jamie Madill61e16b42017-06-19 11:13:23 -0400270 mCurrentSurface(static_cast<egl::Surface *>(EGL_NO_SURFACE)),
271 mCurrentDisplay(static_cast<egl::Display *>(EGL_NO_DISPLAY)),
Jamie Madill4e0e6f82017-02-17 11:06:03 -0500272 mSurfacelessFramebuffer(nullptr),
Jamie Madille14951e2017-03-09 18:55:16 -0500273 mWebGLContext(GetWebGLContext(attribs)),
Jamie Madill32447362017-06-28 14:53:52 -0400274 mMemoryProgramCache(memoryProgramCache),
Jamie Madille14951e2017-03-09 18:55:16 -0500275 mScratchBuffer(1000u)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000276{
Geoff Lang077f20a2016-11-01 10:08:02 -0400277 if (mRobustAccess)
278 {
279 UNIMPLEMENTED();
280 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000281
Jamie Madill4e0e6f82017-02-17 11:06:03 -0500282 initCaps(displayExtensions);
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700283 initWorkarounds();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400284
Jamie Madill4928b7c2017-06-20 12:57:39 -0400285 mGLState.initialize(this, GetDebug(attribs), GetBindGeneratesResource(attribs),
Jamie Madillc43be722017-07-13 16:22:14 -0400286 GetClientArraysEnabled(attribs), robustResourceInit,
287 mMemoryProgramCache != nullptr);
Régis Fénéon83107972015-02-05 12:57:44 +0100288
Shannon Woods53a94a82014-06-24 15:20:36 -0400289 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400290
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000291 // [OpenGL ES 2.0.24] section 3.7 page 83:
292 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
293 // and cube map texture state vectors respectively associated with them.
294 // In order that access to these initial textures not be lost, they are treated as texture
295 // objects all of whose names are 0.
296
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400297 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400298 mZeroTextures[GL_TEXTURE_2D].set(this, zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500299
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400300 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400301 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(this, zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400302
Geoff Langeb66a6e2016-10-31 13:06:12 -0400303 if (getClientVersion() >= Version(3, 0))
Geoff Lang76b10c92014-09-05 16:28:14 -0400304 {
305 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400306 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400307 mZeroTextures[GL_TEXTURE_3D].set(this, zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400308
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400309 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400310 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(this, zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400311 }
Geoff Lang3b573612016-10-31 14:08:10 -0400312 if (getClientVersion() >= Version(3, 1))
313 {
314 Texture *zeroTexture2DMultisample =
315 new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_MULTISAMPLE);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400316 mZeroTextures[GL_TEXTURE_2D_MULTISAMPLE].set(this, zeroTexture2DMultisample);
Jiajia Qin6eafb042016-12-27 17:04:07 +0800317
318 bindGenericAtomicCounterBuffer(0);
319 for (unsigned int i = 0; i < mCaps.maxAtomicCounterBufferBindings; i++)
320 {
321 bindIndexedAtomicCounterBuffer(0, i, 0, 0);
322 }
Jiajia Qinf546e7d2017-03-27 14:12:59 +0800323
324 bindGenericShaderStorageBuffer(0);
325 for (unsigned int i = 0; i < mCaps.maxShaderStorageBufferBindings; i++)
326 {
327 bindIndexedShaderStorageBuffer(0, i, 0, 0);
328 }
Geoff Lang3b573612016-10-31 14:08:10 -0400329 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000330
Ian Ewellbda75592016-04-18 17:25:54 -0400331 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
332 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400333 Texture *zeroTextureExternal =
334 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400335 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(this, zeroTextureExternal);
Ian Ewellbda75592016-04-18 17:25:54 -0400336 }
337
Jamie Madill4928b7c2017-06-20 12:57:39 -0400338 mGLState.initializeZeroTextures(this, mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500339
Jamie Madill57a89722013-07-02 11:57:03 -0400340 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000341 bindArrayBuffer(0);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800342 bindDrawIndirectBuffer(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000343 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400344
Jamie Madill01a80ee2016-11-07 12:06:18 -0500345 bindRenderbuffer(GL_RENDERBUFFER, 0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000346
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000347 bindGenericUniformBuffer(0);
Geoff Lang4dc3af02016-11-18 14:09:27 -0500348 for (unsigned int i = 0; i < mCaps.maxUniformBufferBindings; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000349 {
350 bindIndexedUniformBuffer(0, i, 0, -1);
351 }
352
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000353 bindCopyReadBuffer(0);
354 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000355 bindPixelPackBuffer(0);
356 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000357
Geoff Langeb66a6e2016-10-31 13:06:12 -0400358 if (getClientVersion() >= Version(3, 0))
Geoff Lang1a683462015-09-29 15:09:59 -0400359 {
360 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
361 // In the initial state, a default transform feedback object is bound and treated as
362 // a transform feedback object with a name of zero. That object is bound any time
363 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400364 bindTransformFeedback(0);
365 }
Geoff Langc8058452014-02-03 12:04:11 -0500366
Jamie Madillad9f24e2016-02-12 09:27:24 -0500367 // Initialize dirty bit masks
368 // TODO(jmadill): additional ES3 state
369 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
370 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
371 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
372 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
373 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
374 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400375 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500376 // No dirty objects.
377
378 // Readpixels uses the pack state and read FBO
379 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
380 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
381 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
382 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
383 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400384 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500385 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
386
387 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
388 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
389 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
390 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
391 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
392 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
393 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
394 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
395 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
396 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
397 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
398 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
399
400 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
401 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700402 mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500403 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
404 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400405
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400406 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000407}
408
Jamie Madill4928b7c2017-06-20 12:57:39 -0400409egl::Error Context::onDestroy(const egl::Display *display)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000410{
Corentin Wallez80b24112015-08-25 16:41:57 -0400411 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000412 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400413 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000414 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400415 mFenceNVMap.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000416
Corentin Wallez80b24112015-08-25 16:41:57 -0400417 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000418 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400419 if (query.second != nullptr)
420 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400421 query.second->release(this);
Geoff Langf0aa8422015-09-29 15:08:34 -0400422 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000423 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400424 mQueryMap.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000425
Corentin Wallez80b24112015-08-25 16:41:57 -0400426 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400427 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400428 if (vertexArray.second)
429 {
430 vertexArray.second->onDestroy(this);
431 }
Jamie Madill57a89722013-07-02 11:57:03 -0400432 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400433 mVertexArrayMap.clear();
Jamie Madill57a89722013-07-02 11:57:03 -0400434
Corentin Wallez80b24112015-08-25 16:41:57 -0400435 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500436 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500437 if (transformFeedback.second != nullptr)
438 {
Jamie Madill6c1f6712017-02-14 19:08:04 -0500439 transformFeedback.second->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500440 }
Geoff Langc8058452014-02-03 12:04:11 -0500441 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400442 mTransformFeedbackMap.clear();
Geoff Langc8058452014-02-03 12:04:11 -0500443
Jamie Madilldedd7b92014-11-05 16:30:36 -0500444 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400445 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400446 zeroTexture.second->onDestroy(this);
447 zeroTexture.second.set(this, nullptr);
Geoff Lang76b10c92014-09-05 16:28:14 -0400448 }
449 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000450
Corentin Wallezccab69d2017-01-27 16:57:15 -0500451 SafeDelete(mSurfacelessFramebuffer);
452
Jamie Madill4928b7c2017-06-20 12:57:39 -0400453 ANGLE_TRY(releaseSurface(display));
Jamie Madill2f348d22017-06-05 10:50:59 -0400454 releaseShaderCompiler();
Jamie Madill6c1f6712017-02-14 19:08:04 -0500455
Jamie Madill4928b7c2017-06-20 12:57:39 -0400456 mGLState.reset(this);
457
Jamie Madill6c1f6712017-02-14 19:08:04 -0500458 mState.mBuffers->release(this);
459 mState.mShaderPrograms->release(this);
460 mState.mTextures->release(this);
461 mState.mRenderbuffers->release(this);
462 mState.mSamplers->release(this);
463 mState.mFenceSyncs->release(this);
464 mState.mPaths->release(this);
465 mState.mFramebuffers->release(this);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400466
467 return egl::NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000468}
469
Jamie Madill70ee0f62017-02-06 16:04:20 -0500470Context::~Context()
471{
472}
473
Jamie Madill4928b7c2017-06-20 12:57:39 -0400474egl::Error Context::makeCurrent(egl::Display *display, egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000475{
Jamie Madill61e16b42017-06-19 11:13:23 -0400476 mCurrentDisplay = display;
477
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000478 if (!mHasBeenCurrent)
479 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000480 initRendererString();
Geoff Langc339c4e2016-11-29 10:37:36 -0500481 initVersionStrings();
Geoff Langcec35902014-04-16 10:52:36 -0400482 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000483
Corentin Wallezc295e512017-01-27 17:47:50 -0500484 int width = 0;
485 int height = 0;
486 if (surface != nullptr)
487 {
488 width = surface->getWidth();
489 height = surface->getHeight();
490 }
491
492 mGLState.setViewportParams(0, 0, width, height);
493 mGLState.setScissorParams(0, 0, width, height);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000494
495 mHasBeenCurrent = true;
496 }
497
Jamie Madill1b94d432015-08-07 13:23:23 -0400498 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700499 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400500
Jamie Madill4928b7c2017-06-20 12:57:39 -0400501 ANGLE_TRY(releaseSurface(display));
Corentin Wallezccab69d2017-01-27 16:57:15 -0500502
503 Framebuffer *newDefault = nullptr;
504 if (surface != nullptr)
505 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400506 ANGLE_TRY(surface->setIsCurrent(this, true));
Corentin Wallezccab69d2017-01-27 16:57:15 -0500507 mCurrentSurface = surface;
508 newDefault = surface->getDefaultFramebuffer();
509 }
510 else
511 {
512 if (mSurfacelessFramebuffer == nullptr)
513 {
514 mSurfacelessFramebuffer = new Framebuffer(mImplementation.get());
515 }
516
517 newDefault = mSurfacelessFramebuffer;
518 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000519
Corentin Wallez37c39792015-08-20 14:19:46 -0400520 // Update default framebuffer, the binding of the previous default
521 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400522 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700523 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400524 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700525 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400526 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700527 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400528 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700529 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400530 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500531 mState.mFramebuffers->setDefaultFramebuffer(newDefault);
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400532 }
Ian Ewell292f0052016-02-04 10:37:32 -0500533
534 // Notify the renderer of a context switch
Jamie Madill4928b7c2017-06-20 12:57:39 -0400535 mImplementation->onMakeCurrent(this);
536 return egl::NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000537}
538
Jamie Madill4928b7c2017-06-20 12:57:39 -0400539egl::Error Context::releaseSurface(const egl::Display *display)
Jamie Madill77a72f62015-04-14 11:18:32 -0400540{
Corentin Wallez37c39792015-08-20 14:19:46 -0400541 // Remove the default framebuffer
Corentin Wallezc295e512017-01-27 17:47:50 -0500542 Framebuffer *currentDefault = nullptr;
543 if (mCurrentSurface != nullptr)
Corentin Wallez51706ea2015-08-07 14:39:22 -0400544 {
Corentin Wallezc295e512017-01-27 17:47:50 -0500545 currentDefault = mCurrentSurface->getDefaultFramebuffer();
546 }
547 else if (mSurfacelessFramebuffer != nullptr)
548 {
549 currentDefault = mSurfacelessFramebuffer;
Corentin Wallez51706ea2015-08-07 14:39:22 -0400550 }
551
Corentin Wallezc295e512017-01-27 17:47:50 -0500552 if (mGLState.getReadFramebuffer() == currentDefault)
553 {
554 mGLState.setReadFramebufferBinding(nullptr);
555 }
556 if (mGLState.getDrawFramebuffer() == currentDefault)
557 {
558 mGLState.setDrawFramebufferBinding(nullptr);
559 }
560 mState.mFramebuffers->setDefaultFramebuffer(nullptr);
561
562 if (mCurrentSurface)
563 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400564 ANGLE_TRY(mCurrentSurface->setIsCurrent(this, false));
Corentin Wallezc295e512017-01-27 17:47:50 -0500565 mCurrentSurface = nullptr;
566 }
Jamie Madill4928b7c2017-06-20 12:57:39 -0400567
568 return egl::NoError();
Jamie Madill77a72f62015-04-14 11:18:32 -0400569}
570
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000571GLuint Context::createBuffer()
572{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500573 return mState.mBuffers->createBuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000574}
575
576GLuint Context::createProgram()
577{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500578 return mState.mShaderPrograms->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000579}
580
581GLuint Context::createShader(GLenum type)
582{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500583 return mState.mShaderPrograms->createShader(mImplementation.get(), mLimitations, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000584}
585
586GLuint Context::createTexture()
587{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500588 return mState.mTextures->createTexture();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000589}
590
591GLuint Context::createRenderbuffer()
592{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500593 return mState.mRenderbuffers->createRenderbuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000594}
595
Geoff Lang882033e2014-09-30 11:26:07 -0400596GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400597{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500598 GLuint handle = mState.mFenceSyncs->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400599
Cooper Partind8e62a32015-01-29 15:21:25 -0800600 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400601}
602
Sami Väisänene45e53b2016-05-25 10:36:04 +0300603GLuint Context::createPaths(GLsizei range)
604{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500605 auto resultOrError = mState.mPaths->createPaths(mImplementation.get(), range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300606 if (resultOrError.isError())
607 {
608 handleError(resultOrError.getError());
609 return 0;
610 }
611 return resultOrError.getResult();
612}
613
Jamie Madill57a89722013-07-02 11:57:03 -0400614GLuint Context::createVertexArray()
615{
Jamie Madill96a483b2017-06-27 16:49:21 -0400616 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
617 mVertexArrayMap.assign(vertexArray, nullptr);
Geoff Lang36167ab2015-12-07 10:27:14 -0500618 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400619}
620
Jamie Madilldc356042013-07-19 16:36:57 -0400621GLuint Context::createSampler()
622{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500623 return mState.mSamplers->createSampler();
Jamie Madilldc356042013-07-19 16:36:57 -0400624}
625
Geoff Langc8058452014-02-03 12:04:11 -0500626GLuint Context::createTransformFeedback()
627{
Jamie Madill96a483b2017-06-27 16:49:21 -0400628 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
629 mTransformFeedbackMap.assign(transformFeedback, nullptr);
Geoff Lang36167ab2015-12-07 10:27:14 -0500630 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500631}
632
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000633// Returns an unused framebuffer name
634GLuint Context::createFramebuffer()
635{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500636 return mState.mFramebuffers->createFramebuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000637}
638
Jamie Madill33dc8432013-07-26 11:55:05 -0400639GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000640{
Jamie Madill33dc8432013-07-26 11:55:05 -0400641 GLuint handle = mFenceNVHandleAllocator.allocate();
Jamie Madill96a483b2017-06-27 16:49:21 -0400642 mFenceNVMap.assign(handle, new FenceNV(mImplementation->createFenceNV()));
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000643 return handle;
644}
645
646// Returns an unused query name
647GLuint Context::createQuery()
648{
649 GLuint handle = mQueryHandleAllocator.allocate();
Jamie Madill96a483b2017-06-27 16:49:21 -0400650 mQueryMap.assign(handle, nullptr);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000651 return handle;
652}
653
654void Context::deleteBuffer(GLuint buffer)
655{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500656 if (mState.mBuffers->getBuffer(buffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000657 {
658 detachBuffer(buffer);
659 }
Jamie Madill893ab082014-05-16 16:56:10 -0400660
Jamie Madill6c1f6712017-02-14 19:08:04 -0500661 mState.mBuffers->deleteObject(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000662}
663
664void Context::deleteShader(GLuint shader)
665{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500666 mState.mShaderPrograms->deleteShader(this, shader);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000667}
668
669void Context::deleteProgram(GLuint program)
670{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500671 mState.mShaderPrograms->deleteProgram(this, program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000672}
673
674void Context::deleteTexture(GLuint texture)
675{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500676 if (mState.mTextures->getTexture(texture))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000677 {
678 detachTexture(texture);
679 }
680
Jamie Madill6c1f6712017-02-14 19:08:04 -0500681 mState.mTextures->deleteObject(this, texture);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000682}
683
684void Context::deleteRenderbuffer(GLuint renderbuffer)
685{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500686 if (mState.mRenderbuffers->getRenderbuffer(renderbuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000687 {
688 detachRenderbuffer(renderbuffer);
689 }
Jamie Madill893ab082014-05-16 16:56:10 -0400690
Jamie Madill6c1f6712017-02-14 19:08:04 -0500691 mState.mRenderbuffers->deleteObject(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000692}
693
Jamie Madillcd055f82013-07-26 11:55:15 -0400694void Context::deleteFenceSync(GLsync fenceSync)
695{
696 // The spec specifies the underlying Fence object is not deleted until all current
697 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
698 // and since our API is currently designed for being called from a single thread, we can delete
699 // the fence immediately.
Jamie Madill6c1f6712017-02-14 19:08:04 -0500700 mState.mFenceSyncs->deleteObject(this,
701 static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400702}
703
Sami Väisänene45e53b2016-05-25 10:36:04 +0300704void Context::deletePaths(GLuint first, GLsizei range)
705{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500706 mState.mPaths->deletePaths(first, range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300707}
708
709bool Context::hasPathData(GLuint path) const
710{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500711 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300712 if (pathObj == nullptr)
713 return false;
714
715 return pathObj->hasPathData();
716}
717
718bool Context::hasPath(GLuint path) const
719{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500720 return mState.mPaths->hasPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300721}
722
723void Context::setPathCommands(GLuint path,
724 GLsizei numCommands,
725 const GLubyte *commands,
726 GLsizei numCoords,
727 GLenum coordType,
728 const void *coords)
729{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500730 auto *pathObject = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300731
732 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
733}
734
735void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
736{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500737 auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300738
739 switch (pname)
740 {
741 case GL_PATH_STROKE_WIDTH_CHROMIUM:
742 pathObj->setStrokeWidth(value);
743 break;
744 case GL_PATH_END_CAPS_CHROMIUM:
745 pathObj->setEndCaps(static_cast<GLenum>(value));
746 break;
747 case GL_PATH_JOIN_STYLE_CHROMIUM:
748 pathObj->setJoinStyle(static_cast<GLenum>(value));
749 break;
750 case GL_PATH_MITER_LIMIT_CHROMIUM:
751 pathObj->setMiterLimit(value);
752 break;
753 case GL_PATH_STROKE_BOUND_CHROMIUM:
754 pathObj->setStrokeBound(value);
755 break;
756 default:
757 UNREACHABLE();
758 break;
759 }
760}
761
762void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
763{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500764 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300765
766 switch (pname)
767 {
768 case GL_PATH_STROKE_WIDTH_CHROMIUM:
769 *value = pathObj->getStrokeWidth();
770 break;
771 case GL_PATH_END_CAPS_CHROMIUM:
772 *value = static_cast<GLfloat>(pathObj->getEndCaps());
773 break;
774 case GL_PATH_JOIN_STYLE_CHROMIUM:
775 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
776 break;
777 case GL_PATH_MITER_LIMIT_CHROMIUM:
778 *value = pathObj->getMiterLimit();
779 break;
780 case GL_PATH_STROKE_BOUND_CHROMIUM:
781 *value = pathObj->getStrokeBound();
782 break;
783 default:
784 UNREACHABLE();
785 break;
786 }
787}
788
789void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
790{
791 mGLState.setPathStencilFunc(func, ref, mask);
792}
793
Jamie Madill57a89722013-07-02 11:57:03 -0400794void Context::deleteVertexArray(GLuint vertexArray)
795{
Jamie Madill96a483b2017-06-27 16:49:21 -0400796 VertexArray *vertexArrayObject = nullptr;
797 if (mVertexArrayMap.erase(vertexArray, &vertexArrayObject))
Geoff Lang50b3fe82015-12-08 14:49:12 +0000798 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500799 if (vertexArrayObject != nullptr)
800 {
801 detachVertexArray(vertexArray);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400802 vertexArrayObject->onDestroy(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500803 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000804
Geoff Lang36167ab2015-12-07 10:27:14 -0500805 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400806 }
807}
808
Jamie Madilldc356042013-07-19 16:36:57 -0400809void Context::deleteSampler(GLuint sampler)
810{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500811 if (mState.mSamplers->getSampler(sampler))
Jamie Madilldc356042013-07-19 16:36:57 -0400812 {
813 detachSampler(sampler);
814 }
815
Jamie Madill6c1f6712017-02-14 19:08:04 -0500816 mState.mSamplers->deleteObject(this, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400817}
818
Geoff Langc8058452014-02-03 12:04:11 -0500819void Context::deleteTransformFeedback(GLuint transformFeedback)
820{
Geoff Lang6e60d6b2017-04-12 12:59:04 -0400821 if (transformFeedback == 0)
822 {
823 return;
824 }
825
Jamie Madill96a483b2017-06-27 16:49:21 -0400826 TransformFeedback *transformFeedbackObject = nullptr;
827 if (mTransformFeedbackMap.erase(transformFeedback, &transformFeedbackObject))
Geoff Langc8058452014-02-03 12:04:11 -0500828 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500829 if (transformFeedbackObject != nullptr)
830 {
831 detachTransformFeedback(transformFeedback);
Jamie Madill6c1f6712017-02-14 19:08:04 -0500832 transformFeedbackObject->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500833 }
834
Geoff Lang36167ab2015-12-07 10:27:14 -0500835 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500836 }
837}
838
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000839void Context::deleteFramebuffer(GLuint framebuffer)
840{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500841 if (mState.mFramebuffers->getFramebuffer(framebuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000842 {
843 detachFramebuffer(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000844 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500845
Jamie Madill6c1f6712017-02-14 19:08:04 -0500846 mState.mFramebuffers->deleteObject(this, framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000847}
848
Jamie Madill33dc8432013-07-26 11:55:05 -0400849void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000850{
Jamie Madill96a483b2017-06-27 16:49:21 -0400851 FenceNV *fenceObject = nullptr;
852 if (mFenceNVMap.erase(fence, &fenceObject))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000853 {
Jamie Madill96a483b2017-06-27 16:49:21 -0400854 mFenceNVHandleAllocator.release(fence);
855 delete fenceObject;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000856 }
857}
858
859void Context::deleteQuery(GLuint query)
860{
Jamie Madill96a483b2017-06-27 16:49:21 -0400861 Query *queryObject = nullptr;
862 if (mQueryMap.erase(query, &queryObject))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000863 {
Jamie Madill96a483b2017-06-27 16:49:21 -0400864 mQueryHandleAllocator.release(query);
865 if (queryObject)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000866 {
Jamie Madill96a483b2017-06-27 16:49:21 -0400867 queryObject->release(this);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000868 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000869 }
870}
871
Geoff Lang70d0f492015-12-10 17:45:46 -0500872Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000873{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500874 return mState.mBuffers->getBuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000875}
876
Jamie Madill570f7c82014-07-03 10:38:54 -0400877Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000878{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500879 return mState.mTextures->getTexture(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000880}
881
Geoff Lang70d0f492015-12-10 17:45:46 -0500882Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000883{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500884 return mState.mRenderbuffers->getRenderbuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000885}
886
Jamie Madillcd055f82013-07-26 11:55:15 -0400887FenceSync *Context::getFenceSync(GLsync handle) const
888{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500889 return mState.mFenceSyncs->getFenceSync(
890 static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400891}
892
Jamie Madill57a89722013-07-02 11:57:03 -0400893VertexArray *Context::getVertexArray(GLuint handle) const
894{
Jamie Madill96a483b2017-06-27 16:49:21 -0400895 return mVertexArrayMap.query(handle);
Jamie Madill57a89722013-07-02 11:57:03 -0400896}
897
Jamie Madilldc356042013-07-19 16:36:57 -0400898Sampler *Context::getSampler(GLuint handle) const
899{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500900 return mState.mSamplers->getSampler(handle);
Jamie Madilldc356042013-07-19 16:36:57 -0400901}
902
Geoff Langc8058452014-02-03 12:04:11 -0500903TransformFeedback *Context::getTransformFeedback(GLuint handle) const
904{
Jamie Madill96a483b2017-06-27 16:49:21 -0400905 return mTransformFeedbackMap.query(handle);
Geoff Langc8058452014-02-03 12:04:11 -0500906}
907
Geoff Lang70d0f492015-12-10 17:45:46 -0500908LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
909{
910 switch (identifier)
911 {
912 case GL_BUFFER:
913 return getBuffer(name);
914 case GL_SHADER:
915 return getShader(name);
916 case GL_PROGRAM:
917 return getProgram(name);
918 case GL_VERTEX_ARRAY:
919 return getVertexArray(name);
920 case GL_QUERY:
921 return getQuery(name);
922 case GL_TRANSFORM_FEEDBACK:
923 return getTransformFeedback(name);
924 case GL_SAMPLER:
925 return getSampler(name);
926 case GL_TEXTURE:
927 return getTexture(name);
928 case GL_RENDERBUFFER:
929 return getRenderbuffer(name);
930 case GL_FRAMEBUFFER:
931 return getFramebuffer(name);
932 default:
933 UNREACHABLE();
934 return nullptr;
935 }
936}
937
938LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
939{
940 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
941}
942
Martin Radev9d901792016-07-15 15:58:58 +0300943void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
944{
945 LabeledObject *object = getLabeledObject(identifier, name);
946 ASSERT(object != nullptr);
947
948 std::string labelName = GetObjectLabelFromPointer(length, label);
949 object->setLabel(labelName);
950}
951
952void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
953{
954 LabeledObject *object = getLabeledObjectFromPtr(ptr);
955 ASSERT(object != nullptr);
956
957 std::string labelName = GetObjectLabelFromPointer(length, label);
958 object->setLabel(labelName);
959}
960
961void Context::getObjectLabel(GLenum identifier,
962 GLuint name,
963 GLsizei bufSize,
964 GLsizei *length,
965 GLchar *label) const
966{
967 LabeledObject *object = getLabeledObject(identifier, name);
968 ASSERT(object != nullptr);
969
970 const std::string &objectLabel = object->getLabel();
971 GetObjectLabelBase(objectLabel, bufSize, length, label);
972}
973
974void Context::getObjectPtrLabel(const void *ptr,
975 GLsizei bufSize,
976 GLsizei *length,
977 GLchar *label) const
978{
979 LabeledObject *object = getLabeledObjectFromPtr(ptr);
980 ASSERT(object != nullptr);
981
982 const std::string &objectLabel = object->getLabel();
983 GetObjectLabelBase(objectLabel, bufSize, length, label);
984}
985
Jamie Madilldc356042013-07-19 16:36:57 -0400986bool Context::isSampler(GLuint samplerName) const
987{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500988 return mState.mSamplers->isSampler(samplerName);
Jamie Madilldc356042013-07-19 16:36:57 -0400989}
990
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500991void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000992{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500993 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400994 mGLState.setArrayBufferBinding(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000995}
996
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800997void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
998{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500999 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001000 mGLState.setDrawIndirectBufferBinding(this, buffer);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08001001}
1002
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001003void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001004{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001005 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001006 mGLState.setElementArrayBuffer(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001007}
1008
Jamie Madilldedd7b92014-11-05 16:30:36 -05001009void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001010{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001011 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001012
Jamie Madilldedd7b92014-11-05 16:30:36 -05001013 if (handle == 0)
1014 {
1015 texture = mZeroTextures[target].get();
1016 }
1017 else
1018 {
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001019 texture = mState.mTextures->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -05001020 }
1021
1022 ASSERT(texture);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001023 mGLState.setSamplerTexture(this, target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +00001024}
1025
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001026void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001027{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001028 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
1029 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001030 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001031}
1032
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001033void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001034{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001035 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
1036 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001037 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001038}
1039
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001040void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -04001041{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001042 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001043 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -04001044}
1045
Shao80957d92017-02-20 21:25:59 +08001046void Context::bindVertexBuffer(GLuint bindingIndex,
1047 GLuint bufferHandle,
1048 GLintptr offset,
1049 GLsizei stride)
1050{
1051 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001052 mGLState.bindVertexBuffer(this, bindingIndex, buffer, offset, stride);
Shao80957d92017-02-20 21:25:59 +08001053}
1054
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001055void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -04001056{
Geoff Lang76b10c92014-09-05 16:28:14 -04001057 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -04001058 Sampler *sampler =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001059 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001060 mGLState.setSamplerBinding(this, textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001061}
1062
Xinghua Cao65ec0b22017-03-28 16:10:52 +08001063void Context::bindImageTexture(GLuint unit,
1064 GLuint texture,
1065 GLint level,
1066 GLboolean layered,
1067 GLint layer,
1068 GLenum access,
1069 GLenum format)
1070{
1071 Texture *tex = mState.mTextures->getTexture(texture);
1072 mGLState.setImageUnit(this, unit, tex, level, layered, layer, access, format);
1073}
1074
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001075void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001076{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001077 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001078 mGLState.setGenericUniformBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001079}
1080
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001081void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1082 GLuint index,
1083 GLintptr offset,
1084 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +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.setIndexedUniformBufferBinding(this, index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001088}
1089
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001090void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +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.getCurrentTransformFeedback()->bindGenericBuffer(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001094}
1095
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001096void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1097 GLuint index,
1098 GLintptr offset,
1099 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001100{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001101 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001102 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(this, index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001103}
1104
Jiajia Qin6eafb042016-12-27 17:04:07 +08001105void Context::bindGenericAtomicCounterBuffer(GLuint bufferHandle)
1106{
1107 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001108 mGLState.setGenericAtomicCounterBufferBinding(this, buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08001109}
1110
1111void Context::bindIndexedAtomicCounterBuffer(GLuint bufferHandle,
1112 GLuint index,
1113 GLintptr offset,
1114 GLsizeiptr size)
1115{
1116 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001117 mGLState.setIndexedAtomicCounterBufferBinding(this, index, buffer, offset, size);
Jiajia Qin6eafb042016-12-27 17:04:07 +08001118}
1119
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001120void Context::bindGenericShaderStorageBuffer(GLuint bufferHandle)
1121{
1122 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001123 mGLState.setGenericShaderStorageBufferBinding(this, buffer);
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001124}
1125
1126void Context::bindIndexedShaderStorageBuffer(GLuint bufferHandle,
1127 GLuint index,
1128 GLintptr offset,
1129 GLsizeiptr size)
1130{
1131 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001132 mGLState.setIndexedShaderStorageBufferBinding(this, index, buffer, offset, size);
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001133}
1134
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001135void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001136{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001137 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001138 mGLState.setCopyReadBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001139}
1140
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001141void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001142{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001143 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001144 mGLState.setCopyWriteBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001145}
1146
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001147void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001148{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001149 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001150 mGLState.setPixelPackBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001151}
1152
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001153void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001154{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001155 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001156 mGLState.setPixelUnpackBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001157}
1158
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001159void Context::useProgram(GLuint program)
1160{
Jamie Madill6c1f6712017-02-14 19:08:04 -05001161 mGLState.setProgram(this, getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001162}
1163
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001164void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001165{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001166 TransformFeedback *transformFeedback =
1167 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001168 mGLState.setTransformFeedbackBinding(this, transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001169}
1170
Geoff Lang5aad9672014-09-08 11:10:42 -04001171Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001172{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001173 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001174 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001175
Geoff Lang5aad9672014-09-08 11:10:42 -04001176 // begin query
1177 Error error = queryObject->begin();
1178 if (error.isError())
1179 {
1180 return error;
1181 }
1182
1183 // set query as active for specified target only if begin succeeded
Jamie Madill4928b7c2017-06-20 12:57:39 -04001184 mGLState.setActiveQuery(this, target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001185
He Yunchaoacd18982017-01-04 10:46:42 +08001186 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001187}
1188
Geoff Lang5aad9672014-09-08 11:10:42 -04001189Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001190{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001191 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001192 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001193
Geoff Lang5aad9672014-09-08 11:10:42 -04001194 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001195
Geoff Lang5aad9672014-09-08 11:10:42 -04001196 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madill4928b7c2017-06-20 12:57:39 -04001197 mGLState.setActiveQuery(this, target, nullptr);
Geoff Lang5aad9672014-09-08 11:10:42 -04001198
1199 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001200}
1201
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001202Error Context::queryCounter(GLuint id, GLenum target)
1203{
1204 ASSERT(target == GL_TIMESTAMP_EXT);
1205
1206 Query *queryObject = getQuery(id, true, target);
1207 ASSERT(queryObject);
1208
1209 return queryObject->queryCounter();
1210}
1211
1212void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1213{
1214 switch (pname)
1215 {
1216 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001217 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001218 break;
1219 case GL_QUERY_COUNTER_BITS_EXT:
1220 switch (target)
1221 {
1222 case GL_TIME_ELAPSED_EXT:
1223 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1224 break;
1225 case GL_TIMESTAMP_EXT:
1226 params[0] = getExtensions().queryCounterBitsTimestamp;
1227 break;
1228 default:
1229 UNREACHABLE();
1230 params[0] = 0;
1231 break;
1232 }
1233 break;
1234 default:
1235 UNREACHABLE();
1236 return;
1237 }
1238}
1239
Geoff Lang2186c382016-10-14 10:54:54 -04001240void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001241{
Geoff Lang2186c382016-10-14 10:54:54 -04001242 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001243}
1244
Geoff Lang2186c382016-10-14 10:54:54 -04001245void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001246{
Geoff Lang2186c382016-10-14 10:54:54 -04001247 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001248}
1249
Geoff Lang2186c382016-10-14 10:54:54 -04001250void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001251{
Geoff Lang2186c382016-10-14 10:54:54 -04001252 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001253}
1254
Geoff Lang2186c382016-10-14 10:54:54 -04001255void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001256{
Geoff Lang2186c382016-10-14 10:54:54 -04001257 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001258}
1259
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001260Framebuffer *Context::getFramebuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001261{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001262 return mState.mFramebuffers->getFramebuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001263}
1264
Jamie Madill2f348d22017-06-05 10:50:59 -04001265FenceNV *Context::getFenceNV(GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001266{
Jamie Madill96a483b2017-06-27 16:49:21 -04001267 return mFenceNVMap.query(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001268}
1269
Jamie Madill2f348d22017-06-05 10:50:59 -04001270Query *Context::getQuery(GLuint handle, bool create, GLenum type)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001271{
Jamie Madill96a483b2017-06-27 16:49:21 -04001272 if (!mQueryMap.contains(handle))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001273 {
Yunchao Hef81ce4a2017-04-24 10:49:17 +08001274 return nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001275 }
Jamie Madill96a483b2017-06-27 16:49:21 -04001276
1277 Query *query = mQueryMap.query(handle);
1278 if (!query && create)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001279 {
Jamie Madill96a483b2017-06-27 16:49:21 -04001280 query = new Query(mImplementation->createQuery(type), handle);
1281 query->addRef();
1282 mQueryMap.assign(handle, query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001283 }
Jamie Madill96a483b2017-06-27 16:49:21 -04001284 return query;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001285}
1286
Geoff Lang70d0f492015-12-10 17:45:46 -05001287Query *Context::getQuery(GLuint handle) const
1288{
Jamie Madill96a483b2017-06-27 16:49:21 -04001289 return mQueryMap.query(handle);
Geoff Lang70d0f492015-12-10 17:45:46 -05001290}
1291
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001292Texture *Context::getTargetTexture(GLenum target) const
1293{
Ian Ewellbda75592016-04-18 17:25:54 -04001294 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001295 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001296}
1297
Geoff Lang76b10c92014-09-05 16:28:14 -04001298Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001299{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001300 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001301}
1302
Geoff Lang492a7e42014-11-05 13:27:06 -05001303Compiler *Context::getCompiler() const
1304{
Jamie Madill2f348d22017-06-05 10:50:59 -04001305 if (mCompiler.get() == nullptr)
1306 {
Jamie Madill4928b7c2017-06-20 12:57:39 -04001307 mCompiler.set(this, new Compiler(mImplementation.get(), mState));
Jamie Madill2f348d22017-06-05 10:50:59 -04001308 }
1309 return mCompiler.get();
Geoff Lang492a7e42014-11-05 13:27:06 -05001310}
1311
Jamie Madillc1d770e2017-04-13 17:31:24 -04001312void Context::getBooleanvImpl(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001313{
1314 switch (pname)
1315 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001316 case GL_SHADER_COMPILER:
1317 *params = GL_TRUE;
1318 break;
1319 case GL_CONTEXT_ROBUST_ACCESS_EXT:
1320 *params = mRobustAccess ? GL_TRUE : GL_FALSE;
1321 break;
1322 default:
1323 mGLState.getBooleanv(pname, params);
1324 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001325 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001326}
1327
Jamie Madillc1d770e2017-04-13 17:31:24 -04001328void Context::getFloatvImpl(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001329{
Shannon Woods53a94a82014-06-24 15:20:36 -04001330 // Queries about context capabilities and maximums are answered by Context.
1331 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001332 switch (pname)
1333 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001334 case GL_ALIASED_LINE_WIDTH_RANGE:
1335 params[0] = mCaps.minAliasedLineWidth;
1336 params[1] = mCaps.maxAliasedLineWidth;
1337 break;
1338 case GL_ALIASED_POINT_SIZE_RANGE:
1339 params[0] = mCaps.minAliasedPointSize;
1340 params[1] = mCaps.maxAliasedPointSize;
1341 break;
1342 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1343 ASSERT(mExtensions.textureFilterAnisotropic);
1344 *params = mExtensions.maxTextureAnisotropy;
1345 break;
1346 case GL_MAX_TEXTURE_LOD_BIAS:
1347 *params = mCaps.maxLODBias;
1348 break;
1349
1350 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1351 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1352 {
1353 ASSERT(mExtensions.pathRendering);
1354 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1355 memcpy(params, m, 16 * sizeof(GLfloat));
1356 }
Geoff Lange6d4e122015-06-29 13:33:55 -04001357 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001358
Jamie Madill231c7f52017-04-26 13:45:37 -04001359 default:
1360 mGLState.getFloatv(pname, params);
1361 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001362 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001363}
1364
Jamie Madillc1d770e2017-04-13 17:31:24 -04001365void Context::getIntegervImpl(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001366{
Shannon Woods53a94a82014-06-24 15:20:36 -04001367 // Queries about context capabilities and maximums are answered by Context.
1368 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001369
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001370 switch (pname)
1371 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001372 case GL_MAX_VERTEX_ATTRIBS:
1373 *params = mCaps.maxVertexAttributes;
1374 break;
1375 case GL_MAX_VERTEX_UNIFORM_VECTORS:
1376 *params = mCaps.maxVertexUniformVectors;
1377 break;
1378 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
1379 *params = mCaps.maxVertexUniformComponents;
1380 break;
1381 case GL_MAX_VARYING_VECTORS:
1382 *params = mCaps.maxVaryingVectors;
1383 break;
1384 case GL_MAX_VARYING_COMPONENTS:
1385 *params = mCaps.maxVertexOutputComponents;
1386 break;
1387 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1388 *params = mCaps.maxCombinedTextureImageUnits;
1389 break;
1390 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1391 *params = mCaps.maxVertexTextureImageUnits;
1392 break;
1393 case GL_MAX_TEXTURE_IMAGE_UNITS:
1394 *params = mCaps.maxTextureImageUnits;
1395 break;
1396 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1397 *params = mCaps.maxFragmentUniformVectors;
1398 break;
1399 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
1400 *params = mCaps.maxFragmentUniformComponents;
1401 break;
1402 case GL_MAX_RENDERBUFFER_SIZE:
1403 *params = mCaps.maxRenderbufferSize;
1404 break;
1405 case GL_MAX_COLOR_ATTACHMENTS_EXT:
1406 *params = mCaps.maxColorAttachments;
1407 break;
1408 case GL_MAX_DRAW_BUFFERS_EXT:
1409 *params = mCaps.maxDrawBuffers;
1410 break;
1411 // case GL_FRAMEBUFFER_BINDING: // now equivalent to
1412 // GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1413 case GL_SUBPIXEL_BITS:
1414 *params = 4;
1415 break;
1416 case GL_MAX_TEXTURE_SIZE:
1417 *params = mCaps.max2DTextureSize;
1418 break;
1419 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1420 *params = mCaps.maxCubeMapTextureSize;
1421 break;
1422 case GL_MAX_3D_TEXTURE_SIZE:
1423 *params = mCaps.max3DTextureSize;
1424 break;
1425 case GL_MAX_ARRAY_TEXTURE_LAYERS:
1426 *params = mCaps.maxArrayTextureLayers;
1427 break;
1428 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
1429 *params = mCaps.uniformBufferOffsetAlignment;
1430 break;
1431 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
1432 *params = mCaps.maxUniformBufferBindings;
1433 break;
1434 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
1435 *params = mCaps.maxVertexUniformBlocks;
1436 break;
1437 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
1438 *params = mCaps.maxFragmentUniformBlocks;
1439 break;
1440 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
1441 *params = mCaps.maxCombinedTextureImageUnits;
1442 break;
1443 case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
1444 *params = mCaps.maxVertexOutputComponents;
1445 break;
1446 case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
1447 *params = mCaps.maxFragmentInputComponents;
1448 break;
1449 case GL_MIN_PROGRAM_TEXEL_OFFSET:
1450 *params = mCaps.minProgramTexelOffset;
1451 break;
1452 case GL_MAX_PROGRAM_TEXEL_OFFSET:
1453 *params = mCaps.maxProgramTexelOffset;
1454 break;
1455 case GL_MAJOR_VERSION:
1456 *params = getClientVersion().major;
1457 break;
1458 case GL_MINOR_VERSION:
1459 *params = getClientVersion().minor;
1460 break;
1461 case GL_MAX_ELEMENTS_INDICES:
1462 *params = mCaps.maxElementsIndices;
1463 break;
1464 case GL_MAX_ELEMENTS_VERTICES:
1465 *params = mCaps.maxElementsVertices;
1466 break;
1467 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
1468 *params = mCaps.maxTransformFeedbackInterleavedComponents;
1469 break;
1470 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
1471 *params = mCaps.maxTransformFeedbackSeparateAttributes;
1472 break;
1473 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
1474 *params = mCaps.maxTransformFeedbackSeparateComponents;
1475 break;
1476 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1477 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1478 break;
1479 case GL_MAX_SAMPLES_ANGLE:
1480 *params = mCaps.maxSamples;
1481 break;
1482 case GL_MAX_VIEWPORT_DIMS:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001483 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001484 params[0] = mCaps.maxViewportWidth;
1485 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001486 }
1487 break;
Jamie Madill231c7f52017-04-26 13:45:37 -04001488 case GL_COMPRESSED_TEXTURE_FORMATS:
1489 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(),
1490 params);
1491 break;
1492 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1493 *params = mResetStrategy;
1494 break;
1495 case GL_NUM_SHADER_BINARY_FORMATS:
1496 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
1497 break;
1498 case GL_SHADER_BINARY_FORMATS:
1499 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1500 break;
1501 case GL_NUM_PROGRAM_BINARY_FORMATS:
1502 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
1503 break;
1504 case GL_PROGRAM_BINARY_FORMATS:
1505 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
1506 break;
1507 case GL_NUM_EXTENSIONS:
1508 *params = static_cast<GLint>(mExtensionStrings.size());
1509 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001510
Jamie Madill231c7f52017-04-26 13:45:37 -04001511 // GL_KHR_debug
1512 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1513 *params = mExtensions.maxDebugMessageLength;
1514 break;
1515 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1516 *params = mExtensions.maxDebugLoggedMessages;
1517 break;
1518 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1519 *params = mExtensions.maxDebugGroupStackDepth;
1520 break;
1521 case GL_MAX_LABEL_LENGTH:
1522 *params = mExtensions.maxLabelLength;
1523 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001524
Martin Radeve5285d22017-07-14 16:23:53 +03001525 // GL_ANGLE_multiview
1526 case GL_MAX_VIEWS_ANGLE:
1527 *params = mExtensions.maxViews;
1528 break;
1529
Jamie Madill231c7f52017-04-26 13:45:37 -04001530 // GL_EXT_disjoint_timer_query
1531 case GL_GPU_DISJOINT_EXT:
1532 *params = mImplementation->getGPUDisjoint();
1533 break;
1534 case GL_MAX_FRAMEBUFFER_WIDTH:
1535 *params = mCaps.maxFramebufferWidth;
1536 break;
1537 case GL_MAX_FRAMEBUFFER_HEIGHT:
1538 *params = mCaps.maxFramebufferHeight;
1539 break;
1540 case GL_MAX_FRAMEBUFFER_SAMPLES:
1541 *params = mCaps.maxFramebufferSamples;
1542 break;
1543 case GL_MAX_SAMPLE_MASK_WORDS:
1544 *params = mCaps.maxSampleMaskWords;
1545 break;
1546 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1547 *params = mCaps.maxColorTextureSamples;
1548 break;
1549 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1550 *params = mCaps.maxDepthTextureSamples;
1551 break;
1552 case GL_MAX_INTEGER_SAMPLES:
1553 *params = mCaps.maxIntegerSamples;
1554 break;
1555 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1556 *params = mCaps.maxVertexAttribRelativeOffset;
1557 break;
1558 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1559 *params = mCaps.maxVertexAttribBindings;
1560 break;
1561 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1562 *params = mCaps.maxVertexAttribStride;
1563 break;
1564 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1565 *params = mCaps.maxVertexAtomicCounterBuffers;
1566 break;
1567 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1568 *params = mCaps.maxVertexAtomicCounters;
1569 break;
1570 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1571 *params = mCaps.maxVertexImageUniforms;
1572 break;
1573 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1574 *params = mCaps.maxVertexShaderStorageBlocks;
1575 break;
1576 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1577 *params = mCaps.maxFragmentAtomicCounterBuffers;
1578 break;
1579 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1580 *params = mCaps.maxFragmentAtomicCounters;
1581 break;
1582 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1583 *params = mCaps.maxFragmentImageUniforms;
1584 break;
1585 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1586 *params = mCaps.maxFragmentShaderStorageBlocks;
1587 break;
1588 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1589 *params = mCaps.minProgramTextureGatherOffset;
1590 break;
1591 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1592 *params = mCaps.maxProgramTextureGatherOffset;
1593 break;
1594 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1595 *params = mCaps.maxComputeWorkGroupInvocations;
1596 break;
1597 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1598 *params = mCaps.maxComputeUniformBlocks;
1599 break;
1600 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1601 *params = mCaps.maxComputeTextureImageUnits;
1602 break;
1603 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1604 *params = mCaps.maxComputeSharedMemorySize;
1605 break;
1606 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1607 *params = mCaps.maxComputeUniformComponents;
1608 break;
1609 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1610 *params = mCaps.maxComputeAtomicCounterBuffers;
1611 break;
1612 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1613 *params = mCaps.maxComputeAtomicCounters;
1614 break;
1615 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1616 *params = mCaps.maxComputeImageUniforms;
1617 break;
1618 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1619 *params = mCaps.maxCombinedComputeUniformComponents;
1620 break;
1621 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1622 *params = mCaps.maxComputeShaderStorageBlocks;
1623 break;
1624 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1625 *params = mCaps.maxCombinedShaderOutputResources;
1626 break;
1627 case GL_MAX_UNIFORM_LOCATIONS:
1628 *params = mCaps.maxUniformLocations;
1629 break;
1630 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1631 *params = mCaps.maxAtomicCounterBufferBindings;
1632 break;
1633 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1634 *params = mCaps.maxAtomicCounterBufferSize;
1635 break;
1636 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1637 *params = mCaps.maxCombinedAtomicCounterBuffers;
1638 break;
1639 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1640 *params = mCaps.maxCombinedAtomicCounters;
1641 break;
1642 case GL_MAX_IMAGE_UNITS:
1643 *params = mCaps.maxImageUnits;
1644 break;
1645 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1646 *params = mCaps.maxCombinedImageUniforms;
1647 break;
1648 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1649 *params = mCaps.maxShaderStorageBufferBindings;
1650 break;
1651 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1652 *params = mCaps.maxCombinedShaderStorageBlocks;
1653 break;
1654 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1655 *params = mCaps.shaderStorageBufferOffsetAlignment;
1656 break;
1657 default:
1658 mGLState.getIntegerv(this, pname, params);
1659 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001660 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001661}
1662
Jamie Madill893ab082014-05-16 16:56:10 -04001663void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001664{
Shannon Woods53a94a82014-06-24 15:20:36 -04001665 // Queries about context capabilities and maximums are answered by Context.
1666 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001667 switch (pname)
1668 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001669 case GL_MAX_ELEMENT_INDEX:
1670 *params = mCaps.maxElementIndex;
1671 break;
1672 case GL_MAX_UNIFORM_BLOCK_SIZE:
1673 *params = mCaps.maxUniformBlockSize;
1674 break;
1675 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
1676 *params = mCaps.maxCombinedVertexUniformComponents;
1677 break;
1678 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
1679 *params = mCaps.maxCombinedFragmentUniformComponents;
1680 break;
1681 case GL_MAX_SERVER_WAIT_TIMEOUT:
1682 *params = mCaps.maxServerWaitTimeout;
1683 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001684
Jamie Madill231c7f52017-04-26 13:45:37 -04001685 // GL_EXT_disjoint_timer_query
1686 case GL_TIMESTAMP_EXT:
1687 *params = mImplementation->getTimestamp();
1688 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001689
Jamie Madill231c7f52017-04-26 13:45:37 -04001690 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1691 *params = mCaps.maxShaderStorageBlockSize;
1692 break;
1693 default:
1694 UNREACHABLE();
1695 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001696 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001697}
1698
Geoff Lang70d0f492015-12-10 17:45:46 -05001699void Context::getPointerv(GLenum pname, void **params) const
1700{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001701 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001702}
1703
Martin Radev66fb8202016-07-28 11:45:20 +03001704void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001705{
Shannon Woods53a94a82014-06-24 15:20:36 -04001706 // Queries about context capabilities and maximums are answered by Context.
1707 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001708
1709 GLenum nativeType;
1710 unsigned int numParams;
1711 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1712 ASSERT(queryStatus);
1713
1714 if (nativeType == GL_INT)
1715 {
1716 switch (target)
1717 {
1718 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1719 ASSERT(index < 3u);
1720 *data = mCaps.maxComputeWorkGroupCount[index];
1721 break;
1722 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1723 ASSERT(index < 3u);
1724 *data = mCaps.maxComputeWorkGroupSize[index];
1725 break;
1726 default:
1727 mGLState.getIntegeri_v(target, index, data);
1728 }
1729 }
1730 else
1731 {
1732 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1733 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001734}
1735
Martin Radev66fb8202016-07-28 11:45:20 +03001736void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001737{
Shannon Woods53a94a82014-06-24 15:20:36 -04001738 // Queries about context capabilities and maximums are answered by Context.
1739 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001740
1741 GLenum nativeType;
1742 unsigned int numParams;
1743 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1744 ASSERT(queryStatus);
1745
1746 if (nativeType == GL_INT_64_ANGLEX)
1747 {
1748 mGLState.getInteger64i_v(target, index, data);
1749 }
1750 else
1751 {
1752 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1753 }
1754}
1755
1756void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1757{
1758 // Queries about context capabilities and maximums are answered by Context.
1759 // Queries about current GL state values are answered by State.
1760
1761 GLenum nativeType;
1762 unsigned int numParams;
1763 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1764 ASSERT(queryStatus);
1765
1766 if (nativeType == GL_BOOL)
1767 {
1768 mGLState.getBooleani_v(target, index, data);
1769 }
1770 else
1771 {
1772 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1773 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001774}
1775
He Yunchao010e4db2017-03-03 14:22:06 +08001776void Context::getBufferParameteriv(GLenum target, GLenum pname, GLint *params)
1777{
1778 Buffer *buffer = mGLState.getTargetBuffer(target);
1779 QueryBufferParameteriv(buffer, pname, params);
1780}
1781
1782void Context::getFramebufferAttachmentParameteriv(GLenum target,
1783 GLenum attachment,
1784 GLenum pname,
1785 GLint *params)
1786{
1787 const Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
1788 QueryFramebufferAttachmentParameteriv(framebuffer, attachment, pname, params);
1789}
1790
1791void Context::getRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
1792{
1793 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
1794 QueryRenderbufferiv(this, renderbuffer, pname, params);
1795}
1796
1797void Context::getTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
1798{
1799 Texture *texture = getTargetTexture(target);
1800 QueryTexParameterfv(texture, pname, params);
1801}
1802
1803void Context::getTexParameteriv(GLenum target, GLenum pname, GLint *params)
1804{
1805 Texture *texture = getTargetTexture(target);
1806 QueryTexParameteriv(texture, pname, params);
1807}
1808void Context::texParameterf(GLenum target, GLenum pname, GLfloat param)
1809{
1810 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001811 SetTexParameterf(this, texture, pname, param);
He Yunchao010e4db2017-03-03 14:22:06 +08001812}
1813
1814void Context::texParameterfv(GLenum target, GLenum pname, const GLfloat *params)
1815{
1816 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001817 SetTexParameterfv(this, texture, pname, params);
He Yunchao010e4db2017-03-03 14:22:06 +08001818}
1819
1820void Context::texParameteri(GLenum target, GLenum pname, GLint param)
1821{
1822 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001823 SetTexParameteri(this, texture, pname, param);
He Yunchao010e4db2017-03-03 14:22:06 +08001824}
1825
1826void Context::texParameteriv(GLenum target, GLenum pname, const GLint *params)
1827{
1828 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001829 SetTexParameteriv(this, texture, pname, params);
He Yunchao010e4db2017-03-03 14:22:06 +08001830}
1831
Jamie Madill675fe712016-12-19 13:07:54 -05001832void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001833{
Jamie Madill1b94d432015-08-07 13:23:23 -04001834 syncRendererState();
Jamie Madillc564c072017-06-01 12:45:42 -04001835 auto error = mImplementation->drawArrays(this, mode, first, count);
Jamie Madill675fe712016-12-19 13:07:54 -05001836 handleError(error);
1837 if (!error.isError())
1838 {
1839 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1840 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001841}
1842
Jamie Madill675fe712016-12-19 13:07:54 -05001843void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Geoff Langf6db0982015-08-25 13:04:00 -04001844{
1845 syncRendererState();
Jamie Madillc564c072017-06-01 12:45:42 -04001846 auto error = mImplementation->drawArraysInstanced(this, mode, first, count, instanceCount);
Jamie Madill675fe712016-12-19 13:07:54 -05001847 handleError(error);
1848 if (!error.isError())
1849 {
1850 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1851 }
Geoff Langf6db0982015-08-25 13:04:00 -04001852}
1853
Jamie Madill876429b2017-04-20 15:46:24 -04001854void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001855{
Jamie Madill1b94d432015-08-07 13:23:23 -04001856 syncRendererState();
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001857 const IndexRange &indexRange = getParams<HasIndexRange>().getIndexRange().value();
Jamie Madillc564c072017-06-01 12:45:42 -04001858 handleError(mImplementation->drawElements(this, mode, count, type, indices, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001859}
1860
Jamie Madill675fe712016-12-19 13:07:54 -05001861void Context::drawElementsInstanced(GLenum mode,
1862 GLsizei count,
1863 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001864 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001865 GLsizei instances)
Geoff Langf6db0982015-08-25 13:04:00 -04001866{
1867 syncRendererState();
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001868 const IndexRange &indexRange = getParams<HasIndexRange>().getIndexRange().value();
Jamie Madillc564c072017-06-01 12:45:42 -04001869 handleError(mImplementation->drawElementsInstanced(this, mode, count, type, indices, instances,
1870 indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001871}
1872
Jamie Madill675fe712016-12-19 13:07:54 -05001873void Context::drawRangeElements(GLenum mode,
1874 GLuint start,
1875 GLuint end,
1876 GLsizei count,
1877 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001878 const void *indices)
Geoff Langf6db0982015-08-25 13:04:00 -04001879{
1880 syncRendererState();
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001881 const IndexRange &indexRange = getParams<HasIndexRange>().getIndexRange().value();
Jamie Madillc564c072017-06-01 12:45:42 -04001882 handleError(mImplementation->drawRangeElements(this, mode, start, end, count, type, indices,
1883 indexRange));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001884}
1885
Jamie Madill876429b2017-04-20 15:46:24 -04001886void Context::drawArraysIndirect(GLenum mode, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001887{
1888 syncRendererState();
Jamie Madillc564c072017-06-01 12:45:42 -04001889 handleError(mImplementation->drawArraysIndirect(this, mode, indirect));
Jiajia Qind9671222016-11-29 16:30:31 +08001890}
1891
Jamie Madill876429b2017-04-20 15:46:24 -04001892void Context::drawElementsIndirect(GLenum mode, GLenum type, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001893{
1894 syncRendererState();
Jamie Madillc564c072017-06-01 12:45:42 -04001895 handleError(mImplementation->drawElementsIndirect(this, mode, type, indirect));
Jiajia Qind9671222016-11-29 16:30:31 +08001896}
1897
Jamie Madill675fe712016-12-19 13:07:54 -05001898void Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001899{
Jamie Madill675fe712016-12-19 13:07:54 -05001900 handleError(mImplementation->flush());
Geoff Lang129753a2015-01-09 16:52:09 -05001901}
1902
Jamie Madill675fe712016-12-19 13:07:54 -05001903void Context::finish()
Geoff Lang129753a2015-01-09 16:52:09 -05001904{
Jamie Madill675fe712016-12-19 13:07:54 -05001905 handleError(mImplementation->finish());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001906}
1907
Austin Kinross6ee1e782015-05-29 17:05:37 -07001908void Context::insertEventMarker(GLsizei length, const char *marker)
1909{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001910 ASSERT(mImplementation);
1911 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001912}
1913
1914void Context::pushGroupMarker(GLsizei length, const char *marker)
1915{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001916 ASSERT(mImplementation);
1917 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001918}
1919
1920void Context::popGroupMarker()
1921{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001922 ASSERT(mImplementation);
1923 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001924}
1925
Geoff Langd8605522016-04-13 10:19:12 -04001926void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1927{
1928 Program *programObject = getProgram(program);
1929 ASSERT(programObject);
1930
1931 programObject->bindUniformLocation(location, name);
1932}
1933
Sami Väisänena797e062016-05-12 15:23:40 +03001934void Context::setCoverageModulation(GLenum components)
1935{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001936 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001937}
1938
Sami Väisänene45e53b2016-05-25 10:36:04 +03001939void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1940{
1941 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1942}
1943
1944void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1945{
1946 GLfloat I[16];
1947 angle::Matrix<GLfloat>::setToIdentity(I);
1948
1949 mGLState.loadPathRenderingMatrix(matrixMode, I);
1950}
1951
1952void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1953{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001954 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001955 if (!pathObj)
1956 return;
1957
1958 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1959 syncRendererState();
1960
1961 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1962}
1963
1964void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1965{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001966 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001967 if (!pathObj)
1968 return;
1969
1970 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1971 syncRendererState();
1972
1973 mImplementation->stencilStrokePath(pathObj, reference, mask);
1974}
1975
1976void Context::coverFillPath(GLuint path, GLenum coverMode)
1977{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001978 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001979 if (!pathObj)
1980 return;
1981
1982 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1983 syncRendererState();
1984
1985 mImplementation->coverFillPath(pathObj, coverMode);
1986}
1987
1988void Context::coverStrokePath(GLuint path, GLenum coverMode)
1989{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001990 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001991 if (!pathObj)
1992 return;
1993
1994 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1995 syncRendererState();
1996
1997 mImplementation->coverStrokePath(pathObj, coverMode);
1998}
1999
2000void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
2001{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002002 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03002003 if (!pathObj)
2004 return;
2005
2006 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2007 syncRendererState();
2008
2009 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
2010}
2011
2012void Context::stencilThenCoverStrokePath(GLuint path,
2013 GLint reference,
2014 GLuint mask,
2015 GLenum coverMode)
2016{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002017 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03002018 if (!pathObj)
2019 return;
2020
2021 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2022 syncRendererState();
2023
2024 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
2025}
2026
Sami Väisänend59ca052016-06-21 16:10:00 +03002027void Context::coverFillPathInstanced(GLsizei numPaths,
2028 GLenum pathNameType,
2029 const void *paths,
2030 GLuint pathBase,
2031 GLenum coverMode,
2032 GLenum transformType,
2033 const GLfloat *transformValues)
2034{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002035 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002036
2037 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2038 syncRendererState();
2039
2040 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
2041}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002042
Sami Väisänend59ca052016-06-21 16:10:00 +03002043void Context::coverStrokePathInstanced(GLsizei numPaths,
2044 GLenum pathNameType,
2045 const void *paths,
2046 GLuint pathBase,
2047 GLenum coverMode,
2048 GLenum transformType,
2049 const GLfloat *transformValues)
2050{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002051 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002052
2053 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2054 syncRendererState();
2055
2056 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
2057 transformValues);
2058}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002059
Sami Väisänend59ca052016-06-21 16:10:00 +03002060void Context::stencilFillPathInstanced(GLsizei numPaths,
2061 GLenum pathNameType,
2062 const void *paths,
2063 GLuint pathBase,
2064 GLenum fillMode,
2065 GLuint mask,
2066 GLenum transformType,
2067 const GLfloat *transformValues)
2068{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002069 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002070
2071 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2072 syncRendererState();
2073
2074 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
2075 transformValues);
2076}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002077
Sami Väisänend59ca052016-06-21 16:10:00 +03002078void Context::stencilStrokePathInstanced(GLsizei numPaths,
2079 GLenum pathNameType,
2080 const void *paths,
2081 GLuint pathBase,
2082 GLint reference,
2083 GLuint mask,
2084 GLenum transformType,
2085 const GLfloat *transformValues)
2086{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002087 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002088
2089 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2090 syncRendererState();
2091
2092 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
2093 transformValues);
2094}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002095
Sami Väisänend59ca052016-06-21 16:10:00 +03002096void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
2097 GLenum pathNameType,
2098 const void *paths,
2099 GLuint pathBase,
2100 GLenum fillMode,
2101 GLuint mask,
2102 GLenum coverMode,
2103 GLenum transformType,
2104 const GLfloat *transformValues)
2105{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002106 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002107
2108 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2109 syncRendererState();
2110
2111 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
2112 transformType, transformValues);
2113}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002114
Sami Väisänend59ca052016-06-21 16:10:00 +03002115void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
2116 GLenum pathNameType,
2117 const void *paths,
2118 GLuint pathBase,
2119 GLint reference,
2120 GLuint mask,
2121 GLenum coverMode,
2122 GLenum transformType,
2123 const GLfloat *transformValues)
2124{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002125 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002126
2127 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2128 syncRendererState();
2129
2130 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
2131 transformType, transformValues);
2132}
2133
Sami Väisänen46eaa942016-06-29 10:26:37 +03002134void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
2135{
2136 auto *programObject = getProgram(program);
2137
2138 programObject->bindFragmentInputLocation(location, name);
2139}
2140
2141void Context::programPathFragmentInputGen(GLuint program,
2142 GLint location,
2143 GLenum genMode,
2144 GLint components,
2145 const GLfloat *coeffs)
2146{
2147 auto *programObject = getProgram(program);
2148
Jamie Madillbd044ed2017-06-05 12:59:21 -04002149 programObject->pathFragmentInputGen(this, location, genMode, components, coeffs);
Sami Väisänen46eaa942016-06-29 10:26:37 +03002150}
2151
jchen1015015f72017-03-16 13:54:21 +08002152GLuint Context::getProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name)
2153{
jchen10fd7c3b52017-03-21 15:36:03 +08002154 const auto *programObject = getProgram(program);
jchen1015015f72017-03-16 13:54:21 +08002155 return QueryProgramResourceIndex(programObject, programInterface, name);
2156}
2157
jchen10fd7c3b52017-03-21 15:36:03 +08002158void Context::getProgramResourceName(GLuint program,
2159 GLenum programInterface,
2160 GLuint index,
2161 GLsizei bufSize,
2162 GLsizei *length,
2163 GLchar *name)
2164{
2165 const auto *programObject = getProgram(program);
2166 QueryProgramResourceName(programObject, programInterface, index, bufSize, length, name);
2167}
2168
jchen10191381f2017-04-11 13:59:04 +08002169GLint Context::getProgramResourceLocation(GLuint program,
2170 GLenum programInterface,
2171 const GLchar *name)
2172{
2173 const auto *programObject = getProgram(program);
2174 return QueryProgramResourceLocation(programObject, programInterface, name);
2175}
2176
Jamie Madill437fa652016-05-03 15:13:24 -04002177void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002178{
Geoff Langda5777c2014-07-11 09:52:58 -04002179 if (error.isError())
2180 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002181 GLenum code = error.getCode();
2182 mErrors.insert(code);
2183 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
2184 {
2185 markContextLost();
2186 }
Geoff Lang70d0f492015-12-10 17:45:46 -05002187
2188 if (!error.getMessage().empty())
2189 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002190 auto *debug = &mGLState.getDebug();
2191 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
2192 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05002193 }
Geoff Langda5777c2014-07-11 09:52:58 -04002194 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002195}
2196
2197// Get one of the recorded errors and clear its flag, if any.
2198// [OpenGL ES 2.0.24] section 2.5 page 13.
2199GLenum Context::getError()
2200{
Geoff Langda5777c2014-07-11 09:52:58 -04002201 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002202 {
Geoff Langda5777c2014-07-11 09:52:58 -04002203 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002204 }
Geoff Langda5777c2014-07-11 09:52:58 -04002205 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002206 {
Geoff Langda5777c2014-07-11 09:52:58 -04002207 GLenum error = *mErrors.begin();
2208 mErrors.erase(mErrors.begin());
2209 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002210 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002211}
2212
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002213// NOTE: this function should not assume that this context is current!
2214void Context::markContextLost()
2215{
2216 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002217 {
Jamie Madill231c7f52017-04-26 13:45:37 -04002218 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002219 mContextLostForced = true;
2220 }
Jamie Madill231c7f52017-04-26 13:45:37 -04002221 mContextLost = true;
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002222}
2223
2224bool Context::isContextLost()
2225{
2226 return mContextLost;
2227}
2228
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002229GLenum Context::getResetStatus()
2230{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002231 // Even if the application doesn't want to know about resets, we want to know
2232 // as it will allow us to skip all the calls.
2233 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002234 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002235 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002236 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002237 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002238 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002239
2240 // EXT_robustness, section 2.6: If the reset notification behavior is
2241 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2242 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2243 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002244 }
2245
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002246 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2247 // status should be returned at least once, and GL_NO_ERROR should be returned
2248 // once the device has finished resetting.
2249 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002250 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002251 ASSERT(mResetStatus == GL_NO_ERROR);
2252 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002253
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002254 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002255 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002256 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002257 }
2258 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002259 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002260 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002261 // If markContextLost was used to mark the context lost then
2262 // assume that is not recoverable, and continue to report the
2263 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002264 mResetStatus = mImplementation->getResetStatus();
2265 }
Jamie Madill893ab082014-05-16 16:56:10 -04002266
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002267 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002268}
2269
2270bool Context::isResetNotificationEnabled()
2271{
2272 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2273}
2274
Corentin Walleze3b10e82015-05-20 11:06:25 -04002275const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002276{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002277 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002278}
2279
2280EGLenum Context::getClientType() const
2281{
2282 return mClientType;
2283}
2284
2285EGLenum Context::getRenderBuffer() const
2286{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002287 const Framebuffer *framebuffer = mState.mFramebuffers->getFramebuffer(0);
2288 if (framebuffer == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -04002289 {
2290 return EGL_NONE;
2291 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002292
2293 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2294 ASSERT(backAttachment != nullptr);
2295 return backAttachment->getSurface()->getRenderBuffer();
Régis Fénéon83107972015-02-05 12:57:44 +01002296}
2297
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002298VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002299{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002300 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002301 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2302 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002303 {
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002304 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle,
2305 mCaps.maxVertexAttributes, mCaps.maxVertexAttribBindings);
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002306
Jamie Madill96a483b2017-06-27 16:49:21 -04002307 mVertexArrayMap.assign(vertexArrayHandle, vertexArray);
Geoff Lang36167ab2015-12-07 10:27:14 -05002308 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002309
2310 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002311}
2312
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002313TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002314{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002315 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002316 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2317 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002318 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002319 transformFeedback =
2320 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002321 transformFeedback->addRef();
Jamie Madill96a483b2017-06-27 16:49:21 -04002322 mTransformFeedbackMap.assign(transformFeedbackHandle, transformFeedback);
Geoff Lang36167ab2015-12-07 10:27:14 -05002323 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002324
2325 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002326}
2327
2328bool Context::isVertexArrayGenerated(GLuint vertexArray)
2329{
Jamie Madill96a483b2017-06-27 16:49:21 -04002330 ASSERT(mVertexArrayMap.contains(0));
2331 return mVertexArrayMap.contains(vertexArray);
Geoff Lang36167ab2015-12-07 10:27:14 -05002332}
2333
2334bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2335{
Jamie Madill96a483b2017-06-27 16:49:21 -04002336 ASSERT(mTransformFeedbackMap.contains(0));
2337 return mTransformFeedbackMap.contains(transformFeedback);
Geoff Lang36167ab2015-12-07 10:27:14 -05002338}
2339
Shannon Woods53a94a82014-06-24 15:20:36 -04002340void Context::detachTexture(GLuint texture)
2341{
2342 // Simple pass-through to State's detachTexture method, as textures do not require
2343 // allocation map management either here or in the resource manager at detach time.
2344 // Zero textures are held by the Context, and we don't attempt to request them from
2345 // the State.
Jamie Madilla02315b2017-02-23 14:14:47 -05002346 mGLState.detachTexture(this, mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002347}
2348
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002349void Context::detachBuffer(GLuint buffer)
2350{
Yuly Novikov5807a532015-12-03 13:01:22 -05002351 // Simple pass-through to State's detachBuffer method, since
2352 // only buffer attachments to container objects that are bound to the current context
2353 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002354
Yuly Novikov5807a532015-12-03 13:01:22 -05002355 // [OpenGL ES 3.2] section 5.1.2 page 45:
2356 // Attachments to unbound container objects, such as
2357 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2358 // are not affected and continue to act as references on the deleted object
Jamie Madill4928b7c2017-06-20 12:57:39 -04002359 mGLState.detachBuffer(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002360}
2361
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002362void Context::detachFramebuffer(GLuint framebuffer)
2363{
Shannon Woods53a94a82014-06-24 15:20:36 -04002364 // Framebuffer detachment is handled by Context, because 0 is a valid
2365 // Framebuffer object, and a pointer to it must be passed from Context
2366 // to State at binding time.
2367
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002368 // [OpenGL ES 2.0.24] section 4.4 page 107:
Jamie Madill231c7f52017-04-26 13:45:37 -04002369 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as
2370 // though BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of
2371 // zero.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002372
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002373 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002374 {
2375 bindReadFramebuffer(0);
2376 }
2377
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002378 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002379 {
2380 bindDrawFramebuffer(0);
2381 }
2382}
2383
2384void Context::detachRenderbuffer(GLuint renderbuffer)
2385{
Jamie Madilla02315b2017-02-23 14:14:47 -05002386 mGLState.detachRenderbuffer(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002387}
2388
Jamie Madill57a89722013-07-02 11:57:03 -04002389void Context::detachVertexArray(GLuint vertexArray)
2390{
Jamie Madill77a72f62015-04-14 11:18:32 -04002391 // Vertex array detachment is handled by Context, because 0 is a valid
2392 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002393 // binding time.
2394
Jamie Madill57a89722013-07-02 11:57:03 -04002395 // [OpenGL ES 3.0.2] section 2.10 page 43:
2396 // If a vertex array object that is currently bound is deleted, the binding
2397 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002398 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002399 {
2400 bindVertexArray(0);
2401 }
2402}
2403
Geoff Langc8058452014-02-03 12:04:11 -05002404void Context::detachTransformFeedback(GLuint transformFeedback)
2405{
Corentin Walleza2257da2016-04-19 16:43:12 -04002406 // Transform feedback detachment is handled by Context, because 0 is a valid
2407 // transform feedback, and a pointer to it must be passed from Context to State at
2408 // binding time.
2409
2410 // The OpenGL specification doesn't mention what should happen when the currently bound
2411 // transform feedback object is deleted. Since it is a container object, we treat it like
2412 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madill4928b7c2017-06-20 12:57:39 -04002413 if (mGLState.removeTransformFeedbackBinding(this, transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002414 {
2415 bindTransformFeedback(0);
2416 }
Geoff Langc8058452014-02-03 12:04:11 -05002417}
2418
Jamie Madilldc356042013-07-19 16:36:57 -04002419void Context::detachSampler(GLuint sampler)
2420{
Jamie Madill4928b7c2017-06-20 12:57:39 -04002421 mGLState.detachSampler(this, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002422}
2423
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002424void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2425{
Shaodde78e82017-05-22 14:13:27 +08002426 mGLState.setVertexAttribDivisor(this, index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002427}
2428
Jamie Madille29d1672013-07-19 16:36:57 -04002429void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2430{
Geoff Langc1984ed2016-10-07 12:41:00 -04002431 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002432 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002433 SetSamplerParameteri(samplerObject, pname, param);
2434}
Jamie Madille29d1672013-07-19 16:36:57 -04002435
Geoff Langc1984ed2016-10-07 12:41:00 -04002436void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2437{
2438 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002439 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002440 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002441}
2442
2443void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2444{
Geoff Langc1984ed2016-10-07 12:41:00 -04002445 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002446 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002447 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002448}
2449
Geoff Langc1984ed2016-10-07 12:41:00 -04002450void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002451{
Geoff Langc1984ed2016-10-07 12:41:00 -04002452 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002453 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002454 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002455}
2456
Geoff Langc1984ed2016-10-07 12:41:00 -04002457void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002458{
Geoff Langc1984ed2016-10-07 12:41:00 -04002459 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002460 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002461 QuerySamplerParameteriv(samplerObject, pname, params);
2462}
Jamie Madill9675b802013-07-19 16:36:59 -04002463
Geoff Langc1984ed2016-10-07 12:41:00 -04002464void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2465{
2466 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002467 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002468 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002469}
2470
Olli Etuahof0fee072016-03-30 15:11:58 +03002471void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2472{
2473 gl::Program *programObject = getProgram(program);
Yunchao He61afff12017-03-14 15:34:03 +08002474 SetProgramParameteri(programObject, pname, value);
Olli Etuahof0fee072016-03-30 15:11:58 +03002475}
2476
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002477void Context::initRendererString()
2478{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002479 std::ostringstream rendererString;
2480 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002481 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002482 rendererString << ")";
2483
Geoff Langcec35902014-04-16 10:52:36 -04002484 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002485}
2486
Geoff Langc339c4e2016-11-29 10:37:36 -05002487void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002488{
Geoff Langc339c4e2016-11-29 10:37:36 -05002489 const Version &clientVersion = getClientVersion();
2490
2491 std::ostringstream versionString;
2492 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2493 << ANGLE_VERSION_STRING << ")";
2494 mVersionString = MakeStaticString(versionString.str());
2495
2496 std::ostringstream shadingLanguageVersionString;
2497 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2498 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2499 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2500 << ")";
2501 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002502}
2503
Geoff Langcec35902014-04-16 10:52:36 -04002504void Context::initExtensionStrings()
2505{
Geoff Langc339c4e2016-11-29 10:37:36 -05002506 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2507 std::ostringstream combinedStringStream;
2508 std::copy(strings.begin(), strings.end(),
2509 std::ostream_iterator<const char *>(combinedStringStream, " "));
2510 return MakeStaticString(combinedStringStream.str());
2511 };
2512
2513 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002514 for (const auto &extensionString : mExtensions.getStrings())
2515 {
2516 mExtensionStrings.push_back(MakeStaticString(extensionString));
2517 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002518 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002519
Bryan Bernhart58806562017-01-05 13:09:31 -08002520 const gl::Extensions &nativeExtensions = mImplementation->getNativeExtensions();
2521
Geoff Langc339c4e2016-11-29 10:37:36 -05002522 mRequestableExtensionStrings.clear();
2523 for (const auto &extensionInfo : GetExtensionInfoMap())
2524 {
2525 if (extensionInfo.second.Requestable &&
Bryan Bernhart58806562017-01-05 13:09:31 -08002526 !(mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
2527 nativeExtensions.*(extensionInfo.second.ExtensionsMember))
Geoff Langc339c4e2016-11-29 10:37:36 -05002528 {
2529 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2530 }
2531 }
2532 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002533}
2534
Geoff Langc339c4e2016-11-29 10:37:36 -05002535const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002536{
Geoff Langc339c4e2016-11-29 10:37:36 -05002537 switch (name)
2538 {
2539 case GL_VENDOR:
2540 return reinterpret_cast<const GLubyte *>("Google Inc.");
2541
2542 case GL_RENDERER:
2543 return reinterpret_cast<const GLubyte *>(mRendererString);
2544
2545 case GL_VERSION:
2546 return reinterpret_cast<const GLubyte *>(mVersionString);
2547
2548 case GL_SHADING_LANGUAGE_VERSION:
2549 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2550
2551 case GL_EXTENSIONS:
2552 return reinterpret_cast<const GLubyte *>(mExtensionString);
2553
2554 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2555 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2556
2557 default:
2558 UNREACHABLE();
2559 return nullptr;
2560 }
Geoff Langcec35902014-04-16 10:52:36 -04002561}
2562
Geoff Langc339c4e2016-11-29 10:37:36 -05002563const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002564{
Geoff Langc339c4e2016-11-29 10:37:36 -05002565 switch (name)
2566 {
2567 case GL_EXTENSIONS:
2568 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2569
2570 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2571 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2572
2573 default:
2574 UNREACHABLE();
2575 return nullptr;
2576 }
Geoff Langcec35902014-04-16 10:52:36 -04002577}
2578
2579size_t Context::getExtensionStringCount() const
2580{
2581 return mExtensionStrings.size();
2582}
2583
Geoff Langc339c4e2016-11-29 10:37:36 -05002584void Context::requestExtension(const char *name)
2585{
2586 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2587 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2588 const auto &extension = extensionInfos.at(name);
2589 ASSERT(extension.Requestable);
2590
2591 if (mExtensions.*(extension.ExtensionsMember))
2592 {
2593 // Extension already enabled
2594 return;
2595 }
2596
2597 mExtensions.*(extension.ExtensionsMember) = true;
2598 updateCaps();
2599 initExtensionStrings();
Bryan Bernhart58806562017-01-05 13:09:31 -08002600
Jamie Madill2f348d22017-06-05 10:50:59 -04002601 // Release the shader compiler so it will be re-created with the requested extensions enabled.
2602 releaseShaderCompiler();
Geoff Lang9aded172017-04-05 11:07:56 -04002603
2604 // Invalidate all cached completenesses for textures and framebuffer. Some extensions make new
2605 // formats renderable or sampleable.
2606 mState.mTextures->invalidateTextureComplenessCache();
2607 for (auto &zeroTexture : mZeroTextures)
2608 {
2609 zeroTexture.second->invalidateCompletenessCache();
2610 }
2611
2612 mState.mFramebuffers->invalidateFramebufferComplenessCache();
Geoff Langc339c4e2016-11-29 10:37:36 -05002613}
2614
2615size_t Context::getRequestableExtensionStringCount() const
2616{
2617 return mRequestableExtensionStrings.size();
2618}
2619
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002620void Context::beginTransformFeedback(GLenum primitiveMode)
2621{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002622 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002623 ASSERT(transformFeedback != nullptr);
2624 ASSERT(!transformFeedback->isPaused());
2625
Jamie Madill6c1f6712017-02-14 19:08:04 -05002626 transformFeedback->begin(this, primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002627}
2628
2629bool Context::hasActiveTransformFeedback(GLuint program) const
2630{
2631 for (auto pair : mTransformFeedbackMap)
2632 {
2633 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2634 {
2635 return true;
2636 }
2637 }
2638 return false;
2639}
2640
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002641void Context::initCaps(const egl::DisplayExtensions &displayExtensions)
Geoff Lang493daf52014-07-03 13:38:44 -04002642{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002643 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002644
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002645 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002646
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002647 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002648
Geoff Langeb66a6e2016-10-31 13:06:12 -04002649 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002650 {
2651 // Disable ES3+ extensions
Jamie Madill231c7f52017-04-26 13:45:37 -04002652 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002653 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002654 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002655 }
2656
Geoff Langeb66a6e2016-10-31 13:06:12 -04002657 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002658 {
2659 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
Jamie Madill231c7f52017-04-26 13:45:37 -04002660 // mExtensions.sRGB = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002661 }
2662
Jamie Madill00ed7a12016-05-19 13:13:38 -04002663 // Some extensions are always available because they are implemented in the GL layer.
Jamie Madill231c7f52017-04-26 13:45:37 -04002664 mExtensions.bindUniformLocation = true;
2665 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002666 mExtensions.bindGeneratesResource = true;
Geoff Langfeb8c682017-02-13 16:07:35 -05002667 mExtensions.clientArrays = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002668 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002669
2670 // Enable the no error extension if the context was created with the flag.
2671 mExtensions.noError = mSkipValidation;
2672
Corentin Wallezccab69d2017-01-27 16:57:15 -05002673 // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
Corentin Wallezc295e512017-01-27 17:47:50 -05002674 mExtensions.surfacelessContext = displayExtensions.surfacelessContext;
Corentin Wallezccab69d2017-01-27 16:57:15 -05002675
Geoff Lang70d0f492015-12-10 17:45:46 -05002676 // Explicitly enable GL_KHR_debug
2677 mExtensions.debug = true;
2678 mExtensions.maxDebugMessageLength = 1024;
2679 mExtensions.maxDebugLoggedMessages = 1024;
2680 mExtensions.maxDebugGroupStackDepth = 1024;
2681 mExtensions.maxLabelLength = 1024;
2682
Geoff Langff5b2d52016-09-07 11:32:23 -04002683 // Explicitly enable GL_ANGLE_robust_client_memory
2684 mExtensions.robustClientMemory = true;
2685
Jamie Madille08a1d32017-03-07 17:24:06 -05002686 // Determine robust resource init availability from EGL.
2687 mExtensions.robustResourceInitialization =
Jamie Madill948bbe52017-06-01 13:10:42 -04002688 egl::Display::GetClientExtensions().displayRobustResourceInitialization;
Jamie Madille08a1d32017-03-07 17:24:06 -05002689
Jamie Madillc43be722017-07-13 16:22:14 -04002690 // Enable the cache control query unconditionally.
2691 mExtensions.programCacheControl = true;
2692
Geoff Lang301d1612014-07-09 10:34:37 -04002693 // Apply implementation limits
2694 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002695 mCaps.maxVertexAttribBindings =
2696 getClientVersion() < ES_3_1
2697 ? mCaps.maxVertexAttributes
2698 : std::min<GLuint>(mCaps.maxVertexAttribBindings, MAX_VERTEX_ATTRIB_BINDINGS);
2699
Jamie Madill231c7f52017-04-26 13:45:37 -04002700 mCaps.maxVertexUniformBlocks = std::min<GLuint>(
2701 mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2702 mCaps.maxVertexOutputComponents =
2703 std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang301d1612014-07-09 10:34:37 -04002704
Jamie Madill231c7f52017-04-26 13:45:37 -04002705 mCaps.maxFragmentInputComponents =
2706 std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002707
Geoff Langc287ea62016-09-16 14:46:51 -04002708 // WebGL compatibility
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002709 mExtensions.webglCompatibility = mWebGLContext;
Geoff Langc287ea62016-09-16 14:46:51 -04002710 for (const auto &extensionInfo : GetExtensionInfoMap())
2711 {
2712 // If this context is for WebGL, disable all enableable extensions
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002713 if (mWebGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002714 {
2715 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2716 }
2717 }
2718
2719 // Generate texture caps
2720 updateCaps();
2721}
2722
2723void Context::updateCaps()
2724{
Geoff Lang900013c2014-07-07 11:32:19 -04002725 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002726 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002727
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002728 for (auto capsIt : mImplementation->getNativeTextureCaps())
Geoff Lang493daf52014-07-03 13:38:44 -04002729 {
Geoff Langca271392017-04-05 12:30:00 -04002730 GLenum sizedInternalFormat = capsIt.first;
Jamie Madill231c7f52017-04-26 13:45:37 -04002731 TextureCaps formatCaps = capsIt.second;
Geoff Lang493daf52014-07-03 13:38:44 -04002732
Geoff Langca271392017-04-05 12:30:00 -04002733 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002734
Geoff Lang0d8b7242015-09-09 14:56:53 -04002735 // Update the format caps based on the client version and extensions.
2736 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2737 // ES3.
2738 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002739 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002740 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002741 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002742 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002743 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002744
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002745 // OpenGL ES does not support multisampling with non-rendererable formats
2746 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
Olli Etuaho50c562d2017-06-06 14:43:30 +03002747 if (!formatCaps.renderable ||
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002748 (getClientVersion() < ES_3_1 &&
2749 (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
Geoff Lang493daf52014-07-03 13:38:44 -04002750 {
Geoff Langd87878e2014-09-19 15:42:59 -04002751 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002752 }
Olli Etuaho50c562d2017-06-06 14:43:30 +03002753 else
2754 {
2755 // We may have limited the max samples for some required renderbuffer formats due to
2756 // non-conformant formats. In this case MAX_SAMPLES needs to be lowered accordingly.
2757 GLuint formatMaxSamples = formatCaps.getMaxSamples();
2758
2759 // GLES 3.0.5 section 4.4.2.2: "Implementations must support creation of renderbuffers
2760 // in these required formats with up to the value of MAX_SAMPLES multisamples, with the
2761 // exception of signed and unsigned integer formats."
2762 if (formatInfo.componentType != GL_INT && formatInfo.componentType != GL_UNSIGNED_INT &&
2763 formatInfo.isRequiredRenderbufferFormat(getClientVersion()))
2764 {
2765 ASSERT(getClientVersion() < ES_3_0 || formatMaxSamples >= 4);
2766 mCaps.maxSamples = std::min(mCaps.maxSamples, formatMaxSamples);
2767 }
2768
2769 // Handle GLES 3.1 MAX_*_SAMPLES values similarly to MAX_SAMPLES.
2770 if (getClientVersion() >= ES_3_1)
2771 {
2772 // GLES 3.1 section 9.2.5: "Implementations must support creation of renderbuffers
2773 // in these required formats with up to the value of MAX_SAMPLES multisamples, with
2774 // the exception that the signed and unsigned integer formats are required only to
2775 // support creation of renderbuffers with up to the value of MAX_INTEGER_SAMPLES
2776 // multisamples, which must be at least one."
2777 if (formatInfo.componentType == GL_INT ||
2778 formatInfo.componentType == GL_UNSIGNED_INT)
2779 {
2780 mCaps.maxIntegerSamples = std::min(mCaps.maxIntegerSamples, formatMaxSamples);
2781 }
2782
2783 // GLES 3.1 section 19.3.1.
2784 if (formatCaps.texturable)
2785 {
2786 if (formatInfo.depthBits > 0)
2787 {
2788 mCaps.maxDepthTextureSamples =
2789 std::min(mCaps.maxDepthTextureSamples, formatMaxSamples);
2790 }
2791 else if (formatInfo.redBits > 0)
2792 {
2793 mCaps.maxColorTextureSamples =
2794 std::min(mCaps.maxColorTextureSamples, formatMaxSamples);
2795 }
2796 }
2797 }
2798 }
Geoff Langd87878e2014-09-19 15:42:59 -04002799
2800 if (formatCaps.texturable && formatInfo.compressed)
2801 {
Geoff Langca271392017-04-05 12:30:00 -04002802 mCaps.compressedTextureFormats.push_back(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002803 }
2804
Geoff Langca271392017-04-05 12:30:00 -04002805 mTextureCaps.insert(sizedInternalFormat, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002806 }
Jamie Madill32447362017-06-28 14:53:52 -04002807
2808 // If program binary is disabled, blank out the memory cache pointer.
2809 if (!mImplementation->getNativeExtensions().getProgramBinary)
2810 {
2811 mMemoryProgramCache = nullptr;
2812 }
Geoff Lang493daf52014-07-03 13:38:44 -04002813}
2814
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002815void Context::initWorkarounds()
2816{
Jamie Madill761b02c2017-06-23 16:27:06 -04002817 // Apply back-end workarounds.
2818 mImplementation->applyNativeWorkarounds(&mWorkarounds);
2819
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002820 // Lose the context upon out of memory error if the application is
2821 // expecting to watch for those events.
2822 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2823}
2824
Jamie Madill1b94d432015-08-07 13:23:23 -04002825void Context::syncRendererState()
2826{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002827 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
Jamie Madillfe548342017-06-19 11:13:24 -04002828 mImplementation->syncState(this, dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002829 mGLState.clearDirtyBits();
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002830 mGLState.syncDirtyObjects(this);
Jamie Madill1b94d432015-08-07 13:23:23 -04002831}
2832
Jamie Madillad9f24e2016-02-12 09:27:24 -05002833void Context::syncRendererState(const State::DirtyBits &bitMask,
2834 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002835{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002836 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
Jamie Madillfe548342017-06-19 11:13:24 -04002837 mImplementation->syncState(this, dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002838 mGLState.clearDirtyBits(dirtyBits);
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002839 mGLState.syncDirtyObjects(this, objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002840}
Jamie Madillc29968b2016-01-20 11:17:23 -05002841
2842void Context::blitFramebuffer(GLint srcX0,
2843 GLint srcY0,
2844 GLint srcX1,
2845 GLint srcY1,
2846 GLint dstX0,
2847 GLint dstY0,
2848 GLint dstX1,
2849 GLint dstY1,
2850 GLbitfield mask,
2851 GLenum filter)
2852{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002853 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002854 ASSERT(drawFramebuffer);
2855
2856 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2857 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2858
Jamie Madillad9f24e2016-02-12 09:27:24 -05002859 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002860
Jamie Madillc564c072017-06-01 12:45:42 -04002861 handleError(drawFramebuffer->blit(this, srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002862}
Jamie Madillc29968b2016-01-20 11:17:23 -05002863
2864void Context::clear(GLbitfield mask)
2865{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002866 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002867 handleError(mGLState.getDrawFramebuffer()->clear(this, mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002868}
2869
2870void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2871{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002872 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002873 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002874}
2875
2876void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2877{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002878 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002879 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002880}
2881
2882void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2883{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002884 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002885 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002886}
2887
2888void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2889{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002890 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002891 ASSERT(framebufferObject);
2892
2893 // If a buffer is not present, the clear has no effect
2894 if (framebufferObject->getDepthbuffer() == nullptr &&
2895 framebufferObject->getStencilbuffer() == nullptr)
2896 {
2897 return;
2898 }
2899
Jamie Madillad9f24e2016-02-12 09:27:24 -05002900 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002901 handleError(framebufferObject->clearBufferfi(this, buffer, drawbuffer, depth, stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002902}
2903
2904void Context::readPixels(GLint x,
2905 GLint y,
2906 GLsizei width,
2907 GLsizei height,
2908 GLenum format,
2909 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002910 void *pixels)
Jamie Madillc29968b2016-01-20 11:17:23 -05002911{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002912 if (width == 0 || height == 0)
2913 {
2914 return;
2915 }
2916
Jamie Madillad9f24e2016-02-12 09:27:24 -05002917 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002918
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002919 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002920 ASSERT(framebufferObject);
2921
2922 Rectangle area(x, y, width, height);
Jamie Madillc564c072017-06-01 12:45:42 -04002923 handleError(framebufferObject->readPixels(this, area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002924}
2925
2926void Context::copyTexImage2D(GLenum target,
2927 GLint level,
2928 GLenum internalformat,
2929 GLint x,
2930 GLint y,
2931 GLsizei width,
2932 GLsizei height,
2933 GLint border)
2934{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002935 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002936 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002937
Jamie Madillc29968b2016-01-20 11:17:23 -05002938 Rectangle sourceArea(x, y, width, height);
2939
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002940 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002941 Texture *texture =
2942 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002943 handleError(texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002944}
2945
2946void Context::copyTexSubImage2D(GLenum target,
2947 GLint level,
2948 GLint xoffset,
2949 GLint yoffset,
2950 GLint x,
2951 GLint y,
2952 GLsizei width,
2953 GLsizei height)
2954{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002955 if (width == 0 || height == 0)
2956 {
2957 return;
2958 }
2959
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002960 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002961 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002962
Jamie Madillc29968b2016-01-20 11:17:23 -05002963 Offset destOffset(xoffset, yoffset, 0);
2964 Rectangle sourceArea(x, y, width, height);
2965
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002966 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002967 Texture *texture =
2968 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002969 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002970}
2971
2972void Context::copyTexSubImage3D(GLenum target,
2973 GLint level,
2974 GLint xoffset,
2975 GLint yoffset,
2976 GLint zoffset,
2977 GLint x,
2978 GLint y,
2979 GLsizei width,
2980 GLsizei height)
2981{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002982 if (width == 0 || height == 0)
2983 {
2984 return;
2985 }
2986
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002987 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002988 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002989
Jamie Madillc29968b2016-01-20 11:17:23 -05002990 Offset destOffset(xoffset, yoffset, zoffset);
2991 Rectangle sourceArea(x, y, width, height);
2992
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002993 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002994 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002995 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002996}
2997
2998void Context::framebufferTexture2D(GLenum target,
2999 GLenum attachment,
3000 GLenum textarget,
3001 GLuint texture,
3002 GLint level)
3003{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003004 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003005 ASSERT(framebuffer);
3006
3007 if (texture != 0)
3008 {
3009 Texture *textureObj = getTexture(texture);
3010
3011 ImageIndex index = ImageIndex::MakeInvalid();
3012
3013 if (textarget == GL_TEXTURE_2D)
3014 {
3015 index = ImageIndex::Make2D(level);
3016 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08003017 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
3018 {
3019 ASSERT(level == 0);
3020 index = ImageIndex::Make2DMultisample();
3021 }
Jamie Madillc29968b2016-01-20 11:17:23 -05003022 else
3023 {
3024 ASSERT(IsCubeMapTextureTarget(textarget));
3025 index = ImageIndex::MakeCube(textarget, level);
3026 }
3027
Jamie Madilla02315b2017-02-23 14:14:47 -05003028 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
Jamie Madillc29968b2016-01-20 11:17:23 -05003029 }
3030 else
3031 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003032 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003033 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003034
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003035 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003036}
3037
3038void Context::framebufferRenderbuffer(GLenum target,
3039 GLenum attachment,
3040 GLenum renderbuffertarget,
3041 GLuint renderbuffer)
3042{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003043 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003044 ASSERT(framebuffer);
3045
3046 if (renderbuffer != 0)
3047 {
3048 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
Jamie Madilla02315b2017-02-23 14:14:47 -05003049
3050 framebuffer->setAttachment(this, GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
Jamie Madillc29968b2016-01-20 11:17:23 -05003051 renderbufferObject);
3052 }
3053 else
3054 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003055 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003056 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003057
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003058 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003059}
3060
3061void Context::framebufferTextureLayer(GLenum target,
3062 GLenum attachment,
3063 GLuint texture,
3064 GLint level,
3065 GLint layer)
3066{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003067 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003068 ASSERT(framebuffer);
3069
3070 if (texture != 0)
3071 {
3072 Texture *textureObject = getTexture(texture);
3073
3074 ImageIndex index = ImageIndex::MakeInvalid();
3075
3076 if (textureObject->getTarget() == GL_TEXTURE_3D)
3077 {
3078 index = ImageIndex::Make3D(level, layer);
3079 }
3080 else
3081 {
3082 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
3083 index = ImageIndex::Make2DArray(level, layer);
3084 }
3085
Jamie Madilla02315b2017-02-23 14:14:47 -05003086 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObject);
Jamie Madillc29968b2016-01-20 11:17:23 -05003087 }
3088 else
3089 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003090 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003091 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003092
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003093 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003094}
3095
3096void Context::drawBuffers(GLsizei n, const GLenum *bufs)
3097{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003098 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003099 ASSERT(framebuffer);
3100 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003101 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003102}
3103
3104void Context::readBuffer(GLenum mode)
3105{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003106 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003107 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003108 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003109}
3110
3111void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
3112{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003113 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003114 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003115
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003116 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003117 ASSERT(framebuffer);
3118
3119 // The specification isn't clear what should be done when the framebuffer isn't complete.
3120 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill4928b7c2017-06-20 12:57:39 -04003121 handleError(framebuffer->discard(this, numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003122}
3123
3124void Context::invalidateFramebuffer(GLenum target,
3125 GLsizei numAttachments,
3126 const GLenum *attachments)
3127{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003128 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003129 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003130
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003131 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003132 ASSERT(framebuffer);
3133
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003134 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003135 {
Jamie Madill437fa652016-05-03 15:13:24 -04003136 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003137 }
Jamie Madill437fa652016-05-03 15:13:24 -04003138
Jamie Madill4928b7c2017-06-20 12:57:39 -04003139 handleError(framebuffer->invalidate(this, numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003140}
3141
3142void Context::invalidateSubFramebuffer(GLenum target,
3143 GLsizei numAttachments,
3144 const GLenum *attachments,
3145 GLint x,
3146 GLint y,
3147 GLsizei width,
3148 GLsizei height)
3149{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003150 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003151 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003152
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003153 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003154 ASSERT(framebuffer);
3155
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003156 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003157 {
Jamie Madill437fa652016-05-03 15:13:24 -04003158 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003159 }
Jamie Madill437fa652016-05-03 15:13:24 -04003160
3161 Rectangle area(x, y, width, height);
Jamie Madill4928b7c2017-06-20 12:57:39 -04003162 handleError(framebuffer->invalidateSub(this, numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05003163}
3164
Jamie Madill73a84962016-02-12 09:27:23 -05003165void Context::texImage2D(GLenum target,
3166 GLint level,
3167 GLint internalformat,
3168 GLsizei width,
3169 GLsizei height,
3170 GLint border,
3171 GLenum format,
3172 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003173 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003174{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003175 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003176
3177 Extents size(width, height, 1);
3178 Texture *texture =
3179 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003180 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3181 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003182}
3183
3184void Context::texImage3D(GLenum target,
3185 GLint level,
3186 GLint internalformat,
3187 GLsizei width,
3188 GLsizei height,
3189 GLsizei depth,
3190 GLint border,
3191 GLenum format,
3192 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003193 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003194{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003195 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003196
3197 Extents size(width, height, depth);
3198 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003199 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3200 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003201}
3202
3203void Context::texSubImage2D(GLenum target,
3204 GLint level,
3205 GLint xoffset,
3206 GLint yoffset,
3207 GLsizei width,
3208 GLsizei height,
3209 GLenum format,
3210 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003211 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003212{
3213 // Zero sized uploads are valid but no-ops
3214 if (width == 0 || height == 0)
3215 {
3216 return;
3217 }
3218
Jamie Madillad9f24e2016-02-12 09:27:24 -05003219 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003220
3221 Box area(xoffset, yoffset, 0, width, height, 1);
3222 Texture *texture =
3223 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003224 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3225 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003226}
3227
3228void Context::texSubImage3D(GLenum target,
3229 GLint level,
3230 GLint xoffset,
3231 GLint yoffset,
3232 GLint zoffset,
3233 GLsizei width,
3234 GLsizei height,
3235 GLsizei depth,
3236 GLenum format,
3237 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003238 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003239{
3240 // Zero sized uploads are valid but no-ops
3241 if (width == 0 || height == 0 || depth == 0)
3242 {
3243 return;
3244 }
3245
Jamie Madillad9f24e2016-02-12 09:27:24 -05003246 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003247
3248 Box area(xoffset, yoffset, zoffset, width, height, depth);
3249 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003250 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3251 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003252}
3253
3254void Context::compressedTexImage2D(GLenum target,
3255 GLint level,
3256 GLenum internalformat,
3257 GLsizei width,
3258 GLsizei height,
3259 GLint border,
3260 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003261 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003262{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003263 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003264
3265 Extents size(width, height, 1);
3266 Texture *texture =
3267 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003268 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003269 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003270 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003271}
3272
3273void Context::compressedTexImage3D(GLenum target,
3274 GLint level,
3275 GLenum internalformat,
3276 GLsizei width,
3277 GLsizei height,
3278 GLsizei depth,
3279 GLint border,
3280 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003281 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003282{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003283 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003284
3285 Extents size(width, height, depth);
3286 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003287 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003288 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003289 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003290}
3291
3292void Context::compressedTexSubImage2D(GLenum target,
3293 GLint level,
3294 GLint xoffset,
3295 GLint yoffset,
3296 GLsizei width,
3297 GLsizei height,
3298 GLenum format,
3299 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003300 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003301{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003302 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003303
3304 Box area(xoffset, yoffset, 0, width, height, 1);
3305 Texture *texture =
3306 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003307 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003308 format, imageSize,
3309 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003310}
3311
3312void Context::compressedTexSubImage3D(GLenum target,
3313 GLint level,
3314 GLint xoffset,
3315 GLint yoffset,
3316 GLint zoffset,
3317 GLsizei width,
3318 GLsizei height,
3319 GLsizei depth,
3320 GLenum format,
3321 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003322 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003323{
3324 // Zero sized uploads are valid but no-ops
3325 if (width == 0 || height == 0)
3326 {
3327 return;
3328 }
3329
Jamie Madillad9f24e2016-02-12 09:27:24 -05003330 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003331
3332 Box area(xoffset, yoffset, zoffset, width, height, depth);
3333 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003334 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003335 format, imageSize,
3336 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003337}
3338
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003339void Context::generateMipmap(GLenum target)
3340{
3341 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003342 handleError(texture->generateMipmap(this));
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003343}
3344
Geoff Lang97073d12016-04-20 10:42:34 -07003345void Context::copyTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003346 GLint sourceLevel,
3347 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003348 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003349 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003350 GLint internalFormat,
3351 GLenum destType,
3352 GLboolean unpackFlipY,
3353 GLboolean unpackPremultiplyAlpha,
3354 GLboolean unpackUnmultiplyAlpha)
3355{
3356 syncStateForTexImage();
3357
3358 gl::Texture *sourceTexture = getTexture(sourceId);
3359 gl::Texture *destTexture = getTexture(destId);
Geoff Langfc72a072017-03-24 14:52:39 -04003360 handleError(destTexture->copyTexture(
3361 this, destTarget, destLevel, internalFormat, destType, sourceLevel, unpackFlipY == GL_TRUE,
3362 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003363}
3364
3365void Context::copySubTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003366 GLint sourceLevel,
3367 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003368 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003369 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003370 GLint xoffset,
3371 GLint yoffset,
3372 GLint x,
3373 GLint y,
3374 GLsizei width,
3375 GLsizei height,
3376 GLboolean unpackFlipY,
3377 GLboolean unpackPremultiplyAlpha,
3378 GLboolean unpackUnmultiplyAlpha)
3379{
3380 // Zero sized copies are valid but no-ops
3381 if (width == 0 || height == 0)
3382 {
3383 return;
3384 }
3385
3386 syncStateForTexImage();
3387
3388 gl::Texture *sourceTexture = getTexture(sourceId);
3389 gl::Texture *destTexture = getTexture(destId);
3390 Offset offset(xoffset, yoffset, 0);
3391 Rectangle area(x, y, width, height);
Geoff Langfc72a072017-03-24 14:52:39 -04003392 handleError(destTexture->copySubTexture(
3393 this, destTarget, destLevel, offset, sourceLevel, area, unpackFlipY == GL_TRUE,
3394 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003395}
3396
Geoff Lang47110bf2016-04-20 11:13:22 -07003397void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3398{
3399 syncStateForTexImage();
3400
3401 gl::Texture *sourceTexture = getTexture(sourceId);
3402 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003403 handleError(destTexture->copyCompressedTexture(this, sourceTexture));
Geoff Lang47110bf2016-04-20 11:13:22 -07003404}
3405
Geoff Lang496c02d2016-10-20 11:38:11 -07003406void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003407{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003408 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003409 ASSERT(buffer);
3410
Geoff Lang496c02d2016-10-20 11:38:11 -07003411 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003412}
3413
Jamie Madill876429b2017-04-20 15:46:24 -04003414void *Context::mapBuffer(GLenum target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003415{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003416 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003417 ASSERT(buffer);
3418
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003419 Error error = buffer->map(this, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003420 if (error.isError())
3421 {
Jamie Madill437fa652016-05-03 15:13:24 -04003422 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003423 return nullptr;
3424 }
3425
3426 return buffer->getMapPointer();
3427}
3428
3429GLboolean Context::unmapBuffer(GLenum target)
3430{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003431 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003432 ASSERT(buffer);
3433
3434 GLboolean result;
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003435 Error error = buffer->unmap(this, &result);
Olli Etuaho4f667482016-03-30 15:56:35 +03003436 if (error.isError())
3437 {
Jamie Madill437fa652016-05-03 15:13:24 -04003438 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003439 return GL_FALSE;
3440 }
3441
3442 return result;
3443}
3444
Jamie Madill876429b2017-04-20 15:46:24 -04003445void *Context::mapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003446{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003447 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003448 ASSERT(buffer);
3449
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003450 Error error = buffer->mapRange(this, offset, length, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003451 if (error.isError())
3452 {
Jamie Madill437fa652016-05-03 15:13:24 -04003453 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003454 return nullptr;
3455 }
3456
3457 return buffer->getMapPointer();
3458}
3459
3460void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3461{
3462 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3463}
3464
Jamie Madillad9f24e2016-02-12 09:27:24 -05003465void Context::syncStateForReadPixels()
3466{
3467 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3468}
3469
3470void Context::syncStateForTexImage()
3471{
3472 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3473}
3474
3475void Context::syncStateForClear()
3476{
3477 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3478}
3479
3480void Context::syncStateForBlit()
3481{
3482 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3483}
3484
Jamie Madillc20ab272016-06-09 07:20:46 -07003485void Context::activeTexture(GLenum texture)
3486{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003487 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003488}
3489
Jamie Madill876429b2017-04-20 15:46:24 -04003490void Context::blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003491{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003492 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003493}
3494
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003495void Context::blendEquation(GLenum mode)
3496{
3497 mGLState.setBlendEquation(mode, mode);
3498}
3499
Jamie Madillc20ab272016-06-09 07:20:46 -07003500void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3501{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003502 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003503}
3504
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003505void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3506{
3507 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3508}
3509
Jamie Madillc20ab272016-06-09 07:20:46 -07003510void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3511{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003512 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003513}
3514
Jamie Madill876429b2017-04-20 15:46:24 -04003515void Context::clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003516{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003517 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003518}
3519
Jamie Madill876429b2017-04-20 15:46:24 -04003520void Context::clearDepthf(GLfloat depth)
Jamie Madillc20ab272016-06-09 07:20:46 -07003521{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003522 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003523}
3524
3525void Context::clearStencil(GLint s)
3526{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003527 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003528}
3529
3530void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3531{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003532 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003533}
3534
3535void Context::cullFace(GLenum mode)
3536{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003537 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003538}
3539
3540void Context::depthFunc(GLenum func)
3541{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003542 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003543}
3544
3545void Context::depthMask(GLboolean flag)
3546{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003547 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003548}
3549
Jamie Madill876429b2017-04-20 15:46:24 -04003550void Context::depthRangef(GLfloat zNear, GLfloat zFar)
Jamie Madillc20ab272016-06-09 07:20:46 -07003551{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003552 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003553}
3554
3555void Context::disable(GLenum cap)
3556{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003557 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003558}
3559
3560void Context::disableVertexAttribArray(GLuint index)
3561{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003562 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003563}
3564
3565void Context::enable(GLenum cap)
3566{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003567 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003568}
3569
3570void Context::enableVertexAttribArray(GLuint index)
3571{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003572 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003573}
3574
3575void Context::frontFace(GLenum mode)
3576{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003577 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003578}
3579
3580void Context::hint(GLenum target, GLenum mode)
3581{
3582 switch (target)
3583 {
3584 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003585 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003586 break;
3587
3588 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003589 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003590 break;
3591
3592 default:
3593 UNREACHABLE();
3594 return;
3595 }
3596}
3597
3598void Context::lineWidth(GLfloat width)
3599{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003600 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003601}
3602
3603void Context::pixelStorei(GLenum pname, GLint param)
3604{
3605 switch (pname)
3606 {
3607 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003608 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003609 break;
3610
3611 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003612 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003613 break;
3614
3615 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003616 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003617 break;
3618
3619 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003620 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003621 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003622 break;
3623
3624 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003625 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003626 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003627 break;
3628
3629 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003630 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003631 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003632 break;
3633
3634 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003635 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003636 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003637 break;
3638
3639 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003640 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003641 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003642 break;
3643
3644 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003645 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003646 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003647 break;
3648
3649 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003650 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003651 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003652 break;
3653
3654 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003655 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003656 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003657 break;
3658
3659 default:
3660 UNREACHABLE();
3661 return;
3662 }
3663}
3664
3665void Context::polygonOffset(GLfloat factor, GLfloat units)
3666{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003667 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003668}
3669
Jamie Madill876429b2017-04-20 15:46:24 -04003670void Context::sampleCoverage(GLfloat value, GLboolean invert)
Jamie Madillc20ab272016-06-09 07:20:46 -07003671{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003672 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003673}
3674
3675void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3676{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003677 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003678}
3679
3680void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3681{
3682 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3683 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003684 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003685 }
3686
3687 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3688 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003689 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003690 }
3691}
3692
3693void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3694{
3695 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3696 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003697 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003698 }
3699
3700 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3701 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003702 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003703 }
3704}
3705
3706void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3707{
3708 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3709 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003710 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003711 }
3712
3713 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3714 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003715 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003716 }
3717}
3718
3719void Context::vertexAttrib1f(GLuint index, GLfloat x)
3720{
3721 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003722 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003723}
3724
3725void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3726{
3727 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003728 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003729}
3730
3731void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3732{
3733 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003734 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003735}
3736
3737void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3738{
3739 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003740 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003741}
3742
3743void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3744{
3745 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003746 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003747}
3748
3749void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3750{
3751 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003752 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003753}
3754
3755void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3756{
3757 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003758 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003759}
3760
3761void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3762{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003763 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003764}
3765
3766void Context::vertexAttribPointer(GLuint index,
3767 GLint size,
3768 GLenum type,
3769 GLboolean normalized,
3770 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003771 const void *ptr)
Jamie Madillc20ab272016-06-09 07:20:46 -07003772{
Shaodde78e82017-05-22 14:13:27 +08003773 mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size,
3774 type, normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003775}
3776
Shao80957d92017-02-20 21:25:59 +08003777void Context::vertexAttribFormat(GLuint attribIndex,
3778 GLint size,
3779 GLenum type,
3780 GLboolean normalized,
3781 GLuint relativeOffset)
3782{
3783 mGLState.setVertexAttribFormat(attribIndex, size, type, normalized == GL_TRUE, false,
3784 relativeOffset);
3785}
3786
3787void Context::vertexAttribIFormat(GLuint attribIndex,
3788 GLint size,
3789 GLenum type,
3790 GLuint relativeOffset)
3791{
3792 mGLState.setVertexAttribFormat(attribIndex, size, type, false, true, relativeOffset);
3793}
3794
3795void Context::vertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
3796{
Shaodde78e82017-05-22 14:13:27 +08003797 mGLState.setVertexAttribBinding(this, attribIndex, bindingIndex);
Shao80957d92017-02-20 21:25:59 +08003798}
3799
3800void Context::setVertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
3801{
3802 mGLState.setVertexBindingDivisor(bindingIndex, divisor);
3803}
3804
Jamie Madillc20ab272016-06-09 07:20:46 -07003805void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3806{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003807 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003808}
3809
3810void Context::vertexAttribIPointer(GLuint index,
3811 GLint size,
3812 GLenum type,
3813 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003814 const void *pointer)
Jamie Madillc20ab272016-06-09 07:20:46 -07003815{
Shaodde78e82017-05-22 14:13:27 +08003816 mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size,
3817 type, false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003818}
3819
3820void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3821{
3822 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003823 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003824}
3825
3826void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3827{
3828 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003829 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003830}
3831
3832void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3833{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003834 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003835}
3836
3837void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3838{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003839 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003840}
3841
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003842void Context::getVertexAttribiv(GLuint index, GLenum pname, GLint *params)
3843{
3844 const VertexAttribCurrentValueData &currentValues =
3845 getGLState().getVertexAttribCurrentValue(index);
3846 const VertexArray *vao = getGLState().getVertexArray();
3847 QueryVertexAttribiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3848 currentValues, pname, params);
3849}
3850
3851void Context::getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
3852{
3853 const VertexAttribCurrentValueData &currentValues =
3854 getGLState().getVertexAttribCurrentValue(index);
3855 const VertexArray *vao = getGLState().getVertexArray();
3856 QueryVertexAttribfv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3857 currentValues, pname, params);
3858}
3859
3860void Context::getVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
3861{
3862 const VertexAttribCurrentValueData &currentValues =
3863 getGLState().getVertexAttribCurrentValue(index);
3864 const VertexArray *vao = getGLState().getVertexArray();
3865 QueryVertexAttribIiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3866 currentValues, pname, params);
3867}
3868
3869void Context::getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
3870{
3871 const VertexAttribCurrentValueData &currentValues =
3872 getGLState().getVertexAttribCurrentValue(index);
3873 const VertexArray *vao = getGLState().getVertexArray();
3874 QueryVertexAttribIuiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3875 currentValues, pname, params);
3876}
3877
Jamie Madill876429b2017-04-20 15:46:24 -04003878void Context::getVertexAttribPointerv(GLuint index, GLenum pname, void **pointer)
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003879{
3880 const VertexAttribute &attrib = getGLState().getVertexArray()->getVertexAttribute(index);
3881 QueryVertexAttribPointerv(attrib, pname, pointer);
3882}
3883
Jamie Madillc20ab272016-06-09 07:20:46 -07003884void Context::debugMessageControl(GLenum source,
3885 GLenum type,
3886 GLenum severity,
3887 GLsizei count,
3888 const GLuint *ids,
3889 GLboolean enabled)
3890{
3891 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003892 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3893 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003894}
3895
3896void Context::debugMessageInsert(GLenum source,
3897 GLenum type,
3898 GLuint id,
3899 GLenum severity,
3900 GLsizei length,
3901 const GLchar *buf)
3902{
3903 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003904 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003905}
3906
3907void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3908{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003909 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003910}
3911
3912GLuint Context::getDebugMessageLog(GLuint count,
3913 GLsizei bufSize,
3914 GLenum *sources,
3915 GLenum *types,
3916 GLuint *ids,
3917 GLenum *severities,
3918 GLsizei *lengths,
3919 GLchar *messageLog)
3920{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003921 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3922 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003923}
3924
3925void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3926{
3927 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003928 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003929}
3930
3931void Context::popDebugGroup()
3932{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003933 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003934}
3935
Jamie Madill876429b2017-04-20 15:46:24 -04003936void Context::bufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage)
Jamie Madill29639852016-09-02 15:00:09 -04003937{
3938 Buffer *buffer = mGLState.getTargetBuffer(target);
3939 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003940 handleError(buffer->bufferData(this, target, data, size, usage));
Jamie Madill29639852016-09-02 15:00:09 -04003941}
3942
Jamie Madill876429b2017-04-20 15:46:24 -04003943void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04003944{
3945 if (data == nullptr)
3946 {
3947 return;
3948 }
3949
3950 Buffer *buffer = mGLState.getTargetBuffer(target);
3951 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003952 handleError(buffer->bufferSubData(this, target, data, size, offset));
Jamie Madill29639852016-09-02 15:00:09 -04003953}
3954
Jamie Madillef300b12016-10-07 15:12:09 -04003955void Context::attachShader(GLuint program, GLuint shader)
3956{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003957 auto programObject = mState.mShaderPrograms->getProgram(program);
3958 auto shaderObject = mState.mShaderPrograms->getShader(shader);
Jamie Madillef300b12016-10-07 15:12:09 -04003959 ASSERT(programObject && shaderObject);
3960 programObject->attachShader(shaderObject);
3961}
3962
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003963const Workarounds &Context::getWorkarounds() const
3964{
3965 return mWorkarounds;
3966}
3967
Jamie Madillb0817d12016-11-01 15:48:31 -04003968void Context::copyBufferSubData(GLenum readTarget,
3969 GLenum writeTarget,
3970 GLintptr readOffset,
3971 GLintptr writeOffset,
3972 GLsizeiptr size)
3973{
3974 // if size is zero, the copy is a successful no-op
3975 if (size == 0)
3976 {
3977 return;
3978 }
3979
3980 // TODO(jmadill): cache these.
3981 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3982 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3983
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003984 handleError(writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size));
Jamie Madillb0817d12016-11-01 15:48:31 -04003985}
3986
Jamie Madill01a80ee2016-11-07 12:06:18 -05003987void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3988{
3989 Program *programObject = getProgram(program);
3990 // TODO(jmadill): Re-use this from the validation if possible.
3991 ASSERT(programObject);
3992 programObject->bindAttributeLocation(index, name);
3993}
3994
3995void Context::bindBuffer(GLenum target, GLuint buffer)
3996{
3997 switch (target)
3998 {
3999 case GL_ARRAY_BUFFER:
4000 bindArrayBuffer(buffer);
4001 break;
4002 case GL_ELEMENT_ARRAY_BUFFER:
4003 bindElementArrayBuffer(buffer);
4004 break;
4005 case GL_COPY_READ_BUFFER:
4006 bindCopyReadBuffer(buffer);
4007 break;
4008 case GL_COPY_WRITE_BUFFER:
4009 bindCopyWriteBuffer(buffer);
4010 break;
4011 case GL_PIXEL_PACK_BUFFER:
4012 bindPixelPackBuffer(buffer);
4013 break;
4014 case GL_PIXEL_UNPACK_BUFFER:
4015 bindPixelUnpackBuffer(buffer);
4016 break;
4017 case GL_UNIFORM_BUFFER:
4018 bindGenericUniformBuffer(buffer);
4019 break;
4020 case GL_TRANSFORM_FEEDBACK_BUFFER:
4021 bindGenericTransformFeedbackBuffer(buffer);
4022 break;
Geoff Lang3b573612016-10-31 14:08:10 -04004023 case GL_ATOMIC_COUNTER_BUFFER:
Jiajia Qin6eafb042016-12-27 17:04:07 +08004024 bindGenericAtomicCounterBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004025 break;
4026 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08004027 bindGenericShaderStorageBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004028 break;
4029 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08004030 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004031 break;
4032 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05004033 if (buffer != 0)
4034 {
4035 // Binding buffers to this binding point is not implemented yet.
4036 UNIMPLEMENTED();
4037 }
Geoff Lang3b573612016-10-31 14:08:10 -04004038 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05004039
4040 default:
4041 UNREACHABLE();
4042 break;
4043 }
4044}
4045
Jiajia Qin6eafb042016-12-27 17:04:07 +08004046void Context::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
4047{
4048 bindBufferRange(target, index, buffer, 0, 0);
4049}
4050
4051void Context::bindBufferRange(GLenum target,
4052 GLuint index,
4053 GLuint buffer,
4054 GLintptr offset,
4055 GLsizeiptr size)
4056{
4057 switch (target)
4058 {
4059 case GL_TRANSFORM_FEEDBACK_BUFFER:
4060 bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
4061 bindGenericTransformFeedbackBuffer(buffer);
4062 break;
4063 case GL_UNIFORM_BUFFER:
4064 bindIndexedUniformBuffer(buffer, index, offset, size);
4065 bindGenericUniformBuffer(buffer);
4066 break;
4067 case GL_ATOMIC_COUNTER_BUFFER:
4068 bindIndexedAtomicCounterBuffer(buffer, index, offset, size);
4069 bindGenericAtomicCounterBuffer(buffer);
4070 break;
4071 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08004072 bindIndexedShaderStorageBuffer(buffer, index, offset, size);
4073 bindGenericShaderStorageBuffer(buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08004074 break;
4075 default:
4076 UNREACHABLE();
4077 break;
4078 }
4079}
4080
Jamie Madill01a80ee2016-11-07 12:06:18 -05004081void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
4082{
4083 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4084 {
4085 bindReadFramebuffer(framebuffer);
4086 }
4087
4088 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4089 {
4090 bindDrawFramebuffer(framebuffer);
4091 }
4092}
4093
4094void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
4095{
4096 ASSERT(target == GL_RENDERBUFFER);
4097 Renderbuffer *object =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05004098 mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
Jamie Madill4928b7c2017-06-20 12:57:39 -04004099 mGLState.setRenderbufferBinding(this, object);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004100}
4101
JiangYizhoubddc46b2016-12-09 09:50:51 +08004102void Context::texStorage2DMultisample(GLenum target,
4103 GLsizei samples,
4104 GLenum internalformat,
4105 GLsizei width,
4106 GLsizei height,
4107 GLboolean fixedsamplelocations)
4108{
4109 Extents size(width, height, 1);
4110 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05004111 handleError(texture->setStorageMultisample(this, target, samples, internalformat, size,
JiangYizhoubddc46b2016-12-09 09:50:51 +08004112 fixedsamplelocations));
4113}
4114
4115void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
4116{
Jamie Madilldd43e6c2017-03-24 14:18:49 -04004117 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
JiangYizhoubddc46b2016-12-09 09:50:51 +08004118 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
4119
4120 switch (pname)
4121 {
4122 case GL_SAMPLE_POSITION:
4123 handleError(framebuffer->getSamplePosition(index, val));
4124 break;
4125 default:
4126 UNREACHABLE();
4127 }
4128}
4129
Jamie Madille8fb6402017-02-14 17:56:40 -05004130void Context::renderbufferStorage(GLenum target,
4131 GLenum internalformat,
4132 GLsizei width,
4133 GLsizei height)
4134{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004135 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4136 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
4137
Jamie Madille8fb6402017-02-14 17:56:40 -05004138 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4928b7c2017-06-20 12:57:39 -04004139 handleError(renderbuffer->setStorage(this, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004140}
4141
4142void Context::renderbufferStorageMultisample(GLenum target,
4143 GLsizei samples,
4144 GLenum internalformat,
4145 GLsizei width,
4146 GLsizei height)
4147{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004148 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4149 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
Jamie Madille8fb6402017-02-14 17:56:40 -05004150
4151 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004152 handleError(
Jamie Madill4928b7c2017-06-20 12:57:39 -04004153 renderbuffer->setStorageMultisample(this, samples, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004154}
4155
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004156void Context::getSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)
4157{
4158 const FenceSync *syncObject = getFenceSync(sync);
Geoff Lang82483b92017-04-11 15:33:00 -04004159 handleError(QuerySynciv(syncObject, pname, bufSize, length, values));
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004160}
4161
JiangYizhoue18e6392017-02-20 10:32:23 +08004162void Context::getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
4163{
4164 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4165 QueryFramebufferParameteriv(framebuffer, pname, params);
4166}
4167
4168void Context::setFramebufferParameteri(GLenum target, GLenum pname, GLint param)
4169{
4170 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4171 SetFramebufferParameteri(framebuffer, pname, param);
4172}
4173
Jamie Madille14951e2017-03-09 18:55:16 -05004174Error Context::getScratchBuffer(size_t requestedSize, angle::MemoryBuffer **scratchBufferOut) const
4175{
4176 if (!mScratchBuffer.get(requestedSize, scratchBufferOut))
4177 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004178 return OutOfMemory() << "Failed to allocate internal buffer.";
Jamie Madille14951e2017-03-09 18:55:16 -05004179 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004180 return NoError();
Jamie Madille14951e2017-03-09 18:55:16 -05004181}
4182
Xinghua Cao2b396592017-03-29 15:36:04 +08004183void Context::dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ)
4184{
4185 if (numGroupsX == 0u || numGroupsY == 0u || numGroupsZ == 0u)
4186 {
4187 return;
4188 }
4189
Jamie Madillfe548342017-06-19 11:13:24 -04004190 mImplementation->dispatchCompute(this, numGroupsX, numGroupsY, numGroupsZ);
Xinghua Cao2b396592017-03-29 15:36:04 +08004191}
4192
JiangYizhou165361c2017-06-07 14:56:57 +08004193void Context::texStorage2D(GLenum target,
4194 GLsizei levels,
4195 GLenum internalFormat,
4196 GLsizei width,
4197 GLsizei height)
4198{
4199 Extents size(width, height, 1);
4200 Texture *texture = getTargetTexture(target);
4201 handleError(texture->setStorage(this, target, levels, internalFormat, size));
4202}
4203
4204void Context::texStorage3D(GLenum target,
4205 GLsizei levels,
4206 GLenum internalFormat,
4207 GLsizei width,
4208 GLsizei height,
4209 GLsizei depth)
4210{
4211 Extents size(width, height, depth);
4212 Texture *texture = getTargetTexture(target);
4213 handleError(texture->setStorage(this, target, levels, internalFormat, size));
4214}
4215
Jamie Madillc1d770e2017-04-13 17:31:24 -04004216GLenum Context::checkFramebufferStatus(GLenum target)
4217{
4218 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4219 ASSERT(framebuffer);
4220
4221 return framebuffer->checkStatus(this);
4222}
4223
4224void Context::compileShader(GLuint shader)
4225{
4226 Shader *shaderObject = GetValidShader(this, shader);
4227 if (!shaderObject)
4228 {
4229 return;
4230 }
4231 shaderObject->compile(this);
4232}
4233
4234void Context::deleteBuffers(GLsizei n, const GLuint *buffers)
4235{
4236 for (int i = 0; i < n; i++)
4237 {
4238 deleteBuffer(buffers[i]);
4239 }
4240}
4241
4242void Context::deleteFramebuffers(GLsizei n, const GLuint *framebuffers)
4243{
4244 for (int i = 0; i < n; i++)
4245 {
4246 if (framebuffers[i] != 0)
4247 {
4248 deleteFramebuffer(framebuffers[i]);
4249 }
4250 }
4251}
4252
4253void Context::deleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)
4254{
4255 for (int i = 0; i < n; i++)
4256 {
4257 deleteRenderbuffer(renderbuffers[i]);
4258 }
4259}
4260
4261void Context::deleteTextures(GLsizei n, const GLuint *textures)
4262{
4263 for (int i = 0; i < n; i++)
4264 {
4265 if (textures[i] != 0)
4266 {
4267 deleteTexture(textures[i]);
4268 }
4269 }
4270}
4271
4272void Context::detachShader(GLuint program, GLuint shader)
4273{
4274 Program *programObject = getProgram(program);
4275 ASSERT(programObject);
4276
4277 Shader *shaderObject = getShader(shader);
4278 ASSERT(shaderObject);
4279
4280 programObject->detachShader(this, shaderObject);
4281}
4282
4283void Context::genBuffers(GLsizei n, GLuint *buffers)
4284{
4285 for (int i = 0; i < n; i++)
4286 {
4287 buffers[i] = createBuffer();
4288 }
4289}
4290
4291void Context::genFramebuffers(GLsizei n, GLuint *framebuffers)
4292{
4293 for (int i = 0; i < n; i++)
4294 {
4295 framebuffers[i] = createFramebuffer();
4296 }
4297}
4298
4299void Context::genRenderbuffers(GLsizei n, GLuint *renderbuffers)
4300{
4301 for (int i = 0; i < n; i++)
4302 {
4303 renderbuffers[i] = createRenderbuffer();
4304 }
4305}
4306
4307void Context::genTextures(GLsizei n, GLuint *textures)
4308{
4309 for (int i = 0; i < n; i++)
4310 {
4311 textures[i] = createTexture();
4312 }
4313}
4314
4315void Context::getActiveAttrib(GLuint program,
4316 GLuint index,
4317 GLsizei bufsize,
4318 GLsizei *length,
4319 GLint *size,
4320 GLenum *type,
4321 GLchar *name)
4322{
4323 Program *programObject = getProgram(program);
4324 ASSERT(programObject);
4325 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
4326}
4327
4328void Context::getActiveUniform(GLuint program,
4329 GLuint index,
4330 GLsizei bufsize,
4331 GLsizei *length,
4332 GLint *size,
4333 GLenum *type,
4334 GLchar *name)
4335{
4336 Program *programObject = getProgram(program);
4337 ASSERT(programObject);
4338 programObject->getActiveUniform(index, bufsize, length, size, type, name);
4339}
4340
4341void Context::getAttachedShaders(GLuint program, GLsizei maxcount, GLsizei *count, GLuint *shaders)
4342{
4343 Program *programObject = getProgram(program);
4344 ASSERT(programObject);
4345 programObject->getAttachedShaders(maxcount, count, shaders);
4346}
4347
4348GLint Context::getAttribLocation(GLuint program, const GLchar *name)
4349{
4350 Program *programObject = getProgram(program);
4351 ASSERT(programObject);
4352 return programObject->getAttributeLocation(name);
4353}
4354
4355void Context::getBooleanv(GLenum pname, GLboolean *params)
4356{
4357 GLenum nativeType;
4358 unsigned int numParams = 0;
4359 getQueryParameterInfo(pname, &nativeType, &numParams);
4360
4361 if (nativeType == GL_BOOL)
4362 {
4363 getBooleanvImpl(pname, params);
4364 }
4365 else
4366 {
4367 CastStateValues(this, nativeType, pname, numParams, params);
4368 }
4369}
4370
4371void Context::getFloatv(GLenum pname, GLfloat *params)
4372{
4373 GLenum nativeType;
4374 unsigned int numParams = 0;
4375 getQueryParameterInfo(pname, &nativeType, &numParams);
4376
4377 if (nativeType == GL_FLOAT)
4378 {
4379 getFloatvImpl(pname, params);
4380 }
4381 else
4382 {
4383 CastStateValues(this, nativeType, pname, numParams, params);
4384 }
4385}
4386
4387void Context::getIntegerv(GLenum pname, GLint *params)
4388{
4389 GLenum nativeType;
4390 unsigned int numParams = 0;
4391 getQueryParameterInfo(pname, &nativeType, &numParams);
4392
4393 if (nativeType == GL_INT)
4394 {
4395 getIntegervImpl(pname, params);
4396 }
4397 else
4398 {
4399 CastStateValues(this, nativeType, pname, numParams, params);
4400 }
4401}
4402
4403void Context::getProgramiv(GLuint program, GLenum pname, GLint *params)
4404{
4405 Program *programObject = getProgram(program);
4406 ASSERT(programObject);
Jamie Madillffe00c02017-06-27 16:26:55 -04004407 QueryProgramiv(this, programObject, pname, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004408}
4409
Jamie Madillbe849e42017-05-02 15:49:00 -04004410void Context::getProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei *length, GLchar *infolog)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004411{
4412 Program *programObject = getProgram(program);
4413 ASSERT(programObject);
4414 programObject->getInfoLog(bufsize, length, infolog);
4415}
4416
4417void Context::getShaderiv(GLuint shader, GLenum pname, GLint *params)
4418{
4419 Shader *shaderObject = getShader(shader);
4420 ASSERT(shaderObject);
Jamie Madillbd044ed2017-06-05 12:59:21 -04004421 QueryShaderiv(this, shaderObject, pname, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004422}
4423
4424void Context::getShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *infolog)
4425{
4426 Shader *shaderObject = getShader(shader);
4427 ASSERT(shaderObject);
Jamie Madillbd044ed2017-06-05 12:59:21 -04004428 shaderObject->getInfoLog(this, bufsize, length, infolog);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004429}
4430
4431void Context::getShaderPrecisionFormat(GLenum shadertype,
4432 GLenum precisiontype,
4433 GLint *range,
4434 GLint *precision)
4435{
4436 // TODO(jmadill): Compute shaders.
4437
4438 switch (shadertype)
4439 {
4440 case GL_VERTEX_SHADER:
4441 switch (precisiontype)
4442 {
4443 case GL_LOW_FLOAT:
4444 mCaps.vertexLowpFloat.get(range, precision);
4445 break;
4446 case GL_MEDIUM_FLOAT:
4447 mCaps.vertexMediumpFloat.get(range, precision);
4448 break;
4449 case GL_HIGH_FLOAT:
4450 mCaps.vertexHighpFloat.get(range, precision);
4451 break;
4452
4453 case GL_LOW_INT:
4454 mCaps.vertexLowpInt.get(range, precision);
4455 break;
4456 case GL_MEDIUM_INT:
4457 mCaps.vertexMediumpInt.get(range, precision);
4458 break;
4459 case GL_HIGH_INT:
4460 mCaps.vertexHighpInt.get(range, precision);
4461 break;
4462
4463 default:
4464 UNREACHABLE();
4465 return;
4466 }
4467 break;
4468
4469 case GL_FRAGMENT_SHADER:
4470 switch (precisiontype)
4471 {
4472 case GL_LOW_FLOAT:
4473 mCaps.fragmentLowpFloat.get(range, precision);
4474 break;
4475 case GL_MEDIUM_FLOAT:
4476 mCaps.fragmentMediumpFloat.get(range, precision);
4477 break;
4478 case GL_HIGH_FLOAT:
4479 mCaps.fragmentHighpFloat.get(range, precision);
4480 break;
4481
4482 case GL_LOW_INT:
4483 mCaps.fragmentLowpInt.get(range, precision);
4484 break;
4485 case GL_MEDIUM_INT:
4486 mCaps.fragmentMediumpInt.get(range, precision);
4487 break;
4488 case GL_HIGH_INT:
4489 mCaps.fragmentHighpInt.get(range, precision);
4490 break;
4491
4492 default:
4493 UNREACHABLE();
4494 return;
4495 }
4496 break;
4497
4498 default:
4499 UNREACHABLE();
4500 return;
4501 }
4502}
4503
4504void Context::getShaderSource(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source)
4505{
4506 Shader *shaderObject = getShader(shader);
4507 ASSERT(shaderObject);
4508 shaderObject->getSource(bufsize, length, source);
4509}
4510
4511void Context::getUniformfv(GLuint program, GLint location, GLfloat *params)
4512{
4513 Program *programObject = getProgram(program);
4514 ASSERT(programObject);
4515 programObject->getUniformfv(location, params);
4516}
4517
4518void Context::getUniformiv(GLuint program, GLint location, GLint *params)
4519{
4520 Program *programObject = getProgram(program);
4521 ASSERT(programObject);
4522 programObject->getUniformiv(location, params);
4523}
4524
4525GLint Context::getUniformLocation(GLuint program, const GLchar *name)
4526{
4527 Program *programObject = getProgram(program);
4528 ASSERT(programObject);
4529 return programObject->getUniformLocation(name);
4530}
4531
4532GLboolean Context::isBuffer(GLuint buffer)
4533{
4534 if (buffer == 0)
4535 {
4536 return GL_FALSE;
4537 }
4538
4539 return (getBuffer(buffer) ? GL_TRUE : GL_FALSE);
4540}
4541
4542GLboolean Context::isEnabled(GLenum cap)
4543{
4544 return mGLState.getEnableFeature(cap);
4545}
4546
4547GLboolean Context::isFramebuffer(GLuint framebuffer)
4548{
4549 if (framebuffer == 0)
4550 {
4551 return GL_FALSE;
4552 }
4553
4554 return (getFramebuffer(framebuffer) ? GL_TRUE : GL_FALSE);
4555}
4556
4557GLboolean Context::isProgram(GLuint program)
4558{
4559 if (program == 0)
4560 {
4561 return GL_FALSE;
4562 }
4563
4564 return (getProgram(program) ? GL_TRUE : GL_FALSE);
4565}
4566
4567GLboolean Context::isRenderbuffer(GLuint renderbuffer)
4568{
4569 if (renderbuffer == 0)
4570 {
4571 return GL_FALSE;
4572 }
4573
4574 return (getRenderbuffer(renderbuffer) ? GL_TRUE : GL_FALSE);
4575}
4576
4577GLboolean Context::isShader(GLuint shader)
4578{
4579 if (shader == 0)
4580 {
4581 return GL_FALSE;
4582 }
4583
4584 return (getShader(shader) ? GL_TRUE : GL_FALSE);
4585}
4586
4587GLboolean Context::isTexture(GLuint texture)
4588{
4589 if (texture == 0)
4590 {
4591 return GL_FALSE;
4592 }
4593
4594 return (getTexture(texture) ? GL_TRUE : GL_FALSE);
4595}
4596
4597void Context::linkProgram(GLuint program)
4598{
4599 Program *programObject = getProgram(program);
4600 ASSERT(programObject);
4601 handleError(programObject->link(this));
4602}
4603
4604void Context::releaseShaderCompiler()
4605{
Jamie Madill4928b7c2017-06-20 12:57:39 -04004606 mCompiler.set(this, nullptr);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004607}
4608
4609void Context::shaderBinary(GLsizei n,
4610 const GLuint *shaders,
4611 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04004612 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004613 GLsizei length)
4614{
4615 // No binary shader formats are supported.
4616 UNIMPLEMENTED();
4617}
4618
4619void Context::shaderSource(GLuint shader,
4620 GLsizei count,
4621 const GLchar *const *string,
4622 const GLint *length)
4623{
4624 Shader *shaderObject = getShader(shader);
4625 ASSERT(shaderObject);
4626 shaderObject->setSource(count, string, length);
4627}
4628
4629void Context::stencilFunc(GLenum func, GLint ref, GLuint mask)
4630{
4631 stencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
4632}
4633
4634void Context::stencilMask(GLuint mask)
4635{
4636 stencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4637}
4638
4639void Context::stencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4640{
4641 stencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4642}
4643
4644void Context::uniform1f(GLint location, GLfloat x)
4645{
4646 Program *program = mGLState.getProgram();
4647 program->setUniform1fv(location, 1, &x);
4648}
4649
4650void Context::uniform1fv(GLint location, GLsizei count, const GLfloat *v)
4651{
4652 Program *program = mGLState.getProgram();
4653 program->setUniform1fv(location, count, v);
4654}
4655
4656void Context::uniform1i(GLint location, GLint x)
4657{
4658 Program *program = mGLState.getProgram();
4659 program->setUniform1iv(location, 1, &x);
4660}
4661
4662void Context::uniform1iv(GLint location, GLsizei count, const GLint *v)
4663{
4664 Program *program = mGLState.getProgram();
4665 program->setUniform1iv(location, count, v);
4666}
4667
4668void Context::uniform2f(GLint location, GLfloat x, GLfloat y)
4669{
4670 GLfloat xy[2] = {x, y};
4671 Program *program = mGLState.getProgram();
4672 program->setUniform2fv(location, 1, xy);
4673}
4674
4675void Context::uniform2fv(GLint location, GLsizei count, const GLfloat *v)
4676{
4677 Program *program = mGLState.getProgram();
4678 program->setUniform2fv(location, count, v);
4679}
4680
4681void Context::uniform2i(GLint location, GLint x, GLint y)
4682{
4683 GLint xy[2] = {x, y};
4684 Program *program = mGLState.getProgram();
4685 program->setUniform2iv(location, 1, xy);
4686}
4687
4688void Context::uniform2iv(GLint location, GLsizei count, const GLint *v)
4689{
4690 Program *program = mGLState.getProgram();
4691 program->setUniform2iv(location, count, v);
4692}
4693
4694void Context::uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4695{
4696 GLfloat xyz[3] = {x, y, z};
4697 Program *program = mGLState.getProgram();
4698 program->setUniform3fv(location, 1, xyz);
4699}
4700
4701void Context::uniform3fv(GLint location, GLsizei count, const GLfloat *v)
4702{
4703 Program *program = mGLState.getProgram();
4704 program->setUniform3fv(location, count, v);
4705}
4706
4707void Context::uniform3i(GLint location, GLint x, GLint y, GLint z)
4708{
4709 GLint xyz[3] = {x, y, z};
4710 Program *program = mGLState.getProgram();
4711 program->setUniform3iv(location, 1, xyz);
4712}
4713
4714void Context::uniform3iv(GLint location, GLsizei count, const GLint *v)
4715{
4716 Program *program = mGLState.getProgram();
4717 program->setUniform3iv(location, count, v);
4718}
4719
4720void Context::uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4721{
4722 GLfloat xyzw[4] = {x, y, z, w};
4723 Program *program = mGLState.getProgram();
4724 program->setUniform4fv(location, 1, xyzw);
4725}
4726
4727void Context::uniform4fv(GLint location, GLsizei count, const GLfloat *v)
4728{
4729 Program *program = mGLState.getProgram();
4730 program->setUniform4fv(location, count, v);
4731}
4732
4733void Context::uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4734{
4735 GLint xyzw[4] = {x, y, z, w};
4736 Program *program = mGLState.getProgram();
4737 program->setUniform4iv(location, 1, xyzw);
4738}
4739
4740void Context::uniform4iv(GLint location, GLsizei count, const GLint *v)
4741{
4742 Program *program = mGLState.getProgram();
4743 program->setUniform4iv(location, count, v);
4744}
4745
4746void Context::uniformMatrix2fv(GLint location,
4747 GLsizei count,
4748 GLboolean transpose,
4749 const GLfloat *value)
4750{
4751 Program *program = mGLState.getProgram();
4752 program->setUniformMatrix2fv(location, count, transpose, value);
4753}
4754
4755void Context::uniformMatrix3fv(GLint location,
4756 GLsizei count,
4757 GLboolean transpose,
4758 const GLfloat *value)
4759{
4760 Program *program = mGLState.getProgram();
4761 program->setUniformMatrix3fv(location, count, transpose, value);
4762}
4763
4764void Context::uniformMatrix4fv(GLint location,
4765 GLsizei count,
4766 GLboolean transpose,
4767 const GLfloat *value)
4768{
4769 Program *program = mGLState.getProgram();
4770 program->setUniformMatrix4fv(location, count, transpose, value);
4771}
4772
4773void Context::validateProgram(GLuint program)
4774{
4775 Program *programObject = getProgram(program);
4776 ASSERT(programObject);
4777 programObject->validate(mCaps);
4778}
4779
Jamie Madilld04908b2017-06-09 14:15:35 -04004780void Context::getProgramBinary(GLuint program,
4781 GLsizei bufSize,
4782 GLsizei *length,
4783 GLenum *binaryFormat,
4784 void *binary)
4785{
4786 Program *programObject = getProgram(program);
4787 ASSERT(programObject != nullptr);
4788
4789 handleError(programObject->saveBinary(this, binaryFormat, binary, bufSize, length));
4790}
4791
4792void Context::programBinary(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length)
4793{
4794 Program *programObject = getProgram(program);
4795 ASSERT(programObject != nullptr);
4796
4797 handleError(programObject->loadBinary(this, binaryFormat, binary, length));
4798}
4799
Jamie Madillc29968b2016-01-20 11:17:23 -05004800} // namespace gl