blob: 8213f3d6bd9700b57a74ef8d31731b0f37c4e10a [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 Madill231c7f52017-04-26 13:45:37 -040012#include <string.h>
Jamie Madillb9293972015-02-19 11:07:54 -050013#include <iterator>
14#include <sstream>
Sami Väisänend59ca052016-06-21 16:10:00 +030015#include <vector>
Jamie Madillb9293972015-02-19 11:07:54 -050016
Sami Väisänene45e53b2016-05-25 10:36:04 +030017#include "common/matrix_utils.h"
Geoff Lang0b7eef72014-06-12 14:10:47 -040018#include "common/platform.h"
Jamie Madillb9293972015-02-19 11:07:54 -050019#include "common/utilities.h"
Geoff Langc339c4e2016-11-29 10:37:36 -050020#include "common/version.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050021#include "libANGLE/Buffer.h"
Jamie Madillb9293972015-02-19 11:07:54 -050022#include "libANGLE/Compiler.h"
Jamie Madill948bbe52017-06-01 13:10:42 -040023#include "libANGLE/Display.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050024#include "libANGLE/Fence.h"
25#include "libANGLE/Framebuffer.h"
26#include "libANGLE/FramebufferAttachment.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030027#include "libANGLE/Path.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050028#include "libANGLE/Program.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050029#include "libANGLE/Query.h"
Jamie Madillb9293972015-02-19 11:07:54 -050030#include "libANGLE/Renderbuffer.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050031#include "libANGLE/ResourceManager.h"
32#include "libANGLE/Sampler.h"
Jamie Madill9dd0cf02014-11-24 11:38:51 -050033#include "libANGLE/Surface.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050034#include "libANGLE/Texture.h"
35#include "libANGLE/TransformFeedback.h"
36#include "libANGLE/VertexArray.h"
Kenneth Russellf2f6f652016-10-05 19:53:23 -070037#include "libANGLE/Workarounds.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040038#include "libANGLE/formatutils.h"
Martin Radev66fb8202016-07-28 11:45:20 +030039#include "libANGLE/queryconversions.h"
Geoff Langc1984ed2016-10-07 12:41:00 -040040#include "libANGLE/queryutils.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040041#include "libANGLE/renderer/ContextImpl.h"
42#include "libANGLE/renderer/EGLImplFactory.h"
43#include "libANGLE/validationES.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
Martin Radev9d901792016-07-15 15:58:58 +0300207std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
208{
209 std::string labelName;
210 if (label != nullptr)
211 {
212 size_t labelLength = length < 0 ? strlen(label) : length;
213 labelName = std::string(label, labelLength);
214 }
215 return labelName;
216}
217
218void GetObjectLabelBase(const std::string &objectLabel,
219 GLsizei bufSize,
220 GLsizei *length,
221 GLchar *label)
222{
223 size_t writeLength = objectLabel.length();
224 if (label != nullptr && bufSize > 0)
225 {
226 writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
227 std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
228 label[writeLength] = '\0';
229 }
230
231 if (length != nullptr)
232 {
233 *length = static_cast<GLsizei>(writeLength);
234 }
235}
236
Geoff Langf6db0982015-08-25 13:04:00 -0400237} // anonymous namespace
238
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000239namespace gl
240{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000241
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400242Context::Context(rx::EGLImplFactory *implFactory,
243 const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400244 const Context *shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500245 TextureManager *shareTextures,
Corentin Wallezc295e512017-01-27 17:47:50 -0500246 const egl::AttributeMap &attribs,
Jamie Madill948bbe52017-06-01 13:10:42 -0400247 const egl::DisplayExtensions &displayExtensions,
248 bool robustResourceInit)
Martin Radev1be913c2016-07-11 17:59:16 +0300249
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500250 : ValidationContext(shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500251 shareTextures,
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500252 GetClientVersion(attribs),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700253 &mGLState,
Jamie Madillf25855c2015-11-03 11:06:18 -0500254 mCaps,
255 mTextureCaps,
256 mExtensions,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500257 mLimitations,
258 GetNoError(attribs)),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700259 mImplementation(implFactory->createContext(mState)),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500260 mCompiler(nullptr),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400261 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500262 mClientType(EGL_OPENGL_ES_API),
263 mHasBeenCurrent(false),
264 mContextLost(false),
265 mResetStatus(GL_NO_ERROR),
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700266 mContextLostForced(false),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500267 mResetStrategy(GetResetStrategy(attribs)),
268 mRobustAccess(GetRobustAccess(attribs)),
Corentin Wallezccab69d2017-01-27 16:57:15 -0500269 mCurrentSurface(nullptr),
Jamie Madill4e0e6f82017-02-17 11:06:03 -0500270 mSurfacelessFramebuffer(nullptr),
Jamie Madille14951e2017-03-09 18:55:16 -0500271 mWebGLContext(GetWebGLContext(attribs)),
272 mScratchBuffer(1000u)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000273{
Geoff Lang077f20a2016-11-01 10:08:02 -0400274 if (mRobustAccess)
275 {
276 UNIMPLEMENTED();
277 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000278
Jamie Madill4e0e6f82017-02-17 11:06:03 -0500279 initCaps(displayExtensions);
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700280 initWorkarounds();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400281
Geoff Langeb66a6e2016-10-31 13:06:12 -0400282 mGLState.initialize(mCaps, mExtensions, getClientVersion(), GetDebug(attribs),
Jamie Madille08a1d32017-03-07 17:24:06 -0500283 GetBindGeneratesResource(attribs), GetClientArraysEnabled(attribs),
Jamie Madill948bbe52017-06-01 13:10:42 -0400284 robustResourceInit);
Régis Fénéon83107972015-02-05 12:57:44 +0100285
Shannon Woods53a94a82014-06-24 15:20:36 -0400286 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400287
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000288 // [OpenGL ES 2.0.24] section 3.7 page 83:
289 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
290 // and cube map texture state vectors respectively associated with them.
291 // In order that access to these initial textures not be lost, they are treated as texture
292 // objects all of whose names are 0.
293
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400294 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500295 mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500296
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400297 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500298 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400299
Geoff Langeb66a6e2016-10-31 13:06:12 -0400300 if (getClientVersion() >= Version(3, 0))
Geoff Lang76b10c92014-09-05 16:28:14 -0400301 {
302 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400303 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500304 mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400305
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400306 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500307 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400308 }
Geoff Lang3b573612016-10-31 14:08:10 -0400309 if (getClientVersion() >= Version(3, 1))
310 {
311 Texture *zeroTexture2DMultisample =
312 new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_MULTISAMPLE);
313 mZeroTextures[GL_TEXTURE_2D_MULTISAMPLE].set(zeroTexture2DMultisample);
Jiajia Qin6eafb042016-12-27 17:04:07 +0800314
315 bindGenericAtomicCounterBuffer(0);
316 for (unsigned int i = 0; i < mCaps.maxAtomicCounterBufferBindings; i++)
317 {
318 bindIndexedAtomicCounterBuffer(0, i, 0, 0);
319 }
Jiajia Qinf546e7d2017-03-27 14:12:59 +0800320
321 bindGenericShaderStorageBuffer(0);
322 for (unsigned int i = 0; i < mCaps.maxShaderStorageBufferBindings; i++)
323 {
324 bindIndexedShaderStorageBuffer(0, i, 0, 0);
325 }
Geoff Lang3b573612016-10-31 14:08:10 -0400326 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000327
Ian Ewellbda75592016-04-18 17:25:54 -0400328 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
329 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400330 Texture *zeroTextureExternal =
331 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Ian Ewellbda75592016-04-18 17:25:54 -0400332 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(zeroTextureExternal);
333 }
334
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700335 mGLState.initializeZeroTextures(mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500336
Jamie Madill57a89722013-07-02 11:57:03 -0400337 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000338 bindArrayBuffer(0);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800339 bindDrawIndirectBuffer(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000340 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400341
Jamie Madill01a80ee2016-11-07 12:06:18 -0500342 bindRenderbuffer(GL_RENDERBUFFER, 0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000343
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000344 bindGenericUniformBuffer(0);
Geoff Lang4dc3af02016-11-18 14:09:27 -0500345 for (unsigned int i = 0; i < mCaps.maxUniformBufferBindings; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000346 {
347 bindIndexedUniformBuffer(0, i, 0, -1);
348 }
349
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000350 bindCopyReadBuffer(0);
351 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000352 bindPixelPackBuffer(0);
353 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000354
Geoff Langeb66a6e2016-10-31 13:06:12 -0400355 if (getClientVersion() >= Version(3, 0))
Geoff Lang1a683462015-09-29 15:09:59 -0400356 {
357 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
358 // In the initial state, a default transform feedback object is bound and treated as
359 // a transform feedback object with a name of zero. That object is bound any time
360 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400361 bindTransformFeedback(0);
362 }
Geoff Langc8058452014-02-03 12:04:11 -0500363
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700364 mCompiler = new Compiler(mImplementation.get(), mState);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500365
366 // Initialize dirty bit masks
367 // TODO(jmadill): additional ES3 state
368 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
369 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
370 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
371 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
372 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
373 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400374 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500375 // No dirty objects.
376
377 // Readpixels uses the pack state and read FBO
378 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
379 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
380 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
381 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
382 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400383 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500384 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
385
386 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
387 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
388 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
389 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
390 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
391 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
392 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
393 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
394 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
395 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
396 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
397 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
398
399 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
400 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700401 mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500402 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
403 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400404
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400405 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000406}
407
Jamie Madill70ee0f62017-02-06 16:04:20 -0500408void Context::destroy(egl::Display *display)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000409{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500410 mGLState.reset(this);
Geoff Lang21329412014-12-02 20:50:30 +0000411
Corentin Wallez80b24112015-08-25 16:41:57 -0400412 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000413 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400414 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000415 }
416
Corentin Wallez80b24112015-08-25 16:41:57 -0400417 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000418 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400419 if (query.second != nullptr)
420 {
421 query.second->release();
422 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000423 }
424
Corentin Wallez80b24112015-08-25 16:41:57 -0400425 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400426 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400427 SafeDelete(vertexArray.second);
Jamie Madill57a89722013-07-02 11:57:03 -0400428 }
429
Corentin Wallez80b24112015-08-25 16:41:57 -0400430 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500431 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500432 if (transformFeedback.second != nullptr)
433 {
Jamie Madill6c1f6712017-02-14 19:08:04 -0500434 transformFeedback.second->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500435 }
Geoff Langc8058452014-02-03 12:04:11 -0500436 }
437
Jamie Madilldedd7b92014-11-05 16:30:36 -0500438 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400439 {
Yunchao Hef81ce4a2017-04-24 10:49:17 +0800440 zeroTexture.second.set(nullptr);
Geoff Lang76b10c92014-09-05 16:28:14 -0400441 }
442 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000443
Corentin Wallezccab69d2017-01-27 16:57:15 -0500444 SafeDelete(mSurfacelessFramebuffer);
445
Jamie Madill70ee0f62017-02-06 16:04:20 -0500446 releaseSurface(display);
Corentin Wallez51706ea2015-08-07 14:39:22 -0400447
Geoff Lang492a7e42014-11-05 13:27:06 -0500448 SafeDelete(mCompiler);
Jamie Madill6c1f6712017-02-14 19:08:04 -0500449
450 mState.mBuffers->release(this);
451 mState.mShaderPrograms->release(this);
452 mState.mTextures->release(this);
453 mState.mRenderbuffers->release(this);
454 mState.mSamplers->release(this);
455 mState.mFenceSyncs->release(this);
456 mState.mPaths->release(this);
457 mState.mFramebuffers->release(this);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000458}
459
Jamie Madill70ee0f62017-02-06 16:04:20 -0500460Context::~Context()
461{
462}
463
464void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000465{
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000466 if (!mHasBeenCurrent)
467 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000468 initRendererString();
Geoff Langc339c4e2016-11-29 10:37:36 -0500469 initVersionStrings();
Geoff Langcec35902014-04-16 10:52:36 -0400470 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000471
Corentin Wallezc295e512017-01-27 17:47:50 -0500472 int width = 0;
473 int height = 0;
474 if (surface != nullptr)
475 {
476 width = surface->getWidth();
477 height = surface->getHeight();
478 }
479
480 mGLState.setViewportParams(0, 0, width, height);
481 mGLState.setScissorParams(0, 0, width, height);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000482
483 mHasBeenCurrent = true;
484 }
485
Jamie Madill1b94d432015-08-07 13:23:23 -0400486 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700487 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400488
Jamie Madill70ee0f62017-02-06 16:04:20 -0500489 releaseSurface(display);
Corentin Wallezccab69d2017-01-27 16:57:15 -0500490
491 Framebuffer *newDefault = nullptr;
492 if (surface != nullptr)
493 {
Jamie Madill70ee0f62017-02-06 16:04:20 -0500494 surface->setIsCurrent(display, true);
Corentin Wallezccab69d2017-01-27 16:57:15 -0500495 mCurrentSurface = surface;
496 newDefault = surface->getDefaultFramebuffer();
497 }
498 else
499 {
500 if (mSurfacelessFramebuffer == nullptr)
501 {
502 mSurfacelessFramebuffer = new Framebuffer(mImplementation.get());
503 }
504
505 newDefault = mSurfacelessFramebuffer;
506 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000507
Corentin Wallez37c39792015-08-20 14:19:46 -0400508 // Update default framebuffer, the binding of the previous default
509 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400510 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700511 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400512 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700513 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400514 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700515 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400516 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700517 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400518 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500519 mState.mFramebuffers->setDefaultFramebuffer(newDefault);
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400520 }
Ian Ewell292f0052016-02-04 10:37:32 -0500521
522 // Notify the renderer of a context switch
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700523 mImplementation->onMakeCurrent(mState);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000524}
525
Jamie Madill70ee0f62017-02-06 16:04:20 -0500526void Context::releaseSurface(egl::Display *display)
Jamie Madill77a72f62015-04-14 11:18:32 -0400527{
Corentin Wallez37c39792015-08-20 14:19:46 -0400528 // Remove the default framebuffer
Corentin Wallezc295e512017-01-27 17:47:50 -0500529 Framebuffer *currentDefault = nullptr;
530 if (mCurrentSurface != nullptr)
Corentin Wallez51706ea2015-08-07 14:39:22 -0400531 {
Corentin Wallezc295e512017-01-27 17:47:50 -0500532 currentDefault = mCurrentSurface->getDefaultFramebuffer();
533 }
534 else if (mSurfacelessFramebuffer != nullptr)
535 {
536 currentDefault = mSurfacelessFramebuffer;
Corentin Wallez51706ea2015-08-07 14:39:22 -0400537 }
538
Corentin Wallezc295e512017-01-27 17:47:50 -0500539 if (mGLState.getReadFramebuffer() == currentDefault)
540 {
541 mGLState.setReadFramebufferBinding(nullptr);
542 }
543 if (mGLState.getDrawFramebuffer() == currentDefault)
544 {
545 mGLState.setDrawFramebufferBinding(nullptr);
546 }
547 mState.mFramebuffers->setDefaultFramebuffer(nullptr);
548
549 if (mCurrentSurface)
550 {
Jamie Madill70ee0f62017-02-06 16:04:20 -0500551 mCurrentSurface->setIsCurrent(display, false);
Corentin Wallezc295e512017-01-27 17:47:50 -0500552 mCurrentSurface = nullptr;
553 }
Jamie Madill77a72f62015-04-14 11:18:32 -0400554}
555
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000556GLuint Context::createBuffer()
557{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500558 return mState.mBuffers->createBuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000559}
560
561GLuint Context::createProgram()
562{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500563 return mState.mShaderPrograms->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000564}
565
566GLuint Context::createShader(GLenum type)
567{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500568 return mState.mShaderPrograms->createShader(mImplementation.get(), mLimitations, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000569}
570
571GLuint Context::createTexture()
572{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500573 return mState.mTextures->createTexture();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000574}
575
576GLuint Context::createRenderbuffer()
577{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500578 return mState.mRenderbuffers->createRenderbuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000579}
580
Geoff Lang882033e2014-09-30 11:26:07 -0400581GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400582{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500583 GLuint handle = mState.mFenceSyncs->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400584
Cooper Partind8e62a32015-01-29 15:21:25 -0800585 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400586}
587
Sami Väisänene45e53b2016-05-25 10:36:04 +0300588GLuint Context::createPaths(GLsizei range)
589{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500590 auto resultOrError = mState.mPaths->createPaths(mImplementation.get(), range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300591 if (resultOrError.isError())
592 {
593 handleError(resultOrError.getError());
594 return 0;
595 }
596 return resultOrError.getResult();
597}
598
Jamie Madill57a89722013-07-02 11:57:03 -0400599GLuint Context::createVertexArray()
600{
Geoff Lang36167ab2015-12-07 10:27:14 -0500601 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
602 mVertexArrayMap[vertexArray] = nullptr;
603 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400604}
605
Jamie Madilldc356042013-07-19 16:36:57 -0400606GLuint Context::createSampler()
607{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500608 return mState.mSamplers->createSampler();
Jamie Madilldc356042013-07-19 16:36:57 -0400609}
610
Geoff Langc8058452014-02-03 12:04:11 -0500611GLuint Context::createTransformFeedback()
612{
Geoff Lang36167ab2015-12-07 10:27:14 -0500613 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
614 mTransformFeedbackMap[transformFeedback] = nullptr;
615 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500616}
617
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000618// Returns an unused framebuffer name
619GLuint Context::createFramebuffer()
620{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500621 return mState.mFramebuffers->createFramebuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000622}
623
Jamie Madill33dc8432013-07-26 11:55:05 -0400624GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000625{
Jamie Madill33dc8432013-07-26 11:55:05 -0400626 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000627
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400628 mFenceNVMap[handle] = new FenceNV(mImplementation->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000629
630 return handle;
631}
632
633// Returns an unused query name
634GLuint Context::createQuery()
635{
636 GLuint handle = mQueryHandleAllocator.allocate();
637
Yunchao Hed7297bf2017-04-19 15:27:10 +0800638 mQueryMap[handle] = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000639
640 return handle;
641}
642
643void Context::deleteBuffer(GLuint buffer)
644{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500645 if (mState.mBuffers->getBuffer(buffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000646 {
647 detachBuffer(buffer);
648 }
Jamie Madill893ab082014-05-16 16:56:10 -0400649
Jamie Madill6c1f6712017-02-14 19:08:04 -0500650 mState.mBuffers->deleteObject(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000651}
652
653void Context::deleteShader(GLuint shader)
654{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500655 mState.mShaderPrograms->deleteShader(this, shader);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000656}
657
658void Context::deleteProgram(GLuint program)
659{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500660 mState.mShaderPrograms->deleteProgram(this, program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000661}
662
663void Context::deleteTexture(GLuint texture)
664{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500665 if (mState.mTextures->getTexture(texture))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000666 {
667 detachTexture(texture);
668 }
669
Jamie Madill6c1f6712017-02-14 19:08:04 -0500670 mState.mTextures->deleteObject(this, texture);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000671}
672
673void Context::deleteRenderbuffer(GLuint renderbuffer)
674{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500675 if (mState.mRenderbuffers->getRenderbuffer(renderbuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000676 {
677 detachRenderbuffer(renderbuffer);
678 }
Jamie Madill893ab082014-05-16 16:56:10 -0400679
Jamie Madill6c1f6712017-02-14 19:08:04 -0500680 mState.mRenderbuffers->deleteObject(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000681}
682
Jamie Madillcd055f82013-07-26 11:55:15 -0400683void Context::deleteFenceSync(GLsync fenceSync)
684{
685 // The spec specifies the underlying Fence object is not deleted until all current
686 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
687 // and since our API is currently designed for being called from a single thread, we can delete
688 // the fence immediately.
Jamie Madill6c1f6712017-02-14 19:08:04 -0500689 mState.mFenceSyncs->deleteObject(this,
690 static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400691}
692
Sami Väisänene45e53b2016-05-25 10:36:04 +0300693void Context::deletePaths(GLuint first, GLsizei range)
694{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500695 mState.mPaths->deletePaths(first, range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300696}
697
698bool Context::hasPathData(GLuint path) const
699{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500700 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300701 if (pathObj == nullptr)
702 return false;
703
704 return pathObj->hasPathData();
705}
706
707bool Context::hasPath(GLuint path) const
708{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500709 return mState.mPaths->hasPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300710}
711
712void Context::setPathCommands(GLuint path,
713 GLsizei numCommands,
714 const GLubyte *commands,
715 GLsizei numCoords,
716 GLenum coordType,
717 const void *coords)
718{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500719 auto *pathObject = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300720
721 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
722}
723
724void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
725{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500726 auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300727
728 switch (pname)
729 {
730 case GL_PATH_STROKE_WIDTH_CHROMIUM:
731 pathObj->setStrokeWidth(value);
732 break;
733 case GL_PATH_END_CAPS_CHROMIUM:
734 pathObj->setEndCaps(static_cast<GLenum>(value));
735 break;
736 case GL_PATH_JOIN_STYLE_CHROMIUM:
737 pathObj->setJoinStyle(static_cast<GLenum>(value));
738 break;
739 case GL_PATH_MITER_LIMIT_CHROMIUM:
740 pathObj->setMiterLimit(value);
741 break;
742 case GL_PATH_STROKE_BOUND_CHROMIUM:
743 pathObj->setStrokeBound(value);
744 break;
745 default:
746 UNREACHABLE();
747 break;
748 }
749}
750
751void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
752{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500753 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300754
755 switch (pname)
756 {
757 case GL_PATH_STROKE_WIDTH_CHROMIUM:
758 *value = pathObj->getStrokeWidth();
759 break;
760 case GL_PATH_END_CAPS_CHROMIUM:
761 *value = static_cast<GLfloat>(pathObj->getEndCaps());
762 break;
763 case GL_PATH_JOIN_STYLE_CHROMIUM:
764 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
765 break;
766 case GL_PATH_MITER_LIMIT_CHROMIUM:
767 *value = pathObj->getMiterLimit();
768 break;
769 case GL_PATH_STROKE_BOUND_CHROMIUM:
770 *value = pathObj->getStrokeBound();
771 break;
772 default:
773 UNREACHABLE();
774 break;
775 }
776}
777
778void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
779{
780 mGLState.setPathStencilFunc(func, ref, mask);
781}
782
Jamie Madill57a89722013-07-02 11:57:03 -0400783void Context::deleteVertexArray(GLuint vertexArray)
784{
Geoff Lang36167ab2015-12-07 10:27:14 -0500785 auto iter = mVertexArrayMap.find(vertexArray);
786 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000787 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500788 VertexArray *vertexArrayObject = iter->second;
789 if (vertexArrayObject != nullptr)
790 {
791 detachVertexArray(vertexArray);
792 delete vertexArrayObject;
793 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000794
Geoff Lang36167ab2015-12-07 10:27:14 -0500795 mVertexArrayMap.erase(iter);
796 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400797 }
798}
799
Jamie Madilldc356042013-07-19 16:36:57 -0400800void Context::deleteSampler(GLuint sampler)
801{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500802 if (mState.mSamplers->getSampler(sampler))
Jamie Madilldc356042013-07-19 16:36:57 -0400803 {
804 detachSampler(sampler);
805 }
806
Jamie Madill6c1f6712017-02-14 19:08:04 -0500807 mState.mSamplers->deleteObject(this, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400808}
809
Geoff Langc8058452014-02-03 12:04:11 -0500810void Context::deleteTransformFeedback(GLuint transformFeedback)
811{
Geoff Lang6e60d6b2017-04-12 12:59:04 -0400812 if (transformFeedback == 0)
813 {
814 return;
815 }
816
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500817 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500818 if (iter != mTransformFeedbackMap.end())
819 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500820 TransformFeedback *transformFeedbackObject = iter->second;
821 if (transformFeedbackObject != nullptr)
822 {
823 detachTransformFeedback(transformFeedback);
Jamie Madill6c1f6712017-02-14 19:08:04 -0500824 transformFeedbackObject->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500825 }
826
Geoff Lang50b3fe82015-12-08 14:49:12 +0000827 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500828 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500829 }
830}
831
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000832void Context::deleteFramebuffer(GLuint framebuffer)
833{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500834 if (mState.mFramebuffers->getFramebuffer(framebuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000835 {
836 detachFramebuffer(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000837 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500838
Jamie Madill6c1f6712017-02-14 19:08:04 -0500839 mState.mFramebuffers->deleteObject(this, framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000840}
841
Jamie Madill33dc8432013-07-26 11:55:05 -0400842void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000843{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500844 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000845
Jamie Madill33dc8432013-07-26 11:55:05 -0400846 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000847 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400848 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000849 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400850 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000851 }
852}
853
854void Context::deleteQuery(GLuint query)
855{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500856 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000857 if (queryObject != mQueryMap.end())
858 {
859 mQueryHandleAllocator.release(queryObject->first);
860 if (queryObject->second)
861 {
862 queryObject->second->release();
863 }
864 mQueryMap.erase(queryObject);
865 }
866}
867
Geoff Lang70d0f492015-12-10 17:45:46 -0500868Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000869{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500870 return mState.mBuffers->getBuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000871}
872
Jamie Madill570f7c82014-07-03 10:38:54 -0400873Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000874{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500875 return mState.mTextures->getTexture(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000876}
877
Geoff Lang70d0f492015-12-10 17:45:46 -0500878Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000879{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500880 return mState.mRenderbuffers->getRenderbuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000881}
882
Jamie Madillcd055f82013-07-26 11:55:15 -0400883FenceSync *Context::getFenceSync(GLsync handle) const
884{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500885 return mState.mFenceSyncs->getFenceSync(
886 static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400887}
888
Jamie Madill57a89722013-07-02 11:57:03 -0400889VertexArray *Context::getVertexArray(GLuint handle) const
890{
891 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500892 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400893}
894
Jamie Madilldc356042013-07-19 16:36:57 -0400895Sampler *Context::getSampler(GLuint handle) const
896{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500897 return mState.mSamplers->getSampler(handle);
Jamie Madilldc356042013-07-19 16:36:57 -0400898}
899
Geoff Langc8058452014-02-03 12:04:11 -0500900TransformFeedback *Context::getTransformFeedback(GLuint handle) const
901{
Geoff Lang36167ab2015-12-07 10:27:14 -0500902 auto iter = mTransformFeedbackMap.find(handle);
903 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500904}
905
Geoff Lang70d0f492015-12-10 17:45:46 -0500906LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
907{
908 switch (identifier)
909 {
910 case GL_BUFFER:
911 return getBuffer(name);
912 case GL_SHADER:
913 return getShader(name);
914 case GL_PROGRAM:
915 return getProgram(name);
916 case GL_VERTEX_ARRAY:
917 return getVertexArray(name);
918 case GL_QUERY:
919 return getQuery(name);
920 case GL_TRANSFORM_FEEDBACK:
921 return getTransformFeedback(name);
922 case GL_SAMPLER:
923 return getSampler(name);
924 case GL_TEXTURE:
925 return getTexture(name);
926 case GL_RENDERBUFFER:
927 return getRenderbuffer(name);
928 case GL_FRAMEBUFFER:
929 return getFramebuffer(name);
930 default:
931 UNREACHABLE();
932 return nullptr;
933 }
934}
935
936LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
937{
938 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
939}
940
Martin Radev9d901792016-07-15 15:58:58 +0300941void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
942{
943 LabeledObject *object = getLabeledObject(identifier, name);
944 ASSERT(object != nullptr);
945
946 std::string labelName = GetObjectLabelFromPointer(length, label);
947 object->setLabel(labelName);
948}
949
950void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
951{
952 LabeledObject *object = getLabeledObjectFromPtr(ptr);
953 ASSERT(object != nullptr);
954
955 std::string labelName = GetObjectLabelFromPointer(length, label);
956 object->setLabel(labelName);
957}
958
959void Context::getObjectLabel(GLenum identifier,
960 GLuint name,
961 GLsizei bufSize,
962 GLsizei *length,
963 GLchar *label) const
964{
965 LabeledObject *object = getLabeledObject(identifier, name);
966 ASSERT(object != nullptr);
967
968 const std::string &objectLabel = object->getLabel();
969 GetObjectLabelBase(objectLabel, bufSize, length, label);
970}
971
972void Context::getObjectPtrLabel(const void *ptr,
973 GLsizei bufSize,
974 GLsizei *length,
975 GLchar *label) const
976{
977 LabeledObject *object = getLabeledObjectFromPtr(ptr);
978 ASSERT(object != nullptr);
979
980 const std::string &objectLabel = object->getLabel();
981 GetObjectLabelBase(objectLabel, bufSize, length, label);
982}
983
Jamie Madilldc356042013-07-19 16:36:57 -0400984bool Context::isSampler(GLuint samplerName) const
985{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500986 return mState.mSamplers->isSampler(samplerName);
Jamie Madilldc356042013-07-19 16:36:57 -0400987}
988
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500989void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000990{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500991 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700992 mGLState.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000993}
994
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800995void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
996{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500997 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800998 mGLState.setDrawIndirectBufferBinding(buffer);
999}
1000
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001001void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001002{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001003 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Shao80957d92017-02-20 21:25:59 +08001004 mGLState.setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001005}
1006
Jamie Madilldedd7b92014-11-05 16:30:36 -05001007void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001008{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001009 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001010
Jamie Madilldedd7b92014-11-05 16:30:36 -05001011 if (handle == 0)
1012 {
1013 texture = mZeroTextures[target].get();
1014 }
1015 else
1016 {
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001017 texture = mState.mTextures->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -05001018 }
1019
1020 ASSERT(texture);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001021 mGLState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +00001022}
1023
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001024void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001025{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001026 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
1027 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001028 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001029}
1030
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001031void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001032{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001033 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
1034 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001035 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001036}
1037
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001038void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -04001039{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001040 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001041 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -04001042}
1043
Shao80957d92017-02-20 21:25:59 +08001044void Context::bindVertexBuffer(GLuint bindingIndex,
1045 GLuint bufferHandle,
1046 GLintptr offset,
1047 GLsizei stride)
1048{
1049 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
1050 mGLState.bindVertexBuffer(bindingIndex, buffer, offset, stride);
1051}
1052
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001053void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -04001054{
Geoff Lang76b10c92014-09-05 16:28:14 -04001055 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -04001056 Sampler *sampler =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001057 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001058 mGLState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001059}
1060
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001061void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001062{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001063 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001064 mGLState.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001065}
1066
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001067void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1068 GLuint index,
1069 GLintptr offset,
1070 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001071{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001072 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001073 mGLState.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001074}
1075
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001076void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001077{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001078 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001079 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001080}
1081
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001082void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1083 GLuint index,
1084 GLintptr offset,
1085 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001086{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001087 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001088 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001089}
1090
Jiajia Qin6eafb042016-12-27 17:04:07 +08001091void Context::bindGenericAtomicCounterBuffer(GLuint bufferHandle)
1092{
1093 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
1094 mGLState.setGenericAtomicCounterBufferBinding(buffer);
1095}
1096
1097void Context::bindIndexedAtomicCounterBuffer(GLuint bufferHandle,
1098 GLuint index,
1099 GLintptr offset,
1100 GLsizeiptr size)
1101{
1102 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
1103 mGLState.setIndexedAtomicCounterBufferBinding(index, buffer, offset, size);
1104}
1105
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001106void Context::bindGenericShaderStorageBuffer(GLuint bufferHandle)
1107{
1108 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
1109 mGLState.setGenericShaderStorageBufferBinding(buffer);
1110}
1111
1112void Context::bindIndexedShaderStorageBuffer(GLuint bufferHandle,
1113 GLuint index,
1114 GLintptr offset,
1115 GLsizeiptr size)
1116{
1117 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
1118 mGLState.setIndexedShaderStorageBufferBinding(index, buffer, offset, size);
1119}
1120
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001121void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001122{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001123 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001124 mGLState.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001125}
1126
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001127void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001128{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001129 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001130 mGLState.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001131}
1132
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001133void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001134{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001135 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001136 mGLState.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001137}
1138
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001139void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001140{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001141 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001142 mGLState.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001143}
1144
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001145void Context::useProgram(GLuint program)
1146{
Jamie Madill6c1f6712017-02-14 19:08:04 -05001147 mGLState.setProgram(this, getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001148}
1149
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001150void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001151{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001152 TransformFeedback *transformFeedback =
1153 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001154 mGLState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001155}
1156
Geoff Lang5aad9672014-09-08 11:10:42 -04001157Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001158{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001159 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001160 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001161
Geoff Lang5aad9672014-09-08 11:10:42 -04001162 // begin query
1163 Error error = queryObject->begin();
1164 if (error.isError())
1165 {
1166 return error;
1167 }
1168
1169 // set query as active for specified target only if begin succeeded
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001170 mGLState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001171
He Yunchaoacd18982017-01-04 10:46:42 +08001172 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001173}
1174
Geoff Lang5aad9672014-09-08 11:10:42 -04001175Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001176{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001177 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001178 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001179
Geoff Lang5aad9672014-09-08 11:10:42 -04001180 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001181
Geoff Lang5aad9672014-09-08 11:10:42 -04001182 // Always unbind the query, even if there was an error. This may delete the query object.
Yunchao Hef81ce4a2017-04-24 10:49:17 +08001183 mGLState.setActiveQuery(target, nullptr);
Geoff Lang5aad9672014-09-08 11:10:42 -04001184
1185 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001186}
1187
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001188Error Context::queryCounter(GLuint id, GLenum target)
1189{
1190 ASSERT(target == GL_TIMESTAMP_EXT);
1191
1192 Query *queryObject = getQuery(id, true, target);
1193 ASSERT(queryObject);
1194
1195 return queryObject->queryCounter();
1196}
1197
1198void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1199{
1200 switch (pname)
1201 {
1202 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001203 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001204 break;
1205 case GL_QUERY_COUNTER_BITS_EXT:
1206 switch (target)
1207 {
1208 case GL_TIME_ELAPSED_EXT:
1209 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1210 break;
1211 case GL_TIMESTAMP_EXT:
1212 params[0] = getExtensions().queryCounterBitsTimestamp;
1213 break;
1214 default:
1215 UNREACHABLE();
1216 params[0] = 0;
1217 break;
1218 }
1219 break;
1220 default:
1221 UNREACHABLE();
1222 return;
1223 }
1224}
1225
Geoff Lang2186c382016-10-14 10:54:54 -04001226void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001227{
Geoff Lang2186c382016-10-14 10:54:54 -04001228 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001229}
1230
Geoff Lang2186c382016-10-14 10:54:54 -04001231void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001232{
Geoff Lang2186c382016-10-14 10:54:54 -04001233 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001234}
1235
Geoff Lang2186c382016-10-14 10:54:54 -04001236void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001237{
Geoff Lang2186c382016-10-14 10:54:54 -04001238 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001239}
1240
Geoff Lang2186c382016-10-14 10:54:54 -04001241void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001242{
Geoff Lang2186c382016-10-14 10:54:54 -04001243 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001244}
1245
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001246Framebuffer *Context::getFramebuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001247{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001248 return mState.mFramebuffers->getFramebuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001249}
1250
Jamie Madill33dc8432013-07-26 11:55:05 -04001251FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001252{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001253 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001254
Jamie Madill33dc8432013-07-26 11:55:05 -04001255 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001256 {
Yunchao Hef81ce4a2017-04-24 10:49:17 +08001257 return nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001258 }
1259 else
1260 {
1261 return fence->second;
1262 }
1263}
1264
1265Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1266{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001267 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001268
1269 if (query == mQueryMap.end())
1270 {
Yunchao Hef81ce4a2017-04-24 10:49:17 +08001271 return nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001272 }
1273 else
1274 {
1275 if (!query->second && create)
1276 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001277 query->second = new Query(mImplementation->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001278 query->second->addRef();
1279 }
1280 return query->second;
1281 }
1282}
1283
Geoff Lang70d0f492015-12-10 17:45:46 -05001284Query *Context::getQuery(GLuint handle) const
1285{
1286 auto iter = mQueryMap.find(handle);
1287 return (iter != mQueryMap.end()) ? iter->second : nullptr;
1288}
1289
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001290Texture *Context::getTargetTexture(GLenum target) const
1291{
Ian Ewellbda75592016-04-18 17:25:54 -04001292 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001293 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001294}
1295
Geoff Lang76b10c92014-09-05 16:28:14 -04001296Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001297{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001298 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001299}
1300
Geoff Lang492a7e42014-11-05 13:27:06 -05001301Compiler *Context::getCompiler() const
1302{
1303 return mCompiler;
1304}
1305
Jamie Madillc1d770e2017-04-13 17:31:24 -04001306void Context::getBooleanvImpl(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001307{
1308 switch (pname)
1309 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001310 case GL_SHADER_COMPILER:
1311 *params = GL_TRUE;
1312 break;
1313 case GL_CONTEXT_ROBUST_ACCESS_EXT:
1314 *params = mRobustAccess ? GL_TRUE : GL_FALSE;
1315 break;
1316 default:
1317 mGLState.getBooleanv(pname, params);
1318 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001319 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001320}
1321
Jamie Madillc1d770e2017-04-13 17:31:24 -04001322void Context::getFloatvImpl(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001323{
Shannon Woods53a94a82014-06-24 15:20:36 -04001324 // Queries about context capabilities and maximums are answered by Context.
1325 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001326 switch (pname)
1327 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001328 case GL_ALIASED_LINE_WIDTH_RANGE:
1329 params[0] = mCaps.minAliasedLineWidth;
1330 params[1] = mCaps.maxAliasedLineWidth;
1331 break;
1332 case GL_ALIASED_POINT_SIZE_RANGE:
1333 params[0] = mCaps.minAliasedPointSize;
1334 params[1] = mCaps.maxAliasedPointSize;
1335 break;
1336 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1337 ASSERT(mExtensions.textureFilterAnisotropic);
1338 *params = mExtensions.maxTextureAnisotropy;
1339 break;
1340 case GL_MAX_TEXTURE_LOD_BIAS:
1341 *params = mCaps.maxLODBias;
1342 break;
1343
1344 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1345 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1346 {
1347 ASSERT(mExtensions.pathRendering);
1348 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1349 memcpy(params, m, 16 * sizeof(GLfloat));
1350 }
Geoff Lange6d4e122015-06-29 13:33:55 -04001351 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001352
Jamie Madill231c7f52017-04-26 13:45:37 -04001353 default:
1354 mGLState.getFloatv(pname, params);
1355 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001356 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001357}
1358
Jamie Madillc1d770e2017-04-13 17:31:24 -04001359void Context::getIntegervImpl(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001360{
Shannon Woods53a94a82014-06-24 15:20:36 -04001361 // Queries about context capabilities and maximums are answered by Context.
1362 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001363
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001364 switch (pname)
1365 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001366 case GL_MAX_VERTEX_ATTRIBS:
1367 *params = mCaps.maxVertexAttributes;
1368 break;
1369 case GL_MAX_VERTEX_UNIFORM_VECTORS:
1370 *params = mCaps.maxVertexUniformVectors;
1371 break;
1372 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
1373 *params = mCaps.maxVertexUniformComponents;
1374 break;
1375 case GL_MAX_VARYING_VECTORS:
1376 *params = mCaps.maxVaryingVectors;
1377 break;
1378 case GL_MAX_VARYING_COMPONENTS:
1379 *params = mCaps.maxVertexOutputComponents;
1380 break;
1381 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1382 *params = mCaps.maxCombinedTextureImageUnits;
1383 break;
1384 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1385 *params = mCaps.maxVertexTextureImageUnits;
1386 break;
1387 case GL_MAX_TEXTURE_IMAGE_UNITS:
1388 *params = mCaps.maxTextureImageUnits;
1389 break;
1390 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1391 *params = mCaps.maxFragmentUniformVectors;
1392 break;
1393 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
1394 *params = mCaps.maxFragmentUniformComponents;
1395 break;
1396 case GL_MAX_RENDERBUFFER_SIZE:
1397 *params = mCaps.maxRenderbufferSize;
1398 break;
1399 case GL_MAX_COLOR_ATTACHMENTS_EXT:
1400 *params = mCaps.maxColorAttachments;
1401 break;
1402 case GL_MAX_DRAW_BUFFERS_EXT:
1403 *params = mCaps.maxDrawBuffers;
1404 break;
1405 // case GL_FRAMEBUFFER_BINDING: // now equivalent to
1406 // GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1407 case GL_SUBPIXEL_BITS:
1408 *params = 4;
1409 break;
1410 case GL_MAX_TEXTURE_SIZE:
1411 *params = mCaps.max2DTextureSize;
1412 break;
1413 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1414 *params = mCaps.maxCubeMapTextureSize;
1415 break;
1416 case GL_MAX_3D_TEXTURE_SIZE:
1417 *params = mCaps.max3DTextureSize;
1418 break;
1419 case GL_MAX_ARRAY_TEXTURE_LAYERS:
1420 *params = mCaps.maxArrayTextureLayers;
1421 break;
1422 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
1423 *params = mCaps.uniformBufferOffsetAlignment;
1424 break;
1425 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
1426 *params = mCaps.maxUniformBufferBindings;
1427 break;
1428 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
1429 *params = mCaps.maxVertexUniformBlocks;
1430 break;
1431 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
1432 *params = mCaps.maxFragmentUniformBlocks;
1433 break;
1434 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
1435 *params = mCaps.maxCombinedTextureImageUnits;
1436 break;
1437 case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
1438 *params = mCaps.maxVertexOutputComponents;
1439 break;
1440 case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
1441 *params = mCaps.maxFragmentInputComponents;
1442 break;
1443 case GL_MIN_PROGRAM_TEXEL_OFFSET:
1444 *params = mCaps.minProgramTexelOffset;
1445 break;
1446 case GL_MAX_PROGRAM_TEXEL_OFFSET:
1447 *params = mCaps.maxProgramTexelOffset;
1448 break;
1449 case GL_MAJOR_VERSION:
1450 *params = getClientVersion().major;
1451 break;
1452 case GL_MINOR_VERSION:
1453 *params = getClientVersion().minor;
1454 break;
1455 case GL_MAX_ELEMENTS_INDICES:
1456 *params = mCaps.maxElementsIndices;
1457 break;
1458 case GL_MAX_ELEMENTS_VERTICES:
1459 *params = mCaps.maxElementsVertices;
1460 break;
1461 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
1462 *params = mCaps.maxTransformFeedbackInterleavedComponents;
1463 break;
1464 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
1465 *params = mCaps.maxTransformFeedbackSeparateAttributes;
1466 break;
1467 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
1468 *params = mCaps.maxTransformFeedbackSeparateComponents;
1469 break;
1470 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1471 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1472 break;
1473 case GL_MAX_SAMPLES_ANGLE:
1474 *params = mCaps.maxSamples;
1475 break;
1476 case GL_MAX_VIEWPORT_DIMS:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001477 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001478 params[0] = mCaps.maxViewportWidth;
1479 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001480 }
1481 break;
Jamie Madill231c7f52017-04-26 13:45:37 -04001482 case GL_COMPRESSED_TEXTURE_FORMATS:
1483 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(),
1484 params);
1485 break;
1486 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1487 *params = mResetStrategy;
1488 break;
1489 case GL_NUM_SHADER_BINARY_FORMATS:
1490 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
1491 break;
1492 case GL_SHADER_BINARY_FORMATS:
1493 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1494 break;
1495 case GL_NUM_PROGRAM_BINARY_FORMATS:
1496 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
1497 break;
1498 case GL_PROGRAM_BINARY_FORMATS:
1499 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
1500 break;
1501 case GL_NUM_EXTENSIONS:
1502 *params = static_cast<GLint>(mExtensionStrings.size());
1503 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001504
Jamie Madill231c7f52017-04-26 13:45:37 -04001505 // GL_KHR_debug
1506 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1507 *params = mExtensions.maxDebugMessageLength;
1508 break;
1509 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1510 *params = mExtensions.maxDebugLoggedMessages;
1511 break;
1512 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1513 *params = mExtensions.maxDebugGroupStackDepth;
1514 break;
1515 case GL_MAX_LABEL_LENGTH:
1516 *params = mExtensions.maxLabelLength;
1517 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001518
Jamie Madill231c7f52017-04-26 13:45:37 -04001519 // GL_EXT_disjoint_timer_query
1520 case GL_GPU_DISJOINT_EXT:
1521 *params = mImplementation->getGPUDisjoint();
1522 break;
1523 case GL_MAX_FRAMEBUFFER_WIDTH:
1524 *params = mCaps.maxFramebufferWidth;
1525 break;
1526 case GL_MAX_FRAMEBUFFER_HEIGHT:
1527 *params = mCaps.maxFramebufferHeight;
1528 break;
1529 case GL_MAX_FRAMEBUFFER_SAMPLES:
1530 *params = mCaps.maxFramebufferSamples;
1531 break;
1532 case GL_MAX_SAMPLE_MASK_WORDS:
1533 *params = mCaps.maxSampleMaskWords;
1534 break;
1535 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1536 *params = mCaps.maxColorTextureSamples;
1537 break;
1538 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1539 *params = mCaps.maxDepthTextureSamples;
1540 break;
1541 case GL_MAX_INTEGER_SAMPLES:
1542 *params = mCaps.maxIntegerSamples;
1543 break;
1544 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1545 *params = mCaps.maxVertexAttribRelativeOffset;
1546 break;
1547 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1548 *params = mCaps.maxVertexAttribBindings;
1549 break;
1550 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1551 *params = mCaps.maxVertexAttribStride;
1552 break;
1553 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1554 *params = mCaps.maxVertexAtomicCounterBuffers;
1555 break;
1556 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1557 *params = mCaps.maxVertexAtomicCounters;
1558 break;
1559 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1560 *params = mCaps.maxVertexImageUniforms;
1561 break;
1562 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1563 *params = mCaps.maxVertexShaderStorageBlocks;
1564 break;
1565 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1566 *params = mCaps.maxFragmentAtomicCounterBuffers;
1567 break;
1568 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1569 *params = mCaps.maxFragmentAtomicCounters;
1570 break;
1571 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1572 *params = mCaps.maxFragmentImageUniforms;
1573 break;
1574 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1575 *params = mCaps.maxFragmentShaderStorageBlocks;
1576 break;
1577 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1578 *params = mCaps.minProgramTextureGatherOffset;
1579 break;
1580 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1581 *params = mCaps.maxProgramTextureGatherOffset;
1582 break;
1583 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1584 *params = mCaps.maxComputeWorkGroupInvocations;
1585 break;
1586 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1587 *params = mCaps.maxComputeUniformBlocks;
1588 break;
1589 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1590 *params = mCaps.maxComputeTextureImageUnits;
1591 break;
1592 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1593 *params = mCaps.maxComputeSharedMemorySize;
1594 break;
1595 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1596 *params = mCaps.maxComputeUniformComponents;
1597 break;
1598 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1599 *params = mCaps.maxComputeAtomicCounterBuffers;
1600 break;
1601 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1602 *params = mCaps.maxComputeAtomicCounters;
1603 break;
1604 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1605 *params = mCaps.maxComputeImageUniforms;
1606 break;
1607 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1608 *params = mCaps.maxCombinedComputeUniformComponents;
1609 break;
1610 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1611 *params = mCaps.maxComputeShaderStorageBlocks;
1612 break;
1613 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1614 *params = mCaps.maxCombinedShaderOutputResources;
1615 break;
1616 case GL_MAX_UNIFORM_LOCATIONS:
1617 *params = mCaps.maxUniformLocations;
1618 break;
1619 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1620 *params = mCaps.maxAtomicCounterBufferBindings;
1621 break;
1622 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1623 *params = mCaps.maxAtomicCounterBufferSize;
1624 break;
1625 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1626 *params = mCaps.maxCombinedAtomicCounterBuffers;
1627 break;
1628 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1629 *params = mCaps.maxCombinedAtomicCounters;
1630 break;
1631 case GL_MAX_IMAGE_UNITS:
1632 *params = mCaps.maxImageUnits;
1633 break;
1634 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1635 *params = mCaps.maxCombinedImageUniforms;
1636 break;
1637 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1638 *params = mCaps.maxShaderStorageBufferBindings;
1639 break;
1640 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1641 *params = mCaps.maxCombinedShaderStorageBlocks;
1642 break;
1643 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1644 *params = mCaps.shaderStorageBufferOffsetAlignment;
1645 break;
1646 default:
1647 mGLState.getIntegerv(this, pname, params);
1648 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001649 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001650}
1651
Jamie Madill893ab082014-05-16 16:56:10 -04001652void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -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.
Jamie Madill0fda9862013-07-19 16:36:55 -04001656 switch (pname)
1657 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001658 case GL_MAX_ELEMENT_INDEX:
1659 *params = mCaps.maxElementIndex;
1660 break;
1661 case GL_MAX_UNIFORM_BLOCK_SIZE:
1662 *params = mCaps.maxUniformBlockSize;
1663 break;
1664 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
1665 *params = mCaps.maxCombinedVertexUniformComponents;
1666 break;
1667 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
1668 *params = mCaps.maxCombinedFragmentUniformComponents;
1669 break;
1670 case GL_MAX_SERVER_WAIT_TIMEOUT:
1671 *params = mCaps.maxServerWaitTimeout;
1672 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001673
Jamie Madill231c7f52017-04-26 13:45:37 -04001674 // GL_EXT_disjoint_timer_query
1675 case GL_TIMESTAMP_EXT:
1676 *params = mImplementation->getTimestamp();
1677 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001678
Jamie Madill231c7f52017-04-26 13:45:37 -04001679 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1680 *params = mCaps.maxShaderStorageBlockSize;
1681 break;
1682 default:
1683 UNREACHABLE();
1684 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001685 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001686}
1687
Geoff Lang70d0f492015-12-10 17:45:46 -05001688void Context::getPointerv(GLenum pname, void **params) const
1689{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001690 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001691}
1692
Martin Radev66fb8202016-07-28 11:45:20 +03001693void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001694{
Shannon Woods53a94a82014-06-24 15:20:36 -04001695 // Queries about context capabilities and maximums are answered by Context.
1696 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001697
1698 GLenum nativeType;
1699 unsigned int numParams;
1700 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1701 ASSERT(queryStatus);
1702
1703 if (nativeType == GL_INT)
1704 {
1705 switch (target)
1706 {
1707 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1708 ASSERT(index < 3u);
1709 *data = mCaps.maxComputeWorkGroupCount[index];
1710 break;
1711 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1712 ASSERT(index < 3u);
1713 *data = mCaps.maxComputeWorkGroupSize[index];
1714 break;
1715 default:
1716 mGLState.getIntegeri_v(target, index, data);
1717 }
1718 }
1719 else
1720 {
1721 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1722 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001723}
1724
Martin Radev66fb8202016-07-28 11:45:20 +03001725void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001726{
Shannon Woods53a94a82014-06-24 15:20:36 -04001727 // Queries about context capabilities and maximums are answered by Context.
1728 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001729
1730 GLenum nativeType;
1731 unsigned int numParams;
1732 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1733 ASSERT(queryStatus);
1734
1735 if (nativeType == GL_INT_64_ANGLEX)
1736 {
1737 mGLState.getInteger64i_v(target, index, data);
1738 }
1739 else
1740 {
1741 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1742 }
1743}
1744
1745void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1746{
1747 // Queries about context capabilities and maximums are answered by Context.
1748 // Queries about current GL state values are answered by State.
1749
1750 GLenum nativeType;
1751 unsigned int numParams;
1752 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1753 ASSERT(queryStatus);
1754
1755 if (nativeType == GL_BOOL)
1756 {
1757 mGLState.getBooleani_v(target, index, data);
1758 }
1759 else
1760 {
1761 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1762 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001763}
1764
He Yunchao010e4db2017-03-03 14:22:06 +08001765void Context::getBufferParameteriv(GLenum target, GLenum pname, GLint *params)
1766{
1767 Buffer *buffer = mGLState.getTargetBuffer(target);
1768 QueryBufferParameteriv(buffer, pname, params);
1769}
1770
1771void Context::getFramebufferAttachmentParameteriv(GLenum target,
1772 GLenum attachment,
1773 GLenum pname,
1774 GLint *params)
1775{
1776 const Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
1777 QueryFramebufferAttachmentParameteriv(framebuffer, attachment, pname, params);
1778}
1779
1780void Context::getRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
1781{
1782 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
1783 QueryRenderbufferiv(this, renderbuffer, pname, params);
1784}
1785
1786void Context::getTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
1787{
1788 Texture *texture = getTargetTexture(target);
1789 QueryTexParameterfv(texture, pname, params);
1790}
1791
1792void Context::getTexParameteriv(GLenum target, GLenum pname, GLint *params)
1793{
1794 Texture *texture = getTargetTexture(target);
1795 QueryTexParameteriv(texture, pname, params);
1796}
1797void Context::texParameterf(GLenum target, GLenum pname, GLfloat param)
1798{
1799 Texture *texture = getTargetTexture(target);
1800 SetTexParameterf(texture, pname, param);
1801}
1802
1803void Context::texParameterfv(GLenum target, GLenum pname, const GLfloat *params)
1804{
1805 Texture *texture = getTargetTexture(target);
1806 SetTexParameterfv(texture, pname, params);
1807}
1808
1809void Context::texParameteri(GLenum target, GLenum pname, GLint param)
1810{
1811 Texture *texture = getTargetTexture(target);
1812 SetTexParameteri(texture, pname, param);
1813}
1814
1815void Context::texParameteriv(GLenum target, GLenum pname, const GLint *params)
1816{
1817 Texture *texture = getTargetTexture(target);
1818 SetTexParameteriv(texture, pname, params);
1819}
1820
Jamie Madill675fe712016-12-19 13:07:54 -05001821void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001822{
Jamie Madill1b94d432015-08-07 13:23:23 -04001823 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001824 auto error = mImplementation->drawArrays(mode, first, count);
1825 handleError(error);
1826 if (!error.isError())
1827 {
1828 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1829 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001830}
1831
Jamie Madill675fe712016-12-19 13:07:54 -05001832void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Geoff Langf6db0982015-08-25 13:04:00 -04001833{
1834 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001835 auto error = mImplementation->drawArraysInstanced(mode, first, count, instanceCount);
1836 handleError(error);
1837 if (!error.isError())
1838 {
1839 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1840 }
Geoff Langf6db0982015-08-25 13:04:00 -04001841}
1842
Jamie Madill876429b2017-04-20 15:46:24 -04001843void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001844{
Jamie Madill1b94d432015-08-07 13:23:23 -04001845 syncRendererState();
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001846 const IndexRange &indexRange = getParams<HasIndexRange>().getIndexRange().value();
Jamie Madill675fe712016-12-19 13:07:54 -05001847 handleError(mImplementation->drawElements(mode, count, type, indices, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001848}
1849
Jamie Madill675fe712016-12-19 13:07:54 -05001850void Context::drawElementsInstanced(GLenum mode,
1851 GLsizei count,
1852 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001853 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001854 GLsizei instances)
Geoff Langf6db0982015-08-25 13:04:00 -04001855{
1856 syncRendererState();
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001857 const IndexRange &indexRange = getParams<HasIndexRange>().getIndexRange().value();
Jamie Madill675fe712016-12-19 13:07:54 -05001858 handleError(
1859 mImplementation->drawElementsInstanced(mode, count, type, indices, instances, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001860}
1861
Jamie Madill675fe712016-12-19 13:07:54 -05001862void Context::drawRangeElements(GLenum mode,
1863 GLuint start,
1864 GLuint end,
1865 GLsizei count,
1866 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001867 const void *indices)
Geoff Langf6db0982015-08-25 13:04:00 -04001868{
1869 syncRendererState();
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001870 const IndexRange &indexRange = getParams<HasIndexRange>().getIndexRange().value();
Jamie Madill675fe712016-12-19 13:07:54 -05001871 handleError(
1872 mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001873}
1874
Jamie Madill876429b2017-04-20 15:46:24 -04001875void Context::drawArraysIndirect(GLenum mode, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001876{
1877 syncRendererState();
1878 handleError(mImplementation->drawArraysIndirect(mode, indirect));
1879}
1880
Jamie Madill876429b2017-04-20 15:46:24 -04001881void Context::drawElementsIndirect(GLenum mode, GLenum type, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001882{
1883 syncRendererState();
1884 handleError(mImplementation->drawElementsIndirect(mode, type, indirect));
1885}
1886
Jamie Madill675fe712016-12-19 13:07:54 -05001887void Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001888{
Jamie Madill675fe712016-12-19 13:07:54 -05001889 handleError(mImplementation->flush());
Geoff Lang129753a2015-01-09 16:52:09 -05001890}
1891
Jamie Madill675fe712016-12-19 13:07:54 -05001892void Context::finish()
Geoff Lang129753a2015-01-09 16:52:09 -05001893{
Jamie Madill675fe712016-12-19 13:07:54 -05001894 handleError(mImplementation->finish());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001895}
1896
Austin Kinross6ee1e782015-05-29 17:05:37 -07001897void Context::insertEventMarker(GLsizei length, const char *marker)
1898{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001899 ASSERT(mImplementation);
1900 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001901}
1902
1903void Context::pushGroupMarker(GLsizei length, const char *marker)
1904{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001905 ASSERT(mImplementation);
1906 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001907}
1908
1909void Context::popGroupMarker()
1910{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001911 ASSERT(mImplementation);
1912 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001913}
1914
Geoff Langd8605522016-04-13 10:19:12 -04001915void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1916{
1917 Program *programObject = getProgram(program);
1918 ASSERT(programObject);
1919
1920 programObject->bindUniformLocation(location, name);
1921}
1922
Sami Väisänena797e062016-05-12 15:23:40 +03001923void Context::setCoverageModulation(GLenum components)
1924{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001925 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001926}
1927
Sami Väisänene45e53b2016-05-25 10:36:04 +03001928void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1929{
1930 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1931}
1932
1933void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1934{
1935 GLfloat I[16];
1936 angle::Matrix<GLfloat>::setToIdentity(I);
1937
1938 mGLState.loadPathRenderingMatrix(matrixMode, I);
1939}
1940
1941void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1942{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001943 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001944 if (!pathObj)
1945 return;
1946
1947 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1948 syncRendererState();
1949
1950 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1951}
1952
1953void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1954{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001955 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001956 if (!pathObj)
1957 return;
1958
1959 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1960 syncRendererState();
1961
1962 mImplementation->stencilStrokePath(pathObj, reference, mask);
1963}
1964
1965void Context::coverFillPath(GLuint path, GLenum coverMode)
1966{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001967 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001968 if (!pathObj)
1969 return;
1970
1971 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1972 syncRendererState();
1973
1974 mImplementation->coverFillPath(pathObj, coverMode);
1975}
1976
1977void Context::coverStrokePath(GLuint path, GLenum coverMode)
1978{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001979 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001980 if (!pathObj)
1981 return;
1982
1983 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1984 syncRendererState();
1985
1986 mImplementation->coverStrokePath(pathObj, coverMode);
1987}
1988
1989void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1990{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001991 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001992 if (!pathObj)
1993 return;
1994
1995 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1996 syncRendererState();
1997
1998 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1999}
2000
2001void Context::stencilThenCoverStrokePath(GLuint path,
2002 GLint reference,
2003 GLuint mask,
2004 GLenum coverMode)
2005{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002006 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03002007 if (!pathObj)
2008 return;
2009
2010 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2011 syncRendererState();
2012
2013 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
2014}
2015
Sami Väisänend59ca052016-06-21 16:10:00 +03002016void Context::coverFillPathInstanced(GLsizei numPaths,
2017 GLenum pathNameType,
2018 const void *paths,
2019 GLuint pathBase,
2020 GLenum coverMode,
2021 GLenum transformType,
2022 const GLfloat *transformValues)
2023{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002024 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002025
2026 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2027 syncRendererState();
2028
2029 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
2030}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002031
Sami Väisänend59ca052016-06-21 16:10:00 +03002032void Context::coverStrokePathInstanced(GLsizei numPaths,
2033 GLenum pathNameType,
2034 const void *paths,
2035 GLuint pathBase,
2036 GLenum coverMode,
2037 GLenum transformType,
2038 const GLfloat *transformValues)
2039{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002040 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002041
2042 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2043 syncRendererState();
2044
2045 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
2046 transformValues);
2047}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002048
Sami Väisänend59ca052016-06-21 16:10:00 +03002049void Context::stencilFillPathInstanced(GLsizei numPaths,
2050 GLenum pathNameType,
2051 const void *paths,
2052 GLuint pathBase,
2053 GLenum fillMode,
2054 GLuint mask,
2055 GLenum transformType,
2056 const GLfloat *transformValues)
2057{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002058 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002059
2060 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2061 syncRendererState();
2062
2063 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
2064 transformValues);
2065}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002066
Sami Väisänend59ca052016-06-21 16:10:00 +03002067void Context::stencilStrokePathInstanced(GLsizei numPaths,
2068 GLenum pathNameType,
2069 const void *paths,
2070 GLuint pathBase,
2071 GLint reference,
2072 GLuint mask,
2073 GLenum transformType,
2074 const GLfloat *transformValues)
2075{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002076 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002077
2078 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2079 syncRendererState();
2080
2081 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
2082 transformValues);
2083}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002084
Sami Väisänend59ca052016-06-21 16:10:00 +03002085void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
2086 GLenum pathNameType,
2087 const void *paths,
2088 GLuint pathBase,
2089 GLenum fillMode,
2090 GLuint mask,
2091 GLenum coverMode,
2092 GLenum transformType,
2093 const GLfloat *transformValues)
2094{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002095 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002096
2097 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2098 syncRendererState();
2099
2100 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
2101 transformType, transformValues);
2102}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002103
Sami Väisänend59ca052016-06-21 16:10:00 +03002104void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
2105 GLenum pathNameType,
2106 const void *paths,
2107 GLuint pathBase,
2108 GLint reference,
2109 GLuint mask,
2110 GLenum coverMode,
2111 GLenum transformType,
2112 const GLfloat *transformValues)
2113{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002114 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002115
2116 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2117 syncRendererState();
2118
2119 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
2120 transformType, transformValues);
2121}
2122
Sami Väisänen46eaa942016-06-29 10:26:37 +03002123void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
2124{
2125 auto *programObject = getProgram(program);
2126
2127 programObject->bindFragmentInputLocation(location, name);
2128}
2129
2130void Context::programPathFragmentInputGen(GLuint program,
2131 GLint location,
2132 GLenum genMode,
2133 GLint components,
2134 const GLfloat *coeffs)
2135{
2136 auto *programObject = getProgram(program);
2137
2138 programObject->pathFragmentInputGen(location, genMode, components, coeffs);
2139}
2140
jchen1015015f72017-03-16 13:54:21 +08002141GLuint Context::getProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name)
2142{
jchen10fd7c3b52017-03-21 15:36:03 +08002143 const auto *programObject = getProgram(program);
jchen1015015f72017-03-16 13:54:21 +08002144 return QueryProgramResourceIndex(programObject, programInterface, name);
2145}
2146
jchen10fd7c3b52017-03-21 15:36:03 +08002147void Context::getProgramResourceName(GLuint program,
2148 GLenum programInterface,
2149 GLuint index,
2150 GLsizei bufSize,
2151 GLsizei *length,
2152 GLchar *name)
2153{
2154 const auto *programObject = getProgram(program);
2155 QueryProgramResourceName(programObject, programInterface, index, bufSize, length, name);
2156}
2157
Jamie Madill437fa652016-05-03 15:13:24 -04002158void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002159{
Geoff Langda5777c2014-07-11 09:52:58 -04002160 if (error.isError())
2161 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002162 GLenum code = error.getCode();
2163 mErrors.insert(code);
2164 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
2165 {
2166 markContextLost();
2167 }
Geoff Lang70d0f492015-12-10 17:45:46 -05002168
2169 if (!error.getMessage().empty())
2170 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002171 auto *debug = &mGLState.getDebug();
2172 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
2173 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05002174 }
Geoff Langda5777c2014-07-11 09:52:58 -04002175 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002176}
2177
2178// Get one of the recorded errors and clear its flag, if any.
2179// [OpenGL ES 2.0.24] section 2.5 page 13.
2180GLenum Context::getError()
2181{
Geoff Langda5777c2014-07-11 09:52:58 -04002182 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002183 {
Geoff Langda5777c2014-07-11 09:52:58 -04002184 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002185 }
Geoff Langda5777c2014-07-11 09:52:58 -04002186 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002187 {
Geoff Langda5777c2014-07-11 09:52:58 -04002188 GLenum error = *mErrors.begin();
2189 mErrors.erase(mErrors.begin());
2190 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002191 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002192}
2193
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002194// NOTE: this function should not assume that this context is current!
2195void Context::markContextLost()
2196{
2197 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002198 {
Jamie Madill231c7f52017-04-26 13:45:37 -04002199 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002200 mContextLostForced = true;
2201 }
Jamie Madill231c7f52017-04-26 13:45:37 -04002202 mContextLost = true;
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002203}
2204
2205bool Context::isContextLost()
2206{
2207 return mContextLost;
2208}
2209
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002210GLenum Context::getResetStatus()
2211{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002212 // Even if the application doesn't want to know about resets, we want to know
2213 // as it will allow us to skip all the calls.
2214 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002215 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002216 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002217 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002218 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002219 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002220
2221 // EXT_robustness, section 2.6: If the reset notification behavior is
2222 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2223 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2224 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002225 }
2226
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002227 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2228 // status should be returned at least once, and GL_NO_ERROR should be returned
2229 // once the device has finished resetting.
2230 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002231 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002232 ASSERT(mResetStatus == GL_NO_ERROR);
2233 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002234
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002235 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002236 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002237 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002238 }
2239 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002240 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002241 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002242 // If markContextLost was used to mark the context lost then
2243 // assume that is not recoverable, and continue to report the
2244 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002245 mResetStatus = mImplementation->getResetStatus();
2246 }
Jamie Madill893ab082014-05-16 16:56:10 -04002247
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002248 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002249}
2250
2251bool Context::isResetNotificationEnabled()
2252{
2253 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2254}
2255
Corentin Walleze3b10e82015-05-20 11:06:25 -04002256const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002257{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002258 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002259}
2260
2261EGLenum Context::getClientType() const
2262{
2263 return mClientType;
2264}
2265
2266EGLenum Context::getRenderBuffer() const
2267{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002268 const Framebuffer *framebuffer = mState.mFramebuffers->getFramebuffer(0);
2269 if (framebuffer == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -04002270 {
2271 return EGL_NONE;
2272 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002273
2274 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2275 ASSERT(backAttachment != nullptr);
2276 return backAttachment->getSurface()->getRenderBuffer();
Régis Fénéon83107972015-02-05 12:57:44 +01002277}
2278
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002279VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002280{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002281 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002282 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2283 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002284 {
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002285 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle,
2286 mCaps.maxVertexAttributes, mCaps.maxVertexAttribBindings);
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002287
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002288 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002289 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002290
2291 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002292}
2293
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002294TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002295{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002296 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002297 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2298 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002299 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002300 transformFeedback =
2301 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002302 transformFeedback->addRef();
2303 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002304 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002305
2306 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002307}
2308
2309bool Context::isVertexArrayGenerated(GLuint vertexArray)
2310{
Geoff Langf41a7152016-09-19 15:11:17 -04002311 ASSERT(mVertexArrayMap.find(0) != mVertexArrayMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002312 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
2313}
2314
2315bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2316{
Geoff Langf41a7152016-09-19 15:11:17 -04002317 ASSERT(mTransformFeedbackMap.find(0) != mTransformFeedbackMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002318 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
2319}
2320
Shannon Woods53a94a82014-06-24 15:20:36 -04002321void Context::detachTexture(GLuint texture)
2322{
2323 // Simple pass-through to State's detachTexture method, as textures do not require
2324 // allocation map management either here or in the resource manager at detach time.
2325 // Zero textures are held by the Context, and we don't attempt to request them from
2326 // the State.
Jamie Madilla02315b2017-02-23 14:14:47 -05002327 mGLState.detachTexture(this, mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002328}
2329
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002330void Context::detachBuffer(GLuint buffer)
2331{
Yuly Novikov5807a532015-12-03 13:01:22 -05002332 // Simple pass-through to State's detachBuffer method, since
2333 // only buffer attachments to container objects that are bound to the current context
2334 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002335
Yuly Novikov5807a532015-12-03 13:01:22 -05002336 // [OpenGL ES 3.2] section 5.1.2 page 45:
2337 // Attachments to unbound container objects, such as
2338 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2339 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002340 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002341}
2342
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002343void Context::detachFramebuffer(GLuint framebuffer)
2344{
Shannon Woods53a94a82014-06-24 15:20:36 -04002345 // Framebuffer detachment is handled by Context, because 0 is a valid
2346 // Framebuffer object, and a pointer to it must be passed from Context
2347 // to State at binding time.
2348
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002349 // [OpenGL ES 2.0.24] section 4.4 page 107:
Jamie Madill231c7f52017-04-26 13:45:37 -04002350 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as
2351 // though BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of
2352 // zero.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002353
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002354 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002355 {
2356 bindReadFramebuffer(0);
2357 }
2358
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002359 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002360 {
2361 bindDrawFramebuffer(0);
2362 }
2363}
2364
2365void Context::detachRenderbuffer(GLuint renderbuffer)
2366{
Jamie Madilla02315b2017-02-23 14:14:47 -05002367 mGLState.detachRenderbuffer(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002368}
2369
Jamie Madill57a89722013-07-02 11:57:03 -04002370void Context::detachVertexArray(GLuint vertexArray)
2371{
Jamie Madill77a72f62015-04-14 11:18:32 -04002372 // Vertex array detachment is handled by Context, because 0 is a valid
2373 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002374 // binding time.
2375
Jamie Madill57a89722013-07-02 11:57:03 -04002376 // [OpenGL ES 3.0.2] section 2.10 page 43:
2377 // If a vertex array object that is currently bound is deleted, the binding
2378 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002379 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002380 {
2381 bindVertexArray(0);
2382 }
2383}
2384
Geoff Langc8058452014-02-03 12:04:11 -05002385void Context::detachTransformFeedback(GLuint transformFeedback)
2386{
Corentin Walleza2257da2016-04-19 16:43:12 -04002387 // Transform feedback detachment is handled by Context, because 0 is a valid
2388 // transform feedback, and a pointer to it must be passed from Context to State at
2389 // binding time.
2390
2391 // The OpenGL specification doesn't mention what should happen when the currently bound
2392 // transform feedback object is deleted. Since it is a container object, we treat it like
2393 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002394 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002395 {
2396 bindTransformFeedback(0);
2397 }
Geoff Langc8058452014-02-03 12:04:11 -05002398}
2399
Jamie Madilldc356042013-07-19 16:36:57 -04002400void Context::detachSampler(GLuint sampler)
2401{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002402 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002403}
2404
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002405void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2406{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002407 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002408}
2409
Jamie Madille29d1672013-07-19 16:36:57 -04002410void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2411{
Geoff Langc1984ed2016-10-07 12:41:00 -04002412 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002413 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002414 SetSamplerParameteri(samplerObject, pname, param);
2415}
Jamie Madille29d1672013-07-19 16:36:57 -04002416
Geoff Langc1984ed2016-10-07 12:41:00 -04002417void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2418{
2419 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002420 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002421 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002422}
2423
2424void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2425{
Geoff Langc1984ed2016-10-07 12:41:00 -04002426 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002427 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002428 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002429}
2430
Geoff Langc1984ed2016-10-07 12:41:00 -04002431void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002432{
Geoff Langc1984ed2016-10-07 12:41:00 -04002433 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002434 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002435 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002436}
2437
Geoff Langc1984ed2016-10-07 12:41:00 -04002438void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002439{
Geoff Langc1984ed2016-10-07 12:41:00 -04002440 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002441 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002442 QuerySamplerParameteriv(samplerObject, pname, params);
2443}
Jamie Madill9675b802013-07-19 16:36:59 -04002444
Geoff Langc1984ed2016-10-07 12:41:00 -04002445void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2446{
2447 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002448 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002449 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002450}
2451
Olli Etuahof0fee072016-03-30 15:11:58 +03002452void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2453{
2454 gl::Program *programObject = getProgram(program);
Yunchao He61afff12017-03-14 15:34:03 +08002455 SetProgramParameteri(programObject, pname, value);
Olli Etuahof0fee072016-03-30 15:11:58 +03002456}
2457
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002458void Context::initRendererString()
2459{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002460 std::ostringstream rendererString;
2461 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002462 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002463 rendererString << ")";
2464
Geoff Langcec35902014-04-16 10:52:36 -04002465 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002466}
2467
Geoff Langc339c4e2016-11-29 10:37:36 -05002468void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002469{
Geoff Langc339c4e2016-11-29 10:37:36 -05002470 const Version &clientVersion = getClientVersion();
2471
2472 std::ostringstream versionString;
2473 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2474 << ANGLE_VERSION_STRING << ")";
2475 mVersionString = MakeStaticString(versionString.str());
2476
2477 std::ostringstream shadingLanguageVersionString;
2478 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2479 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2480 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2481 << ")";
2482 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002483}
2484
Geoff Langcec35902014-04-16 10:52:36 -04002485void Context::initExtensionStrings()
2486{
Geoff Langc339c4e2016-11-29 10:37:36 -05002487 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2488 std::ostringstream combinedStringStream;
2489 std::copy(strings.begin(), strings.end(),
2490 std::ostream_iterator<const char *>(combinedStringStream, " "));
2491 return MakeStaticString(combinedStringStream.str());
2492 };
2493
2494 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002495 for (const auto &extensionString : mExtensions.getStrings())
2496 {
2497 mExtensionStrings.push_back(MakeStaticString(extensionString));
2498 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002499 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002500
Bryan Bernhart58806562017-01-05 13:09:31 -08002501 const gl::Extensions &nativeExtensions = mImplementation->getNativeExtensions();
2502
Geoff Langc339c4e2016-11-29 10:37:36 -05002503 mRequestableExtensionStrings.clear();
2504 for (const auto &extensionInfo : GetExtensionInfoMap())
2505 {
2506 if (extensionInfo.second.Requestable &&
Bryan Bernhart58806562017-01-05 13:09:31 -08002507 !(mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
2508 nativeExtensions.*(extensionInfo.second.ExtensionsMember))
Geoff Langc339c4e2016-11-29 10:37:36 -05002509 {
2510 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2511 }
2512 }
2513 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002514}
2515
Geoff Langc339c4e2016-11-29 10:37:36 -05002516const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002517{
Geoff Langc339c4e2016-11-29 10:37:36 -05002518 switch (name)
2519 {
2520 case GL_VENDOR:
2521 return reinterpret_cast<const GLubyte *>("Google Inc.");
2522
2523 case GL_RENDERER:
2524 return reinterpret_cast<const GLubyte *>(mRendererString);
2525
2526 case GL_VERSION:
2527 return reinterpret_cast<const GLubyte *>(mVersionString);
2528
2529 case GL_SHADING_LANGUAGE_VERSION:
2530 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2531
2532 case GL_EXTENSIONS:
2533 return reinterpret_cast<const GLubyte *>(mExtensionString);
2534
2535 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2536 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2537
2538 default:
2539 UNREACHABLE();
2540 return nullptr;
2541 }
Geoff Langcec35902014-04-16 10:52:36 -04002542}
2543
Geoff Langc339c4e2016-11-29 10:37:36 -05002544const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002545{
Geoff Langc339c4e2016-11-29 10:37:36 -05002546 switch (name)
2547 {
2548 case GL_EXTENSIONS:
2549 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2550
2551 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2552 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2553
2554 default:
2555 UNREACHABLE();
2556 return nullptr;
2557 }
Geoff Langcec35902014-04-16 10:52:36 -04002558}
2559
2560size_t Context::getExtensionStringCount() const
2561{
2562 return mExtensionStrings.size();
2563}
2564
Geoff Langc339c4e2016-11-29 10:37:36 -05002565void Context::requestExtension(const char *name)
2566{
2567 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2568 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2569 const auto &extension = extensionInfos.at(name);
2570 ASSERT(extension.Requestable);
2571
2572 if (mExtensions.*(extension.ExtensionsMember))
2573 {
2574 // Extension already enabled
2575 return;
2576 }
2577
2578 mExtensions.*(extension.ExtensionsMember) = true;
2579 updateCaps();
2580 initExtensionStrings();
Bryan Bernhart58806562017-01-05 13:09:31 -08002581
2582 // Re-create the compiler with the requested extensions enabled.
2583 SafeDelete(mCompiler);
2584 mCompiler = new Compiler(mImplementation.get(), mState);
Geoff Lang9aded172017-04-05 11:07:56 -04002585
2586 // Invalidate all cached completenesses for textures and framebuffer. Some extensions make new
2587 // formats renderable or sampleable.
2588 mState.mTextures->invalidateTextureComplenessCache();
2589 for (auto &zeroTexture : mZeroTextures)
2590 {
2591 zeroTexture.second->invalidateCompletenessCache();
2592 }
2593
2594 mState.mFramebuffers->invalidateFramebufferComplenessCache();
Geoff Langc339c4e2016-11-29 10:37:36 -05002595}
2596
2597size_t Context::getRequestableExtensionStringCount() const
2598{
2599 return mRequestableExtensionStrings.size();
2600}
2601
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002602void Context::beginTransformFeedback(GLenum primitiveMode)
2603{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002604 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002605 ASSERT(transformFeedback != nullptr);
2606 ASSERT(!transformFeedback->isPaused());
2607
Jamie Madill6c1f6712017-02-14 19:08:04 -05002608 transformFeedback->begin(this, primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002609}
2610
2611bool Context::hasActiveTransformFeedback(GLuint program) const
2612{
2613 for (auto pair : mTransformFeedbackMap)
2614 {
2615 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2616 {
2617 return true;
2618 }
2619 }
2620 return false;
2621}
2622
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002623void Context::initCaps(const egl::DisplayExtensions &displayExtensions)
Geoff Lang493daf52014-07-03 13:38:44 -04002624{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002625 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002626
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002627 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002628
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002629 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002630
Geoff Langeb66a6e2016-10-31 13:06:12 -04002631 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002632 {
2633 // Disable ES3+ extensions
Jamie Madill231c7f52017-04-26 13:45:37 -04002634 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002635 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002636 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002637 }
2638
Geoff Langeb66a6e2016-10-31 13:06:12 -04002639 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002640 {
2641 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
Jamie Madill231c7f52017-04-26 13:45:37 -04002642 // mExtensions.sRGB = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002643 }
2644
Jamie Madill00ed7a12016-05-19 13:13:38 -04002645 // Some extensions are always available because they are implemented in the GL layer.
Jamie Madill231c7f52017-04-26 13:45:37 -04002646 mExtensions.bindUniformLocation = true;
2647 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002648 mExtensions.bindGeneratesResource = true;
Geoff Langfeb8c682017-02-13 16:07:35 -05002649 mExtensions.clientArrays = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002650 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002651
2652 // Enable the no error extension if the context was created with the flag.
2653 mExtensions.noError = mSkipValidation;
2654
Corentin Wallezccab69d2017-01-27 16:57:15 -05002655 // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
Corentin Wallezc295e512017-01-27 17:47:50 -05002656 mExtensions.surfacelessContext = displayExtensions.surfacelessContext;
Corentin Wallezccab69d2017-01-27 16:57:15 -05002657
Geoff Lang70d0f492015-12-10 17:45:46 -05002658 // Explicitly enable GL_KHR_debug
2659 mExtensions.debug = true;
2660 mExtensions.maxDebugMessageLength = 1024;
2661 mExtensions.maxDebugLoggedMessages = 1024;
2662 mExtensions.maxDebugGroupStackDepth = 1024;
2663 mExtensions.maxLabelLength = 1024;
2664
Geoff Langff5b2d52016-09-07 11:32:23 -04002665 // Explicitly enable GL_ANGLE_robust_client_memory
2666 mExtensions.robustClientMemory = true;
2667
Jamie Madille08a1d32017-03-07 17:24:06 -05002668 // Determine robust resource init availability from EGL.
2669 mExtensions.robustResourceInitialization =
Jamie Madill948bbe52017-06-01 13:10:42 -04002670 egl::Display::GetClientExtensions().displayRobustResourceInitialization;
Jamie Madille08a1d32017-03-07 17:24:06 -05002671
Geoff Lang301d1612014-07-09 10:34:37 -04002672 // Apply implementation limits
2673 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002674 mCaps.maxVertexAttribBindings =
2675 getClientVersion() < ES_3_1
2676 ? mCaps.maxVertexAttributes
2677 : std::min<GLuint>(mCaps.maxVertexAttribBindings, MAX_VERTEX_ATTRIB_BINDINGS);
2678
Jamie Madill231c7f52017-04-26 13:45:37 -04002679 mCaps.maxVertexUniformBlocks = std::min<GLuint>(
2680 mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2681 mCaps.maxVertexOutputComponents =
2682 std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang301d1612014-07-09 10:34:37 -04002683
Jamie Madill231c7f52017-04-26 13:45:37 -04002684 mCaps.maxFragmentInputComponents =
2685 std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002686
Geoff Langc287ea62016-09-16 14:46:51 -04002687 // WebGL compatibility
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002688 mExtensions.webglCompatibility = mWebGLContext;
Geoff Langc287ea62016-09-16 14:46:51 -04002689 for (const auto &extensionInfo : GetExtensionInfoMap())
2690 {
2691 // If this context is for WebGL, disable all enableable extensions
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002692 if (mWebGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002693 {
2694 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2695 }
2696 }
2697
2698 // Generate texture caps
2699 updateCaps();
2700}
2701
2702void Context::updateCaps()
2703{
Geoff Lang900013c2014-07-07 11:32:19 -04002704 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002705 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002706
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002707 for (auto capsIt : mImplementation->getNativeTextureCaps())
Geoff Lang493daf52014-07-03 13:38:44 -04002708 {
Geoff Langca271392017-04-05 12:30:00 -04002709 GLenum sizedInternalFormat = capsIt.first;
Jamie Madill231c7f52017-04-26 13:45:37 -04002710 TextureCaps formatCaps = capsIt.second;
Geoff Lang493daf52014-07-03 13:38:44 -04002711
Geoff Langca271392017-04-05 12:30:00 -04002712 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002713
Geoff Lang0d8b7242015-09-09 14:56:53 -04002714 // Update the format caps based on the client version and extensions.
2715 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2716 // ES3.
2717 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002718 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002719 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002720 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002721 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002722 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002723
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002724 // OpenGL ES does not support multisampling with non-rendererable formats
2725 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
2726 if (!formatInfo.renderSupport ||
2727 (getClientVersion() < ES_3_1 &&
2728 (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
Geoff Lang493daf52014-07-03 13:38:44 -04002729 {
Geoff Langd87878e2014-09-19 15:42:59 -04002730 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002731 }
Geoff Langd87878e2014-09-19 15:42:59 -04002732
2733 if (formatCaps.texturable && formatInfo.compressed)
2734 {
Geoff Langca271392017-04-05 12:30:00 -04002735 mCaps.compressedTextureFormats.push_back(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002736 }
2737
Geoff Langca271392017-04-05 12:30:00 -04002738 mTextureCaps.insert(sizedInternalFormat, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002739 }
2740}
2741
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002742void Context::initWorkarounds()
2743{
2744 // Lose the context upon out of memory error if the application is
2745 // expecting to watch for those events.
2746 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2747}
2748
Jamie Madill1b94d432015-08-07 13:23:23 -04002749void Context::syncRendererState()
2750{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002751 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
Frank Henigman5a53d542017-02-16 21:24:10 -05002752 mImplementation->syncState(dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002753 mGLState.clearDirtyBits();
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002754 mGLState.syncDirtyObjects(this);
Jamie Madill1b94d432015-08-07 13:23:23 -04002755}
2756
Jamie Madillad9f24e2016-02-12 09:27:24 -05002757void Context::syncRendererState(const State::DirtyBits &bitMask,
2758 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002759{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002760 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
Frank Henigman5a53d542017-02-16 21:24:10 -05002761 mImplementation->syncState(dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002762 mGLState.clearDirtyBits(dirtyBits);
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002763 mGLState.syncDirtyObjects(this, objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002764}
Jamie Madillc29968b2016-01-20 11:17:23 -05002765
2766void Context::blitFramebuffer(GLint srcX0,
2767 GLint srcY0,
2768 GLint srcX1,
2769 GLint srcY1,
2770 GLint dstX0,
2771 GLint dstY0,
2772 GLint dstX1,
2773 GLint dstY1,
2774 GLbitfield mask,
2775 GLenum filter)
2776{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002777 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002778 ASSERT(drawFramebuffer);
2779
2780 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2781 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2782
Jamie Madillad9f24e2016-02-12 09:27:24 -05002783 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002784
Jamie Madill8415b5f2016-04-26 13:41:39 -04002785 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002786}
Jamie Madillc29968b2016-01-20 11:17:23 -05002787
2788void Context::clear(GLbitfield mask)
2789{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002790 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002791 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002792}
2793
2794void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2795{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002796 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002797 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2798 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002799}
2800
2801void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2802{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002803 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002804 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2805 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002806}
2807
2808void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2809{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002810 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002811 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2812 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002813}
2814
2815void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2816{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002817 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002818 ASSERT(framebufferObject);
2819
2820 // If a buffer is not present, the clear has no effect
2821 if (framebufferObject->getDepthbuffer() == nullptr &&
2822 framebufferObject->getStencilbuffer() == nullptr)
2823 {
2824 return;
2825 }
2826
Jamie Madillad9f24e2016-02-12 09:27:24 -05002827 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002828 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2829 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002830}
2831
2832void Context::readPixels(GLint x,
2833 GLint y,
2834 GLsizei width,
2835 GLsizei height,
2836 GLenum format,
2837 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002838 void *pixels)
Jamie Madillc29968b2016-01-20 11:17:23 -05002839{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002840 if (width == 0 || height == 0)
2841 {
2842 return;
2843 }
2844
Jamie Madillad9f24e2016-02-12 09:27:24 -05002845 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002846
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002847 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002848 ASSERT(framebufferObject);
2849
2850 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002851 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002852}
2853
2854void Context::copyTexImage2D(GLenum target,
2855 GLint level,
2856 GLenum internalformat,
2857 GLint x,
2858 GLint y,
2859 GLsizei width,
2860 GLsizei height,
2861 GLint border)
2862{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002863 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002864 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002865
Jamie Madillc29968b2016-01-20 11:17:23 -05002866 Rectangle sourceArea(x, y, width, height);
2867
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002868 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002869 Texture *texture =
2870 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002871 handleError(texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002872}
2873
2874void Context::copyTexSubImage2D(GLenum target,
2875 GLint level,
2876 GLint xoffset,
2877 GLint yoffset,
2878 GLint x,
2879 GLint y,
2880 GLsizei width,
2881 GLsizei height)
2882{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002883 if (width == 0 || height == 0)
2884 {
2885 return;
2886 }
2887
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002888 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002889 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002890
Jamie Madillc29968b2016-01-20 11:17:23 -05002891 Offset destOffset(xoffset, yoffset, 0);
2892 Rectangle sourceArea(x, y, width, height);
2893
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002894 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002895 Texture *texture =
2896 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002897 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002898}
2899
2900void Context::copyTexSubImage3D(GLenum target,
2901 GLint level,
2902 GLint xoffset,
2903 GLint yoffset,
2904 GLint zoffset,
2905 GLint x,
2906 GLint y,
2907 GLsizei width,
2908 GLsizei height)
2909{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002910 if (width == 0 || height == 0)
2911 {
2912 return;
2913 }
2914
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002915 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002916 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002917
Jamie Madillc29968b2016-01-20 11:17:23 -05002918 Offset destOffset(xoffset, yoffset, zoffset);
2919 Rectangle sourceArea(x, y, width, height);
2920
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002921 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002922 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002923 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002924}
2925
2926void Context::framebufferTexture2D(GLenum target,
2927 GLenum attachment,
2928 GLenum textarget,
2929 GLuint texture,
2930 GLint level)
2931{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002932 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002933 ASSERT(framebuffer);
2934
2935 if (texture != 0)
2936 {
2937 Texture *textureObj = getTexture(texture);
2938
2939 ImageIndex index = ImageIndex::MakeInvalid();
2940
2941 if (textarget == GL_TEXTURE_2D)
2942 {
2943 index = ImageIndex::Make2D(level);
2944 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08002945 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
2946 {
2947 ASSERT(level == 0);
2948 index = ImageIndex::Make2DMultisample();
2949 }
Jamie Madillc29968b2016-01-20 11:17:23 -05002950 else
2951 {
2952 ASSERT(IsCubeMapTextureTarget(textarget));
2953 index = ImageIndex::MakeCube(textarget, level);
2954 }
2955
Jamie Madilla02315b2017-02-23 14:14:47 -05002956 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
Jamie Madillc29968b2016-01-20 11:17:23 -05002957 }
2958 else
2959 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002960 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002961 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002962
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002963 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002964}
2965
2966void Context::framebufferRenderbuffer(GLenum target,
2967 GLenum attachment,
2968 GLenum renderbuffertarget,
2969 GLuint renderbuffer)
2970{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002971 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002972 ASSERT(framebuffer);
2973
2974 if (renderbuffer != 0)
2975 {
2976 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
Jamie Madilla02315b2017-02-23 14:14:47 -05002977
2978 framebuffer->setAttachment(this, GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
Jamie Madillc29968b2016-01-20 11:17:23 -05002979 renderbufferObject);
2980 }
2981 else
2982 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002983 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002984 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002985
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002986 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002987}
2988
2989void Context::framebufferTextureLayer(GLenum target,
2990 GLenum attachment,
2991 GLuint texture,
2992 GLint level,
2993 GLint layer)
2994{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002995 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002996 ASSERT(framebuffer);
2997
2998 if (texture != 0)
2999 {
3000 Texture *textureObject = getTexture(texture);
3001
3002 ImageIndex index = ImageIndex::MakeInvalid();
3003
3004 if (textureObject->getTarget() == GL_TEXTURE_3D)
3005 {
3006 index = ImageIndex::Make3D(level, layer);
3007 }
3008 else
3009 {
3010 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
3011 index = ImageIndex::Make2DArray(level, layer);
3012 }
3013
Jamie Madilla02315b2017-02-23 14:14:47 -05003014 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObject);
Jamie Madillc29968b2016-01-20 11:17:23 -05003015 }
3016 else
3017 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003018 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003019 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003020
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003021 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003022}
3023
3024void Context::drawBuffers(GLsizei n, const GLenum *bufs)
3025{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003026 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003027 ASSERT(framebuffer);
3028 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003029 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003030}
3031
3032void Context::readBuffer(GLenum mode)
3033{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003034 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003035 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003036 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003037}
3038
3039void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
3040{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003041 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003042 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003043
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003044 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003045 ASSERT(framebuffer);
3046
3047 // The specification isn't clear what should be done when the framebuffer isn't complete.
3048 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04003049 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003050}
3051
3052void Context::invalidateFramebuffer(GLenum target,
3053 GLsizei numAttachments,
3054 const GLenum *attachments)
3055{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003056 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003057 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003058
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003059 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003060 ASSERT(framebuffer);
3061
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003062 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003063 {
Jamie Madill437fa652016-05-03 15:13:24 -04003064 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003065 }
Jamie Madill437fa652016-05-03 15:13:24 -04003066
3067 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003068}
3069
3070void Context::invalidateSubFramebuffer(GLenum target,
3071 GLsizei numAttachments,
3072 const GLenum *attachments,
3073 GLint x,
3074 GLint y,
3075 GLsizei width,
3076 GLsizei height)
3077{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003078 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003079 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003080
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003081 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003082 ASSERT(framebuffer);
3083
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003084 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003085 {
Jamie Madill437fa652016-05-03 15:13:24 -04003086 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003087 }
Jamie Madill437fa652016-05-03 15:13:24 -04003088
3089 Rectangle area(x, y, width, height);
3090 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05003091}
3092
Jamie Madill73a84962016-02-12 09:27:23 -05003093void Context::texImage2D(GLenum target,
3094 GLint level,
3095 GLint internalformat,
3096 GLsizei width,
3097 GLsizei height,
3098 GLint border,
3099 GLenum format,
3100 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003101 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003102{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003103 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003104
3105 Extents size(width, height, 1);
3106 Texture *texture =
3107 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003108 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3109 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003110}
3111
3112void Context::texImage3D(GLenum target,
3113 GLint level,
3114 GLint internalformat,
3115 GLsizei width,
3116 GLsizei height,
3117 GLsizei depth,
3118 GLint border,
3119 GLenum format,
3120 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003121 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003122{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003123 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003124
3125 Extents size(width, height, depth);
3126 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003127 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3128 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003129}
3130
3131void Context::texSubImage2D(GLenum target,
3132 GLint level,
3133 GLint xoffset,
3134 GLint yoffset,
3135 GLsizei width,
3136 GLsizei height,
3137 GLenum format,
3138 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003139 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003140{
3141 // Zero sized uploads are valid but no-ops
3142 if (width == 0 || height == 0)
3143 {
3144 return;
3145 }
3146
Jamie Madillad9f24e2016-02-12 09:27:24 -05003147 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003148
3149 Box area(xoffset, yoffset, 0, width, height, 1);
3150 Texture *texture =
3151 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003152 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3153 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003154}
3155
3156void Context::texSubImage3D(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 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003166 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003167{
3168 // Zero sized uploads are valid but no-ops
3169 if (width == 0 || height == 0 || depth == 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->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3179 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003180}
3181
3182void Context::compressedTexImage2D(GLenum target,
3183 GLint level,
3184 GLenum internalformat,
3185 GLsizei width,
3186 GLsizei height,
3187 GLint border,
3188 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003189 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003190{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003191 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003192
3193 Extents size(width, height, 1);
3194 Texture *texture =
3195 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003196 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003197 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003198 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003199}
3200
3201void Context::compressedTexImage3D(GLenum target,
3202 GLint level,
3203 GLenum internalformat,
3204 GLsizei width,
3205 GLsizei height,
3206 GLsizei depth,
3207 GLint border,
3208 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003209 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003210{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003211 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003212
3213 Extents size(width, height, depth);
3214 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003215 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003216 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003217 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003218}
3219
3220void Context::compressedTexSubImage2D(GLenum target,
3221 GLint level,
3222 GLint xoffset,
3223 GLint yoffset,
3224 GLsizei width,
3225 GLsizei height,
3226 GLenum format,
3227 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003228 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003229{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003230 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003231
3232 Box area(xoffset, yoffset, 0, width, height, 1);
3233 Texture *texture =
3234 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003235 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003236 format, imageSize,
3237 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003238}
3239
3240void Context::compressedTexSubImage3D(GLenum target,
3241 GLint level,
3242 GLint xoffset,
3243 GLint yoffset,
3244 GLint zoffset,
3245 GLsizei width,
3246 GLsizei height,
3247 GLsizei depth,
3248 GLenum format,
3249 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003250 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003251{
3252 // Zero sized uploads are valid but no-ops
3253 if (width == 0 || height == 0)
3254 {
3255 return;
3256 }
3257
Jamie Madillad9f24e2016-02-12 09:27:24 -05003258 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003259
3260 Box area(xoffset, yoffset, zoffset, width, height, depth);
3261 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003262 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003263 format, imageSize,
3264 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003265}
3266
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003267void Context::generateMipmap(GLenum target)
3268{
3269 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003270 handleError(texture->generateMipmap(this));
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003271}
3272
Geoff Lang97073d12016-04-20 10:42:34 -07003273void Context::copyTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003274 GLint sourceLevel,
3275 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003276 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003277 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003278 GLint internalFormat,
3279 GLenum destType,
3280 GLboolean unpackFlipY,
3281 GLboolean unpackPremultiplyAlpha,
3282 GLboolean unpackUnmultiplyAlpha)
3283{
3284 syncStateForTexImage();
3285
3286 gl::Texture *sourceTexture = getTexture(sourceId);
3287 gl::Texture *destTexture = getTexture(destId);
Geoff Langfc72a072017-03-24 14:52:39 -04003288 handleError(destTexture->copyTexture(
3289 this, destTarget, destLevel, internalFormat, destType, sourceLevel, unpackFlipY == GL_TRUE,
3290 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003291}
3292
3293void Context::copySubTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003294 GLint sourceLevel,
3295 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003296 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003297 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003298 GLint xoffset,
3299 GLint yoffset,
3300 GLint x,
3301 GLint y,
3302 GLsizei width,
3303 GLsizei height,
3304 GLboolean unpackFlipY,
3305 GLboolean unpackPremultiplyAlpha,
3306 GLboolean unpackUnmultiplyAlpha)
3307{
3308 // Zero sized copies are valid but no-ops
3309 if (width == 0 || height == 0)
3310 {
3311 return;
3312 }
3313
3314 syncStateForTexImage();
3315
3316 gl::Texture *sourceTexture = getTexture(sourceId);
3317 gl::Texture *destTexture = getTexture(destId);
3318 Offset offset(xoffset, yoffset, 0);
3319 Rectangle area(x, y, width, height);
Geoff Langfc72a072017-03-24 14:52:39 -04003320 handleError(destTexture->copySubTexture(
3321 this, destTarget, destLevel, offset, sourceLevel, area, unpackFlipY == GL_TRUE,
3322 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003323}
3324
Geoff Lang47110bf2016-04-20 11:13:22 -07003325void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3326{
3327 syncStateForTexImage();
3328
3329 gl::Texture *sourceTexture = getTexture(sourceId);
3330 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003331 handleError(destTexture->copyCompressedTexture(this, sourceTexture));
Geoff Lang47110bf2016-04-20 11:13:22 -07003332}
3333
Geoff Lang496c02d2016-10-20 11:38:11 -07003334void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003335{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003336 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003337 ASSERT(buffer);
3338
Geoff Lang496c02d2016-10-20 11:38:11 -07003339 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003340}
3341
Jamie Madill876429b2017-04-20 15:46:24 -04003342void *Context::mapBuffer(GLenum target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003343{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003344 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003345 ASSERT(buffer);
3346
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003347 Error error = buffer->map(this, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003348 if (error.isError())
3349 {
Jamie Madill437fa652016-05-03 15:13:24 -04003350 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003351 return nullptr;
3352 }
3353
3354 return buffer->getMapPointer();
3355}
3356
3357GLboolean Context::unmapBuffer(GLenum target)
3358{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003359 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003360 ASSERT(buffer);
3361
3362 GLboolean result;
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003363 Error error = buffer->unmap(this, &result);
Olli Etuaho4f667482016-03-30 15:56:35 +03003364 if (error.isError())
3365 {
Jamie Madill437fa652016-05-03 15:13:24 -04003366 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003367 return GL_FALSE;
3368 }
3369
3370 return result;
3371}
3372
Jamie Madill876429b2017-04-20 15:46:24 -04003373void *Context::mapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003374{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003375 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003376 ASSERT(buffer);
3377
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003378 Error error = buffer->mapRange(this, offset, length, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003379 if (error.isError())
3380 {
Jamie Madill437fa652016-05-03 15:13:24 -04003381 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003382 return nullptr;
3383 }
3384
3385 return buffer->getMapPointer();
3386}
3387
3388void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3389{
3390 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3391}
3392
Jamie Madillad9f24e2016-02-12 09:27:24 -05003393void Context::syncStateForReadPixels()
3394{
3395 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3396}
3397
3398void Context::syncStateForTexImage()
3399{
3400 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3401}
3402
3403void Context::syncStateForClear()
3404{
3405 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3406}
3407
3408void Context::syncStateForBlit()
3409{
3410 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3411}
3412
Jamie Madillc20ab272016-06-09 07:20:46 -07003413void Context::activeTexture(GLenum texture)
3414{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003415 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003416}
3417
Jamie Madill876429b2017-04-20 15:46:24 -04003418void Context::blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003419{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003420 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003421}
3422
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003423void Context::blendEquation(GLenum mode)
3424{
3425 mGLState.setBlendEquation(mode, mode);
3426}
3427
Jamie Madillc20ab272016-06-09 07:20:46 -07003428void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3429{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003430 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003431}
3432
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003433void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3434{
3435 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3436}
3437
Jamie Madillc20ab272016-06-09 07:20:46 -07003438void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3439{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003440 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003441}
3442
Jamie Madill876429b2017-04-20 15:46:24 -04003443void Context::clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003444{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003445 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003446}
3447
Jamie Madill876429b2017-04-20 15:46:24 -04003448void Context::clearDepthf(GLfloat depth)
Jamie Madillc20ab272016-06-09 07:20:46 -07003449{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003450 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003451}
3452
3453void Context::clearStencil(GLint s)
3454{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003455 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003456}
3457
3458void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3459{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003460 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003461}
3462
3463void Context::cullFace(GLenum mode)
3464{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003465 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003466}
3467
3468void Context::depthFunc(GLenum func)
3469{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003470 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003471}
3472
3473void Context::depthMask(GLboolean flag)
3474{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003475 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003476}
3477
Jamie Madill876429b2017-04-20 15:46:24 -04003478void Context::depthRangef(GLfloat zNear, GLfloat zFar)
Jamie Madillc20ab272016-06-09 07:20:46 -07003479{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003480 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003481}
3482
3483void Context::disable(GLenum cap)
3484{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003485 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003486}
3487
3488void Context::disableVertexAttribArray(GLuint index)
3489{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003490 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003491}
3492
3493void Context::enable(GLenum cap)
3494{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003495 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003496}
3497
3498void Context::enableVertexAttribArray(GLuint index)
3499{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003500 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003501}
3502
3503void Context::frontFace(GLenum mode)
3504{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003505 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003506}
3507
3508void Context::hint(GLenum target, GLenum mode)
3509{
3510 switch (target)
3511 {
3512 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003513 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003514 break;
3515
3516 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003517 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003518 break;
3519
3520 default:
3521 UNREACHABLE();
3522 return;
3523 }
3524}
3525
3526void Context::lineWidth(GLfloat width)
3527{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003528 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003529}
3530
3531void Context::pixelStorei(GLenum pname, GLint param)
3532{
3533 switch (pname)
3534 {
3535 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003536 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003537 break;
3538
3539 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003540 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003541 break;
3542
3543 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003544 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003545 break;
3546
3547 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003548 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003549 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003550 break;
3551
3552 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003553 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003554 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003555 break;
3556
3557 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003558 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003559 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003560 break;
3561
3562 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003563 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003564 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003565 break;
3566
3567 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003568 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003569 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003570 break;
3571
3572 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003573 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003574 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003575 break;
3576
3577 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003578 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003579 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003580 break;
3581
3582 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003583 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003584 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003585 break;
3586
3587 default:
3588 UNREACHABLE();
3589 return;
3590 }
3591}
3592
3593void Context::polygonOffset(GLfloat factor, GLfloat units)
3594{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003595 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003596}
3597
Jamie Madill876429b2017-04-20 15:46:24 -04003598void Context::sampleCoverage(GLfloat value, GLboolean invert)
Jamie Madillc20ab272016-06-09 07:20:46 -07003599{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003600 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003601}
3602
3603void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3604{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003605 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003606}
3607
3608void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3609{
3610 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3611 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003612 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003613 }
3614
3615 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3616 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003617 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003618 }
3619}
3620
3621void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3622{
3623 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3624 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003625 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003626 }
3627
3628 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3629 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003630 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003631 }
3632}
3633
3634void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3635{
3636 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3637 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003638 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003639 }
3640
3641 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3642 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003643 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003644 }
3645}
3646
3647void Context::vertexAttrib1f(GLuint index, GLfloat x)
3648{
3649 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003650 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003651}
3652
3653void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3654{
3655 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003656 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003657}
3658
3659void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3660{
3661 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003662 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003663}
3664
3665void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3666{
3667 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003668 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003669}
3670
3671void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3672{
3673 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003674 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003675}
3676
3677void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3678{
3679 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003680 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003681}
3682
3683void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3684{
3685 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003686 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003687}
3688
3689void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3690{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003691 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003692}
3693
3694void Context::vertexAttribPointer(GLuint index,
3695 GLint size,
3696 GLenum type,
3697 GLboolean normalized,
3698 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003699 const void *ptr)
Jamie Madillc20ab272016-06-09 07:20:46 -07003700{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003701 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3702 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003703}
3704
Shao80957d92017-02-20 21:25:59 +08003705void Context::vertexAttribFormat(GLuint attribIndex,
3706 GLint size,
3707 GLenum type,
3708 GLboolean normalized,
3709 GLuint relativeOffset)
3710{
3711 mGLState.setVertexAttribFormat(attribIndex, size, type, normalized == GL_TRUE, false,
3712 relativeOffset);
3713}
3714
3715void Context::vertexAttribIFormat(GLuint attribIndex,
3716 GLint size,
3717 GLenum type,
3718 GLuint relativeOffset)
3719{
3720 mGLState.setVertexAttribFormat(attribIndex, size, type, false, true, relativeOffset);
3721}
3722
3723void Context::vertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
3724{
3725 mGLState.setVertexAttribBinding(attribIndex, bindingIndex);
3726}
3727
3728void Context::setVertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
3729{
3730 mGLState.setVertexBindingDivisor(bindingIndex, divisor);
3731}
3732
Jamie Madillc20ab272016-06-09 07:20:46 -07003733void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3734{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003735 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003736}
3737
3738void Context::vertexAttribIPointer(GLuint index,
3739 GLint size,
3740 GLenum type,
3741 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003742 const void *pointer)
Jamie Madillc20ab272016-06-09 07:20:46 -07003743{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003744 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3745 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003746}
3747
3748void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3749{
3750 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003751 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003752}
3753
3754void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3755{
3756 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003757 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003758}
3759
3760void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3761{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003762 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003763}
3764
3765void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3766{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003767 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003768}
3769
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003770void Context::getVertexAttribiv(GLuint index, GLenum pname, GLint *params)
3771{
3772 const VertexAttribCurrentValueData &currentValues =
3773 getGLState().getVertexAttribCurrentValue(index);
3774 const VertexArray *vao = getGLState().getVertexArray();
3775 QueryVertexAttribiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3776 currentValues, pname, params);
3777}
3778
3779void Context::getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
3780{
3781 const VertexAttribCurrentValueData &currentValues =
3782 getGLState().getVertexAttribCurrentValue(index);
3783 const VertexArray *vao = getGLState().getVertexArray();
3784 QueryVertexAttribfv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3785 currentValues, pname, params);
3786}
3787
3788void Context::getVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
3789{
3790 const VertexAttribCurrentValueData &currentValues =
3791 getGLState().getVertexAttribCurrentValue(index);
3792 const VertexArray *vao = getGLState().getVertexArray();
3793 QueryVertexAttribIiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3794 currentValues, pname, params);
3795}
3796
3797void Context::getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
3798{
3799 const VertexAttribCurrentValueData &currentValues =
3800 getGLState().getVertexAttribCurrentValue(index);
3801 const VertexArray *vao = getGLState().getVertexArray();
3802 QueryVertexAttribIuiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3803 currentValues, pname, params);
3804}
3805
Jamie Madill876429b2017-04-20 15:46:24 -04003806void Context::getVertexAttribPointerv(GLuint index, GLenum pname, void **pointer)
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003807{
3808 const VertexAttribute &attrib = getGLState().getVertexArray()->getVertexAttribute(index);
3809 QueryVertexAttribPointerv(attrib, pname, pointer);
3810}
3811
Jamie Madillc20ab272016-06-09 07:20:46 -07003812void Context::debugMessageControl(GLenum source,
3813 GLenum type,
3814 GLenum severity,
3815 GLsizei count,
3816 const GLuint *ids,
3817 GLboolean enabled)
3818{
3819 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003820 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3821 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003822}
3823
3824void Context::debugMessageInsert(GLenum source,
3825 GLenum type,
3826 GLuint id,
3827 GLenum severity,
3828 GLsizei length,
3829 const GLchar *buf)
3830{
3831 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003832 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003833}
3834
3835void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3836{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003837 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003838}
3839
3840GLuint Context::getDebugMessageLog(GLuint count,
3841 GLsizei bufSize,
3842 GLenum *sources,
3843 GLenum *types,
3844 GLuint *ids,
3845 GLenum *severities,
3846 GLsizei *lengths,
3847 GLchar *messageLog)
3848{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003849 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3850 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003851}
3852
3853void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3854{
3855 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003856 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003857}
3858
3859void Context::popDebugGroup()
3860{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003861 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003862}
3863
Jamie Madill876429b2017-04-20 15:46:24 -04003864void Context::bufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage)
Jamie Madill29639852016-09-02 15:00:09 -04003865{
3866 Buffer *buffer = mGLState.getTargetBuffer(target);
3867 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003868 handleError(buffer->bufferData(this, target, data, size, usage));
Jamie Madill29639852016-09-02 15:00:09 -04003869}
3870
Jamie Madill876429b2017-04-20 15:46:24 -04003871void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04003872{
3873 if (data == nullptr)
3874 {
3875 return;
3876 }
3877
3878 Buffer *buffer = mGLState.getTargetBuffer(target);
3879 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003880 handleError(buffer->bufferSubData(this, target, data, size, offset));
Jamie Madill29639852016-09-02 15:00:09 -04003881}
3882
Jamie Madillef300b12016-10-07 15:12:09 -04003883void Context::attachShader(GLuint program, GLuint shader)
3884{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003885 auto programObject = mState.mShaderPrograms->getProgram(program);
3886 auto shaderObject = mState.mShaderPrograms->getShader(shader);
Jamie Madillef300b12016-10-07 15:12:09 -04003887 ASSERT(programObject && shaderObject);
3888 programObject->attachShader(shaderObject);
3889}
3890
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003891const Workarounds &Context::getWorkarounds() const
3892{
3893 return mWorkarounds;
3894}
3895
Jamie Madillb0817d12016-11-01 15:48:31 -04003896void Context::copyBufferSubData(GLenum readTarget,
3897 GLenum writeTarget,
3898 GLintptr readOffset,
3899 GLintptr writeOffset,
3900 GLsizeiptr size)
3901{
3902 // if size is zero, the copy is a successful no-op
3903 if (size == 0)
3904 {
3905 return;
3906 }
3907
3908 // TODO(jmadill): cache these.
3909 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3910 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3911
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003912 handleError(writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size));
Jamie Madillb0817d12016-11-01 15:48:31 -04003913}
3914
Jamie Madill01a80ee2016-11-07 12:06:18 -05003915void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3916{
3917 Program *programObject = getProgram(program);
3918 // TODO(jmadill): Re-use this from the validation if possible.
3919 ASSERT(programObject);
3920 programObject->bindAttributeLocation(index, name);
3921}
3922
3923void Context::bindBuffer(GLenum target, GLuint buffer)
3924{
3925 switch (target)
3926 {
3927 case GL_ARRAY_BUFFER:
3928 bindArrayBuffer(buffer);
3929 break;
3930 case GL_ELEMENT_ARRAY_BUFFER:
3931 bindElementArrayBuffer(buffer);
3932 break;
3933 case GL_COPY_READ_BUFFER:
3934 bindCopyReadBuffer(buffer);
3935 break;
3936 case GL_COPY_WRITE_BUFFER:
3937 bindCopyWriteBuffer(buffer);
3938 break;
3939 case GL_PIXEL_PACK_BUFFER:
3940 bindPixelPackBuffer(buffer);
3941 break;
3942 case GL_PIXEL_UNPACK_BUFFER:
3943 bindPixelUnpackBuffer(buffer);
3944 break;
3945 case GL_UNIFORM_BUFFER:
3946 bindGenericUniformBuffer(buffer);
3947 break;
3948 case GL_TRANSFORM_FEEDBACK_BUFFER:
3949 bindGenericTransformFeedbackBuffer(buffer);
3950 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003951 case GL_ATOMIC_COUNTER_BUFFER:
Jiajia Qin6eafb042016-12-27 17:04:07 +08003952 bindGenericAtomicCounterBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003953 break;
3954 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08003955 bindGenericShaderStorageBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003956 break;
3957 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08003958 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003959 break;
3960 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003961 if (buffer != 0)
3962 {
3963 // Binding buffers to this binding point is not implemented yet.
3964 UNIMPLEMENTED();
3965 }
Geoff Lang3b573612016-10-31 14:08:10 -04003966 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05003967
3968 default:
3969 UNREACHABLE();
3970 break;
3971 }
3972}
3973
Jiajia Qin6eafb042016-12-27 17:04:07 +08003974void Context::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
3975{
3976 bindBufferRange(target, index, buffer, 0, 0);
3977}
3978
3979void Context::bindBufferRange(GLenum target,
3980 GLuint index,
3981 GLuint buffer,
3982 GLintptr offset,
3983 GLsizeiptr size)
3984{
3985 switch (target)
3986 {
3987 case GL_TRANSFORM_FEEDBACK_BUFFER:
3988 bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
3989 bindGenericTransformFeedbackBuffer(buffer);
3990 break;
3991 case GL_UNIFORM_BUFFER:
3992 bindIndexedUniformBuffer(buffer, index, offset, size);
3993 bindGenericUniformBuffer(buffer);
3994 break;
3995 case GL_ATOMIC_COUNTER_BUFFER:
3996 bindIndexedAtomicCounterBuffer(buffer, index, offset, size);
3997 bindGenericAtomicCounterBuffer(buffer);
3998 break;
3999 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08004000 bindIndexedShaderStorageBuffer(buffer, index, offset, size);
4001 bindGenericShaderStorageBuffer(buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08004002 break;
4003 default:
4004 UNREACHABLE();
4005 break;
4006 }
4007}
4008
Jamie Madill01a80ee2016-11-07 12:06:18 -05004009void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
4010{
4011 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4012 {
4013 bindReadFramebuffer(framebuffer);
4014 }
4015
4016 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4017 {
4018 bindDrawFramebuffer(framebuffer);
4019 }
4020}
4021
4022void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
4023{
4024 ASSERT(target == GL_RENDERBUFFER);
4025 Renderbuffer *object =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05004026 mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004027 mGLState.setRenderbufferBinding(object);
4028}
4029
JiangYizhoubddc46b2016-12-09 09:50:51 +08004030void Context::texStorage2DMultisample(GLenum target,
4031 GLsizei samples,
4032 GLenum internalformat,
4033 GLsizei width,
4034 GLsizei height,
4035 GLboolean fixedsamplelocations)
4036{
4037 Extents size(width, height, 1);
4038 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05004039 handleError(texture->setStorageMultisample(this, target, samples, internalformat, size,
JiangYizhoubddc46b2016-12-09 09:50:51 +08004040 fixedsamplelocations));
4041}
4042
4043void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
4044{
Jamie Madilldd43e6c2017-03-24 14:18:49 -04004045 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
JiangYizhoubddc46b2016-12-09 09:50:51 +08004046 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
4047
4048 switch (pname)
4049 {
4050 case GL_SAMPLE_POSITION:
4051 handleError(framebuffer->getSamplePosition(index, val));
4052 break;
4053 default:
4054 UNREACHABLE();
4055 }
4056}
4057
Jamie Madille8fb6402017-02-14 17:56:40 -05004058void Context::renderbufferStorage(GLenum target,
4059 GLenum internalformat,
4060 GLsizei width,
4061 GLsizei height)
4062{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004063 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4064 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
4065
Jamie Madille8fb6402017-02-14 17:56:40 -05004066 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004067 handleError(renderbuffer->setStorage(convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004068}
4069
4070void Context::renderbufferStorageMultisample(GLenum target,
4071 GLsizei samples,
4072 GLenum internalformat,
4073 GLsizei width,
4074 GLsizei height)
4075{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004076 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4077 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
Jamie Madille8fb6402017-02-14 17:56:40 -05004078
4079 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004080 handleError(
4081 renderbuffer->setStorageMultisample(samples, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004082}
4083
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004084void Context::getSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)
4085{
4086 const FenceSync *syncObject = getFenceSync(sync);
Geoff Lang82483b92017-04-11 15:33:00 -04004087 handleError(QuerySynciv(syncObject, pname, bufSize, length, values));
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004088}
4089
JiangYizhoue18e6392017-02-20 10:32:23 +08004090void Context::getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
4091{
4092 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4093 QueryFramebufferParameteriv(framebuffer, pname, params);
4094}
4095
4096void Context::setFramebufferParameteri(GLenum target, GLenum pname, GLint param)
4097{
4098 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4099 SetFramebufferParameteri(framebuffer, pname, param);
4100}
4101
Jamie Madille14951e2017-03-09 18:55:16 -05004102Error Context::getScratchBuffer(size_t requestedSize, angle::MemoryBuffer **scratchBufferOut) const
4103{
4104 if (!mScratchBuffer.get(requestedSize, scratchBufferOut))
4105 {
4106 return gl::OutOfMemory() << "Failed to allocate internal buffer.";
4107 }
4108 return gl::NoError();
4109}
4110
Xinghua Cao2b396592017-03-29 15:36:04 +08004111void Context::dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ)
4112{
4113 if (numGroupsX == 0u || numGroupsY == 0u || numGroupsZ == 0u)
4114 {
4115 return;
4116 }
4117
4118 mImplementation->dispatchCompute(numGroupsX, numGroupsY, numGroupsZ);
4119}
4120
Jamie Madillc1d770e2017-04-13 17:31:24 -04004121GLenum Context::checkFramebufferStatus(GLenum target)
4122{
4123 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4124 ASSERT(framebuffer);
4125
4126 return framebuffer->checkStatus(this);
4127}
4128
4129void Context::compileShader(GLuint shader)
4130{
4131 Shader *shaderObject = GetValidShader(this, shader);
4132 if (!shaderObject)
4133 {
4134 return;
4135 }
4136 shaderObject->compile(this);
4137}
4138
4139void Context::deleteBuffers(GLsizei n, const GLuint *buffers)
4140{
4141 for (int i = 0; i < n; i++)
4142 {
4143 deleteBuffer(buffers[i]);
4144 }
4145}
4146
4147void Context::deleteFramebuffers(GLsizei n, const GLuint *framebuffers)
4148{
4149 for (int i = 0; i < n; i++)
4150 {
4151 if (framebuffers[i] != 0)
4152 {
4153 deleteFramebuffer(framebuffers[i]);
4154 }
4155 }
4156}
4157
4158void Context::deleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)
4159{
4160 for (int i = 0; i < n; i++)
4161 {
4162 deleteRenderbuffer(renderbuffers[i]);
4163 }
4164}
4165
4166void Context::deleteTextures(GLsizei n, const GLuint *textures)
4167{
4168 for (int i = 0; i < n; i++)
4169 {
4170 if (textures[i] != 0)
4171 {
4172 deleteTexture(textures[i]);
4173 }
4174 }
4175}
4176
4177void Context::detachShader(GLuint program, GLuint shader)
4178{
4179 Program *programObject = getProgram(program);
4180 ASSERT(programObject);
4181
4182 Shader *shaderObject = getShader(shader);
4183 ASSERT(shaderObject);
4184
4185 programObject->detachShader(this, shaderObject);
4186}
4187
4188void Context::genBuffers(GLsizei n, GLuint *buffers)
4189{
4190 for (int i = 0; i < n; i++)
4191 {
4192 buffers[i] = createBuffer();
4193 }
4194}
4195
4196void Context::genFramebuffers(GLsizei n, GLuint *framebuffers)
4197{
4198 for (int i = 0; i < n; i++)
4199 {
4200 framebuffers[i] = createFramebuffer();
4201 }
4202}
4203
4204void Context::genRenderbuffers(GLsizei n, GLuint *renderbuffers)
4205{
4206 for (int i = 0; i < n; i++)
4207 {
4208 renderbuffers[i] = createRenderbuffer();
4209 }
4210}
4211
4212void Context::genTextures(GLsizei n, GLuint *textures)
4213{
4214 for (int i = 0; i < n; i++)
4215 {
4216 textures[i] = createTexture();
4217 }
4218}
4219
4220void Context::getActiveAttrib(GLuint program,
4221 GLuint index,
4222 GLsizei bufsize,
4223 GLsizei *length,
4224 GLint *size,
4225 GLenum *type,
4226 GLchar *name)
4227{
4228 Program *programObject = getProgram(program);
4229 ASSERT(programObject);
4230 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
4231}
4232
4233void Context::getActiveUniform(GLuint program,
4234 GLuint index,
4235 GLsizei bufsize,
4236 GLsizei *length,
4237 GLint *size,
4238 GLenum *type,
4239 GLchar *name)
4240{
4241 Program *programObject = getProgram(program);
4242 ASSERT(programObject);
4243 programObject->getActiveUniform(index, bufsize, length, size, type, name);
4244}
4245
4246void Context::getAttachedShaders(GLuint program, GLsizei maxcount, GLsizei *count, GLuint *shaders)
4247{
4248 Program *programObject = getProgram(program);
4249 ASSERT(programObject);
4250 programObject->getAttachedShaders(maxcount, count, shaders);
4251}
4252
4253GLint Context::getAttribLocation(GLuint program, const GLchar *name)
4254{
4255 Program *programObject = getProgram(program);
4256 ASSERT(programObject);
4257 return programObject->getAttributeLocation(name);
4258}
4259
4260void Context::getBooleanv(GLenum pname, GLboolean *params)
4261{
4262 GLenum nativeType;
4263 unsigned int numParams = 0;
4264 getQueryParameterInfo(pname, &nativeType, &numParams);
4265
4266 if (nativeType == GL_BOOL)
4267 {
4268 getBooleanvImpl(pname, params);
4269 }
4270 else
4271 {
4272 CastStateValues(this, nativeType, pname, numParams, params);
4273 }
4274}
4275
4276void Context::getFloatv(GLenum pname, GLfloat *params)
4277{
4278 GLenum nativeType;
4279 unsigned int numParams = 0;
4280 getQueryParameterInfo(pname, &nativeType, &numParams);
4281
4282 if (nativeType == GL_FLOAT)
4283 {
4284 getFloatvImpl(pname, params);
4285 }
4286 else
4287 {
4288 CastStateValues(this, nativeType, pname, numParams, params);
4289 }
4290}
4291
4292void Context::getIntegerv(GLenum pname, GLint *params)
4293{
4294 GLenum nativeType;
4295 unsigned int numParams = 0;
4296 getQueryParameterInfo(pname, &nativeType, &numParams);
4297
4298 if (nativeType == GL_INT)
4299 {
4300 getIntegervImpl(pname, params);
4301 }
4302 else
4303 {
4304 CastStateValues(this, nativeType, pname, numParams, params);
4305 }
4306}
4307
4308void Context::getProgramiv(GLuint program, GLenum pname, GLint *params)
4309{
4310 Program *programObject = getProgram(program);
4311 ASSERT(programObject);
4312 QueryProgramiv(programObject, pname, params);
4313}
4314
Jamie Madillbe849e42017-05-02 15:49:00 -04004315void Context::getProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei *length, GLchar *infolog)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004316{
4317 Program *programObject = getProgram(program);
4318 ASSERT(programObject);
4319 programObject->getInfoLog(bufsize, length, infolog);
4320}
4321
4322void Context::getShaderiv(GLuint shader, GLenum pname, GLint *params)
4323{
4324 Shader *shaderObject = getShader(shader);
4325 ASSERT(shaderObject);
4326 QueryShaderiv(shaderObject, pname, params);
4327}
4328
4329void Context::getShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *infolog)
4330{
4331 Shader *shaderObject = getShader(shader);
4332 ASSERT(shaderObject);
4333 shaderObject->getInfoLog(bufsize, length, infolog);
4334}
4335
4336void Context::getShaderPrecisionFormat(GLenum shadertype,
4337 GLenum precisiontype,
4338 GLint *range,
4339 GLint *precision)
4340{
4341 // TODO(jmadill): Compute shaders.
4342
4343 switch (shadertype)
4344 {
4345 case GL_VERTEX_SHADER:
4346 switch (precisiontype)
4347 {
4348 case GL_LOW_FLOAT:
4349 mCaps.vertexLowpFloat.get(range, precision);
4350 break;
4351 case GL_MEDIUM_FLOAT:
4352 mCaps.vertexMediumpFloat.get(range, precision);
4353 break;
4354 case GL_HIGH_FLOAT:
4355 mCaps.vertexHighpFloat.get(range, precision);
4356 break;
4357
4358 case GL_LOW_INT:
4359 mCaps.vertexLowpInt.get(range, precision);
4360 break;
4361 case GL_MEDIUM_INT:
4362 mCaps.vertexMediumpInt.get(range, precision);
4363 break;
4364 case GL_HIGH_INT:
4365 mCaps.vertexHighpInt.get(range, precision);
4366 break;
4367
4368 default:
4369 UNREACHABLE();
4370 return;
4371 }
4372 break;
4373
4374 case GL_FRAGMENT_SHADER:
4375 switch (precisiontype)
4376 {
4377 case GL_LOW_FLOAT:
4378 mCaps.fragmentLowpFloat.get(range, precision);
4379 break;
4380 case GL_MEDIUM_FLOAT:
4381 mCaps.fragmentMediumpFloat.get(range, precision);
4382 break;
4383 case GL_HIGH_FLOAT:
4384 mCaps.fragmentHighpFloat.get(range, precision);
4385 break;
4386
4387 case GL_LOW_INT:
4388 mCaps.fragmentLowpInt.get(range, precision);
4389 break;
4390 case GL_MEDIUM_INT:
4391 mCaps.fragmentMediumpInt.get(range, precision);
4392 break;
4393 case GL_HIGH_INT:
4394 mCaps.fragmentHighpInt.get(range, precision);
4395 break;
4396
4397 default:
4398 UNREACHABLE();
4399 return;
4400 }
4401 break;
4402
4403 default:
4404 UNREACHABLE();
4405 return;
4406 }
4407}
4408
4409void Context::getShaderSource(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source)
4410{
4411 Shader *shaderObject = getShader(shader);
4412 ASSERT(shaderObject);
4413 shaderObject->getSource(bufsize, length, source);
4414}
4415
4416void Context::getUniformfv(GLuint program, GLint location, GLfloat *params)
4417{
4418 Program *programObject = getProgram(program);
4419 ASSERT(programObject);
4420 programObject->getUniformfv(location, params);
4421}
4422
4423void Context::getUniformiv(GLuint program, GLint location, GLint *params)
4424{
4425 Program *programObject = getProgram(program);
4426 ASSERT(programObject);
4427 programObject->getUniformiv(location, params);
4428}
4429
4430GLint Context::getUniformLocation(GLuint program, const GLchar *name)
4431{
4432 Program *programObject = getProgram(program);
4433 ASSERT(programObject);
4434 return programObject->getUniformLocation(name);
4435}
4436
4437GLboolean Context::isBuffer(GLuint buffer)
4438{
4439 if (buffer == 0)
4440 {
4441 return GL_FALSE;
4442 }
4443
4444 return (getBuffer(buffer) ? GL_TRUE : GL_FALSE);
4445}
4446
4447GLboolean Context::isEnabled(GLenum cap)
4448{
4449 return mGLState.getEnableFeature(cap);
4450}
4451
4452GLboolean Context::isFramebuffer(GLuint framebuffer)
4453{
4454 if (framebuffer == 0)
4455 {
4456 return GL_FALSE;
4457 }
4458
4459 return (getFramebuffer(framebuffer) ? GL_TRUE : GL_FALSE);
4460}
4461
4462GLboolean Context::isProgram(GLuint program)
4463{
4464 if (program == 0)
4465 {
4466 return GL_FALSE;
4467 }
4468
4469 return (getProgram(program) ? GL_TRUE : GL_FALSE);
4470}
4471
4472GLboolean Context::isRenderbuffer(GLuint renderbuffer)
4473{
4474 if (renderbuffer == 0)
4475 {
4476 return GL_FALSE;
4477 }
4478
4479 return (getRenderbuffer(renderbuffer) ? GL_TRUE : GL_FALSE);
4480}
4481
4482GLboolean Context::isShader(GLuint shader)
4483{
4484 if (shader == 0)
4485 {
4486 return GL_FALSE;
4487 }
4488
4489 return (getShader(shader) ? GL_TRUE : GL_FALSE);
4490}
4491
4492GLboolean Context::isTexture(GLuint texture)
4493{
4494 if (texture == 0)
4495 {
4496 return GL_FALSE;
4497 }
4498
4499 return (getTexture(texture) ? GL_TRUE : GL_FALSE);
4500}
4501
4502void Context::linkProgram(GLuint program)
4503{
4504 Program *programObject = getProgram(program);
4505 ASSERT(programObject);
4506 handleError(programObject->link(this));
4507}
4508
4509void Context::releaseShaderCompiler()
4510{
4511 handleError(mCompiler->release());
4512}
4513
4514void Context::shaderBinary(GLsizei n,
4515 const GLuint *shaders,
4516 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04004517 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004518 GLsizei length)
4519{
4520 // No binary shader formats are supported.
4521 UNIMPLEMENTED();
4522}
4523
4524void Context::shaderSource(GLuint shader,
4525 GLsizei count,
4526 const GLchar *const *string,
4527 const GLint *length)
4528{
4529 Shader *shaderObject = getShader(shader);
4530 ASSERT(shaderObject);
4531 shaderObject->setSource(count, string, length);
4532}
4533
4534void Context::stencilFunc(GLenum func, GLint ref, GLuint mask)
4535{
4536 stencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
4537}
4538
4539void Context::stencilMask(GLuint mask)
4540{
4541 stencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4542}
4543
4544void Context::stencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4545{
4546 stencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4547}
4548
4549void Context::uniform1f(GLint location, GLfloat x)
4550{
4551 Program *program = mGLState.getProgram();
4552 program->setUniform1fv(location, 1, &x);
4553}
4554
4555void Context::uniform1fv(GLint location, GLsizei count, const GLfloat *v)
4556{
4557 Program *program = mGLState.getProgram();
4558 program->setUniform1fv(location, count, v);
4559}
4560
4561void Context::uniform1i(GLint location, GLint x)
4562{
4563 Program *program = mGLState.getProgram();
4564 program->setUniform1iv(location, 1, &x);
4565}
4566
4567void Context::uniform1iv(GLint location, GLsizei count, const GLint *v)
4568{
4569 Program *program = mGLState.getProgram();
4570 program->setUniform1iv(location, count, v);
4571}
4572
4573void Context::uniform2f(GLint location, GLfloat x, GLfloat y)
4574{
4575 GLfloat xy[2] = {x, y};
4576 Program *program = mGLState.getProgram();
4577 program->setUniform2fv(location, 1, xy);
4578}
4579
4580void Context::uniform2fv(GLint location, GLsizei count, const GLfloat *v)
4581{
4582 Program *program = mGLState.getProgram();
4583 program->setUniform2fv(location, count, v);
4584}
4585
4586void Context::uniform2i(GLint location, GLint x, GLint y)
4587{
4588 GLint xy[2] = {x, y};
4589 Program *program = mGLState.getProgram();
4590 program->setUniform2iv(location, 1, xy);
4591}
4592
4593void Context::uniform2iv(GLint location, GLsizei count, const GLint *v)
4594{
4595 Program *program = mGLState.getProgram();
4596 program->setUniform2iv(location, count, v);
4597}
4598
4599void Context::uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4600{
4601 GLfloat xyz[3] = {x, y, z};
4602 Program *program = mGLState.getProgram();
4603 program->setUniform3fv(location, 1, xyz);
4604}
4605
4606void Context::uniform3fv(GLint location, GLsizei count, const GLfloat *v)
4607{
4608 Program *program = mGLState.getProgram();
4609 program->setUniform3fv(location, count, v);
4610}
4611
4612void Context::uniform3i(GLint location, GLint x, GLint y, GLint z)
4613{
4614 GLint xyz[3] = {x, y, z};
4615 Program *program = mGLState.getProgram();
4616 program->setUniform3iv(location, 1, xyz);
4617}
4618
4619void Context::uniform3iv(GLint location, GLsizei count, const GLint *v)
4620{
4621 Program *program = mGLState.getProgram();
4622 program->setUniform3iv(location, count, v);
4623}
4624
4625void Context::uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4626{
4627 GLfloat xyzw[4] = {x, y, z, w};
4628 Program *program = mGLState.getProgram();
4629 program->setUniform4fv(location, 1, xyzw);
4630}
4631
4632void Context::uniform4fv(GLint location, GLsizei count, const GLfloat *v)
4633{
4634 Program *program = mGLState.getProgram();
4635 program->setUniform4fv(location, count, v);
4636}
4637
4638void Context::uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4639{
4640 GLint xyzw[4] = {x, y, z, w};
4641 Program *program = mGLState.getProgram();
4642 program->setUniform4iv(location, 1, xyzw);
4643}
4644
4645void Context::uniform4iv(GLint location, GLsizei count, const GLint *v)
4646{
4647 Program *program = mGLState.getProgram();
4648 program->setUniform4iv(location, count, v);
4649}
4650
4651void Context::uniformMatrix2fv(GLint location,
4652 GLsizei count,
4653 GLboolean transpose,
4654 const GLfloat *value)
4655{
4656 Program *program = mGLState.getProgram();
4657 program->setUniformMatrix2fv(location, count, transpose, value);
4658}
4659
4660void Context::uniformMatrix3fv(GLint location,
4661 GLsizei count,
4662 GLboolean transpose,
4663 const GLfloat *value)
4664{
4665 Program *program = mGLState.getProgram();
4666 program->setUniformMatrix3fv(location, count, transpose, value);
4667}
4668
4669void Context::uniformMatrix4fv(GLint location,
4670 GLsizei count,
4671 GLboolean transpose,
4672 const GLfloat *value)
4673{
4674 Program *program = mGLState.getProgram();
4675 program->setUniformMatrix4fv(location, count, transpose, value);
4676}
4677
4678void Context::validateProgram(GLuint program)
4679{
4680 Program *programObject = getProgram(program);
4681 ASSERT(programObject);
4682 programObject->validate(mCaps);
4683}
4684
Jamie Madillc29968b2016-01-20 11:17:23 -05004685} // namespace gl