blob: ec4de3e2102a0fb819b337f17e75403ce9959432 [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();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500121 return gl::InternalError() << "Unreachable Error";
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500122 }
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 Madill2f348d22017-06-05 10:50:59 -0400260 mCompiler(),
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)),
Jamie Madill61e16b42017-06-19 11:13:23 -0400269 mCurrentSurface(static_cast<egl::Surface *>(EGL_NO_SURFACE)),
270 mCurrentDisplay(static_cast<egl::Display *>(EGL_NO_DISPLAY)),
Jamie Madill4e0e6f82017-02-17 11:06:03 -0500271 mSurfacelessFramebuffer(nullptr),
Jamie Madille14951e2017-03-09 18:55:16 -0500272 mWebGLContext(GetWebGLContext(attribs)),
273 mScratchBuffer(1000u)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000274{
Geoff Lang077f20a2016-11-01 10:08:02 -0400275 if (mRobustAccess)
276 {
277 UNIMPLEMENTED();
278 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000279
Jamie Madill4e0e6f82017-02-17 11:06:03 -0500280 initCaps(displayExtensions);
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700281 initWorkarounds();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400282
Geoff Langeb66a6e2016-10-31 13:06:12 -0400283 mGLState.initialize(mCaps, mExtensions, getClientVersion(), GetDebug(attribs),
Jamie Madille08a1d32017-03-07 17:24:06 -0500284 GetBindGeneratesResource(attribs), GetClientArraysEnabled(attribs),
Jamie Madill948bbe52017-06-01 13:10:42 -0400285 robustResourceInit);
Régis Fénéon83107972015-02-05 12:57:44 +0100286
Shannon Woods53a94a82014-06-24 15:20:36 -0400287 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400288
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000289 // [OpenGL ES 2.0.24] section 3.7 page 83:
290 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
291 // and cube map texture state vectors respectively associated with them.
292 // In order that access to these initial textures not be lost, they are treated as texture
293 // objects all of whose names are 0.
294
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400295 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500296 mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500297
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400298 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500299 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400300
Geoff Langeb66a6e2016-10-31 13:06:12 -0400301 if (getClientVersion() >= Version(3, 0))
Geoff Lang76b10c92014-09-05 16:28:14 -0400302 {
303 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400304 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500305 mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400306
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400307 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500308 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400309 }
Geoff Lang3b573612016-10-31 14:08:10 -0400310 if (getClientVersion() >= Version(3, 1))
311 {
312 Texture *zeroTexture2DMultisample =
313 new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_MULTISAMPLE);
314 mZeroTextures[GL_TEXTURE_2D_MULTISAMPLE].set(zeroTexture2DMultisample);
Jiajia Qin6eafb042016-12-27 17:04:07 +0800315
316 bindGenericAtomicCounterBuffer(0);
317 for (unsigned int i = 0; i < mCaps.maxAtomicCounterBufferBindings; i++)
318 {
319 bindIndexedAtomicCounterBuffer(0, i, 0, 0);
320 }
Jiajia Qinf546e7d2017-03-27 14:12:59 +0800321
322 bindGenericShaderStorageBuffer(0);
323 for (unsigned int i = 0; i < mCaps.maxShaderStorageBufferBindings; i++)
324 {
325 bindIndexedShaderStorageBuffer(0, i, 0, 0);
326 }
Geoff Lang3b573612016-10-31 14:08:10 -0400327 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000328
Ian Ewellbda75592016-04-18 17:25:54 -0400329 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
330 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400331 Texture *zeroTextureExternal =
332 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Ian Ewellbda75592016-04-18 17:25:54 -0400333 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(zeroTextureExternal);
334 }
335
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700336 mGLState.initializeZeroTextures(mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500337
Jamie Madill57a89722013-07-02 11:57:03 -0400338 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000339 bindArrayBuffer(0);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800340 bindDrawIndirectBuffer(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000341 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400342
Jamie Madill01a80ee2016-11-07 12:06:18 -0500343 bindRenderbuffer(GL_RENDERBUFFER, 0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000344
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000345 bindGenericUniformBuffer(0);
Geoff Lang4dc3af02016-11-18 14:09:27 -0500346 for (unsigned int i = 0; i < mCaps.maxUniformBufferBindings; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000347 {
348 bindIndexedUniformBuffer(0, i, 0, -1);
349 }
350
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000351 bindCopyReadBuffer(0);
352 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000353 bindPixelPackBuffer(0);
354 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000355
Geoff Langeb66a6e2016-10-31 13:06:12 -0400356 if (getClientVersion() >= Version(3, 0))
Geoff Lang1a683462015-09-29 15:09:59 -0400357 {
358 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
359 // In the initial state, a default transform feedback object is bound and treated as
360 // a transform feedback object with a name of zero. That object is bound any time
361 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400362 bindTransformFeedback(0);
363 }
Geoff Langc8058452014-02-03 12:04:11 -0500364
Jamie Madillad9f24e2016-02-12 09:27:24 -0500365 // Initialize dirty bit masks
366 // TODO(jmadill): additional ES3 state
367 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
368 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
369 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
370 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
371 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
372 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400373 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500374 // No dirty objects.
375
376 // Readpixels uses the pack state and read FBO
377 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
378 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
379 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
380 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
381 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400382 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500383 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
384
385 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
386 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
387 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
388 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
389 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
390 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
391 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
392 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
393 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
394 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
395 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
396 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
397
398 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
399 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700400 mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500401 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
402 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400403
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400404 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000405}
406
Jamie Madill70ee0f62017-02-06 16:04:20 -0500407void Context::destroy(egl::Display *display)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000408{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500409 mGLState.reset(this);
Geoff Lang21329412014-12-02 20:50:30 +0000410
Corentin Wallez80b24112015-08-25 16:41:57 -0400411 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000412 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400413 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000414 }
415
Corentin Wallez80b24112015-08-25 16:41:57 -0400416 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000417 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400418 if (query.second != nullptr)
419 {
420 query.second->release();
421 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000422 }
423
Corentin Wallez80b24112015-08-25 16:41:57 -0400424 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400425 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400426 SafeDelete(vertexArray.second);
Jamie Madill57a89722013-07-02 11:57:03 -0400427 }
428
Corentin Wallez80b24112015-08-25 16:41:57 -0400429 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500430 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500431 if (transformFeedback.second != nullptr)
432 {
Jamie Madill6c1f6712017-02-14 19:08:04 -0500433 transformFeedback.second->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500434 }
Geoff Langc8058452014-02-03 12:04:11 -0500435 }
436
Jamie Madilldedd7b92014-11-05 16:30:36 -0500437 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400438 {
Yunchao Hef81ce4a2017-04-24 10:49:17 +0800439 zeroTexture.second.set(nullptr);
Geoff Lang76b10c92014-09-05 16:28:14 -0400440 }
441 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000442
Corentin Wallezccab69d2017-01-27 16:57:15 -0500443 SafeDelete(mSurfacelessFramebuffer);
444
Jamie Madill70ee0f62017-02-06 16:04:20 -0500445 releaseSurface(display);
Jamie Madill2f348d22017-06-05 10:50:59 -0400446 releaseShaderCompiler();
Jamie Madill6c1f6712017-02-14 19:08:04 -0500447
448 mState.mBuffers->release(this);
449 mState.mShaderPrograms->release(this);
450 mState.mTextures->release(this);
451 mState.mRenderbuffers->release(this);
452 mState.mSamplers->release(this);
453 mState.mFenceSyncs->release(this);
454 mState.mPaths->release(this);
455 mState.mFramebuffers->release(this);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000456}
457
Jamie Madill70ee0f62017-02-06 16:04:20 -0500458Context::~Context()
459{
460}
461
462void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000463{
Jamie Madill61e16b42017-06-19 11:13:23 -0400464 mCurrentDisplay = display;
465
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 Madill2f348d22017-06-05 10:50:59 -04001251FenceNV *Context::getFenceNV(GLuint 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
Jamie Madill2f348d22017-06-05 10:50:59 -04001265Query *Context::getQuery(GLuint handle, bool create, GLenum type)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001266{
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{
Jamie Madill2f348d22017-06-05 10:50:59 -04001303 if (mCompiler.get() == nullptr)
1304 {
1305 mCompiler.set(new Compiler(mImplementation.get(), mState));
1306 }
1307 return mCompiler.get();
Geoff Lang492a7e42014-11-05 13:27:06 -05001308}
1309
Jamie Madillc1d770e2017-04-13 17:31:24 -04001310void Context::getBooleanvImpl(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001311{
1312 switch (pname)
1313 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001314 case GL_SHADER_COMPILER:
1315 *params = GL_TRUE;
1316 break;
1317 case GL_CONTEXT_ROBUST_ACCESS_EXT:
1318 *params = mRobustAccess ? GL_TRUE : GL_FALSE;
1319 break;
1320 default:
1321 mGLState.getBooleanv(pname, params);
1322 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001323 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001324}
1325
Jamie Madillc1d770e2017-04-13 17:31:24 -04001326void Context::getFloatvImpl(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001327{
Shannon Woods53a94a82014-06-24 15:20:36 -04001328 // Queries about context capabilities and maximums are answered by Context.
1329 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001330 switch (pname)
1331 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001332 case GL_ALIASED_LINE_WIDTH_RANGE:
1333 params[0] = mCaps.minAliasedLineWidth;
1334 params[1] = mCaps.maxAliasedLineWidth;
1335 break;
1336 case GL_ALIASED_POINT_SIZE_RANGE:
1337 params[0] = mCaps.minAliasedPointSize;
1338 params[1] = mCaps.maxAliasedPointSize;
1339 break;
1340 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1341 ASSERT(mExtensions.textureFilterAnisotropic);
1342 *params = mExtensions.maxTextureAnisotropy;
1343 break;
1344 case GL_MAX_TEXTURE_LOD_BIAS:
1345 *params = mCaps.maxLODBias;
1346 break;
1347
1348 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1349 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1350 {
1351 ASSERT(mExtensions.pathRendering);
1352 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1353 memcpy(params, m, 16 * sizeof(GLfloat));
1354 }
Geoff Lange6d4e122015-06-29 13:33:55 -04001355 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001356
Jamie Madill231c7f52017-04-26 13:45:37 -04001357 default:
1358 mGLState.getFloatv(pname, params);
1359 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001360 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001361}
1362
Jamie Madillc1d770e2017-04-13 17:31:24 -04001363void Context::getIntegervImpl(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001364{
Shannon Woods53a94a82014-06-24 15:20:36 -04001365 // Queries about context capabilities and maximums are answered by Context.
1366 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001367
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001368 switch (pname)
1369 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001370 case GL_MAX_VERTEX_ATTRIBS:
1371 *params = mCaps.maxVertexAttributes;
1372 break;
1373 case GL_MAX_VERTEX_UNIFORM_VECTORS:
1374 *params = mCaps.maxVertexUniformVectors;
1375 break;
1376 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
1377 *params = mCaps.maxVertexUniformComponents;
1378 break;
1379 case GL_MAX_VARYING_VECTORS:
1380 *params = mCaps.maxVaryingVectors;
1381 break;
1382 case GL_MAX_VARYING_COMPONENTS:
1383 *params = mCaps.maxVertexOutputComponents;
1384 break;
1385 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1386 *params = mCaps.maxCombinedTextureImageUnits;
1387 break;
1388 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1389 *params = mCaps.maxVertexTextureImageUnits;
1390 break;
1391 case GL_MAX_TEXTURE_IMAGE_UNITS:
1392 *params = mCaps.maxTextureImageUnits;
1393 break;
1394 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1395 *params = mCaps.maxFragmentUniformVectors;
1396 break;
1397 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
1398 *params = mCaps.maxFragmentUniformComponents;
1399 break;
1400 case GL_MAX_RENDERBUFFER_SIZE:
1401 *params = mCaps.maxRenderbufferSize;
1402 break;
1403 case GL_MAX_COLOR_ATTACHMENTS_EXT:
1404 *params = mCaps.maxColorAttachments;
1405 break;
1406 case GL_MAX_DRAW_BUFFERS_EXT:
1407 *params = mCaps.maxDrawBuffers;
1408 break;
1409 // case GL_FRAMEBUFFER_BINDING: // now equivalent to
1410 // GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1411 case GL_SUBPIXEL_BITS:
1412 *params = 4;
1413 break;
1414 case GL_MAX_TEXTURE_SIZE:
1415 *params = mCaps.max2DTextureSize;
1416 break;
1417 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1418 *params = mCaps.maxCubeMapTextureSize;
1419 break;
1420 case GL_MAX_3D_TEXTURE_SIZE:
1421 *params = mCaps.max3DTextureSize;
1422 break;
1423 case GL_MAX_ARRAY_TEXTURE_LAYERS:
1424 *params = mCaps.maxArrayTextureLayers;
1425 break;
1426 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
1427 *params = mCaps.uniformBufferOffsetAlignment;
1428 break;
1429 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
1430 *params = mCaps.maxUniformBufferBindings;
1431 break;
1432 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
1433 *params = mCaps.maxVertexUniformBlocks;
1434 break;
1435 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
1436 *params = mCaps.maxFragmentUniformBlocks;
1437 break;
1438 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
1439 *params = mCaps.maxCombinedTextureImageUnits;
1440 break;
1441 case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
1442 *params = mCaps.maxVertexOutputComponents;
1443 break;
1444 case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
1445 *params = mCaps.maxFragmentInputComponents;
1446 break;
1447 case GL_MIN_PROGRAM_TEXEL_OFFSET:
1448 *params = mCaps.minProgramTexelOffset;
1449 break;
1450 case GL_MAX_PROGRAM_TEXEL_OFFSET:
1451 *params = mCaps.maxProgramTexelOffset;
1452 break;
1453 case GL_MAJOR_VERSION:
1454 *params = getClientVersion().major;
1455 break;
1456 case GL_MINOR_VERSION:
1457 *params = getClientVersion().minor;
1458 break;
1459 case GL_MAX_ELEMENTS_INDICES:
1460 *params = mCaps.maxElementsIndices;
1461 break;
1462 case GL_MAX_ELEMENTS_VERTICES:
1463 *params = mCaps.maxElementsVertices;
1464 break;
1465 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
1466 *params = mCaps.maxTransformFeedbackInterleavedComponents;
1467 break;
1468 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
1469 *params = mCaps.maxTransformFeedbackSeparateAttributes;
1470 break;
1471 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
1472 *params = mCaps.maxTransformFeedbackSeparateComponents;
1473 break;
1474 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1475 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1476 break;
1477 case GL_MAX_SAMPLES_ANGLE:
1478 *params = mCaps.maxSamples;
1479 break;
1480 case GL_MAX_VIEWPORT_DIMS:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001481 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001482 params[0] = mCaps.maxViewportWidth;
1483 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001484 }
1485 break;
Jamie Madill231c7f52017-04-26 13:45:37 -04001486 case GL_COMPRESSED_TEXTURE_FORMATS:
1487 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(),
1488 params);
1489 break;
1490 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1491 *params = mResetStrategy;
1492 break;
1493 case GL_NUM_SHADER_BINARY_FORMATS:
1494 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
1495 break;
1496 case GL_SHADER_BINARY_FORMATS:
1497 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1498 break;
1499 case GL_NUM_PROGRAM_BINARY_FORMATS:
1500 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
1501 break;
1502 case GL_PROGRAM_BINARY_FORMATS:
1503 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
1504 break;
1505 case GL_NUM_EXTENSIONS:
1506 *params = static_cast<GLint>(mExtensionStrings.size());
1507 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001508
Jamie Madill231c7f52017-04-26 13:45:37 -04001509 // GL_KHR_debug
1510 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1511 *params = mExtensions.maxDebugMessageLength;
1512 break;
1513 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1514 *params = mExtensions.maxDebugLoggedMessages;
1515 break;
1516 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1517 *params = mExtensions.maxDebugGroupStackDepth;
1518 break;
1519 case GL_MAX_LABEL_LENGTH:
1520 *params = mExtensions.maxLabelLength;
1521 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001522
Jamie Madill231c7f52017-04-26 13:45:37 -04001523 // GL_EXT_disjoint_timer_query
1524 case GL_GPU_DISJOINT_EXT:
1525 *params = mImplementation->getGPUDisjoint();
1526 break;
1527 case GL_MAX_FRAMEBUFFER_WIDTH:
1528 *params = mCaps.maxFramebufferWidth;
1529 break;
1530 case GL_MAX_FRAMEBUFFER_HEIGHT:
1531 *params = mCaps.maxFramebufferHeight;
1532 break;
1533 case GL_MAX_FRAMEBUFFER_SAMPLES:
1534 *params = mCaps.maxFramebufferSamples;
1535 break;
1536 case GL_MAX_SAMPLE_MASK_WORDS:
1537 *params = mCaps.maxSampleMaskWords;
1538 break;
1539 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1540 *params = mCaps.maxColorTextureSamples;
1541 break;
1542 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1543 *params = mCaps.maxDepthTextureSamples;
1544 break;
1545 case GL_MAX_INTEGER_SAMPLES:
1546 *params = mCaps.maxIntegerSamples;
1547 break;
1548 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1549 *params = mCaps.maxVertexAttribRelativeOffset;
1550 break;
1551 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1552 *params = mCaps.maxVertexAttribBindings;
1553 break;
1554 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1555 *params = mCaps.maxVertexAttribStride;
1556 break;
1557 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1558 *params = mCaps.maxVertexAtomicCounterBuffers;
1559 break;
1560 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1561 *params = mCaps.maxVertexAtomicCounters;
1562 break;
1563 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1564 *params = mCaps.maxVertexImageUniforms;
1565 break;
1566 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1567 *params = mCaps.maxVertexShaderStorageBlocks;
1568 break;
1569 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1570 *params = mCaps.maxFragmentAtomicCounterBuffers;
1571 break;
1572 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1573 *params = mCaps.maxFragmentAtomicCounters;
1574 break;
1575 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1576 *params = mCaps.maxFragmentImageUniforms;
1577 break;
1578 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1579 *params = mCaps.maxFragmentShaderStorageBlocks;
1580 break;
1581 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1582 *params = mCaps.minProgramTextureGatherOffset;
1583 break;
1584 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1585 *params = mCaps.maxProgramTextureGatherOffset;
1586 break;
1587 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1588 *params = mCaps.maxComputeWorkGroupInvocations;
1589 break;
1590 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1591 *params = mCaps.maxComputeUniformBlocks;
1592 break;
1593 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1594 *params = mCaps.maxComputeTextureImageUnits;
1595 break;
1596 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1597 *params = mCaps.maxComputeSharedMemorySize;
1598 break;
1599 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1600 *params = mCaps.maxComputeUniformComponents;
1601 break;
1602 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1603 *params = mCaps.maxComputeAtomicCounterBuffers;
1604 break;
1605 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1606 *params = mCaps.maxComputeAtomicCounters;
1607 break;
1608 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1609 *params = mCaps.maxComputeImageUniforms;
1610 break;
1611 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1612 *params = mCaps.maxCombinedComputeUniformComponents;
1613 break;
1614 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1615 *params = mCaps.maxComputeShaderStorageBlocks;
1616 break;
1617 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1618 *params = mCaps.maxCombinedShaderOutputResources;
1619 break;
1620 case GL_MAX_UNIFORM_LOCATIONS:
1621 *params = mCaps.maxUniformLocations;
1622 break;
1623 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1624 *params = mCaps.maxAtomicCounterBufferBindings;
1625 break;
1626 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1627 *params = mCaps.maxAtomicCounterBufferSize;
1628 break;
1629 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1630 *params = mCaps.maxCombinedAtomicCounterBuffers;
1631 break;
1632 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1633 *params = mCaps.maxCombinedAtomicCounters;
1634 break;
1635 case GL_MAX_IMAGE_UNITS:
1636 *params = mCaps.maxImageUnits;
1637 break;
1638 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1639 *params = mCaps.maxCombinedImageUniforms;
1640 break;
1641 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1642 *params = mCaps.maxShaderStorageBufferBindings;
1643 break;
1644 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1645 *params = mCaps.maxCombinedShaderStorageBlocks;
1646 break;
1647 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1648 *params = mCaps.shaderStorageBufferOffsetAlignment;
1649 break;
1650 default:
1651 mGLState.getIntegerv(this, pname, params);
1652 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001653 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001654}
1655
Jamie Madill893ab082014-05-16 16:56:10 -04001656void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001657{
Shannon Woods53a94a82014-06-24 15:20:36 -04001658 // Queries about context capabilities and maximums are answered by Context.
1659 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001660 switch (pname)
1661 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001662 case GL_MAX_ELEMENT_INDEX:
1663 *params = mCaps.maxElementIndex;
1664 break;
1665 case GL_MAX_UNIFORM_BLOCK_SIZE:
1666 *params = mCaps.maxUniformBlockSize;
1667 break;
1668 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
1669 *params = mCaps.maxCombinedVertexUniformComponents;
1670 break;
1671 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
1672 *params = mCaps.maxCombinedFragmentUniformComponents;
1673 break;
1674 case GL_MAX_SERVER_WAIT_TIMEOUT:
1675 *params = mCaps.maxServerWaitTimeout;
1676 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001677
Jamie Madill231c7f52017-04-26 13:45:37 -04001678 // GL_EXT_disjoint_timer_query
1679 case GL_TIMESTAMP_EXT:
1680 *params = mImplementation->getTimestamp();
1681 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001682
Jamie Madill231c7f52017-04-26 13:45:37 -04001683 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1684 *params = mCaps.maxShaderStorageBlockSize;
1685 break;
1686 default:
1687 UNREACHABLE();
1688 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001689 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001690}
1691
Geoff Lang70d0f492015-12-10 17:45:46 -05001692void Context::getPointerv(GLenum pname, void **params) const
1693{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001694 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001695}
1696
Martin Radev66fb8202016-07-28 11:45:20 +03001697void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001698{
Shannon Woods53a94a82014-06-24 15:20:36 -04001699 // Queries about context capabilities and maximums are answered by Context.
1700 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001701
1702 GLenum nativeType;
1703 unsigned int numParams;
1704 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1705 ASSERT(queryStatus);
1706
1707 if (nativeType == GL_INT)
1708 {
1709 switch (target)
1710 {
1711 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1712 ASSERT(index < 3u);
1713 *data = mCaps.maxComputeWorkGroupCount[index];
1714 break;
1715 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1716 ASSERT(index < 3u);
1717 *data = mCaps.maxComputeWorkGroupSize[index];
1718 break;
1719 default:
1720 mGLState.getIntegeri_v(target, index, data);
1721 }
1722 }
1723 else
1724 {
1725 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1726 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001727}
1728
Martin Radev66fb8202016-07-28 11:45:20 +03001729void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001730{
Shannon Woods53a94a82014-06-24 15:20:36 -04001731 // Queries about context capabilities and maximums are answered by Context.
1732 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001733
1734 GLenum nativeType;
1735 unsigned int numParams;
1736 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1737 ASSERT(queryStatus);
1738
1739 if (nativeType == GL_INT_64_ANGLEX)
1740 {
1741 mGLState.getInteger64i_v(target, index, data);
1742 }
1743 else
1744 {
1745 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1746 }
1747}
1748
1749void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1750{
1751 // Queries about context capabilities and maximums are answered by Context.
1752 // Queries about current GL state values are answered by State.
1753
1754 GLenum nativeType;
1755 unsigned int numParams;
1756 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1757 ASSERT(queryStatus);
1758
1759 if (nativeType == GL_BOOL)
1760 {
1761 mGLState.getBooleani_v(target, index, data);
1762 }
1763 else
1764 {
1765 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1766 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001767}
1768
He Yunchao010e4db2017-03-03 14:22:06 +08001769void Context::getBufferParameteriv(GLenum target, GLenum pname, GLint *params)
1770{
1771 Buffer *buffer = mGLState.getTargetBuffer(target);
1772 QueryBufferParameteriv(buffer, pname, params);
1773}
1774
1775void Context::getFramebufferAttachmentParameteriv(GLenum target,
1776 GLenum attachment,
1777 GLenum pname,
1778 GLint *params)
1779{
1780 const Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
1781 QueryFramebufferAttachmentParameteriv(framebuffer, attachment, pname, params);
1782}
1783
1784void Context::getRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
1785{
1786 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
1787 QueryRenderbufferiv(this, renderbuffer, pname, params);
1788}
1789
1790void Context::getTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
1791{
1792 Texture *texture = getTargetTexture(target);
1793 QueryTexParameterfv(texture, pname, params);
1794}
1795
1796void Context::getTexParameteriv(GLenum target, GLenum pname, GLint *params)
1797{
1798 Texture *texture = getTargetTexture(target);
1799 QueryTexParameteriv(texture, pname, params);
1800}
1801void Context::texParameterf(GLenum target, GLenum pname, GLfloat param)
1802{
1803 Texture *texture = getTargetTexture(target);
1804 SetTexParameterf(texture, pname, param);
1805}
1806
1807void Context::texParameterfv(GLenum target, GLenum pname, const GLfloat *params)
1808{
1809 Texture *texture = getTargetTexture(target);
1810 SetTexParameterfv(texture, pname, params);
1811}
1812
1813void Context::texParameteri(GLenum target, GLenum pname, GLint param)
1814{
1815 Texture *texture = getTargetTexture(target);
1816 SetTexParameteri(texture, pname, param);
1817}
1818
1819void Context::texParameteriv(GLenum target, GLenum pname, const GLint *params)
1820{
1821 Texture *texture = getTargetTexture(target);
1822 SetTexParameteriv(texture, pname, params);
1823}
1824
Jamie Madill675fe712016-12-19 13:07:54 -05001825void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001826{
Jamie Madill1b94d432015-08-07 13:23:23 -04001827 syncRendererState();
Jamie Madillc564c072017-06-01 12:45:42 -04001828 auto error = mImplementation->drawArrays(this, mode, first, count);
Jamie Madill675fe712016-12-19 13:07:54 -05001829 handleError(error);
1830 if (!error.isError())
1831 {
1832 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1833 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001834}
1835
Jamie Madill675fe712016-12-19 13:07:54 -05001836void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Geoff Langf6db0982015-08-25 13:04:00 -04001837{
1838 syncRendererState();
Jamie Madillc564c072017-06-01 12:45:42 -04001839 auto error = mImplementation->drawArraysInstanced(this, mode, first, count, instanceCount);
Jamie Madill675fe712016-12-19 13:07:54 -05001840 handleError(error);
1841 if (!error.isError())
1842 {
1843 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1844 }
Geoff Langf6db0982015-08-25 13:04:00 -04001845}
1846
Jamie Madill876429b2017-04-20 15:46:24 -04001847void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001848{
Jamie Madill1b94d432015-08-07 13:23:23 -04001849 syncRendererState();
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001850 const IndexRange &indexRange = getParams<HasIndexRange>().getIndexRange().value();
Jamie Madillc564c072017-06-01 12:45:42 -04001851 handleError(mImplementation->drawElements(this, mode, count, type, indices, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001852}
1853
Jamie Madill675fe712016-12-19 13:07:54 -05001854void Context::drawElementsInstanced(GLenum mode,
1855 GLsizei count,
1856 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001857 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001858 GLsizei instances)
Geoff Langf6db0982015-08-25 13:04:00 -04001859{
1860 syncRendererState();
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001861 const IndexRange &indexRange = getParams<HasIndexRange>().getIndexRange().value();
Jamie Madillc564c072017-06-01 12:45:42 -04001862 handleError(mImplementation->drawElementsInstanced(this, mode, count, type, indices, instances,
1863 indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001864}
1865
Jamie Madill675fe712016-12-19 13:07:54 -05001866void Context::drawRangeElements(GLenum mode,
1867 GLuint start,
1868 GLuint end,
1869 GLsizei count,
1870 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001871 const void *indices)
Geoff Langf6db0982015-08-25 13:04:00 -04001872{
1873 syncRendererState();
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001874 const IndexRange &indexRange = getParams<HasIndexRange>().getIndexRange().value();
Jamie Madillc564c072017-06-01 12:45:42 -04001875 handleError(mImplementation->drawRangeElements(this, mode, start, end, count, type, indices,
1876 indexRange));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001877}
1878
Jamie Madill876429b2017-04-20 15:46:24 -04001879void Context::drawArraysIndirect(GLenum mode, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001880{
1881 syncRendererState();
Jamie Madillc564c072017-06-01 12:45:42 -04001882 handleError(mImplementation->drawArraysIndirect(this, mode, indirect));
Jiajia Qind9671222016-11-29 16:30:31 +08001883}
1884
Jamie Madill876429b2017-04-20 15:46:24 -04001885void Context::drawElementsIndirect(GLenum mode, GLenum type, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001886{
1887 syncRendererState();
Jamie Madillc564c072017-06-01 12:45:42 -04001888 handleError(mImplementation->drawElementsIndirect(this, mode, type, indirect));
Jiajia Qind9671222016-11-29 16:30:31 +08001889}
1890
Jamie Madill675fe712016-12-19 13:07:54 -05001891void Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001892{
Jamie Madill675fe712016-12-19 13:07:54 -05001893 handleError(mImplementation->flush());
Geoff Lang129753a2015-01-09 16:52:09 -05001894}
1895
Jamie Madill675fe712016-12-19 13:07:54 -05001896void Context::finish()
Geoff Lang129753a2015-01-09 16:52:09 -05001897{
Jamie Madill675fe712016-12-19 13:07:54 -05001898 handleError(mImplementation->finish());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001899}
1900
Austin Kinross6ee1e782015-05-29 17:05:37 -07001901void Context::insertEventMarker(GLsizei length, const char *marker)
1902{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001903 ASSERT(mImplementation);
1904 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001905}
1906
1907void Context::pushGroupMarker(GLsizei length, const char *marker)
1908{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001909 ASSERT(mImplementation);
1910 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001911}
1912
1913void Context::popGroupMarker()
1914{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001915 ASSERT(mImplementation);
1916 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001917}
1918
Geoff Langd8605522016-04-13 10:19:12 -04001919void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1920{
1921 Program *programObject = getProgram(program);
1922 ASSERT(programObject);
1923
1924 programObject->bindUniformLocation(location, name);
1925}
1926
Sami Väisänena797e062016-05-12 15:23:40 +03001927void Context::setCoverageModulation(GLenum components)
1928{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001929 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001930}
1931
Sami Väisänene45e53b2016-05-25 10:36:04 +03001932void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1933{
1934 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1935}
1936
1937void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1938{
1939 GLfloat I[16];
1940 angle::Matrix<GLfloat>::setToIdentity(I);
1941
1942 mGLState.loadPathRenderingMatrix(matrixMode, I);
1943}
1944
1945void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1946{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001947 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001948 if (!pathObj)
1949 return;
1950
1951 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1952 syncRendererState();
1953
1954 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1955}
1956
1957void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1958{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001959 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001960 if (!pathObj)
1961 return;
1962
1963 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1964 syncRendererState();
1965
1966 mImplementation->stencilStrokePath(pathObj, reference, mask);
1967}
1968
1969void Context::coverFillPath(GLuint path, GLenum coverMode)
1970{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001971 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001972 if (!pathObj)
1973 return;
1974
1975 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1976 syncRendererState();
1977
1978 mImplementation->coverFillPath(pathObj, coverMode);
1979}
1980
1981void Context::coverStrokePath(GLuint path, GLenum coverMode)
1982{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001983 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001984 if (!pathObj)
1985 return;
1986
1987 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1988 syncRendererState();
1989
1990 mImplementation->coverStrokePath(pathObj, coverMode);
1991}
1992
1993void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1994{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001995 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001996 if (!pathObj)
1997 return;
1998
1999 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2000 syncRendererState();
2001
2002 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
2003}
2004
2005void Context::stencilThenCoverStrokePath(GLuint path,
2006 GLint reference,
2007 GLuint mask,
2008 GLenum coverMode)
2009{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002010 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03002011 if (!pathObj)
2012 return;
2013
2014 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2015 syncRendererState();
2016
2017 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
2018}
2019
Sami Väisänend59ca052016-06-21 16:10:00 +03002020void Context::coverFillPathInstanced(GLsizei numPaths,
2021 GLenum pathNameType,
2022 const void *paths,
2023 GLuint pathBase,
2024 GLenum coverMode,
2025 GLenum transformType,
2026 const GLfloat *transformValues)
2027{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002028 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002029
2030 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2031 syncRendererState();
2032
2033 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
2034}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002035
Sami Väisänend59ca052016-06-21 16:10:00 +03002036void Context::coverStrokePathInstanced(GLsizei numPaths,
2037 GLenum pathNameType,
2038 const void *paths,
2039 GLuint pathBase,
2040 GLenum coverMode,
2041 GLenum transformType,
2042 const GLfloat *transformValues)
2043{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002044 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002045
2046 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2047 syncRendererState();
2048
2049 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
2050 transformValues);
2051}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002052
Sami Väisänend59ca052016-06-21 16:10:00 +03002053void Context::stencilFillPathInstanced(GLsizei numPaths,
2054 GLenum pathNameType,
2055 const void *paths,
2056 GLuint pathBase,
2057 GLenum fillMode,
2058 GLuint mask,
2059 GLenum transformType,
2060 const GLfloat *transformValues)
2061{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002062 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002063
2064 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2065 syncRendererState();
2066
2067 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
2068 transformValues);
2069}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002070
Sami Väisänend59ca052016-06-21 16:10:00 +03002071void Context::stencilStrokePathInstanced(GLsizei numPaths,
2072 GLenum pathNameType,
2073 const void *paths,
2074 GLuint pathBase,
2075 GLint reference,
2076 GLuint mask,
2077 GLenum transformType,
2078 const GLfloat *transformValues)
2079{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002080 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002081
2082 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2083 syncRendererState();
2084
2085 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
2086 transformValues);
2087}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002088
Sami Väisänend59ca052016-06-21 16:10:00 +03002089void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
2090 GLenum pathNameType,
2091 const void *paths,
2092 GLuint pathBase,
2093 GLenum fillMode,
2094 GLuint mask,
2095 GLenum coverMode,
2096 GLenum transformType,
2097 const GLfloat *transformValues)
2098{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002099 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002100
2101 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2102 syncRendererState();
2103
2104 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
2105 transformType, transformValues);
2106}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002107
Sami Väisänend59ca052016-06-21 16:10:00 +03002108void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
2109 GLenum pathNameType,
2110 const void *paths,
2111 GLuint pathBase,
2112 GLint reference,
2113 GLuint mask,
2114 GLenum coverMode,
2115 GLenum transformType,
2116 const GLfloat *transformValues)
2117{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002118 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002119
2120 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2121 syncRendererState();
2122
2123 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
2124 transformType, transformValues);
2125}
2126
Sami Väisänen46eaa942016-06-29 10:26:37 +03002127void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
2128{
2129 auto *programObject = getProgram(program);
2130
2131 programObject->bindFragmentInputLocation(location, name);
2132}
2133
2134void Context::programPathFragmentInputGen(GLuint program,
2135 GLint location,
2136 GLenum genMode,
2137 GLint components,
2138 const GLfloat *coeffs)
2139{
2140 auto *programObject = getProgram(program);
2141
Jamie Madillbd044ed2017-06-05 12:59:21 -04002142 programObject->pathFragmentInputGen(this, location, genMode, components, coeffs);
Sami Väisänen46eaa942016-06-29 10:26:37 +03002143}
2144
jchen1015015f72017-03-16 13:54:21 +08002145GLuint Context::getProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name)
2146{
jchen10fd7c3b52017-03-21 15:36:03 +08002147 const auto *programObject = getProgram(program);
jchen1015015f72017-03-16 13:54:21 +08002148 return QueryProgramResourceIndex(programObject, programInterface, name);
2149}
2150
jchen10fd7c3b52017-03-21 15:36:03 +08002151void Context::getProgramResourceName(GLuint program,
2152 GLenum programInterface,
2153 GLuint index,
2154 GLsizei bufSize,
2155 GLsizei *length,
2156 GLchar *name)
2157{
2158 const auto *programObject = getProgram(program);
2159 QueryProgramResourceName(programObject, programInterface, index, bufSize, length, name);
2160}
2161
Jamie Madill437fa652016-05-03 15:13:24 -04002162void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002163{
Geoff Langda5777c2014-07-11 09:52:58 -04002164 if (error.isError())
2165 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002166 GLenum code = error.getCode();
2167 mErrors.insert(code);
2168 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
2169 {
2170 markContextLost();
2171 }
Geoff Lang70d0f492015-12-10 17:45:46 -05002172
2173 if (!error.getMessage().empty())
2174 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002175 auto *debug = &mGLState.getDebug();
2176 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
2177 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05002178 }
Geoff Langda5777c2014-07-11 09:52:58 -04002179 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002180}
2181
2182// Get one of the recorded errors and clear its flag, if any.
2183// [OpenGL ES 2.0.24] section 2.5 page 13.
2184GLenum Context::getError()
2185{
Geoff Langda5777c2014-07-11 09:52:58 -04002186 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002187 {
Geoff Langda5777c2014-07-11 09:52:58 -04002188 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002189 }
Geoff Langda5777c2014-07-11 09:52:58 -04002190 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002191 {
Geoff Langda5777c2014-07-11 09:52:58 -04002192 GLenum error = *mErrors.begin();
2193 mErrors.erase(mErrors.begin());
2194 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002195 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002196}
2197
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002198// NOTE: this function should not assume that this context is current!
2199void Context::markContextLost()
2200{
2201 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002202 {
Jamie Madill231c7f52017-04-26 13:45:37 -04002203 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002204 mContextLostForced = true;
2205 }
Jamie Madill231c7f52017-04-26 13:45:37 -04002206 mContextLost = true;
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002207}
2208
2209bool Context::isContextLost()
2210{
2211 return mContextLost;
2212}
2213
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002214GLenum Context::getResetStatus()
2215{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002216 // Even if the application doesn't want to know about resets, we want to know
2217 // as it will allow us to skip all the calls.
2218 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002219 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002220 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002221 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002222 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002223 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002224
2225 // EXT_robustness, section 2.6: If the reset notification behavior is
2226 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2227 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2228 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002229 }
2230
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002231 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2232 // status should be returned at least once, and GL_NO_ERROR should be returned
2233 // once the device has finished resetting.
2234 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002235 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002236 ASSERT(mResetStatus == GL_NO_ERROR);
2237 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002238
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002239 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002240 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002241 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002242 }
2243 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002244 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002245 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002246 // If markContextLost was used to mark the context lost then
2247 // assume that is not recoverable, and continue to report the
2248 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002249 mResetStatus = mImplementation->getResetStatus();
2250 }
Jamie Madill893ab082014-05-16 16:56:10 -04002251
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002252 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002253}
2254
2255bool Context::isResetNotificationEnabled()
2256{
2257 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2258}
2259
Corentin Walleze3b10e82015-05-20 11:06:25 -04002260const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002261{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002262 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002263}
2264
2265EGLenum Context::getClientType() const
2266{
2267 return mClientType;
2268}
2269
2270EGLenum Context::getRenderBuffer() const
2271{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002272 const Framebuffer *framebuffer = mState.mFramebuffers->getFramebuffer(0);
2273 if (framebuffer == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -04002274 {
2275 return EGL_NONE;
2276 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002277
2278 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2279 ASSERT(backAttachment != nullptr);
2280 return backAttachment->getSurface()->getRenderBuffer();
Régis Fénéon83107972015-02-05 12:57:44 +01002281}
2282
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002283VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002284{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002285 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002286 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2287 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002288 {
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002289 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle,
2290 mCaps.maxVertexAttributes, mCaps.maxVertexAttribBindings);
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002291
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002292 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002293 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002294
2295 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002296}
2297
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002298TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002299{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002300 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002301 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2302 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002303 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002304 transformFeedback =
2305 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002306 transformFeedback->addRef();
2307 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002308 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002309
2310 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002311}
2312
2313bool Context::isVertexArrayGenerated(GLuint vertexArray)
2314{
Geoff Langf41a7152016-09-19 15:11:17 -04002315 ASSERT(mVertexArrayMap.find(0) != mVertexArrayMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002316 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
2317}
2318
2319bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2320{
Geoff Langf41a7152016-09-19 15:11:17 -04002321 ASSERT(mTransformFeedbackMap.find(0) != mTransformFeedbackMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002322 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
2323}
2324
Shannon Woods53a94a82014-06-24 15:20:36 -04002325void Context::detachTexture(GLuint texture)
2326{
2327 // Simple pass-through to State's detachTexture method, as textures do not require
2328 // allocation map management either here or in the resource manager at detach time.
2329 // Zero textures are held by the Context, and we don't attempt to request them from
2330 // the State.
Jamie Madilla02315b2017-02-23 14:14:47 -05002331 mGLState.detachTexture(this, mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002332}
2333
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002334void Context::detachBuffer(GLuint buffer)
2335{
Yuly Novikov5807a532015-12-03 13:01:22 -05002336 // Simple pass-through to State's detachBuffer method, since
2337 // only buffer attachments to container objects that are bound to the current context
2338 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002339
Yuly Novikov5807a532015-12-03 13:01:22 -05002340 // [OpenGL ES 3.2] section 5.1.2 page 45:
2341 // Attachments to unbound container objects, such as
2342 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2343 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002344 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002345}
2346
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002347void Context::detachFramebuffer(GLuint framebuffer)
2348{
Shannon Woods53a94a82014-06-24 15:20:36 -04002349 // Framebuffer detachment is handled by Context, because 0 is a valid
2350 // Framebuffer object, and a pointer to it must be passed from Context
2351 // to State at binding time.
2352
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002353 // [OpenGL ES 2.0.24] section 4.4 page 107:
Jamie Madill231c7f52017-04-26 13:45:37 -04002354 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as
2355 // though BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of
2356 // zero.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002357
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002358 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002359 {
2360 bindReadFramebuffer(0);
2361 }
2362
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002363 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002364 {
2365 bindDrawFramebuffer(0);
2366 }
2367}
2368
2369void Context::detachRenderbuffer(GLuint renderbuffer)
2370{
Jamie Madilla02315b2017-02-23 14:14:47 -05002371 mGLState.detachRenderbuffer(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002372}
2373
Jamie Madill57a89722013-07-02 11:57:03 -04002374void Context::detachVertexArray(GLuint vertexArray)
2375{
Jamie Madill77a72f62015-04-14 11:18:32 -04002376 // Vertex array detachment is handled by Context, because 0 is a valid
2377 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002378 // binding time.
2379
Jamie Madill57a89722013-07-02 11:57:03 -04002380 // [OpenGL ES 3.0.2] section 2.10 page 43:
2381 // If a vertex array object that is currently bound is deleted, the binding
2382 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002383 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002384 {
2385 bindVertexArray(0);
2386 }
2387}
2388
Geoff Langc8058452014-02-03 12:04:11 -05002389void Context::detachTransformFeedback(GLuint transformFeedback)
2390{
Corentin Walleza2257da2016-04-19 16:43:12 -04002391 // Transform feedback detachment is handled by Context, because 0 is a valid
2392 // transform feedback, and a pointer to it must be passed from Context to State at
2393 // binding time.
2394
2395 // The OpenGL specification doesn't mention what should happen when the currently bound
2396 // transform feedback object is deleted. Since it is a container object, we treat it like
2397 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002398 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002399 {
2400 bindTransformFeedback(0);
2401 }
Geoff Langc8058452014-02-03 12:04:11 -05002402}
2403
Jamie Madilldc356042013-07-19 16:36:57 -04002404void Context::detachSampler(GLuint sampler)
2405{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002406 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002407}
2408
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002409void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2410{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002411 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002412}
2413
Jamie Madille29d1672013-07-19 16:36:57 -04002414void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2415{
Geoff Langc1984ed2016-10-07 12:41:00 -04002416 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002417 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002418 SetSamplerParameteri(samplerObject, pname, param);
2419}
Jamie Madille29d1672013-07-19 16:36:57 -04002420
Geoff Langc1984ed2016-10-07 12:41:00 -04002421void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2422{
2423 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002424 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002425 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002426}
2427
2428void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2429{
Geoff Langc1984ed2016-10-07 12:41:00 -04002430 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002431 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002432 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002433}
2434
Geoff Langc1984ed2016-10-07 12:41:00 -04002435void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002436{
Geoff Langc1984ed2016-10-07 12:41:00 -04002437 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002438 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002439 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002440}
2441
Geoff Langc1984ed2016-10-07 12:41:00 -04002442void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002443{
Geoff Langc1984ed2016-10-07 12:41:00 -04002444 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002445 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002446 QuerySamplerParameteriv(samplerObject, pname, params);
2447}
Jamie Madill9675b802013-07-19 16:36:59 -04002448
Geoff Langc1984ed2016-10-07 12:41:00 -04002449void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2450{
2451 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002452 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002453 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002454}
2455
Olli Etuahof0fee072016-03-30 15:11:58 +03002456void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2457{
2458 gl::Program *programObject = getProgram(program);
Yunchao He61afff12017-03-14 15:34:03 +08002459 SetProgramParameteri(programObject, pname, value);
Olli Etuahof0fee072016-03-30 15:11:58 +03002460}
2461
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002462void Context::initRendererString()
2463{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002464 std::ostringstream rendererString;
2465 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002466 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002467 rendererString << ")";
2468
Geoff Langcec35902014-04-16 10:52:36 -04002469 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002470}
2471
Geoff Langc339c4e2016-11-29 10:37:36 -05002472void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002473{
Geoff Langc339c4e2016-11-29 10:37:36 -05002474 const Version &clientVersion = getClientVersion();
2475
2476 std::ostringstream versionString;
2477 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2478 << ANGLE_VERSION_STRING << ")";
2479 mVersionString = MakeStaticString(versionString.str());
2480
2481 std::ostringstream shadingLanguageVersionString;
2482 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2483 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2484 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2485 << ")";
2486 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002487}
2488
Geoff Langcec35902014-04-16 10:52:36 -04002489void Context::initExtensionStrings()
2490{
Geoff Langc339c4e2016-11-29 10:37:36 -05002491 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2492 std::ostringstream combinedStringStream;
2493 std::copy(strings.begin(), strings.end(),
2494 std::ostream_iterator<const char *>(combinedStringStream, " "));
2495 return MakeStaticString(combinedStringStream.str());
2496 };
2497
2498 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002499 for (const auto &extensionString : mExtensions.getStrings())
2500 {
2501 mExtensionStrings.push_back(MakeStaticString(extensionString));
2502 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002503 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002504
Bryan Bernhart58806562017-01-05 13:09:31 -08002505 const gl::Extensions &nativeExtensions = mImplementation->getNativeExtensions();
2506
Geoff Langc339c4e2016-11-29 10:37:36 -05002507 mRequestableExtensionStrings.clear();
2508 for (const auto &extensionInfo : GetExtensionInfoMap())
2509 {
2510 if (extensionInfo.second.Requestable &&
Bryan Bernhart58806562017-01-05 13:09:31 -08002511 !(mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
2512 nativeExtensions.*(extensionInfo.second.ExtensionsMember))
Geoff Langc339c4e2016-11-29 10:37:36 -05002513 {
2514 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2515 }
2516 }
2517 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002518}
2519
Geoff Langc339c4e2016-11-29 10:37:36 -05002520const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002521{
Geoff Langc339c4e2016-11-29 10:37:36 -05002522 switch (name)
2523 {
2524 case GL_VENDOR:
2525 return reinterpret_cast<const GLubyte *>("Google Inc.");
2526
2527 case GL_RENDERER:
2528 return reinterpret_cast<const GLubyte *>(mRendererString);
2529
2530 case GL_VERSION:
2531 return reinterpret_cast<const GLubyte *>(mVersionString);
2532
2533 case GL_SHADING_LANGUAGE_VERSION:
2534 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2535
2536 case GL_EXTENSIONS:
2537 return reinterpret_cast<const GLubyte *>(mExtensionString);
2538
2539 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2540 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2541
2542 default:
2543 UNREACHABLE();
2544 return nullptr;
2545 }
Geoff Langcec35902014-04-16 10:52:36 -04002546}
2547
Geoff Langc339c4e2016-11-29 10:37:36 -05002548const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002549{
Geoff Langc339c4e2016-11-29 10:37:36 -05002550 switch (name)
2551 {
2552 case GL_EXTENSIONS:
2553 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2554
2555 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2556 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2557
2558 default:
2559 UNREACHABLE();
2560 return nullptr;
2561 }
Geoff Langcec35902014-04-16 10:52:36 -04002562}
2563
2564size_t Context::getExtensionStringCount() const
2565{
2566 return mExtensionStrings.size();
2567}
2568
Geoff Langc339c4e2016-11-29 10:37:36 -05002569void Context::requestExtension(const char *name)
2570{
2571 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2572 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2573 const auto &extension = extensionInfos.at(name);
2574 ASSERT(extension.Requestable);
2575
2576 if (mExtensions.*(extension.ExtensionsMember))
2577 {
2578 // Extension already enabled
2579 return;
2580 }
2581
2582 mExtensions.*(extension.ExtensionsMember) = true;
2583 updateCaps();
2584 initExtensionStrings();
Bryan Bernhart58806562017-01-05 13:09:31 -08002585
Jamie Madill2f348d22017-06-05 10:50:59 -04002586 // Release the shader compiler so it will be re-created with the requested extensions enabled.
2587 releaseShaderCompiler();
Geoff Lang9aded172017-04-05 11:07:56 -04002588
2589 // Invalidate all cached completenesses for textures and framebuffer. Some extensions make new
2590 // formats renderable or sampleable.
2591 mState.mTextures->invalidateTextureComplenessCache();
2592 for (auto &zeroTexture : mZeroTextures)
2593 {
2594 zeroTexture.second->invalidateCompletenessCache();
2595 }
2596
2597 mState.mFramebuffers->invalidateFramebufferComplenessCache();
Geoff Langc339c4e2016-11-29 10:37:36 -05002598}
2599
2600size_t Context::getRequestableExtensionStringCount() const
2601{
2602 return mRequestableExtensionStrings.size();
2603}
2604
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002605void Context::beginTransformFeedback(GLenum primitiveMode)
2606{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002607 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002608 ASSERT(transformFeedback != nullptr);
2609 ASSERT(!transformFeedback->isPaused());
2610
Jamie Madill6c1f6712017-02-14 19:08:04 -05002611 transformFeedback->begin(this, primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002612}
2613
2614bool Context::hasActiveTransformFeedback(GLuint program) const
2615{
2616 for (auto pair : mTransformFeedbackMap)
2617 {
2618 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2619 {
2620 return true;
2621 }
2622 }
2623 return false;
2624}
2625
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002626void Context::initCaps(const egl::DisplayExtensions &displayExtensions)
Geoff Lang493daf52014-07-03 13:38:44 -04002627{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002628 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002629
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002630 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002631
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002632 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002633
Geoff Langeb66a6e2016-10-31 13:06:12 -04002634 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002635 {
2636 // Disable ES3+ extensions
Jamie Madill231c7f52017-04-26 13:45:37 -04002637 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002638 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002639 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002640 }
2641
Geoff Langeb66a6e2016-10-31 13:06:12 -04002642 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002643 {
2644 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
Jamie Madill231c7f52017-04-26 13:45:37 -04002645 // mExtensions.sRGB = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002646 }
2647
Jamie Madill00ed7a12016-05-19 13:13:38 -04002648 // Some extensions are always available because they are implemented in the GL layer.
Jamie Madill231c7f52017-04-26 13:45:37 -04002649 mExtensions.bindUniformLocation = true;
2650 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002651 mExtensions.bindGeneratesResource = true;
Geoff Langfeb8c682017-02-13 16:07:35 -05002652 mExtensions.clientArrays = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002653 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002654
2655 // Enable the no error extension if the context was created with the flag.
2656 mExtensions.noError = mSkipValidation;
2657
Corentin Wallezccab69d2017-01-27 16:57:15 -05002658 // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
Corentin Wallezc295e512017-01-27 17:47:50 -05002659 mExtensions.surfacelessContext = displayExtensions.surfacelessContext;
Corentin Wallezccab69d2017-01-27 16:57:15 -05002660
Geoff Lang70d0f492015-12-10 17:45:46 -05002661 // Explicitly enable GL_KHR_debug
2662 mExtensions.debug = true;
2663 mExtensions.maxDebugMessageLength = 1024;
2664 mExtensions.maxDebugLoggedMessages = 1024;
2665 mExtensions.maxDebugGroupStackDepth = 1024;
2666 mExtensions.maxLabelLength = 1024;
2667
Geoff Langff5b2d52016-09-07 11:32:23 -04002668 // Explicitly enable GL_ANGLE_robust_client_memory
2669 mExtensions.robustClientMemory = true;
2670
Jamie Madille08a1d32017-03-07 17:24:06 -05002671 // Determine robust resource init availability from EGL.
2672 mExtensions.robustResourceInitialization =
Jamie Madill948bbe52017-06-01 13:10:42 -04002673 egl::Display::GetClientExtensions().displayRobustResourceInitialization;
Jamie Madille08a1d32017-03-07 17:24:06 -05002674
Geoff Lang301d1612014-07-09 10:34:37 -04002675 // Apply implementation limits
2676 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002677 mCaps.maxVertexAttribBindings =
2678 getClientVersion() < ES_3_1
2679 ? mCaps.maxVertexAttributes
2680 : std::min<GLuint>(mCaps.maxVertexAttribBindings, MAX_VERTEX_ATTRIB_BINDINGS);
2681
Jamie Madill231c7f52017-04-26 13:45:37 -04002682 mCaps.maxVertexUniformBlocks = std::min<GLuint>(
2683 mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2684 mCaps.maxVertexOutputComponents =
2685 std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang301d1612014-07-09 10:34:37 -04002686
Jamie Madill231c7f52017-04-26 13:45:37 -04002687 mCaps.maxFragmentInputComponents =
2688 std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002689
Geoff Langc287ea62016-09-16 14:46:51 -04002690 // WebGL compatibility
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002691 mExtensions.webglCompatibility = mWebGLContext;
Geoff Langc287ea62016-09-16 14:46:51 -04002692 for (const auto &extensionInfo : GetExtensionInfoMap())
2693 {
2694 // If this context is for WebGL, disable all enableable extensions
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002695 if (mWebGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002696 {
2697 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2698 }
2699 }
2700
2701 // Generate texture caps
2702 updateCaps();
2703}
2704
2705void Context::updateCaps()
2706{
Geoff Lang900013c2014-07-07 11:32:19 -04002707 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002708 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002709
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002710 for (auto capsIt : mImplementation->getNativeTextureCaps())
Geoff Lang493daf52014-07-03 13:38:44 -04002711 {
Geoff Langca271392017-04-05 12:30:00 -04002712 GLenum sizedInternalFormat = capsIt.first;
Jamie Madill231c7f52017-04-26 13:45:37 -04002713 TextureCaps formatCaps = capsIt.second;
Geoff Lang493daf52014-07-03 13:38:44 -04002714
Geoff Langca271392017-04-05 12:30:00 -04002715 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002716
Geoff Lang0d8b7242015-09-09 14:56:53 -04002717 // Update the format caps based on the client version and extensions.
2718 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2719 // ES3.
2720 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002721 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002722 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002723 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002724 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002725 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002726
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002727 // OpenGL ES does not support multisampling with non-rendererable formats
2728 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
Olli Etuaho3cd0dd32017-06-06 14:43:30 +03002729 if (!formatCaps.renderable ||
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002730 (getClientVersion() < ES_3_1 &&
2731 (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
Geoff Lang493daf52014-07-03 13:38:44 -04002732 {
Geoff Langd87878e2014-09-19 15:42:59 -04002733 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002734 }
Olli Etuaho3cd0dd32017-06-06 14:43:30 +03002735 else
2736 {
2737 // We may have limited the max samples for some required renderbuffer formats due to
2738 // non-conformant formats. In this case MAX_SAMPLES needs to be lowered accordingly.
2739 GLuint formatMaxSamples = formatCaps.getMaxSamples();
2740
2741 // GLES 3.0.5 section 4.4.2.2: "Implementations must support creation of renderbuffers
2742 // in these required formats with up to the value of MAX_SAMPLES multisamples, with the
2743 // exception of signed and unsigned integer formats."
2744 if (formatInfo.componentType != GL_INT && formatInfo.componentType != GL_UNSIGNED_INT &&
2745 formatInfo.isRequiredRenderbufferFormat(getClientVersion()))
2746 {
2747 ASSERT(getClientVersion() < ES_3_0 || formatMaxSamples >= 4);
2748 mCaps.maxSamples = std::min(mCaps.maxSamples, formatMaxSamples);
2749 }
2750
2751 // Handle GLES 3.1 MAX_*_SAMPLES values similarly to MAX_SAMPLES.
2752 if (getClientVersion() >= ES_3_1)
2753 {
2754 // GLES 3.1 section 9.2.5: "Implementations must support creation of renderbuffers
2755 // in these required formats with up to the value of MAX_SAMPLES multisamples, with
2756 // the exception that the signed and unsigned integer formats are required only to
2757 // support creation of renderbuffers with up to the value of MAX_INTEGER_SAMPLES
2758 // multisamples, which must be at least one."
2759 if (formatInfo.componentType == GL_INT ||
2760 formatInfo.componentType == GL_UNSIGNED_INT)
2761 {
2762 mCaps.maxIntegerSamples = std::min(mCaps.maxIntegerSamples, formatMaxSamples);
2763 }
2764
2765 // GLES 3.1 section 19.3.1.
2766 if (formatCaps.texturable)
2767 {
2768 if (formatInfo.depthBits > 0)
2769 {
2770 mCaps.maxDepthTextureSamples =
2771 std::min(mCaps.maxDepthTextureSamples, formatMaxSamples);
2772 }
2773 else if (formatInfo.redBits > 0)
2774 {
2775 mCaps.maxColorTextureSamples =
2776 std::min(mCaps.maxColorTextureSamples, formatMaxSamples);
2777 }
2778 }
2779 }
2780 }
Geoff Langd87878e2014-09-19 15:42:59 -04002781
2782 if (formatCaps.texturable && formatInfo.compressed)
2783 {
Geoff Langca271392017-04-05 12:30:00 -04002784 mCaps.compressedTextureFormats.push_back(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002785 }
2786
Geoff Langca271392017-04-05 12:30:00 -04002787 mTextureCaps.insert(sizedInternalFormat, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002788 }
2789}
2790
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002791void Context::initWorkarounds()
2792{
2793 // Lose the context upon out of memory error if the application is
2794 // expecting to watch for those events.
2795 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2796}
2797
Jamie Madill1b94d432015-08-07 13:23:23 -04002798void Context::syncRendererState()
2799{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002800 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
Jamie Madillfe548342017-06-19 11:13:24 -04002801 mImplementation->syncState(this, dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002802 mGLState.clearDirtyBits();
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002803 mGLState.syncDirtyObjects(this);
Jamie Madill1b94d432015-08-07 13:23:23 -04002804}
2805
Jamie Madillad9f24e2016-02-12 09:27:24 -05002806void Context::syncRendererState(const State::DirtyBits &bitMask,
2807 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002808{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002809 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
Jamie Madillfe548342017-06-19 11:13:24 -04002810 mImplementation->syncState(this, dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002811 mGLState.clearDirtyBits(dirtyBits);
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002812 mGLState.syncDirtyObjects(this, objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002813}
Jamie Madillc29968b2016-01-20 11:17:23 -05002814
2815void Context::blitFramebuffer(GLint srcX0,
2816 GLint srcY0,
2817 GLint srcX1,
2818 GLint srcY1,
2819 GLint dstX0,
2820 GLint dstY0,
2821 GLint dstX1,
2822 GLint dstY1,
2823 GLbitfield mask,
2824 GLenum filter)
2825{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002826 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002827 ASSERT(drawFramebuffer);
2828
2829 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2830 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2831
Jamie Madillad9f24e2016-02-12 09:27:24 -05002832 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002833
Jamie Madillc564c072017-06-01 12:45:42 -04002834 handleError(drawFramebuffer->blit(this, srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002835}
Jamie Madillc29968b2016-01-20 11:17:23 -05002836
2837void Context::clear(GLbitfield mask)
2838{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002839 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002840 handleError(mGLState.getDrawFramebuffer()->clear(this, mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002841}
2842
2843void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2844{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002845 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002846 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002847}
2848
2849void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2850{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002851 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002852 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002853}
2854
2855void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2856{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002857 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002858 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002859}
2860
2861void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2862{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002863 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002864 ASSERT(framebufferObject);
2865
2866 // If a buffer is not present, the clear has no effect
2867 if (framebufferObject->getDepthbuffer() == nullptr &&
2868 framebufferObject->getStencilbuffer() == nullptr)
2869 {
2870 return;
2871 }
2872
Jamie Madillad9f24e2016-02-12 09:27:24 -05002873 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002874 handleError(framebufferObject->clearBufferfi(this, buffer, drawbuffer, depth, stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002875}
2876
2877void Context::readPixels(GLint x,
2878 GLint y,
2879 GLsizei width,
2880 GLsizei height,
2881 GLenum format,
2882 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002883 void *pixels)
Jamie Madillc29968b2016-01-20 11:17:23 -05002884{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002885 if (width == 0 || height == 0)
2886 {
2887 return;
2888 }
2889
Jamie Madillad9f24e2016-02-12 09:27:24 -05002890 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002891
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002892 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002893 ASSERT(framebufferObject);
2894
2895 Rectangle area(x, y, width, height);
Jamie Madillc564c072017-06-01 12:45:42 -04002896 handleError(framebufferObject->readPixels(this, area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002897}
2898
2899void Context::copyTexImage2D(GLenum target,
2900 GLint level,
2901 GLenum internalformat,
2902 GLint x,
2903 GLint y,
2904 GLsizei width,
2905 GLsizei height,
2906 GLint border)
2907{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002908 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002909 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002910
Jamie Madillc29968b2016-01-20 11:17:23 -05002911 Rectangle sourceArea(x, y, width, height);
2912
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002913 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002914 Texture *texture =
2915 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002916 handleError(texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002917}
2918
2919void Context::copyTexSubImage2D(GLenum target,
2920 GLint level,
2921 GLint xoffset,
2922 GLint yoffset,
2923 GLint x,
2924 GLint y,
2925 GLsizei width,
2926 GLsizei height)
2927{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002928 if (width == 0 || height == 0)
2929 {
2930 return;
2931 }
2932
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002933 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002934 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002935
Jamie Madillc29968b2016-01-20 11:17:23 -05002936 Offset destOffset(xoffset, yoffset, 0);
2937 Rectangle sourceArea(x, y, width, height);
2938
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002939 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002940 Texture *texture =
2941 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002942 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002943}
2944
2945void Context::copyTexSubImage3D(GLenum target,
2946 GLint level,
2947 GLint xoffset,
2948 GLint yoffset,
2949 GLint zoffset,
2950 GLint x,
2951 GLint y,
2952 GLsizei width,
2953 GLsizei height)
2954{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002955 if (width == 0 || height == 0)
2956 {
2957 return;
2958 }
2959
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002960 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002961 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002962
Jamie Madillc29968b2016-01-20 11:17:23 -05002963 Offset destOffset(xoffset, yoffset, zoffset);
2964 Rectangle sourceArea(x, y, width, height);
2965
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002966 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002967 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002968 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002969}
2970
2971void Context::framebufferTexture2D(GLenum target,
2972 GLenum attachment,
2973 GLenum textarget,
2974 GLuint texture,
2975 GLint level)
2976{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002977 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002978 ASSERT(framebuffer);
2979
2980 if (texture != 0)
2981 {
2982 Texture *textureObj = getTexture(texture);
2983
2984 ImageIndex index = ImageIndex::MakeInvalid();
2985
2986 if (textarget == GL_TEXTURE_2D)
2987 {
2988 index = ImageIndex::Make2D(level);
2989 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08002990 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
2991 {
2992 ASSERT(level == 0);
2993 index = ImageIndex::Make2DMultisample();
2994 }
Jamie Madillc29968b2016-01-20 11:17:23 -05002995 else
2996 {
2997 ASSERT(IsCubeMapTextureTarget(textarget));
2998 index = ImageIndex::MakeCube(textarget, level);
2999 }
3000
Jamie Madilla02315b2017-02-23 14:14:47 -05003001 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
Jamie Madillc29968b2016-01-20 11:17:23 -05003002 }
3003 else
3004 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003005 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003006 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003007
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003008 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003009}
3010
3011void Context::framebufferRenderbuffer(GLenum target,
3012 GLenum attachment,
3013 GLenum renderbuffertarget,
3014 GLuint renderbuffer)
3015{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003016 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003017 ASSERT(framebuffer);
3018
3019 if (renderbuffer != 0)
3020 {
3021 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
Jamie Madilla02315b2017-02-23 14:14:47 -05003022
3023 framebuffer->setAttachment(this, GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
Jamie Madillc29968b2016-01-20 11:17:23 -05003024 renderbufferObject);
3025 }
3026 else
3027 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003028 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003029 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003030
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003031 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003032}
3033
3034void Context::framebufferTextureLayer(GLenum target,
3035 GLenum attachment,
3036 GLuint texture,
3037 GLint level,
3038 GLint layer)
3039{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003040 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003041 ASSERT(framebuffer);
3042
3043 if (texture != 0)
3044 {
3045 Texture *textureObject = getTexture(texture);
3046
3047 ImageIndex index = ImageIndex::MakeInvalid();
3048
3049 if (textureObject->getTarget() == GL_TEXTURE_3D)
3050 {
3051 index = ImageIndex::Make3D(level, layer);
3052 }
3053 else
3054 {
3055 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
3056 index = ImageIndex::Make2DArray(level, layer);
3057 }
3058
Jamie Madilla02315b2017-02-23 14:14:47 -05003059 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObject);
Jamie Madillc29968b2016-01-20 11:17:23 -05003060 }
3061 else
3062 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003063 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003064 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003065
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003066 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003067}
3068
3069void Context::drawBuffers(GLsizei n, const GLenum *bufs)
3070{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003071 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003072 ASSERT(framebuffer);
3073 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003074 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003075}
3076
3077void Context::readBuffer(GLenum mode)
3078{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003079 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003080 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003081 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003082}
3083
3084void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
3085{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003086 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003087 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003088
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003089 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003090 ASSERT(framebuffer);
3091
3092 // The specification isn't clear what should be done when the framebuffer isn't complete.
3093 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04003094 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003095}
3096
3097void Context::invalidateFramebuffer(GLenum target,
3098 GLsizei numAttachments,
3099 const GLenum *attachments)
3100{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003101 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003102 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003103
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003104 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003105 ASSERT(framebuffer);
3106
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003107 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003108 {
Jamie Madill437fa652016-05-03 15:13:24 -04003109 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003110 }
Jamie Madill437fa652016-05-03 15:13:24 -04003111
3112 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003113}
3114
3115void Context::invalidateSubFramebuffer(GLenum target,
3116 GLsizei numAttachments,
3117 const GLenum *attachments,
3118 GLint x,
3119 GLint y,
3120 GLsizei width,
3121 GLsizei height)
3122{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003123 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003124 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003125
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003126 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003127 ASSERT(framebuffer);
3128
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003129 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003130 {
Jamie Madill437fa652016-05-03 15:13:24 -04003131 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003132 }
Jamie Madill437fa652016-05-03 15:13:24 -04003133
3134 Rectangle area(x, y, width, height);
3135 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05003136}
3137
Jamie Madill73a84962016-02-12 09:27:23 -05003138void Context::texImage2D(GLenum target,
3139 GLint level,
3140 GLint internalformat,
3141 GLsizei width,
3142 GLsizei height,
3143 GLint border,
3144 GLenum format,
3145 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003146 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003147{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003148 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003149
3150 Extents size(width, height, 1);
3151 Texture *texture =
3152 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003153 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3154 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003155}
3156
3157void Context::texImage3D(GLenum target,
3158 GLint level,
3159 GLint internalformat,
3160 GLsizei width,
3161 GLsizei height,
3162 GLsizei depth,
3163 GLint border,
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{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003168 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003169
3170 Extents size(width, height, depth);
3171 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003172 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3173 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003174}
3175
3176void Context::texSubImage2D(GLenum target,
3177 GLint level,
3178 GLint xoffset,
3179 GLint yoffset,
3180 GLsizei width,
3181 GLsizei height,
3182 GLenum format,
3183 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003184 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003185{
3186 // Zero sized uploads are valid but no-ops
3187 if (width == 0 || height == 0)
3188 {
3189 return;
3190 }
3191
Jamie Madillad9f24e2016-02-12 09:27:24 -05003192 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003193
3194 Box area(xoffset, yoffset, 0, width, height, 1);
3195 Texture *texture =
3196 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003197 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3198 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003199}
3200
3201void Context::texSubImage3D(GLenum target,
3202 GLint level,
3203 GLint xoffset,
3204 GLint yoffset,
3205 GLint zoffset,
3206 GLsizei width,
3207 GLsizei height,
3208 GLsizei depth,
3209 GLenum format,
3210 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003211 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003212{
3213 // Zero sized uploads are valid but no-ops
3214 if (width == 0 || height == 0 || depth == 0)
3215 {
3216 return;
3217 }
3218
Jamie Madillad9f24e2016-02-12 09:27:24 -05003219 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003220
3221 Box area(xoffset, yoffset, zoffset, width, height, depth);
3222 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003223 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3224 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003225}
3226
3227void Context::compressedTexImage2D(GLenum target,
3228 GLint level,
3229 GLenum internalformat,
3230 GLsizei width,
3231 GLsizei height,
3232 GLint border,
3233 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003234 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003235{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003236 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003237
3238 Extents size(width, height, 1);
3239 Texture *texture =
3240 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003241 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003242 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003243 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003244}
3245
3246void Context::compressedTexImage3D(GLenum target,
3247 GLint level,
3248 GLenum internalformat,
3249 GLsizei width,
3250 GLsizei height,
3251 GLsizei depth,
3252 GLint border,
3253 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003254 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003255{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003256 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003257
3258 Extents size(width, height, depth);
3259 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003260 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003261 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003262 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003263}
3264
3265void Context::compressedTexSubImage2D(GLenum target,
3266 GLint level,
3267 GLint xoffset,
3268 GLint yoffset,
3269 GLsizei width,
3270 GLsizei height,
3271 GLenum format,
3272 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003273 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003274{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003275 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003276
3277 Box area(xoffset, yoffset, 0, width, height, 1);
3278 Texture *texture =
3279 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003280 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003281 format, imageSize,
3282 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003283}
3284
3285void Context::compressedTexSubImage3D(GLenum target,
3286 GLint level,
3287 GLint xoffset,
3288 GLint yoffset,
3289 GLint zoffset,
3290 GLsizei width,
3291 GLsizei height,
3292 GLsizei depth,
3293 GLenum format,
3294 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003295 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003296{
3297 // Zero sized uploads are valid but no-ops
3298 if (width == 0 || height == 0)
3299 {
3300 return;
3301 }
3302
Jamie Madillad9f24e2016-02-12 09:27:24 -05003303 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003304
3305 Box area(xoffset, yoffset, zoffset, width, height, depth);
3306 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003307 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003308 format, imageSize,
3309 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003310}
3311
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003312void Context::generateMipmap(GLenum target)
3313{
3314 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003315 handleError(texture->generateMipmap(this));
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003316}
3317
Geoff Lang97073d12016-04-20 10:42:34 -07003318void Context::copyTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003319 GLint sourceLevel,
3320 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003321 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003322 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003323 GLint internalFormat,
3324 GLenum destType,
3325 GLboolean unpackFlipY,
3326 GLboolean unpackPremultiplyAlpha,
3327 GLboolean unpackUnmultiplyAlpha)
3328{
3329 syncStateForTexImage();
3330
3331 gl::Texture *sourceTexture = getTexture(sourceId);
3332 gl::Texture *destTexture = getTexture(destId);
Geoff Langfc72a072017-03-24 14:52:39 -04003333 handleError(destTexture->copyTexture(
3334 this, destTarget, destLevel, internalFormat, destType, sourceLevel, unpackFlipY == GL_TRUE,
3335 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003336}
3337
3338void Context::copySubTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003339 GLint sourceLevel,
3340 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003341 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003342 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003343 GLint xoffset,
3344 GLint yoffset,
3345 GLint x,
3346 GLint y,
3347 GLsizei width,
3348 GLsizei height,
3349 GLboolean unpackFlipY,
3350 GLboolean unpackPremultiplyAlpha,
3351 GLboolean unpackUnmultiplyAlpha)
3352{
3353 // Zero sized copies are valid but no-ops
3354 if (width == 0 || height == 0)
3355 {
3356 return;
3357 }
3358
3359 syncStateForTexImage();
3360
3361 gl::Texture *sourceTexture = getTexture(sourceId);
3362 gl::Texture *destTexture = getTexture(destId);
3363 Offset offset(xoffset, yoffset, 0);
3364 Rectangle area(x, y, width, height);
Geoff Langfc72a072017-03-24 14:52:39 -04003365 handleError(destTexture->copySubTexture(
3366 this, destTarget, destLevel, offset, sourceLevel, area, unpackFlipY == GL_TRUE,
3367 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003368}
3369
Geoff Lang47110bf2016-04-20 11:13:22 -07003370void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3371{
3372 syncStateForTexImage();
3373
3374 gl::Texture *sourceTexture = getTexture(sourceId);
3375 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003376 handleError(destTexture->copyCompressedTexture(this, sourceTexture));
Geoff Lang47110bf2016-04-20 11:13:22 -07003377}
3378
Geoff Lang496c02d2016-10-20 11:38:11 -07003379void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003380{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003381 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003382 ASSERT(buffer);
3383
Geoff Lang496c02d2016-10-20 11:38:11 -07003384 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003385}
3386
Jamie Madill876429b2017-04-20 15:46:24 -04003387void *Context::mapBuffer(GLenum target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003388{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003389 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003390 ASSERT(buffer);
3391
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003392 Error error = buffer->map(this, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003393 if (error.isError())
3394 {
Jamie Madill437fa652016-05-03 15:13:24 -04003395 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003396 return nullptr;
3397 }
3398
3399 return buffer->getMapPointer();
3400}
3401
3402GLboolean Context::unmapBuffer(GLenum target)
3403{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003404 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003405 ASSERT(buffer);
3406
3407 GLboolean result;
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003408 Error error = buffer->unmap(this, &result);
Olli Etuaho4f667482016-03-30 15:56:35 +03003409 if (error.isError())
3410 {
Jamie Madill437fa652016-05-03 15:13:24 -04003411 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003412 return GL_FALSE;
3413 }
3414
3415 return result;
3416}
3417
Jamie Madill876429b2017-04-20 15:46:24 -04003418void *Context::mapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003419{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003420 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003421 ASSERT(buffer);
3422
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003423 Error error = buffer->mapRange(this, offset, length, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003424 if (error.isError())
3425 {
Jamie Madill437fa652016-05-03 15:13:24 -04003426 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003427 return nullptr;
3428 }
3429
3430 return buffer->getMapPointer();
3431}
3432
3433void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3434{
3435 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3436}
3437
Jamie Madillad9f24e2016-02-12 09:27:24 -05003438void Context::syncStateForReadPixels()
3439{
3440 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3441}
3442
3443void Context::syncStateForTexImage()
3444{
3445 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3446}
3447
3448void Context::syncStateForClear()
3449{
3450 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3451}
3452
3453void Context::syncStateForBlit()
3454{
3455 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3456}
3457
Jamie Madillc20ab272016-06-09 07:20:46 -07003458void Context::activeTexture(GLenum texture)
3459{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003460 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003461}
3462
Jamie Madill876429b2017-04-20 15:46:24 -04003463void Context::blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003464{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003465 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003466}
3467
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003468void Context::blendEquation(GLenum mode)
3469{
3470 mGLState.setBlendEquation(mode, mode);
3471}
3472
Jamie Madillc20ab272016-06-09 07:20:46 -07003473void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3474{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003475 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003476}
3477
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003478void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3479{
3480 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3481}
3482
Jamie Madillc20ab272016-06-09 07:20:46 -07003483void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3484{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003485 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003486}
3487
Jamie Madill876429b2017-04-20 15:46:24 -04003488void Context::clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003489{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003490 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003491}
3492
Jamie Madill876429b2017-04-20 15:46:24 -04003493void Context::clearDepthf(GLfloat depth)
Jamie Madillc20ab272016-06-09 07:20:46 -07003494{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003495 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003496}
3497
3498void Context::clearStencil(GLint s)
3499{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003500 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003501}
3502
3503void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3504{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003505 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003506}
3507
3508void Context::cullFace(GLenum mode)
3509{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003510 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003511}
3512
3513void Context::depthFunc(GLenum func)
3514{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003515 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003516}
3517
3518void Context::depthMask(GLboolean flag)
3519{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003520 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003521}
3522
Jamie Madill876429b2017-04-20 15:46:24 -04003523void Context::depthRangef(GLfloat zNear, GLfloat zFar)
Jamie Madillc20ab272016-06-09 07:20:46 -07003524{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003525 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003526}
3527
3528void Context::disable(GLenum cap)
3529{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003530 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003531}
3532
3533void Context::disableVertexAttribArray(GLuint index)
3534{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003535 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003536}
3537
3538void Context::enable(GLenum cap)
3539{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003540 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003541}
3542
3543void Context::enableVertexAttribArray(GLuint index)
3544{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003545 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003546}
3547
3548void Context::frontFace(GLenum mode)
3549{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003550 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003551}
3552
3553void Context::hint(GLenum target, GLenum mode)
3554{
3555 switch (target)
3556 {
3557 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003558 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003559 break;
3560
3561 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003562 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003563 break;
3564
3565 default:
3566 UNREACHABLE();
3567 return;
3568 }
3569}
3570
3571void Context::lineWidth(GLfloat width)
3572{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003573 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003574}
3575
3576void Context::pixelStorei(GLenum pname, GLint param)
3577{
3578 switch (pname)
3579 {
3580 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003581 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003582 break;
3583
3584 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003585 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003586 break;
3587
3588 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003589 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003590 break;
3591
3592 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003593 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003594 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003595 break;
3596
3597 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003598 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003599 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003600 break;
3601
3602 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003603 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003604 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003605 break;
3606
3607 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003608 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003609 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003610 break;
3611
3612 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003613 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003614 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003615 break;
3616
3617 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003618 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003619 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003620 break;
3621
3622 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003623 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003624 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003625 break;
3626
3627 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003628 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003629 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003630 break;
3631
3632 default:
3633 UNREACHABLE();
3634 return;
3635 }
3636}
3637
3638void Context::polygonOffset(GLfloat factor, GLfloat units)
3639{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003640 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003641}
3642
Jamie Madill876429b2017-04-20 15:46:24 -04003643void Context::sampleCoverage(GLfloat value, GLboolean invert)
Jamie Madillc20ab272016-06-09 07:20:46 -07003644{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003645 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003646}
3647
3648void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3649{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003650 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003651}
3652
3653void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3654{
3655 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3656 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003657 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003658 }
3659
3660 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3661 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003662 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003663 }
3664}
3665
3666void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3667{
3668 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3669 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003670 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003671 }
3672
3673 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3674 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003675 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003676 }
3677}
3678
3679void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3680{
3681 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3682 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003683 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003684 }
3685
3686 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3687 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003688 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003689 }
3690}
3691
3692void Context::vertexAttrib1f(GLuint index, GLfloat x)
3693{
3694 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003695 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003696}
3697
3698void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3699{
3700 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003701 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003702}
3703
3704void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3705{
3706 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003707 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003708}
3709
3710void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3711{
3712 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003713 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003714}
3715
3716void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3717{
3718 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003719 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003720}
3721
3722void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3723{
3724 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003725 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003726}
3727
3728void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3729{
3730 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003731 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003732}
3733
3734void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3735{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003736 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003737}
3738
3739void Context::vertexAttribPointer(GLuint index,
3740 GLint size,
3741 GLenum type,
3742 GLboolean normalized,
3743 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003744 const void *ptr)
Jamie Madillc20ab272016-06-09 07:20:46 -07003745{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003746 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3747 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003748}
3749
Shao80957d92017-02-20 21:25:59 +08003750void Context::vertexAttribFormat(GLuint attribIndex,
3751 GLint size,
3752 GLenum type,
3753 GLboolean normalized,
3754 GLuint relativeOffset)
3755{
3756 mGLState.setVertexAttribFormat(attribIndex, size, type, normalized == GL_TRUE, false,
3757 relativeOffset);
3758}
3759
3760void Context::vertexAttribIFormat(GLuint attribIndex,
3761 GLint size,
3762 GLenum type,
3763 GLuint relativeOffset)
3764{
3765 mGLState.setVertexAttribFormat(attribIndex, size, type, false, true, relativeOffset);
3766}
3767
3768void Context::vertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
3769{
3770 mGLState.setVertexAttribBinding(attribIndex, bindingIndex);
3771}
3772
3773void Context::setVertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
3774{
3775 mGLState.setVertexBindingDivisor(bindingIndex, divisor);
3776}
3777
Jamie Madillc20ab272016-06-09 07:20:46 -07003778void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3779{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003780 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003781}
3782
3783void Context::vertexAttribIPointer(GLuint index,
3784 GLint size,
3785 GLenum type,
3786 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003787 const void *pointer)
Jamie Madillc20ab272016-06-09 07:20:46 -07003788{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003789 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3790 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003791}
3792
3793void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3794{
3795 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003796 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003797}
3798
3799void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3800{
3801 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003802 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003803}
3804
3805void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3806{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003807 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003808}
3809
3810void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3811{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003812 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003813}
3814
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003815void Context::getVertexAttribiv(GLuint index, GLenum pname, GLint *params)
3816{
3817 const VertexAttribCurrentValueData &currentValues =
3818 getGLState().getVertexAttribCurrentValue(index);
3819 const VertexArray *vao = getGLState().getVertexArray();
3820 QueryVertexAttribiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3821 currentValues, pname, params);
3822}
3823
3824void Context::getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
3825{
3826 const VertexAttribCurrentValueData &currentValues =
3827 getGLState().getVertexAttribCurrentValue(index);
3828 const VertexArray *vao = getGLState().getVertexArray();
3829 QueryVertexAttribfv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3830 currentValues, pname, params);
3831}
3832
3833void Context::getVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
3834{
3835 const VertexAttribCurrentValueData &currentValues =
3836 getGLState().getVertexAttribCurrentValue(index);
3837 const VertexArray *vao = getGLState().getVertexArray();
3838 QueryVertexAttribIiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3839 currentValues, pname, params);
3840}
3841
3842void Context::getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
3843{
3844 const VertexAttribCurrentValueData &currentValues =
3845 getGLState().getVertexAttribCurrentValue(index);
3846 const VertexArray *vao = getGLState().getVertexArray();
3847 QueryVertexAttribIuiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3848 currentValues, pname, params);
3849}
3850
Jamie Madill876429b2017-04-20 15:46:24 -04003851void Context::getVertexAttribPointerv(GLuint index, GLenum pname, void **pointer)
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003852{
3853 const VertexAttribute &attrib = getGLState().getVertexArray()->getVertexAttribute(index);
3854 QueryVertexAttribPointerv(attrib, pname, pointer);
3855}
3856
Jamie Madillc20ab272016-06-09 07:20:46 -07003857void Context::debugMessageControl(GLenum source,
3858 GLenum type,
3859 GLenum severity,
3860 GLsizei count,
3861 const GLuint *ids,
3862 GLboolean enabled)
3863{
3864 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003865 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3866 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003867}
3868
3869void Context::debugMessageInsert(GLenum source,
3870 GLenum type,
3871 GLuint id,
3872 GLenum severity,
3873 GLsizei length,
3874 const GLchar *buf)
3875{
3876 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003877 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003878}
3879
3880void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3881{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003882 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003883}
3884
3885GLuint Context::getDebugMessageLog(GLuint count,
3886 GLsizei bufSize,
3887 GLenum *sources,
3888 GLenum *types,
3889 GLuint *ids,
3890 GLenum *severities,
3891 GLsizei *lengths,
3892 GLchar *messageLog)
3893{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003894 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3895 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003896}
3897
3898void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3899{
3900 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003901 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003902}
3903
3904void Context::popDebugGroup()
3905{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003906 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003907}
3908
Jamie Madill876429b2017-04-20 15:46:24 -04003909void Context::bufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage)
Jamie Madill29639852016-09-02 15:00:09 -04003910{
3911 Buffer *buffer = mGLState.getTargetBuffer(target);
3912 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003913 handleError(buffer->bufferData(this, target, data, size, usage));
Jamie Madill29639852016-09-02 15:00:09 -04003914}
3915
Jamie Madill876429b2017-04-20 15:46:24 -04003916void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04003917{
3918 if (data == nullptr)
3919 {
3920 return;
3921 }
3922
3923 Buffer *buffer = mGLState.getTargetBuffer(target);
3924 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003925 handleError(buffer->bufferSubData(this, target, data, size, offset));
Jamie Madill29639852016-09-02 15:00:09 -04003926}
3927
Jamie Madillef300b12016-10-07 15:12:09 -04003928void Context::attachShader(GLuint program, GLuint shader)
3929{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003930 auto programObject = mState.mShaderPrograms->getProgram(program);
3931 auto shaderObject = mState.mShaderPrograms->getShader(shader);
Jamie Madillef300b12016-10-07 15:12:09 -04003932 ASSERT(programObject && shaderObject);
3933 programObject->attachShader(shaderObject);
3934}
3935
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003936const Workarounds &Context::getWorkarounds() const
3937{
3938 return mWorkarounds;
3939}
3940
Jamie Madillb0817d12016-11-01 15:48:31 -04003941void Context::copyBufferSubData(GLenum readTarget,
3942 GLenum writeTarget,
3943 GLintptr readOffset,
3944 GLintptr writeOffset,
3945 GLsizeiptr size)
3946{
3947 // if size is zero, the copy is a successful no-op
3948 if (size == 0)
3949 {
3950 return;
3951 }
3952
3953 // TODO(jmadill): cache these.
3954 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3955 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3956
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003957 handleError(writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size));
Jamie Madillb0817d12016-11-01 15:48:31 -04003958}
3959
Jamie Madill01a80ee2016-11-07 12:06:18 -05003960void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3961{
3962 Program *programObject = getProgram(program);
3963 // TODO(jmadill): Re-use this from the validation if possible.
3964 ASSERT(programObject);
3965 programObject->bindAttributeLocation(index, name);
3966}
3967
3968void Context::bindBuffer(GLenum target, GLuint buffer)
3969{
3970 switch (target)
3971 {
3972 case GL_ARRAY_BUFFER:
3973 bindArrayBuffer(buffer);
3974 break;
3975 case GL_ELEMENT_ARRAY_BUFFER:
3976 bindElementArrayBuffer(buffer);
3977 break;
3978 case GL_COPY_READ_BUFFER:
3979 bindCopyReadBuffer(buffer);
3980 break;
3981 case GL_COPY_WRITE_BUFFER:
3982 bindCopyWriteBuffer(buffer);
3983 break;
3984 case GL_PIXEL_PACK_BUFFER:
3985 bindPixelPackBuffer(buffer);
3986 break;
3987 case GL_PIXEL_UNPACK_BUFFER:
3988 bindPixelUnpackBuffer(buffer);
3989 break;
3990 case GL_UNIFORM_BUFFER:
3991 bindGenericUniformBuffer(buffer);
3992 break;
3993 case GL_TRANSFORM_FEEDBACK_BUFFER:
3994 bindGenericTransformFeedbackBuffer(buffer);
3995 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003996 case GL_ATOMIC_COUNTER_BUFFER:
Jiajia Qin6eafb042016-12-27 17:04:07 +08003997 bindGenericAtomicCounterBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003998 break;
3999 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08004000 bindGenericShaderStorageBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004001 break;
4002 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08004003 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004004 break;
4005 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05004006 if (buffer != 0)
4007 {
4008 // Binding buffers to this binding point is not implemented yet.
4009 UNIMPLEMENTED();
4010 }
Geoff Lang3b573612016-10-31 14:08:10 -04004011 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05004012
4013 default:
4014 UNREACHABLE();
4015 break;
4016 }
4017}
4018
Jiajia Qin6eafb042016-12-27 17:04:07 +08004019void Context::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
4020{
4021 bindBufferRange(target, index, buffer, 0, 0);
4022}
4023
4024void Context::bindBufferRange(GLenum target,
4025 GLuint index,
4026 GLuint buffer,
4027 GLintptr offset,
4028 GLsizeiptr size)
4029{
4030 switch (target)
4031 {
4032 case GL_TRANSFORM_FEEDBACK_BUFFER:
4033 bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
4034 bindGenericTransformFeedbackBuffer(buffer);
4035 break;
4036 case GL_UNIFORM_BUFFER:
4037 bindIndexedUniformBuffer(buffer, index, offset, size);
4038 bindGenericUniformBuffer(buffer);
4039 break;
4040 case GL_ATOMIC_COUNTER_BUFFER:
4041 bindIndexedAtomicCounterBuffer(buffer, index, offset, size);
4042 bindGenericAtomicCounterBuffer(buffer);
4043 break;
4044 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08004045 bindIndexedShaderStorageBuffer(buffer, index, offset, size);
4046 bindGenericShaderStorageBuffer(buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08004047 break;
4048 default:
4049 UNREACHABLE();
4050 break;
4051 }
4052}
4053
Jamie Madill01a80ee2016-11-07 12:06:18 -05004054void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
4055{
4056 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4057 {
4058 bindReadFramebuffer(framebuffer);
4059 }
4060
4061 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4062 {
4063 bindDrawFramebuffer(framebuffer);
4064 }
4065}
4066
4067void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
4068{
4069 ASSERT(target == GL_RENDERBUFFER);
4070 Renderbuffer *object =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05004071 mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004072 mGLState.setRenderbufferBinding(object);
4073}
4074
JiangYizhoubddc46b2016-12-09 09:50:51 +08004075void Context::texStorage2DMultisample(GLenum target,
4076 GLsizei samples,
4077 GLenum internalformat,
4078 GLsizei width,
4079 GLsizei height,
4080 GLboolean fixedsamplelocations)
4081{
4082 Extents size(width, height, 1);
4083 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05004084 handleError(texture->setStorageMultisample(this, target, samples, internalformat, size,
JiangYizhoubddc46b2016-12-09 09:50:51 +08004085 fixedsamplelocations));
4086}
4087
4088void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
4089{
Jamie Madilldd43e6c2017-03-24 14:18:49 -04004090 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
JiangYizhoubddc46b2016-12-09 09:50:51 +08004091 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
4092
4093 switch (pname)
4094 {
4095 case GL_SAMPLE_POSITION:
4096 handleError(framebuffer->getSamplePosition(index, val));
4097 break;
4098 default:
4099 UNREACHABLE();
4100 }
4101}
4102
Jamie Madille8fb6402017-02-14 17:56:40 -05004103void Context::renderbufferStorage(GLenum target,
4104 GLenum internalformat,
4105 GLsizei width,
4106 GLsizei height)
4107{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004108 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4109 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
4110
Jamie Madille8fb6402017-02-14 17:56:40 -05004111 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004112 handleError(renderbuffer->setStorage(convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004113}
4114
4115void Context::renderbufferStorageMultisample(GLenum target,
4116 GLsizei samples,
4117 GLenum internalformat,
4118 GLsizei width,
4119 GLsizei height)
4120{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004121 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4122 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
Jamie Madille8fb6402017-02-14 17:56:40 -05004123
4124 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004125 handleError(
4126 renderbuffer->setStorageMultisample(samples, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004127}
4128
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004129void Context::getSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)
4130{
4131 const FenceSync *syncObject = getFenceSync(sync);
Geoff Lang82483b92017-04-11 15:33:00 -04004132 handleError(QuerySynciv(syncObject, pname, bufSize, length, values));
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004133}
4134
JiangYizhoue18e6392017-02-20 10:32:23 +08004135void Context::getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
4136{
4137 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4138 QueryFramebufferParameteriv(framebuffer, pname, params);
4139}
4140
4141void Context::setFramebufferParameteri(GLenum target, GLenum pname, GLint param)
4142{
4143 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4144 SetFramebufferParameteri(framebuffer, pname, param);
4145}
4146
Jamie Madille14951e2017-03-09 18:55:16 -05004147Error Context::getScratchBuffer(size_t requestedSize, angle::MemoryBuffer **scratchBufferOut) const
4148{
4149 if (!mScratchBuffer.get(requestedSize, scratchBufferOut))
4150 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004151 return OutOfMemory() << "Failed to allocate internal buffer.";
Jamie Madille14951e2017-03-09 18:55:16 -05004152 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004153 return NoError();
Jamie Madille14951e2017-03-09 18:55:16 -05004154}
4155
Xinghua Cao2b396592017-03-29 15:36:04 +08004156void Context::dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ)
4157{
4158 if (numGroupsX == 0u || numGroupsY == 0u || numGroupsZ == 0u)
4159 {
4160 return;
4161 }
4162
Jamie Madillfe548342017-06-19 11:13:24 -04004163 mImplementation->dispatchCompute(this, numGroupsX, numGroupsY, numGroupsZ);
Xinghua Cao2b396592017-03-29 15:36:04 +08004164}
4165
JiangYizhou165361c2017-06-07 14:56:57 +08004166void Context::texStorage2D(GLenum target,
4167 GLsizei levels,
4168 GLenum internalFormat,
4169 GLsizei width,
4170 GLsizei height)
4171{
4172 Extents size(width, height, 1);
4173 Texture *texture = getTargetTexture(target);
4174 handleError(texture->setStorage(this, target, levels, internalFormat, size));
4175}
4176
4177void Context::texStorage3D(GLenum target,
4178 GLsizei levels,
4179 GLenum internalFormat,
4180 GLsizei width,
4181 GLsizei height,
4182 GLsizei depth)
4183{
4184 Extents size(width, height, depth);
4185 Texture *texture = getTargetTexture(target);
4186 handleError(texture->setStorage(this, target, levels, internalFormat, size));
4187}
4188
Jamie Madillc1d770e2017-04-13 17:31:24 -04004189GLenum Context::checkFramebufferStatus(GLenum target)
4190{
4191 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4192 ASSERT(framebuffer);
4193
4194 return framebuffer->checkStatus(this);
4195}
4196
4197void Context::compileShader(GLuint shader)
4198{
4199 Shader *shaderObject = GetValidShader(this, shader);
4200 if (!shaderObject)
4201 {
4202 return;
4203 }
4204 shaderObject->compile(this);
4205}
4206
4207void Context::deleteBuffers(GLsizei n, const GLuint *buffers)
4208{
4209 for (int i = 0; i < n; i++)
4210 {
4211 deleteBuffer(buffers[i]);
4212 }
4213}
4214
4215void Context::deleteFramebuffers(GLsizei n, const GLuint *framebuffers)
4216{
4217 for (int i = 0; i < n; i++)
4218 {
4219 if (framebuffers[i] != 0)
4220 {
4221 deleteFramebuffer(framebuffers[i]);
4222 }
4223 }
4224}
4225
4226void Context::deleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)
4227{
4228 for (int i = 0; i < n; i++)
4229 {
4230 deleteRenderbuffer(renderbuffers[i]);
4231 }
4232}
4233
4234void Context::deleteTextures(GLsizei n, const GLuint *textures)
4235{
4236 for (int i = 0; i < n; i++)
4237 {
4238 if (textures[i] != 0)
4239 {
4240 deleteTexture(textures[i]);
4241 }
4242 }
4243}
4244
4245void Context::detachShader(GLuint program, GLuint shader)
4246{
4247 Program *programObject = getProgram(program);
4248 ASSERT(programObject);
4249
4250 Shader *shaderObject = getShader(shader);
4251 ASSERT(shaderObject);
4252
4253 programObject->detachShader(this, shaderObject);
4254}
4255
4256void Context::genBuffers(GLsizei n, GLuint *buffers)
4257{
4258 for (int i = 0; i < n; i++)
4259 {
4260 buffers[i] = createBuffer();
4261 }
4262}
4263
4264void Context::genFramebuffers(GLsizei n, GLuint *framebuffers)
4265{
4266 for (int i = 0; i < n; i++)
4267 {
4268 framebuffers[i] = createFramebuffer();
4269 }
4270}
4271
4272void Context::genRenderbuffers(GLsizei n, GLuint *renderbuffers)
4273{
4274 for (int i = 0; i < n; i++)
4275 {
4276 renderbuffers[i] = createRenderbuffer();
4277 }
4278}
4279
4280void Context::genTextures(GLsizei n, GLuint *textures)
4281{
4282 for (int i = 0; i < n; i++)
4283 {
4284 textures[i] = createTexture();
4285 }
4286}
4287
4288void Context::getActiveAttrib(GLuint program,
4289 GLuint index,
4290 GLsizei bufsize,
4291 GLsizei *length,
4292 GLint *size,
4293 GLenum *type,
4294 GLchar *name)
4295{
4296 Program *programObject = getProgram(program);
4297 ASSERT(programObject);
4298 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
4299}
4300
4301void Context::getActiveUniform(GLuint program,
4302 GLuint index,
4303 GLsizei bufsize,
4304 GLsizei *length,
4305 GLint *size,
4306 GLenum *type,
4307 GLchar *name)
4308{
4309 Program *programObject = getProgram(program);
4310 ASSERT(programObject);
4311 programObject->getActiveUniform(index, bufsize, length, size, type, name);
4312}
4313
4314void Context::getAttachedShaders(GLuint program, GLsizei maxcount, GLsizei *count, GLuint *shaders)
4315{
4316 Program *programObject = getProgram(program);
4317 ASSERT(programObject);
4318 programObject->getAttachedShaders(maxcount, count, shaders);
4319}
4320
4321GLint Context::getAttribLocation(GLuint program, const GLchar *name)
4322{
4323 Program *programObject = getProgram(program);
4324 ASSERT(programObject);
4325 return programObject->getAttributeLocation(name);
4326}
4327
4328void Context::getBooleanv(GLenum pname, GLboolean *params)
4329{
4330 GLenum nativeType;
4331 unsigned int numParams = 0;
4332 getQueryParameterInfo(pname, &nativeType, &numParams);
4333
4334 if (nativeType == GL_BOOL)
4335 {
4336 getBooleanvImpl(pname, params);
4337 }
4338 else
4339 {
4340 CastStateValues(this, nativeType, pname, numParams, params);
4341 }
4342}
4343
4344void Context::getFloatv(GLenum pname, GLfloat *params)
4345{
4346 GLenum nativeType;
4347 unsigned int numParams = 0;
4348 getQueryParameterInfo(pname, &nativeType, &numParams);
4349
4350 if (nativeType == GL_FLOAT)
4351 {
4352 getFloatvImpl(pname, params);
4353 }
4354 else
4355 {
4356 CastStateValues(this, nativeType, pname, numParams, params);
4357 }
4358}
4359
4360void Context::getIntegerv(GLenum pname, GLint *params)
4361{
4362 GLenum nativeType;
4363 unsigned int numParams = 0;
4364 getQueryParameterInfo(pname, &nativeType, &numParams);
4365
4366 if (nativeType == GL_INT)
4367 {
4368 getIntegervImpl(pname, params);
4369 }
4370 else
4371 {
4372 CastStateValues(this, nativeType, pname, numParams, params);
4373 }
4374}
4375
4376void Context::getProgramiv(GLuint program, GLenum pname, GLint *params)
4377{
4378 Program *programObject = getProgram(program);
4379 ASSERT(programObject);
4380 QueryProgramiv(programObject, pname, params);
4381}
4382
Jamie Madillbe849e42017-05-02 15:49:00 -04004383void Context::getProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei *length, GLchar *infolog)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004384{
4385 Program *programObject = getProgram(program);
4386 ASSERT(programObject);
4387 programObject->getInfoLog(bufsize, length, infolog);
4388}
4389
4390void Context::getShaderiv(GLuint shader, GLenum pname, GLint *params)
4391{
4392 Shader *shaderObject = getShader(shader);
4393 ASSERT(shaderObject);
Jamie Madillbd044ed2017-06-05 12:59:21 -04004394 QueryShaderiv(this, shaderObject, pname, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004395}
4396
4397void Context::getShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *infolog)
4398{
4399 Shader *shaderObject = getShader(shader);
4400 ASSERT(shaderObject);
Jamie Madillbd044ed2017-06-05 12:59:21 -04004401 shaderObject->getInfoLog(this, bufsize, length, infolog);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004402}
4403
4404void Context::getShaderPrecisionFormat(GLenum shadertype,
4405 GLenum precisiontype,
4406 GLint *range,
4407 GLint *precision)
4408{
4409 // TODO(jmadill): Compute shaders.
4410
4411 switch (shadertype)
4412 {
4413 case GL_VERTEX_SHADER:
4414 switch (precisiontype)
4415 {
4416 case GL_LOW_FLOAT:
4417 mCaps.vertexLowpFloat.get(range, precision);
4418 break;
4419 case GL_MEDIUM_FLOAT:
4420 mCaps.vertexMediumpFloat.get(range, precision);
4421 break;
4422 case GL_HIGH_FLOAT:
4423 mCaps.vertexHighpFloat.get(range, precision);
4424 break;
4425
4426 case GL_LOW_INT:
4427 mCaps.vertexLowpInt.get(range, precision);
4428 break;
4429 case GL_MEDIUM_INT:
4430 mCaps.vertexMediumpInt.get(range, precision);
4431 break;
4432 case GL_HIGH_INT:
4433 mCaps.vertexHighpInt.get(range, precision);
4434 break;
4435
4436 default:
4437 UNREACHABLE();
4438 return;
4439 }
4440 break;
4441
4442 case GL_FRAGMENT_SHADER:
4443 switch (precisiontype)
4444 {
4445 case GL_LOW_FLOAT:
4446 mCaps.fragmentLowpFloat.get(range, precision);
4447 break;
4448 case GL_MEDIUM_FLOAT:
4449 mCaps.fragmentMediumpFloat.get(range, precision);
4450 break;
4451 case GL_HIGH_FLOAT:
4452 mCaps.fragmentHighpFloat.get(range, precision);
4453 break;
4454
4455 case GL_LOW_INT:
4456 mCaps.fragmentLowpInt.get(range, precision);
4457 break;
4458 case GL_MEDIUM_INT:
4459 mCaps.fragmentMediumpInt.get(range, precision);
4460 break;
4461 case GL_HIGH_INT:
4462 mCaps.fragmentHighpInt.get(range, precision);
4463 break;
4464
4465 default:
4466 UNREACHABLE();
4467 return;
4468 }
4469 break;
4470
4471 default:
4472 UNREACHABLE();
4473 return;
4474 }
4475}
4476
4477void Context::getShaderSource(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source)
4478{
4479 Shader *shaderObject = getShader(shader);
4480 ASSERT(shaderObject);
4481 shaderObject->getSource(bufsize, length, source);
4482}
4483
4484void Context::getUniformfv(GLuint program, GLint location, GLfloat *params)
4485{
4486 Program *programObject = getProgram(program);
4487 ASSERT(programObject);
4488 programObject->getUniformfv(location, params);
4489}
4490
4491void Context::getUniformiv(GLuint program, GLint location, GLint *params)
4492{
4493 Program *programObject = getProgram(program);
4494 ASSERT(programObject);
4495 programObject->getUniformiv(location, params);
4496}
4497
4498GLint Context::getUniformLocation(GLuint program, const GLchar *name)
4499{
4500 Program *programObject = getProgram(program);
4501 ASSERT(programObject);
4502 return programObject->getUniformLocation(name);
4503}
4504
4505GLboolean Context::isBuffer(GLuint buffer)
4506{
4507 if (buffer == 0)
4508 {
4509 return GL_FALSE;
4510 }
4511
4512 return (getBuffer(buffer) ? GL_TRUE : GL_FALSE);
4513}
4514
4515GLboolean Context::isEnabled(GLenum cap)
4516{
4517 return mGLState.getEnableFeature(cap);
4518}
4519
4520GLboolean Context::isFramebuffer(GLuint framebuffer)
4521{
4522 if (framebuffer == 0)
4523 {
4524 return GL_FALSE;
4525 }
4526
4527 return (getFramebuffer(framebuffer) ? GL_TRUE : GL_FALSE);
4528}
4529
4530GLboolean Context::isProgram(GLuint program)
4531{
4532 if (program == 0)
4533 {
4534 return GL_FALSE;
4535 }
4536
4537 return (getProgram(program) ? GL_TRUE : GL_FALSE);
4538}
4539
4540GLboolean Context::isRenderbuffer(GLuint renderbuffer)
4541{
4542 if (renderbuffer == 0)
4543 {
4544 return GL_FALSE;
4545 }
4546
4547 return (getRenderbuffer(renderbuffer) ? GL_TRUE : GL_FALSE);
4548}
4549
4550GLboolean Context::isShader(GLuint shader)
4551{
4552 if (shader == 0)
4553 {
4554 return GL_FALSE;
4555 }
4556
4557 return (getShader(shader) ? GL_TRUE : GL_FALSE);
4558}
4559
4560GLboolean Context::isTexture(GLuint texture)
4561{
4562 if (texture == 0)
4563 {
4564 return GL_FALSE;
4565 }
4566
4567 return (getTexture(texture) ? GL_TRUE : GL_FALSE);
4568}
4569
4570void Context::linkProgram(GLuint program)
4571{
4572 Program *programObject = getProgram(program);
4573 ASSERT(programObject);
4574 handleError(programObject->link(this));
4575}
4576
4577void Context::releaseShaderCompiler()
4578{
Jamie Madill2f348d22017-06-05 10:50:59 -04004579 mCompiler.set(nullptr);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004580}
4581
4582void Context::shaderBinary(GLsizei n,
4583 const GLuint *shaders,
4584 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04004585 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004586 GLsizei length)
4587{
4588 // No binary shader formats are supported.
4589 UNIMPLEMENTED();
4590}
4591
4592void Context::shaderSource(GLuint shader,
4593 GLsizei count,
4594 const GLchar *const *string,
4595 const GLint *length)
4596{
4597 Shader *shaderObject = getShader(shader);
4598 ASSERT(shaderObject);
4599 shaderObject->setSource(count, string, length);
4600}
4601
4602void Context::stencilFunc(GLenum func, GLint ref, GLuint mask)
4603{
4604 stencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
4605}
4606
4607void Context::stencilMask(GLuint mask)
4608{
4609 stencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4610}
4611
4612void Context::stencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4613{
4614 stencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4615}
4616
4617void Context::uniform1f(GLint location, GLfloat x)
4618{
4619 Program *program = mGLState.getProgram();
4620 program->setUniform1fv(location, 1, &x);
4621}
4622
4623void Context::uniform1fv(GLint location, GLsizei count, const GLfloat *v)
4624{
4625 Program *program = mGLState.getProgram();
4626 program->setUniform1fv(location, count, v);
4627}
4628
4629void Context::uniform1i(GLint location, GLint x)
4630{
4631 Program *program = mGLState.getProgram();
4632 program->setUniform1iv(location, 1, &x);
4633}
4634
4635void Context::uniform1iv(GLint location, GLsizei count, const GLint *v)
4636{
4637 Program *program = mGLState.getProgram();
4638 program->setUniform1iv(location, count, v);
4639}
4640
4641void Context::uniform2f(GLint location, GLfloat x, GLfloat y)
4642{
4643 GLfloat xy[2] = {x, y};
4644 Program *program = mGLState.getProgram();
4645 program->setUniform2fv(location, 1, xy);
4646}
4647
4648void Context::uniform2fv(GLint location, GLsizei count, const GLfloat *v)
4649{
4650 Program *program = mGLState.getProgram();
4651 program->setUniform2fv(location, count, v);
4652}
4653
4654void Context::uniform2i(GLint location, GLint x, GLint y)
4655{
4656 GLint xy[2] = {x, y};
4657 Program *program = mGLState.getProgram();
4658 program->setUniform2iv(location, 1, xy);
4659}
4660
4661void Context::uniform2iv(GLint location, GLsizei count, const GLint *v)
4662{
4663 Program *program = mGLState.getProgram();
4664 program->setUniform2iv(location, count, v);
4665}
4666
4667void Context::uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4668{
4669 GLfloat xyz[3] = {x, y, z};
4670 Program *program = mGLState.getProgram();
4671 program->setUniform3fv(location, 1, xyz);
4672}
4673
4674void Context::uniform3fv(GLint location, GLsizei count, const GLfloat *v)
4675{
4676 Program *program = mGLState.getProgram();
4677 program->setUniform3fv(location, count, v);
4678}
4679
4680void Context::uniform3i(GLint location, GLint x, GLint y, GLint z)
4681{
4682 GLint xyz[3] = {x, y, z};
4683 Program *program = mGLState.getProgram();
4684 program->setUniform3iv(location, 1, xyz);
4685}
4686
4687void Context::uniform3iv(GLint location, GLsizei count, const GLint *v)
4688{
4689 Program *program = mGLState.getProgram();
4690 program->setUniform3iv(location, count, v);
4691}
4692
4693void Context::uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4694{
4695 GLfloat xyzw[4] = {x, y, z, w};
4696 Program *program = mGLState.getProgram();
4697 program->setUniform4fv(location, 1, xyzw);
4698}
4699
4700void Context::uniform4fv(GLint location, GLsizei count, const GLfloat *v)
4701{
4702 Program *program = mGLState.getProgram();
4703 program->setUniform4fv(location, count, v);
4704}
4705
4706void Context::uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4707{
4708 GLint xyzw[4] = {x, y, z, w};
4709 Program *program = mGLState.getProgram();
4710 program->setUniform4iv(location, 1, xyzw);
4711}
4712
4713void Context::uniform4iv(GLint location, GLsizei count, const GLint *v)
4714{
4715 Program *program = mGLState.getProgram();
4716 program->setUniform4iv(location, count, v);
4717}
4718
4719void Context::uniformMatrix2fv(GLint location,
4720 GLsizei count,
4721 GLboolean transpose,
4722 const GLfloat *value)
4723{
4724 Program *program = mGLState.getProgram();
4725 program->setUniformMatrix2fv(location, count, transpose, value);
4726}
4727
4728void Context::uniformMatrix3fv(GLint location,
4729 GLsizei count,
4730 GLboolean transpose,
4731 const GLfloat *value)
4732{
4733 Program *program = mGLState.getProgram();
4734 program->setUniformMatrix3fv(location, count, transpose, value);
4735}
4736
4737void Context::uniformMatrix4fv(GLint location,
4738 GLsizei count,
4739 GLboolean transpose,
4740 const GLfloat *value)
4741{
4742 Program *program = mGLState.getProgram();
4743 program->setUniformMatrix4fv(location, count, transpose, value);
4744}
4745
4746void Context::validateProgram(GLuint program)
4747{
4748 Program *programObject = getProgram(program);
4749 ASSERT(programObject);
4750 programObject->validate(mCaps);
4751}
4752
Jamie Madilld04908b2017-06-09 14:15:35 -04004753void Context::getProgramBinary(GLuint program,
4754 GLsizei bufSize,
4755 GLsizei *length,
4756 GLenum *binaryFormat,
4757 void *binary)
4758{
4759 Program *programObject = getProgram(program);
4760 ASSERT(programObject != nullptr);
4761
4762 handleError(programObject->saveBinary(this, binaryFormat, binary, bufSize, length));
4763}
4764
4765void Context::programBinary(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length)
4766{
4767 Program *programObject = getProgram(program);
4768 ASSERT(programObject != nullptr);
4769
4770 handleError(programObject->loadBinary(this, binaryFormat, binary, length));
4771}
4772
Jamie Madillc29968b2016-01-20 11:17:23 -05004773} // namespace gl