blob: 2663bb8a81bf946615fce7379bcd0604200d7820 [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,
249 GetNoError(attribs)),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700250 mImplementation(implFactory->createContext(mState)),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500251 mCompiler(nullptr),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400252 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500253 mClientType(EGL_OPENGL_ES_API),
254 mHasBeenCurrent(false),
255 mContextLost(false),
256 mResetStatus(GL_NO_ERROR),
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700257 mContextLostForced(false),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500258 mResetStrategy(GetResetStrategy(attribs)),
259 mRobustAccess(GetRobustAccess(attribs)),
Corentin Wallezccab69d2017-01-27 16:57:15 -0500260 mCurrentSurface(nullptr),
261 mSurfacelessFramebuffer(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 Wallez80b24112015-08-25 16:41:57 -0400388 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000389 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400390 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000391 }
392
Corentin Wallez80b24112015-08-25 16:41:57 -0400393 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000394 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400395 if (query.second != nullptr)
396 {
397 query.second->release();
398 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000399 }
400
Corentin Wallez80b24112015-08-25 16:41:57 -0400401 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400402 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400403 SafeDelete(vertexArray.second);
Jamie Madill57a89722013-07-02 11:57:03 -0400404 }
405
Corentin Wallez80b24112015-08-25 16:41:57 -0400406 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500407 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500408 if (transformFeedback.second != nullptr)
409 {
410 transformFeedback.second->release();
411 }
Geoff Langc8058452014-02-03 12:04:11 -0500412 }
413
Jamie Madilldedd7b92014-11-05 16:30:36 -0500414 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400415 {
Jamie Madilldedd7b92014-11-05 16:30:36 -0500416 zeroTexture.second.set(NULL);
Geoff Lang76b10c92014-09-05 16:28:14 -0400417 }
418 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000419
Corentin Wallezccab69d2017-01-27 16:57:15 -0500420 SafeDelete(mSurfacelessFramebuffer);
421
Corentin Wallez51706ea2015-08-07 14:39:22 -0400422 if (mCurrentSurface != nullptr)
423 {
424 releaseSurface();
425 }
426
Geoff Lang492a7e42014-11-05 13:27:06 -0500427 SafeDelete(mCompiler);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000428}
429
daniel@transgaming.comad629872012-11-28 19:32:06 +0000430void Context::makeCurrent(egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000431{
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000432 if (!mHasBeenCurrent)
433 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000434 initRendererString();
Geoff Langc339c4e2016-11-29 10:37:36 -0500435 initVersionStrings();
Geoff Langcec35902014-04-16 10:52:36 -0400436 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000437
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700438 mGLState.setViewportParams(0, 0, surface->getWidth(), surface->getHeight());
439 mGLState.setScissorParams(0, 0, surface->getWidth(), surface->getHeight());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000440
441 mHasBeenCurrent = true;
442 }
443
Jamie Madill1b94d432015-08-07 13:23:23 -0400444 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700445 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400446
Corentin Wallez51706ea2015-08-07 14:39:22 -0400447 if (mCurrentSurface)
448 {
449 releaseSurface();
450 }
Corentin Wallezccab69d2017-01-27 16:57:15 -0500451
452 Framebuffer *newDefault = nullptr;
453 if (surface != nullptr)
454 {
455 surface->setIsCurrent(true);
456 mCurrentSurface = surface;
457 newDefault = surface->getDefaultFramebuffer();
458 }
459 else
460 {
461 if (mSurfacelessFramebuffer == nullptr)
462 {
463 mSurfacelessFramebuffer = new Framebuffer(mImplementation.get());
464 }
465
466 newDefault = mSurfacelessFramebuffer;
467 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000468
Corentin Wallez37c39792015-08-20 14:19:46 -0400469 // Update default framebuffer, the binding of the previous default
470 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400471 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700472 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400473 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700474 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400475 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700476 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400477 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700478 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400479 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500480 mState.mFramebuffers->setDefaultFramebuffer(newDefault);
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400481 }
Ian Ewell292f0052016-02-04 10:37:32 -0500482
483 // Notify the renderer of a context switch
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700484 mImplementation->onMakeCurrent(mState);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000485}
486
Jamie Madill77a72f62015-04-14 11:18:32 -0400487void Context::releaseSurface()
488{
Corentin Wallez37c39792015-08-20 14:19:46 -0400489 ASSERT(mCurrentSurface != nullptr);
490
491 // Remove the default framebuffer
Corentin Wallez51706ea2015-08-07 14:39:22 -0400492 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400493 Framebuffer *currentDefault = mCurrentSurface->getDefaultFramebuffer();
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700494 if (mGLState.getReadFramebuffer() == currentDefault)
Corentin Wallez37c39792015-08-20 14:19:46 -0400495 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700496 mGLState.setReadFramebufferBinding(nullptr);
Corentin Wallez37c39792015-08-20 14:19:46 -0400497 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700498 if (mGLState.getDrawFramebuffer() == currentDefault)
Corentin Wallez37c39792015-08-20 14:19:46 -0400499 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700500 mGLState.setDrawFramebufferBinding(nullptr);
Corentin Wallez37c39792015-08-20 14:19:46 -0400501 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500502 mState.mFramebuffers->setDefaultFramebuffer(nullptr);
Corentin Wallez51706ea2015-08-07 14:39:22 -0400503 }
504
Corentin Wallez51706ea2015-08-07 14:39:22 -0400505 mCurrentSurface->setIsCurrent(false);
506 mCurrentSurface = nullptr;
Jamie Madill77a72f62015-04-14 11:18:32 -0400507}
508
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000509GLuint Context::createBuffer()
510{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500511 return mState.mBuffers->createBuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000512}
513
514GLuint Context::createProgram()
515{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500516 return mState.mShaderPrograms->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000517}
518
519GLuint Context::createShader(GLenum type)
520{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500521 return mState.mShaderPrograms->createShader(mImplementation.get(), mLimitations, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000522}
523
524GLuint Context::createTexture()
525{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500526 return mState.mTextures->createTexture();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000527}
528
529GLuint Context::createRenderbuffer()
530{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500531 return mState.mRenderbuffers->createRenderbuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000532}
533
Geoff Lang882033e2014-09-30 11:26:07 -0400534GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400535{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500536 GLuint handle = mState.mFenceSyncs->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400537
Cooper Partind8e62a32015-01-29 15:21:25 -0800538 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400539}
540
Sami Väisänene45e53b2016-05-25 10:36:04 +0300541GLuint Context::createPaths(GLsizei range)
542{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500543 auto resultOrError = mState.mPaths->createPaths(mImplementation.get(), range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300544 if (resultOrError.isError())
545 {
546 handleError(resultOrError.getError());
547 return 0;
548 }
549 return resultOrError.getResult();
550}
551
Jamie Madill57a89722013-07-02 11:57:03 -0400552GLuint Context::createVertexArray()
553{
Geoff Lang36167ab2015-12-07 10:27:14 -0500554 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
555 mVertexArrayMap[vertexArray] = nullptr;
556 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400557}
558
Jamie Madilldc356042013-07-19 16:36:57 -0400559GLuint Context::createSampler()
560{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500561 return mState.mSamplers->createSampler();
Jamie Madilldc356042013-07-19 16:36:57 -0400562}
563
Geoff Langc8058452014-02-03 12:04:11 -0500564GLuint Context::createTransformFeedback()
565{
Geoff Lang36167ab2015-12-07 10:27:14 -0500566 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
567 mTransformFeedbackMap[transformFeedback] = nullptr;
568 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500569}
570
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000571// Returns an unused framebuffer name
572GLuint Context::createFramebuffer()
573{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500574 return mState.mFramebuffers->createFramebuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000575}
576
Jamie Madill33dc8432013-07-26 11:55:05 -0400577GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000578{
Jamie Madill33dc8432013-07-26 11:55:05 -0400579 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000580
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400581 mFenceNVMap[handle] = new FenceNV(mImplementation->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000582
583 return handle;
584}
585
586// Returns an unused query name
587GLuint Context::createQuery()
588{
589 GLuint handle = mQueryHandleAllocator.allocate();
590
591 mQueryMap[handle] = NULL;
592
593 return handle;
594}
595
596void Context::deleteBuffer(GLuint buffer)
597{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500598 if (mState.mBuffers->getBuffer(buffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000599 {
600 detachBuffer(buffer);
601 }
Jamie Madill893ab082014-05-16 16:56:10 -0400602
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500603 mState.mBuffers->deleteBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000604}
605
606void Context::deleteShader(GLuint shader)
607{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500608 mState.mShaderPrograms->deleteShader(shader);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000609}
610
611void Context::deleteProgram(GLuint program)
612{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500613 mState.mShaderPrograms->deleteProgram(program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000614}
615
616void Context::deleteTexture(GLuint texture)
617{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500618 if (mState.mTextures->getTexture(texture))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000619 {
620 detachTexture(texture);
621 }
622
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500623 mState.mTextures->deleteTexture(texture);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000624}
625
626void Context::deleteRenderbuffer(GLuint renderbuffer)
627{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500628 if (mState.mRenderbuffers->getRenderbuffer(renderbuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000629 {
630 detachRenderbuffer(renderbuffer);
631 }
Jamie Madill893ab082014-05-16 16:56:10 -0400632
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500633 mState.mRenderbuffers->deleteRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000634}
635
Jamie Madillcd055f82013-07-26 11:55:15 -0400636void Context::deleteFenceSync(GLsync fenceSync)
637{
638 // The spec specifies the underlying Fence object is not deleted until all current
639 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
640 // and since our API is currently designed for being called from a single thread, we can delete
641 // the fence immediately.
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500642 mState.mFenceSyncs->deleteFenceSync(
643 static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400644}
645
Sami Väisänene45e53b2016-05-25 10:36:04 +0300646void Context::deletePaths(GLuint first, GLsizei range)
647{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500648 mState.mPaths->deletePaths(first, range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300649}
650
651bool Context::hasPathData(GLuint path) const
652{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500653 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300654 if (pathObj == nullptr)
655 return false;
656
657 return pathObj->hasPathData();
658}
659
660bool Context::hasPath(GLuint path) const
661{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500662 return mState.mPaths->hasPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300663}
664
665void Context::setPathCommands(GLuint path,
666 GLsizei numCommands,
667 const GLubyte *commands,
668 GLsizei numCoords,
669 GLenum coordType,
670 const void *coords)
671{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500672 auto *pathObject = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300673
674 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
675}
676
677void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
678{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500679 auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300680
681 switch (pname)
682 {
683 case GL_PATH_STROKE_WIDTH_CHROMIUM:
684 pathObj->setStrokeWidth(value);
685 break;
686 case GL_PATH_END_CAPS_CHROMIUM:
687 pathObj->setEndCaps(static_cast<GLenum>(value));
688 break;
689 case GL_PATH_JOIN_STYLE_CHROMIUM:
690 pathObj->setJoinStyle(static_cast<GLenum>(value));
691 break;
692 case GL_PATH_MITER_LIMIT_CHROMIUM:
693 pathObj->setMiterLimit(value);
694 break;
695 case GL_PATH_STROKE_BOUND_CHROMIUM:
696 pathObj->setStrokeBound(value);
697 break;
698 default:
699 UNREACHABLE();
700 break;
701 }
702}
703
704void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
705{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500706 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300707
708 switch (pname)
709 {
710 case GL_PATH_STROKE_WIDTH_CHROMIUM:
711 *value = pathObj->getStrokeWidth();
712 break;
713 case GL_PATH_END_CAPS_CHROMIUM:
714 *value = static_cast<GLfloat>(pathObj->getEndCaps());
715 break;
716 case GL_PATH_JOIN_STYLE_CHROMIUM:
717 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
718 break;
719 case GL_PATH_MITER_LIMIT_CHROMIUM:
720 *value = pathObj->getMiterLimit();
721 break;
722 case GL_PATH_STROKE_BOUND_CHROMIUM:
723 *value = pathObj->getStrokeBound();
724 break;
725 default:
726 UNREACHABLE();
727 break;
728 }
729}
730
731void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
732{
733 mGLState.setPathStencilFunc(func, ref, mask);
734}
735
Jamie Madill57a89722013-07-02 11:57:03 -0400736void Context::deleteVertexArray(GLuint vertexArray)
737{
Geoff Lang36167ab2015-12-07 10:27:14 -0500738 auto iter = mVertexArrayMap.find(vertexArray);
739 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000740 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500741 VertexArray *vertexArrayObject = iter->second;
742 if (vertexArrayObject != nullptr)
743 {
744 detachVertexArray(vertexArray);
745 delete vertexArrayObject;
746 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000747
Geoff Lang36167ab2015-12-07 10:27:14 -0500748 mVertexArrayMap.erase(iter);
749 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400750 }
751}
752
Jamie Madilldc356042013-07-19 16:36:57 -0400753void Context::deleteSampler(GLuint sampler)
754{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500755 if (mState.mSamplers->getSampler(sampler))
Jamie Madilldc356042013-07-19 16:36:57 -0400756 {
757 detachSampler(sampler);
758 }
759
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500760 mState.mSamplers->deleteSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400761}
762
Geoff Langc8058452014-02-03 12:04:11 -0500763void Context::deleteTransformFeedback(GLuint transformFeedback)
764{
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500765 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500766 if (iter != mTransformFeedbackMap.end())
767 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500768 TransformFeedback *transformFeedbackObject = iter->second;
769 if (transformFeedbackObject != nullptr)
770 {
771 detachTransformFeedback(transformFeedback);
772 transformFeedbackObject->release();
773 }
774
Geoff Lang50b3fe82015-12-08 14:49:12 +0000775 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500776 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500777 }
778}
779
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000780void Context::deleteFramebuffer(GLuint framebuffer)
781{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500782 if (mState.mFramebuffers->getFramebuffer(framebuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000783 {
784 detachFramebuffer(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000785 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500786
787 mState.mFramebuffers->deleteFramebuffer(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000788}
789
Jamie Madill33dc8432013-07-26 11:55:05 -0400790void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000791{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500792 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000793
Jamie Madill33dc8432013-07-26 11:55:05 -0400794 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000795 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400796 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000797 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400798 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000799 }
800}
801
802void Context::deleteQuery(GLuint query)
803{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500804 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000805 if (queryObject != mQueryMap.end())
806 {
807 mQueryHandleAllocator.release(queryObject->first);
808 if (queryObject->second)
809 {
810 queryObject->second->release();
811 }
812 mQueryMap.erase(queryObject);
813 }
814}
815
Geoff Lang70d0f492015-12-10 17:45:46 -0500816Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000817{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500818 return mState.mBuffers->getBuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000819}
820
Jamie Madill570f7c82014-07-03 10:38:54 -0400821Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000822{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500823 return mState.mTextures->getTexture(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000824}
825
Geoff Lang70d0f492015-12-10 17:45:46 -0500826Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000827{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500828 return mState.mRenderbuffers->getRenderbuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000829}
830
Jamie Madillcd055f82013-07-26 11:55:15 -0400831FenceSync *Context::getFenceSync(GLsync handle) const
832{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500833 return mState.mFenceSyncs->getFenceSync(
834 static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400835}
836
Jamie Madill57a89722013-07-02 11:57:03 -0400837VertexArray *Context::getVertexArray(GLuint handle) const
838{
839 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500840 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400841}
842
Jamie Madilldc356042013-07-19 16:36:57 -0400843Sampler *Context::getSampler(GLuint handle) const
844{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500845 return mState.mSamplers->getSampler(handle);
Jamie Madilldc356042013-07-19 16:36:57 -0400846}
847
Geoff Langc8058452014-02-03 12:04:11 -0500848TransformFeedback *Context::getTransformFeedback(GLuint handle) const
849{
Geoff Lang36167ab2015-12-07 10:27:14 -0500850 auto iter = mTransformFeedbackMap.find(handle);
851 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500852}
853
Geoff Lang70d0f492015-12-10 17:45:46 -0500854LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
855{
856 switch (identifier)
857 {
858 case GL_BUFFER:
859 return getBuffer(name);
860 case GL_SHADER:
861 return getShader(name);
862 case GL_PROGRAM:
863 return getProgram(name);
864 case GL_VERTEX_ARRAY:
865 return getVertexArray(name);
866 case GL_QUERY:
867 return getQuery(name);
868 case GL_TRANSFORM_FEEDBACK:
869 return getTransformFeedback(name);
870 case GL_SAMPLER:
871 return getSampler(name);
872 case GL_TEXTURE:
873 return getTexture(name);
874 case GL_RENDERBUFFER:
875 return getRenderbuffer(name);
876 case GL_FRAMEBUFFER:
877 return getFramebuffer(name);
878 default:
879 UNREACHABLE();
880 return nullptr;
881 }
882}
883
884LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
885{
886 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
887}
888
Martin Radev9d901792016-07-15 15:58:58 +0300889void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
890{
891 LabeledObject *object = getLabeledObject(identifier, name);
892 ASSERT(object != nullptr);
893
894 std::string labelName = GetObjectLabelFromPointer(length, label);
895 object->setLabel(labelName);
896}
897
898void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
899{
900 LabeledObject *object = getLabeledObjectFromPtr(ptr);
901 ASSERT(object != nullptr);
902
903 std::string labelName = GetObjectLabelFromPointer(length, label);
904 object->setLabel(labelName);
905}
906
907void Context::getObjectLabel(GLenum identifier,
908 GLuint name,
909 GLsizei bufSize,
910 GLsizei *length,
911 GLchar *label) const
912{
913 LabeledObject *object = getLabeledObject(identifier, name);
914 ASSERT(object != nullptr);
915
916 const std::string &objectLabel = object->getLabel();
917 GetObjectLabelBase(objectLabel, bufSize, length, label);
918}
919
920void Context::getObjectPtrLabel(const void *ptr,
921 GLsizei bufSize,
922 GLsizei *length,
923 GLchar *label) const
924{
925 LabeledObject *object = getLabeledObjectFromPtr(ptr);
926 ASSERT(object != nullptr);
927
928 const std::string &objectLabel = object->getLabel();
929 GetObjectLabelBase(objectLabel, bufSize, length, label);
930}
931
Jamie Madilldc356042013-07-19 16:36:57 -0400932bool Context::isSampler(GLuint samplerName) const
933{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500934 return mState.mSamplers->isSampler(samplerName);
Jamie Madilldc356042013-07-19 16:36:57 -0400935}
936
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500937void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000938{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500939 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700940 mGLState.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000941}
942
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800943void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
944{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500945 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800946 mGLState.setDrawIndirectBufferBinding(buffer);
947}
948
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500949void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000950{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500951 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700952 mGLState.getVertexArray()->setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000953}
954
Jamie Madilldedd7b92014-11-05 16:30:36 -0500955void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000956{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500957 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000958
Jamie Madilldedd7b92014-11-05 16:30:36 -0500959 if (handle == 0)
960 {
961 texture = mZeroTextures[target].get();
962 }
963 else
964 {
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500965 texture = mState.mTextures->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500966 }
967
968 ASSERT(texture);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700969 mGLState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000970}
971
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500972void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000973{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500974 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
975 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700976 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000977}
978
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500979void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000980{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500981 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
982 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700983 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000984}
985
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500986void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -0400987{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500988 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700989 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400990}
991
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500992void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -0400993{
Geoff Lang76b10c92014-09-05 16:28:14 -0400994 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -0400995 Sampler *sampler =
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500996 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700997 mGLState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400998}
999
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001000void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001001{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001002 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001003 mGLState.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001004}
1005
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001006void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1007 GLuint index,
1008 GLintptr offset,
1009 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001010{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001011 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001012 mGLState.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001013}
1014
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001015void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001016{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001017 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001018 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001019}
1020
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001021void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1022 GLuint index,
1023 GLintptr offset,
1024 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001025{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001026 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001027 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001028}
1029
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001030void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001031{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001032 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001033 mGLState.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001034}
1035
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001036void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001037{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001038 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001039 mGLState.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001040}
1041
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001042void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001043{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001044 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001045 mGLState.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001046}
1047
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001048void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001049{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001050 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001051 mGLState.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001052}
1053
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001054void Context::useProgram(GLuint program)
1055{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001056 mGLState.setProgram(getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001057}
1058
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001059void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001060{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001061 TransformFeedback *transformFeedback =
1062 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001063 mGLState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001064}
1065
Geoff Lang5aad9672014-09-08 11:10:42 -04001066Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001067{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001068 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001069 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001070
Geoff Lang5aad9672014-09-08 11:10:42 -04001071 // begin query
1072 Error error = queryObject->begin();
1073 if (error.isError())
1074 {
1075 return error;
1076 }
1077
1078 // set query as active for specified target only if begin succeeded
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001079 mGLState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001080
He Yunchaoacd18982017-01-04 10:46:42 +08001081 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001082}
1083
Geoff Lang5aad9672014-09-08 11:10:42 -04001084Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001085{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001086 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001087 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001088
Geoff Lang5aad9672014-09-08 11:10:42 -04001089 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001090
Geoff Lang5aad9672014-09-08 11:10:42 -04001091 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001092 mGLState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -04001093
1094 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001095}
1096
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001097Error Context::queryCounter(GLuint id, GLenum target)
1098{
1099 ASSERT(target == GL_TIMESTAMP_EXT);
1100
1101 Query *queryObject = getQuery(id, true, target);
1102 ASSERT(queryObject);
1103
1104 return queryObject->queryCounter();
1105}
1106
1107void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1108{
1109 switch (pname)
1110 {
1111 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001112 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001113 break;
1114 case GL_QUERY_COUNTER_BITS_EXT:
1115 switch (target)
1116 {
1117 case GL_TIME_ELAPSED_EXT:
1118 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1119 break;
1120 case GL_TIMESTAMP_EXT:
1121 params[0] = getExtensions().queryCounterBitsTimestamp;
1122 break;
1123 default:
1124 UNREACHABLE();
1125 params[0] = 0;
1126 break;
1127 }
1128 break;
1129 default:
1130 UNREACHABLE();
1131 return;
1132 }
1133}
1134
Geoff Lang2186c382016-10-14 10:54:54 -04001135void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001136{
Geoff Lang2186c382016-10-14 10:54:54 -04001137 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001138}
1139
Geoff Lang2186c382016-10-14 10:54:54 -04001140void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001141{
Geoff Lang2186c382016-10-14 10:54:54 -04001142 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001143}
1144
Geoff Lang2186c382016-10-14 10:54:54 -04001145void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001146{
Geoff Lang2186c382016-10-14 10:54:54 -04001147 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001148}
1149
Geoff Lang2186c382016-10-14 10:54:54 -04001150void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001151{
Geoff Lang2186c382016-10-14 10:54:54 -04001152 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001153}
1154
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001155Framebuffer *Context::getFramebuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001156{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001157 return mState.mFramebuffers->getFramebuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001158}
1159
Jamie Madill33dc8432013-07-26 11:55:05 -04001160FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001161{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001162 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001163
Jamie Madill33dc8432013-07-26 11:55:05 -04001164 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001165 {
1166 return NULL;
1167 }
1168 else
1169 {
1170 return fence->second;
1171 }
1172}
1173
1174Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1175{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001176 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001177
1178 if (query == mQueryMap.end())
1179 {
1180 return NULL;
1181 }
1182 else
1183 {
1184 if (!query->second && create)
1185 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001186 query->second = new Query(mImplementation->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001187 query->second->addRef();
1188 }
1189 return query->second;
1190 }
1191}
1192
Geoff Lang70d0f492015-12-10 17:45:46 -05001193Query *Context::getQuery(GLuint handle) const
1194{
1195 auto iter = mQueryMap.find(handle);
1196 return (iter != mQueryMap.end()) ? iter->second : nullptr;
1197}
1198
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001199Texture *Context::getTargetTexture(GLenum target) const
1200{
Ian Ewellbda75592016-04-18 17:25:54 -04001201 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001202 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001203}
1204
Geoff Lang76b10c92014-09-05 16:28:14 -04001205Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001206{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001207 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001208}
1209
Geoff Lang492a7e42014-11-05 13:27:06 -05001210Compiler *Context::getCompiler() const
1211{
1212 return mCompiler;
1213}
1214
Jamie Madill893ab082014-05-16 16:56:10 -04001215void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001216{
1217 switch (pname)
1218 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001219 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001220 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001221 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001222 mGLState.getBooleanv(pname, params);
1223 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001224 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001225}
1226
Jamie Madill893ab082014-05-16 16:56:10 -04001227void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001228{
Shannon Woods53a94a82014-06-24 15:20:36 -04001229 // Queries about context capabilities and maximums are answered by Context.
1230 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001231 switch (pname)
1232 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001233 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001234 params[0] = mCaps.minAliasedLineWidth;
1235 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001236 break;
1237 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001238 params[0] = mCaps.minAliasedPointSize;
1239 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001240 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001241 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001242 ASSERT(mExtensions.textureFilterAnisotropic);
1243 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001244 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001245 case GL_MAX_TEXTURE_LOD_BIAS:
1246 *params = mCaps.maxLODBias;
1247 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001248
1249 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1250 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1251 {
1252 ASSERT(mExtensions.pathRendering);
1253 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1254 memcpy(params, m, 16 * sizeof(GLfloat));
1255 }
1256 break;
1257
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001258 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001259 mGLState.getFloatv(pname, params);
1260 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001261 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001262}
1263
Jamie Madill893ab082014-05-16 16:56:10 -04001264void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001265{
Shannon Woods53a94a82014-06-24 15:20:36 -04001266 // Queries about context capabilities and maximums are answered by Context.
1267 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001268
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001269 switch (pname)
1270 {
Geoff Lang301d1612014-07-09 10:34:37 -04001271 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1272 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1273 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001274 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1275 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1276 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001277 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1278 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1279 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001280 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001281 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1282 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1283 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001284 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001285 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001286 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1287 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1288 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1289 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001290 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1291 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001292 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1293 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001294 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001295 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1296 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1297 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1298 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Martin Radev1be913c2016-07-11 17:59:16 +03001299 case GL_MAJOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001300 *params = getClientVersion().major;
Martin Radev1be913c2016-07-11 17:59:16 +03001301 break;
1302 case GL_MINOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001303 *params = getClientVersion().minor;
Martin Radev1be913c2016-07-11 17:59:16 +03001304 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001305 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1306 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001307 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1308 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1309 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001310 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1311 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1312 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001313 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001314 case GL_MAX_VIEWPORT_DIMS:
1315 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001316 params[0] = mCaps.maxViewportWidth;
1317 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001318 }
1319 break;
1320 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001321 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001322 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001323 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1324 *params = mResetStrategy;
1325 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001326 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001327 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001328 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001329 case GL_SHADER_BINARY_FORMATS:
1330 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1331 break;
1332 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001333 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001334 break;
1335 case GL_PROGRAM_BINARY_FORMATS:
1336 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001337 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001338 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001339 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001340 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001341
1342 // GL_KHR_debug
1343 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1344 *params = mExtensions.maxDebugMessageLength;
1345 break;
1346 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1347 *params = mExtensions.maxDebugLoggedMessages;
1348 break;
1349 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1350 *params = mExtensions.maxDebugGroupStackDepth;
1351 break;
1352 case GL_MAX_LABEL_LENGTH:
1353 *params = mExtensions.maxLabelLength;
1354 break;
1355
Ian Ewell53f59f42016-01-28 17:36:55 -05001356 // GL_EXT_disjoint_timer_query
1357 case GL_GPU_DISJOINT_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001358 *params = mImplementation->getGPUDisjoint();
Ian Ewell53f59f42016-01-28 17:36:55 -05001359 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001360 case GL_MAX_FRAMEBUFFER_WIDTH:
1361 *params = mCaps.maxFramebufferWidth;
1362 break;
1363 case GL_MAX_FRAMEBUFFER_HEIGHT:
1364 *params = mCaps.maxFramebufferHeight;
1365 break;
1366 case GL_MAX_FRAMEBUFFER_SAMPLES:
1367 *params = mCaps.maxFramebufferSamples;
1368 break;
1369 case GL_MAX_SAMPLE_MASK_WORDS:
1370 *params = mCaps.maxSampleMaskWords;
1371 break;
1372 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1373 *params = mCaps.maxColorTextureSamples;
1374 break;
1375 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1376 *params = mCaps.maxDepthTextureSamples;
1377 break;
1378 case GL_MAX_INTEGER_SAMPLES:
1379 *params = mCaps.maxIntegerSamples;
1380 break;
1381 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1382 *params = mCaps.maxVertexAttribRelativeOffset;
1383 break;
1384 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1385 *params = mCaps.maxVertexAttribBindings;
1386 break;
1387 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1388 *params = mCaps.maxVertexAttribStride;
1389 break;
1390 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1391 *params = mCaps.maxVertexAtomicCounterBuffers;
1392 break;
1393 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1394 *params = mCaps.maxVertexAtomicCounters;
1395 break;
1396 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1397 *params = mCaps.maxVertexImageUniforms;
1398 break;
1399 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1400 *params = mCaps.maxVertexShaderStorageBlocks;
1401 break;
1402 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1403 *params = mCaps.maxFragmentAtomicCounterBuffers;
1404 break;
1405 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1406 *params = mCaps.maxFragmentAtomicCounters;
1407 break;
1408 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1409 *params = mCaps.maxFragmentImageUniforms;
1410 break;
1411 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1412 *params = mCaps.maxFragmentShaderStorageBlocks;
1413 break;
1414 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1415 *params = mCaps.minProgramTextureGatherOffset;
1416 break;
1417 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1418 *params = mCaps.maxProgramTextureGatherOffset;
1419 break;
1420 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1421 *params = mCaps.maxComputeWorkGroupInvocations;
1422 break;
1423 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1424 *params = mCaps.maxComputeUniformBlocks;
1425 break;
1426 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1427 *params = mCaps.maxComputeTextureImageUnits;
1428 break;
1429 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1430 *params = mCaps.maxComputeSharedMemorySize;
1431 break;
1432 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1433 *params = mCaps.maxComputeUniformComponents;
1434 break;
1435 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1436 *params = mCaps.maxComputeAtomicCounterBuffers;
1437 break;
1438 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1439 *params = mCaps.maxComputeAtomicCounters;
1440 break;
1441 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1442 *params = mCaps.maxComputeImageUniforms;
1443 break;
1444 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1445 *params = mCaps.maxCombinedComputeUniformComponents;
1446 break;
1447 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1448 *params = mCaps.maxComputeShaderStorageBlocks;
1449 break;
1450 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1451 *params = mCaps.maxCombinedShaderOutputResources;
1452 break;
1453 case GL_MAX_UNIFORM_LOCATIONS:
1454 *params = mCaps.maxUniformLocations;
1455 break;
1456 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1457 *params = mCaps.maxAtomicCounterBufferBindings;
1458 break;
1459 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1460 *params = mCaps.maxAtomicCounterBufferSize;
1461 break;
1462 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1463 *params = mCaps.maxCombinedAtomicCounterBuffers;
1464 break;
1465 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1466 *params = mCaps.maxCombinedAtomicCounters;
1467 break;
1468 case GL_MAX_IMAGE_UNITS:
1469 *params = mCaps.maxImageUnits;
1470 break;
1471 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1472 *params = mCaps.maxCombinedImageUniforms;
1473 break;
1474 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1475 *params = mCaps.maxShaderStorageBufferBindings;
1476 break;
1477 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1478 *params = mCaps.maxCombinedShaderStorageBlocks;
1479 break;
1480 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1481 *params = mCaps.shaderStorageBufferOffsetAlignment;
1482 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001483 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001484 mGLState.getIntegerv(mState, pname, params);
1485 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001486 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001487}
1488
Jamie Madill893ab082014-05-16 16:56:10 -04001489void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001490{
Shannon Woods53a94a82014-06-24 15:20:36 -04001491 // Queries about context capabilities and maximums are answered by Context.
1492 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001493 switch (pname)
1494 {
1495 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001496 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001497 break;
1498 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001499 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001500 break;
1501 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001502 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001503 break;
1504 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001505 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001506 break;
1507 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001508 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001509 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001510
1511 // GL_EXT_disjoint_timer_query
1512 case GL_TIMESTAMP_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001513 *params = mImplementation->getTimestamp();
Ian Ewell53f59f42016-01-28 17:36:55 -05001514 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001515
1516 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1517 *params = mCaps.maxShaderStorageBlockSize;
1518 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001519 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001520 UNREACHABLE();
1521 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001522 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001523}
1524
Geoff Lang70d0f492015-12-10 17:45:46 -05001525void Context::getPointerv(GLenum pname, void **params) const
1526{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001527 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001528}
1529
Martin Radev66fb8202016-07-28 11:45:20 +03001530void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001531{
Shannon Woods53a94a82014-06-24 15:20:36 -04001532 // Queries about context capabilities and maximums are answered by Context.
1533 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001534
1535 GLenum nativeType;
1536 unsigned int numParams;
1537 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1538 ASSERT(queryStatus);
1539
1540 if (nativeType == GL_INT)
1541 {
1542 switch (target)
1543 {
1544 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1545 ASSERT(index < 3u);
1546 *data = mCaps.maxComputeWorkGroupCount[index];
1547 break;
1548 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1549 ASSERT(index < 3u);
1550 *data = mCaps.maxComputeWorkGroupSize[index];
1551 break;
1552 default:
1553 mGLState.getIntegeri_v(target, index, data);
1554 }
1555 }
1556 else
1557 {
1558 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1559 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001560}
1561
Martin Radev66fb8202016-07-28 11:45:20 +03001562void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001563{
Shannon Woods53a94a82014-06-24 15:20:36 -04001564 // Queries about context capabilities and maximums are answered by Context.
1565 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001566
1567 GLenum nativeType;
1568 unsigned int numParams;
1569 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1570 ASSERT(queryStatus);
1571
1572 if (nativeType == GL_INT_64_ANGLEX)
1573 {
1574 mGLState.getInteger64i_v(target, index, data);
1575 }
1576 else
1577 {
1578 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1579 }
1580}
1581
1582void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1583{
1584 // Queries about context capabilities and maximums are answered by Context.
1585 // Queries about current GL state values are answered by State.
1586
1587 GLenum nativeType;
1588 unsigned int numParams;
1589 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1590 ASSERT(queryStatus);
1591
1592 if (nativeType == GL_BOOL)
1593 {
1594 mGLState.getBooleani_v(target, index, data);
1595 }
1596 else
1597 {
1598 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1599 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001600}
1601
Jamie Madill675fe712016-12-19 13:07:54 -05001602void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001603{
Jamie Madill1b94d432015-08-07 13:23:23 -04001604 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001605 auto error = mImplementation->drawArrays(mode, first, count);
1606 handleError(error);
1607 if (!error.isError())
1608 {
1609 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1610 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001611}
1612
Jamie Madill675fe712016-12-19 13:07:54 -05001613void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Geoff Langf6db0982015-08-25 13:04:00 -04001614{
1615 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001616 auto error = mImplementation->drawArraysInstanced(mode, first, count, instanceCount);
1617 handleError(error);
1618 if (!error.isError())
1619 {
1620 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1621 }
Geoff Langf6db0982015-08-25 13:04:00 -04001622}
1623
Jamie Madill675fe712016-12-19 13:07:54 -05001624void Context::drawElements(GLenum mode,
1625 GLsizei count,
1626 GLenum type,
1627 const GLvoid *indices,
1628 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001629{
Jamie Madill1b94d432015-08-07 13:23:23 -04001630 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001631 handleError(mImplementation->drawElements(mode, count, type, indices, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001632}
1633
Jamie Madill675fe712016-12-19 13:07:54 -05001634void Context::drawElementsInstanced(GLenum mode,
1635 GLsizei count,
1636 GLenum type,
1637 const GLvoid *indices,
1638 GLsizei instances,
1639 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001640{
1641 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001642 handleError(
1643 mImplementation->drawElementsInstanced(mode, count, type, indices, instances, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001644}
1645
Jamie Madill675fe712016-12-19 13:07:54 -05001646void Context::drawRangeElements(GLenum mode,
1647 GLuint start,
1648 GLuint end,
1649 GLsizei count,
1650 GLenum type,
1651 const GLvoid *indices,
1652 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001653{
1654 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001655 handleError(
1656 mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001657}
1658
Jiajia Qind9671222016-11-29 16:30:31 +08001659void Context::drawArraysIndirect(GLenum mode, const GLvoid *indirect)
1660{
1661 syncRendererState();
1662 handleError(mImplementation->drawArraysIndirect(mode, indirect));
1663}
1664
1665void Context::drawElementsIndirect(GLenum mode, GLenum type, const GLvoid *indirect)
1666{
1667 syncRendererState();
1668 handleError(mImplementation->drawElementsIndirect(mode, type, indirect));
1669}
1670
Jamie Madill675fe712016-12-19 13:07:54 -05001671void Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001672{
Jamie Madill675fe712016-12-19 13:07:54 -05001673 handleError(mImplementation->flush());
Geoff Lang129753a2015-01-09 16:52:09 -05001674}
1675
Jamie Madill675fe712016-12-19 13:07:54 -05001676void Context::finish()
Geoff Lang129753a2015-01-09 16:52:09 -05001677{
Jamie Madill675fe712016-12-19 13:07:54 -05001678 handleError(mImplementation->finish());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001679}
1680
Austin Kinross6ee1e782015-05-29 17:05:37 -07001681void Context::insertEventMarker(GLsizei length, const char *marker)
1682{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001683 ASSERT(mImplementation);
1684 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001685}
1686
1687void Context::pushGroupMarker(GLsizei length, const char *marker)
1688{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001689 ASSERT(mImplementation);
1690 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001691}
1692
1693void Context::popGroupMarker()
1694{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001695 ASSERT(mImplementation);
1696 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001697}
1698
Geoff Langd8605522016-04-13 10:19:12 -04001699void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1700{
1701 Program *programObject = getProgram(program);
1702 ASSERT(programObject);
1703
1704 programObject->bindUniformLocation(location, name);
1705}
1706
Sami Väisänena797e062016-05-12 15:23:40 +03001707void Context::setCoverageModulation(GLenum components)
1708{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001709 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001710}
1711
Sami Väisänene45e53b2016-05-25 10:36:04 +03001712void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1713{
1714 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1715}
1716
1717void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1718{
1719 GLfloat I[16];
1720 angle::Matrix<GLfloat>::setToIdentity(I);
1721
1722 mGLState.loadPathRenderingMatrix(matrixMode, I);
1723}
1724
1725void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1726{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001727 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001728 if (!pathObj)
1729 return;
1730
1731 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1732 syncRendererState();
1733
1734 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1735}
1736
1737void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1738{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001739 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001740 if (!pathObj)
1741 return;
1742
1743 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1744 syncRendererState();
1745
1746 mImplementation->stencilStrokePath(pathObj, reference, mask);
1747}
1748
1749void Context::coverFillPath(GLuint path, GLenum coverMode)
1750{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001751 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001752 if (!pathObj)
1753 return;
1754
1755 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1756 syncRendererState();
1757
1758 mImplementation->coverFillPath(pathObj, coverMode);
1759}
1760
1761void Context::coverStrokePath(GLuint path, GLenum coverMode)
1762{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001763 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001764 if (!pathObj)
1765 return;
1766
1767 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1768 syncRendererState();
1769
1770 mImplementation->coverStrokePath(pathObj, coverMode);
1771}
1772
1773void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1774{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001775 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001776 if (!pathObj)
1777 return;
1778
1779 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1780 syncRendererState();
1781
1782 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1783}
1784
1785void Context::stencilThenCoverStrokePath(GLuint path,
1786 GLint reference,
1787 GLuint mask,
1788 GLenum coverMode)
1789{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001790 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001791 if (!pathObj)
1792 return;
1793
1794 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1795 syncRendererState();
1796
1797 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1798}
1799
Sami Väisänend59ca052016-06-21 16:10:00 +03001800void Context::coverFillPathInstanced(GLsizei numPaths,
1801 GLenum pathNameType,
1802 const void *paths,
1803 GLuint pathBase,
1804 GLenum coverMode,
1805 GLenum transformType,
1806 const GLfloat *transformValues)
1807{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001808 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001809
1810 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1811 syncRendererState();
1812
1813 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1814}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001815
Sami Väisänend59ca052016-06-21 16:10:00 +03001816void Context::coverStrokePathInstanced(GLsizei numPaths,
1817 GLenum pathNameType,
1818 const void *paths,
1819 GLuint pathBase,
1820 GLenum coverMode,
1821 GLenum transformType,
1822 const GLfloat *transformValues)
1823{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001824 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001825
1826 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1827 syncRendererState();
1828
1829 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1830 transformValues);
1831}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001832
Sami Väisänend59ca052016-06-21 16:10:00 +03001833void Context::stencilFillPathInstanced(GLsizei numPaths,
1834 GLenum pathNameType,
1835 const void *paths,
1836 GLuint pathBase,
1837 GLenum fillMode,
1838 GLuint mask,
1839 GLenum transformType,
1840 const GLfloat *transformValues)
1841{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001842 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001843
1844 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1845 syncRendererState();
1846
1847 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1848 transformValues);
1849}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001850
Sami Väisänend59ca052016-06-21 16:10:00 +03001851void Context::stencilStrokePathInstanced(GLsizei numPaths,
1852 GLenum pathNameType,
1853 const void *paths,
1854 GLuint pathBase,
1855 GLint reference,
1856 GLuint mask,
1857 GLenum transformType,
1858 const GLfloat *transformValues)
1859{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001860 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001861
1862 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1863 syncRendererState();
1864
1865 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
1866 transformValues);
1867}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001868
Sami Väisänend59ca052016-06-21 16:10:00 +03001869void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
1870 GLenum pathNameType,
1871 const void *paths,
1872 GLuint pathBase,
1873 GLenum fillMode,
1874 GLuint mask,
1875 GLenum coverMode,
1876 GLenum transformType,
1877 const GLfloat *transformValues)
1878{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001879 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001880
1881 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1882 syncRendererState();
1883
1884 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
1885 transformType, transformValues);
1886}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001887
Sami Väisänend59ca052016-06-21 16:10:00 +03001888void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
1889 GLenum pathNameType,
1890 const void *paths,
1891 GLuint pathBase,
1892 GLint reference,
1893 GLuint mask,
1894 GLenum coverMode,
1895 GLenum transformType,
1896 const GLfloat *transformValues)
1897{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001898 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001899
1900 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1901 syncRendererState();
1902
1903 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
1904 transformType, transformValues);
1905}
1906
Sami Väisänen46eaa942016-06-29 10:26:37 +03001907void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
1908{
1909 auto *programObject = getProgram(program);
1910
1911 programObject->bindFragmentInputLocation(location, name);
1912}
1913
1914void Context::programPathFragmentInputGen(GLuint program,
1915 GLint location,
1916 GLenum genMode,
1917 GLint components,
1918 const GLfloat *coeffs)
1919{
1920 auto *programObject = getProgram(program);
1921
1922 programObject->pathFragmentInputGen(location, genMode, components, coeffs);
1923}
1924
Jamie Madill437fa652016-05-03 15:13:24 -04001925void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001926{
Geoff Langda5777c2014-07-11 09:52:58 -04001927 if (error.isError())
1928 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001929 GLenum code = error.getCode();
1930 mErrors.insert(code);
1931 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
1932 {
1933 markContextLost();
1934 }
Geoff Lang70d0f492015-12-10 17:45:46 -05001935
1936 if (!error.getMessage().empty())
1937 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001938 auto *debug = &mGLState.getDebug();
1939 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1940 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05001941 }
Geoff Langda5777c2014-07-11 09:52:58 -04001942 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001943}
1944
1945// Get one of the recorded errors and clear its flag, if any.
1946// [OpenGL ES 2.0.24] section 2.5 page 13.
1947GLenum Context::getError()
1948{
Geoff Langda5777c2014-07-11 09:52:58 -04001949 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001950 {
Geoff Langda5777c2014-07-11 09:52:58 -04001951 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001952 }
Geoff Langda5777c2014-07-11 09:52:58 -04001953 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001954 {
Geoff Langda5777c2014-07-11 09:52:58 -04001955 GLenum error = *mErrors.begin();
1956 mErrors.erase(mErrors.begin());
1957 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001958 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001959}
1960
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001961// NOTE: this function should not assume that this context is current!
1962void Context::markContextLost()
1963{
1964 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001965 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001966 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001967 mContextLostForced = true;
1968 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001969 mContextLost = true;
1970}
1971
1972bool Context::isContextLost()
1973{
1974 return mContextLost;
1975}
1976
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001977GLenum Context::getResetStatus()
1978{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001979 // Even if the application doesn't want to know about resets, we want to know
1980 // as it will allow us to skip all the calls.
1981 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001982 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001983 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001984 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001985 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001986 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001987
1988 // EXT_robustness, section 2.6: If the reset notification behavior is
1989 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
1990 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
1991 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001992 }
1993
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001994 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
1995 // status should be returned at least once, and GL_NO_ERROR should be returned
1996 // once the device has finished resetting.
1997 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001998 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001999 ASSERT(mResetStatus == GL_NO_ERROR);
2000 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002001
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002002 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002003 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002004 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002005 }
2006 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002007 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002008 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002009 // If markContextLost was used to mark the context lost then
2010 // assume that is not recoverable, and continue to report the
2011 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002012 mResetStatus = mImplementation->getResetStatus();
2013 }
Jamie Madill893ab082014-05-16 16:56:10 -04002014
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002015 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002016}
2017
2018bool Context::isResetNotificationEnabled()
2019{
2020 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2021}
2022
Corentin Walleze3b10e82015-05-20 11:06:25 -04002023const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002024{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002025 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002026}
2027
2028EGLenum Context::getClientType() const
2029{
2030 return mClientType;
2031}
2032
2033EGLenum Context::getRenderBuffer() const
2034{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002035 const Framebuffer *framebuffer = mState.mFramebuffers->getFramebuffer(0);
2036 if (framebuffer == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -04002037 {
2038 return EGL_NONE;
2039 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002040
2041 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2042 ASSERT(backAttachment != nullptr);
2043 return backAttachment->getSurface()->getRenderBuffer();
Régis Fénéon83107972015-02-05 12:57:44 +01002044}
2045
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002046VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002047{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002048 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002049 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2050 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002051 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002052 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle, MAX_VERTEX_ATTRIBS);
2053
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002054 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002055 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002056
2057 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002058}
2059
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002060TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002061{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002062 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002063 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2064 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002065 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002066 transformFeedback =
2067 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002068 transformFeedback->addRef();
2069 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002070 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002071
2072 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002073}
2074
2075bool Context::isVertexArrayGenerated(GLuint vertexArray)
2076{
Geoff Langf41a7152016-09-19 15:11:17 -04002077 ASSERT(mVertexArrayMap.find(0) != mVertexArrayMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002078 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
2079}
2080
2081bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2082{
Geoff Langf41a7152016-09-19 15:11:17 -04002083 ASSERT(mTransformFeedbackMap.find(0) != mTransformFeedbackMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002084 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
2085}
2086
Shannon Woods53a94a82014-06-24 15:20:36 -04002087void Context::detachTexture(GLuint texture)
2088{
2089 // Simple pass-through to State's detachTexture method, as textures do not require
2090 // allocation map management either here or in the resource manager at detach time.
2091 // Zero textures are held by the Context, and we don't attempt to request them from
2092 // the State.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002093 mGLState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002094}
2095
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002096void Context::detachBuffer(GLuint buffer)
2097{
Yuly Novikov5807a532015-12-03 13:01:22 -05002098 // Simple pass-through to State's detachBuffer method, since
2099 // only buffer attachments to container objects that are bound to the current context
2100 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002101
Yuly Novikov5807a532015-12-03 13:01:22 -05002102 // [OpenGL ES 3.2] section 5.1.2 page 45:
2103 // Attachments to unbound container objects, such as
2104 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2105 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002106 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002107}
2108
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002109void Context::detachFramebuffer(GLuint framebuffer)
2110{
Shannon Woods53a94a82014-06-24 15:20:36 -04002111 // Framebuffer detachment is handled by Context, because 0 is a valid
2112 // Framebuffer object, and a pointer to it must be passed from Context
2113 // to State at binding time.
2114
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002115 // [OpenGL ES 2.0.24] section 4.4 page 107:
2116 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2117 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2118
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002119 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002120 {
2121 bindReadFramebuffer(0);
2122 }
2123
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002124 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002125 {
2126 bindDrawFramebuffer(0);
2127 }
2128}
2129
2130void Context::detachRenderbuffer(GLuint renderbuffer)
2131{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002132 mGLState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002133}
2134
Jamie Madill57a89722013-07-02 11:57:03 -04002135void Context::detachVertexArray(GLuint vertexArray)
2136{
Jamie Madill77a72f62015-04-14 11:18:32 -04002137 // Vertex array detachment is handled by Context, because 0 is a valid
2138 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002139 // binding time.
2140
Jamie Madill57a89722013-07-02 11:57:03 -04002141 // [OpenGL ES 3.0.2] section 2.10 page 43:
2142 // If a vertex array object that is currently bound is deleted, the binding
2143 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002144 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002145 {
2146 bindVertexArray(0);
2147 }
2148}
2149
Geoff Langc8058452014-02-03 12:04:11 -05002150void Context::detachTransformFeedback(GLuint transformFeedback)
2151{
Corentin Walleza2257da2016-04-19 16:43:12 -04002152 // Transform feedback detachment is handled by Context, because 0 is a valid
2153 // transform feedback, and a pointer to it must be passed from Context to State at
2154 // binding time.
2155
2156 // The OpenGL specification doesn't mention what should happen when the currently bound
2157 // transform feedback object is deleted. Since it is a container object, we treat it like
2158 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002159 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002160 {
2161 bindTransformFeedback(0);
2162 }
Geoff Langc8058452014-02-03 12:04:11 -05002163}
2164
Jamie Madilldc356042013-07-19 16:36:57 -04002165void Context::detachSampler(GLuint sampler)
2166{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002167 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002168}
2169
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002170void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2171{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002172 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002173}
2174
Jamie Madille29d1672013-07-19 16:36:57 -04002175void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2176{
Geoff Langc1984ed2016-10-07 12:41:00 -04002177 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002178 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002179 SetSamplerParameteri(samplerObject, pname, param);
2180}
Jamie Madille29d1672013-07-19 16:36:57 -04002181
Geoff Langc1984ed2016-10-07 12:41:00 -04002182void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2183{
2184 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002185 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002186 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002187}
2188
2189void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2190{
Geoff Langc1984ed2016-10-07 12:41:00 -04002191 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002192 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002193 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002194}
2195
Geoff Langc1984ed2016-10-07 12:41:00 -04002196void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002197{
Geoff Langc1984ed2016-10-07 12:41:00 -04002198 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002199 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002200 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002201}
2202
Geoff Langc1984ed2016-10-07 12:41:00 -04002203void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002204{
Geoff Langc1984ed2016-10-07 12:41:00 -04002205 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002206 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002207 QuerySamplerParameteriv(samplerObject, pname, params);
2208}
Jamie Madill9675b802013-07-19 16:36:59 -04002209
Geoff Langc1984ed2016-10-07 12:41:00 -04002210void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2211{
2212 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002213 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002214 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002215}
2216
Olli Etuahof0fee072016-03-30 15:11:58 +03002217void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2218{
2219 gl::Program *programObject = getProgram(program);
2220 ASSERT(programObject != nullptr);
2221
2222 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
2223 programObject->setBinaryRetrievableHint(value != GL_FALSE);
2224}
2225
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002226void Context::initRendererString()
2227{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002228 std::ostringstream rendererString;
2229 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002230 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002231 rendererString << ")";
2232
Geoff Langcec35902014-04-16 10:52:36 -04002233 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002234}
2235
Geoff Langc339c4e2016-11-29 10:37:36 -05002236void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002237{
Geoff Langc339c4e2016-11-29 10:37:36 -05002238 const Version &clientVersion = getClientVersion();
2239
2240 std::ostringstream versionString;
2241 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2242 << ANGLE_VERSION_STRING << ")";
2243 mVersionString = MakeStaticString(versionString.str());
2244
2245 std::ostringstream shadingLanguageVersionString;
2246 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2247 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2248 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2249 << ")";
2250 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002251}
2252
Geoff Langcec35902014-04-16 10:52:36 -04002253void Context::initExtensionStrings()
2254{
Geoff Langc339c4e2016-11-29 10:37:36 -05002255 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2256 std::ostringstream combinedStringStream;
2257 std::copy(strings.begin(), strings.end(),
2258 std::ostream_iterator<const char *>(combinedStringStream, " "));
2259 return MakeStaticString(combinedStringStream.str());
2260 };
2261
2262 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002263 for (const auto &extensionString : mExtensions.getStrings())
2264 {
2265 mExtensionStrings.push_back(MakeStaticString(extensionString));
2266 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002267 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002268
Bryan Bernhart58806562017-01-05 13:09:31 -08002269 const gl::Extensions &nativeExtensions = mImplementation->getNativeExtensions();
2270
Geoff Langc339c4e2016-11-29 10:37:36 -05002271 mRequestableExtensionStrings.clear();
2272 for (const auto &extensionInfo : GetExtensionInfoMap())
2273 {
2274 if (extensionInfo.second.Requestable &&
Bryan Bernhart58806562017-01-05 13:09:31 -08002275 !(mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
2276 nativeExtensions.*(extensionInfo.second.ExtensionsMember))
Geoff Langc339c4e2016-11-29 10:37:36 -05002277 {
2278 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2279 }
2280 }
2281 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002282}
2283
Geoff Langc339c4e2016-11-29 10:37:36 -05002284const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002285{
Geoff Langc339c4e2016-11-29 10:37:36 -05002286 switch (name)
2287 {
2288 case GL_VENDOR:
2289 return reinterpret_cast<const GLubyte *>("Google Inc.");
2290
2291 case GL_RENDERER:
2292 return reinterpret_cast<const GLubyte *>(mRendererString);
2293
2294 case GL_VERSION:
2295 return reinterpret_cast<const GLubyte *>(mVersionString);
2296
2297 case GL_SHADING_LANGUAGE_VERSION:
2298 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2299
2300 case GL_EXTENSIONS:
2301 return reinterpret_cast<const GLubyte *>(mExtensionString);
2302
2303 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2304 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2305
2306 default:
2307 UNREACHABLE();
2308 return nullptr;
2309 }
Geoff Langcec35902014-04-16 10:52:36 -04002310}
2311
Geoff Langc339c4e2016-11-29 10:37:36 -05002312const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002313{
Geoff Langc339c4e2016-11-29 10:37:36 -05002314 switch (name)
2315 {
2316 case GL_EXTENSIONS:
2317 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2318
2319 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2320 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2321
2322 default:
2323 UNREACHABLE();
2324 return nullptr;
2325 }
Geoff Langcec35902014-04-16 10:52:36 -04002326}
2327
2328size_t Context::getExtensionStringCount() const
2329{
2330 return mExtensionStrings.size();
2331}
2332
Geoff Langc339c4e2016-11-29 10:37:36 -05002333void Context::requestExtension(const char *name)
2334{
2335 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2336 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2337 const auto &extension = extensionInfos.at(name);
2338 ASSERT(extension.Requestable);
2339
2340 if (mExtensions.*(extension.ExtensionsMember))
2341 {
2342 // Extension already enabled
2343 return;
2344 }
2345
2346 mExtensions.*(extension.ExtensionsMember) = true;
2347 updateCaps();
2348 initExtensionStrings();
Bryan Bernhart58806562017-01-05 13:09:31 -08002349
2350 // Re-create the compiler with the requested extensions enabled.
2351 SafeDelete(mCompiler);
2352 mCompiler = new Compiler(mImplementation.get(), mState);
Geoff Langc339c4e2016-11-29 10:37:36 -05002353}
2354
2355size_t Context::getRequestableExtensionStringCount() const
2356{
2357 return mRequestableExtensionStrings.size();
2358}
2359
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002360void Context::beginTransformFeedback(GLenum primitiveMode)
2361{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002362 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002363 ASSERT(transformFeedback != nullptr);
2364 ASSERT(!transformFeedback->isPaused());
2365
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002366 transformFeedback->begin(primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002367}
2368
2369bool Context::hasActiveTransformFeedback(GLuint program) const
2370{
2371 for (auto pair : mTransformFeedbackMap)
2372 {
2373 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2374 {
2375 return true;
2376 }
2377 }
2378 return false;
2379}
2380
Geoff Langc287ea62016-09-16 14:46:51 -04002381void Context::initCaps(bool webGLContext)
Geoff Lang493daf52014-07-03 13:38:44 -04002382{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002383 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002384
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002385 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002386
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002387 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002388
Geoff Langeb66a6e2016-10-31 13:06:12 -04002389 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002390 {
2391 // Disable ES3+ extensions
2392 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002393 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002394 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002395 }
2396
Geoff Langeb66a6e2016-10-31 13:06:12 -04002397 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002398 {
2399 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2400 //mExtensions.sRGB = false;
2401 }
2402
Jamie Madill00ed7a12016-05-19 13:13:38 -04002403 // Some extensions are always available because they are implemented in the GL layer.
2404 mExtensions.bindUniformLocation = true;
2405 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002406 mExtensions.bindGeneratesResource = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002407 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002408
2409 // Enable the no error extension if the context was created with the flag.
2410 mExtensions.noError = mSkipValidation;
2411
Corentin Wallezccab69d2017-01-27 16:57:15 -05002412 // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
2413 mExtensions.surfacelessContext = true;
2414
Geoff Lang70d0f492015-12-10 17:45:46 -05002415 // Explicitly enable GL_KHR_debug
2416 mExtensions.debug = true;
2417 mExtensions.maxDebugMessageLength = 1024;
2418 mExtensions.maxDebugLoggedMessages = 1024;
2419 mExtensions.maxDebugGroupStackDepth = 1024;
2420 mExtensions.maxLabelLength = 1024;
2421
Geoff Langff5b2d52016-09-07 11:32:23 -04002422 // Explicitly enable GL_ANGLE_robust_client_memory
2423 mExtensions.robustClientMemory = true;
2424
Geoff Lang301d1612014-07-09 10:34:37 -04002425 // Apply implementation limits
2426 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04002427 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2428 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2429
2430 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002431
Geoff Langc287ea62016-09-16 14:46:51 -04002432 // WebGL compatibility
2433 mExtensions.webglCompatibility = webGLContext;
2434 for (const auto &extensionInfo : GetExtensionInfoMap())
2435 {
2436 // If this context is for WebGL, disable all enableable extensions
Geoff Langc339c4e2016-11-29 10:37:36 -05002437 if (webGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002438 {
2439 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2440 }
2441 }
2442
2443 // Generate texture caps
2444 updateCaps();
2445}
2446
2447void Context::updateCaps()
2448{
Geoff Lang900013c2014-07-07 11:32:19 -04002449 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002450 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002451
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002452 const TextureCapsMap &rendererFormats = mImplementation->getNativeTextureCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002453 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2454 {
2455 GLenum format = i->first;
2456 TextureCaps formatCaps = i->second;
2457
Geoff Lang5d601382014-07-22 15:14:06 -04002458 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002459
Geoff Lang0d8b7242015-09-09 14:56:53 -04002460 // Update the format caps based on the client version and extensions.
2461 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2462 // ES3.
2463 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002464 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002465 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002466 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002467 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002468 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002469
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002470 // OpenGL ES does not support multisampling with non-rendererable formats
2471 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
2472 if (!formatInfo.renderSupport ||
2473 (getClientVersion() < ES_3_1 &&
2474 (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
Geoff Lang493daf52014-07-03 13:38:44 -04002475 {
Geoff Langd87878e2014-09-19 15:42:59 -04002476 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002477 }
Geoff Langd87878e2014-09-19 15:42:59 -04002478
2479 if (formatCaps.texturable && formatInfo.compressed)
2480 {
2481 mCaps.compressedTextureFormats.push_back(format);
2482 }
2483
2484 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002485 }
2486}
2487
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002488void Context::initWorkarounds()
2489{
2490 // Lose the context upon out of memory error if the application is
2491 // expecting to watch for those events.
2492 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2493}
2494
Jamie Madill1b94d432015-08-07 13:23:23 -04002495void Context::syncRendererState()
2496{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002497 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
2498 mImplementation->syncState(mGLState, dirtyBits);
2499 mGLState.clearDirtyBits();
2500 mGLState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002501}
2502
Jamie Madillad9f24e2016-02-12 09:27:24 -05002503void Context::syncRendererState(const State::DirtyBits &bitMask,
2504 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002505{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002506 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
2507 mImplementation->syncState(mGLState, dirtyBits);
2508 mGLState.clearDirtyBits(dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002509
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002510 mGLState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002511}
Jamie Madillc29968b2016-01-20 11:17:23 -05002512
2513void Context::blitFramebuffer(GLint srcX0,
2514 GLint srcY0,
2515 GLint srcX1,
2516 GLint srcY1,
2517 GLint dstX0,
2518 GLint dstY0,
2519 GLint dstX1,
2520 GLint dstY1,
2521 GLbitfield mask,
2522 GLenum filter)
2523{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002524 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002525 ASSERT(drawFramebuffer);
2526
2527 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2528 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2529
Jamie Madillad9f24e2016-02-12 09:27:24 -05002530 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002531
Jamie Madill8415b5f2016-04-26 13:41:39 -04002532 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002533}
Jamie Madillc29968b2016-01-20 11:17:23 -05002534
2535void Context::clear(GLbitfield mask)
2536{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002537 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002538 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002539}
2540
2541void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2542{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002543 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002544 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2545 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002546}
2547
2548void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2549{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002550 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002551 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2552 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002553}
2554
2555void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2556{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002557 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002558 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2559 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002560}
2561
2562void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2563{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002564 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002565 ASSERT(framebufferObject);
2566
2567 // If a buffer is not present, the clear has no effect
2568 if (framebufferObject->getDepthbuffer() == nullptr &&
2569 framebufferObject->getStencilbuffer() == nullptr)
2570 {
2571 return;
2572 }
2573
Jamie Madillad9f24e2016-02-12 09:27:24 -05002574 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002575 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2576 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002577}
2578
2579void Context::readPixels(GLint x,
2580 GLint y,
2581 GLsizei width,
2582 GLsizei height,
2583 GLenum format,
2584 GLenum type,
2585 GLvoid *pixels)
2586{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002587 if (width == 0 || height == 0)
2588 {
2589 return;
2590 }
2591
Jamie Madillad9f24e2016-02-12 09:27:24 -05002592 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002593
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002594 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002595 ASSERT(framebufferObject);
2596
2597 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002598 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002599}
2600
2601void Context::copyTexImage2D(GLenum target,
2602 GLint level,
2603 GLenum internalformat,
2604 GLint x,
2605 GLint y,
2606 GLsizei width,
2607 GLsizei height,
2608 GLint border)
2609{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002610 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002611 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002612
Jamie Madillc29968b2016-01-20 11:17:23 -05002613 Rectangle sourceArea(x, y, width, height);
2614
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002615 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002616 Texture *texture =
2617 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002618 handleError(texture->copyImage(target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002619}
2620
2621void Context::copyTexSubImage2D(GLenum target,
2622 GLint level,
2623 GLint xoffset,
2624 GLint yoffset,
2625 GLint x,
2626 GLint y,
2627 GLsizei width,
2628 GLsizei height)
2629{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002630 if (width == 0 || height == 0)
2631 {
2632 return;
2633 }
2634
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002635 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002636 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002637
Jamie Madillc29968b2016-01-20 11:17:23 -05002638 Offset destOffset(xoffset, yoffset, 0);
2639 Rectangle sourceArea(x, y, width, height);
2640
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002641 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002642 Texture *texture =
2643 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002644 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002645}
2646
2647void Context::copyTexSubImage3D(GLenum target,
2648 GLint level,
2649 GLint xoffset,
2650 GLint yoffset,
2651 GLint zoffset,
2652 GLint x,
2653 GLint y,
2654 GLsizei width,
2655 GLsizei height)
2656{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002657 if (width == 0 || height == 0)
2658 {
2659 return;
2660 }
2661
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002662 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002663 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002664
Jamie Madillc29968b2016-01-20 11:17:23 -05002665 Offset destOffset(xoffset, yoffset, zoffset);
2666 Rectangle sourceArea(x, y, width, height);
2667
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002668 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002669 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002670 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002671}
2672
2673void Context::framebufferTexture2D(GLenum target,
2674 GLenum attachment,
2675 GLenum textarget,
2676 GLuint texture,
2677 GLint level)
2678{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002679 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002680 ASSERT(framebuffer);
2681
2682 if (texture != 0)
2683 {
2684 Texture *textureObj = getTexture(texture);
2685
2686 ImageIndex index = ImageIndex::MakeInvalid();
2687
2688 if (textarget == GL_TEXTURE_2D)
2689 {
2690 index = ImageIndex::Make2D(level);
2691 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08002692 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
2693 {
2694 ASSERT(level == 0);
2695 index = ImageIndex::Make2DMultisample();
2696 }
Jamie Madillc29968b2016-01-20 11:17:23 -05002697 else
2698 {
2699 ASSERT(IsCubeMapTextureTarget(textarget));
2700 index = ImageIndex::MakeCube(textarget, level);
2701 }
2702
2703 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2704 }
2705 else
2706 {
2707 framebuffer->resetAttachment(attachment);
2708 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002709
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002710 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002711}
2712
2713void Context::framebufferRenderbuffer(GLenum target,
2714 GLenum attachment,
2715 GLenum renderbuffertarget,
2716 GLuint renderbuffer)
2717{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002718 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002719 ASSERT(framebuffer);
2720
2721 if (renderbuffer != 0)
2722 {
2723 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2724 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2725 renderbufferObject);
2726 }
2727 else
2728 {
2729 framebuffer->resetAttachment(attachment);
2730 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002731
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002732 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002733}
2734
2735void Context::framebufferTextureLayer(GLenum target,
2736 GLenum attachment,
2737 GLuint texture,
2738 GLint level,
2739 GLint layer)
2740{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002741 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002742 ASSERT(framebuffer);
2743
2744 if (texture != 0)
2745 {
2746 Texture *textureObject = getTexture(texture);
2747
2748 ImageIndex index = ImageIndex::MakeInvalid();
2749
2750 if (textureObject->getTarget() == GL_TEXTURE_3D)
2751 {
2752 index = ImageIndex::Make3D(level, layer);
2753 }
2754 else
2755 {
2756 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2757 index = ImageIndex::Make2DArray(level, layer);
2758 }
2759
2760 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2761 }
2762 else
2763 {
2764 framebuffer->resetAttachment(attachment);
2765 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002766
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002767 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002768}
2769
2770void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2771{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002772 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002773 ASSERT(framebuffer);
2774 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002775 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002776}
2777
2778void Context::readBuffer(GLenum mode)
2779{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002780 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002781 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002782 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002783}
2784
2785void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2786{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002787 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002788 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002789
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002790 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002791 ASSERT(framebuffer);
2792
2793 // The specification isn't clear what should be done when the framebuffer isn't complete.
2794 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002795 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002796}
2797
2798void Context::invalidateFramebuffer(GLenum target,
2799 GLsizei numAttachments,
2800 const GLenum *attachments)
2801{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002802 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002803 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002804
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002805 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002806 ASSERT(framebuffer);
2807
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002808 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002809 {
Jamie Madill437fa652016-05-03 15:13:24 -04002810 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002811 }
Jamie Madill437fa652016-05-03 15:13:24 -04002812
2813 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002814}
2815
2816void Context::invalidateSubFramebuffer(GLenum target,
2817 GLsizei numAttachments,
2818 const GLenum *attachments,
2819 GLint x,
2820 GLint y,
2821 GLsizei width,
2822 GLsizei height)
2823{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002824 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002825 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002826
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002827 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002828 ASSERT(framebuffer);
2829
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002830 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002831 {
Jamie Madill437fa652016-05-03 15:13:24 -04002832 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002833 }
Jamie Madill437fa652016-05-03 15:13:24 -04002834
2835 Rectangle area(x, y, width, height);
2836 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002837}
2838
Jamie Madill73a84962016-02-12 09:27:23 -05002839void Context::texImage2D(GLenum target,
2840 GLint level,
2841 GLint internalformat,
2842 GLsizei width,
2843 GLsizei height,
2844 GLint border,
2845 GLenum format,
2846 GLenum type,
2847 const GLvoid *pixels)
2848{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002849 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002850
2851 Extents size(width, height, 1);
2852 Texture *texture =
2853 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002854 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002855 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002856}
2857
2858void Context::texImage3D(GLenum target,
2859 GLint level,
2860 GLint internalformat,
2861 GLsizei width,
2862 GLsizei height,
2863 GLsizei depth,
2864 GLint border,
2865 GLenum format,
2866 GLenum type,
2867 const GLvoid *pixels)
2868{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002869 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002870
2871 Extents size(width, height, depth);
2872 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002873 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002874 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002875}
2876
2877void Context::texSubImage2D(GLenum target,
2878 GLint level,
2879 GLint xoffset,
2880 GLint yoffset,
2881 GLsizei width,
2882 GLsizei height,
2883 GLenum format,
2884 GLenum type,
2885 const GLvoid *pixels)
2886{
2887 // Zero sized uploads are valid but no-ops
2888 if (width == 0 || height == 0)
2889 {
2890 return;
2891 }
2892
Jamie Madillad9f24e2016-02-12 09:27:24 -05002893 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002894
2895 Box area(xoffset, yoffset, 0, width, height, 1);
2896 Texture *texture =
2897 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002898 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002899 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002900}
2901
2902void Context::texSubImage3D(GLenum target,
2903 GLint level,
2904 GLint xoffset,
2905 GLint yoffset,
2906 GLint zoffset,
2907 GLsizei width,
2908 GLsizei height,
2909 GLsizei depth,
2910 GLenum format,
2911 GLenum type,
2912 const GLvoid *pixels)
2913{
2914 // Zero sized uploads are valid but no-ops
2915 if (width == 0 || height == 0 || depth == 0)
2916 {
2917 return;
2918 }
2919
Jamie Madillad9f24e2016-02-12 09:27:24 -05002920 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002921
2922 Box area(xoffset, yoffset, zoffset, width, height, depth);
2923 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002924 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002925 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002926}
2927
2928void Context::compressedTexImage2D(GLenum target,
2929 GLint level,
2930 GLenum internalformat,
2931 GLsizei width,
2932 GLsizei height,
2933 GLint border,
2934 GLsizei imageSize,
2935 const GLvoid *data)
2936{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002937 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002938
2939 Extents size(width, height, 1);
2940 Texture *texture =
2941 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002942 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2943 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002944 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002945}
2946
2947void Context::compressedTexImage3D(GLenum target,
2948 GLint level,
2949 GLenum internalformat,
2950 GLsizei width,
2951 GLsizei height,
2952 GLsizei depth,
2953 GLint border,
2954 GLsizei imageSize,
2955 const GLvoid *data)
2956{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002957 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002958
2959 Extents size(width, height, depth);
2960 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002961 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2962 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002963 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002964}
2965
2966void Context::compressedTexSubImage2D(GLenum target,
2967 GLint level,
2968 GLint xoffset,
2969 GLint yoffset,
2970 GLsizei width,
2971 GLsizei height,
2972 GLenum format,
2973 GLsizei imageSize,
2974 const GLvoid *data)
2975{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002976 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002977
2978 Box area(xoffset, yoffset, 0, width, height, 1);
2979 Texture *texture =
2980 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002981 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
2982 format, imageSize,
2983 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002984}
2985
2986void Context::compressedTexSubImage3D(GLenum target,
2987 GLint level,
2988 GLint xoffset,
2989 GLint yoffset,
2990 GLint zoffset,
2991 GLsizei width,
2992 GLsizei height,
2993 GLsizei depth,
2994 GLenum format,
2995 GLsizei imageSize,
2996 const GLvoid *data)
2997{
2998 // Zero sized uploads are valid but no-ops
2999 if (width == 0 || height == 0)
3000 {
3001 return;
3002 }
3003
Jamie Madillad9f24e2016-02-12 09:27:24 -05003004 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003005
3006 Box area(xoffset, yoffset, zoffset, width, height, depth);
3007 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003008 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
3009 format, imageSize,
3010 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003011}
3012
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003013void Context::generateMipmap(GLenum target)
3014{
3015 Texture *texture = getTargetTexture(target);
3016 handleError(texture->generateMipmap());
3017}
3018
Geoff Lang97073d12016-04-20 10:42:34 -07003019void Context::copyTextureCHROMIUM(GLuint sourceId,
3020 GLuint destId,
3021 GLint internalFormat,
3022 GLenum destType,
3023 GLboolean unpackFlipY,
3024 GLboolean unpackPremultiplyAlpha,
3025 GLboolean unpackUnmultiplyAlpha)
3026{
3027 syncStateForTexImage();
3028
3029 gl::Texture *sourceTexture = getTexture(sourceId);
3030 gl::Texture *destTexture = getTexture(destId);
3031 handleError(destTexture->copyTexture(internalFormat, destType, unpackFlipY == GL_TRUE,
3032 unpackPremultiplyAlpha == GL_TRUE,
3033 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3034}
3035
3036void Context::copySubTextureCHROMIUM(GLuint sourceId,
3037 GLuint destId,
3038 GLint xoffset,
3039 GLint yoffset,
3040 GLint x,
3041 GLint y,
3042 GLsizei width,
3043 GLsizei height,
3044 GLboolean unpackFlipY,
3045 GLboolean unpackPremultiplyAlpha,
3046 GLboolean unpackUnmultiplyAlpha)
3047{
3048 // Zero sized copies are valid but no-ops
3049 if (width == 0 || height == 0)
3050 {
3051 return;
3052 }
3053
3054 syncStateForTexImage();
3055
3056 gl::Texture *sourceTexture = getTexture(sourceId);
3057 gl::Texture *destTexture = getTexture(destId);
3058 Offset offset(xoffset, yoffset, 0);
3059 Rectangle area(x, y, width, height);
3060 handleError(destTexture->copySubTexture(offset, area, unpackFlipY == GL_TRUE,
3061 unpackPremultiplyAlpha == GL_TRUE,
3062 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3063}
3064
Geoff Lang47110bf2016-04-20 11:13:22 -07003065void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3066{
3067 syncStateForTexImage();
3068
3069 gl::Texture *sourceTexture = getTexture(sourceId);
3070 gl::Texture *destTexture = getTexture(destId);
3071 handleError(destTexture->copyCompressedTexture(sourceTexture));
3072}
3073
Geoff Lang496c02d2016-10-20 11:38:11 -07003074void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003075{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003076 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003077 ASSERT(buffer);
3078
Geoff Lang496c02d2016-10-20 11:38:11 -07003079 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003080}
3081
3082GLvoid *Context::mapBuffer(GLenum target, GLenum access)
3083{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003084 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003085 ASSERT(buffer);
3086
3087 Error error = buffer->map(access);
3088 if (error.isError())
3089 {
Jamie Madill437fa652016-05-03 15:13:24 -04003090 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003091 return nullptr;
3092 }
3093
3094 return buffer->getMapPointer();
3095}
3096
3097GLboolean Context::unmapBuffer(GLenum target)
3098{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003099 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003100 ASSERT(buffer);
3101
3102 GLboolean result;
3103 Error error = buffer->unmap(&result);
3104 if (error.isError())
3105 {
Jamie Madill437fa652016-05-03 15:13:24 -04003106 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003107 return GL_FALSE;
3108 }
3109
3110 return result;
3111}
3112
3113GLvoid *Context::mapBufferRange(GLenum target,
3114 GLintptr offset,
3115 GLsizeiptr length,
3116 GLbitfield access)
3117{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003118 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003119 ASSERT(buffer);
3120
3121 Error error = buffer->mapRange(offset, length, access);
3122 if (error.isError())
3123 {
Jamie Madill437fa652016-05-03 15:13:24 -04003124 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003125 return nullptr;
3126 }
3127
3128 return buffer->getMapPointer();
3129}
3130
3131void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3132{
3133 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3134}
3135
Jamie Madillad9f24e2016-02-12 09:27:24 -05003136void Context::syncStateForReadPixels()
3137{
3138 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3139}
3140
3141void Context::syncStateForTexImage()
3142{
3143 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3144}
3145
3146void Context::syncStateForClear()
3147{
3148 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3149}
3150
3151void Context::syncStateForBlit()
3152{
3153 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3154}
3155
Jamie Madillc20ab272016-06-09 07:20:46 -07003156void Context::activeTexture(GLenum texture)
3157{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003158 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003159}
3160
3161void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3162{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003163 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003164}
3165
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003166void Context::blendEquation(GLenum mode)
3167{
3168 mGLState.setBlendEquation(mode, mode);
3169}
3170
Jamie Madillc20ab272016-06-09 07:20:46 -07003171void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3172{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003173 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003174}
3175
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003176void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3177{
3178 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3179}
3180
Jamie Madillc20ab272016-06-09 07:20:46 -07003181void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3182{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003183 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003184}
3185
3186void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3187{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003188 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003189}
3190
3191void Context::clearDepthf(GLclampf depth)
3192{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003193 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003194}
3195
3196void Context::clearStencil(GLint s)
3197{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003198 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003199}
3200
3201void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3202{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003203 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003204}
3205
3206void Context::cullFace(GLenum mode)
3207{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003208 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003209}
3210
3211void Context::depthFunc(GLenum func)
3212{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003213 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003214}
3215
3216void Context::depthMask(GLboolean flag)
3217{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003218 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003219}
3220
3221void Context::depthRangef(GLclampf zNear, GLclampf zFar)
3222{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003223 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003224}
3225
3226void Context::disable(GLenum cap)
3227{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003228 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003229}
3230
3231void Context::disableVertexAttribArray(GLuint index)
3232{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003233 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003234}
3235
3236void Context::enable(GLenum cap)
3237{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003238 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003239}
3240
3241void Context::enableVertexAttribArray(GLuint index)
3242{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003243 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003244}
3245
3246void Context::frontFace(GLenum mode)
3247{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003248 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003249}
3250
3251void Context::hint(GLenum target, GLenum mode)
3252{
3253 switch (target)
3254 {
3255 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003256 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003257 break;
3258
3259 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003260 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003261 break;
3262
3263 default:
3264 UNREACHABLE();
3265 return;
3266 }
3267}
3268
3269void Context::lineWidth(GLfloat width)
3270{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003271 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003272}
3273
3274void Context::pixelStorei(GLenum pname, GLint param)
3275{
3276 switch (pname)
3277 {
3278 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003279 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003280 break;
3281
3282 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003283 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003284 break;
3285
3286 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003287 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003288 break;
3289
3290 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003291 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003292 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003293 break;
3294
3295 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003296 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003297 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003298 break;
3299
3300 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003301 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003302 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003303 break;
3304
3305 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003306 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003307 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003308 break;
3309
3310 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003311 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003312 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003313 break;
3314
3315 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003316 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003317 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003318 break;
3319
3320 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003321 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003322 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003323 break;
3324
3325 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003326 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003327 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003328 break;
3329
3330 default:
3331 UNREACHABLE();
3332 return;
3333 }
3334}
3335
3336void Context::polygonOffset(GLfloat factor, GLfloat units)
3337{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003338 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003339}
3340
3341void Context::sampleCoverage(GLclampf value, GLboolean invert)
3342{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003343 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003344}
3345
3346void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3347{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003348 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003349}
3350
3351void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3352{
3353 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3354 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003355 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003356 }
3357
3358 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3359 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003360 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003361 }
3362}
3363
3364void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3365{
3366 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3367 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003368 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003369 }
3370
3371 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3372 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003373 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003374 }
3375}
3376
3377void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3378{
3379 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3380 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003381 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003382 }
3383
3384 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3385 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003386 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003387 }
3388}
3389
3390void Context::vertexAttrib1f(GLuint index, GLfloat x)
3391{
3392 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003393 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003394}
3395
3396void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3397{
3398 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003399 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003400}
3401
3402void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3403{
3404 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003405 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003406}
3407
3408void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3409{
3410 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003411 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003412}
3413
3414void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3415{
3416 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003417 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003418}
3419
3420void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3421{
3422 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003423 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003424}
3425
3426void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3427{
3428 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003429 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003430}
3431
3432void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3433{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003434 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003435}
3436
3437void Context::vertexAttribPointer(GLuint index,
3438 GLint size,
3439 GLenum type,
3440 GLboolean normalized,
3441 GLsizei stride,
3442 const GLvoid *ptr)
3443{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003444 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3445 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003446}
3447
3448void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3449{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003450 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003451}
3452
3453void Context::vertexAttribIPointer(GLuint index,
3454 GLint size,
3455 GLenum type,
3456 GLsizei stride,
3457 const GLvoid *pointer)
3458{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003459 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3460 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003461}
3462
3463void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3464{
3465 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003466 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003467}
3468
3469void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3470{
3471 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003472 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003473}
3474
3475void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3476{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003477 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003478}
3479
3480void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3481{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003482 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003483}
3484
3485void Context::debugMessageControl(GLenum source,
3486 GLenum type,
3487 GLenum severity,
3488 GLsizei count,
3489 const GLuint *ids,
3490 GLboolean enabled)
3491{
3492 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003493 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3494 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003495}
3496
3497void Context::debugMessageInsert(GLenum source,
3498 GLenum type,
3499 GLuint id,
3500 GLenum severity,
3501 GLsizei length,
3502 const GLchar *buf)
3503{
3504 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003505 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003506}
3507
3508void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3509{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003510 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003511}
3512
3513GLuint Context::getDebugMessageLog(GLuint count,
3514 GLsizei bufSize,
3515 GLenum *sources,
3516 GLenum *types,
3517 GLuint *ids,
3518 GLenum *severities,
3519 GLsizei *lengths,
3520 GLchar *messageLog)
3521{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003522 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3523 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003524}
3525
3526void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3527{
3528 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003529 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003530}
3531
3532void Context::popDebugGroup()
3533{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003534 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003535}
3536
Jamie Madill29639852016-09-02 15:00:09 -04003537void Context::bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
3538{
3539 Buffer *buffer = mGLState.getTargetBuffer(target);
3540 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003541 handleError(buffer->bufferData(this, target, data, size, usage));
Jamie Madill29639852016-09-02 15:00:09 -04003542}
3543
3544void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
3545{
3546 if (data == nullptr)
3547 {
3548 return;
3549 }
3550
3551 Buffer *buffer = mGLState.getTargetBuffer(target);
3552 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003553 handleError(buffer->bufferSubData(this, target, data, size, offset));
Jamie Madill29639852016-09-02 15:00:09 -04003554}
3555
Jamie Madillef300b12016-10-07 15:12:09 -04003556void Context::attachShader(GLuint program, GLuint shader)
3557{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003558 auto programObject = mState.mShaderPrograms->getProgram(program);
3559 auto shaderObject = mState.mShaderPrograms->getShader(shader);
Jamie Madillef300b12016-10-07 15:12:09 -04003560 ASSERT(programObject && shaderObject);
3561 programObject->attachShader(shaderObject);
3562}
3563
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003564const Workarounds &Context::getWorkarounds() const
3565{
3566 return mWorkarounds;
3567}
3568
Jamie Madillb0817d12016-11-01 15:48:31 -04003569void Context::copyBufferSubData(GLenum readTarget,
3570 GLenum writeTarget,
3571 GLintptr readOffset,
3572 GLintptr writeOffset,
3573 GLsizeiptr size)
3574{
3575 // if size is zero, the copy is a successful no-op
3576 if (size == 0)
3577 {
3578 return;
3579 }
3580
3581 // TODO(jmadill): cache these.
3582 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3583 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3584
3585 handleError(writeBuffer->copyBufferSubData(readBuffer, readOffset, writeOffset, size));
3586}
3587
Jamie Madill01a80ee2016-11-07 12:06:18 -05003588void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3589{
3590 Program *programObject = getProgram(program);
3591 // TODO(jmadill): Re-use this from the validation if possible.
3592 ASSERT(programObject);
3593 programObject->bindAttributeLocation(index, name);
3594}
3595
3596void Context::bindBuffer(GLenum target, GLuint buffer)
3597{
3598 switch (target)
3599 {
3600 case GL_ARRAY_BUFFER:
3601 bindArrayBuffer(buffer);
3602 break;
3603 case GL_ELEMENT_ARRAY_BUFFER:
3604 bindElementArrayBuffer(buffer);
3605 break;
3606 case GL_COPY_READ_BUFFER:
3607 bindCopyReadBuffer(buffer);
3608 break;
3609 case GL_COPY_WRITE_BUFFER:
3610 bindCopyWriteBuffer(buffer);
3611 break;
3612 case GL_PIXEL_PACK_BUFFER:
3613 bindPixelPackBuffer(buffer);
3614 break;
3615 case GL_PIXEL_UNPACK_BUFFER:
3616 bindPixelUnpackBuffer(buffer);
3617 break;
3618 case GL_UNIFORM_BUFFER:
3619 bindGenericUniformBuffer(buffer);
3620 break;
3621 case GL_TRANSFORM_FEEDBACK_BUFFER:
3622 bindGenericTransformFeedbackBuffer(buffer);
3623 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003624 case GL_ATOMIC_COUNTER_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003625 if (buffer != 0)
3626 {
3627 // Binding buffers to this binding point is not implemented yet.
3628 UNIMPLEMENTED();
3629 }
Geoff Lang3b573612016-10-31 14:08:10 -04003630 break;
3631 case GL_SHADER_STORAGE_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003632 if (buffer != 0)
3633 {
3634 // Binding buffers to this binding point is not implemented yet.
3635 UNIMPLEMENTED();
3636 }
Geoff Lang3b573612016-10-31 14:08:10 -04003637 break;
3638 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08003639 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003640 break;
3641 case GL_DISPATCH_INDIRECT_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;
Jamie Madill01a80ee2016-11-07 12:06:18 -05003648
3649 default:
3650 UNREACHABLE();
3651 break;
3652 }
3653}
3654
3655void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
3656{
3657 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3658 {
3659 bindReadFramebuffer(framebuffer);
3660 }
3661
3662 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3663 {
3664 bindDrawFramebuffer(framebuffer);
3665 }
3666}
3667
3668void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
3669{
3670 ASSERT(target == GL_RENDERBUFFER);
3671 Renderbuffer *object =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003672 mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
Jamie Madill01a80ee2016-11-07 12:06:18 -05003673 mGLState.setRenderbufferBinding(object);
3674}
3675
JiangYizhoubddc46b2016-12-09 09:50:51 +08003676void Context::texStorage2DMultisample(GLenum target,
3677 GLsizei samples,
3678 GLenum internalformat,
3679 GLsizei width,
3680 GLsizei height,
3681 GLboolean fixedsamplelocations)
3682{
3683 Extents size(width, height, 1);
3684 Texture *texture = getTargetTexture(target);
3685 handleError(texture->setStorageMultisample(target, samples, internalformat, size,
3686 fixedsamplelocations));
3687}
3688
3689void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
3690{
3691 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
3692 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
3693
3694 switch (pname)
3695 {
3696 case GL_SAMPLE_POSITION:
3697 handleError(framebuffer->getSamplePosition(index, val));
3698 break;
3699 default:
3700 UNREACHABLE();
3701 }
3702}
3703
Jamie Madillc29968b2016-01-20 11:17:23 -05003704} // namespace gl