blob: ffc6e82cf1bae44f788e0d3e281fcd3f3d521827 [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 Madillb9293972015-02-19 11:07:54 -050012#include <iterator>
13#include <sstream>
Sami Väisänene45e53b2016-05-25 10:36:04 +030014#include <string.h>
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 Madill9dd0cf02014-11-24 11:38:51 -050023#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"
37#include "libANGLE/formatutils.h"
38#include "libANGLE/validationES.h"
Kenneth Russellf2f6f652016-10-05 19:53:23 -070039#include "libANGLE/Workarounds.h"
Jamie Madill437fa652016-05-03 15:13:24 -040040#include "libANGLE/renderer/ContextImpl.h"
Jamie Madill53ea9cc2016-05-17 10:12:52 -040041#include "libANGLE/renderer/EGLImplFactory.h"
Martin Radev66fb8202016-07-28 11:45:20 +030042#include "libANGLE/queryconversions.h"
Geoff Langc1984ed2016-10-07 12:41:00 -040043#include "libANGLE/queryutils.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();
121 return gl::Error(GL_INVALID_OPERATION, "Unreachable Error");
122 }
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 {
132 const OffsetBindingPointer<gl::Buffer> &buffer =
133 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
Martin Radev9d901792016-07-15 15:58:58 +0300202std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
203{
204 std::string labelName;
205 if (label != nullptr)
206 {
207 size_t labelLength = length < 0 ? strlen(label) : length;
208 labelName = std::string(label, labelLength);
209 }
210 return labelName;
211}
212
213void GetObjectLabelBase(const std::string &objectLabel,
214 GLsizei bufSize,
215 GLsizei *length,
216 GLchar *label)
217{
218 size_t writeLength = objectLabel.length();
219 if (label != nullptr && bufSize > 0)
220 {
221 writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
222 std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
223 label[writeLength] = '\0';
224 }
225
226 if (length != nullptr)
227 {
228 *length = static_cast<GLsizei>(writeLength);
229 }
230}
231
Geoff Langf6db0982015-08-25 13:04:00 -0400232} // anonymous namespace
233
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000234namespace gl
235{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000236
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400237Context::Context(rx::EGLImplFactory *implFactory,
238 const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400239 const Context *shareContext,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500240 const egl::AttributeMap &attribs)
Martin Radev1be913c2016-07-11 17:59:16 +0300241
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500242 : ValidationContext(shareContext,
243 GetClientVersion(attribs),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700244 &mGLState,
Jamie Madillf25855c2015-11-03 11:06:18 -0500245 mCaps,
246 mTextureCaps,
247 mExtensions,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500248 mLimitations,
Jamie Madill01a80ee2016-11-07 12:06:18 -0500249 mFramebufferMap,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500250 GetNoError(attribs)),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700251 mImplementation(implFactory->createContext(mState)),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500252 mCompiler(nullptr),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400253 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500254 mClientType(EGL_OPENGL_ES_API),
255 mHasBeenCurrent(false),
256 mContextLost(false),
257 mResetStatus(GL_NO_ERROR),
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700258 mContextLostForced(false),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500259 mResetStrategy(GetResetStrategy(attribs)),
260 mRobustAccess(GetRobustAccess(attribs)),
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500261 mCurrentSurface(nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000262{
Geoff Lang077f20a2016-11-01 10:08:02 -0400263 if (mRobustAccess)
264 {
265 UNIMPLEMENTED();
266 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000267
Geoff Langc287ea62016-09-16 14:46:51 -0400268 initCaps(GetWebGLContext(attribs));
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700269 initWorkarounds();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400270
Geoff Langeb66a6e2016-10-31 13:06:12 -0400271 mGLState.initialize(mCaps, mExtensions, getClientVersion(), GetDebug(attribs),
Geoff Langf41a7152016-09-19 15:11:17 -0400272 GetBindGeneratesResource(attribs));
Régis Fénéon83107972015-02-05 12:57:44 +0100273
Shannon Woods53a94a82014-06-24 15:20:36 -0400274 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400275
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000276 // [OpenGL ES 2.0.24] section 3.7 page 83:
277 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
278 // and cube map texture state vectors respectively associated with them.
279 // In order that access to these initial textures not be lost, they are treated as texture
280 // objects all of whose names are 0.
281
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400282 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500283 mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500284
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400285 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500286 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400287
Geoff Langeb66a6e2016-10-31 13:06:12 -0400288 if (getClientVersion() >= Version(3, 0))
Geoff Lang76b10c92014-09-05 16:28:14 -0400289 {
290 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400291 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500292 mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400293
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400294 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500295 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400296 }
Geoff Lang3b573612016-10-31 14:08:10 -0400297 if (getClientVersion() >= Version(3, 1))
298 {
299 Texture *zeroTexture2DMultisample =
300 new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_MULTISAMPLE);
301 mZeroTextures[GL_TEXTURE_2D_MULTISAMPLE].set(zeroTexture2DMultisample);
302 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000303
Ian Ewellbda75592016-04-18 17:25:54 -0400304 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
305 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400306 Texture *zeroTextureExternal =
307 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Ian Ewellbda75592016-04-18 17:25:54 -0400308 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(zeroTextureExternal);
309 }
310
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700311 mGLState.initializeZeroTextures(mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500312
Jamie Madill57a89722013-07-02 11:57:03 -0400313 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000314 bindArrayBuffer(0);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800315 bindDrawIndirectBuffer(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000316 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400317
Jamie Madill01a80ee2016-11-07 12:06:18 -0500318 bindRenderbuffer(GL_RENDERBUFFER, 0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000319
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000320 bindGenericUniformBuffer(0);
Geoff Lang4dc3af02016-11-18 14:09:27 -0500321 for (unsigned int i = 0; i < mCaps.maxUniformBufferBindings; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000322 {
323 bindIndexedUniformBuffer(0, i, 0, -1);
324 }
325
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000326 bindCopyReadBuffer(0);
327 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000328 bindPixelPackBuffer(0);
329 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000330
Geoff Langeb66a6e2016-10-31 13:06:12 -0400331 if (getClientVersion() >= Version(3, 0))
Geoff Lang1a683462015-09-29 15:09:59 -0400332 {
333 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
334 // In the initial state, a default transform feedback object is bound and treated as
335 // a transform feedback object with a name of zero. That object is bound any time
336 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400337 bindTransformFeedback(0);
338 }
Geoff Langc8058452014-02-03 12:04:11 -0500339
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700340 mCompiler = new Compiler(mImplementation.get(), mState);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500341
342 // Initialize dirty bit masks
343 // TODO(jmadill): additional ES3 state
344 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
345 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
346 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
347 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
348 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
349 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400350 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500351 // No dirty objects.
352
353 // Readpixels uses the pack state and read FBO
354 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
355 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
356 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
357 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
358 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400359 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500360 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
361
362 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
363 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
364 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
365 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
366 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
367 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
368 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
369 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
370 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
371 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
372 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
373 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
374
375 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
376 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700377 mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500378 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
379 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400380
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400381 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000382}
383
384Context::~Context()
385{
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700386 mGLState.reset();
Geoff Lang21329412014-12-02 20:50:30 +0000387
Corentin Wallez37c39792015-08-20 14:19:46 -0400388 for (auto framebuffer : mFramebufferMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000389 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400390 // Default framebuffer are owned by their respective Surface
Geoff Langf6227922015-09-04 11:05:47 -0400391 if (framebuffer.second != nullptr && framebuffer.second->id() != 0)
Corentin Wallez37c39792015-08-20 14:19:46 -0400392 {
393 SafeDelete(framebuffer.second);
394 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000395 }
396
Corentin Wallez80b24112015-08-25 16:41:57 -0400397 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000398 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400399 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000400 }
401
Corentin Wallez80b24112015-08-25 16:41:57 -0400402 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000403 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400404 if (query.second != nullptr)
405 {
406 query.second->release();
407 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000408 }
409
Corentin Wallez80b24112015-08-25 16:41:57 -0400410 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400411 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400412 SafeDelete(vertexArray.second);
Jamie Madill57a89722013-07-02 11:57:03 -0400413 }
414
Corentin Wallez80b24112015-08-25 16:41:57 -0400415 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500416 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500417 if (transformFeedback.second != nullptr)
418 {
419 transformFeedback.second->release();
420 }
Geoff Langc8058452014-02-03 12:04:11 -0500421 }
422
Jamie Madilldedd7b92014-11-05 16:30:36 -0500423 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400424 {
Jamie Madilldedd7b92014-11-05 16:30:36 -0500425 zeroTexture.second.set(NULL);
Geoff Lang76b10c92014-09-05 16:28:14 -0400426 }
427 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000428
Corentin Wallez51706ea2015-08-07 14:39:22 -0400429 if (mCurrentSurface != nullptr)
430 {
431 releaseSurface();
432 }
433
Geoff Lang492a7e42014-11-05 13:27:06 -0500434 SafeDelete(mCompiler);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000435}
436
daniel@transgaming.comad629872012-11-28 19:32:06 +0000437void Context::makeCurrent(egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000438{
Jamie Madill77a72f62015-04-14 11:18:32 -0400439 ASSERT(surface != nullptr);
440
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000441 if (!mHasBeenCurrent)
442 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000443 initRendererString();
Geoff Langc339c4e2016-11-29 10:37:36 -0500444 initVersionStrings();
Geoff Langcec35902014-04-16 10:52:36 -0400445 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000446
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700447 mGLState.setViewportParams(0, 0, surface->getWidth(), surface->getHeight());
448 mGLState.setScissorParams(0, 0, surface->getWidth(), surface->getHeight());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000449
450 mHasBeenCurrent = true;
451 }
452
Jamie Madill1b94d432015-08-07 13:23:23 -0400453 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700454 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400455
Corentin Wallez51706ea2015-08-07 14:39:22 -0400456 if (mCurrentSurface)
457 {
458 releaseSurface();
459 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000460 surface->setIsCurrent(true);
Corentin Wallez37c39792015-08-20 14:19:46 -0400461 mCurrentSurface = surface;
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000462
Corentin Wallez37c39792015-08-20 14:19:46 -0400463 // Update default framebuffer, the binding of the previous default
464 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400465 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400466 Framebuffer *newDefault = surface->getDefaultFramebuffer();
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700467 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400468 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700469 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400470 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700471 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400472 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700473 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400474 }
475 mFramebufferMap[0] = newDefault;
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400476 }
Ian Ewell292f0052016-02-04 10:37:32 -0500477
478 // Notify the renderer of a context switch
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700479 mImplementation->onMakeCurrent(mState);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000480}
481
Jamie Madill77a72f62015-04-14 11:18:32 -0400482void Context::releaseSurface()
483{
Corentin Wallez37c39792015-08-20 14:19:46 -0400484 ASSERT(mCurrentSurface != nullptr);
485
486 // Remove the default framebuffer
Corentin Wallez51706ea2015-08-07 14:39:22 -0400487 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400488 Framebuffer *currentDefault = mCurrentSurface->getDefaultFramebuffer();
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700489 if (mGLState.getReadFramebuffer() == currentDefault)
Corentin Wallez37c39792015-08-20 14:19:46 -0400490 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700491 mGLState.setReadFramebufferBinding(nullptr);
Corentin Wallez37c39792015-08-20 14:19:46 -0400492 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700493 if (mGLState.getDrawFramebuffer() == currentDefault)
Corentin Wallez37c39792015-08-20 14:19:46 -0400494 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700495 mGLState.setDrawFramebufferBinding(nullptr);
Corentin Wallez37c39792015-08-20 14:19:46 -0400496 }
497 mFramebufferMap.erase(0);
Corentin Wallez51706ea2015-08-07 14:39:22 -0400498 }
499
Corentin Wallez51706ea2015-08-07 14:39:22 -0400500 mCurrentSurface->setIsCurrent(false);
501 mCurrentSurface = nullptr;
Jamie Madill77a72f62015-04-14 11:18:32 -0400502}
503
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000504GLuint Context::createBuffer()
505{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500506 return mState.mBuffers->createBuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000507}
508
509GLuint Context::createProgram()
510{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500511 return mState.mShaderPrograms->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000512}
513
514GLuint Context::createShader(GLenum type)
515{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500516 return mState.mShaderPrograms->createShader(mImplementation.get(), mLimitations, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000517}
518
519GLuint Context::createTexture()
520{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500521 return mState.mTextures->createTexture();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000522}
523
524GLuint Context::createRenderbuffer()
525{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500526 return mState.mRenderbuffers->createRenderbuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000527}
528
Geoff Lang882033e2014-09-30 11:26:07 -0400529GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400530{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500531 GLuint handle = mState.mFenceSyncs->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400532
Cooper Partind8e62a32015-01-29 15:21:25 -0800533 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400534}
535
Sami Väisänene45e53b2016-05-25 10:36:04 +0300536GLuint Context::createPaths(GLsizei range)
537{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500538 auto resultOrError = mState.mPaths->createPaths(mImplementation.get(), range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300539 if (resultOrError.isError())
540 {
541 handleError(resultOrError.getError());
542 return 0;
543 }
544 return resultOrError.getResult();
545}
546
Jamie Madill57a89722013-07-02 11:57:03 -0400547GLuint Context::createVertexArray()
548{
Geoff Lang36167ab2015-12-07 10:27:14 -0500549 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
550 mVertexArrayMap[vertexArray] = nullptr;
551 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400552}
553
Jamie Madilldc356042013-07-19 16:36:57 -0400554GLuint Context::createSampler()
555{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500556 return mState.mSamplers->createSampler();
Jamie Madilldc356042013-07-19 16:36:57 -0400557}
558
Geoff Langc8058452014-02-03 12:04:11 -0500559GLuint Context::createTransformFeedback()
560{
Geoff Lang36167ab2015-12-07 10:27:14 -0500561 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
562 mTransformFeedbackMap[transformFeedback] = nullptr;
563 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500564}
565
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000566// Returns an unused framebuffer name
567GLuint Context::createFramebuffer()
568{
569 GLuint handle = mFramebufferHandleAllocator.allocate();
570
571 mFramebufferMap[handle] = NULL;
572
573 return handle;
574}
575
Jamie Madill33dc8432013-07-26 11:55:05 -0400576GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000577{
Jamie Madill33dc8432013-07-26 11:55:05 -0400578 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000579
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400580 mFenceNVMap[handle] = new FenceNV(mImplementation->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000581
582 return handle;
583}
584
585// Returns an unused query name
586GLuint Context::createQuery()
587{
588 GLuint handle = mQueryHandleAllocator.allocate();
589
590 mQueryMap[handle] = NULL;
591
592 return handle;
593}
594
595void Context::deleteBuffer(GLuint buffer)
596{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500597 if (mState.mBuffers->getBuffer(buffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000598 {
599 detachBuffer(buffer);
600 }
Jamie Madill893ab082014-05-16 16:56:10 -0400601
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500602 mState.mBuffers->deleteBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000603}
604
605void Context::deleteShader(GLuint shader)
606{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500607 mState.mShaderPrograms->deleteShader(shader);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000608}
609
610void Context::deleteProgram(GLuint program)
611{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500612 mState.mShaderPrograms->deleteProgram(program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000613}
614
615void Context::deleteTexture(GLuint texture)
616{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500617 if (mState.mTextures->getTexture(texture))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000618 {
619 detachTexture(texture);
620 }
621
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500622 mState.mTextures->deleteTexture(texture);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000623}
624
625void Context::deleteRenderbuffer(GLuint renderbuffer)
626{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500627 if (mState.mRenderbuffers->getRenderbuffer(renderbuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000628 {
629 detachRenderbuffer(renderbuffer);
630 }
Jamie Madill893ab082014-05-16 16:56:10 -0400631
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500632 mState.mRenderbuffers->deleteRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000633}
634
Jamie Madillcd055f82013-07-26 11:55:15 -0400635void Context::deleteFenceSync(GLsync fenceSync)
636{
637 // The spec specifies the underlying Fence object is not deleted until all current
638 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
639 // and since our API is currently designed for being called from a single thread, we can delete
640 // the fence immediately.
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500641 mState.mFenceSyncs->deleteFenceSync(
642 static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400643}
644
Sami Väisänene45e53b2016-05-25 10:36:04 +0300645void Context::deletePaths(GLuint first, GLsizei range)
646{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500647 mState.mPaths->deletePaths(first, range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300648}
649
650bool Context::hasPathData(GLuint path) const
651{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500652 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300653 if (pathObj == nullptr)
654 return false;
655
656 return pathObj->hasPathData();
657}
658
659bool Context::hasPath(GLuint path) const
660{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500661 return mState.mPaths->hasPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300662}
663
664void Context::setPathCommands(GLuint path,
665 GLsizei numCommands,
666 const GLubyte *commands,
667 GLsizei numCoords,
668 GLenum coordType,
669 const void *coords)
670{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500671 auto *pathObject = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300672
673 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
674}
675
676void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
677{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500678 auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300679
680 switch (pname)
681 {
682 case GL_PATH_STROKE_WIDTH_CHROMIUM:
683 pathObj->setStrokeWidth(value);
684 break;
685 case GL_PATH_END_CAPS_CHROMIUM:
686 pathObj->setEndCaps(static_cast<GLenum>(value));
687 break;
688 case GL_PATH_JOIN_STYLE_CHROMIUM:
689 pathObj->setJoinStyle(static_cast<GLenum>(value));
690 break;
691 case GL_PATH_MITER_LIMIT_CHROMIUM:
692 pathObj->setMiterLimit(value);
693 break;
694 case GL_PATH_STROKE_BOUND_CHROMIUM:
695 pathObj->setStrokeBound(value);
696 break;
697 default:
698 UNREACHABLE();
699 break;
700 }
701}
702
703void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
704{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500705 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300706
707 switch (pname)
708 {
709 case GL_PATH_STROKE_WIDTH_CHROMIUM:
710 *value = pathObj->getStrokeWidth();
711 break;
712 case GL_PATH_END_CAPS_CHROMIUM:
713 *value = static_cast<GLfloat>(pathObj->getEndCaps());
714 break;
715 case GL_PATH_JOIN_STYLE_CHROMIUM:
716 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
717 break;
718 case GL_PATH_MITER_LIMIT_CHROMIUM:
719 *value = pathObj->getMiterLimit();
720 break;
721 case GL_PATH_STROKE_BOUND_CHROMIUM:
722 *value = pathObj->getStrokeBound();
723 break;
724 default:
725 UNREACHABLE();
726 break;
727 }
728}
729
730void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
731{
732 mGLState.setPathStencilFunc(func, ref, mask);
733}
734
Jamie Madill57a89722013-07-02 11:57:03 -0400735void Context::deleteVertexArray(GLuint vertexArray)
736{
Geoff Lang36167ab2015-12-07 10:27:14 -0500737 auto iter = mVertexArrayMap.find(vertexArray);
738 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000739 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500740 VertexArray *vertexArrayObject = iter->second;
741 if (vertexArrayObject != nullptr)
742 {
743 detachVertexArray(vertexArray);
744 delete vertexArrayObject;
745 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000746
Geoff Lang36167ab2015-12-07 10:27:14 -0500747 mVertexArrayMap.erase(iter);
748 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400749 }
750}
751
Jamie Madilldc356042013-07-19 16:36:57 -0400752void Context::deleteSampler(GLuint sampler)
753{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500754 if (mState.mSamplers->getSampler(sampler))
Jamie Madilldc356042013-07-19 16:36:57 -0400755 {
756 detachSampler(sampler);
757 }
758
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500759 mState.mSamplers->deleteSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400760}
761
Geoff Langc8058452014-02-03 12:04:11 -0500762void Context::deleteTransformFeedback(GLuint transformFeedback)
763{
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500764 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500765 if (iter != mTransformFeedbackMap.end())
766 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500767 TransformFeedback *transformFeedbackObject = iter->second;
768 if (transformFeedbackObject != nullptr)
769 {
770 detachTransformFeedback(transformFeedback);
771 transformFeedbackObject->release();
772 }
773
Geoff Lang50b3fe82015-12-08 14:49:12 +0000774 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500775 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500776 }
777}
778
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000779void Context::deleteFramebuffer(GLuint framebuffer)
780{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500781 auto framebufferObject = mFramebufferMap.find(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000782
783 if (framebufferObject != mFramebufferMap.end())
784 {
785 detachFramebuffer(framebuffer);
786
787 mFramebufferHandleAllocator.release(framebufferObject->first);
788 delete framebufferObject->second;
789 mFramebufferMap.erase(framebufferObject);
790 }
791}
792
Jamie Madill33dc8432013-07-26 11:55:05 -0400793void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000794{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500795 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000796
Jamie Madill33dc8432013-07-26 11:55:05 -0400797 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000798 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400799 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000800 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400801 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000802 }
803}
804
805void Context::deleteQuery(GLuint query)
806{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500807 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000808 if (queryObject != mQueryMap.end())
809 {
810 mQueryHandleAllocator.release(queryObject->first);
811 if (queryObject->second)
812 {
813 queryObject->second->release();
814 }
815 mQueryMap.erase(queryObject);
816 }
817}
818
Geoff Lang70d0f492015-12-10 17:45:46 -0500819Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000820{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500821 return mState.mBuffers->getBuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000822}
823
Jamie Madill570f7c82014-07-03 10:38:54 -0400824Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000825{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500826 return mState.mTextures->getTexture(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000827}
828
Geoff Lang70d0f492015-12-10 17:45:46 -0500829Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000830{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500831 return mState.mRenderbuffers->getRenderbuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000832}
833
Jamie Madillcd055f82013-07-26 11:55:15 -0400834FenceSync *Context::getFenceSync(GLsync handle) const
835{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500836 return mState.mFenceSyncs->getFenceSync(
837 static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400838}
839
Jamie Madill57a89722013-07-02 11:57:03 -0400840VertexArray *Context::getVertexArray(GLuint handle) const
841{
842 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500843 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400844}
845
Jamie Madilldc356042013-07-19 16:36:57 -0400846Sampler *Context::getSampler(GLuint handle) const
847{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500848 return mState.mSamplers->getSampler(handle);
Jamie Madilldc356042013-07-19 16:36:57 -0400849}
850
Geoff Langc8058452014-02-03 12:04:11 -0500851TransformFeedback *Context::getTransformFeedback(GLuint handle) const
852{
Geoff Lang36167ab2015-12-07 10:27:14 -0500853 auto iter = mTransformFeedbackMap.find(handle);
854 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500855}
856
Geoff Lang70d0f492015-12-10 17:45:46 -0500857LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
858{
859 switch (identifier)
860 {
861 case GL_BUFFER:
862 return getBuffer(name);
863 case GL_SHADER:
864 return getShader(name);
865 case GL_PROGRAM:
866 return getProgram(name);
867 case GL_VERTEX_ARRAY:
868 return getVertexArray(name);
869 case GL_QUERY:
870 return getQuery(name);
871 case GL_TRANSFORM_FEEDBACK:
872 return getTransformFeedback(name);
873 case GL_SAMPLER:
874 return getSampler(name);
875 case GL_TEXTURE:
876 return getTexture(name);
877 case GL_RENDERBUFFER:
878 return getRenderbuffer(name);
879 case GL_FRAMEBUFFER:
880 return getFramebuffer(name);
881 default:
882 UNREACHABLE();
883 return nullptr;
884 }
885}
886
887LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
888{
889 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
890}
891
Martin Radev9d901792016-07-15 15:58:58 +0300892void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
893{
894 LabeledObject *object = getLabeledObject(identifier, name);
895 ASSERT(object != nullptr);
896
897 std::string labelName = GetObjectLabelFromPointer(length, label);
898 object->setLabel(labelName);
899}
900
901void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
902{
903 LabeledObject *object = getLabeledObjectFromPtr(ptr);
904 ASSERT(object != nullptr);
905
906 std::string labelName = GetObjectLabelFromPointer(length, label);
907 object->setLabel(labelName);
908}
909
910void Context::getObjectLabel(GLenum identifier,
911 GLuint name,
912 GLsizei bufSize,
913 GLsizei *length,
914 GLchar *label) const
915{
916 LabeledObject *object = getLabeledObject(identifier, name);
917 ASSERT(object != nullptr);
918
919 const std::string &objectLabel = object->getLabel();
920 GetObjectLabelBase(objectLabel, bufSize, length, label);
921}
922
923void Context::getObjectPtrLabel(const void *ptr,
924 GLsizei bufSize,
925 GLsizei *length,
926 GLchar *label) const
927{
928 LabeledObject *object = getLabeledObjectFromPtr(ptr);
929 ASSERT(object != nullptr);
930
931 const std::string &objectLabel = object->getLabel();
932 GetObjectLabelBase(objectLabel, bufSize, length, label);
933}
934
Jamie Madilldc356042013-07-19 16:36:57 -0400935bool Context::isSampler(GLuint samplerName) const
936{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500937 return mState.mSamplers->isSampler(samplerName);
Jamie Madilldc356042013-07-19 16:36:57 -0400938}
939
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500940void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000941{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500942 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700943 mGLState.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000944}
945
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800946void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
947{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500948 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800949 mGLState.setDrawIndirectBufferBinding(buffer);
950}
951
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500952void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000953{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500954 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700955 mGLState.getVertexArray()->setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000956}
957
Jamie Madilldedd7b92014-11-05 16:30:36 -0500958void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000959{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500960 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000961
Jamie Madilldedd7b92014-11-05 16:30:36 -0500962 if (handle == 0)
963 {
964 texture = mZeroTextures[target].get();
965 }
966 else
967 {
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500968 texture = mState.mTextures->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500969 }
970
971 ASSERT(texture);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700972 mGLState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000973}
974
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500975void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000976{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500977 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700978 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000979}
980
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500981void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000982{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500983 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700984 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000985}
986
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500987void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -0400988{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500989 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700990 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400991}
992
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500993void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -0400994{
Geoff Lang76b10c92014-09-05 16:28:14 -0400995 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -0400996 Sampler *sampler =
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500997 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700998 mGLState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400999}
1000
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001001void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001002{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001003 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001004 mGLState.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001005}
1006
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001007void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1008 GLuint index,
1009 GLintptr offset,
1010 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001011{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001012 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001013 mGLState.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001014}
1015
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001016void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001017{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001018 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001019 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001020}
1021
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001022void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1023 GLuint index,
1024 GLintptr offset,
1025 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001026{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001027 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001028 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001029}
1030
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001031void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001032{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001033 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001034 mGLState.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001035}
1036
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001037void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001038{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001039 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001040 mGLState.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001041}
1042
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001043void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001044{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001045 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001046 mGLState.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001047}
1048
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001049void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001050{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001051 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001052 mGLState.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001053}
1054
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001055void Context::useProgram(GLuint program)
1056{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001057 mGLState.setProgram(getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001058}
1059
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001060void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001061{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001062 TransformFeedback *transformFeedback =
1063 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001064 mGLState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001065}
1066
Geoff Lang5aad9672014-09-08 11:10:42 -04001067Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001068{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001069 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001070 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001071
Geoff Lang5aad9672014-09-08 11:10:42 -04001072 // begin query
1073 Error error = queryObject->begin();
1074 if (error.isError())
1075 {
1076 return error;
1077 }
1078
1079 // set query as active for specified target only if begin succeeded
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001080 mGLState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001081
He Yunchaoacd18982017-01-04 10:46:42 +08001082 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001083}
1084
Geoff Lang5aad9672014-09-08 11:10:42 -04001085Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001086{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001087 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001088 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001089
Geoff Lang5aad9672014-09-08 11:10:42 -04001090 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001091
Geoff Lang5aad9672014-09-08 11:10:42 -04001092 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001093 mGLState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -04001094
1095 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001096}
1097
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001098Error Context::queryCounter(GLuint id, GLenum target)
1099{
1100 ASSERT(target == GL_TIMESTAMP_EXT);
1101
1102 Query *queryObject = getQuery(id, true, target);
1103 ASSERT(queryObject);
1104
1105 return queryObject->queryCounter();
1106}
1107
1108void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1109{
1110 switch (pname)
1111 {
1112 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001113 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001114 break;
1115 case GL_QUERY_COUNTER_BITS_EXT:
1116 switch (target)
1117 {
1118 case GL_TIME_ELAPSED_EXT:
1119 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1120 break;
1121 case GL_TIMESTAMP_EXT:
1122 params[0] = getExtensions().queryCounterBitsTimestamp;
1123 break;
1124 default:
1125 UNREACHABLE();
1126 params[0] = 0;
1127 break;
1128 }
1129 break;
1130 default:
1131 UNREACHABLE();
1132 return;
1133 }
1134}
1135
Geoff Lang2186c382016-10-14 10:54:54 -04001136void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001137{
Geoff Lang2186c382016-10-14 10:54:54 -04001138 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001139}
1140
Geoff Lang2186c382016-10-14 10:54:54 -04001141void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001142{
Geoff Lang2186c382016-10-14 10:54:54 -04001143 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001144}
1145
Geoff Lang2186c382016-10-14 10:54:54 -04001146void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001147{
Geoff Lang2186c382016-10-14 10:54:54 -04001148 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001149}
1150
Geoff Lang2186c382016-10-14 10:54:54 -04001151void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001152{
Geoff Lang2186c382016-10-14 10:54:54 -04001153 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001154}
1155
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001156Framebuffer *Context::getFramebuffer(unsigned int handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001157{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001158 auto framebufferIt = mFramebufferMap.find(handle);
1159 return ((framebufferIt == mFramebufferMap.end()) ? nullptr : framebufferIt->second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001160}
1161
Jamie Madill33dc8432013-07-26 11:55:05 -04001162FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001163{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001164 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001165
Jamie Madill33dc8432013-07-26 11:55:05 -04001166 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001167 {
1168 return NULL;
1169 }
1170 else
1171 {
1172 return fence->second;
1173 }
1174}
1175
1176Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1177{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001178 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001179
1180 if (query == mQueryMap.end())
1181 {
1182 return NULL;
1183 }
1184 else
1185 {
1186 if (!query->second && create)
1187 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001188 query->second = new Query(mImplementation->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001189 query->second->addRef();
1190 }
1191 return query->second;
1192 }
1193}
1194
Geoff Lang70d0f492015-12-10 17:45:46 -05001195Query *Context::getQuery(GLuint handle) const
1196{
1197 auto iter = mQueryMap.find(handle);
1198 return (iter != mQueryMap.end()) ? iter->second : nullptr;
1199}
1200
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001201Texture *Context::getTargetTexture(GLenum target) const
1202{
Ian Ewellbda75592016-04-18 17:25:54 -04001203 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001204 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001205}
1206
Geoff Lang76b10c92014-09-05 16:28:14 -04001207Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001208{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001209 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001210}
1211
Geoff Lang492a7e42014-11-05 13:27:06 -05001212Compiler *Context::getCompiler() const
1213{
1214 return mCompiler;
1215}
1216
Jamie Madill893ab082014-05-16 16:56:10 -04001217void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001218{
1219 switch (pname)
1220 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001221 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001222 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001223 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001224 mGLState.getBooleanv(pname, params);
1225 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001226 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001227}
1228
Jamie Madill893ab082014-05-16 16:56:10 -04001229void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001230{
Shannon Woods53a94a82014-06-24 15:20:36 -04001231 // Queries about context capabilities and maximums are answered by Context.
1232 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001233 switch (pname)
1234 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001235 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001236 params[0] = mCaps.minAliasedLineWidth;
1237 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001238 break;
1239 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001240 params[0] = mCaps.minAliasedPointSize;
1241 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001242 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001243 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001244 ASSERT(mExtensions.textureFilterAnisotropic);
1245 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001246 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001247 case GL_MAX_TEXTURE_LOD_BIAS:
1248 *params = mCaps.maxLODBias;
1249 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001250
1251 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1252 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1253 {
1254 ASSERT(mExtensions.pathRendering);
1255 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1256 memcpy(params, m, 16 * sizeof(GLfloat));
1257 }
1258 break;
1259
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001260 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001261 mGLState.getFloatv(pname, params);
1262 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001263 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001264}
1265
Jamie Madill893ab082014-05-16 16:56:10 -04001266void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001267{
Shannon Woods53a94a82014-06-24 15:20:36 -04001268 // Queries about context capabilities and maximums are answered by Context.
1269 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001270
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001271 switch (pname)
1272 {
Geoff Lang301d1612014-07-09 10:34:37 -04001273 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1274 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1275 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001276 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1277 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1278 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001279 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1280 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1281 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001282 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001283 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1284 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1285 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001286 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001287 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001288 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1289 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1290 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1291 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001292 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1293 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001294 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1295 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001296 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001297 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1298 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1299 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1300 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Martin Radev1be913c2016-07-11 17:59:16 +03001301 case GL_MAJOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001302 *params = getClientVersion().major;
Martin Radev1be913c2016-07-11 17:59:16 +03001303 break;
1304 case GL_MINOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001305 *params = getClientVersion().minor;
Martin Radev1be913c2016-07-11 17:59:16 +03001306 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001307 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1308 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001309 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1310 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1311 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001312 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1313 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1314 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001315 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001316 case GL_MAX_VIEWPORT_DIMS:
1317 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001318 params[0] = mCaps.maxViewportWidth;
1319 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001320 }
1321 break;
1322 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001323 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001324 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001325 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1326 *params = mResetStrategy;
1327 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001328 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001329 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001330 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001331 case GL_SHADER_BINARY_FORMATS:
1332 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1333 break;
1334 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001335 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001336 break;
1337 case GL_PROGRAM_BINARY_FORMATS:
1338 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001339 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001340 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001341 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001342 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001343
1344 // GL_KHR_debug
1345 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1346 *params = mExtensions.maxDebugMessageLength;
1347 break;
1348 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1349 *params = mExtensions.maxDebugLoggedMessages;
1350 break;
1351 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1352 *params = mExtensions.maxDebugGroupStackDepth;
1353 break;
1354 case GL_MAX_LABEL_LENGTH:
1355 *params = mExtensions.maxLabelLength;
1356 break;
1357
Ian Ewell53f59f42016-01-28 17:36:55 -05001358 // GL_EXT_disjoint_timer_query
1359 case GL_GPU_DISJOINT_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001360 *params = mImplementation->getGPUDisjoint();
Ian Ewell53f59f42016-01-28 17:36:55 -05001361 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001362 case GL_MAX_FRAMEBUFFER_WIDTH:
1363 *params = mCaps.maxFramebufferWidth;
1364 break;
1365 case GL_MAX_FRAMEBUFFER_HEIGHT:
1366 *params = mCaps.maxFramebufferHeight;
1367 break;
1368 case GL_MAX_FRAMEBUFFER_SAMPLES:
1369 *params = mCaps.maxFramebufferSamples;
1370 break;
1371 case GL_MAX_SAMPLE_MASK_WORDS:
1372 *params = mCaps.maxSampleMaskWords;
1373 break;
1374 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1375 *params = mCaps.maxColorTextureSamples;
1376 break;
1377 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1378 *params = mCaps.maxDepthTextureSamples;
1379 break;
1380 case GL_MAX_INTEGER_SAMPLES:
1381 *params = mCaps.maxIntegerSamples;
1382 break;
1383 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1384 *params = mCaps.maxVertexAttribRelativeOffset;
1385 break;
1386 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1387 *params = mCaps.maxVertexAttribBindings;
1388 break;
1389 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1390 *params = mCaps.maxVertexAttribStride;
1391 break;
1392 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1393 *params = mCaps.maxVertexAtomicCounterBuffers;
1394 break;
1395 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1396 *params = mCaps.maxVertexAtomicCounters;
1397 break;
1398 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1399 *params = mCaps.maxVertexImageUniforms;
1400 break;
1401 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1402 *params = mCaps.maxVertexShaderStorageBlocks;
1403 break;
1404 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1405 *params = mCaps.maxFragmentAtomicCounterBuffers;
1406 break;
1407 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1408 *params = mCaps.maxFragmentAtomicCounters;
1409 break;
1410 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1411 *params = mCaps.maxFragmentImageUniforms;
1412 break;
1413 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1414 *params = mCaps.maxFragmentShaderStorageBlocks;
1415 break;
1416 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1417 *params = mCaps.minProgramTextureGatherOffset;
1418 break;
1419 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1420 *params = mCaps.maxProgramTextureGatherOffset;
1421 break;
1422 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1423 *params = mCaps.maxComputeWorkGroupInvocations;
1424 break;
1425 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1426 *params = mCaps.maxComputeUniformBlocks;
1427 break;
1428 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1429 *params = mCaps.maxComputeTextureImageUnits;
1430 break;
1431 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1432 *params = mCaps.maxComputeSharedMemorySize;
1433 break;
1434 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1435 *params = mCaps.maxComputeUniformComponents;
1436 break;
1437 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1438 *params = mCaps.maxComputeAtomicCounterBuffers;
1439 break;
1440 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1441 *params = mCaps.maxComputeAtomicCounters;
1442 break;
1443 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1444 *params = mCaps.maxComputeImageUniforms;
1445 break;
1446 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1447 *params = mCaps.maxCombinedComputeUniformComponents;
1448 break;
1449 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1450 *params = mCaps.maxComputeShaderStorageBlocks;
1451 break;
1452 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1453 *params = mCaps.maxCombinedShaderOutputResources;
1454 break;
1455 case GL_MAX_UNIFORM_LOCATIONS:
1456 *params = mCaps.maxUniformLocations;
1457 break;
1458 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1459 *params = mCaps.maxAtomicCounterBufferBindings;
1460 break;
1461 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1462 *params = mCaps.maxAtomicCounterBufferSize;
1463 break;
1464 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1465 *params = mCaps.maxCombinedAtomicCounterBuffers;
1466 break;
1467 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1468 *params = mCaps.maxCombinedAtomicCounters;
1469 break;
1470 case GL_MAX_IMAGE_UNITS:
1471 *params = mCaps.maxImageUnits;
1472 break;
1473 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1474 *params = mCaps.maxCombinedImageUniforms;
1475 break;
1476 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1477 *params = mCaps.maxShaderStorageBufferBindings;
1478 break;
1479 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1480 *params = mCaps.maxCombinedShaderStorageBlocks;
1481 break;
1482 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1483 *params = mCaps.shaderStorageBufferOffsetAlignment;
1484 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001485 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001486 mGLState.getIntegerv(mState, pname, params);
1487 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001488 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001489}
1490
Jamie Madill893ab082014-05-16 16:56:10 -04001491void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001492{
Shannon Woods53a94a82014-06-24 15:20:36 -04001493 // Queries about context capabilities and maximums are answered by Context.
1494 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001495 switch (pname)
1496 {
1497 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001498 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001499 break;
1500 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001501 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001502 break;
1503 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001504 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001505 break;
1506 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001507 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001508 break;
1509 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001510 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001511 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001512
1513 // GL_EXT_disjoint_timer_query
1514 case GL_TIMESTAMP_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001515 *params = mImplementation->getTimestamp();
Ian Ewell53f59f42016-01-28 17:36:55 -05001516 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001517
1518 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1519 *params = mCaps.maxShaderStorageBlockSize;
1520 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001521 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001522 UNREACHABLE();
1523 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001524 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001525}
1526
Geoff Lang70d0f492015-12-10 17:45:46 -05001527void Context::getPointerv(GLenum pname, void **params) const
1528{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001529 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001530}
1531
Martin Radev66fb8202016-07-28 11:45:20 +03001532void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001533{
Shannon Woods53a94a82014-06-24 15:20:36 -04001534 // Queries about context capabilities and maximums are answered by Context.
1535 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001536
1537 GLenum nativeType;
1538 unsigned int numParams;
1539 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1540 ASSERT(queryStatus);
1541
1542 if (nativeType == GL_INT)
1543 {
1544 switch (target)
1545 {
1546 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1547 ASSERT(index < 3u);
1548 *data = mCaps.maxComputeWorkGroupCount[index];
1549 break;
1550 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1551 ASSERT(index < 3u);
1552 *data = mCaps.maxComputeWorkGroupSize[index];
1553 break;
1554 default:
1555 mGLState.getIntegeri_v(target, index, data);
1556 }
1557 }
1558 else
1559 {
1560 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1561 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001562}
1563
Martin Radev66fb8202016-07-28 11:45:20 +03001564void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001565{
Shannon Woods53a94a82014-06-24 15:20:36 -04001566 // Queries about context capabilities and maximums are answered by Context.
1567 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001568
1569 GLenum nativeType;
1570 unsigned int numParams;
1571 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1572 ASSERT(queryStatus);
1573
1574 if (nativeType == GL_INT_64_ANGLEX)
1575 {
1576 mGLState.getInteger64i_v(target, index, data);
1577 }
1578 else
1579 {
1580 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1581 }
1582}
1583
1584void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1585{
1586 // Queries about context capabilities and maximums are answered by Context.
1587 // Queries about current GL state values are answered by State.
1588
1589 GLenum nativeType;
1590 unsigned int numParams;
1591 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1592 ASSERT(queryStatus);
1593
1594 if (nativeType == GL_BOOL)
1595 {
1596 mGLState.getBooleani_v(target, index, data);
1597 }
1598 else
1599 {
1600 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1601 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001602}
1603
Jamie Madill675fe712016-12-19 13:07:54 -05001604void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001605{
Jamie Madill1b94d432015-08-07 13:23:23 -04001606 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001607 auto error = mImplementation->drawArrays(mode, first, count);
1608 handleError(error);
1609 if (!error.isError())
1610 {
1611 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1612 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001613}
1614
Jamie Madill675fe712016-12-19 13:07:54 -05001615void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Geoff Langf6db0982015-08-25 13:04:00 -04001616{
1617 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001618 auto error = mImplementation->drawArraysInstanced(mode, first, count, instanceCount);
1619 handleError(error);
1620 if (!error.isError())
1621 {
1622 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1623 }
Geoff Langf6db0982015-08-25 13:04:00 -04001624}
1625
Jamie Madill675fe712016-12-19 13:07:54 -05001626void Context::drawElements(GLenum mode,
1627 GLsizei count,
1628 GLenum type,
1629 const GLvoid *indices,
1630 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001631{
Jamie Madill1b94d432015-08-07 13:23:23 -04001632 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001633 handleError(mImplementation->drawElements(mode, count, type, indices, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001634}
1635
Jamie Madill675fe712016-12-19 13:07:54 -05001636void Context::drawElementsInstanced(GLenum mode,
1637 GLsizei count,
1638 GLenum type,
1639 const GLvoid *indices,
1640 GLsizei instances,
1641 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001642{
1643 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001644 handleError(
1645 mImplementation->drawElementsInstanced(mode, count, type, indices, instances, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001646}
1647
Jamie Madill675fe712016-12-19 13:07:54 -05001648void Context::drawRangeElements(GLenum mode,
1649 GLuint start,
1650 GLuint end,
1651 GLsizei count,
1652 GLenum type,
1653 const GLvoid *indices,
1654 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001655{
1656 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001657 handleError(
1658 mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001659}
1660
Jiajia Qind9671222016-11-29 16:30:31 +08001661void Context::drawArraysIndirect(GLenum mode, const GLvoid *indirect)
1662{
1663 syncRendererState();
1664 handleError(mImplementation->drawArraysIndirect(mode, indirect));
1665}
1666
1667void Context::drawElementsIndirect(GLenum mode, GLenum type, const GLvoid *indirect)
1668{
1669 syncRendererState();
1670 handleError(mImplementation->drawElementsIndirect(mode, type, indirect));
1671}
1672
Jamie Madill675fe712016-12-19 13:07:54 -05001673void Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001674{
Jamie Madill675fe712016-12-19 13:07:54 -05001675 handleError(mImplementation->flush());
Geoff Lang129753a2015-01-09 16:52:09 -05001676}
1677
Jamie Madill675fe712016-12-19 13:07:54 -05001678void Context::finish()
Geoff Lang129753a2015-01-09 16:52:09 -05001679{
Jamie Madill675fe712016-12-19 13:07:54 -05001680 handleError(mImplementation->finish());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001681}
1682
Austin Kinross6ee1e782015-05-29 17:05:37 -07001683void Context::insertEventMarker(GLsizei length, const char *marker)
1684{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001685 ASSERT(mImplementation);
1686 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001687}
1688
1689void Context::pushGroupMarker(GLsizei length, const char *marker)
1690{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001691 ASSERT(mImplementation);
1692 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001693}
1694
1695void Context::popGroupMarker()
1696{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001697 ASSERT(mImplementation);
1698 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001699}
1700
Geoff Langd8605522016-04-13 10:19:12 -04001701void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1702{
1703 Program *programObject = getProgram(program);
1704 ASSERT(programObject);
1705
1706 programObject->bindUniformLocation(location, name);
1707}
1708
Sami Väisänena797e062016-05-12 15:23:40 +03001709void Context::setCoverageModulation(GLenum components)
1710{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001711 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001712}
1713
Sami Väisänene45e53b2016-05-25 10:36:04 +03001714void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1715{
1716 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1717}
1718
1719void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1720{
1721 GLfloat I[16];
1722 angle::Matrix<GLfloat>::setToIdentity(I);
1723
1724 mGLState.loadPathRenderingMatrix(matrixMode, I);
1725}
1726
1727void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1728{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001729 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001730 if (!pathObj)
1731 return;
1732
1733 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1734 syncRendererState();
1735
1736 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1737}
1738
1739void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1740{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001741 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001742 if (!pathObj)
1743 return;
1744
1745 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1746 syncRendererState();
1747
1748 mImplementation->stencilStrokePath(pathObj, reference, mask);
1749}
1750
1751void Context::coverFillPath(GLuint path, GLenum coverMode)
1752{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001753 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001754 if (!pathObj)
1755 return;
1756
1757 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1758 syncRendererState();
1759
1760 mImplementation->coverFillPath(pathObj, coverMode);
1761}
1762
1763void Context::coverStrokePath(GLuint path, GLenum coverMode)
1764{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001765 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001766 if (!pathObj)
1767 return;
1768
1769 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1770 syncRendererState();
1771
1772 mImplementation->coverStrokePath(pathObj, coverMode);
1773}
1774
1775void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1776{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001777 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001778 if (!pathObj)
1779 return;
1780
1781 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1782 syncRendererState();
1783
1784 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1785}
1786
1787void Context::stencilThenCoverStrokePath(GLuint path,
1788 GLint reference,
1789 GLuint mask,
1790 GLenum coverMode)
1791{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001792 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001793 if (!pathObj)
1794 return;
1795
1796 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1797 syncRendererState();
1798
1799 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1800}
1801
Sami Väisänend59ca052016-06-21 16:10:00 +03001802void Context::coverFillPathInstanced(GLsizei numPaths,
1803 GLenum pathNameType,
1804 const void *paths,
1805 GLuint pathBase,
1806 GLenum coverMode,
1807 GLenum transformType,
1808 const GLfloat *transformValues)
1809{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001810 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001811
1812 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1813 syncRendererState();
1814
1815 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1816}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001817
Sami Väisänend59ca052016-06-21 16:10:00 +03001818void Context::coverStrokePathInstanced(GLsizei numPaths,
1819 GLenum pathNameType,
1820 const void *paths,
1821 GLuint pathBase,
1822 GLenum coverMode,
1823 GLenum transformType,
1824 const GLfloat *transformValues)
1825{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001826 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001827
1828 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1829 syncRendererState();
1830
1831 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1832 transformValues);
1833}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001834
Sami Väisänend59ca052016-06-21 16:10:00 +03001835void Context::stencilFillPathInstanced(GLsizei numPaths,
1836 GLenum pathNameType,
1837 const void *paths,
1838 GLuint pathBase,
1839 GLenum fillMode,
1840 GLuint mask,
1841 GLenum transformType,
1842 const GLfloat *transformValues)
1843{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001844 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001845
1846 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1847 syncRendererState();
1848
1849 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1850 transformValues);
1851}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001852
Sami Väisänend59ca052016-06-21 16:10:00 +03001853void Context::stencilStrokePathInstanced(GLsizei numPaths,
1854 GLenum pathNameType,
1855 const void *paths,
1856 GLuint pathBase,
1857 GLint reference,
1858 GLuint mask,
1859 GLenum transformType,
1860 const GLfloat *transformValues)
1861{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001862 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001863
1864 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1865 syncRendererState();
1866
1867 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
1868 transformValues);
1869}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001870
Sami Väisänend59ca052016-06-21 16:10:00 +03001871void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
1872 GLenum pathNameType,
1873 const void *paths,
1874 GLuint pathBase,
1875 GLenum fillMode,
1876 GLuint mask,
1877 GLenum coverMode,
1878 GLenum transformType,
1879 const GLfloat *transformValues)
1880{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001881 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001882
1883 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1884 syncRendererState();
1885
1886 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
1887 transformType, transformValues);
1888}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001889
Sami Väisänend59ca052016-06-21 16:10:00 +03001890void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
1891 GLenum pathNameType,
1892 const void *paths,
1893 GLuint pathBase,
1894 GLint reference,
1895 GLuint mask,
1896 GLenum coverMode,
1897 GLenum transformType,
1898 const GLfloat *transformValues)
1899{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001900 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001901
1902 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1903 syncRendererState();
1904
1905 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
1906 transformType, transformValues);
1907}
1908
Sami Väisänen46eaa942016-06-29 10:26:37 +03001909void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
1910{
1911 auto *programObject = getProgram(program);
1912
1913 programObject->bindFragmentInputLocation(location, name);
1914}
1915
1916void Context::programPathFragmentInputGen(GLuint program,
1917 GLint location,
1918 GLenum genMode,
1919 GLint components,
1920 const GLfloat *coeffs)
1921{
1922 auto *programObject = getProgram(program);
1923
1924 programObject->pathFragmentInputGen(location, genMode, components, coeffs);
1925}
1926
Jamie Madill437fa652016-05-03 15:13:24 -04001927void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001928{
Geoff Langda5777c2014-07-11 09:52:58 -04001929 if (error.isError())
1930 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001931 GLenum code = error.getCode();
1932 mErrors.insert(code);
1933 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
1934 {
1935 markContextLost();
1936 }
Geoff Lang70d0f492015-12-10 17:45:46 -05001937
1938 if (!error.getMessage().empty())
1939 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001940 auto *debug = &mGLState.getDebug();
1941 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1942 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05001943 }
Geoff Langda5777c2014-07-11 09:52:58 -04001944 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001945}
1946
1947// Get one of the recorded errors and clear its flag, if any.
1948// [OpenGL ES 2.0.24] section 2.5 page 13.
1949GLenum Context::getError()
1950{
Geoff Langda5777c2014-07-11 09:52:58 -04001951 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001952 {
Geoff Langda5777c2014-07-11 09:52:58 -04001953 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001954 }
Geoff Langda5777c2014-07-11 09:52:58 -04001955 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001956 {
Geoff Langda5777c2014-07-11 09:52:58 -04001957 GLenum error = *mErrors.begin();
1958 mErrors.erase(mErrors.begin());
1959 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001960 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001961}
1962
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001963// NOTE: this function should not assume that this context is current!
1964void Context::markContextLost()
1965{
1966 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001967 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001968 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001969 mContextLostForced = true;
1970 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001971 mContextLost = true;
1972}
1973
1974bool Context::isContextLost()
1975{
1976 return mContextLost;
1977}
1978
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001979GLenum Context::getResetStatus()
1980{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001981 // Even if the application doesn't want to know about resets, we want to know
1982 // as it will allow us to skip all the calls.
1983 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001984 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001985 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001986 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001987 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001988 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001989
1990 // EXT_robustness, section 2.6: If the reset notification behavior is
1991 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
1992 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
1993 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001994 }
1995
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001996 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
1997 // status should be returned at least once, and GL_NO_ERROR should be returned
1998 // once the device has finished resetting.
1999 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002000 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002001 ASSERT(mResetStatus == GL_NO_ERROR);
2002 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002003
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002004 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002005 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002006 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002007 }
2008 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002009 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002010 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002011 // If markContextLost was used to mark the context lost then
2012 // assume that is not recoverable, and continue to report the
2013 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002014 mResetStatus = mImplementation->getResetStatus();
2015 }
Jamie Madill893ab082014-05-16 16:56:10 -04002016
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002017 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002018}
2019
2020bool Context::isResetNotificationEnabled()
2021{
2022 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2023}
2024
Corentin Walleze3b10e82015-05-20 11:06:25 -04002025const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002026{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002027 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002028}
2029
2030EGLenum Context::getClientType() const
2031{
2032 return mClientType;
2033}
2034
2035EGLenum Context::getRenderBuffer() const
2036{
Corentin Wallez37c39792015-08-20 14:19:46 -04002037 auto framebufferIt = mFramebufferMap.find(0);
2038 if (framebufferIt != mFramebufferMap.end())
2039 {
2040 const Framebuffer *framebuffer = framebufferIt->second;
2041 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2042
2043 ASSERT(backAttachment != nullptr);
2044 return backAttachment->getSurface()->getRenderBuffer();
2045 }
2046 else
2047 {
2048 return EGL_NONE;
2049 }
Régis Fénéon83107972015-02-05 12:57:44 +01002050}
2051
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002052VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002053{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002054 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002055 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2056 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002057 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002058 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle, MAX_VERTEX_ATTRIBS);
2059
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002060 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002061 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002062
2063 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002064}
2065
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002066TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002067{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002068 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002069 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2070 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002071 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002072 transformFeedback =
2073 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002074 transformFeedback->addRef();
2075 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002076 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002077
2078 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002079}
2080
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002081Framebuffer *Context::checkFramebufferAllocation(GLuint framebuffer)
2082{
2083 // Can be called from Bind without a prior call to Gen.
2084 auto framebufferIt = mFramebufferMap.find(framebuffer);
2085 bool neverCreated = framebufferIt == mFramebufferMap.end();
2086 if (neverCreated || framebufferIt->second == nullptr)
2087 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002088 Framebuffer *newFBO = new Framebuffer(mCaps, mImplementation.get(), framebuffer);
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002089 if (neverCreated)
2090 {
2091 mFramebufferHandleAllocator.reserve(framebuffer);
2092 mFramebufferMap[framebuffer] = newFBO;
2093 return newFBO;
2094 }
2095
2096 framebufferIt->second = newFBO;
2097 }
2098
2099 return framebufferIt->second;
2100}
2101
Geoff Lang36167ab2015-12-07 10:27:14 -05002102bool Context::isVertexArrayGenerated(GLuint vertexArray)
2103{
Geoff Langf41a7152016-09-19 15:11:17 -04002104 ASSERT(mVertexArrayMap.find(0) != mVertexArrayMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002105 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
2106}
2107
2108bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2109{
Geoff Langf41a7152016-09-19 15:11:17 -04002110 ASSERT(mTransformFeedbackMap.find(0) != mTransformFeedbackMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002111 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
2112}
2113
Shannon Woods53a94a82014-06-24 15:20:36 -04002114void Context::detachTexture(GLuint texture)
2115{
2116 // Simple pass-through to State's detachTexture method, as textures do not require
2117 // allocation map management either here or in the resource manager at detach time.
2118 // Zero textures are held by the Context, and we don't attempt to request them from
2119 // the State.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002120 mGLState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002121}
2122
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002123void Context::detachBuffer(GLuint buffer)
2124{
Yuly Novikov5807a532015-12-03 13:01:22 -05002125 // Simple pass-through to State's detachBuffer method, since
2126 // only buffer attachments to container objects that are bound to the current context
2127 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002128
Yuly Novikov5807a532015-12-03 13:01:22 -05002129 // [OpenGL ES 3.2] section 5.1.2 page 45:
2130 // Attachments to unbound container objects, such as
2131 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2132 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002133 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002134}
2135
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002136void Context::detachFramebuffer(GLuint framebuffer)
2137{
Shannon Woods53a94a82014-06-24 15:20:36 -04002138 // Framebuffer detachment is handled by Context, because 0 is a valid
2139 // Framebuffer object, and a pointer to it must be passed from Context
2140 // to State at binding time.
2141
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002142 // [OpenGL ES 2.0.24] section 4.4 page 107:
2143 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2144 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2145
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002146 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002147 {
2148 bindReadFramebuffer(0);
2149 }
2150
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002151 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002152 {
2153 bindDrawFramebuffer(0);
2154 }
2155}
2156
2157void Context::detachRenderbuffer(GLuint renderbuffer)
2158{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002159 mGLState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002160}
2161
Jamie Madill57a89722013-07-02 11:57:03 -04002162void Context::detachVertexArray(GLuint vertexArray)
2163{
Jamie Madill77a72f62015-04-14 11:18:32 -04002164 // Vertex array detachment is handled by Context, because 0 is a valid
2165 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002166 // binding time.
2167
Jamie Madill57a89722013-07-02 11:57:03 -04002168 // [OpenGL ES 3.0.2] section 2.10 page 43:
2169 // If a vertex array object that is currently bound is deleted, the binding
2170 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002171 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002172 {
2173 bindVertexArray(0);
2174 }
2175}
2176
Geoff Langc8058452014-02-03 12:04:11 -05002177void Context::detachTransformFeedback(GLuint transformFeedback)
2178{
Corentin Walleza2257da2016-04-19 16:43:12 -04002179 // Transform feedback detachment is handled by Context, because 0 is a valid
2180 // transform feedback, and a pointer to it must be passed from Context to State at
2181 // binding time.
2182
2183 // The OpenGL specification doesn't mention what should happen when the currently bound
2184 // transform feedback object is deleted. Since it is a container object, we treat it like
2185 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002186 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002187 {
2188 bindTransformFeedback(0);
2189 }
Geoff Langc8058452014-02-03 12:04:11 -05002190}
2191
Jamie Madilldc356042013-07-19 16:36:57 -04002192void Context::detachSampler(GLuint sampler)
2193{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002194 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002195}
2196
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002197void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2198{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002199 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002200}
2201
Jamie Madille29d1672013-07-19 16:36:57 -04002202void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2203{
Geoff Langc1984ed2016-10-07 12:41:00 -04002204 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002205 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002206 SetSamplerParameteri(samplerObject, pname, param);
2207}
Jamie Madille29d1672013-07-19 16:36:57 -04002208
Geoff Langc1984ed2016-10-07 12:41:00 -04002209void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2210{
2211 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002212 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002213 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002214}
2215
2216void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2217{
Geoff Langc1984ed2016-10-07 12:41:00 -04002218 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002219 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002220 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002221}
2222
Geoff Langc1984ed2016-10-07 12:41:00 -04002223void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002224{
Geoff Langc1984ed2016-10-07 12:41:00 -04002225 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002226 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002227 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002228}
2229
Geoff Langc1984ed2016-10-07 12:41:00 -04002230void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002231{
Geoff Langc1984ed2016-10-07 12:41:00 -04002232 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002233 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002234 QuerySamplerParameteriv(samplerObject, pname, params);
2235}
Jamie Madill9675b802013-07-19 16:36:59 -04002236
Geoff Langc1984ed2016-10-07 12:41:00 -04002237void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2238{
2239 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002240 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002241 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002242}
2243
Olli Etuahof0fee072016-03-30 15:11:58 +03002244void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2245{
2246 gl::Program *programObject = getProgram(program);
2247 ASSERT(programObject != nullptr);
2248
2249 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
2250 programObject->setBinaryRetrievableHint(value != GL_FALSE);
2251}
2252
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002253void Context::initRendererString()
2254{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002255 std::ostringstream rendererString;
2256 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002257 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002258 rendererString << ")";
2259
Geoff Langcec35902014-04-16 10:52:36 -04002260 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002261}
2262
Geoff Langc339c4e2016-11-29 10:37:36 -05002263void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002264{
Geoff Langc339c4e2016-11-29 10:37:36 -05002265 const Version &clientVersion = getClientVersion();
2266
2267 std::ostringstream versionString;
2268 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2269 << ANGLE_VERSION_STRING << ")";
2270 mVersionString = MakeStaticString(versionString.str());
2271
2272 std::ostringstream shadingLanguageVersionString;
2273 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2274 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2275 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2276 << ")";
2277 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002278}
2279
Geoff Langcec35902014-04-16 10:52:36 -04002280void Context::initExtensionStrings()
2281{
Geoff Langc339c4e2016-11-29 10:37:36 -05002282 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2283 std::ostringstream combinedStringStream;
2284 std::copy(strings.begin(), strings.end(),
2285 std::ostream_iterator<const char *>(combinedStringStream, " "));
2286 return MakeStaticString(combinedStringStream.str());
2287 };
2288
2289 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002290 for (const auto &extensionString : mExtensions.getStrings())
2291 {
2292 mExtensionStrings.push_back(MakeStaticString(extensionString));
2293 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002294 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002295
Geoff Langc339c4e2016-11-29 10:37:36 -05002296 mRequestableExtensionStrings.clear();
2297 for (const auto &extensionInfo : GetExtensionInfoMap())
2298 {
2299 if (extensionInfo.second.Requestable &&
2300 !(mExtensions.*(extensionInfo.second.ExtensionsMember)))
2301 {
2302 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2303 }
2304 }
2305 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002306}
2307
Geoff Langc339c4e2016-11-29 10:37:36 -05002308const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002309{
Geoff Langc339c4e2016-11-29 10:37:36 -05002310 switch (name)
2311 {
2312 case GL_VENDOR:
2313 return reinterpret_cast<const GLubyte *>("Google Inc.");
2314
2315 case GL_RENDERER:
2316 return reinterpret_cast<const GLubyte *>(mRendererString);
2317
2318 case GL_VERSION:
2319 return reinterpret_cast<const GLubyte *>(mVersionString);
2320
2321 case GL_SHADING_LANGUAGE_VERSION:
2322 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2323
2324 case GL_EXTENSIONS:
2325 return reinterpret_cast<const GLubyte *>(mExtensionString);
2326
2327 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2328 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2329
2330 default:
2331 UNREACHABLE();
2332 return nullptr;
2333 }
Geoff Langcec35902014-04-16 10:52:36 -04002334}
2335
Geoff Langc339c4e2016-11-29 10:37:36 -05002336const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002337{
Geoff Langc339c4e2016-11-29 10:37:36 -05002338 switch (name)
2339 {
2340 case GL_EXTENSIONS:
2341 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2342
2343 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2344 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2345
2346 default:
2347 UNREACHABLE();
2348 return nullptr;
2349 }
Geoff Langcec35902014-04-16 10:52:36 -04002350}
2351
2352size_t Context::getExtensionStringCount() const
2353{
2354 return mExtensionStrings.size();
2355}
2356
Geoff Langc339c4e2016-11-29 10:37:36 -05002357void Context::requestExtension(const char *name)
2358{
2359 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2360 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2361 const auto &extension = extensionInfos.at(name);
2362 ASSERT(extension.Requestable);
2363
2364 if (mExtensions.*(extension.ExtensionsMember))
2365 {
2366 // Extension already enabled
2367 return;
2368 }
2369
2370 mExtensions.*(extension.ExtensionsMember) = true;
2371 updateCaps();
2372 initExtensionStrings();
2373}
2374
2375size_t Context::getRequestableExtensionStringCount() const
2376{
2377 return mRequestableExtensionStrings.size();
2378}
2379
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002380void Context::beginTransformFeedback(GLenum primitiveMode)
2381{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002382 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002383 ASSERT(transformFeedback != nullptr);
2384 ASSERT(!transformFeedback->isPaused());
2385
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002386 transformFeedback->begin(primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002387}
2388
2389bool Context::hasActiveTransformFeedback(GLuint program) const
2390{
2391 for (auto pair : mTransformFeedbackMap)
2392 {
2393 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2394 {
2395 return true;
2396 }
2397 }
2398 return false;
2399}
2400
Geoff Langc287ea62016-09-16 14:46:51 -04002401void Context::initCaps(bool webGLContext)
Geoff Lang493daf52014-07-03 13:38:44 -04002402{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002403 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002404
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002405 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002406
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002407 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002408
Geoff Langeb66a6e2016-10-31 13:06:12 -04002409 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002410 {
2411 // Disable ES3+ extensions
2412 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002413 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002414 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002415 }
2416
Geoff Langeb66a6e2016-10-31 13:06:12 -04002417 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002418 {
2419 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2420 //mExtensions.sRGB = false;
2421 }
2422
Jamie Madill00ed7a12016-05-19 13:13:38 -04002423 // Some extensions are always available because they are implemented in the GL layer.
2424 mExtensions.bindUniformLocation = true;
2425 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002426 mExtensions.bindGeneratesResource = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002427 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002428
2429 // Enable the no error extension if the context was created with the flag.
2430 mExtensions.noError = mSkipValidation;
2431
Geoff Lang70d0f492015-12-10 17:45:46 -05002432 // Explicitly enable GL_KHR_debug
2433 mExtensions.debug = true;
2434 mExtensions.maxDebugMessageLength = 1024;
2435 mExtensions.maxDebugLoggedMessages = 1024;
2436 mExtensions.maxDebugGroupStackDepth = 1024;
2437 mExtensions.maxLabelLength = 1024;
2438
Geoff Langff5b2d52016-09-07 11:32:23 -04002439 // Explicitly enable GL_ANGLE_robust_client_memory
2440 mExtensions.robustClientMemory = true;
2441
Geoff Lang301d1612014-07-09 10:34:37 -04002442 // Apply implementation limits
2443 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04002444 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2445 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2446
2447 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002448
Geoff Langc287ea62016-09-16 14:46:51 -04002449 // WebGL compatibility
2450 mExtensions.webglCompatibility = webGLContext;
2451 for (const auto &extensionInfo : GetExtensionInfoMap())
2452 {
2453 // If this context is for WebGL, disable all enableable extensions
Geoff Langc339c4e2016-11-29 10:37:36 -05002454 if (webGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002455 {
2456 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2457 }
2458 }
2459
2460 // Generate texture caps
2461 updateCaps();
2462}
2463
2464void Context::updateCaps()
2465{
Geoff Lang900013c2014-07-07 11:32:19 -04002466 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002467 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002468
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002469 const TextureCapsMap &rendererFormats = mImplementation->getNativeTextureCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002470 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2471 {
2472 GLenum format = i->first;
2473 TextureCaps formatCaps = i->second;
2474
Geoff Lang5d601382014-07-22 15:14:06 -04002475 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002476
Geoff Lang0d8b7242015-09-09 14:56:53 -04002477 // Update the format caps based on the client version and extensions.
2478 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2479 // ES3.
2480 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002481 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002482 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002483 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002484 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002485 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002486
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002487 // OpenGL ES does not support multisampling with non-rendererable formats
2488 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
2489 if (!formatInfo.renderSupport ||
2490 (getClientVersion() < ES_3_1 &&
2491 (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
Geoff Lang493daf52014-07-03 13:38:44 -04002492 {
Geoff Langd87878e2014-09-19 15:42:59 -04002493 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002494 }
Geoff Langd87878e2014-09-19 15:42:59 -04002495
2496 if (formatCaps.texturable && formatInfo.compressed)
2497 {
2498 mCaps.compressedTextureFormats.push_back(format);
2499 }
2500
2501 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002502 }
2503}
2504
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002505void Context::initWorkarounds()
2506{
2507 // Lose the context upon out of memory error if the application is
2508 // expecting to watch for those events.
2509 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2510}
2511
Jamie Madill1b94d432015-08-07 13:23:23 -04002512void Context::syncRendererState()
2513{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002514 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
2515 mImplementation->syncState(mGLState, dirtyBits);
2516 mGLState.clearDirtyBits();
2517 mGLState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002518}
2519
Jamie Madillad9f24e2016-02-12 09:27:24 -05002520void Context::syncRendererState(const State::DirtyBits &bitMask,
2521 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002522{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002523 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
2524 mImplementation->syncState(mGLState, dirtyBits);
2525 mGLState.clearDirtyBits(dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002526
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002527 mGLState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002528}
Jamie Madillc29968b2016-01-20 11:17:23 -05002529
2530void Context::blitFramebuffer(GLint srcX0,
2531 GLint srcY0,
2532 GLint srcX1,
2533 GLint srcY1,
2534 GLint dstX0,
2535 GLint dstY0,
2536 GLint dstX1,
2537 GLint dstY1,
2538 GLbitfield mask,
2539 GLenum filter)
2540{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002541 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002542 ASSERT(drawFramebuffer);
2543
2544 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2545 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2546
Jamie Madillad9f24e2016-02-12 09:27:24 -05002547 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002548
Jamie Madill8415b5f2016-04-26 13:41:39 -04002549 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002550}
Jamie Madillc29968b2016-01-20 11:17:23 -05002551
2552void Context::clear(GLbitfield mask)
2553{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002554 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002555 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002556}
2557
2558void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2559{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002560 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002561 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2562 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002563}
2564
2565void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2566{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002567 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002568 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2569 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002570}
2571
2572void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2573{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002574 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002575 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2576 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002577}
2578
2579void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2580{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002581 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002582 ASSERT(framebufferObject);
2583
2584 // If a buffer is not present, the clear has no effect
2585 if (framebufferObject->getDepthbuffer() == nullptr &&
2586 framebufferObject->getStencilbuffer() == nullptr)
2587 {
2588 return;
2589 }
2590
Jamie Madillad9f24e2016-02-12 09:27:24 -05002591 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002592 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2593 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002594}
2595
2596void Context::readPixels(GLint x,
2597 GLint y,
2598 GLsizei width,
2599 GLsizei height,
2600 GLenum format,
2601 GLenum type,
2602 GLvoid *pixels)
2603{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002604 if (width == 0 || height == 0)
2605 {
2606 return;
2607 }
2608
Jamie Madillad9f24e2016-02-12 09:27:24 -05002609 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002610
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002611 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002612 ASSERT(framebufferObject);
2613
2614 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002615 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002616}
2617
2618void Context::copyTexImage2D(GLenum target,
2619 GLint level,
2620 GLenum internalformat,
2621 GLint x,
2622 GLint y,
2623 GLsizei width,
2624 GLsizei height,
2625 GLint border)
2626{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002627 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002628 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002629
Jamie Madillc29968b2016-01-20 11:17:23 -05002630 Rectangle sourceArea(x, y, width, height);
2631
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002632 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002633 Texture *texture =
2634 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002635 handleError(texture->copyImage(target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002636}
2637
2638void Context::copyTexSubImage2D(GLenum target,
2639 GLint level,
2640 GLint xoffset,
2641 GLint yoffset,
2642 GLint x,
2643 GLint y,
2644 GLsizei width,
2645 GLsizei height)
2646{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002647 if (width == 0 || height == 0)
2648 {
2649 return;
2650 }
2651
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002652 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002653 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002654
Jamie Madillc29968b2016-01-20 11:17:23 -05002655 Offset destOffset(xoffset, yoffset, 0);
2656 Rectangle sourceArea(x, y, width, height);
2657
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002658 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002659 Texture *texture =
2660 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002661 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002662}
2663
2664void Context::copyTexSubImage3D(GLenum target,
2665 GLint level,
2666 GLint xoffset,
2667 GLint yoffset,
2668 GLint zoffset,
2669 GLint x,
2670 GLint y,
2671 GLsizei width,
2672 GLsizei height)
2673{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002674 if (width == 0 || height == 0)
2675 {
2676 return;
2677 }
2678
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002679 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002680 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002681
Jamie Madillc29968b2016-01-20 11:17:23 -05002682 Offset destOffset(xoffset, yoffset, zoffset);
2683 Rectangle sourceArea(x, y, width, height);
2684
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002685 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002686 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002687 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002688}
2689
2690void Context::framebufferTexture2D(GLenum target,
2691 GLenum attachment,
2692 GLenum textarget,
2693 GLuint texture,
2694 GLint level)
2695{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002696 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002697 ASSERT(framebuffer);
2698
2699 if (texture != 0)
2700 {
2701 Texture *textureObj = getTexture(texture);
2702
2703 ImageIndex index = ImageIndex::MakeInvalid();
2704
2705 if (textarget == GL_TEXTURE_2D)
2706 {
2707 index = ImageIndex::Make2D(level);
2708 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08002709 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
2710 {
2711 ASSERT(level == 0);
2712 index = ImageIndex::Make2DMultisample();
2713 }
Jamie Madillc29968b2016-01-20 11:17:23 -05002714 else
2715 {
2716 ASSERT(IsCubeMapTextureTarget(textarget));
2717 index = ImageIndex::MakeCube(textarget, level);
2718 }
2719
2720 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2721 }
2722 else
2723 {
2724 framebuffer->resetAttachment(attachment);
2725 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002726
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002727 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002728}
2729
2730void Context::framebufferRenderbuffer(GLenum target,
2731 GLenum attachment,
2732 GLenum renderbuffertarget,
2733 GLuint renderbuffer)
2734{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002735 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002736 ASSERT(framebuffer);
2737
2738 if (renderbuffer != 0)
2739 {
2740 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2741 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2742 renderbufferObject);
2743 }
2744 else
2745 {
2746 framebuffer->resetAttachment(attachment);
2747 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002748
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002749 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002750}
2751
2752void Context::framebufferTextureLayer(GLenum target,
2753 GLenum attachment,
2754 GLuint texture,
2755 GLint level,
2756 GLint layer)
2757{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002758 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002759 ASSERT(framebuffer);
2760
2761 if (texture != 0)
2762 {
2763 Texture *textureObject = getTexture(texture);
2764
2765 ImageIndex index = ImageIndex::MakeInvalid();
2766
2767 if (textureObject->getTarget() == GL_TEXTURE_3D)
2768 {
2769 index = ImageIndex::Make3D(level, layer);
2770 }
2771 else
2772 {
2773 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2774 index = ImageIndex::Make2DArray(level, layer);
2775 }
2776
2777 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2778 }
2779 else
2780 {
2781 framebuffer->resetAttachment(attachment);
2782 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002783
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002784 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002785}
2786
2787void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2788{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002789 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002790 ASSERT(framebuffer);
2791 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002792 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002793}
2794
2795void Context::readBuffer(GLenum mode)
2796{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002797 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002798 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002799 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002800}
2801
2802void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2803{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002804 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002805 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002806
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002807 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002808 ASSERT(framebuffer);
2809
2810 // The specification isn't clear what should be done when the framebuffer isn't complete.
2811 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002812 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002813}
2814
2815void Context::invalidateFramebuffer(GLenum target,
2816 GLsizei numAttachments,
2817 const GLenum *attachments)
2818{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002819 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002820 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002821
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002822 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002823 ASSERT(framebuffer);
2824
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002825 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002826 {
Jamie Madill437fa652016-05-03 15:13:24 -04002827 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002828 }
Jamie Madill437fa652016-05-03 15:13:24 -04002829
2830 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002831}
2832
2833void Context::invalidateSubFramebuffer(GLenum target,
2834 GLsizei numAttachments,
2835 const GLenum *attachments,
2836 GLint x,
2837 GLint y,
2838 GLsizei width,
2839 GLsizei height)
2840{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002841 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002842 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002843
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002844 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002845 ASSERT(framebuffer);
2846
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002847 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002848 {
Jamie Madill437fa652016-05-03 15:13:24 -04002849 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002850 }
Jamie Madill437fa652016-05-03 15:13:24 -04002851
2852 Rectangle area(x, y, width, height);
2853 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002854}
2855
Jamie Madill73a84962016-02-12 09:27:23 -05002856void Context::texImage2D(GLenum target,
2857 GLint level,
2858 GLint internalformat,
2859 GLsizei width,
2860 GLsizei height,
2861 GLint border,
2862 GLenum format,
2863 GLenum type,
2864 const GLvoid *pixels)
2865{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002866 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002867
2868 Extents size(width, height, 1);
2869 Texture *texture =
2870 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002871 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002872 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002873}
2874
2875void Context::texImage3D(GLenum target,
2876 GLint level,
2877 GLint internalformat,
2878 GLsizei width,
2879 GLsizei height,
2880 GLsizei depth,
2881 GLint border,
2882 GLenum format,
2883 GLenum type,
2884 const GLvoid *pixels)
2885{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002886 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002887
2888 Extents size(width, height, depth);
2889 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002890 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002891 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002892}
2893
2894void Context::texSubImage2D(GLenum target,
2895 GLint level,
2896 GLint xoffset,
2897 GLint yoffset,
2898 GLsizei width,
2899 GLsizei height,
2900 GLenum format,
2901 GLenum type,
2902 const GLvoid *pixels)
2903{
2904 // Zero sized uploads are valid but no-ops
2905 if (width == 0 || height == 0)
2906 {
2907 return;
2908 }
2909
Jamie Madillad9f24e2016-02-12 09:27:24 -05002910 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002911
2912 Box area(xoffset, yoffset, 0, width, height, 1);
2913 Texture *texture =
2914 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002915 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002916 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002917}
2918
2919void Context::texSubImage3D(GLenum target,
2920 GLint level,
2921 GLint xoffset,
2922 GLint yoffset,
2923 GLint zoffset,
2924 GLsizei width,
2925 GLsizei height,
2926 GLsizei depth,
2927 GLenum format,
2928 GLenum type,
2929 const GLvoid *pixels)
2930{
2931 // Zero sized uploads are valid but no-ops
2932 if (width == 0 || height == 0 || depth == 0)
2933 {
2934 return;
2935 }
2936
Jamie Madillad9f24e2016-02-12 09:27:24 -05002937 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002938
2939 Box area(xoffset, yoffset, zoffset, width, height, depth);
2940 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002941 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002942 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002943}
2944
2945void Context::compressedTexImage2D(GLenum target,
2946 GLint level,
2947 GLenum internalformat,
2948 GLsizei width,
2949 GLsizei height,
2950 GLint border,
2951 GLsizei imageSize,
2952 const GLvoid *data)
2953{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002954 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002955
2956 Extents size(width, height, 1);
2957 Texture *texture =
2958 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002959 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2960 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002961 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002962}
2963
2964void Context::compressedTexImage3D(GLenum target,
2965 GLint level,
2966 GLenum internalformat,
2967 GLsizei width,
2968 GLsizei height,
2969 GLsizei depth,
2970 GLint border,
2971 GLsizei imageSize,
2972 const GLvoid *data)
2973{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002974 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002975
2976 Extents size(width, height, depth);
2977 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002978 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2979 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002980 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002981}
2982
2983void Context::compressedTexSubImage2D(GLenum target,
2984 GLint level,
2985 GLint xoffset,
2986 GLint yoffset,
2987 GLsizei width,
2988 GLsizei height,
2989 GLenum format,
2990 GLsizei imageSize,
2991 const GLvoid *data)
2992{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002993 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002994
2995 Box area(xoffset, yoffset, 0, width, height, 1);
2996 Texture *texture =
2997 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002998 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
2999 format, imageSize,
3000 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003001}
3002
3003void Context::compressedTexSubImage3D(GLenum target,
3004 GLint level,
3005 GLint xoffset,
3006 GLint yoffset,
3007 GLint zoffset,
3008 GLsizei width,
3009 GLsizei height,
3010 GLsizei depth,
3011 GLenum format,
3012 GLsizei imageSize,
3013 const GLvoid *data)
3014{
3015 // Zero sized uploads are valid but no-ops
3016 if (width == 0 || height == 0)
3017 {
3018 return;
3019 }
3020
Jamie Madillad9f24e2016-02-12 09:27:24 -05003021 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003022
3023 Box area(xoffset, yoffset, zoffset, width, height, depth);
3024 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003025 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
3026 format, imageSize,
3027 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003028}
3029
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003030void Context::generateMipmap(GLenum target)
3031{
3032 Texture *texture = getTargetTexture(target);
3033 handleError(texture->generateMipmap());
3034}
3035
Geoff Lang97073d12016-04-20 10:42:34 -07003036void Context::copyTextureCHROMIUM(GLuint sourceId,
3037 GLuint destId,
3038 GLint internalFormat,
3039 GLenum destType,
3040 GLboolean unpackFlipY,
3041 GLboolean unpackPremultiplyAlpha,
3042 GLboolean unpackUnmultiplyAlpha)
3043{
3044 syncStateForTexImage();
3045
3046 gl::Texture *sourceTexture = getTexture(sourceId);
3047 gl::Texture *destTexture = getTexture(destId);
3048 handleError(destTexture->copyTexture(internalFormat, destType, unpackFlipY == GL_TRUE,
3049 unpackPremultiplyAlpha == GL_TRUE,
3050 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3051}
3052
3053void Context::copySubTextureCHROMIUM(GLuint sourceId,
3054 GLuint destId,
3055 GLint xoffset,
3056 GLint yoffset,
3057 GLint x,
3058 GLint y,
3059 GLsizei width,
3060 GLsizei height,
3061 GLboolean unpackFlipY,
3062 GLboolean unpackPremultiplyAlpha,
3063 GLboolean unpackUnmultiplyAlpha)
3064{
3065 // Zero sized copies are valid but no-ops
3066 if (width == 0 || height == 0)
3067 {
3068 return;
3069 }
3070
3071 syncStateForTexImage();
3072
3073 gl::Texture *sourceTexture = getTexture(sourceId);
3074 gl::Texture *destTexture = getTexture(destId);
3075 Offset offset(xoffset, yoffset, 0);
3076 Rectangle area(x, y, width, height);
3077 handleError(destTexture->copySubTexture(offset, area, unpackFlipY == GL_TRUE,
3078 unpackPremultiplyAlpha == GL_TRUE,
3079 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3080}
3081
Geoff Lang47110bf2016-04-20 11:13:22 -07003082void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3083{
3084 syncStateForTexImage();
3085
3086 gl::Texture *sourceTexture = getTexture(sourceId);
3087 gl::Texture *destTexture = getTexture(destId);
3088 handleError(destTexture->copyCompressedTexture(sourceTexture));
3089}
3090
Geoff Lang496c02d2016-10-20 11:38:11 -07003091void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003092{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003093 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003094 ASSERT(buffer);
3095
Geoff Lang496c02d2016-10-20 11:38:11 -07003096 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003097}
3098
3099GLvoid *Context::mapBuffer(GLenum target, GLenum access)
3100{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003101 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003102 ASSERT(buffer);
3103
3104 Error error = buffer->map(access);
3105 if (error.isError())
3106 {
Jamie Madill437fa652016-05-03 15:13:24 -04003107 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003108 return nullptr;
3109 }
3110
3111 return buffer->getMapPointer();
3112}
3113
3114GLboolean Context::unmapBuffer(GLenum target)
3115{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003116 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003117 ASSERT(buffer);
3118
3119 GLboolean result;
3120 Error error = buffer->unmap(&result);
3121 if (error.isError())
3122 {
Jamie Madill437fa652016-05-03 15:13:24 -04003123 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003124 return GL_FALSE;
3125 }
3126
3127 return result;
3128}
3129
3130GLvoid *Context::mapBufferRange(GLenum target,
3131 GLintptr offset,
3132 GLsizeiptr length,
3133 GLbitfield access)
3134{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003135 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003136 ASSERT(buffer);
3137
3138 Error error = buffer->mapRange(offset, length, access);
3139 if (error.isError())
3140 {
Jamie Madill437fa652016-05-03 15:13:24 -04003141 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003142 return nullptr;
3143 }
3144
3145 return buffer->getMapPointer();
3146}
3147
3148void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3149{
3150 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3151}
3152
Jamie Madillad9f24e2016-02-12 09:27:24 -05003153void Context::syncStateForReadPixels()
3154{
3155 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3156}
3157
3158void Context::syncStateForTexImage()
3159{
3160 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3161}
3162
3163void Context::syncStateForClear()
3164{
3165 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3166}
3167
3168void Context::syncStateForBlit()
3169{
3170 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3171}
3172
Jamie Madillc20ab272016-06-09 07:20:46 -07003173void Context::activeTexture(GLenum texture)
3174{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003175 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003176}
3177
3178void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3179{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003180 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003181}
3182
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003183void Context::blendEquation(GLenum mode)
3184{
3185 mGLState.setBlendEquation(mode, mode);
3186}
3187
Jamie Madillc20ab272016-06-09 07:20:46 -07003188void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3189{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003190 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003191}
3192
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003193void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3194{
3195 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3196}
3197
Jamie Madillc20ab272016-06-09 07:20:46 -07003198void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3199{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003200 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003201}
3202
3203void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3204{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003205 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003206}
3207
3208void Context::clearDepthf(GLclampf depth)
3209{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003210 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003211}
3212
3213void Context::clearStencil(GLint s)
3214{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003215 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003216}
3217
3218void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3219{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003220 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003221}
3222
3223void Context::cullFace(GLenum mode)
3224{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003225 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003226}
3227
3228void Context::depthFunc(GLenum func)
3229{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003230 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003231}
3232
3233void Context::depthMask(GLboolean flag)
3234{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003235 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003236}
3237
3238void Context::depthRangef(GLclampf zNear, GLclampf zFar)
3239{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003240 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003241}
3242
3243void Context::disable(GLenum cap)
3244{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003245 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003246}
3247
3248void Context::disableVertexAttribArray(GLuint index)
3249{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003250 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003251}
3252
3253void Context::enable(GLenum cap)
3254{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003255 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003256}
3257
3258void Context::enableVertexAttribArray(GLuint index)
3259{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003260 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003261}
3262
3263void Context::frontFace(GLenum mode)
3264{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003265 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003266}
3267
3268void Context::hint(GLenum target, GLenum mode)
3269{
3270 switch (target)
3271 {
3272 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003273 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003274 break;
3275
3276 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003277 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003278 break;
3279
3280 default:
3281 UNREACHABLE();
3282 return;
3283 }
3284}
3285
3286void Context::lineWidth(GLfloat width)
3287{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003288 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003289}
3290
3291void Context::pixelStorei(GLenum pname, GLint param)
3292{
3293 switch (pname)
3294 {
3295 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003296 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003297 break;
3298
3299 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003300 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003301 break;
3302
3303 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003304 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003305 break;
3306
3307 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003308 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003309 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003310 break;
3311
3312 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003313 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003314 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003315 break;
3316
3317 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003318 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003319 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003320 break;
3321
3322 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003323 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003324 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003325 break;
3326
3327 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003328 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003329 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003330 break;
3331
3332 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003333 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003334 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003335 break;
3336
3337 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003338 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003339 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003340 break;
3341
3342 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003343 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003344 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003345 break;
3346
3347 default:
3348 UNREACHABLE();
3349 return;
3350 }
3351}
3352
3353void Context::polygonOffset(GLfloat factor, GLfloat units)
3354{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003355 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003356}
3357
3358void Context::sampleCoverage(GLclampf value, GLboolean invert)
3359{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003360 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003361}
3362
3363void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3364{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003365 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003366}
3367
3368void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3369{
3370 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3371 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003372 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003373 }
3374
3375 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3376 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003377 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003378 }
3379}
3380
3381void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3382{
3383 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3384 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003385 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003386 }
3387
3388 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3389 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003390 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003391 }
3392}
3393
3394void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3395{
3396 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3397 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003398 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003399 }
3400
3401 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3402 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003403 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003404 }
3405}
3406
3407void Context::vertexAttrib1f(GLuint index, GLfloat x)
3408{
3409 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003410 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003411}
3412
3413void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3414{
3415 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003416 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003417}
3418
3419void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3420{
3421 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003422 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003423}
3424
3425void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3426{
3427 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003428 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003429}
3430
3431void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3432{
3433 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003434 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003435}
3436
3437void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3438{
3439 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003440 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003441}
3442
3443void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3444{
3445 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003446 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003447}
3448
3449void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3450{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003451 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003452}
3453
3454void Context::vertexAttribPointer(GLuint index,
3455 GLint size,
3456 GLenum type,
3457 GLboolean normalized,
3458 GLsizei stride,
3459 const GLvoid *ptr)
3460{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003461 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3462 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003463}
3464
3465void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3466{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003467 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003468}
3469
3470void Context::vertexAttribIPointer(GLuint index,
3471 GLint size,
3472 GLenum type,
3473 GLsizei stride,
3474 const GLvoid *pointer)
3475{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003476 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3477 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003478}
3479
3480void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3481{
3482 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003483 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003484}
3485
3486void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3487{
3488 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003489 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003490}
3491
3492void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3493{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003494 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003495}
3496
3497void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3498{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003499 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003500}
3501
3502void Context::debugMessageControl(GLenum source,
3503 GLenum type,
3504 GLenum severity,
3505 GLsizei count,
3506 const GLuint *ids,
3507 GLboolean enabled)
3508{
3509 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003510 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3511 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003512}
3513
3514void Context::debugMessageInsert(GLenum source,
3515 GLenum type,
3516 GLuint id,
3517 GLenum severity,
3518 GLsizei length,
3519 const GLchar *buf)
3520{
3521 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003522 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003523}
3524
3525void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3526{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003527 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003528}
3529
3530GLuint Context::getDebugMessageLog(GLuint count,
3531 GLsizei bufSize,
3532 GLenum *sources,
3533 GLenum *types,
3534 GLuint *ids,
3535 GLenum *severities,
3536 GLsizei *lengths,
3537 GLchar *messageLog)
3538{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003539 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3540 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003541}
3542
3543void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3544{
3545 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003546 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003547}
3548
3549void Context::popDebugGroup()
3550{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003551 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003552}
3553
Jamie Madill29639852016-09-02 15:00:09 -04003554void Context::bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
3555{
3556 Buffer *buffer = mGLState.getTargetBuffer(target);
3557 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003558 handleError(buffer->bufferData(this, target, data, size, usage));
Jamie Madill29639852016-09-02 15:00:09 -04003559}
3560
3561void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
3562{
3563 if (data == nullptr)
3564 {
3565 return;
3566 }
3567
3568 Buffer *buffer = mGLState.getTargetBuffer(target);
3569 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003570 handleError(buffer->bufferSubData(this, target, data, size, offset));
Jamie Madill29639852016-09-02 15:00:09 -04003571}
3572
Jamie Madillef300b12016-10-07 15:12:09 -04003573void Context::attachShader(GLuint program, GLuint shader)
3574{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003575 auto programObject = mState.mShaderPrograms->getProgram(program);
3576 auto shaderObject = mState.mShaderPrograms->getShader(shader);
Jamie Madillef300b12016-10-07 15:12:09 -04003577 ASSERT(programObject && shaderObject);
3578 programObject->attachShader(shaderObject);
3579}
3580
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003581const Workarounds &Context::getWorkarounds() const
3582{
3583 return mWorkarounds;
3584}
3585
Jamie Madillb0817d12016-11-01 15:48:31 -04003586void Context::copyBufferSubData(GLenum readTarget,
3587 GLenum writeTarget,
3588 GLintptr readOffset,
3589 GLintptr writeOffset,
3590 GLsizeiptr size)
3591{
3592 // if size is zero, the copy is a successful no-op
3593 if (size == 0)
3594 {
3595 return;
3596 }
3597
3598 // TODO(jmadill): cache these.
3599 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3600 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3601
3602 handleError(writeBuffer->copyBufferSubData(readBuffer, readOffset, writeOffset, size));
3603}
3604
Jamie Madill01a80ee2016-11-07 12:06:18 -05003605void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3606{
3607 Program *programObject = getProgram(program);
3608 // TODO(jmadill): Re-use this from the validation if possible.
3609 ASSERT(programObject);
3610 programObject->bindAttributeLocation(index, name);
3611}
3612
3613void Context::bindBuffer(GLenum target, GLuint buffer)
3614{
3615 switch (target)
3616 {
3617 case GL_ARRAY_BUFFER:
3618 bindArrayBuffer(buffer);
3619 break;
3620 case GL_ELEMENT_ARRAY_BUFFER:
3621 bindElementArrayBuffer(buffer);
3622 break;
3623 case GL_COPY_READ_BUFFER:
3624 bindCopyReadBuffer(buffer);
3625 break;
3626 case GL_COPY_WRITE_BUFFER:
3627 bindCopyWriteBuffer(buffer);
3628 break;
3629 case GL_PIXEL_PACK_BUFFER:
3630 bindPixelPackBuffer(buffer);
3631 break;
3632 case GL_PIXEL_UNPACK_BUFFER:
3633 bindPixelUnpackBuffer(buffer);
3634 break;
3635 case GL_UNIFORM_BUFFER:
3636 bindGenericUniformBuffer(buffer);
3637 break;
3638 case GL_TRANSFORM_FEEDBACK_BUFFER:
3639 bindGenericTransformFeedbackBuffer(buffer);
3640 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003641 case GL_ATOMIC_COUNTER_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003642 if (buffer != 0)
3643 {
3644 // Binding buffers to this binding point is not implemented yet.
3645 UNIMPLEMENTED();
3646 }
Geoff Lang3b573612016-10-31 14:08:10 -04003647 break;
3648 case GL_SHADER_STORAGE_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003649 if (buffer != 0)
3650 {
3651 // Binding buffers to this binding point is not implemented yet.
3652 UNIMPLEMENTED();
3653 }
Geoff Lang3b573612016-10-31 14:08:10 -04003654 break;
3655 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08003656 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003657 break;
3658 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003659 if (buffer != 0)
3660 {
3661 // Binding buffers to this binding point is not implemented yet.
3662 UNIMPLEMENTED();
3663 }
Geoff Lang3b573612016-10-31 14:08:10 -04003664 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05003665
3666 default:
3667 UNREACHABLE();
3668 break;
3669 }
3670}
3671
3672void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
3673{
3674 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3675 {
3676 bindReadFramebuffer(framebuffer);
3677 }
3678
3679 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3680 {
3681 bindDrawFramebuffer(framebuffer);
3682 }
3683}
3684
3685void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
3686{
3687 ASSERT(target == GL_RENDERBUFFER);
3688 Renderbuffer *object =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003689 mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
Jamie Madill01a80ee2016-11-07 12:06:18 -05003690 mGLState.setRenderbufferBinding(object);
3691}
3692
JiangYizhoubddc46b2016-12-09 09:50:51 +08003693void Context::texStorage2DMultisample(GLenum target,
3694 GLsizei samples,
3695 GLenum internalformat,
3696 GLsizei width,
3697 GLsizei height,
3698 GLboolean fixedsamplelocations)
3699{
3700 Extents size(width, height, 1);
3701 Texture *texture = getTargetTexture(target);
3702 handleError(texture->setStorageMultisample(target, samples, internalformat, size,
3703 fixedsamplelocations));
3704}
3705
3706void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
3707{
3708 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
3709 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
3710
3711 switch (pname)
3712 {
3713 case GL_SAMPLE_POSITION:
3714 handleError(framebuffer->getSamplePosition(index, val));
3715 break;
3716 default:
3717 UNREACHABLE();
3718 }
3719}
3720
Jamie Madillc29968b2016-01-20 11:17:23 -05003721} // namespace gl