blob: affc0087da554c79d05b69006533ab98a46bd04c [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 Madill675fe712016-12-19 13:07:54 -05001775void Context::drawElements(GLenum mode,
1776 GLsizei count,
1777 GLenum type,
1778 const GLvoid *indices,
1779 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001780{
Jamie Madill1b94d432015-08-07 13:23:23 -04001781 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001782 handleError(mImplementation->drawElements(mode, count, type, indices, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001783}
1784
Jamie Madill675fe712016-12-19 13:07:54 -05001785void Context::drawElementsInstanced(GLenum mode,
1786 GLsizei count,
1787 GLenum type,
1788 const GLvoid *indices,
1789 GLsizei instances,
1790 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001791{
1792 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001793 handleError(
1794 mImplementation->drawElementsInstanced(mode, count, type, indices, instances, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001795}
1796
Jamie Madill675fe712016-12-19 13:07:54 -05001797void Context::drawRangeElements(GLenum mode,
1798 GLuint start,
1799 GLuint end,
1800 GLsizei count,
1801 GLenum type,
1802 const GLvoid *indices,
1803 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001804{
1805 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001806 handleError(
1807 mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001808}
1809
Jiajia Qind9671222016-11-29 16:30:31 +08001810void Context::drawArraysIndirect(GLenum mode, const GLvoid *indirect)
1811{
1812 syncRendererState();
1813 handleError(mImplementation->drawArraysIndirect(mode, indirect));
1814}
1815
1816void Context::drawElementsIndirect(GLenum mode, GLenum type, const GLvoid *indirect)
1817{
1818 syncRendererState();
1819 handleError(mImplementation->drawElementsIndirect(mode, type, indirect));
1820}
1821
Jamie Madill675fe712016-12-19 13:07:54 -05001822void Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001823{
Jamie Madill675fe712016-12-19 13:07:54 -05001824 handleError(mImplementation->flush());
Geoff Lang129753a2015-01-09 16:52:09 -05001825}
1826
Jamie Madill675fe712016-12-19 13:07:54 -05001827void Context::finish()
Geoff Lang129753a2015-01-09 16:52:09 -05001828{
Jamie Madill675fe712016-12-19 13:07:54 -05001829 handleError(mImplementation->finish());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001830}
1831
Austin Kinross6ee1e782015-05-29 17:05:37 -07001832void Context::insertEventMarker(GLsizei length, const char *marker)
1833{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001834 ASSERT(mImplementation);
1835 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001836}
1837
1838void Context::pushGroupMarker(GLsizei length, const char *marker)
1839{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001840 ASSERT(mImplementation);
1841 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001842}
1843
1844void Context::popGroupMarker()
1845{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001846 ASSERT(mImplementation);
1847 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001848}
1849
Geoff Langd8605522016-04-13 10:19:12 -04001850void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1851{
1852 Program *programObject = getProgram(program);
1853 ASSERT(programObject);
1854
1855 programObject->bindUniformLocation(location, name);
1856}
1857
Sami Väisänena797e062016-05-12 15:23:40 +03001858void Context::setCoverageModulation(GLenum components)
1859{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001860 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001861}
1862
Sami Väisänene45e53b2016-05-25 10:36:04 +03001863void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1864{
1865 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1866}
1867
1868void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1869{
1870 GLfloat I[16];
1871 angle::Matrix<GLfloat>::setToIdentity(I);
1872
1873 mGLState.loadPathRenderingMatrix(matrixMode, I);
1874}
1875
1876void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1877{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001878 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001879 if (!pathObj)
1880 return;
1881
1882 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1883 syncRendererState();
1884
1885 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1886}
1887
1888void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1889{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001890 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001891 if (!pathObj)
1892 return;
1893
1894 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1895 syncRendererState();
1896
1897 mImplementation->stencilStrokePath(pathObj, reference, mask);
1898}
1899
1900void Context::coverFillPath(GLuint path, GLenum coverMode)
1901{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001902 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001903 if (!pathObj)
1904 return;
1905
1906 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1907 syncRendererState();
1908
1909 mImplementation->coverFillPath(pathObj, coverMode);
1910}
1911
1912void Context::coverStrokePath(GLuint path, GLenum coverMode)
1913{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001914 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001915 if (!pathObj)
1916 return;
1917
1918 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1919 syncRendererState();
1920
1921 mImplementation->coverStrokePath(pathObj, coverMode);
1922}
1923
1924void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1925{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001926 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001927 if (!pathObj)
1928 return;
1929
1930 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1931 syncRendererState();
1932
1933 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1934}
1935
1936void Context::stencilThenCoverStrokePath(GLuint path,
1937 GLint reference,
1938 GLuint mask,
1939 GLenum coverMode)
1940{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001941 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001942 if (!pathObj)
1943 return;
1944
1945 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1946 syncRendererState();
1947
1948 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1949}
1950
Sami Väisänend59ca052016-06-21 16:10:00 +03001951void Context::coverFillPathInstanced(GLsizei numPaths,
1952 GLenum pathNameType,
1953 const void *paths,
1954 GLuint pathBase,
1955 GLenum coverMode,
1956 GLenum transformType,
1957 const GLfloat *transformValues)
1958{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001959 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001960
1961 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1962 syncRendererState();
1963
1964 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1965}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001966
Sami Väisänend59ca052016-06-21 16:10:00 +03001967void Context::coverStrokePathInstanced(GLsizei numPaths,
1968 GLenum pathNameType,
1969 const void *paths,
1970 GLuint pathBase,
1971 GLenum coverMode,
1972 GLenum transformType,
1973 const GLfloat *transformValues)
1974{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001975 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001976
1977 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1978 syncRendererState();
1979
1980 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1981 transformValues);
1982}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001983
Sami Väisänend59ca052016-06-21 16:10:00 +03001984void Context::stencilFillPathInstanced(GLsizei numPaths,
1985 GLenum pathNameType,
1986 const void *paths,
1987 GLuint pathBase,
1988 GLenum fillMode,
1989 GLuint mask,
1990 GLenum transformType,
1991 const GLfloat *transformValues)
1992{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001993 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001994
1995 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1996 syncRendererState();
1997
1998 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1999 transformValues);
2000}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002001
Sami Väisänend59ca052016-06-21 16:10:00 +03002002void Context::stencilStrokePathInstanced(GLsizei numPaths,
2003 GLenum pathNameType,
2004 const void *paths,
2005 GLuint pathBase,
2006 GLint reference,
2007 GLuint mask,
2008 GLenum transformType,
2009 const GLfloat *transformValues)
2010{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002011 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002012
2013 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2014 syncRendererState();
2015
2016 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
2017 transformValues);
2018}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002019
Sami Väisänend59ca052016-06-21 16:10:00 +03002020void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
2021 GLenum pathNameType,
2022 const void *paths,
2023 GLuint pathBase,
2024 GLenum fillMode,
2025 GLuint mask,
2026 GLenum coverMode,
2027 GLenum transformType,
2028 const GLfloat *transformValues)
2029{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002030 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002031
2032 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2033 syncRendererState();
2034
2035 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
2036 transformType, transformValues);
2037}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002038
Sami Väisänend59ca052016-06-21 16:10:00 +03002039void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
2040 GLenum pathNameType,
2041 const void *paths,
2042 GLuint pathBase,
2043 GLint reference,
2044 GLuint mask,
2045 GLenum coverMode,
2046 GLenum transformType,
2047 const GLfloat *transformValues)
2048{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002049 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002050
2051 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2052 syncRendererState();
2053
2054 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
2055 transformType, transformValues);
2056}
2057
Sami Väisänen46eaa942016-06-29 10:26:37 +03002058void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
2059{
2060 auto *programObject = getProgram(program);
2061
2062 programObject->bindFragmentInputLocation(location, name);
2063}
2064
2065void Context::programPathFragmentInputGen(GLuint program,
2066 GLint location,
2067 GLenum genMode,
2068 GLint components,
2069 const GLfloat *coeffs)
2070{
2071 auto *programObject = getProgram(program);
2072
2073 programObject->pathFragmentInputGen(location, genMode, components, coeffs);
2074}
2075
jchen1015015f72017-03-16 13:54:21 +08002076GLuint Context::getProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name)
2077{
jchen10fd7c3b52017-03-21 15:36:03 +08002078 const auto *programObject = getProgram(program);
jchen1015015f72017-03-16 13:54:21 +08002079 return QueryProgramResourceIndex(programObject, programInterface, name);
2080}
2081
jchen10fd7c3b52017-03-21 15:36:03 +08002082void Context::getProgramResourceName(GLuint program,
2083 GLenum programInterface,
2084 GLuint index,
2085 GLsizei bufSize,
2086 GLsizei *length,
2087 GLchar *name)
2088{
2089 const auto *programObject = getProgram(program);
2090 QueryProgramResourceName(programObject, programInterface, index, bufSize, length, name);
2091}
2092
Jamie Madill437fa652016-05-03 15:13:24 -04002093void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002094{
Geoff Langda5777c2014-07-11 09:52:58 -04002095 if (error.isError())
2096 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002097 GLenum code = error.getCode();
2098 mErrors.insert(code);
2099 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
2100 {
2101 markContextLost();
2102 }
Geoff Lang70d0f492015-12-10 17:45:46 -05002103
2104 if (!error.getMessage().empty())
2105 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002106 auto *debug = &mGLState.getDebug();
2107 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
2108 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05002109 }
Geoff Langda5777c2014-07-11 09:52:58 -04002110 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002111}
2112
2113// Get one of the recorded errors and clear its flag, if any.
2114// [OpenGL ES 2.0.24] section 2.5 page 13.
2115GLenum Context::getError()
2116{
Geoff Langda5777c2014-07-11 09:52:58 -04002117 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002118 {
Geoff Langda5777c2014-07-11 09:52:58 -04002119 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002120 }
Geoff Langda5777c2014-07-11 09:52:58 -04002121 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002122 {
Geoff Langda5777c2014-07-11 09:52:58 -04002123 GLenum error = *mErrors.begin();
2124 mErrors.erase(mErrors.begin());
2125 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002126 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002127}
2128
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002129// NOTE: this function should not assume that this context is current!
2130void Context::markContextLost()
2131{
2132 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002133 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002134 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002135 mContextLostForced = true;
2136 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002137 mContextLost = true;
2138}
2139
2140bool Context::isContextLost()
2141{
2142 return mContextLost;
2143}
2144
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002145GLenum Context::getResetStatus()
2146{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002147 // Even if the application doesn't want to know about resets, we want to know
2148 // as it will allow us to skip all the calls.
2149 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002150 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002151 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002152 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002153 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002154 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002155
2156 // EXT_robustness, section 2.6: If the reset notification behavior is
2157 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2158 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2159 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002160 }
2161
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002162 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2163 // status should be returned at least once, and GL_NO_ERROR should be returned
2164 // once the device has finished resetting.
2165 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002166 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002167 ASSERT(mResetStatus == GL_NO_ERROR);
2168 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002169
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002170 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002171 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002172 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002173 }
2174 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002175 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002176 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002177 // If markContextLost was used to mark the context lost then
2178 // assume that is not recoverable, and continue to report the
2179 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002180 mResetStatus = mImplementation->getResetStatus();
2181 }
Jamie Madill893ab082014-05-16 16:56:10 -04002182
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002183 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002184}
2185
2186bool Context::isResetNotificationEnabled()
2187{
2188 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2189}
2190
Corentin Walleze3b10e82015-05-20 11:06:25 -04002191const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002192{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002193 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002194}
2195
2196EGLenum Context::getClientType() const
2197{
2198 return mClientType;
2199}
2200
2201EGLenum Context::getRenderBuffer() const
2202{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002203 const Framebuffer *framebuffer = mState.mFramebuffers->getFramebuffer(0);
2204 if (framebuffer == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -04002205 {
2206 return EGL_NONE;
2207 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002208
2209 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2210 ASSERT(backAttachment != nullptr);
2211 return backAttachment->getSurface()->getRenderBuffer();
Régis Fénéon83107972015-02-05 12:57:44 +01002212}
2213
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002214VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002215{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002216 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002217 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2218 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002219 {
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002220 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle,
2221 mCaps.maxVertexAttributes, mCaps.maxVertexAttribBindings);
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002222
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002223 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002224 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002225
2226 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002227}
2228
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002229TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002230{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002231 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002232 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2233 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002234 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002235 transformFeedback =
2236 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002237 transformFeedback->addRef();
2238 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002239 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002240
2241 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002242}
2243
2244bool Context::isVertexArrayGenerated(GLuint vertexArray)
2245{
Geoff Langf41a7152016-09-19 15:11:17 -04002246 ASSERT(mVertexArrayMap.find(0) != mVertexArrayMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002247 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
2248}
2249
2250bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2251{
Geoff Langf41a7152016-09-19 15:11:17 -04002252 ASSERT(mTransformFeedbackMap.find(0) != mTransformFeedbackMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002253 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
2254}
2255
Shannon Woods53a94a82014-06-24 15:20:36 -04002256void Context::detachTexture(GLuint texture)
2257{
2258 // Simple pass-through to State's detachTexture method, as textures do not require
2259 // allocation map management either here or in the resource manager at detach time.
2260 // Zero textures are held by the Context, and we don't attempt to request them from
2261 // the State.
Jamie Madilla02315b2017-02-23 14:14:47 -05002262 mGLState.detachTexture(this, mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002263}
2264
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002265void Context::detachBuffer(GLuint buffer)
2266{
Yuly Novikov5807a532015-12-03 13:01:22 -05002267 // Simple pass-through to State's detachBuffer method, since
2268 // only buffer attachments to container objects that are bound to the current context
2269 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002270
Yuly Novikov5807a532015-12-03 13:01:22 -05002271 // [OpenGL ES 3.2] section 5.1.2 page 45:
2272 // Attachments to unbound container objects, such as
2273 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2274 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002275 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002276}
2277
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002278void Context::detachFramebuffer(GLuint framebuffer)
2279{
Shannon Woods53a94a82014-06-24 15:20:36 -04002280 // Framebuffer detachment is handled by Context, because 0 is a valid
2281 // Framebuffer object, and a pointer to it must be passed from Context
2282 // to State at binding time.
2283
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002284 // [OpenGL ES 2.0.24] section 4.4 page 107:
2285 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2286 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2287
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002288 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002289 {
2290 bindReadFramebuffer(0);
2291 }
2292
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002293 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002294 {
2295 bindDrawFramebuffer(0);
2296 }
2297}
2298
2299void Context::detachRenderbuffer(GLuint renderbuffer)
2300{
Jamie Madilla02315b2017-02-23 14:14:47 -05002301 mGLState.detachRenderbuffer(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002302}
2303
Jamie Madill57a89722013-07-02 11:57:03 -04002304void Context::detachVertexArray(GLuint vertexArray)
2305{
Jamie Madill77a72f62015-04-14 11:18:32 -04002306 // Vertex array detachment is handled by Context, because 0 is a valid
2307 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002308 // binding time.
2309
Jamie Madill57a89722013-07-02 11:57:03 -04002310 // [OpenGL ES 3.0.2] section 2.10 page 43:
2311 // If a vertex array object that is currently bound is deleted, the binding
2312 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002313 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002314 {
2315 bindVertexArray(0);
2316 }
2317}
2318
Geoff Langc8058452014-02-03 12:04:11 -05002319void Context::detachTransformFeedback(GLuint transformFeedback)
2320{
Corentin Walleza2257da2016-04-19 16:43:12 -04002321 // Transform feedback detachment is handled by Context, because 0 is a valid
2322 // transform feedback, and a pointer to it must be passed from Context to State at
2323 // binding time.
2324
2325 // The OpenGL specification doesn't mention what should happen when the currently bound
2326 // transform feedback object is deleted. Since it is a container object, we treat it like
2327 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002328 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002329 {
2330 bindTransformFeedback(0);
2331 }
Geoff Langc8058452014-02-03 12:04:11 -05002332}
2333
Jamie Madilldc356042013-07-19 16:36:57 -04002334void Context::detachSampler(GLuint sampler)
2335{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002336 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002337}
2338
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002339void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2340{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002341 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002342}
2343
Jamie Madille29d1672013-07-19 16:36:57 -04002344void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2345{
Geoff Langc1984ed2016-10-07 12:41:00 -04002346 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002347 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002348 SetSamplerParameteri(samplerObject, pname, param);
2349}
Jamie Madille29d1672013-07-19 16:36:57 -04002350
Geoff Langc1984ed2016-10-07 12:41:00 -04002351void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2352{
2353 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002354 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002355 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002356}
2357
2358void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2359{
Geoff Langc1984ed2016-10-07 12:41:00 -04002360 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002361 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002362 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002363}
2364
Geoff Langc1984ed2016-10-07 12:41:00 -04002365void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002366{
Geoff Langc1984ed2016-10-07 12:41:00 -04002367 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002368 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002369 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002370}
2371
Geoff Langc1984ed2016-10-07 12:41:00 -04002372void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002373{
Geoff Langc1984ed2016-10-07 12:41:00 -04002374 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002375 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002376 QuerySamplerParameteriv(samplerObject, pname, params);
2377}
Jamie Madill9675b802013-07-19 16:36:59 -04002378
Geoff Langc1984ed2016-10-07 12:41:00 -04002379void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2380{
2381 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002382 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002383 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002384}
2385
Olli Etuahof0fee072016-03-30 15:11:58 +03002386void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2387{
2388 gl::Program *programObject = getProgram(program);
Yunchao He61afff12017-03-14 15:34:03 +08002389 SetProgramParameteri(programObject, pname, value);
Olli Etuahof0fee072016-03-30 15:11:58 +03002390}
2391
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002392void Context::initRendererString()
2393{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002394 std::ostringstream rendererString;
2395 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002396 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002397 rendererString << ")";
2398
Geoff Langcec35902014-04-16 10:52:36 -04002399 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002400}
2401
Geoff Langc339c4e2016-11-29 10:37:36 -05002402void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002403{
Geoff Langc339c4e2016-11-29 10:37:36 -05002404 const Version &clientVersion = getClientVersion();
2405
2406 std::ostringstream versionString;
2407 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2408 << ANGLE_VERSION_STRING << ")";
2409 mVersionString = MakeStaticString(versionString.str());
2410
2411 std::ostringstream shadingLanguageVersionString;
2412 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2413 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2414 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2415 << ")";
2416 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002417}
2418
Geoff Langcec35902014-04-16 10:52:36 -04002419void Context::initExtensionStrings()
2420{
Geoff Langc339c4e2016-11-29 10:37:36 -05002421 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2422 std::ostringstream combinedStringStream;
2423 std::copy(strings.begin(), strings.end(),
2424 std::ostream_iterator<const char *>(combinedStringStream, " "));
2425 return MakeStaticString(combinedStringStream.str());
2426 };
2427
2428 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002429 for (const auto &extensionString : mExtensions.getStrings())
2430 {
2431 mExtensionStrings.push_back(MakeStaticString(extensionString));
2432 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002433 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002434
Bryan Bernhart58806562017-01-05 13:09:31 -08002435 const gl::Extensions &nativeExtensions = mImplementation->getNativeExtensions();
2436
Geoff Langc339c4e2016-11-29 10:37:36 -05002437 mRequestableExtensionStrings.clear();
2438 for (const auto &extensionInfo : GetExtensionInfoMap())
2439 {
2440 if (extensionInfo.second.Requestable &&
Bryan Bernhart58806562017-01-05 13:09:31 -08002441 !(mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
2442 nativeExtensions.*(extensionInfo.second.ExtensionsMember))
Geoff Langc339c4e2016-11-29 10:37:36 -05002443 {
2444 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2445 }
2446 }
2447 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002448}
2449
Geoff Langc339c4e2016-11-29 10:37:36 -05002450const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002451{
Geoff Langc339c4e2016-11-29 10:37:36 -05002452 switch (name)
2453 {
2454 case GL_VENDOR:
2455 return reinterpret_cast<const GLubyte *>("Google Inc.");
2456
2457 case GL_RENDERER:
2458 return reinterpret_cast<const GLubyte *>(mRendererString);
2459
2460 case GL_VERSION:
2461 return reinterpret_cast<const GLubyte *>(mVersionString);
2462
2463 case GL_SHADING_LANGUAGE_VERSION:
2464 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2465
2466 case GL_EXTENSIONS:
2467 return reinterpret_cast<const GLubyte *>(mExtensionString);
2468
2469 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2470 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2471
2472 default:
2473 UNREACHABLE();
2474 return nullptr;
2475 }
Geoff Langcec35902014-04-16 10:52:36 -04002476}
2477
Geoff Langc339c4e2016-11-29 10:37:36 -05002478const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002479{
Geoff Langc339c4e2016-11-29 10:37:36 -05002480 switch (name)
2481 {
2482 case GL_EXTENSIONS:
2483 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2484
2485 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2486 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2487
2488 default:
2489 UNREACHABLE();
2490 return nullptr;
2491 }
Geoff Langcec35902014-04-16 10:52:36 -04002492}
2493
2494size_t Context::getExtensionStringCount() const
2495{
2496 return mExtensionStrings.size();
2497}
2498
Geoff Langc339c4e2016-11-29 10:37:36 -05002499void Context::requestExtension(const char *name)
2500{
2501 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2502 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2503 const auto &extension = extensionInfos.at(name);
2504 ASSERT(extension.Requestable);
2505
2506 if (mExtensions.*(extension.ExtensionsMember))
2507 {
2508 // Extension already enabled
2509 return;
2510 }
2511
2512 mExtensions.*(extension.ExtensionsMember) = true;
2513 updateCaps();
2514 initExtensionStrings();
Bryan Bernhart58806562017-01-05 13:09:31 -08002515
2516 // Re-create the compiler with the requested extensions enabled.
2517 SafeDelete(mCompiler);
2518 mCompiler = new Compiler(mImplementation.get(), mState);
Geoff Lang9aded172017-04-05 11:07:56 -04002519
2520 // Invalidate all cached completenesses for textures and framebuffer. Some extensions make new
2521 // formats renderable or sampleable.
2522 mState.mTextures->invalidateTextureComplenessCache();
2523 for (auto &zeroTexture : mZeroTextures)
2524 {
2525 zeroTexture.second->invalidateCompletenessCache();
2526 }
2527
2528 mState.mFramebuffers->invalidateFramebufferComplenessCache();
Geoff Langc339c4e2016-11-29 10:37:36 -05002529}
2530
2531size_t Context::getRequestableExtensionStringCount() const
2532{
2533 return mRequestableExtensionStrings.size();
2534}
2535
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002536void Context::beginTransformFeedback(GLenum primitiveMode)
2537{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002538 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002539 ASSERT(transformFeedback != nullptr);
2540 ASSERT(!transformFeedback->isPaused());
2541
Jamie Madill6c1f6712017-02-14 19:08:04 -05002542 transformFeedback->begin(this, primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002543}
2544
2545bool Context::hasActiveTransformFeedback(GLuint program) const
2546{
2547 for (auto pair : mTransformFeedbackMap)
2548 {
2549 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2550 {
2551 return true;
2552 }
2553 }
2554 return false;
2555}
2556
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002557void Context::initCaps(const egl::DisplayExtensions &displayExtensions)
Geoff Lang493daf52014-07-03 13:38:44 -04002558{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002559 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002560
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002561 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002562
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002563 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002564
Geoff Langeb66a6e2016-10-31 13:06:12 -04002565 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002566 {
2567 // Disable ES3+ extensions
2568 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002569 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002570 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002571 }
2572
Geoff Langeb66a6e2016-10-31 13:06:12 -04002573 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002574 {
2575 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2576 //mExtensions.sRGB = false;
2577 }
2578
Jamie Madill00ed7a12016-05-19 13:13:38 -04002579 // Some extensions are always available because they are implemented in the GL layer.
2580 mExtensions.bindUniformLocation = true;
2581 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002582 mExtensions.bindGeneratesResource = true;
Geoff Langfeb8c682017-02-13 16:07:35 -05002583 mExtensions.clientArrays = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002584 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002585
2586 // Enable the no error extension if the context was created with the flag.
2587 mExtensions.noError = mSkipValidation;
2588
Corentin Wallezccab69d2017-01-27 16:57:15 -05002589 // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
Corentin Wallezc295e512017-01-27 17:47:50 -05002590 mExtensions.surfacelessContext = displayExtensions.surfacelessContext;
Corentin Wallezccab69d2017-01-27 16:57:15 -05002591
Geoff Lang70d0f492015-12-10 17:45:46 -05002592 // Explicitly enable GL_KHR_debug
2593 mExtensions.debug = true;
2594 mExtensions.maxDebugMessageLength = 1024;
2595 mExtensions.maxDebugLoggedMessages = 1024;
2596 mExtensions.maxDebugGroupStackDepth = 1024;
2597 mExtensions.maxLabelLength = 1024;
2598
Geoff Langff5b2d52016-09-07 11:32:23 -04002599 // Explicitly enable GL_ANGLE_robust_client_memory
2600 mExtensions.robustClientMemory = true;
2601
Jamie Madille08a1d32017-03-07 17:24:06 -05002602 // Determine robust resource init availability from EGL.
2603 mExtensions.robustResourceInitialization =
2604 displayExtensions.createContextRobustResourceInitialization;
2605
Geoff Lang301d1612014-07-09 10:34:37 -04002606 // Apply implementation limits
2607 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002608 mCaps.maxVertexAttribBindings =
2609 getClientVersion() < ES_3_1
2610 ? mCaps.maxVertexAttributes
2611 : std::min<GLuint>(mCaps.maxVertexAttribBindings, MAX_VERTEX_ATTRIB_BINDINGS);
2612
Geoff Lang301d1612014-07-09 10:34:37 -04002613 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2614 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2615
2616 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002617
Geoff Langc287ea62016-09-16 14:46:51 -04002618 // WebGL compatibility
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002619 mExtensions.webglCompatibility = mWebGLContext;
Geoff Langc287ea62016-09-16 14:46:51 -04002620 for (const auto &extensionInfo : GetExtensionInfoMap())
2621 {
2622 // If this context is for WebGL, disable all enableable extensions
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002623 if (mWebGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002624 {
2625 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2626 }
2627 }
2628
2629 // Generate texture caps
2630 updateCaps();
2631}
2632
2633void Context::updateCaps()
2634{
Geoff Lang900013c2014-07-07 11:32:19 -04002635 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002636 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002637
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002638 for (auto capsIt : mImplementation->getNativeTextureCaps())
Geoff Lang493daf52014-07-03 13:38:44 -04002639 {
Geoff Langca271392017-04-05 12:30:00 -04002640 GLenum sizedInternalFormat = capsIt.first;
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002641 TextureCaps formatCaps = capsIt.second;
Geoff Lang493daf52014-07-03 13:38:44 -04002642
Geoff Langca271392017-04-05 12:30:00 -04002643 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002644
Geoff Lang0d8b7242015-09-09 14:56:53 -04002645 // Update the format caps based on the client version and extensions.
2646 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2647 // ES3.
2648 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002649 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002650 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002651 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002652 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002653 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002654
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002655 // OpenGL ES does not support multisampling with non-rendererable formats
2656 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
2657 if (!formatInfo.renderSupport ||
2658 (getClientVersion() < ES_3_1 &&
2659 (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
Geoff Lang493daf52014-07-03 13:38:44 -04002660 {
Geoff Langd87878e2014-09-19 15:42:59 -04002661 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002662 }
Geoff Langd87878e2014-09-19 15:42:59 -04002663
2664 if (formatCaps.texturable && formatInfo.compressed)
2665 {
Geoff Langca271392017-04-05 12:30:00 -04002666 mCaps.compressedTextureFormats.push_back(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002667 }
2668
Geoff Langca271392017-04-05 12:30:00 -04002669 mTextureCaps.insert(sizedInternalFormat, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002670 }
2671}
2672
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002673void Context::initWorkarounds()
2674{
2675 // Lose the context upon out of memory error if the application is
2676 // expecting to watch for those events.
2677 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2678}
2679
Jamie Madill1b94d432015-08-07 13:23:23 -04002680void Context::syncRendererState()
2681{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002682 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
Frank Henigman5a53d542017-02-16 21:24:10 -05002683 mImplementation->syncState(dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002684 mGLState.clearDirtyBits();
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002685 mGLState.syncDirtyObjects(this);
Jamie Madill1b94d432015-08-07 13:23:23 -04002686}
2687
Jamie Madillad9f24e2016-02-12 09:27:24 -05002688void Context::syncRendererState(const State::DirtyBits &bitMask,
2689 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002690{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002691 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
Frank Henigman5a53d542017-02-16 21:24:10 -05002692 mImplementation->syncState(dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002693 mGLState.clearDirtyBits(dirtyBits);
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002694 mGLState.syncDirtyObjects(this, objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002695}
Jamie Madillc29968b2016-01-20 11:17:23 -05002696
2697void Context::blitFramebuffer(GLint srcX0,
2698 GLint srcY0,
2699 GLint srcX1,
2700 GLint srcY1,
2701 GLint dstX0,
2702 GLint dstY0,
2703 GLint dstX1,
2704 GLint dstY1,
2705 GLbitfield mask,
2706 GLenum filter)
2707{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002708 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002709 ASSERT(drawFramebuffer);
2710
2711 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2712 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2713
Jamie Madillad9f24e2016-02-12 09:27:24 -05002714 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002715
Jamie Madill8415b5f2016-04-26 13:41:39 -04002716 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002717}
Jamie Madillc29968b2016-01-20 11:17:23 -05002718
2719void Context::clear(GLbitfield mask)
2720{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002721 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002722 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002723}
2724
2725void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2726{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002727 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002728 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2729 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002730}
2731
2732void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2733{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002734 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002735 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2736 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002737}
2738
2739void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2740{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002741 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002742 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2743 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002744}
2745
2746void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2747{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002748 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002749 ASSERT(framebufferObject);
2750
2751 // If a buffer is not present, the clear has no effect
2752 if (framebufferObject->getDepthbuffer() == nullptr &&
2753 framebufferObject->getStencilbuffer() == nullptr)
2754 {
2755 return;
2756 }
2757
Jamie Madillad9f24e2016-02-12 09:27:24 -05002758 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002759 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2760 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002761}
2762
2763void Context::readPixels(GLint x,
2764 GLint y,
2765 GLsizei width,
2766 GLsizei height,
2767 GLenum format,
2768 GLenum type,
2769 GLvoid *pixels)
2770{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002771 if (width == 0 || height == 0)
2772 {
2773 return;
2774 }
2775
Jamie Madillad9f24e2016-02-12 09:27:24 -05002776 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002777
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002778 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002779 ASSERT(framebufferObject);
2780
2781 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002782 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002783}
2784
2785void Context::copyTexImage2D(GLenum target,
2786 GLint level,
2787 GLenum internalformat,
2788 GLint x,
2789 GLint y,
2790 GLsizei width,
2791 GLsizei height,
2792 GLint border)
2793{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002794 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002795 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002796
Jamie Madillc29968b2016-01-20 11:17:23 -05002797 Rectangle sourceArea(x, y, width, height);
2798
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002799 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002800 Texture *texture =
2801 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002802 handleError(texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002803}
2804
2805void Context::copyTexSubImage2D(GLenum target,
2806 GLint level,
2807 GLint xoffset,
2808 GLint yoffset,
2809 GLint x,
2810 GLint y,
2811 GLsizei width,
2812 GLsizei height)
2813{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002814 if (width == 0 || height == 0)
2815 {
2816 return;
2817 }
2818
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002819 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002820 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002821
Jamie Madillc29968b2016-01-20 11:17:23 -05002822 Offset destOffset(xoffset, yoffset, 0);
2823 Rectangle sourceArea(x, y, width, height);
2824
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002825 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002826 Texture *texture =
2827 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002828 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002829}
2830
2831void Context::copyTexSubImage3D(GLenum target,
2832 GLint level,
2833 GLint xoffset,
2834 GLint yoffset,
2835 GLint zoffset,
2836 GLint x,
2837 GLint y,
2838 GLsizei width,
2839 GLsizei height)
2840{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002841 if (width == 0 || height == 0)
2842 {
2843 return;
2844 }
2845
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002846 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002847 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002848
Jamie Madillc29968b2016-01-20 11:17:23 -05002849 Offset destOffset(xoffset, yoffset, zoffset);
2850 Rectangle sourceArea(x, y, width, height);
2851
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002852 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002853 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002854 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002855}
2856
2857void Context::framebufferTexture2D(GLenum target,
2858 GLenum attachment,
2859 GLenum textarget,
2860 GLuint texture,
2861 GLint level)
2862{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002863 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002864 ASSERT(framebuffer);
2865
2866 if (texture != 0)
2867 {
2868 Texture *textureObj = getTexture(texture);
2869
2870 ImageIndex index = ImageIndex::MakeInvalid();
2871
2872 if (textarget == GL_TEXTURE_2D)
2873 {
2874 index = ImageIndex::Make2D(level);
2875 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08002876 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
2877 {
2878 ASSERT(level == 0);
2879 index = ImageIndex::Make2DMultisample();
2880 }
Jamie Madillc29968b2016-01-20 11:17:23 -05002881 else
2882 {
2883 ASSERT(IsCubeMapTextureTarget(textarget));
2884 index = ImageIndex::MakeCube(textarget, level);
2885 }
2886
Jamie Madilla02315b2017-02-23 14:14:47 -05002887 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
Jamie Madillc29968b2016-01-20 11:17:23 -05002888 }
2889 else
2890 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002891 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002892 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002893
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002894 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002895}
2896
2897void Context::framebufferRenderbuffer(GLenum target,
2898 GLenum attachment,
2899 GLenum renderbuffertarget,
2900 GLuint renderbuffer)
2901{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002902 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002903 ASSERT(framebuffer);
2904
2905 if (renderbuffer != 0)
2906 {
2907 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
Jamie Madilla02315b2017-02-23 14:14:47 -05002908
2909 framebuffer->setAttachment(this, GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
Jamie Madillc29968b2016-01-20 11:17:23 -05002910 renderbufferObject);
2911 }
2912 else
2913 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002914 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002915 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002916
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002917 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002918}
2919
2920void Context::framebufferTextureLayer(GLenum target,
2921 GLenum attachment,
2922 GLuint texture,
2923 GLint level,
2924 GLint layer)
2925{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002926 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002927 ASSERT(framebuffer);
2928
2929 if (texture != 0)
2930 {
2931 Texture *textureObject = getTexture(texture);
2932
2933 ImageIndex index = ImageIndex::MakeInvalid();
2934
2935 if (textureObject->getTarget() == GL_TEXTURE_3D)
2936 {
2937 index = ImageIndex::Make3D(level, layer);
2938 }
2939 else
2940 {
2941 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2942 index = ImageIndex::Make2DArray(level, layer);
2943 }
2944
Jamie Madilla02315b2017-02-23 14:14:47 -05002945 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObject);
Jamie Madillc29968b2016-01-20 11:17:23 -05002946 }
2947 else
2948 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002949 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002950 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002951
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002952 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002953}
2954
2955void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2956{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002957 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002958 ASSERT(framebuffer);
2959 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002960 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002961}
2962
2963void Context::readBuffer(GLenum mode)
2964{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002965 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002966 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002967 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002968}
2969
2970void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2971{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002972 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002973 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002974
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002975 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002976 ASSERT(framebuffer);
2977
2978 // The specification isn't clear what should be done when the framebuffer isn't complete.
2979 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002980 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002981}
2982
2983void Context::invalidateFramebuffer(GLenum target,
2984 GLsizei numAttachments,
2985 const GLenum *attachments)
2986{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002987 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002988 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002989
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002990 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002991 ASSERT(framebuffer);
2992
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002993 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002994 {
Jamie Madill437fa652016-05-03 15:13:24 -04002995 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002996 }
Jamie Madill437fa652016-05-03 15:13:24 -04002997
2998 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002999}
3000
3001void Context::invalidateSubFramebuffer(GLenum target,
3002 GLsizei numAttachments,
3003 const GLenum *attachments,
3004 GLint x,
3005 GLint y,
3006 GLsizei width,
3007 GLsizei height)
3008{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003009 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003010 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003011
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003012 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003013 ASSERT(framebuffer);
3014
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003015 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003016 {
Jamie Madill437fa652016-05-03 15:13:24 -04003017 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003018 }
Jamie Madill437fa652016-05-03 15:13:24 -04003019
3020 Rectangle area(x, y, width, height);
3021 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05003022}
3023
Jamie Madill73a84962016-02-12 09:27:23 -05003024void Context::texImage2D(GLenum target,
3025 GLint level,
3026 GLint internalformat,
3027 GLsizei width,
3028 GLsizei height,
3029 GLint border,
3030 GLenum format,
3031 GLenum type,
3032 const GLvoid *pixels)
3033{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003034 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003035
3036 Extents size(width, height, 1);
3037 Texture *texture =
3038 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003039 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3040 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003041}
3042
3043void Context::texImage3D(GLenum target,
3044 GLint level,
3045 GLint internalformat,
3046 GLsizei width,
3047 GLsizei height,
3048 GLsizei depth,
3049 GLint border,
3050 GLenum format,
3051 GLenum type,
3052 const GLvoid *pixels)
3053{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003054 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003055
3056 Extents size(width, height, depth);
3057 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003058 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3059 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003060}
3061
3062void Context::texSubImage2D(GLenum target,
3063 GLint level,
3064 GLint xoffset,
3065 GLint yoffset,
3066 GLsizei width,
3067 GLsizei height,
3068 GLenum format,
3069 GLenum type,
3070 const GLvoid *pixels)
3071{
3072 // Zero sized uploads are valid but no-ops
3073 if (width == 0 || height == 0)
3074 {
3075 return;
3076 }
3077
Jamie Madillad9f24e2016-02-12 09:27:24 -05003078 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003079
3080 Box area(xoffset, yoffset, 0, width, height, 1);
3081 Texture *texture =
3082 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003083 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3084 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003085}
3086
3087void Context::texSubImage3D(GLenum target,
3088 GLint level,
3089 GLint xoffset,
3090 GLint yoffset,
3091 GLint zoffset,
3092 GLsizei width,
3093 GLsizei height,
3094 GLsizei depth,
3095 GLenum format,
3096 GLenum type,
3097 const GLvoid *pixels)
3098{
3099 // Zero sized uploads are valid but no-ops
3100 if (width == 0 || height == 0 || depth == 0)
3101 {
3102 return;
3103 }
3104
Jamie Madillad9f24e2016-02-12 09:27:24 -05003105 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003106
3107 Box area(xoffset, yoffset, zoffset, width, height, depth);
3108 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003109 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3110 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003111}
3112
3113void Context::compressedTexImage2D(GLenum target,
3114 GLint level,
3115 GLenum internalformat,
3116 GLsizei width,
3117 GLsizei height,
3118 GLint border,
3119 GLsizei imageSize,
3120 const GLvoid *data)
3121{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003122 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003123
3124 Extents size(width, height, 1);
3125 Texture *texture =
3126 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003127 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003128 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003129 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003130}
3131
3132void Context::compressedTexImage3D(GLenum target,
3133 GLint level,
3134 GLenum internalformat,
3135 GLsizei width,
3136 GLsizei height,
3137 GLsizei depth,
3138 GLint border,
3139 GLsizei imageSize,
3140 const GLvoid *data)
3141{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003142 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003143
3144 Extents size(width, height, depth);
3145 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003146 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003147 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003148 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003149}
3150
3151void Context::compressedTexSubImage2D(GLenum target,
3152 GLint level,
3153 GLint xoffset,
3154 GLint yoffset,
3155 GLsizei width,
3156 GLsizei height,
3157 GLenum format,
3158 GLsizei imageSize,
3159 const GLvoid *data)
3160{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003161 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003162
3163 Box area(xoffset, yoffset, 0, width, height, 1);
3164 Texture *texture =
3165 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003166 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003167 format, imageSize,
3168 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003169}
3170
3171void Context::compressedTexSubImage3D(GLenum target,
3172 GLint level,
3173 GLint xoffset,
3174 GLint yoffset,
3175 GLint zoffset,
3176 GLsizei width,
3177 GLsizei height,
3178 GLsizei depth,
3179 GLenum format,
3180 GLsizei imageSize,
3181 const GLvoid *data)
3182{
3183 // Zero sized uploads are valid but no-ops
3184 if (width == 0 || height == 0)
3185 {
3186 return;
3187 }
3188
Jamie Madillad9f24e2016-02-12 09:27:24 -05003189 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003190
3191 Box area(xoffset, yoffset, zoffset, width, height, depth);
3192 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003193 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003194 format, imageSize,
3195 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003196}
3197
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003198void Context::generateMipmap(GLenum target)
3199{
3200 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003201 handleError(texture->generateMipmap(this));
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003202}
3203
Geoff Lang97073d12016-04-20 10:42:34 -07003204void Context::copyTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003205 GLint sourceLevel,
3206 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003207 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003208 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003209 GLint internalFormat,
3210 GLenum destType,
3211 GLboolean unpackFlipY,
3212 GLboolean unpackPremultiplyAlpha,
3213 GLboolean unpackUnmultiplyAlpha)
3214{
3215 syncStateForTexImage();
3216
3217 gl::Texture *sourceTexture = getTexture(sourceId);
3218 gl::Texture *destTexture = getTexture(destId);
Geoff Langfc72a072017-03-24 14:52:39 -04003219 handleError(destTexture->copyTexture(
3220 this, destTarget, destLevel, internalFormat, destType, sourceLevel, unpackFlipY == GL_TRUE,
3221 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003222}
3223
3224void Context::copySubTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003225 GLint sourceLevel,
3226 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003227 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003228 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003229 GLint xoffset,
3230 GLint yoffset,
3231 GLint x,
3232 GLint y,
3233 GLsizei width,
3234 GLsizei height,
3235 GLboolean unpackFlipY,
3236 GLboolean unpackPremultiplyAlpha,
3237 GLboolean unpackUnmultiplyAlpha)
3238{
3239 // Zero sized copies are valid but no-ops
3240 if (width == 0 || height == 0)
3241 {
3242 return;
3243 }
3244
3245 syncStateForTexImage();
3246
3247 gl::Texture *sourceTexture = getTexture(sourceId);
3248 gl::Texture *destTexture = getTexture(destId);
3249 Offset offset(xoffset, yoffset, 0);
3250 Rectangle area(x, y, width, height);
Geoff Langfc72a072017-03-24 14:52:39 -04003251 handleError(destTexture->copySubTexture(
3252 this, destTarget, destLevel, offset, sourceLevel, area, unpackFlipY == GL_TRUE,
3253 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003254}
3255
Geoff Lang47110bf2016-04-20 11:13:22 -07003256void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3257{
3258 syncStateForTexImage();
3259
3260 gl::Texture *sourceTexture = getTexture(sourceId);
3261 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003262 handleError(destTexture->copyCompressedTexture(this, sourceTexture));
Geoff Lang47110bf2016-04-20 11:13:22 -07003263}
3264
Geoff Lang496c02d2016-10-20 11:38:11 -07003265void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003266{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003267 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003268 ASSERT(buffer);
3269
Geoff Lang496c02d2016-10-20 11:38:11 -07003270 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003271}
3272
3273GLvoid *Context::mapBuffer(GLenum target, GLenum access)
3274{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003275 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003276 ASSERT(buffer);
3277
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003278 Error error = buffer->map(this, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003279 if (error.isError())
3280 {
Jamie Madill437fa652016-05-03 15:13:24 -04003281 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003282 return nullptr;
3283 }
3284
3285 return buffer->getMapPointer();
3286}
3287
3288GLboolean Context::unmapBuffer(GLenum target)
3289{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003290 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003291 ASSERT(buffer);
3292
3293 GLboolean result;
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003294 Error error = buffer->unmap(this, &result);
Olli Etuaho4f667482016-03-30 15:56:35 +03003295 if (error.isError())
3296 {
Jamie Madill437fa652016-05-03 15:13:24 -04003297 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003298 return GL_FALSE;
3299 }
3300
3301 return result;
3302}
3303
3304GLvoid *Context::mapBufferRange(GLenum target,
3305 GLintptr offset,
3306 GLsizeiptr length,
3307 GLbitfield access)
3308{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003309 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003310 ASSERT(buffer);
3311
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003312 Error error = buffer->mapRange(this, offset, length, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003313 if (error.isError())
3314 {
Jamie Madill437fa652016-05-03 15:13:24 -04003315 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003316 return nullptr;
3317 }
3318
3319 return buffer->getMapPointer();
3320}
3321
3322void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3323{
3324 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3325}
3326
Jamie Madillad9f24e2016-02-12 09:27:24 -05003327void Context::syncStateForReadPixels()
3328{
3329 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3330}
3331
3332void Context::syncStateForTexImage()
3333{
3334 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3335}
3336
3337void Context::syncStateForClear()
3338{
3339 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3340}
3341
3342void Context::syncStateForBlit()
3343{
3344 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3345}
3346
Jamie Madillc20ab272016-06-09 07:20:46 -07003347void Context::activeTexture(GLenum texture)
3348{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003349 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003350}
3351
3352void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3353{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003354 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003355}
3356
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003357void Context::blendEquation(GLenum mode)
3358{
3359 mGLState.setBlendEquation(mode, mode);
3360}
3361
Jamie Madillc20ab272016-06-09 07:20:46 -07003362void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3363{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003364 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003365}
3366
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003367void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3368{
3369 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3370}
3371
Jamie Madillc20ab272016-06-09 07:20:46 -07003372void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3373{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003374 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003375}
3376
3377void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3378{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003379 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003380}
3381
3382void Context::clearDepthf(GLclampf depth)
3383{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003384 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003385}
3386
3387void Context::clearStencil(GLint s)
3388{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003389 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003390}
3391
3392void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3393{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003394 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003395}
3396
3397void Context::cullFace(GLenum mode)
3398{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003399 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003400}
3401
3402void Context::depthFunc(GLenum func)
3403{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003404 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003405}
3406
3407void Context::depthMask(GLboolean flag)
3408{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003409 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003410}
3411
3412void Context::depthRangef(GLclampf zNear, GLclampf zFar)
3413{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003414 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003415}
3416
3417void Context::disable(GLenum cap)
3418{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003419 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003420}
3421
3422void Context::disableVertexAttribArray(GLuint index)
3423{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003424 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003425}
3426
3427void Context::enable(GLenum cap)
3428{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003429 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003430}
3431
3432void Context::enableVertexAttribArray(GLuint index)
3433{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003434 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003435}
3436
3437void Context::frontFace(GLenum mode)
3438{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003439 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003440}
3441
3442void Context::hint(GLenum target, GLenum mode)
3443{
3444 switch (target)
3445 {
3446 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003447 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003448 break;
3449
3450 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003451 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003452 break;
3453
3454 default:
3455 UNREACHABLE();
3456 return;
3457 }
3458}
3459
3460void Context::lineWidth(GLfloat width)
3461{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003462 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003463}
3464
3465void Context::pixelStorei(GLenum pname, GLint param)
3466{
3467 switch (pname)
3468 {
3469 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003470 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003471 break;
3472
3473 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003474 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003475 break;
3476
3477 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003478 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003479 break;
3480
3481 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003482 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003483 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003484 break;
3485
3486 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003487 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003488 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003489 break;
3490
3491 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003492 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003493 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003494 break;
3495
3496 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003497 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003498 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003499 break;
3500
3501 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003502 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003503 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003504 break;
3505
3506 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003507 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003508 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003509 break;
3510
3511 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003512 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003513 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003514 break;
3515
3516 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003517 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003518 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003519 break;
3520
3521 default:
3522 UNREACHABLE();
3523 return;
3524 }
3525}
3526
3527void Context::polygonOffset(GLfloat factor, GLfloat units)
3528{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003529 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003530}
3531
3532void Context::sampleCoverage(GLclampf value, GLboolean invert)
3533{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003534 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003535}
3536
3537void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3538{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003539 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003540}
3541
3542void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3543{
3544 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3545 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003546 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003547 }
3548
3549 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3550 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003551 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003552 }
3553}
3554
3555void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3556{
3557 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3558 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003559 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003560 }
3561
3562 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3563 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003564 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003565 }
3566}
3567
3568void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3569{
3570 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3571 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003572 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003573 }
3574
3575 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3576 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003577 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003578 }
3579}
3580
3581void Context::vertexAttrib1f(GLuint index, GLfloat x)
3582{
3583 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003584 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003585}
3586
3587void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3588{
3589 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003590 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003591}
3592
3593void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3594{
3595 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003596 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003597}
3598
3599void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3600{
3601 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003602 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003603}
3604
3605void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3606{
3607 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003608 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003609}
3610
3611void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3612{
3613 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003614 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003615}
3616
3617void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3618{
3619 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003620 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003621}
3622
3623void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3624{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003625 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003626}
3627
3628void Context::vertexAttribPointer(GLuint index,
3629 GLint size,
3630 GLenum type,
3631 GLboolean normalized,
3632 GLsizei stride,
3633 const GLvoid *ptr)
3634{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003635 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3636 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003637}
3638
Shao80957d92017-02-20 21:25:59 +08003639void Context::vertexAttribFormat(GLuint attribIndex,
3640 GLint size,
3641 GLenum type,
3642 GLboolean normalized,
3643 GLuint relativeOffset)
3644{
3645 mGLState.setVertexAttribFormat(attribIndex, size, type, normalized == GL_TRUE, false,
3646 relativeOffset);
3647}
3648
3649void Context::vertexAttribIFormat(GLuint attribIndex,
3650 GLint size,
3651 GLenum type,
3652 GLuint relativeOffset)
3653{
3654 mGLState.setVertexAttribFormat(attribIndex, size, type, false, true, relativeOffset);
3655}
3656
3657void Context::vertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
3658{
3659 mGLState.setVertexAttribBinding(attribIndex, bindingIndex);
3660}
3661
3662void Context::setVertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
3663{
3664 mGLState.setVertexBindingDivisor(bindingIndex, divisor);
3665}
3666
Jamie Madillc20ab272016-06-09 07:20:46 -07003667void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3668{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003669 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003670}
3671
3672void Context::vertexAttribIPointer(GLuint index,
3673 GLint size,
3674 GLenum type,
3675 GLsizei stride,
3676 const GLvoid *pointer)
3677{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003678 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3679 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003680}
3681
3682void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3683{
3684 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003685 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003686}
3687
3688void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3689{
3690 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003691 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003692}
3693
3694void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3695{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003696 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003697}
3698
3699void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3700{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003701 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003702}
3703
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003704void Context::getVertexAttribiv(GLuint index, GLenum pname, GLint *params)
3705{
3706 const VertexAttribCurrentValueData &currentValues =
3707 getGLState().getVertexAttribCurrentValue(index);
3708 const VertexArray *vao = getGLState().getVertexArray();
3709 QueryVertexAttribiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3710 currentValues, pname, params);
3711}
3712
3713void Context::getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
3714{
3715 const VertexAttribCurrentValueData &currentValues =
3716 getGLState().getVertexAttribCurrentValue(index);
3717 const VertexArray *vao = getGLState().getVertexArray();
3718 QueryVertexAttribfv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3719 currentValues, pname, params);
3720}
3721
3722void Context::getVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
3723{
3724 const VertexAttribCurrentValueData &currentValues =
3725 getGLState().getVertexAttribCurrentValue(index);
3726 const VertexArray *vao = getGLState().getVertexArray();
3727 QueryVertexAttribIiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3728 currentValues, pname, params);
3729}
3730
3731void Context::getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
3732{
3733 const VertexAttribCurrentValueData &currentValues =
3734 getGLState().getVertexAttribCurrentValue(index);
3735 const VertexArray *vao = getGLState().getVertexArray();
3736 QueryVertexAttribIuiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3737 currentValues, pname, params);
3738}
3739
3740void Context::getVertexAttribPointerv(GLuint index, GLenum pname, GLvoid **pointer)
3741{
3742 const VertexAttribute &attrib = getGLState().getVertexArray()->getVertexAttribute(index);
3743 QueryVertexAttribPointerv(attrib, pname, pointer);
3744}
3745
Jamie Madillc20ab272016-06-09 07:20:46 -07003746void Context::debugMessageControl(GLenum source,
3747 GLenum type,
3748 GLenum severity,
3749 GLsizei count,
3750 const GLuint *ids,
3751 GLboolean enabled)
3752{
3753 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003754 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3755 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003756}
3757
3758void Context::debugMessageInsert(GLenum source,
3759 GLenum type,
3760 GLuint id,
3761 GLenum severity,
3762 GLsizei length,
3763 const GLchar *buf)
3764{
3765 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003766 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003767}
3768
3769void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3770{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003771 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003772}
3773
3774GLuint Context::getDebugMessageLog(GLuint count,
3775 GLsizei bufSize,
3776 GLenum *sources,
3777 GLenum *types,
3778 GLuint *ids,
3779 GLenum *severities,
3780 GLsizei *lengths,
3781 GLchar *messageLog)
3782{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003783 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3784 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003785}
3786
3787void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3788{
3789 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003790 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003791}
3792
3793void Context::popDebugGroup()
3794{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003795 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003796}
3797
Jamie Madill29639852016-09-02 15:00:09 -04003798void Context::bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
3799{
3800 Buffer *buffer = mGLState.getTargetBuffer(target);
3801 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003802 handleError(buffer->bufferData(this, target, data, size, usage));
Jamie Madill29639852016-09-02 15:00:09 -04003803}
3804
3805void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
3806{
3807 if (data == nullptr)
3808 {
3809 return;
3810 }
3811
3812 Buffer *buffer = mGLState.getTargetBuffer(target);
3813 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003814 handleError(buffer->bufferSubData(this, target, data, size, offset));
Jamie Madill29639852016-09-02 15:00:09 -04003815}
3816
Jamie Madillef300b12016-10-07 15:12:09 -04003817void Context::attachShader(GLuint program, GLuint shader)
3818{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003819 auto programObject = mState.mShaderPrograms->getProgram(program);
3820 auto shaderObject = mState.mShaderPrograms->getShader(shader);
Jamie Madillef300b12016-10-07 15:12:09 -04003821 ASSERT(programObject && shaderObject);
3822 programObject->attachShader(shaderObject);
3823}
3824
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003825const Workarounds &Context::getWorkarounds() const
3826{
3827 return mWorkarounds;
3828}
3829
Jamie Madillb0817d12016-11-01 15:48:31 -04003830void Context::copyBufferSubData(GLenum readTarget,
3831 GLenum writeTarget,
3832 GLintptr readOffset,
3833 GLintptr writeOffset,
3834 GLsizeiptr size)
3835{
3836 // if size is zero, the copy is a successful no-op
3837 if (size == 0)
3838 {
3839 return;
3840 }
3841
3842 // TODO(jmadill): cache these.
3843 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3844 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3845
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003846 handleError(writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size));
Jamie Madillb0817d12016-11-01 15:48:31 -04003847}
3848
Jamie Madill01a80ee2016-11-07 12:06:18 -05003849void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3850{
3851 Program *programObject = getProgram(program);
3852 // TODO(jmadill): Re-use this from the validation if possible.
3853 ASSERT(programObject);
3854 programObject->bindAttributeLocation(index, name);
3855}
3856
3857void Context::bindBuffer(GLenum target, GLuint buffer)
3858{
3859 switch (target)
3860 {
3861 case GL_ARRAY_BUFFER:
3862 bindArrayBuffer(buffer);
3863 break;
3864 case GL_ELEMENT_ARRAY_BUFFER:
3865 bindElementArrayBuffer(buffer);
3866 break;
3867 case GL_COPY_READ_BUFFER:
3868 bindCopyReadBuffer(buffer);
3869 break;
3870 case GL_COPY_WRITE_BUFFER:
3871 bindCopyWriteBuffer(buffer);
3872 break;
3873 case GL_PIXEL_PACK_BUFFER:
3874 bindPixelPackBuffer(buffer);
3875 break;
3876 case GL_PIXEL_UNPACK_BUFFER:
3877 bindPixelUnpackBuffer(buffer);
3878 break;
3879 case GL_UNIFORM_BUFFER:
3880 bindGenericUniformBuffer(buffer);
3881 break;
3882 case GL_TRANSFORM_FEEDBACK_BUFFER:
3883 bindGenericTransformFeedbackBuffer(buffer);
3884 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003885 case GL_ATOMIC_COUNTER_BUFFER:
Jiajia Qin6eafb042016-12-27 17:04:07 +08003886 bindGenericAtomicCounterBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003887 break;
3888 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08003889 bindGenericShaderStorageBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003890 break;
3891 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08003892 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003893 break;
3894 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003895 if (buffer != 0)
3896 {
3897 // Binding buffers to this binding point is not implemented yet.
3898 UNIMPLEMENTED();
3899 }
Geoff Lang3b573612016-10-31 14:08:10 -04003900 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05003901
3902 default:
3903 UNREACHABLE();
3904 break;
3905 }
3906}
3907
Jiajia Qin6eafb042016-12-27 17:04:07 +08003908void Context::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
3909{
3910 bindBufferRange(target, index, buffer, 0, 0);
3911}
3912
3913void Context::bindBufferRange(GLenum target,
3914 GLuint index,
3915 GLuint buffer,
3916 GLintptr offset,
3917 GLsizeiptr size)
3918{
3919 switch (target)
3920 {
3921 case GL_TRANSFORM_FEEDBACK_BUFFER:
3922 bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
3923 bindGenericTransformFeedbackBuffer(buffer);
3924 break;
3925 case GL_UNIFORM_BUFFER:
3926 bindIndexedUniformBuffer(buffer, index, offset, size);
3927 bindGenericUniformBuffer(buffer);
3928 break;
3929 case GL_ATOMIC_COUNTER_BUFFER:
3930 bindIndexedAtomicCounterBuffer(buffer, index, offset, size);
3931 bindGenericAtomicCounterBuffer(buffer);
3932 break;
3933 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08003934 bindIndexedShaderStorageBuffer(buffer, index, offset, size);
3935 bindGenericShaderStorageBuffer(buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08003936 break;
3937 default:
3938 UNREACHABLE();
3939 break;
3940 }
3941}
3942
Jamie Madill01a80ee2016-11-07 12:06:18 -05003943void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
3944{
3945 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3946 {
3947 bindReadFramebuffer(framebuffer);
3948 }
3949
3950 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3951 {
3952 bindDrawFramebuffer(framebuffer);
3953 }
3954}
3955
3956void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
3957{
3958 ASSERT(target == GL_RENDERBUFFER);
3959 Renderbuffer *object =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003960 mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
Jamie Madill01a80ee2016-11-07 12:06:18 -05003961 mGLState.setRenderbufferBinding(object);
3962}
3963
JiangYizhoubddc46b2016-12-09 09:50:51 +08003964void Context::texStorage2DMultisample(GLenum target,
3965 GLsizei samples,
3966 GLenum internalformat,
3967 GLsizei width,
3968 GLsizei height,
3969 GLboolean fixedsamplelocations)
3970{
3971 Extents size(width, height, 1);
3972 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003973 handleError(texture->setStorageMultisample(this, target, samples, internalformat, size,
JiangYizhoubddc46b2016-12-09 09:50:51 +08003974 fixedsamplelocations));
3975}
3976
3977void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
3978{
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003979 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
JiangYizhoubddc46b2016-12-09 09:50:51 +08003980 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
3981
3982 switch (pname)
3983 {
3984 case GL_SAMPLE_POSITION:
3985 handleError(framebuffer->getSamplePosition(index, val));
3986 break;
3987 default:
3988 UNREACHABLE();
3989 }
3990}
3991
Jamie Madille8fb6402017-02-14 17:56:40 -05003992void Context::renderbufferStorage(GLenum target,
3993 GLenum internalformat,
3994 GLsizei width,
3995 GLsizei height)
3996{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05003997 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
3998 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
3999
Jamie Madille8fb6402017-02-14 17:56:40 -05004000 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004001 handleError(renderbuffer->setStorage(convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004002}
4003
4004void Context::renderbufferStorageMultisample(GLenum target,
4005 GLsizei samples,
4006 GLenum internalformat,
4007 GLsizei width,
4008 GLsizei height)
4009{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004010 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4011 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
Jamie Madille8fb6402017-02-14 17:56:40 -05004012
4013 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004014 handleError(
4015 renderbuffer->setStorageMultisample(samples, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004016}
4017
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004018void Context::getSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)
4019{
4020 const FenceSync *syncObject = getFenceSync(sync);
Geoff Lang82483b92017-04-11 15:33:00 -04004021 handleError(QuerySynciv(syncObject, pname, bufSize, length, values));
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004022}
4023
JiangYizhoue18e6392017-02-20 10:32:23 +08004024void Context::getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
4025{
4026 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4027 QueryFramebufferParameteriv(framebuffer, pname, params);
4028}
4029
4030void Context::setFramebufferParameteri(GLenum target, GLenum pname, GLint param)
4031{
4032 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4033 SetFramebufferParameteri(framebuffer, pname, param);
4034}
4035
Jamie Madille14951e2017-03-09 18:55:16 -05004036Error Context::getScratchBuffer(size_t requestedSize, angle::MemoryBuffer **scratchBufferOut) const
4037{
4038 if (!mScratchBuffer.get(requestedSize, scratchBufferOut))
4039 {
4040 return gl::OutOfMemory() << "Failed to allocate internal buffer.";
4041 }
4042 return gl::NoError();
4043}
4044
Xinghua Cao2b396592017-03-29 15:36:04 +08004045void Context::dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ)
4046{
4047 if (numGroupsX == 0u || numGroupsY == 0u || numGroupsZ == 0u)
4048 {
4049 return;
4050 }
4051
4052 mImplementation->dispatchCompute(numGroupsX, numGroupsY, numGroupsZ);
4053}
4054
Jamie Madillc1d770e2017-04-13 17:31:24 -04004055GLenum Context::checkFramebufferStatus(GLenum target)
4056{
4057 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4058 ASSERT(framebuffer);
4059
4060 return framebuffer->checkStatus(this);
4061}
4062
4063void Context::compileShader(GLuint shader)
4064{
4065 Shader *shaderObject = GetValidShader(this, shader);
4066 if (!shaderObject)
4067 {
4068 return;
4069 }
4070 shaderObject->compile(this);
4071}
4072
4073void Context::deleteBuffers(GLsizei n, const GLuint *buffers)
4074{
4075 for (int i = 0; i < n; i++)
4076 {
4077 deleteBuffer(buffers[i]);
4078 }
4079}
4080
4081void Context::deleteFramebuffers(GLsizei n, const GLuint *framebuffers)
4082{
4083 for (int i = 0; i < n; i++)
4084 {
4085 if (framebuffers[i] != 0)
4086 {
4087 deleteFramebuffer(framebuffers[i]);
4088 }
4089 }
4090}
4091
4092void Context::deleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)
4093{
4094 for (int i = 0; i < n; i++)
4095 {
4096 deleteRenderbuffer(renderbuffers[i]);
4097 }
4098}
4099
4100void Context::deleteTextures(GLsizei n, const GLuint *textures)
4101{
4102 for (int i = 0; i < n; i++)
4103 {
4104 if (textures[i] != 0)
4105 {
4106 deleteTexture(textures[i]);
4107 }
4108 }
4109}
4110
4111void Context::detachShader(GLuint program, GLuint shader)
4112{
4113 Program *programObject = getProgram(program);
4114 ASSERT(programObject);
4115
4116 Shader *shaderObject = getShader(shader);
4117 ASSERT(shaderObject);
4118
4119 programObject->detachShader(this, shaderObject);
4120}
4121
4122void Context::genBuffers(GLsizei n, GLuint *buffers)
4123{
4124 for (int i = 0; i < n; i++)
4125 {
4126 buffers[i] = createBuffer();
4127 }
4128}
4129
4130void Context::genFramebuffers(GLsizei n, GLuint *framebuffers)
4131{
4132 for (int i = 0; i < n; i++)
4133 {
4134 framebuffers[i] = createFramebuffer();
4135 }
4136}
4137
4138void Context::genRenderbuffers(GLsizei n, GLuint *renderbuffers)
4139{
4140 for (int i = 0; i < n; i++)
4141 {
4142 renderbuffers[i] = createRenderbuffer();
4143 }
4144}
4145
4146void Context::genTextures(GLsizei n, GLuint *textures)
4147{
4148 for (int i = 0; i < n; i++)
4149 {
4150 textures[i] = createTexture();
4151 }
4152}
4153
4154void Context::getActiveAttrib(GLuint program,
4155 GLuint index,
4156 GLsizei bufsize,
4157 GLsizei *length,
4158 GLint *size,
4159 GLenum *type,
4160 GLchar *name)
4161{
4162 Program *programObject = getProgram(program);
4163 ASSERT(programObject);
4164 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
4165}
4166
4167void Context::getActiveUniform(GLuint program,
4168 GLuint index,
4169 GLsizei bufsize,
4170 GLsizei *length,
4171 GLint *size,
4172 GLenum *type,
4173 GLchar *name)
4174{
4175 Program *programObject = getProgram(program);
4176 ASSERT(programObject);
4177 programObject->getActiveUniform(index, bufsize, length, size, type, name);
4178}
4179
4180void Context::getAttachedShaders(GLuint program, GLsizei maxcount, GLsizei *count, GLuint *shaders)
4181{
4182 Program *programObject = getProgram(program);
4183 ASSERT(programObject);
4184 programObject->getAttachedShaders(maxcount, count, shaders);
4185}
4186
4187GLint Context::getAttribLocation(GLuint program, const GLchar *name)
4188{
4189 Program *programObject = getProgram(program);
4190 ASSERT(programObject);
4191 return programObject->getAttributeLocation(name);
4192}
4193
4194void Context::getBooleanv(GLenum pname, GLboolean *params)
4195{
4196 GLenum nativeType;
4197 unsigned int numParams = 0;
4198 getQueryParameterInfo(pname, &nativeType, &numParams);
4199
4200 if (nativeType == GL_BOOL)
4201 {
4202 getBooleanvImpl(pname, params);
4203 }
4204 else
4205 {
4206 CastStateValues(this, nativeType, pname, numParams, params);
4207 }
4208}
4209
4210void Context::getFloatv(GLenum pname, GLfloat *params)
4211{
4212 GLenum nativeType;
4213 unsigned int numParams = 0;
4214 getQueryParameterInfo(pname, &nativeType, &numParams);
4215
4216 if (nativeType == GL_FLOAT)
4217 {
4218 getFloatvImpl(pname, params);
4219 }
4220 else
4221 {
4222 CastStateValues(this, nativeType, pname, numParams, params);
4223 }
4224}
4225
4226void Context::getIntegerv(GLenum pname, GLint *params)
4227{
4228 GLenum nativeType;
4229 unsigned int numParams = 0;
4230 getQueryParameterInfo(pname, &nativeType, &numParams);
4231
4232 if (nativeType == GL_INT)
4233 {
4234 getIntegervImpl(pname, params);
4235 }
4236 else
4237 {
4238 CastStateValues(this, nativeType, pname, numParams, params);
4239 }
4240}
4241
4242void Context::getProgramiv(GLuint program, GLenum pname, GLint *params)
4243{
4244 Program *programObject = getProgram(program);
4245 ASSERT(programObject);
4246 QueryProgramiv(programObject, pname, params);
4247}
4248
4249void Context::getInfoLog(GLuint program, GLsizei bufsize, GLsizei *length, GLchar *infolog)
4250{
4251 Program *programObject = getProgram(program);
4252 ASSERT(programObject);
4253 programObject->getInfoLog(bufsize, length, infolog);
4254}
4255
4256void Context::getShaderiv(GLuint shader, GLenum pname, GLint *params)
4257{
4258 Shader *shaderObject = getShader(shader);
4259 ASSERT(shaderObject);
4260 QueryShaderiv(shaderObject, pname, params);
4261}
4262
4263void Context::getShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *infolog)
4264{
4265 Shader *shaderObject = getShader(shader);
4266 ASSERT(shaderObject);
4267 shaderObject->getInfoLog(bufsize, length, infolog);
4268}
4269
4270void Context::getShaderPrecisionFormat(GLenum shadertype,
4271 GLenum precisiontype,
4272 GLint *range,
4273 GLint *precision)
4274{
4275 // TODO(jmadill): Compute shaders.
4276
4277 switch (shadertype)
4278 {
4279 case GL_VERTEX_SHADER:
4280 switch (precisiontype)
4281 {
4282 case GL_LOW_FLOAT:
4283 mCaps.vertexLowpFloat.get(range, precision);
4284 break;
4285 case GL_MEDIUM_FLOAT:
4286 mCaps.vertexMediumpFloat.get(range, precision);
4287 break;
4288 case GL_HIGH_FLOAT:
4289 mCaps.vertexHighpFloat.get(range, precision);
4290 break;
4291
4292 case GL_LOW_INT:
4293 mCaps.vertexLowpInt.get(range, precision);
4294 break;
4295 case GL_MEDIUM_INT:
4296 mCaps.vertexMediumpInt.get(range, precision);
4297 break;
4298 case GL_HIGH_INT:
4299 mCaps.vertexHighpInt.get(range, precision);
4300 break;
4301
4302 default:
4303 UNREACHABLE();
4304 return;
4305 }
4306 break;
4307
4308 case GL_FRAGMENT_SHADER:
4309 switch (precisiontype)
4310 {
4311 case GL_LOW_FLOAT:
4312 mCaps.fragmentLowpFloat.get(range, precision);
4313 break;
4314 case GL_MEDIUM_FLOAT:
4315 mCaps.fragmentMediumpFloat.get(range, precision);
4316 break;
4317 case GL_HIGH_FLOAT:
4318 mCaps.fragmentHighpFloat.get(range, precision);
4319 break;
4320
4321 case GL_LOW_INT:
4322 mCaps.fragmentLowpInt.get(range, precision);
4323 break;
4324 case GL_MEDIUM_INT:
4325 mCaps.fragmentMediumpInt.get(range, precision);
4326 break;
4327 case GL_HIGH_INT:
4328 mCaps.fragmentHighpInt.get(range, precision);
4329 break;
4330
4331 default:
4332 UNREACHABLE();
4333 return;
4334 }
4335 break;
4336
4337 default:
4338 UNREACHABLE();
4339 return;
4340 }
4341}
4342
4343void Context::getShaderSource(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source)
4344{
4345 Shader *shaderObject = getShader(shader);
4346 ASSERT(shaderObject);
4347 shaderObject->getSource(bufsize, length, source);
4348}
4349
4350void Context::getUniformfv(GLuint program, GLint location, GLfloat *params)
4351{
4352 Program *programObject = getProgram(program);
4353 ASSERT(programObject);
4354 programObject->getUniformfv(location, params);
4355}
4356
4357void Context::getUniformiv(GLuint program, GLint location, GLint *params)
4358{
4359 Program *programObject = getProgram(program);
4360 ASSERT(programObject);
4361 programObject->getUniformiv(location, params);
4362}
4363
4364GLint Context::getUniformLocation(GLuint program, const GLchar *name)
4365{
4366 Program *programObject = getProgram(program);
4367 ASSERT(programObject);
4368 return programObject->getUniformLocation(name);
4369}
4370
4371GLboolean Context::isBuffer(GLuint buffer)
4372{
4373 if (buffer == 0)
4374 {
4375 return GL_FALSE;
4376 }
4377
4378 return (getBuffer(buffer) ? GL_TRUE : GL_FALSE);
4379}
4380
4381GLboolean Context::isEnabled(GLenum cap)
4382{
4383 return mGLState.getEnableFeature(cap);
4384}
4385
4386GLboolean Context::isFramebuffer(GLuint framebuffer)
4387{
4388 if (framebuffer == 0)
4389 {
4390 return GL_FALSE;
4391 }
4392
4393 return (getFramebuffer(framebuffer) ? GL_TRUE : GL_FALSE);
4394}
4395
4396GLboolean Context::isProgram(GLuint program)
4397{
4398 if (program == 0)
4399 {
4400 return GL_FALSE;
4401 }
4402
4403 return (getProgram(program) ? GL_TRUE : GL_FALSE);
4404}
4405
4406GLboolean Context::isRenderbuffer(GLuint renderbuffer)
4407{
4408 if (renderbuffer == 0)
4409 {
4410 return GL_FALSE;
4411 }
4412
4413 return (getRenderbuffer(renderbuffer) ? GL_TRUE : GL_FALSE);
4414}
4415
4416GLboolean Context::isShader(GLuint shader)
4417{
4418 if (shader == 0)
4419 {
4420 return GL_FALSE;
4421 }
4422
4423 return (getShader(shader) ? GL_TRUE : GL_FALSE);
4424}
4425
4426GLboolean Context::isTexture(GLuint texture)
4427{
4428 if (texture == 0)
4429 {
4430 return GL_FALSE;
4431 }
4432
4433 return (getTexture(texture) ? GL_TRUE : GL_FALSE);
4434}
4435
4436void Context::linkProgram(GLuint program)
4437{
4438 Program *programObject = getProgram(program);
4439 ASSERT(programObject);
4440 handleError(programObject->link(this));
4441}
4442
4443void Context::releaseShaderCompiler()
4444{
4445 handleError(mCompiler->release());
4446}
4447
4448void Context::shaderBinary(GLsizei n,
4449 const GLuint *shaders,
4450 GLenum binaryformat,
4451 const GLvoid *binary,
4452 GLsizei length)
4453{
4454 // No binary shader formats are supported.
4455 UNIMPLEMENTED();
4456}
4457
4458void Context::shaderSource(GLuint shader,
4459 GLsizei count,
4460 const GLchar *const *string,
4461 const GLint *length)
4462{
4463 Shader *shaderObject = getShader(shader);
4464 ASSERT(shaderObject);
4465 shaderObject->setSource(count, string, length);
4466}
4467
4468void Context::stencilFunc(GLenum func, GLint ref, GLuint mask)
4469{
4470 stencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
4471}
4472
4473void Context::stencilMask(GLuint mask)
4474{
4475 stencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4476}
4477
4478void Context::stencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4479{
4480 stencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4481}
4482
4483void Context::uniform1f(GLint location, GLfloat x)
4484{
4485 Program *program = mGLState.getProgram();
4486 program->setUniform1fv(location, 1, &x);
4487}
4488
4489void Context::uniform1fv(GLint location, GLsizei count, const GLfloat *v)
4490{
4491 Program *program = mGLState.getProgram();
4492 program->setUniform1fv(location, count, v);
4493}
4494
4495void Context::uniform1i(GLint location, GLint x)
4496{
4497 Program *program = mGLState.getProgram();
4498 program->setUniform1iv(location, 1, &x);
4499}
4500
4501void Context::uniform1iv(GLint location, GLsizei count, const GLint *v)
4502{
4503 Program *program = mGLState.getProgram();
4504 program->setUniform1iv(location, count, v);
4505}
4506
4507void Context::uniform2f(GLint location, GLfloat x, GLfloat y)
4508{
4509 GLfloat xy[2] = {x, y};
4510 Program *program = mGLState.getProgram();
4511 program->setUniform2fv(location, 1, xy);
4512}
4513
4514void Context::uniform2fv(GLint location, GLsizei count, const GLfloat *v)
4515{
4516 Program *program = mGLState.getProgram();
4517 program->setUniform2fv(location, count, v);
4518}
4519
4520void Context::uniform2i(GLint location, GLint x, GLint y)
4521{
4522 GLint xy[2] = {x, y};
4523 Program *program = mGLState.getProgram();
4524 program->setUniform2iv(location, 1, xy);
4525}
4526
4527void Context::uniform2iv(GLint location, GLsizei count, const GLint *v)
4528{
4529 Program *program = mGLState.getProgram();
4530 program->setUniform2iv(location, count, v);
4531}
4532
4533void Context::uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4534{
4535 GLfloat xyz[3] = {x, y, z};
4536 Program *program = mGLState.getProgram();
4537 program->setUniform3fv(location, 1, xyz);
4538}
4539
4540void Context::uniform3fv(GLint location, GLsizei count, const GLfloat *v)
4541{
4542 Program *program = mGLState.getProgram();
4543 program->setUniform3fv(location, count, v);
4544}
4545
4546void Context::uniform3i(GLint location, GLint x, GLint y, GLint z)
4547{
4548 GLint xyz[3] = {x, y, z};
4549 Program *program = mGLState.getProgram();
4550 program->setUniform3iv(location, 1, xyz);
4551}
4552
4553void Context::uniform3iv(GLint location, GLsizei count, const GLint *v)
4554{
4555 Program *program = mGLState.getProgram();
4556 program->setUniform3iv(location, count, v);
4557}
4558
4559void Context::uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4560{
4561 GLfloat xyzw[4] = {x, y, z, w};
4562 Program *program = mGLState.getProgram();
4563 program->setUniform4fv(location, 1, xyzw);
4564}
4565
4566void Context::uniform4fv(GLint location, GLsizei count, const GLfloat *v)
4567{
4568 Program *program = mGLState.getProgram();
4569 program->setUniform4fv(location, count, v);
4570}
4571
4572void Context::uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4573{
4574 GLint xyzw[4] = {x, y, z, w};
4575 Program *program = mGLState.getProgram();
4576 program->setUniform4iv(location, 1, xyzw);
4577}
4578
4579void Context::uniform4iv(GLint location, GLsizei count, const GLint *v)
4580{
4581 Program *program = mGLState.getProgram();
4582 program->setUniform4iv(location, count, v);
4583}
4584
4585void Context::uniformMatrix2fv(GLint location,
4586 GLsizei count,
4587 GLboolean transpose,
4588 const GLfloat *value)
4589{
4590 Program *program = mGLState.getProgram();
4591 program->setUniformMatrix2fv(location, count, transpose, value);
4592}
4593
4594void Context::uniformMatrix3fv(GLint location,
4595 GLsizei count,
4596 GLboolean transpose,
4597 const GLfloat *value)
4598{
4599 Program *program = mGLState.getProgram();
4600 program->setUniformMatrix3fv(location, count, transpose, value);
4601}
4602
4603void Context::uniformMatrix4fv(GLint location,
4604 GLsizei count,
4605 GLboolean transpose,
4606 const GLfloat *value)
4607{
4608 Program *program = mGLState.getProgram();
4609 program->setUniformMatrix4fv(location, count, transpose, value);
4610}
4611
4612void Context::validateProgram(GLuint program)
4613{
4614 Program *programObject = getProgram(program);
4615 ASSERT(programObject);
4616 programObject->validate(mCaps);
4617}
4618
Jamie Madillc29968b2016-01-20 11:17:23 -05004619} // namespace gl