blob: 35dcce6a0500b350516dbdd232da8014f78fa00d [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 Madillb3f26b92017-07-19 15:07:41 -0400275 mScratchBuffer(1000u),
276 mZeroFilledBuffer(1000u)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000277{
Geoff Lang077f20a2016-11-01 10:08:02 -0400278 if (mRobustAccess)
279 {
280 UNIMPLEMENTED();
281 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000282
Jamie Madill4e0e6f82017-02-17 11:06:03 -0500283 initCaps(displayExtensions);
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700284 initWorkarounds();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400285
Jamie Madill4928b7c2017-06-20 12:57:39 -0400286 mGLState.initialize(this, GetDebug(attribs), GetBindGeneratesResource(attribs),
Jamie Madillc43be722017-07-13 16:22:14 -0400287 GetClientArraysEnabled(attribs), robustResourceInit,
288 mMemoryProgramCache != nullptr);
Régis Fénéon83107972015-02-05 12:57:44 +0100289
Shannon Woods53a94a82014-06-24 15:20:36 -0400290 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400291
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000292 // [OpenGL ES 2.0.24] section 3.7 page 83:
293 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
294 // and cube map texture state vectors respectively associated with them.
295 // In order that access to these initial textures not be lost, they are treated as texture
296 // objects all of whose names are 0.
297
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400298 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400299 mZeroTextures[GL_TEXTURE_2D].set(this, zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500300
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400301 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400302 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(this, zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400303
Geoff Langeb66a6e2016-10-31 13:06:12 -0400304 if (getClientVersion() >= Version(3, 0))
Geoff Lang76b10c92014-09-05 16:28:14 -0400305 {
306 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400307 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400308 mZeroTextures[GL_TEXTURE_3D].set(this, zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400309
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400310 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400311 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(this, zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400312 }
Geoff Lang3b573612016-10-31 14:08:10 -0400313 if (getClientVersion() >= Version(3, 1))
314 {
315 Texture *zeroTexture2DMultisample =
316 new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_MULTISAMPLE);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400317 mZeroTextures[GL_TEXTURE_2D_MULTISAMPLE].set(this, zeroTexture2DMultisample);
Jiajia Qin6eafb042016-12-27 17:04:07 +0800318
319 bindGenericAtomicCounterBuffer(0);
320 for (unsigned int i = 0; i < mCaps.maxAtomicCounterBufferBindings; i++)
321 {
322 bindIndexedAtomicCounterBuffer(0, i, 0, 0);
323 }
Jiajia Qinf546e7d2017-03-27 14:12:59 +0800324
325 bindGenericShaderStorageBuffer(0);
326 for (unsigned int i = 0; i < mCaps.maxShaderStorageBufferBindings; i++)
327 {
328 bindIndexedShaderStorageBuffer(0, i, 0, 0);
329 }
Geoff Lang3b573612016-10-31 14:08:10 -0400330 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000331
Ian Ewellbda75592016-04-18 17:25:54 -0400332 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
333 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400334 Texture *zeroTextureExternal =
335 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400336 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(this, zeroTextureExternal);
Ian Ewellbda75592016-04-18 17:25:54 -0400337 }
338
Jamie Madill4928b7c2017-06-20 12:57:39 -0400339 mGLState.initializeZeroTextures(this, mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500340
Jamie Madill57a89722013-07-02 11:57:03 -0400341 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000342 bindArrayBuffer(0);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800343 bindDrawIndirectBuffer(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000344 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400345
Jamie Madill01a80ee2016-11-07 12:06:18 -0500346 bindRenderbuffer(GL_RENDERBUFFER, 0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000347
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000348 bindGenericUniformBuffer(0);
Geoff Lang4dc3af02016-11-18 14:09:27 -0500349 for (unsigned int i = 0; i < mCaps.maxUniformBufferBindings; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000350 {
351 bindIndexedUniformBuffer(0, i, 0, -1);
352 }
353
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000354 bindCopyReadBuffer(0);
355 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000356 bindPixelPackBuffer(0);
357 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000358
Geoff Langeb66a6e2016-10-31 13:06:12 -0400359 if (getClientVersion() >= Version(3, 0))
Geoff Lang1a683462015-09-29 15:09:59 -0400360 {
361 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
362 // In the initial state, a default transform feedback object is bound and treated as
363 // a transform feedback object with a name of zero. That object is bound any time
364 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400365 bindTransformFeedback(0);
366 }
Geoff Langc8058452014-02-03 12:04:11 -0500367
Jamie Madillad9f24e2016-02-12 09:27:24 -0500368 // Initialize dirty bit masks
369 // TODO(jmadill): additional ES3 state
370 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
371 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
372 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
373 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
374 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
375 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400376 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500377 // No dirty objects.
378
379 // Readpixels uses the pack state and read FBO
380 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
381 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
382 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
383 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
384 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400385 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500386 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
387
388 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
389 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
390 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
391 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
392 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
393 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
394 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
395 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
396 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
397 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
398 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
399 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
400
401 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
402 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700403 mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500404 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
405 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400406
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400407 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000408}
409
Jamie Madill4928b7c2017-06-20 12:57:39 -0400410egl::Error Context::onDestroy(const egl::Display *display)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000411{
Corentin Wallez80b24112015-08-25 16:41:57 -0400412 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000413 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400414 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000415 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400416 mFenceNVMap.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000417
Corentin Wallez80b24112015-08-25 16:41:57 -0400418 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000419 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400420 if (query.second != nullptr)
421 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400422 query.second->release(this);
Geoff Langf0aa8422015-09-29 15:08:34 -0400423 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000424 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400425 mQueryMap.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000426
Corentin Wallez80b24112015-08-25 16:41:57 -0400427 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400428 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400429 if (vertexArray.second)
430 {
431 vertexArray.second->onDestroy(this);
432 }
Jamie Madill57a89722013-07-02 11:57:03 -0400433 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400434 mVertexArrayMap.clear();
Jamie Madill57a89722013-07-02 11:57:03 -0400435
Corentin Wallez80b24112015-08-25 16:41:57 -0400436 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500437 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500438 if (transformFeedback.second != nullptr)
439 {
Jamie Madill6c1f6712017-02-14 19:08:04 -0500440 transformFeedback.second->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500441 }
Geoff Langc8058452014-02-03 12:04:11 -0500442 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400443 mTransformFeedbackMap.clear();
Geoff Langc8058452014-02-03 12:04:11 -0500444
Jamie Madilldedd7b92014-11-05 16:30:36 -0500445 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400446 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400447 zeroTexture.second->onDestroy(this);
448 zeroTexture.second.set(this, nullptr);
Geoff Lang76b10c92014-09-05 16:28:14 -0400449 }
450 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000451
Corentin Wallezccab69d2017-01-27 16:57:15 -0500452 SafeDelete(mSurfacelessFramebuffer);
453
Jamie Madill4928b7c2017-06-20 12:57:39 -0400454 ANGLE_TRY(releaseSurface(display));
Jamie Madill2f348d22017-06-05 10:50:59 -0400455 releaseShaderCompiler();
Jamie Madill6c1f6712017-02-14 19:08:04 -0500456
Jamie Madill4928b7c2017-06-20 12:57:39 -0400457 mGLState.reset(this);
458
Jamie Madill6c1f6712017-02-14 19:08:04 -0500459 mState.mBuffers->release(this);
460 mState.mShaderPrograms->release(this);
461 mState.mTextures->release(this);
462 mState.mRenderbuffers->release(this);
463 mState.mSamplers->release(this);
464 mState.mFenceSyncs->release(this);
465 mState.mPaths->release(this);
466 mState.mFramebuffers->release(this);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400467
468 return egl::NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000469}
470
Jamie Madill70ee0f62017-02-06 16:04:20 -0500471Context::~Context()
472{
473}
474
Jamie Madill4928b7c2017-06-20 12:57:39 -0400475egl::Error Context::makeCurrent(egl::Display *display, egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000476{
Jamie Madill61e16b42017-06-19 11:13:23 -0400477 mCurrentDisplay = display;
478
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000479 if (!mHasBeenCurrent)
480 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000481 initRendererString();
Geoff Langc339c4e2016-11-29 10:37:36 -0500482 initVersionStrings();
Geoff Langcec35902014-04-16 10:52:36 -0400483 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000484
Corentin Wallezc295e512017-01-27 17:47:50 -0500485 int width = 0;
486 int height = 0;
487 if (surface != nullptr)
488 {
489 width = surface->getWidth();
490 height = surface->getHeight();
491 }
492
493 mGLState.setViewportParams(0, 0, width, height);
494 mGLState.setScissorParams(0, 0, width, height);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000495
496 mHasBeenCurrent = true;
497 }
498
Jamie Madill1b94d432015-08-07 13:23:23 -0400499 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700500 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400501
Jamie Madill4928b7c2017-06-20 12:57:39 -0400502 ANGLE_TRY(releaseSurface(display));
Corentin Wallezccab69d2017-01-27 16:57:15 -0500503
504 Framebuffer *newDefault = nullptr;
505 if (surface != nullptr)
506 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400507 ANGLE_TRY(surface->setIsCurrent(this, true));
Corentin Wallezccab69d2017-01-27 16:57:15 -0500508 mCurrentSurface = surface;
509 newDefault = surface->getDefaultFramebuffer();
510 }
511 else
512 {
513 if (mSurfacelessFramebuffer == nullptr)
514 {
515 mSurfacelessFramebuffer = new Framebuffer(mImplementation.get());
516 }
517
518 newDefault = mSurfacelessFramebuffer;
519 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000520
Corentin Wallez37c39792015-08-20 14:19:46 -0400521 // Update default framebuffer, the binding of the previous default
522 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400523 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700524 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400525 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700526 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400527 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700528 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400529 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700530 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400531 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500532 mState.mFramebuffers->setDefaultFramebuffer(newDefault);
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400533 }
Ian Ewell292f0052016-02-04 10:37:32 -0500534
535 // Notify the renderer of a context switch
Jamie Madill4928b7c2017-06-20 12:57:39 -0400536 mImplementation->onMakeCurrent(this);
537 return egl::NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000538}
539
Jamie Madill4928b7c2017-06-20 12:57:39 -0400540egl::Error Context::releaseSurface(const egl::Display *display)
Jamie Madill77a72f62015-04-14 11:18:32 -0400541{
Corentin Wallez37c39792015-08-20 14:19:46 -0400542 // Remove the default framebuffer
Corentin Wallezc295e512017-01-27 17:47:50 -0500543 Framebuffer *currentDefault = nullptr;
544 if (mCurrentSurface != nullptr)
Corentin Wallez51706ea2015-08-07 14:39:22 -0400545 {
Corentin Wallezc295e512017-01-27 17:47:50 -0500546 currentDefault = mCurrentSurface->getDefaultFramebuffer();
547 }
548 else if (mSurfacelessFramebuffer != nullptr)
549 {
550 currentDefault = mSurfacelessFramebuffer;
Corentin Wallez51706ea2015-08-07 14:39:22 -0400551 }
552
Corentin Wallezc295e512017-01-27 17:47:50 -0500553 if (mGLState.getReadFramebuffer() == currentDefault)
554 {
555 mGLState.setReadFramebufferBinding(nullptr);
556 }
557 if (mGLState.getDrawFramebuffer() == currentDefault)
558 {
559 mGLState.setDrawFramebufferBinding(nullptr);
560 }
561 mState.mFramebuffers->setDefaultFramebuffer(nullptr);
562
563 if (mCurrentSurface)
564 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400565 ANGLE_TRY(mCurrentSurface->setIsCurrent(this, false));
Corentin Wallezc295e512017-01-27 17:47:50 -0500566 mCurrentSurface = nullptr;
567 }
Jamie Madill4928b7c2017-06-20 12:57:39 -0400568
569 return egl::NoError();
Jamie Madill77a72f62015-04-14 11:18:32 -0400570}
571
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000572GLuint Context::createBuffer()
573{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500574 return mState.mBuffers->createBuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000575}
576
577GLuint Context::createProgram()
578{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500579 return mState.mShaderPrograms->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000580}
581
582GLuint Context::createShader(GLenum type)
583{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500584 return mState.mShaderPrograms->createShader(mImplementation.get(), mLimitations, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000585}
586
587GLuint Context::createTexture()
588{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500589 return mState.mTextures->createTexture();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000590}
591
592GLuint Context::createRenderbuffer()
593{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500594 return mState.mRenderbuffers->createRenderbuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000595}
596
Geoff Lang882033e2014-09-30 11:26:07 -0400597GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400598{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500599 GLuint handle = mState.mFenceSyncs->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400600
Cooper Partind8e62a32015-01-29 15:21:25 -0800601 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400602}
603
Sami Väisänene45e53b2016-05-25 10:36:04 +0300604GLuint Context::createPaths(GLsizei range)
605{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500606 auto resultOrError = mState.mPaths->createPaths(mImplementation.get(), range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300607 if (resultOrError.isError())
608 {
609 handleError(resultOrError.getError());
610 return 0;
611 }
612 return resultOrError.getResult();
613}
614
Jamie Madill57a89722013-07-02 11:57:03 -0400615GLuint Context::createVertexArray()
616{
Jamie Madill96a483b2017-06-27 16:49:21 -0400617 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
618 mVertexArrayMap.assign(vertexArray, nullptr);
Geoff Lang36167ab2015-12-07 10:27:14 -0500619 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400620}
621
Jamie Madilldc356042013-07-19 16:36:57 -0400622GLuint Context::createSampler()
623{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500624 return mState.mSamplers->createSampler();
Jamie Madilldc356042013-07-19 16:36:57 -0400625}
626
Geoff Langc8058452014-02-03 12:04:11 -0500627GLuint Context::createTransformFeedback()
628{
Jamie Madill96a483b2017-06-27 16:49:21 -0400629 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
630 mTransformFeedbackMap.assign(transformFeedback, nullptr);
Geoff Lang36167ab2015-12-07 10:27:14 -0500631 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500632}
633
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000634// Returns an unused framebuffer name
635GLuint Context::createFramebuffer()
636{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500637 return mState.mFramebuffers->createFramebuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000638}
639
Jamie Madill33dc8432013-07-26 11:55:05 -0400640GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000641{
Jamie Madill33dc8432013-07-26 11:55:05 -0400642 GLuint handle = mFenceNVHandleAllocator.allocate();
Jamie Madill96a483b2017-06-27 16:49:21 -0400643 mFenceNVMap.assign(handle, new FenceNV(mImplementation->createFenceNV()));
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000644 return handle;
645}
646
647// Returns an unused query name
648GLuint Context::createQuery()
649{
650 GLuint handle = mQueryHandleAllocator.allocate();
Jamie Madill96a483b2017-06-27 16:49:21 -0400651 mQueryMap.assign(handle, nullptr);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000652 return handle;
653}
654
655void Context::deleteBuffer(GLuint buffer)
656{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500657 if (mState.mBuffers->getBuffer(buffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000658 {
659 detachBuffer(buffer);
660 }
Jamie Madill893ab082014-05-16 16:56:10 -0400661
Jamie Madill6c1f6712017-02-14 19:08:04 -0500662 mState.mBuffers->deleteObject(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000663}
664
665void Context::deleteShader(GLuint shader)
666{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500667 mState.mShaderPrograms->deleteShader(this, shader);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000668}
669
670void Context::deleteProgram(GLuint program)
671{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500672 mState.mShaderPrograms->deleteProgram(this, program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000673}
674
675void Context::deleteTexture(GLuint texture)
676{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500677 if (mState.mTextures->getTexture(texture))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000678 {
679 detachTexture(texture);
680 }
681
Jamie Madill6c1f6712017-02-14 19:08:04 -0500682 mState.mTextures->deleteObject(this, texture);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000683}
684
685void Context::deleteRenderbuffer(GLuint renderbuffer)
686{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500687 if (mState.mRenderbuffers->getRenderbuffer(renderbuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000688 {
689 detachRenderbuffer(renderbuffer);
690 }
Jamie Madill893ab082014-05-16 16:56:10 -0400691
Jamie Madill6c1f6712017-02-14 19:08:04 -0500692 mState.mRenderbuffers->deleteObject(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000693}
694
Jamie Madillcd055f82013-07-26 11:55:15 -0400695void Context::deleteFenceSync(GLsync fenceSync)
696{
697 // The spec specifies the underlying Fence object is not deleted until all current
698 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
699 // and since our API is currently designed for being called from a single thread, we can delete
700 // the fence immediately.
Jamie Madill6c1f6712017-02-14 19:08:04 -0500701 mState.mFenceSyncs->deleteObject(this,
702 static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400703}
704
Sami Väisänene45e53b2016-05-25 10:36:04 +0300705void Context::deletePaths(GLuint first, GLsizei range)
706{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500707 mState.mPaths->deletePaths(first, range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300708}
709
710bool Context::hasPathData(GLuint path) const
711{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500712 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300713 if (pathObj == nullptr)
714 return false;
715
716 return pathObj->hasPathData();
717}
718
719bool Context::hasPath(GLuint path) const
720{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500721 return mState.mPaths->hasPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300722}
723
724void Context::setPathCommands(GLuint path,
725 GLsizei numCommands,
726 const GLubyte *commands,
727 GLsizei numCoords,
728 GLenum coordType,
729 const void *coords)
730{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500731 auto *pathObject = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300732
733 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
734}
735
736void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
737{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500738 auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300739
740 switch (pname)
741 {
742 case GL_PATH_STROKE_WIDTH_CHROMIUM:
743 pathObj->setStrokeWidth(value);
744 break;
745 case GL_PATH_END_CAPS_CHROMIUM:
746 pathObj->setEndCaps(static_cast<GLenum>(value));
747 break;
748 case GL_PATH_JOIN_STYLE_CHROMIUM:
749 pathObj->setJoinStyle(static_cast<GLenum>(value));
750 break;
751 case GL_PATH_MITER_LIMIT_CHROMIUM:
752 pathObj->setMiterLimit(value);
753 break;
754 case GL_PATH_STROKE_BOUND_CHROMIUM:
755 pathObj->setStrokeBound(value);
756 break;
757 default:
758 UNREACHABLE();
759 break;
760 }
761}
762
763void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
764{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500765 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300766
767 switch (pname)
768 {
769 case GL_PATH_STROKE_WIDTH_CHROMIUM:
770 *value = pathObj->getStrokeWidth();
771 break;
772 case GL_PATH_END_CAPS_CHROMIUM:
773 *value = static_cast<GLfloat>(pathObj->getEndCaps());
774 break;
775 case GL_PATH_JOIN_STYLE_CHROMIUM:
776 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
777 break;
778 case GL_PATH_MITER_LIMIT_CHROMIUM:
779 *value = pathObj->getMiterLimit();
780 break;
781 case GL_PATH_STROKE_BOUND_CHROMIUM:
782 *value = pathObj->getStrokeBound();
783 break;
784 default:
785 UNREACHABLE();
786 break;
787 }
788}
789
790void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
791{
792 mGLState.setPathStencilFunc(func, ref, mask);
793}
794
Jamie Madill57a89722013-07-02 11:57:03 -0400795void Context::deleteVertexArray(GLuint vertexArray)
796{
Jamie Madill96a483b2017-06-27 16:49:21 -0400797 VertexArray *vertexArrayObject = nullptr;
798 if (mVertexArrayMap.erase(vertexArray, &vertexArrayObject))
Geoff Lang50b3fe82015-12-08 14:49:12 +0000799 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500800 if (vertexArrayObject != nullptr)
801 {
802 detachVertexArray(vertexArray);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400803 vertexArrayObject->onDestroy(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500804 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000805
Geoff Lang36167ab2015-12-07 10:27:14 -0500806 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400807 }
808}
809
Jamie Madilldc356042013-07-19 16:36:57 -0400810void Context::deleteSampler(GLuint sampler)
811{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500812 if (mState.mSamplers->getSampler(sampler))
Jamie Madilldc356042013-07-19 16:36:57 -0400813 {
814 detachSampler(sampler);
815 }
816
Jamie Madill6c1f6712017-02-14 19:08:04 -0500817 mState.mSamplers->deleteObject(this, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400818}
819
Geoff Langc8058452014-02-03 12:04:11 -0500820void Context::deleteTransformFeedback(GLuint transformFeedback)
821{
Geoff Lang6e60d6b2017-04-12 12:59:04 -0400822 if (transformFeedback == 0)
823 {
824 return;
825 }
826
Jamie Madill96a483b2017-06-27 16:49:21 -0400827 TransformFeedback *transformFeedbackObject = nullptr;
828 if (mTransformFeedbackMap.erase(transformFeedback, &transformFeedbackObject))
Geoff Langc8058452014-02-03 12:04:11 -0500829 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500830 if (transformFeedbackObject != nullptr)
831 {
832 detachTransformFeedback(transformFeedback);
Jamie Madill6c1f6712017-02-14 19:08:04 -0500833 transformFeedbackObject->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500834 }
835
Geoff Lang36167ab2015-12-07 10:27:14 -0500836 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500837 }
838}
839
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000840void Context::deleteFramebuffer(GLuint framebuffer)
841{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500842 if (mState.mFramebuffers->getFramebuffer(framebuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000843 {
844 detachFramebuffer(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000845 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500846
Jamie Madill6c1f6712017-02-14 19:08:04 -0500847 mState.mFramebuffers->deleteObject(this, framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000848}
849
Jamie Madill33dc8432013-07-26 11:55:05 -0400850void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000851{
Jamie Madill96a483b2017-06-27 16:49:21 -0400852 FenceNV *fenceObject = nullptr;
853 if (mFenceNVMap.erase(fence, &fenceObject))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000854 {
Jamie Madill96a483b2017-06-27 16:49:21 -0400855 mFenceNVHandleAllocator.release(fence);
856 delete fenceObject;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000857 }
858}
859
860void Context::deleteQuery(GLuint query)
861{
Jamie Madill96a483b2017-06-27 16:49:21 -0400862 Query *queryObject = nullptr;
863 if (mQueryMap.erase(query, &queryObject))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000864 {
Jamie Madill96a483b2017-06-27 16:49:21 -0400865 mQueryHandleAllocator.release(query);
866 if (queryObject)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000867 {
Jamie Madill96a483b2017-06-27 16:49:21 -0400868 queryObject->release(this);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000869 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000870 }
871}
872
Geoff Lang70d0f492015-12-10 17:45:46 -0500873Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000874{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500875 return mState.mBuffers->getBuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000876}
877
Jamie Madill570f7c82014-07-03 10:38:54 -0400878Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000879{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500880 return mState.mTextures->getTexture(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000881}
882
Geoff Lang70d0f492015-12-10 17:45:46 -0500883Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000884{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500885 return mState.mRenderbuffers->getRenderbuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000886}
887
Jamie Madillcd055f82013-07-26 11:55:15 -0400888FenceSync *Context::getFenceSync(GLsync handle) const
889{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500890 return mState.mFenceSyncs->getFenceSync(
891 static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400892}
893
Jamie Madill57a89722013-07-02 11:57:03 -0400894VertexArray *Context::getVertexArray(GLuint handle) const
895{
Jamie Madill96a483b2017-06-27 16:49:21 -0400896 return mVertexArrayMap.query(handle);
Jamie Madill57a89722013-07-02 11:57:03 -0400897}
898
Jamie Madilldc356042013-07-19 16:36:57 -0400899Sampler *Context::getSampler(GLuint handle) const
900{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500901 return mState.mSamplers->getSampler(handle);
Jamie Madilldc356042013-07-19 16:36:57 -0400902}
903
Geoff Langc8058452014-02-03 12:04:11 -0500904TransformFeedback *Context::getTransformFeedback(GLuint handle) const
905{
Jamie Madill96a483b2017-06-27 16:49:21 -0400906 return mTransformFeedbackMap.query(handle);
Geoff Langc8058452014-02-03 12:04:11 -0500907}
908
Geoff Lang70d0f492015-12-10 17:45:46 -0500909LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
910{
911 switch (identifier)
912 {
913 case GL_BUFFER:
914 return getBuffer(name);
915 case GL_SHADER:
916 return getShader(name);
917 case GL_PROGRAM:
918 return getProgram(name);
919 case GL_VERTEX_ARRAY:
920 return getVertexArray(name);
921 case GL_QUERY:
922 return getQuery(name);
923 case GL_TRANSFORM_FEEDBACK:
924 return getTransformFeedback(name);
925 case GL_SAMPLER:
926 return getSampler(name);
927 case GL_TEXTURE:
928 return getTexture(name);
929 case GL_RENDERBUFFER:
930 return getRenderbuffer(name);
931 case GL_FRAMEBUFFER:
932 return getFramebuffer(name);
933 default:
934 UNREACHABLE();
935 return nullptr;
936 }
937}
938
939LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
940{
941 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
942}
943
Martin Radev9d901792016-07-15 15:58:58 +0300944void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
945{
946 LabeledObject *object = getLabeledObject(identifier, name);
947 ASSERT(object != nullptr);
948
949 std::string labelName = GetObjectLabelFromPointer(length, label);
950 object->setLabel(labelName);
951}
952
953void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
954{
955 LabeledObject *object = getLabeledObjectFromPtr(ptr);
956 ASSERT(object != nullptr);
957
958 std::string labelName = GetObjectLabelFromPointer(length, label);
959 object->setLabel(labelName);
960}
961
962void Context::getObjectLabel(GLenum identifier,
963 GLuint name,
964 GLsizei bufSize,
965 GLsizei *length,
966 GLchar *label) const
967{
968 LabeledObject *object = getLabeledObject(identifier, name);
969 ASSERT(object != nullptr);
970
971 const std::string &objectLabel = object->getLabel();
972 GetObjectLabelBase(objectLabel, bufSize, length, label);
973}
974
975void Context::getObjectPtrLabel(const void *ptr,
976 GLsizei bufSize,
977 GLsizei *length,
978 GLchar *label) const
979{
980 LabeledObject *object = getLabeledObjectFromPtr(ptr);
981 ASSERT(object != nullptr);
982
983 const std::string &objectLabel = object->getLabel();
984 GetObjectLabelBase(objectLabel, bufSize, length, label);
985}
986
Jamie Madilldc356042013-07-19 16:36:57 -0400987bool Context::isSampler(GLuint samplerName) const
988{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500989 return mState.mSamplers->isSampler(samplerName);
Jamie Madilldc356042013-07-19 16:36:57 -0400990}
991
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500992void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000993{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500994 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400995 mGLState.setArrayBufferBinding(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000996}
997
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800998void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
999{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001000 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001001 mGLState.setDrawIndirectBufferBinding(this, buffer);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08001002}
1003
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001004void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001005{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001006 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001007 mGLState.setElementArrayBuffer(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001008}
1009
Jamie Madilldedd7b92014-11-05 16:30:36 -05001010void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001011{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001012 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001013
Jamie Madilldedd7b92014-11-05 16:30:36 -05001014 if (handle == 0)
1015 {
1016 texture = mZeroTextures[target].get();
1017 }
1018 else
1019 {
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001020 texture = mState.mTextures->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -05001021 }
1022
1023 ASSERT(texture);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001024 mGLState.setSamplerTexture(this, target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +00001025}
1026
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001027void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001028{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001029 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
1030 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001031 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001032}
1033
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001034void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001035{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001036 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
1037 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001038 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001039}
1040
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001041void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -04001042{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001043 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001044 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -04001045}
1046
Shao80957d92017-02-20 21:25:59 +08001047void Context::bindVertexBuffer(GLuint bindingIndex,
1048 GLuint bufferHandle,
1049 GLintptr offset,
1050 GLsizei stride)
1051{
1052 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001053 mGLState.bindVertexBuffer(this, bindingIndex, buffer, offset, stride);
Shao80957d92017-02-20 21:25:59 +08001054}
1055
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001056void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -04001057{
Geoff Lang76b10c92014-09-05 16:28:14 -04001058 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -04001059 Sampler *sampler =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001060 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001061 mGLState.setSamplerBinding(this, textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001062}
1063
Xinghua Cao65ec0b22017-03-28 16:10:52 +08001064void Context::bindImageTexture(GLuint unit,
1065 GLuint texture,
1066 GLint level,
1067 GLboolean layered,
1068 GLint layer,
1069 GLenum access,
1070 GLenum format)
1071{
1072 Texture *tex = mState.mTextures->getTexture(texture);
1073 mGLState.setImageUnit(this, unit, tex, level, layered, layer, access, format);
1074}
1075
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001076void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001077{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001078 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001079 mGLState.setGenericUniformBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001080}
1081
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001082void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1083 GLuint index,
1084 GLintptr offset,
1085 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001086{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001087 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001088 mGLState.setIndexedUniformBufferBinding(this, index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001089}
1090
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001091void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001092{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001093 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001094 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001095}
1096
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001097void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1098 GLuint index,
1099 GLintptr offset,
1100 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001101{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001102 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001103 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(this, index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001104}
1105
Jiajia Qin6eafb042016-12-27 17:04:07 +08001106void Context::bindGenericAtomicCounterBuffer(GLuint bufferHandle)
1107{
1108 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001109 mGLState.setGenericAtomicCounterBufferBinding(this, buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08001110}
1111
1112void Context::bindIndexedAtomicCounterBuffer(GLuint bufferHandle,
1113 GLuint index,
1114 GLintptr offset,
1115 GLsizeiptr size)
1116{
1117 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001118 mGLState.setIndexedAtomicCounterBufferBinding(this, index, buffer, offset, size);
Jiajia Qin6eafb042016-12-27 17:04:07 +08001119}
1120
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001121void Context::bindGenericShaderStorageBuffer(GLuint bufferHandle)
1122{
1123 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001124 mGLState.setGenericShaderStorageBufferBinding(this, buffer);
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001125}
1126
1127void Context::bindIndexedShaderStorageBuffer(GLuint bufferHandle,
1128 GLuint index,
1129 GLintptr offset,
1130 GLsizeiptr size)
1131{
1132 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001133 mGLState.setIndexedShaderStorageBufferBinding(this, index, buffer, offset, size);
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001134}
1135
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001136void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001137{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001138 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001139 mGLState.setCopyReadBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001140}
1141
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001142void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001143{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001144 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001145 mGLState.setCopyWriteBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001146}
1147
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001148void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001149{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001150 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001151 mGLState.setPixelPackBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001152}
1153
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001154void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001155{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001156 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001157 mGLState.setPixelUnpackBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001158}
1159
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001160void Context::useProgram(GLuint program)
1161{
Jamie Madill6c1f6712017-02-14 19:08:04 -05001162 mGLState.setProgram(this, getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001163}
1164
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001165void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001166{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001167 TransformFeedback *transformFeedback =
1168 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001169 mGLState.setTransformFeedbackBinding(this, transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001170}
1171
Geoff Lang5aad9672014-09-08 11:10:42 -04001172Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001173{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001174 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001175 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001176
Geoff Lang5aad9672014-09-08 11:10:42 -04001177 // begin query
1178 Error error = queryObject->begin();
1179 if (error.isError())
1180 {
1181 return error;
1182 }
1183
1184 // set query as active for specified target only if begin succeeded
Jamie Madill4928b7c2017-06-20 12:57:39 -04001185 mGLState.setActiveQuery(this, target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001186
He Yunchaoacd18982017-01-04 10:46:42 +08001187 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001188}
1189
Geoff Lang5aad9672014-09-08 11:10:42 -04001190Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001191{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001192 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001193 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001194
Geoff Lang5aad9672014-09-08 11:10:42 -04001195 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001196
Geoff Lang5aad9672014-09-08 11:10:42 -04001197 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madill4928b7c2017-06-20 12:57:39 -04001198 mGLState.setActiveQuery(this, target, nullptr);
Geoff Lang5aad9672014-09-08 11:10:42 -04001199
1200 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001201}
1202
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001203Error Context::queryCounter(GLuint id, GLenum target)
1204{
1205 ASSERT(target == GL_TIMESTAMP_EXT);
1206
1207 Query *queryObject = getQuery(id, true, target);
1208 ASSERT(queryObject);
1209
1210 return queryObject->queryCounter();
1211}
1212
1213void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1214{
1215 switch (pname)
1216 {
1217 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001218 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001219 break;
1220 case GL_QUERY_COUNTER_BITS_EXT:
1221 switch (target)
1222 {
1223 case GL_TIME_ELAPSED_EXT:
1224 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1225 break;
1226 case GL_TIMESTAMP_EXT:
1227 params[0] = getExtensions().queryCounterBitsTimestamp;
1228 break;
1229 default:
1230 UNREACHABLE();
1231 params[0] = 0;
1232 break;
1233 }
1234 break;
1235 default:
1236 UNREACHABLE();
1237 return;
1238 }
1239}
1240
Geoff Lang2186c382016-10-14 10:54:54 -04001241void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001242{
Geoff Lang2186c382016-10-14 10:54:54 -04001243 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001244}
1245
Geoff Lang2186c382016-10-14 10:54:54 -04001246void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001247{
Geoff Lang2186c382016-10-14 10:54:54 -04001248 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001249}
1250
Geoff Lang2186c382016-10-14 10:54:54 -04001251void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001252{
Geoff Lang2186c382016-10-14 10:54:54 -04001253 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001254}
1255
Geoff Lang2186c382016-10-14 10:54:54 -04001256void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001257{
Geoff Lang2186c382016-10-14 10:54:54 -04001258 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001259}
1260
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001261Framebuffer *Context::getFramebuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001262{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001263 return mState.mFramebuffers->getFramebuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001264}
1265
Jamie Madill2f348d22017-06-05 10:50:59 -04001266FenceNV *Context::getFenceNV(GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001267{
Jamie Madill96a483b2017-06-27 16:49:21 -04001268 return mFenceNVMap.query(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001269}
1270
Jamie Madill2f348d22017-06-05 10:50:59 -04001271Query *Context::getQuery(GLuint handle, bool create, GLenum type)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001272{
Jamie Madill96a483b2017-06-27 16:49:21 -04001273 if (!mQueryMap.contains(handle))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001274 {
Yunchao Hef81ce4a2017-04-24 10:49:17 +08001275 return nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001276 }
Jamie Madill96a483b2017-06-27 16:49:21 -04001277
1278 Query *query = mQueryMap.query(handle);
1279 if (!query && create)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001280 {
Jamie Madill96a483b2017-06-27 16:49:21 -04001281 query = new Query(mImplementation->createQuery(type), handle);
1282 query->addRef();
1283 mQueryMap.assign(handle, query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001284 }
Jamie Madill96a483b2017-06-27 16:49:21 -04001285 return query;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001286}
1287
Geoff Lang70d0f492015-12-10 17:45:46 -05001288Query *Context::getQuery(GLuint handle) const
1289{
Jamie Madill96a483b2017-06-27 16:49:21 -04001290 return mQueryMap.query(handle);
Geoff Lang70d0f492015-12-10 17:45:46 -05001291}
1292
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001293Texture *Context::getTargetTexture(GLenum target) const
1294{
Ian Ewellbda75592016-04-18 17:25:54 -04001295 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001296 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001297}
1298
Geoff Lang76b10c92014-09-05 16:28:14 -04001299Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001300{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001301 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001302}
1303
Geoff Lang492a7e42014-11-05 13:27:06 -05001304Compiler *Context::getCompiler() const
1305{
Jamie Madill2f348d22017-06-05 10:50:59 -04001306 if (mCompiler.get() == nullptr)
1307 {
Jamie Madill4928b7c2017-06-20 12:57:39 -04001308 mCompiler.set(this, new Compiler(mImplementation.get(), mState));
Jamie Madill2f348d22017-06-05 10:50:59 -04001309 }
1310 return mCompiler.get();
Geoff Lang492a7e42014-11-05 13:27:06 -05001311}
1312
Jamie Madillc1d770e2017-04-13 17:31:24 -04001313void Context::getBooleanvImpl(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001314{
1315 switch (pname)
1316 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001317 case GL_SHADER_COMPILER:
1318 *params = GL_TRUE;
1319 break;
1320 case GL_CONTEXT_ROBUST_ACCESS_EXT:
1321 *params = mRobustAccess ? GL_TRUE : GL_FALSE;
1322 break;
1323 default:
1324 mGLState.getBooleanv(pname, params);
1325 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001326 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001327}
1328
Jamie Madillc1d770e2017-04-13 17:31:24 -04001329void Context::getFloatvImpl(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001330{
Shannon Woods53a94a82014-06-24 15:20:36 -04001331 // Queries about context capabilities and maximums are answered by Context.
1332 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001333 switch (pname)
1334 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001335 case GL_ALIASED_LINE_WIDTH_RANGE:
1336 params[0] = mCaps.minAliasedLineWidth;
1337 params[1] = mCaps.maxAliasedLineWidth;
1338 break;
1339 case GL_ALIASED_POINT_SIZE_RANGE:
1340 params[0] = mCaps.minAliasedPointSize;
1341 params[1] = mCaps.maxAliasedPointSize;
1342 break;
1343 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1344 ASSERT(mExtensions.textureFilterAnisotropic);
1345 *params = mExtensions.maxTextureAnisotropy;
1346 break;
1347 case GL_MAX_TEXTURE_LOD_BIAS:
1348 *params = mCaps.maxLODBias;
1349 break;
1350
1351 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1352 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1353 {
1354 ASSERT(mExtensions.pathRendering);
1355 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1356 memcpy(params, m, 16 * sizeof(GLfloat));
1357 }
Geoff Lange6d4e122015-06-29 13:33:55 -04001358 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001359
Jamie Madill231c7f52017-04-26 13:45:37 -04001360 default:
1361 mGLState.getFloatv(pname, params);
1362 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001363 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001364}
1365
Jamie Madillc1d770e2017-04-13 17:31:24 -04001366void Context::getIntegervImpl(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001367{
Shannon Woods53a94a82014-06-24 15:20:36 -04001368 // Queries about context capabilities and maximums are answered by Context.
1369 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001370
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001371 switch (pname)
1372 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001373 case GL_MAX_VERTEX_ATTRIBS:
1374 *params = mCaps.maxVertexAttributes;
1375 break;
1376 case GL_MAX_VERTEX_UNIFORM_VECTORS:
1377 *params = mCaps.maxVertexUniformVectors;
1378 break;
1379 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
1380 *params = mCaps.maxVertexUniformComponents;
1381 break;
1382 case GL_MAX_VARYING_VECTORS:
1383 *params = mCaps.maxVaryingVectors;
1384 break;
1385 case GL_MAX_VARYING_COMPONENTS:
1386 *params = mCaps.maxVertexOutputComponents;
1387 break;
1388 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1389 *params = mCaps.maxCombinedTextureImageUnits;
1390 break;
1391 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1392 *params = mCaps.maxVertexTextureImageUnits;
1393 break;
1394 case GL_MAX_TEXTURE_IMAGE_UNITS:
1395 *params = mCaps.maxTextureImageUnits;
1396 break;
1397 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1398 *params = mCaps.maxFragmentUniformVectors;
1399 break;
1400 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
1401 *params = mCaps.maxFragmentUniformComponents;
1402 break;
1403 case GL_MAX_RENDERBUFFER_SIZE:
1404 *params = mCaps.maxRenderbufferSize;
1405 break;
1406 case GL_MAX_COLOR_ATTACHMENTS_EXT:
1407 *params = mCaps.maxColorAttachments;
1408 break;
1409 case GL_MAX_DRAW_BUFFERS_EXT:
1410 *params = mCaps.maxDrawBuffers;
1411 break;
1412 // case GL_FRAMEBUFFER_BINDING: // now equivalent to
1413 // GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1414 case GL_SUBPIXEL_BITS:
1415 *params = 4;
1416 break;
1417 case GL_MAX_TEXTURE_SIZE:
1418 *params = mCaps.max2DTextureSize;
1419 break;
1420 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1421 *params = mCaps.maxCubeMapTextureSize;
1422 break;
1423 case GL_MAX_3D_TEXTURE_SIZE:
1424 *params = mCaps.max3DTextureSize;
1425 break;
1426 case GL_MAX_ARRAY_TEXTURE_LAYERS:
1427 *params = mCaps.maxArrayTextureLayers;
1428 break;
1429 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
1430 *params = mCaps.uniformBufferOffsetAlignment;
1431 break;
1432 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
1433 *params = mCaps.maxUniformBufferBindings;
1434 break;
1435 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
1436 *params = mCaps.maxVertexUniformBlocks;
1437 break;
1438 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
1439 *params = mCaps.maxFragmentUniformBlocks;
1440 break;
1441 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
1442 *params = mCaps.maxCombinedTextureImageUnits;
1443 break;
1444 case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
1445 *params = mCaps.maxVertexOutputComponents;
1446 break;
1447 case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
1448 *params = mCaps.maxFragmentInputComponents;
1449 break;
1450 case GL_MIN_PROGRAM_TEXEL_OFFSET:
1451 *params = mCaps.minProgramTexelOffset;
1452 break;
1453 case GL_MAX_PROGRAM_TEXEL_OFFSET:
1454 *params = mCaps.maxProgramTexelOffset;
1455 break;
1456 case GL_MAJOR_VERSION:
1457 *params = getClientVersion().major;
1458 break;
1459 case GL_MINOR_VERSION:
1460 *params = getClientVersion().minor;
1461 break;
1462 case GL_MAX_ELEMENTS_INDICES:
1463 *params = mCaps.maxElementsIndices;
1464 break;
1465 case GL_MAX_ELEMENTS_VERTICES:
1466 *params = mCaps.maxElementsVertices;
1467 break;
1468 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
1469 *params = mCaps.maxTransformFeedbackInterleavedComponents;
1470 break;
1471 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
1472 *params = mCaps.maxTransformFeedbackSeparateAttributes;
1473 break;
1474 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
1475 *params = mCaps.maxTransformFeedbackSeparateComponents;
1476 break;
1477 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1478 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1479 break;
1480 case GL_MAX_SAMPLES_ANGLE:
1481 *params = mCaps.maxSamples;
1482 break;
1483 case GL_MAX_VIEWPORT_DIMS:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001484 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001485 params[0] = mCaps.maxViewportWidth;
1486 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001487 }
1488 break;
Jamie Madill231c7f52017-04-26 13:45:37 -04001489 case GL_COMPRESSED_TEXTURE_FORMATS:
1490 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(),
1491 params);
1492 break;
1493 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1494 *params = mResetStrategy;
1495 break;
1496 case GL_NUM_SHADER_BINARY_FORMATS:
1497 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
1498 break;
1499 case GL_SHADER_BINARY_FORMATS:
1500 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1501 break;
1502 case GL_NUM_PROGRAM_BINARY_FORMATS:
1503 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
1504 break;
1505 case GL_PROGRAM_BINARY_FORMATS:
1506 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
1507 break;
1508 case GL_NUM_EXTENSIONS:
1509 *params = static_cast<GLint>(mExtensionStrings.size());
1510 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001511
Jamie Madill231c7f52017-04-26 13:45:37 -04001512 // GL_KHR_debug
1513 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1514 *params = mExtensions.maxDebugMessageLength;
1515 break;
1516 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1517 *params = mExtensions.maxDebugLoggedMessages;
1518 break;
1519 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1520 *params = mExtensions.maxDebugGroupStackDepth;
1521 break;
1522 case GL_MAX_LABEL_LENGTH:
1523 *params = mExtensions.maxLabelLength;
1524 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001525
Martin Radeve5285d22017-07-14 16:23:53 +03001526 // GL_ANGLE_multiview
1527 case GL_MAX_VIEWS_ANGLE:
1528 *params = mExtensions.maxViews;
1529 break;
1530
Jamie Madill231c7f52017-04-26 13:45:37 -04001531 // GL_EXT_disjoint_timer_query
1532 case GL_GPU_DISJOINT_EXT:
1533 *params = mImplementation->getGPUDisjoint();
1534 break;
1535 case GL_MAX_FRAMEBUFFER_WIDTH:
1536 *params = mCaps.maxFramebufferWidth;
1537 break;
1538 case GL_MAX_FRAMEBUFFER_HEIGHT:
1539 *params = mCaps.maxFramebufferHeight;
1540 break;
1541 case GL_MAX_FRAMEBUFFER_SAMPLES:
1542 *params = mCaps.maxFramebufferSamples;
1543 break;
1544 case GL_MAX_SAMPLE_MASK_WORDS:
1545 *params = mCaps.maxSampleMaskWords;
1546 break;
1547 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1548 *params = mCaps.maxColorTextureSamples;
1549 break;
1550 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1551 *params = mCaps.maxDepthTextureSamples;
1552 break;
1553 case GL_MAX_INTEGER_SAMPLES:
1554 *params = mCaps.maxIntegerSamples;
1555 break;
1556 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1557 *params = mCaps.maxVertexAttribRelativeOffset;
1558 break;
1559 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1560 *params = mCaps.maxVertexAttribBindings;
1561 break;
1562 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1563 *params = mCaps.maxVertexAttribStride;
1564 break;
1565 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1566 *params = mCaps.maxVertexAtomicCounterBuffers;
1567 break;
1568 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1569 *params = mCaps.maxVertexAtomicCounters;
1570 break;
1571 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1572 *params = mCaps.maxVertexImageUniforms;
1573 break;
1574 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1575 *params = mCaps.maxVertexShaderStorageBlocks;
1576 break;
1577 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1578 *params = mCaps.maxFragmentAtomicCounterBuffers;
1579 break;
1580 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1581 *params = mCaps.maxFragmentAtomicCounters;
1582 break;
1583 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1584 *params = mCaps.maxFragmentImageUniforms;
1585 break;
1586 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1587 *params = mCaps.maxFragmentShaderStorageBlocks;
1588 break;
1589 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1590 *params = mCaps.minProgramTextureGatherOffset;
1591 break;
1592 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1593 *params = mCaps.maxProgramTextureGatherOffset;
1594 break;
1595 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1596 *params = mCaps.maxComputeWorkGroupInvocations;
1597 break;
1598 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1599 *params = mCaps.maxComputeUniformBlocks;
1600 break;
1601 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1602 *params = mCaps.maxComputeTextureImageUnits;
1603 break;
1604 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1605 *params = mCaps.maxComputeSharedMemorySize;
1606 break;
1607 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1608 *params = mCaps.maxComputeUniformComponents;
1609 break;
1610 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1611 *params = mCaps.maxComputeAtomicCounterBuffers;
1612 break;
1613 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1614 *params = mCaps.maxComputeAtomicCounters;
1615 break;
1616 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1617 *params = mCaps.maxComputeImageUniforms;
1618 break;
1619 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1620 *params = mCaps.maxCombinedComputeUniformComponents;
1621 break;
1622 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1623 *params = mCaps.maxComputeShaderStorageBlocks;
1624 break;
1625 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1626 *params = mCaps.maxCombinedShaderOutputResources;
1627 break;
1628 case GL_MAX_UNIFORM_LOCATIONS:
1629 *params = mCaps.maxUniformLocations;
1630 break;
1631 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1632 *params = mCaps.maxAtomicCounterBufferBindings;
1633 break;
1634 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1635 *params = mCaps.maxAtomicCounterBufferSize;
1636 break;
1637 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1638 *params = mCaps.maxCombinedAtomicCounterBuffers;
1639 break;
1640 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1641 *params = mCaps.maxCombinedAtomicCounters;
1642 break;
1643 case GL_MAX_IMAGE_UNITS:
1644 *params = mCaps.maxImageUnits;
1645 break;
1646 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1647 *params = mCaps.maxCombinedImageUniforms;
1648 break;
1649 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1650 *params = mCaps.maxShaderStorageBufferBindings;
1651 break;
1652 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1653 *params = mCaps.maxCombinedShaderStorageBlocks;
1654 break;
1655 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1656 *params = mCaps.shaderStorageBufferOffsetAlignment;
1657 break;
1658 default:
1659 mGLState.getIntegerv(this, pname, params);
1660 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001661 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001662}
1663
Jamie Madill893ab082014-05-16 16:56:10 -04001664void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001665{
Shannon Woods53a94a82014-06-24 15:20:36 -04001666 // Queries about context capabilities and maximums are answered by Context.
1667 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001668 switch (pname)
1669 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001670 case GL_MAX_ELEMENT_INDEX:
1671 *params = mCaps.maxElementIndex;
1672 break;
1673 case GL_MAX_UNIFORM_BLOCK_SIZE:
1674 *params = mCaps.maxUniformBlockSize;
1675 break;
1676 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
1677 *params = mCaps.maxCombinedVertexUniformComponents;
1678 break;
1679 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
1680 *params = mCaps.maxCombinedFragmentUniformComponents;
1681 break;
1682 case GL_MAX_SERVER_WAIT_TIMEOUT:
1683 *params = mCaps.maxServerWaitTimeout;
1684 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001685
Jamie Madill231c7f52017-04-26 13:45:37 -04001686 // GL_EXT_disjoint_timer_query
1687 case GL_TIMESTAMP_EXT:
1688 *params = mImplementation->getTimestamp();
1689 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001690
Jamie Madill231c7f52017-04-26 13:45:37 -04001691 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1692 *params = mCaps.maxShaderStorageBlockSize;
1693 break;
1694 default:
1695 UNREACHABLE();
1696 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001697 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001698}
1699
Geoff Lang70d0f492015-12-10 17:45:46 -05001700void Context::getPointerv(GLenum pname, void **params) const
1701{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001702 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001703}
1704
Martin Radev66fb8202016-07-28 11:45:20 +03001705void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001706{
Shannon Woods53a94a82014-06-24 15:20:36 -04001707 // Queries about context capabilities and maximums are answered by Context.
1708 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001709
1710 GLenum nativeType;
1711 unsigned int numParams;
1712 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1713 ASSERT(queryStatus);
1714
1715 if (nativeType == GL_INT)
1716 {
1717 switch (target)
1718 {
1719 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1720 ASSERT(index < 3u);
1721 *data = mCaps.maxComputeWorkGroupCount[index];
1722 break;
1723 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1724 ASSERT(index < 3u);
1725 *data = mCaps.maxComputeWorkGroupSize[index];
1726 break;
1727 default:
1728 mGLState.getIntegeri_v(target, index, data);
1729 }
1730 }
1731 else
1732 {
1733 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1734 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001735}
1736
Martin Radev66fb8202016-07-28 11:45:20 +03001737void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001738{
Shannon Woods53a94a82014-06-24 15:20:36 -04001739 // Queries about context capabilities and maximums are answered by Context.
1740 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001741
1742 GLenum nativeType;
1743 unsigned int numParams;
1744 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1745 ASSERT(queryStatus);
1746
1747 if (nativeType == GL_INT_64_ANGLEX)
1748 {
1749 mGLState.getInteger64i_v(target, index, data);
1750 }
1751 else
1752 {
1753 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1754 }
1755}
1756
1757void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1758{
1759 // Queries about context capabilities and maximums are answered by Context.
1760 // Queries about current GL state values are answered by State.
1761
1762 GLenum nativeType;
1763 unsigned int numParams;
1764 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1765 ASSERT(queryStatus);
1766
1767 if (nativeType == GL_BOOL)
1768 {
1769 mGLState.getBooleani_v(target, index, data);
1770 }
1771 else
1772 {
1773 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1774 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001775}
1776
He Yunchao010e4db2017-03-03 14:22:06 +08001777void Context::getBufferParameteriv(GLenum target, GLenum pname, GLint *params)
1778{
1779 Buffer *buffer = mGLState.getTargetBuffer(target);
1780 QueryBufferParameteriv(buffer, pname, params);
1781}
1782
1783void Context::getFramebufferAttachmentParameteriv(GLenum target,
1784 GLenum attachment,
1785 GLenum pname,
1786 GLint *params)
1787{
1788 const Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
1789 QueryFramebufferAttachmentParameteriv(framebuffer, attachment, pname, params);
1790}
1791
1792void Context::getRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
1793{
1794 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
1795 QueryRenderbufferiv(this, renderbuffer, pname, params);
1796}
1797
1798void Context::getTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
1799{
1800 Texture *texture = getTargetTexture(target);
1801 QueryTexParameterfv(texture, pname, params);
1802}
1803
1804void Context::getTexParameteriv(GLenum target, GLenum pname, GLint *params)
1805{
1806 Texture *texture = getTargetTexture(target);
1807 QueryTexParameteriv(texture, pname, params);
1808}
1809void Context::texParameterf(GLenum target, GLenum pname, GLfloat param)
1810{
1811 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001812 SetTexParameterf(this, texture, pname, param);
He Yunchao010e4db2017-03-03 14:22:06 +08001813}
1814
1815void Context::texParameterfv(GLenum target, GLenum pname, const GLfloat *params)
1816{
1817 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001818 SetTexParameterfv(this, texture, pname, params);
He Yunchao010e4db2017-03-03 14:22:06 +08001819}
1820
1821void Context::texParameteri(GLenum target, GLenum pname, GLint param)
1822{
1823 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001824 SetTexParameteri(this, texture, pname, param);
He Yunchao010e4db2017-03-03 14:22:06 +08001825}
1826
1827void Context::texParameteriv(GLenum target, GLenum pname, const GLint *params)
1828{
1829 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001830 SetTexParameteriv(this, texture, pname, params);
He Yunchao010e4db2017-03-03 14:22:06 +08001831}
1832
Jamie Madill675fe712016-12-19 13:07:54 -05001833void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001834{
Jamie Madill1b94d432015-08-07 13:23:23 -04001835 syncRendererState();
Jamie Madillc564c072017-06-01 12:45:42 -04001836 auto error = mImplementation->drawArrays(this, mode, first, count);
Jamie Madill675fe712016-12-19 13:07:54 -05001837 handleError(error);
1838 if (!error.isError())
1839 {
1840 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1841 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001842}
1843
Jamie Madill675fe712016-12-19 13:07:54 -05001844void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Geoff Langf6db0982015-08-25 13:04:00 -04001845{
1846 syncRendererState();
Jamie Madillc564c072017-06-01 12:45:42 -04001847 auto error = mImplementation->drawArraysInstanced(this, mode, first, count, instanceCount);
Jamie Madill675fe712016-12-19 13:07:54 -05001848 handleError(error);
1849 if (!error.isError())
1850 {
1851 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1852 }
Geoff Langf6db0982015-08-25 13:04:00 -04001853}
1854
Jamie Madill876429b2017-04-20 15:46:24 -04001855void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001856{
Jamie Madill1b94d432015-08-07 13:23:23 -04001857 syncRendererState();
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001858 const IndexRange &indexRange = getParams<HasIndexRange>().getIndexRange().value();
Jamie Madillc564c072017-06-01 12:45:42 -04001859 handleError(mImplementation->drawElements(this, mode, count, type, indices, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001860}
1861
Jamie Madill675fe712016-12-19 13:07:54 -05001862void Context::drawElementsInstanced(GLenum mode,
1863 GLsizei count,
1864 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001865 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001866 GLsizei instances)
Geoff Langf6db0982015-08-25 13:04:00 -04001867{
1868 syncRendererState();
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001869 const IndexRange &indexRange = getParams<HasIndexRange>().getIndexRange().value();
Jamie Madillc564c072017-06-01 12:45:42 -04001870 handleError(mImplementation->drawElementsInstanced(this, mode, count, type, indices, instances,
1871 indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001872}
1873
Jamie Madill675fe712016-12-19 13:07:54 -05001874void Context::drawRangeElements(GLenum mode,
1875 GLuint start,
1876 GLuint end,
1877 GLsizei count,
1878 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001879 const void *indices)
Geoff Langf6db0982015-08-25 13:04:00 -04001880{
1881 syncRendererState();
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001882 const IndexRange &indexRange = getParams<HasIndexRange>().getIndexRange().value();
Jamie Madillc564c072017-06-01 12:45:42 -04001883 handleError(mImplementation->drawRangeElements(this, mode, start, end, count, type, indices,
1884 indexRange));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001885}
1886
Jamie Madill876429b2017-04-20 15:46:24 -04001887void Context::drawArraysIndirect(GLenum mode, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001888{
1889 syncRendererState();
Jamie Madillc564c072017-06-01 12:45:42 -04001890 handleError(mImplementation->drawArraysIndirect(this, mode, indirect));
Jiajia Qind9671222016-11-29 16:30:31 +08001891}
1892
Jamie Madill876429b2017-04-20 15:46:24 -04001893void Context::drawElementsIndirect(GLenum mode, GLenum type, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001894{
1895 syncRendererState();
Jamie Madillc564c072017-06-01 12:45:42 -04001896 handleError(mImplementation->drawElementsIndirect(this, mode, type, indirect));
Jiajia Qind9671222016-11-29 16:30:31 +08001897}
1898
Jamie Madill675fe712016-12-19 13:07:54 -05001899void Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001900{
Jamie Madill675fe712016-12-19 13:07:54 -05001901 handleError(mImplementation->flush());
Geoff Lang129753a2015-01-09 16:52:09 -05001902}
1903
Jamie Madill675fe712016-12-19 13:07:54 -05001904void Context::finish()
Geoff Lang129753a2015-01-09 16:52:09 -05001905{
Jamie Madill675fe712016-12-19 13:07:54 -05001906 handleError(mImplementation->finish());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001907}
1908
Austin Kinross6ee1e782015-05-29 17:05:37 -07001909void Context::insertEventMarker(GLsizei length, const char *marker)
1910{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001911 ASSERT(mImplementation);
1912 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001913}
1914
1915void Context::pushGroupMarker(GLsizei length, const char *marker)
1916{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001917 ASSERT(mImplementation);
1918 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001919}
1920
1921void Context::popGroupMarker()
1922{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001923 ASSERT(mImplementation);
1924 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001925}
1926
Geoff Langd8605522016-04-13 10:19:12 -04001927void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1928{
1929 Program *programObject = getProgram(program);
1930 ASSERT(programObject);
1931
1932 programObject->bindUniformLocation(location, name);
1933}
1934
Sami Väisänena797e062016-05-12 15:23:40 +03001935void Context::setCoverageModulation(GLenum components)
1936{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001937 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001938}
1939
Sami Väisänene45e53b2016-05-25 10:36:04 +03001940void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1941{
1942 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1943}
1944
1945void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1946{
1947 GLfloat I[16];
1948 angle::Matrix<GLfloat>::setToIdentity(I);
1949
1950 mGLState.loadPathRenderingMatrix(matrixMode, I);
1951}
1952
1953void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1954{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001955 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001956 if (!pathObj)
1957 return;
1958
1959 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1960 syncRendererState();
1961
1962 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1963}
1964
1965void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1966{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001967 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001968 if (!pathObj)
1969 return;
1970
1971 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1972 syncRendererState();
1973
1974 mImplementation->stencilStrokePath(pathObj, reference, mask);
1975}
1976
1977void Context::coverFillPath(GLuint path, GLenum coverMode)
1978{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001979 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001980 if (!pathObj)
1981 return;
1982
1983 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1984 syncRendererState();
1985
1986 mImplementation->coverFillPath(pathObj, coverMode);
1987}
1988
1989void Context::coverStrokePath(GLuint path, GLenum coverMode)
1990{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001991 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001992 if (!pathObj)
1993 return;
1994
1995 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1996 syncRendererState();
1997
1998 mImplementation->coverStrokePath(pathObj, coverMode);
1999}
2000
2001void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
2002{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002003 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03002004 if (!pathObj)
2005 return;
2006
2007 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2008 syncRendererState();
2009
2010 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
2011}
2012
2013void Context::stencilThenCoverStrokePath(GLuint path,
2014 GLint reference,
2015 GLuint mask,
2016 GLenum coverMode)
2017{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002018 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03002019 if (!pathObj)
2020 return;
2021
2022 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2023 syncRendererState();
2024
2025 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
2026}
2027
Sami Väisänend59ca052016-06-21 16:10:00 +03002028void Context::coverFillPathInstanced(GLsizei numPaths,
2029 GLenum pathNameType,
2030 const void *paths,
2031 GLuint pathBase,
2032 GLenum coverMode,
2033 GLenum transformType,
2034 const GLfloat *transformValues)
2035{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002036 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002037
2038 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2039 syncRendererState();
2040
2041 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
2042}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002043
Sami Väisänend59ca052016-06-21 16:10:00 +03002044void Context::coverStrokePathInstanced(GLsizei numPaths,
2045 GLenum pathNameType,
2046 const void *paths,
2047 GLuint pathBase,
2048 GLenum coverMode,
2049 GLenum transformType,
2050 const GLfloat *transformValues)
2051{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002052 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002053
2054 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2055 syncRendererState();
2056
2057 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
2058 transformValues);
2059}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002060
Sami Väisänend59ca052016-06-21 16:10:00 +03002061void Context::stencilFillPathInstanced(GLsizei numPaths,
2062 GLenum pathNameType,
2063 const void *paths,
2064 GLuint pathBase,
2065 GLenum fillMode,
2066 GLuint mask,
2067 GLenum transformType,
2068 const GLfloat *transformValues)
2069{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002070 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002071
2072 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2073 syncRendererState();
2074
2075 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
2076 transformValues);
2077}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002078
Sami Väisänend59ca052016-06-21 16:10:00 +03002079void Context::stencilStrokePathInstanced(GLsizei numPaths,
2080 GLenum pathNameType,
2081 const void *paths,
2082 GLuint pathBase,
2083 GLint reference,
2084 GLuint mask,
2085 GLenum transformType,
2086 const GLfloat *transformValues)
2087{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002088 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002089
2090 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2091 syncRendererState();
2092
2093 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
2094 transformValues);
2095}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002096
Sami Väisänend59ca052016-06-21 16:10:00 +03002097void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
2098 GLenum pathNameType,
2099 const void *paths,
2100 GLuint pathBase,
2101 GLenum fillMode,
2102 GLuint mask,
2103 GLenum coverMode,
2104 GLenum transformType,
2105 const GLfloat *transformValues)
2106{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002107 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002108
2109 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2110 syncRendererState();
2111
2112 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
2113 transformType, transformValues);
2114}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002115
Sami Väisänend59ca052016-06-21 16:10:00 +03002116void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
2117 GLenum pathNameType,
2118 const void *paths,
2119 GLuint pathBase,
2120 GLint reference,
2121 GLuint mask,
2122 GLenum coverMode,
2123 GLenum transformType,
2124 const GLfloat *transformValues)
2125{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002126 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002127
2128 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2129 syncRendererState();
2130
2131 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
2132 transformType, transformValues);
2133}
2134
Sami Väisänen46eaa942016-06-29 10:26:37 +03002135void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
2136{
2137 auto *programObject = getProgram(program);
2138
2139 programObject->bindFragmentInputLocation(location, name);
2140}
2141
2142void Context::programPathFragmentInputGen(GLuint program,
2143 GLint location,
2144 GLenum genMode,
2145 GLint components,
2146 const GLfloat *coeffs)
2147{
2148 auto *programObject = getProgram(program);
2149
Jamie Madillbd044ed2017-06-05 12:59:21 -04002150 programObject->pathFragmentInputGen(this, location, genMode, components, coeffs);
Sami Väisänen46eaa942016-06-29 10:26:37 +03002151}
2152
jchen1015015f72017-03-16 13:54:21 +08002153GLuint Context::getProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name)
2154{
jchen10fd7c3b52017-03-21 15:36:03 +08002155 const auto *programObject = getProgram(program);
jchen1015015f72017-03-16 13:54:21 +08002156 return QueryProgramResourceIndex(programObject, programInterface, name);
2157}
2158
jchen10fd7c3b52017-03-21 15:36:03 +08002159void Context::getProgramResourceName(GLuint program,
2160 GLenum programInterface,
2161 GLuint index,
2162 GLsizei bufSize,
2163 GLsizei *length,
2164 GLchar *name)
2165{
2166 const auto *programObject = getProgram(program);
2167 QueryProgramResourceName(programObject, programInterface, index, bufSize, length, name);
2168}
2169
jchen10191381f2017-04-11 13:59:04 +08002170GLint Context::getProgramResourceLocation(GLuint program,
2171 GLenum programInterface,
2172 const GLchar *name)
2173{
2174 const auto *programObject = getProgram(program);
2175 return QueryProgramResourceLocation(programObject, programInterface, name);
2176}
2177
Jamie Madill437fa652016-05-03 15:13:24 -04002178void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002179{
Geoff Langda5777c2014-07-11 09:52:58 -04002180 if (error.isError())
2181 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002182 GLenum code = error.getCode();
2183 mErrors.insert(code);
2184 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
2185 {
2186 markContextLost();
2187 }
Geoff Lang70d0f492015-12-10 17:45:46 -05002188
2189 if (!error.getMessage().empty())
2190 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002191 auto *debug = &mGLState.getDebug();
2192 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
2193 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05002194 }
Geoff Langda5777c2014-07-11 09:52:58 -04002195 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002196}
2197
2198// Get one of the recorded errors and clear its flag, if any.
2199// [OpenGL ES 2.0.24] section 2.5 page 13.
2200GLenum Context::getError()
2201{
Geoff Langda5777c2014-07-11 09:52:58 -04002202 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002203 {
Geoff Langda5777c2014-07-11 09:52:58 -04002204 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002205 }
Geoff Langda5777c2014-07-11 09:52:58 -04002206 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002207 {
Geoff Langda5777c2014-07-11 09:52:58 -04002208 GLenum error = *mErrors.begin();
2209 mErrors.erase(mErrors.begin());
2210 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002211 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002212}
2213
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002214// NOTE: this function should not assume that this context is current!
2215void Context::markContextLost()
2216{
2217 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002218 {
Jamie Madill231c7f52017-04-26 13:45:37 -04002219 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002220 mContextLostForced = true;
2221 }
Jamie Madill231c7f52017-04-26 13:45:37 -04002222 mContextLost = true;
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002223}
2224
2225bool Context::isContextLost()
2226{
2227 return mContextLost;
2228}
2229
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002230GLenum Context::getResetStatus()
2231{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002232 // Even if the application doesn't want to know about resets, we want to know
2233 // as it will allow us to skip all the calls.
2234 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002235 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002236 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002237 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002238 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002239 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002240
2241 // EXT_robustness, section 2.6: If the reset notification behavior is
2242 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2243 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2244 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002245 }
2246
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002247 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2248 // status should be returned at least once, and GL_NO_ERROR should be returned
2249 // once the device has finished resetting.
2250 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002251 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002252 ASSERT(mResetStatus == GL_NO_ERROR);
2253 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002254
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002255 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002256 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002257 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002258 }
2259 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002260 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002261 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002262 // If markContextLost was used to mark the context lost then
2263 // assume that is not recoverable, and continue to report the
2264 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002265 mResetStatus = mImplementation->getResetStatus();
2266 }
Jamie Madill893ab082014-05-16 16:56:10 -04002267
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002268 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002269}
2270
2271bool Context::isResetNotificationEnabled()
2272{
2273 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2274}
2275
Corentin Walleze3b10e82015-05-20 11:06:25 -04002276const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002277{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002278 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002279}
2280
2281EGLenum Context::getClientType() const
2282{
2283 return mClientType;
2284}
2285
2286EGLenum Context::getRenderBuffer() const
2287{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002288 const Framebuffer *framebuffer = mState.mFramebuffers->getFramebuffer(0);
2289 if (framebuffer == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -04002290 {
2291 return EGL_NONE;
2292 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002293
2294 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2295 ASSERT(backAttachment != nullptr);
2296 return backAttachment->getSurface()->getRenderBuffer();
Régis Fénéon83107972015-02-05 12:57:44 +01002297}
2298
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002299VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002300{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002301 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002302 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2303 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002304 {
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002305 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle,
2306 mCaps.maxVertexAttributes, mCaps.maxVertexAttribBindings);
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002307
Jamie Madill96a483b2017-06-27 16:49:21 -04002308 mVertexArrayMap.assign(vertexArrayHandle, vertexArray);
Geoff Lang36167ab2015-12-07 10:27:14 -05002309 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002310
2311 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002312}
2313
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002314TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002315{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002316 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002317 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2318 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002319 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002320 transformFeedback =
2321 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002322 transformFeedback->addRef();
Jamie Madill96a483b2017-06-27 16:49:21 -04002323 mTransformFeedbackMap.assign(transformFeedbackHandle, transformFeedback);
Geoff Lang36167ab2015-12-07 10:27:14 -05002324 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002325
2326 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002327}
2328
2329bool Context::isVertexArrayGenerated(GLuint vertexArray)
2330{
Jamie Madill96a483b2017-06-27 16:49:21 -04002331 ASSERT(mVertexArrayMap.contains(0));
2332 return mVertexArrayMap.contains(vertexArray);
Geoff Lang36167ab2015-12-07 10:27:14 -05002333}
2334
2335bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2336{
Jamie Madill96a483b2017-06-27 16:49:21 -04002337 ASSERT(mTransformFeedbackMap.contains(0));
2338 return mTransformFeedbackMap.contains(transformFeedback);
Geoff Lang36167ab2015-12-07 10:27:14 -05002339}
2340
Shannon Woods53a94a82014-06-24 15:20:36 -04002341void Context::detachTexture(GLuint texture)
2342{
2343 // Simple pass-through to State's detachTexture method, as textures do not require
2344 // allocation map management either here or in the resource manager at detach time.
2345 // Zero textures are held by the Context, and we don't attempt to request them from
2346 // the State.
Jamie Madilla02315b2017-02-23 14:14:47 -05002347 mGLState.detachTexture(this, mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002348}
2349
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002350void Context::detachBuffer(GLuint buffer)
2351{
Yuly Novikov5807a532015-12-03 13:01:22 -05002352 // Simple pass-through to State's detachBuffer method, since
2353 // only buffer attachments to container objects that are bound to the current context
2354 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002355
Yuly Novikov5807a532015-12-03 13:01:22 -05002356 // [OpenGL ES 3.2] section 5.1.2 page 45:
2357 // Attachments to unbound container objects, such as
2358 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2359 // are not affected and continue to act as references on the deleted object
Jamie Madill4928b7c2017-06-20 12:57:39 -04002360 mGLState.detachBuffer(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002361}
2362
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002363void Context::detachFramebuffer(GLuint framebuffer)
2364{
Shannon Woods53a94a82014-06-24 15:20:36 -04002365 // Framebuffer detachment is handled by Context, because 0 is a valid
2366 // Framebuffer object, and a pointer to it must be passed from Context
2367 // to State at binding time.
2368
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002369 // [OpenGL ES 2.0.24] section 4.4 page 107:
Jamie Madill231c7f52017-04-26 13:45:37 -04002370 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as
2371 // though BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of
2372 // zero.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002373
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002374 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002375 {
2376 bindReadFramebuffer(0);
2377 }
2378
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002379 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002380 {
2381 bindDrawFramebuffer(0);
2382 }
2383}
2384
2385void Context::detachRenderbuffer(GLuint renderbuffer)
2386{
Jamie Madilla02315b2017-02-23 14:14:47 -05002387 mGLState.detachRenderbuffer(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002388}
2389
Jamie Madill57a89722013-07-02 11:57:03 -04002390void Context::detachVertexArray(GLuint vertexArray)
2391{
Jamie Madill77a72f62015-04-14 11:18:32 -04002392 // Vertex array detachment is handled by Context, because 0 is a valid
2393 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002394 // binding time.
2395
Jamie Madill57a89722013-07-02 11:57:03 -04002396 // [OpenGL ES 3.0.2] section 2.10 page 43:
2397 // If a vertex array object that is currently bound is deleted, the binding
2398 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002399 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002400 {
2401 bindVertexArray(0);
2402 }
2403}
2404
Geoff Langc8058452014-02-03 12:04:11 -05002405void Context::detachTransformFeedback(GLuint transformFeedback)
2406{
Corentin Walleza2257da2016-04-19 16:43:12 -04002407 // Transform feedback detachment is handled by Context, because 0 is a valid
2408 // transform feedback, and a pointer to it must be passed from Context to State at
2409 // binding time.
2410
2411 // The OpenGL specification doesn't mention what should happen when the currently bound
2412 // transform feedback object is deleted. Since it is a container object, we treat it like
2413 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madill4928b7c2017-06-20 12:57:39 -04002414 if (mGLState.removeTransformFeedbackBinding(this, transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002415 {
2416 bindTransformFeedback(0);
2417 }
Geoff Langc8058452014-02-03 12:04:11 -05002418}
2419
Jamie Madilldc356042013-07-19 16:36:57 -04002420void Context::detachSampler(GLuint sampler)
2421{
Jamie Madill4928b7c2017-06-20 12:57:39 -04002422 mGLState.detachSampler(this, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002423}
2424
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002425void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2426{
Shaodde78e82017-05-22 14:13:27 +08002427 mGLState.setVertexAttribDivisor(this, index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002428}
2429
Jamie Madille29d1672013-07-19 16:36:57 -04002430void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2431{
Geoff Langc1984ed2016-10-07 12:41:00 -04002432 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002433 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002434 SetSamplerParameteri(samplerObject, pname, param);
2435}
Jamie Madille29d1672013-07-19 16:36:57 -04002436
Geoff Langc1984ed2016-10-07 12:41:00 -04002437void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2438{
2439 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002440 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002441 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002442}
2443
2444void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2445{
Geoff Langc1984ed2016-10-07 12:41:00 -04002446 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002447 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002448 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002449}
2450
Geoff Langc1984ed2016-10-07 12:41:00 -04002451void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002452{
Geoff Langc1984ed2016-10-07 12:41:00 -04002453 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002454 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002455 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002456}
2457
Geoff Langc1984ed2016-10-07 12:41:00 -04002458void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002459{
Geoff Langc1984ed2016-10-07 12:41:00 -04002460 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002461 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002462 QuerySamplerParameteriv(samplerObject, pname, params);
2463}
Jamie Madill9675b802013-07-19 16:36:59 -04002464
Geoff Langc1984ed2016-10-07 12:41:00 -04002465void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2466{
2467 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002468 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002469 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002470}
2471
Olli Etuahof0fee072016-03-30 15:11:58 +03002472void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2473{
2474 gl::Program *programObject = getProgram(program);
Yunchao He61afff12017-03-14 15:34:03 +08002475 SetProgramParameteri(programObject, pname, value);
Olli Etuahof0fee072016-03-30 15:11:58 +03002476}
2477
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002478void Context::initRendererString()
2479{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002480 std::ostringstream rendererString;
2481 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002482 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002483 rendererString << ")";
2484
Geoff Langcec35902014-04-16 10:52:36 -04002485 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002486}
2487
Geoff Langc339c4e2016-11-29 10:37:36 -05002488void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002489{
Geoff Langc339c4e2016-11-29 10:37:36 -05002490 const Version &clientVersion = getClientVersion();
2491
2492 std::ostringstream versionString;
2493 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2494 << ANGLE_VERSION_STRING << ")";
2495 mVersionString = MakeStaticString(versionString.str());
2496
2497 std::ostringstream shadingLanguageVersionString;
2498 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2499 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2500 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2501 << ")";
2502 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002503}
2504
Geoff Langcec35902014-04-16 10:52:36 -04002505void Context::initExtensionStrings()
2506{
Geoff Langc339c4e2016-11-29 10:37:36 -05002507 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2508 std::ostringstream combinedStringStream;
2509 std::copy(strings.begin(), strings.end(),
2510 std::ostream_iterator<const char *>(combinedStringStream, " "));
2511 return MakeStaticString(combinedStringStream.str());
2512 };
2513
2514 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002515 for (const auto &extensionString : mExtensions.getStrings())
2516 {
2517 mExtensionStrings.push_back(MakeStaticString(extensionString));
2518 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002519 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002520
Bryan Bernhart58806562017-01-05 13:09:31 -08002521 const gl::Extensions &nativeExtensions = mImplementation->getNativeExtensions();
2522
Geoff Langc339c4e2016-11-29 10:37:36 -05002523 mRequestableExtensionStrings.clear();
2524 for (const auto &extensionInfo : GetExtensionInfoMap())
2525 {
2526 if (extensionInfo.second.Requestable &&
Bryan Bernhart58806562017-01-05 13:09:31 -08002527 !(mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
2528 nativeExtensions.*(extensionInfo.second.ExtensionsMember))
Geoff Langc339c4e2016-11-29 10:37:36 -05002529 {
2530 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2531 }
2532 }
2533 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002534}
2535
Geoff Langc339c4e2016-11-29 10:37:36 -05002536const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002537{
Geoff Langc339c4e2016-11-29 10:37:36 -05002538 switch (name)
2539 {
2540 case GL_VENDOR:
2541 return reinterpret_cast<const GLubyte *>("Google Inc.");
2542
2543 case GL_RENDERER:
2544 return reinterpret_cast<const GLubyte *>(mRendererString);
2545
2546 case GL_VERSION:
2547 return reinterpret_cast<const GLubyte *>(mVersionString);
2548
2549 case GL_SHADING_LANGUAGE_VERSION:
2550 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2551
2552 case GL_EXTENSIONS:
2553 return reinterpret_cast<const GLubyte *>(mExtensionString);
2554
2555 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2556 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2557
2558 default:
2559 UNREACHABLE();
2560 return nullptr;
2561 }
Geoff Langcec35902014-04-16 10:52:36 -04002562}
2563
Geoff Langc339c4e2016-11-29 10:37:36 -05002564const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002565{
Geoff Langc339c4e2016-11-29 10:37:36 -05002566 switch (name)
2567 {
2568 case GL_EXTENSIONS:
2569 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2570
2571 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2572 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2573
2574 default:
2575 UNREACHABLE();
2576 return nullptr;
2577 }
Geoff Langcec35902014-04-16 10:52:36 -04002578}
2579
2580size_t Context::getExtensionStringCount() const
2581{
2582 return mExtensionStrings.size();
2583}
2584
Geoff Langc339c4e2016-11-29 10:37:36 -05002585void Context::requestExtension(const char *name)
2586{
2587 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2588 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2589 const auto &extension = extensionInfos.at(name);
2590 ASSERT(extension.Requestable);
2591
2592 if (mExtensions.*(extension.ExtensionsMember))
2593 {
2594 // Extension already enabled
2595 return;
2596 }
2597
2598 mExtensions.*(extension.ExtensionsMember) = true;
2599 updateCaps();
2600 initExtensionStrings();
Bryan Bernhart58806562017-01-05 13:09:31 -08002601
Jamie Madill2f348d22017-06-05 10:50:59 -04002602 // Release the shader compiler so it will be re-created with the requested extensions enabled.
2603 releaseShaderCompiler();
Geoff Lang9aded172017-04-05 11:07:56 -04002604
2605 // Invalidate all cached completenesses for textures and framebuffer. Some extensions make new
2606 // formats renderable or sampleable.
2607 mState.mTextures->invalidateTextureComplenessCache();
2608 for (auto &zeroTexture : mZeroTextures)
2609 {
2610 zeroTexture.second->invalidateCompletenessCache();
2611 }
2612
2613 mState.mFramebuffers->invalidateFramebufferComplenessCache();
Geoff Langc339c4e2016-11-29 10:37:36 -05002614}
2615
2616size_t Context::getRequestableExtensionStringCount() const
2617{
2618 return mRequestableExtensionStrings.size();
2619}
2620
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002621void Context::beginTransformFeedback(GLenum primitiveMode)
2622{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002623 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002624 ASSERT(transformFeedback != nullptr);
2625 ASSERT(!transformFeedback->isPaused());
2626
Jamie Madill6c1f6712017-02-14 19:08:04 -05002627 transformFeedback->begin(this, primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002628}
2629
2630bool Context::hasActiveTransformFeedback(GLuint program) const
2631{
2632 for (auto pair : mTransformFeedbackMap)
2633 {
2634 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2635 {
2636 return true;
2637 }
2638 }
2639 return false;
2640}
2641
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002642void Context::initCaps(const egl::DisplayExtensions &displayExtensions)
Geoff Lang493daf52014-07-03 13:38:44 -04002643{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002644 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002645
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002646 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002647
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002648 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002649
Geoff Langeb66a6e2016-10-31 13:06:12 -04002650 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002651 {
2652 // Disable ES3+ extensions
Jamie Madill231c7f52017-04-26 13:45:37 -04002653 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002654 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002655 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002656 }
2657
Geoff Langeb66a6e2016-10-31 13:06:12 -04002658 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002659 {
2660 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
Jamie Madill231c7f52017-04-26 13:45:37 -04002661 // mExtensions.sRGB = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002662 }
2663
Jamie Madill00ed7a12016-05-19 13:13:38 -04002664 // Some extensions are always available because they are implemented in the GL layer.
Jamie Madill231c7f52017-04-26 13:45:37 -04002665 mExtensions.bindUniformLocation = true;
2666 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002667 mExtensions.bindGeneratesResource = true;
Geoff Langfeb8c682017-02-13 16:07:35 -05002668 mExtensions.clientArrays = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002669 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002670
2671 // Enable the no error extension if the context was created with the flag.
2672 mExtensions.noError = mSkipValidation;
2673
Corentin Wallezccab69d2017-01-27 16:57:15 -05002674 // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
Corentin Wallezc295e512017-01-27 17:47:50 -05002675 mExtensions.surfacelessContext = displayExtensions.surfacelessContext;
Corentin Wallezccab69d2017-01-27 16:57:15 -05002676
Geoff Lang70d0f492015-12-10 17:45:46 -05002677 // Explicitly enable GL_KHR_debug
2678 mExtensions.debug = true;
2679 mExtensions.maxDebugMessageLength = 1024;
2680 mExtensions.maxDebugLoggedMessages = 1024;
2681 mExtensions.maxDebugGroupStackDepth = 1024;
2682 mExtensions.maxLabelLength = 1024;
2683
Geoff Langff5b2d52016-09-07 11:32:23 -04002684 // Explicitly enable GL_ANGLE_robust_client_memory
2685 mExtensions.robustClientMemory = true;
2686
Jamie Madille08a1d32017-03-07 17:24:06 -05002687 // Determine robust resource init availability from EGL.
2688 mExtensions.robustResourceInitialization =
Jamie Madill948bbe52017-06-01 13:10:42 -04002689 egl::Display::GetClientExtensions().displayRobustResourceInitialization;
Jamie Madille08a1d32017-03-07 17:24:06 -05002690
Jamie Madillc43be722017-07-13 16:22:14 -04002691 // Enable the cache control query unconditionally.
2692 mExtensions.programCacheControl = true;
2693
Geoff Lang301d1612014-07-09 10:34:37 -04002694 // Apply implementation limits
2695 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002696 mCaps.maxVertexAttribBindings =
2697 getClientVersion() < ES_3_1
2698 ? mCaps.maxVertexAttributes
2699 : std::min<GLuint>(mCaps.maxVertexAttribBindings, MAX_VERTEX_ATTRIB_BINDINGS);
2700
Jamie Madill231c7f52017-04-26 13:45:37 -04002701 mCaps.maxVertexUniformBlocks = std::min<GLuint>(
2702 mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2703 mCaps.maxVertexOutputComponents =
2704 std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang301d1612014-07-09 10:34:37 -04002705
Jamie Madill231c7f52017-04-26 13:45:37 -04002706 mCaps.maxFragmentInputComponents =
2707 std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002708
Geoff Langc287ea62016-09-16 14:46:51 -04002709 // WebGL compatibility
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002710 mExtensions.webglCompatibility = mWebGLContext;
Geoff Langc287ea62016-09-16 14:46:51 -04002711 for (const auto &extensionInfo : GetExtensionInfoMap())
2712 {
2713 // If this context is for WebGL, disable all enableable extensions
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002714 if (mWebGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002715 {
2716 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2717 }
2718 }
2719
2720 // Generate texture caps
2721 updateCaps();
2722}
2723
2724void Context::updateCaps()
2725{
Geoff Lang900013c2014-07-07 11:32:19 -04002726 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002727 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002728
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002729 for (auto capsIt : mImplementation->getNativeTextureCaps())
Geoff Lang493daf52014-07-03 13:38:44 -04002730 {
Geoff Langca271392017-04-05 12:30:00 -04002731 GLenum sizedInternalFormat = capsIt.first;
Jamie Madill231c7f52017-04-26 13:45:37 -04002732 TextureCaps formatCaps = capsIt.second;
Geoff Lang493daf52014-07-03 13:38:44 -04002733
Geoff Langca271392017-04-05 12:30:00 -04002734 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002735
Geoff Lang0d8b7242015-09-09 14:56:53 -04002736 // Update the format caps based on the client version and extensions.
2737 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2738 // ES3.
2739 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002740 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002741 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002742 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002743 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002744 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002745
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002746 // OpenGL ES does not support multisampling with non-rendererable formats
2747 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
Olli Etuaho50c562d2017-06-06 14:43:30 +03002748 if (!formatCaps.renderable ||
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002749 (getClientVersion() < ES_3_1 &&
2750 (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
Geoff Lang493daf52014-07-03 13:38:44 -04002751 {
Geoff Langd87878e2014-09-19 15:42:59 -04002752 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002753 }
Olli Etuaho50c562d2017-06-06 14:43:30 +03002754 else
2755 {
2756 // We may have limited the max samples for some required renderbuffer formats due to
2757 // non-conformant formats. In this case MAX_SAMPLES needs to be lowered accordingly.
2758 GLuint formatMaxSamples = formatCaps.getMaxSamples();
2759
2760 // GLES 3.0.5 section 4.4.2.2: "Implementations must support creation of renderbuffers
2761 // in these required formats with up to the value of MAX_SAMPLES multisamples, with the
2762 // exception of signed and unsigned integer formats."
2763 if (formatInfo.componentType != GL_INT && formatInfo.componentType != GL_UNSIGNED_INT &&
2764 formatInfo.isRequiredRenderbufferFormat(getClientVersion()))
2765 {
2766 ASSERT(getClientVersion() < ES_3_0 || formatMaxSamples >= 4);
2767 mCaps.maxSamples = std::min(mCaps.maxSamples, formatMaxSamples);
2768 }
2769
2770 // Handle GLES 3.1 MAX_*_SAMPLES values similarly to MAX_SAMPLES.
2771 if (getClientVersion() >= ES_3_1)
2772 {
2773 // GLES 3.1 section 9.2.5: "Implementations must support creation of renderbuffers
2774 // in these required formats with up to the value of MAX_SAMPLES multisamples, with
2775 // the exception that the signed and unsigned integer formats are required only to
2776 // support creation of renderbuffers with up to the value of MAX_INTEGER_SAMPLES
2777 // multisamples, which must be at least one."
2778 if (formatInfo.componentType == GL_INT ||
2779 formatInfo.componentType == GL_UNSIGNED_INT)
2780 {
2781 mCaps.maxIntegerSamples = std::min(mCaps.maxIntegerSamples, formatMaxSamples);
2782 }
2783
2784 // GLES 3.1 section 19.3.1.
2785 if (formatCaps.texturable)
2786 {
2787 if (formatInfo.depthBits > 0)
2788 {
2789 mCaps.maxDepthTextureSamples =
2790 std::min(mCaps.maxDepthTextureSamples, formatMaxSamples);
2791 }
2792 else if (formatInfo.redBits > 0)
2793 {
2794 mCaps.maxColorTextureSamples =
2795 std::min(mCaps.maxColorTextureSamples, formatMaxSamples);
2796 }
2797 }
2798 }
2799 }
Geoff Langd87878e2014-09-19 15:42:59 -04002800
2801 if (formatCaps.texturable && formatInfo.compressed)
2802 {
Geoff Langca271392017-04-05 12:30:00 -04002803 mCaps.compressedTextureFormats.push_back(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002804 }
2805
Geoff Langca271392017-04-05 12:30:00 -04002806 mTextureCaps.insert(sizedInternalFormat, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002807 }
Jamie Madill32447362017-06-28 14:53:52 -04002808
2809 // If program binary is disabled, blank out the memory cache pointer.
2810 if (!mImplementation->getNativeExtensions().getProgramBinary)
2811 {
2812 mMemoryProgramCache = nullptr;
2813 }
Geoff Lang493daf52014-07-03 13:38:44 -04002814}
2815
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002816void Context::initWorkarounds()
2817{
Jamie Madill761b02c2017-06-23 16:27:06 -04002818 // Apply back-end workarounds.
2819 mImplementation->applyNativeWorkarounds(&mWorkarounds);
2820
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002821 // Lose the context upon out of memory error if the application is
2822 // expecting to watch for those events.
2823 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2824}
2825
Jamie Madill1b94d432015-08-07 13:23:23 -04002826void Context::syncRendererState()
2827{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002828 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
Jamie Madillfe548342017-06-19 11:13:24 -04002829 mImplementation->syncState(this, dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002830 mGLState.clearDirtyBits();
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002831 mGLState.syncDirtyObjects(this);
Jamie Madill1b94d432015-08-07 13:23:23 -04002832}
2833
Jamie Madillad9f24e2016-02-12 09:27:24 -05002834void Context::syncRendererState(const State::DirtyBits &bitMask,
2835 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002836{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002837 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
Jamie Madillfe548342017-06-19 11:13:24 -04002838 mImplementation->syncState(this, dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002839 mGLState.clearDirtyBits(dirtyBits);
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002840 mGLState.syncDirtyObjects(this, objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002841}
Jamie Madillc29968b2016-01-20 11:17:23 -05002842
2843void Context::blitFramebuffer(GLint srcX0,
2844 GLint srcY0,
2845 GLint srcX1,
2846 GLint srcY1,
2847 GLint dstX0,
2848 GLint dstY0,
2849 GLint dstX1,
2850 GLint dstY1,
2851 GLbitfield mask,
2852 GLenum filter)
2853{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002854 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002855 ASSERT(drawFramebuffer);
2856
2857 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2858 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2859
Jamie Madillad9f24e2016-02-12 09:27:24 -05002860 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002861
Jamie Madillc564c072017-06-01 12:45:42 -04002862 handleError(drawFramebuffer->blit(this, srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002863}
Jamie Madillc29968b2016-01-20 11:17:23 -05002864
2865void Context::clear(GLbitfield mask)
2866{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002867 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002868 handleError(mGLState.getDrawFramebuffer()->clear(this, mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002869}
2870
2871void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2872{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002873 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002874 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002875}
2876
2877void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2878{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002879 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002880 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002881}
2882
2883void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2884{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002885 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002886 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002887}
2888
2889void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2890{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002891 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002892 ASSERT(framebufferObject);
2893
2894 // If a buffer is not present, the clear has no effect
2895 if (framebufferObject->getDepthbuffer() == nullptr &&
2896 framebufferObject->getStencilbuffer() == nullptr)
2897 {
2898 return;
2899 }
2900
Jamie Madillad9f24e2016-02-12 09:27:24 -05002901 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002902 handleError(framebufferObject->clearBufferfi(this, buffer, drawbuffer, depth, stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002903}
2904
2905void Context::readPixels(GLint x,
2906 GLint y,
2907 GLsizei width,
2908 GLsizei height,
2909 GLenum format,
2910 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002911 void *pixels)
Jamie Madillc29968b2016-01-20 11:17:23 -05002912{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002913 if (width == 0 || height == 0)
2914 {
2915 return;
2916 }
2917
Jamie Madillad9f24e2016-02-12 09:27:24 -05002918 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002919
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002920 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002921 ASSERT(framebufferObject);
2922
2923 Rectangle area(x, y, width, height);
Jamie Madillc564c072017-06-01 12:45:42 -04002924 handleError(framebufferObject->readPixels(this, area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002925}
2926
2927void Context::copyTexImage2D(GLenum target,
2928 GLint level,
2929 GLenum internalformat,
2930 GLint x,
2931 GLint y,
2932 GLsizei width,
2933 GLsizei height,
2934 GLint border)
2935{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002936 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002937 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002938
Jamie Madillc29968b2016-01-20 11:17:23 -05002939 Rectangle sourceArea(x, y, width, height);
2940
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002941 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002942 Texture *texture =
2943 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002944 handleError(texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002945}
2946
2947void Context::copyTexSubImage2D(GLenum target,
2948 GLint level,
2949 GLint xoffset,
2950 GLint yoffset,
2951 GLint x,
2952 GLint y,
2953 GLsizei width,
2954 GLsizei height)
2955{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002956 if (width == 0 || height == 0)
2957 {
2958 return;
2959 }
2960
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002961 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002962 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002963
Jamie Madillc29968b2016-01-20 11:17:23 -05002964 Offset destOffset(xoffset, yoffset, 0);
2965 Rectangle sourceArea(x, y, width, height);
2966
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002967 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002968 Texture *texture =
2969 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002970 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002971}
2972
2973void Context::copyTexSubImage3D(GLenum target,
2974 GLint level,
2975 GLint xoffset,
2976 GLint yoffset,
2977 GLint zoffset,
2978 GLint x,
2979 GLint y,
2980 GLsizei width,
2981 GLsizei height)
2982{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002983 if (width == 0 || height == 0)
2984 {
2985 return;
2986 }
2987
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002988 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002989 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002990
Jamie Madillc29968b2016-01-20 11:17:23 -05002991 Offset destOffset(xoffset, yoffset, zoffset);
2992 Rectangle sourceArea(x, y, width, height);
2993
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002994 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002995 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002996 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002997}
2998
2999void Context::framebufferTexture2D(GLenum target,
3000 GLenum attachment,
3001 GLenum textarget,
3002 GLuint texture,
3003 GLint level)
3004{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003005 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003006 ASSERT(framebuffer);
3007
3008 if (texture != 0)
3009 {
3010 Texture *textureObj = getTexture(texture);
3011
3012 ImageIndex index = ImageIndex::MakeInvalid();
3013
3014 if (textarget == GL_TEXTURE_2D)
3015 {
3016 index = ImageIndex::Make2D(level);
3017 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08003018 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
3019 {
3020 ASSERT(level == 0);
3021 index = ImageIndex::Make2DMultisample();
3022 }
Jamie Madillc29968b2016-01-20 11:17:23 -05003023 else
3024 {
3025 ASSERT(IsCubeMapTextureTarget(textarget));
3026 index = ImageIndex::MakeCube(textarget, level);
3027 }
3028
Jamie Madilla02315b2017-02-23 14:14:47 -05003029 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
Jamie Madillc29968b2016-01-20 11:17:23 -05003030 }
3031 else
3032 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003033 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003034 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003035
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003036 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003037}
3038
3039void Context::framebufferRenderbuffer(GLenum target,
3040 GLenum attachment,
3041 GLenum renderbuffertarget,
3042 GLuint renderbuffer)
3043{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003044 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003045 ASSERT(framebuffer);
3046
3047 if (renderbuffer != 0)
3048 {
3049 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
Jamie Madilla02315b2017-02-23 14:14:47 -05003050
3051 framebuffer->setAttachment(this, GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
Jamie Madillc29968b2016-01-20 11:17:23 -05003052 renderbufferObject);
3053 }
3054 else
3055 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003056 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003057 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003058
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003059 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003060}
3061
3062void Context::framebufferTextureLayer(GLenum target,
3063 GLenum attachment,
3064 GLuint texture,
3065 GLint level,
3066 GLint layer)
3067{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003068 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003069 ASSERT(framebuffer);
3070
3071 if (texture != 0)
3072 {
3073 Texture *textureObject = getTexture(texture);
3074
3075 ImageIndex index = ImageIndex::MakeInvalid();
3076
3077 if (textureObject->getTarget() == GL_TEXTURE_3D)
3078 {
3079 index = ImageIndex::Make3D(level, layer);
3080 }
3081 else
3082 {
3083 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
3084 index = ImageIndex::Make2DArray(level, layer);
3085 }
3086
Jamie Madilla02315b2017-02-23 14:14:47 -05003087 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObject);
Jamie Madillc29968b2016-01-20 11:17:23 -05003088 }
3089 else
3090 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003091 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003092 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003093
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003094 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003095}
3096
3097void Context::drawBuffers(GLsizei n, const GLenum *bufs)
3098{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003099 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003100 ASSERT(framebuffer);
3101 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003102 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003103}
3104
3105void Context::readBuffer(GLenum mode)
3106{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003107 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003108 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003109 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003110}
3111
3112void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
3113{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003114 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003115 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003116
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003117 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003118 ASSERT(framebuffer);
3119
3120 // The specification isn't clear what should be done when the framebuffer isn't complete.
3121 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill4928b7c2017-06-20 12:57:39 -04003122 handleError(framebuffer->discard(this, numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003123}
3124
3125void Context::invalidateFramebuffer(GLenum target,
3126 GLsizei numAttachments,
3127 const GLenum *attachments)
3128{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003129 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003130 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003131
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003132 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003133 ASSERT(framebuffer);
3134
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003135 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003136 {
Jamie Madill437fa652016-05-03 15:13:24 -04003137 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003138 }
Jamie Madill437fa652016-05-03 15:13:24 -04003139
Jamie Madill4928b7c2017-06-20 12:57:39 -04003140 handleError(framebuffer->invalidate(this, numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003141}
3142
3143void Context::invalidateSubFramebuffer(GLenum target,
3144 GLsizei numAttachments,
3145 const GLenum *attachments,
3146 GLint x,
3147 GLint y,
3148 GLsizei width,
3149 GLsizei height)
3150{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003151 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003152 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003153
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003154 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003155 ASSERT(framebuffer);
3156
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003157 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003158 {
Jamie Madill437fa652016-05-03 15:13:24 -04003159 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003160 }
Jamie Madill437fa652016-05-03 15:13:24 -04003161
3162 Rectangle area(x, y, width, height);
Jamie Madill4928b7c2017-06-20 12:57:39 -04003163 handleError(framebuffer->invalidateSub(this, numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05003164}
3165
Jamie Madill73a84962016-02-12 09:27:23 -05003166void Context::texImage2D(GLenum target,
3167 GLint level,
3168 GLint internalformat,
3169 GLsizei width,
3170 GLsizei height,
3171 GLint border,
3172 GLenum format,
3173 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003174 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003175{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003176 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003177
3178 Extents size(width, height, 1);
3179 Texture *texture =
3180 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003181 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3182 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003183}
3184
3185void Context::texImage3D(GLenum target,
3186 GLint level,
3187 GLint internalformat,
3188 GLsizei width,
3189 GLsizei height,
3190 GLsizei depth,
3191 GLint border,
3192 GLenum format,
3193 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003194 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003195{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003196 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003197
3198 Extents size(width, height, depth);
3199 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003200 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3201 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003202}
3203
3204void Context::texSubImage2D(GLenum target,
3205 GLint level,
3206 GLint xoffset,
3207 GLint yoffset,
3208 GLsizei width,
3209 GLsizei height,
3210 GLenum format,
3211 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003212 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003213{
3214 // Zero sized uploads are valid but no-ops
3215 if (width == 0 || height == 0)
3216 {
3217 return;
3218 }
3219
Jamie Madillad9f24e2016-02-12 09:27:24 -05003220 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003221
3222 Box area(xoffset, yoffset, 0, width, height, 1);
3223 Texture *texture =
3224 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003225 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3226 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003227}
3228
3229void Context::texSubImage3D(GLenum target,
3230 GLint level,
3231 GLint xoffset,
3232 GLint yoffset,
3233 GLint zoffset,
3234 GLsizei width,
3235 GLsizei height,
3236 GLsizei depth,
3237 GLenum format,
3238 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003239 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003240{
3241 // Zero sized uploads are valid but no-ops
3242 if (width == 0 || height == 0 || depth == 0)
3243 {
3244 return;
3245 }
3246
Jamie Madillad9f24e2016-02-12 09:27:24 -05003247 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003248
3249 Box area(xoffset, yoffset, zoffset, width, height, depth);
3250 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003251 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3252 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003253}
3254
3255void Context::compressedTexImage2D(GLenum target,
3256 GLint level,
3257 GLenum internalformat,
3258 GLsizei width,
3259 GLsizei height,
3260 GLint border,
3261 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003262 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003263{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003264 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003265
3266 Extents size(width, height, 1);
3267 Texture *texture =
3268 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003269 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003270 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003271 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003272}
3273
3274void Context::compressedTexImage3D(GLenum target,
3275 GLint level,
3276 GLenum internalformat,
3277 GLsizei width,
3278 GLsizei height,
3279 GLsizei depth,
3280 GLint border,
3281 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003282 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003283{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003284 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003285
3286 Extents size(width, height, depth);
3287 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003288 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003289 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003290 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003291}
3292
3293void Context::compressedTexSubImage2D(GLenum target,
3294 GLint level,
3295 GLint xoffset,
3296 GLint yoffset,
3297 GLsizei width,
3298 GLsizei height,
3299 GLenum format,
3300 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003301 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003302{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003303 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003304
3305 Box area(xoffset, yoffset, 0, width, height, 1);
3306 Texture *texture =
3307 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003308 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003309 format, imageSize,
3310 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003311}
3312
3313void Context::compressedTexSubImage3D(GLenum target,
3314 GLint level,
3315 GLint xoffset,
3316 GLint yoffset,
3317 GLint zoffset,
3318 GLsizei width,
3319 GLsizei height,
3320 GLsizei depth,
3321 GLenum format,
3322 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003323 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003324{
3325 // Zero sized uploads are valid but no-ops
3326 if (width == 0 || height == 0)
3327 {
3328 return;
3329 }
3330
Jamie Madillad9f24e2016-02-12 09:27:24 -05003331 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003332
3333 Box area(xoffset, yoffset, zoffset, width, height, depth);
3334 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003335 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003336 format, imageSize,
3337 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003338}
3339
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003340void Context::generateMipmap(GLenum target)
3341{
3342 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003343 handleError(texture->generateMipmap(this));
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003344}
3345
Geoff Lang97073d12016-04-20 10:42:34 -07003346void Context::copyTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003347 GLint sourceLevel,
3348 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003349 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003350 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003351 GLint internalFormat,
3352 GLenum destType,
3353 GLboolean unpackFlipY,
3354 GLboolean unpackPremultiplyAlpha,
3355 GLboolean unpackUnmultiplyAlpha)
3356{
3357 syncStateForTexImage();
3358
3359 gl::Texture *sourceTexture = getTexture(sourceId);
3360 gl::Texture *destTexture = getTexture(destId);
Geoff Langfc72a072017-03-24 14:52:39 -04003361 handleError(destTexture->copyTexture(
3362 this, destTarget, destLevel, internalFormat, destType, sourceLevel, unpackFlipY == GL_TRUE,
3363 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003364}
3365
3366void Context::copySubTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003367 GLint sourceLevel,
3368 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003369 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003370 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003371 GLint xoffset,
3372 GLint yoffset,
3373 GLint x,
3374 GLint y,
3375 GLsizei width,
3376 GLsizei height,
3377 GLboolean unpackFlipY,
3378 GLboolean unpackPremultiplyAlpha,
3379 GLboolean unpackUnmultiplyAlpha)
3380{
3381 // Zero sized copies are valid but no-ops
3382 if (width == 0 || height == 0)
3383 {
3384 return;
3385 }
3386
3387 syncStateForTexImage();
3388
3389 gl::Texture *sourceTexture = getTexture(sourceId);
3390 gl::Texture *destTexture = getTexture(destId);
3391 Offset offset(xoffset, yoffset, 0);
3392 Rectangle area(x, y, width, height);
Geoff Langfc72a072017-03-24 14:52:39 -04003393 handleError(destTexture->copySubTexture(
3394 this, destTarget, destLevel, offset, sourceLevel, area, unpackFlipY == GL_TRUE,
3395 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003396}
3397
Geoff Lang47110bf2016-04-20 11:13:22 -07003398void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3399{
3400 syncStateForTexImage();
3401
3402 gl::Texture *sourceTexture = getTexture(sourceId);
3403 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003404 handleError(destTexture->copyCompressedTexture(this, sourceTexture));
Geoff Lang47110bf2016-04-20 11:13:22 -07003405}
3406
Geoff Lang496c02d2016-10-20 11:38:11 -07003407void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003408{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003409 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003410 ASSERT(buffer);
3411
Geoff Lang496c02d2016-10-20 11:38:11 -07003412 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003413}
3414
Jamie Madill876429b2017-04-20 15:46:24 -04003415void *Context::mapBuffer(GLenum target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003416{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003417 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003418 ASSERT(buffer);
3419
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003420 Error error = buffer->map(this, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003421 if (error.isError())
3422 {
Jamie Madill437fa652016-05-03 15:13:24 -04003423 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003424 return nullptr;
3425 }
3426
3427 return buffer->getMapPointer();
3428}
3429
3430GLboolean Context::unmapBuffer(GLenum target)
3431{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003432 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003433 ASSERT(buffer);
3434
3435 GLboolean result;
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003436 Error error = buffer->unmap(this, &result);
Olli Etuaho4f667482016-03-30 15:56:35 +03003437 if (error.isError())
3438 {
Jamie Madill437fa652016-05-03 15:13:24 -04003439 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003440 return GL_FALSE;
3441 }
3442
3443 return result;
3444}
3445
Jamie Madill876429b2017-04-20 15:46:24 -04003446void *Context::mapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003447{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003448 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003449 ASSERT(buffer);
3450
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003451 Error error = buffer->mapRange(this, offset, length, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003452 if (error.isError())
3453 {
Jamie Madill437fa652016-05-03 15:13:24 -04003454 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003455 return nullptr;
3456 }
3457
3458 return buffer->getMapPointer();
3459}
3460
3461void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3462{
3463 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3464}
3465
Jamie Madillad9f24e2016-02-12 09:27:24 -05003466void Context::syncStateForReadPixels()
3467{
3468 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3469}
3470
3471void Context::syncStateForTexImage()
3472{
3473 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3474}
3475
3476void Context::syncStateForClear()
3477{
3478 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3479}
3480
3481void Context::syncStateForBlit()
3482{
3483 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3484}
3485
Jamie Madillc20ab272016-06-09 07:20:46 -07003486void Context::activeTexture(GLenum texture)
3487{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003488 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003489}
3490
Jamie Madill876429b2017-04-20 15:46:24 -04003491void Context::blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003492{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003493 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003494}
3495
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003496void Context::blendEquation(GLenum mode)
3497{
3498 mGLState.setBlendEquation(mode, mode);
3499}
3500
Jamie Madillc20ab272016-06-09 07:20:46 -07003501void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3502{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003503 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003504}
3505
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003506void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3507{
3508 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3509}
3510
Jamie Madillc20ab272016-06-09 07:20:46 -07003511void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3512{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003513 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003514}
3515
Jamie Madill876429b2017-04-20 15:46:24 -04003516void Context::clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003517{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003518 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003519}
3520
Jamie Madill876429b2017-04-20 15:46:24 -04003521void Context::clearDepthf(GLfloat depth)
Jamie Madillc20ab272016-06-09 07:20:46 -07003522{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003523 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003524}
3525
3526void Context::clearStencil(GLint s)
3527{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003528 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003529}
3530
3531void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3532{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003533 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003534}
3535
3536void Context::cullFace(GLenum mode)
3537{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003538 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003539}
3540
3541void Context::depthFunc(GLenum func)
3542{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003543 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003544}
3545
3546void Context::depthMask(GLboolean flag)
3547{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003548 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003549}
3550
Jamie Madill876429b2017-04-20 15:46:24 -04003551void Context::depthRangef(GLfloat zNear, GLfloat zFar)
Jamie Madillc20ab272016-06-09 07:20:46 -07003552{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003553 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003554}
3555
3556void Context::disable(GLenum cap)
3557{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003558 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003559}
3560
3561void Context::disableVertexAttribArray(GLuint index)
3562{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003563 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003564}
3565
3566void Context::enable(GLenum cap)
3567{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003568 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003569}
3570
3571void Context::enableVertexAttribArray(GLuint index)
3572{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003573 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003574}
3575
3576void Context::frontFace(GLenum mode)
3577{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003578 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003579}
3580
3581void Context::hint(GLenum target, GLenum mode)
3582{
3583 switch (target)
3584 {
3585 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003586 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003587 break;
3588
3589 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003590 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003591 break;
3592
3593 default:
3594 UNREACHABLE();
3595 return;
3596 }
3597}
3598
3599void Context::lineWidth(GLfloat width)
3600{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003601 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003602}
3603
3604void Context::pixelStorei(GLenum pname, GLint param)
3605{
3606 switch (pname)
3607 {
3608 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003609 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003610 break;
3611
3612 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003613 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003614 break;
3615
3616 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003617 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003618 break;
3619
3620 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003621 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003622 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003623 break;
3624
3625 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003626 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003627 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003628 break;
3629
3630 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003631 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003632 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003633 break;
3634
3635 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003636 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003637 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003638 break;
3639
3640 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003641 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003642 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003643 break;
3644
3645 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003646 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003647 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003648 break;
3649
3650 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003651 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003652 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003653 break;
3654
3655 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003656 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003657 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003658 break;
3659
3660 default:
3661 UNREACHABLE();
3662 return;
3663 }
3664}
3665
3666void Context::polygonOffset(GLfloat factor, GLfloat units)
3667{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003668 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003669}
3670
Jamie Madill876429b2017-04-20 15:46:24 -04003671void Context::sampleCoverage(GLfloat value, GLboolean invert)
Jamie Madillc20ab272016-06-09 07:20:46 -07003672{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003673 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003674}
3675
3676void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3677{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003678 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003679}
3680
3681void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3682{
3683 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3684 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003685 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003686 }
3687
3688 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3689 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003690 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003691 }
3692}
3693
3694void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3695{
3696 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3697 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003698 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003699 }
3700
3701 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3702 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003703 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003704 }
3705}
3706
3707void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3708{
3709 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3710 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003711 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003712 }
3713
3714 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3715 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003716 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003717 }
3718}
3719
3720void Context::vertexAttrib1f(GLuint index, GLfloat x)
3721{
3722 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003723 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003724}
3725
3726void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3727{
3728 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003729 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003730}
3731
3732void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3733{
3734 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003735 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003736}
3737
3738void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3739{
3740 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003741 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003742}
3743
3744void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3745{
3746 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003747 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003748}
3749
3750void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3751{
3752 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003753 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003754}
3755
3756void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3757{
3758 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003759 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003760}
3761
3762void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3763{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003764 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003765}
3766
3767void Context::vertexAttribPointer(GLuint index,
3768 GLint size,
3769 GLenum type,
3770 GLboolean normalized,
3771 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003772 const void *ptr)
Jamie Madillc20ab272016-06-09 07:20:46 -07003773{
Shaodde78e82017-05-22 14:13:27 +08003774 mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size,
3775 type, normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003776}
3777
Shao80957d92017-02-20 21:25:59 +08003778void Context::vertexAttribFormat(GLuint attribIndex,
3779 GLint size,
3780 GLenum type,
3781 GLboolean normalized,
3782 GLuint relativeOffset)
3783{
3784 mGLState.setVertexAttribFormat(attribIndex, size, type, normalized == GL_TRUE, false,
3785 relativeOffset);
3786}
3787
3788void Context::vertexAttribIFormat(GLuint attribIndex,
3789 GLint size,
3790 GLenum type,
3791 GLuint relativeOffset)
3792{
3793 mGLState.setVertexAttribFormat(attribIndex, size, type, false, true, relativeOffset);
3794}
3795
3796void Context::vertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
3797{
Shaodde78e82017-05-22 14:13:27 +08003798 mGLState.setVertexAttribBinding(this, attribIndex, bindingIndex);
Shao80957d92017-02-20 21:25:59 +08003799}
3800
3801void Context::setVertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
3802{
3803 mGLState.setVertexBindingDivisor(bindingIndex, divisor);
3804}
3805
Jamie Madillc20ab272016-06-09 07:20:46 -07003806void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3807{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003808 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003809}
3810
3811void Context::vertexAttribIPointer(GLuint index,
3812 GLint size,
3813 GLenum type,
3814 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003815 const void *pointer)
Jamie Madillc20ab272016-06-09 07:20:46 -07003816{
Shaodde78e82017-05-22 14:13:27 +08003817 mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size,
3818 type, false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003819}
3820
3821void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3822{
3823 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003824 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003825}
3826
3827void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3828{
3829 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003830 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003831}
3832
3833void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3834{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003835 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003836}
3837
3838void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3839{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003840 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003841}
3842
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003843void Context::getVertexAttribiv(GLuint index, GLenum pname, GLint *params)
3844{
3845 const VertexAttribCurrentValueData &currentValues =
3846 getGLState().getVertexAttribCurrentValue(index);
3847 const VertexArray *vao = getGLState().getVertexArray();
3848 QueryVertexAttribiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3849 currentValues, pname, params);
3850}
3851
3852void Context::getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
3853{
3854 const VertexAttribCurrentValueData &currentValues =
3855 getGLState().getVertexAttribCurrentValue(index);
3856 const VertexArray *vao = getGLState().getVertexArray();
3857 QueryVertexAttribfv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3858 currentValues, pname, params);
3859}
3860
3861void Context::getVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
3862{
3863 const VertexAttribCurrentValueData &currentValues =
3864 getGLState().getVertexAttribCurrentValue(index);
3865 const VertexArray *vao = getGLState().getVertexArray();
3866 QueryVertexAttribIiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3867 currentValues, pname, params);
3868}
3869
3870void Context::getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
3871{
3872 const VertexAttribCurrentValueData &currentValues =
3873 getGLState().getVertexAttribCurrentValue(index);
3874 const VertexArray *vao = getGLState().getVertexArray();
3875 QueryVertexAttribIuiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3876 currentValues, pname, params);
3877}
3878
Jamie Madill876429b2017-04-20 15:46:24 -04003879void Context::getVertexAttribPointerv(GLuint index, GLenum pname, void **pointer)
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003880{
3881 const VertexAttribute &attrib = getGLState().getVertexArray()->getVertexAttribute(index);
3882 QueryVertexAttribPointerv(attrib, pname, pointer);
3883}
3884
Jamie Madillc20ab272016-06-09 07:20:46 -07003885void Context::debugMessageControl(GLenum source,
3886 GLenum type,
3887 GLenum severity,
3888 GLsizei count,
3889 const GLuint *ids,
3890 GLboolean enabled)
3891{
3892 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003893 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3894 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003895}
3896
3897void Context::debugMessageInsert(GLenum source,
3898 GLenum type,
3899 GLuint id,
3900 GLenum severity,
3901 GLsizei length,
3902 const GLchar *buf)
3903{
3904 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003905 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003906}
3907
3908void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3909{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003910 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003911}
3912
3913GLuint Context::getDebugMessageLog(GLuint count,
3914 GLsizei bufSize,
3915 GLenum *sources,
3916 GLenum *types,
3917 GLuint *ids,
3918 GLenum *severities,
3919 GLsizei *lengths,
3920 GLchar *messageLog)
3921{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003922 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3923 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003924}
3925
3926void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3927{
3928 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003929 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003930}
3931
3932void Context::popDebugGroup()
3933{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003934 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003935}
3936
Jamie Madill876429b2017-04-20 15:46:24 -04003937void Context::bufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage)
Jamie Madill29639852016-09-02 15:00:09 -04003938{
3939 Buffer *buffer = mGLState.getTargetBuffer(target);
3940 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003941 handleError(buffer->bufferData(this, target, data, size, usage));
Jamie Madill29639852016-09-02 15:00:09 -04003942}
3943
Jamie Madill876429b2017-04-20 15:46:24 -04003944void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04003945{
3946 if (data == nullptr)
3947 {
3948 return;
3949 }
3950
3951 Buffer *buffer = mGLState.getTargetBuffer(target);
3952 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003953 handleError(buffer->bufferSubData(this, target, data, size, offset));
Jamie Madill29639852016-09-02 15:00:09 -04003954}
3955
Jamie Madillef300b12016-10-07 15:12:09 -04003956void Context::attachShader(GLuint program, GLuint shader)
3957{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003958 auto programObject = mState.mShaderPrograms->getProgram(program);
3959 auto shaderObject = mState.mShaderPrograms->getShader(shader);
Jamie Madillef300b12016-10-07 15:12:09 -04003960 ASSERT(programObject && shaderObject);
3961 programObject->attachShader(shaderObject);
3962}
3963
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003964const Workarounds &Context::getWorkarounds() const
3965{
3966 return mWorkarounds;
3967}
3968
Jamie Madillb0817d12016-11-01 15:48:31 -04003969void Context::copyBufferSubData(GLenum readTarget,
3970 GLenum writeTarget,
3971 GLintptr readOffset,
3972 GLintptr writeOffset,
3973 GLsizeiptr size)
3974{
3975 // if size is zero, the copy is a successful no-op
3976 if (size == 0)
3977 {
3978 return;
3979 }
3980
3981 // TODO(jmadill): cache these.
3982 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3983 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3984
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003985 handleError(writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size));
Jamie Madillb0817d12016-11-01 15:48:31 -04003986}
3987
Jamie Madill01a80ee2016-11-07 12:06:18 -05003988void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3989{
3990 Program *programObject = getProgram(program);
3991 // TODO(jmadill): Re-use this from the validation if possible.
3992 ASSERT(programObject);
3993 programObject->bindAttributeLocation(index, name);
3994}
3995
3996void Context::bindBuffer(GLenum target, GLuint buffer)
3997{
3998 switch (target)
3999 {
4000 case GL_ARRAY_BUFFER:
4001 bindArrayBuffer(buffer);
4002 break;
4003 case GL_ELEMENT_ARRAY_BUFFER:
4004 bindElementArrayBuffer(buffer);
4005 break;
4006 case GL_COPY_READ_BUFFER:
4007 bindCopyReadBuffer(buffer);
4008 break;
4009 case GL_COPY_WRITE_BUFFER:
4010 bindCopyWriteBuffer(buffer);
4011 break;
4012 case GL_PIXEL_PACK_BUFFER:
4013 bindPixelPackBuffer(buffer);
4014 break;
4015 case GL_PIXEL_UNPACK_BUFFER:
4016 bindPixelUnpackBuffer(buffer);
4017 break;
4018 case GL_UNIFORM_BUFFER:
4019 bindGenericUniformBuffer(buffer);
4020 break;
4021 case GL_TRANSFORM_FEEDBACK_BUFFER:
4022 bindGenericTransformFeedbackBuffer(buffer);
4023 break;
Geoff Lang3b573612016-10-31 14:08:10 -04004024 case GL_ATOMIC_COUNTER_BUFFER:
Jiajia Qin6eafb042016-12-27 17:04:07 +08004025 bindGenericAtomicCounterBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004026 break;
4027 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08004028 bindGenericShaderStorageBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004029 break;
4030 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08004031 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004032 break;
4033 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05004034 if (buffer != 0)
4035 {
4036 // Binding buffers to this binding point is not implemented yet.
4037 UNIMPLEMENTED();
4038 }
Geoff Lang3b573612016-10-31 14:08:10 -04004039 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05004040
4041 default:
4042 UNREACHABLE();
4043 break;
4044 }
4045}
4046
Jiajia Qin6eafb042016-12-27 17:04:07 +08004047void Context::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
4048{
4049 bindBufferRange(target, index, buffer, 0, 0);
4050}
4051
4052void Context::bindBufferRange(GLenum target,
4053 GLuint index,
4054 GLuint buffer,
4055 GLintptr offset,
4056 GLsizeiptr size)
4057{
4058 switch (target)
4059 {
4060 case GL_TRANSFORM_FEEDBACK_BUFFER:
4061 bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
4062 bindGenericTransformFeedbackBuffer(buffer);
4063 break;
4064 case GL_UNIFORM_BUFFER:
4065 bindIndexedUniformBuffer(buffer, index, offset, size);
4066 bindGenericUniformBuffer(buffer);
4067 break;
4068 case GL_ATOMIC_COUNTER_BUFFER:
4069 bindIndexedAtomicCounterBuffer(buffer, index, offset, size);
4070 bindGenericAtomicCounterBuffer(buffer);
4071 break;
4072 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08004073 bindIndexedShaderStorageBuffer(buffer, index, offset, size);
4074 bindGenericShaderStorageBuffer(buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08004075 break;
4076 default:
4077 UNREACHABLE();
4078 break;
4079 }
4080}
4081
Jamie Madill01a80ee2016-11-07 12:06:18 -05004082void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
4083{
4084 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4085 {
4086 bindReadFramebuffer(framebuffer);
4087 }
4088
4089 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4090 {
4091 bindDrawFramebuffer(framebuffer);
4092 }
4093}
4094
4095void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
4096{
4097 ASSERT(target == GL_RENDERBUFFER);
4098 Renderbuffer *object =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05004099 mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
Jamie Madill4928b7c2017-06-20 12:57:39 -04004100 mGLState.setRenderbufferBinding(this, object);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004101}
4102
JiangYizhoubddc46b2016-12-09 09:50:51 +08004103void Context::texStorage2DMultisample(GLenum target,
4104 GLsizei samples,
4105 GLenum internalformat,
4106 GLsizei width,
4107 GLsizei height,
4108 GLboolean fixedsamplelocations)
4109{
4110 Extents size(width, height, 1);
4111 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05004112 handleError(texture->setStorageMultisample(this, target, samples, internalformat, size,
JiangYizhoubddc46b2016-12-09 09:50:51 +08004113 fixedsamplelocations));
4114}
4115
4116void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
4117{
Jamie Madilldd43e6c2017-03-24 14:18:49 -04004118 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
JiangYizhoubddc46b2016-12-09 09:50:51 +08004119 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
4120
4121 switch (pname)
4122 {
4123 case GL_SAMPLE_POSITION:
4124 handleError(framebuffer->getSamplePosition(index, val));
4125 break;
4126 default:
4127 UNREACHABLE();
4128 }
4129}
4130
Jamie Madille8fb6402017-02-14 17:56:40 -05004131void Context::renderbufferStorage(GLenum target,
4132 GLenum internalformat,
4133 GLsizei width,
4134 GLsizei height)
4135{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004136 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4137 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
4138
Jamie Madille8fb6402017-02-14 17:56:40 -05004139 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4928b7c2017-06-20 12:57:39 -04004140 handleError(renderbuffer->setStorage(this, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004141}
4142
4143void Context::renderbufferStorageMultisample(GLenum target,
4144 GLsizei samples,
4145 GLenum internalformat,
4146 GLsizei width,
4147 GLsizei height)
4148{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004149 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4150 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
Jamie Madille8fb6402017-02-14 17:56:40 -05004151
4152 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004153 handleError(
Jamie Madill4928b7c2017-06-20 12:57:39 -04004154 renderbuffer->setStorageMultisample(this, samples, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004155}
4156
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004157void Context::getSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)
4158{
4159 const FenceSync *syncObject = getFenceSync(sync);
Geoff Lang82483b92017-04-11 15:33:00 -04004160 handleError(QuerySynciv(syncObject, pname, bufSize, length, values));
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004161}
4162
JiangYizhoue18e6392017-02-20 10:32:23 +08004163void Context::getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
4164{
4165 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4166 QueryFramebufferParameteriv(framebuffer, pname, params);
4167}
4168
4169void Context::setFramebufferParameteri(GLenum target, GLenum pname, GLint param)
4170{
4171 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4172 SetFramebufferParameteri(framebuffer, pname, param);
4173}
4174
Jamie Madillb3f26b92017-07-19 15:07:41 -04004175Error Context::getScratchBuffer(size_t requstedSizeBytes,
4176 angle::MemoryBuffer **scratchBufferOut) const
Jamie Madille14951e2017-03-09 18:55:16 -05004177{
Jamie Madillb3f26b92017-07-19 15:07:41 -04004178 if (!mScratchBuffer.get(requstedSizeBytes, scratchBufferOut))
4179 {
4180 return OutOfMemory() << "Failed to allocate internal buffer.";
4181 }
4182 return NoError();
4183}
4184
4185Error Context::getZeroFilledBuffer(size_t requstedSizeBytes,
4186 angle::MemoryBuffer **zeroBufferOut) const
4187{
4188 if (!mZeroFilledBuffer.getInitialized(requstedSizeBytes, zeroBufferOut, 0))
Jamie Madille14951e2017-03-09 18:55:16 -05004189 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004190 return OutOfMemory() << "Failed to allocate internal buffer.";
Jamie Madille14951e2017-03-09 18:55:16 -05004191 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004192 return NoError();
Jamie Madille14951e2017-03-09 18:55:16 -05004193}
4194
Xinghua Cao2b396592017-03-29 15:36:04 +08004195void Context::dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ)
4196{
4197 if (numGroupsX == 0u || numGroupsY == 0u || numGroupsZ == 0u)
4198 {
4199 return;
4200 }
4201
Jamie Madillfe548342017-06-19 11:13:24 -04004202 mImplementation->dispatchCompute(this, numGroupsX, numGroupsY, numGroupsZ);
Xinghua Cao2b396592017-03-29 15:36:04 +08004203}
4204
JiangYizhou165361c2017-06-07 14:56:57 +08004205void Context::texStorage2D(GLenum target,
4206 GLsizei levels,
4207 GLenum internalFormat,
4208 GLsizei width,
4209 GLsizei height)
4210{
4211 Extents size(width, height, 1);
4212 Texture *texture = getTargetTexture(target);
4213 handleError(texture->setStorage(this, target, levels, internalFormat, size));
4214}
4215
4216void Context::texStorage3D(GLenum target,
4217 GLsizei levels,
4218 GLenum internalFormat,
4219 GLsizei width,
4220 GLsizei height,
4221 GLsizei depth)
4222{
4223 Extents size(width, height, depth);
4224 Texture *texture = getTargetTexture(target);
4225 handleError(texture->setStorage(this, target, levels, internalFormat, size));
4226}
4227
Jamie Madillc1d770e2017-04-13 17:31:24 -04004228GLenum Context::checkFramebufferStatus(GLenum target)
4229{
4230 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4231 ASSERT(framebuffer);
4232
4233 return framebuffer->checkStatus(this);
4234}
4235
4236void Context::compileShader(GLuint shader)
4237{
4238 Shader *shaderObject = GetValidShader(this, shader);
4239 if (!shaderObject)
4240 {
4241 return;
4242 }
4243 shaderObject->compile(this);
4244}
4245
4246void Context::deleteBuffers(GLsizei n, const GLuint *buffers)
4247{
4248 for (int i = 0; i < n; i++)
4249 {
4250 deleteBuffer(buffers[i]);
4251 }
4252}
4253
4254void Context::deleteFramebuffers(GLsizei n, const GLuint *framebuffers)
4255{
4256 for (int i = 0; i < n; i++)
4257 {
4258 if (framebuffers[i] != 0)
4259 {
4260 deleteFramebuffer(framebuffers[i]);
4261 }
4262 }
4263}
4264
4265void Context::deleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)
4266{
4267 for (int i = 0; i < n; i++)
4268 {
4269 deleteRenderbuffer(renderbuffers[i]);
4270 }
4271}
4272
4273void Context::deleteTextures(GLsizei n, const GLuint *textures)
4274{
4275 for (int i = 0; i < n; i++)
4276 {
4277 if (textures[i] != 0)
4278 {
4279 deleteTexture(textures[i]);
4280 }
4281 }
4282}
4283
4284void Context::detachShader(GLuint program, GLuint shader)
4285{
4286 Program *programObject = getProgram(program);
4287 ASSERT(programObject);
4288
4289 Shader *shaderObject = getShader(shader);
4290 ASSERT(shaderObject);
4291
4292 programObject->detachShader(this, shaderObject);
4293}
4294
4295void Context::genBuffers(GLsizei n, GLuint *buffers)
4296{
4297 for (int i = 0; i < n; i++)
4298 {
4299 buffers[i] = createBuffer();
4300 }
4301}
4302
4303void Context::genFramebuffers(GLsizei n, GLuint *framebuffers)
4304{
4305 for (int i = 0; i < n; i++)
4306 {
4307 framebuffers[i] = createFramebuffer();
4308 }
4309}
4310
4311void Context::genRenderbuffers(GLsizei n, GLuint *renderbuffers)
4312{
4313 for (int i = 0; i < n; i++)
4314 {
4315 renderbuffers[i] = createRenderbuffer();
4316 }
4317}
4318
4319void Context::genTextures(GLsizei n, GLuint *textures)
4320{
4321 for (int i = 0; i < n; i++)
4322 {
4323 textures[i] = createTexture();
4324 }
4325}
4326
4327void Context::getActiveAttrib(GLuint program,
4328 GLuint index,
4329 GLsizei bufsize,
4330 GLsizei *length,
4331 GLint *size,
4332 GLenum *type,
4333 GLchar *name)
4334{
4335 Program *programObject = getProgram(program);
4336 ASSERT(programObject);
4337 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
4338}
4339
4340void Context::getActiveUniform(GLuint program,
4341 GLuint index,
4342 GLsizei bufsize,
4343 GLsizei *length,
4344 GLint *size,
4345 GLenum *type,
4346 GLchar *name)
4347{
4348 Program *programObject = getProgram(program);
4349 ASSERT(programObject);
4350 programObject->getActiveUniform(index, bufsize, length, size, type, name);
4351}
4352
4353void Context::getAttachedShaders(GLuint program, GLsizei maxcount, GLsizei *count, GLuint *shaders)
4354{
4355 Program *programObject = getProgram(program);
4356 ASSERT(programObject);
4357 programObject->getAttachedShaders(maxcount, count, shaders);
4358}
4359
4360GLint Context::getAttribLocation(GLuint program, const GLchar *name)
4361{
4362 Program *programObject = getProgram(program);
4363 ASSERT(programObject);
4364 return programObject->getAttributeLocation(name);
4365}
4366
4367void Context::getBooleanv(GLenum pname, GLboolean *params)
4368{
4369 GLenum nativeType;
4370 unsigned int numParams = 0;
4371 getQueryParameterInfo(pname, &nativeType, &numParams);
4372
4373 if (nativeType == GL_BOOL)
4374 {
4375 getBooleanvImpl(pname, params);
4376 }
4377 else
4378 {
4379 CastStateValues(this, nativeType, pname, numParams, params);
4380 }
4381}
4382
4383void Context::getFloatv(GLenum pname, GLfloat *params)
4384{
4385 GLenum nativeType;
4386 unsigned int numParams = 0;
4387 getQueryParameterInfo(pname, &nativeType, &numParams);
4388
4389 if (nativeType == GL_FLOAT)
4390 {
4391 getFloatvImpl(pname, params);
4392 }
4393 else
4394 {
4395 CastStateValues(this, nativeType, pname, numParams, params);
4396 }
4397}
4398
4399void Context::getIntegerv(GLenum pname, GLint *params)
4400{
4401 GLenum nativeType;
4402 unsigned int numParams = 0;
4403 getQueryParameterInfo(pname, &nativeType, &numParams);
4404
4405 if (nativeType == GL_INT)
4406 {
4407 getIntegervImpl(pname, params);
4408 }
4409 else
4410 {
4411 CastStateValues(this, nativeType, pname, numParams, params);
4412 }
4413}
4414
4415void Context::getProgramiv(GLuint program, GLenum pname, GLint *params)
4416{
4417 Program *programObject = getProgram(program);
4418 ASSERT(programObject);
Jamie Madillffe00c02017-06-27 16:26:55 -04004419 QueryProgramiv(this, programObject, pname, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004420}
4421
Jamie Madillbe849e42017-05-02 15:49:00 -04004422void Context::getProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei *length, GLchar *infolog)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004423{
4424 Program *programObject = getProgram(program);
4425 ASSERT(programObject);
4426 programObject->getInfoLog(bufsize, length, infolog);
4427}
4428
4429void Context::getShaderiv(GLuint shader, GLenum pname, GLint *params)
4430{
4431 Shader *shaderObject = getShader(shader);
4432 ASSERT(shaderObject);
Jamie Madillbd044ed2017-06-05 12:59:21 -04004433 QueryShaderiv(this, shaderObject, pname, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004434}
4435
4436void Context::getShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *infolog)
4437{
4438 Shader *shaderObject = getShader(shader);
4439 ASSERT(shaderObject);
Jamie Madillbd044ed2017-06-05 12:59:21 -04004440 shaderObject->getInfoLog(this, bufsize, length, infolog);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004441}
4442
4443void Context::getShaderPrecisionFormat(GLenum shadertype,
4444 GLenum precisiontype,
4445 GLint *range,
4446 GLint *precision)
4447{
4448 // TODO(jmadill): Compute shaders.
4449
4450 switch (shadertype)
4451 {
4452 case GL_VERTEX_SHADER:
4453 switch (precisiontype)
4454 {
4455 case GL_LOW_FLOAT:
4456 mCaps.vertexLowpFloat.get(range, precision);
4457 break;
4458 case GL_MEDIUM_FLOAT:
4459 mCaps.vertexMediumpFloat.get(range, precision);
4460 break;
4461 case GL_HIGH_FLOAT:
4462 mCaps.vertexHighpFloat.get(range, precision);
4463 break;
4464
4465 case GL_LOW_INT:
4466 mCaps.vertexLowpInt.get(range, precision);
4467 break;
4468 case GL_MEDIUM_INT:
4469 mCaps.vertexMediumpInt.get(range, precision);
4470 break;
4471 case GL_HIGH_INT:
4472 mCaps.vertexHighpInt.get(range, precision);
4473 break;
4474
4475 default:
4476 UNREACHABLE();
4477 return;
4478 }
4479 break;
4480
4481 case GL_FRAGMENT_SHADER:
4482 switch (precisiontype)
4483 {
4484 case GL_LOW_FLOAT:
4485 mCaps.fragmentLowpFloat.get(range, precision);
4486 break;
4487 case GL_MEDIUM_FLOAT:
4488 mCaps.fragmentMediumpFloat.get(range, precision);
4489 break;
4490 case GL_HIGH_FLOAT:
4491 mCaps.fragmentHighpFloat.get(range, precision);
4492 break;
4493
4494 case GL_LOW_INT:
4495 mCaps.fragmentLowpInt.get(range, precision);
4496 break;
4497 case GL_MEDIUM_INT:
4498 mCaps.fragmentMediumpInt.get(range, precision);
4499 break;
4500 case GL_HIGH_INT:
4501 mCaps.fragmentHighpInt.get(range, precision);
4502 break;
4503
4504 default:
4505 UNREACHABLE();
4506 return;
4507 }
4508 break;
4509
4510 default:
4511 UNREACHABLE();
4512 return;
4513 }
4514}
4515
4516void Context::getShaderSource(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source)
4517{
4518 Shader *shaderObject = getShader(shader);
4519 ASSERT(shaderObject);
4520 shaderObject->getSource(bufsize, length, source);
4521}
4522
4523void Context::getUniformfv(GLuint program, GLint location, GLfloat *params)
4524{
4525 Program *programObject = getProgram(program);
4526 ASSERT(programObject);
4527 programObject->getUniformfv(location, params);
4528}
4529
4530void Context::getUniformiv(GLuint program, GLint location, GLint *params)
4531{
4532 Program *programObject = getProgram(program);
4533 ASSERT(programObject);
4534 programObject->getUniformiv(location, params);
4535}
4536
4537GLint Context::getUniformLocation(GLuint program, const GLchar *name)
4538{
4539 Program *programObject = getProgram(program);
4540 ASSERT(programObject);
4541 return programObject->getUniformLocation(name);
4542}
4543
4544GLboolean Context::isBuffer(GLuint buffer)
4545{
4546 if (buffer == 0)
4547 {
4548 return GL_FALSE;
4549 }
4550
4551 return (getBuffer(buffer) ? GL_TRUE : GL_FALSE);
4552}
4553
4554GLboolean Context::isEnabled(GLenum cap)
4555{
4556 return mGLState.getEnableFeature(cap);
4557}
4558
4559GLboolean Context::isFramebuffer(GLuint framebuffer)
4560{
4561 if (framebuffer == 0)
4562 {
4563 return GL_FALSE;
4564 }
4565
4566 return (getFramebuffer(framebuffer) ? GL_TRUE : GL_FALSE);
4567}
4568
4569GLboolean Context::isProgram(GLuint program)
4570{
4571 if (program == 0)
4572 {
4573 return GL_FALSE;
4574 }
4575
4576 return (getProgram(program) ? GL_TRUE : GL_FALSE);
4577}
4578
4579GLboolean Context::isRenderbuffer(GLuint renderbuffer)
4580{
4581 if (renderbuffer == 0)
4582 {
4583 return GL_FALSE;
4584 }
4585
4586 return (getRenderbuffer(renderbuffer) ? GL_TRUE : GL_FALSE);
4587}
4588
4589GLboolean Context::isShader(GLuint shader)
4590{
4591 if (shader == 0)
4592 {
4593 return GL_FALSE;
4594 }
4595
4596 return (getShader(shader) ? GL_TRUE : GL_FALSE);
4597}
4598
4599GLboolean Context::isTexture(GLuint texture)
4600{
4601 if (texture == 0)
4602 {
4603 return GL_FALSE;
4604 }
4605
4606 return (getTexture(texture) ? GL_TRUE : GL_FALSE);
4607}
4608
4609void Context::linkProgram(GLuint program)
4610{
4611 Program *programObject = getProgram(program);
4612 ASSERT(programObject);
4613 handleError(programObject->link(this));
4614}
4615
4616void Context::releaseShaderCompiler()
4617{
Jamie Madill4928b7c2017-06-20 12:57:39 -04004618 mCompiler.set(this, nullptr);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004619}
4620
4621void Context::shaderBinary(GLsizei n,
4622 const GLuint *shaders,
4623 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04004624 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004625 GLsizei length)
4626{
4627 // No binary shader formats are supported.
4628 UNIMPLEMENTED();
4629}
4630
4631void Context::shaderSource(GLuint shader,
4632 GLsizei count,
4633 const GLchar *const *string,
4634 const GLint *length)
4635{
4636 Shader *shaderObject = getShader(shader);
4637 ASSERT(shaderObject);
4638 shaderObject->setSource(count, string, length);
4639}
4640
4641void Context::stencilFunc(GLenum func, GLint ref, GLuint mask)
4642{
4643 stencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
4644}
4645
4646void Context::stencilMask(GLuint mask)
4647{
4648 stencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4649}
4650
4651void Context::stencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4652{
4653 stencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4654}
4655
4656void Context::uniform1f(GLint location, GLfloat x)
4657{
4658 Program *program = mGLState.getProgram();
4659 program->setUniform1fv(location, 1, &x);
4660}
4661
4662void Context::uniform1fv(GLint location, GLsizei count, const GLfloat *v)
4663{
4664 Program *program = mGLState.getProgram();
4665 program->setUniform1fv(location, count, v);
4666}
4667
4668void Context::uniform1i(GLint location, GLint x)
4669{
4670 Program *program = mGLState.getProgram();
4671 program->setUniform1iv(location, 1, &x);
4672}
4673
4674void Context::uniform1iv(GLint location, GLsizei count, const GLint *v)
4675{
4676 Program *program = mGLState.getProgram();
4677 program->setUniform1iv(location, count, v);
4678}
4679
4680void Context::uniform2f(GLint location, GLfloat x, GLfloat y)
4681{
4682 GLfloat xy[2] = {x, y};
4683 Program *program = mGLState.getProgram();
4684 program->setUniform2fv(location, 1, xy);
4685}
4686
4687void Context::uniform2fv(GLint location, GLsizei count, const GLfloat *v)
4688{
4689 Program *program = mGLState.getProgram();
4690 program->setUniform2fv(location, count, v);
4691}
4692
4693void Context::uniform2i(GLint location, GLint x, GLint y)
4694{
4695 GLint xy[2] = {x, y};
4696 Program *program = mGLState.getProgram();
4697 program->setUniform2iv(location, 1, xy);
4698}
4699
4700void Context::uniform2iv(GLint location, GLsizei count, const GLint *v)
4701{
4702 Program *program = mGLState.getProgram();
4703 program->setUniform2iv(location, count, v);
4704}
4705
4706void Context::uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4707{
4708 GLfloat xyz[3] = {x, y, z};
4709 Program *program = mGLState.getProgram();
4710 program->setUniform3fv(location, 1, xyz);
4711}
4712
4713void Context::uniform3fv(GLint location, GLsizei count, const GLfloat *v)
4714{
4715 Program *program = mGLState.getProgram();
4716 program->setUniform3fv(location, count, v);
4717}
4718
4719void Context::uniform3i(GLint location, GLint x, GLint y, GLint z)
4720{
4721 GLint xyz[3] = {x, y, z};
4722 Program *program = mGLState.getProgram();
4723 program->setUniform3iv(location, 1, xyz);
4724}
4725
4726void Context::uniform3iv(GLint location, GLsizei count, const GLint *v)
4727{
4728 Program *program = mGLState.getProgram();
4729 program->setUniform3iv(location, count, v);
4730}
4731
4732void Context::uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4733{
4734 GLfloat xyzw[4] = {x, y, z, w};
4735 Program *program = mGLState.getProgram();
4736 program->setUniform4fv(location, 1, xyzw);
4737}
4738
4739void Context::uniform4fv(GLint location, GLsizei count, const GLfloat *v)
4740{
4741 Program *program = mGLState.getProgram();
4742 program->setUniform4fv(location, count, v);
4743}
4744
4745void Context::uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4746{
4747 GLint xyzw[4] = {x, y, z, w};
4748 Program *program = mGLState.getProgram();
4749 program->setUniform4iv(location, 1, xyzw);
4750}
4751
4752void Context::uniform4iv(GLint location, GLsizei count, const GLint *v)
4753{
4754 Program *program = mGLState.getProgram();
4755 program->setUniform4iv(location, count, v);
4756}
4757
4758void Context::uniformMatrix2fv(GLint location,
4759 GLsizei count,
4760 GLboolean transpose,
4761 const GLfloat *value)
4762{
4763 Program *program = mGLState.getProgram();
4764 program->setUniformMatrix2fv(location, count, transpose, value);
4765}
4766
4767void Context::uniformMatrix3fv(GLint location,
4768 GLsizei count,
4769 GLboolean transpose,
4770 const GLfloat *value)
4771{
4772 Program *program = mGLState.getProgram();
4773 program->setUniformMatrix3fv(location, count, transpose, value);
4774}
4775
4776void Context::uniformMatrix4fv(GLint location,
4777 GLsizei count,
4778 GLboolean transpose,
4779 const GLfloat *value)
4780{
4781 Program *program = mGLState.getProgram();
4782 program->setUniformMatrix4fv(location, count, transpose, value);
4783}
4784
4785void Context::validateProgram(GLuint program)
4786{
4787 Program *programObject = getProgram(program);
4788 ASSERT(programObject);
4789 programObject->validate(mCaps);
4790}
4791
Jamie Madilld04908b2017-06-09 14:15:35 -04004792void Context::getProgramBinary(GLuint program,
4793 GLsizei bufSize,
4794 GLsizei *length,
4795 GLenum *binaryFormat,
4796 void *binary)
4797{
4798 Program *programObject = getProgram(program);
4799 ASSERT(programObject != nullptr);
4800
4801 handleError(programObject->saveBinary(this, binaryFormat, binary, bufSize, length));
4802}
4803
4804void Context::programBinary(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length)
4805{
4806 Program *programObject = getProgram(program);
4807 ASSERT(programObject != nullptr);
4808
4809 handleError(programObject->loadBinary(this, binaryFormat, binary, length));
4810}
4811
Jamie Madillc29968b2016-01-20 11:17:23 -05004812} // namespace gl