blob: 85d7f00fc6991e2297fc0cfb8f69bfd68adf0cff [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 {
Jamie Madilldedd7b92014-11-05 16:30:36 -0500444 zeroTexture.second.set(NULL);
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
642 mQueryMap[handle] = NULL;
643
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{
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500816 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500817 if (iter != mTransformFeedbackMap.end())
818 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500819 TransformFeedback *transformFeedbackObject = iter->second;
820 if (transformFeedbackObject != nullptr)
821 {
822 detachTransformFeedback(transformFeedback);
Jamie Madill6c1f6712017-02-14 19:08:04 -0500823 transformFeedbackObject->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500824 }
825
Geoff Lang50b3fe82015-12-08 14:49:12 +0000826 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500827 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500828 }
829}
830
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000831void Context::deleteFramebuffer(GLuint framebuffer)
832{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500833 if (mState.mFramebuffers->getFramebuffer(framebuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000834 {
835 detachFramebuffer(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000836 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500837
Jamie Madill6c1f6712017-02-14 19:08:04 -0500838 mState.mFramebuffers->deleteObject(this, framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000839}
840
Jamie Madill33dc8432013-07-26 11:55:05 -0400841void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000842{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500843 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000844
Jamie Madill33dc8432013-07-26 11:55:05 -0400845 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000846 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400847 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000848 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400849 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000850 }
851}
852
853void Context::deleteQuery(GLuint query)
854{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500855 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000856 if (queryObject != mQueryMap.end())
857 {
858 mQueryHandleAllocator.release(queryObject->first);
859 if (queryObject->second)
860 {
861 queryObject->second->release();
862 }
863 mQueryMap.erase(queryObject);
864 }
865}
866
Geoff Lang70d0f492015-12-10 17:45:46 -0500867Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000868{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500869 return mState.mBuffers->getBuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000870}
871
Jamie Madill570f7c82014-07-03 10:38:54 -0400872Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000873{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500874 return mState.mTextures->getTexture(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000875}
876
Geoff Lang70d0f492015-12-10 17:45:46 -0500877Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000878{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500879 return mState.mRenderbuffers->getRenderbuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000880}
881
Jamie Madillcd055f82013-07-26 11:55:15 -0400882FenceSync *Context::getFenceSync(GLsync handle) const
883{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500884 return mState.mFenceSyncs->getFenceSync(
885 static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400886}
887
Jamie Madill57a89722013-07-02 11:57:03 -0400888VertexArray *Context::getVertexArray(GLuint handle) const
889{
890 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500891 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400892}
893
Jamie Madilldc356042013-07-19 16:36:57 -0400894Sampler *Context::getSampler(GLuint handle) const
895{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500896 return mState.mSamplers->getSampler(handle);
Jamie Madilldc356042013-07-19 16:36:57 -0400897}
898
Geoff Langc8058452014-02-03 12:04:11 -0500899TransformFeedback *Context::getTransformFeedback(GLuint handle) const
900{
Geoff Lang36167ab2015-12-07 10:27:14 -0500901 auto iter = mTransformFeedbackMap.find(handle);
902 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500903}
904
Geoff Lang70d0f492015-12-10 17:45:46 -0500905LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
906{
907 switch (identifier)
908 {
909 case GL_BUFFER:
910 return getBuffer(name);
911 case GL_SHADER:
912 return getShader(name);
913 case GL_PROGRAM:
914 return getProgram(name);
915 case GL_VERTEX_ARRAY:
916 return getVertexArray(name);
917 case GL_QUERY:
918 return getQuery(name);
919 case GL_TRANSFORM_FEEDBACK:
920 return getTransformFeedback(name);
921 case GL_SAMPLER:
922 return getSampler(name);
923 case GL_TEXTURE:
924 return getTexture(name);
925 case GL_RENDERBUFFER:
926 return getRenderbuffer(name);
927 case GL_FRAMEBUFFER:
928 return getFramebuffer(name);
929 default:
930 UNREACHABLE();
931 return nullptr;
932 }
933}
934
935LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
936{
937 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
938}
939
Martin Radev9d901792016-07-15 15:58:58 +0300940void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
941{
942 LabeledObject *object = getLabeledObject(identifier, name);
943 ASSERT(object != nullptr);
944
945 std::string labelName = GetObjectLabelFromPointer(length, label);
946 object->setLabel(labelName);
947}
948
949void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
950{
951 LabeledObject *object = getLabeledObjectFromPtr(ptr);
952 ASSERT(object != nullptr);
953
954 std::string labelName = GetObjectLabelFromPointer(length, label);
955 object->setLabel(labelName);
956}
957
958void Context::getObjectLabel(GLenum identifier,
959 GLuint name,
960 GLsizei bufSize,
961 GLsizei *length,
962 GLchar *label) const
963{
964 LabeledObject *object = getLabeledObject(identifier, name);
965 ASSERT(object != nullptr);
966
967 const std::string &objectLabel = object->getLabel();
968 GetObjectLabelBase(objectLabel, bufSize, length, label);
969}
970
971void Context::getObjectPtrLabel(const void *ptr,
972 GLsizei bufSize,
973 GLsizei *length,
974 GLchar *label) const
975{
976 LabeledObject *object = getLabeledObjectFromPtr(ptr);
977 ASSERT(object != nullptr);
978
979 const std::string &objectLabel = object->getLabel();
980 GetObjectLabelBase(objectLabel, bufSize, length, label);
981}
982
Jamie Madilldc356042013-07-19 16:36:57 -0400983bool Context::isSampler(GLuint samplerName) const
984{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500985 return mState.mSamplers->isSampler(samplerName);
Jamie Madilldc356042013-07-19 16:36:57 -0400986}
987
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500988void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000989{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500990 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700991 mGLState.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000992}
993
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800994void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
995{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500996 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800997 mGLState.setDrawIndirectBufferBinding(buffer);
998}
999
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001000void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001001{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001002 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Shao80957d92017-02-20 21:25:59 +08001003 mGLState.setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001004}
1005
Jamie Madilldedd7b92014-11-05 16:30:36 -05001006void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001007{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001008 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001009
Jamie Madilldedd7b92014-11-05 16:30:36 -05001010 if (handle == 0)
1011 {
1012 texture = mZeroTextures[target].get();
1013 }
1014 else
1015 {
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001016 texture = mState.mTextures->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -05001017 }
1018
1019 ASSERT(texture);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001020 mGLState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +00001021}
1022
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001023void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001024{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001025 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
1026 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001027 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001028}
1029
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001030void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001031{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001032 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
1033 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001034 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001035}
1036
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001037void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -04001038{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001039 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001040 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -04001041}
1042
Shao80957d92017-02-20 21:25:59 +08001043void Context::bindVertexBuffer(GLuint bindingIndex,
1044 GLuint bufferHandle,
1045 GLintptr offset,
1046 GLsizei stride)
1047{
1048 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
1049 mGLState.bindVertexBuffer(bindingIndex, buffer, offset, stride);
1050}
1051
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001052void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -04001053{
Geoff Lang76b10c92014-09-05 16:28:14 -04001054 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -04001055 Sampler *sampler =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001056 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001057 mGLState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001058}
1059
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001060void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001061{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001062 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001063 mGLState.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001064}
1065
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001066void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1067 GLuint index,
1068 GLintptr offset,
1069 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001070{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001071 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001072 mGLState.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001073}
1074
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001075void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001076{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001077 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001078 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001079}
1080
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001081void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1082 GLuint index,
1083 GLintptr offset,
1084 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001085{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001086 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001087 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001088}
1089
Jiajia Qin6eafb042016-12-27 17:04:07 +08001090void Context::bindGenericAtomicCounterBuffer(GLuint bufferHandle)
1091{
1092 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
1093 mGLState.setGenericAtomicCounterBufferBinding(buffer);
1094}
1095
1096void Context::bindIndexedAtomicCounterBuffer(GLuint bufferHandle,
1097 GLuint index,
1098 GLintptr offset,
1099 GLsizeiptr size)
1100{
1101 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
1102 mGLState.setIndexedAtomicCounterBufferBinding(index, buffer, offset, size);
1103}
1104
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001105void Context::bindGenericShaderStorageBuffer(GLuint bufferHandle)
1106{
1107 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
1108 mGLState.setGenericShaderStorageBufferBinding(buffer);
1109}
1110
1111void Context::bindIndexedShaderStorageBuffer(GLuint bufferHandle,
1112 GLuint index,
1113 GLintptr offset,
1114 GLsizeiptr size)
1115{
1116 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
1117 mGLState.setIndexedShaderStorageBufferBinding(index, buffer, offset, size);
1118}
1119
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001120void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001121{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001122 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001123 mGLState.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001124}
1125
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001126void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001127{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001128 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001129 mGLState.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001130}
1131
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001132void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001133{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001134 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001135 mGLState.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001136}
1137
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001138void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001139{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001140 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001141 mGLState.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001142}
1143
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001144void Context::useProgram(GLuint program)
1145{
Jamie Madill6c1f6712017-02-14 19:08:04 -05001146 mGLState.setProgram(this, getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001147}
1148
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001149void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001150{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001151 TransformFeedback *transformFeedback =
1152 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001153 mGLState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001154}
1155
Geoff Lang5aad9672014-09-08 11:10:42 -04001156Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001157{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001158 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001159 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001160
Geoff Lang5aad9672014-09-08 11:10:42 -04001161 // begin query
1162 Error error = queryObject->begin();
1163 if (error.isError())
1164 {
1165 return error;
1166 }
1167
1168 // set query as active for specified target only if begin succeeded
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001169 mGLState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001170
He Yunchaoacd18982017-01-04 10:46:42 +08001171 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001172}
1173
Geoff Lang5aad9672014-09-08 11:10:42 -04001174Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001175{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001176 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001177 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001178
Geoff Lang5aad9672014-09-08 11:10:42 -04001179 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001180
Geoff Lang5aad9672014-09-08 11:10:42 -04001181 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001182 mGLState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -04001183
1184 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001185}
1186
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001187Error Context::queryCounter(GLuint id, GLenum target)
1188{
1189 ASSERT(target == GL_TIMESTAMP_EXT);
1190
1191 Query *queryObject = getQuery(id, true, target);
1192 ASSERT(queryObject);
1193
1194 return queryObject->queryCounter();
1195}
1196
1197void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1198{
1199 switch (pname)
1200 {
1201 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001202 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001203 break;
1204 case GL_QUERY_COUNTER_BITS_EXT:
1205 switch (target)
1206 {
1207 case GL_TIME_ELAPSED_EXT:
1208 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1209 break;
1210 case GL_TIMESTAMP_EXT:
1211 params[0] = getExtensions().queryCounterBitsTimestamp;
1212 break;
1213 default:
1214 UNREACHABLE();
1215 params[0] = 0;
1216 break;
1217 }
1218 break;
1219 default:
1220 UNREACHABLE();
1221 return;
1222 }
1223}
1224
Geoff Lang2186c382016-10-14 10:54:54 -04001225void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001226{
Geoff Lang2186c382016-10-14 10:54:54 -04001227 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001228}
1229
Geoff Lang2186c382016-10-14 10:54:54 -04001230void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *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::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *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::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *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 Lang3bf8e3a2016-12-01 17:28:52 -05001245Framebuffer *Context::getFramebuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001246{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001247 return mState.mFramebuffers->getFramebuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001248}
1249
Jamie Madill33dc8432013-07-26 11:55:05 -04001250FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001251{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001252 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001253
Jamie Madill33dc8432013-07-26 11:55:05 -04001254 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001255 {
1256 return NULL;
1257 }
1258 else
1259 {
1260 return fence->second;
1261 }
1262}
1263
1264Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1265{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001266 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001267
1268 if (query == mQueryMap.end())
1269 {
1270 return NULL;
1271 }
1272 else
1273 {
1274 if (!query->second && create)
1275 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001276 query->second = new Query(mImplementation->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001277 query->second->addRef();
1278 }
1279 return query->second;
1280 }
1281}
1282
Geoff Lang70d0f492015-12-10 17:45:46 -05001283Query *Context::getQuery(GLuint handle) const
1284{
1285 auto iter = mQueryMap.find(handle);
1286 return (iter != mQueryMap.end()) ? iter->second : nullptr;
1287}
1288
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001289Texture *Context::getTargetTexture(GLenum target) const
1290{
Ian Ewellbda75592016-04-18 17:25:54 -04001291 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001292 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001293}
1294
Geoff Lang76b10c92014-09-05 16:28:14 -04001295Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001296{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001297 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001298}
1299
Geoff Lang492a7e42014-11-05 13:27:06 -05001300Compiler *Context::getCompiler() const
1301{
1302 return mCompiler;
1303}
1304
Jamie Madill893ab082014-05-16 16:56:10 -04001305void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001306{
1307 switch (pname)
1308 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001309 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001310 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001311 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001312 mGLState.getBooleanv(pname, params);
1313 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001314 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001315}
1316
Jamie Madill893ab082014-05-16 16:56:10 -04001317void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001318{
Shannon Woods53a94a82014-06-24 15:20:36 -04001319 // Queries about context capabilities and maximums are answered by Context.
1320 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001321 switch (pname)
1322 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001323 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001324 params[0] = mCaps.minAliasedLineWidth;
1325 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001326 break;
1327 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001328 params[0] = mCaps.minAliasedPointSize;
1329 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001330 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001331 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001332 ASSERT(mExtensions.textureFilterAnisotropic);
1333 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001334 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001335 case GL_MAX_TEXTURE_LOD_BIAS:
1336 *params = mCaps.maxLODBias;
1337 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001338
1339 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1340 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1341 {
1342 ASSERT(mExtensions.pathRendering);
1343 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1344 memcpy(params, m, 16 * sizeof(GLfloat));
1345 }
1346 break;
1347
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001348 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001349 mGLState.getFloatv(pname, params);
1350 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001351 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001352}
1353
Jamie Madill893ab082014-05-16 16:56:10 -04001354void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001355{
Shannon Woods53a94a82014-06-24 15:20:36 -04001356 // Queries about context capabilities and maximums are answered by Context.
1357 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001358
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001359 switch (pname)
1360 {
Geoff Lang301d1612014-07-09 10:34:37 -04001361 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1362 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1363 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001364 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1365 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1366 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001367 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1368 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1369 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001370 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001371 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1372 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1373 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001374 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001375 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001376 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1377 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1378 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1379 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001380 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1381 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001382 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1383 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001384 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001385 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1386 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1387 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1388 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Martin Radev1be913c2016-07-11 17:59:16 +03001389 case GL_MAJOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001390 *params = getClientVersion().major;
Martin Radev1be913c2016-07-11 17:59:16 +03001391 break;
1392 case GL_MINOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001393 *params = getClientVersion().minor;
Martin Radev1be913c2016-07-11 17:59:16 +03001394 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001395 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1396 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001397 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1398 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1399 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001400 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1401 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1402 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001403 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001404 case GL_MAX_VIEWPORT_DIMS:
1405 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001406 params[0] = mCaps.maxViewportWidth;
1407 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001408 }
1409 break;
1410 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001411 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001412 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001413 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1414 *params = mResetStrategy;
1415 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001416 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001417 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001418 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001419 case GL_SHADER_BINARY_FORMATS:
1420 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1421 break;
1422 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001423 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001424 break;
1425 case GL_PROGRAM_BINARY_FORMATS:
1426 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001427 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001428 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001429 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001430 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001431
1432 // GL_KHR_debug
1433 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1434 *params = mExtensions.maxDebugMessageLength;
1435 break;
1436 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1437 *params = mExtensions.maxDebugLoggedMessages;
1438 break;
1439 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1440 *params = mExtensions.maxDebugGroupStackDepth;
1441 break;
1442 case GL_MAX_LABEL_LENGTH:
1443 *params = mExtensions.maxLabelLength;
1444 break;
1445
Ian Ewell53f59f42016-01-28 17:36:55 -05001446 // GL_EXT_disjoint_timer_query
1447 case GL_GPU_DISJOINT_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001448 *params = mImplementation->getGPUDisjoint();
Ian Ewell53f59f42016-01-28 17:36:55 -05001449 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001450 case GL_MAX_FRAMEBUFFER_WIDTH:
1451 *params = mCaps.maxFramebufferWidth;
1452 break;
1453 case GL_MAX_FRAMEBUFFER_HEIGHT:
1454 *params = mCaps.maxFramebufferHeight;
1455 break;
1456 case GL_MAX_FRAMEBUFFER_SAMPLES:
1457 *params = mCaps.maxFramebufferSamples;
1458 break;
1459 case GL_MAX_SAMPLE_MASK_WORDS:
1460 *params = mCaps.maxSampleMaskWords;
1461 break;
1462 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1463 *params = mCaps.maxColorTextureSamples;
1464 break;
1465 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1466 *params = mCaps.maxDepthTextureSamples;
1467 break;
1468 case GL_MAX_INTEGER_SAMPLES:
1469 *params = mCaps.maxIntegerSamples;
1470 break;
1471 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1472 *params = mCaps.maxVertexAttribRelativeOffset;
1473 break;
1474 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1475 *params = mCaps.maxVertexAttribBindings;
1476 break;
1477 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1478 *params = mCaps.maxVertexAttribStride;
1479 break;
1480 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1481 *params = mCaps.maxVertexAtomicCounterBuffers;
1482 break;
1483 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1484 *params = mCaps.maxVertexAtomicCounters;
1485 break;
1486 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1487 *params = mCaps.maxVertexImageUniforms;
1488 break;
1489 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1490 *params = mCaps.maxVertexShaderStorageBlocks;
1491 break;
1492 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1493 *params = mCaps.maxFragmentAtomicCounterBuffers;
1494 break;
1495 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1496 *params = mCaps.maxFragmentAtomicCounters;
1497 break;
1498 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1499 *params = mCaps.maxFragmentImageUniforms;
1500 break;
1501 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1502 *params = mCaps.maxFragmentShaderStorageBlocks;
1503 break;
1504 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1505 *params = mCaps.minProgramTextureGatherOffset;
1506 break;
1507 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1508 *params = mCaps.maxProgramTextureGatherOffset;
1509 break;
1510 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1511 *params = mCaps.maxComputeWorkGroupInvocations;
1512 break;
1513 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1514 *params = mCaps.maxComputeUniformBlocks;
1515 break;
1516 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1517 *params = mCaps.maxComputeTextureImageUnits;
1518 break;
1519 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1520 *params = mCaps.maxComputeSharedMemorySize;
1521 break;
1522 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1523 *params = mCaps.maxComputeUniformComponents;
1524 break;
1525 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1526 *params = mCaps.maxComputeAtomicCounterBuffers;
1527 break;
1528 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1529 *params = mCaps.maxComputeAtomicCounters;
1530 break;
1531 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1532 *params = mCaps.maxComputeImageUniforms;
1533 break;
1534 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1535 *params = mCaps.maxCombinedComputeUniformComponents;
1536 break;
1537 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1538 *params = mCaps.maxComputeShaderStorageBlocks;
1539 break;
1540 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1541 *params = mCaps.maxCombinedShaderOutputResources;
1542 break;
1543 case GL_MAX_UNIFORM_LOCATIONS:
1544 *params = mCaps.maxUniformLocations;
1545 break;
1546 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1547 *params = mCaps.maxAtomicCounterBufferBindings;
1548 break;
1549 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1550 *params = mCaps.maxAtomicCounterBufferSize;
1551 break;
1552 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1553 *params = mCaps.maxCombinedAtomicCounterBuffers;
1554 break;
1555 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1556 *params = mCaps.maxCombinedAtomicCounters;
1557 break;
1558 case GL_MAX_IMAGE_UNITS:
1559 *params = mCaps.maxImageUnits;
1560 break;
1561 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1562 *params = mCaps.maxCombinedImageUniforms;
1563 break;
1564 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1565 *params = mCaps.maxShaderStorageBufferBindings;
1566 break;
1567 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1568 *params = mCaps.maxCombinedShaderStorageBlocks;
1569 break;
1570 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1571 *params = mCaps.shaderStorageBufferOffsetAlignment;
1572 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001573 default:
Jamie Madilldd43e6c2017-03-24 14:18:49 -04001574 mGLState.getIntegerv(this, pname, params);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001575 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001576 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001577}
1578
Jamie Madill893ab082014-05-16 16:56:10 -04001579void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001580{
Shannon Woods53a94a82014-06-24 15:20:36 -04001581 // Queries about context capabilities and maximums are answered by Context.
1582 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001583 switch (pname)
1584 {
1585 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001586 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001587 break;
1588 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001589 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001590 break;
1591 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001592 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001593 break;
1594 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001595 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001596 break;
1597 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001598 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001599 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001600
1601 // GL_EXT_disjoint_timer_query
1602 case GL_TIMESTAMP_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001603 *params = mImplementation->getTimestamp();
Ian Ewell53f59f42016-01-28 17:36:55 -05001604 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001605
1606 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1607 *params = mCaps.maxShaderStorageBlockSize;
1608 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001609 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001610 UNREACHABLE();
1611 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001612 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001613}
1614
Geoff Lang70d0f492015-12-10 17:45:46 -05001615void Context::getPointerv(GLenum pname, void **params) const
1616{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001617 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001618}
1619
Martin Radev66fb8202016-07-28 11:45:20 +03001620void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001621{
Shannon Woods53a94a82014-06-24 15:20:36 -04001622 // Queries about context capabilities and maximums are answered by Context.
1623 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001624
1625 GLenum nativeType;
1626 unsigned int numParams;
1627 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1628 ASSERT(queryStatus);
1629
1630 if (nativeType == GL_INT)
1631 {
1632 switch (target)
1633 {
1634 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1635 ASSERT(index < 3u);
1636 *data = mCaps.maxComputeWorkGroupCount[index];
1637 break;
1638 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1639 ASSERT(index < 3u);
1640 *data = mCaps.maxComputeWorkGroupSize[index];
1641 break;
1642 default:
1643 mGLState.getIntegeri_v(target, index, data);
1644 }
1645 }
1646 else
1647 {
1648 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1649 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001650}
1651
Martin Radev66fb8202016-07-28 11:45:20 +03001652void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001653{
Shannon Woods53a94a82014-06-24 15:20:36 -04001654 // Queries about context capabilities and maximums are answered by Context.
1655 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001656
1657 GLenum nativeType;
1658 unsigned int numParams;
1659 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1660 ASSERT(queryStatus);
1661
1662 if (nativeType == GL_INT_64_ANGLEX)
1663 {
1664 mGLState.getInteger64i_v(target, index, data);
1665 }
1666 else
1667 {
1668 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1669 }
1670}
1671
1672void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1673{
1674 // Queries about context capabilities and maximums are answered by Context.
1675 // Queries about current GL state values are answered by State.
1676
1677 GLenum nativeType;
1678 unsigned int numParams;
1679 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1680 ASSERT(queryStatus);
1681
1682 if (nativeType == GL_BOOL)
1683 {
1684 mGLState.getBooleani_v(target, index, data);
1685 }
1686 else
1687 {
1688 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1689 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001690}
1691
He Yunchao010e4db2017-03-03 14:22:06 +08001692void Context::getBufferParameteriv(GLenum target, GLenum pname, GLint *params)
1693{
1694 Buffer *buffer = mGLState.getTargetBuffer(target);
1695 QueryBufferParameteriv(buffer, pname, params);
1696}
1697
1698void Context::getFramebufferAttachmentParameteriv(GLenum target,
1699 GLenum attachment,
1700 GLenum pname,
1701 GLint *params)
1702{
1703 const Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
1704 QueryFramebufferAttachmentParameteriv(framebuffer, attachment, pname, params);
1705}
1706
1707void Context::getRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
1708{
1709 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
1710 QueryRenderbufferiv(this, renderbuffer, pname, params);
1711}
1712
1713void Context::getTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
1714{
1715 Texture *texture = getTargetTexture(target);
1716 QueryTexParameterfv(texture, pname, params);
1717}
1718
1719void Context::getTexParameteriv(GLenum target, GLenum pname, GLint *params)
1720{
1721 Texture *texture = getTargetTexture(target);
1722 QueryTexParameteriv(texture, pname, params);
1723}
1724void Context::texParameterf(GLenum target, GLenum pname, GLfloat param)
1725{
1726 Texture *texture = getTargetTexture(target);
1727 SetTexParameterf(texture, pname, param);
1728}
1729
1730void Context::texParameterfv(GLenum target, GLenum pname, const GLfloat *params)
1731{
1732 Texture *texture = getTargetTexture(target);
1733 SetTexParameterfv(texture, pname, params);
1734}
1735
1736void Context::texParameteri(GLenum target, GLenum pname, GLint param)
1737{
1738 Texture *texture = getTargetTexture(target);
1739 SetTexParameteri(texture, pname, param);
1740}
1741
1742void Context::texParameteriv(GLenum target, GLenum pname, const GLint *params)
1743{
1744 Texture *texture = getTargetTexture(target);
1745 SetTexParameteriv(texture, pname, params);
1746}
1747
Jamie Madill675fe712016-12-19 13:07:54 -05001748void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001749{
Jamie Madill1b94d432015-08-07 13:23:23 -04001750 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001751 auto error = mImplementation->drawArrays(mode, first, count);
1752 handleError(error);
1753 if (!error.isError())
1754 {
1755 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1756 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001757}
1758
Jamie Madill675fe712016-12-19 13:07:54 -05001759void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Geoff Langf6db0982015-08-25 13:04:00 -04001760{
1761 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001762 auto error = mImplementation->drawArraysInstanced(mode, first, count, instanceCount);
1763 handleError(error);
1764 if (!error.isError())
1765 {
1766 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1767 }
Geoff Langf6db0982015-08-25 13:04:00 -04001768}
1769
Jamie Madill675fe712016-12-19 13:07:54 -05001770void Context::drawElements(GLenum mode,
1771 GLsizei count,
1772 GLenum type,
1773 const GLvoid *indices,
1774 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001775{
Jamie Madill1b94d432015-08-07 13:23:23 -04001776 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001777 handleError(mImplementation->drawElements(mode, count, type, indices, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001778}
1779
Jamie Madill675fe712016-12-19 13:07:54 -05001780void Context::drawElementsInstanced(GLenum mode,
1781 GLsizei count,
1782 GLenum type,
1783 const GLvoid *indices,
1784 GLsizei instances,
1785 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001786{
1787 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001788 handleError(
1789 mImplementation->drawElementsInstanced(mode, count, type, indices, instances, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001790}
1791
Jamie Madill675fe712016-12-19 13:07:54 -05001792void Context::drawRangeElements(GLenum mode,
1793 GLuint start,
1794 GLuint end,
1795 GLsizei count,
1796 GLenum type,
1797 const GLvoid *indices,
1798 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001799{
1800 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001801 handleError(
1802 mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001803}
1804
Jiajia Qind9671222016-11-29 16:30:31 +08001805void Context::drawArraysIndirect(GLenum mode, const GLvoid *indirect)
1806{
1807 syncRendererState();
1808 handleError(mImplementation->drawArraysIndirect(mode, indirect));
1809}
1810
1811void Context::drawElementsIndirect(GLenum mode, GLenum type, const GLvoid *indirect)
1812{
1813 syncRendererState();
1814 handleError(mImplementation->drawElementsIndirect(mode, type, indirect));
1815}
1816
Jamie Madill675fe712016-12-19 13:07:54 -05001817void Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001818{
Jamie Madill675fe712016-12-19 13:07:54 -05001819 handleError(mImplementation->flush());
Geoff Lang129753a2015-01-09 16:52:09 -05001820}
1821
Jamie Madill675fe712016-12-19 13:07:54 -05001822void Context::finish()
Geoff Lang129753a2015-01-09 16:52:09 -05001823{
Jamie Madill675fe712016-12-19 13:07:54 -05001824 handleError(mImplementation->finish());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001825}
1826
Austin Kinross6ee1e782015-05-29 17:05:37 -07001827void Context::insertEventMarker(GLsizei length, const char *marker)
1828{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001829 ASSERT(mImplementation);
1830 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001831}
1832
1833void Context::pushGroupMarker(GLsizei length, const char *marker)
1834{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001835 ASSERT(mImplementation);
1836 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001837}
1838
1839void Context::popGroupMarker()
1840{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001841 ASSERT(mImplementation);
1842 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001843}
1844
Geoff Langd8605522016-04-13 10:19:12 -04001845void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1846{
1847 Program *programObject = getProgram(program);
1848 ASSERT(programObject);
1849
1850 programObject->bindUniformLocation(location, name);
1851}
1852
Sami Väisänena797e062016-05-12 15:23:40 +03001853void Context::setCoverageModulation(GLenum components)
1854{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001855 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001856}
1857
Sami Väisänene45e53b2016-05-25 10:36:04 +03001858void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1859{
1860 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1861}
1862
1863void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1864{
1865 GLfloat I[16];
1866 angle::Matrix<GLfloat>::setToIdentity(I);
1867
1868 mGLState.loadPathRenderingMatrix(matrixMode, I);
1869}
1870
1871void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1872{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001873 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001874 if (!pathObj)
1875 return;
1876
1877 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1878 syncRendererState();
1879
1880 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1881}
1882
1883void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1884{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001885 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001886 if (!pathObj)
1887 return;
1888
1889 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1890 syncRendererState();
1891
1892 mImplementation->stencilStrokePath(pathObj, reference, mask);
1893}
1894
1895void Context::coverFillPath(GLuint path, GLenum coverMode)
1896{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001897 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001898 if (!pathObj)
1899 return;
1900
1901 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1902 syncRendererState();
1903
1904 mImplementation->coverFillPath(pathObj, coverMode);
1905}
1906
1907void Context::coverStrokePath(GLuint path, GLenum coverMode)
1908{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001909 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001910 if (!pathObj)
1911 return;
1912
1913 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1914 syncRendererState();
1915
1916 mImplementation->coverStrokePath(pathObj, coverMode);
1917}
1918
1919void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1920{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001921 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001922 if (!pathObj)
1923 return;
1924
1925 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1926 syncRendererState();
1927
1928 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1929}
1930
1931void Context::stencilThenCoverStrokePath(GLuint path,
1932 GLint reference,
1933 GLuint mask,
1934 GLenum coverMode)
1935{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001936 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001937 if (!pathObj)
1938 return;
1939
1940 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1941 syncRendererState();
1942
1943 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1944}
1945
Sami Väisänend59ca052016-06-21 16:10:00 +03001946void Context::coverFillPathInstanced(GLsizei numPaths,
1947 GLenum pathNameType,
1948 const void *paths,
1949 GLuint pathBase,
1950 GLenum coverMode,
1951 GLenum transformType,
1952 const GLfloat *transformValues)
1953{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001954 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001955
1956 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1957 syncRendererState();
1958
1959 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1960}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001961
Sami Väisänend59ca052016-06-21 16:10:00 +03001962void Context::coverStrokePathInstanced(GLsizei numPaths,
1963 GLenum pathNameType,
1964 const void *paths,
1965 GLuint pathBase,
1966 GLenum coverMode,
1967 GLenum transformType,
1968 const GLfloat *transformValues)
1969{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001970 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001971
1972 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1973 syncRendererState();
1974
1975 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1976 transformValues);
1977}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001978
Sami Väisänend59ca052016-06-21 16:10:00 +03001979void Context::stencilFillPathInstanced(GLsizei numPaths,
1980 GLenum pathNameType,
1981 const void *paths,
1982 GLuint pathBase,
1983 GLenum fillMode,
1984 GLuint mask,
1985 GLenum transformType,
1986 const GLfloat *transformValues)
1987{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001988 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001989
1990 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1991 syncRendererState();
1992
1993 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1994 transformValues);
1995}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001996
Sami Väisänend59ca052016-06-21 16:10:00 +03001997void Context::stencilStrokePathInstanced(GLsizei numPaths,
1998 GLenum pathNameType,
1999 const void *paths,
2000 GLuint pathBase,
2001 GLint reference,
2002 GLuint mask,
2003 GLenum transformType,
2004 const GLfloat *transformValues)
2005{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002006 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002007
2008 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2009 syncRendererState();
2010
2011 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
2012 transformValues);
2013}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002014
Sami Väisänend59ca052016-06-21 16:10:00 +03002015void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
2016 GLenum pathNameType,
2017 const void *paths,
2018 GLuint pathBase,
2019 GLenum fillMode,
2020 GLuint mask,
2021 GLenum coverMode,
2022 GLenum transformType,
2023 const GLfloat *transformValues)
2024{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002025 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002026
2027 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2028 syncRendererState();
2029
2030 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
2031 transformType, transformValues);
2032}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002033
Sami Väisänend59ca052016-06-21 16:10:00 +03002034void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
2035 GLenum pathNameType,
2036 const void *paths,
2037 GLuint pathBase,
2038 GLint reference,
2039 GLuint mask,
2040 GLenum coverMode,
2041 GLenum transformType,
2042 const GLfloat *transformValues)
2043{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002044 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002045
2046 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2047 syncRendererState();
2048
2049 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
2050 transformType, transformValues);
2051}
2052
Sami Väisänen46eaa942016-06-29 10:26:37 +03002053void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
2054{
2055 auto *programObject = getProgram(program);
2056
2057 programObject->bindFragmentInputLocation(location, name);
2058}
2059
2060void Context::programPathFragmentInputGen(GLuint program,
2061 GLint location,
2062 GLenum genMode,
2063 GLint components,
2064 const GLfloat *coeffs)
2065{
2066 auto *programObject = getProgram(program);
2067
2068 programObject->pathFragmentInputGen(location, genMode, components, coeffs);
2069}
2070
jchen1015015f72017-03-16 13:54:21 +08002071GLuint Context::getProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name)
2072{
jchen10fd7c3b52017-03-21 15:36:03 +08002073 const auto *programObject = getProgram(program);
jchen1015015f72017-03-16 13:54:21 +08002074 return QueryProgramResourceIndex(programObject, programInterface, name);
2075}
2076
jchen10fd7c3b52017-03-21 15:36:03 +08002077void Context::getProgramResourceName(GLuint program,
2078 GLenum programInterface,
2079 GLuint index,
2080 GLsizei bufSize,
2081 GLsizei *length,
2082 GLchar *name)
2083{
2084 const auto *programObject = getProgram(program);
2085 QueryProgramResourceName(programObject, programInterface, index, bufSize, length, name);
2086}
2087
Jamie Madill437fa652016-05-03 15:13:24 -04002088void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002089{
Geoff Langda5777c2014-07-11 09:52:58 -04002090 if (error.isError())
2091 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002092 GLenum code = error.getCode();
2093 mErrors.insert(code);
2094 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
2095 {
2096 markContextLost();
2097 }
Geoff Lang70d0f492015-12-10 17:45:46 -05002098
2099 if (!error.getMessage().empty())
2100 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002101 auto *debug = &mGLState.getDebug();
2102 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
2103 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05002104 }
Geoff Langda5777c2014-07-11 09:52:58 -04002105 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002106}
2107
2108// Get one of the recorded errors and clear its flag, if any.
2109// [OpenGL ES 2.0.24] section 2.5 page 13.
2110GLenum Context::getError()
2111{
Geoff Langda5777c2014-07-11 09:52:58 -04002112 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002113 {
Geoff Langda5777c2014-07-11 09:52:58 -04002114 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002115 }
Geoff Langda5777c2014-07-11 09:52:58 -04002116 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002117 {
Geoff Langda5777c2014-07-11 09:52:58 -04002118 GLenum error = *mErrors.begin();
2119 mErrors.erase(mErrors.begin());
2120 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002121 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002122}
2123
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002124// NOTE: this function should not assume that this context is current!
2125void Context::markContextLost()
2126{
2127 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002128 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002129 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002130 mContextLostForced = true;
2131 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002132 mContextLost = true;
2133}
2134
2135bool Context::isContextLost()
2136{
2137 return mContextLost;
2138}
2139
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002140GLenum Context::getResetStatus()
2141{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002142 // Even if the application doesn't want to know about resets, we want to know
2143 // as it will allow us to skip all the calls.
2144 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002145 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002146 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002147 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002148 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002149 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002150
2151 // EXT_robustness, section 2.6: If the reset notification behavior is
2152 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2153 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2154 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002155 }
2156
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002157 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2158 // status should be returned at least once, and GL_NO_ERROR should be returned
2159 // once the device has finished resetting.
2160 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002161 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002162 ASSERT(mResetStatus == GL_NO_ERROR);
2163 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002164
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002165 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002166 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002167 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002168 }
2169 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002170 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002171 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002172 // If markContextLost was used to mark the context lost then
2173 // assume that is not recoverable, and continue to report the
2174 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002175 mResetStatus = mImplementation->getResetStatus();
2176 }
Jamie Madill893ab082014-05-16 16:56:10 -04002177
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002178 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002179}
2180
2181bool Context::isResetNotificationEnabled()
2182{
2183 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2184}
2185
Corentin Walleze3b10e82015-05-20 11:06:25 -04002186const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002187{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002188 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002189}
2190
2191EGLenum Context::getClientType() const
2192{
2193 return mClientType;
2194}
2195
2196EGLenum Context::getRenderBuffer() const
2197{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002198 const Framebuffer *framebuffer = mState.mFramebuffers->getFramebuffer(0);
2199 if (framebuffer == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -04002200 {
2201 return EGL_NONE;
2202 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002203
2204 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2205 ASSERT(backAttachment != nullptr);
2206 return backAttachment->getSurface()->getRenderBuffer();
Régis Fénéon83107972015-02-05 12:57:44 +01002207}
2208
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002209VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002210{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002211 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002212 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2213 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002214 {
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002215 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle,
2216 mCaps.maxVertexAttributes, mCaps.maxVertexAttribBindings);
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002217
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002218 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002219 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002220
2221 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002222}
2223
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002224TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002225{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002226 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002227 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2228 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002229 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002230 transformFeedback =
2231 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002232 transformFeedback->addRef();
2233 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002234 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002235
2236 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002237}
2238
2239bool Context::isVertexArrayGenerated(GLuint vertexArray)
2240{
Geoff Langf41a7152016-09-19 15:11:17 -04002241 ASSERT(mVertexArrayMap.find(0) != mVertexArrayMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002242 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
2243}
2244
2245bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2246{
Geoff Langf41a7152016-09-19 15:11:17 -04002247 ASSERT(mTransformFeedbackMap.find(0) != mTransformFeedbackMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002248 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
2249}
2250
Shannon Woods53a94a82014-06-24 15:20:36 -04002251void Context::detachTexture(GLuint texture)
2252{
2253 // Simple pass-through to State's detachTexture method, as textures do not require
2254 // allocation map management either here or in the resource manager at detach time.
2255 // Zero textures are held by the Context, and we don't attempt to request them from
2256 // the State.
Jamie Madilla02315b2017-02-23 14:14:47 -05002257 mGLState.detachTexture(this, mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002258}
2259
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002260void Context::detachBuffer(GLuint buffer)
2261{
Yuly Novikov5807a532015-12-03 13:01:22 -05002262 // Simple pass-through to State's detachBuffer method, since
2263 // only buffer attachments to container objects that are bound to the current context
2264 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002265
Yuly Novikov5807a532015-12-03 13:01:22 -05002266 // [OpenGL ES 3.2] section 5.1.2 page 45:
2267 // Attachments to unbound container objects, such as
2268 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2269 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002270 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002271}
2272
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002273void Context::detachFramebuffer(GLuint framebuffer)
2274{
Shannon Woods53a94a82014-06-24 15:20:36 -04002275 // Framebuffer detachment is handled by Context, because 0 is a valid
2276 // Framebuffer object, and a pointer to it must be passed from Context
2277 // to State at binding time.
2278
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002279 // [OpenGL ES 2.0.24] section 4.4 page 107:
2280 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2281 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2282
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002283 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002284 {
2285 bindReadFramebuffer(0);
2286 }
2287
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002288 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002289 {
2290 bindDrawFramebuffer(0);
2291 }
2292}
2293
2294void Context::detachRenderbuffer(GLuint renderbuffer)
2295{
Jamie Madilla02315b2017-02-23 14:14:47 -05002296 mGLState.detachRenderbuffer(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002297}
2298
Jamie Madill57a89722013-07-02 11:57:03 -04002299void Context::detachVertexArray(GLuint vertexArray)
2300{
Jamie Madill77a72f62015-04-14 11:18:32 -04002301 // Vertex array detachment is handled by Context, because 0 is a valid
2302 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002303 // binding time.
2304
Jamie Madill57a89722013-07-02 11:57:03 -04002305 // [OpenGL ES 3.0.2] section 2.10 page 43:
2306 // If a vertex array object that is currently bound is deleted, the binding
2307 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002308 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002309 {
2310 bindVertexArray(0);
2311 }
2312}
2313
Geoff Langc8058452014-02-03 12:04:11 -05002314void Context::detachTransformFeedback(GLuint transformFeedback)
2315{
Corentin Walleza2257da2016-04-19 16:43:12 -04002316 // Transform feedback detachment is handled by Context, because 0 is a valid
2317 // transform feedback, and a pointer to it must be passed from Context to State at
2318 // binding time.
2319
2320 // The OpenGL specification doesn't mention what should happen when the currently bound
2321 // transform feedback object is deleted. Since it is a container object, we treat it like
2322 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002323 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002324 {
2325 bindTransformFeedback(0);
2326 }
Geoff Langc8058452014-02-03 12:04:11 -05002327}
2328
Jamie Madilldc356042013-07-19 16:36:57 -04002329void Context::detachSampler(GLuint sampler)
2330{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002331 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002332}
2333
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002334void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2335{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002336 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002337}
2338
Jamie Madille29d1672013-07-19 16:36:57 -04002339void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2340{
Geoff Langc1984ed2016-10-07 12:41:00 -04002341 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002342 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002343 SetSamplerParameteri(samplerObject, pname, param);
2344}
Jamie Madille29d1672013-07-19 16:36:57 -04002345
Geoff Langc1984ed2016-10-07 12:41:00 -04002346void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2347{
2348 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002349 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002350 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002351}
2352
2353void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2354{
Geoff Langc1984ed2016-10-07 12:41:00 -04002355 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002356 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002357 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002358}
2359
Geoff Langc1984ed2016-10-07 12:41:00 -04002360void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002361{
Geoff Langc1984ed2016-10-07 12:41:00 -04002362 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002363 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002364 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002365}
2366
Geoff Langc1984ed2016-10-07 12:41:00 -04002367void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002368{
Geoff Langc1984ed2016-10-07 12:41:00 -04002369 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002370 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002371 QuerySamplerParameteriv(samplerObject, pname, params);
2372}
Jamie Madill9675b802013-07-19 16:36:59 -04002373
Geoff Langc1984ed2016-10-07 12:41:00 -04002374void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2375{
2376 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002377 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002378 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002379}
2380
Olli Etuahof0fee072016-03-30 15:11:58 +03002381void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2382{
2383 gl::Program *programObject = getProgram(program);
Yunchao He61afff12017-03-14 15:34:03 +08002384 SetProgramParameteri(programObject, pname, value);
Olli Etuahof0fee072016-03-30 15:11:58 +03002385}
2386
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002387void Context::initRendererString()
2388{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002389 std::ostringstream rendererString;
2390 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002391 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002392 rendererString << ")";
2393
Geoff Langcec35902014-04-16 10:52:36 -04002394 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002395}
2396
Geoff Langc339c4e2016-11-29 10:37:36 -05002397void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002398{
Geoff Langc339c4e2016-11-29 10:37:36 -05002399 const Version &clientVersion = getClientVersion();
2400
2401 std::ostringstream versionString;
2402 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2403 << ANGLE_VERSION_STRING << ")";
2404 mVersionString = MakeStaticString(versionString.str());
2405
2406 std::ostringstream shadingLanguageVersionString;
2407 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2408 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2409 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2410 << ")";
2411 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002412}
2413
Geoff Langcec35902014-04-16 10:52:36 -04002414void Context::initExtensionStrings()
2415{
Geoff Langc339c4e2016-11-29 10:37:36 -05002416 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2417 std::ostringstream combinedStringStream;
2418 std::copy(strings.begin(), strings.end(),
2419 std::ostream_iterator<const char *>(combinedStringStream, " "));
2420 return MakeStaticString(combinedStringStream.str());
2421 };
2422
2423 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002424 for (const auto &extensionString : mExtensions.getStrings())
2425 {
2426 mExtensionStrings.push_back(MakeStaticString(extensionString));
2427 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002428 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002429
Bryan Bernhart58806562017-01-05 13:09:31 -08002430 const gl::Extensions &nativeExtensions = mImplementation->getNativeExtensions();
2431
Geoff Langc339c4e2016-11-29 10:37:36 -05002432 mRequestableExtensionStrings.clear();
2433 for (const auto &extensionInfo : GetExtensionInfoMap())
2434 {
2435 if (extensionInfo.second.Requestable &&
Bryan Bernhart58806562017-01-05 13:09:31 -08002436 !(mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
2437 nativeExtensions.*(extensionInfo.second.ExtensionsMember))
Geoff Langc339c4e2016-11-29 10:37:36 -05002438 {
2439 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2440 }
2441 }
2442 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002443}
2444
Geoff Langc339c4e2016-11-29 10:37:36 -05002445const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002446{
Geoff Langc339c4e2016-11-29 10:37:36 -05002447 switch (name)
2448 {
2449 case GL_VENDOR:
2450 return reinterpret_cast<const GLubyte *>("Google Inc.");
2451
2452 case GL_RENDERER:
2453 return reinterpret_cast<const GLubyte *>(mRendererString);
2454
2455 case GL_VERSION:
2456 return reinterpret_cast<const GLubyte *>(mVersionString);
2457
2458 case GL_SHADING_LANGUAGE_VERSION:
2459 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2460
2461 case GL_EXTENSIONS:
2462 return reinterpret_cast<const GLubyte *>(mExtensionString);
2463
2464 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2465 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2466
2467 default:
2468 UNREACHABLE();
2469 return nullptr;
2470 }
Geoff Langcec35902014-04-16 10:52:36 -04002471}
2472
Geoff Langc339c4e2016-11-29 10:37:36 -05002473const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002474{
Geoff Langc339c4e2016-11-29 10:37:36 -05002475 switch (name)
2476 {
2477 case GL_EXTENSIONS:
2478 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2479
2480 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2481 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2482
2483 default:
2484 UNREACHABLE();
2485 return nullptr;
2486 }
Geoff Langcec35902014-04-16 10:52:36 -04002487}
2488
2489size_t Context::getExtensionStringCount() const
2490{
2491 return mExtensionStrings.size();
2492}
2493
Geoff Langc339c4e2016-11-29 10:37:36 -05002494void Context::requestExtension(const char *name)
2495{
2496 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2497 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2498 const auto &extension = extensionInfos.at(name);
2499 ASSERT(extension.Requestable);
2500
2501 if (mExtensions.*(extension.ExtensionsMember))
2502 {
2503 // Extension already enabled
2504 return;
2505 }
2506
2507 mExtensions.*(extension.ExtensionsMember) = true;
2508 updateCaps();
2509 initExtensionStrings();
Bryan Bernhart58806562017-01-05 13:09:31 -08002510
2511 // Re-create the compiler with the requested extensions enabled.
2512 SafeDelete(mCompiler);
2513 mCompiler = new Compiler(mImplementation.get(), mState);
Geoff Lang9aded172017-04-05 11:07:56 -04002514
2515 // Invalidate all cached completenesses for textures and framebuffer. Some extensions make new
2516 // formats renderable or sampleable.
2517 mState.mTextures->invalidateTextureComplenessCache();
2518 for (auto &zeroTexture : mZeroTextures)
2519 {
2520 zeroTexture.second->invalidateCompletenessCache();
2521 }
2522
2523 mState.mFramebuffers->invalidateFramebufferComplenessCache();
Geoff Langc339c4e2016-11-29 10:37:36 -05002524}
2525
2526size_t Context::getRequestableExtensionStringCount() const
2527{
2528 return mRequestableExtensionStrings.size();
2529}
2530
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002531void Context::beginTransformFeedback(GLenum primitiveMode)
2532{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002533 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002534 ASSERT(transformFeedback != nullptr);
2535 ASSERT(!transformFeedback->isPaused());
2536
Jamie Madill6c1f6712017-02-14 19:08:04 -05002537 transformFeedback->begin(this, primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002538}
2539
2540bool Context::hasActiveTransformFeedback(GLuint program) const
2541{
2542 for (auto pair : mTransformFeedbackMap)
2543 {
2544 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2545 {
2546 return true;
2547 }
2548 }
2549 return false;
2550}
2551
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002552void Context::initCaps(const egl::DisplayExtensions &displayExtensions)
Geoff Lang493daf52014-07-03 13:38:44 -04002553{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002554 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002555
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002556 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002557
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002558 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002559
Geoff Langeb66a6e2016-10-31 13:06:12 -04002560 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002561 {
2562 // Disable ES3+ extensions
2563 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002564 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002565 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002566 }
2567
Geoff Langeb66a6e2016-10-31 13:06:12 -04002568 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002569 {
2570 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2571 //mExtensions.sRGB = false;
2572 }
2573
Jamie Madill00ed7a12016-05-19 13:13:38 -04002574 // Some extensions are always available because they are implemented in the GL layer.
2575 mExtensions.bindUniformLocation = true;
2576 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002577 mExtensions.bindGeneratesResource = true;
Geoff Langfeb8c682017-02-13 16:07:35 -05002578 mExtensions.clientArrays = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002579 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002580
2581 // Enable the no error extension if the context was created with the flag.
2582 mExtensions.noError = mSkipValidation;
2583
Corentin Wallezccab69d2017-01-27 16:57:15 -05002584 // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
Corentin Wallezc295e512017-01-27 17:47:50 -05002585 mExtensions.surfacelessContext = displayExtensions.surfacelessContext;
Corentin Wallezccab69d2017-01-27 16:57:15 -05002586
Geoff Lang70d0f492015-12-10 17:45:46 -05002587 // Explicitly enable GL_KHR_debug
2588 mExtensions.debug = true;
2589 mExtensions.maxDebugMessageLength = 1024;
2590 mExtensions.maxDebugLoggedMessages = 1024;
2591 mExtensions.maxDebugGroupStackDepth = 1024;
2592 mExtensions.maxLabelLength = 1024;
2593
Geoff Langff5b2d52016-09-07 11:32:23 -04002594 // Explicitly enable GL_ANGLE_robust_client_memory
2595 mExtensions.robustClientMemory = true;
2596
Jamie Madille08a1d32017-03-07 17:24:06 -05002597 // Determine robust resource init availability from EGL.
2598 mExtensions.robustResourceInitialization =
2599 displayExtensions.createContextRobustResourceInitialization;
2600
Geoff Lang301d1612014-07-09 10:34:37 -04002601 // Apply implementation limits
2602 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002603 mCaps.maxVertexAttribBindings =
2604 getClientVersion() < ES_3_1
2605 ? mCaps.maxVertexAttributes
2606 : std::min<GLuint>(mCaps.maxVertexAttribBindings, MAX_VERTEX_ATTRIB_BINDINGS);
2607
Geoff Lang301d1612014-07-09 10:34:37 -04002608 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2609 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2610
2611 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002612
Geoff Langc287ea62016-09-16 14:46:51 -04002613 // WebGL compatibility
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002614 mExtensions.webglCompatibility = mWebGLContext;
Geoff Langc287ea62016-09-16 14:46:51 -04002615 for (const auto &extensionInfo : GetExtensionInfoMap())
2616 {
2617 // If this context is for WebGL, disable all enableable extensions
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002618 if (mWebGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002619 {
2620 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2621 }
2622 }
2623
2624 // Generate texture caps
2625 updateCaps();
2626}
2627
2628void Context::updateCaps()
2629{
Geoff Lang900013c2014-07-07 11:32:19 -04002630 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002631 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002632
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002633 for (auto capsIt : mImplementation->getNativeTextureCaps())
Geoff Lang493daf52014-07-03 13:38:44 -04002634 {
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002635 GLenum format = capsIt.first;
2636 TextureCaps formatCaps = capsIt.second;
Geoff Lang493daf52014-07-03 13:38:44 -04002637
Geoff Lang5d601382014-07-22 15:14:06 -04002638 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002639
Geoff Lang0d8b7242015-09-09 14:56:53 -04002640 // Update the format caps based on the client version and extensions.
2641 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2642 // ES3.
2643 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002644 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002645 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002646 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002647 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002648 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002649
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002650 // OpenGL ES does not support multisampling with non-rendererable formats
2651 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
2652 if (!formatInfo.renderSupport ||
2653 (getClientVersion() < ES_3_1 &&
2654 (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
Geoff Lang493daf52014-07-03 13:38:44 -04002655 {
Geoff Langd87878e2014-09-19 15:42:59 -04002656 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002657 }
Geoff Langd87878e2014-09-19 15:42:59 -04002658
2659 if (formatCaps.texturable && formatInfo.compressed)
2660 {
2661 mCaps.compressedTextureFormats.push_back(format);
2662 }
2663
2664 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002665 }
2666}
2667
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002668void Context::initWorkarounds()
2669{
2670 // Lose the context upon out of memory error if the application is
2671 // expecting to watch for those events.
2672 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2673}
2674
Jamie Madill1b94d432015-08-07 13:23:23 -04002675void Context::syncRendererState()
2676{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002677 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
Frank Henigman5a53d542017-02-16 21:24:10 -05002678 mImplementation->syncState(dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002679 mGLState.clearDirtyBits();
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002680 mGLState.syncDirtyObjects(this);
Jamie Madill1b94d432015-08-07 13:23:23 -04002681}
2682
Jamie Madillad9f24e2016-02-12 09:27:24 -05002683void Context::syncRendererState(const State::DirtyBits &bitMask,
2684 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002685{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002686 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
Frank Henigman5a53d542017-02-16 21:24:10 -05002687 mImplementation->syncState(dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002688 mGLState.clearDirtyBits(dirtyBits);
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002689 mGLState.syncDirtyObjects(this, objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002690}
Jamie Madillc29968b2016-01-20 11:17:23 -05002691
2692void Context::blitFramebuffer(GLint srcX0,
2693 GLint srcY0,
2694 GLint srcX1,
2695 GLint srcY1,
2696 GLint dstX0,
2697 GLint dstY0,
2698 GLint dstX1,
2699 GLint dstY1,
2700 GLbitfield mask,
2701 GLenum filter)
2702{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002703 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002704 ASSERT(drawFramebuffer);
2705
2706 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2707 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2708
Jamie Madillad9f24e2016-02-12 09:27:24 -05002709 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002710
Jamie Madill8415b5f2016-04-26 13:41:39 -04002711 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002712}
Jamie Madillc29968b2016-01-20 11:17:23 -05002713
2714void Context::clear(GLbitfield mask)
2715{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002716 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002717 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002718}
2719
2720void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2721{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002722 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002723 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2724 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002725}
2726
2727void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2728{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002729 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002730 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2731 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002732}
2733
2734void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2735{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002736 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002737 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2738 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002739}
2740
2741void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2742{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002743 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002744 ASSERT(framebufferObject);
2745
2746 // If a buffer is not present, the clear has no effect
2747 if (framebufferObject->getDepthbuffer() == nullptr &&
2748 framebufferObject->getStencilbuffer() == nullptr)
2749 {
2750 return;
2751 }
2752
Jamie Madillad9f24e2016-02-12 09:27:24 -05002753 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002754 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2755 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002756}
2757
2758void Context::readPixels(GLint x,
2759 GLint y,
2760 GLsizei width,
2761 GLsizei height,
2762 GLenum format,
2763 GLenum type,
2764 GLvoid *pixels)
2765{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002766 if (width == 0 || height == 0)
2767 {
2768 return;
2769 }
2770
Jamie Madillad9f24e2016-02-12 09:27:24 -05002771 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002772
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002773 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002774 ASSERT(framebufferObject);
2775
2776 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002777 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002778}
2779
2780void Context::copyTexImage2D(GLenum target,
2781 GLint level,
2782 GLenum internalformat,
2783 GLint x,
2784 GLint y,
2785 GLsizei width,
2786 GLsizei height,
2787 GLint border)
2788{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002789 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002790 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002791
Jamie Madillc29968b2016-01-20 11:17:23 -05002792 Rectangle sourceArea(x, y, width, height);
2793
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002794 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002795 Texture *texture =
2796 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002797 handleError(texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002798}
2799
2800void Context::copyTexSubImage2D(GLenum target,
2801 GLint level,
2802 GLint xoffset,
2803 GLint yoffset,
2804 GLint x,
2805 GLint y,
2806 GLsizei width,
2807 GLsizei height)
2808{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002809 if (width == 0 || height == 0)
2810 {
2811 return;
2812 }
2813
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002814 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002815 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002816
Jamie Madillc29968b2016-01-20 11:17:23 -05002817 Offset destOffset(xoffset, yoffset, 0);
2818 Rectangle sourceArea(x, y, width, height);
2819
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002820 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002821 Texture *texture =
2822 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002823 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002824}
2825
2826void Context::copyTexSubImage3D(GLenum target,
2827 GLint level,
2828 GLint xoffset,
2829 GLint yoffset,
2830 GLint zoffset,
2831 GLint x,
2832 GLint y,
2833 GLsizei width,
2834 GLsizei height)
2835{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002836 if (width == 0 || height == 0)
2837 {
2838 return;
2839 }
2840
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002841 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002842 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002843
Jamie Madillc29968b2016-01-20 11:17:23 -05002844 Offset destOffset(xoffset, yoffset, zoffset);
2845 Rectangle sourceArea(x, y, width, height);
2846
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002847 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002848 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002849 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002850}
2851
2852void Context::framebufferTexture2D(GLenum target,
2853 GLenum attachment,
2854 GLenum textarget,
2855 GLuint texture,
2856 GLint level)
2857{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002858 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002859 ASSERT(framebuffer);
2860
2861 if (texture != 0)
2862 {
2863 Texture *textureObj = getTexture(texture);
2864
2865 ImageIndex index = ImageIndex::MakeInvalid();
2866
2867 if (textarget == GL_TEXTURE_2D)
2868 {
2869 index = ImageIndex::Make2D(level);
2870 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08002871 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
2872 {
2873 ASSERT(level == 0);
2874 index = ImageIndex::Make2DMultisample();
2875 }
Jamie Madillc29968b2016-01-20 11:17:23 -05002876 else
2877 {
2878 ASSERT(IsCubeMapTextureTarget(textarget));
2879 index = ImageIndex::MakeCube(textarget, level);
2880 }
2881
Jamie Madilla02315b2017-02-23 14:14:47 -05002882 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
Jamie Madillc29968b2016-01-20 11:17:23 -05002883 }
2884 else
2885 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002886 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002887 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002888
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002889 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002890}
2891
2892void Context::framebufferRenderbuffer(GLenum target,
2893 GLenum attachment,
2894 GLenum renderbuffertarget,
2895 GLuint renderbuffer)
2896{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002897 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002898 ASSERT(framebuffer);
2899
2900 if (renderbuffer != 0)
2901 {
2902 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
Jamie Madilla02315b2017-02-23 14:14:47 -05002903
2904 framebuffer->setAttachment(this, GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
Jamie Madillc29968b2016-01-20 11:17:23 -05002905 renderbufferObject);
2906 }
2907 else
2908 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002909 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002910 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002911
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002912 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002913}
2914
2915void Context::framebufferTextureLayer(GLenum target,
2916 GLenum attachment,
2917 GLuint texture,
2918 GLint level,
2919 GLint layer)
2920{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002921 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002922 ASSERT(framebuffer);
2923
2924 if (texture != 0)
2925 {
2926 Texture *textureObject = getTexture(texture);
2927
2928 ImageIndex index = ImageIndex::MakeInvalid();
2929
2930 if (textureObject->getTarget() == GL_TEXTURE_3D)
2931 {
2932 index = ImageIndex::Make3D(level, layer);
2933 }
2934 else
2935 {
2936 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2937 index = ImageIndex::Make2DArray(level, layer);
2938 }
2939
Jamie Madilla02315b2017-02-23 14:14:47 -05002940 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObject);
Jamie Madillc29968b2016-01-20 11:17:23 -05002941 }
2942 else
2943 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002944 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002945 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002946
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002947 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002948}
2949
2950void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2951{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002952 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002953 ASSERT(framebuffer);
2954 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002955 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002956}
2957
2958void Context::readBuffer(GLenum mode)
2959{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002960 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002961 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002962 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002963}
2964
2965void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2966{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002967 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002968 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002969
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002970 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002971 ASSERT(framebuffer);
2972
2973 // The specification isn't clear what should be done when the framebuffer isn't complete.
2974 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002975 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002976}
2977
2978void Context::invalidateFramebuffer(GLenum target,
2979 GLsizei numAttachments,
2980 const GLenum *attachments)
2981{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002982 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002983 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002984
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002985 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002986 ASSERT(framebuffer);
2987
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002988 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002989 {
Jamie Madill437fa652016-05-03 15:13:24 -04002990 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002991 }
Jamie Madill437fa652016-05-03 15:13:24 -04002992
2993 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002994}
2995
2996void Context::invalidateSubFramebuffer(GLenum target,
2997 GLsizei numAttachments,
2998 const GLenum *attachments,
2999 GLint x,
3000 GLint y,
3001 GLsizei width,
3002 GLsizei height)
3003{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003004 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003005 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003006
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003007 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003008 ASSERT(framebuffer);
3009
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003010 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003011 {
Jamie Madill437fa652016-05-03 15:13:24 -04003012 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003013 }
Jamie Madill437fa652016-05-03 15:13:24 -04003014
3015 Rectangle area(x, y, width, height);
3016 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05003017}
3018
Jamie Madill73a84962016-02-12 09:27:23 -05003019void Context::texImage2D(GLenum target,
3020 GLint level,
3021 GLint internalformat,
3022 GLsizei width,
3023 GLsizei height,
3024 GLint border,
3025 GLenum format,
3026 GLenum type,
3027 const GLvoid *pixels)
3028{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003029 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003030
3031 Extents size(width, height, 1);
3032 Texture *texture =
3033 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003034 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3035 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003036}
3037
3038void Context::texImage3D(GLenum target,
3039 GLint level,
3040 GLint internalformat,
3041 GLsizei width,
3042 GLsizei height,
3043 GLsizei depth,
3044 GLint border,
3045 GLenum format,
3046 GLenum type,
3047 const GLvoid *pixels)
3048{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003049 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003050
3051 Extents size(width, height, depth);
3052 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003053 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3054 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003055}
3056
3057void Context::texSubImage2D(GLenum target,
3058 GLint level,
3059 GLint xoffset,
3060 GLint yoffset,
3061 GLsizei width,
3062 GLsizei height,
3063 GLenum format,
3064 GLenum type,
3065 const GLvoid *pixels)
3066{
3067 // Zero sized uploads are valid but no-ops
3068 if (width == 0 || height == 0)
3069 {
3070 return;
3071 }
3072
Jamie Madillad9f24e2016-02-12 09:27:24 -05003073 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003074
3075 Box area(xoffset, yoffset, 0, width, height, 1);
3076 Texture *texture =
3077 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003078 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3079 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003080}
3081
3082void Context::texSubImage3D(GLenum target,
3083 GLint level,
3084 GLint xoffset,
3085 GLint yoffset,
3086 GLint zoffset,
3087 GLsizei width,
3088 GLsizei height,
3089 GLsizei depth,
3090 GLenum format,
3091 GLenum type,
3092 const GLvoid *pixels)
3093{
3094 // Zero sized uploads are valid but no-ops
3095 if (width == 0 || height == 0 || depth == 0)
3096 {
3097 return;
3098 }
3099
Jamie Madillad9f24e2016-02-12 09:27:24 -05003100 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003101
3102 Box area(xoffset, yoffset, zoffset, width, height, depth);
3103 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003104 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3105 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003106}
3107
3108void Context::compressedTexImage2D(GLenum target,
3109 GLint level,
3110 GLenum internalformat,
3111 GLsizei width,
3112 GLsizei height,
3113 GLint border,
3114 GLsizei imageSize,
3115 const GLvoid *data)
3116{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003117 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003118
3119 Extents size(width, height, 1);
3120 Texture *texture =
3121 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003122 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003123 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003124 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003125}
3126
3127void Context::compressedTexImage3D(GLenum target,
3128 GLint level,
3129 GLenum internalformat,
3130 GLsizei width,
3131 GLsizei height,
3132 GLsizei depth,
3133 GLint border,
3134 GLsizei imageSize,
3135 const GLvoid *data)
3136{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003137 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003138
3139 Extents size(width, height, depth);
3140 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003141 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003142 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003143 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003144}
3145
3146void Context::compressedTexSubImage2D(GLenum target,
3147 GLint level,
3148 GLint xoffset,
3149 GLint yoffset,
3150 GLsizei width,
3151 GLsizei height,
3152 GLenum format,
3153 GLsizei imageSize,
3154 const GLvoid *data)
3155{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003156 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003157
3158 Box area(xoffset, yoffset, 0, width, height, 1);
3159 Texture *texture =
3160 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003161 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003162 format, imageSize,
3163 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003164}
3165
3166void Context::compressedTexSubImage3D(GLenum target,
3167 GLint level,
3168 GLint xoffset,
3169 GLint yoffset,
3170 GLint zoffset,
3171 GLsizei width,
3172 GLsizei height,
3173 GLsizei depth,
3174 GLenum format,
3175 GLsizei imageSize,
3176 const GLvoid *data)
3177{
3178 // Zero sized uploads are valid but no-ops
3179 if (width == 0 || height == 0)
3180 {
3181 return;
3182 }
3183
Jamie Madillad9f24e2016-02-12 09:27:24 -05003184 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003185
3186 Box area(xoffset, yoffset, zoffset, width, height, depth);
3187 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003188 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003189 format, imageSize,
3190 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003191}
3192
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003193void Context::generateMipmap(GLenum target)
3194{
3195 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003196 handleError(texture->generateMipmap(this));
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003197}
3198
Geoff Lang97073d12016-04-20 10:42:34 -07003199void Context::copyTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003200 GLint sourceLevel,
3201 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003202 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003203 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003204 GLint internalFormat,
3205 GLenum destType,
3206 GLboolean unpackFlipY,
3207 GLboolean unpackPremultiplyAlpha,
3208 GLboolean unpackUnmultiplyAlpha)
3209{
3210 syncStateForTexImage();
3211
3212 gl::Texture *sourceTexture = getTexture(sourceId);
3213 gl::Texture *destTexture = getTexture(destId);
Geoff Langfc72a072017-03-24 14:52:39 -04003214 handleError(destTexture->copyTexture(
3215 this, destTarget, destLevel, internalFormat, destType, sourceLevel, unpackFlipY == GL_TRUE,
3216 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003217}
3218
3219void Context::copySubTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003220 GLint sourceLevel,
3221 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003222 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003223 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003224 GLint xoffset,
3225 GLint yoffset,
3226 GLint x,
3227 GLint y,
3228 GLsizei width,
3229 GLsizei height,
3230 GLboolean unpackFlipY,
3231 GLboolean unpackPremultiplyAlpha,
3232 GLboolean unpackUnmultiplyAlpha)
3233{
3234 // Zero sized copies are valid but no-ops
3235 if (width == 0 || height == 0)
3236 {
3237 return;
3238 }
3239
3240 syncStateForTexImage();
3241
3242 gl::Texture *sourceTexture = getTexture(sourceId);
3243 gl::Texture *destTexture = getTexture(destId);
3244 Offset offset(xoffset, yoffset, 0);
3245 Rectangle area(x, y, width, height);
Geoff Langfc72a072017-03-24 14:52:39 -04003246 handleError(destTexture->copySubTexture(
3247 this, destTarget, destLevel, offset, sourceLevel, area, unpackFlipY == GL_TRUE,
3248 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003249}
3250
Geoff Lang47110bf2016-04-20 11:13:22 -07003251void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3252{
3253 syncStateForTexImage();
3254
3255 gl::Texture *sourceTexture = getTexture(sourceId);
3256 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003257 handleError(destTexture->copyCompressedTexture(this, sourceTexture));
Geoff Lang47110bf2016-04-20 11:13:22 -07003258}
3259
Geoff Lang496c02d2016-10-20 11:38:11 -07003260void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003261{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003262 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003263 ASSERT(buffer);
3264
Geoff Lang496c02d2016-10-20 11:38:11 -07003265 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003266}
3267
3268GLvoid *Context::mapBuffer(GLenum target, GLenum access)
3269{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003270 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003271 ASSERT(buffer);
3272
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003273 Error error = buffer->map(this, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003274 if (error.isError())
3275 {
Jamie Madill437fa652016-05-03 15:13:24 -04003276 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003277 return nullptr;
3278 }
3279
3280 return buffer->getMapPointer();
3281}
3282
3283GLboolean Context::unmapBuffer(GLenum target)
3284{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003285 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003286 ASSERT(buffer);
3287
3288 GLboolean result;
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003289 Error error = buffer->unmap(this, &result);
Olli Etuaho4f667482016-03-30 15:56:35 +03003290 if (error.isError())
3291 {
Jamie Madill437fa652016-05-03 15:13:24 -04003292 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003293 return GL_FALSE;
3294 }
3295
3296 return result;
3297}
3298
3299GLvoid *Context::mapBufferRange(GLenum target,
3300 GLintptr offset,
3301 GLsizeiptr length,
3302 GLbitfield access)
3303{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003304 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003305 ASSERT(buffer);
3306
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003307 Error error = buffer->mapRange(this, offset, length, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003308 if (error.isError())
3309 {
Jamie Madill437fa652016-05-03 15:13:24 -04003310 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003311 return nullptr;
3312 }
3313
3314 return buffer->getMapPointer();
3315}
3316
3317void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3318{
3319 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3320}
3321
Jamie Madillad9f24e2016-02-12 09:27:24 -05003322void Context::syncStateForReadPixels()
3323{
3324 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3325}
3326
3327void Context::syncStateForTexImage()
3328{
3329 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3330}
3331
3332void Context::syncStateForClear()
3333{
3334 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3335}
3336
3337void Context::syncStateForBlit()
3338{
3339 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3340}
3341
Jamie Madillc20ab272016-06-09 07:20:46 -07003342void Context::activeTexture(GLenum texture)
3343{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003344 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003345}
3346
3347void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3348{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003349 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003350}
3351
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003352void Context::blendEquation(GLenum mode)
3353{
3354 mGLState.setBlendEquation(mode, mode);
3355}
3356
Jamie Madillc20ab272016-06-09 07:20:46 -07003357void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3358{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003359 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003360}
3361
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003362void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3363{
3364 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3365}
3366
Jamie Madillc20ab272016-06-09 07:20:46 -07003367void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3368{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003369 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003370}
3371
3372void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3373{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003374 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003375}
3376
3377void Context::clearDepthf(GLclampf depth)
3378{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003379 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003380}
3381
3382void Context::clearStencil(GLint s)
3383{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003384 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003385}
3386
3387void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3388{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003389 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003390}
3391
3392void Context::cullFace(GLenum mode)
3393{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003394 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003395}
3396
3397void Context::depthFunc(GLenum func)
3398{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003399 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003400}
3401
3402void Context::depthMask(GLboolean flag)
3403{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003404 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003405}
3406
3407void Context::depthRangef(GLclampf zNear, GLclampf zFar)
3408{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003409 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003410}
3411
3412void Context::disable(GLenum cap)
3413{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003414 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003415}
3416
3417void Context::disableVertexAttribArray(GLuint index)
3418{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003419 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003420}
3421
3422void Context::enable(GLenum cap)
3423{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003424 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003425}
3426
3427void Context::enableVertexAttribArray(GLuint index)
3428{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003429 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003430}
3431
3432void Context::frontFace(GLenum mode)
3433{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003434 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003435}
3436
3437void Context::hint(GLenum target, GLenum mode)
3438{
3439 switch (target)
3440 {
3441 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003442 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003443 break;
3444
3445 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003446 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003447 break;
3448
3449 default:
3450 UNREACHABLE();
3451 return;
3452 }
3453}
3454
3455void Context::lineWidth(GLfloat width)
3456{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003457 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003458}
3459
3460void Context::pixelStorei(GLenum pname, GLint param)
3461{
3462 switch (pname)
3463 {
3464 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003465 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003466 break;
3467
3468 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003469 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003470 break;
3471
3472 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003473 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003474 break;
3475
3476 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003477 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003478 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003479 break;
3480
3481 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003482 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003483 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003484 break;
3485
3486 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003487 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003488 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003489 break;
3490
3491 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003492 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003493 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003494 break;
3495
3496 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003497 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003498 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003499 break;
3500
3501 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003502 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003503 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003504 break;
3505
3506 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003507 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003508 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003509 break;
3510
3511 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003512 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003513 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003514 break;
3515
3516 default:
3517 UNREACHABLE();
3518 return;
3519 }
3520}
3521
3522void Context::polygonOffset(GLfloat factor, GLfloat units)
3523{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003524 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003525}
3526
3527void Context::sampleCoverage(GLclampf value, GLboolean invert)
3528{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003529 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003530}
3531
3532void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3533{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003534 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003535}
3536
3537void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3538{
3539 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3540 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003541 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003542 }
3543
3544 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3545 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003546 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003547 }
3548}
3549
3550void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3551{
3552 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3553 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003554 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003555 }
3556
3557 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3558 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003559 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003560 }
3561}
3562
3563void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3564{
3565 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3566 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003567 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003568 }
3569
3570 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3571 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003572 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003573 }
3574}
3575
3576void Context::vertexAttrib1f(GLuint index, GLfloat x)
3577{
3578 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003579 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003580}
3581
3582void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3583{
3584 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003585 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003586}
3587
3588void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3589{
3590 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003591 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003592}
3593
3594void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3595{
3596 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003597 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003598}
3599
3600void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3601{
3602 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003603 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003604}
3605
3606void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3607{
3608 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003609 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003610}
3611
3612void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3613{
3614 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003615 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003616}
3617
3618void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3619{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003620 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003621}
3622
3623void Context::vertexAttribPointer(GLuint index,
3624 GLint size,
3625 GLenum type,
3626 GLboolean normalized,
3627 GLsizei stride,
3628 const GLvoid *ptr)
3629{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003630 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3631 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003632}
3633
Shao80957d92017-02-20 21:25:59 +08003634void Context::vertexAttribFormat(GLuint attribIndex,
3635 GLint size,
3636 GLenum type,
3637 GLboolean normalized,
3638 GLuint relativeOffset)
3639{
3640 mGLState.setVertexAttribFormat(attribIndex, size, type, normalized == GL_TRUE, false,
3641 relativeOffset);
3642}
3643
3644void Context::vertexAttribIFormat(GLuint attribIndex,
3645 GLint size,
3646 GLenum type,
3647 GLuint relativeOffset)
3648{
3649 mGLState.setVertexAttribFormat(attribIndex, size, type, false, true, relativeOffset);
3650}
3651
3652void Context::vertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
3653{
3654 mGLState.setVertexAttribBinding(attribIndex, bindingIndex);
3655}
3656
3657void Context::setVertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
3658{
3659 mGLState.setVertexBindingDivisor(bindingIndex, divisor);
3660}
3661
Jamie Madillc20ab272016-06-09 07:20:46 -07003662void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3663{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003664 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003665}
3666
3667void Context::vertexAttribIPointer(GLuint index,
3668 GLint size,
3669 GLenum type,
3670 GLsizei stride,
3671 const GLvoid *pointer)
3672{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003673 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3674 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003675}
3676
3677void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3678{
3679 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003680 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003681}
3682
3683void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3684{
3685 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003686 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003687}
3688
3689void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3690{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003691 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003692}
3693
3694void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3695{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003696 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003697}
3698
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003699void Context::getVertexAttribiv(GLuint index, GLenum pname, GLint *params)
3700{
3701 const VertexAttribCurrentValueData &currentValues =
3702 getGLState().getVertexAttribCurrentValue(index);
3703 const VertexArray *vao = getGLState().getVertexArray();
3704 QueryVertexAttribiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3705 currentValues, pname, params);
3706}
3707
3708void Context::getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
3709{
3710 const VertexAttribCurrentValueData &currentValues =
3711 getGLState().getVertexAttribCurrentValue(index);
3712 const VertexArray *vao = getGLState().getVertexArray();
3713 QueryVertexAttribfv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3714 currentValues, pname, params);
3715}
3716
3717void Context::getVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
3718{
3719 const VertexAttribCurrentValueData &currentValues =
3720 getGLState().getVertexAttribCurrentValue(index);
3721 const VertexArray *vao = getGLState().getVertexArray();
3722 QueryVertexAttribIiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3723 currentValues, pname, params);
3724}
3725
3726void Context::getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
3727{
3728 const VertexAttribCurrentValueData &currentValues =
3729 getGLState().getVertexAttribCurrentValue(index);
3730 const VertexArray *vao = getGLState().getVertexArray();
3731 QueryVertexAttribIuiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3732 currentValues, pname, params);
3733}
3734
3735void Context::getVertexAttribPointerv(GLuint index, GLenum pname, GLvoid **pointer)
3736{
3737 const VertexAttribute &attrib = getGLState().getVertexArray()->getVertexAttribute(index);
3738 QueryVertexAttribPointerv(attrib, pname, pointer);
3739}
3740
Jamie Madillc20ab272016-06-09 07:20:46 -07003741void Context::debugMessageControl(GLenum source,
3742 GLenum type,
3743 GLenum severity,
3744 GLsizei count,
3745 const GLuint *ids,
3746 GLboolean enabled)
3747{
3748 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003749 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3750 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003751}
3752
3753void Context::debugMessageInsert(GLenum source,
3754 GLenum type,
3755 GLuint id,
3756 GLenum severity,
3757 GLsizei length,
3758 const GLchar *buf)
3759{
3760 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003761 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003762}
3763
3764void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3765{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003766 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003767}
3768
3769GLuint Context::getDebugMessageLog(GLuint count,
3770 GLsizei bufSize,
3771 GLenum *sources,
3772 GLenum *types,
3773 GLuint *ids,
3774 GLenum *severities,
3775 GLsizei *lengths,
3776 GLchar *messageLog)
3777{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003778 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3779 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003780}
3781
3782void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3783{
3784 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003785 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003786}
3787
3788void Context::popDebugGroup()
3789{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003790 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003791}
3792
Jamie Madill29639852016-09-02 15:00:09 -04003793void Context::bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
3794{
3795 Buffer *buffer = mGLState.getTargetBuffer(target);
3796 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003797 handleError(buffer->bufferData(this, target, data, size, usage));
Jamie Madill29639852016-09-02 15:00:09 -04003798}
3799
3800void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
3801{
3802 if (data == nullptr)
3803 {
3804 return;
3805 }
3806
3807 Buffer *buffer = mGLState.getTargetBuffer(target);
3808 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003809 handleError(buffer->bufferSubData(this, target, data, size, offset));
Jamie Madill29639852016-09-02 15:00:09 -04003810}
3811
Jamie Madillef300b12016-10-07 15:12:09 -04003812void Context::attachShader(GLuint program, GLuint shader)
3813{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003814 auto programObject = mState.mShaderPrograms->getProgram(program);
3815 auto shaderObject = mState.mShaderPrograms->getShader(shader);
Jamie Madillef300b12016-10-07 15:12:09 -04003816 ASSERT(programObject && shaderObject);
3817 programObject->attachShader(shaderObject);
3818}
3819
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003820const Workarounds &Context::getWorkarounds() const
3821{
3822 return mWorkarounds;
3823}
3824
Jamie Madillb0817d12016-11-01 15:48:31 -04003825void Context::copyBufferSubData(GLenum readTarget,
3826 GLenum writeTarget,
3827 GLintptr readOffset,
3828 GLintptr writeOffset,
3829 GLsizeiptr size)
3830{
3831 // if size is zero, the copy is a successful no-op
3832 if (size == 0)
3833 {
3834 return;
3835 }
3836
3837 // TODO(jmadill): cache these.
3838 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3839 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3840
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003841 handleError(writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size));
Jamie Madillb0817d12016-11-01 15:48:31 -04003842}
3843
Jamie Madill01a80ee2016-11-07 12:06:18 -05003844void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3845{
3846 Program *programObject = getProgram(program);
3847 // TODO(jmadill): Re-use this from the validation if possible.
3848 ASSERT(programObject);
3849 programObject->bindAttributeLocation(index, name);
3850}
3851
3852void Context::bindBuffer(GLenum target, GLuint buffer)
3853{
3854 switch (target)
3855 {
3856 case GL_ARRAY_BUFFER:
3857 bindArrayBuffer(buffer);
3858 break;
3859 case GL_ELEMENT_ARRAY_BUFFER:
3860 bindElementArrayBuffer(buffer);
3861 break;
3862 case GL_COPY_READ_BUFFER:
3863 bindCopyReadBuffer(buffer);
3864 break;
3865 case GL_COPY_WRITE_BUFFER:
3866 bindCopyWriteBuffer(buffer);
3867 break;
3868 case GL_PIXEL_PACK_BUFFER:
3869 bindPixelPackBuffer(buffer);
3870 break;
3871 case GL_PIXEL_UNPACK_BUFFER:
3872 bindPixelUnpackBuffer(buffer);
3873 break;
3874 case GL_UNIFORM_BUFFER:
3875 bindGenericUniformBuffer(buffer);
3876 break;
3877 case GL_TRANSFORM_FEEDBACK_BUFFER:
3878 bindGenericTransformFeedbackBuffer(buffer);
3879 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003880 case GL_ATOMIC_COUNTER_BUFFER:
Jiajia Qin6eafb042016-12-27 17:04:07 +08003881 bindGenericAtomicCounterBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003882 break;
3883 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08003884 bindGenericShaderStorageBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003885 break;
3886 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08003887 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003888 break;
3889 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003890 if (buffer != 0)
3891 {
3892 // Binding buffers to this binding point is not implemented yet.
3893 UNIMPLEMENTED();
3894 }
Geoff Lang3b573612016-10-31 14:08:10 -04003895 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05003896
3897 default:
3898 UNREACHABLE();
3899 break;
3900 }
3901}
3902
Jiajia Qin6eafb042016-12-27 17:04:07 +08003903void Context::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
3904{
3905 bindBufferRange(target, index, buffer, 0, 0);
3906}
3907
3908void Context::bindBufferRange(GLenum target,
3909 GLuint index,
3910 GLuint buffer,
3911 GLintptr offset,
3912 GLsizeiptr size)
3913{
3914 switch (target)
3915 {
3916 case GL_TRANSFORM_FEEDBACK_BUFFER:
3917 bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
3918 bindGenericTransformFeedbackBuffer(buffer);
3919 break;
3920 case GL_UNIFORM_BUFFER:
3921 bindIndexedUniformBuffer(buffer, index, offset, size);
3922 bindGenericUniformBuffer(buffer);
3923 break;
3924 case GL_ATOMIC_COUNTER_BUFFER:
3925 bindIndexedAtomicCounterBuffer(buffer, index, offset, size);
3926 bindGenericAtomicCounterBuffer(buffer);
3927 break;
3928 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08003929 bindIndexedShaderStorageBuffer(buffer, index, offset, size);
3930 bindGenericShaderStorageBuffer(buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08003931 break;
3932 default:
3933 UNREACHABLE();
3934 break;
3935 }
3936}
3937
Jamie Madill01a80ee2016-11-07 12:06:18 -05003938void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
3939{
3940 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3941 {
3942 bindReadFramebuffer(framebuffer);
3943 }
3944
3945 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3946 {
3947 bindDrawFramebuffer(framebuffer);
3948 }
3949}
3950
3951void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
3952{
3953 ASSERT(target == GL_RENDERBUFFER);
3954 Renderbuffer *object =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003955 mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
Jamie Madill01a80ee2016-11-07 12:06:18 -05003956 mGLState.setRenderbufferBinding(object);
3957}
3958
JiangYizhoubddc46b2016-12-09 09:50:51 +08003959void Context::texStorage2DMultisample(GLenum target,
3960 GLsizei samples,
3961 GLenum internalformat,
3962 GLsizei width,
3963 GLsizei height,
3964 GLboolean fixedsamplelocations)
3965{
3966 Extents size(width, height, 1);
3967 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003968 handleError(texture->setStorageMultisample(this, target, samples, internalformat, size,
JiangYizhoubddc46b2016-12-09 09:50:51 +08003969 fixedsamplelocations));
3970}
3971
3972void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
3973{
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003974 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
JiangYizhoubddc46b2016-12-09 09:50:51 +08003975 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
3976
3977 switch (pname)
3978 {
3979 case GL_SAMPLE_POSITION:
3980 handleError(framebuffer->getSamplePosition(index, val));
3981 break;
3982 default:
3983 UNREACHABLE();
3984 }
3985}
3986
Jamie Madille8fb6402017-02-14 17:56:40 -05003987void Context::renderbufferStorage(GLenum target,
3988 GLenum internalformat,
3989 GLsizei width,
3990 GLsizei height)
3991{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05003992 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
3993 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
3994
Jamie Madille8fb6402017-02-14 17:56:40 -05003995 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05003996 handleError(renderbuffer->setStorage(convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05003997}
3998
3999void Context::renderbufferStorageMultisample(GLenum target,
4000 GLsizei samples,
4001 GLenum internalformat,
4002 GLsizei width,
4003 GLsizei height)
4004{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004005 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4006 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
Jamie Madille8fb6402017-02-14 17:56:40 -05004007
4008 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004009 handleError(
4010 renderbuffer->setStorageMultisample(samples, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004011}
4012
JiangYizhoue18e6392017-02-20 10:32:23 +08004013void Context::getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
4014{
4015 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4016 QueryFramebufferParameteriv(framebuffer, pname, params);
4017}
4018
4019void Context::setFramebufferParameteri(GLenum target, GLenum pname, GLint param)
4020{
4021 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4022 SetFramebufferParameteri(framebuffer, pname, param);
4023}
4024
Jamie Madille14951e2017-03-09 18:55:16 -05004025Error Context::getScratchBuffer(size_t requestedSize, angle::MemoryBuffer **scratchBufferOut) const
4026{
4027 if (!mScratchBuffer.get(requestedSize, scratchBufferOut))
4028 {
4029 return gl::OutOfMemory() << "Failed to allocate internal buffer.";
4030 }
4031 return gl::NoError();
4032}
4033
Jamie Madillc29968b2016-01-20 11:17:23 -05004034} // namespace gl