blob: a8a5ade25c1e3a43cc8847e0f7544fde8853fb6c [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 Langc339c4e2016-11-29 10:37:36 -05002514}
2515
2516size_t Context::getRequestableExtensionStringCount() const
2517{
2518 return mRequestableExtensionStrings.size();
2519}
2520
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002521void Context::beginTransformFeedback(GLenum primitiveMode)
2522{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002523 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002524 ASSERT(transformFeedback != nullptr);
2525 ASSERT(!transformFeedback->isPaused());
2526
Jamie Madill6c1f6712017-02-14 19:08:04 -05002527 transformFeedback->begin(this, primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002528}
2529
2530bool Context::hasActiveTransformFeedback(GLuint program) const
2531{
2532 for (auto pair : mTransformFeedbackMap)
2533 {
2534 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2535 {
2536 return true;
2537 }
2538 }
2539 return false;
2540}
2541
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002542void Context::initCaps(const egl::DisplayExtensions &displayExtensions)
Geoff Lang493daf52014-07-03 13:38:44 -04002543{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002544 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002545
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002546 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002547
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002548 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002549
Geoff Langeb66a6e2016-10-31 13:06:12 -04002550 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002551 {
2552 // Disable ES3+ extensions
2553 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002554 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002555 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002556 }
2557
Geoff Langeb66a6e2016-10-31 13:06:12 -04002558 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002559 {
2560 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2561 //mExtensions.sRGB = false;
2562 }
2563
Jamie Madill00ed7a12016-05-19 13:13:38 -04002564 // Some extensions are always available because they are implemented in the GL layer.
2565 mExtensions.bindUniformLocation = true;
2566 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002567 mExtensions.bindGeneratesResource = true;
Geoff Langfeb8c682017-02-13 16:07:35 -05002568 mExtensions.clientArrays = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002569 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002570
2571 // Enable the no error extension if the context was created with the flag.
2572 mExtensions.noError = mSkipValidation;
2573
Corentin Wallezccab69d2017-01-27 16:57:15 -05002574 // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
Corentin Wallezc295e512017-01-27 17:47:50 -05002575 mExtensions.surfacelessContext = displayExtensions.surfacelessContext;
Corentin Wallezccab69d2017-01-27 16:57:15 -05002576
Geoff Lang70d0f492015-12-10 17:45:46 -05002577 // Explicitly enable GL_KHR_debug
2578 mExtensions.debug = true;
2579 mExtensions.maxDebugMessageLength = 1024;
2580 mExtensions.maxDebugLoggedMessages = 1024;
2581 mExtensions.maxDebugGroupStackDepth = 1024;
2582 mExtensions.maxLabelLength = 1024;
2583
Geoff Langff5b2d52016-09-07 11:32:23 -04002584 // Explicitly enable GL_ANGLE_robust_client_memory
2585 mExtensions.robustClientMemory = true;
2586
Jamie Madille08a1d32017-03-07 17:24:06 -05002587 // Determine robust resource init availability from EGL.
2588 mExtensions.robustResourceInitialization =
2589 displayExtensions.createContextRobustResourceInitialization;
2590
Geoff Lang301d1612014-07-09 10:34:37 -04002591 // Apply implementation limits
2592 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002593 mCaps.maxVertexAttribBindings =
2594 getClientVersion() < ES_3_1
2595 ? mCaps.maxVertexAttributes
2596 : std::min<GLuint>(mCaps.maxVertexAttribBindings, MAX_VERTEX_ATTRIB_BINDINGS);
2597
Geoff Lang301d1612014-07-09 10:34:37 -04002598 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2599 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2600
2601 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002602
Geoff Langc287ea62016-09-16 14:46:51 -04002603 // WebGL compatibility
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002604 mExtensions.webglCompatibility = mWebGLContext;
Geoff Langc287ea62016-09-16 14:46:51 -04002605 for (const auto &extensionInfo : GetExtensionInfoMap())
2606 {
2607 // If this context is for WebGL, disable all enableable extensions
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002608 if (mWebGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002609 {
2610 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2611 }
2612 }
2613
2614 // Generate texture caps
2615 updateCaps();
2616}
2617
2618void Context::updateCaps()
2619{
Geoff Lang900013c2014-07-07 11:32:19 -04002620 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002621 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002622
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002623 for (auto capsIt : mImplementation->getNativeTextureCaps())
Geoff Lang493daf52014-07-03 13:38:44 -04002624 {
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002625 GLenum format = capsIt.first;
2626 TextureCaps formatCaps = capsIt.second;
Geoff Lang493daf52014-07-03 13:38:44 -04002627
Geoff Lang5d601382014-07-22 15:14:06 -04002628 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002629
Geoff Lang0d8b7242015-09-09 14:56:53 -04002630 // Update the format caps based on the client version and extensions.
2631 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2632 // ES3.
2633 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002634 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002635 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002636 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002637 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002638 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002639
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002640 // OpenGL ES does not support multisampling with non-rendererable formats
2641 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
2642 if (!formatInfo.renderSupport ||
2643 (getClientVersion() < ES_3_1 &&
2644 (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
Geoff Lang493daf52014-07-03 13:38:44 -04002645 {
Geoff Langd87878e2014-09-19 15:42:59 -04002646 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002647 }
Geoff Langd87878e2014-09-19 15:42:59 -04002648
2649 if (formatCaps.texturable && formatInfo.compressed)
2650 {
2651 mCaps.compressedTextureFormats.push_back(format);
2652 }
2653
2654 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002655 }
2656}
2657
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002658void Context::initWorkarounds()
2659{
2660 // Lose the context upon out of memory error if the application is
2661 // expecting to watch for those events.
2662 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2663}
2664
Jamie Madill1b94d432015-08-07 13:23:23 -04002665void Context::syncRendererState()
2666{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002667 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
Frank Henigman5a53d542017-02-16 21:24:10 -05002668 mImplementation->syncState(dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002669 mGLState.clearDirtyBits();
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002670 mGLState.syncDirtyObjects(this);
Jamie Madill1b94d432015-08-07 13:23:23 -04002671}
2672
Jamie Madillad9f24e2016-02-12 09:27:24 -05002673void Context::syncRendererState(const State::DirtyBits &bitMask,
2674 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002675{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002676 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
Frank Henigman5a53d542017-02-16 21:24:10 -05002677 mImplementation->syncState(dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002678 mGLState.clearDirtyBits(dirtyBits);
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002679 mGLState.syncDirtyObjects(this, objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002680}
Jamie Madillc29968b2016-01-20 11:17:23 -05002681
2682void Context::blitFramebuffer(GLint srcX0,
2683 GLint srcY0,
2684 GLint srcX1,
2685 GLint srcY1,
2686 GLint dstX0,
2687 GLint dstY0,
2688 GLint dstX1,
2689 GLint dstY1,
2690 GLbitfield mask,
2691 GLenum filter)
2692{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002693 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002694 ASSERT(drawFramebuffer);
2695
2696 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2697 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2698
Jamie Madillad9f24e2016-02-12 09:27:24 -05002699 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002700
Jamie Madill8415b5f2016-04-26 13:41:39 -04002701 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002702}
Jamie Madillc29968b2016-01-20 11:17:23 -05002703
2704void Context::clear(GLbitfield mask)
2705{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002706 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002707 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002708}
2709
2710void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2711{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002712 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002713 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2714 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002715}
2716
2717void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2718{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002719 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002720 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2721 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002722}
2723
2724void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2725{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002726 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002727 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2728 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002729}
2730
2731void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2732{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002733 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002734 ASSERT(framebufferObject);
2735
2736 // If a buffer is not present, the clear has no effect
2737 if (framebufferObject->getDepthbuffer() == nullptr &&
2738 framebufferObject->getStencilbuffer() == nullptr)
2739 {
2740 return;
2741 }
2742
Jamie Madillad9f24e2016-02-12 09:27:24 -05002743 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002744 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2745 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002746}
2747
2748void Context::readPixels(GLint x,
2749 GLint y,
2750 GLsizei width,
2751 GLsizei height,
2752 GLenum format,
2753 GLenum type,
2754 GLvoid *pixels)
2755{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002756 if (width == 0 || height == 0)
2757 {
2758 return;
2759 }
2760
Jamie Madillad9f24e2016-02-12 09:27:24 -05002761 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002762
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002763 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002764 ASSERT(framebufferObject);
2765
2766 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002767 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002768}
2769
2770void Context::copyTexImage2D(GLenum target,
2771 GLint level,
2772 GLenum internalformat,
2773 GLint x,
2774 GLint y,
2775 GLsizei width,
2776 GLsizei height,
2777 GLint border)
2778{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002779 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002780 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002781
Jamie Madillc29968b2016-01-20 11:17:23 -05002782 Rectangle sourceArea(x, y, width, height);
2783
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002784 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002785 Texture *texture =
2786 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002787 handleError(texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002788}
2789
2790void Context::copyTexSubImage2D(GLenum target,
2791 GLint level,
2792 GLint xoffset,
2793 GLint yoffset,
2794 GLint x,
2795 GLint y,
2796 GLsizei width,
2797 GLsizei height)
2798{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002799 if (width == 0 || height == 0)
2800 {
2801 return;
2802 }
2803
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002804 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002805 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002806
Jamie Madillc29968b2016-01-20 11:17:23 -05002807 Offset destOffset(xoffset, yoffset, 0);
2808 Rectangle sourceArea(x, y, width, height);
2809
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002810 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002811 Texture *texture =
2812 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002813 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002814}
2815
2816void Context::copyTexSubImage3D(GLenum target,
2817 GLint level,
2818 GLint xoffset,
2819 GLint yoffset,
2820 GLint zoffset,
2821 GLint x,
2822 GLint y,
2823 GLsizei width,
2824 GLsizei height)
2825{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002826 if (width == 0 || height == 0)
2827 {
2828 return;
2829 }
2830
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002831 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002832 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002833
Jamie Madillc29968b2016-01-20 11:17:23 -05002834 Offset destOffset(xoffset, yoffset, zoffset);
2835 Rectangle sourceArea(x, y, width, height);
2836
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002837 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002838 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002839 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002840}
2841
2842void Context::framebufferTexture2D(GLenum target,
2843 GLenum attachment,
2844 GLenum textarget,
2845 GLuint texture,
2846 GLint level)
2847{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002848 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002849 ASSERT(framebuffer);
2850
2851 if (texture != 0)
2852 {
2853 Texture *textureObj = getTexture(texture);
2854
2855 ImageIndex index = ImageIndex::MakeInvalid();
2856
2857 if (textarget == GL_TEXTURE_2D)
2858 {
2859 index = ImageIndex::Make2D(level);
2860 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08002861 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
2862 {
2863 ASSERT(level == 0);
2864 index = ImageIndex::Make2DMultisample();
2865 }
Jamie Madillc29968b2016-01-20 11:17:23 -05002866 else
2867 {
2868 ASSERT(IsCubeMapTextureTarget(textarget));
2869 index = ImageIndex::MakeCube(textarget, level);
2870 }
2871
Jamie Madilla02315b2017-02-23 14:14:47 -05002872 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
Jamie Madillc29968b2016-01-20 11:17:23 -05002873 }
2874 else
2875 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002876 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002877 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002878
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002879 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002880}
2881
2882void Context::framebufferRenderbuffer(GLenum target,
2883 GLenum attachment,
2884 GLenum renderbuffertarget,
2885 GLuint renderbuffer)
2886{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002887 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002888 ASSERT(framebuffer);
2889
2890 if (renderbuffer != 0)
2891 {
2892 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
Jamie Madilla02315b2017-02-23 14:14:47 -05002893
2894 framebuffer->setAttachment(this, GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
Jamie Madillc29968b2016-01-20 11:17:23 -05002895 renderbufferObject);
2896 }
2897 else
2898 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002899 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002900 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002901
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002902 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002903}
2904
2905void Context::framebufferTextureLayer(GLenum target,
2906 GLenum attachment,
2907 GLuint texture,
2908 GLint level,
2909 GLint layer)
2910{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002911 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002912 ASSERT(framebuffer);
2913
2914 if (texture != 0)
2915 {
2916 Texture *textureObject = getTexture(texture);
2917
2918 ImageIndex index = ImageIndex::MakeInvalid();
2919
2920 if (textureObject->getTarget() == GL_TEXTURE_3D)
2921 {
2922 index = ImageIndex::Make3D(level, layer);
2923 }
2924 else
2925 {
2926 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2927 index = ImageIndex::Make2DArray(level, layer);
2928 }
2929
Jamie Madilla02315b2017-02-23 14:14:47 -05002930 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObject);
Jamie Madillc29968b2016-01-20 11:17:23 -05002931 }
2932 else
2933 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002934 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002935 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002936
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002937 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002938}
2939
2940void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2941{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002942 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002943 ASSERT(framebuffer);
2944 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002945 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002946}
2947
2948void Context::readBuffer(GLenum mode)
2949{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002950 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002951 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002952 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002953}
2954
2955void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2956{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002957 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002958 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002959
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002960 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002961 ASSERT(framebuffer);
2962
2963 // The specification isn't clear what should be done when the framebuffer isn't complete.
2964 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002965 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002966}
2967
2968void Context::invalidateFramebuffer(GLenum target,
2969 GLsizei numAttachments,
2970 const GLenum *attachments)
2971{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002972 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002973 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002974
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002975 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002976 ASSERT(framebuffer);
2977
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002978 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002979 {
Jamie Madill437fa652016-05-03 15:13:24 -04002980 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002981 }
Jamie Madill437fa652016-05-03 15:13:24 -04002982
2983 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002984}
2985
2986void Context::invalidateSubFramebuffer(GLenum target,
2987 GLsizei numAttachments,
2988 const GLenum *attachments,
2989 GLint x,
2990 GLint y,
2991 GLsizei width,
2992 GLsizei height)
2993{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002994 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002995 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002996
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002997 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002998 ASSERT(framebuffer);
2999
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003000 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003001 {
Jamie Madill437fa652016-05-03 15:13:24 -04003002 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003003 }
Jamie Madill437fa652016-05-03 15:13:24 -04003004
3005 Rectangle area(x, y, width, height);
3006 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05003007}
3008
Jamie Madill73a84962016-02-12 09:27:23 -05003009void Context::texImage2D(GLenum target,
3010 GLint level,
3011 GLint internalformat,
3012 GLsizei width,
3013 GLsizei height,
3014 GLint border,
3015 GLenum format,
3016 GLenum type,
3017 const GLvoid *pixels)
3018{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003019 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003020
3021 Extents size(width, height, 1);
3022 Texture *texture =
3023 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003024 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3025 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003026}
3027
3028void Context::texImage3D(GLenum target,
3029 GLint level,
3030 GLint internalformat,
3031 GLsizei width,
3032 GLsizei height,
3033 GLsizei depth,
3034 GLint border,
3035 GLenum format,
3036 GLenum type,
3037 const GLvoid *pixels)
3038{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003039 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003040
3041 Extents size(width, height, depth);
3042 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003043 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3044 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003045}
3046
3047void Context::texSubImage2D(GLenum target,
3048 GLint level,
3049 GLint xoffset,
3050 GLint yoffset,
3051 GLsizei width,
3052 GLsizei height,
3053 GLenum format,
3054 GLenum type,
3055 const GLvoid *pixels)
3056{
3057 // Zero sized uploads are valid but no-ops
3058 if (width == 0 || height == 0)
3059 {
3060 return;
3061 }
3062
Jamie Madillad9f24e2016-02-12 09:27:24 -05003063 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003064
3065 Box area(xoffset, yoffset, 0, width, height, 1);
3066 Texture *texture =
3067 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003068 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3069 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003070}
3071
3072void Context::texSubImage3D(GLenum target,
3073 GLint level,
3074 GLint xoffset,
3075 GLint yoffset,
3076 GLint zoffset,
3077 GLsizei width,
3078 GLsizei height,
3079 GLsizei depth,
3080 GLenum format,
3081 GLenum type,
3082 const GLvoid *pixels)
3083{
3084 // Zero sized uploads are valid but no-ops
3085 if (width == 0 || height == 0 || depth == 0)
3086 {
3087 return;
3088 }
3089
Jamie Madillad9f24e2016-02-12 09:27:24 -05003090 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003091
3092 Box area(xoffset, yoffset, zoffset, width, height, depth);
3093 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003094 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3095 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003096}
3097
3098void Context::compressedTexImage2D(GLenum target,
3099 GLint level,
3100 GLenum internalformat,
3101 GLsizei width,
3102 GLsizei height,
3103 GLint border,
3104 GLsizei imageSize,
3105 const GLvoid *data)
3106{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003107 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003108
3109 Extents size(width, height, 1);
3110 Texture *texture =
3111 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003112 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003113 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003114 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003115}
3116
3117void Context::compressedTexImage3D(GLenum target,
3118 GLint level,
3119 GLenum internalformat,
3120 GLsizei width,
3121 GLsizei height,
3122 GLsizei depth,
3123 GLint border,
3124 GLsizei imageSize,
3125 const GLvoid *data)
3126{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003127 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003128
3129 Extents size(width, height, depth);
3130 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003131 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003132 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003133 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003134}
3135
3136void Context::compressedTexSubImage2D(GLenum target,
3137 GLint level,
3138 GLint xoffset,
3139 GLint yoffset,
3140 GLsizei width,
3141 GLsizei height,
3142 GLenum format,
3143 GLsizei imageSize,
3144 const GLvoid *data)
3145{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003146 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003147
3148 Box area(xoffset, yoffset, 0, width, height, 1);
3149 Texture *texture =
3150 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003151 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003152 format, imageSize,
3153 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003154}
3155
3156void Context::compressedTexSubImage3D(GLenum target,
3157 GLint level,
3158 GLint xoffset,
3159 GLint yoffset,
3160 GLint zoffset,
3161 GLsizei width,
3162 GLsizei height,
3163 GLsizei depth,
3164 GLenum format,
3165 GLsizei imageSize,
3166 const GLvoid *data)
3167{
3168 // Zero sized uploads are valid but no-ops
3169 if (width == 0 || height == 0)
3170 {
3171 return;
3172 }
3173
Jamie Madillad9f24e2016-02-12 09:27:24 -05003174 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003175
3176 Box area(xoffset, yoffset, zoffset, width, height, depth);
3177 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003178 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003179 format, imageSize,
3180 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003181}
3182
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003183void Context::generateMipmap(GLenum target)
3184{
3185 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003186 handleError(texture->generateMipmap(this));
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003187}
3188
Geoff Lang97073d12016-04-20 10:42:34 -07003189void Context::copyTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003190 GLint sourceLevel,
3191 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003192 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003193 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003194 GLint internalFormat,
3195 GLenum destType,
3196 GLboolean unpackFlipY,
3197 GLboolean unpackPremultiplyAlpha,
3198 GLboolean unpackUnmultiplyAlpha)
3199{
3200 syncStateForTexImage();
3201
3202 gl::Texture *sourceTexture = getTexture(sourceId);
3203 gl::Texture *destTexture = getTexture(destId);
Geoff Langfc72a072017-03-24 14:52:39 -04003204 handleError(destTexture->copyTexture(
3205 this, destTarget, destLevel, internalFormat, destType, sourceLevel, unpackFlipY == GL_TRUE,
3206 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003207}
3208
3209void Context::copySubTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003210 GLint sourceLevel,
3211 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003212 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003213 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003214 GLint xoffset,
3215 GLint yoffset,
3216 GLint x,
3217 GLint y,
3218 GLsizei width,
3219 GLsizei height,
3220 GLboolean unpackFlipY,
3221 GLboolean unpackPremultiplyAlpha,
3222 GLboolean unpackUnmultiplyAlpha)
3223{
3224 // Zero sized copies are valid but no-ops
3225 if (width == 0 || height == 0)
3226 {
3227 return;
3228 }
3229
3230 syncStateForTexImage();
3231
3232 gl::Texture *sourceTexture = getTexture(sourceId);
3233 gl::Texture *destTexture = getTexture(destId);
3234 Offset offset(xoffset, yoffset, 0);
3235 Rectangle area(x, y, width, height);
Geoff Langfc72a072017-03-24 14:52:39 -04003236 handleError(destTexture->copySubTexture(
3237 this, destTarget, destLevel, offset, sourceLevel, area, unpackFlipY == GL_TRUE,
3238 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003239}
3240
Geoff Lang47110bf2016-04-20 11:13:22 -07003241void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3242{
3243 syncStateForTexImage();
3244
3245 gl::Texture *sourceTexture = getTexture(sourceId);
3246 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003247 handleError(destTexture->copyCompressedTexture(this, sourceTexture));
Geoff Lang47110bf2016-04-20 11:13:22 -07003248}
3249
Geoff Lang496c02d2016-10-20 11:38:11 -07003250void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003251{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003252 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003253 ASSERT(buffer);
3254
Geoff Lang496c02d2016-10-20 11:38:11 -07003255 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003256}
3257
3258GLvoid *Context::mapBuffer(GLenum target, GLenum access)
3259{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003260 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003261 ASSERT(buffer);
3262
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003263 Error error = buffer->map(this, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003264 if (error.isError())
3265 {
Jamie Madill437fa652016-05-03 15:13:24 -04003266 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003267 return nullptr;
3268 }
3269
3270 return buffer->getMapPointer();
3271}
3272
3273GLboolean Context::unmapBuffer(GLenum target)
3274{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003275 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003276 ASSERT(buffer);
3277
3278 GLboolean result;
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003279 Error error = buffer->unmap(this, &result);
Olli Etuaho4f667482016-03-30 15:56:35 +03003280 if (error.isError())
3281 {
Jamie Madill437fa652016-05-03 15:13:24 -04003282 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003283 return GL_FALSE;
3284 }
3285
3286 return result;
3287}
3288
3289GLvoid *Context::mapBufferRange(GLenum target,
3290 GLintptr offset,
3291 GLsizeiptr length,
3292 GLbitfield access)
3293{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003294 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003295 ASSERT(buffer);
3296
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003297 Error error = buffer->mapRange(this, offset, length, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003298 if (error.isError())
3299 {
Jamie Madill437fa652016-05-03 15:13:24 -04003300 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003301 return nullptr;
3302 }
3303
3304 return buffer->getMapPointer();
3305}
3306
3307void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3308{
3309 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3310}
3311
Jamie Madillad9f24e2016-02-12 09:27:24 -05003312void Context::syncStateForReadPixels()
3313{
3314 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3315}
3316
3317void Context::syncStateForTexImage()
3318{
3319 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3320}
3321
3322void Context::syncStateForClear()
3323{
3324 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3325}
3326
3327void Context::syncStateForBlit()
3328{
3329 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3330}
3331
Jamie Madillc20ab272016-06-09 07:20:46 -07003332void Context::activeTexture(GLenum texture)
3333{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003334 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003335}
3336
3337void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3338{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003339 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003340}
3341
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003342void Context::blendEquation(GLenum mode)
3343{
3344 mGLState.setBlendEquation(mode, mode);
3345}
3346
Jamie Madillc20ab272016-06-09 07:20:46 -07003347void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3348{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003349 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003350}
3351
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003352void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3353{
3354 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3355}
3356
Jamie Madillc20ab272016-06-09 07:20:46 -07003357void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3358{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003359 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003360}
3361
3362void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3363{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003364 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003365}
3366
3367void Context::clearDepthf(GLclampf depth)
3368{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003369 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003370}
3371
3372void Context::clearStencil(GLint s)
3373{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003374 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003375}
3376
3377void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3378{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003379 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003380}
3381
3382void Context::cullFace(GLenum mode)
3383{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003384 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003385}
3386
3387void Context::depthFunc(GLenum func)
3388{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003389 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003390}
3391
3392void Context::depthMask(GLboolean flag)
3393{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003394 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003395}
3396
3397void Context::depthRangef(GLclampf zNear, GLclampf zFar)
3398{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003399 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003400}
3401
3402void Context::disable(GLenum cap)
3403{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003404 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003405}
3406
3407void Context::disableVertexAttribArray(GLuint index)
3408{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003409 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003410}
3411
3412void Context::enable(GLenum cap)
3413{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003414 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003415}
3416
3417void Context::enableVertexAttribArray(GLuint index)
3418{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003419 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003420}
3421
3422void Context::frontFace(GLenum mode)
3423{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003424 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003425}
3426
3427void Context::hint(GLenum target, GLenum mode)
3428{
3429 switch (target)
3430 {
3431 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003432 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003433 break;
3434
3435 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003436 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003437 break;
3438
3439 default:
3440 UNREACHABLE();
3441 return;
3442 }
3443}
3444
3445void Context::lineWidth(GLfloat width)
3446{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003447 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003448}
3449
3450void Context::pixelStorei(GLenum pname, GLint param)
3451{
3452 switch (pname)
3453 {
3454 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003455 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003456 break;
3457
3458 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003459 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003460 break;
3461
3462 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003463 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003464 break;
3465
3466 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003467 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003468 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003469 break;
3470
3471 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003472 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003473 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003474 break;
3475
3476 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003477 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003478 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003479 break;
3480
3481 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003482 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003483 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003484 break;
3485
3486 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003487 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003488 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003489 break;
3490
3491 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003492 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003493 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003494 break;
3495
3496 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003497 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003498 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003499 break;
3500
3501 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003502 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003503 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003504 break;
3505
3506 default:
3507 UNREACHABLE();
3508 return;
3509 }
3510}
3511
3512void Context::polygonOffset(GLfloat factor, GLfloat units)
3513{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003514 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003515}
3516
3517void Context::sampleCoverage(GLclampf value, GLboolean invert)
3518{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003519 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003520}
3521
3522void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3523{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003524 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003525}
3526
3527void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3528{
3529 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3530 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003531 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003532 }
3533
3534 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3535 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003536 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003537 }
3538}
3539
3540void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3541{
3542 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3543 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003544 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003545 }
3546
3547 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3548 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003549 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003550 }
3551}
3552
3553void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3554{
3555 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3556 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003557 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003558 }
3559
3560 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3561 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003562 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003563 }
3564}
3565
3566void Context::vertexAttrib1f(GLuint index, GLfloat x)
3567{
3568 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003569 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003570}
3571
3572void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3573{
3574 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003575 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003576}
3577
3578void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3579{
3580 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003581 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003582}
3583
3584void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3585{
3586 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003587 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003588}
3589
3590void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3591{
3592 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003593 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003594}
3595
3596void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3597{
3598 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003599 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003600}
3601
3602void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3603{
3604 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003605 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003606}
3607
3608void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3609{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003610 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003611}
3612
3613void Context::vertexAttribPointer(GLuint index,
3614 GLint size,
3615 GLenum type,
3616 GLboolean normalized,
3617 GLsizei stride,
3618 const GLvoid *ptr)
3619{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003620 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3621 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003622}
3623
Shao80957d92017-02-20 21:25:59 +08003624void Context::vertexAttribFormat(GLuint attribIndex,
3625 GLint size,
3626 GLenum type,
3627 GLboolean normalized,
3628 GLuint relativeOffset)
3629{
3630 mGLState.setVertexAttribFormat(attribIndex, size, type, normalized == GL_TRUE, false,
3631 relativeOffset);
3632}
3633
3634void Context::vertexAttribIFormat(GLuint attribIndex,
3635 GLint size,
3636 GLenum type,
3637 GLuint relativeOffset)
3638{
3639 mGLState.setVertexAttribFormat(attribIndex, size, type, false, true, relativeOffset);
3640}
3641
3642void Context::vertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
3643{
3644 mGLState.setVertexAttribBinding(attribIndex, bindingIndex);
3645}
3646
3647void Context::setVertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
3648{
3649 mGLState.setVertexBindingDivisor(bindingIndex, divisor);
3650}
3651
Jamie Madillc20ab272016-06-09 07:20:46 -07003652void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3653{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003654 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003655}
3656
3657void Context::vertexAttribIPointer(GLuint index,
3658 GLint size,
3659 GLenum type,
3660 GLsizei stride,
3661 const GLvoid *pointer)
3662{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003663 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3664 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003665}
3666
3667void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3668{
3669 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003670 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003671}
3672
3673void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3674{
3675 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003676 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003677}
3678
3679void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3680{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003681 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003682}
3683
3684void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3685{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003686 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003687}
3688
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003689void Context::getVertexAttribiv(GLuint index, GLenum pname, GLint *params)
3690{
3691 const VertexAttribCurrentValueData &currentValues =
3692 getGLState().getVertexAttribCurrentValue(index);
3693 const VertexArray *vao = getGLState().getVertexArray();
3694 QueryVertexAttribiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3695 currentValues, pname, params);
3696}
3697
3698void Context::getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
3699{
3700 const VertexAttribCurrentValueData &currentValues =
3701 getGLState().getVertexAttribCurrentValue(index);
3702 const VertexArray *vao = getGLState().getVertexArray();
3703 QueryVertexAttribfv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3704 currentValues, pname, params);
3705}
3706
3707void Context::getVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
3708{
3709 const VertexAttribCurrentValueData &currentValues =
3710 getGLState().getVertexAttribCurrentValue(index);
3711 const VertexArray *vao = getGLState().getVertexArray();
3712 QueryVertexAttribIiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3713 currentValues, pname, params);
3714}
3715
3716void Context::getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
3717{
3718 const VertexAttribCurrentValueData &currentValues =
3719 getGLState().getVertexAttribCurrentValue(index);
3720 const VertexArray *vao = getGLState().getVertexArray();
3721 QueryVertexAttribIuiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3722 currentValues, pname, params);
3723}
3724
3725void Context::getVertexAttribPointerv(GLuint index, GLenum pname, GLvoid **pointer)
3726{
3727 const VertexAttribute &attrib = getGLState().getVertexArray()->getVertexAttribute(index);
3728 QueryVertexAttribPointerv(attrib, pname, pointer);
3729}
3730
Jamie Madillc20ab272016-06-09 07:20:46 -07003731void Context::debugMessageControl(GLenum source,
3732 GLenum type,
3733 GLenum severity,
3734 GLsizei count,
3735 const GLuint *ids,
3736 GLboolean enabled)
3737{
3738 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003739 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3740 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003741}
3742
3743void Context::debugMessageInsert(GLenum source,
3744 GLenum type,
3745 GLuint id,
3746 GLenum severity,
3747 GLsizei length,
3748 const GLchar *buf)
3749{
3750 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003751 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003752}
3753
3754void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3755{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003756 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003757}
3758
3759GLuint Context::getDebugMessageLog(GLuint count,
3760 GLsizei bufSize,
3761 GLenum *sources,
3762 GLenum *types,
3763 GLuint *ids,
3764 GLenum *severities,
3765 GLsizei *lengths,
3766 GLchar *messageLog)
3767{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003768 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3769 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003770}
3771
3772void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3773{
3774 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003775 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003776}
3777
3778void Context::popDebugGroup()
3779{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003780 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003781}
3782
Jamie Madill29639852016-09-02 15:00:09 -04003783void Context::bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
3784{
3785 Buffer *buffer = mGLState.getTargetBuffer(target);
3786 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003787 handleError(buffer->bufferData(this, target, data, size, usage));
Jamie Madill29639852016-09-02 15:00:09 -04003788}
3789
3790void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
3791{
3792 if (data == nullptr)
3793 {
3794 return;
3795 }
3796
3797 Buffer *buffer = mGLState.getTargetBuffer(target);
3798 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003799 handleError(buffer->bufferSubData(this, target, data, size, offset));
Jamie Madill29639852016-09-02 15:00:09 -04003800}
3801
Jamie Madillef300b12016-10-07 15:12:09 -04003802void Context::attachShader(GLuint program, GLuint shader)
3803{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003804 auto programObject = mState.mShaderPrograms->getProgram(program);
3805 auto shaderObject = mState.mShaderPrograms->getShader(shader);
Jamie Madillef300b12016-10-07 15:12:09 -04003806 ASSERT(programObject && shaderObject);
3807 programObject->attachShader(shaderObject);
3808}
3809
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003810const Workarounds &Context::getWorkarounds() const
3811{
3812 return mWorkarounds;
3813}
3814
Jamie Madillb0817d12016-11-01 15:48:31 -04003815void Context::copyBufferSubData(GLenum readTarget,
3816 GLenum writeTarget,
3817 GLintptr readOffset,
3818 GLintptr writeOffset,
3819 GLsizeiptr size)
3820{
3821 // if size is zero, the copy is a successful no-op
3822 if (size == 0)
3823 {
3824 return;
3825 }
3826
3827 // TODO(jmadill): cache these.
3828 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3829 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3830
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003831 handleError(writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size));
Jamie Madillb0817d12016-11-01 15:48:31 -04003832}
3833
Jamie Madill01a80ee2016-11-07 12:06:18 -05003834void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3835{
3836 Program *programObject = getProgram(program);
3837 // TODO(jmadill): Re-use this from the validation if possible.
3838 ASSERT(programObject);
3839 programObject->bindAttributeLocation(index, name);
3840}
3841
3842void Context::bindBuffer(GLenum target, GLuint buffer)
3843{
3844 switch (target)
3845 {
3846 case GL_ARRAY_BUFFER:
3847 bindArrayBuffer(buffer);
3848 break;
3849 case GL_ELEMENT_ARRAY_BUFFER:
3850 bindElementArrayBuffer(buffer);
3851 break;
3852 case GL_COPY_READ_BUFFER:
3853 bindCopyReadBuffer(buffer);
3854 break;
3855 case GL_COPY_WRITE_BUFFER:
3856 bindCopyWriteBuffer(buffer);
3857 break;
3858 case GL_PIXEL_PACK_BUFFER:
3859 bindPixelPackBuffer(buffer);
3860 break;
3861 case GL_PIXEL_UNPACK_BUFFER:
3862 bindPixelUnpackBuffer(buffer);
3863 break;
3864 case GL_UNIFORM_BUFFER:
3865 bindGenericUniformBuffer(buffer);
3866 break;
3867 case GL_TRANSFORM_FEEDBACK_BUFFER:
3868 bindGenericTransformFeedbackBuffer(buffer);
3869 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003870 case GL_ATOMIC_COUNTER_BUFFER:
Jiajia Qin6eafb042016-12-27 17:04:07 +08003871 bindGenericAtomicCounterBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003872 break;
3873 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08003874 bindGenericShaderStorageBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003875 break;
3876 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08003877 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003878 break;
3879 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003880 if (buffer != 0)
3881 {
3882 // Binding buffers to this binding point is not implemented yet.
3883 UNIMPLEMENTED();
3884 }
Geoff Lang3b573612016-10-31 14:08:10 -04003885 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05003886
3887 default:
3888 UNREACHABLE();
3889 break;
3890 }
3891}
3892
Jiajia Qin6eafb042016-12-27 17:04:07 +08003893void Context::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
3894{
3895 bindBufferRange(target, index, buffer, 0, 0);
3896}
3897
3898void Context::bindBufferRange(GLenum target,
3899 GLuint index,
3900 GLuint buffer,
3901 GLintptr offset,
3902 GLsizeiptr size)
3903{
3904 switch (target)
3905 {
3906 case GL_TRANSFORM_FEEDBACK_BUFFER:
3907 bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
3908 bindGenericTransformFeedbackBuffer(buffer);
3909 break;
3910 case GL_UNIFORM_BUFFER:
3911 bindIndexedUniformBuffer(buffer, index, offset, size);
3912 bindGenericUniformBuffer(buffer);
3913 break;
3914 case GL_ATOMIC_COUNTER_BUFFER:
3915 bindIndexedAtomicCounterBuffer(buffer, index, offset, size);
3916 bindGenericAtomicCounterBuffer(buffer);
3917 break;
3918 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08003919 bindIndexedShaderStorageBuffer(buffer, index, offset, size);
3920 bindGenericShaderStorageBuffer(buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08003921 break;
3922 default:
3923 UNREACHABLE();
3924 break;
3925 }
3926}
3927
Jamie Madill01a80ee2016-11-07 12:06:18 -05003928void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
3929{
3930 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3931 {
3932 bindReadFramebuffer(framebuffer);
3933 }
3934
3935 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3936 {
3937 bindDrawFramebuffer(framebuffer);
3938 }
3939}
3940
3941void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
3942{
3943 ASSERT(target == GL_RENDERBUFFER);
3944 Renderbuffer *object =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003945 mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
Jamie Madill01a80ee2016-11-07 12:06:18 -05003946 mGLState.setRenderbufferBinding(object);
3947}
3948
JiangYizhoubddc46b2016-12-09 09:50:51 +08003949void Context::texStorage2DMultisample(GLenum target,
3950 GLsizei samples,
3951 GLenum internalformat,
3952 GLsizei width,
3953 GLsizei height,
3954 GLboolean fixedsamplelocations)
3955{
3956 Extents size(width, height, 1);
3957 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003958 handleError(texture->setStorageMultisample(this, target, samples, internalformat, size,
JiangYizhoubddc46b2016-12-09 09:50:51 +08003959 fixedsamplelocations));
3960}
3961
3962void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
3963{
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003964 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
JiangYizhoubddc46b2016-12-09 09:50:51 +08003965 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
3966
3967 switch (pname)
3968 {
3969 case GL_SAMPLE_POSITION:
3970 handleError(framebuffer->getSamplePosition(index, val));
3971 break;
3972 default:
3973 UNREACHABLE();
3974 }
3975}
3976
Jamie Madille8fb6402017-02-14 17:56:40 -05003977void Context::renderbufferStorage(GLenum target,
3978 GLenum internalformat,
3979 GLsizei width,
3980 GLsizei height)
3981{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05003982 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
3983 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
3984
Jamie Madille8fb6402017-02-14 17:56:40 -05003985 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05003986 handleError(renderbuffer->setStorage(convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05003987}
3988
3989void Context::renderbufferStorageMultisample(GLenum target,
3990 GLsizei samples,
3991 GLenum internalformat,
3992 GLsizei width,
3993 GLsizei height)
3994{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05003995 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
3996 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
Jamie Madille8fb6402017-02-14 17:56:40 -05003997
3998 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05003999 handleError(
4000 renderbuffer->setStorageMultisample(samples, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004001}
4002
JiangYizhoue18e6392017-02-20 10:32:23 +08004003void Context::getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
4004{
4005 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4006 QueryFramebufferParameteriv(framebuffer, pname, params);
4007}
4008
4009void Context::setFramebufferParameteri(GLenum target, GLenum pname, GLint param)
4010{
4011 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4012 SetFramebufferParameteri(framebuffer, pname, param);
4013}
4014
Jamie Madille14951e2017-03-09 18:55:16 -05004015Error Context::getScratchBuffer(size_t requestedSize, angle::MemoryBuffer **scratchBufferOut) const
4016{
4017 if (!mScratchBuffer.get(requestedSize, scratchBufferOut))
4018 {
4019 return gl::OutOfMemory() << "Failed to allocate internal buffer.";
4020 }
4021 return gl::NoError();
4022}
4023
Jamie Madillc29968b2016-01-20 11:17:23 -05004024} // namespace gl