blob: d255bd887985aadf38a74d5309ed046844772973 [file] [log] [blame]
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001//
Geoff Langeeba6e12014-02-03 13:12:30 -05002// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// Context.cpp: Implements the gl::Context class, managing all GL state and performing
8// rendering operations. It is the GLES2 specific implementation of EGLContext.
9
Geoff Lang2b5420c2014-11-19 14:20:15 -050010#include "libANGLE/Context.h"
apatrick@chromium.org144f2802012-07-12 01:42:34 +000011
Jamie Madill231c7f52017-04-26 13:45:37 -040012#include <string.h>
Jamie Madillb9293972015-02-19 11:07:54 -050013#include <iterator>
14#include <sstream>
Sami Väisänend59ca052016-06-21 16:10:00 +030015#include <vector>
Jamie Madillb9293972015-02-19 11:07:54 -050016
Sami Väisänene45e53b2016-05-25 10:36:04 +030017#include "common/matrix_utils.h"
Geoff Lang0b7eef72014-06-12 14:10:47 -040018#include "common/platform.h"
Jamie Madillb9293972015-02-19 11:07:54 -050019#include "common/utilities.h"
Geoff Langc339c4e2016-11-29 10:37:36 -050020#include "common/version.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050021#include "libANGLE/Buffer.h"
Jamie Madillb9293972015-02-19 11:07:54 -050022#include "libANGLE/Compiler.h"
Jamie Madill948bbe52017-06-01 13:10:42 -040023#include "libANGLE/Display.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050024#include "libANGLE/Fence.h"
25#include "libANGLE/Framebuffer.h"
26#include "libANGLE/FramebufferAttachment.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030027#include "libANGLE/Path.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050028#include "libANGLE/Program.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050029#include "libANGLE/Query.h"
Jamie Madillb9293972015-02-19 11:07:54 -050030#include "libANGLE/Renderbuffer.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050031#include "libANGLE/ResourceManager.h"
32#include "libANGLE/Sampler.h"
Jamie Madill9dd0cf02014-11-24 11:38:51 -050033#include "libANGLE/Surface.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050034#include "libANGLE/Texture.h"
35#include "libANGLE/TransformFeedback.h"
36#include "libANGLE/VertexArray.h"
Kenneth Russellf2f6f652016-10-05 19:53:23 -070037#include "libANGLE/Workarounds.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040038#include "libANGLE/formatutils.h"
Martin Radev66fb8202016-07-28 11:45:20 +030039#include "libANGLE/queryconversions.h"
Geoff Langc1984ed2016-10-07 12:41:00 -040040#include "libANGLE/queryutils.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040041#include "libANGLE/renderer/ContextImpl.h"
42#include "libANGLE/renderer/EGLImplFactory.h"
43#include "libANGLE/validationES.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000044
Geoff Langf6db0982015-08-25 13:04:00 -040045namespace
46{
47
Ian Ewell3ffd78b2016-01-22 16:09:42 -050048template <typename T>
Geoff Lang4ddf5af2016-12-01 14:30:44 -050049std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
Sami Väisänend59ca052016-06-21 16:10:00 +030050 GLsizei numPaths,
51 const void *paths,
52 GLuint pathBase)
53{
54 std::vector<gl::Path *> ret;
55 ret.reserve(numPaths);
56
57 const auto *nameArray = static_cast<const T *>(paths);
58
59 for (GLsizei i = 0; i < numPaths; ++i)
60 {
61 const GLuint pathName = nameArray[i] + pathBase;
62
63 ret.push_back(resourceManager.getPath(pathName));
64 }
65
66 return ret;
67}
68
Geoff Lang4ddf5af2016-12-01 14:30:44 -050069std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
Sami Väisänend59ca052016-06-21 16:10:00 +030070 GLsizei numPaths,
71 GLenum pathNameType,
72 const void *paths,
73 GLuint pathBase)
74{
75 switch (pathNameType)
76 {
77 case GL_UNSIGNED_BYTE:
78 return GatherPaths<GLubyte>(resourceManager, numPaths, paths, pathBase);
79
80 case GL_BYTE:
81 return GatherPaths<GLbyte>(resourceManager, numPaths, paths, pathBase);
82
83 case GL_UNSIGNED_SHORT:
84 return GatherPaths<GLushort>(resourceManager, numPaths, paths, pathBase);
85
86 case GL_SHORT:
87 return GatherPaths<GLshort>(resourceManager, numPaths, paths, pathBase);
88
89 case GL_UNSIGNED_INT:
90 return GatherPaths<GLuint>(resourceManager, numPaths, paths, pathBase);
91
92 case GL_INT:
93 return GatherPaths<GLint>(resourceManager, numPaths, paths, pathBase);
94 }
95
96 UNREACHABLE();
97 return std::vector<gl::Path *>();
98}
99
100template <typename T>
Geoff Lang2186c382016-10-14 10:54:54 -0400101gl::Error GetQueryObjectParameter(gl::Query *query, GLenum pname, T *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500102{
Geoff Lang2186c382016-10-14 10:54:54 -0400103 ASSERT(query != nullptr);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500104
105 switch (pname)
106 {
107 case GL_QUERY_RESULT_EXT:
Geoff Lang2186c382016-10-14 10:54:54 -0400108 return query->getResult(params);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500109 case GL_QUERY_RESULT_AVAILABLE_EXT:
110 {
111 bool available;
Geoff Lang2186c382016-10-14 10:54:54 -0400112 gl::Error error = query->isResultAvailable(&available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500113 if (!error.isError())
114 {
Geoff Lang2186c382016-10-14 10:54:54 -0400115 *params = gl::ConvertFromGLboolean<T>(available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500116 }
117 return error;
118 }
119 default:
120 UNREACHABLE();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500121 return gl::InternalError() << "Unreachable Error";
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500122 }
123}
124
Geoff Langf6db0982015-08-25 13:04:00 -0400125void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback)
126{
Geoff Lang1a683462015-09-29 15:09:59 -0400127 if (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
Geoff Langf6db0982015-08-25 13:04:00 -0400128 {
129 for (size_t tfBufferIndex = 0; tfBufferIndex < transformFeedback->getIndexedBufferCount();
130 tfBufferIndex++)
131 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400132 const gl::OffsetBindingPointer<gl::Buffer> &buffer =
Geoff Langf6db0982015-08-25 13:04:00 -0400133 transformFeedback->getIndexedBuffer(tfBufferIndex);
134 if (buffer.get() != nullptr)
135 {
136 buffer->onTransformFeedback();
137 }
138 }
139 }
140}
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500141
142// Attribute map queries.
Martin Radev1be913c2016-07-11 17:59:16 +0300143EGLint GetClientMajorVersion(const egl::AttributeMap &attribs)
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500144{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400145 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1));
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500146}
147
Martin Radev1be913c2016-07-11 17:59:16 +0300148EGLint GetClientMinorVersion(const egl::AttributeMap &attribs)
149{
150 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_MINOR_VERSION, 0));
151}
152
Geoff Langeb66a6e2016-10-31 13:06:12 -0400153gl::Version GetClientVersion(const egl::AttributeMap &attribs)
154{
155 return gl::Version(GetClientMajorVersion(attribs), GetClientMinorVersion(attribs));
156}
157
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500158GLenum GetResetStrategy(const egl::AttributeMap &attribs)
159{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400160 EGLAttrib attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
161 EGL_NO_RESET_NOTIFICATION_EXT);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500162 switch (attrib)
163 {
164 case EGL_NO_RESET_NOTIFICATION:
165 return GL_NO_RESET_NOTIFICATION_EXT;
166 case EGL_LOSE_CONTEXT_ON_RESET:
167 return GL_LOSE_CONTEXT_ON_RESET_EXT;
168 default:
169 UNREACHABLE();
170 return GL_NONE;
171 }
172}
173
174bool GetRobustAccess(const egl::AttributeMap &attribs)
175{
Geoff Lang077f20a2016-11-01 10:08:02 -0400176 return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE) ||
177 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) !=
178 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500179}
180
181bool GetDebug(const egl::AttributeMap &attribs)
182{
Geoff Lang077f20a2016-11-01 10:08:02 -0400183 return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE) ||
184 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR) != 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500185}
186
187bool GetNoError(const egl::AttributeMap &attribs)
188{
189 return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
190}
191
Geoff Langc287ea62016-09-16 14:46:51 -0400192bool GetWebGLContext(const egl::AttributeMap &attribs)
193{
194 return (attribs.get(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE, EGL_FALSE) == EGL_TRUE);
195}
196
Geoff Langf41a7152016-09-19 15:11:17 -0400197bool GetBindGeneratesResource(const egl::AttributeMap &attribs)
198{
199 return (attribs.get(EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE) == EGL_TRUE);
200}
201
Geoff Langfeb8c682017-02-13 16:07:35 -0500202bool GetClientArraysEnabled(const egl::AttributeMap &attribs)
203{
204 return (attribs.get(EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE, EGL_TRUE) == EGL_TRUE);
205}
206
Martin Radev9d901792016-07-15 15:58:58 +0300207std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
208{
209 std::string labelName;
210 if (label != nullptr)
211 {
212 size_t labelLength = length < 0 ? strlen(label) : length;
213 labelName = std::string(label, labelLength);
214 }
215 return labelName;
216}
217
218void GetObjectLabelBase(const std::string &objectLabel,
219 GLsizei bufSize,
220 GLsizei *length,
221 GLchar *label)
222{
223 size_t writeLength = objectLabel.length();
224 if (label != nullptr && bufSize > 0)
225 {
226 writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
227 std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
228 label[writeLength] = '\0';
229 }
230
231 if (length != nullptr)
232 {
233 *length = static_cast<GLsizei>(writeLength);
234 }
235}
236
Geoff Langf6db0982015-08-25 13:04:00 -0400237} // anonymous namespace
238
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000239namespace gl
240{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000241
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400242Context::Context(rx::EGLImplFactory *implFactory,
243 const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400244 const Context *shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500245 TextureManager *shareTextures,
Jamie Madill32447362017-06-28 14:53:52 -0400246 MemoryProgramCache *memoryProgramCache,
Corentin Wallezc295e512017-01-27 17:47:50 -0500247 const egl::AttributeMap &attribs,
Jamie Madill948bbe52017-06-01 13:10:42 -0400248 const egl::DisplayExtensions &displayExtensions,
249 bool robustResourceInit)
Martin Radev1be913c2016-07-11 17:59:16 +0300250
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500251 : ValidationContext(shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500252 shareTextures,
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500253 GetClientVersion(attribs),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700254 &mGLState,
Jamie Madillf25855c2015-11-03 11:06:18 -0500255 mCaps,
256 mTextureCaps,
257 mExtensions,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500258 mLimitations,
259 GetNoError(attribs)),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700260 mImplementation(implFactory->createContext(mState)),
Jamie Madill2f348d22017-06-05 10:50:59 -0400261 mCompiler(),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400262 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500263 mClientType(EGL_OPENGL_ES_API),
264 mHasBeenCurrent(false),
265 mContextLost(false),
266 mResetStatus(GL_NO_ERROR),
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700267 mContextLostForced(false),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500268 mResetStrategy(GetResetStrategy(attribs)),
269 mRobustAccess(GetRobustAccess(attribs)),
Jamie Madill61e16b42017-06-19 11:13:23 -0400270 mCurrentSurface(static_cast<egl::Surface *>(EGL_NO_SURFACE)),
271 mCurrentDisplay(static_cast<egl::Display *>(EGL_NO_DISPLAY)),
Jamie Madill4e0e6f82017-02-17 11:06:03 -0500272 mSurfacelessFramebuffer(nullptr),
Jamie Madille14951e2017-03-09 18:55:16 -0500273 mWebGLContext(GetWebGLContext(attribs)),
Jamie Madill32447362017-06-28 14:53:52 -0400274 mMemoryProgramCache(memoryProgramCache),
Jamie Madille14951e2017-03-09 18:55:16 -0500275 mScratchBuffer(1000u)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000276{
Geoff Lang077f20a2016-11-01 10:08:02 -0400277 if (mRobustAccess)
278 {
279 UNIMPLEMENTED();
280 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000281
Jamie Madill4e0e6f82017-02-17 11:06:03 -0500282 initCaps(displayExtensions);
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700283 initWorkarounds();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400284
Jamie Madill4928b7c2017-06-20 12:57:39 -0400285 mGLState.initialize(this, GetDebug(attribs), GetBindGeneratesResource(attribs),
Jamie Madillc43be722017-07-13 16:22:14 -0400286 GetClientArraysEnabled(attribs), robustResourceInit,
287 mMemoryProgramCache != nullptr);
Régis Fénéon83107972015-02-05 12:57:44 +0100288
Shannon Woods53a94a82014-06-24 15:20:36 -0400289 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400290
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000291 // [OpenGL ES 2.0.24] section 3.7 page 83:
292 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
293 // and cube map texture state vectors respectively associated with them.
294 // In order that access to these initial textures not be lost, they are treated as texture
295 // objects all of whose names are 0.
296
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400297 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400298 mZeroTextures[GL_TEXTURE_2D].set(this, zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500299
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400300 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400301 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(this, zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400302
Geoff Langeb66a6e2016-10-31 13:06:12 -0400303 if (getClientVersion() >= Version(3, 0))
Geoff Lang76b10c92014-09-05 16:28:14 -0400304 {
305 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400306 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400307 mZeroTextures[GL_TEXTURE_3D].set(this, zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400308
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400309 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400310 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(this, zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400311 }
Geoff Lang3b573612016-10-31 14:08:10 -0400312 if (getClientVersion() >= Version(3, 1))
313 {
314 Texture *zeroTexture2DMultisample =
315 new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_MULTISAMPLE);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400316 mZeroTextures[GL_TEXTURE_2D_MULTISAMPLE].set(this, zeroTexture2DMultisample);
Jiajia Qin6eafb042016-12-27 17:04:07 +0800317
318 bindGenericAtomicCounterBuffer(0);
319 for (unsigned int i = 0; i < mCaps.maxAtomicCounterBufferBindings; i++)
320 {
321 bindIndexedAtomicCounterBuffer(0, i, 0, 0);
322 }
Jiajia Qinf546e7d2017-03-27 14:12:59 +0800323
324 bindGenericShaderStorageBuffer(0);
325 for (unsigned int i = 0; i < mCaps.maxShaderStorageBufferBindings; i++)
326 {
327 bindIndexedShaderStorageBuffer(0, i, 0, 0);
328 }
Geoff Lang3b573612016-10-31 14:08:10 -0400329 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000330
Ian Ewellbda75592016-04-18 17:25:54 -0400331 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
332 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400333 Texture *zeroTextureExternal =
334 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400335 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(this, zeroTextureExternal);
Ian Ewellbda75592016-04-18 17:25:54 -0400336 }
337
Jamie Madill4928b7c2017-06-20 12:57:39 -0400338 mGLState.initializeZeroTextures(this, mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500339
Jamie Madill57a89722013-07-02 11:57:03 -0400340 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000341 bindArrayBuffer(0);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800342 bindDrawIndirectBuffer(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000343 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400344
Jamie Madill01a80ee2016-11-07 12:06:18 -0500345 bindRenderbuffer(GL_RENDERBUFFER, 0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000346
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000347 bindGenericUniformBuffer(0);
Geoff Lang4dc3af02016-11-18 14:09:27 -0500348 for (unsigned int i = 0; i < mCaps.maxUniformBufferBindings; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000349 {
350 bindIndexedUniformBuffer(0, i, 0, -1);
351 }
352
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000353 bindCopyReadBuffer(0);
354 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000355 bindPixelPackBuffer(0);
356 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000357
Geoff Langeb66a6e2016-10-31 13:06:12 -0400358 if (getClientVersion() >= Version(3, 0))
Geoff Lang1a683462015-09-29 15:09:59 -0400359 {
360 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
361 // In the initial state, a default transform feedback object is bound and treated as
362 // a transform feedback object with a name of zero. That object is bound any time
363 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400364 bindTransformFeedback(0);
365 }
Geoff Langc8058452014-02-03 12:04:11 -0500366
Jamie Madillad9f24e2016-02-12 09:27:24 -0500367 // Initialize dirty bit masks
368 // TODO(jmadill): additional ES3 state
369 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
370 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
371 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
372 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
373 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
374 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400375 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500376 // No dirty objects.
377
378 // Readpixels uses the pack state and read FBO
379 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
380 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
381 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
382 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
383 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400384 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500385 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
386
387 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
388 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
389 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
390 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
391 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
392 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
393 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
394 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
395 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
396 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
397 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
398 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
399
400 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
401 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700402 mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500403 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
404 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400405
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400406 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000407}
408
Jamie Madill4928b7c2017-06-20 12:57:39 -0400409egl::Error Context::onDestroy(const egl::Display *display)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000410{
Corentin Wallez80b24112015-08-25 16:41:57 -0400411 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000412 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400413 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000414 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400415 mFenceNVMap.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000416
Corentin Wallez80b24112015-08-25 16:41:57 -0400417 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000418 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400419 if (query.second != nullptr)
420 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400421 query.second->release(this);
Geoff Langf0aa8422015-09-29 15:08:34 -0400422 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000423 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400424 mQueryMap.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000425
Corentin Wallez80b24112015-08-25 16:41:57 -0400426 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400427 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400428 if (vertexArray.second)
429 {
430 vertexArray.second->onDestroy(this);
431 }
Jamie Madill57a89722013-07-02 11:57:03 -0400432 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400433 mVertexArrayMap.clear();
Jamie Madill57a89722013-07-02 11:57:03 -0400434
Corentin Wallez80b24112015-08-25 16:41:57 -0400435 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500436 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500437 if (transformFeedback.second != nullptr)
438 {
Jamie Madill6c1f6712017-02-14 19:08:04 -0500439 transformFeedback.second->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500440 }
Geoff Langc8058452014-02-03 12:04:11 -0500441 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400442 mTransformFeedbackMap.clear();
Geoff Langc8058452014-02-03 12:04:11 -0500443
Jamie Madilldedd7b92014-11-05 16:30:36 -0500444 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400445 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400446 zeroTexture.second->onDestroy(this);
447 zeroTexture.second.set(this, nullptr);
Geoff Lang76b10c92014-09-05 16:28:14 -0400448 }
449 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000450
Corentin Wallezccab69d2017-01-27 16:57:15 -0500451 SafeDelete(mSurfacelessFramebuffer);
452
Jamie Madill4928b7c2017-06-20 12:57:39 -0400453 ANGLE_TRY(releaseSurface(display));
Jamie Madill2f348d22017-06-05 10:50:59 -0400454 releaseShaderCompiler();
Jamie Madill6c1f6712017-02-14 19:08:04 -0500455
Jamie Madill4928b7c2017-06-20 12:57:39 -0400456 mGLState.reset(this);
457
Jamie Madill6c1f6712017-02-14 19:08:04 -0500458 mState.mBuffers->release(this);
459 mState.mShaderPrograms->release(this);
460 mState.mTextures->release(this);
461 mState.mRenderbuffers->release(this);
462 mState.mSamplers->release(this);
463 mState.mFenceSyncs->release(this);
464 mState.mPaths->release(this);
465 mState.mFramebuffers->release(this);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400466
467 return egl::NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000468}
469
Jamie Madill70ee0f62017-02-06 16:04:20 -0500470Context::~Context()
471{
472}
473
Jamie Madill4928b7c2017-06-20 12:57:39 -0400474egl::Error Context::makeCurrent(egl::Display *display, egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000475{
Jamie Madill61e16b42017-06-19 11:13:23 -0400476 mCurrentDisplay = display;
477
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000478 if (!mHasBeenCurrent)
479 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000480 initRendererString();
Geoff Langc339c4e2016-11-29 10:37:36 -0500481 initVersionStrings();
Geoff Langcec35902014-04-16 10:52:36 -0400482 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000483
Corentin Wallezc295e512017-01-27 17:47:50 -0500484 int width = 0;
485 int height = 0;
486 if (surface != nullptr)
487 {
488 width = surface->getWidth();
489 height = surface->getHeight();
490 }
491
492 mGLState.setViewportParams(0, 0, width, height);
493 mGLState.setScissorParams(0, 0, width, height);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000494
495 mHasBeenCurrent = true;
496 }
497
Jamie Madill1b94d432015-08-07 13:23:23 -0400498 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700499 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400500
Jamie Madill4928b7c2017-06-20 12:57:39 -0400501 ANGLE_TRY(releaseSurface(display));
Corentin Wallezccab69d2017-01-27 16:57:15 -0500502
503 Framebuffer *newDefault = nullptr;
504 if (surface != nullptr)
505 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400506 ANGLE_TRY(surface->setIsCurrent(this, true));
Corentin Wallezccab69d2017-01-27 16:57:15 -0500507 mCurrentSurface = surface;
508 newDefault = surface->getDefaultFramebuffer();
509 }
510 else
511 {
512 if (mSurfacelessFramebuffer == nullptr)
513 {
514 mSurfacelessFramebuffer = new Framebuffer(mImplementation.get());
515 }
516
517 newDefault = mSurfacelessFramebuffer;
518 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000519
Corentin Wallez37c39792015-08-20 14:19:46 -0400520 // Update default framebuffer, the binding of the previous default
521 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400522 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700523 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400524 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700525 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400526 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700527 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400528 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700529 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400530 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500531 mState.mFramebuffers->setDefaultFramebuffer(newDefault);
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400532 }
Ian Ewell292f0052016-02-04 10:37:32 -0500533
534 // Notify the renderer of a context switch
Jamie Madill4928b7c2017-06-20 12:57:39 -0400535 mImplementation->onMakeCurrent(this);
536 return egl::NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000537}
538
Jamie Madill4928b7c2017-06-20 12:57:39 -0400539egl::Error Context::releaseSurface(const egl::Display *display)
Jamie Madill77a72f62015-04-14 11:18:32 -0400540{
Corentin Wallez37c39792015-08-20 14:19:46 -0400541 // Remove the default framebuffer
Corentin Wallezc295e512017-01-27 17:47:50 -0500542 Framebuffer *currentDefault = nullptr;
543 if (mCurrentSurface != nullptr)
Corentin Wallez51706ea2015-08-07 14:39:22 -0400544 {
Corentin Wallezc295e512017-01-27 17:47:50 -0500545 currentDefault = mCurrentSurface->getDefaultFramebuffer();
546 }
547 else if (mSurfacelessFramebuffer != nullptr)
548 {
549 currentDefault = mSurfacelessFramebuffer;
Corentin Wallez51706ea2015-08-07 14:39:22 -0400550 }
551
Corentin Wallezc295e512017-01-27 17:47:50 -0500552 if (mGLState.getReadFramebuffer() == currentDefault)
553 {
554 mGLState.setReadFramebufferBinding(nullptr);
555 }
556 if (mGLState.getDrawFramebuffer() == currentDefault)
557 {
558 mGLState.setDrawFramebufferBinding(nullptr);
559 }
560 mState.mFramebuffers->setDefaultFramebuffer(nullptr);
561
562 if (mCurrentSurface)
563 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400564 ANGLE_TRY(mCurrentSurface->setIsCurrent(this, false));
Corentin Wallezc295e512017-01-27 17:47:50 -0500565 mCurrentSurface = nullptr;
566 }
Jamie Madill4928b7c2017-06-20 12:57:39 -0400567
568 return egl::NoError();
Jamie Madill77a72f62015-04-14 11:18:32 -0400569}
570
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000571GLuint Context::createBuffer()
572{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500573 return mState.mBuffers->createBuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000574}
575
576GLuint Context::createProgram()
577{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500578 return mState.mShaderPrograms->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000579}
580
581GLuint Context::createShader(GLenum type)
582{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500583 return mState.mShaderPrograms->createShader(mImplementation.get(), mLimitations, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000584}
585
586GLuint Context::createTexture()
587{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500588 return mState.mTextures->createTexture();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000589}
590
591GLuint Context::createRenderbuffer()
592{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500593 return mState.mRenderbuffers->createRenderbuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000594}
595
Geoff Lang882033e2014-09-30 11:26:07 -0400596GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400597{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500598 GLuint handle = mState.mFenceSyncs->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400599
Cooper Partind8e62a32015-01-29 15:21:25 -0800600 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400601}
602
Sami Väisänene45e53b2016-05-25 10:36:04 +0300603GLuint Context::createPaths(GLsizei range)
604{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500605 auto resultOrError = mState.mPaths->createPaths(mImplementation.get(), range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300606 if (resultOrError.isError())
607 {
608 handleError(resultOrError.getError());
609 return 0;
610 }
611 return resultOrError.getResult();
612}
613
Jamie Madill57a89722013-07-02 11:57:03 -0400614GLuint Context::createVertexArray()
615{
Jamie Madill96a483b2017-06-27 16:49:21 -0400616 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
617 mVertexArrayMap.assign(vertexArray, nullptr);
Geoff Lang36167ab2015-12-07 10:27:14 -0500618 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400619}
620
Jamie Madilldc356042013-07-19 16:36:57 -0400621GLuint Context::createSampler()
622{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500623 return mState.mSamplers->createSampler();
Jamie Madilldc356042013-07-19 16:36:57 -0400624}
625
Geoff Langc8058452014-02-03 12:04:11 -0500626GLuint Context::createTransformFeedback()
627{
Jamie Madill96a483b2017-06-27 16:49:21 -0400628 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
629 mTransformFeedbackMap.assign(transformFeedback, nullptr);
Geoff Lang36167ab2015-12-07 10:27:14 -0500630 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500631}
632
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000633// Returns an unused framebuffer name
634GLuint Context::createFramebuffer()
635{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500636 return mState.mFramebuffers->createFramebuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000637}
638
Jamie Madill33dc8432013-07-26 11:55:05 -0400639GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000640{
Jamie Madill33dc8432013-07-26 11:55:05 -0400641 GLuint handle = mFenceNVHandleAllocator.allocate();
Jamie Madill96a483b2017-06-27 16:49:21 -0400642 mFenceNVMap.assign(handle, new FenceNV(mImplementation->createFenceNV()));
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000643 return handle;
644}
645
646// Returns an unused query name
647GLuint Context::createQuery()
648{
649 GLuint handle = mQueryHandleAllocator.allocate();
Jamie Madill96a483b2017-06-27 16:49:21 -0400650 mQueryMap.assign(handle, nullptr);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000651 return handle;
652}
653
654void Context::deleteBuffer(GLuint buffer)
655{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500656 if (mState.mBuffers->getBuffer(buffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000657 {
658 detachBuffer(buffer);
659 }
Jamie Madill893ab082014-05-16 16:56:10 -0400660
Jamie Madill6c1f6712017-02-14 19:08:04 -0500661 mState.mBuffers->deleteObject(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000662}
663
664void Context::deleteShader(GLuint shader)
665{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500666 mState.mShaderPrograms->deleteShader(this, shader);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000667}
668
669void Context::deleteProgram(GLuint program)
670{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500671 mState.mShaderPrograms->deleteProgram(this, program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000672}
673
674void Context::deleteTexture(GLuint texture)
675{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500676 if (mState.mTextures->getTexture(texture))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000677 {
678 detachTexture(texture);
679 }
680
Jamie Madill6c1f6712017-02-14 19:08:04 -0500681 mState.mTextures->deleteObject(this, texture);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000682}
683
684void Context::deleteRenderbuffer(GLuint renderbuffer)
685{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500686 if (mState.mRenderbuffers->getRenderbuffer(renderbuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000687 {
688 detachRenderbuffer(renderbuffer);
689 }
Jamie Madill893ab082014-05-16 16:56:10 -0400690
Jamie Madill6c1f6712017-02-14 19:08:04 -0500691 mState.mRenderbuffers->deleteObject(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000692}
693
Jamie Madillcd055f82013-07-26 11:55:15 -0400694void Context::deleteFenceSync(GLsync fenceSync)
695{
696 // The spec specifies the underlying Fence object is not deleted until all current
697 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
698 // and since our API is currently designed for being called from a single thread, we can delete
699 // the fence immediately.
Jamie Madill6c1f6712017-02-14 19:08:04 -0500700 mState.mFenceSyncs->deleteObject(this,
701 static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400702}
703
Sami Väisänene45e53b2016-05-25 10:36:04 +0300704void Context::deletePaths(GLuint first, GLsizei range)
705{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500706 mState.mPaths->deletePaths(first, range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300707}
708
709bool Context::hasPathData(GLuint path) const
710{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500711 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300712 if (pathObj == nullptr)
713 return false;
714
715 return pathObj->hasPathData();
716}
717
718bool Context::hasPath(GLuint path) const
719{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500720 return mState.mPaths->hasPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300721}
722
723void Context::setPathCommands(GLuint path,
724 GLsizei numCommands,
725 const GLubyte *commands,
726 GLsizei numCoords,
727 GLenum coordType,
728 const void *coords)
729{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500730 auto *pathObject = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300731
732 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
733}
734
735void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
736{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500737 auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300738
739 switch (pname)
740 {
741 case GL_PATH_STROKE_WIDTH_CHROMIUM:
742 pathObj->setStrokeWidth(value);
743 break;
744 case GL_PATH_END_CAPS_CHROMIUM:
745 pathObj->setEndCaps(static_cast<GLenum>(value));
746 break;
747 case GL_PATH_JOIN_STYLE_CHROMIUM:
748 pathObj->setJoinStyle(static_cast<GLenum>(value));
749 break;
750 case GL_PATH_MITER_LIMIT_CHROMIUM:
751 pathObj->setMiterLimit(value);
752 break;
753 case GL_PATH_STROKE_BOUND_CHROMIUM:
754 pathObj->setStrokeBound(value);
755 break;
756 default:
757 UNREACHABLE();
758 break;
759 }
760}
761
762void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
763{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500764 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300765
766 switch (pname)
767 {
768 case GL_PATH_STROKE_WIDTH_CHROMIUM:
769 *value = pathObj->getStrokeWidth();
770 break;
771 case GL_PATH_END_CAPS_CHROMIUM:
772 *value = static_cast<GLfloat>(pathObj->getEndCaps());
773 break;
774 case GL_PATH_JOIN_STYLE_CHROMIUM:
775 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
776 break;
777 case GL_PATH_MITER_LIMIT_CHROMIUM:
778 *value = pathObj->getMiterLimit();
779 break;
780 case GL_PATH_STROKE_BOUND_CHROMIUM:
781 *value = pathObj->getStrokeBound();
782 break;
783 default:
784 UNREACHABLE();
785 break;
786 }
787}
788
789void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
790{
791 mGLState.setPathStencilFunc(func, ref, mask);
792}
793
Jamie Madill57a89722013-07-02 11:57:03 -0400794void Context::deleteVertexArray(GLuint vertexArray)
795{
Jamie Madill96a483b2017-06-27 16:49:21 -0400796 VertexArray *vertexArrayObject = nullptr;
797 if (mVertexArrayMap.erase(vertexArray, &vertexArrayObject))
Geoff Lang50b3fe82015-12-08 14:49:12 +0000798 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500799 if (vertexArrayObject != nullptr)
800 {
801 detachVertexArray(vertexArray);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400802 vertexArrayObject->onDestroy(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500803 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000804
Geoff Lang36167ab2015-12-07 10:27:14 -0500805 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400806 }
807}
808
Jamie Madilldc356042013-07-19 16:36:57 -0400809void Context::deleteSampler(GLuint sampler)
810{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500811 if (mState.mSamplers->getSampler(sampler))
Jamie Madilldc356042013-07-19 16:36:57 -0400812 {
813 detachSampler(sampler);
814 }
815
Jamie Madill6c1f6712017-02-14 19:08:04 -0500816 mState.mSamplers->deleteObject(this, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400817}
818
Geoff Langc8058452014-02-03 12:04:11 -0500819void Context::deleteTransformFeedback(GLuint transformFeedback)
820{
Geoff Lang6e60d6b2017-04-12 12:59:04 -0400821 if (transformFeedback == 0)
822 {
823 return;
824 }
825
Jamie Madill96a483b2017-06-27 16:49:21 -0400826 TransformFeedback *transformFeedbackObject = nullptr;
827 if (mTransformFeedbackMap.erase(transformFeedback, &transformFeedbackObject))
Geoff Langc8058452014-02-03 12:04:11 -0500828 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500829 if (transformFeedbackObject != nullptr)
830 {
831 detachTransformFeedback(transformFeedback);
Jamie Madill6c1f6712017-02-14 19:08:04 -0500832 transformFeedbackObject->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500833 }
834
Geoff Lang36167ab2015-12-07 10:27:14 -0500835 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500836 }
837}
838
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000839void Context::deleteFramebuffer(GLuint framebuffer)
840{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500841 if (mState.mFramebuffers->getFramebuffer(framebuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000842 {
843 detachFramebuffer(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000844 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500845
Jamie Madill6c1f6712017-02-14 19:08:04 -0500846 mState.mFramebuffers->deleteObject(this, framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000847}
848
Jamie Madill33dc8432013-07-26 11:55:05 -0400849void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000850{
Jamie Madill96a483b2017-06-27 16:49:21 -0400851 FenceNV *fenceObject = nullptr;
852 if (mFenceNVMap.erase(fence, &fenceObject))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000853 {
Jamie Madill96a483b2017-06-27 16:49:21 -0400854 mFenceNVHandleAllocator.release(fence);
855 delete fenceObject;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000856 }
857}
858
859void Context::deleteQuery(GLuint query)
860{
Jamie Madill96a483b2017-06-27 16:49:21 -0400861 Query *queryObject = nullptr;
862 if (mQueryMap.erase(query, &queryObject))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000863 {
Jamie Madill96a483b2017-06-27 16:49:21 -0400864 mQueryHandleAllocator.release(query);
865 if (queryObject)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000866 {
Jamie Madill96a483b2017-06-27 16:49:21 -0400867 queryObject->release(this);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000868 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000869 }
870}
871
Geoff Lang70d0f492015-12-10 17:45:46 -0500872Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000873{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500874 return mState.mBuffers->getBuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000875}
876
Jamie Madill570f7c82014-07-03 10:38:54 -0400877Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000878{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500879 return mState.mTextures->getTexture(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000880}
881
Geoff Lang70d0f492015-12-10 17:45:46 -0500882Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000883{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500884 return mState.mRenderbuffers->getRenderbuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000885}
886
Jamie Madillcd055f82013-07-26 11:55:15 -0400887FenceSync *Context::getFenceSync(GLsync handle) const
888{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500889 return mState.mFenceSyncs->getFenceSync(
890 static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400891}
892
Jamie Madill57a89722013-07-02 11:57:03 -0400893VertexArray *Context::getVertexArray(GLuint handle) const
894{
Jamie Madill96a483b2017-06-27 16:49:21 -0400895 return mVertexArrayMap.query(handle);
Jamie Madill57a89722013-07-02 11:57:03 -0400896}
897
Jamie Madilldc356042013-07-19 16:36:57 -0400898Sampler *Context::getSampler(GLuint handle) const
899{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500900 return mState.mSamplers->getSampler(handle);
Jamie Madilldc356042013-07-19 16:36:57 -0400901}
902
Geoff Langc8058452014-02-03 12:04:11 -0500903TransformFeedback *Context::getTransformFeedback(GLuint handle) const
904{
Jamie Madill96a483b2017-06-27 16:49:21 -0400905 return mTransformFeedbackMap.query(handle);
Geoff Langc8058452014-02-03 12:04:11 -0500906}
907
Geoff Lang70d0f492015-12-10 17:45:46 -0500908LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
909{
910 switch (identifier)
911 {
912 case GL_BUFFER:
913 return getBuffer(name);
914 case GL_SHADER:
915 return getShader(name);
916 case GL_PROGRAM:
917 return getProgram(name);
918 case GL_VERTEX_ARRAY:
919 return getVertexArray(name);
920 case GL_QUERY:
921 return getQuery(name);
922 case GL_TRANSFORM_FEEDBACK:
923 return getTransformFeedback(name);
924 case GL_SAMPLER:
925 return getSampler(name);
926 case GL_TEXTURE:
927 return getTexture(name);
928 case GL_RENDERBUFFER:
929 return getRenderbuffer(name);
930 case GL_FRAMEBUFFER:
931 return getFramebuffer(name);
932 default:
933 UNREACHABLE();
934 return nullptr;
935 }
936}
937
938LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
939{
940 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
941}
942
Martin Radev9d901792016-07-15 15:58:58 +0300943void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
944{
945 LabeledObject *object = getLabeledObject(identifier, name);
946 ASSERT(object != nullptr);
947
948 std::string labelName = GetObjectLabelFromPointer(length, label);
949 object->setLabel(labelName);
950}
951
952void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
953{
954 LabeledObject *object = getLabeledObjectFromPtr(ptr);
955 ASSERT(object != nullptr);
956
957 std::string labelName = GetObjectLabelFromPointer(length, label);
958 object->setLabel(labelName);
959}
960
961void Context::getObjectLabel(GLenum identifier,
962 GLuint name,
963 GLsizei bufSize,
964 GLsizei *length,
965 GLchar *label) const
966{
967 LabeledObject *object = getLabeledObject(identifier, name);
968 ASSERT(object != nullptr);
969
970 const std::string &objectLabel = object->getLabel();
971 GetObjectLabelBase(objectLabel, bufSize, length, label);
972}
973
974void Context::getObjectPtrLabel(const void *ptr,
975 GLsizei bufSize,
976 GLsizei *length,
977 GLchar *label) const
978{
979 LabeledObject *object = getLabeledObjectFromPtr(ptr);
980 ASSERT(object != nullptr);
981
982 const std::string &objectLabel = object->getLabel();
983 GetObjectLabelBase(objectLabel, bufSize, length, label);
984}
985
Jamie Madilldc356042013-07-19 16:36:57 -0400986bool Context::isSampler(GLuint samplerName) const
987{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500988 return mState.mSamplers->isSampler(samplerName);
Jamie Madilldc356042013-07-19 16:36:57 -0400989}
990
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500991void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000992{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500993 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400994 mGLState.setArrayBufferBinding(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000995}
996
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800997void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
998{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500999 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001000 mGLState.setDrawIndirectBufferBinding(this, buffer);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08001001}
1002
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001003void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001004{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001005 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001006 mGLState.setElementArrayBuffer(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001007}
1008
Jamie Madilldedd7b92014-11-05 16:30:36 -05001009void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001010{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001011 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001012
Jamie Madilldedd7b92014-11-05 16:30:36 -05001013 if (handle == 0)
1014 {
1015 texture = mZeroTextures[target].get();
1016 }
1017 else
1018 {
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001019 texture = mState.mTextures->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -05001020 }
1021
1022 ASSERT(texture);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001023 mGLState.setSamplerTexture(this, target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +00001024}
1025
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001026void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001027{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001028 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
1029 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001030 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001031}
1032
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001033void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001034{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001035 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
1036 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001037 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001038}
1039
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001040void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -04001041{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001042 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001043 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -04001044}
1045
Shao80957d92017-02-20 21:25:59 +08001046void Context::bindVertexBuffer(GLuint bindingIndex,
1047 GLuint bufferHandle,
1048 GLintptr offset,
1049 GLsizei stride)
1050{
1051 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001052 mGLState.bindVertexBuffer(this, bindingIndex, buffer, offset, stride);
Shao80957d92017-02-20 21:25:59 +08001053}
1054
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001055void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -04001056{
Geoff Lang76b10c92014-09-05 16:28:14 -04001057 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -04001058 Sampler *sampler =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001059 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001060 mGLState.setSamplerBinding(this, textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001061}
1062
Xinghua Cao65ec0b22017-03-28 16:10:52 +08001063void Context::bindImageTexture(GLuint unit,
1064 GLuint texture,
1065 GLint level,
1066 GLboolean layered,
1067 GLint layer,
1068 GLenum access,
1069 GLenum format)
1070{
1071 Texture *tex = mState.mTextures->getTexture(texture);
1072 mGLState.setImageUnit(this, unit, tex, level, layered, layer, access, format);
1073}
1074
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001075void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001076{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001077 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001078 mGLState.setGenericUniformBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001079}
1080
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001081void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1082 GLuint index,
1083 GLintptr offset,
1084 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001085{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001086 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001087 mGLState.setIndexedUniformBufferBinding(this, index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001088}
1089
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001090void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001091{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001092 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001093 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001094}
1095
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001096void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1097 GLuint index,
1098 GLintptr offset,
1099 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001100{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001101 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001102 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(this, index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001103}
1104
Jiajia Qin6eafb042016-12-27 17:04:07 +08001105void Context::bindGenericAtomicCounterBuffer(GLuint bufferHandle)
1106{
1107 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001108 mGLState.setGenericAtomicCounterBufferBinding(this, buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08001109}
1110
1111void Context::bindIndexedAtomicCounterBuffer(GLuint bufferHandle,
1112 GLuint index,
1113 GLintptr offset,
1114 GLsizeiptr size)
1115{
1116 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001117 mGLState.setIndexedAtomicCounterBufferBinding(this, index, buffer, offset, size);
Jiajia Qin6eafb042016-12-27 17:04:07 +08001118}
1119
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001120void Context::bindGenericShaderStorageBuffer(GLuint bufferHandle)
1121{
1122 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001123 mGLState.setGenericShaderStorageBufferBinding(this, buffer);
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001124}
1125
1126void Context::bindIndexedShaderStorageBuffer(GLuint bufferHandle,
1127 GLuint index,
1128 GLintptr offset,
1129 GLsizeiptr size)
1130{
1131 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001132 mGLState.setIndexedShaderStorageBufferBinding(this, index, buffer, offset, size);
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001133}
1134
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001135void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001136{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001137 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001138 mGLState.setCopyReadBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001139}
1140
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001141void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001142{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001143 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001144 mGLState.setCopyWriteBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001145}
1146
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001147void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001148{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001149 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001150 mGLState.setPixelPackBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001151}
1152
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001153void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001154{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001155 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001156 mGLState.setPixelUnpackBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001157}
1158
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001159void Context::useProgram(GLuint program)
1160{
Jamie Madill6c1f6712017-02-14 19:08:04 -05001161 mGLState.setProgram(this, getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001162}
1163
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001164void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001165{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001166 TransformFeedback *transformFeedback =
1167 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001168 mGLState.setTransformFeedbackBinding(this, transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001169}
1170
Geoff Lang5aad9672014-09-08 11:10:42 -04001171Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001172{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001173 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001174 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001175
Geoff Lang5aad9672014-09-08 11:10:42 -04001176 // begin query
1177 Error error = queryObject->begin();
1178 if (error.isError())
1179 {
1180 return error;
1181 }
1182
1183 // set query as active for specified target only if begin succeeded
Jamie Madill4928b7c2017-06-20 12:57:39 -04001184 mGLState.setActiveQuery(this, target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001185
He Yunchaoacd18982017-01-04 10:46:42 +08001186 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001187}
1188
Geoff Lang5aad9672014-09-08 11:10:42 -04001189Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001190{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001191 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001192 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001193
Geoff Lang5aad9672014-09-08 11:10:42 -04001194 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001195
Geoff Lang5aad9672014-09-08 11:10:42 -04001196 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madill4928b7c2017-06-20 12:57:39 -04001197 mGLState.setActiveQuery(this, target, nullptr);
Geoff Lang5aad9672014-09-08 11:10:42 -04001198
1199 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001200}
1201
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001202Error Context::queryCounter(GLuint id, GLenum target)
1203{
1204 ASSERT(target == GL_TIMESTAMP_EXT);
1205
1206 Query *queryObject = getQuery(id, true, target);
1207 ASSERT(queryObject);
1208
1209 return queryObject->queryCounter();
1210}
1211
1212void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1213{
1214 switch (pname)
1215 {
1216 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001217 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001218 break;
1219 case GL_QUERY_COUNTER_BITS_EXT:
1220 switch (target)
1221 {
1222 case GL_TIME_ELAPSED_EXT:
1223 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1224 break;
1225 case GL_TIMESTAMP_EXT:
1226 params[0] = getExtensions().queryCounterBitsTimestamp;
1227 break;
1228 default:
1229 UNREACHABLE();
1230 params[0] = 0;
1231 break;
1232 }
1233 break;
1234 default:
1235 UNREACHABLE();
1236 return;
1237 }
1238}
1239
Geoff Lang2186c382016-10-14 10:54:54 -04001240void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001241{
Geoff Lang2186c382016-10-14 10:54:54 -04001242 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001243}
1244
Geoff Lang2186c382016-10-14 10:54:54 -04001245void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001246{
Geoff Lang2186c382016-10-14 10:54:54 -04001247 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001248}
1249
Geoff Lang2186c382016-10-14 10:54:54 -04001250void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001251{
Geoff Lang2186c382016-10-14 10:54:54 -04001252 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001253}
1254
Geoff Lang2186c382016-10-14 10:54:54 -04001255void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001256{
Geoff Lang2186c382016-10-14 10:54:54 -04001257 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001258}
1259
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001260Framebuffer *Context::getFramebuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001261{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001262 return mState.mFramebuffers->getFramebuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001263}
1264
Jamie Madill2f348d22017-06-05 10:50:59 -04001265FenceNV *Context::getFenceNV(GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001266{
Jamie Madill96a483b2017-06-27 16:49:21 -04001267 return mFenceNVMap.query(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001268}
1269
Jamie Madill2f348d22017-06-05 10:50:59 -04001270Query *Context::getQuery(GLuint handle, bool create, GLenum type)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001271{
Jamie Madill96a483b2017-06-27 16:49:21 -04001272 if (!mQueryMap.contains(handle))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001273 {
Yunchao Hef81ce4a2017-04-24 10:49:17 +08001274 return nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001275 }
Jamie Madill96a483b2017-06-27 16:49:21 -04001276
1277 Query *query = mQueryMap.query(handle);
1278 if (!query && create)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001279 {
Jamie Madill96a483b2017-06-27 16:49:21 -04001280 query = new Query(mImplementation->createQuery(type), handle);
1281 query->addRef();
1282 mQueryMap.assign(handle, query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001283 }
Jamie Madill96a483b2017-06-27 16:49:21 -04001284 return query;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001285}
1286
Geoff Lang70d0f492015-12-10 17:45:46 -05001287Query *Context::getQuery(GLuint handle) const
1288{
Jamie Madill96a483b2017-06-27 16:49:21 -04001289 return mQueryMap.query(handle);
Geoff Lang70d0f492015-12-10 17:45:46 -05001290}
1291
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001292Texture *Context::getTargetTexture(GLenum target) const
1293{
Ian Ewellbda75592016-04-18 17:25:54 -04001294 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001295 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001296}
1297
Geoff Lang76b10c92014-09-05 16:28:14 -04001298Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001299{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001300 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001301}
1302
Geoff Lang492a7e42014-11-05 13:27:06 -05001303Compiler *Context::getCompiler() const
1304{
Jamie Madill2f348d22017-06-05 10:50:59 -04001305 if (mCompiler.get() == nullptr)
1306 {
Jamie Madill4928b7c2017-06-20 12:57:39 -04001307 mCompiler.set(this, new Compiler(mImplementation.get(), mState));
Jamie Madill2f348d22017-06-05 10:50:59 -04001308 }
1309 return mCompiler.get();
Geoff Lang492a7e42014-11-05 13:27:06 -05001310}
1311
Jamie Madillc1d770e2017-04-13 17:31:24 -04001312void Context::getBooleanvImpl(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001313{
1314 switch (pname)
1315 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001316 case GL_SHADER_COMPILER:
1317 *params = GL_TRUE;
1318 break;
1319 case GL_CONTEXT_ROBUST_ACCESS_EXT:
1320 *params = mRobustAccess ? GL_TRUE : GL_FALSE;
1321 break;
1322 default:
1323 mGLState.getBooleanv(pname, params);
1324 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001325 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001326}
1327
Jamie Madillc1d770e2017-04-13 17:31:24 -04001328void Context::getFloatvImpl(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001329{
Shannon Woods53a94a82014-06-24 15:20:36 -04001330 // Queries about context capabilities and maximums are answered by Context.
1331 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001332 switch (pname)
1333 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001334 case GL_ALIASED_LINE_WIDTH_RANGE:
1335 params[0] = mCaps.minAliasedLineWidth;
1336 params[1] = mCaps.maxAliasedLineWidth;
1337 break;
1338 case GL_ALIASED_POINT_SIZE_RANGE:
1339 params[0] = mCaps.minAliasedPointSize;
1340 params[1] = mCaps.maxAliasedPointSize;
1341 break;
1342 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1343 ASSERT(mExtensions.textureFilterAnisotropic);
1344 *params = mExtensions.maxTextureAnisotropy;
1345 break;
1346 case GL_MAX_TEXTURE_LOD_BIAS:
1347 *params = mCaps.maxLODBias;
1348 break;
1349
1350 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1351 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1352 {
1353 ASSERT(mExtensions.pathRendering);
1354 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1355 memcpy(params, m, 16 * sizeof(GLfloat));
1356 }
Geoff Lange6d4e122015-06-29 13:33:55 -04001357 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001358
Jamie Madill231c7f52017-04-26 13:45:37 -04001359 default:
1360 mGLState.getFloatv(pname, params);
1361 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001362 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001363}
1364
Jamie Madillc1d770e2017-04-13 17:31:24 -04001365void Context::getIntegervImpl(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001366{
Shannon Woods53a94a82014-06-24 15:20:36 -04001367 // Queries about context capabilities and maximums are answered by Context.
1368 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001369
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001370 switch (pname)
1371 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001372 case GL_MAX_VERTEX_ATTRIBS:
1373 *params = mCaps.maxVertexAttributes;
1374 break;
1375 case GL_MAX_VERTEX_UNIFORM_VECTORS:
1376 *params = mCaps.maxVertexUniformVectors;
1377 break;
1378 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
1379 *params = mCaps.maxVertexUniformComponents;
1380 break;
1381 case GL_MAX_VARYING_VECTORS:
1382 *params = mCaps.maxVaryingVectors;
1383 break;
1384 case GL_MAX_VARYING_COMPONENTS:
1385 *params = mCaps.maxVertexOutputComponents;
1386 break;
1387 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1388 *params = mCaps.maxCombinedTextureImageUnits;
1389 break;
1390 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1391 *params = mCaps.maxVertexTextureImageUnits;
1392 break;
1393 case GL_MAX_TEXTURE_IMAGE_UNITS:
1394 *params = mCaps.maxTextureImageUnits;
1395 break;
1396 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1397 *params = mCaps.maxFragmentUniformVectors;
1398 break;
1399 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
1400 *params = mCaps.maxFragmentUniformComponents;
1401 break;
1402 case GL_MAX_RENDERBUFFER_SIZE:
1403 *params = mCaps.maxRenderbufferSize;
1404 break;
1405 case GL_MAX_COLOR_ATTACHMENTS_EXT:
1406 *params = mCaps.maxColorAttachments;
1407 break;
1408 case GL_MAX_DRAW_BUFFERS_EXT:
1409 *params = mCaps.maxDrawBuffers;
1410 break;
1411 // case GL_FRAMEBUFFER_BINDING: // now equivalent to
1412 // GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1413 case GL_SUBPIXEL_BITS:
1414 *params = 4;
1415 break;
1416 case GL_MAX_TEXTURE_SIZE:
1417 *params = mCaps.max2DTextureSize;
1418 break;
1419 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1420 *params = mCaps.maxCubeMapTextureSize;
1421 break;
1422 case GL_MAX_3D_TEXTURE_SIZE:
1423 *params = mCaps.max3DTextureSize;
1424 break;
1425 case GL_MAX_ARRAY_TEXTURE_LAYERS:
1426 *params = mCaps.maxArrayTextureLayers;
1427 break;
1428 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
1429 *params = mCaps.uniformBufferOffsetAlignment;
1430 break;
1431 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
1432 *params = mCaps.maxUniformBufferBindings;
1433 break;
1434 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
1435 *params = mCaps.maxVertexUniformBlocks;
1436 break;
1437 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
1438 *params = mCaps.maxFragmentUniformBlocks;
1439 break;
1440 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
1441 *params = mCaps.maxCombinedTextureImageUnits;
1442 break;
1443 case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
1444 *params = mCaps.maxVertexOutputComponents;
1445 break;
1446 case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
1447 *params = mCaps.maxFragmentInputComponents;
1448 break;
1449 case GL_MIN_PROGRAM_TEXEL_OFFSET:
1450 *params = mCaps.minProgramTexelOffset;
1451 break;
1452 case GL_MAX_PROGRAM_TEXEL_OFFSET:
1453 *params = mCaps.maxProgramTexelOffset;
1454 break;
1455 case GL_MAJOR_VERSION:
1456 *params = getClientVersion().major;
1457 break;
1458 case GL_MINOR_VERSION:
1459 *params = getClientVersion().minor;
1460 break;
1461 case GL_MAX_ELEMENTS_INDICES:
1462 *params = mCaps.maxElementsIndices;
1463 break;
1464 case GL_MAX_ELEMENTS_VERTICES:
1465 *params = mCaps.maxElementsVertices;
1466 break;
1467 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
1468 *params = mCaps.maxTransformFeedbackInterleavedComponents;
1469 break;
1470 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
1471 *params = mCaps.maxTransformFeedbackSeparateAttributes;
1472 break;
1473 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
1474 *params = mCaps.maxTransformFeedbackSeparateComponents;
1475 break;
1476 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1477 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1478 break;
1479 case GL_MAX_SAMPLES_ANGLE:
1480 *params = mCaps.maxSamples;
1481 break;
1482 case GL_MAX_VIEWPORT_DIMS:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001483 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001484 params[0] = mCaps.maxViewportWidth;
1485 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001486 }
1487 break;
Jamie Madill231c7f52017-04-26 13:45:37 -04001488 case GL_COMPRESSED_TEXTURE_FORMATS:
1489 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(),
1490 params);
1491 break;
1492 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1493 *params = mResetStrategy;
1494 break;
1495 case GL_NUM_SHADER_BINARY_FORMATS:
1496 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
1497 break;
1498 case GL_SHADER_BINARY_FORMATS:
1499 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1500 break;
1501 case GL_NUM_PROGRAM_BINARY_FORMATS:
1502 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
1503 break;
1504 case GL_PROGRAM_BINARY_FORMATS:
1505 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
1506 break;
1507 case GL_NUM_EXTENSIONS:
1508 *params = static_cast<GLint>(mExtensionStrings.size());
1509 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001510
Jamie Madill231c7f52017-04-26 13:45:37 -04001511 // GL_KHR_debug
1512 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1513 *params = mExtensions.maxDebugMessageLength;
1514 break;
1515 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1516 *params = mExtensions.maxDebugLoggedMessages;
1517 break;
1518 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1519 *params = mExtensions.maxDebugGroupStackDepth;
1520 break;
1521 case GL_MAX_LABEL_LENGTH:
1522 *params = mExtensions.maxLabelLength;
1523 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001524
Martin Radeve5285d22017-07-14 16:23:53 +03001525 // GL_ANGLE_multiview
1526 case GL_MAX_VIEWS_ANGLE:
1527 *params = mExtensions.maxViews;
1528 break;
1529
Jamie Madill231c7f52017-04-26 13:45:37 -04001530 // GL_EXT_disjoint_timer_query
1531 case GL_GPU_DISJOINT_EXT:
1532 *params = mImplementation->getGPUDisjoint();
1533 break;
1534 case GL_MAX_FRAMEBUFFER_WIDTH:
1535 *params = mCaps.maxFramebufferWidth;
1536 break;
1537 case GL_MAX_FRAMEBUFFER_HEIGHT:
1538 *params = mCaps.maxFramebufferHeight;
1539 break;
1540 case GL_MAX_FRAMEBUFFER_SAMPLES:
1541 *params = mCaps.maxFramebufferSamples;
1542 break;
1543 case GL_MAX_SAMPLE_MASK_WORDS:
1544 *params = mCaps.maxSampleMaskWords;
1545 break;
1546 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1547 *params = mCaps.maxColorTextureSamples;
1548 break;
1549 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1550 *params = mCaps.maxDepthTextureSamples;
1551 break;
1552 case GL_MAX_INTEGER_SAMPLES:
1553 *params = mCaps.maxIntegerSamples;
1554 break;
1555 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1556 *params = mCaps.maxVertexAttribRelativeOffset;
1557 break;
1558 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1559 *params = mCaps.maxVertexAttribBindings;
1560 break;
1561 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1562 *params = mCaps.maxVertexAttribStride;
1563 break;
1564 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1565 *params = mCaps.maxVertexAtomicCounterBuffers;
1566 break;
1567 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1568 *params = mCaps.maxVertexAtomicCounters;
1569 break;
1570 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1571 *params = mCaps.maxVertexImageUniforms;
1572 break;
1573 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1574 *params = mCaps.maxVertexShaderStorageBlocks;
1575 break;
1576 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1577 *params = mCaps.maxFragmentAtomicCounterBuffers;
1578 break;
1579 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1580 *params = mCaps.maxFragmentAtomicCounters;
1581 break;
1582 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1583 *params = mCaps.maxFragmentImageUniforms;
1584 break;
1585 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1586 *params = mCaps.maxFragmentShaderStorageBlocks;
1587 break;
1588 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1589 *params = mCaps.minProgramTextureGatherOffset;
1590 break;
1591 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1592 *params = mCaps.maxProgramTextureGatherOffset;
1593 break;
1594 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1595 *params = mCaps.maxComputeWorkGroupInvocations;
1596 break;
1597 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1598 *params = mCaps.maxComputeUniformBlocks;
1599 break;
1600 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1601 *params = mCaps.maxComputeTextureImageUnits;
1602 break;
1603 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1604 *params = mCaps.maxComputeSharedMemorySize;
1605 break;
1606 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1607 *params = mCaps.maxComputeUniformComponents;
1608 break;
1609 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1610 *params = mCaps.maxComputeAtomicCounterBuffers;
1611 break;
1612 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1613 *params = mCaps.maxComputeAtomicCounters;
1614 break;
1615 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1616 *params = mCaps.maxComputeImageUniforms;
1617 break;
1618 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1619 *params = mCaps.maxCombinedComputeUniformComponents;
1620 break;
1621 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1622 *params = mCaps.maxComputeShaderStorageBlocks;
1623 break;
1624 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1625 *params = mCaps.maxCombinedShaderOutputResources;
1626 break;
1627 case GL_MAX_UNIFORM_LOCATIONS:
1628 *params = mCaps.maxUniformLocations;
1629 break;
1630 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1631 *params = mCaps.maxAtomicCounterBufferBindings;
1632 break;
1633 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1634 *params = mCaps.maxAtomicCounterBufferSize;
1635 break;
1636 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1637 *params = mCaps.maxCombinedAtomicCounterBuffers;
1638 break;
1639 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1640 *params = mCaps.maxCombinedAtomicCounters;
1641 break;
1642 case GL_MAX_IMAGE_UNITS:
1643 *params = mCaps.maxImageUnits;
1644 break;
1645 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1646 *params = mCaps.maxCombinedImageUniforms;
1647 break;
1648 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1649 *params = mCaps.maxShaderStorageBufferBindings;
1650 break;
1651 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1652 *params = mCaps.maxCombinedShaderStorageBlocks;
1653 break;
1654 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1655 *params = mCaps.shaderStorageBufferOffsetAlignment;
1656 break;
1657 default:
1658 mGLState.getIntegerv(this, pname, params);
1659 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001660 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001661}
1662
Jamie Madill893ab082014-05-16 16:56:10 -04001663void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001664{
Shannon Woods53a94a82014-06-24 15:20:36 -04001665 // Queries about context capabilities and maximums are answered by Context.
1666 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001667 switch (pname)
1668 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001669 case GL_MAX_ELEMENT_INDEX:
1670 *params = mCaps.maxElementIndex;
1671 break;
1672 case GL_MAX_UNIFORM_BLOCK_SIZE:
1673 *params = mCaps.maxUniformBlockSize;
1674 break;
1675 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
1676 *params = mCaps.maxCombinedVertexUniformComponents;
1677 break;
1678 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
1679 *params = mCaps.maxCombinedFragmentUniformComponents;
1680 break;
1681 case GL_MAX_SERVER_WAIT_TIMEOUT:
1682 *params = mCaps.maxServerWaitTimeout;
1683 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001684
Jamie Madill231c7f52017-04-26 13:45:37 -04001685 // GL_EXT_disjoint_timer_query
1686 case GL_TIMESTAMP_EXT:
1687 *params = mImplementation->getTimestamp();
1688 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001689
Jamie Madill231c7f52017-04-26 13:45:37 -04001690 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1691 *params = mCaps.maxShaderStorageBlockSize;
1692 break;
1693 default:
1694 UNREACHABLE();
1695 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001696 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001697}
1698
Geoff Lang70d0f492015-12-10 17:45:46 -05001699void Context::getPointerv(GLenum pname, void **params) const
1700{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001701 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001702}
1703
Martin Radev66fb8202016-07-28 11:45:20 +03001704void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001705{
Shannon Woods53a94a82014-06-24 15:20:36 -04001706 // Queries about context capabilities and maximums are answered by Context.
1707 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001708
1709 GLenum nativeType;
1710 unsigned int numParams;
1711 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1712 ASSERT(queryStatus);
1713
1714 if (nativeType == GL_INT)
1715 {
1716 switch (target)
1717 {
1718 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1719 ASSERT(index < 3u);
1720 *data = mCaps.maxComputeWorkGroupCount[index];
1721 break;
1722 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1723 ASSERT(index < 3u);
1724 *data = mCaps.maxComputeWorkGroupSize[index];
1725 break;
1726 default:
1727 mGLState.getIntegeri_v(target, index, data);
1728 }
1729 }
1730 else
1731 {
1732 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1733 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001734}
1735
Martin Radev66fb8202016-07-28 11:45:20 +03001736void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001737{
Shannon Woods53a94a82014-06-24 15:20:36 -04001738 // Queries about context capabilities and maximums are answered by Context.
1739 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001740
1741 GLenum nativeType;
1742 unsigned int numParams;
1743 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1744 ASSERT(queryStatus);
1745
1746 if (nativeType == GL_INT_64_ANGLEX)
1747 {
1748 mGLState.getInteger64i_v(target, index, data);
1749 }
1750 else
1751 {
1752 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1753 }
1754}
1755
1756void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1757{
1758 // Queries about context capabilities and maximums are answered by Context.
1759 // Queries about current GL state values are answered by State.
1760
1761 GLenum nativeType;
1762 unsigned int numParams;
1763 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1764 ASSERT(queryStatus);
1765
1766 if (nativeType == GL_BOOL)
1767 {
1768 mGLState.getBooleani_v(target, index, data);
1769 }
1770 else
1771 {
1772 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1773 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001774}
1775
He Yunchao010e4db2017-03-03 14:22:06 +08001776void Context::getBufferParameteriv(GLenum target, GLenum pname, GLint *params)
1777{
1778 Buffer *buffer = mGLState.getTargetBuffer(target);
1779 QueryBufferParameteriv(buffer, pname, params);
1780}
1781
1782void Context::getFramebufferAttachmentParameteriv(GLenum target,
1783 GLenum attachment,
1784 GLenum pname,
1785 GLint *params)
1786{
1787 const Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
1788 QueryFramebufferAttachmentParameteriv(framebuffer, attachment, pname, params);
1789}
1790
1791void Context::getRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
1792{
1793 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
1794 QueryRenderbufferiv(this, renderbuffer, pname, params);
1795}
1796
1797void Context::getTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
1798{
1799 Texture *texture = getTargetTexture(target);
1800 QueryTexParameterfv(texture, pname, params);
1801}
1802
1803void Context::getTexParameteriv(GLenum target, GLenum pname, GLint *params)
1804{
1805 Texture *texture = getTargetTexture(target);
1806 QueryTexParameteriv(texture, pname, params);
1807}
1808void Context::texParameterf(GLenum target, GLenum pname, GLfloat param)
1809{
1810 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001811 SetTexParameterf(this, texture, pname, param);
He Yunchao010e4db2017-03-03 14:22:06 +08001812}
1813
1814void Context::texParameterfv(GLenum target, GLenum pname, const GLfloat *params)
1815{
1816 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001817 SetTexParameterfv(this, texture, pname, params);
He Yunchao010e4db2017-03-03 14:22:06 +08001818}
1819
1820void Context::texParameteri(GLenum target, GLenum pname, GLint param)
1821{
1822 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001823 SetTexParameteri(this, texture, pname, param);
He Yunchao010e4db2017-03-03 14:22:06 +08001824}
1825
1826void Context::texParameteriv(GLenum target, GLenum pname, const GLint *params)
1827{
1828 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001829 SetTexParameteriv(this, texture, pname, params);
He Yunchao010e4db2017-03-03 14:22:06 +08001830}
1831
Jamie Madill675fe712016-12-19 13:07:54 -05001832void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001833{
Jamie Madill1b94d432015-08-07 13:23:23 -04001834 syncRendererState();
Jamie Madillc564c072017-06-01 12:45:42 -04001835 auto error = mImplementation->drawArrays(this, mode, first, count);
Jamie Madill675fe712016-12-19 13:07:54 -05001836 handleError(error);
1837 if (!error.isError())
1838 {
1839 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1840 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001841}
1842
Jamie Madill675fe712016-12-19 13:07:54 -05001843void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Geoff Langf6db0982015-08-25 13:04:00 -04001844{
1845 syncRendererState();
Jamie Madillc564c072017-06-01 12:45:42 -04001846 auto error = mImplementation->drawArraysInstanced(this, mode, first, count, instanceCount);
Jamie Madill675fe712016-12-19 13:07:54 -05001847 handleError(error);
1848 if (!error.isError())
1849 {
1850 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1851 }
Geoff Langf6db0982015-08-25 13:04:00 -04001852}
1853
Jamie Madill876429b2017-04-20 15:46:24 -04001854void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001855{
Jamie Madill1b94d432015-08-07 13:23:23 -04001856 syncRendererState();
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001857 const IndexRange &indexRange = getParams<HasIndexRange>().getIndexRange().value();
Jamie Madillc564c072017-06-01 12:45:42 -04001858 handleError(mImplementation->drawElements(this, mode, count, type, indices, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001859}
1860
Jamie Madill675fe712016-12-19 13:07:54 -05001861void Context::drawElementsInstanced(GLenum mode,
1862 GLsizei count,
1863 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001864 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001865 GLsizei instances)
Geoff Langf6db0982015-08-25 13:04:00 -04001866{
1867 syncRendererState();
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001868 const IndexRange &indexRange = getParams<HasIndexRange>().getIndexRange().value();
Jamie Madillc564c072017-06-01 12:45:42 -04001869 handleError(mImplementation->drawElementsInstanced(this, mode, count, type, indices, instances,
1870 indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001871}
1872
Jamie Madill675fe712016-12-19 13:07:54 -05001873void Context::drawRangeElements(GLenum mode,
1874 GLuint start,
1875 GLuint end,
1876 GLsizei count,
1877 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001878 const void *indices)
Geoff Langf6db0982015-08-25 13:04:00 -04001879{
1880 syncRendererState();
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001881 const IndexRange &indexRange = getParams<HasIndexRange>().getIndexRange().value();
Jamie Madillc564c072017-06-01 12:45:42 -04001882 handleError(mImplementation->drawRangeElements(this, mode, start, end, count, type, indices,
1883 indexRange));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001884}
1885
Jamie Madill876429b2017-04-20 15:46:24 -04001886void Context::drawArraysIndirect(GLenum mode, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001887{
1888 syncRendererState();
Jamie Madillc564c072017-06-01 12:45:42 -04001889 handleError(mImplementation->drawArraysIndirect(this, mode, indirect));
Jiajia Qind9671222016-11-29 16:30:31 +08001890}
1891
Jamie Madill876429b2017-04-20 15:46:24 -04001892void Context::drawElementsIndirect(GLenum mode, GLenum type, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001893{
1894 syncRendererState();
Jamie Madillc564c072017-06-01 12:45:42 -04001895 handleError(mImplementation->drawElementsIndirect(this, mode, type, indirect));
Jiajia Qind9671222016-11-29 16:30:31 +08001896}
1897
Jamie Madill675fe712016-12-19 13:07:54 -05001898void Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001899{
Jamie Madill675fe712016-12-19 13:07:54 -05001900 handleError(mImplementation->flush());
Geoff Lang129753a2015-01-09 16:52:09 -05001901}
1902
Jamie Madill675fe712016-12-19 13:07:54 -05001903void Context::finish()
Geoff Lang129753a2015-01-09 16:52:09 -05001904{
Jamie Madill675fe712016-12-19 13:07:54 -05001905 handleError(mImplementation->finish());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001906}
1907
Austin Kinross6ee1e782015-05-29 17:05:37 -07001908void Context::insertEventMarker(GLsizei length, const char *marker)
1909{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001910 ASSERT(mImplementation);
1911 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001912}
1913
1914void Context::pushGroupMarker(GLsizei length, const char *marker)
1915{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001916 ASSERT(mImplementation);
1917 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001918}
1919
1920void Context::popGroupMarker()
1921{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001922 ASSERT(mImplementation);
1923 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001924}
1925
Geoff Langd8605522016-04-13 10:19:12 -04001926void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1927{
1928 Program *programObject = getProgram(program);
1929 ASSERT(programObject);
1930
1931 programObject->bindUniformLocation(location, name);
1932}
1933
Sami Väisänena797e062016-05-12 15:23:40 +03001934void Context::setCoverageModulation(GLenum components)
1935{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001936 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001937}
1938
Sami Väisänene45e53b2016-05-25 10:36:04 +03001939void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1940{
1941 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1942}
1943
1944void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1945{
1946 GLfloat I[16];
1947 angle::Matrix<GLfloat>::setToIdentity(I);
1948
1949 mGLState.loadPathRenderingMatrix(matrixMode, I);
1950}
1951
1952void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1953{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001954 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001955 if (!pathObj)
1956 return;
1957
1958 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1959 syncRendererState();
1960
1961 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1962}
1963
1964void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1965{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001966 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001967 if (!pathObj)
1968 return;
1969
1970 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1971 syncRendererState();
1972
1973 mImplementation->stencilStrokePath(pathObj, reference, mask);
1974}
1975
1976void Context::coverFillPath(GLuint path, GLenum coverMode)
1977{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001978 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001979 if (!pathObj)
1980 return;
1981
1982 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1983 syncRendererState();
1984
1985 mImplementation->coverFillPath(pathObj, coverMode);
1986}
1987
1988void Context::coverStrokePath(GLuint path, GLenum coverMode)
1989{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001990 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001991 if (!pathObj)
1992 return;
1993
1994 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1995 syncRendererState();
1996
1997 mImplementation->coverStrokePath(pathObj, coverMode);
1998}
1999
2000void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
2001{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002002 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03002003 if (!pathObj)
2004 return;
2005
2006 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2007 syncRendererState();
2008
2009 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
2010}
2011
2012void Context::stencilThenCoverStrokePath(GLuint path,
2013 GLint reference,
2014 GLuint mask,
2015 GLenum coverMode)
2016{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002017 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03002018 if (!pathObj)
2019 return;
2020
2021 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2022 syncRendererState();
2023
2024 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
2025}
2026
Sami Väisänend59ca052016-06-21 16:10:00 +03002027void Context::coverFillPathInstanced(GLsizei numPaths,
2028 GLenum pathNameType,
2029 const void *paths,
2030 GLuint pathBase,
2031 GLenum coverMode,
2032 GLenum transformType,
2033 const GLfloat *transformValues)
2034{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002035 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002036
2037 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2038 syncRendererState();
2039
2040 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
2041}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002042
Sami Väisänend59ca052016-06-21 16:10:00 +03002043void Context::coverStrokePathInstanced(GLsizei numPaths,
2044 GLenum pathNameType,
2045 const void *paths,
2046 GLuint pathBase,
2047 GLenum coverMode,
2048 GLenum transformType,
2049 const GLfloat *transformValues)
2050{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002051 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002052
2053 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2054 syncRendererState();
2055
2056 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
2057 transformValues);
2058}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002059
Sami Väisänend59ca052016-06-21 16:10:00 +03002060void Context::stencilFillPathInstanced(GLsizei numPaths,
2061 GLenum pathNameType,
2062 const void *paths,
2063 GLuint pathBase,
2064 GLenum fillMode,
2065 GLuint mask,
2066 GLenum transformType,
2067 const GLfloat *transformValues)
2068{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002069 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002070
2071 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2072 syncRendererState();
2073
2074 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
2075 transformValues);
2076}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002077
Sami Väisänend59ca052016-06-21 16:10:00 +03002078void Context::stencilStrokePathInstanced(GLsizei numPaths,
2079 GLenum pathNameType,
2080 const void *paths,
2081 GLuint pathBase,
2082 GLint reference,
2083 GLuint mask,
2084 GLenum transformType,
2085 const GLfloat *transformValues)
2086{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002087 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002088
2089 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2090 syncRendererState();
2091
2092 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
2093 transformValues);
2094}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002095
Sami Väisänend59ca052016-06-21 16:10:00 +03002096void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
2097 GLenum pathNameType,
2098 const void *paths,
2099 GLuint pathBase,
2100 GLenum fillMode,
2101 GLuint mask,
2102 GLenum coverMode,
2103 GLenum transformType,
2104 const GLfloat *transformValues)
2105{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002106 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002107
2108 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2109 syncRendererState();
2110
2111 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
2112 transformType, transformValues);
2113}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002114
Sami Väisänend59ca052016-06-21 16:10:00 +03002115void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
2116 GLenum pathNameType,
2117 const void *paths,
2118 GLuint pathBase,
2119 GLint reference,
2120 GLuint mask,
2121 GLenum coverMode,
2122 GLenum transformType,
2123 const GLfloat *transformValues)
2124{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002125 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002126
2127 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2128 syncRendererState();
2129
2130 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
2131 transformType, transformValues);
2132}
2133
Sami Väisänen46eaa942016-06-29 10:26:37 +03002134void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
2135{
2136 auto *programObject = getProgram(program);
2137
2138 programObject->bindFragmentInputLocation(location, name);
2139}
2140
2141void Context::programPathFragmentInputGen(GLuint program,
2142 GLint location,
2143 GLenum genMode,
2144 GLint components,
2145 const GLfloat *coeffs)
2146{
2147 auto *programObject = getProgram(program);
2148
Jamie Madillbd044ed2017-06-05 12:59:21 -04002149 programObject->pathFragmentInputGen(this, location, genMode, components, coeffs);
Sami Väisänen46eaa942016-06-29 10:26:37 +03002150}
2151
jchen1015015f72017-03-16 13:54:21 +08002152GLuint Context::getProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name)
2153{
jchen10fd7c3b52017-03-21 15:36:03 +08002154 const auto *programObject = getProgram(program);
jchen1015015f72017-03-16 13:54:21 +08002155 return QueryProgramResourceIndex(programObject, programInterface, name);
2156}
2157
jchen10fd7c3b52017-03-21 15:36:03 +08002158void Context::getProgramResourceName(GLuint program,
2159 GLenum programInterface,
2160 GLuint index,
2161 GLsizei bufSize,
2162 GLsizei *length,
2163 GLchar *name)
2164{
2165 const auto *programObject = getProgram(program);
2166 QueryProgramResourceName(programObject, programInterface, index, bufSize, length, name);
2167}
2168
Jamie Madill437fa652016-05-03 15:13:24 -04002169void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002170{
Geoff Langda5777c2014-07-11 09:52:58 -04002171 if (error.isError())
2172 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002173 GLenum code = error.getCode();
2174 mErrors.insert(code);
2175 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
2176 {
2177 markContextLost();
2178 }
Geoff Lang70d0f492015-12-10 17:45:46 -05002179
2180 if (!error.getMessage().empty())
2181 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002182 auto *debug = &mGLState.getDebug();
2183 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
2184 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05002185 }
Geoff Langda5777c2014-07-11 09:52:58 -04002186 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002187}
2188
2189// Get one of the recorded errors and clear its flag, if any.
2190// [OpenGL ES 2.0.24] section 2.5 page 13.
2191GLenum Context::getError()
2192{
Geoff Langda5777c2014-07-11 09:52:58 -04002193 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002194 {
Geoff Langda5777c2014-07-11 09:52:58 -04002195 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002196 }
Geoff Langda5777c2014-07-11 09:52:58 -04002197 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002198 {
Geoff Langda5777c2014-07-11 09:52:58 -04002199 GLenum error = *mErrors.begin();
2200 mErrors.erase(mErrors.begin());
2201 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002202 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002203}
2204
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002205// NOTE: this function should not assume that this context is current!
2206void Context::markContextLost()
2207{
2208 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002209 {
Jamie Madill231c7f52017-04-26 13:45:37 -04002210 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002211 mContextLostForced = true;
2212 }
Jamie Madill231c7f52017-04-26 13:45:37 -04002213 mContextLost = true;
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002214}
2215
2216bool Context::isContextLost()
2217{
2218 return mContextLost;
2219}
2220
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002221GLenum Context::getResetStatus()
2222{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002223 // Even if the application doesn't want to know about resets, we want to know
2224 // as it will allow us to skip all the calls.
2225 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002226 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002227 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002228 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002229 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002230 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002231
2232 // EXT_robustness, section 2.6: If the reset notification behavior is
2233 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2234 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2235 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002236 }
2237
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002238 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2239 // status should be returned at least once, and GL_NO_ERROR should be returned
2240 // once the device has finished resetting.
2241 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002242 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002243 ASSERT(mResetStatus == GL_NO_ERROR);
2244 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002245
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002246 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002247 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002248 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002249 }
2250 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002251 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002252 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002253 // If markContextLost was used to mark the context lost then
2254 // assume that is not recoverable, and continue to report the
2255 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002256 mResetStatus = mImplementation->getResetStatus();
2257 }
Jamie Madill893ab082014-05-16 16:56:10 -04002258
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002259 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002260}
2261
2262bool Context::isResetNotificationEnabled()
2263{
2264 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2265}
2266
Corentin Walleze3b10e82015-05-20 11:06:25 -04002267const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002268{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002269 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002270}
2271
2272EGLenum Context::getClientType() const
2273{
2274 return mClientType;
2275}
2276
2277EGLenum Context::getRenderBuffer() const
2278{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002279 const Framebuffer *framebuffer = mState.mFramebuffers->getFramebuffer(0);
2280 if (framebuffer == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -04002281 {
2282 return EGL_NONE;
2283 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002284
2285 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2286 ASSERT(backAttachment != nullptr);
2287 return backAttachment->getSurface()->getRenderBuffer();
Régis Fénéon83107972015-02-05 12:57:44 +01002288}
2289
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002290VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002291{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002292 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002293 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2294 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002295 {
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002296 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle,
2297 mCaps.maxVertexAttributes, mCaps.maxVertexAttribBindings);
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002298
Jamie Madill96a483b2017-06-27 16:49:21 -04002299 mVertexArrayMap.assign(vertexArrayHandle, vertexArray);
Geoff Lang36167ab2015-12-07 10:27:14 -05002300 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002301
2302 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002303}
2304
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002305TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002306{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002307 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002308 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2309 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002310 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002311 transformFeedback =
2312 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002313 transformFeedback->addRef();
Jamie Madill96a483b2017-06-27 16:49:21 -04002314 mTransformFeedbackMap.assign(transformFeedbackHandle, transformFeedback);
Geoff Lang36167ab2015-12-07 10:27:14 -05002315 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002316
2317 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002318}
2319
2320bool Context::isVertexArrayGenerated(GLuint vertexArray)
2321{
Jamie Madill96a483b2017-06-27 16:49:21 -04002322 ASSERT(mVertexArrayMap.contains(0));
2323 return mVertexArrayMap.contains(vertexArray);
Geoff Lang36167ab2015-12-07 10:27:14 -05002324}
2325
2326bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2327{
Jamie Madill96a483b2017-06-27 16:49:21 -04002328 ASSERT(mTransformFeedbackMap.contains(0));
2329 return mTransformFeedbackMap.contains(transformFeedback);
Geoff Lang36167ab2015-12-07 10:27:14 -05002330}
2331
Shannon Woods53a94a82014-06-24 15:20:36 -04002332void Context::detachTexture(GLuint texture)
2333{
2334 // Simple pass-through to State's detachTexture method, as textures do not require
2335 // allocation map management either here or in the resource manager at detach time.
2336 // Zero textures are held by the Context, and we don't attempt to request them from
2337 // the State.
Jamie Madilla02315b2017-02-23 14:14:47 -05002338 mGLState.detachTexture(this, mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002339}
2340
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002341void Context::detachBuffer(GLuint buffer)
2342{
Yuly Novikov5807a532015-12-03 13:01:22 -05002343 // Simple pass-through to State's detachBuffer method, since
2344 // only buffer attachments to container objects that are bound to the current context
2345 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002346
Yuly Novikov5807a532015-12-03 13:01:22 -05002347 // [OpenGL ES 3.2] section 5.1.2 page 45:
2348 // Attachments to unbound container objects, such as
2349 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2350 // are not affected and continue to act as references on the deleted object
Jamie Madill4928b7c2017-06-20 12:57:39 -04002351 mGLState.detachBuffer(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002352}
2353
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002354void Context::detachFramebuffer(GLuint framebuffer)
2355{
Shannon Woods53a94a82014-06-24 15:20:36 -04002356 // Framebuffer detachment is handled by Context, because 0 is a valid
2357 // Framebuffer object, and a pointer to it must be passed from Context
2358 // to State at binding time.
2359
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002360 // [OpenGL ES 2.0.24] section 4.4 page 107:
Jamie Madill231c7f52017-04-26 13:45:37 -04002361 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as
2362 // though BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of
2363 // zero.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002364
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002365 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002366 {
2367 bindReadFramebuffer(0);
2368 }
2369
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002370 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002371 {
2372 bindDrawFramebuffer(0);
2373 }
2374}
2375
2376void Context::detachRenderbuffer(GLuint renderbuffer)
2377{
Jamie Madilla02315b2017-02-23 14:14:47 -05002378 mGLState.detachRenderbuffer(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002379}
2380
Jamie Madill57a89722013-07-02 11:57:03 -04002381void Context::detachVertexArray(GLuint vertexArray)
2382{
Jamie Madill77a72f62015-04-14 11:18:32 -04002383 // Vertex array detachment is handled by Context, because 0 is a valid
2384 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002385 // binding time.
2386
Jamie Madill57a89722013-07-02 11:57:03 -04002387 // [OpenGL ES 3.0.2] section 2.10 page 43:
2388 // If a vertex array object that is currently bound is deleted, the binding
2389 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002390 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002391 {
2392 bindVertexArray(0);
2393 }
2394}
2395
Geoff Langc8058452014-02-03 12:04:11 -05002396void Context::detachTransformFeedback(GLuint transformFeedback)
2397{
Corentin Walleza2257da2016-04-19 16:43:12 -04002398 // Transform feedback detachment is handled by Context, because 0 is a valid
2399 // transform feedback, and a pointer to it must be passed from Context to State at
2400 // binding time.
2401
2402 // The OpenGL specification doesn't mention what should happen when the currently bound
2403 // transform feedback object is deleted. Since it is a container object, we treat it like
2404 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madill4928b7c2017-06-20 12:57:39 -04002405 if (mGLState.removeTransformFeedbackBinding(this, transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002406 {
2407 bindTransformFeedback(0);
2408 }
Geoff Langc8058452014-02-03 12:04:11 -05002409}
2410
Jamie Madilldc356042013-07-19 16:36:57 -04002411void Context::detachSampler(GLuint sampler)
2412{
Jamie Madill4928b7c2017-06-20 12:57:39 -04002413 mGLState.detachSampler(this, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002414}
2415
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002416void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2417{
Shaodde78e82017-05-22 14:13:27 +08002418 mGLState.setVertexAttribDivisor(this, index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002419}
2420
Jamie Madille29d1672013-07-19 16:36:57 -04002421void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2422{
Geoff Langc1984ed2016-10-07 12:41:00 -04002423 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002424 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002425 SetSamplerParameteri(samplerObject, pname, param);
2426}
Jamie Madille29d1672013-07-19 16:36:57 -04002427
Geoff Langc1984ed2016-10-07 12:41:00 -04002428void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2429{
2430 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002431 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002432 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002433}
2434
2435void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2436{
Geoff Langc1984ed2016-10-07 12:41:00 -04002437 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002438 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002439 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002440}
2441
Geoff Langc1984ed2016-10-07 12:41:00 -04002442void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002443{
Geoff Langc1984ed2016-10-07 12:41:00 -04002444 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002445 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002446 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002447}
2448
Geoff Langc1984ed2016-10-07 12:41:00 -04002449void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002450{
Geoff Langc1984ed2016-10-07 12:41:00 -04002451 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002452 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002453 QuerySamplerParameteriv(samplerObject, pname, params);
2454}
Jamie Madill9675b802013-07-19 16:36:59 -04002455
Geoff Langc1984ed2016-10-07 12:41:00 -04002456void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2457{
2458 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002459 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002460 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002461}
2462
Olli Etuahof0fee072016-03-30 15:11:58 +03002463void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2464{
2465 gl::Program *programObject = getProgram(program);
Yunchao He61afff12017-03-14 15:34:03 +08002466 SetProgramParameteri(programObject, pname, value);
Olli Etuahof0fee072016-03-30 15:11:58 +03002467}
2468
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002469void Context::initRendererString()
2470{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002471 std::ostringstream rendererString;
2472 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002473 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002474 rendererString << ")";
2475
Geoff Langcec35902014-04-16 10:52:36 -04002476 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002477}
2478
Geoff Langc339c4e2016-11-29 10:37:36 -05002479void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002480{
Geoff Langc339c4e2016-11-29 10:37:36 -05002481 const Version &clientVersion = getClientVersion();
2482
2483 std::ostringstream versionString;
2484 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2485 << ANGLE_VERSION_STRING << ")";
2486 mVersionString = MakeStaticString(versionString.str());
2487
2488 std::ostringstream shadingLanguageVersionString;
2489 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2490 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2491 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2492 << ")";
2493 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002494}
2495
Geoff Langcec35902014-04-16 10:52:36 -04002496void Context::initExtensionStrings()
2497{
Geoff Langc339c4e2016-11-29 10:37:36 -05002498 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2499 std::ostringstream combinedStringStream;
2500 std::copy(strings.begin(), strings.end(),
2501 std::ostream_iterator<const char *>(combinedStringStream, " "));
2502 return MakeStaticString(combinedStringStream.str());
2503 };
2504
2505 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002506 for (const auto &extensionString : mExtensions.getStrings())
2507 {
2508 mExtensionStrings.push_back(MakeStaticString(extensionString));
2509 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002510 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002511
Bryan Bernhart58806562017-01-05 13:09:31 -08002512 const gl::Extensions &nativeExtensions = mImplementation->getNativeExtensions();
2513
Geoff Langc339c4e2016-11-29 10:37:36 -05002514 mRequestableExtensionStrings.clear();
2515 for (const auto &extensionInfo : GetExtensionInfoMap())
2516 {
2517 if (extensionInfo.second.Requestable &&
Bryan Bernhart58806562017-01-05 13:09:31 -08002518 !(mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
2519 nativeExtensions.*(extensionInfo.second.ExtensionsMember))
Geoff Langc339c4e2016-11-29 10:37:36 -05002520 {
2521 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2522 }
2523 }
2524 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002525}
2526
Geoff Langc339c4e2016-11-29 10:37:36 -05002527const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002528{
Geoff Langc339c4e2016-11-29 10:37:36 -05002529 switch (name)
2530 {
2531 case GL_VENDOR:
2532 return reinterpret_cast<const GLubyte *>("Google Inc.");
2533
2534 case GL_RENDERER:
2535 return reinterpret_cast<const GLubyte *>(mRendererString);
2536
2537 case GL_VERSION:
2538 return reinterpret_cast<const GLubyte *>(mVersionString);
2539
2540 case GL_SHADING_LANGUAGE_VERSION:
2541 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2542
2543 case GL_EXTENSIONS:
2544 return reinterpret_cast<const GLubyte *>(mExtensionString);
2545
2546 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2547 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2548
2549 default:
2550 UNREACHABLE();
2551 return nullptr;
2552 }
Geoff Langcec35902014-04-16 10:52:36 -04002553}
2554
Geoff Langc339c4e2016-11-29 10:37:36 -05002555const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002556{
Geoff Langc339c4e2016-11-29 10:37:36 -05002557 switch (name)
2558 {
2559 case GL_EXTENSIONS:
2560 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2561
2562 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2563 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2564
2565 default:
2566 UNREACHABLE();
2567 return nullptr;
2568 }
Geoff Langcec35902014-04-16 10:52:36 -04002569}
2570
2571size_t Context::getExtensionStringCount() const
2572{
2573 return mExtensionStrings.size();
2574}
2575
Geoff Langc339c4e2016-11-29 10:37:36 -05002576void Context::requestExtension(const char *name)
2577{
2578 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2579 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2580 const auto &extension = extensionInfos.at(name);
2581 ASSERT(extension.Requestable);
2582
2583 if (mExtensions.*(extension.ExtensionsMember))
2584 {
2585 // Extension already enabled
2586 return;
2587 }
2588
2589 mExtensions.*(extension.ExtensionsMember) = true;
2590 updateCaps();
2591 initExtensionStrings();
Bryan Bernhart58806562017-01-05 13:09:31 -08002592
Jamie Madill2f348d22017-06-05 10:50:59 -04002593 // Release the shader compiler so it will be re-created with the requested extensions enabled.
2594 releaseShaderCompiler();
Geoff Lang9aded172017-04-05 11:07:56 -04002595
2596 // Invalidate all cached completenesses for textures and framebuffer. Some extensions make new
2597 // formats renderable or sampleable.
2598 mState.mTextures->invalidateTextureComplenessCache();
2599 for (auto &zeroTexture : mZeroTextures)
2600 {
2601 zeroTexture.second->invalidateCompletenessCache();
2602 }
2603
2604 mState.mFramebuffers->invalidateFramebufferComplenessCache();
Geoff Langc339c4e2016-11-29 10:37:36 -05002605}
2606
2607size_t Context::getRequestableExtensionStringCount() const
2608{
2609 return mRequestableExtensionStrings.size();
2610}
2611
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002612void Context::beginTransformFeedback(GLenum primitiveMode)
2613{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002614 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002615 ASSERT(transformFeedback != nullptr);
2616 ASSERT(!transformFeedback->isPaused());
2617
Jamie Madill6c1f6712017-02-14 19:08:04 -05002618 transformFeedback->begin(this, primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002619}
2620
2621bool Context::hasActiveTransformFeedback(GLuint program) const
2622{
2623 for (auto pair : mTransformFeedbackMap)
2624 {
2625 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2626 {
2627 return true;
2628 }
2629 }
2630 return false;
2631}
2632
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002633void Context::initCaps(const egl::DisplayExtensions &displayExtensions)
Geoff Lang493daf52014-07-03 13:38:44 -04002634{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002635 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002636
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002637 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002638
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002639 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002640
Geoff Langeb66a6e2016-10-31 13:06:12 -04002641 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002642 {
2643 // Disable ES3+ extensions
Jamie Madill231c7f52017-04-26 13:45:37 -04002644 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002645 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002646 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002647 }
2648
Geoff Langeb66a6e2016-10-31 13:06:12 -04002649 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002650 {
2651 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
Jamie Madill231c7f52017-04-26 13:45:37 -04002652 // mExtensions.sRGB = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002653 }
2654
Jamie Madill00ed7a12016-05-19 13:13:38 -04002655 // Some extensions are always available because they are implemented in the GL layer.
Jamie Madill231c7f52017-04-26 13:45:37 -04002656 mExtensions.bindUniformLocation = true;
2657 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002658 mExtensions.bindGeneratesResource = true;
Geoff Langfeb8c682017-02-13 16:07:35 -05002659 mExtensions.clientArrays = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002660 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002661
2662 // Enable the no error extension if the context was created with the flag.
2663 mExtensions.noError = mSkipValidation;
2664
Corentin Wallezccab69d2017-01-27 16:57:15 -05002665 // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
Corentin Wallezc295e512017-01-27 17:47:50 -05002666 mExtensions.surfacelessContext = displayExtensions.surfacelessContext;
Corentin Wallezccab69d2017-01-27 16:57:15 -05002667
Geoff Lang70d0f492015-12-10 17:45:46 -05002668 // Explicitly enable GL_KHR_debug
2669 mExtensions.debug = true;
2670 mExtensions.maxDebugMessageLength = 1024;
2671 mExtensions.maxDebugLoggedMessages = 1024;
2672 mExtensions.maxDebugGroupStackDepth = 1024;
2673 mExtensions.maxLabelLength = 1024;
2674
Geoff Langff5b2d52016-09-07 11:32:23 -04002675 // Explicitly enable GL_ANGLE_robust_client_memory
2676 mExtensions.robustClientMemory = true;
2677
Jamie Madille08a1d32017-03-07 17:24:06 -05002678 // Determine robust resource init availability from EGL.
2679 mExtensions.robustResourceInitialization =
Jamie Madill948bbe52017-06-01 13:10:42 -04002680 egl::Display::GetClientExtensions().displayRobustResourceInitialization;
Jamie Madille08a1d32017-03-07 17:24:06 -05002681
Jamie Madillc43be722017-07-13 16:22:14 -04002682 // Enable the cache control query unconditionally.
2683 mExtensions.programCacheControl = true;
2684
Geoff Lang301d1612014-07-09 10:34:37 -04002685 // Apply implementation limits
2686 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002687 mCaps.maxVertexAttribBindings =
2688 getClientVersion() < ES_3_1
2689 ? mCaps.maxVertexAttributes
2690 : std::min<GLuint>(mCaps.maxVertexAttribBindings, MAX_VERTEX_ATTRIB_BINDINGS);
2691
Jamie Madill231c7f52017-04-26 13:45:37 -04002692 mCaps.maxVertexUniformBlocks = std::min<GLuint>(
2693 mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2694 mCaps.maxVertexOutputComponents =
2695 std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang301d1612014-07-09 10:34:37 -04002696
Jamie Madill231c7f52017-04-26 13:45:37 -04002697 mCaps.maxFragmentInputComponents =
2698 std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002699
Geoff Langc287ea62016-09-16 14:46:51 -04002700 // WebGL compatibility
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002701 mExtensions.webglCompatibility = mWebGLContext;
Geoff Langc287ea62016-09-16 14:46:51 -04002702 for (const auto &extensionInfo : GetExtensionInfoMap())
2703 {
2704 // If this context is for WebGL, disable all enableable extensions
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002705 if (mWebGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002706 {
2707 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2708 }
2709 }
2710
2711 // Generate texture caps
2712 updateCaps();
2713}
2714
2715void Context::updateCaps()
2716{
Geoff Lang900013c2014-07-07 11:32:19 -04002717 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002718 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002719
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002720 for (auto capsIt : mImplementation->getNativeTextureCaps())
Geoff Lang493daf52014-07-03 13:38:44 -04002721 {
Geoff Langca271392017-04-05 12:30:00 -04002722 GLenum sizedInternalFormat = capsIt.first;
Jamie Madill231c7f52017-04-26 13:45:37 -04002723 TextureCaps formatCaps = capsIt.second;
Geoff Lang493daf52014-07-03 13:38:44 -04002724
Geoff Langca271392017-04-05 12:30:00 -04002725 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002726
Geoff Lang0d8b7242015-09-09 14:56:53 -04002727 // Update the format caps based on the client version and extensions.
2728 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2729 // ES3.
2730 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002731 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002732 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002733 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002734 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002735 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002736
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002737 // OpenGL ES does not support multisampling with non-rendererable formats
2738 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
Olli Etuaho50c562d2017-06-06 14:43:30 +03002739 if (!formatCaps.renderable ||
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002740 (getClientVersion() < ES_3_1 &&
2741 (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
Geoff Lang493daf52014-07-03 13:38:44 -04002742 {
Geoff Langd87878e2014-09-19 15:42:59 -04002743 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002744 }
Olli Etuaho50c562d2017-06-06 14:43:30 +03002745 else
2746 {
2747 // We may have limited the max samples for some required renderbuffer formats due to
2748 // non-conformant formats. In this case MAX_SAMPLES needs to be lowered accordingly.
2749 GLuint formatMaxSamples = formatCaps.getMaxSamples();
2750
2751 // GLES 3.0.5 section 4.4.2.2: "Implementations must support creation of renderbuffers
2752 // in these required formats with up to the value of MAX_SAMPLES multisamples, with the
2753 // exception of signed and unsigned integer formats."
2754 if (formatInfo.componentType != GL_INT && formatInfo.componentType != GL_UNSIGNED_INT &&
2755 formatInfo.isRequiredRenderbufferFormat(getClientVersion()))
2756 {
2757 ASSERT(getClientVersion() < ES_3_0 || formatMaxSamples >= 4);
2758 mCaps.maxSamples = std::min(mCaps.maxSamples, formatMaxSamples);
2759 }
2760
2761 // Handle GLES 3.1 MAX_*_SAMPLES values similarly to MAX_SAMPLES.
2762 if (getClientVersion() >= ES_3_1)
2763 {
2764 // GLES 3.1 section 9.2.5: "Implementations must support creation of renderbuffers
2765 // in these required formats with up to the value of MAX_SAMPLES multisamples, with
2766 // the exception that the signed and unsigned integer formats are required only to
2767 // support creation of renderbuffers with up to the value of MAX_INTEGER_SAMPLES
2768 // multisamples, which must be at least one."
2769 if (formatInfo.componentType == GL_INT ||
2770 formatInfo.componentType == GL_UNSIGNED_INT)
2771 {
2772 mCaps.maxIntegerSamples = std::min(mCaps.maxIntegerSamples, formatMaxSamples);
2773 }
2774
2775 // GLES 3.1 section 19.3.1.
2776 if (formatCaps.texturable)
2777 {
2778 if (formatInfo.depthBits > 0)
2779 {
2780 mCaps.maxDepthTextureSamples =
2781 std::min(mCaps.maxDepthTextureSamples, formatMaxSamples);
2782 }
2783 else if (formatInfo.redBits > 0)
2784 {
2785 mCaps.maxColorTextureSamples =
2786 std::min(mCaps.maxColorTextureSamples, formatMaxSamples);
2787 }
2788 }
2789 }
2790 }
Geoff Langd87878e2014-09-19 15:42:59 -04002791
2792 if (formatCaps.texturable && formatInfo.compressed)
2793 {
Geoff Langca271392017-04-05 12:30:00 -04002794 mCaps.compressedTextureFormats.push_back(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002795 }
2796
Geoff Langca271392017-04-05 12:30:00 -04002797 mTextureCaps.insert(sizedInternalFormat, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002798 }
Jamie Madill32447362017-06-28 14:53:52 -04002799
2800 // If program binary is disabled, blank out the memory cache pointer.
2801 if (!mImplementation->getNativeExtensions().getProgramBinary)
2802 {
2803 mMemoryProgramCache = nullptr;
2804 }
Geoff Lang493daf52014-07-03 13:38:44 -04002805}
2806
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002807void Context::initWorkarounds()
2808{
Jamie Madill761b02c2017-06-23 16:27:06 -04002809 // Apply back-end workarounds.
2810 mImplementation->applyNativeWorkarounds(&mWorkarounds);
2811
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002812 // Lose the context upon out of memory error if the application is
2813 // expecting to watch for those events.
2814 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2815}
2816
Jamie Madill1b94d432015-08-07 13:23:23 -04002817void Context::syncRendererState()
2818{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002819 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
Jamie Madillfe548342017-06-19 11:13:24 -04002820 mImplementation->syncState(this, dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002821 mGLState.clearDirtyBits();
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002822 mGLState.syncDirtyObjects(this);
Jamie Madill1b94d432015-08-07 13:23:23 -04002823}
2824
Jamie Madillad9f24e2016-02-12 09:27:24 -05002825void Context::syncRendererState(const State::DirtyBits &bitMask,
2826 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002827{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002828 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
Jamie Madillfe548342017-06-19 11:13:24 -04002829 mImplementation->syncState(this, dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002830 mGLState.clearDirtyBits(dirtyBits);
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002831 mGLState.syncDirtyObjects(this, objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002832}
Jamie Madillc29968b2016-01-20 11:17:23 -05002833
2834void Context::blitFramebuffer(GLint srcX0,
2835 GLint srcY0,
2836 GLint srcX1,
2837 GLint srcY1,
2838 GLint dstX0,
2839 GLint dstY0,
2840 GLint dstX1,
2841 GLint dstY1,
2842 GLbitfield mask,
2843 GLenum filter)
2844{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002845 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002846 ASSERT(drawFramebuffer);
2847
2848 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2849 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2850
Jamie Madillad9f24e2016-02-12 09:27:24 -05002851 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002852
Jamie Madillc564c072017-06-01 12:45:42 -04002853 handleError(drawFramebuffer->blit(this, srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002854}
Jamie Madillc29968b2016-01-20 11:17:23 -05002855
2856void Context::clear(GLbitfield mask)
2857{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002858 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002859 handleError(mGLState.getDrawFramebuffer()->clear(this, mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002860}
2861
2862void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2863{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002864 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002865 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002866}
2867
2868void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2869{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002870 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002871 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002872}
2873
2874void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2875{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002876 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002877 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002878}
2879
2880void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2881{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002882 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002883 ASSERT(framebufferObject);
2884
2885 // If a buffer is not present, the clear has no effect
2886 if (framebufferObject->getDepthbuffer() == nullptr &&
2887 framebufferObject->getStencilbuffer() == nullptr)
2888 {
2889 return;
2890 }
2891
Jamie Madillad9f24e2016-02-12 09:27:24 -05002892 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002893 handleError(framebufferObject->clearBufferfi(this, buffer, drawbuffer, depth, stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002894}
2895
2896void Context::readPixels(GLint x,
2897 GLint y,
2898 GLsizei width,
2899 GLsizei height,
2900 GLenum format,
2901 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002902 void *pixels)
Jamie Madillc29968b2016-01-20 11:17:23 -05002903{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002904 if (width == 0 || height == 0)
2905 {
2906 return;
2907 }
2908
Jamie Madillad9f24e2016-02-12 09:27:24 -05002909 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002910
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002911 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002912 ASSERT(framebufferObject);
2913
2914 Rectangle area(x, y, width, height);
Jamie Madillc564c072017-06-01 12:45:42 -04002915 handleError(framebufferObject->readPixels(this, area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002916}
2917
2918void Context::copyTexImage2D(GLenum target,
2919 GLint level,
2920 GLenum internalformat,
2921 GLint x,
2922 GLint y,
2923 GLsizei width,
2924 GLsizei height,
2925 GLint border)
2926{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002927 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002928 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002929
Jamie Madillc29968b2016-01-20 11:17:23 -05002930 Rectangle sourceArea(x, y, width, height);
2931
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002932 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002933 Texture *texture =
2934 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002935 handleError(texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002936}
2937
2938void Context::copyTexSubImage2D(GLenum target,
2939 GLint level,
2940 GLint xoffset,
2941 GLint yoffset,
2942 GLint x,
2943 GLint y,
2944 GLsizei width,
2945 GLsizei height)
2946{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002947 if (width == 0 || height == 0)
2948 {
2949 return;
2950 }
2951
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002952 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002953 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002954
Jamie Madillc29968b2016-01-20 11:17:23 -05002955 Offset destOffset(xoffset, yoffset, 0);
2956 Rectangle sourceArea(x, y, width, height);
2957
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002958 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002959 Texture *texture =
2960 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002961 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002962}
2963
2964void Context::copyTexSubImage3D(GLenum target,
2965 GLint level,
2966 GLint xoffset,
2967 GLint yoffset,
2968 GLint zoffset,
2969 GLint x,
2970 GLint y,
2971 GLsizei width,
2972 GLsizei height)
2973{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002974 if (width == 0 || height == 0)
2975 {
2976 return;
2977 }
2978
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002979 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002980 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002981
Jamie Madillc29968b2016-01-20 11:17:23 -05002982 Offset destOffset(xoffset, yoffset, zoffset);
2983 Rectangle sourceArea(x, y, width, height);
2984
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002985 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002986 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002987 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002988}
2989
2990void Context::framebufferTexture2D(GLenum target,
2991 GLenum attachment,
2992 GLenum textarget,
2993 GLuint texture,
2994 GLint level)
2995{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002996 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002997 ASSERT(framebuffer);
2998
2999 if (texture != 0)
3000 {
3001 Texture *textureObj = getTexture(texture);
3002
3003 ImageIndex index = ImageIndex::MakeInvalid();
3004
3005 if (textarget == GL_TEXTURE_2D)
3006 {
3007 index = ImageIndex::Make2D(level);
3008 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08003009 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
3010 {
3011 ASSERT(level == 0);
3012 index = ImageIndex::Make2DMultisample();
3013 }
Jamie Madillc29968b2016-01-20 11:17:23 -05003014 else
3015 {
3016 ASSERT(IsCubeMapTextureTarget(textarget));
3017 index = ImageIndex::MakeCube(textarget, level);
3018 }
3019
Jamie Madilla02315b2017-02-23 14:14:47 -05003020 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
Jamie Madillc29968b2016-01-20 11:17:23 -05003021 }
3022 else
3023 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003024 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003025 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003026
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003027 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003028}
3029
3030void Context::framebufferRenderbuffer(GLenum target,
3031 GLenum attachment,
3032 GLenum renderbuffertarget,
3033 GLuint renderbuffer)
3034{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003035 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003036 ASSERT(framebuffer);
3037
3038 if (renderbuffer != 0)
3039 {
3040 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
Jamie Madilla02315b2017-02-23 14:14:47 -05003041
3042 framebuffer->setAttachment(this, GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
Jamie Madillc29968b2016-01-20 11:17:23 -05003043 renderbufferObject);
3044 }
3045 else
3046 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003047 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003048 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003049
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003050 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003051}
3052
3053void Context::framebufferTextureLayer(GLenum target,
3054 GLenum attachment,
3055 GLuint texture,
3056 GLint level,
3057 GLint layer)
3058{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003059 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003060 ASSERT(framebuffer);
3061
3062 if (texture != 0)
3063 {
3064 Texture *textureObject = getTexture(texture);
3065
3066 ImageIndex index = ImageIndex::MakeInvalid();
3067
3068 if (textureObject->getTarget() == GL_TEXTURE_3D)
3069 {
3070 index = ImageIndex::Make3D(level, layer);
3071 }
3072 else
3073 {
3074 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
3075 index = ImageIndex::Make2DArray(level, layer);
3076 }
3077
Jamie Madilla02315b2017-02-23 14:14:47 -05003078 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObject);
Jamie Madillc29968b2016-01-20 11:17:23 -05003079 }
3080 else
3081 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003082 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003083 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003084
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003085 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003086}
3087
3088void Context::drawBuffers(GLsizei n, const GLenum *bufs)
3089{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003090 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003091 ASSERT(framebuffer);
3092 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003093 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003094}
3095
3096void Context::readBuffer(GLenum mode)
3097{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003098 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003099 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003100 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003101}
3102
3103void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
3104{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003105 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003106 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003107
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003108 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003109 ASSERT(framebuffer);
3110
3111 // The specification isn't clear what should be done when the framebuffer isn't complete.
3112 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill4928b7c2017-06-20 12:57:39 -04003113 handleError(framebuffer->discard(this, numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003114}
3115
3116void Context::invalidateFramebuffer(GLenum target,
3117 GLsizei numAttachments,
3118 const GLenum *attachments)
3119{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003120 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003121 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003122
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003123 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003124 ASSERT(framebuffer);
3125
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003126 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003127 {
Jamie Madill437fa652016-05-03 15:13:24 -04003128 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003129 }
Jamie Madill437fa652016-05-03 15:13:24 -04003130
Jamie Madill4928b7c2017-06-20 12:57:39 -04003131 handleError(framebuffer->invalidate(this, numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003132}
3133
3134void Context::invalidateSubFramebuffer(GLenum target,
3135 GLsizei numAttachments,
3136 const GLenum *attachments,
3137 GLint x,
3138 GLint y,
3139 GLsizei width,
3140 GLsizei height)
3141{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003142 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003143 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003144
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003145 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003146 ASSERT(framebuffer);
3147
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003148 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003149 {
Jamie Madill437fa652016-05-03 15:13:24 -04003150 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003151 }
Jamie Madill437fa652016-05-03 15:13:24 -04003152
3153 Rectangle area(x, y, width, height);
Jamie Madill4928b7c2017-06-20 12:57:39 -04003154 handleError(framebuffer->invalidateSub(this, numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05003155}
3156
Jamie Madill73a84962016-02-12 09:27:23 -05003157void Context::texImage2D(GLenum target,
3158 GLint level,
3159 GLint internalformat,
3160 GLsizei width,
3161 GLsizei height,
3162 GLint border,
3163 GLenum format,
3164 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003165 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003166{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003167 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003168
3169 Extents size(width, height, 1);
3170 Texture *texture =
3171 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003172 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3173 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003174}
3175
3176void Context::texImage3D(GLenum target,
3177 GLint level,
3178 GLint internalformat,
3179 GLsizei width,
3180 GLsizei height,
3181 GLsizei depth,
3182 GLint border,
3183 GLenum format,
3184 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003185 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003186{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003187 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003188
3189 Extents size(width, height, depth);
3190 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003191 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3192 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003193}
3194
3195void Context::texSubImage2D(GLenum target,
3196 GLint level,
3197 GLint xoffset,
3198 GLint yoffset,
3199 GLsizei width,
3200 GLsizei height,
3201 GLenum format,
3202 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003203 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003204{
3205 // Zero sized uploads are valid but no-ops
3206 if (width == 0 || height == 0)
3207 {
3208 return;
3209 }
3210
Jamie Madillad9f24e2016-02-12 09:27:24 -05003211 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003212
3213 Box area(xoffset, yoffset, 0, width, height, 1);
3214 Texture *texture =
3215 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003216 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3217 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003218}
3219
3220void Context::texSubImage3D(GLenum target,
3221 GLint level,
3222 GLint xoffset,
3223 GLint yoffset,
3224 GLint zoffset,
3225 GLsizei width,
3226 GLsizei height,
3227 GLsizei depth,
3228 GLenum format,
3229 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003230 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003231{
3232 // Zero sized uploads are valid but no-ops
3233 if (width == 0 || height == 0 || depth == 0)
3234 {
3235 return;
3236 }
3237
Jamie Madillad9f24e2016-02-12 09:27:24 -05003238 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003239
3240 Box area(xoffset, yoffset, zoffset, width, height, depth);
3241 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003242 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3243 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003244}
3245
3246void Context::compressedTexImage2D(GLenum target,
3247 GLint level,
3248 GLenum internalformat,
3249 GLsizei width,
3250 GLsizei height,
3251 GLint border,
3252 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003253 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003254{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003255 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003256
3257 Extents size(width, height, 1);
3258 Texture *texture =
3259 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003260 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003261 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003262 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003263}
3264
3265void Context::compressedTexImage3D(GLenum target,
3266 GLint level,
3267 GLenum internalformat,
3268 GLsizei width,
3269 GLsizei height,
3270 GLsizei depth,
3271 GLint border,
3272 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003273 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003274{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003275 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003276
3277 Extents size(width, height, depth);
3278 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003279 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003280 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003281 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003282}
3283
3284void Context::compressedTexSubImage2D(GLenum target,
3285 GLint level,
3286 GLint xoffset,
3287 GLint yoffset,
3288 GLsizei width,
3289 GLsizei height,
3290 GLenum format,
3291 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003292 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003293{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003294 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003295
3296 Box area(xoffset, yoffset, 0, width, height, 1);
3297 Texture *texture =
3298 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003299 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003300 format, imageSize,
3301 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003302}
3303
3304void Context::compressedTexSubImage3D(GLenum target,
3305 GLint level,
3306 GLint xoffset,
3307 GLint yoffset,
3308 GLint zoffset,
3309 GLsizei width,
3310 GLsizei height,
3311 GLsizei depth,
3312 GLenum format,
3313 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003314 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003315{
3316 // Zero sized uploads are valid but no-ops
3317 if (width == 0 || height == 0)
3318 {
3319 return;
3320 }
3321
Jamie Madillad9f24e2016-02-12 09:27:24 -05003322 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003323
3324 Box area(xoffset, yoffset, zoffset, width, height, depth);
3325 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003326 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003327 format, imageSize,
3328 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003329}
3330
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003331void Context::generateMipmap(GLenum target)
3332{
3333 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003334 handleError(texture->generateMipmap(this));
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003335}
3336
Geoff Lang97073d12016-04-20 10:42:34 -07003337void Context::copyTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003338 GLint sourceLevel,
3339 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003340 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003341 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003342 GLint internalFormat,
3343 GLenum destType,
3344 GLboolean unpackFlipY,
3345 GLboolean unpackPremultiplyAlpha,
3346 GLboolean unpackUnmultiplyAlpha)
3347{
3348 syncStateForTexImage();
3349
3350 gl::Texture *sourceTexture = getTexture(sourceId);
3351 gl::Texture *destTexture = getTexture(destId);
Geoff Langfc72a072017-03-24 14:52:39 -04003352 handleError(destTexture->copyTexture(
3353 this, destTarget, destLevel, internalFormat, destType, sourceLevel, unpackFlipY == GL_TRUE,
3354 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003355}
3356
3357void Context::copySubTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003358 GLint sourceLevel,
3359 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003360 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003361 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003362 GLint xoffset,
3363 GLint yoffset,
3364 GLint x,
3365 GLint y,
3366 GLsizei width,
3367 GLsizei height,
3368 GLboolean unpackFlipY,
3369 GLboolean unpackPremultiplyAlpha,
3370 GLboolean unpackUnmultiplyAlpha)
3371{
3372 // Zero sized copies are valid but no-ops
3373 if (width == 0 || height == 0)
3374 {
3375 return;
3376 }
3377
3378 syncStateForTexImage();
3379
3380 gl::Texture *sourceTexture = getTexture(sourceId);
3381 gl::Texture *destTexture = getTexture(destId);
3382 Offset offset(xoffset, yoffset, 0);
3383 Rectangle area(x, y, width, height);
Geoff Langfc72a072017-03-24 14:52:39 -04003384 handleError(destTexture->copySubTexture(
3385 this, destTarget, destLevel, offset, sourceLevel, area, unpackFlipY == GL_TRUE,
3386 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003387}
3388
Geoff Lang47110bf2016-04-20 11:13:22 -07003389void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3390{
3391 syncStateForTexImage();
3392
3393 gl::Texture *sourceTexture = getTexture(sourceId);
3394 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003395 handleError(destTexture->copyCompressedTexture(this, sourceTexture));
Geoff Lang47110bf2016-04-20 11:13:22 -07003396}
3397
Geoff Lang496c02d2016-10-20 11:38:11 -07003398void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003399{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003400 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003401 ASSERT(buffer);
3402
Geoff Lang496c02d2016-10-20 11:38:11 -07003403 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003404}
3405
Jamie Madill876429b2017-04-20 15:46:24 -04003406void *Context::mapBuffer(GLenum target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003407{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003408 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003409 ASSERT(buffer);
3410
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003411 Error error = buffer->map(this, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003412 if (error.isError())
3413 {
Jamie Madill437fa652016-05-03 15:13:24 -04003414 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003415 return nullptr;
3416 }
3417
3418 return buffer->getMapPointer();
3419}
3420
3421GLboolean Context::unmapBuffer(GLenum target)
3422{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003423 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003424 ASSERT(buffer);
3425
3426 GLboolean result;
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003427 Error error = buffer->unmap(this, &result);
Olli Etuaho4f667482016-03-30 15:56:35 +03003428 if (error.isError())
3429 {
Jamie Madill437fa652016-05-03 15:13:24 -04003430 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003431 return GL_FALSE;
3432 }
3433
3434 return result;
3435}
3436
Jamie Madill876429b2017-04-20 15:46:24 -04003437void *Context::mapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003438{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003439 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003440 ASSERT(buffer);
3441
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003442 Error error = buffer->mapRange(this, offset, length, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003443 if (error.isError())
3444 {
Jamie Madill437fa652016-05-03 15:13:24 -04003445 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003446 return nullptr;
3447 }
3448
3449 return buffer->getMapPointer();
3450}
3451
3452void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3453{
3454 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3455}
3456
Jamie Madillad9f24e2016-02-12 09:27:24 -05003457void Context::syncStateForReadPixels()
3458{
3459 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3460}
3461
3462void Context::syncStateForTexImage()
3463{
3464 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3465}
3466
3467void Context::syncStateForClear()
3468{
3469 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3470}
3471
3472void Context::syncStateForBlit()
3473{
3474 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3475}
3476
Jamie Madillc20ab272016-06-09 07:20:46 -07003477void Context::activeTexture(GLenum texture)
3478{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003479 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003480}
3481
Jamie Madill876429b2017-04-20 15:46:24 -04003482void Context::blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003483{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003484 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003485}
3486
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003487void Context::blendEquation(GLenum mode)
3488{
3489 mGLState.setBlendEquation(mode, mode);
3490}
3491
Jamie Madillc20ab272016-06-09 07:20:46 -07003492void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3493{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003494 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003495}
3496
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003497void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3498{
3499 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3500}
3501
Jamie Madillc20ab272016-06-09 07:20:46 -07003502void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3503{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003504 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003505}
3506
Jamie Madill876429b2017-04-20 15:46:24 -04003507void Context::clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003508{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003509 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003510}
3511
Jamie Madill876429b2017-04-20 15:46:24 -04003512void Context::clearDepthf(GLfloat depth)
Jamie Madillc20ab272016-06-09 07:20:46 -07003513{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003514 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003515}
3516
3517void Context::clearStencil(GLint s)
3518{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003519 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003520}
3521
3522void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3523{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003524 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003525}
3526
3527void Context::cullFace(GLenum mode)
3528{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003529 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003530}
3531
3532void Context::depthFunc(GLenum func)
3533{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003534 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003535}
3536
3537void Context::depthMask(GLboolean flag)
3538{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003539 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003540}
3541
Jamie Madill876429b2017-04-20 15:46:24 -04003542void Context::depthRangef(GLfloat zNear, GLfloat zFar)
Jamie Madillc20ab272016-06-09 07:20:46 -07003543{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003544 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003545}
3546
3547void Context::disable(GLenum cap)
3548{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003549 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003550}
3551
3552void Context::disableVertexAttribArray(GLuint index)
3553{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003554 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003555}
3556
3557void Context::enable(GLenum cap)
3558{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003559 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003560}
3561
3562void Context::enableVertexAttribArray(GLuint index)
3563{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003564 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003565}
3566
3567void Context::frontFace(GLenum mode)
3568{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003569 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003570}
3571
3572void Context::hint(GLenum target, GLenum mode)
3573{
3574 switch (target)
3575 {
3576 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003577 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003578 break;
3579
3580 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003581 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003582 break;
3583
3584 default:
3585 UNREACHABLE();
3586 return;
3587 }
3588}
3589
3590void Context::lineWidth(GLfloat width)
3591{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003592 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003593}
3594
3595void Context::pixelStorei(GLenum pname, GLint param)
3596{
3597 switch (pname)
3598 {
3599 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003600 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003601 break;
3602
3603 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003604 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003605 break;
3606
3607 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003608 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003609 break;
3610
3611 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003612 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003613 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003614 break;
3615
3616 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003617 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003618 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003619 break;
3620
3621 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003622 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003623 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003624 break;
3625
3626 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003627 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003628 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003629 break;
3630
3631 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003632 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003633 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003634 break;
3635
3636 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003637 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003638 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003639 break;
3640
3641 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003642 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003643 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003644 break;
3645
3646 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003647 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003648 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003649 break;
3650
3651 default:
3652 UNREACHABLE();
3653 return;
3654 }
3655}
3656
3657void Context::polygonOffset(GLfloat factor, GLfloat units)
3658{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003659 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003660}
3661
Jamie Madill876429b2017-04-20 15:46:24 -04003662void Context::sampleCoverage(GLfloat value, GLboolean invert)
Jamie Madillc20ab272016-06-09 07:20:46 -07003663{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003664 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003665}
3666
3667void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3668{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003669 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003670}
3671
3672void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3673{
3674 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3675 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003676 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003677 }
3678
3679 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3680 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003681 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003682 }
3683}
3684
3685void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3686{
3687 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3688 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003689 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003690 }
3691
3692 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3693 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003694 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003695 }
3696}
3697
3698void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3699{
3700 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3701 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003702 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003703 }
3704
3705 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3706 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003707 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003708 }
3709}
3710
3711void Context::vertexAttrib1f(GLuint index, GLfloat x)
3712{
3713 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003714 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003715}
3716
3717void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3718{
3719 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003720 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003721}
3722
3723void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3724{
3725 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003726 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003727}
3728
3729void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3730{
3731 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003732 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003733}
3734
3735void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3736{
3737 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003738 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003739}
3740
3741void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3742{
3743 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003744 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003745}
3746
3747void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3748{
3749 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003750 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003751}
3752
3753void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3754{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003755 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003756}
3757
3758void Context::vertexAttribPointer(GLuint index,
3759 GLint size,
3760 GLenum type,
3761 GLboolean normalized,
3762 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003763 const void *ptr)
Jamie Madillc20ab272016-06-09 07:20:46 -07003764{
Shaodde78e82017-05-22 14:13:27 +08003765 mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size,
3766 type, normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003767}
3768
Shao80957d92017-02-20 21:25:59 +08003769void Context::vertexAttribFormat(GLuint attribIndex,
3770 GLint size,
3771 GLenum type,
3772 GLboolean normalized,
3773 GLuint relativeOffset)
3774{
3775 mGLState.setVertexAttribFormat(attribIndex, size, type, normalized == GL_TRUE, false,
3776 relativeOffset);
3777}
3778
3779void Context::vertexAttribIFormat(GLuint attribIndex,
3780 GLint size,
3781 GLenum type,
3782 GLuint relativeOffset)
3783{
3784 mGLState.setVertexAttribFormat(attribIndex, size, type, false, true, relativeOffset);
3785}
3786
3787void Context::vertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
3788{
Shaodde78e82017-05-22 14:13:27 +08003789 mGLState.setVertexAttribBinding(this, attribIndex, bindingIndex);
Shao80957d92017-02-20 21:25:59 +08003790}
3791
3792void Context::setVertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
3793{
3794 mGLState.setVertexBindingDivisor(bindingIndex, divisor);
3795}
3796
Jamie Madillc20ab272016-06-09 07:20:46 -07003797void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3798{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003799 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003800}
3801
3802void Context::vertexAttribIPointer(GLuint index,
3803 GLint size,
3804 GLenum type,
3805 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003806 const void *pointer)
Jamie Madillc20ab272016-06-09 07:20:46 -07003807{
Shaodde78e82017-05-22 14:13:27 +08003808 mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size,
3809 type, false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003810}
3811
3812void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3813{
3814 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003815 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003816}
3817
3818void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3819{
3820 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003821 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003822}
3823
3824void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3825{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003826 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003827}
3828
3829void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3830{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003831 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003832}
3833
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003834void Context::getVertexAttribiv(GLuint index, GLenum pname, GLint *params)
3835{
3836 const VertexAttribCurrentValueData &currentValues =
3837 getGLState().getVertexAttribCurrentValue(index);
3838 const VertexArray *vao = getGLState().getVertexArray();
3839 QueryVertexAttribiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3840 currentValues, pname, params);
3841}
3842
3843void Context::getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
3844{
3845 const VertexAttribCurrentValueData &currentValues =
3846 getGLState().getVertexAttribCurrentValue(index);
3847 const VertexArray *vao = getGLState().getVertexArray();
3848 QueryVertexAttribfv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3849 currentValues, pname, params);
3850}
3851
3852void Context::getVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
3853{
3854 const VertexAttribCurrentValueData &currentValues =
3855 getGLState().getVertexAttribCurrentValue(index);
3856 const VertexArray *vao = getGLState().getVertexArray();
3857 QueryVertexAttribIiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3858 currentValues, pname, params);
3859}
3860
3861void Context::getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
3862{
3863 const VertexAttribCurrentValueData &currentValues =
3864 getGLState().getVertexAttribCurrentValue(index);
3865 const VertexArray *vao = getGLState().getVertexArray();
3866 QueryVertexAttribIuiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3867 currentValues, pname, params);
3868}
3869
Jamie Madill876429b2017-04-20 15:46:24 -04003870void Context::getVertexAttribPointerv(GLuint index, GLenum pname, void **pointer)
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003871{
3872 const VertexAttribute &attrib = getGLState().getVertexArray()->getVertexAttribute(index);
3873 QueryVertexAttribPointerv(attrib, pname, pointer);
3874}
3875
Jamie Madillc20ab272016-06-09 07:20:46 -07003876void Context::debugMessageControl(GLenum source,
3877 GLenum type,
3878 GLenum severity,
3879 GLsizei count,
3880 const GLuint *ids,
3881 GLboolean enabled)
3882{
3883 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003884 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3885 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003886}
3887
3888void Context::debugMessageInsert(GLenum source,
3889 GLenum type,
3890 GLuint id,
3891 GLenum severity,
3892 GLsizei length,
3893 const GLchar *buf)
3894{
3895 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003896 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003897}
3898
3899void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3900{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003901 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003902}
3903
3904GLuint Context::getDebugMessageLog(GLuint count,
3905 GLsizei bufSize,
3906 GLenum *sources,
3907 GLenum *types,
3908 GLuint *ids,
3909 GLenum *severities,
3910 GLsizei *lengths,
3911 GLchar *messageLog)
3912{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003913 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3914 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003915}
3916
3917void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3918{
3919 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003920 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003921}
3922
3923void Context::popDebugGroup()
3924{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003925 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003926}
3927
Jamie Madill876429b2017-04-20 15:46:24 -04003928void Context::bufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage)
Jamie Madill29639852016-09-02 15:00:09 -04003929{
3930 Buffer *buffer = mGLState.getTargetBuffer(target);
3931 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003932 handleError(buffer->bufferData(this, target, data, size, usage));
Jamie Madill29639852016-09-02 15:00:09 -04003933}
3934
Jamie Madill876429b2017-04-20 15:46:24 -04003935void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04003936{
3937 if (data == nullptr)
3938 {
3939 return;
3940 }
3941
3942 Buffer *buffer = mGLState.getTargetBuffer(target);
3943 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003944 handleError(buffer->bufferSubData(this, target, data, size, offset));
Jamie Madill29639852016-09-02 15:00:09 -04003945}
3946
Jamie Madillef300b12016-10-07 15:12:09 -04003947void Context::attachShader(GLuint program, GLuint shader)
3948{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003949 auto programObject = mState.mShaderPrograms->getProgram(program);
3950 auto shaderObject = mState.mShaderPrograms->getShader(shader);
Jamie Madillef300b12016-10-07 15:12:09 -04003951 ASSERT(programObject && shaderObject);
3952 programObject->attachShader(shaderObject);
3953}
3954
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003955const Workarounds &Context::getWorkarounds() const
3956{
3957 return mWorkarounds;
3958}
3959
Jamie Madillb0817d12016-11-01 15:48:31 -04003960void Context::copyBufferSubData(GLenum readTarget,
3961 GLenum writeTarget,
3962 GLintptr readOffset,
3963 GLintptr writeOffset,
3964 GLsizeiptr size)
3965{
3966 // if size is zero, the copy is a successful no-op
3967 if (size == 0)
3968 {
3969 return;
3970 }
3971
3972 // TODO(jmadill): cache these.
3973 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3974 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3975
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003976 handleError(writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size));
Jamie Madillb0817d12016-11-01 15:48:31 -04003977}
3978
Jamie Madill01a80ee2016-11-07 12:06:18 -05003979void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3980{
3981 Program *programObject = getProgram(program);
3982 // TODO(jmadill): Re-use this from the validation if possible.
3983 ASSERT(programObject);
3984 programObject->bindAttributeLocation(index, name);
3985}
3986
3987void Context::bindBuffer(GLenum target, GLuint buffer)
3988{
3989 switch (target)
3990 {
3991 case GL_ARRAY_BUFFER:
3992 bindArrayBuffer(buffer);
3993 break;
3994 case GL_ELEMENT_ARRAY_BUFFER:
3995 bindElementArrayBuffer(buffer);
3996 break;
3997 case GL_COPY_READ_BUFFER:
3998 bindCopyReadBuffer(buffer);
3999 break;
4000 case GL_COPY_WRITE_BUFFER:
4001 bindCopyWriteBuffer(buffer);
4002 break;
4003 case GL_PIXEL_PACK_BUFFER:
4004 bindPixelPackBuffer(buffer);
4005 break;
4006 case GL_PIXEL_UNPACK_BUFFER:
4007 bindPixelUnpackBuffer(buffer);
4008 break;
4009 case GL_UNIFORM_BUFFER:
4010 bindGenericUniformBuffer(buffer);
4011 break;
4012 case GL_TRANSFORM_FEEDBACK_BUFFER:
4013 bindGenericTransformFeedbackBuffer(buffer);
4014 break;
Geoff Lang3b573612016-10-31 14:08:10 -04004015 case GL_ATOMIC_COUNTER_BUFFER:
Jiajia Qin6eafb042016-12-27 17:04:07 +08004016 bindGenericAtomicCounterBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004017 break;
4018 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08004019 bindGenericShaderStorageBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004020 break;
4021 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08004022 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004023 break;
4024 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05004025 if (buffer != 0)
4026 {
4027 // Binding buffers to this binding point is not implemented yet.
4028 UNIMPLEMENTED();
4029 }
Geoff Lang3b573612016-10-31 14:08:10 -04004030 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05004031
4032 default:
4033 UNREACHABLE();
4034 break;
4035 }
4036}
4037
Jiajia Qin6eafb042016-12-27 17:04:07 +08004038void Context::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
4039{
4040 bindBufferRange(target, index, buffer, 0, 0);
4041}
4042
4043void Context::bindBufferRange(GLenum target,
4044 GLuint index,
4045 GLuint buffer,
4046 GLintptr offset,
4047 GLsizeiptr size)
4048{
4049 switch (target)
4050 {
4051 case GL_TRANSFORM_FEEDBACK_BUFFER:
4052 bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
4053 bindGenericTransformFeedbackBuffer(buffer);
4054 break;
4055 case GL_UNIFORM_BUFFER:
4056 bindIndexedUniformBuffer(buffer, index, offset, size);
4057 bindGenericUniformBuffer(buffer);
4058 break;
4059 case GL_ATOMIC_COUNTER_BUFFER:
4060 bindIndexedAtomicCounterBuffer(buffer, index, offset, size);
4061 bindGenericAtomicCounterBuffer(buffer);
4062 break;
4063 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08004064 bindIndexedShaderStorageBuffer(buffer, index, offset, size);
4065 bindGenericShaderStorageBuffer(buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08004066 break;
4067 default:
4068 UNREACHABLE();
4069 break;
4070 }
4071}
4072
Jamie Madill01a80ee2016-11-07 12:06:18 -05004073void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
4074{
4075 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4076 {
4077 bindReadFramebuffer(framebuffer);
4078 }
4079
4080 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4081 {
4082 bindDrawFramebuffer(framebuffer);
4083 }
4084}
4085
4086void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
4087{
4088 ASSERT(target == GL_RENDERBUFFER);
4089 Renderbuffer *object =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05004090 mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
Jamie Madill4928b7c2017-06-20 12:57:39 -04004091 mGLState.setRenderbufferBinding(this, object);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004092}
4093
JiangYizhoubddc46b2016-12-09 09:50:51 +08004094void Context::texStorage2DMultisample(GLenum target,
4095 GLsizei samples,
4096 GLenum internalformat,
4097 GLsizei width,
4098 GLsizei height,
4099 GLboolean fixedsamplelocations)
4100{
4101 Extents size(width, height, 1);
4102 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05004103 handleError(texture->setStorageMultisample(this, target, samples, internalformat, size,
JiangYizhoubddc46b2016-12-09 09:50:51 +08004104 fixedsamplelocations));
4105}
4106
4107void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
4108{
Jamie Madilldd43e6c2017-03-24 14:18:49 -04004109 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
JiangYizhoubddc46b2016-12-09 09:50:51 +08004110 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
4111
4112 switch (pname)
4113 {
4114 case GL_SAMPLE_POSITION:
4115 handleError(framebuffer->getSamplePosition(index, val));
4116 break;
4117 default:
4118 UNREACHABLE();
4119 }
4120}
4121
Jamie Madille8fb6402017-02-14 17:56:40 -05004122void Context::renderbufferStorage(GLenum target,
4123 GLenum internalformat,
4124 GLsizei width,
4125 GLsizei height)
4126{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004127 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4128 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
4129
Jamie Madille8fb6402017-02-14 17:56:40 -05004130 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4928b7c2017-06-20 12:57:39 -04004131 handleError(renderbuffer->setStorage(this, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004132}
4133
4134void Context::renderbufferStorageMultisample(GLenum target,
4135 GLsizei samples,
4136 GLenum internalformat,
4137 GLsizei width,
4138 GLsizei height)
4139{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004140 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4141 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
Jamie Madille8fb6402017-02-14 17:56:40 -05004142
4143 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004144 handleError(
Jamie Madill4928b7c2017-06-20 12:57:39 -04004145 renderbuffer->setStorageMultisample(this, samples, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004146}
4147
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004148void Context::getSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)
4149{
4150 const FenceSync *syncObject = getFenceSync(sync);
Geoff Lang82483b92017-04-11 15:33:00 -04004151 handleError(QuerySynciv(syncObject, pname, bufSize, length, values));
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004152}
4153
JiangYizhoue18e6392017-02-20 10:32:23 +08004154void Context::getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
4155{
4156 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4157 QueryFramebufferParameteriv(framebuffer, pname, params);
4158}
4159
4160void Context::setFramebufferParameteri(GLenum target, GLenum pname, GLint param)
4161{
4162 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4163 SetFramebufferParameteri(framebuffer, pname, param);
4164}
4165
Jamie Madille14951e2017-03-09 18:55:16 -05004166Error Context::getScratchBuffer(size_t requestedSize, angle::MemoryBuffer **scratchBufferOut) const
4167{
4168 if (!mScratchBuffer.get(requestedSize, scratchBufferOut))
4169 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004170 return OutOfMemory() << "Failed to allocate internal buffer.";
Jamie Madille14951e2017-03-09 18:55:16 -05004171 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004172 return NoError();
Jamie Madille14951e2017-03-09 18:55:16 -05004173}
4174
Xinghua Cao2b396592017-03-29 15:36:04 +08004175void Context::dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ)
4176{
4177 if (numGroupsX == 0u || numGroupsY == 0u || numGroupsZ == 0u)
4178 {
4179 return;
4180 }
4181
Jamie Madillfe548342017-06-19 11:13:24 -04004182 mImplementation->dispatchCompute(this, numGroupsX, numGroupsY, numGroupsZ);
Xinghua Cao2b396592017-03-29 15:36:04 +08004183}
4184
JiangYizhou165361c2017-06-07 14:56:57 +08004185void Context::texStorage2D(GLenum target,
4186 GLsizei levels,
4187 GLenum internalFormat,
4188 GLsizei width,
4189 GLsizei height)
4190{
4191 Extents size(width, height, 1);
4192 Texture *texture = getTargetTexture(target);
4193 handleError(texture->setStorage(this, target, levels, internalFormat, size));
4194}
4195
4196void Context::texStorage3D(GLenum target,
4197 GLsizei levels,
4198 GLenum internalFormat,
4199 GLsizei width,
4200 GLsizei height,
4201 GLsizei depth)
4202{
4203 Extents size(width, height, depth);
4204 Texture *texture = getTargetTexture(target);
4205 handleError(texture->setStorage(this, target, levels, internalFormat, size));
4206}
4207
Jamie Madillc1d770e2017-04-13 17:31:24 -04004208GLenum Context::checkFramebufferStatus(GLenum target)
4209{
4210 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4211 ASSERT(framebuffer);
4212
4213 return framebuffer->checkStatus(this);
4214}
4215
4216void Context::compileShader(GLuint shader)
4217{
4218 Shader *shaderObject = GetValidShader(this, shader);
4219 if (!shaderObject)
4220 {
4221 return;
4222 }
4223 shaderObject->compile(this);
4224}
4225
4226void Context::deleteBuffers(GLsizei n, const GLuint *buffers)
4227{
4228 for (int i = 0; i < n; i++)
4229 {
4230 deleteBuffer(buffers[i]);
4231 }
4232}
4233
4234void Context::deleteFramebuffers(GLsizei n, const GLuint *framebuffers)
4235{
4236 for (int i = 0; i < n; i++)
4237 {
4238 if (framebuffers[i] != 0)
4239 {
4240 deleteFramebuffer(framebuffers[i]);
4241 }
4242 }
4243}
4244
4245void Context::deleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)
4246{
4247 for (int i = 0; i < n; i++)
4248 {
4249 deleteRenderbuffer(renderbuffers[i]);
4250 }
4251}
4252
4253void Context::deleteTextures(GLsizei n, const GLuint *textures)
4254{
4255 for (int i = 0; i < n; i++)
4256 {
4257 if (textures[i] != 0)
4258 {
4259 deleteTexture(textures[i]);
4260 }
4261 }
4262}
4263
4264void Context::detachShader(GLuint program, GLuint shader)
4265{
4266 Program *programObject = getProgram(program);
4267 ASSERT(programObject);
4268
4269 Shader *shaderObject = getShader(shader);
4270 ASSERT(shaderObject);
4271
4272 programObject->detachShader(this, shaderObject);
4273}
4274
4275void Context::genBuffers(GLsizei n, GLuint *buffers)
4276{
4277 for (int i = 0; i < n; i++)
4278 {
4279 buffers[i] = createBuffer();
4280 }
4281}
4282
4283void Context::genFramebuffers(GLsizei n, GLuint *framebuffers)
4284{
4285 for (int i = 0; i < n; i++)
4286 {
4287 framebuffers[i] = createFramebuffer();
4288 }
4289}
4290
4291void Context::genRenderbuffers(GLsizei n, GLuint *renderbuffers)
4292{
4293 for (int i = 0; i < n; i++)
4294 {
4295 renderbuffers[i] = createRenderbuffer();
4296 }
4297}
4298
4299void Context::genTextures(GLsizei n, GLuint *textures)
4300{
4301 for (int i = 0; i < n; i++)
4302 {
4303 textures[i] = createTexture();
4304 }
4305}
4306
4307void Context::getActiveAttrib(GLuint program,
4308 GLuint index,
4309 GLsizei bufsize,
4310 GLsizei *length,
4311 GLint *size,
4312 GLenum *type,
4313 GLchar *name)
4314{
4315 Program *programObject = getProgram(program);
4316 ASSERT(programObject);
4317 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
4318}
4319
4320void Context::getActiveUniform(GLuint program,
4321 GLuint index,
4322 GLsizei bufsize,
4323 GLsizei *length,
4324 GLint *size,
4325 GLenum *type,
4326 GLchar *name)
4327{
4328 Program *programObject = getProgram(program);
4329 ASSERT(programObject);
4330 programObject->getActiveUniform(index, bufsize, length, size, type, name);
4331}
4332
4333void Context::getAttachedShaders(GLuint program, GLsizei maxcount, GLsizei *count, GLuint *shaders)
4334{
4335 Program *programObject = getProgram(program);
4336 ASSERT(programObject);
4337 programObject->getAttachedShaders(maxcount, count, shaders);
4338}
4339
4340GLint Context::getAttribLocation(GLuint program, const GLchar *name)
4341{
4342 Program *programObject = getProgram(program);
4343 ASSERT(programObject);
4344 return programObject->getAttributeLocation(name);
4345}
4346
4347void Context::getBooleanv(GLenum pname, GLboolean *params)
4348{
4349 GLenum nativeType;
4350 unsigned int numParams = 0;
4351 getQueryParameterInfo(pname, &nativeType, &numParams);
4352
4353 if (nativeType == GL_BOOL)
4354 {
4355 getBooleanvImpl(pname, params);
4356 }
4357 else
4358 {
4359 CastStateValues(this, nativeType, pname, numParams, params);
4360 }
4361}
4362
4363void Context::getFloatv(GLenum pname, GLfloat *params)
4364{
4365 GLenum nativeType;
4366 unsigned int numParams = 0;
4367 getQueryParameterInfo(pname, &nativeType, &numParams);
4368
4369 if (nativeType == GL_FLOAT)
4370 {
4371 getFloatvImpl(pname, params);
4372 }
4373 else
4374 {
4375 CastStateValues(this, nativeType, pname, numParams, params);
4376 }
4377}
4378
4379void Context::getIntegerv(GLenum pname, GLint *params)
4380{
4381 GLenum nativeType;
4382 unsigned int numParams = 0;
4383 getQueryParameterInfo(pname, &nativeType, &numParams);
4384
4385 if (nativeType == GL_INT)
4386 {
4387 getIntegervImpl(pname, params);
4388 }
4389 else
4390 {
4391 CastStateValues(this, nativeType, pname, numParams, params);
4392 }
4393}
4394
4395void Context::getProgramiv(GLuint program, GLenum pname, GLint *params)
4396{
4397 Program *programObject = getProgram(program);
4398 ASSERT(programObject);
Jamie Madillffe00c02017-06-27 16:26:55 -04004399 QueryProgramiv(this, programObject, pname, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004400}
4401
Jamie Madillbe849e42017-05-02 15:49:00 -04004402void Context::getProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei *length, GLchar *infolog)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004403{
4404 Program *programObject = getProgram(program);
4405 ASSERT(programObject);
4406 programObject->getInfoLog(bufsize, length, infolog);
4407}
4408
4409void Context::getShaderiv(GLuint shader, GLenum pname, GLint *params)
4410{
4411 Shader *shaderObject = getShader(shader);
4412 ASSERT(shaderObject);
Jamie Madillbd044ed2017-06-05 12:59:21 -04004413 QueryShaderiv(this, shaderObject, pname, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004414}
4415
4416void Context::getShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *infolog)
4417{
4418 Shader *shaderObject = getShader(shader);
4419 ASSERT(shaderObject);
Jamie Madillbd044ed2017-06-05 12:59:21 -04004420 shaderObject->getInfoLog(this, bufsize, length, infolog);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004421}
4422
4423void Context::getShaderPrecisionFormat(GLenum shadertype,
4424 GLenum precisiontype,
4425 GLint *range,
4426 GLint *precision)
4427{
4428 // TODO(jmadill): Compute shaders.
4429
4430 switch (shadertype)
4431 {
4432 case GL_VERTEX_SHADER:
4433 switch (precisiontype)
4434 {
4435 case GL_LOW_FLOAT:
4436 mCaps.vertexLowpFloat.get(range, precision);
4437 break;
4438 case GL_MEDIUM_FLOAT:
4439 mCaps.vertexMediumpFloat.get(range, precision);
4440 break;
4441 case GL_HIGH_FLOAT:
4442 mCaps.vertexHighpFloat.get(range, precision);
4443 break;
4444
4445 case GL_LOW_INT:
4446 mCaps.vertexLowpInt.get(range, precision);
4447 break;
4448 case GL_MEDIUM_INT:
4449 mCaps.vertexMediumpInt.get(range, precision);
4450 break;
4451 case GL_HIGH_INT:
4452 mCaps.vertexHighpInt.get(range, precision);
4453 break;
4454
4455 default:
4456 UNREACHABLE();
4457 return;
4458 }
4459 break;
4460
4461 case GL_FRAGMENT_SHADER:
4462 switch (precisiontype)
4463 {
4464 case GL_LOW_FLOAT:
4465 mCaps.fragmentLowpFloat.get(range, precision);
4466 break;
4467 case GL_MEDIUM_FLOAT:
4468 mCaps.fragmentMediumpFloat.get(range, precision);
4469 break;
4470 case GL_HIGH_FLOAT:
4471 mCaps.fragmentHighpFloat.get(range, precision);
4472 break;
4473
4474 case GL_LOW_INT:
4475 mCaps.fragmentLowpInt.get(range, precision);
4476 break;
4477 case GL_MEDIUM_INT:
4478 mCaps.fragmentMediumpInt.get(range, precision);
4479 break;
4480 case GL_HIGH_INT:
4481 mCaps.fragmentHighpInt.get(range, precision);
4482 break;
4483
4484 default:
4485 UNREACHABLE();
4486 return;
4487 }
4488 break;
4489
4490 default:
4491 UNREACHABLE();
4492 return;
4493 }
4494}
4495
4496void Context::getShaderSource(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source)
4497{
4498 Shader *shaderObject = getShader(shader);
4499 ASSERT(shaderObject);
4500 shaderObject->getSource(bufsize, length, source);
4501}
4502
4503void Context::getUniformfv(GLuint program, GLint location, GLfloat *params)
4504{
4505 Program *programObject = getProgram(program);
4506 ASSERT(programObject);
4507 programObject->getUniformfv(location, params);
4508}
4509
4510void Context::getUniformiv(GLuint program, GLint location, GLint *params)
4511{
4512 Program *programObject = getProgram(program);
4513 ASSERT(programObject);
4514 programObject->getUniformiv(location, params);
4515}
4516
4517GLint Context::getUniformLocation(GLuint program, const GLchar *name)
4518{
4519 Program *programObject = getProgram(program);
4520 ASSERT(programObject);
4521 return programObject->getUniformLocation(name);
4522}
4523
4524GLboolean Context::isBuffer(GLuint buffer)
4525{
4526 if (buffer == 0)
4527 {
4528 return GL_FALSE;
4529 }
4530
4531 return (getBuffer(buffer) ? GL_TRUE : GL_FALSE);
4532}
4533
4534GLboolean Context::isEnabled(GLenum cap)
4535{
4536 return mGLState.getEnableFeature(cap);
4537}
4538
4539GLboolean Context::isFramebuffer(GLuint framebuffer)
4540{
4541 if (framebuffer == 0)
4542 {
4543 return GL_FALSE;
4544 }
4545
4546 return (getFramebuffer(framebuffer) ? GL_TRUE : GL_FALSE);
4547}
4548
4549GLboolean Context::isProgram(GLuint program)
4550{
4551 if (program == 0)
4552 {
4553 return GL_FALSE;
4554 }
4555
4556 return (getProgram(program) ? GL_TRUE : GL_FALSE);
4557}
4558
4559GLboolean Context::isRenderbuffer(GLuint renderbuffer)
4560{
4561 if (renderbuffer == 0)
4562 {
4563 return GL_FALSE;
4564 }
4565
4566 return (getRenderbuffer(renderbuffer) ? GL_TRUE : GL_FALSE);
4567}
4568
4569GLboolean Context::isShader(GLuint shader)
4570{
4571 if (shader == 0)
4572 {
4573 return GL_FALSE;
4574 }
4575
4576 return (getShader(shader) ? GL_TRUE : GL_FALSE);
4577}
4578
4579GLboolean Context::isTexture(GLuint texture)
4580{
4581 if (texture == 0)
4582 {
4583 return GL_FALSE;
4584 }
4585
4586 return (getTexture(texture) ? GL_TRUE : GL_FALSE);
4587}
4588
4589void Context::linkProgram(GLuint program)
4590{
4591 Program *programObject = getProgram(program);
4592 ASSERT(programObject);
4593 handleError(programObject->link(this));
4594}
4595
4596void Context::releaseShaderCompiler()
4597{
Jamie Madill4928b7c2017-06-20 12:57:39 -04004598 mCompiler.set(this, nullptr);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004599}
4600
4601void Context::shaderBinary(GLsizei n,
4602 const GLuint *shaders,
4603 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04004604 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004605 GLsizei length)
4606{
4607 // No binary shader formats are supported.
4608 UNIMPLEMENTED();
4609}
4610
4611void Context::shaderSource(GLuint shader,
4612 GLsizei count,
4613 const GLchar *const *string,
4614 const GLint *length)
4615{
4616 Shader *shaderObject = getShader(shader);
4617 ASSERT(shaderObject);
4618 shaderObject->setSource(count, string, length);
4619}
4620
4621void Context::stencilFunc(GLenum func, GLint ref, GLuint mask)
4622{
4623 stencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
4624}
4625
4626void Context::stencilMask(GLuint mask)
4627{
4628 stencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4629}
4630
4631void Context::stencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4632{
4633 stencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4634}
4635
4636void Context::uniform1f(GLint location, GLfloat x)
4637{
4638 Program *program = mGLState.getProgram();
4639 program->setUniform1fv(location, 1, &x);
4640}
4641
4642void Context::uniform1fv(GLint location, GLsizei count, const GLfloat *v)
4643{
4644 Program *program = mGLState.getProgram();
4645 program->setUniform1fv(location, count, v);
4646}
4647
4648void Context::uniform1i(GLint location, GLint x)
4649{
4650 Program *program = mGLState.getProgram();
4651 program->setUniform1iv(location, 1, &x);
4652}
4653
4654void Context::uniform1iv(GLint location, GLsizei count, const GLint *v)
4655{
4656 Program *program = mGLState.getProgram();
4657 program->setUniform1iv(location, count, v);
4658}
4659
4660void Context::uniform2f(GLint location, GLfloat x, GLfloat y)
4661{
4662 GLfloat xy[2] = {x, y};
4663 Program *program = mGLState.getProgram();
4664 program->setUniform2fv(location, 1, xy);
4665}
4666
4667void Context::uniform2fv(GLint location, GLsizei count, const GLfloat *v)
4668{
4669 Program *program = mGLState.getProgram();
4670 program->setUniform2fv(location, count, v);
4671}
4672
4673void Context::uniform2i(GLint location, GLint x, GLint y)
4674{
4675 GLint xy[2] = {x, y};
4676 Program *program = mGLState.getProgram();
4677 program->setUniform2iv(location, 1, xy);
4678}
4679
4680void Context::uniform2iv(GLint location, GLsizei count, const GLint *v)
4681{
4682 Program *program = mGLState.getProgram();
4683 program->setUniform2iv(location, count, v);
4684}
4685
4686void Context::uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4687{
4688 GLfloat xyz[3] = {x, y, z};
4689 Program *program = mGLState.getProgram();
4690 program->setUniform3fv(location, 1, xyz);
4691}
4692
4693void Context::uniform3fv(GLint location, GLsizei count, const GLfloat *v)
4694{
4695 Program *program = mGLState.getProgram();
4696 program->setUniform3fv(location, count, v);
4697}
4698
4699void Context::uniform3i(GLint location, GLint x, GLint y, GLint z)
4700{
4701 GLint xyz[3] = {x, y, z};
4702 Program *program = mGLState.getProgram();
4703 program->setUniform3iv(location, 1, xyz);
4704}
4705
4706void Context::uniform3iv(GLint location, GLsizei count, const GLint *v)
4707{
4708 Program *program = mGLState.getProgram();
4709 program->setUniform3iv(location, count, v);
4710}
4711
4712void Context::uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4713{
4714 GLfloat xyzw[4] = {x, y, z, w};
4715 Program *program = mGLState.getProgram();
4716 program->setUniform4fv(location, 1, xyzw);
4717}
4718
4719void Context::uniform4fv(GLint location, GLsizei count, const GLfloat *v)
4720{
4721 Program *program = mGLState.getProgram();
4722 program->setUniform4fv(location, count, v);
4723}
4724
4725void Context::uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4726{
4727 GLint xyzw[4] = {x, y, z, w};
4728 Program *program = mGLState.getProgram();
4729 program->setUniform4iv(location, 1, xyzw);
4730}
4731
4732void Context::uniform4iv(GLint location, GLsizei count, const GLint *v)
4733{
4734 Program *program = mGLState.getProgram();
4735 program->setUniform4iv(location, count, v);
4736}
4737
4738void Context::uniformMatrix2fv(GLint location,
4739 GLsizei count,
4740 GLboolean transpose,
4741 const GLfloat *value)
4742{
4743 Program *program = mGLState.getProgram();
4744 program->setUniformMatrix2fv(location, count, transpose, value);
4745}
4746
4747void Context::uniformMatrix3fv(GLint location,
4748 GLsizei count,
4749 GLboolean transpose,
4750 const GLfloat *value)
4751{
4752 Program *program = mGLState.getProgram();
4753 program->setUniformMatrix3fv(location, count, transpose, value);
4754}
4755
4756void Context::uniformMatrix4fv(GLint location,
4757 GLsizei count,
4758 GLboolean transpose,
4759 const GLfloat *value)
4760{
4761 Program *program = mGLState.getProgram();
4762 program->setUniformMatrix4fv(location, count, transpose, value);
4763}
4764
4765void Context::validateProgram(GLuint program)
4766{
4767 Program *programObject = getProgram(program);
4768 ASSERT(programObject);
4769 programObject->validate(mCaps);
4770}
4771
Jamie Madilld04908b2017-06-09 14:15:35 -04004772void Context::getProgramBinary(GLuint program,
4773 GLsizei bufSize,
4774 GLsizei *length,
4775 GLenum *binaryFormat,
4776 void *binary)
4777{
4778 Program *programObject = getProgram(program);
4779 ASSERT(programObject != nullptr);
4780
4781 handleError(programObject->saveBinary(this, binaryFormat, binary, bufSize, length));
4782}
4783
4784void Context::programBinary(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length)
4785{
4786 Program *programObject = getProgram(program);
4787 ASSERT(programObject != nullptr);
4788
4789 handleError(programObject->loadBinary(this, binaryFormat, binary, length));
4790}
4791
Jamie Madillc29968b2016-01-20 11:17:23 -05004792} // namespace gl