blob: b711081d994810911d0bdbc1bedc94f2f15ac463 [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"
Geoff Lang2b5420c2014-11-19 14:20:15 -050023#include "libANGLE/Fence.h"
24#include "libANGLE/Framebuffer.h"
25#include "libANGLE/FramebufferAttachment.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030026#include "libANGLE/Path.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050027#include "libANGLE/Program.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050028#include "libANGLE/Query.h"
Jiawei-Shao2597fb62016-12-09 16:38:02 +080029#include "libANGLE/queryutils.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
Geoff Langfeb8c682017-02-13 16:07:35 -0500202bool GetClientArraysEnabled(const egl::AttributeMap &attribs)
203{
204 return (attribs.get(EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE, EGL_TRUE) == EGL_TRUE);
205}
206
Jamie Madille08a1d32017-03-07 17:24:06 -0500207bool GetRobustResourceInit(const egl::AttributeMap &attribs)
208{
209 return (attribs.get(EGL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE, EGL_FALSE) == EGL_TRUE);
210}
211
Martin Radev9d901792016-07-15 15:58:58 +0300212std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
213{
214 std::string labelName;
215 if (label != nullptr)
216 {
217 size_t labelLength = length < 0 ? strlen(label) : length;
218 labelName = std::string(label, labelLength);
219 }
220 return labelName;
221}
222
223void GetObjectLabelBase(const std::string &objectLabel,
224 GLsizei bufSize,
225 GLsizei *length,
226 GLchar *label)
227{
228 size_t writeLength = objectLabel.length();
229 if (label != nullptr && bufSize > 0)
230 {
231 writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
232 std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
233 label[writeLength] = '\0';
234 }
235
236 if (length != nullptr)
237 {
238 *length = static_cast<GLsizei>(writeLength);
239 }
240}
241
Geoff Langf6db0982015-08-25 13:04:00 -0400242} // anonymous namespace
243
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000244namespace gl
245{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000246
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400247Context::Context(rx::EGLImplFactory *implFactory,
248 const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400249 const Context *shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500250 TextureManager *shareTextures,
Corentin Wallezc295e512017-01-27 17:47:50 -0500251 const egl::AttributeMap &attribs,
252 const egl::DisplayExtensions &displayExtensions)
Martin Radev1be913c2016-07-11 17:59:16 +0300253
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500254 : ValidationContext(shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500255 shareTextures,
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500256 GetClientVersion(attribs),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700257 &mGLState,
Jamie Madillf25855c2015-11-03 11:06:18 -0500258 mCaps,
259 mTextureCaps,
260 mExtensions,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500261 mLimitations,
262 GetNoError(attribs)),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700263 mImplementation(implFactory->createContext(mState)),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500264 mCompiler(nullptr),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400265 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500266 mClientType(EGL_OPENGL_ES_API),
267 mHasBeenCurrent(false),
268 mContextLost(false),
269 mResetStatus(GL_NO_ERROR),
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700270 mContextLostForced(false),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500271 mResetStrategy(GetResetStrategy(attribs)),
272 mRobustAccess(GetRobustAccess(attribs)),
Corentin Wallezccab69d2017-01-27 16:57:15 -0500273 mCurrentSurface(nullptr),
Jamie Madill4e0e6f82017-02-17 11:06:03 -0500274 mSurfacelessFramebuffer(nullptr),
Jamie Madille14951e2017-03-09 18:55:16 -0500275 mWebGLContext(GetWebGLContext(attribs)),
276 mScratchBuffer(1000u)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000277{
Geoff Lang077f20a2016-11-01 10:08:02 -0400278 if (mRobustAccess)
279 {
280 UNIMPLEMENTED();
281 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000282
Jamie Madill4e0e6f82017-02-17 11:06:03 -0500283 initCaps(displayExtensions);
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700284 initWorkarounds();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400285
Geoff Langeb66a6e2016-10-31 13:06:12 -0400286 mGLState.initialize(mCaps, mExtensions, getClientVersion(), GetDebug(attribs),
Jamie Madille08a1d32017-03-07 17:24:06 -0500287 GetBindGeneratesResource(attribs), GetClientArraysEnabled(attribs),
288 GetRobustResourceInit(attribs));
Régis Fénéon83107972015-02-05 12:57:44 +0100289
Shannon Woods53a94a82014-06-24 15:20:36 -0400290 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400291
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000292 // [OpenGL ES 2.0.24] section 3.7 page 83:
293 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
294 // and cube map texture state vectors respectively associated with them.
295 // In order that access to these initial textures not be lost, they are treated as texture
296 // objects all of whose names are 0.
297
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400298 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500299 mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500300
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400301 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500302 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400303
Geoff Langeb66a6e2016-10-31 13:06:12 -0400304 if (getClientVersion() >= Version(3, 0))
Geoff Lang76b10c92014-09-05 16:28:14 -0400305 {
306 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400307 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500308 mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400309
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400310 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500311 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400312 }
Geoff Lang3b573612016-10-31 14:08:10 -0400313 if (getClientVersion() >= Version(3, 1))
314 {
315 Texture *zeroTexture2DMultisample =
316 new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_MULTISAMPLE);
317 mZeroTextures[GL_TEXTURE_2D_MULTISAMPLE].set(zeroTexture2DMultisample);
Jiajia Qin6eafb042016-12-27 17:04:07 +0800318
319 bindGenericAtomicCounterBuffer(0);
320 for (unsigned int i = 0; i < mCaps.maxAtomicCounterBufferBindings; i++)
321 {
322 bindIndexedAtomicCounterBuffer(0, i, 0, 0);
323 }
Jiajia Qinf546e7d2017-03-27 14:12:59 +0800324
325 bindGenericShaderStorageBuffer(0);
326 for (unsigned int i = 0; i < mCaps.maxShaderStorageBufferBindings; i++)
327 {
328 bindIndexedShaderStorageBuffer(0, i, 0, 0);
329 }
Geoff Lang3b573612016-10-31 14:08:10 -0400330 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000331
Ian Ewellbda75592016-04-18 17:25:54 -0400332 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
333 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400334 Texture *zeroTextureExternal =
335 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Ian Ewellbda75592016-04-18 17:25:54 -0400336 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(zeroTextureExternal);
337 }
338
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700339 mGLState.initializeZeroTextures(mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500340
Jamie Madill57a89722013-07-02 11:57:03 -0400341 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000342 bindArrayBuffer(0);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800343 bindDrawIndirectBuffer(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000344 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400345
Jamie Madill01a80ee2016-11-07 12:06:18 -0500346 bindRenderbuffer(GL_RENDERBUFFER, 0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000347
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000348 bindGenericUniformBuffer(0);
Geoff Lang4dc3af02016-11-18 14:09:27 -0500349 for (unsigned int i = 0; i < mCaps.maxUniformBufferBindings; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000350 {
351 bindIndexedUniformBuffer(0, i, 0, -1);
352 }
353
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000354 bindCopyReadBuffer(0);
355 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000356 bindPixelPackBuffer(0);
357 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000358
Geoff Langeb66a6e2016-10-31 13:06:12 -0400359 if (getClientVersion() >= Version(3, 0))
Geoff Lang1a683462015-09-29 15:09:59 -0400360 {
361 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
362 // In the initial state, a default transform feedback object is bound and treated as
363 // a transform feedback object with a name of zero. That object is bound any time
364 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400365 bindTransformFeedback(0);
366 }
Geoff Langc8058452014-02-03 12:04:11 -0500367
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700368 mCompiler = new Compiler(mImplementation.get(), mState);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500369
370 // Initialize dirty bit masks
371 // TODO(jmadill): additional ES3 state
372 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
373 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
374 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
375 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
376 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
377 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400378 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500379 // No dirty objects.
380
381 // Readpixels uses the pack state and read FBO
382 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
383 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
384 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
385 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
386 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400387 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500388 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
389
390 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
391 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
392 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
393 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
394 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
395 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
396 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
397 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
398 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
399 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
400 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
401 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
402
403 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
404 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700405 mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500406 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
407 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400408
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400409 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000410}
411
Jamie Madill70ee0f62017-02-06 16:04:20 -0500412void Context::destroy(egl::Display *display)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000413{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500414 mGLState.reset(this);
Geoff Lang21329412014-12-02 20:50:30 +0000415
Corentin Wallez80b24112015-08-25 16:41:57 -0400416 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000417 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400418 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000419 }
420
Corentin Wallez80b24112015-08-25 16:41:57 -0400421 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000422 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400423 if (query.second != nullptr)
424 {
425 query.second->release();
426 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000427 }
428
Corentin Wallez80b24112015-08-25 16:41:57 -0400429 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400430 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400431 SafeDelete(vertexArray.second);
Jamie Madill57a89722013-07-02 11:57:03 -0400432 }
433
Corentin Wallez80b24112015-08-25 16:41:57 -0400434 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500435 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500436 if (transformFeedback.second != nullptr)
437 {
Jamie Madill6c1f6712017-02-14 19:08:04 -0500438 transformFeedback.second->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500439 }
Geoff Langc8058452014-02-03 12:04:11 -0500440 }
441
Jamie Madilldedd7b92014-11-05 16:30:36 -0500442 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400443 {
Yunchao Hef81ce4a2017-04-24 10:49:17 +0800444 zeroTexture.second.set(nullptr);
Geoff Lang76b10c92014-09-05 16:28:14 -0400445 }
446 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000447
Corentin Wallezccab69d2017-01-27 16:57:15 -0500448 SafeDelete(mSurfacelessFramebuffer);
449
Jamie Madill70ee0f62017-02-06 16:04:20 -0500450 releaseSurface(display);
Corentin Wallez51706ea2015-08-07 14:39:22 -0400451
Geoff Lang492a7e42014-11-05 13:27:06 -0500452 SafeDelete(mCompiler);
Jamie Madill6c1f6712017-02-14 19:08:04 -0500453
454 mState.mBuffers->release(this);
455 mState.mShaderPrograms->release(this);
456 mState.mTextures->release(this);
457 mState.mRenderbuffers->release(this);
458 mState.mSamplers->release(this);
459 mState.mFenceSyncs->release(this);
460 mState.mPaths->release(this);
461 mState.mFramebuffers->release(this);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000462}
463
Jamie Madill70ee0f62017-02-06 16:04:20 -0500464Context::~Context()
465{
466}
467
468void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000469{
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000470 if (!mHasBeenCurrent)
471 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000472 initRendererString();
Geoff Langc339c4e2016-11-29 10:37:36 -0500473 initVersionStrings();
Geoff Langcec35902014-04-16 10:52:36 -0400474 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000475
Corentin Wallezc295e512017-01-27 17:47:50 -0500476 int width = 0;
477 int height = 0;
478 if (surface != nullptr)
479 {
480 width = surface->getWidth();
481 height = surface->getHeight();
482 }
483
484 mGLState.setViewportParams(0, 0, width, height);
485 mGLState.setScissorParams(0, 0, width, height);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000486
487 mHasBeenCurrent = true;
488 }
489
Jamie Madill1b94d432015-08-07 13:23:23 -0400490 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700491 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400492
Jamie Madill70ee0f62017-02-06 16:04:20 -0500493 releaseSurface(display);
Corentin Wallezccab69d2017-01-27 16:57:15 -0500494
495 Framebuffer *newDefault = nullptr;
496 if (surface != nullptr)
497 {
Jamie Madill70ee0f62017-02-06 16:04:20 -0500498 surface->setIsCurrent(display, true);
Corentin Wallezccab69d2017-01-27 16:57:15 -0500499 mCurrentSurface = surface;
500 newDefault = surface->getDefaultFramebuffer();
501 }
502 else
503 {
504 if (mSurfacelessFramebuffer == nullptr)
505 {
506 mSurfacelessFramebuffer = new Framebuffer(mImplementation.get());
507 }
508
509 newDefault = mSurfacelessFramebuffer;
510 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000511
Corentin Wallez37c39792015-08-20 14:19:46 -0400512 // Update default framebuffer, the binding of the previous default
513 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400514 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700515 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400516 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700517 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400518 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700519 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400520 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700521 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400522 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500523 mState.mFramebuffers->setDefaultFramebuffer(newDefault);
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400524 }
Ian Ewell292f0052016-02-04 10:37:32 -0500525
526 // Notify the renderer of a context switch
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700527 mImplementation->onMakeCurrent(mState);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000528}
529
Jamie Madill70ee0f62017-02-06 16:04:20 -0500530void Context::releaseSurface(egl::Display *display)
Jamie Madill77a72f62015-04-14 11:18:32 -0400531{
Corentin Wallez37c39792015-08-20 14:19:46 -0400532 // Remove the default framebuffer
Corentin Wallezc295e512017-01-27 17:47:50 -0500533 Framebuffer *currentDefault = nullptr;
534 if (mCurrentSurface != nullptr)
Corentin Wallez51706ea2015-08-07 14:39:22 -0400535 {
Corentin Wallezc295e512017-01-27 17:47:50 -0500536 currentDefault = mCurrentSurface->getDefaultFramebuffer();
537 }
538 else if (mSurfacelessFramebuffer != nullptr)
539 {
540 currentDefault = mSurfacelessFramebuffer;
Corentin Wallez51706ea2015-08-07 14:39:22 -0400541 }
542
Corentin Wallezc295e512017-01-27 17:47:50 -0500543 if (mGLState.getReadFramebuffer() == currentDefault)
544 {
545 mGLState.setReadFramebufferBinding(nullptr);
546 }
547 if (mGLState.getDrawFramebuffer() == currentDefault)
548 {
549 mGLState.setDrawFramebufferBinding(nullptr);
550 }
551 mState.mFramebuffers->setDefaultFramebuffer(nullptr);
552
553 if (mCurrentSurface)
554 {
Jamie Madill70ee0f62017-02-06 16:04:20 -0500555 mCurrentSurface->setIsCurrent(display, false);
Corentin Wallezc295e512017-01-27 17:47:50 -0500556 mCurrentSurface = nullptr;
557 }
Jamie Madill77a72f62015-04-14 11:18:32 -0400558}
559
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000560GLuint Context::createBuffer()
561{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500562 return mState.mBuffers->createBuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000563}
564
565GLuint Context::createProgram()
566{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500567 return mState.mShaderPrograms->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000568}
569
570GLuint Context::createShader(GLenum type)
571{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500572 return mState.mShaderPrograms->createShader(mImplementation.get(), mLimitations, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000573}
574
575GLuint Context::createTexture()
576{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500577 return mState.mTextures->createTexture();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000578}
579
580GLuint Context::createRenderbuffer()
581{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500582 return mState.mRenderbuffers->createRenderbuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000583}
584
Geoff Lang882033e2014-09-30 11:26:07 -0400585GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400586{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500587 GLuint handle = mState.mFenceSyncs->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400588
Cooper Partind8e62a32015-01-29 15:21:25 -0800589 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400590}
591
Sami Väisänene45e53b2016-05-25 10:36:04 +0300592GLuint Context::createPaths(GLsizei range)
593{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500594 auto resultOrError = mState.mPaths->createPaths(mImplementation.get(), range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300595 if (resultOrError.isError())
596 {
597 handleError(resultOrError.getError());
598 return 0;
599 }
600 return resultOrError.getResult();
601}
602
Jamie Madill57a89722013-07-02 11:57:03 -0400603GLuint Context::createVertexArray()
604{
Geoff Lang36167ab2015-12-07 10:27:14 -0500605 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
606 mVertexArrayMap[vertexArray] = nullptr;
607 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400608}
609
Jamie Madilldc356042013-07-19 16:36:57 -0400610GLuint Context::createSampler()
611{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500612 return mState.mSamplers->createSampler();
Jamie Madilldc356042013-07-19 16:36:57 -0400613}
614
Geoff Langc8058452014-02-03 12:04:11 -0500615GLuint Context::createTransformFeedback()
616{
Geoff Lang36167ab2015-12-07 10:27:14 -0500617 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
618 mTransformFeedbackMap[transformFeedback] = nullptr;
619 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500620}
621
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000622// Returns an unused framebuffer name
623GLuint Context::createFramebuffer()
624{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500625 return mState.mFramebuffers->createFramebuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000626}
627
Jamie Madill33dc8432013-07-26 11:55:05 -0400628GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000629{
Jamie Madill33dc8432013-07-26 11:55:05 -0400630 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000631
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400632 mFenceNVMap[handle] = new FenceNV(mImplementation->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000633
634 return handle;
635}
636
637// Returns an unused query name
638GLuint Context::createQuery()
639{
640 GLuint handle = mQueryHandleAllocator.allocate();
641
Yunchao Hed7297bf2017-04-19 15:27:10 +0800642 mQueryMap[handle] = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000643
644 return handle;
645}
646
647void Context::deleteBuffer(GLuint buffer)
648{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500649 if (mState.mBuffers->getBuffer(buffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000650 {
651 detachBuffer(buffer);
652 }
Jamie Madill893ab082014-05-16 16:56:10 -0400653
Jamie Madill6c1f6712017-02-14 19:08:04 -0500654 mState.mBuffers->deleteObject(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000655}
656
657void Context::deleteShader(GLuint shader)
658{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500659 mState.mShaderPrograms->deleteShader(this, shader);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000660}
661
662void Context::deleteProgram(GLuint program)
663{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500664 mState.mShaderPrograms->deleteProgram(this, program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000665}
666
667void Context::deleteTexture(GLuint texture)
668{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500669 if (mState.mTextures->getTexture(texture))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000670 {
671 detachTexture(texture);
672 }
673
Jamie Madill6c1f6712017-02-14 19:08:04 -0500674 mState.mTextures->deleteObject(this, texture);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000675}
676
677void Context::deleteRenderbuffer(GLuint renderbuffer)
678{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500679 if (mState.mRenderbuffers->getRenderbuffer(renderbuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000680 {
681 detachRenderbuffer(renderbuffer);
682 }
Jamie Madill893ab082014-05-16 16:56:10 -0400683
Jamie Madill6c1f6712017-02-14 19:08:04 -0500684 mState.mRenderbuffers->deleteObject(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000685}
686
Jamie Madillcd055f82013-07-26 11:55:15 -0400687void Context::deleteFenceSync(GLsync fenceSync)
688{
689 // The spec specifies the underlying Fence object is not deleted until all current
690 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
691 // and since our API is currently designed for being called from a single thread, we can delete
692 // the fence immediately.
Jamie Madill6c1f6712017-02-14 19:08:04 -0500693 mState.mFenceSyncs->deleteObject(this,
694 static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400695}
696
Sami Väisänene45e53b2016-05-25 10:36:04 +0300697void Context::deletePaths(GLuint first, GLsizei range)
698{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500699 mState.mPaths->deletePaths(first, range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300700}
701
702bool Context::hasPathData(GLuint path) const
703{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500704 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300705 if (pathObj == nullptr)
706 return false;
707
708 return pathObj->hasPathData();
709}
710
711bool Context::hasPath(GLuint path) const
712{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500713 return mState.mPaths->hasPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300714}
715
716void Context::setPathCommands(GLuint path,
717 GLsizei numCommands,
718 const GLubyte *commands,
719 GLsizei numCoords,
720 GLenum coordType,
721 const void *coords)
722{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500723 auto *pathObject = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300724
725 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
726}
727
728void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
729{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500730 auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300731
732 switch (pname)
733 {
734 case GL_PATH_STROKE_WIDTH_CHROMIUM:
735 pathObj->setStrokeWidth(value);
736 break;
737 case GL_PATH_END_CAPS_CHROMIUM:
738 pathObj->setEndCaps(static_cast<GLenum>(value));
739 break;
740 case GL_PATH_JOIN_STYLE_CHROMIUM:
741 pathObj->setJoinStyle(static_cast<GLenum>(value));
742 break;
743 case GL_PATH_MITER_LIMIT_CHROMIUM:
744 pathObj->setMiterLimit(value);
745 break;
746 case GL_PATH_STROKE_BOUND_CHROMIUM:
747 pathObj->setStrokeBound(value);
748 break;
749 default:
750 UNREACHABLE();
751 break;
752 }
753}
754
755void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
756{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500757 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300758
759 switch (pname)
760 {
761 case GL_PATH_STROKE_WIDTH_CHROMIUM:
762 *value = pathObj->getStrokeWidth();
763 break;
764 case GL_PATH_END_CAPS_CHROMIUM:
765 *value = static_cast<GLfloat>(pathObj->getEndCaps());
766 break;
767 case GL_PATH_JOIN_STYLE_CHROMIUM:
768 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
769 break;
770 case GL_PATH_MITER_LIMIT_CHROMIUM:
771 *value = pathObj->getMiterLimit();
772 break;
773 case GL_PATH_STROKE_BOUND_CHROMIUM:
774 *value = pathObj->getStrokeBound();
775 break;
776 default:
777 UNREACHABLE();
778 break;
779 }
780}
781
782void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
783{
784 mGLState.setPathStencilFunc(func, ref, mask);
785}
786
Jamie Madill57a89722013-07-02 11:57:03 -0400787void Context::deleteVertexArray(GLuint vertexArray)
788{
Geoff Lang36167ab2015-12-07 10:27:14 -0500789 auto iter = mVertexArrayMap.find(vertexArray);
790 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000791 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500792 VertexArray *vertexArrayObject = iter->second;
793 if (vertexArrayObject != nullptr)
794 {
795 detachVertexArray(vertexArray);
796 delete vertexArrayObject;
797 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000798
Geoff Lang36167ab2015-12-07 10:27:14 -0500799 mVertexArrayMap.erase(iter);
800 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400801 }
802}
803
Jamie Madilldc356042013-07-19 16:36:57 -0400804void Context::deleteSampler(GLuint sampler)
805{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500806 if (mState.mSamplers->getSampler(sampler))
Jamie Madilldc356042013-07-19 16:36:57 -0400807 {
808 detachSampler(sampler);
809 }
810
Jamie Madill6c1f6712017-02-14 19:08:04 -0500811 mState.mSamplers->deleteObject(this, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400812}
813
Geoff Langc8058452014-02-03 12:04:11 -0500814void Context::deleteTransformFeedback(GLuint transformFeedback)
815{
Geoff Lang6e60d6b2017-04-12 12:59:04 -0400816 if (transformFeedback == 0)
817 {
818 return;
819 }
820
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500821 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500822 if (iter != mTransformFeedbackMap.end())
823 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500824 TransformFeedback *transformFeedbackObject = iter->second;
825 if (transformFeedbackObject != nullptr)
826 {
827 detachTransformFeedback(transformFeedback);
Jamie Madill6c1f6712017-02-14 19:08:04 -0500828 transformFeedbackObject->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500829 }
830
Geoff Lang50b3fe82015-12-08 14:49:12 +0000831 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500832 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500833 }
834}
835
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000836void Context::deleteFramebuffer(GLuint framebuffer)
837{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500838 if (mState.mFramebuffers->getFramebuffer(framebuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000839 {
840 detachFramebuffer(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000841 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500842
Jamie Madill6c1f6712017-02-14 19:08:04 -0500843 mState.mFramebuffers->deleteObject(this, framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000844}
845
Jamie Madill33dc8432013-07-26 11:55:05 -0400846void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000847{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500848 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000849
Jamie Madill33dc8432013-07-26 11:55:05 -0400850 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000851 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400852 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000853 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400854 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000855 }
856}
857
858void Context::deleteQuery(GLuint query)
859{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500860 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000861 if (queryObject != mQueryMap.end())
862 {
863 mQueryHandleAllocator.release(queryObject->first);
864 if (queryObject->second)
865 {
866 queryObject->second->release();
867 }
868 mQueryMap.erase(queryObject);
869 }
870}
871
Geoff Lang70d0f492015-12-10 17:45:46 -0500872Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000873{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500874 return mState.mBuffers->getBuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000875}
876
Jamie Madill570f7c82014-07-03 10:38:54 -0400877Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000878{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500879 return mState.mTextures->getTexture(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000880}
881
Geoff Lang70d0f492015-12-10 17:45:46 -0500882Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000883{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500884 return mState.mRenderbuffers->getRenderbuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000885}
886
Jamie Madillcd055f82013-07-26 11:55:15 -0400887FenceSync *Context::getFenceSync(GLsync handle) const
888{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500889 return mState.mFenceSyncs->getFenceSync(
890 static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400891}
892
Jamie Madill57a89722013-07-02 11:57:03 -0400893VertexArray *Context::getVertexArray(GLuint handle) const
894{
895 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500896 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400897}
898
Jamie Madilldc356042013-07-19 16:36:57 -0400899Sampler *Context::getSampler(GLuint handle) const
900{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500901 return mState.mSamplers->getSampler(handle);
Jamie Madilldc356042013-07-19 16:36:57 -0400902}
903
Geoff Langc8058452014-02-03 12:04:11 -0500904TransformFeedback *Context::getTransformFeedback(GLuint handle) const
905{
Geoff Lang36167ab2015-12-07 10:27:14 -0500906 auto iter = mTransformFeedbackMap.find(handle);
907 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500908}
909
Geoff Lang70d0f492015-12-10 17:45:46 -0500910LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
911{
912 switch (identifier)
913 {
914 case GL_BUFFER:
915 return getBuffer(name);
916 case GL_SHADER:
917 return getShader(name);
918 case GL_PROGRAM:
919 return getProgram(name);
920 case GL_VERTEX_ARRAY:
921 return getVertexArray(name);
922 case GL_QUERY:
923 return getQuery(name);
924 case GL_TRANSFORM_FEEDBACK:
925 return getTransformFeedback(name);
926 case GL_SAMPLER:
927 return getSampler(name);
928 case GL_TEXTURE:
929 return getTexture(name);
930 case GL_RENDERBUFFER:
931 return getRenderbuffer(name);
932 case GL_FRAMEBUFFER:
933 return getFramebuffer(name);
934 default:
935 UNREACHABLE();
936 return nullptr;
937 }
938}
939
940LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
941{
942 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
943}
944
Martin Radev9d901792016-07-15 15:58:58 +0300945void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
946{
947 LabeledObject *object = getLabeledObject(identifier, name);
948 ASSERT(object != nullptr);
949
950 std::string labelName = GetObjectLabelFromPointer(length, label);
951 object->setLabel(labelName);
952}
953
954void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
955{
956 LabeledObject *object = getLabeledObjectFromPtr(ptr);
957 ASSERT(object != nullptr);
958
959 std::string labelName = GetObjectLabelFromPointer(length, label);
960 object->setLabel(labelName);
961}
962
963void Context::getObjectLabel(GLenum identifier,
964 GLuint name,
965 GLsizei bufSize,
966 GLsizei *length,
967 GLchar *label) const
968{
969 LabeledObject *object = getLabeledObject(identifier, name);
970 ASSERT(object != nullptr);
971
972 const std::string &objectLabel = object->getLabel();
973 GetObjectLabelBase(objectLabel, bufSize, length, label);
974}
975
976void Context::getObjectPtrLabel(const void *ptr,
977 GLsizei bufSize,
978 GLsizei *length,
979 GLchar *label) const
980{
981 LabeledObject *object = getLabeledObjectFromPtr(ptr);
982 ASSERT(object != nullptr);
983
984 const std::string &objectLabel = object->getLabel();
985 GetObjectLabelBase(objectLabel, bufSize, length, label);
986}
987
Jamie Madilldc356042013-07-19 16:36:57 -0400988bool Context::isSampler(GLuint samplerName) const
989{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500990 return mState.mSamplers->isSampler(samplerName);
Jamie Madilldc356042013-07-19 16:36:57 -0400991}
992
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500993void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000994{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500995 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700996 mGLState.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000997}
998
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800999void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
1000{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001001 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08001002 mGLState.setDrawIndirectBufferBinding(buffer);
1003}
1004
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001005void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001006{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001007 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Shao80957d92017-02-20 21:25:59 +08001008 mGLState.setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001009}
1010
Jamie Madilldedd7b92014-11-05 16:30:36 -05001011void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001012{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001013 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001014
Jamie Madilldedd7b92014-11-05 16:30:36 -05001015 if (handle == 0)
1016 {
1017 texture = mZeroTextures[target].get();
1018 }
1019 else
1020 {
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001021 texture = mState.mTextures->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -05001022 }
1023
1024 ASSERT(texture);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001025 mGLState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +00001026}
1027
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001028void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001029{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001030 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
1031 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001032 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001033}
1034
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001035void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001036{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001037 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
1038 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001039 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001040}
1041
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001042void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -04001043{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001044 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001045 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -04001046}
1047
Shao80957d92017-02-20 21:25:59 +08001048void Context::bindVertexBuffer(GLuint bindingIndex,
1049 GLuint bufferHandle,
1050 GLintptr offset,
1051 GLsizei stride)
1052{
1053 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
1054 mGLState.bindVertexBuffer(bindingIndex, buffer, offset, stride);
1055}
1056
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001057void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -04001058{
Geoff Lang76b10c92014-09-05 16:28:14 -04001059 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -04001060 Sampler *sampler =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001061 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001062 mGLState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001063}
1064
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001065void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001066{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001067 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001068 mGLState.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001069}
1070
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001071void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1072 GLuint index,
1073 GLintptr offset,
1074 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001075{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001076 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001077 mGLState.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001078}
1079
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001080void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001081{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001082 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001083 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001084}
1085
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001086void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1087 GLuint index,
1088 GLintptr offset,
1089 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001090{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001091 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001092 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001093}
1094
Jiajia Qin6eafb042016-12-27 17:04:07 +08001095void Context::bindGenericAtomicCounterBuffer(GLuint bufferHandle)
1096{
1097 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
1098 mGLState.setGenericAtomicCounterBufferBinding(buffer);
1099}
1100
1101void Context::bindIndexedAtomicCounterBuffer(GLuint bufferHandle,
1102 GLuint index,
1103 GLintptr offset,
1104 GLsizeiptr size)
1105{
1106 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
1107 mGLState.setIndexedAtomicCounterBufferBinding(index, buffer, offset, size);
1108}
1109
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001110void Context::bindGenericShaderStorageBuffer(GLuint bufferHandle)
1111{
1112 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
1113 mGLState.setGenericShaderStorageBufferBinding(buffer);
1114}
1115
1116void Context::bindIndexedShaderStorageBuffer(GLuint bufferHandle,
1117 GLuint index,
1118 GLintptr offset,
1119 GLsizeiptr size)
1120{
1121 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
1122 mGLState.setIndexedShaderStorageBufferBinding(index, buffer, offset, size);
1123}
1124
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001125void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001126{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001127 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001128 mGLState.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001129}
1130
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001131void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001132{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001133 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001134 mGLState.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001135}
1136
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001137void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001138{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001139 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001140 mGLState.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001141}
1142
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001143void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001144{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001145 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001146 mGLState.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001147}
1148
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001149void Context::useProgram(GLuint program)
1150{
Jamie Madill6c1f6712017-02-14 19:08:04 -05001151 mGLState.setProgram(this, getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001152}
1153
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001154void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001155{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001156 TransformFeedback *transformFeedback =
1157 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001158 mGLState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001159}
1160
Geoff Lang5aad9672014-09-08 11:10:42 -04001161Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001162{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001163 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001164 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001165
Geoff Lang5aad9672014-09-08 11:10:42 -04001166 // begin query
1167 Error error = queryObject->begin();
1168 if (error.isError())
1169 {
1170 return error;
1171 }
1172
1173 // set query as active for specified target only if begin succeeded
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001174 mGLState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001175
He Yunchaoacd18982017-01-04 10:46:42 +08001176 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001177}
1178
Geoff Lang5aad9672014-09-08 11:10:42 -04001179Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001180{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001181 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001182 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001183
Geoff Lang5aad9672014-09-08 11:10:42 -04001184 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001185
Geoff Lang5aad9672014-09-08 11:10:42 -04001186 // Always unbind the query, even if there was an error. This may delete the query object.
Yunchao Hef81ce4a2017-04-24 10:49:17 +08001187 mGLState.setActiveQuery(target, nullptr);
Geoff Lang5aad9672014-09-08 11:10:42 -04001188
1189 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001190}
1191
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001192Error Context::queryCounter(GLuint id, GLenum target)
1193{
1194 ASSERT(target == GL_TIMESTAMP_EXT);
1195
1196 Query *queryObject = getQuery(id, true, target);
1197 ASSERT(queryObject);
1198
1199 return queryObject->queryCounter();
1200}
1201
1202void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1203{
1204 switch (pname)
1205 {
1206 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001207 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001208 break;
1209 case GL_QUERY_COUNTER_BITS_EXT:
1210 switch (target)
1211 {
1212 case GL_TIME_ELAPSED_EXT:
1213 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1214 break;
1215 case GL_TIMESTAMP_EXT:
1216 params[0] = getExtensions().queryCounterBitsTimestamp;
1217 break;
1218 default:
1219 UNREACHABLE();
1220 params[0] = 0;
1221 break;
1222 }
1223 break;
1224 default:
1225 UNREACHABLE();
1226 return;
1227 }
1228}
1229
Geoff Lang2186c382016-10-14 10:54:54 -04001230void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001231{
Geoff Lang2186c382016-10-14 10:54:54 -04001232 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001233}
1234
Geoff Lang2186c382016-10-14 10:54:54 -04001235void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001236{
Geoff Lang2186c382016-10-14 10:54:54 -04001237 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001238}
1239
Geoff Lang2186c382016-10-14 10:54:54 -04001240void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001241{
Geoff Lang2186c382016-10-14 10:54:54 -04001242 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001243}
1244
Geoff Lang2186c382016-10-14 10:54:54 -04001245void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001246{
Geoff Lang2186c382016-10-14 10:54:54 -04001247 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001248}
1249
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001250Framebuffer *Context::getFramebuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001251{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001252 return mState.mFramebuffers->getFramebuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001253}
1254
Jamie Madill33dc8432013-07-26 11:55:05 -04001255FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001256{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001257 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001258
Jamie Madill33dc8432013-07-26 11:55:05 -04001259 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001260 {
Yunchao Hef81ce4a2017-04-24 10:49:17 +08001261 return nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001262 }
1263 else
1264 {
1265 return fence->second;
1266 }
1267}
1268
1269Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1270{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001271 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001272
1273 if (query == mQueryMap.end())
1274 {
Yunchao Hef81ce4a2017-04-24 10:49:17 +08001275 return nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001276 }
1277 else
1278 {
1279 if (!query->second && create)
1280 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001281 query->second = new Query(mImplementation->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001282 query->second->addRef();
1283 }
1284 return query->second;
1285 }
1286}
1287
Geoff Lang70d0f492015-12-10 17:45:46 -05001288Query *Context::getQuery(GLuint handle) const
1289{
1290 auto iter = mQueryMap.find(handle);
1291 return (iter != mQueryMap.end()) ? iter->second : nullptr;
1292}
1293
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001294Texture *Context::getTargetTexture(GLenum target) const
1295{
Ian Ewellbda75592016-04-18 17:25:54 -04001296 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001297 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001298}
1299
Geoff Lang76b10c92014-09-05 16:28:14 -04001300Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001301{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001302 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001303}
1304
Geoff Lang492a7e42014-11-05 13:27:06 -05001305Compiler *Context::getCompiler() const
1306{
1307 return mCompiler;
1308}
1309
Jamie Madillc1d770e2017-04-13 17:31:24 -04001310void Context::getBooleanvImpl(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001311{
1312 switch (pname)
1313 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001314 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001315 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001316 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001317 mGLState.getBooleanv(pname, params);
1318 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001319 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001320}
1321
Jamie Madillc1d770e2017-04-13 17:31:24 -04001322void Context::getFloatvImpl(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001323{
Shannon Woods53a94a82014-06-24 15:20:36 -04001324 // Queries about context capabilities and maximums are answered by Context.
1325 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001326 switch (pname)
1327 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001328 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001329 params[0] = mCaps.minAliasedLineWidth;
1330 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001331 break;
1332 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001333 params[0] = mCaps.minAliasedPointSize;
1334 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001335 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001336 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001337 ASSERT(mExtensions.textureFilterAnisotropic);
1338 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001339 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001340 case GL_MAX_TEXTURE_LOD_BIAS:
1341 *params = mCaps.maxLODBias;
1342 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001343
1344 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1345 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1346 {
1347 ASSERT(mExtensions.pathRendering);
1348 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1349 memcpy(params, m, 16 * sizeof(GLfloat));
1350 }
1351 break;
1352
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001353 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001354 mGLState.getFloatv(pname, params);
1355 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001356 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001357}
1358
Jamie Madillc1d770e2017-04-13 17:31:24 -04001359void Context::getIntegervImpl(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001360{
Shannon Woods53a94a82014-06-24 15:20:36 -04001361 // Queries about context capabilities and maximums are answered by Context.
1362 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001363
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001364 switch (pname)
1365 {
Geoff Lang301d1612014-07-09 10:34:37 -04001366 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1367 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1368 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001369 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1370 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1371 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001372 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1373 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1374 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001375 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001376 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1377 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1378 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001379 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001380 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001381 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1382 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1383 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1384 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001385 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1386 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001387 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1388 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001389 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001390 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1391 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1392 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1393 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Martin Radev1be913c2016-07-11 17:59:16 +03001394 case GL_MAJOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001395 *params = getClientVersion().major;
Martin Radev1be913c2016-07-11 17:59:16 +03001396 break;
1397 case GL_MINOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001398 *params = getClientVersion().minor;
Martin Radev1be913c2016-07-11 17:59:16 +03001399 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001400 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1401 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001402 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1403 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1404 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001405 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1406 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1407 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001408 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001409 case GL_MAX_VIEWPORT_DIMS:
1410 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001411 params[0] = mCaps.maxViewportWidth;
1412 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001413 }
1414 break;
1415 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001416 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001417 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001418 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1419 *params = mResetStrategy;
1420 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001421 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001422 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001423 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001424 case GL_SHADER_BINARY_FORMATS:
1425 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1426 break;
1427 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001428 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001429 break;
1430 case GL_PROGRAM_BINARY_FORMATS:
1431 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001432 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001433 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001434 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001435 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001436
1437 // GL_KHR_debug
1438 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1439 *params = mExtensions.maxDebugMessageLength;
1440 break;
1441 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1442 *params = mExtensions.maxDebugLoggedMessages;
1443 break;
1444 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1445 *params = mExtensions.maxDebugGroupStackDepth;
1446 break;
1447 case GL_MAX_LABEL_LENGTH:
1448 *params = mExtensions.maxLabelLength;
1449 break;
1450
Ian Ewell53f59f42016-01-28 17:36:55 -05001451 // GL_EXT_disjoint_timer_query
1452 case GL_GPU_DISJOINT_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001453 *params = mImplementation->getGPUDisjoint();
Ian Ewell53f59f42016-01-28 17:36:55 -05001454 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001455 case GL_MAX_FRAMEBUFFER_WIDTH:
1456 *params = mCaps.maxFramebufferWidth;
1457 break;
1458 case GL_MAX_FRAMEBUFFER_HEIGHT:
1459 *params = mCaps.maxFramebufferHeight;
1460 break;
1461 case GL_MAX_FRAMEBUFFER_SAMPLES:
1462 *params = mCaps.maxFramebufferSamples;
1463 break;
1464 case GL_MAX_SAMPLE_MASK_WORDS:
1465 *params = mCaps.maxSampleMaskWords;
1466 break;
1467 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1468 *params = mCaps.maxColorTextureSamples;
1469 break;
1470 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1471 *params = mCaps.maxDepthTextureSamples;
1472 break;
1473 case GL_MAX_INTEGER_SAMPLES:
1474 *params = mCaps.maxIntegerSamples;
1475 break;
1476 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1477 *params = mCaps.maxVertexAttribRelativeOffset;
1478 break;
1479 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1480 *params = mCaps.maxVertexAttribBindings;
1481 break;
1482 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1483 *params = mCaps.maxVertexAttribStride;
1484 break;
1485 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1486 *params = mCaps.maxVertexAtomicCounterBuffers;
1487 break;
1488 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1489 *params = mCaps.maxVertexAtomicCounters;
1490 break;
1491 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1492 *params = mCaps.maxVertexImageUniforms;
1493 break;
1494 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1495 *params = mCaps.maxVertexShaderStorageBlocks;
1496 break;
1497 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1498 *params = mCaps.maxFragmentAtomicCounterBuffers;
1499 break;
1500 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1501 *params = mCaps.maxFragmentAtomicCounters;
1502 break;
1503 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1504 *params = mCaps.maxFragmentImageUniforms;
1505 break;
1506 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1507 *params = mCaps.maxFragmentShaderStorageBlocks;
1508 break;
1509 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1510 *params = mCaps.minProgramTextureGatherOffset;
1511 break;
1512 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1513 *params = mCaps.maxProgramTextureGatherOffset;
1514 break;
1515 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1516 *params = mCaps.maxComputeWorkGroupInvocations;
1517 break;
1518 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1519 *params = mCaps.maxComputeUniformBlocks;
1520 break;
1521 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1522 *params = mCaps.maxComputeTextureImageUnits;
1523 break;
1524 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1525 *params = mCaps.maxComputeSharedMemorySize;
1526 break;
1527 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1528 *params = mCaps.maxComputeUniformComponents;
1529 break;
1530 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1531 *params = mCaps.maxComputeAtomicCounterBuffers;
1532 break;
1533 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1534 *params = mCaps.maxComputeAtomicCounters;
1535 break;
1536 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1537 *params = mCaps.maxComputeImageUniforms;
1538 break;
1539 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1540 *params = mCaps.maxCombinedComputeUniformComponents;
1541 break;
1542 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1543 *params = mCaps.maxComputeShaderStorageBlocks;
1544 break;
1545 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1546 *params = mCaps.maxCombinedShaderOutputResources;
1547 break;
1548 case GL_MAX_UNIFORM_LOCATIONS:
1549 *params = mCaps.maxUniformLocations;
1550 break;
1551 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1552 *params = mCaps.maxAtomicCounterBufferBindings;
1553 break;
1554 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1555 *params = mCaps.maxAtomicCounterBufferSize;
1556 break;
1557 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1558 *params = mCaps.maxCombinedAtomicCounterBuffers;
1559 break;
1560 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1561 *params = mCaps.maxCombinedAtomicCounters;
1562 break;
1563 case GL_MAX_IMAGE_UNITS:
1564 *params = mCaps.maxImageUnits;
1565 break;
1566 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1567 *params = mCaps.maxCombinedImageUniforms;
1568 break;
1569 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1570 *params = mCaps.maxShaderStorageBufferBindings;
1571 break;
1572 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1573 *params = mCaps.maxCombinedShaderStorageBlocks;
1574 break;
1575 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1576 *params = mCaps.shaderStorageBufferOffsetAlignment;
1577 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001578 default:
Jamie Madilldd43e6c2017-03-24 14:18:49 -04001579 mGLState.getIntegerv(this, pname, params);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001580 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001581 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001582}
1583
Jamie Madill893ab082014-05-16 16:56:10 -04001584void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001585{
Shannon Woods53a94a82014-06-24 15:20:36 -04001586 // Queries about context capabilities and maximums are answered by Context.
1587 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001588 switch (pname)
1589 {
1590 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001591 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001592 break;
1593 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001594 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001595 break;
1596 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001597 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001598 break;
1599 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001600 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001601 break;
1602 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001603 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001604 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001605
1606 // GL_EXT_disjoint_timer_query
1607 case GL_TIMESTAMP_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001608 *params = mImplementation->getTimestamp();
Ian Ewell53f59f42016-01-28 17:36:55 -05001609 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001610
1611 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1612 *params = mCaps.maxShaderStorageBlockSize;
1613 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001614 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001615 UNREACHABLE();
1616 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001617 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001618}
1619
Geoff Lang70d0f492015-12-10 17:45:46 -05001620void Context::getPointerv(GLenum pname, void **params) const
1621{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001622 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001623}
1624
Martin Radev66fb8202016-07-28 11:45:20 +03001625void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001626{
Shannon Woods53a94a82014-06-24 15:20:36 -04001627 // Queries about context capabilities and maximums are answered by Context.
1628 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001629
1630 GLenum nativeType;
1631 unsigned int numParams;
1632 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1633 ASSERT(queryStatus);
1634
1635 if (nativeType == GL_INT)
1636 {
1637 switch (target)
1638 {
1639 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1640 ASSERT(index < 3u);
1641 *data = mCaps.maxComputeWorkGroupCount[index];
1642 break;
1643 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1644 ASSERT(index < 3u);
1645 *data = mCaps.maxComputeWorkGroupSize[index];
1646 break;
1647 default:
1648 mGLState.getIntegeri_v(target, index, data);
1649 }
1650 }
1651 else
1652 {
1653 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1654 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001655}
1656
Martin Radev66fb8202016-07-28 11:45:20 +03001657void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001658{
Shannon Woods53a94a82014-06-24 15:20:36 -04001659 // Queries about context capabilities and maximums are answered by Context.
1660 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001661
1662 GLenum nativeType;
1663 unsigned int numParams;
1664 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1665 ASSERT(queryStatus);
1666
1667 if (nativeType == GL_INT_64_ANGLEX)
1668 {
1669 mGLState.getInteger64i_v(target, index, data);
1670 }
1671 else
1672 {
1673 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1674 }
1675}
1676
1677void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1678{
1679 // Queries about context capabilities and maximums are answered by Context.
1680 // Queries about current GL state values are answered by State.
1681
1682 GLenum nativeType;
1683 unsigned int numParams;
1684 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1685 ASSERT(queryStatus);
1686
1687 if (nativeType == GL_BOOL)
1688 {
1689 mGLState.getBooleani_v(target, index, data);
1690 }
1691 else
1692 {
1693 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1694 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001695}
1696
He Yunchao010e4db2017-03-03 14:22:06 +08001697void Context::getBufferParameteriv(GLenum target, GLenum pname, GLint *params)
1698{
1699 Buffer *buffer = mGLState.getTargetBuffer(target);
1700 QueryBufferParameteriv(buffer, pname, params);
1701}
1702
1703void Context::getFramebufferAttachmentParameteriv(GLenum target,
1704 GLenum attachment,
1705 GLenum pname,
1706 GLint *params)
1707{
1708 const Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
1709 QueryFramebufferAttachmentParameteriv(framebuffer, attachment, pname, params);
1710}
1711
1712void Context::getRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
1713{
1714 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
1715 QueryRenderbufferiv(this, renderbuffer, pname, params);
1716}
1717
1718void Context::getTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
1719{
1720 Texture *texture = getTargetTexture(target);
1721 QueryTexParameterfv(texture, pname, params);
1722}
1723
1724void Context::getTexParameteriv(GLenum target, GLenum pname, GLint *params)
1725{
1726 Texture *texture = getTargetTexture(target);
1727 QueryTexParameteriv(texture, pname, params);
1728}
1729void Context::texParameterf(GLenum target, GLenum pname, GLfloat param)
1730{
1731 Texture *texture = getTargetTexture(target);
1732 SetTexParameterf(texture, pname, param);
1733}
1734
1735void Context::texParameterfv(GLenum target, GLenum pname, const GLfloat *params)
1736{
1737 Texture *texture = getTargetTexture(target);
1738 SetTexParameterfv(texture, pname, params);
1739}
1740
1741void Context::texParameteri(GLenum target, GLenum pname, GLint param)
1742{
1743 Texture *texture = getTargetTexture(target);
1744 SetTexParameteri(texture, pname, param);
1745}
1746
1747void Context::texParameteriv(GLenum target, GLenum pname, const GLint *params)
1748{
1749 Texture *texture = getTargetTexture(target);
1750 SetTexParameteriv(texture, pname, params);
1751}
1752
Jamie Madill675fe712016-12-19 13:07:54 -05001753void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001754{
Jamie Madill1b94d432015-08-07 13:23:23 -04001755 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001756 auto error = mImplementation->drawArrays(mode, first, count);
1757 handleError(error);
1758 if (!error.isError())
1759 {
1760 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1761 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001762}
1763
Jamie Madill675fe712016-12-19 13:07:54 -05001764void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Geoff Langf6db0982015-08-25 13:04:00 -04001765{
1766 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001767 auto error = mImplementation->drawArraysInstanced(mode, first, count, instanceCount);
1768 handleError(error);
1769 if (!error.isError())
1770 {
1771 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1772 }
Geoff Langf6db0982015-08-25 13:04:00 -04001773}
1774
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001775void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001776{
Jamie Madill1b94d432015-08-07 13:23:23 -04001777 syncRendererState();
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001778 const IndexRange &indexRange = getParams<HasIndexRange>().getIndexRange().value();
Jamie Madill675fe712016-12-19 13:07:54 -05001779 handleError(mImplementation->drawElements(mode, count, type, indices, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001780}
1781
Jamie Madill675fe712016-12-19 13:07:54 -05001782void Context::drawElementsInstanced(GLenum mode,
1783 GLsizei count,
1784 GLenum type,
1785 const GLvoid *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001786 GLsizei instances)
Geoff Langf6db0982015-08-25 13:04:00 -04001787{
1788 syncRendererState();
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001789 const IndexRange &indexRange = getParams<HasIndexRange>().getIndexRange().value();
Jamie Madill675fe712016-12-19 13:07:54 -05001790 handleError(
1791 mImplementation->drawElementsInstanced(mode, count, type, indices, instances, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001792}
1793
Jamie Madill675fe712016-12-19 13:07:54 -05001794void Context::drawRangeElements(GLenum mode,
1795 GLuint start,
1796 GLuint end,
1797 GLsizei count,
1798 GLenum type,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001799 const GLvoid *indices)
Geoff Langf6db0982015-08-25 13:04:00 -04001800{
1801 syncRendererState();
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001802 const IndexRange &indexRange = getParams<HasIndexRange>().getIndexRange().value();
Jamie Madill675fe712016-12-19 13:07:54 -05001803 handleError(
1804 mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001805}
1806
Jiajia Qind9671222016-11-29 16:30:31 +08001807void Context::drawArraysIndirect(GLenum mode, const GLvoid *indirect)
1808{
1809 syncRendererState();
1810 handleError(mImplementation->drawArraysIndirect(mode, indirect));
1811}
1812
1813void Context::drawElementsIndirect(GLenum mode, GLenum type, const GLvoid *indirect)
1814{
1815 syncRendererState();
1816 handleError(mImplementation->drawElementsIndirect(mode, type, indirect));
1817}
1818
Jamie Madill675fe712016-12-19 13:07:54 -05001819void Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001820{
Jamie Madill675fe712016-12-19 13:07:54 -05001821 handleError(mImplementation->flush());
Geoff Lang129753a2015-01-09 16:52:09 -05001822}
1823
Jamie Madill675fe712016-12-19 13:07:54 -05001824void Context::finish()
Geoff Lang129753a2015-01-09 16:52:09 -05001825{
Jamie Madill675fe712016-12-19 13:07:54 -05001826 handleError(mImplementation->finish());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001827}
1828
Austin Kinross6ee1e782015-05-29 17:05:37 -07001829void Context::insertEventMarker(GLsizei length, const char *marker)
1830{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001831 ASSERT(mImplementation);
1832 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001833}
1834
1835void Context::pushGroupMarker(GLsizei length, const char *marker)
1836{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001837 ASSERT(mImplementation);
1838 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001839}
1840
1841void Context::popGroupMarker()
1842{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001843 ASSERT(mImplementation);
1844 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001845}
1846
Geoff Langd8605522016-04-13 10:19:12 -04001847void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1848{
1849 Program *programObject = getProgram(program);
1850 ASSERT(programObject);
1851
1852 programObject->bindUniformLocation(location, name);
1853}
1854
Sami Väisänena797e062016-05-12 15:23:40 +03001855void Context::setCoverageModulation(GLenum components)
1856{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001857 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001858}
1859
Sami Väisänene45e53b2016-05-25 10:36:04 +03001860void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1861{
1862 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1863}
1864
1865void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1866{
1867 GLfloat I[16];
1868 angle::Matrix<GLfloat>::setToIdentity(I);
1869
1870 mGLState.loadPathRenderingMatrix(matrixMode, I);
1871}
1872
1873void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1874{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001875 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001876 if (!pathObj)
1877 return;
1878
1879 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1880 syncRendererState();
1881
1882 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1883}
1884
1885void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1886{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001887 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001888 if (!pathObj)
1889 return;
1890
1891 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1892 syncRendererState();
1893
1894 mImplementation->stencilStrokePath(pathObj, reference, mask);
1895}
1896
1897void Context::coverFillPath(GLuint path, GLenum coverMode)
1898{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001899 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001900 if (!pathObj)
1901 return;
1902
1903 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1904 syncRendererState();
1905
1906 mImplementation->coverFillPath(pathObj, coverMode);
1907}
1908
1909void Context::coverStrokePath(GLuint path, GLenum coverMode)
1910{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001911 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001912 if (!pathObj)
1913 return;
1914
1915 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1916 syncRendererState();
1917
1918 mImplementation->coverStrokePath(pathObj, coverMode);
1919}
1920
1921void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1922{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001923 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001924 if (!pathObj)
1925 return;
1926
1927 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1928 syncRendererState();
1929
1930 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1931}
1932
1933void Context::stencilThenCoverStrokePath(GLuint path,
1934 GLint reference,
1935 GLuint mask,
1936 GLenum coverMode)
1937{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001938 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001939 if (!pathObj)
1940 return;
1941
1942 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1943 syncRendererState();
1944
1945 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1946}
1947
Sami Väisänend59ca052016-06-21 16:10:00 +03001948void Context::coverFillPathInstanced(GLsizei numPaths,
1949 GLenum pathNameType,
1950 const void *paths,
1951 GLuint pathBase,
1952 GLenum coverMode,
1953 GLenum transformType,
1954 const GLfloat *transformValues)
1955{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001956 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001957
1958 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1959 syncRendererState();
1960
1961 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1962}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001963
Sami Väisänend59ca052016-06-21 16:10:00 +03001964void Context::coverStrokePathInstanced(GLsizei numPaths,
1965 GLenum pathNameType,
1966 const void *paths,
1967 GLuint pathBase,
1968 GLenum coverMode,
1969 GLenum transformType,
1970 const GLfloat *transformValues)
1971{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001972 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001973
1974 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1975 syncRendererState();
1976
1977 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1978 transformValues);
1979}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001980
Sami Väisänend59ca052016-06-21 16:10:00 +03001981void Context::stencilFillPathInstanced(GLsizei numPaths,
1982 GLenum pathNameType,
1983 const void *paths,
1984 GLuint pathBase,
1985 GLenum fillMode,
1986 GLuint mask,
1987 GLenum transformType,
1988 const GLfloat *transformValues)
1989{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001990 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001991
1992 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1993 syncRendererState();
1994
1995 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1996 transformValues);
1997}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001998
Sami Väisänend59ca052016-06-21 16:10:00 +03001999void Context::stencilStrokePathInstanced(GLsizei numPaths,
2000 GLenum pathNameType,
2001 const void *paths,
2002 GLuint pathBase,
2003 GLint reference,
2004 GLuint mask,
2005 GLenum transformType,
2006 const GLfloat *transformValues)
2007{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002008 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002009
2010 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2011 syncRendererState();
2012
2013 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
2014 transformValues);
2015}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002016
Sami Väisänend59ca052016-06-21 16:10:00 +03002017void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
2018 GLenum pathNameType,
2019 const void *paths,
2020 GLuint pathBase,
2021 GLenum fillMode,
2022 GLuint mask,
2023 GLenum coverMode,
2024 GLenum transformType,
2025 const GLfloat *transformValues)
2026{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002027 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002028
2029 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2030 syncRendererState();
2031
2032 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
2033 transformType, transformValues);
2034}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002035
Sami Väisänend59ca052016-06-21 16:10:00 +03002036void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
2037 GLenum pathNameType,
2038 const void *paths,
2039 GLuint pathBase,
2040 GLint reference,
2041 GLuint mask,
2042 GLenum coverMode,
2043 GLenum transformType,
2044 const GLfloat *transformValues)
2045{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002046 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002047
2048 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2049 syncRendererState();
2050
2051 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
2052 transformType, transformValues);
2053}
2054
Sami Väisänen46eaa942016-06-29 10:26:37 +03002055void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
2056{
2057 auto *programObject = getProgram(program);
2058
2059 programObject->bindFragmentInputLocation(location, name);
2060}
2061
2062void Context::programPathFragmentInputGen(GLuint program,
2063 GLint location,
2064 GLenum genMode,
2065 GLint components,
2066 const GLfloat *coeffs)
2067{
2068 auto *programObject = getProgram(program);
2069
2070 programObject->pathFragmentInputGen(location, genMode, components, coeffs);
2071}
2072
jchen1015015f72017-03-16 13:54:21 +08002073GLuint Context::getProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name)
2074{
jchen10fd7c3b52017-03-21 15:36:03 +08002075 const auto *programObject = getProgram(program);
jchen1015015f72017-03-16 13:54:21 +08002076 return QueryProgramResourceIndex(programObject, programInterface, name);
2077}
2078
jchen10fd7c3b52017-03-21 15:36:03 +08002079void Context::getProgramResourceName(GLuint program,
2080 GLenum programInterface,
2081 GLuint index,
2082 GLsizei bufSize,
2083 GLsizei *length,
2084 GLchar *name)
2085{
2086 const auto *programObject = getProgram(program);
2087 QueryProgramResourceName(programObject, programInterface, index, bufSize, length, name);
2088}
2089
Jamie Madill437fa652016-05-03 15:13:24 -04002090void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002091{
Geoff Langda5777c2014-07-11 09:52:58 -04002092 if (error.isError())
2093 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002094 GLenum code = error.getCode();
2095 mErrors.insert(code);
2096 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
2097 {
2098 markContextLost();
2099 }
Geoff Lang70d0f492015-12-10 17:45:46 -05002100
2101 if (!error.getMessage().empty())
2102 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002103 auto *debug = &mGLState.getDebug();
2104 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
2105 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05002106 }
Geoff Langda5777c2014-07-11 09:52:58 -04002107 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002108}
2109
2110// Get one of the recorded errors and clear its flag, if any.
2111// [OpenGL ES 2.0.24] section 2.5 page 13.
2112GLenum Context::getError()
2113{
Geoff Langda5777c2014-07-11 09:52:58 -04002114 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002115 {
Geoff Langda5777c2014-07-11 09:52:58 -04002116 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002117 }
Geoff Langda5777c2014-07-11 09:52:58 -04002118 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002119 {
Geoff Langda5777c2014-07-11 09:52:58 -04002120 GLenum error = *mErrors.begin();
2121 mErrors.erase(mErrors.begin());
2122 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002123 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002124}
2125
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002126// NOTE: this function should not assume that this context is current!
2127void Context::markContextLost()
2128{
2129 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002130 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002131 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002132 mContextLostForced = true;
2133 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002134 mContextLost = true;
2135}
2136
2137bool Context::isContextLost()
2138{
2139 return mContextLost;
2140}
2141
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002142GLenum Context::getResetStatus()
2143{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002144 // Even if the application doesn't want to know about resets, we want to know
2145 // as it will allow us to skip all the calls.
2146 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002147 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002148 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002149 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002150 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002151 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002152
2153 // EXT_robustness, section 2.6: If the reset notification behavior is
2154 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2155 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2156 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002157 }
2158
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002159 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2160 // status should be returned at least once, and GL_NO_ERROR should be returned
2161 // once the device has finished resetting.
2162 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002163 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002164 ASSERT(mResetStatus == GL_NO_ERROR);
2165 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002166
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002167 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002168 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002169 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002170 }
2171 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002172 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002173 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002174 // If markContextLost was used to mark the context lost then
2175 // assume that is not recoverable, and continue to report the
2176 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002177 mResetStatus = mImplementation->getResetStatus();
2178 }
Jamie Madill893ab082014-05-16 16:56:10 -04002179
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002180 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002181}
2182
2183bool Context::isResetNotificationEnabled()
2184{
2185 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2186}
2187
Corentin Walleze3b10e82015-05-20 11:06:25 -04002188const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002189{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002190 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002191}
2192
2193EGLenum Context::getClientType() const
2194{
2195 return mClientType;
2196}
2197
2198EGLenum Context::getRenderBuffer() const
2199{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002200 const Framebuffer *framebuffer = mState.mFramebuffers->getFramebuffer(0);
2201 if (framebuffer == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -04002202 {
2203 return EGL_NONE;
2204 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002205
2206 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2207 ASSERT(backAttachment != nullptr);
2208 return backAttachment->getSurface()->getRenderBuffer();
Régis Fénéon83107972015-02-05 12:57:44 +01002209}
2210
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002211VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002212{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002213 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002214 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2215 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002216 {
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002217 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle,
2218 mCaps.maxVertexAttributes, mCaps.maxVertexAttribBindings);
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002219
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002220 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002221 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002222
2223 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002224}
2225
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002226TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002227{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002228 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002229 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2230 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002231 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002232 transformFeedback =
2233 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002234 transformFeedback->addRef();
2235 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002236 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002237
2238 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002239}
2240
2241bool Context::isVertexArrayGenerated(GLuint vertexArray)
2242{
Geoff Langf41a7152016-09-19 15:11:17 -04002243 ASSERT(mVertexArrayMap.find(0) != mVertexArrayMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002244 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
2245}
2246
2247bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2248{
Geoff Langf41a7152016-09-19 15:11:17 -04002249 ASSERT(mTransformFeedbackMap.find(0) != mTransformFeedbackMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002250 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
2251}
2252
Shannon Woods53a94a82014-06-24 15:20:36 -04002253void Context::detachTexture(GLuint texture)
2254{
2255 // Simple pass-through to State's detachTexture method, as textures do not require
2256 // allocation map management either here or in the resource manager at detach time.
2257 // Zero textures are held by the Context, and we don't attempt to request them from
2258 // the State.
Jamie Madilla02315b2017-02-23 14:14:47 -05002259 mGLState.detachTexture(this, mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002260}
2261
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002262void Context::detachBuffer(GLuint buffer)
2263{
Yuly Novikov5807a532015-12-03 13:01:22 -05002264 // Simple pass-through to State's detachBuffer method, since
2265 // only buffer attachments to container objects that are bound to the current context
2266 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002267
Yuly Novikov5807a532015-12-03 13:01:22 -05002268 // [OpenGL ES 3.2] section 5.1.2 page 45:
2269 // Attachments to unbound container objects, such as
2270 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2271 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002272 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002273}
2274
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002275void Context::detachFramebuffer(GLuint framebuffer)
2276{
Shannon Woods53a94a82014-06-24 15:20:36 -04002277 // Framebuffer detachment is handled by Context, because 0 is a valid
2278 // Framebuffer object, and a pointer to it must be passed from Context
2279 // to State at binding time.
2280
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002281 // [OpenGL ES 2.0.24] section 4.4 page 107:
2282 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2283 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2284
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002285 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002286 {
2287 bindReadFramebuffer(0);
2288 }
2289
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002290 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002291 {
2292 bindDrawFramebuffer(0);
2293 }
2294}
2295
2296void Context::detachRenderbuffer(GLuint renderbuffer)
2297{
Jamie Madilla02315b2017-02-23 14:14:47 -05002298 mGLState.detachRenderbuffer(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002299}
2300
Jamie Madill57a89722013-07-02 11:57:03 -04002301void Context::detachVertexArray(GLuint vertexArray)
2302{
Jamie Madill77a72f62015-04-14 11:18:32 -04002303 // Vertex array detachment is handled by Context, because 0 is a valid
2304 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002305 // binding time.
2306
Jamie Madill57a89722013-07-02 11:57:03 -04002307 // [OpenGL ES 3.0.2] section 2.10 page 43:
2308 // If a vertex array object that is currently bound is deleted, the binding
2309 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002310 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002311 {
2312 bindVertexArray(0);
2313 }
2314}
2315
Geoff Langc8058452014-02-03 12:04:11 -05002316void Context::detachTransformFeedback(GLuint transformFeedback)
2317{
Corentin Walleza2257da2016-04-19 16:43:12 -04002318 // Transform feedback detachment is handled by Context, because 0 is a valid
2319 // transform feedback, and a pointer to it must be passed from Context to State at
2320 // binding time.
2321
2322 // The OpenGL specification doesn't mention what should happen when the currently bound
2323 // transform feedback object is deleted. Since it is a container object, we treat it like
2324 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002325 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002326 {
2327 bindTransformFeedback(0);
2328 }
Geoff Langc8058452014-02-03 12:04:11 -05002329}
2330
Jamie Madilldc356042013-07-19 16:36:57 -04002331void Context::detachSampler(GLuint sampler)
2332{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002333 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002334}
2335
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002336void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2337{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002338 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002339}
2340
Jamie Madille29d1672013-07-19 16:36:57 -04002341void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2342{
Geoff Langc1984ed2016-10-07 12:41:00 -04002343 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002344 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002345 SetSamplerParameteri(samplerObject, pname, param);
2346}
Jamie Madille29d1672013-07-19 16:36:57 -04002347
Geoff Langc1984ed2016-10-07 12:41:00 -04002348void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2349{
2350 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002351 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002352 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002353}
2354
2355void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2356{
Geoff Langc1984ed2016-10-07 12:41:00 -04002357 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002358 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002359 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002360}
2361
Geoff Langc1984ed2016-10-07 12:41:00 -04002362void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002363{
Geoff Langc1984ed2016-10-07 12:41:00 -04002364 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002365 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002366 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002367}
2368
Geoff Langc1984ed2016-10-07 12:41:00 -04002369void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002370{
Geoff Langc1984ed2016-10-07 12:41:00 -04002371 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002372 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002373 QuerySamplerParameteriv(samplerObject, pname, params);
2374}
Jamie Madill9675b802013-07-19 16:36:59 -04002375
Geoff Langc1984ed2016-10-07 12:41:00 -04002376void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2377{
2378 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002379 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002380 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002381}
2382
Olli Etuahof0fee072016-03-30 15:11:58 +03002383void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2384{
2385 gl::Program *programObject = getProgram(program);
Yunchao He61afff12017-03-14 15:34:03 +08002386 SetProgramParameteri(programObject, pname, value);
Olli Etuahof0fee072016-03-30 15:11:58 +03002387}
2388
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002389void Context::initRendererString()
2390{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002391 std::ostringstream rendererString;
2392 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002393 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002394 rendererString << ")";
2395
Geoff Langcec35902014-04-16 10:52:36 -04002396 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002397}
2398
Geoff Langc339c4e2016-11-29 10:37:36 -05002399void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002400{
Geoff Langc339c4e2016-11-29 10:37:36 -05002401 const Version &clientVersion = getClientVersion();
2402
2403 std::ostringstream versionString;
2404 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2405 << ANGLE_VERSION_STRING << ")";
2406 mVersionString = MakeStaticString(versionString.str());
2407
2408 std::ostringstream shadingLanguageVersionString;
2409 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2410 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2411 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2412 << ")";
2413 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002414}
2415
Geoff Langcec35902014-04-16 10:52:36 -04002416void Context::initExtensionStrings()
2417{
Geoff Langc339c4e2016-11-29 10:37:36 -05002418 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2419 std::ostringstream combinedStringStream;
2420 std::copy(strings.begin(), strings.end(),
2421 std::ostream_iterator<const char *>(combinedStringStream, " "));
2422 return MakeStaticString(combinedStringStream.str());
2423 };
2424
2425 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002426 for (const auto &extensionString : mExtensions.getStrings())
2427 {
2428 mExtensionStrings.push_back(MakeStaticString(extensionString));
2429 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002430 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002431
Bryan Bernhart58806562017-01-05 13:09:31 -08002432 const gl::Extensions &nativeExtensions = mImplementation->getNativeExtensions();
2433
Geoff Langc339c4e2016-11-29 10:37:36 -05002434 mRequestableExtensionStrings.clear();
2435 for (const auto &extensionInfo : GetExtensionInfoMap())
2436 {
2437 if (extensionInfo.second.Requestable &&
Bryan Bernhart58806562017-01-05 13:09:31 -08002438 !(mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
2439 nativeExtensions.*(extensionInfo.second.ExtensionsMember))
Geoff Langc339c4e2016-11-29 10:37:36 -05002440 {
2441 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2442 }
2443 }
2444 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002445}
2446
Geoff Langc339c4e2016-11-29 10:37:36 -05002447const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002448{
Geoff Langc339c4e2016-11-29 10:37:36 -05002449 switch (name)
2450 {
2451 case GL_VENDOR:
2452 return reinterpret_cast<const GLubyte *>("Google Inc.");
2453
2454 case GL_RENDERER:
2455 return reinterpret_cast<const GLubyte *>(mRendererString);
2456
2457 case GL_VERSION:
2458 return reinterpret_cast<const GLubyte *>(mVersionString);
2459
2460 case GL_SHADING_LANGUAGE_VERSION:
2461 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2462
2463 case GL_EXTENSIONS:
2464 return reinterpret_cast<const GLubyte *>(mExtensionString);
2465
2466 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2467 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2468
2469 default:
2470 UNREACHABLE();
2471 return nullptr;
2472 }
Geoff Langcec35902014-04-16 10:52:36 -04002473}
2474
Geoff Langc339c4e2016-11-29 10:37:36 -05002475const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002476{
Geoff Langc339c4e2016-11-29 10:37:36 -05002477 switch (name)
2478 {
2479 case GL_EXTENSIONS:
2480 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2481
2482 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2483 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2484
2485 default:
2486 UNREACHABLE();
2487 return nullptr;
2488 }
Geoff Langcec35902014-04-16 10:52:36 -04002489}
2490
2491size_t Context::getExtensionStringCount() const
2492{
2493 return mExtensionStrings.size();
2494}
2495
Geoff Langc339c4e2016-11-29 10:37:36 -05002496void Context::requestExtension(const char *name)
2497{
2498 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2499 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2500 const auto &extension = extensionInfos.at(name);
2501 ASSERT(extension.Requestable);
2502
2503 if (mExtensions.*(extension.ExtensionsMember))
2504 {
2505 // Extension already enabled
2506 return;
2507 }
2508
2509 mExtensions.*(extension.ExtensionsMember) = true;
2510 updateCaps();
2511 initExtensionStrings();
Bryan Bernhart58806562017-01-05 13:09:31 -08002512
2513 // Re-create the compiler with the requested extensions enabled.
2514 SafeDelete(mCompiler);
2515 mCompiler = new Compiler(mImplementation.get(), mState);
Geoff Lang9aded172017-04-05 11:07:56 -04002516
2517 // Invalidate all cached completenesses for textures and framebuffer. Some extensions make new
2518 // formats renderable or sampleable.
2519 mState.mTextures->invalidateTextureComplenessCache();
2520 for (auto &zeroTexture : mZeroTextures)
2521 {
2522 zeroTexture.second->invalidateCompletenessCache();
2523 }
2524
2525 mState.mFramebuffers->invalidateFramebufferComplenessCache();
Geoff Langc339c4e2016-11-29 10:37:36 -05002526}
2527
2528size_t Context::getRequestableExtensionStringCount() const
2529{
2530 return mRequestableExtensionStrings.size();
2531}
2532
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002533void Context::beginTransformFeedback(GLenum primitiveMode)
2534{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002535 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002536 ASSERT(transformFeedback != nullptr);
2537 ASSERT(!transformFeedback->isPaused());
2538
Jamie Madill6c1f6712017-02-14 19:08:04 -05002539 transformFeedback->begin(this, primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002540}
2541
2542bool Context::hasActiveTransformFeedback(GLuint program) const
2543{
2544 for (auto pair : mTransformFeedbackMap)
2545 {
2546 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2547 {
2548 return true;
2549 }
2550 }
2551 return false;
2552}
2553
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002554void Context::initCaps(const egl::DisplayExtensions &displayExtensions)
Geoff Lang493daf52014-07-03 13:38:44 -04002555{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002556 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002557
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002558 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002559
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002560 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002561
Geoff Langeb66a6e2016-10-31 13:06:12 -04002562 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002563 {
2564 // Disable ES3+ extensions
2565 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002566 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002567 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002568 }
2569
Geoff Langeb66a6e2016-10-31 13:06:12 -04002570 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002571 {
2572 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2573 //mExtensions.sRGB = false;
2574 }
2575
Jamie Madill00ed7a12016-05-19 13:13:38 -04002576 // Some extensions are always available because they are implemented in the GL layer.
2577 mExtensions.bindUniformLocation = true;
2578 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002579 mExtensions.bindGeneratesResource = true;
Geoff Langfeb8c682017-02-13 16:07:35 -05002580 mExtensions.clientArrays = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002581 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002582
2583 // Enable the no error extension if the context was created with the flag.
2584 mExtensions.noError = mSkipValidation;
2585
Corentin Wallezccab69d2017-01-27 16:57:15 -05002586 // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
Corentin Wallezc295e512017-01-27 17:47:50 -05002587 mExtensions.surfacelessContext = displayExtensions.surfacelessContext;
Corentin Wallezccab69d2017-01-27 16:57:15 -05002588
Geoff Lang70d0f492015-12-10 17:45:46 -05002589 // Explicitly enable GL_KHR_debug
2590 mExtensions.debug = true;
2591 mExtensions.maxDebugMessageLength = 1024;
2592 mExtensions.maxDebugLoggedMessages = 1024;
2593 mExtensions.maxDebugGroupStackDepth = 1024;
2594 mExtensions.maxLabelLength = 1024;
2595
Geoff Langff5b2d52016-09-07 11:32:23 -04002596 // Explicitly enable GL_ANGLE_robust_client_memory
2597 mExtensions.robustClientMemory = true;
2598
Jamie Madille08a1d32017-03-07 17:24:06 -05002599 // Determine robust resource init availability from EGL.
2600 mExtensions.robustResourceInitialization =
2601 displayExtensions.createContextRobustResourceInitialization;
2602
Geoff Lang301d1612014-07-09 10:34:37 -04002603 // Apply implementation limits
2604 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002605 mCaps.maxVertexAttribBindings =
2606 getClientVersion() < ES_3_1
2607 ? mCaps.maxVertexAttributes
2608 : std::min<GLuint>(mCaps.maxVertexAttribBindings, MAX_VERTEX_ATTRIB_BINDINGS);
2609
Geoff Lang301d1612014-07-09 10:34:37 -04002610 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2611 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2612
2613 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002614
Geoff Langc287ea62016-09-16 14:46:51 -04002615 // WebGL compatibility
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002616 mExtensions.webglCompatibility = mWebGLContext;
Geoff Langc287ea62016-09-16 14:46:51 -04002617 for (const auto &extensionInfo : GetExtensionInfoMap())
2618 {
2619 // If this context is for WebGL, disable all enableable extensions
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002620 if (mWebGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002621 {
2622 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2623 }
2624 }
2625
2626 // Generate texture caps
2627 updateCaps();
2628}
2629
2630void Context::updateCaps()
2631{
Geoff Lang900013c2014-07-07 11:32:19 -04002632 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002633 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002634
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002635 for (auto capsIt : mImplementation->getNativeTextureCaps())
Geoff Lang493daf52014-07-03 13:38:44 -04002636 {
Geoff Langca271392017-04-05 12:30:00 -04002637 GLenum sizedInternalFormat = capsIt.first;
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002638 TextureCaps formatCaps = capsIt.second;
Geoff Lang493daf52014-07-03 13:38:44 -04002639
Geoff Langca271392017-04-05 12:30:00 -04002640 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002641
Geoff Lang0d8b7242015-09-09 14:56:53 -04002642 // Update the format caps based on the client version and extensions.
2643 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2644 // ES3.
2645 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002646 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002647 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002648 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002649 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002650 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002651
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002652 // OpenGL ES does not support multisampling with non-rendererable formats
2653 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
2654 if (!formatInfo.renderSupport ||
2655 (getClientVersion() < ES_3_1 &&
2656 (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
Geoff Lang493daf52014-07-03 13:38:44 -04002657 {
Geoff Langd87878e2014-09-19 15:42:59 -04002658 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002659 }
Geoff Langd87878e2014-09-19 15:42:59 -04002660
2661 if (formatCaps.texturable && formatInfo.compressed)
2662 {
Geoff Langca271392017-04-05 12:30:00 -04002663 mCaps.compressedTextureFormats.push_back(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002664 }
2665
Geoff Langca271392017-04-05 12:30:00 -04002666 mTextureCaps.insert(sizedInternalFormat, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002667 }
2668}
2669
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002670void Context::initWorkarounds()
2671{
2672 // Lose the context upon out of memory error if the application is
2673 // expecting to watch for those events.
2674 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2675}
2676
Jamie Madill1b94d432015-08-07 13:23:23 -04002677void Context::syncRendererState()
2678{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002679 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
Frank Henigman5a53d542017-02-16 21:24:10 -05002680 mImplementation->syncState(dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002681 mGLState.clearDirtyBits();
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002682 mGLState.syncDirtyObjects(this);
Jamie Madill1b94d432015-08-07 13:23:23 -04002683}
2684
Jamie Madillad9f24e2016-02-12 09:27:24 -05002685void Context::syncRendererState(const State::DirtyBits &bitMask,
2686 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002687{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002688 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
Frank Henigman5a53d542017-02-16 21:24:10 -05002689 mImplementation->syncState(dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002690 mGLState.clearDirtyBits(dirtyBits);
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002691 mGLState.syncDirtyObjects(this, objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002692}
Jamie Madillc29968b2016-01-20 11:17:23 -05002693
2694void Context::blitFramebuffer(GLint srcX0,
2695 GLint srcY0,
2696 GLint srcX1,
2697 GLint srcY1,
2698 GLint dstX0,
2699 GLint dstY0,
2700 GLint dstX1,
2701 GLint dstY1,
2702 GLbitfield mask,
2703 GLenum filter)
2704{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002705 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002706 ASSERT(drawFramebuffer);
2707
2708 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2709 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2710
Jamie Madillad9f24e2016-02-12 09:27:24 -05002711 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002712
Jamie Madill8415b5f2016-04-26 13:41:39 -04002713 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002714}
Jamie Madillc29968b2016-01-20 11:17:23 -05002715
2716void Context::clear(GLbitfield mask)
2717{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002718 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002719 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002720}
2721
2722void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2723{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002724 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002725 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2726 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002727}
2728
2729void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2730{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002731 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002732 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2733 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002734}
2735
2736void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2737{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002738 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002739 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2740 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002741}
2742
2743void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2744{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002745 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002746 ASSERT(framebufferObject);
2747
2748 // If a buffer is not present, the clear has no effect
2749 if (framebufferObject->getDepthbuffer() == nullptr &&
2750 framebufferObject->getStencilbuffer() == nullptr)
2751 {
2752 return;
2753 }
2754
Jamie Madillad9f24e2016-02-12 09:27:24 -05002755 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002756 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2757 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002758}
2759
2760void Context::readPixels(GLint x,
2761 GLint y,
2762 GLsizei width,
2763 GLsizei height,
2764 GLenum format,
2765 GLenum type,
2766 GLvoid *pixels)
2767{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002768 if (width == 0 || height == 0)
2769 {
2770 return;
2771 }
2772
Jamie Madillad9f24e2016-02-12 09:27:24 -05002773 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002774
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002775 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002776 ASSERT(framebufferObject);
2777
2778 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002779 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002780}
2781
2782void Context::copyTexImage2D(GLenum target,
2783 GLint level,
2784 GLenum internalformat,
2785 GLint x,
2786 GLint y,
2787 GLsizei width,
2788 GLsizei height,
2789 GLint border)
2790{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002791 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002792 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002793
Jamie Madillc29968b2016-01-20 11:17:23 -05002794 Rectangle sourceArea(x, y, width, height);
2795
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002796 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002797 Texture *texture =
2798 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002799 handleError(texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002800}
2801
2802void Context::copyTexSubImage2D(GLenum target,
2803 GLint level,
2804 GLint xoffset,
2805 GLint yoffset,
2806 GLint x,
2807 GLint y,
2808 GLsizei width,
2809 GLsizei height)
2810{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002811 if (width == 0 || height == 0)
2812 {
2813 return;
2814 }
2815
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002816 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002817 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002818
Jamie Madillc29968b2016-01-20 11:17:23 -05002819 Offset destOffset(xoffset, yoffset, 0);
2820 Rectangle sourceArea(x, y, width, height);
2821
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002822 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002823 Texture *texture =
2824 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002825 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002826}
2827
2828void Context::copyTexSubImage3D(GLenum target,
2829 GLint level,
2830 GLint xoffset,
2831 GLint yoffset,
2832 GLint zoffset,
2833 GLint x,
2834 GLint y,
2835 GLsizei width,
2836 GLsizei height)
2837{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002838 if (width == 0 || height == 0)
2839 {
2840 return;
2841 }
2842
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002843 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002844 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002845
Jamie Madillc29968b2016-01-20 11:17:23 -05002846 Offset destOffset(xoffset, yoffset, zoffset);
2847 Rectangle sourceArea(x, y, width, height);
2848
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002849 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002850 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002851 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002852}
2853
2854void Context::framebufferTexture2D(GLenum target,
2855 GLenum attachment,
2856 GLenum textarget,
2857 GLuint texture,
2858 GLint level)
2859{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002860 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002861 ASSERT(framebuffer);
2862
2863 if (texture != 0)
2864 {
2865 Texture *textureObj = getTexture(texture);
2866
2867 ImageIndex index = ImageIndex::MakeInvalid();
2868
2869 if (textarget == GL_TEXTURE_2D)
2870 {
2871 index = ImageIndex::Make2D(level);
2872 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08002873 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
2874 {
2875 ASSERT(level == 0);
2876 index = ImageIndex::Make2DMultisample();
2877 }
Jamie Madillc29968b2016-01-20 11:17:23 -05002878 else
2879 {
2880 ASSERT(IsCubeMapTextureTarget(textarget));
2881 index = ImageIndex::MakeCube(textarget, level);
2882 }
2883
Jamie Madilla02315b2017-02-23 14:14:47 -05002884 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
Jamie Madillc29968b2016-01-20 11:17:23 -05002885 }
2886 else
2887 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002888 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002889 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002890
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002891 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002892}
2893
2894void Context::framebufferRenderbuffer(GLenum target,
2895 GLenum attachment,
2896 GLenum renderbuffertarget,
2897 GLuint renderbuffer)
2898{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002899 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002900 ASSERT(framebuffer);
2901
2902 if (renderbuffer != 0)
2903 {
2904 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
Jamie Madilla02315b2017-02-23 14:14:47 -05002905
2906 framebuffer->setAttachment(this, GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
Jamie Madillc29968b2016-01-20 11:17:23 -05002907 renderbufferObject);
2908 }
2909 else
2910 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002911 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002912 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002913
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002914 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002915}
2916
2917void Context::framebufferTextureLayer(GLenum target,
2918 GLenum attachment,
2919 GLuint texture,
2920 GLint level,
2921 GLint layer)
2922{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002923 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002924 ASSERT(framebuffer);
2925
2926 if (texture != 0)
2927 {
2928 Texture *textureObject = getTexture(texture);
2929
2930 ImageIndex index = ImageIndex::MakeInvalid();
2931
2932 if (textureObject->getTarget() == GL_TEXTURE_3D)
2933 {
2934 index = ImageIndex::Make3D(level, layer);
2935 }
2936 else
2937 {
2938 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2939 index = ImageIndex::Make2DArray(level, layer);
2940 }
2941
Jamie Madilla02315b2017-02-23 14:14:47 -05002942 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObject);
Jamie Madillc29968b2016-01-20 11:17:23 -05002943 }
2944 else
2945 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002946 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002947 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002948
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002949 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002950}
2951
2952void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2953{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002954 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002955 ASSERT(framebuffer);
2956 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002957 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002958}
2959
2960void Context::readBuffer(GLenum mode)
2961{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002962 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002963 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002964 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002965}
2966
2967void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2968{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002969 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002970 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002971
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002972 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002973 ASSERT(framebuffer);
2974
2975 // The specification isn't clear what should be done when the framebuffer isn't complete.
2976 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002977 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002978}
2979
2980void Context::invalidateFramebuffer(GLenum target,
2981 GLsizei numAttachments,
2982 const GLenum *attachments)
2983{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002984 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002985 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002986
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002987 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002988 ASSERT(framebuffer);
2989
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002990 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002991 {
Jamie Madill437fa652016-05-03 15:13:24 -04002992 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002993 }
Jamie Madill437fa652016-05-03 15:13:24 -04002994
2995 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002996}
2997
2998void Context::invalidateSubFramebuffer(GLenum target,
2999 GLsizei numAttachments,
3000 const GLenum *attachments,
3001 GLint x,
3002 GLint y,
3003 GLsizei width,
3004 GLsizei height)
3005{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003006 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003007 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003008
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003009 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003010 ASSERT(framebuffer);
3011
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003012 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003013 {
Jamie Madill437fa652016-05-03 15:13:24 -04003014 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003015 }
Jamie Madill437fa652016-05-03 15:13:24 -04003016
3017 Rectangle area(x, y, width, height);
3018 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05003019}
3020
Jamie Madill73a84962016-02-12 09:27:23 -05003021void Context::texImage2D(GLenum target,
3022 GLint level,
3023 GLint internalformat,
3024 GLsizei width,
3025 GLsizei height,
3026 GLint border,
3027 GLenum format,
3028 GLenum type,
3029 const GLvoid *pixels)
3030{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003031 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003032
3033 Extents size(width, height, 1);
3034 Texture *texture =
3035 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003036 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3037 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003038}
3039
3040void Context::texImage3D(GLenum target,
3041 GLint level,
3042 GLint internalformat,
3043 GLsizei width,
3044 GLsizei height,
3045 GLsizei depth,
3046 GLint border,
3047 GLenum format,
3048 GLenum type,
3049 const GLvoid *pixels)
3050{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003051 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003052
3053 Extents size(width, height, depth);
3054 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003055 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3056 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003057}
3058
3059void Context::texSubImage2D(GLenum target,
3060 GLint level,
3061 GLint xoffset,
3062 GLint yoffset,
3063 GLsizei width,
3064 GLsizei height,
3065 GLenum format,
3066 GLenum type,
3067 const GLvoid *pixels)
3068{
3069 // Zero sized uploads are valid but no-ops
3070 if (width == 0 || height == 0)
3071 {
3072 return;
3073 }
3074
Jamie Madillad9f24e2016-02-12 09:27:24 -05003075 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003076
3077 Box area(xoffset, yoffset, 0, width, height, 1);
3078 Texture *texture =
3079 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003080 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3081 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003082}
3083
3084void Context::texSubImage3D(GLenum target,
3085 GLint level,
3086 GLint xoffset,
3087 GLint yoffset,
3088 GLint zoffset,
3089 GLsizei width,
3090 GLsizei height,
3091 GLsizei depth,
3092 GLenum format,
3093 GLenum type,
3094 const GLvoid *pixels)
3095{
3096 // Zero sized uploads are valid but no-ops
3097 if (width == 0 || height == 0 || depth == 0)
3098 {
3099 return;
3100 }
3101
Jamie Madillad9f24e2016-02-12 09:27:24 -05003102 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003103
3104 Box area(xoffset, yoffset, zoffset, width, height, depth);
3105 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003106 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3107 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003108}
3109
3110void Context::compressedTexImage2D(GLenum target,
3111 GLint level,
3112 GLenum internalformat,
3113 GLsizei width,
3114 GLsizei height,
3115 GLint border,
3116 GLsizei imageSize,
3117 const GLvoid *data)
3118{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003119 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003120
3121 Extents size(width, height, 1);
3122 Texture *texture =
3123 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003124 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003125 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003126 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003127}
3128
3129void Context::compressedTexImage3D(GLenum target,
3130 GLint level,
3131 GLenum internalformat,
3132 GLsizei width,
3133 GLsizei height,
3134 GLsizei depth,
3135 GLint border,
3136 GLsizei imageSize,
3137 const GLvoid *data)
3138{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003139 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003140
3141 Extents size(width, height, depth);
3142 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003143 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003144 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003145 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003146}
3147
3148void Context::compressedTexSubImage2D(GLenum target,
3149 GLint level,
3150 GLint xoffset,
3151 GLint yoffset,
3152 GLsizei width,
3153 GLsizei height,
3154 GLenum format,
3155 GLsizei imageSize,
3156 const GLvoid *data)
3157{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003158 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003159
3160 Box area(xoffset, yoffset, 0, width, height, 1);
3161 Texture *texture =
3162 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003163 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003164 format, imageSize,
3165 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003166}
3167
3168void Context::compressedTexSubImage3D(GLenum target,
3169 GLint level,
3170 GLint xoffset,
3171 GLint yoffset,
3172 GLint zoffset,
3173 GLsizei width,
3174 GLsizei height,
3175 GLsizei depth,
3176 GLenum format,
3177 GLsizei imageSize,
3178 const GLvoid *data)
3179{
3180 // Zero sized uploads are valid but no-ops
3181 if (width == 0 || height == 0)
3182 {
3183 return;
3184 }
3185
Jamie Madillad9f24e2016-02-12 09:27:24 -05003186 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003187
3188 Box area(xoffset, yoffset, zoffset, width, height, depth);
3189 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003190 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003191 format, imageSize,
3192 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003193}
3194
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003195void Context::generateMipmap(GLenum target)
3196{
3197 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003198 handleError(texture->generateMipmap(this));
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003199}
3200
Geoff Lang97073d12016-04-20 10:42:34 -07003201void Context::copyTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003202 GLint sourceLevel,
3203 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003204 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003205 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003206 GLint internalFormat,
3207 GLenum destType,
3208 GLboolean unpackFlipY,
3209 GLboolean unpackPremultiplyAlpha,
3210 GLboolean unpackUnmultiplyAlpha)
3211{
3212 syncStateForTexImage();
3213
3214 gl::Texture *sourceTexture = getTexture(sourceId);
3215 gl::Texture *destTexture = getTexture(destId);
Geoff Langfc72a072017-03-24 14:52:39 -04003216 handleError(destTexture->copyTexture(
3217 this, destTarget, destLevel, internalFormat, destType, sourceLevel, unpackFlipY == GL_TRUE,
3218 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003219}
3220
3221void Context::copySubTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003222 GLint sourceLevel,
3223 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003224 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003225 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003226 GLint xoffset,
3227 GLint yoffset,
3228 GLint x,
3229 GLint y,
3230 GLsizei width,
3231 GLsizei height,
3232 GLboolean unpackFlipY,
3233 GLboolean unpackPremultiplyAlpha,
3234 GLboolean unpackUnmultiplyAlpha)
3235{
3236 // Zero sized copies are valid but no-ops
3237 if (width == 0 || height == 0)
3238 {
3239 return;
3240 }
3241
3242 syncStateForTexImage();
3243
3244 gl::Texture *sourceTexture = getTexture(sourceId);
3245 gl::Texture *destTexture = getTexture(destId);
3246 Offset offset(xoffset, yoffset, 0);
3247 Rectangle area(x, y, width, height);
Geoff Langfc72a072017-03-24 14:52:39 -04003248 handleError(destTexture->copySubTexture(
3249 this, destTarget, destLevel, offset, sourceLevel, area, unpackFlipY == GL_TRUE,
3250 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003251}
3252
Geoff Lang47110bf2016-04-20 11:13:22 -07003253void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3254{
3255 syncStateForTexImage();
3256
3257 gl::Texture *sourceTexture = getTexture(sourceId);
3258 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003259 handleError(destTexture->copyCompressedTexture(this, sourceTexture));
Geoff Lang47110bf2016-04-20 11:13:22 -07003260}
3261
Geoff Lang496c02d2016-10-20 11:38:11 -07003262void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003263{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003264 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003265 ASSERT(buffer);
3266
Geoff Lang496c02d2016-10-20 11:38:11 -07003267 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003268}
3269
3270GLvoid *Context::mapBuffer(GLenum target, GLenum access)
3271{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003272 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003273 ASSERT(buffer);
3274
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003275 Error error = buffer->map(this, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003276 if (error.isError())
3277 {
Jamie Madill437fa652016-05-03 15:13:24 -04003278 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003279 return nullptr;
3280 }
3281
3282 return buffer->getMapPointer();
3283}
3284
3285GLboolean Context::unmapBuffer(GLenum target)
3286{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003287 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003288 ASSERT(buffer);
3289
3290 GLboolean result;
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003291 Error error = buffer->unmap(this, &result);
Olli Etuaho4f667482016-03-30 15:56:35 +03003292 if (error.isError())
3293 {
Jamie Madill437fa652016-05-03 15:13:24 -04003294 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003295 return GL_FALSE;
3296 }
3297
3298 return result;
3299}
3300
3301GLvoid *Context::mapBufferRange(GLenum target,
3302 GLintptr offset,
3303 GLsizeiptr length,
3304 GLbitfield access)
3305{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003306 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003307 ASSERT(buffer);
3308
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003309 Error error = buffer->mapRange(this, offset, length, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003310 if (error.isError())
3311 {
Jamie Madill437fa652016-05-03 15:13:24 -04003312 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003313 return nullptr;
3314 }
3315
3316 return buffer->getMapPointer();
3317}
3318
3319void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3320{
3321 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3322}
3323
Jamie Madillad9f24e2016-02-12 09:27:24 -05003324void Context::syncStateForReadPixels()
3325{
3326 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3327}
3328
3329void Context::syncStateForTexImage()
3330{
3331 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3332}
3333
3334void Context::syncStateForClear()
3335{
3336 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3337}
3338
3339void Context::syncStateForBlit()
3340{
3341 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3342}
3343
Jamie Madillc20ab272016-06-09 07:20:46 -07003344void Context::activeTexture(GLenum texture)
3345{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003346 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003347}
3348
3349void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3350{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003351 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003352}
3353
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003354void Context::blendEquation(GLenum mode)
3355{
3356 mGLState.setBlendEquation(mode, mode);
3357}
3358
Jamie Madillc20ab272016-06-09 07:20:46 -07003359void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3360{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003361 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003362}
3363
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003364void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3365{
3366 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3367}
3368
Jamie Madillc20ab272016-06-09 07:20:46 -07003369void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3370{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003371 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003372}
3373
3374void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3375{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003376 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003377}
3378
3379void Context::clearDepthf(GLclampf depth)
3380{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003381 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003382}
3383
3384void Context::clearStencil(GLint s)
3385{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003386 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003387}
3388
3389void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3390{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003391 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003392}
3393
3394void Context::cullFace(GLenum mode)
3395{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003396 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003397}
3398
3399void Context::depthFunc(GLenum func)
3400{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003401 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003402}
3403
3404void Context::depthMask(GLboolean flag)
3405{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003406 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003407}
3408
3409void Context::depthRangef(GLclampf zNear, GLclampf zFar)
3410{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003411 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003412}
3413
3414void Context::disable(GLenum cap)
3415{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003416 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003417}
3418
3419void Context::disableVertexAttribArray(GLuint index)
3420{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003421 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003422}
3423
3424void Context::enable(GLenum cap)
3425{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003426 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003427}
3428
3429void Context::enableVertexAttribArray(GLuint index)
3430{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003431 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003432}
3433
3434void Context::frontFace(GLenum mode)
3435{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003436 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003437}
3438
3439void Context::hint(GLenum target, GLenum mode)
3440{
3441 switch (target)
3442 {
3443 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003444 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003445 break;
3446
3447 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003448 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003449 break;
3450
3451 default:
3452 UNREACHABLE();
3453 return;
3454 }
3455}
3456
3457void Context::lineWidth(GLfloat width)
3458{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003459 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003460}
3461
3462void Context::pixelStorei(GLenum pname, GLint param)
3463{
3464 switch (pname)
3465 {
3466 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003467 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003468 break;
3469
3470 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003471 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003472 break;
3473
3474 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003475 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003476 break;
3477
3478 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003479 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003480 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003481 break;
3482
3483 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003484 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003485 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003486 break;
3487
3488 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003489 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003490 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003491 break;
3492
3493 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003494 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003495 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003496 break;
3497
3498 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003499 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003500 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003501 break;
3502
3503 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003504 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003505 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003506 break;
3507
3508 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003509 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003510 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003511 break;
3512
3513 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003514 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003515 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003516 break;
3517
3518 default:
3519 UNREACHABLE();
3520 return;
3521 }
3522}
3523
3524void Context::polygonOffset(GLfloat factor, GLfloat units)
3525{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003526 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003527}
3528
3529void Context::sampleCoverage(GLclampf value, GLboolean invert)
3530{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003531 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003532}
3533
3534void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3535{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003536 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003537}
3538
3539void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3540{
3541 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3542 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003543 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003544 }
3545
3546 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3547 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003548 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003549 }
3550}
3551
3552void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3553{
3554 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3555 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003556 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003557 }
3558
3559 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3560 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003561 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003562 }
3563}
3564
3565void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3566{
3567 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3568 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003569 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003570 }
3571
3572 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3573 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003574 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003575 }
3576}
3577
3578void Context::vertexAttrib1f(GLuint index, GLfloat x)
3579{
3580 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003581 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003582}
3583
3584void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3585{
3586 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003587 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003588}
3589
3590void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3591{
3592 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003593 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003594}
3595
3596void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3597{
3598 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003599 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003600}
3601
3602void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3603{
3604 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003605 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003606}
3607
3608void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3609{
3610 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003611 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003612}
3613
3614void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3615{
3616 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003617 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003618}
3619
3620void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3621{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003622 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003623}
3624
3625void Context::vertexAttribPointer(GLuint index,
3626 GLint size,
3627 GLenum type,
3628 GLboolean normalized,
3629 GLsizei stride,
3630 const GLvoid *ptr)
3631{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003632 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3633 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003634}
3635
Shao80957d92017-02-20 21:25:59 +08003636void Context::vertexAttribFormat(GLuint attribIndex,
3637 GLint size,
3638 GLenum type,
3639 GLboolean normalized,
3640 GLuint relativeOffset)
3641{
3642 mGLState.setVertexAttribFormat(attribIndex, size, type, normalized == GL_TRUE, false,
3643 relativeOffset);
3644}
3645
3646void Context::vertexAttribIFormat(GLuint attribIndex,
3647 GLint size,
3648 GLenum type,
3649 GLuint relativeOffset)
3650{
3651 mGLState.setVertexAttribFormat(attribIndex, size, type, false, true, relativeOffset);
3652}
3653
3654void Context::vertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
3655{
3656 mGLState.setVertexAttribBinding(attribIndex, bindingIndex);
3657}
3658
3659void Context::setVertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
3660{
3661 mGLState.setVertexBindingDivisor(bindingIndex, divisor);
3662}
3663
Jamie Madillc20ab272016-06-09 07:20:46 -07003664void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3665{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003666 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003667}
3668
3669void Context::vertexAttribIPointer(GLuint index,
3670 GLint size,
3671 GLenum type,
3672 GLsizei stride,
3673 const GLvoid *pointer)
3674{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003675 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3676 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003677}
3678
3679void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3680{
3681 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003682 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003683}
3684
3685void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3686{
3687 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003688 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003689}
3690
3691void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3692{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003693 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003694}
3695
3696void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3697{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003698 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003699}
3700
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003701void Context::getVertexAttribiv(GLuint index, GLenum pname, GLint *params)
3702{
3703 const VertexAttribCurrentValueData &currentValues =
3704 getGLState().getVertexAttribCurrentValue(index);
3705 const VertexArray *vao = getGLState().getVertexArray();
3706 QueryVertexAttribiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3707 currentValues, pname, params);
3708}
3709
3710void Context::getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
3711{
3712 const VertexAttribCurrentValueData &currentValues =
3713 getGLState().getVertexAttribCurrentValue(index);
3714 const VertexArray *vao = getGLState().getVertexArray();
3715 QueryVertexAttribfv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3716 currentValues, pname, params);
3717}
3718
3719void Context::getVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
3720{
3721 const VertexAttribCurrentValueData &currentValues =
3722 getGLState().getVertexAttribCurrentValue(index);
3723 const VertexArray *vao = getGLState().getVertexArray();
3724 QueryVertexAttribIiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3725 currentValues, pname, params);
3726}
3727
3728void Context::getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
3729{
3730 const VertexAttribCurrentValueData &currentValues =
3731 getGLState().getVertexAttribCurrentValue(index);
3732 const VertexArray *vao = getGLState().getVertexArray();
3733 QueryVertexAttribIuiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3734 currentValues, pname, params);
3735}
3736
3737void Context::getVertexAttribPointerv(GLuint index, GLenum pname, GLvoid **pointer)
3738{
3739 const VertexAttribute &attrib = getGLState().getVertexArray()->getVertexAttribute(index);
3740 QueryVertexAttribPointerv(attrib, pname, pointer);
3741}
3742
Jamie Madillc20ab272016-06-09 07:20:46 -07003743void Context::debugMessageControl(GLenum source,
3744 GLenum type,
3745 GLenum severity,
3746 GLsizei count,
3747 const GLuint *ids,
3748 GLboolean enabled)
3749{
3750 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003751 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3752 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003753}
3754
3755void Context::debugMessageInsert(GLenum source,
3756 GLenum type,
3757 GLuint id,
3758 GLenum severity,
3759 GLsizei length,
3760 const GLchar *buf)
3761{
3762 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003763 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003764}
3765
3766void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3767{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003768 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003769}
3770
3771GLuint Context::getDebugMessageLog(GLuint count,
3772 GLsizei bufSize,
3773 GLenum *sources,
3774 GLenum *types,
3775 GLuint *ids,
3776 GLenum *severities,
3777 GLsizei *lengths,
3778 GLchar *messageLog)
3779{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003780 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3781 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003782}
3783
3784void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3785{
3786 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003787 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003788}
3789
3790void Context::popDebugGroup()
3791{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003792 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003793}
3794
Jamie Madill29639852016-09-02 15:00:09 -04003795void Context::bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
3796{
3797 Buffer *buffer = mGLState.getTargetBuffer(target);
3798 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003799 handleError(buffer->bufferData(this, target, data, size, usage));
Jamie Madill29639852016-09-02 15:00:09 -04003800}
3801
3802void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
3803{
3804 if (data == nullptr)
3805 {
3806 return;
3807 }
3808
3809 Buffer *buffer = mGLState.getTargetBuffer(target);
3810 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003811 handleError(buffer->bufferSubData(this, target, data, size, offset));
Jamie Madill29639852016-09-02 15:00:09 -04003812}
3813
Jamie Madillef300b12016-10-07 15:12:09 -04003814void Context::attachShader(GLuint program, GLuint shader)
3815{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003816 auto programObject = mState.mShaderPrograms->getProgram(program);
3817 auto shaderObject = mState.mShaderPrograms->getShader(shader);
Jamie Madillef300b12016-10-07 15:12:09 -04003818 ASSERT(programObject && shaderObject);
3819 programObject->attachShader(shaderObject);
3820}
3821
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003822const Workarounds &Context::getWorkarounds() const
3823{
3824 return mWorkarounds;
3825}
3826
Jamie Madillb0817d12016-11-01 15:48:31 -04003827void Context::copyBufferSubData(GLenum readTarget,
3828 GLenum writeTarget,
3829 GLintptr readOffset,
3830 GLintptr writeOffset,
3831 GLsizeiptr size)
3832{
3833 // if size is zero, the copy is a successful no-op
3834 if (size == 0)
3835 {
3836 return;
3837 }
3838
3839 // TODO(jmadill): cache these.
3840 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3841 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3842
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003843 handleError(writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size));
Jamie Madillb0817d12016-11-01 15:48:31 -04003844}
3845
Jamie Madill01a80ee2016-11-07 12:06:18 -05003846void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3847{
3848 Program *programObject = getProgram(program);
3849 // TODO(jmadill): Re-use this from the validation if possible.
3850 ASSERT(programObject);
3851 programObject->bindAttributeLocation(index, name);
3852}
3853
3854void Context::bindBuffer(GLenum target, GLuint buffer)
3855{
3856 switch (target)
3857 {
3858 case GL_ARRAY_BUFFER:
3859 bindArrayBuffer(buffer);
3860 break;
3861 case GL_ELEMENT_ARRAY_BUFFER:
3862 bindElementArrayBuffer(buffer);
3863 break;
3864 case GL_COPY_READ_BUFFER:
3865 bindCopyReadBuffer(buffer);
3866 break;
3867 case GL_COPY_WRITE_BUFFER:
3868 bindCopyWriteBuffer(buffer);
3869 break;
3870 case GL_PIXEL_PACK_BUFFER:
3871 bindPixelPackBuffer(buffer);
3872 break;
3873 case GL_PIXEL_UNPACK_BUFFER:
3874 bindPixelUnpackBuffer(buffer);
3875 break;
3876 case GL_UNIFORM_BUFFER:
3877 bindGenericUniformBuffer(buffer);
3878 break;
3879 case GL_TRANSFORM_FEEDBACK_BUFFER:
3880 bindGenericTransformFeedbackBuffer(buffer);
3881 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003882 case GL_ATOMIC_COUNTER_BUFFER:
Jiajia Qin6eafb042016-12-27 17:04:07 +08003883 bindGenericAtomicCounterBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003884 break;
3885 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08003886 bindGenericShaderStorageBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003887 break;
3888 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08003889 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003890 break;
3891 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003892 if (buffer != 0)
3893 {
3894 // Binding buffers to this binding point is not implemented yet.
3895 UNIMPLEMENTED();
3896 }
Geoff Lang3b573612016-10-31 14:08:10 -04003897 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05003898
3899 default:
3900 UNREACHABLE();
3901 break;
3902 }
3903}
3904
Jiajia Qin6eafb042016-12-27 17:04:07 +08003905void Context::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
3906{
3907 bindBufferRange(target, index, buffer, 0, 0);
3908}
3909
3910void Context::bindBufferRange(GLenum target,
3911 GLuint index,
3912 GLuint buffer,
3913 GLintptr offset,
3914 GLsizeiptr size)
3915{
3916 switch (target)
3917 {
3918 case GL_TRANSFORM_FEEDBACK_BUFFER:
3919 bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
3920 bindGenericTransformFeedbackBuffer(buffer);
3921 break;
3922 case GL_UNIFORM_BUFFER:
3923 bindIndexedUniformBuffer(buffer, index, offset, size);
3924 bindGenericUniformBuffer(buffer);
3925 break;
3926 case GL_ATOMIC_COUNTER_BUFFER:
3927 bindIndexedAtomicCounterBuffer(buffer, index, offset, size);
3928 bindGenericAtomicCounterBuffer(buffer);
3929 break;
3930 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08003931 bindIndexedShaderStorageBuffer(buffer, index, offset, size);
3932 bindGenericShaderStorageBuffer(buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08003933 break;
3934 default:
3935 UNREACHABLE();
3936 break;
3937 }
3938}
3939
Jamie Madill01a80ee2016-11-07 12:06:18 -05003940void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
3941{
3942 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3943 {
3944 bindReadFramebuffer(framebuffer);
3945 }
3946
3947 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3948 {
3949 bindDrawFramebuffer(framebuffer);
3950 }
3951}
3952
3953void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
3954{
3955 ASSERT(target == GL_RENDERBUFFER);
3956 Renderbuffer *object =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003957 mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
Jamie Madill01a80ee2016-11-07 12:06:18 -05003958 mGLState.setRenderbufferBinding(object);
3959}
3960
JiangYizhoubddc46b2016-12-09 09:50:51 +08003961void Context::texStorage2DMultisample(GLenum target,
3962 GLsizei samples,
3963 GLenum internalformat,
3964 GLsizei width,
3965 GLsizei height,
3966 GLboolean fixedsamplelocations)
3967{
3968 Extents size(width, height, 1);
3969 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003970 handleError(texture->setStorageMultisample(this, target, samples, internalformat, size,
JiangYizhoubddc46b2016-12-09 09:50:51 +08003971 fixedsamplelocations));
3972}
3973
3974void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
3975{
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003976 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
JiangYizhoubddc46b2016-12-09 09:50:51 +08003977 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
3978
3979 switch (pname)
3980 {
3981 case GL_SAMPLE_POSITION:
3982 handleError(framebuffer->getSamplePosition(index, val));
3983 break;
3984 default:
3985 UNREACHABLE();
3986 }
3987}
3988
Jamie Madille8fb6402017-02-14 17:56:40 -05003989void Context::renderbufferStorage(GLenum target,
3990 GLenum internalformat,
3991 GLsizei width,
3992 GLsizei height)
3993{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05003994 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
3995 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
3996
Jamie Madille8fb6402017-02-14 17:56:40 -05003997 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05003998 handleError(renderbuffer->setStorage(convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05003999}
4000
4001void Context::renderbufferStorageMultisample(GLenum target,
4002 GLsizei samples,
4003 GLenum internalformat,
4004 GLsizei width,
4005 GLsizei height)
4006{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004007 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4008 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
Jamie Madille8fb6402017-02-14 17:56:40 -05004009
4010 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004011 handleError(
4012 renderbuffer->setStorageMultisample(samples, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004013}
4014
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004015void Context::getSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)
4016{
4017 const FenceSync *syncObject = getFenceSync(sync);
Geoff Lang82483b92017-04-11 15:33:00 -04004018 handleError(QuerySynciv(syncObject, pname, bufSize, length, values));
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004019}
4020
JiangYizhoue18e6392017-02-20 10:32:23 +08004021void Context::getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
4022{
4023 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4024 QueryFramebufferParameteriv(framebuffer, pname, params);
4025}
4026
4027void Context::setFramebufferParameteri(GLenum target, GLenum pname, GLint param)
4028{
4029 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4030 SetFramebufferParameteri(framebuffer, pname, param);
4031}
4032
Jamie Madille14951e2017-03-09 18:55:16 -05004033Error Context::getScratchBuffer(size_t requestedSize, angle::MemoryBuffer **scratchBufferOut) const
4034{
4035 if (!mScratchBuffer.get(requestedSize, scratchBufferOut))
4036 {
4037 return gl::OutOfMemory() << "Failed to allocate internal buffer.";
4038 }
4039 return gl::NoError();
4040}
4041
Xinghua Cao2b396592017-03-29 15:36:04 +08004042void Context::dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ)
4043{
4044 if (numGroupsX == 0u || numGroupsY == 0u || numGroupsZ == 0u)
4045 {
4046 return;
4047 }
4048
4049 mImplementation->dispatchCompute(numGroupsX, numGroupsY, numGroupsZ);
4050}
4051
Jamie Madillc1d770e2017-04-13 17:31:24 -04004052GLenum Context::checkFramebufferStatus(GLenum target)
4053{
4054 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4055 ASSERT(framebuffer);
4056
4057 return framebuffer->checkStatus(this);
4058}
4059
4060void Context::compileShader(GLuint shader)
4061{
4062 Shader *shaderObject = GetValidShader(this, shader);
4063 if (!shaderObject)
4064 {
4065 return;
4066 }
4067 shaderObject->compile(this);
4068}
4069
4070void Context::deleteBuffers(GLsizei n, const GLuint *buffers)
4071{
4072 for (int i = 0; i < n; i++)
4073 {
4074 deleteBuffer(buffers[i]);
4075 }
4076}
4077
4078void Context::deleteFramebuffers(GLsizei n, const GLuint *framebuffers)
4079{
4080 for (int i = 0; i < n; i++)
4081 {
4082 if (framebuffers[i] != 0)
4083 {
4084 deleteFramebuffer(framebuffers[i]);
4085 }
4086 }
4087}
4088
4089void Context::deleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)
4090{
4091 for (int i = 0; i < n; i++)
4092 {
4093 deleteRenderbuffer(renderbuffers[i]);
4094 }
4095}
4096
4097void Context::deleteTextures(GLsizei n, const GLuint *textures)
4098{
4099 for (int i = 0; i < n; i++)
4100 {
4101 if (textures[i] != 0)
4102 {
4103 deleteTexture(textures[i]);
4104 }
4105 }
4106}
4107
4108void Context::detachShader(GLuint program, GLuint shader)
4109{
4110 Program *programObject = getProgram(program);
4111 ASSERT(programObject);
4112
4113 Shader *shaderObject = getShader(shader);
4114 ASSERT(shaderObject);
4115
4116 programObject->detachShader(this, shaderObject);
4117}
4118
4119void Context::genBuffers(GLsizei n, GLuint *buffers)
4120{
4121 for (int i = 0; i < n; i++)
4122 {
4123 buffers[i] = createBuffer();
4124 }
4125}
4126
4127void Context::genFramebuffers(GLsizei n, GLuint *framebuffers)
4128{
4129 for (int i = 0; i < n; i++)
4130 {
4131 framebuffers[i] = createFramebuffer();
4132 }
4133}
4134
4135void Context::genRenderbuffers(GLsizei n, GLuint *renderbuffers)
4136{
4137 for (int i = 0; i < n; i++)
4138 {
4139 renderbuffers[i] = createRenderbuffer();
4140 }
4141}
4142
4143void Context::genTextures(GLsizei n, GLuint *textures)
4144{
4145 for (int i = 0; i < n; i++)
4146 {
4147 textures[i] = createTexture();
4148 }
4149}
4150
4151void Context::getActiveAttrib(GLuint program,
4152 GLuint index,
4153 GLsizei bufsize,
4154 GLsizei *length,
4155 GLint *size,
4156 GLenum *type,
4157 GLchar *name)
4158{
4159 Program *programObject = getProgram(program);
4160 ASSERT(programObject);
4161 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
4162}
4163
4164void Context::getActiveUniform(GLuint program,
4165 GLuint index,
4166 GLsizei bufsize,
4167 GLsizei *length,
4168 GLint *size,
4169 GLenum *type,
4170 GLchar *name)
4171{
4172 Program *programObject = getProgram(program);
4173 ASSERT(programObject);
4174 programObject->getActiveUniform(index, bufsize, length, size, type, name);
4175}
4176
4177void Context::getAttachedShaders(GLuint program, GLsizei maxcount, GLsizei *count, GLuint *shaders)
4178{
4179 Program *programObject = getProgram(program);
4180 ASSERT(programObject);
4181 programObject->getAttachedShaders(maxcount, count, shaders);
4182}
4183
4184GLint Context::getAttribLocation(GLuint program, const GLchar *name)
4185{
4186 Program *programObject = getProgram(program);
4187 ASSERT(programObject);
4188 return programObject->getAttributeLocation(name);
4189}
4190
4191void Context::getBooleanv(GLenum pname, GLboolean *params)
4192{
4193 GLenum nativeType;
4194 unsigned int numParams = 0;
4195 getQueryParameterInfo(pname, &nativeType, &numParams);
4196
4197 if (nativeType == GL_BOOL)
4198 {
4199 getBooleanvImpl(pname, params);
4200 }
4201 else
4202 {
4203 CastStateValues(this, nativeType, pname, numParams, params);
4204 }
4205}
4206
4207void Context::getFloatv(GLenum pname, GLfloat *params)
4208{
4209 GLenum nativeType;
4210 unsigned int numParams = 0;
4211 getQueryParameterInfo(pname, &nativeType, &numParams);
4212
4213 if (nativeType == GL_FLOAT)
4214 {
4215 getFloatvImpl(pname, params);
4216 }
4217 else
4218 {
4219 CastStateValues(this, nativeType, pname, numParams, params);
4220 }
4221}
4222
4223void Context::getIntegerv(GLenum pname, GLint *params)
4224{
4225 GLenum nativeType;
4226 unsigned int numParams = 0;
4227 getQueryParameterInfo(pname, &nativeType, &numParams);
4228
4229 if (nativeType == GL_INT)
4230 {
4231 getIntegervImpl(pname, params);
4232 }
4233 else
4234 {
4235 CastStateValues(this, nativeType, pname, numParams, params);
4236 }
4237}
4238
4239void Context::getProgramiv(GLuint program, GLenum pname, GLint *params)
4240{
4241 Program *programObject = getProgram(program);
4242 ASSERT(programObject);
4243 QueryProgramiv(programObject, pname, params);
4244}
4245
4246void Context::getInfoLog(GLuint program, GLsizei bufsize, GLsizei *length, GLchar *infolog)
4247{
4248 Program *programObject = getProgram(program);
4249 ASSERT(programObject);
4250 programObject->getInfoLog(bufsize, length, infolog);
4251}
4252
4253void Context::getShaderiv(GLuint shader, GLenum pname, GLint *params)
4254{
4255 Shader *shaderObject = getShader(shader);
4256 ASSERT(shaderObject);
4257 QueryShaderiv(shaderObject, pname, params);
4258}
4259
4260void Context::getShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *infolog)
4261{
4262 Shader *shaderObject = getShader(shader);
4263 ASSERT(shaderObject);
4264 shaderObject->getInfoLog(bufsize, length, infolog);
4265}
4266
4267void Context::getShaderPrecisionFormat(GLenum shadertype,
4268 GLenum precisiontype,
4269 GLint *range,
4270 GLint *precision)
4271{
4272 // TODO(jmadill): Compute shaders.
4273
4274 switch (shadertype)
4275 {
4276 case GL_VERTEX_SHADER:
4277 switch (precisiontype)
4278 {
4279 case GL_LOW_FLOAT:
4280 mCaps.vertexLowpFloat.get(range, precision);
4281 break;
4282 case GL_MEDIUM_FLOAT:
4283 mCaps.vertexMediumpFloat.get(range, precision);
4284 break;
4285 case GL_HIGH_FLOAT:
4286 mCaps.vertexHighpFloat.get(range, precision);
4287 break;
4288
4289 case GL_LOW_INT:
4290 mCaps.vertexLowpInt.get(range, precision);
4291 break;
4292 case GL_MEDIUM_INT:
4293 mCaps.vertexMediumpInt.get(range, precision);
4294 break;
4295 case GL_HIGH_INT:
4296 mCaps.vertexHighpInt.get(range, precision);
4297 break;
4298
4299 default:
4300 UNREACHABLE();
4301 return;
4302 }
4303 break;
4304
4305 case GL_FRAGMENT_SHADER:
4306 switch (precisiontype)
4307 {
4308 case GL_LOW_FLOAT:
4309 mCaps.fragmentLowpFloat.get(range, precision);
4310 break;
4311 case GL_MEDIUM_FLOAT:
4312 mCaps.fragmentMediumpFloat.get(range, precision);
4313 break;
4314 case GL_HIGH_FLOAT:
4315 mCaps.fragmentHighpFloat.get(range, precision);
4316 break;
4317
4318 case GL_LOW_INT:
4319 mCaps.fragmentLowpInt.get(range, precision);
4320 break;
4321 case GL_MEDIUM_INT:
4322 mCaps.fragmentMediumpInt.get(range, precision);
4323 break;
4324 case GL_HIGH_INT:
4325 mCaps.fragmentHighpInt.get(range, precision);
4326 break;
4327
4328 default:
4329 UNREACHABLE();
4330 return;
4331 }
4332 break;
4333
4334 default:
4335 UNREACHABLE();
4336 return;
4337 }
4338}
4339
4340void Context::getShaderSource(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source)
4341{
4342 Shader *shaderObject = getShader(shader);
4343 ASSERT(shaderObject);
4344 shaderObject->getSource(bufsize, length, source);
4345}
4346
4347void Context::getUniformfv(GLuint program, GLint location, GLfloat *params)
4348{
4349 Program *programObject = getProgram(program);
4350 ASSERT(programObject);
4351 programObject->getUniformfv(location, params);
4352}
4353
4354void Context::getUniformiv(GLuint program, GLint location, GLint *params)
4355{
4356 Program *programObject = getProgram(program);
4357 ASSERT(programObject);
4358 programObject->getUniformiv(location, params);
4359}
4360
4361GLint Context::getUniformLocation(GLuint program, const GLchar *name)
4362{
4363 Program *programObject = getProgram(program);
4364 ASSERT(programObject);
4365 return programObject->getUniformLocation(name);
4366}
4367
4368GLboolean Context::isBuffer(GLuint buffer)
4369{
4370 if (buffer == 0)
4371 {
4372 return GL_FALSE;
4373 }
4374
4375 return (getBuffer(buffer) ? GL_TRUE : GL_FALSE);
4376}
4377
4378GLboolean Context::isEnabled(GLenum cap)
4379{
4380 return mGLState.getEnableFeature(cap);
4381}
4382
4383GLboolean Context::isFramebuffer(GLuint framebuffer)
4384{
4385 if (framebuffer == 0)
4386 {
4387 return GL_FALSE;
4388 }
4389
4390 return (getFramebuffer(framebuffer) ? GL_TRUE : GL_FALSE);
4391}
4392
4393GLboolean Context::isProgram(GLuint program)
4394{
4395 if (program == 0)
4396 {
4397 return GL_FALSE;
4398 }
4399
4400 return (getProgram(program) ? GL_TRUE : GL_FALSE);
4401}
4402
4403GLboolean Context::isRenderbuffer(GLuint renderbuffer)
4404{
4405 if (renderbuffer == 0)
4406 {
4407 return GL_FALSE;
4408 }
4409
4410 return (getRenderbuffer(renderbuffer) ? GL_TRUE : GL_FALSE);
4411}
4412
4413GLboolean Context::isShader(GLuint shader)
4414{
4415 if (shader == 0)
4416 {
4417 return GL_FALSE;
4418 }
4419
4420 return (getShader(shader) ? GL_TRUE : GL_FALSE);
4421}
4422
4423GLboolean Context::isTexture(GLuint texture)
4424{
4425 if (texture == 0)
4426 {
4427 return GL_FALSE;
4428 }
4429
4430 return (getTexture(texture) ? GL_TRUE : GL_FALSE);
4431}
4432
4433void Context::linkProgram(GLuint program)
4434{
4435 Program *programObject = getProgram(program);
4436 ASSERT(programObject);
4437 handleError(programObject->link(this));
4438}
4439
4440void Context::releaseShaderCompiler()
4441{
4442 handleError(mCompiler->release());
4443}
4444
4445void Context::shaderBinary(GLsizei n,
4446 const GLuint *shaders,
4447 GLenum binaryformat,
4448 const GLvoid *binary,
4449 GLsizei length)
4450{
4451 // No binary shader formats are supported.
4452 UNIMPLEMENTED();
4453}
4454
4455void Context::shaderSource(GLuint shader,
4456 GLsizei count,
4457 const GLchar *const *string,
4458 const GLint *length)
4459{
4460 Shader *shaderObject = getShader(shader);
4461 ASSERT(shaderObject);
4462 shaderObject->setSource(count, string, length);
4463}
4464
4465void Context::stencilFunc(GLenum func, GLint ref, GLuint mask)
4466{
4467 stencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
4468}
4469
4470void Context::stencilMask(GLuint mask)
4471{
4472 stencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4473}
4474
4475void Context::stencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4476{
4477 stencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4478}
4479
4480void Context::uniform1f(GLint location, GLfloat x)
4481{
4482 Program *program = mGLState.getProgram();
4483 program->setUniform1fv(location, 1, &x);
4484}
4485
4486void Context::uniform1fv(GLint location, GLsizei count, const GLfloat *v)
4487{
4488 Program *program = mGLState.getProgram();
4489 program->setUniform1fv(location, count, v);
4490}
4491
4492void Context::uniform1i(GLint location, GLint x)
4493{
4494 Program *program = mGLState.getProgram();
4495 program->setUniform1iv(location, 1, &x);
4496}
4497
4498void Context::uniform1iv(GLint location, GLsizei count, const GLint *v)
4499{
4500 Program *program = mGLState.getProgram();
4501 program->setUniform1iv(location, count, v);
4502}
4503
4504void Context::uniform2f(GLint location, GLfloat x, GLfloat y)
4505{
4506 GLfloat xy[2] = {x, y};
4507 Program *program = mGLState.getProgram();
4508 program->setUniform2fv(location, 1, xy);
4509}
4510
4511void Context::uniform2fv(GLint location, GLsizei count, const GLfloat *v)
4512{
4513 Program *program = mGLState.getProgram();
4514 program->setUniform2fv(location, count, v);
4515}
4516
4517void Context::uniform2i(GLint location, GLint x, GLint y)
4518{
4519 GLint xy[2] = {x, y};
4520 Program *program = mGLState.getProgram();
4521 program->setUniform2iv(location, 1, xy);
4522}
4523
4524void Context::uniform2iv(GLint location, GLsizei count, const GLint *v)
4525{
4526 Program *program = mGLState.getProgram();
4527 program->setUniform2iv(location, count, v);
4528}
4529
4530void Context::uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4531{
4532 GLfloat xyz[3] = {x, y, z};
4533 Program *program = mGLState.getProgram();
4534 program->setUniform3fv(location, 1, xyz);
4535}
4536
4537void Context::uniform3fv(GLint location, GLsizei count, const GLfloat *v)
4538{
4539 Program *program = mGLState.getProgram();
4540 program->setUniform3fv(location, count, v);
4541}
4542
4543void Context::uniform3i(GLint location, GLint x, GLint y, GLint z)
4544{
4545 GLint xyz[3] = {x, y, z};
4546 Program *program = mGLState.getProgram();
4547 program->setUniform3iv(location, 1, xyz);
4548}
4549
4550void Context::uniform3iv(GLint location, GLsizei count, const GLint *v)
4551{
4552 Program *program = mGLState.getProgram();
4553 program->setUniform3iv(location, count, v);
4554}
4555
4556void Context::uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4557{
4558 GLfloat xyzw[4] = {x, y, z, w};
4559 Program *program = mGLState.getProgram();
4560 program->setUniform4fv(location, 1, xyzw);
4561}
4562
4563void Context::uniform4fv(GLint location, GLsizei count, const GLfloat *v)
4564{
4565 Program *program = mGLState.getProgram();
4566 program->setUniform4fv(location, count, v);
4567}
4568
4569void Context::uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4570{
4571 GLint xyzw[4] = {x, y, z, w};
4572 Program *program = mGLState.getProgram();
4573 program->setUniform4iv(location, 1, xyzw);
4574}
4575
4576void Context::uniform4iv(GLint location, GLsizei count, const GLint *v)
4577{
4578 Program *program = mGLState.getProgram();
4579 program->setUniform4iv(location, count, v);
4580}
4581
4582void Context::uniformMatrix2fv(GLint location,
4583 GLsizei count,
4584 GLboolean transpose,
4585 const GLfloat *value)
4586{
4587 Program *program = mGLState.getProgram();
4588 program->setUniformMatrix2fv(location, count, transpose, value);
4589}
4590
4591void Context::uniformMatrix3fv(GLint location,
4592 GLsizei count,
4593 GLboolean transpose,
4594 const GLfloat *value)
4595{
4596 Program *program = mGLState.getProgram();
4597 program->setUniformMatrix3fv(location, count, transpose, value);
4598}
4599
4600void Context::uniformMatrix4fv(GLint location,
4601 GLsizei count,
4602 GLboolean transpose,
4603 const GLfloat *value)
4604{
4605 Program *program = mGLState.getProgram();
4606 program->setUniformMatrix4fv(location, count, transpose, value);
4607}
4608
4609void Context::validateProgram(GLuint program)
4610{
4611 Program *programObject = getProgram(program);
4612 ASSERT(programObject);
4613 programObject->validate(mCaps);
4614}
4615
Jamie Madillc29968b2016-01-20 11:17:23 -05004616} // namespace gl