blob: 5a0977775a02680508ac2fd5daa30b3c1ea2dc66 [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
Jamie Madillb6664922017-07-25 12:55:04 -040048#define ANGLE_HANDLE_ERR(X) \
49 handleError(X); \
50 return;
51#define ANGLE_CONTEXT_TRY(EXPR) ANGLE_TRY_TEMPLATE(EXPR, ANGLE_HANDLE_ERR);
52
Ian Ewell3ffd78b2016-01-22 16:09:42 -050053template <typename T>
Geoff Lang4ddf5af2016-12-01 14:30:44 -050054std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
Sami Väisänend59ca052016-06-21 16:10:00 +030055 GLsizei numPaths,
56 const void *paths,
57 GLuint pathBase)
58{
59 std::vector<gl::Path *> ret;
60 ret.reserve(numPaths);
61
62 const auto *nameArray = static_cast<const T *>(paths);
63
64 for (GLsizei i = 0; i < numPaths; ++i)
65 {
66 const GLuint pathName = nameArray[i] + pathBase;
67
68 ret.push_back(resourceManager.getPath(pathName));
69 }
70
71 return ret;
72}
73
Geoff Lang4ddf5af2016-12-01 14:30:44 -050074std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
Sami Väisänend59ca052016-06-21 16:10:00 +030075 GLsizei numPaths,
76 GLenum pathNameType,
77 const void *paths,
78 GLuint pathBase)
79{
80 switch (pathNameType)
81 {
82 case GL_UNSIGNED_BYTE:
83 return GatherPaths<GLubyte>(resourceManager, numPaths, paths, pathBase);
84
85 case GL_BYTE:
86 return GatherPaths<GLbyte>(resourceManager, numPaths, paths, pathBase);
87
88 case GL_UNSIGNED_SHORT:
89 return GatherPaths<GLushort>(resourceManager, numPaths, paths, pathBase);
90
91 case GL_SHORT:
92 return GatherPaths<GLshort>(resourceManager, numPaths, paths, pathBase);
93
94 case GL_UNSIGNED_INT:
95 return GatherPaths<GLuint>(resourceManager, numPaths, paths, pathBase);
96
97 case GL_INT:
98 return GatherPaths<GLint>(resourceManager, numPaths, paths, pathBase);
99 }
100
101 UNREACHABLE();
102 return std::vector<gl::Path *>();
103}
104
105template <typename T>
Geoff Lang2186c382016-10-14 10:54:54 -0400106gl::Error GetQueryObjectParameter(gl::Query *query, GLenum pname, T *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500107{
Geoff Lang2186c382016-10-14 10:54:54 -0400108 ASSERT(query != nullptr);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500109
110 switch (pname)
111 {
112 case GL_QUERY_RESULT_EXT:
Geoff Lang2186c382016-10-14 10:54:54 -0400113 return query->getResult(params);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500114 case GL_QUERY_RESULT_AVAILABLE_EXT:
115 {
116 bool available;
Geoff Lang2186c382016-10-14 10:54:54 -0400117 gl::Error error = query->isResultAvailable(&available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500118 if (!error.isError())
119 {
Geoff Lang2186c382016-10-14 10:54:54 -0400120 *params = gl::ConvertFromGLboolean<T>(available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500121 }
122 return error;
123 }
124 default:
125 UNREACHABLE();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500126 return gl::InternalError() << "Unreachable Error";
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500127 }
128}
129
Geoff Langf6db0982015-08-25 13:04:00 -0400130void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback)
131{
Geoff Lang1a683462015-09-29 15:09:59 -0400132 if (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
Geoff Langf6db0982015-08-25 13:04:00 -0400133 {
134 for (size_t tfBufferIndex = 0; tfBufferIndex < transformFeedback->getIndexedBufferCount();
135 tfBufferIndex++)
136 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400137 const gl::OffsetBindingPointer<gl::Buffer> &buffer =
Geoff Langf6db0982015-08-25 13:04:00 -0400138 transformFeedback->getIndexedBuffer(tfBufferIndex);
139 if (buffer.get() != nullptr)
140 {
141 buffer->onTransformFeedback();
142 }
143 }
144 }
145}
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500146
147// Attribute map queries.
Martin Radev1be913c2016-07-11 17:59:16 +0300148EGLint GetClientMajorVersion(const egl::AttributeMap &attribs)
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500149{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400150 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1));
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500151}
152
Martin Radev1be913c2016-07-11 17:59:16 +0300153EGLint GetClientMinorVersion(const egl::AttributeMap &attribs)
154{
155 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_MINOR_VERSION, 0));
156}
157
Geoff Langeb66a6e2016-10-31 13:06:12 -0400158gl::Version GetClientVersion(const egl::AttributeMap &attribs)
159{
160 return gl::Version(GetClientMajorVersion(attribs), GetClientMinorVersion(attribs));
161}
162
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500163GLenum GetResetStrategy(const egl::AttributeMap &attribs)
164{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400165 EGLAttrib attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
166 EGL_NO_RESET_NOTIFICATION_EXT);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500167 switch (attrib)
168 {
169 case EGL_NO_RESET_NOTIFICATION:
170 return GL_NO_RESET_NOTIFICATION_EXT;
171 case EGL_LOSE_CONTEXT_ON_RESET:
172 return GL_LOSE_CONTEXT_ON_RESET_EXT;
173 default:
174 UNREACHABLE();
175 return GL_NONE;
176 }
177}
178
179bool GetRobustAccess(const egl::AttributeMap &attribs)
180{
Geoff Lang077f20a2016-11-01 10:08:02 -0400181 return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE) ||
182 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) !=
183 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500184}
185
186bool GetDebug(const egl::AttributeMap &attribs)
187{
Geoff Lang077f20a2016-11-01 10:08:02 -0400188 return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE) ||
189 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR) != 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500190}
191
192bool GetNoError(const egl::AttributeMap &attribs)
193{
194 return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
195}
196
Geoff Langc287ea62016-09-16 14:46:51 -0400197bool GetWebGLContext(const egl::AttributeMap &attribs)
198{
199 return (attribs.get(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE, EGL_FALSE) == EGL_TRUE);
200}
201
Geoff Langf41a7152016-09-19 15:11:17 -0400202bool GetBindGeneratesResource(const egl::AttributeMap &attribs)
203{
204 return (attribs.get(EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE) == EGL_TRUE);
205}
206
Geoff Langfeb8c682017-02-13 16:07:35 -0500207bool GetClientArraysEnabled(const egl::AttributeMap &attribs)
208{
209 return (attribs.get(EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE, EGL_TRUE) == EGL_TRUE);
210}
211
Martin Radev9d901792016-07-15 15:58:58 +0300212std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
213{
214 std::string labelName;
215 if (label != nullptr)
216 {
217 size_t labelLength = length < 0 ? strlen(label) : length;
218 labelName = std::string(label, labelLength);
219 }
220 return labelName;
221}
222
223void GetObjectLabelBase(const std::string &objectLabel,
224 GLsizei bufSize,
225 GLsizei *length,
226 GLchar *label)
227{
228 size_t writeLength = objectLabel.length();
229 if (label != nullptr && bufSize > 0)
230 {
231 writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
232 std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
233 label[writeLength] = '\0';
234 }
235
236 if (length != nullptr)
237 {
238 *length = static_cast<GLsizei>(writeLength);
239 }
240}
241
Geoff Langf6db0982015-08-25 13:04:00 -0400242} // anonymous namespace
243
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000244namespace gl
245{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000246
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400247Context::Context(rx::EGLImplFactory *implFactory,
248 const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400249 const Context *shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500250 TextureManager *shareTextures,
Jamie Madill32447362017-06-28 14:53:52 -0400251 MemoryProgramCache *memoryProgramCache,
Corentin Wallezc295e512017-01-27 17:47:50 -0500252 const egl::AttributeMap &attribs,
Jamie Madill948bbe52017-06-01 13:10:42 -0400253 const egl::DisplayExtensions &displayExtensions,
254 bool robustResourceInit)
Martin Radev1be913c2016-07-11 17:59:16 +0300255
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500256 : ValidationContext(shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500257 shareTextures,
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500258 GetClientVersion(attribs),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700259 &mGLState,
Jamie Madillf25855c2015-11-03 11:06:18 -0500260 mCaps,
261 mTextureCaps,
262 mExtensions,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500263 mLimitations,
264 GetNoError(attribs)),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700265 mImplementation(implFactory->createContext(mState)),
Jamie Madill2f348d22017-06-05 10:50:59 -0400266 mCompiler(),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400267 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500268 mClientType(EGL_OPENGL_ES_API),
269 mHasBeenCurrent(false),
270 mContextLost(false),
271 mResetStatus(GL_NO_ERROR),
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700272 mContextLostForced(false),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500273 mResetStrategy(GetResetStrategy(attribs)),
274 mRobustAccess(GetRobustAccess(attribs)),
Jamie Madill61e16b42017-06-19 11:13:23 -0400275 mCurrentSurface(static_cast<egl::Surface *>(EGL_NO_SURFACE)),
276 mCurrentDisplay(static_cast<egl::Display *>(EGL_NO_DISPLAY)),
Jamie Madill4e0e6f82017-02-17 11:06:03 -0500277 mSurfacelessFramebuffer(nullptr),
Jamie Madille14951e2017-03-09 18:55:16 -0500278 mWebGLContext(GetWebGLContext(attribs)),
Jamie Madill32447362017-06-28 14:53:52 -0400279 mMemoryProgramCache(memoryProgramCache),
Jamie Madillb3f26b92017-07-19 15:07:41 -0400280 mScratchBuffer(1000u),
281 mZeroFilledBuffer(1000u)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000282{
Geoff Lang077f20a2016-11-01 10:08:02 -0400283 if (mRobustAccess)
284 {
285 UNIMPLEMENTED();
286 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000287
Jamie Madill4e0e6f82017-02-17 11:06:03 -0500288 initCaps(displayExtensions);
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700289 initWorkarounds();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400290
Jamie Madill4928b7c2017-06-20 12:57:39 -0400291 mGLState.initialize(this, GetDebug(attribs), GetBindGeneratesResource(attribs),
Jamie Madillc43be722017-07-13 16:22:14 -0400292 GetClientArraysEnabled(attribs), robustResourceInit,
293 mMemoryProgramCache != nullptr);
Régis Fénéon83107972015-02-05 12:57:44 +0100294
Shannon Woods53a94a82014-06-24 15:20:36 -0400295 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400296
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000297 // [OpenGL ES 2.0.24] section 3.7 page 83:
298 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
299 // and cube map texture state vectors respectively associated with them.
300 // In order that access to these initial textures not be lost, they are treated as texture
301 // objects all of whose names are 0.
302
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400303 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400304 mZeroTextures[GL_TEXTURE_2D].set(this, zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500305
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400306 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400307 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(this, zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400308
Geoff Langeb66a6e2016-10-31 13:06:12 -0400309 if (getClientVersion() >= Version(3, 0))
Geoff Lang76b10c92014-09-05 16:28:14 -0400310 {
311 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400312 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400313 mZeroTextures[GL_TEXTURE_3D].set(this, zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400314
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400315 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400316 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(this, zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400317 }
Geoff Lang3b573612016-10-31 14:08:10 -0400318 if (getClientVersion() >= Version(3, 1))
319 {
320 Texture *zeroTexture2DMultisample =
321 new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_MULTISAMPLE);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400322 mZeroTextures[GL_TEXTURE_2D_MULTISAMPLE].set(this, zeroTexture2DMultisample);
Jiajia Qin6eafb042016-12-27 17:04:07 +0800323
324 bindGenericAtomicCounterBuffer(0);
325 for (unsigned int i = 0; i < mCaps.maxAtomicCounterBufferBindings; i++)
326 {
327 bindIndexedAtomicCounterBuffer(0, i, 0, 0);
328 }
Jiajia Qinf546e7d2017-03-27 14:12:59 +0800329
330 bindGenericShaderStorageBuffer(0);
331 for (unsigned int i = 0; i < mCaps.maxShaderStorageBufferBindings; i++)
332 {
333 bindIndexedShaderStorageBuffer(0, i, 0, 0);
334 }
Geoff Lang3b573612016-10-31 14:08:10 -0400335 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000336
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400337 if (mExtensions.textureRectangle)
338 {
339 Texture *zeroTextureRectangle =
340 new Texture(mImplementation.get(), 0, GL_TEXTURE_RECTANGLE_ANGLE);
341 mZeroTextures[GL_TEXTURE_RECTANGLE_ANGLE].set(this, zeroTextureRectangle);
342 }
343
Ian Ewellbda75592016-04-18 17:25:54 -0400344 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
345 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400346 Texture *zeroTextureExternal =
347 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400348 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(this, zeroTextureExternal);
Ian Ewellbda75592016-04-18 17:25:54 -0400349 }
350
Jamie Madill4928b7c2017-06-20 12:57:39 -0400351 mGLState.initializeZeroTextures(this, mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500352
Jamie Madill57a89722013-07-02 11:57:03 -0400353 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000354 bindArrayBuffer(0);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800355 bindDrawIndirectBuffer(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000356 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400357
Jamie Madill01a80ee2016-11-07 12:06:18 -0500358 bindRenderbuffer(GL_RENDERBUFFER, 0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000359
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000360 bindGenericUniformBuffer(0);
Geoff Lang4dc3af02016-11-18 14:09:27 -0500361 for (unsigned int i = 0; i < mCaps.maxUniformBufferBindings; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000362 {
363 bindIndexedUniformBuffer(0, i, 0, -1);
364 }
365
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000366 bindCopyReadBuffer(0);
367 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000368 bindPixelPackBuffer(0);
369 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000370
Geoff Langeb66a6e2016-10-31 13:06:12 -0400371 if (getClientVersion() >= Version(3, 0))
Geoff Lang1a683462015-09-29 15:09:59 -0400372 {
373 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
374 // In the initial state, a default transform feedback object is bound and treated as
375 // a transform feedback object with a name of zero. That object is bound any time
376 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400377 bindTransformFeedback(0);
378 }
Geoff Langc8058452014-02-03 12:04:11 -0500379
Jamie Madillad9f24e2016-02-12 09:27:24 -0500380 // Initialize dirty bit masks
381 // TODO(jmadill): additional ES3 state
382 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
383 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
384 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
385 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
386 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
387 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400388 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500389 // No dirty objects.
390
391 // Readpixels uses the pack state and read FBO
392 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
393 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
394 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
395 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
396 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400397 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500398 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
399
400 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
401 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
402 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
403 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
404 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
405 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
406 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
407 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
408 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
409 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
410 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
411 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
412
413 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
414 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700415 mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500416 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
417 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400418
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400419 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000420}
421
Jamie Madill4928b7c2017-06-20 12:57:39 -0400422egl::Error Context::onDestroy(const egl::Display *display)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000423{
Corentin Wallez80b24112015-08-25 16:41:57 -0400424 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000425 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400426 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000427 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400428 mFenceNVMap.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000429
Corentin Wallez80b24112015-08-25 16:41:57 -0400430 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000431 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400432 if (query.second != nullptr)
433 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400434 query.second->release(this);
Geoff Langf0aa8422015-09-29 15:08:34 -0400435 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000436 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400437 mQueryMap.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000438
Corentin Wallez80b24112015-08-25 16:41:57 -0400439 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400440 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400441 if (vertexArray.second)
442 {
443 vertexArray.second->onDestroy(this);
444 }
Jamie Madill57a89722013-07-02 11:57:03 -0400445 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400446 mVertexArrayMap.clear();
Jamie Madill57a89722013-07-02 11:57:03 -0400447
Corentin Wallez80b24112015-08-25 16:41:57 -0400448 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500449 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500450 if (transformFeedback.second != nullptr)
451 {
Jamie Madill6c1f6712017-02-14 19:08:04 -0500452 transformFeedback.second->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500453 }
Geoff Langc8058452014-02-03 12:04:11 -0500454 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400455 mTransformFeedbackMap.clear();
Geoff Langc8058452014-02-03 12:04:11 -0500456
Jamie Madilldedd7b92014-11-05 16:30:36 -0500457 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400458 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400459 zeroTexture.second->onDestroy(this);
460 zeroTexture.second.set(this, nullptr);
Geoff Lang76b10c92014-09-05 16:28:14 -0400461 }
462 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000463
Corentin Wallezccab69d2017-01-27 16:57:15 -0500464 SafeDelete(mSurfacelessFramebuffer);
465
Jamie Madill4928b7c2017-06-20 12:57:39 -0400466 ANGLE_TRY(releaseSurface(display));
Jamie Madill2f348d22017-06-05 10:50:59 -0400467 releaseShaderCompiler();
Jamie Madill6c1f6712017-02-14 19:08:04 -0500468
Jamie Madill4928b7c2017-06-20 12:57:39 -0400469 mGLState.reset(this);
470
Jamie Madill6c1f6712017-02-14 19:08:04 -0500471 mState.mBuffers->release(this);
472 mState.mShaderPrograms->release(this);
473 mState.mTextures->release(this);
474 mState.mRenderbuffers->release(this);
475 mState.mSamplers->release(this);
476 mState.mFenceSyncs->release(this);
477 mState.mPaths->release(this);
478 mState.mFramebuffers->release(this);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400479
480 return egl::NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000481}
482
Jamie Madill70ee0f62017-02-06 16:04:20 -0500483Context::~Context()
484{
485}
486
Jamie Madill4928b7c2017-06-20 12:57:39 -0400487egl::Error Context::makeCurrent(egl::Display *display, egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000488{
Jamie Madill61e16b42017-06-19 11:13:23 -0400489 mCurrentDisplay = display;
490
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000491 if (!mHasBeenCurrent)
492 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000493 initRendererString();
Geoff Langc339c4e2016-11-29 10:37:36 -0500494 initVersionStrings();
Geoff Langcec35902014-04-16 10:52:36 -0400495 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000496
Corentin Wallezc295e512017-01-27 17:47:50 -0500497 int width = 0;
498 int height = 0;
499 if (surface != nullptr)
500 {
501 width = surface->getWidth();
502 height = surface->getHeight();
503 }
504
505 mGLState.setViewportParams(0, 0, width, height);
506 mGLState.setScissorParams(0, 0, width, height);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000507
508 mHasBeenCurrent = true;
509 }
510
Jamie Madill1b94d432015-08-07 13:23:23 -0400511 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700512 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400513
Jamie Madill4928b7c2017-06-20 12:57:39 -0400514 ANGLE_TRY(releaseSurface(display));
Corentin Wallezccab69d2017-01-27 16:57:15 -0500515
516 Framebuffer *newDefault = nullptr;
517 if (surface != nullptr)
518 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400519 ANGLE_TRY(surface->setIsCurrent(this, true));
Corentin Wallezccab69d2017-01-27 16:57:15 -0500520 mCurrentSurface = surface;
521 newDefault = surface->getDefaultFramebuffer();
522 }
523 else
524 {
525 if (mSurfacelessFramebuffer == nullptr)
526 {
527 mSurfacelessFramebuffer = new Framebuffer(mImplementation.get());
528 }
529
530 newDefault = mSurfacelessFramebuffer;
531 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000532
Corentin Wallez37c39792015-08-20 14:19:46 -0400533 // Update default framebuffer, the binding of the previous default
534 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400535 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700536 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400537 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700538 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400539 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700540 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400541 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700542 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400543 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500544 mState.mFramebuffers->setDefaultFramebuffer(newDefault);
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400545 }
Ian Ewell292f0052016-02-04 10:37:32 -0500546
547 // Notify the renderer of a context switch
Jamie Madill4928b7c2017-06-20 12:57:39 -0400548 mImplementation->onMakeCurrent(this);
549 return egl::NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000550}
551
Jamie Madill4928b7c2017-06-20 12:57:39 -0400552egl::Error Context::releaseSurface(const egl::Display *display)
Jamie Madill77a72f62015-04-14 11:18:32 -0400553{
Corentin Wallez37c39792015-08-20 14:19:46 -0400554 // Remove the default framebuffer
Corentin Wallezc295e512017-01-27 17:47:50 -0500555 Framebuffer *currentDefault = nullptr;
556 if (mCurrentSurface != nullptr)
Corentin Wallez51706ea2015-08-07 14:39:22 -0400557 {
Corentin Wallezc295e512017-01-27 17:47:50 -0500558 currentDefault = mCurrentSurface->getDefaultFramebuffer();
559 }
560 else if (mSurfacelessFramebuffer != nullptr)
561 {
562 currentDefault = mSurfacelessFramebuffer;
Corentin Wallez51706ea2015-08-07 14:39:22 -0400563 }
564
Corentin Wallezc295e512017-01-27 17:47:50 -0500565 if (mGLState.getReadFramebuffer() == currentDefault)
566 {
567 mGLState.setReadFramebufferBinding(nullptr);
568 }
569 if (mGLState.getDrawFramebuffer() == currentDefault)
570 {
571 mGLState.setDrawFramebufferBinding(nullptr);
572 }
573 mState.mFramebuffers->setDefaultFramebuffer(nullptr);
574
575 if (mCurrentSurface)
576 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400577 ANGLE_TRY(mCurrentSurface->setIsCurrent(this, false));
Corentin Wallezc295e512017-01-27 17:47:50 -0500578 mCurrentSurface = nullptr;
579 }
Jamie Madill4928b7c2017-06-20 12:57:39 -0400580
581 return egl::NoError();
Jamie Madill77a72f62015-04-14 11:18:32 -0400582}
583
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000584GLuint Context::createBuffer()
585{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500586 return mState.mBuffers->createBuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000587}
588
589GLuint Context::createProgram()
590{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500591 return mState.mShaderPrograms->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000592}
593
594GLuint Context::createShader(GLenum type)
595{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500596 return mState.mShaderPrograms->createShader(mImplementation.get(), mLimitations, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000597}
598
599GLuint Context::createTexture()
600{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500601 return mState.mTextures->createTexture();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000602}
603
604GLuint Context::createRenderbuffer()
605{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500606 return mState.mRenderbuffers->createRenderbuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000607}
608
Geoff Lang882033e2014-09-30 11:26:07 -0400609GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400610{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500611 GLuint handle = mState.mFenceSyncs->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400612
Cooper Partind8e62a32015-01-29 15:21:25 -0800613 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400614}
615
Sami Väisänene45e53b2016-05-25 10:36:04 +0300616GLuint Context::createPaths(GLsizei range)
617{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500618 auto resultOrError = mState.mPaths->createPaths(mImplementation.get(), range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300619 if (resultOrError.isError())
620 {
621 handleError(resultOrError.getError());
622 return 0;
623 }
624 return resultOrError.getResult();
625}
626
Jamie Madill57a89722013-07-02 11:57:03 -0400627GLuint Context::createVertexArray()
628{
Jamie Madill96a483b2017-06-27 16:49:21 -0400629 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
630 mVertexArrayMap.assign(vertexArray, nullptr);
Geoff Lang36167ab2015-12-07 10:27:14 -0500631 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400632}
633
Jamie Madilldc356042013-07-19 16:36:57 -0400634GLuint Context::createSampler()
635{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500636 return mState.mSamplers->createSampler();
Jamie Madilldc356042013-07-19 16:36:57 -0400637}
638
Geoff Langc8058452014-02-03 12:04:11 -0500639GLuint Context::createTransformFeedback()
640{
Yunchao Hea438f4e2017-08-04 13:42:39 +0800641 GLuint transformFeedback = mTransformFeedbackHandleAllocator.allocate();
Jamie Madill96a483b2017-06-27 16:49:21 -0400642 mTransformFeedbackMap.assign(transformFeedback, nullptr);
Geoff Lang36167ab2015-12-07 10:27:14 -0500643 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500644}
645
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000646// Returns an unused framebuffer name
647GLuint Context::createFramebuffer()
648{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500649 return mState.mFramebuffers->createFramebuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000650}
651
Jamie Madill33dc8432013-07-26 11:55:05 -0400652GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000653{
Jamie Madill33dc8432013-07-26 11:55:05 -0400654 GLuint handle = mFenceNVHandleAllocator.allocate();
Jamie Madill96a483b2017-06-27 16:49:21 -0400655 mFenceNVMap.assign(handle, new FenceNV(mImplementation->createFenceNV()));
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000656 return handle;
657}
658
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000659void Context::deleteBuffer(GLuint buffer)
660{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500661 if (mState.mBuffers->getBuffer(buffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000662 {
663 detachBuffer(buffer);
664 }
Jamie Madill893ab082014-05-16 16:56:10 -0400665
Jamie Madill6c1f6712017-02-14 19:08:04 -0500666 mState.mBuffers->deleteObject(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000667}
668
669void Context::deleteShader(GLuint shader)
670{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500671 mState.mShaderPrograms->deleteShader(this, shader);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000672}
673
674void Context::deleteProgram(GLuint program)
675{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500676 mState.mShaderPrograms->deleteProgram(this, program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000677}
678
679void Context::deleteTexture(GLuint texture)
680{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500681 if (mState.mTextures->getTexture(texture))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000682 {
683 detachTexture(texture);
684 }
685
Jamie Madill6c1f6712017-02-14 19:08:04 -0500686 mState.mTextures->deleteObject(this, texture);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000687}
688
689void Context::deleteRenderbuffer(GLuint renderbuffer)
690{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500691 if (mState.mRenderbuffers->getRenderbuffer(renderbuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000692 {
693 detachRenderbuffer(renderbuffer);
694 }
Jamie Madill893ab082014-05-16 16:56:10 -0400695
Jamie Madill6c1f6712017-02-14 19:08:04 -0500696 mState.mRenderbuffers->deleteObject(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000697}
698
Jamie Madillcd055f82013-07-26 11:55:15 -0400699void Context::deleteFenceSync(GLsync fenceSync)
700{
701 // The spec specifies the underlying Fence object is not deleted until all current
702 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
703 // and since our API is currently designed for being called from a single thread, we can delete
704 // the fence immediately.
Jamie Madill6c1f6712017-02-14 19:08:04 -0500705 mState.mFenceSyncs->deleteObject(this,
706 static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400707}
708
Sami Väisänene45e53b2016-05-25 10:36:04 +0300709void Context::deletePaths(GLuint first, GLsizei range)
710{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500711 mState.mPaths->deletePaths(first, range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300712}
713
714bool Context::hasPathData(GLuint path) const
715{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500716 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300717 if (pathObj == nullptr)
718 return false;
719
720 return pathObj->hasPathData();
721}
722
723bool Context::hasPath(GLuint path) const
724{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500725 return mState.mPaths->hasPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300726}
727
728void Context::setPathCommands(GLuint path,
729 GLsizei numCommands,
730 const GLubyte *commands,
731 GLsizei numCoords,
732 GLenum coordType,
733 const void *coords)
734{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500735 auto *pathObject = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300736
737 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
738}
739
740void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
741{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500742 auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300743
744 switch (pname)
745 {
746 case GL_PATH_STROKE_WIDTH_CHROMIUM:
747 pathObj->setStrokeWidth(value);
748 break;
749 case GL_PATH_END_CAPS_CHROMIUM:
750 pathObj->setEndCaps(static_cast<GLenum>(value));
751 break;
752 case GL_PATH_JOIN_STYLE_CHROMIUM:
753 pathObj->setJoinStyle(static_cast<GLenum>(value));
754 break;
755 case GL_PATH_MITER_LIMIT_CHROMIUM:
756 pathObj->setMiterLimit(value);
757 break;
758 case GL_PATH_STROKE_BOUND_CHROMIUM:
759 pathObj->setStrokeBound(value);
760 break;
761 default:
762 UNREACHABLE();
763 break;
764 }
765}
766
767void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
768{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500769 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300770
771 switch (pname)
772 {
773 case GL_PATH_STROKE_WIDTH_CHROMIUM:
774 *value = pathObj->getStrokeWidth();
775 break;
776 case GL_PATH_END_CAPS_CHROMIUM:
777 *value = static_cast<GLfloat>(pathObj->getEndCaps());
778 break;
779 case GL_PATH_JOIN_STYLE_CHROMIUM:
780 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
781 break;
782 case GL_PATH_MITER_LIMIT_CHROMIUM:
783 *value = pathObj->getMiterLimit();
784 break;
785 case GL_PATH_STROKE_BOUND_CHROMIUM:
786 *value = pathObj->getStrokeBound();
787 break;
788 default:
789 UNREACHABLE();
790 break;
791 }
792}
793
794void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
795{
796 mGLState.setPathStencilFunc(func, ref, mask);
797}
798
Jamie Madill57a89722013-07-02 11:57:03 -0400799void Context::deleteVertexArray(GLuint vertexArray)
800{
Jamie Madill96a483b2017-06-27 16:49:21 -0400801 VertexArray *vertexArrayObject = nullptr;
802 if (mVertexArrayMap.erase(vertexArray, &vertexArrayObject))
Geoff Lang50b3fe82015-12-08 14:49:12 +0000803 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500804 if (vertexArrayObject != nullptr)
805 {
806 detachVertexArray(vertexArray);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400807 vertexArrayObject->onDestroy(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500808 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000809
Geoff Lang36167ab2015-12-07 10:27:14 -0500810 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400811 }
812}
813
Jamie Madilldc356042013-07-19 16:36:57 -0400814void Context::deleteSampler(GLuint sampler)
815{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500816 if (mState.mSamplers->getSampler(sampler))
Jamie Madilldc356042013-07-19 16:36:57 -0400817 {
818 detachSampler(sampler);
819 }
820
Jamie Madill6c1f6712017-02-14 19:08:04 -0500821 mState.mSamplers->deleteObject(this, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400822}
823
Geoff Langc8058452014-02-03 12:04:11 -0500824void Context::deleteTransformFeedback(GLuint transformFeedback)
825{
Geoff Lang6e60d6b2017-04-12 12:59:04 -0400826 if (transformFeedback == 0)
827 {
828 return;
829 }
830
Jamie Madill96a483b2017-06-27 16:49:21 -0400831 TransformFeedback *transformFeedbackObject = nullptr;
832 if (mTransformFeedbackMap.erase(transformFeedback, &transformFeedbackObject))
Geoff Langc8058452014-02-03 12:04:11 -0500833 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500834 if (transformFeedbackObject != nullptr)
835 {
836 detachTransformFeedback(transformFeedback);
Jamie Madill6c1f6712017-02-14 19:08:04 -0500837 transformFeedbackObject->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500838 }
839
Yunchao Hea438f4e2017-08-04 13:42:39 +0800840 mTransformFeedbackHandleAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500841 }
842}
843
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000844void Context::deleteFramebuffer(GLuint framebuffer)
845{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500846 if (mState.mFramebuffers->getFramebuffer(framebuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000847 {
848 detachFramebuffer(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000849 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500850
Jamie Madill6c1f6712017-02-14 19:08:04 -0500851 mState.mFramebuffers->deleteObject(this, framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000852}
853
Jamie Madill33dc8432013-07-26 11:55:05 -0400854void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000855{
Jamie Madill96a483b2017-06-27 16:49:21 -0400856 FenceNV *fenceObject = nullptr;
857 if (mFenceNVMap.erase(fence, &fenceObject))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000858 {
Jamie Madill96a483b2017-06-27 16:49:21 -0400859 mFenceNVHandleAllocator.release(fence);
860 delete fenceObject;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000861 }
862}
863
Geoff Lang70d0f492015-12-10 17:45:46 -0500864Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000865{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500866 return mState.mBuffers->getBuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000867}
868
Jamie Madill570f7c82014-07-03 10:38:54 -0400869Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000870{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500871 return mState.mTextures->getTexture(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000872}
873
Geoff Lang70d0f492015-12-10 17:45:46 -0500874Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000875{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500876 return mState.mRenderbuffers->getRenderbuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000877}
878
Jamie Madillcd055f82013-07-26 11:55:15 -0400879FenceSync *Context::getFenceSync(GLsync handle) const
880{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500881 return mState.mFenceSyncs->getFenceSync(
882 static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400883}
884
Jamie Madill57a89722013-07-02 11:57:03 -0400885VertexArray *Context::getVertexArray(GLuint handle) const
886{
Jamie Madill96a483b2017-06-27 16:49:21 -0400887 return mVertexArrayMap.query(handle);
Jamie Madill57a89722013-07-02 11:57:03 -0400888}
889
Jamie Madilldc356042013-07-19 16:36:57 -0400890Sampler *Context::getSampler(GLuint handle) const
891{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500892 return mState.mSamplers->getSampler(handle);
Jamie Madilldc356042013-07-19 16:36:57 -0400893}
894
Geoff Langc8058452014-02-03 12:04:11 -0500895TransformFeedback *Context::getTransformFeedback(GLuint handle) const
896{
Jamie Madill96a483b2017-06-27 16:49:21 -0400897 return mTransformFeedbackMap.query(handle);
Geoff Langc8058452014-02-03 12:04:11 -0500898}
899
Geoff Lang70d0f492015-12-10 17:45:46 -0500900LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
901{
902 switch (identifier)
903 {
904 case GL_BUFFER:
905 return getBuffer(name);
906 case GL_SHADER:
907 return getShader(name);
908 case GL_PROGRAM:
909 return getProgram(name);
910 case GL_VERTEX_ARRAY:
911 return getVertexArray(name);
912 case GL_QUERY:
913 return getQuery(name);
914 case GL_TRANSFORM_FEEDBACK:
915 return getTransformFeedback(name);
916 case GL_SAMPLER:
917 return getSampler(name);
918 case GL_TEXTURE:
919 return getTexture(name);
920 case GL_RENDERBUFFER:
921 return getRenderbuffer(name);
922 case GL_FRAMEBUFFER:
923 return getFramebuffer(name);
924 default:
925 UNREACHABLE();
926 return nullptr;
927 }
928}
929
930LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
931{
932 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
933}
934
Martin Radev9d901792016-07-15 15:58:58 +0300935void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
936{
937 LabeledObject *object = getLabeledObject(identifier, name);
938 ASSERT(object != nullptr);
939
940 std::string labelName = GetObjectLabelFromPointer(length, label);
941 object->setLabel(labelName);
942}
943
944void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
945{
946 LabeledObject *object = getLabeledObjectFromPtr(ptr);
947 ASSERT(object != nullptr);
948
949 std::string labelName = GetObjectLabelFromPointer(length, label);
950 object->setLabel(labelName);
951}
952
953void Context::getObjectLabel(GLenum identifier,
954 GLuint name,
955 GLsizei bufSize,
956 GLsizei *length,
957 GLchar *label) const
958{
959 LabeledObject *object = getLabeledObject(identifier, name);
960 ASSERT(object != nullptr);
961
962 const std::string &objectLabel = object->getLabel();
963 GetObjectLabelBase(objectLabel, bufSize, length, label);
964}
965
966void Context::getObjectPtrLabel(const void *ptr,
967 GLsizei bufSize,
968 GLsizei *length,
969 GLchar *label) const
970{
971 LabeledObject *object = getLabeledObjectFromPtr(ptr);
972 ASSERT(object != nullptr);
973
974 const std::string &objectLabel = object->getLabel();
975 GetObjectLabelBase(objectLabel, bufSize, length, label);
976}
977
Jamie Madilldc356042013-07-19 16:36:57 -0400978bool Context::isSampler(GLuint samplerName) const
979{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500980 return mState.mSamplers->isSampler(samplerName);
Jamie Madilldc356042013-07-19 16:36:57 -0400981}
982
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500983void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000984{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500985 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400986 mGLState.setArrayBufferBinding(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000987}
988
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800989void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
990{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500991 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400992 mGLState.setDrawIndirectBufferBinding(this, buffer);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800993}
994
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500995void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000996{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500997 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400998 mGLState.setElementArrayBuffer(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000999}
1000
Jamie Madilldedd7b92014-11-05 16:30:36 -05001001void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001002{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001003 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001004
Jamie Madilldedd7b92014-11-05 16:30:36 -05001005 if (handle == 0)
1006 {
1007 texture = mZeroTextures[target].get();
1008 }
1009 else
1010 {
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001011 texture = mState.mTextures->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -05001012 }
1013
1014 ASSERT(texture);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001015 mGLState.setSamplerTexture(this, target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +00001016}
1017
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001018void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001019{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001020 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
1021 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001022 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001023}
1024
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001025void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001026{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001027 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
1028 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001029 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001030}
1031
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001032void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -04001033{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001034 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001035 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -04001036}
1037
Shao80957d92017-02-20 21:25:59 +08001038void Context::bindVertexBuffer(GLuint bindingIndex,
1039 GLuint bufferHandle,
1040 GLintptr offset,
1041 GLsizei stride)
1042{
1043 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001044 mGLState.bindVertexBuffer(this, bindingIndex, buffer, offset, stride);
Shao80957d92017-02-20 21:25:59 +08001045}
1046
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001047void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -04001048{
Geoff Lang76b10c92014-09-05 16:28:14 -04001049 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -04001050 Sampler *sampler =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001051 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001052 mGLState.setSamplerBinding(this, textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001053}
1054
Xinghua Cao65ec0b22017-03-28 16:10:52 +08001055void Context::bindImageTexture(GLuint unit,
1056 GLuint texture,
1057 GLint level,
1058 GLboolean layered,
1059 GLint layer,
1060 GLenum access,
1061 GLenum format)
1062{
1063 Texture *tex = mState.mTextures->getTexture(texture);
1064 mGLState.setImageUnit(this, unit, tex, level, layered, layer, access, format);
1065}
1066
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001067void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001068{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001069 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001070 mGLState.setGenericUniformBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001071}
1072
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001073void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1074 GLuint index,
1075 GLintptr offset,
1076 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001077{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001078 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001079 mGLState.setIndexedUniformBufferBinding(this, index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001080}
1081
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001082void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001083{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001084 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001085 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001086}
1087
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001088void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1089 GLuint index,
1090 GLintptr offset,
1091 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001092{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001093 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001094 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(this, index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001095}
1096
Jiajia Qin6eafb042016-12-27 17:04:07 +08001097void Context::bindGenericAtomicCounterBuffer(GLuint bufferHandle)
1098{
1099 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001100 mGLState.setGenericAtomicCounterBufferBinding(this, buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08001101}
1102
1103void Context::bindIndexedAtomicCounterBuffer(GLuint bufferHandle,
1104 GLuint index,
1105 GLintptr offset,
1106 GLsizeiptr size)
1107{
1108 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001109 mGLState.setIndexedAtomicCounterBufferBinding(this, index, buffer, offset, size);
Jiajia Qin6eafb042016-12-27 17:04:07 +08001110}
1111
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001112void Context::bindGenericShaderStorageBuffer(GLuint bufferHandle)
1113{
1114 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001115 mGLState.setGenericShaderStorageBufferBinding(this, buffer);
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001116}
1117
1118void Context::bindIndexedShaderStorageBuffer(GLuint bufferHandle,
1119 GLuint index,
1120 GLintptr offset,
1121 GLsizeiptr size)
1122{
1123 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001124 mGLState.setIndexedShaderStorageBufferBinding(this, index, buffer, offset, size);
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001125}
1126
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001127void Context::bindCopyReadBuffer(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 Madill4928b7c2017-06-20 12:57:39 -04001130 mGLState.setCopyReadBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001131}
1132
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001133void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001134{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001135 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001136 mGLState.setCopyWriteBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001137}
1138
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001139void Context::bindPixelPackBuffer(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 Madill4928b7c2017-06-20 12:57:39 -04001142 mGLState.setPixelPackBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001143}
1144
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001145void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001146{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001147 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001148 mGLState.setPixelUnpackBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001149}
1150
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001151void Context::useProgram(GLuint program)
1152{
Jamie Madill6c1f6712017-02-14 19:08:04 -05001153 mGLState.setProgram(this, getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001154}
1155
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001156void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001157{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001158 TransformFeedback *transformFeedback =
1159 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001160 mGLState.setTransformFeedbackBinding(this, transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001161}
1162
Jamie Madillf0e04492017-08-26 15:28:42 -04001163void Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001164{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001165 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001166 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001167
Geoff Lang5aad9672014-09-08 11:10:42 -04001168 // begin query
Jamie Madillf0e04492017-08-26 15:28:42 -04001169 ANGLE_CONTEXT_TRY(queryObject->begin());
Geoff Lang5aad9672014-09-08 11:10:42 -04001170
1171 // set query as active for specified target only if begin succeeded
Jamie Madill4928b7c2017-06-20 12:57:39 -04001172 mGLState.setActiveQuery(this, target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001173}
1174
Jamie Madillf0e04492017-08-26 15:28:42 -04001175void 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
Jamie Madillf0e04492017-08-26 15:28:42 -04001180 handleError(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.
Jamie Madill4928b7c2017-06-20 12:57:39 -04001183 mGLState.setActiveQuery(this, target, nullptr);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001184}
1185
Jamie Madillf0e04492017-08-26 15:28:42 -04001186void Context::queryCounter(GLuint id, GLenum target)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001187{
1188 ASSERT(target == GL_TIMESTAMP_EXT);
1189
1190 Query *queryObject = getQuery(id, true, target);
1191 ASSERT(queryObject);
1192
Jamie Madillf0e04492017-08-26 15:28:42 -04001193 handleError(queryObject->queryCounter());
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001194}
1195
1196void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1197{
1198 switch (pname)
1199 {
1200 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001201 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001202 break;
1203 case GL_QUERY_COUNTER_BITS_EXT:
1204 switch (target)
1205 {
1206 case GL_TIME_ELAPSED_EXT:
1207 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1208 break;
1209 case GL_TIMESTAMP_EXT:
1210 params[0] = getExtensions().queryCounterBitsTimestamp;
1211 break;
1212 default:
1213 UNREACHABLE();
1214 params[0] = 0;
1215 break;
1216 }
1217 break;
1218 default:
1219 UNREACHABLE();
1220 return;
1221 }
1222}
1223
Geoff Lang2186c382016-10-14 10:54:54 -04001224void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001225{
Geoff Lang2186c382016-10-14 10:54:54 -04001226 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001227}
1228
Geoff Lang2186c382016-10-14 10:54:54 -04001229void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001230{
Geoff Lang2186c382016-10-14 10:54:54 -04001231 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001232}
1233
Geoff Lang2186c382016-10-14 10:54:54 -04001234void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001235{
Geoff Lang2186c382016-10-14 10:54:54 -04001236 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001237}
1238
Geoff Lang2186c382016-10-14 10:54:54 -04001239void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001240{
Geoff Lang2186c382016-10-14 10:54:54 -04001241 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001242}
1243
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001244Framebuffer *Context::getFramebuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001245{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001246 return mState.mFramebuffers->getFramebuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001247}
1248
Jamie Madill2f348d22017-06-05 10:50:59 -04001249FenceNV *Context::getFenceNV(GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001250{
Jamie Madill96a483b2017-06-27 16:49:21 -04001251 return mFenceNVMap.query(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001252}
1253
Jamie Madill2f348d22017-06-05 10:50:59 -04001254Query *Context::getQuery(GLuint handle, bool create, GLenum type)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001255{
Jamie Madill96a483b2017-06-27 16:49:21 -04001256 if (!mQueryMap.contains(handle))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001257 {
Yunchao Hef81ce4a2017-04-24 10:49:17 +08001258 return nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001259 }
Jamie Madill96a483b2017-06-27 16:49:21 -04001260
1261 Query *query = mQueryMap.query(handle);
1262 if (!query && create)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001263 {
Jamie Madill96a483b2017-06-27 16:49:21 -04001264 query = new Query(mImplementation->createQuery(type), handle);
1265 query->addRef();
1266 mQueryMap.assign(handle, query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001267 }
Jamie Madill96a483b2017-06-27 16:49:21 -04001268 return query;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001269}
1270
Geoff Lang70d0f492015-12-10 17:45:46 -05001271Query *Context::getQuery(GLuint handle) const
1272{
Jamie Madill96a483b2017-06-27 16:49:21 -04001273 return mQueryMap.query(handle);
Geoff Lang70d0f492015-12-10 17:45:46 -05001274}
1275
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001276Texture *Context::getTargetTexture(GLenum target) const
1277{
Ian Ewellbda75592016-04-18 17:25:54 -04001278 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001279 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001280}
1281
Geoff Lang76b10c92014-09-05 16:28:14 -04001282Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001283{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001284 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001285}
1286
Geoff Lang492a7e42014-11-05 13:27:06 -05001287Compiler *Context::getCompiler() const
1288{
Jamie Madill2f348d22017-06-05 10:50:59 -04001289 if (mCompiler.get() == nullptr)
1290 {
Jamie Madill4928b7c2017-06-20 12:57:39 -04001291 mCompiler.set(this, new Compiler(mImplementation.get(), mState));
Jamie Madill2f348d22017-06-05 10:50:59 -04001292 }
1293 return mCompiler.get();
Geoff Lang492a7e42014-11-05 13:27:06 -05001294}
1295
Jamie Madillc1d770e2017-04-13 17:31:24 -04001296void Context::getBooleanvImpl(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001297{
1298 switch (pname)
1299 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001300 case GL_SHADER_COMPILER:
1301 *params = GL_TRUE;
1302 break;
1303 case GL_CONTEXT_ROBUST_ACCESS_EXT:
1304 *params = mRobustAccess ? GL_TRUE : GL_FALSE;
1305 break;
1306 default:
1307 mGLState.getBooleanv(pname, params);
1308 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001309 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001310}
1311
Jamie Madillc1d770e2017-04-13 17:31:24 -04001312void Context::getFloatvImpl(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001313{
Shannon Woods53a94a82014-06-24 15:20:36 -04001314 // Queries about context capabilities and maximums are answered by Context.
1315 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001316 switch (pname)
1317 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001318 case GL_ALIASED_LINE_WIDTH_RANGE:
1319 params[0] = mCaps.minAliasedLineWidth;
1320 params[1] = mCaps.maxAliasedLineWidth;
1321 break;
1322 case GL_ALIASED_POINT_SIZE_RANGE:
1323 params[0] = mCaps.minAliasedPointSize;
1324 params[1] = mCaps.maxAliasedPointSize;
1325 break;
1326 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1327 ASSERT(mExtensions.textureFilterAnisotropic);
1328 *params = mExtensions.maxTextureAnisotropy;
1329 break;
1330 case GL_MAX_TEXTURE_LOD_BIAS:
1331 *params = mCaps.maxLODBias;
1332 break;
1333
1334 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1335 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1336 {
1337 ASSERT(mExtensions.pathRendering);
1338 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1339 memcpy(params, m, 16 * sizeof(GLfloat));
1340 }
Geoff Lange6d4e122015-06-29 13:33:55 -04001341 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001342
Jamie Madill231c7f52017-04-26 13:45:37 -04001343 default:
1344 mGLState.getFloatv(pname, params);
1345 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001346 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001347}
1348
Jamie Madillc1d770e2017-04-13 17:31:24 -04001349void Context::getIntegervImpl(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001350{
Shannon Woods53a94a82014-06-24 15:20:36 -04001351 // Queries about context capabilities and maximums are answered by Context.
1352 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001353
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001354 switch (pname)
1355 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001356 case GL_MAX_VERTEX_ATTRIBS:
1357 *params = mCaps.maxVertexAttributes;
1358 break;
1359 case GL_MAX_VERTEX_UNIFORM_VECTORS:
1360 *params = mCaps.maxVertexUniformVectors;
1361 break;
1362 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
1363 *params = mCaps.maxVertexUniformComponents;
1364 break;
1365 case GL_MAX_VARYING_VECTORS:
1366 *params = mCaps.maxVaryingVectors;
1367 break;
1368 case GL_MAX_VARYING_COMPONENTS:
1369 *params = mCaps.maxVertexOutputComponents;
1370 break;
1371 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1372 *params = mCaps.maxCombinedTextureImageUnits;
1373 break;
1374 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1375 *params = mCaps.maxVertexTextureImageUnits;
1376 break;
1377 case GL_MAX_TEXTURE_IMAGE_UNITS:
1378 *params = mCaps.maxTextureImageUnits;
1379 break;
1380 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1381 *params = mCaps.maxFragmentUniformVectors;
1382 break;
1383 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
1384 *params = mCaps.maxFragmentUniformComponents;
1385 break;
1386 case GL_MAX_RENDERBUFFER_SIZE:
1387 *params = mCaps.maxRenderbufferSize;
1388 break;
1389 case GL_MAX_COLOR_ATTACHMENTS_EXT:
1390 *params = mCaps.maxColorAttachments;
1391 break;
1392 case GL_MAX_DRAW_BUFFERS_EXT:
1393 *params = mCaps.maxDrawBuffers;
1394 break;
1395 // case GL_FRAMEBUFFER_BINDING: // now equivalent to
1396 // GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1397 case GL_SUBPIXEL_BITS:
1398 *params = 4;
1399 break;
1400 case GL_MAX_TEXTURE_SIZE:
1401 *params = mCaps.max2DTextureSize;
1402 break;
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001403 case GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE:
1404 *params = mCaps.maxRectangleTextureSize;
1405 break;
Jamie Madill231c7f52017-04-26 13:45:37 -04001406 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1407 *params = mCaps.maxCubeMapTextureSize;
1408 break;
1409 case GL_MAX_3D_TEXTURE_SIZE:
1410 *params = mCaps.max3DTextureSize;
1411 break;
1412 case GL_MAX_ARRAY_TEXTURE_LAYERS:
1413 *params = mCaps.maxArrayTextureLayers;
1414 break;
1415 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
1416 *params = mCaps.uniformBufferOffsetAlignment;
1417 break;
1418 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
1419 *params = mCaps.maxUniformBufferBindings;
1420 break;
1421 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
1422 *params = mCaps.maxVertexUniformBlocks;
1423 break;
1424 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
1425 *params = mCaps.maxFragmentUniformBlocks;
1426 break;
1427 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
1428 *params = mCaps.maxCombinedTextureImageUnits;
1429 break;
1430 case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
1431 *params = mCaps.maxVertexOutputComponents;
1432 break;
1433 case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
1434 *params = mCaps.maxFragmentInputComponents;
1435 break;
1436 case GL_MIN_PROGRAM_TEXEL_OFFSET:
1437 *params = mCaps.minProgramTexelOffset;
1438 break;
1439 case GL_MAX_PROGRAM_TEXEL_OFFSET:
1440 *params = mCaps.maxProgramTexelOffset;
1441 break;
1442 case GL_MAJOR_VERSION:
1443 *params = getClientVersion().major;
1444 break;
1445 case GL_MINOR_VERSION:
1446 *params = getClientVersion().minor;
1447 break;
1448 case GL_MAX_ELEMENTS_INDICES:
1449 *params = mCaps.maxElementsIndices;
1450 break;
1451 case GL_MAX_ELEMENTS_VERTICES:
1452 *params = mCaps.maxElementsVertices;
1453 break;
1454 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
1455 *params = mCaps.maxTransformFeedbackInterleavedComponents;
1456 break;
1457 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
1458 *params = mCaps.maxTransformFeedbackSeparateAttributes;
1459 break;
1460 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
1461 *params = mCaps.maxTransformFeedbackSeparateComponents;
1462 break;
1463 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1464 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1465 break;
1466 case GL_MAX_SAMPLES_ANGLE:
1467 *params = mCaps.maxSamples;
1468 break;
1469 case GL_MAX_VIEWPORT_DIMS:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001470 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001471 params[0] = mCaps.maxViewportWidth;
1472 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001473 }
1474 break;
Jamie Madill231c7f52017-04-26 13:45:37 -04001475 case GL_COMPRESSED_TEXTURE_FORMATS:
1476 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(),
1477 params);
1478 break;
1479 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1480 *params = mResetStrategy;
1481 break;
1482 case GL_NUM_SHADER_BINARY_FORMATS:
1483 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
1484 break;
1485 case GL_SHADER_BINARY_FORMATS:
1486 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1487 break;
1488 case GL_NUM_PROGRAM_BINARY_FORMATS:
1489 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
1490 break;
1491 case GL_PROGRAM_BINARY_FORMATS:
1492 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
1493 break;
1494 case GL_NUM_EXTENSIONS:
1495 *params = static_cast<GLint>(mExtensionStrings.size());
1496 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001497
Jamie Madill231c7f52017-04-26 13:45:37 -04001498 // GL_KHR_debug
1499 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1500 *params = mExtensions.maxDebugMessageLength;
1501 break;
1502 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1503 *params = mExtensions.maxDebugLoggedMessages;
1504 break;
1505 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1506 *params = mExtensions.maxDebugGroupStackDepth;
1507 break;
1508 case GL_MAX_LABEL_LENGTH:
1509 *params = mExtensions.maxLabelLength;
1510 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001511
Martin Radeve5285d22017-07-14 16:23:53 +03001512 // GL_ANGLE_multiview
1513 case GL_MAX_VIEWS_ANGLE:
1514 *params = mExtensions.maxViews;
1515 break;
1516
Jamie Madill231c7f52017-04-26 13:45:37 -04001517 // GL_EXT_disjoint_timer_query
1518 case GL_GPU_DISJOINT_EXT:
1519 *params = mImplementation->getGPUDisjoint();
1520 break;
1521 case GL_MAX_FRAMEBUFFER_WIDTH:
1522 *params = mCaps.maxFramebufferWidth;
1523 break;
1524 case GL_MAX_FRAMEBUFFER_HEIGHT:
1525 *params = mCaps.maxFramebufferHeight;
1526 break;
1527 case GL_MAX_FRAMEBUFFER_SAMPLES:
1528 *params = mCaps.maxFramebufferSamples;
1529 break;
1530 case GL_MAX_SAMPLE_MASK_WORDS:
1531 *params = mCaps.maxSampleMaskWords;
1532 break;
1533 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1534 *params = mCaps.maxColorTextureSamples;
1535 break;
1536 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1537 *params = mCaps.maxDepthTextureSamples;
1538 break;
1539 case GL_MAX_INTEGER_SAMPLES:
1540 *params = mCaps.maxIntegerSamples;
1541 break;
1542 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1543 *params = mCaps.maxVertexAttribRelativeOffset;
1544 break;
1545 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1546 *params = mCaps.maxVertexAttribBindings;
1547 break;
1548 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1549 *params = mCaps.maxVertexAttribStride;
1550 break;
1551 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1552 *params = mCaps.maxVertexAtomicCounterBuffers;
1553 break;
1554 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1555 *params = mCaps.maxVertexAtomicCounters;
1556 break;
1557 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1558 *params = mCaps.maxVertexImageUniforms;
1559 break;
1560 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1561 *params = mCaps.maxVertexShaderStorageBlocks;
1562 break;
1563 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1564 *params = mCaps.maxFragmentAtomicCounterBuffers;
1565 break;
1566 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1567 *params = mCaps.maxFragmentAtomicCounters;
1568 break;
1569 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1570 *params = mCaps.maxFragmentImageUniforms;
1571 break;
1572 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1573 *params = mCaps.maxFragmentShaderStorageBlocks;
1574 break;
1575 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1576 *params = mCaps.minProgramTextureGatherOffset;
1577 break;
1578 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1579 *params = mCaps.maxProgramTextureGatherOffset;
1580 break;
1581 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1582 *params = mCaps.maxComputeWorkGroupInvocations;
1583 break;
1584 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1585 *params = mCaps.maxComputeUniformBlocks;
1586 break;
1587 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1588 *params = mCaps.maxComputeTextureImageUnits;
1589 break;
1590 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1591 *params = mCaps.maxComputeSharedMemorySize;
1592 break;
1593 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1594 *params = mCaps.maxComputeUniformComponents;
1595 break;
1596 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1597 *params = mCaps.maxComputeAtomicCounterBuffers;
1598 break;
1599 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1600 *params = mCaps.maxComputeAtomicCounters;
1601 break;
1602 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1603 *params = mCaps.maxComputeImageUniforms;
1604 break;
1605 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1606 *params = mCaps.maxCombinedComputeUniformComponents;
1607 break;
1608 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1609 *params = mCaps.maxComputeShaderStorageBlocks;
1610 break;
1611 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1612 *params = mCaps.maxCombinedShaderOutputResources;
1613 break;
1614 case GL_MAX_UNIFORM_LOCATIONS:
1615 *params = mCaps.maxUniformLocations;
1616 break;
1617 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1618 *params = mCaps.maxAtomicCounterBufferBindings;
1619 break;
1620 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1621 *params = mCaps.maxAtomicCounterBufferSize;
1622 break;
1623 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1624 *params = mCaps.maxCombinedAtomicCounterBuffers;
1625 break;
1626 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1627 *params = mCaps.maxCombinedAtomicCounters;
1628 break;
1629 case GL_MAX_IMAGE_UNITS:
1630 *params = mCaps.maxImageUnits;
1631 break;
1632 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1633 *params = mCaps.maxCombinedImageUniforms;
1634 break;
1635 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1636 *params = mCaps.maxShaderStorageBufferBindings;
1637 break;
1638 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1639 *params = mCaps.maxCombinedShaderStorageBlocks;
1640 break;
1641 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1642 *params = mCaps.shaderStorageBufferOffsetAlignment;
1643 break;
1644 default:
1645 mGLState.getIntegerv(this, pname, params);
1646 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001647 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001648}
1649
Jamie Madill893ab082014-05-16 16:56:10 -04001650void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001651{
Shannon Woods53a94a82014-06-24 15:20:36 -04001652 // Queries about context capabilities and maximums are answered by Context.
1653 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001654 switch (pname)
1655 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001656 case GL_MAX_ELEMENT_INDEX:
1657 *params = mCaps.maxElementIndex;
1658 break;
1659 case GL_MAX_UNIFORM_BLOCK_SIZE:
1660 *params = mCaps.maxUniformBlockSize;
1661 break;
1662 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
1663 *params = mCaps.maxCombinedVertexUniformComponents;
1664 break;
1665 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
1666 *params = mCaps.maxCombinedFragmentUniformComponents;
1667 break;
1668 case GL_MAX_SERVER_WAIT_TIMEOUT:
1669 *params = mCaps.maxServerWaitTimeout;
1670 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001671
Jamie Madill231c7f52017-04-26 13:45:37 -04001672 // GL_EXT_disjoint_timer_query
1673 case GL_TIMESTAMP_EXT:
1674 *params = mImplementation->getTimestamp();
1675 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001676
Jamie Madill231c7f52017-04-26 13:45:37 -04001677 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1678 *params = mCaps.maxShaderStorageBlockSize;
1679 break;
1680 default:
1681 UNREACHABLE();
1682 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001683 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001684}
1685
Geoff Lang70d0f492015-12-10 17:45:46 -05001686void Context::getPointerv(GLenum pname, void **params) const
1687{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001688 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001689}
1690
Martin Radev66fb8202016-07-28 11:45:20 +03001691void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001692{
Shannon Woods53a94a82014-06-24 15:20:36 -04001693 // Queries about context capabilities and maximums are answered by Context.
1694 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001695
1696 GLenum nativeType;
1697 unsigned int numParams;
1698 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1699 ASSERT(queryStatus);
1700
1701 if (nativeType == GL_INT)
1702 {
1703 switch (target)
1704 {
1705 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1706 ASSERT(index < 3u);
1707 *data = mCaps.maxComputeWorkGroupCount[index];
1708 break;
1709 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1710 ASSERT(index < 3u);
1711 *data = mCaps.maxComputeWorkGroupSize[index];
1712 break;
1713 default:
1714 mGLState.getIntegeri_v(target, index, data);
1715 }
1716 }
1717 else
1718 {
1719 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1720 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001721}
1722
Martin Radev66fb8202016-07-28 11:45:20 +03001723void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001724{
Shannon Woods53a94a82014-06-24 15:20:36 -04001725 // Queries about context capabilities and maximums are answered by Context.
1726 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001727
1728 GLenum nativeType;
1729 unsigned int numParams;
1730 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1731 ASSERT(queryStatus);
1732
1733 if (nativeType == GL_INT_64_ANGLEX)
1734 {
1735 mGLState.getInteger64i_v(target, index, data);
1736 }
1737 else
1738 {
1739 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1740 }
1741}
1742
1743void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1744{
1745 // Queries about context capabilities and maximums are answered by Context.
1746 // Queries about current GL state values are answered by State.
1747
1748 GLenum nativeType;
1749 unsigned int numParams;
1750 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1751 ASSERT(queryStatus);
1752
1753 if (nativeType == GL_BOOL)
1754 {
1755 mGLState.getBooleani_v(target, index, data);
1756 }
1757 else
1758 {
1759 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1760 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001761}
1762
He Yunchao010e4db2017-03-03 14:22:06 +08001763void Context::getBufferParameteriv(GLenum target, GLenum pname, GLint *params)
1764{
1765 Buffer *buffer = mGLState.getTargetBuffer(target);
1766 QueryBufferParameteriv(buffer, pname, params);
1767}
1768
1769void Context::getFramebufferAttachmentParameteriv(GLenum target,
1770 GLenum attachment,
1771 GLenum pname,
1772 GLint *params)
1773{
1774 const Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
1775 QueryFramebufferAttachmentParameteriv(framebuffer, attachment, pname, params);
1776}
1777
1778void Context::getRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
1779{
1780 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
1781 QueryRenderbufferiv(this, renderbuffer, pname, params);
1782}
1783
1784void Context::getTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
1785{
1786 Texture *texture = getTargetTexture(target);
1787 QueryTexParameterfv(texture, pname, params);
1788}
1789
1790void Context::getTexParameteriv(GLenum target, GLenum pname, GLint *params)
1791{
1792 Texture *texture = getTargetTexture(target);
1793 QueryTexParameteriv(texture, pname, params);
1794}
1795void Context::texParameterf(GLenum target, GLenum pname, GLfloat param)
1796{
1797 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001798 SetTexParameterf(this, texture, pname, param);
He Yunchao010e4db2017-03-03 14:22:06 +08001799}
1800
1801void Context::texParameterfv(GLenum target, GLenum pname, const GLfloat *params)
1802{
1803 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001804 SetTexParameterfv(this, texture, pname, params);
He Yunchao010e4db2017-03-03 14:22:06 +08001805}
1806
1807void Context::texParameteri(GLenum target, GLenum pname, GLint param)
1808{
1809 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001810 SetTexParameteri(this, texture, pname, param);
He Yunchao010e4db2017-03-03 14:22:06 +08001811}
1812
1813void Context::texParameteriv(GLenum target, GLenum pname, const GLint *params)
1814{
1815 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001816 SetTexParameteriv(this, texture, pname, params);
He Yunchao010e4db2017-03-03 14:22:06 +08001817}
1818
Jamie Madill675fe712016-12-19 13:07:54 -05001819void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001820{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001821 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001822 ANGLE_CONTEXT_TRY(mImplementation->drawArrays(this, mode, first, count));
1823 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001824}
1825
Jamie Madill675fe712016-12-19 13:07:54 -05001826void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Geoff Langf6db0982015-08-25 13:04:00 -04001827{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001828 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001829 ANGLE_CONTEXT_TRY(
1830 mImplementation->drawArraysInstanced(this, mode, first, count, instanceCount));
1831 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Langf6db0982015-08-25 13:04:00 -04001832}
1833
Jamie Madill876429b2017-04-20 15:46:24 -04001834void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001835{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001836 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001837 ANGLE_CONTEXT_TRY(mImplementation->drawElements(this, mode, count, type, indices));
Geoff Langf6db0982015-08-25 13:04:00 -04001838}
1839
Jamie Madill675fe712016-12-19 13:07:54 -05001840void Context::drawElementsInstanced(GLenum mode,
1841 GLsizei count,
1842 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001843 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001844 GLsizei instances)
Geoff Langf6db0982015-08-25 13:04:00 -04001845{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001846 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001847 ANGLE_CONTEXT_TRY(
Qin Jiajia1da00652017-06-20 17:16:25 +08001848 mImplementation->drawElementsInstanced(this, mode, count, type, indices, instances));
Geoff Langf6db0982015-08-25 13:04:00 -04001849}
1850
Jamie Madill675fe712016-12-19 13:07:54 -05001851void Context::drawRangeElements(GLenum mode,
1852 GLuint start,
1853 GLuint end,
1854 GLsizei count,
1855 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001856 const void *indices)
Geoff Langf6db0982015-08-25 13:04:00 -04001857{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001858 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001859 ANGLE_CONTEXT_TRY(
1860 mImplementation->drawRangeElements(this, mode, start, end, count, type, indices));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001861}
1862
Jamie Madill876429b2017-04-20 15:46:24 -04001863void Context::drawArraysIndirect(GLenum mode, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001864{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001865 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001866 ANGLE_CONTEXT_TRY(mImplementation->drawArraysIndirect(this, mode, indirect));
Jiajia Qind9671222016-11-29 16:30:31 +08001867}
1868
Jamie Madill876429b2017-04-20 15:46:24 -04001869void Context::drawElementsIndirect(GLenum mode, GLenum type, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001870{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001871 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001872 ANGLE_CONTEXT_TRY(mImplementation->drawElementsIndirect(this, mode, type, indirect));
Jiajia Qind9671222016-11-29 16:30:31 +08001873}
1874
Jamie Madill675fe712016-12-19 13:07:54 -05001875void Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001876{
Jamie Madill675fe712016-12-19 13:07:54 -05001877 handleError(mImplementation->flush());
Geoff Lang129753a2015-01-09 16:52:09 -05001878}
1879
Jamie Madill675fe712016-12-19 13:07:54 -05001880void Context::finish()
Geoff Lang129753a2015-01-09 16:52:09 -05001881{
Jamie Madill675fe712016-12-19 13:07:54 -05001882 handleError(mImplementation->finish());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001883}
1884
Austin Kinross6ee1e782015-05-29 17:05:37 -07001885void Context::insertEventMarker(GLsizei length, const char *marker)
1886{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001887 ASSERT(mImplementation);
1888 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001889}
1890
1891void Context::pushGroupMarker(GLsizei length, const char *marker)
1892{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001893 ASSERT(mImplementation);
1894 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001895}
1896
1897void Context::popGroupMarker()
1898{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001899 ASSERT(mImplementation);
1900 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001901}
1902
Geoff Langd8605522016-04-13 10:19:12 -04001903void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1904{
1905 Program *programObject = getProgram(program);
1906 ASSERT(programObject);
1907
1908 programObject->bindUniformLocation(location, name);
1909}
1910
Sami Väisänena797e062016-05-12 15:23:40 +03001911void Context::setCoverageModulation(GLenum components)
1912{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001913 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001914}
1915
Sami Väisänene45e53b2016-05-25 10:36:04 +03001916void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1917{
1918 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1919}
1920
1921void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1922{
1923 GLfloat I[16];
1924 angle::Matrix<GLfloat>::setToIdentity(I);
1925
1926 mGLState.loadPathRenderingMatrix(matrixMode, I);
1927}
1928
1929void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1930{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001931 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001932 if (!pathObj)
1933 return;
1934
1935 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1936 syncRendererState();
1937
1938 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1939}
1940
1941void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1942{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001943 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001944 if (!pathObj)
1945 return;
1946
1947 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1948 syncRendererState();
1949
1950 mImplementation->stencilStrokePath(pathObj, reference, mask);
1951}
1952
1953void Context::coverFillPath(GLuint path, GLenum coverMode)
1954{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001955 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001956 if (!pathObj)
1957 return;
1958
1959 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1960 syncRendererState();
1961
1962 mImplementation->coverFillPath(pathObj, coverMode);
1963}
1964
1965void Context::coverStrokePath(GLuint path, GLenum coverMode)
1966{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001967 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001968 if (!pathObj)
1969 return;
1970
1971 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1972 syncRendererState();
1973
1974 mImplementation->coverStrokePath(pathObj, coverMode);
1975}
1976
1977void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1978{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001979 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001980 if (!pathObj)
1981 return;
1982
1983 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1984 syncRendererState();
1985
1986 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1987}
1988
1989void Context::stencilThenCoverStrokePath(GLuint path,
1990 GLint reference,
1991 GLuint mask,
1992 GLenum coverMode)
1993{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001994 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001995 if (!pathObj)
1996 return;
1997
1998 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1999 syncRendererState();
2000
2001 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
2002}
2003
Sami Väisänend59ca052016-06-21 16:10:00 +03002004void Context::coverFillPathInstanced(GLsizei numPaths,
2005 GLenum pathNameType,
2006 const void *paths,
2007 GLuint pathBase,
2008 GLenum coverMode,
2009 GLenum transformType,
2010 const GLfloat *transformValues)
2011{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002012 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002013
2014 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2015 syncRendererState();
2016
2017 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
2018}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002019
Sami Väisänend59ca052016-06-21 16:10:00 +03002020void Context::coverStrokePathInstanced(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->coverStrokePathInstanced(pathObjects, coverMode, transformType,
2034 transformValues);
2035}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002036
Sami Väisänend59ca052016-06-21 16:10:00 +03002037void Context::stencilFillPathInstanced(GLsizei numPaths,
2038 GLenum pathNameType,
2039 const void *paths,
2040 GLuint pathBase,
2041 GLenum fillMode,
2042 GLuint mask,
2043 GLenum transformType,
2044 const GLfloat *transformValues)
2045{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002046 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002047
2048 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2049 syncRendererState();
2050
2051 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
2052 transformValues);
2053}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002054
Sami Väisänend59ca052016-06-21 16:10:00 +03002055void Context::stencilStrokePathInstanced(GLsizei numPaths,
2056 GLenum pathNameType,
2057 const void *paths,
2058 GLuint pathBase,
2059 GLint reference,
2060 GLuint mask,
2061 GLenum transformType,
2062 const GLfloat *transformValues)
2063{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002064 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002065
2066 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2067 syncRendererState();
2068
2069 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
2070 transformValues);
2071}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002072
Sami Väisänend59ca052016-06-21 16:10:00 +03002073void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
2074 GLenum pathNameType,
2075 const void *paths,
2076 GLuint pathBase,
2077 GLenum fillMode,
2078 GLuint mask,
2079 GLenum coverMode,
2080 GLenum transformType,
2081 const GLfloat *transformValues)
2082{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002083 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002084
2085 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2086 syncRendererState();
2087
2088 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
2089 transformType, transformValues);
2090}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002091
Sami Väisänend59ca052016-06-21 16:10:00 +03002092void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
2093 GLenum pathNameType,
2094 const void *paths,
2095 GLuint pathBase,
2096 GLint reference,
2097 GLuint mask,
2098 GLenum coverMode,
2099 GLenum transformType,
2100 const GLfloat *transformValues)
2101{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002102 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002103
2104 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2105 syncRendererState();
2106
2107 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
2108 transformType, transformValues);
2109}
2110
Sami Väisänen46eaa942016-06-29 10:26:37 +03002111void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
2112{
2113 auto *programObject = getProgram(program);
2114
2115 programObject->bindFragmentInputLocation(location, name);
2116}
2117
2118void Context::programPathFragmentInputGen(GLuint program,
2119 GLint location,
2120 GLenum genMode,
2121 GLint components,
2122 const GLfloat *coeffs)
2123{
2124 auto *programObject = getProgram(program);
2125
Jamie Madillbd044ed2017-06-05 12:59:21 -04002126 programObject->pathFragmentInputGen(this, location, genMode, components, coeffs);
Sami Väisänen46eaa942016-06-29 10:26:37 +03002127}
2128
jchen1015015f72017-03-16 13:54:21 +08002129GLuint Context::getProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name)
2130{
jchen10fd7c3b52017-03-21 15:36:03 +08002131 const auto *programObject = getProgram(program);
jchen1015015f72017-03-16 13:54:21 +08002132 return QueryProgramResourceIndex(programObject, programInterface, name);
2133}
2134
jchen10fd7c3b52017-03-21 15:36:03 +08002135void Context::getProgramResourceName(GLuint program,
2136 GLenum programInterface,
2137 GLuint index,
2138 GLsizei bufSize,
2139 GLsizei *length,
2140 GLchar *name)
2141{
2142 const auto *programObject = getProgram(program);
2143 QueryProgramResourceName(programObject, programInterface, index, bufSize, length, name);
2144}
2145
jchen10191381f2017-04-11 13:59:04 +08002146GLint Context::getProgramResourceLocation(GLuint program,
2147 GLenum programInterface,
2148 const GLchar *name)
2149{
2150 const auto *programObject = getProgram(program);
2151 return QueryProgramResourceLocation(programObject, programInterface, name);
2152}
2153
jchen10880683b2017-04-12 16:21:55 +08002154void Context::getProgramResourceiv(GLuint program,
2155 GLenum programInterface,
2156 GLuint index,
2157 GLsizei propCount,
2158 const GLenum *props,
2159 GLsizei bufSize,
2160 GLsizei *length,
2161 GLint *params)
2162{
2163 const auto *programObject = getProgram(program);
2164 QueryProgramResourceiv(programObject, programInterface, index, propCount, props, bufSize,
2165 length, params);
2166}
2167
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002168Error Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002169{
Geoff Langda5777c2014-07-11 09:52:58 -04002170 if (error.isError())
2171 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002172 GLenum code = error.getCode();
2173 mErrors.insert(code);
2174 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
2175 {
2176 markContextLost();
2177 }
Geoff Lang70d0f492015-12-10 17:45:46 -05002178
2179 if (!error.getMessage().empty())
2180 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002181 auto *debug = &mGLState.getDebug();
2182 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
2183 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05002184 }
Geoff Langda5777c2014-07-11 09:52:58 -04002185 }
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002186
2187 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002188}
2189
2190// Get one of the recorded errors and clear its flag, if any.
2191// [OpenGL ES 2.0.24] section 2.5 page 13.
2192GLenum Context::getError()
2193{
Geoff Langda5777c2014-07-11 09:52:58 -04002194 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002195 {
Geoff Langda5777c2014-07-11 09:52:58 -04002196 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002197 }
Geoff Langda5777c2014-07-11 09:52:58 -04002198 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002199 {
Geoff Langda5777c2014-07-11 09:52:58 -04002200 GLenum error = *mErrors.begin();
2201 mErrors.erase(mErrors.begin());
2202 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002203 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002204}
2205
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002206// NOTE: this function should not assume that this context is current!
2207void Context::markContextLost()
2208{
2209 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002210 {
Jamie Madill231c7f52017-04-26 13:45:37 -04002211 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002212 mContextLostForced = true;
2213 }
Jamie Madill231c7f52017-04-26 13:45:37 -04002214 mContextLost = true;
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002215}
2216
2217bool Context::isContextLost()
2218{
2219 return mContextLost;
2220}
2221
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002222GLenum Context::getResetStatus()
2223{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002224 // Even if the application doesn't want to know about resets, we want to know
2225 // as it will allow us to skip all the calls.
2226 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002227 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002228 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002229 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002230 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002231 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002232
2233 // EXT_robustness, section 2.6: If the reset notification behavior is
2234 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2235 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2236 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002237 }
2238
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002239 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2240 // status should be returned at least once, and GL_NO_ERROR should be returned
2241 // once the device has finished resetting.
2242 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002243 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002244 ASSERT(mResetStatus == GL_NO_ERROR);
2245 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002246
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002247 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002248 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002249 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002250 }
2251 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002252 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002253 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002254 // If markContextLost was used to mark the context lost then
2255 // assume that is not recoverable, and continue to report the
2256 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002257 mResetStatus = mImplementation->getResetStatus();
2258 }
Jamie Madill893ab082014-05-16 16:56:10 -04002259
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002260 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002261}
2262
2263bool Context::isResetNotificationEnabled()
2264{
2265 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2266}
2267
Corentin Walleze3b10e82015-05-20 11:06:25 -04002268const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002269{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002270 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002271}
2272
2273EGLenum Context::getClientType() const
2274{
2275 return mClientType;
2276}
2277
2278EGLenum Context::getRenderBuffer() const
2279{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002280 const Framebuffer *framebuffer = mState.mFramebuffers->getFramebuffer(0);
2281 if (framebuffer == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -04002282 {
2283 return EGL_NONE;
2284 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002285
2286 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2287 ASSERT(backAttachment != nullptr);
2288 return backAttachment->getSurface()->getRenderBuffer();
Régis Fénéon83107972015-02-05 12:57:44 +01002289}
2290
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002291VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002292{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002293 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002294 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2295 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002296 {
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002297 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle,
2298 mCaps.maxVertexAttributes, mCaps.maxVertexAttribBindings);
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002299
Jamie Madill96a483b2017-06-27 16:49:21 -04002300 mVertexArrayMap.assign(vertexArrayHandle, vertexArray);
Geoff Lang36167ab2015-12-07 10:27:14 -05002301 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002302
2303 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002304}
2305
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002306TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002307{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002308 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002309 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2310 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002311 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002312 transformFeedback =
2313 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002314 transformFeedback->addRef();
Jamie Madill96a483b2017-06-27 16:49:21 -04002315 mTransformFeedbackMap.assign(transformFeedbackHandle, transformFeedback);
Geoff Lang36167ab2015-12-07 10:27:14 -05002316 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002317
2318 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002319}
2320
2321bool Context::isVertexArrayGenerated(GLuint vertexArray)
2322{
Jamie Madill96a483b2017-06-27 16:49:21 -04002323 ASSERT(mVertexArrayMap.contains(0));
2324 return mVertexArrayMap.contains(vertexArray);
Geoff Lang36167ab2015-12-07 10:27:14 -05002325}
2326
2327bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2328{
Jamie Madill96a483b2017-06-27 16:49:21 -04002329 ASSERT(mTransformFeedbackMap.contains(0));
2330 return mTransformFeedbackMap.contains(transformFeedback);
Geoff Lang36167ab2015-12-07 10:27:14 -05002331}
2332
Shannon Woods53a94a82014-06-24 15:20:36 -04002333void Context::detachTexture(GLuint texture)
2334{
2335 // Simple pass-through to State's detachTexture method, as textures do not require
2336 // allocation map management either here or in the resource manager at detach time.
2337 // Zero textures are held by the Context, and we don't attempt to request them from
2338 // the State.
Jamie Madilla02315b2017-02-23 14:14:47 -05002339 mGLState.detachTexture(this, mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002340}
2341
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002342void Context::detachBuffer(GLuint buffer)
2343{
Yuly Novikov5807a532015-12-03 13:01:22 -05002344 // Simple pass-through to State's detachBuffer method, since
2345 // only buffer attachments to container objects that are bound to the current context
2346 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002347
Yuly Novikov5807a532015-12-03 13:01:22 -05002348 // [OpenGL ES 3.2] section 5.1.2 page 45:
2349 // Attachments to unbound container objects, such as
2350 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2351 // are not affected and continue to act as references on the deleted object
Jamie Madill4928b7c2017-06-20 12:57:39 -04002352 mGLState.detachBuffer(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002353}
2354
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002355void Context::detachFramebuffer(GLuint framebuffer)
2356{
Shannon Woods53a94a82014-06-24 15:20:36 -04002357 // Framebuffer detachment is handled by Context, because 0 is a valid
2358 // Framebuffer object, and a pointer to it must be passed from Context
2359 // to State at binding time.
2360
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002361 // [OpenGL ES 2.0.24] section 4.4 page 107:
Jamie Madill231c7f52017-04-26 13:45:37 -04002362 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as
2363 // though BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of
2364 // zero.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002365
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002366 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002367 {
2368 bindReadFramebuffer(0);
2369 }
2370
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002371 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002372 {
2373 bindDrawFramebuffer(0);
2374 }
2375}
2376
2377void Context::detachRenderbuffer(GLuint renderbuffer)
2378{
Jamie Madilla02315b2017-02-23 14:14:47 -05002379 mGLState.detachRenderbuffer(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002380}
2381
Jamie Madill57a89722013-07-02 11:57:03 -04002382void Context::detachVertexArray(GLuint vertexArray)
2383{
Jamie Madill77a72f62015-04-14 11:18:32 -04002384 // Vertex array detachment is handled by Context, because 0 is a valid
2385 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002386 // binding time.
2387
Jamie Madill57a89722013-07-02 11:57:03 -04002388 // [OpenGL ES 3.0.2] section 2.10 page 43:
2389 // If a vertex array object that is currently bound is deleted, the binding
2390 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002391 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002392 {
2393 bindVertexArray(0);
2394 }
2395}
2396
Geoff Langc8058452014-02-03 12:04:11 -05002397void Context::detachTransformFeedback(GLuint transformFeedback)
2398{
Corentin Walleza2257da2016-04-19 16:43:12 -04002399 // Transform feedback detachment is handled by Context, because 0 is a valid
2400 // transform feedback, and a pointer to it must be passed from Context to State at
2401 // binding time.
2402
2403 // The OpenGL specification doesn't mention what should happen when the currently bound
2404 // transform feedback object is deleted. Since it is a container object, we treat it like
2405 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madill4928b7c2017-06-20 12:57:39 -04002406 if (mGLState.removeTransformFeedbackBinding(this, transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002407 {
2408 bindTransformFeedback(0);
2409 }
Geoff Langc8058452014-02-03 12:04:11 -05002410}
2411
Jamie Madilldc356042013-07-19 16:36:57 -04002412void Context::detachSampler(GLuint sampler)
2413{
Jamie Madill4928b7c2017-06-20 12:57:39 -04002414 mGLState.detachSampler(this, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002415}
2416
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002417void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2418{
Shaodde78e82017-05-22 14:13:27 +08002419 mGLState.setVertexAttribDivisor(this, index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002420}
2421
Jamie Madille29d1672013-07-19 16:36:57 -04002422void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2423{
Geoff Langc1984ed2016-10-07 12:41:00 -04002424 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002425 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002426 SetSamplerParameteri(samplerObject, pname, param);
2427}
Jamie Madille29d1672013-07-19 16:36:57 -04002428
Geoff Langc1984ed2016-10-07 12:41:00 -04002429void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2430{
2431 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002432 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002433 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002434}
2435
2436void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2437{
Geoff Langc1984ed2016-10-07 12:41:00 -04002438 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002439 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002440 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002441}
2442
Geoff Langc1984ed2016-10-07 12:41:00 -04002443void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002444{
Geoff Langc1984ed2016-10-07 12:41:00 -04002445 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002446 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002447 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002448}
2449
Geoff Langc1984ed2016-10-07 12:41:00 -04002450void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002451{
Geoff Langc1984ed2016-10-07 12:41:00 -04002452 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002453 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002454 QuerySamplerParameteriv(samplerObject, pname, params);
2455}
Jamie Madill9675b802013-07-19 16:36:59 -04002456
Geoff Langc1984ed2016-10-07 12:41:00 -04002457void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2458{
2459 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002460 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002461 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002462}
2463
Olli Etuahof0fee072016-03-30 15:11:58 +03002464void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2465{
2466 gl::Program *programObject = getProgram(program);
Yunchao He61afff12017-03-14 15:34:03 +08002467 SetProgramParameteri(programObject, pname, value);
Olli Etuahof0fee072016-03-30 15:11:58 +03002468}
2469
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002470void Context::initRendererString()
2471{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002472 std::ostringstream rendererString;
2473 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002474 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002475 rendererString << ")";
2476
Geoff Langcec35902014-04-16 10:52:36 -04002477 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002478}
2479
Geoff Langc339c4e2016-11-29 10:37:36 -05002480void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002481{
Geoff Langc339c4e2016-11-29 10:37:36 -05002482 const Version &clientVersion = getClientVersion();
2483
2484 std::ostringstream versionString;
2485 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2486 << ANGLE_VERSION_STRING << ")";
2487 mVersionString = MakeStaticString(versionString.str());
2488
2489 std::ostringstream shadingLanguageVersionString;
2490 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2491 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2492 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2493 << ")";
2494 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002495}
2496
Geoff Langcec35902014-04-16 10:52:36 -04002497void Context::initExtensionStrings()
2498{
Geoff Langc339c4e2016-11-29 10:37:36 -05002499 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2500 std::ostringstream combinedStringStream;
2501 std::copy(strings.begin(), strings.end(),
2502 std::ostream_iterator<const char *>(combinedStringStream, " "));
2503 return MakeStaticString(combinedStringStream.str());
2504 };
2505
2506 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002507 for (const auto &extensionString : mExtensions.getStrings())
2508 {
2509 mExtensionStrings.push_back(MakeStaticString(extensionString));
2510 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002511 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002512
Bryan Bernhart58806562017-01-05 13:09:31 -08002513 const gl::Extensions &nativeExtensions = mImplementation->getNativeExtensions();
2514
Geoff Langc339c4e2016-11-29 10:37:36 -05002515 mRequestableExtensionStrings.clear();
2516 for (const auto &extensionInfo : GetExtensionInfoMap())
2517 {
2518 if (extensionInfo.second.Requestable &&
Bryan Bernhart58806562017-01-05 13:09:31 -08002519 !(mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
2520 nativeExtensions.*(extensionInfo.second.ExtensionsMember))
Geoff Langc339c4e2016-11-29 10:37:36 -05002521 {
2522 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2523 }
2524 }
2525 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002526}
2527
Geoff Langc339c4e2016-11-29 10:37:36 -05002528const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002529{
Geoff Langc339c4e2016-11-29 10:37:36 -05002530 switch (name)
2531 {
2532 case GL_VENDOR:
2533 return reinterpret_cast<const GLubyte *>("Google Inc.");
2534
2535 case GL_RENDERER:
2536 return reinterpret_cast<const GLubyte *>(mRendererString);
2537
2538 case GL_VERSION:
2539 return reinterpret_cast<const GLubyte *>(mVersionString);
2540
2541 case GL_SHADING_LANGUAGE_VERSION:
2542 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2543
2544 case GL_EXTENSIONS:
2545 return reinterpret_cast<const GLubyte *>(mExtensionString);
2546
2547 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2548 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2549
2550 default:
2551 UNREACHABLE();
2552 return nullptr;
2553 }
Geoff Langcec35902014-04-16 10:52:36 -04002554}
2555
Geoff Langc339c4e2016-11-29 10:37:36 -05002556const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002557{
Geoff Langc339c4e2016-11-29 10:37:36 -05002558 switch (name)
2559 {
2560 case GL_EXTENSIONS:
2561 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2562
2563 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2564 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2565
2566 default:
2567 UNREACHABLE();
2568 return nullptr;
2569 }
Geoff Langcec35902014-04-16 10:52:36 -04002570}
2571
2572size_t Context::getExtensionStringCount() const
2573{
2574 return mExtensionStrings.size();
2575}
2576
Geoff Langc339c4e2016-11-29 10:37:36 -05002577void Context::requestExtension(const char *name)
2578{
2579 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2580 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2581 const auto &extension = extensionInfos.at(name);
2582 ASSERT(extension.Requestable);
2583
2584 if (mExtensions.*(extension.ExtensionsMember))
2585 {
2586 // Extension already enabled
2587 return;
2588 }
2589
2590 mExtensions.*(extension.ExtensionsMember) = true;
2591 updateCaps();
2592 initExtensionStrings();
Bryan Bernhart58806562017-01-05 13:09:31 -08002593
Jamie Madill2f348d22017-06-05 10:50:59 -04002594 // Release the shader compiler so it will be re-created with the requested extensions enabled.
2595 releaseShaderCompiler();
Geoff Lang9aded172017-04-05 11:07:56 -04002596
2597 // Invalidate all cached completenesses for textures and framebuffer. Some extensions make new
2598 // formats renderable or sampleable.
2599 mState.mTextures->invalidateTextureComplenessCache();
2600 for (auto &zeroTexture : mZeroTextures)
2601 {
2602 zeroTexture.second->invalidateCompletenessCache();
2603 }
2604
2605 mState.mFramebuffers->invalidateFramebufferComplenessCache();
Geoff Langc339c4e2016-11-29 10:37:36 -05002606}
2607
2608size_t Context::getRequestableExtensionStringCount() const
2609{
2610 return mRequestableExtensionStrings.size();
2611}
2612
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002613void Context::beginTransformFeedback(GLenum primitiveMode)
2614{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002615 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002616 ASSERT(transformFeedback != nullptr);
2617 ASSERT(!transformFeedback->isPaused());
2618
Jamie Madill6c1f6712017-02-14 19:08:04 -05002619 transformFeedback->begin(this, primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002620}
2621
2622bool Context::hasActiveTransformFeedback(GLuint program) const
2623{
2624 for (auto pair : mTransformFeedbackMap)
2625 {
2626 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2627 {
2628 return true;
2629 }
2630 }
2631 return false;
2632}
2633
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002634void Context::initCaps(const egl::DisplayExtensions &displayExtensions)
Geoff Lang493daf52014-07-03 13:38:44 -04002635{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002636 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002637
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002638 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002639
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002640 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002641
Geoff Langeb66a6e2016-10-31 13:06:12 -04002642 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002643 {
2644 // Disable ES3+ extensions
Jamie Madill231c7f52017-04-26 13:45:37 -04002645 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002646 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002647 mExtensions.textureNorm16 = false;
Martin Radev137032d2017-07-13 10:11:12 +03002648 mExtensions.multiview = false;
2649 mExtensions.maxViews = 1u;
Geoff Lang493daf52014-07-03 13:38:44 -04002650 }
2651
Geoff Langeb66a6e2016-10-31 13:06:12 -04002652 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002653 {
2654 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
Jamie Madill231c7f52017-04-26 13:45:37 -04002655 // mExtensions.sRGB = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002656 }
2657
Jamie Madill00ed7a12016-05-19 13:13:38 -04002658 // Some extensions are always available because they are implemented in the GL layer.
Jamie Madill231c7f52017-04-26 13:45:37 -04002659 mExtensions.bindUniformLocation = true;
2660 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002661 mExtensions.bindGeneratesResource = true;
Geoff Langfeb8c682017-02-13 16:07:35 -05002662 mExtensions.clientArrays = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002663 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002664
2665 // Enable the no error extension if the context was created with the flag.
2666 mExtensions.noError = mSkipValidation;
2667
Corentin Wallezccab69d2017-01-27 16:57:15 -05002668 // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
Corentin Wallezc295e512017-01-27 17:47:50 -05002669 mExtensions.surfacelessContext = displayExtensions.surfacelessContext;
Corentin Wallezccab69d2017-01-27 16:57:15 -05002670
Geoff Lang70d0f492015-12-10 17:45:46 -05002671 // Explicitly enable GL_KHR_debug
2672 mExtensions.debug = true;
2673 mExtensions.maxDebugMessageLength = 1024;
2674 mExtensions.maxDebugLoggedMessages = 1024;
2675 mExtensions.maxDebugGroupStackDepth = 1024;
2676 mExtensions.maxLabelLength = 1024;
2677
Geoff Langff5b2d52016-09-07 11:32:23 -04002678 // Explicitly enable GL_ANGLE_robust_client_memory
2679 mExtensions.robustClientMemory = true;
2680
Jamie Madille08a1d32017-03-07 17:24:06 -05002681 // Determine robust resource init availability from EGL.
2682 mExtensions.robustResourceInitialization =
Jamie Madill948bbe52017-06-01 13:10:42 -04002683 egl::Display::GetClientExtensions().displayRobustResourceInitialization;
Jamie Madille08a1d32017-03-07 17:24:06 -05002684
Jamie Madillc43be722017-07-13 16:22:14 -04002685 // Enable the cache control query unconditionally.
2686 mExtensions.programCacheControl = true;
2687
Geoff Lang301d1612014-07-09 10:34:37 -04002688 // Apply implementation limits
2689 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002690 mCaps.maxVertexAttribBindings =
2691 getClientVersion() < ES_3_1
2692 ? mCaps.maxVertexAttributes
2693 : std::min<GLuint>(mCaps.maxVertexAttribBindings, MAX_VERTEX_ATTRIB_BINDINGS);
2694
Jamie Madill231c7f52017-04-26 13:45:37 -04002695 mCaps.maxVertexUniformBlocks = std::min<GLuint>(
2696 mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2697 mCaps.maxVertexOutputComponents =
2698 std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang301d1612014-07-09 10:34:37 -04002699
Jamie Madill231c7f52017-04-26 13:45:37 -04002700 mCaps.maxFragmentInputComponents =
2701 std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002702
Geoff Langc287ea62016-09-16 14:46:51 -04002703 // WebGL compatibility
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002704 mExtensions.webglCompatibility = mWebGLContext;
Geoff Langc287ea62016-09-16 14:46:51 -04002705 for (const auto &extensionInfo : GetExtensionInfoMap())
2706 {
2707 // If this context is for WebGL, disable all enableable extensions
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002708 if (mWebGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002709 {
2710 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2711 }
2712 }
2713
2714 // Generate texture caps
2715 updateCaps();
2716}
2717
2718void Context::updateCaps()
2719{
Geoff Lang900013c2014-07-07 11:32:19 -04002720 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002721 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002722
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002723 for (auto capsIt : mImplementation->getNativeTextureCaps())
Geoff Lang493daf52014-07-03 13:38:44 -04002724 {
Geoff Langca271392017-04-05 12:30:00 -04002725 GLenum sizedInternalFormat = capsIt.first;
Jamie Madill231c7f52017-04-26 13:45:37 -04002726 TextureCaps formatCaps = capsIt.second;
Geoff Lang493daf52014-07-03 13:38:44 -04002727
Geoff Langca271392017-04-05 12:30:00 -04002728 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002729
Geoff Lang0d8b7242015-09-09 14:56:53 -04002730 // Update the format caps based on the client version and extensions.
2731 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2732 // ES3.
2733 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002734 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002735 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002736 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002737 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002738 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002739
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002740 // OpenGL ES does not support multisampling with non-rendererable formats
2741 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
Olli Etuaho50c562d2017-06-06 14:43:30 +03002742 if (!formatCaps.renderable ||
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002743 (getClientVersion() < ES_3_1 &&
2744 (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
Geoff Lang493daf52014-07-03 13:38:44 -04002745 {
Geoff Langd87878e2014-09-19 15:42:59 -04002746 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002747 }
Olli Etuaho50c562d2017-06-06 14:43:30 +03002748 else
2749 {
2750 // We may have limited the max samples for some required renderbuffer formats due to
2751 // non-conformant formats. In this case MAX_SAMPLES needs to be lowered accordingly.
2752 GLuint formatMaxSamples = formatCaps.getMaxSamples();
2753
2754 // GLES 3.0.5 section 4.4.2.2: "Implementations must support creation of renderbuffers
2755 // in these required formats with up to the value of MAX_SAMPLES multisamples, with the
2756 // exception of signed and unsigned integer formats."
2757 if (formatInfo.componentType != GL_INT && formatInfo.componentType != GL_UNSIGNED_INT &&
2758 formatInfo.isRequiredRenderbufferFormat(getClientVersion()))
2759 {
2760 ASSERT(getClientVersion() < ES_3_0 || formatMaxSamples >= 4);
2761 mCaps.maxSamples = std::min(mCaps.maxSamples, formatMaxSamples);
2762 }
2763
2764 // Handle GLES 3.1 MAX_*_SAMPLES values similarly to MAX_SAMPLES.
2765 if (getClientVersion() >= ES_3_1)
2766 {
2767 // GLES 3.1 section 9.2.5: "Implementations must support creation of renderbuffers
2768 // in these required formats with up to the value of MAX_SAMPLES multisamples, with
2769 // the exception that the signed and unsigned integer formats are required only to
2770 // support creation of renderbuffers with up to the value of MAX_INTEGER_SAMPLES
2771 // multisamples, which must be at least one."
2772 if (formatInfo.componentType == GL_INT ||
2773 formatInfo.componentType == GL_UNSIGNED_INT)
2774 {
2775 mCaps.maxIntegerSamples = std::min(mCaps.maxIntegerSamples, formatMaxSamples);
2776 }
2777
2778 // GLES 3.1 section 19.3.1.
2779 if (formatCaps.texturable)
2780 {
2781 if (formatInfo.depthBits > 0)
2782 {
2783 mCaps.maxDepthTextureSamples =
2784 std::min(mCaps.maxDepthTextureSamples, formatMaxSamples);
2785 }
2786 else if (formatInfo.redBits > 0)
2787 {
2788 mCaps.maxColorTextureSamples =
2789 std::min(mCaps.maxColorTextureSamples, formatMaxSamples);
2790 }
2791 }
2792 }
2793 }
Geoff Langd87878e2014-09-19 15:42:59 -04002794
2795 if (formatCaps.texturable && formatInfo.compressed)
2796 {
Geoff Langca271392017-04-05 12:30:00 -04002797 mCaps.compressedTextureFormats.push_back(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002798 }
2799
Geoff Langca271392017-04-05 12:30:00 -04002800 mTextureCaps.insert(sizedInternalFormat, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002801 }
Jamie Madill32447362017-06-28 14:53:52 -04002802
2803 // If program binary is disabled, blank out the memory cache pointer.
2804 if (!mImplementation->getNativeExtensions().getProgramBinary)
2805 {
2806 mMemoryProgramCache = nullptr;
2807 }
Geoff Lang493daf52014-07-03 13:38:44 -04002808}
2809
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002810void Context::initWorkarounds()
2811{
Jamie Madill761b02c2017-06-23 16:27:06 -04002812 // Apply back-end workarounds.
2813 mImplementation->applyNativeWorkarounds(&mWorkarounds);
2814
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002815 // Lose the context upon out of memory error if the application is
2816 // expecting to watch for those events.
2817 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2818}
2819
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002820Error Context::prepareForDraw(GLenum drawMode)
Jamie Madillb6664922017-07-25 12:55:04 -04002821{
2822 syncRendererState();
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002823
2824 InfoLog infoLog;
2825 Error err = mImplementation->triggerDrawCallProgramRecompilation(this, &infoLog,
2826 mMemoryProgramCache, drawMode);
Jamie Madilla836b462017-08-16 14:58:35 -04002827 if (err.isError() || infoLog.getLength() > 0)
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002828 {
2829 WARN() << "Dynamic recompilation error log: " << infoLog.str();
2830 }
2831 return err;
Jamie Madillb6664922017-07-25 12:55:04 -04002832}
2833
Jamie Madill1b94d432015-08-07 13:23:23 -04002834void Context::syncRendererState()
2835{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002836 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
Jamie Madillfe548342017-06-19 11:13:24 -04002837 mImplementation->syncState(this, dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002838 mGLState.clearDirtyBits();
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002839 mGLState.syncDirtyObjects(this);
Jamie Madill1b94d432015-08-07 13:23:23 -04002840}
2841
Jamie Madillad9f24e2016-02-12 09:27:24 -05002842void Context::syncRendererState(const State::DirtyBits &bitMask,
2843 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002844{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002845 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
Jamie Madillfe548342017-06-19 11:13:24 -04002846 mImplementation->syncState(this, dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002847 mGLState.clearDirtyBits(dirtyBits);
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002848 mGLState.syncDirtyObjects(this, objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002849}
Jamie Madillc29968b2016-01-20 11:17:23 -05002850
2851void Context::blitFramebuffer(GLint srcX0,
2852 GLint srcY0,
2853 GLint srcX1,
2854 GLint srcY1,
2855 GLint dstX0,
2856 GLint dstY0,
2857 GLint dstX1,
2858 GLint dstY1,
2859 GLbitfield mask,
2860 GLenum filter)
2861{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002862 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002863 ASSERT(drawFramebuffer);
2864
2865 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2866 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2867
Jamie Madillad9f24e2016-02-12 09:27:24 -05002868 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002869
Jamie Madillc564c072017-06-01 12:45:42 -04002870 handleError(drawFramebuffer->blit(this, srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002871}
Jamie Madillc29968b2016-01-20 11:17:23 -05002872
2873void Context::clear(GLbitfield mask)
2874{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002875 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002876 handleError(mGLState.getDrawFramebuffer()->clear(this, mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002877}
2878
2879void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2880{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002881 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002882 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002883}
2884
2885void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2886{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002887 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002888 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002889}
2890
2891void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2892{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002893 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002894 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002895}
2896
2897void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2898{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002899 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002900 ASSERT(framebufferObject);
2901
2902 // If a buffer is not present, the clear has no effect
2903 if (framebufferObject->getDepthbuffer() == nullptr &&
2904 framebufferObject->getStencilbuffer() == nullptr)
2905 {
2906 return;
2907 }
2908
Jamie Madillad9f24e2016-02-12 09:27:24 -05002909 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002910 handleError(framebufferObject->clearBufferfi(this, buffer, drawbuffer, depth, stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002911}
2912
2913void Context::readPixels(GLint x,
2914 GLint y,
2915 GLsizei width,
2916 GLsizei height,
2917 GLenum format,
2918 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002919 void *pixels)
Jamie Madillc29968b2016-01-20 11:17:23 -05002920{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002921 if (width == 0 || height == 0)
2922 {
2923 return;
2924 }
2925
Jamie Madillad9f24e2016-02-12 09:27:24 -05002926 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002927
Jamie Madillb6664922017-07-25 12:55:04 -04002928 Framebuffer *readFBO = mGLState.getReadFramebuffer();
2929 ASSERT(readFBO);
Jamie Madillc29968b2016-01-20 11:17:23 -05002930
2931 Rectangle area(x, y, width, height);
Jamie Madillb6664922017-07-25 12:55:04 -04002932 handleError(readFBO->readPixels(this, area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002933}
2934
2935void Context::copyTexImage2D(GLenum target,
2936 GLint level,
2937 GLenum internalformat,
2938 GLint x,
2939 GLint y,
2940 GLsizei width,
2941 GLsizei height,
2942 GLint border)
2943{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002944 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002945 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002946
Jamie Madillc29968b2016-01-20 11:17:23 -05002947 Rectangle sourceArea(x, y, width, height);
2948
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002949 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002950 Texture *texture =
2951 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002952 handleError(texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002953}
2954
2955void Context::copyTexSubImage2D(GLenum target,
2956 GLint level,
2957 GLint xoffset,
2958 GLint yoffset,
2959 GLint x,
2960 GLint y,
2961 GLsizei width,
2962 GLsizei height)
2963{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002964 if (width == 0 || height == 0)
2965 {
2966 return;
2967 }
2968
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002969 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002970 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002971
Jamie Madillc29968b2016-01-20 11:17:23 -05002972 Offset destOffset(xoffset, yoffset, 0);
2973 Rectangle sourceArea(x, y, width, height);
2974
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002975 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002976 Texture *texture =
2977 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002978 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002979}
2980
2981void Context::copyTexSubImage3D(GLenum target,
2982 GLint level,
2983 GLint xoffset,
2984 GLint yoffset,
2985 GLint zoffset,
2986 GLint x,
2987 GLint y,
2988 GLsizei width,
2989 GLsizei height)
2990{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002991 if (width == 0 || height == 0)
2992 {
2993 return;
2994 }
2995
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002996 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002997 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002998
Jamie Madillc29968b2016-01-20 11:17:23 -05002999 Offset destOffset(xoffset, yoffset, zoffset);
3000 Rectangle sourceArea(x, y, width, height);
3001
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003002 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003003 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003004 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05003005}
3006
3007void Context::framebufferTexture2D(GLenum target,
3008 GLenum attachment,
3009 GLenum textarget,
3010 GLuint texture,
3011 GLint level)
3012{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003013 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003014 ASSERT(framebuffer);
3015
3016 if (texture != 0)
3017 {
3018 Texture *textureObj = getTexture(texture);
3019
3020 ImageIndex index = ImageIndex::MakeInvalid();
3021
3022 if (textarget == GL_TEXTURE_2D)
3023 {
3024 index = ImageIndex::Make2D(level);
3025 }
Corentin Wallez13c0dd42017-07-04 18:27:01 -04003026 else if (textarget == GL_TEXTURE_RECTANGLE_ANGLE)
3027 {
3028 index = ImageIndex::MakeRectangle(level);
3029 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08003030 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
3031 {
3032 ASSERT(level == 0);
3033 index = ImageIndex::Make2DMultisample();
3034 }
Jamie Madillc29968b2016-01-20 11:17:23 -05003035 else
3036 {
3037 ASSERT(IsCubeMapTextureTarget(textarget));
3038 index = ImageIndex::MakeCube(textarget, level);
3039 }
3040
Jamie Madilla02315b2017-02-23 14:14:47 -05003041 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
Jamie Madillc29968b2016-01-20 11:17:23 -05003042 }
3043 else
3044 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003045 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003046 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003047
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003048 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003049}
3050
3051void Context::framebufferRenderbuffer(GLenum target,
3052 GLenum attachment,
3053 GLenum renderbuffertarget,
3054 GLuint renderbuffer)
3055{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003056 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003057 ASSERT(framebuffer);
3058
3059 if (renderbuffer != 0)
3060 {
3061 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
Jamie Madilla02315b2017-02-23 14:14:47 -05003062
3063 framebuffer->setAttachment(this, GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
Jamie Madillc29968b2016-01-20 11:17:23 -05003064 renderbufferObject);
3065 }
3066 else
3067 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003068 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003069 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003070
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003071 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003072}
3073
3074void Context::framebufferTextureLayer(GLenum target,
3075 GLenum attachment,
3076 GLuint texture,
3077 GLint level,
3078 GLint layer)
3079{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003080 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003081 ASSERT(framebuffer);
3082
3083 if (texture != 0)
3084 {
3085 Texture *textureObject = getTexture(texture);
3086
3087 ImageIndex index = ImageIndex::MakeInvalid();
3088
3089 if (textureObject->getTarget() == GL_TEXTURE_3D)
3090 {
3091 index = ImageIndex::Make3D(level, layer);
3092 }
3093 else
3094 {
3095 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
3096 index = ImageIndex::Make2DArray(level, layer);
3097 }
3098
Jamie Madilla02315b2017-02-23 14:14:47 -05003099 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObject);
Jamie Madillc29968b2016-01-20 11:17:23 -05003100 }
3101 else
3102 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003103 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003104 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003105
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003106 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003107}
3108
Martin Radev137032d2017-07-13 10:11:12 +03003109void Context::framebufferTextureMultiviewLayeredANGLE(GLenum target,
3110 GLenum attachment,
3111 GLuint texture,
3112 GLint level,
3113 GLint baseViewIndex,
3114 GLsizei numViews)
3115{
Martin Radev82ef7742017-08-08 17:44:58 +03003116 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
3117 ASSERT(framebuffer);
3118
3119 if (texture != 0)
3120 {
3121 Texture *textureObj = getTexture(texture);
3122
3123 ImageIndex index = ImageIndex::Make2DArray(level, baseViewIndex);
3124 framebuffer->setAttachmentMultiviewLayered(this, GL_TEXTURE, attachment, index, textureObj,
3125 numViews, baseViewIndex);
3126 }
3127 else
3128 {
3129 framebuffer->resetAttachment(this, attachment);
3130 }
3131
3132 mGLState.setObjectDirty(target);
Martin Radev137032d2017-07-13 10:11:12 +03003133}
3134
3135void Context::framebufferTextureMultiviewSideBySideANGLE(GLenum target,
3136 GLenum attachment,
3137 GLuint texture,
3138 GLint level,
3139 GLsizei numViews,
3140 const GLint *viewportOffsets)
3141{
Martin Radev5dae57b2017-07-14 16:15:55 +03003142 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
3143 ASSERT(framebuffer);
3144
3145 if (texture != 0)
3146 {
3147 Texture *textureObj = getTexture(texture);
3148
3149 ImageIndex index = ImageIndex::Make2D(level);
3150 framebuffer->setAttachmentMultiviewSideBySide(this, GL_TEXTURE, attachment, index,
3151 textureObj, numViews, viewportOffsets);
3152 }
3153 else
3154 {
3155 framebuffer->resetAttachment(this, attachment);
3156 }
3157
3158 mGLState.setObjectDirty(target);
Martin Radev137032d2017-07-13 10:11:12 +03003159}
3160
Jamie Madillc29968b2016-01-20 11:17:23 -05003161void Context::drawBuffers(GLsizei n, const GLenum *bufs)
3162{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003163 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003164 ASSERT(framebuffer);
3165 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003166 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003167}
3168
3169void Context::readBuffer(GLenum mode)
3170{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003171 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003172 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003173 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003174}
3175
3176void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
3177{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003178 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003179 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003180
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003181 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003182 ASSERT(framebuffer);
3183
3184 // The specification isn't clear what should be done when the framebuffer isn't complete.
3185 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill4928b7c2017-06-20 12:57:39 -04003186 handleError(framebuffer->discard(this, numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003187}
3188
3189void Context::invalidateFramebuffer(GLenum target,
3190 GLsizei numAttachments,
3191 const GLenum *attachments)
3192{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003193 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003194 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003195
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003196 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003197 ASSERT(framebuffer);
3198
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003199 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003200 {
Jamie Madill437fa652016-05-03 15:13:24 -04003201 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003202 }
Jamie Madill437fa652016-05-03 15:13:24 -04003203
Jamie Madill4928b7c2017-06-20 12:57:39 -04003204 handleError(framebuffer->invalidate(this, numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003205}
3206
3207void Context::invalidateSubFramebuffer(GLenum target,
3208 GLsizei numAttachments,
3209 const GLenum *attachments,
3210 GLint x,
3211 GLint y,
3212 GLsizei width,
3213 GLsizei height)
3214{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003215 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003216 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003217
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003218 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003219 ASSERT(framebuffer);
3220
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003221 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003222 {
Jamie Madill437fa652016-05-03 15:13:24 -04003223 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003224 }
Jamie Madill437fa652016-05-03 15:13:24 -04003225
3226 Rectangle area(x, y, width, height);
Jamie Madill4928b7c2017-06-20 12:57:39 -04003227 handleError(framebuffer->invalidateSub(this, numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05003228}
3229
Jamie Madill73a84962016-02-12 09:27:23 -05003230void Context::texImage2D(GLenum target,
3231 GLint level,
3232 GLint internalformat,
3233 GLsizei width,
3234 GLsizei height,
3235 GLint border,
3236 GLenum format,
3237 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003238 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003239{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003240 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003241
3242 Extents size(width, height, 1);
3243 Texture *texture =
3244 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003245 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3246 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003247}
3248
3249void Context::texImage3D(GLenum target,
3250 GLint level,
3251 GLint internalformat,
3252 GLsizei width,
3253 GLsizei height,
3254 GLsizei depth,
3255 GLint border,
3256 GLenum format,
3257 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003258 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003259{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003260 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003261
3262 Extents size(width, height, depth);
3263 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003264 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3265 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003266}
3267
3268void Context::texSubImage2D(GLenum target,
3269 GLint level,
3270 GLint xoffset,
3271 GLint yoffset,
3272 GLsizei width,
3273 GLsizei height,
3274 GLenum format,
3275 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003276 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003277{
3278 // Zero sized uploads are valid but no-ops
3279 if (width == 0 || height == 0)
3280 {
3281 return;
3282 }
3283
Jamie Madillad9f24e2016-02-12 09:27:24 -05003284 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003285
3286 Box area(xoffset, yoffset, 0, width, height, 1);
3287 Texture *texture =
3288 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003289 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3290 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003291}
3292
3293void Context::texSubImage3D(GLenum target,
3294 GLint level,
3295 GLint xoffset,
3296 GLint yoffset,
3297 GLint zoffset,
3298 GLsizei width,
3299 GLsizei height,
3300 GLsizei depth,
3301 GLenum format,
3302 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003303 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003304{
3305 // Zero sized uploads are valid but no-ops
3306 if (width == 0 || height == 0 || depth == 0)
3307 {
3308 return;
3309 }
3310
Jamie Madillad9f24e2016-02-12 09:27:24 -05003311 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003312
3313 Box area(xoffset, yoffset, zoffset, width, height, depth);
3314 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003315 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3316 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003317}
3318
3319void Context::compressedTexImage2D(GLenum target,
3320 GLint level,
3321 GLenum internalformat,
3322 GLsizei width,
3323 GLsizei height,
3324 GLint border,
3325 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003326 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003327{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003328 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003329
3330 Extents size(width, height, 1);
3331 Texture *texture =
3332 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003333 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003334 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003335 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003336}
3337
3338void Context::compressedTexImage3D(GLenum target,
3339 GLint level,
3340 GLenum internalformat,
3341 GLsizei width,
3342 GLsizei height,
3343 GLsizei depth,
3344 GLint border,
3345 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003346 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003347{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003348 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003349
3350 Extents size(width, height, depth);
3351 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003352 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003353 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003354 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003355}
3356
3357void Context::compressedTexSubImage2D(GLenum target,
3358 GLint level,
3359 GLint xoffset,
3360 GLint yoffset,
3361 GLsizei width,
3362 GLsizei height,
3363 GLenum format,
3364 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003365 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003366{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003367 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003368
3369 Box area(xoffset, yoffset, 0, width, height, 1);
3370 Texture *texture =
3371 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003372 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003373 format, imageSize,
3374 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003375}
3376
3377void Context::compressedTexSubImage3D(GLenum target,
3378 GLint level,
3379 GLint xoffset,
3380 GLint yoffset,
3381 GLint zoffset,
3382 GLsizei width,
3383 GLsizei height,
3384 GLsizei depth,
3385 GLenum format,
3386 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003387 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003388{
3389 // Zero sized uploads are valid but no-ops
3390 if (width == 0 || height == 0)
3391 {
3392 return;
3393 }
3394
Jamie Madillad9f24e2016-02-12 09:27:24 -05003395 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003396
3397 Box area(xoffset, yoffset, zoffset, width, height, depth);
3398 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003399 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003400 format, imageSize,
3401 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003402}
3403
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003404void Context::generateMipmap(GLenum target)
3405{
3406 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003407 handleError(texture->generateMipmap(this));
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003408}
3409
Geoff Lang97073d12016-04-20 10:42:34 -07003410void Context::copyTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003411 GLint sourceLevel,
3412 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003413 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003414 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003415 GLint internalFormat,
3416 GLenum destType,
3417 GLboolean unpackFlipY,
3418 GLboolean unpackPremultiplyAlpha,
3419 GLboolean unpackUnmultiplyAlpha)
3420{
3421 syncStateForTexImage();
3422
3423 gl::Texture *sourceTexture = getTexture(sourceId);
3424 gl::Texture *destTexture = getTexture(destId);
Geoff Langfc72a072017-03-24 14:52:39 -04003425 handleError(destTexture->copyTexture(
3426 this, destTarget, destLevel, internalFormat, destType, sourceLevel, unpackFlipY == GL_TRUE,
3427 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003428}
3429
3430void Context::copySubTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003431 GLint sourceLevel,
3432 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003433 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003434 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003435 GLint xoffset,
3436 GLint yoffset,
3437 GLint x,
3438 GLint y,
3439 GLsizei width,
3440 GLsizei height,
3441 GLboolean unpackFlipY,
3442 GLboolean unpackPremultiplyAlpha,
3443 GLboolean unpackUnmultiplyAlpha)
3444{
3445 // Zero sized copies are valid but no-ops
3446 if (width == 0 || height == 0)
3447 {
3448 return;
3449 }
3450
3451 syncStateForTexImage();
3452
3453 gl::Texture *sourceTexture = getTexture(sourceId);
3454 gl::Texture *destTexture = getTexture(destId);
3455 Offset offset(xoffset, yoffset, 0);
3456 Rectangle area(x, y, width, height);
Geoff Langfc72a072017-03-24 14:52:39 -04003457 handleError(destTexture->copySubTexture(
3458 this, destTarget, destLevel, offset, sourceLevel, area, unpackFlipY == GL_TRUE,
3459 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003460}
3461
Geoff Lang47110bf2016-04-20 11:13:22 -07003462void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3463{
3464 syncStateForTexImage();
3465
3466 gl::Texture *sourceTexture = getTexture(sourceId);
3467 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003468 handleError(destTexture->copyCompressedTexture(this, sourceTexture));
Geoff Lang47110bf2016-04-20 11:13:22 -07003469}
3470
Geoff Lang496c02d2016-10-20 11:38:11 -07003471void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003472{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003473 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003474 ASSERT(buffer);
3475
Geoff Lang496c02d2016-10-20 11:38:11 -07003476 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003477}
3478
Jamie Madill876429b2017-04-20 15:46:24 -04003479void *Context::mapBuffer(GLenum target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003480{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003481 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003482 ASSERT(buffer);
3483
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003484 Error error = buffer->map(this, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003485 if (error.isError())
3486 {
Jamie Madill437fa652016-05-03 15:13:24 -04003487 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003488 return nullptr;
3489 }
3490
3491 return buffer->getMapPointer();
3492}
3493
3494GLboolean Context::unmapBuffer(GLenum target)
3495{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003496 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003497 ASSERT(buffer);
3498
3499 GLboolean result;
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003500 Error error = buffer->unmap(this, &result);
Olli Etuaho4f667482016-03-30 15:56:35 +03003501 if (error.isError())
3502 {
Jamie Madill437fa652016-05-03 15:13:24 -04003503 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003504 return GL_FALSE;
3505 }
3506
3507 return result;
3508}
3509
Jamie Madill876429b2017-04-20 15:46:24 -04003510void *Context::mapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003511{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003512 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003513 ASSERT(buffer);
3514
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003515 Error error = buffer->mapRange(this, offset, length, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003516 if (error.isError())
3517 {
Jamie Madill437fa652016-05-03 15:13:24 -04003518 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003519 return nullptr;
3520 }
3521
3522 return buffer->getMapPointer();
3523}
3524
3525void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3526{
3527 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3528}
3529
Jamie Madillad9f24e2016-02-12 09:27:24 -05003530void Context::syncStateForReadPixels()
3531{
3532 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3533}
3534
3535void Context::syncStateForTexImage()
3536{
3537 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3538}
3539
3540void Context::syncStateForClear()
3541{
3542 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3543}
3544
3545void Context::syncStateForBlit()
3546{
3547 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3548}
3549
Jamie Madillc20ab272016-06-09 07:20:46 -07003550void Context::activeTexture(GLenum texture)
3551{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003552 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003553}
3554
Jamie Madill876429b2017-04-20 15:46:24 -04003555void Context::blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003556{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003557 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003558}
3559
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003560void Context::blendEquation(GLenum mode)
3561{
3562 mGLState.setBlendEquation(mode, mode);
3563}
3564
Jamie Madillc20ab272016-06-09 07:20:46 -07003565void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3566{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003567 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003568}
3569
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003570void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3571{
3572 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3573}
3574
Jamie Madillc20ab272016-06-09 07:20:46 -07003575void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3576{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003577 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003578}
3579
Jamie Madill876429b2017-04-20 15:46:24 -04003580void Context::clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003581{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003582 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003583}
3584
Jamie Madill876429b2017-04-20 15:46:24 -04003585void Context::clearDepthf(GLfloat depth)
Jamie Madillc20ab272016-06-09 07:20:46 -07003586{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003587 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003588}
3589
3590void Context::clearStencil(GLint s)
3591{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003592 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003593}
3594
3595void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3596{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003597 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003598}
3599
3600void Context::cullFace(GLenum mode)
3601{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003602 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003603}
3604
3605void Context::depthFunc(GLenum func)
3606{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003607 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003608}
3609
3610void Context::depthMask(GLboolean flag)
3611{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003612 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003613}
3614
Jamie Madill876429b2017-04-20 15:46:24 -04003615void Context::depthRangef(GLfloat zNear, GLfloat zFar)
Jamie Madillc20ab272016-06-09 07:20:46 -07003616{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003617 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003618}
3619
3620void Context::disable(GLenum cap)
3621{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003622 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003623}
3624
3625void Context::disableVertexAttribArray(GLuint index)
3626{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003627 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003628}
3629
3630void Context::enable(GLenum cap)
3631{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003632 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003633}
3634
3635void Context::enableVertexAttribArray(GLuint index)
3636{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003637 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003638}
3639
3640void Context::frontFace(GLenum mode)
3641{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003642 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003643}
3644
3645void Context::hint(GLenum target, GLenum mode)
3646{
3647 switch (target)
3648 {
3649 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003650 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003651 break;
3652
3653 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003654 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003655 break;
3656
3657 default:
3658 UNREACHABLE();
3659 return;
3660 }
3661}
3662
3663void Context::lineWidth(GLfloat width)
3664{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003665 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003666}
3667
3668void Context::pixelStorei(GLenum pname, GLint param)
3669{
3670 switch (pname)
3671 {
3672 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003673 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003674 break;
3675
3676 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003677 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003678 break;
3679
3680 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003681 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003682 break;
3683
3684 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003685 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003686 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003687 break;
3688
3689 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003690 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003691 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003692 break;
3693
3694 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003695 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003696 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003697 break;
3698
3699 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003700 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003701 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003702 break;
3703
3704 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003705 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003706 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003707 break;
3708
3709 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003710 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003711 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003712 break;
3713
3714 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003715 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003716 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003717 break;
3718
3719 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003720 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003721 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003722 break;
3723
3724 default:
3725 UNREACHABLE();
3726 return;
3727 }
3728}
3729
3730void Context::polygonOffset(GLfloat factor, GLfloat units)
3731{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003732 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003733}
3734
Jamie Madill876429b2017-04-20 15:46:24 -04003735void Context::sampleCoverage(GLfloat value, GLboolean invert)
Jamie Madillc20ab272016-06-09 07:20:46 -07003736{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003737 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003738}
3739
3740void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3741{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003742 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003743}
3744
3745void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3746{
3747 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3748 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003749 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003750 }
3751
3752 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3753 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003754 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003755 }
3756}
3757
3758void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3759{
3760 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3761 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003762 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003763 }
3764
3765 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3766 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003767 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003768 }
3769}
3770
3771void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3772{
3773 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3774 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003775 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003776 }
3777
3778 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3779 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003780 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003781 }
3782}
3783
3784void Context::vertexAttrib1f(GLuint index, GLfloat x)
3785{
3786 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003787 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003788}
3789
3790void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3791{
3792 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003793 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003794}
3795
3796void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3797{
3798 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003799 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003800}
3801
3802void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3803{
3804 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003805 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003806}
3807
3808void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3809{
3810 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003811 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003812}
3813
3814void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3815{
3816 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003817 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003818}
3819
3820void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3821{
3822 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003823 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003824}
3825
3826void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3827{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003828 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003829}
3830
3831void Context::vertexAttribPointer(GLuint index,
3832 GLint size,
3833 GLenum type,
3834 GLboolean normalized,
3835 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003836 const void *ptr)
Jamie Madillc20ab272016-06-09 07:20:46 -07003837{
Shaodde78e82017-05-22 14:13:27 +08003838 mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size,
3839 type, normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003840}
3841
Shao80957d92017-02-20 21:25:59 +08003842void Context::vertexAttribFormat(GLuint attribIndex,
3843 GLint size,
3844 GLenum type,
3845 GLboolean normalized,
3846 GLuint relativeOffset)
3847{
3848 mGLState.setVertexAttribFormat(attribIndex, size, type, normalized == GL_TRUE, false,
3849 relativeOffset);
3850}
3851
3852void Context::vertexAttribIFormat(GLuint attribIndex,
3853 GLint size,
3854 GLenum type,
3855 GLuint relativeOffset)
3856{
3857 mGLState.setVertexAttribFormat(attribIndex, size, type, false, true, relativeOffset);
3858}
3859
3860void Context::vertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
3861{
Shaodde78e82017-05-22 14:13:27 +08003862 mGLState.setVertexAttribBinding(this, attribIndex, bindingIndex);
Shao80957d92017-02-20 21:25:59 +08003863}
3864
3865void Context::setVertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
3866{
3867 mGLState.setVertexBindingDivisor(bindingIndex, divisor);
3868}
3869
Jamie Madillc20ab272016-06-09 07:20:46 -07003870void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3871{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003872 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003873}
3874
3875void Context::vertexAttribIPointer(GLuint index,
3876 GLint size,
3877 GLenum type,
3878 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003879 const void *pointer)
Jamie Madillc20ab272016-06-09 07:20:46 -07003880{
Shaodde78e82017-05-22 14:13:27 +08003881 mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size,
3882 type, false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003883}
3884
3885void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3886{
3887 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003888 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003889}
3890
3891void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3892{
3893 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003894 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003895}
3896
3897void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3898{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003899 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003900}
3901
3902void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3903{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003904 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003905}
3906
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003907void Context::getVertexAttribiv(GLuint index, GLenum pname, GLint *params)
3908{
3909 const VertexAttribCurrentValueData &currentValues =
3910 getGLState().getVertexAttribCurrentValue(index);
3911 const VertexArray *vao = getGLState().getVertexArray();
3912 QueryVertexAttribiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3913 currentValues, pname, params);
3914}
3915
3916void Context::getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
3917{
3918 const VertexAttribCurrentValueData &currentValues =
3919 getGLState().getVertexAttribCurrentValue(index);
3920 const VertexArray *vao = getGLState().getVertexArray();
3921 QueryVertexAttribfv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3922 currentValues, pname, params);
3923}
3924
3925void Context::getVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
3926{
3927 const VertexAttribCurrentValueData &currentValues =
3928 getGLState().getVertexAttribCurrentValue(index);
3929 const VertexArray *vao = getGLState().getVertexArray();
3930 QueryVertexAttribIiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3931 currentValues, pname, params);
3932}
3933
3934void Context::getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
3935{
3936 const VertexAttribCurrentValueData &currentValues =
3937 getGLState().getVertexAttribCurrentValue(index);
3938 const VertexArray *vao = getGLState().getVertexArray();
3939 QueryVertexAttribIuiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3940 currentValues, pname, params);
3941}
3942
Jamie Madill876429b2017-04-20 15:46:24 -04003943void Context::getVertexAttribPointerv(GLuint index, GLenum pname, void **pointer)
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003944{
3945 const VertexAttribute &attrib = getGLState().getVertexArray()->getVertexAttribute(index);
3946 QueryVertexAttribPointerv(attrib, pname, pointer);
3947}
3948
Jamie Madillc20ab272016-06-09 07:20:46 -07003949void Context::debugMessageControl(GLenum source,
3950 GLenum type,
3951 GLenum severity,
3952 GLsizei count,
3953 const GLuint *ids,
3954 GLboolean enabled)
3955{
3956 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003957 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3958 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003959}
3960
3961void Context::debugMessageInsert(GLenum source,
3962 GLenum type,
3963 GLuint id,
3964 GLenum severity,
3965 GLsizei length,
3966 const GLchar *buf)
3967{
3968 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003969 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003970}
3971
3972void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3973{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003974 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003975}
3976
3977GLuint Context::getDebugMessageLog(GLuint count,
3978 GLsizei bufSize,
3979 GLenum *sources,
3980 GLenum *types,
3981 GLuint *ids,
3982 GLenum *severities,
3983 GLsizei *lengths,
3984 GLchar *messageLog)
3985{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003986 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3987 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003988}
3989
3990void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3991{
3992 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003993 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003994}
3995
3996void Context::popDebugGroup()
3997{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003998 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003999}
4000
Jamie Madill876429b2017-04-20 15:46:24 -04004001void Context::bufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage)
Jamie Madill29639852016-09-02 15:00:09 -04004002{
4003 Buffer *buffer = mGLState.getTargetBuffer(target);
4004 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08004005 handleError(buffer->bufferData(this, target, data, size, usage));
Jamie Madill29639852016-09-02 15:00:09 -04004006}
4007
Jamie Madill876429b2017-04-20 15:46:24 -04004008void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004009{
4010 if (data == nullptr)
4011 {
4012 return;
4013 }
4014
4015 Buffer *buffer = mGLState.getTargetBuffer(target);
4016 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08004017 handleError(buffer->bufferSubData(this, target, data, size, offset));
Jamie Madill29639852016-09-02 15:00:09 -04004018}
4019
Jamie Madillef300b12016-10-07 15:12:09 -04004020void Context::attachShader(GLuint program, GLuint shader)
4021{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05004022 auto programObject = mState.mShaderPrograms->getProgram(program);
4023 auto shaderObject = mState.mShaderPrograms->getShader(shader);
Jamie Madillef300b12016-10-07 15:12:09 -04004024 ASSERT(programObject && shaderObject);
4025 programObject->attachShader(shaderObject);
4026}
4027
Kenneth Russellf2f6f652016-10-05 19:53:23 -07004028const Workarounds &Context::getWorkarounds() const
4029{
4030 return mWorkarounds;
4031}
4032
Jamie Madillb0817d12016-11-01 15:48:31 -04004033void Context::copyBufferSubData(GLenum readTarget,
4034 GLenum writeTarget,
4035 GLintptr readOffset,
4036 GLintptr writeOffset,
4037 GLsizeiptr size)
4038{
4039 // if size is zero, the copy is a successful no-op
4040 if (size == 0)
4041 {
4042 return;
4043 }
4044
4045 // TODO(jmadill): cache these.
4046 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
4047 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
4048
Jamie Madill5f56ddb2017-01-13 17:29:55 -05004049 handleError(writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size));
Jamie Madillb0817d12016-11-01 15:48:31 -04004050}
4051
Jamie Madill01a80ee2016-11-07 12:06:18 -05004052void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
4053{
4054 Program *programObject = getProgram(program);
4055 // TODO(jmadill): Re-use this from the validation if possible.
4056 ASSERT(programObject);
4057 programObject->bindAttributeLocation(index, name);
4058}
4059
4060void Context::bindBuffer(GLenum target, GLuint buffer)
4061{
4062 switch (target)
4063 {
4064 case GL_ARRAY_BUFFER:
4065 bindArrayBuffer(buffer);
4066 break;
4067 case GL_ELEMENT_ARRAY_BUFFER:
4068 bindElementArrayBuffer(buffer);
4069 break;
4070 case GL_COPY_READ_BUFFER:
4071 bindCopyReadBuffer(buffer);
4072 break;
4073 case GL_COPY_WRITE_BUFFER:
4074 bindCopyWriteBuffer(buffer);
4075 break;
4076 case GL_PIXEL_PACK_BUFFER:
4077 bindPixelPackBuffer(buffer);
4078 break;
4079 case GL_PIXEL_UNPACK_BUFFER:
4080 bindPixelUnpackBuffer(buffer);
4081 break;
4082 case GL_UNIFORM_BUFFER:
4083 bindGenericUniformBuffer(buffer);
4084 break;
4085 case GL_TRANSFORM_FEEDBACK_BUFFER:
4086 bindGenericTransformFeedbackBuffer(buffer);
4087 break;
Geoff Lang3b573612016-10-31 14:08:10 -04004088 case GL_ATOMIC_COUNTER_BUFFER:
Jiajia Qin6eafb042016-12-27 17:04:07 +08004089 bindGenericAtomicCounterBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004090 break;
4091 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08004092 bindGenericShaderStorageBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004093 break;
4094 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08004095 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004096 break;
4097 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05004098 if (buffer != 0)
4099 {
4100 // Binding buffers to this binding point is not implemented yet.
4101 UNIMPLEMENTED();
4102 }
Geoff Lang3b573612016-10-31 14:08:10 -04004103 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05004104
4105 default:
4106 UNREACHABLE();
4107 break;
4108 }
4109}
4110
Jiajia Qin6eafb042016-12-27 17:04:07 +08004111void Context::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
4112{
4113 bindBufferRange(target, index, buffer, 0, 0);
4114}
4115
4116void Context::bindBufferRange(GLenum target,
4117 GLuint index,
4118 GLuint buffer,
4119 GLintptr offset,
4120 GLsizeiptr size)
4121{
4122 switch (target)
4123 {
4124 case GL_TRANSFORM_FEEDBACK_BUFFER:
4125 bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
4126 bindGenericTransformFeedbackBuffer(buffer);
4127 break;
4128 case GL_UNIFORM_BUFFER:
4129 bindIndexedUniformBuffer(buffer, index, offset, size);
4130 bindGenericUniformBuffer(buffer);
4131 break;
4132 case GL_ATOMIC_COUNTER_BUFFER:
4133 bindIndexedAtomicCounterBuffer(buffer, index, offset, size);
4134 bindGenericAtomicCounterBuffer(buffer);
4135 break;
4136 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08004137 bindIndexedShaderStorageBuffer(buffer, index, offset, size);
4138 bindGenericShaderStorageBuffer(buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08004139 break;
4140 default:
4141 UNREACHABLE();
4142 break;
4143 }
4144}
4145
Jamie Madill01a80ee2016-11-07 12:06:18 -05004146void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
4147{
4148 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4149 {
4150 bindReadFramebuffer(framebuffer);
4151 }
4152
4153 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4154 {
4155 bindDrawFramebuffer(framebuffer);
4156 }
4157}
4158
4159void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
4160{
4161 ASSERT(target == GL_RENDERBUFFER);
4162 Renderbuffer *object =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05004163 mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
Jamie Madill4928b7c2017-06-20 12:57:39 -04004164 mGLState.setRenderbufferBinding(this, object);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004165}
4166
JiangYizhoubddc46b2016-12-09 09:50:51 +08004167void Context::texStorage2DMultisample(GLenum target,
4168 GLsizei samples,
4169 GLenum internalformat,
4170 GLsizei width,
4171 GLsizei height,
4172 GLboolean fixedsamplelocations)
4173{
4174 Extents size(width, height, 1);
4175 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05004176 handleError(texture->setStorageMultisample(this, target, samples, internalformat, size,
JiangYizhoubddc46b2016-12-09 09:50:51 +08004177 fixedsamplelocations));
4178}
4179
4180void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
4181{
Jamie Madilldd43e6c2017-03-24 14:18:49 -04004182 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
JiangYizhoubddc46b2016-12-09 09:50:51 +08004183 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
4184
4185 switch (pname)
4186 {
4187 case GL_SAMPLE_POSITION:
4188 handleError(framebuffer->getSamplePosition(index, val));
4189 break;
4190 default:
4191 UNREACHABLE();
4192 }
4193}
4194
Jamie Madille8fb6402017-02-14 17:56:40 -05004195void Context::renderbufferStorage(GLenum target,
4196 GLenum internalformat,
4197 GLsizei width,
4198 GLsizei height)
4199{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004200 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4201 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
4202
Jamie Madille8fb6402017-02-14 17:56:40 -05004203 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4928b7c2017-06-20 12:57:39 -04004204 handleError(renderbuffer->setStorage(this, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004205}
4206
4207void Context::renderbufferStorageMultisample(GLenum target,
4208 GLsizei samples,
4209 GLenum internalformat,
4210 GLsizei width,
4211 GLsizei height)
4212{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004213 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4214 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
Jamie Madille8fb6402017-02-14 17:56:40 -05004215
4216 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004217 handleError(
Jamie Madill4928b7c2017-06-20 12:57:39 -04004218 renderbuffer->setStorageMultisample(this, samples, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004219}
4220
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004221void Context::getSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)
4222{
4223 const FenceSync *syncObject = getFenceSync(sync);
Geoff Lang82483b92017-04-11 15:33:00 -04004224 handleError(QuerySynciv(syncObject, pname, bufSize, length, values));
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004225}
4226
JiangYizhoue18e6392017-02-20 10:32:23 +08004227void Context::getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
4228{
4229 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4230 QueryFramebufferParameteriv(framebuffer, pname, params);
4231}
4232
4233void Context::setFramebufferParameteri(GLenum target, GLenum pname, GLint param)
4234{
4235 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4236 SetFramebufferParameteri(framebuffer, pname, param);
4237}
4238
Jamie Madillb3f26b92017-07-19 15:07:41 -04004239Error Context::getScratchBuffer(size_t requstedSizeBytes,
4240 angle::MemoryBuffer **scratchBufferOut) const
Jamie Madille14951e2017-03-09 18:55:16 -05004241{
Jamie Madillb3f26b92017-07-19 15:07:41 -04004242 if (!mScratchBuffer.get(requstedSizeBytes, scratchBufferOut))
4243 {
4244 return OutOfMemory() << "Failed to allocate internal buffer.";
4245 }
4246 return NoError();
4247}
4248
4249Error Context::getZeroFilledBuffer(size_t requstedSizeBytes,
4250 angle::MemoryBuffer **zeroBufferOut) const
4251{
4252 if (!mZeroFilledBuffer.getInitialized(requstedSizeBytes, zeroBufferOut, 0))
Jamie Madille14951e2017-03-09 18:55:16 -05004253 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004254 return OutOfMemory() << "Failed to allocate internal buffer.";
Jamie Madille14951e2017-03-09 18:55:16 -05004255 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004256 return NoError();
Jamie Madille14951e2017-03-09 18:55:16 -05004257}
4258
Xinghua Cao2b396592017-03-29 15:36:04 +08004259void Context::dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ)
4260{
4261 if (numGroupsX == 0u || numGroupsY == 0u || numGroupsZ == 0u)
4262 {
4263 return;
4264 }
4265
Jamie Madillfe548342017-06-19 11:13:24 -04004266 mImplementation->dispatchCompute(this, numGroupsX, numGroupsY, numGroupsZ);
Xinghua Cao2b396592017-03-29 15:36:04 +08004267}
4268
JiangYizhou165361c2017-06-07 14:56:57 +08004269void Context::texStorage2D(GLenum target,
4270 GLsizei levels,
4271 GLenum internalFormat,
4272 GLsizei width,
4273 GLsizei height)
4274{
4275 Extents size(width, height, 1);
4276 Texture *texture = getTargetTexture(target);
4277 handleError(texture->setStorage(this, target, levels, internalFormat, size));
4278}
4279
4280void Context::texStorage3D(GLenum target,
4281 GLsizei levels,
4282 GLenum internalFormat,
4283 GLsizei width,
4284 GLsizei height,
4285 GLsizei depth)
4286{
4287 Extents size(width, height, depth);
4288 Texture *texture = getTargetTexture(target);
4289 handleError(texture->setStorage(this, target, levels, internalFormat, size));
4290}
4291
Jamie Madillc1d770e2017-04-13 17:31:24 -04004292GLenum Context::checkFramebufferStatus(GLenum target)
4293{
4294 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4295 ASSERT(framebuffer);
4296
4297 return framebuffer->checkStatus(this);
4298}
4299
4300void Context::compileShader(GLuint shader)
4301{
4302 Shader *shaderObject = GetValidShader(this, shader);
4303 if (!shaderObject)
4304 {
4305 return;
4306 }
4307 shaderObject->compile(this);
4308}
4309
4310void Context::deleteBuffers(GLsizei n, const GLuint *buffers)
4311{
4312 for (int i = 0; i < n; i++)
4313 {
4314 deleteBuffer(buffers[i]);
4315 }
4316}
4317
4318void Context::deleteFramebuffers(GLsizei n, const GLuint *framebuffers)
4319{
4320 for (int i = 0; i < n; i++)
4321 {
4322 if (framebuffers[i] != 0)
4323 {
4324 deleteFramebuffer(framebuffers[i]);
4325 }
4326 }
4327}
4328
4329void Context::deleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)
4330{
4331 for (int i = 0; i < n; i++)
4332 {
4333 deleteRenderbuffer(renderbuffers[i]);
4334 }
4335}
4336
4337void Context::deleteTextures(GLsizei n, const GLuint *textures)
4338{
4339 for (int i = 0; i < n; i++)
4340 {
4341 if (textures[i] != 0)
4342 {
4343 deleteTexture(textures[i]);
4344 }
4345 }
4346}
4347
4348void Context::detachShader(GLuint program, GLuint shader)
4349{
4350 Program *programObject = getProgram(program);
4351 ASSERT(programObject);
4352
4353 Shader *shaderObject = getShader(shader);
4354 ASSERT(shaderObject);
4355
4356 programObject->detachShader(this, shaderObject);
4357}
4358
4359void Context::genBuffers(GLsizei n, GLuint *buffers)
4360{
4361 for (int i = 0; i < n; i++)
4362 {
4363 buffers[i] = createBuffer();
4364 }
4365}
4366
4367void Context::genFramebuffers(GLsizei n, GLuint *framebuffers)
4368{
4369 for (int i = 0; i < n; i++)
4370 {
4371 framebuffers[i] = createFramebuffer();
4372 }
4373}
4374
4375void Context::genRenderbuffers(GLsizei n, GLuint *renderbuffers)
4376{
4377 for (int i = 0; i < n; i++)
4378 {
4379 renderbuffers[i] = createRenderbuffer();
4380 }
4381}
4382
4383void Context::genTextures(GLsizei n, GLuint *textures)
4384{
4385 for (int i = 0; i < n; i++)
4386 {
4387 textures[i] = createTexture();
4388 }
4389}
4390
4391void Context::getActiveAttrib(GLuint program,
4392 GLuint index,
4393 GLsizei bufsize,
4394 GLsizei *length,
4395 GLint *size,
4396 GLenum *type,
4397 GLchar *name)
4398{
4399 Program *programObject = getProgram(program);
4400 ASSERT(programObject);
4401 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
4402}
4403
4404void Context::getActiveUniform(GLuint program,
4405 GLuint index,
4406 GLsizei bufsize,
4407 GLsizei *length,
4408 GLint *size,
4409 GLenum *type,
4410 GLchar *name)
4411{
4412 Program *programObject = getProgram(program);
4413 ASSERT(programObject);
4414 programObject->getActiveUniform(index, bufsize, length, size, type, name);
4415}
4416
4417void Context::getAttachedShaders(GLuint program, GLsizei maxcount, GLsizei *count, GLuint *shaders)
4418{
4419 Program *programObject = getProgram(program);
4420 ASSERT(programObject);
4421 programObject->getAttachedShaders(maxcount, count, shaders);
4422}
4423
4424GLint Context::getAttribLocation(GLuint program, const GLchar *name)
4425{
4426 Program *programObject = getProgram(program);
4427 ASSERT(programObject);
4428 return programObject->getAttributeLocation(name);
4429}
4430
4431void Context::getBooleanv(GLenum pname, GLboolean *params)
4432{
4433 GLenum nativeType;
4434 unsigned int numParams = 0;
4435 getQueryParameterInfo(pname, &nativeType, &numParams);
4436
4437 if (nativeType == GL_BOOL)
4438 {
4439 getBooleanvImpl(pname, params);
4440 }
4441 else
4442 {
4443 CastStateValues(this, nativeType, pname, numParams, params);
4444 }
4445}
4446
4447void Context::getFloatv(GLenum pname, GLfloat *params)
4448{
4449 GLenum nativeType;
4450 unsigned int numParams = 0;
4451 getQueryParameterInfo(pname, &nativeType, &numParams);
4452
4453 if (nativeType == GL_FLOAT)
4454 {
4455 getFloatvImpl(pname, params);
4456 }
4457 else
4458 {
4459 CastStateValues(this, nativeType, pname, numParams, params);
4460 }
4461}
4462
4463void Context::getIntegerv(GLenum pname, GLint *params)
4464{
4465 GLenum nativeType;
4466 unsigned int numParams = 0;
4467 getQueryParameterInfo(pname, &nativeType, &numParams);
4468
4469 if (nativeType == GL_INT)
4470 {
4471 getIntegervImpl(pname, params);
4472 }
4473 else
4474 {
4475 CastStateValues(this, nativeType, pname, numParams, params);
4476 }
4477}
4478
4479void Context::getProgramiv(GLuint program, GLenum pname, GLint *params)
4480{
4481 Program *programObject = getProgram(program);
4482 ASSERT(programObject);
Jamie Madillffe00c02017-06-27 16:26:55 -04004483 QueryProgramiv(this, programObject, pname, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004484}
4485
Jamie Madillbe849e42017-05-02 15:49:00 -04004486void Context::getProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei *length, GLchar *infolog)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004487{
4488 Program *programObject = getProgram(program);
4489 ASSERT(programObject);
4490 programObject->getInfoLog(bufsize, length, infolog);
4491}
4492
4493void Context::getShaderiv(GLuint shader, GLenum pname, GLint *params)
4494{
4495 Shader *shaderObject = getShader(shader);
4496 ASSERT(shaderObject);
Jamie Madillbd044ed2017-06-05 12:59:21 -04004497 QueryShaderiv(this, shaderObject, pname, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004498}
4499
4500void Context::getShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *infolog)
4501{
4502 Shader *shaderObject = getShader(shader);
4503 ASSERT(shaderObject);
Jamie Madillbd044ed2017-06-05 12:59:21 -04004504 shaderObject->getInfoLog(this, bufsize, length, infolog);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004505}
4506
4507void Context::getShaderPrecisionFormat(GLenum shadertype,
4508 GLenum precisiontype,
4509 GLint *range,
4510 GLint *precision)
4511{
4512 // TODO(jmadill): Compute shaders.
4513
4514 switch (shadertype)
4515 {
4516 case GL_VERTEX_SHADER:
4517 switch (precisiontype)
4518 {
4519 case GL_LOW_FLOAT:
4520 mCaps.vertexLowpFloat.get(range, precision);
4521 break;
4522 case GL_MEDIUM_FLOAT:
4523 mCaps.vertexMediumpFloat.get(range, precision);
4524 break;
4525 case GL_HIGH_FLOAT:
4526 mCaps.vertexHighpFloat.get(range, precision);
4527 break;
4528
4529 case GL_LOW_INT:
4530 mCaps.vertexLowpInt.get(range, precision);
4531 break;
4532 case GL_MEDIUM_INT:
4533 mCaps.vertexMediumpInt.get(range, precision);
4534 break;
4535 case GL_HIGH_INT:
4536 mCaps.vertexHighpInt.get(range, precision);
4537 break;
4538
4539 default:
4540 UNREACHABLE();
4541 return;
4542 }
4543 break;
4544
4545 case GL_FRAGMENT_SHADER:
4546 switch (precisiontype)
4547 {
4548 case GL_LOW_FLOAT:
4549 mCaps.fragmentLowpFloat.get(range, precision);
4550 break;
4551 case GL_MEDIUM_FLOAT:
4552 mCaps.fragmentMediumpFloat.get(range, precision);
4553 break;
4554 case GL_HIGH_FLOAT:
4555 mCaps.fragmentHighpFloat.get(range, precision);
4556 break;
4557
4558 case GL_LOW_INT:
4559 mCaps.fragmentLowpInt.get(range, precision);
4560 break;
4561 case GL_MEDIUM_INT:
4562 mCaps.fragmentMediumpInt.get(range, precision);
4563 break;
4564 case GL_HIGH_INT:
4565 mCaps.fragmentHighpInt.get(range, precision);
4566 break;
4567
4568 default:
4569 UNREACHABLE();
4570 return;
4571 }
4572 break;
4573
4574 default:
4575 UNREACHABLE();
4576 return;
4577 }
4578}
4579
4580void Context::getShaderSource(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source)
4581{
4582 Shader *shaderObject = getShader(shader);
4583 ASSERT(shaderObject);
4584 shaderObject->getSource(bufsize, length, source);
4585}
4586
4587void Context::getUniformfv(GLuint program, GLint location, GLfloat *params)
4588{
4589 Program *programObject = getProgram(program);
4590 ASSERT(programObject);
4591 programObject->getUniformfv(location, params);
4592}
4593
4594void Context::getUniformiv(GLuint program, GLint location, GLint *params)
4595{
4596 Program *programObject = getProgram(program);
4597 ASSERT(programObject);
4598 programObject->getUniformiv(location, params);
4599}
4600
4601GLint Context::getUniformLocation(GLuint program, const GLchar *name)
4602{
4603 Program *programObject = getProgram(program);
4604 ASSERT(programObject);
4605 return programObject->getUniformLocation(name);
4606}
4607
4608GLboolean Context::isBuffer(GLuint buffer)
4609{
4610 if (buffer == 0)
4611 {
4612 return GL_FALSE;
4613 }
4614
4615 return (getBuffer(buffer) ? GL_TRUE : GL_FALSE);
4616}
4617
4618GLboolean Context::isEnabled(GLenum cap)
4619{
4620 return mGLState.getEnableFeature(cap);
4621}
4622
4623GLboolean Context::isFramebuffer(GLuint framebuffer)
4624{
4625 if (framebuffer == 0)
4626 {
4627 return GL_FALSE;
4628 }
4629
4630 return (getFramebuffer(framebuffer) ? GL_TRUE : GL_FALSE);
4631}
4632
4633GLboolean Context::isProgram(GLuint program)
4634{
4635 if (program == 0)
4636 {
4637 return GL_FALSE;
4638 }
4639
4640 return (getProgram(program) ? GL_TRUE : GL_FALSE);
4641}
4642
4643GLboolean Context::isRenderbuffer(GLuint renderbuffer)
4644{
4645 if (renderbuffer == 0)
4646 {
4647 return GL_FALSE;
4648 }
4649
4650 return (getRenderbuffer(renderbuffer) ? GL_TRUE : GL_FALSE);
4651}
4652
4653GLboolean Context::isShader(GLuint shader)
4654{
4655 if (shader == 0)
4656 {
4657 return GL_FALSE;
4658 }
4659
4660 return (getShader(shader) ? GL_TRUE : GL_FALSE);
4661}
4662
4663GLboolean Context::isTexture(GLuint texture)
4664{
4665 if (texture == 0)
4666 {
4667 return GL_FALSE;
4668 }
4669
4670 return (getTexture(texture) ? GL_TRUE : GL_FALSE);
4671}
4672
4673void Context::linkProgram(GLuint program)
4674{
4675 Program *programObject = getProgram(program);
4676 ASSERT(programObject);
4677 handleError(programObject->link(this));
4678}
4679
4680void Context::releaseShaderCompiler()
4681{
Jamie Madill4928b7c2017-06-20 12:57:39 -04004682 mCompiler.set(this, nullptr);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004683}
4684
4685void Context::shaderBinary(GLsizei n,
4686 const GLuint *shaders,
4687 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04004688 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004689 GLsizei length)
4690{
4691 // No binary shader formats are supported.
4692 UNIMPLEMENTED();
4693}
4694
4695void Context::shaderSource(GLuint shader,
4696 GLsizei count,
4697 const GLchar *const *string,
4698 const GLint *length)
4699{
4700 Shader *shaderObject = getShader(shader);
4701 ASSERT(shaderObject);
4702 shaderObject->setSource(count, string, length);
4703}
4704
4705void Context::stencilFunc(GLenum func, GLint ref, GLuint mask)
4706{
4707 stencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
4708}
4709
4710void Context::stencilMask(GLuint mask)
4711{
4712 stencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4713}
4714
4715void Context::stencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4716{
4717 stencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4718}
4719
4720void Context::uniform1f(GLint location, GLfloat x)
4721{
4722 Program *program = mGLState.getProgram();
4723 program->setUniform1fv(location, 1, &x);
4724}
4725
4726void Context::uniform1fv(GLint location, GLsizei count, const GLfloat *v)
4727{
4728 Program *program = mGLState.getProgram();
4729 program->setUniform1fv(location, count, v);
4730}
4731
4732void Context::uniform1i(GLint location, GLint x)
4733{
4734 Program *program = mGLState.getProgram();
4735 program->setUniform1iv(location, 1, &x);
4736}
4737
4738void Context::uniform1iv(GLint location, GLsizei count, const GLint *v)
4739{
4740 Program *program = mGLState.getProgram();
4741 program->setUniform1iv(location, count, v);
4742}
4743
4744void Context::uniform2f(GLint location, GLfloat x, GLfloat y)
4745{
4746 GLfloat xy[2] = {x, y};
4747 Program *program = mGLState.getProgram();
4748 program->setUniform2fv(location, 1, xy);
4749}
4750
4751void Context::uniform2fv(GLint location, GLsizei count, const GLfloat *v)
4752{
4753 Program *program = mGLState.getProgram();
4754 program->setUniform2fv(location, count, v);
4755}
4756
4757void Context::uniform2i(GLint location, GLint x, GLint y)
4758{
4759 GLint xy[2] = {x, y};
4760 Program *program = mGLState.getProgram();
4761 program->setUniform2iv(location, 1, xy);
4762}
4763
4764void Context::uniform2iv(GLint location, GLsizei count, const GLint *v)
4765{
4766 Program *program = mGLState.getProgram();
4767 program->setUniform2iv(location, count, v);
4768}
4769
4770void Context::uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4771{
4772 GLfloat xyz[3] = {x, y, z};
4773 Program *program = mGLState.getProgram();
4774 program->setUniform3fv(location, 1, xyz);
4775}
4776
4777void Context::uniform3fv(GLint location, GLsizei count, const GLfloat *v)
4778{
4779 Program *program = mGLState.getProgram();
4780 program->setUniform3fv(location, count, v);
4781}
4782
4783void Context::uniform3i(GLint location, GLint x, GLint y, GLint z)
4784{
4785 GLint xyz[3] = {x, y, z};
4786 Program *program = mGLState.getProgram();
4787 program->setUniform3iv(location, 1, xyz);
4788}
4789
4790void Context::uniform3iv(GLint location, GLsizei count, const GLint *v)
4791{
4792 Program *program = mGLState.getProgram();
4793 program->setUniform3iv(location, count, v);
4794}
4795
4796void Context::uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4797{
4798 GLfloat xyzw[4] = {x, y, z, w};
4799 Program *program = mGLState.getProgram();
4800 program->setUniform4fv(location, 1, xyzw);
4801}
4802
4803void Context::uniform4fv(GLint location, GLsizei count, const GLfloat *v)
4804{
4805 Program *program = mGLState.getProgram();
4806 program->setUniform4fv(location, count, v);
4807}
4808
4809void Context::uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4810{
4811 GLint xyzw[4] = {x, y, z, w};
4812 Program *program = mGLState.getProgram();
4813 program->setUniform4iv(location, 1, xyzw);
4814}
4815
4816void Context::uniform4iv(GLint location, GLsizei count, const GLint *v)
4817{
4818 Program *program = mGLState.getProgram();
4819 program->setUniform4iv(location, count, v);
4820}
4821
4822void Context::uniformMatrix2fv(GLint location,
4823 GLsizei count,
4824 GLboolean transpose,
4825 const GLfloat *value)
4826{
4827 Program *program = mGLState.getProgram();
4828 program->setUniformMatrix2fv(location, count, transpose, value);
4829}
4830
4831void Context::uniformMatrix3fv(GLint location,
4832 GLsizei count,
4833 GLboolean transpose,
4834 const GLfloat *value)
4835{
4836 Program *program = mGLState.getProgram();
4837 program->setUniformMatrix3fv(location, count, transpose, value);
4838}
4839
4840void Context::uniformMatrix4fv(GLint location,
4841 GLsizei count,
4842 GLboolean transpose,
4843 const GLfloat *value)
4844{
4845 Program *program = mGLState.getProgram();
4846 program->setUniformMatrix4fv(location, count, transpose, value);
4847}
4848
4849void Context::validateProgram(GLuint program)
4850{
4851 Program *programObject = getProgram(program);
4852 ASSERT(programObject);
4853 programObject->validate(mCaps);
4854}
4855
Jamie Madilld04908b2017-06-09 14:15:35 -04004856void Context::getProgramBinary(GLuint program,
4857 GLsizei bufSize,
4858 GLsizei *length,
4859 GLenum *binaryFormat,
4860 void *binary)
4861{
4862 Program *programObject = getProgram(program);
4863 ASSERT(programObject != nullptr);
4864
4865 handleError(programObject->saveBinary(this, binaryFormat, binary, bufSize, length));
4866}
4867
4868void Context::programBinary(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length)
4869{
4870 Program *programObject = getProgram(program);
4871 ASSERT(programObject != nullptr);
Jamie Madillb6664922017-07-25 12:55:04 -04004872
Jamie Madilld04908b2017-06-09 14:15:35 -04004873 handleError(programObject->loadBinary(this, binaryFormat, binary, length));
4874}
4875
Jamie Madillff325f12017-08-26 15:06:05 -04004876void Context::uniform1ui(GLint location, GLuint v0)
4877{
4878 Program *program = mGLState.getProgram();
4879 program->setUniform1uiv(location, 1, &v0);
4880}
4881
4882void Context::uniform2ui(GLint location, GLuint v0, GLuint v1)
4883{
4884 Program *program = mGLState.getProgram();
4885 const GLuint xy[] = {v0, v1};
4886 program->setUniform2uiv(location, 1, xy);
4887}
4888
4889void Context::uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
4890{
4891 Program *program = mGLState.getProgram();
4892 const GLuint xyz[] = {v0, v1, v2};
4893 program->setUniform3uiv(location, 1, xyz);
4894}
4895
4896void Context::uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
4897{
4898 Program *program = mGLState.getProgram();
4899 const GLuint xyzw[] = {v0, v1, v2, v3};
4900 program->setUniform4uiv(location, 1, xyzw);
4901}
4902
4903void Context::uniform1uiv(GLint location, GLsizei count, const GLuint *value)
4904{
4905 Program *program = mGLState.getProgram();
4906 program->setUniform1uiv(location, count, value);
4907}
4908void Context::uniform2uiv(GLint location, GLsizei count, const GLuint *value)
4909{
4910 Program *program = mGLState.getProgram();
4911 program->setUniform2uiv(location, count, value);
4912}
4913
4914void Context::uniform3uiv(GLint location, GLsizei count, const GLuint *value)
4915{
4916 Program *program = mGLState.getProgram();
4917 program->setUniform3uiv(location, count, value);
4918}
4919
4920void Context::uniform4uiv(GLint location, GLsizei count, const GLuint *value)
4921{
4922 Program *program = mGLState.getProgram();
4923 program->setUniform4uiv(location, count, value);
4924}
4925
Jamie Madillf0e04492017-08-26 15:28:42 -04004926void Context::genQueries(GLsizei n, GLuint *ids)
4927{
4928 for (GLsizei i = 0; i < n; i++)
4929 {
4930 GLuint handle = mQueryHandleAllocator.allocate();
4931 mQueryMap.assign(handle, nullptr);
4932 ids[i] = handle;
4933 }
4934}
4935
4936void Context::deleteQueries(GLsizei n, const GLuint *ids)
4937{
4938 for (int i = 0; i < n; i++)
4939 {
4940 GLuint query = ids[i];
4941
4942 Query *queryObject = nullptr;
4943 if (mQueryMap.erase(query, &queryObject))
4944 {
4945 mQueryHandleAllocator.release(query);
4946 if (queryObject)
4947 {
4948 queryObject->release(this);
4949 }
4950 }
4951 }
4952}
4953
4954GLboolean Context::isQuery(GLuint id)
4955{
4956 return (getQuery(id, false, GL_NONE) != nullptr) ? GL_TRUE : GL_FALSE;
4957}
4958
Jamie Madillc8c95812017-08-26 18:40:09 -04004959void Context::uniformMatrix2x3fv(GLint location,
4960 GLsizei count,
4961 GLboolean transpose,
4962 const GLfloat *value)
4963{
4964 Program *program = mGLState.getProgram();
4965 program->setUniformMatrix2x3fv(location, count, transpose, value);
4966}
4967
4968void Context::uniformMatrix3x2fv(GLint location,
4969 GLsizei count,
4970 GLboolean transpose,
4971 const GLfloat *value)
4972{
4973 Program *program = mGLState.getProgram();
4974 program->setUniformMatrix3x2fv(location, count, transpose, value);
4975}
4976
4977void Context::uniformMatrix2x4fv(GLint location,
4978 GLsizei count,
4979 GLboolean transpose,
4980 const GLfloat *value)
4981{
4982 Program *program = mGLState.getProgram();
4983 program->setUniformMatrix2x4fv(location, count, transpose, value);
4984}
4985
4986void Context::uniformMatrix4x2fv(GLint location,
4987 GLsizei count,
4988 GLboolean transpose,
4989 const GLfloat *value)
4990{
4991 Program *program = mGLState.getProgram();
4992 program->setUniformMatrix4x2fv(location, count, transpose, value);
4993}
4994
4995void Context::uniformMatrix3x4fv(GLint location,
4996 GLsizei count,
4997 GLboolean transpose,
4998 const GLfloat *value)
4999{
5000 Program *program = mGLState.getProgram();
5001 program->setUniformMatrix3x4fv(location, count, transpose, value);
5002}
5003
5004void Context::uniformMatrix4x3fv(GLint location,
5005 GLsizei count,
5006 GLboolean transpose,
5007 const GLfloat *value)
5008{
5009 Program *program = mGLState.getProgram();
5010 program->setUniformMatrix4x3fv(location, count, transpose, value);
5011}
5012
Jamie Madillc29968b2016-01-20 11:17:23 -05005013} // namespace gl