blob: 8a355f0cd964b69654480a91f82ae487cb8ffbb0 [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{
Jamie Madill14bbb3f2017-09-12 15:23:01 -0400283 mImplementation->setMemoryProgramCache(memoryProgramCache);
284
Jamie Madill4e0e6f82017-02-17 11:06:03 -0500285 initCaps(displayExtensions);
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700286 initWorkarounds();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400287
Jamie Madill4928b7c2017-06-20 12:57:39 -0400288 mGLState.initialize(this, GetDebug(attribs), GetBindGeneratesResource(attribs),
Jamie Madillc43be722017-07-13 16:22:14 -0400289 GetClientArraysEnabled(attribs), robustResourceInit,
290 mMemoryProgramCache != nullptr);
Régis Fénéon83107972015-02-05 12:57:44 +0100291
Shannon Woods53a94a82014-06-24 15:20:36 -0400292 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400293
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000294 // [OpenGL ES 2.0.24] section 3.7 page 83:
295 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
296 // and cube map texture state vectors respectively associated with them.
297 // In order that access to these initial textures not be lost, they are treated as texture
298 // objects all of whose names are 0.
299
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400300 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400301 mZeroTextures[GL_TEXTURE_2D].set(this, zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500302
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400303 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400304 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(this, zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400305
Geoff Langeb66a6e2016-10-31 13:06:12 -0400306 if (getClientVersion() >= Version(3, 0))
Geoff Lang76b10c92014-09-05 16:28:14 -0400307 {
308 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400309 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400310 mZeroTextures[GL_TEXTURE_3D].set(this, zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400311
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400312 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400313 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(this, zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400314 }
Geoff Lang3b573612016-10-31 14:08:10 -0400315 if (getClientVersion() >= Version(3, 1))
316 {
317 Texture *zeroTexture2DMultisample =
318 new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_MULTISAMPLE);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400319 mZeroTextures[GL_TEXTURE_2D_MULTISAMPLE].set(this, zeroTexture2DMultisample);
Jiajia Qin6eafb042016-12-27 17:04:07 +0800320
321 bindGenericAtomicCounterBuffer(0);
322 for (unsigned int i = 0; i < mCaps.maxAtomicCounterBufferBindings; i++)
323 {
324 bindIndexedAtomicCounterBuffer(0, i, 0, 0);
325 }
Jiajia Qinf546e7d2017-03-27 14:12:59 +0800326
327 bindGenericShaderStorageBuffer(0);
328 for (unsigned int i = 0; i < mCaps.maxShaderStorageBufferBindings; i++)
329 {
330 bindIndexedShaderStorageBuffer(0, i, 0, 0);
331 }
Geoff Lang3b573612016-10-31 14:08:10 -0400332 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000333
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400334 if (mExtensions.textureRectangle)
335 {
336 Texture *zeroTextureRectangle =
337 new Texture(mImplementation.get(), 0, GL_TEXTURE_RECTANGLE_ANGLE);
338 mZeroTextures[GL_TEXTURE_RECTANGLE_ANGLE].set(this, zeroTextureRectangle);
339 }
340
Ian Ewellbda75592016-04-18 17:25:54 -0400341 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
342 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400343 Texture *zeroTextureExternal =
344 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400345 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(this, zeroTextureExternal);
Ian Ewellbda75592016-04-18 17:25:54 -0400346 }
347
Jamie Madill4928b7c2017-06-20 12:57:39 -0400348 mGLState.initializeZeroTextures(this, mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500349
Jamie Madill57a89722013-07-02 11:57:03 -0400350 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000351 bindArrayBuffer(0);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800352 bindDrawIndirectBuffer(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000353 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400354
Jamie Madill01a80ee2016-11-07 12:06:18 -0500355 bindRenderbuffer(GL_RENDERBUFFER, 0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000356
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000357 bindGenericUniformBuffer(0);
Geoff Lang4dc3af02016-11-18 14:09:27 -0500358 for (unsigned int i = 0; i < mCaps.maxUniformBufferBindings; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000359 {
360 bindIndexedUniformBuffer(0, i, 0, -1);
361 }
362
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000363 bindCopyReadBuffer(0);
364 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000365 bindPixelPackBuffer(0);
366 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000367
Geoff Langeb66a6e2016-10-31 13:06:12 -0400368 if (getClientVersion() >= Version(3, 0))
Geoff Lang1a683462015-09-29 15:09:59 -0400369 {
370 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
371 // In the initial state, a default transform feedback object is bound and treated as
372 // a transform feedback object with a name of zero. That object is bound any time
373 // BindTransformFeedback is called with id of zero
Jamie Madillf0dcb8b2017-08-26 19:05:13 -0400374 bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
Geoff Lang1a683462015-09-29 15:09:59 -0400375 }
Geoff Langc8058452014-02-03 12:04:11 -0500376
Jamie Madillad9f24e2016-02-12 09:27:24 -0500377 // Initialize dirty bit masks
378 // TODO(jmadill): additional ES3 state
379 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
380 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
381 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
382 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
383 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
384 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400385 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500386 // No dirty objects.
387
388 // Readpixels uses the pack state and read FBO
389 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
390 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
391 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
392 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
393 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400394 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500395 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
396
397 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
398 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
399 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
400 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
401 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
402 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
403 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
404 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
405 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
406 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
407 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
408 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
409
410 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
411 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700412 mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500413 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
414 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400415
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400416 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000417}
418
Jamie Madill4928b7c2017-06-20 12:57:39 -0400419egl::Error Context::onDestroy(const egl::Display *display)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000420{
Corentin Wallez80b24112015-08-25 16:41:57 -0400421 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000422 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400423 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000424 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400425 mFenceNVMap.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000426
Corentin Wallez80b24112015-08-25 16:41:57 -0400427 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000428 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400429 if (query.second != nullptr)
430 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400431 query.second->release(this);
Geoff Langf0aa8422015-09-29 15:08:34 -0400432 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000433 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400434 mQueryMap.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000435
Corentin Wallez80b24112015-08-25 16:41:57 -0400436 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400437 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400438 if (vertexArray.second)
439 {
440 vertexArray.second->onDestroy(this);
441 }
Jamie Madill57a89722013-07-02 11:57:03 -0400442 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400443 mVertexArrayMap.clear();
Jamie Madill57a89722013-07-02 11:57:03 -0400444
Corentin Wallez80b24112015-08-25 16:41:57 -0400445 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500446 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500447 if (transformFeedback.second != nullptr)
448 {
Jamie Madill6c1f6712017-02-14 19:08:04 -0500449 transformFeedback.second->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500450 }
Geoff Langc8058452014-02-03 12:04:11 -0500451 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400452 mTransformFeedbackMap.clear();
Geoff Langc8058452014-02-03 12:04:11 -0500453
Jamie Madilldedd7b92014-11-05 16:30:36 -0500454 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400455 {
Jamie Madill71c88b32017-09-14 22:20:29 -0400456 ANGLE_TRY(zeroTexture.second->onDestroy(this));
Jamie Madill4928b7c2017-06-20 12:57:39 -0400457 zeroTexture.second.set(this, nullptr);
Geoff Lang76b10c92014-09-05 16:28:14 -0400458 }
459 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000460
Corentin Wallezccab69d2017-01-27 16:57:15 -0500461 SafeDelete(mSurfacelessFramebuffer);
462
Jamie Madill4928b7c2017-06-20 12:57:39 -0400463 ANGLE_TRY(releaseSurface(display));
Jamie Madill2f348d22017-06-05 10:50:59 -0400464 releaseShaderCompiler();
Jamie Madill6c1f6712017-02-14 19:08:04 -0500465
Jamie Madill4928b7c2017-06-20 12:57:39 -0400466 mGLState.reset(this);
467
Jamie Madill6c1f6712017-02-14 19:08:04 -0500468 mState.mBuffers->release(this);
469 mState.mShaderPrograms->release(this);
470 mState.mTextures->release(this);
471 mState.mRenderbuffers->release(this);
472 mState.mSamplers->release(this);
Jamie Madill70b5bb02017-08-28 13:32:37 -0400473 mState.mSyncs->release(this);
Jamie Madill6c1f6712017-02-14 19:08:04 -0500474 mState.mPaths->release(this);
475 mState.mFramebuffers->release(this);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400476
477 return egl::NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000478}
479
Jamie Madill70ee0f62017-02-06 16:04:20 -0500480Context::~Context()
481{
482}
483
Jamie Madill4928b7c2017-06-20 12:57:39 -0400484egl::Error Context::makeCurrent(egl::Display *display, egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000485{
Jamie Madill61e16b42017-06-19 11:13:23 -0400486 mCurrentDisplay = display;
487
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000488 if (!mHasBeenCurrent)
489 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000490 initRendererString();
Geoff Langc339c4e2016-11-29 10:37:36 -0500491 initVersionStrings();
Geoff Langcec35902014-04-16 10:52:36 -0400492 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000493
Corentin Wallezc295e512017-01-27 17:47:50 -0500494 int width = 0;
495 int height = 0;
496 if (surface != nullptr)
497 {
498 width = surface->getWidth();
499 height = surface->getHeight();
500 }
501
502 mGLState.setViewportParams(0, 0, width, height);
503 mGLState.setScissorParams(0, 0, width, height);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000504
505 mHasBeenCurrent = true;
506 }
507
Jamie Madill1b94d432015-08-07 13:23:23 -0400508 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700509 mGLState.setAllDirtyBits();
Jamie Madill81c2e252017-09-09 23:32:46 -0400510 mGLState.setAllDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -0400511
Jamie Madill4928b7c2017-06-20 12:57:39 -0400512 ANGLE_TRY(releaseSurface(display));
Corentin Wallezccab69d2017-01-27 16:57:15 -0500513
514 Framebuffer *newDefault = nullptr;
515 if (surface != nullptr)
516 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400517 ANGLE_TRY(surface->setIsCurrent(this, true));
Corentin Wallezccab69d2017-01-27 16:57:15 -0500518 mCurrentSurface = surface;
519 newDefault = surface->getDefaultFramebuffer();
520 }
521 else
522 {
523 if (mSurfacelessFramebuffer == nullptr)
524 {
525 mSurfacelessFramebuffer = new Framebuffer(mImplementation.get());
526 }
527
528 newDefault = mSurfacelessFramebuffer;
529 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000530
Corentin Wallez37c39792015-08-20 14:19:46 -0400531 // Update default framebuffer, the binding of the previous default
532 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400533 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700534 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400535 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700536 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400537 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700538 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400539 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700540 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400541 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500542 mState.mFramebuffers->setDefaultFramebuffer(newDefault);
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400543 }
Ian Ewell292f0052016-02-04 10:37:32 -0500544
545 // Notify the renderer of a context switch
Jamie Madill4928b7c2017-06-20 12:57:39 -0400546 mImplementation->onMakeCurrent(this);
547 return egl::NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000548}
549
Jamie Madill4928b7c2017-06-20 12:57:39 -0400550egl::Error Context::releaseSurface(const egl::Display *display)
Jamie Madill77a72f62015-04-14 11:18:32 -0400551{
Corentin Wallez37c39792015-08-20 14:19:46 -0400552 // Remove the default framebuffer
Corentin Wallezc295e512017-01-27 17:47:50 -0500553 Framebuffer *currentDefault = nullptr;
554 if (mCurrentSurface != nullptr)
Corentin Wallez51706ea2015-08-07 14:39:22 -0400555 {
Corentin Wallezc295e512017-01-27 17:47:50 -0500556 currentDefault = mCurrentSurface->getDefaultFramebuffer();
557 }
558 else if (mSurfacelessFramebuffer != nullptr)
559 {
560 currentDefault = mSurfacelessFramebuffer;
Corentin Wallez51706ea2015-08-07 14:39:22 -0400561 }
562
Corentin Wallezc295e512017-01-27 17:47:50 -0500563 if (mGLState.getReadFramebuffer() == currentDefault)
564 {
565 mGLState.setReadFramebufferBinding(nullptr);
566 }
567 if (mGLState.getDrawFramebuffer() == currentDefault)
568 {
569 mGLState.setDrawFramebufferBinding(nullptr);
570 }
571 mState.mFramebuffers->setDefaultFramebuffer(nullptr);
572
573 if (mCurrentSurface)
574 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400575 ANGLE_TRY(mCurrentSurface->setIsCurrent(this, false));
Corentin Wallezc295e512017-01-27 17:47:50 -0500576 mCurrentSurface = nullptr;
577 }
Jamie Madill4928b7c2017-06-20 12:57:39 -0400578
579 return egl::NoError();
Jamie Madill77a72f62015-04-14 11:18:32 -0400580}
581
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000582GLuint Context::createBuffer()
583{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500584 return mState.mBuffers->createBuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000585}
586
587GLuint Context::createProgram()
588{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500589 return mState.mShaderPrograms->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000590}
591
592GLuint Context::createShader(GLenum type)
593{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500594 return mState.mShaderPrograms->createShader(mImplementation.get(), mLimitations, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000595}
596
597GLuint Context::createTexture()
598{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500599 return mState.mTextures->createTexture();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000600}
601
602GLuint Context::createRenderbuffer()
603{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500604 return mState.mRenderbuffers->createRenderbuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000605}
606
Sami Väisänene45e53b2016-05-25 10:36:04 +0300607GLuint Context::createPaths(GLsizei range)
608{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500609 auto resultOrError = mState.mPaths->createPaths(mImplementation.get(), range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300610 if (resultOrError.isError())
611 {
612 handleError(resultOrError.getError());
613 return 0;
614 }
615 return resultOrError.getResult();
616}
617
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000618// Returns an unused framebuffer name
619GLuint Context::createFramebuffer()
620{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500621 return mState.mFramebuffers->createFramebuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000622}
623
Jamie Madill33dc8432013-07-26 11:55:05 -0400624GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000625{
Jamie Madill33dc8432013-07-26 11:55:05 -0400626 GLuint handle = mFenceNVHandleAllocator.allocate();
Jamie Madill96a483b2017-06-27 16:49:21 -0400627 mFenceNVMap.assign(handle, new FenceNV(mImplementation->createFenceNV()));
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000628 return handle;
629}
630
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000631void Context::deleteBuffer(GLuint buffer)
632{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500633 if (mState.mBuffers->getBuffer(buffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000634 {
635 detachBuffer(buffer);
636 }
Jamie Madill893ab082014-05-16 16:56:10 -0400637
Jamie Madill6c1f6712017-02-14 19:08:04 -0500638 mState.mBuffers->deleteObject(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000639}
640
641void Context::deleteShader(GLuint shader)
642{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500643 mState.mShaderPrograms->deleteShader(this, shader);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000644}
645
646void Context::deleteProgram(GLuint program)
647{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500648 mState.mShaderPrograms->deleteProgram(this, program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000649}
650
651void Context::deleteTexture(GLuint texture)
652{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500653 if (mState.mTextures->getTexture(texture))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000654 {
655 detachTexture(texture);
656 }
657
Jamie Madill6c1f6712017-02-14 19:08:04 -0500658 mState.mTextures->deleteObject(this, texture);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000659}
660
661void Context::deleteRenderbuffer(GLuint renderbuffer)
662{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500663 if (mState.mRenderbuffers->getRenderbuffer(renderbuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000664 {
665 detachRenderbuffer(renderbuffer);
666 }
Jamie Madill893ab082014-05-16 16:56:10 -0400667
Jamie Madill6c1f6712017-02-14 19:08:04 -0500668 mState.mRenderbuffers->deleteObject(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000669}
670
Jamie Madill7f0c5a42017-08-26 22:43:26 -0400671void Context::deleteSync(GLsync sync)
Jamie Madillcd055f82013-07-26 11:55:15 -0400672{
673 // The spec specifies the underlying Fence object is not deleted until all current
674 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
675 // and since our API is currently designed for being called from a single thread, we can delete
676 // the fence immediately.
Jamie Madill70b5bb02017-08-28 13:32:37 -0400677 mState.mSyncs->deleteObject(this, static_cast<GLuint>(reinterpret_cast<uintptr_t>(sync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400678}
679
Sami Väisänene45e53b2016-05-25 10:36:04 +0300680void Context::deletePaths(GLuint first, GLsizei range)
681{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500682 mState.mPaths->deletePaths(first, range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300683}
684
685bool Context::hasPathData(GLuint path) const
686{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500687 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300688 if (pathObj == nullptr)
689 return false;
690
691 return pathObj->hasPathData();
692}
693
694bool Context::hasPath(GLuint path) const
695{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500696 return mState.mPaths->hasPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300697}
698
699void Context::setPathCommands(GLuint path,
700 GLsizei numCommands,
701 const GLubyte *commands,
702 GLsizei numCoords,
703 GLenum coordType,
704 const void *coords)
705{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500706 auto *pathObject = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300707
708 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
709}
710
711void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
712{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500713 auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300714
715 switch (pname)
716 {
717 case GL_PATH_STROKE_WIDTH_CHROMIUM:
718 pathObj->setStrokeWidth(value);
719 break;
720 case GL_PATH_END_CAPS_CHROMIUM:
721 pathObj->setEndCaps(static_cast<GLenum>(value));
722 break;
723 case GL_PATH_JOIN_STYLE_CHROMIUM:
724 pathObj->setJoinStyle(static_cast<GLenum>(value));
725 break;
726 case GL_PATH_MITER_LIMIT_CHROMIUM:
727 pathObj->setMiterLimit(value);
728 break;
729 case GL_PATH_STROKE_BOUND_CHROMIUM:
730 pathObj->setStrokeBound(value);
731 break;
732 default:
733 UNREACHABLE();
734 break;
735 }
736}
737
738void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
739{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500740 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300741
742 switch (pname)
743 {
744 case GL_PATH_STROKE_WIDTH_CHROMIUM:
745 *value = pathObj->getStrokeWidth();
746 break;
747 case GL_PATH_END_CAPS_CHROMIUM:
748 *value = static_cast<GLfloat>(pathObj->getEndCaps());
749 break;
750 case GL_PATH_JOIN_STYLE_CHROMIUM:
751 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
752 break;
753 case GL_PATH_MITER_LIMIT_CHROMIUM:
754 *value = pathObj->getMiterLimit();
755 break;
756 case GL_PATH_STROKE_BOUND_CHROMIUM:
757 *value = pathObj->getStrokeBound();
758 break;
759 default:
760 UNREACHABLE();
761 break;
762 }
763}
764
765void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
766{
767 mGLState.setPathStencilFunc(func, ref, mask);
768}
769
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000770void Context::deleteFramebuffer(GLuint framebuffer)
771{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500772 if (mState.mFramebuffers->getFramebuffer(framebuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000773 {
774 detachFramebuffer(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000775 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500776
Jamie Madill6c1f6712017-02-14 19:08:04 -0500777 mState.mFramebuffers->deleteObject(this, framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000778}
779
Jamie Madill33dc8432013-07-26 11:55:05 -0400780void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000781{
Jamie Madill96a483b2017-06-27 16:49:21 -0400782 FenceNV *fenceObject = nullptr;
783 if (mFenceNVMap.erase(fence, &fenceObject))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000784 {
Jamie Madill96a483b2017-06-27 16:49:21 -0400785 mFenceNVHandleAllocator.release(fence);
786 delete fenceObject;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000787 }
788}
789
Geoff Lang70d0f492015-12-10 17:45:46 -0500790Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000791{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500792 return mState.mBuffers->getBuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000793}
794
Jamie Madill570f7c82014-07-03 10:38:54 -0400795Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000796{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500797 return mState.mTextures->getTexture(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000798}
799
Geoff Lang70d0f492015-12-10 17:45:46 -0500800Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000801{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500802 return mState.mRenderbuffers->getRenderbuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000803}
804
Jamie Madill70b5bb02017-08-28 13:32:37 -0400805Sync *Context::getSync(GLsync handle) const
Jamie Madillcd055f82013-07-26 11:55:15 -0400806{
Jamie Madill70b5bb02017-08-28 13:32:37 -0400807 return mState.mSyncs->getSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400808}
809
Jamie Madill57a89722013-07-02 11:57:03 -0400810VertexArray *Context::getVertexArray(GLuint handle) const
811{
Jamie Madill96a483b2017-06-27 16:49:21 -0400812 return mVertexArrayMap.query(handle);
Jamie Madill57a89722013-07-02 11:57:03 -0400813}
814
Jamie Madilldc356042013-07-19 16:36:57 -0400815Sampler *Context::getSampler(GLuint handle) const
816{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500817 return mState.mSamplers->getSampler(handle);
Jamie Madilldc356042013-07-19 16:36:57 -0400818}
819
Geoff Langc8058452014-02-03 12:04:11 -0500820TransformFeedback *Context::getTransformFeedback(GLuint handle) const
821{
Jamie Madill96a483b2017-06-27 16:49:21 -0400822 return mTransformFeedbackMap.query(handle);
Geoff Langc8058452014-02-03 12:04:11 -0500823}
824
Geoff Lang70d0f492015-12-10 17:45:46 -0500825LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
826{
827 switch (identifier)
828 {
829 case GL_BUFFER:
830 return getBuffer(name);
831 case GL_SHADER:
832 return getShader(name);
833 case GL_PROGRAM:
834 return getProgram(name);
835 case GL_VERTEX_ARRAY:
836 return getVertexArray(name);
837 case GL_QUERY:
838 return getQuery(name);
839 case GL_TRANSFORM_FEEDBACK:
840 return getTransformFeedback(name);
841 case GL_SAMPLER:
842 return getSampler(name);
843 case GL_TEXTURE:
844 return getTexture(name);
845 case GL_RENDERBUFFER:
846 return getRenderbuffer(name);
847 case GL_FRAMEBUFFER:
848 return getFramebuffer(name);
849 default:
850 UNREACHABLE();
851 return nullptr;
852 }
853}
854
855LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
856{
Jamie Madill70b5bb02017-08-28 13:32:37 -0400857 return getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
Geoff Lang70d0f492015-12-10 17:45:46 -0500858}
859
Martin Radev9d901792016-07-15 15:58:58 +0300860void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
861{
862 LabeledObject *object = getLabeledObject(identifier, name);
863 ASSERT(object != nullptr);
864
865 std::string labelName = GetObjectLabelFromPointer(length, label);
866 object->setLabel(labelName);
Jamie Madill8693bdb2017-09-02 15:32:14 -0400867
868 // TODO(jmadill): Determine if the object is dirty based on 'name'. Conservatively assume the
869 // specified object is active until we do this.
870 mGLState.setObjectDirty(identifier);
Martin Radev9d901792016-07-15 15:58:58 +0300871}
872
873void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
874{
875 LabeledObject *object = getLabeledObjectFromPtr(ptr);
876 ASSERT(object != nullptr);
877
878 std::string labelName = GetObjectLabelFromPointer(length, label);
879 object->setLabel(labelName);
880}
881
882void Context::getObjectLabel(GLenum identifier,
883 GLuint name,
884 GLsizei bufSize,
885 GLsizei *length,
886 GLchar *label) const
887{
888 LabeledObject *object = getLabeledObject(identifier, name);
889 ASSERT(object != nullptr);
890
891 const std::string &objectLabel = object->getLabel();
892 GetObjectLabelBase(objectLabel, bufSize, length, label);
893}
894
895void Context::getObjectPtrLabel(const void *ptr,
896 GLsizei bufSize,
897 GLsizei *length,
898 GLchar *label) const
899{
900 LabeledObject *object = getLabeledObjectFromPtr(ptr);
901 ASSERT(object != nullptr);
902
903 const std::string &objectLabel = object->getLabel();
904 GetObjectLabelBase(objectLabel, bufSize, length, label);
905}
906
Jamie Madilldc356042013-07-19 16:36:57 -0400907bool Context::isSampler(GLuint samplerName) const
908{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500909 return mState.mSamplers->isSampler(samplerName);
Jamie Madilldc356042013-07-19 16:36:57 -0400910}
911
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500912void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000913{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500914 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400915 mGLState.setArrayBufferBinding(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000916}
917
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800918void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
919{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500920 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400921 mGLState.setDrawIndirectBufferBinding(this, buffer);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800922}
923
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500924void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000925{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500926 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400927 mGLState.setElementArrayBuffer(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000928}
929
Jamie Madilldedd7b92014-11-05 16:30:36 -0500930void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000931{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500932 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000933
Jamie Madilldedd7b92014-11-05 16:30:36 -0500934 if (handle == 0)
935 {
936 texture = mZeroTextures[target].get();
937 }
938 else
939 {
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500940 texture = mState.mTextures->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500941 }
942
943 ASSERT(texture);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400944 mGLState.setSamplerTexture(this, target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000945}
946
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500947void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000948{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500949 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
950 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700951 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000952}
953
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500954void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000955{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500956 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
957 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700958 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000959}
960
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500961void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -0400962{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500963 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700964 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400965}
966
Shao80957d92017-02-20 21:25:59 +0800967void Context::bindVertexBuffer(GLuint bindingIndex,
968 GLuint bufferHandle,
969 GLintptr offset,
970 GLsizei stride)
971{
972 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400973 mGLState.bindVertexBuffer(this, bindingIndex, buffer, offset, stride);
Shao80957d92017-02-20 21:25:59 +0800974}
975
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500976void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -0400977{
Geoff Lang76b10c92014-09-05 16:28:14 -0400978 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -0400979 Sampler *sampler =
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500980 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400981 mGLState.setSamplerBinding(this, textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400982}
983
Xinghua Cao65ec0b22017-03-28 16:10:52 +0800984void Context::bindImageTexture(GLuint unit,
985 GLuint texture,
986 GLint level,
987 GLboolean layered,
988 GLint layer,
989 GLenum access,
990 GLenum format)
991{
992 Texture *tex = mState.mTextures->getTexture(texture);
993 mGLState.setImageUnit(this, unit, tex, level, layered, layer, access, format);
994}
995
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500996void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000997{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500998 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400999 mGLState.setGenericUniformBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001000}
1001
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001002void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1003 GLuint index,
1004 GLintptr offset,
1005 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001006{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001007 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001008 mGLState.setIndexedUniformBufferBinding(this, index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001009}
1010
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001011void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001012{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001013 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001014 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001015}
1016
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001017void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1018 GLuint index,
1019 GLintptr offset,
1020 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001021{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001022 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001023 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(this, index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001024}
1025
Jiajia Qin6eafb042016-12-27 17:04:07 +08001026void Context::bindGenericAtomicCounterBuffer(GLuint bufferHandle)
1027{
1028 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001029 mGLState.setGenericAtomicCounterBufferBinding(this, buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08001030}
1031
1032void Context::bindIndexedAtomicCounterBuffer(GLuint bufferHandle,
1033 GLuint index,
1034 GLintptr offset,
1035 GLsizeiptr size)
1036{
1037 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001038 mGLState.setIndexedAtomicCounterBufferBinding(this, index, buffer, offset, size);
Jiajia Qin6eafb042016-12-27 17:04:07 +08001039}
1040
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001041void Context::bindGenericShaderStorageBuffer(GLuint bufferHandle)
1042{
1043 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001044 mGLState.setGenericShaderStorageBufferBinding(this, buffer);
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001045}
1046
1047void Context::bindIndexedShaderStorageBuffer(GLuint bufferHandle,
1048 GLuint index,
1049 GLintptr offset,
1050 GLsizeiptr size)
1051{
1052 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001053 mGLState.setIndexedShaderStorageBufferBinding(this, index, buffer, offset, size);
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001054}
1055
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001056void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001057{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001058 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001059 mGLState.setCopyReadBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001060}
1061
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001062void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001063{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001064 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001065 mGLState.setCopyWriteBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001066}
1067
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001068void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001069{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001070 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001071 mGLState.setPixelPackBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001072}
1073
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001074void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001075{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001076 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001077 mGLState.setPixelUnpackBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001078}
1079
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001080void Context::useProgram(GLuint program)
1081{
Jamie Madill6c1f6712017-02-14 19:08:04 -05001082 mGLState.setProgram(this, getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001083}
1084
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04001085void Context::bindTransformFeedback(GLenum target, GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001086{
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04001087 ASSERT(target == GL_TRANSFORM_FEEDBACK);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001088 TransformFeedback *transformFeedback =
1089 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001090 mGLState.setTransformFeedbackBinding(this, transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001091}
1092
Jamie Madillf0e04492017-08-26 15:28:42 -04001093void Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001094{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001095 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001096 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001097
Geoff Lang5aad9672014-09-08 11:10:42 -04001098 // begin query
Jamie Madillf0e04492017-08-26 15:28:42 -04001099 ANGLE_CONTEXT_TRY(queryObject->begin());
Geoff Lang5aad9672014-09-08 11:10:42 -04001100
1101 // set query as active for specified target only if begin succeeded
Jamie Madill4928b7c2017-06-20 12:57:39 -04001102 mGLState.setActiveQuery(this, target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001103}
1104
Jamie Madillf0e04492017-08-26 15:28:42 -04001105void Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001106{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001107 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001108 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001109
Jamie Madillf0e04492017-08-26 15:28:42 -04001110 handleError(queryObject->end());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001111
Geoff Lang5aad9672014-09-08 11:10:42 -04001112 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madill4928b7c2017-06-20 12:57:39 -04001113 mGLState.setActiveQuery(this, target, nullptr);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001114}
1115
Jamie Madillf0e04492017-08-26 15:28:42 -04001116void Context::queryCounter(GLuint id, GLenum target)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001117{
1118 ASSERT(target == GL_TIMESTAMP_EXT);
1119
1120 Query *queryObject = getQuery(id, true, target);
1121 ASSERT(queryObject);
1122
Jamie Madillf0e04492017-08-26 15:28:42 -04001123 handleError(queryObject->queryCounter());
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001124}
1125
1126void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1127{
1128 switch (pname)
1129 {
1130 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001131 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001132 break;
1133 case GL_QUERY_COUNTER_BITS_EXT:
1134 switch (target)
1135 {
1136 case GL_TIME_ELAPSED_EXT:
1137 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1138 break;
1139 case GL_TIMESTAMP_EXT:
1140 params[0] = getExtensions().queryCounterBitsTimestamp;
1141 break;
1142 default:
1143 UNREACHABLE();
1144 params[0] = 0;
1145 break;
1146 }
1147 break;
1148 default:
1149 UNREACHABLE();
1150 return;
1151 }
1152}
1153
Geoff Lang2186c382016-10-14 10:54:54 -04001154void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001155{
Geoff Lang2186c382016-10-14 10:54:54 -04001156 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001157}
1158
Geoff Lang2186c382016-10-14 10:54:54 -04001159void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001160{
Geoff Lang2186c382016-10-14 10:54:54 -04001161 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001162}
1163
Geoff Lang2186c382016-10-14 10:54:54 -04001164void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001165{
Geoff Lang2186c382016-10-14 10:54:54 -04001166 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001167}
1168
Geoff Lang2186c382016-10-14 10:54:54 -04001169void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001170{
Geoff Lang2186c382016-10-14 10:54:54 -04001171 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001172}
1173
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001174Framebuffer *Context::getFramebuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001175{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001176 return mState.mFramebuffers->getFramebuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001177}
1178
Jamie Madill2f348d22017-06-05 10:50:59 -04001179FenceNV *Context::getFenceNV(GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001180{
Jamie Madill96a483b2017-06-27 16:49:21 -04001181 return mFenceNVMap.query(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001182}
1183
Jamie Madill2f348d22017-06-05 10:50:59 -04001184Query *Context::getQuery(GLuint handle, bool create, GLenum type)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001185{
Jamie Madill96a483b2017-06-27 16:49:21 -04001186 if (!mQueryMap.contains(handle))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001187 {
Yunchao Hef81ce4a2017-04-24 10:49:17 +08001188 return nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001189 }
Jamie Madill96a483b2017-06-27 16:49:21 -04001190
1191 Query *query = mQueryMap.query(handle);
1192 if (!query && create)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001193 {
Jamie Madill96a483b2017-06-27 16:49:21 -04001194 query = new Query(mImplementation->createQuery(type), handle);
1195 query->addRef();
1196 mQueryMap.assign(handle, query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001197 }
Jamie Madill96a483b2017-06-27 16:49:21 -04001198 return query;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001199}
1200
Geoff Lang70d0f492015-12-10 17:45:46 -05001201Query *Context::getQuery(GLuint handle) const
1202{
Jamie Madill96a483b2017-06-27 16:49:21 -04001203 return mQueryMap.query(handle);
Geoff Lang70d0f492015-12-10 17:45:46 -05001204}
1205
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001206Texture *Context::getTargetTexture(GLenum target) const
1207{
Ian Ewellbda75592016-04-18 17:25:54 -04001208 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001209 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001210}
1211
Geoff Lang76b10c92014-09-05 16:28:14 -04001212Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001213{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001214 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001215}
1216
Geoff Lang492a7e42014-11-05 13:27:06 -05001217Compiler *Context::getCompiler() const
1218{
Jamie Madill2f348d22017-06-05 10:50:59 -04001219 if (mCompiler.get() == nullptr)
1220 {
Jamie Madill4928b7c2017-06-20 12:57:39 -04001221 mCompiler.set(this, new Compiler(mImplementation.get(), mState));
Jamie Madill2f348d22017-06-05 10:50:59 -04001222 }
1223 return mCompiler.get();
Geoff Lang492a7e42014-11-05 13:27:06 -05001224}
1225
Jamie Madillc1d770e2017-04-13 17:31:24 -04001226void Context::getBooleanvImpl(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001227{
1228 switch (pname)
1229 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001230 case GL_SHADER_COMPILER:
1231 *params = GL_TRUE;
1232 break;
1233 case GL_CONTEXT_ROBUST_ACCESS_EXT:
1234 *params = mRobustAccess ? GL_TRUE : GL_FALSE;
1235 break;
1236 default:
1237 mGLState.getBooleanv(pname, params);
1238 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001239 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001240}
1241
Jamie Madillc1d770e2017-04-13 17:31:24 -04001242void Context::getFloatvImpl(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001243{
Shannon Woods53a94a82014-06-24 15:20:36 -04001244 // Queries about context capabilities and maximums are answered by Context.
1245 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001246 switch (pname)
1247 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001248 case GL_ALIASED_LINE_WIDTH_RANGE:
1249 params[0] = mCaps.minAliasedLineWidth;
1250 params[1] = mCaps.maxAliasedLineWidth;
1251 break;
1252 case GL_ALIASED_POINT_SIZE_RANGE:
1253 params[0] = mCaps.minAliasedPointSize;
1254 params[1] = mCaps.maxAliasedPointSize;
1255 break;
1256 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1257 ASSERT(mExtensions.textureFilterAnisotropic);
1258 *params = mExtensions.maxTextureAnisotropy;
1259 break;
1260 case GL_MAX_TEXTURE_LOD_BIAS:
1261 *params = mCaps.maxLODBias;
1262 break;
1263
1264 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1265 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1266 {
1267 ASSERT(mExtensions.pathRendering);
1268 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1269 memcpy(params, m, 16 * sizeof(GLfloat));
1270 }
Geoff Lange6d4e122015-06-29 13:33:55 -04001271 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001272
Jamie Madill231c7f52017-04-26 13:45:37 -04001273 default:
1274 mGLState.getFloatv(pname, params);
1275 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001276 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001277}
1278
Jamie Madillc1d770e2017-04-13 17:31:24 -04001279void Context::getIntegervImpl(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001280{
Shannon Woods53a94a82014-06-24 15:20:36 -04001281 // Queries about context capabilities and maximums are answered by Context.
1282 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001283
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001284 switch (pname)
1285 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001286 case GL_MAX_VERTEX_ATTRIBS:
1287 *params = mCaps.maxVertexAttributes;
1288 break;
1289 case GL_MAX_VERTEX_UNIFORM_VECTORS:
1290 *params = mCaps.maxVertexUniformVectors;
1291 break;
1292 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
1293 *params = mCaps.maxVertexUniformComponents;
1294 break;
1295 case GL_MAX_VARYING_VECTORS:
1296 *params = mCaps.maxVaryingVectors;
1297 break;
1298 case GL_MAX_VARYING_COMPONENTS:
1299 *params = mCaps.maxVertexOutputComponents;
1300 break;
1301 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1302 *params = mCaps.maxCombinedTextureImageUnits;
1303 break;
1304 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1305 *params = mCaps.maxVertexTextureImageUnits;
1306 break;
1307 case GL_MAX_TEXTURE_IMAGE_UNITS:
1308 *params = mCaps.maxTextureImageUnits;
1309 break;
1310 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1311 *params = mCaps.maxFragmentUniformVectors;
1312 break;
1313 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
1314 *params = mCaps.maxFragmentUniformComponents;
1315 break;
1316 case GL_MAX_RENDERBUFFER_SIZE:
1317 *params = mCaps.maxRenderbufferSize;
1318 break;
1319 case GL_MAX_COLOR_ATTACHMENTS_EXT:
1320 *params = mCaps.maxColorAttachments;
1321 break;
1322 case GL_MAX_DRAW_BUFFERS_EXT:
1323 *params = mCaps.maxDrawBuffers;
1324 break;
1325 // case GL_FRAMEBUFFER_BINDING: // now equivalent to
1326 // GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1327 case GL_SUBPIXEL_BITS:
1328 *params = 4;
1329 break;
1330 case GL_MAX_TEXTURE_SIZE:
1331 *params = mCaps.max2DTextureSize;
1332 break;
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001333 case GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE:
1334 *params = mCaps.maxRectangleTextureSize;
1335 break;
Jamie Madill231c7f52017-04-26 13:45:37 -04001336 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1337 *params = mCaps.maxCubeMapTextureSize;
1338 break;
1339 case GL_MAX_3D_TEXTURE_SIZE:
1340 *params = mCaps.max3DTextureSize;
1341 break;
1342 case GL_MAX_ARRAY_TEXTURE_LAYERS:
1343 *params = mCaps.maxArrayTextureLayers;
1344 break;
1345 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
1346 *params = mCaps.uniformBufferOffsetAlignment;
1347 break;
1348 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
1349 *params = mCaps.maxUniformBufferBindings;
1350 break;
1351 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
1352 *params = mCaps.maxVertexUniformBlocks;
1353 break;
1354 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
1355 *params = mCaps.maxFragmentUniformBlocks;
1356 break;
1357 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
1358 *params = mCaps.maxCombinedTextureImageUnits;
1359 break;
1360 case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
1361 *params = mCaps.maxVertexOutputComponents;
1362 break;
1363 case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
1364 *params = mCaps.maxFragmentInputComponents;
1365 break;
1366 case GL_MIN_PROGRAM_TEXEL_OFFSET:
1367 *params = mCaps.minProgramTexelOffset;
1368 break;
1369 case GL_MAX_PROGRAM_TEXEL_OFFSET:
1370 *params = mCaps.maxProgramTexelOffset;
1371 break;
1372 case GL_MAJOR_VERSION:
1373 *params = getClientVersion().major;
1374 break;
1375 case GL_MINOR_VERSION:
1376 *params = getClientVersion().minor;
1377 break;
1378 case GL_MAX_ELEMENTS_INDICES:
1379 *params = mCaps.maxElementsIndices;
1380 break;
1381 case GL_MAX_ELEMENTS_VERTICES:
1382 *params = mCaps.maxElementsVertices;
1383 break;
1384 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
1385 *params = mCaps.maxTransformFeedbackInterleavedComponents;
1386 break;
1387 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
1388 *params = mCaps.maxTransformFeedbackSeparateAttributes;
1389 break;
1390 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
1391 *params = mCaps.maxTransformFeedbackSeparateComponents;
1392 break;
1393 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1394 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1395 break;
1396 case GL_MAX_SAMPLES_ANGLE:
1397 *params = mCaps.maxSamples;
1398 break;
1399 case GL_MAX_VIEWPORT_DIMS:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001400 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001401 params[0] = mCaps.maxViewportWidth;
1402 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001403 }
1404 break;
Jamie Madill231c7f52017-04-26 13:45:37 -04001405 case GL_COMPRESSED_TEXTURE_FORMATS:
1406 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(),
1407 params);
1408 break;
1409 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1410 *params = mResetStrategy;
1411 break;
1412 case GL_NUM_SHADER_BINARY_FORMATS:
1413 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
1414 break;
1415 case GL_SHADER_BINARY_FORMATS:
1416 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1417 break;
1418 case GL_NUM_PROGRAM_BINARY_FORMATS:
1419 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
1420 break;
1421 case GL_PROGRAM_BINARY_FORMATS:
1422 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
1423 break;
1424 case GL_NUM_EXTENSIONS:
1425 *params = static_cast<GLint>(mExtensionStrings.size());
1426 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001427
Jamie Madill231c7f52017-04-26 13:45:37 -04001428 // GL_KHR_debug
1429 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1430 *params = mExtensions.maxDebugMessageLength;
1431 break;
1432 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1433 *params = mExtensions.maxDebugLoggedMessages;
1434 break;
1435 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1436 *params = mExtensions.maxDebugGroupStackDepth;
1437 break;
1438 case GL_MAX_LABEL_LENGTH:
1439 *params = mExtensions.maxLabelLength;
1440 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001441
Martin Radeve5285d22017-07-14 16:23:53 +03001442 // GL_ANGLE_multiview
1443 case GL_MAX_VIEWS_ANGLE:
1444 *params = mExtensions.maxViews;
1445 break;
1446
Jamie Madill231c7f52017-04-26 13:45:37 -04001447 // GL_EXT_disjoint_timer_query
1448 case GL_GPU_DISJOINT_EXT:
1449 *params = mImplementation->getGPUDisjoint();
1450 break;
1451 case GL_MAX_FRAMEBUFFER_WIDTH:
1452 *params = mCaps.maxFramebufferWidth;
1453 break;
1454 case GL_MAX_FRAMEBUFFER_HEIGHT:
1455 *params = mCaps.maxFramebufferHeight;
1456 break;
1457 case GL_MAX_FRAMEBUFFER_SAMPLES:
1458 *params = mCaps.maxFramebufferSamples;
1459 break;
1460 case GL_MAX_SAMPLE_MASK_WORDS:
1461 *params = mCaps.maxSampleMaskWords;
1462 break;
1463 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1464 *params = mCaps.maxColorTextureSamples;
1465 break;
1466 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1467 *params = mCaps.maxDepthTextureSamples;
1468 break;
1469 case GL_MAX_INTEGER_SAMPLES:
1470 *params = mCaps.maxIntegerSamples;
1471 break;
1472 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1473 *params = mCaps.maxVertexAttribRelativeOffset;
1474 break;
1475 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1476 *params = mCaps.maxVertexAttribBindings;
1477 break;
1478 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1479 *params = mCaps.maxVertexAttribStride;
1480 break;
1481 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1482 *params = mCaps.maxVertexAtomicCounterBuffers;
1483 break;
1484 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1485 *params = mCaps.maxVertexAtomicCounters;
1486 break;
1487 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1488 *params = mCaps.maxVertexImageUniforms;
1489 break;
1490 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1491 *params = mCaps.maxVertexShaderStorageBlocks;
1492 break;
1493 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1494 *params = mCaps.maxFragmentAtomicCounterBuffers;
1495 break;
1496 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1497 *params = mCaps.maxFragmentAtomicCounters;
1498 break;
1499 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1500 *params = mCaps.maxFragmentImageUniforms;
1501 break;
1502 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1503 *params = mCaps.maxFragmentShaderStorageBlocks;
1504 break;
1505 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1506 *params = mCaps.minProgramTextureGatherOffset;
1507 break;
1508 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1509 *params = mCaps.maxProgramTextureGatherOffset;
1510 break;
1511 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1512 *params = mCaps.maxComputeWorkGroupInvocations;
1513 break;
1514 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1515 *params = mCaps.maxComputeUniformBlocks;
1516 break;
1517 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1518 *params = mCaps.maxComputeTextureImageUnits;
1519 break;
1520 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1521 *params = mCaps.maxComputeSharedMemorySize;
1522 break;
1523 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1524 *params = mCaps.maxComputeUniformComponents;
1525 break;
1526 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1527 *params = mCaps.maxComputeAtomicCounterBuffers;
1528 break;
1529 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1530 *params = mCaps.maxComputeAtomicCounters;
1531 break;
1532 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1533 *params = mCaps.maxComputeImageUniforms;
1534 break;
1535 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1536 *params = mCaps.maxCombinedComputeUniformComponents;
1537 break;
1538 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1539 *params = mCaps.maxComputeShaderStorageBlocks;
1540 break;
1541 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1542 *params = mCaps.maxCombinedShaderOutputResources;
1543 break;
1544 case GL_MAX_UNIFORM_LOCATIONS:
1545 *params = mCaps.maxUniformLocations;
1546 break;
1547 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1548 *params = mCaps.maxAtomicCounterBufferBindings;
1549 break;
1550 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1551 *params = mCaps.maxAtomicCounterBufferSize;
1552 break;
1553 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1554 *params = mCaps.maxCombinedAtomicCounterBuffers;
1555 break;
1556 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1557 *params = mCaps.maxCombinedAtomicCounters;
1558 break;
1559 case GL_MAX_IMAGE_UNITS:
1560 *params = mCaps.maxImageUnits;
1561 break;
1562 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1563 *params = mCaps.maxCombinedImageUniforms;
1564 break;
1565 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1566 *params = mCaps.maxShaderStorageBufferBindings;
1567 break;
1568 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1569 *params = mCaps.maxCombinedShaderStorageBlocks;
1570 break;
1571 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1572 *params = mCaps.shaderStorageBufferOffsetAlignment;
1573 break;
1574 default:
1575 mGLState.getIntegerv(this, pname, params);
1576 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001577 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001578}
1579
Jamie Madill7f0c5a42017-08-26 22:43:26 -04001580void Context::getInteger64vImpl(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001581{
Shannon Woods53a94a82014-06-24 15:20:36 -04001582 // Queries about context capabilities and maximums are answered by Context.
1583 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001584 switch (pname)
1585 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001586 case GL_MAX_ELEMENT_INDEX:
1587 *params = mCaps.maxElementIndex;
1588 break;
1589 case GL_MAX_UNIFORM_BLOCK_SIZE:
1590 *params = mCaps.maxUniformBlockSize;
1591 break;
1592 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
1593 *params = mCaps.maxCombinedVertexUniformComponents;
1594 break;
1595 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
1596 *params = mCaps.maxCombinedFragmentUniformComponents;
1597 break;
1598 case GL_MAX_SERVER_WAIT_TIMEOUT:
1599 *params = mCaps.maxServerWaitTimeout;
1600 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001601
Jamie Madill231c7f52017-04-26 13:45:37 -04001602 // GL_EXT_disjoint_timer_query
1603 case GL_TIMESTAMP_EXT:
1604 *params = mImplementation->getTimestamp();
1605 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001606
Jamie Madill231c7f52017-04-26 13:45:37 -04001607 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1608 *params = mCaps.maxShaderStorageBlockSize;
1609 break;
1610 default:
1611 UNREACHABLE();
1612 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001613 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001614}
1615
Geoff Lang70d0f492015-12-10 17:45:46 -05001616void Context::getPointerv(GLenum pname, void **params) const
1617{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001618 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001619}
1620
Martin Radev66fb8202016-07-28 11:45:20 +03001621void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001622{
Shannon Woods53a94a82014-06-24 15:20:36 -04001623 // Queries about context capabilities and maximums are answered by Context.
1624 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001625
1626 GLenum nativeType;
1627 unsigned int numParams;
1628 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1629 ASSERT(queryStatus);
1630
1631 if (nativeType == GL_INT)
1632 {
1633 switch (target)
1634 {
1635 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1636 ASSERT(index < 3u);
1637 *data = mCaps.maxComputeWorkGroupCount[index];
1638 break;
1639 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1640 ASSERT(index < 3u);
1641 *data = mCaps.maxComputeWorkGroupSize[index];
1642 break;
1643 default:
1644 mGLState.getIntegeri_v(target, index, data);
1645 }
1646 }
1647 else
1648 {
1649 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1650 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001651}
1652
Martin Radev66fb8202016-07-28 11:45:20 +03001653void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001654{
Shannon Woods53a94a82014-06-24 15:20:36 -04001655 // Queries about context capabilities and maximums are answered by Context.
1656 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001657
1658 GLenum nativeType;
1659 unsigned int numParams;
1660 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1661 ASSERT(queryStatus);
1662
1663 if (nativeType == GL_INT_64_ANGLEX)
1664 {
1665 mGLState.getInteger64i_v(target, index, data);
1666 }
1667 else
1668 {
1669 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1670 }
1671}
1672
1673void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1674{
1675 // Queries about context capabilities and maximums are answered by Context.
1676 // Queries about current GL state values are answered by State.
1677
1678 GLenum nativeType;
1679 unsigned int numParams;
1680 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1681 ASSERT(queryStatus);
1682
1683 if (nativeType == GL_BOOL)
1684 {
1685 mGLState.getBooleani_v(target, index, data);
1686 }
1687 else
1688 {
1689 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1690 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001691}
1692
He Yunchao010e4db2017-03-03 14:22:06 +08001693void Context::getBufferParameteriv(GLenum target, GLenum pname, GLint *params)
1694{
1695 Buffer *buffer = mGLState.getTargetBuffer(target);
1696 QueryBufferParameteriv(buffer, pname, params);
1697}
1698
1699void Context::getFramebufferAttachmentParameteriv(GLenum target,
1700 GLenum attachment,
1701 GLenum pname,
1702 GLint *params)
1703{
1704 const Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
1705 QueryFramebufferAttachmentParameteriv(framebuffer, attachment, pname, params);
1706}
1707
1708void Context::getRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
1709{
1710 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
1711 QueryRenderbufferiv(this, renderbuffer, pname, params);
1712}
1713
1714void Context::getTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
1715{
1716 Texture *texture = getTargetTexture(target);
1717 QueryTexParameterfv(texture, pname, params);
1718}
1719
1720void Context::getTexParameteriv(GLenum target, GLenum pname, GLint *params)
1721{
1722 Texture *texture = getTargetTexture(target);
1723 QueryTexParameteriv(texture, pname, params);
1724}
1725void Context::texParameterf(GLenum target, GLenum pname, GLfloat param)
1726{
1727 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001728 SetTexParameterf(this, texture, pname, param);
Jamie Madill81c2e252017-09-09 23:32:46 -04001729 onTextureChange(texture);
He Yunchao010e4db2017-03-03 14:22:06 +08001730}
1731
1732void Context::texParameterfv(GLenum target, GLenum pname, const GLfloat *params)
1733{
1734 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001735 SetTexParameterfv(this, texture, pname, params);
Jamie Madill81c2e252017-09-09 23:32:46 -04001736 onTextureChange(texture);
He Yunchao010e4db2017-03-03 14:22:06 +08001737}
1738
1739void Context::texParameteri(GLenum target, GLenum pname, GLint param)
1740{
1741 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001742 SetTexParameteri(this, texture, pname, param);
Jamie Madill81c2e252017-09-09 23:32:46 -04001743 onTextureChange(texture);
He Yunchao010e4db2017-03-03 14:22:06 +08001744}
1745
1746void Context::texParameteriv(GLenum target, GLenum pname, const GLint *params)
1747{
1748 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001749 SetTexParameteriv(this, texture, pname, params);
Jamie Madill81c2e252017-09-09 23:32:46 -04001750 onTextureChange(texture);
He Yunchao010e4db2017-03-03 14:22:06 +08001751}
1752
Jamie Madill675fe712016-12-19 13:07:54 -05001753void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001754{
Jamie Madill14bbb3f2017-09-12 15:23:01 -04001755 syncRendererState();
Jamie Madillb6664922017-07-25 12:55:04 -04001756 ANGLE_CONTEXT_TRY(mImplementation->drawArrays(this, mode, first, count));
1757 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001758}
1759
Jamie Madill675fe712016-12-19 13:07:54 -05001760void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Geoff Langf6db0982015-08-25 13:04:00 -04001761{
Jamie Madill14bbb3f2017-09-12 15:23:01 -04001762 syncRendererState();
Jamie Madillb6664922017-07-25 12:55:04 -04001763 ANGLE_CONTEXT_TRY(
1764 mImplementation->drawArraysInstanced(this, mode, first, count, instanceCount));
1765 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Langf6db0982015-08-25 13:04:00 -04001766}
1767
Jamie Madill876429b2017-04-20 15:46:24 -04001768void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001769{
Jamie Madill14bbb3f2017-09-12 15:23:01 -04001770 syncRendererState();
Jamie Madillb6664922017-07-25 12:55:04 -04001771 ANGLE_CONTEXT_TRY(mImplementation->drawElements(this, mode, count, type, indices));
Geoff Langf6db0982015-08-25 13:04:00 -04001772}
1773
Jamie Madill675fe712016-12-19 13:07:54 -05001774void Context::drawElementsInstanced(GLenum mode,
1775 GLsizei count,
1776 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001777 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001778 GLsizei instances)
Geoff Langf6db0982015-08-25 13:04:00 -04001779{
Jamie Madill14bbb3f2017-09-12 15:23:01 -04001780 syncRendererState();
Jamie Madillb6664922017-07-25 12:55:04 -04001781 ANGLE_CONTEXT_TRY(
Qin Jiajia1da00652017-06-20 17:16:25 +08001782 mImplementation->drawElementsInstanced(this, mode, count, type, indices, instances));
Geoff Langf6db0982015-08-25 13:04:00 -04001783}
1784
Jamie Madill675fe712016-12-19 13:07:54 -05001785void Context::drawRangeElements(GLenum mode,
1786 GLuint start,
1787 GLuint end,
1788 GLsizei count,
1789 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001790 const void *indices)
Geoff Langf6db0982015-08-25 13:04:00 -04001791{
Jamie Madill14bbb3f2017-09-12 15:23:01 -04001792 syncRendererState();
Jamie Madillb6664922017-07-25 12:55:04 -04001793 ANGLE_CONTEXT_TRY(
1794 mImplementation->drawRangeElements(this, mode, start, end, count, type, indices));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001795}
1796
Jamie Madill876429b2017-04-20 15:46:24 -04001797void Context::drawArraysIndirect(GLenum mode, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001798{
Jamie Madill14bbb3f2017-09-12 15:23:01 -04001799 syncRendererState();
Jamie Madillb6664922017-07-25 12:55:04 -04001800 ANGLE_CONTEXT_TRY(mImplementation->drawArraysIndirect(this, mode, indirect));
Jiajia Qind9671222016-11-29 16:30:31 +08001801}
1802
Jamie Madill876429b2017-04-20 15:46:24 -04001803void Context::drawElementsIndirect(GLenum mode, GLenum type, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001804{
Jamie Madill14bbb3f2017-09-12 15:23:01 -04001805 syncRendererState();
Jamie Madillb6664922017-07-25 12:55:04 -04001806 ANGLE_CONTEXT_TRY(mImplementation->drawElementsIndirect(this, mode, type, indirect));
Jiajia Qind9671222016-11-29 16:30:31 +08001807}
1808
Jamie Madill675fe712016-12-19 13:07:54 -05001809void Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001810{
Jamie Madill675fe712016-12-19 13:07:54 -05001811 handleError(mImplementation->flush());
Geoff Lang129753a2015-01-09 16:52:09 -05001812}
1813
Jamie Madill675fe712016-12-19 13:07:54 -05001814void Context::finish()
Geoff Lang129753a2015-01-09 16:52:09 -05001815{
Jamie Madill675fe712016-12-19 13:07:54 -05001816 handleError(mImplementation->finish());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001817}
1818
Austin Kinross6ee1e782015-05-29 17:05:37 -07001819void Context::insertEventMarker(GLsizei length, const char *marker)
1820{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001821 ASSERT(mImplementation);
1822 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001823}
1824
1825void Context::pushGroupMarker(GLsizei length, const char *marker)
1826{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001827 ASSERT(mImplementation);
1828 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001829}
1830
1831void Context::popGroupMarker()
1832{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001833 ASSERT(mImplementation);
1834 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001835}
1836
Geoff Langd8605522016-04-13 10:19:12 -04001837void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1838{
1839 Program *programObject = getProgram(program);
1840 ASSERT(programObject);
1841
1842 programObject->bindUniformLocation(location, name);
1843}
1844
Sami Väisänena797e062016-05-12 15:23:40 +03001845void Context::setCoverageModulation(GLenum components)
1846{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001847 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001848}
1849
Sami Väisänene45e53b2016-05-25 10:36:04 +03001850void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1851{
1852 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1853}
1854
1855void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1856{
1857 GLfloat I[16];
1858 angle::Matrix<GLfloat>::setToIdentity(I);
1859
1860 mGLState.loadPathRenderingMatrix(matrixMode, I);
1861}
1862
1863void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1864{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001865 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001866 if (!pathObj)
1867 return;
1868
1869 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1870 syncRendererState();
1871
1872 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1873}
1874
1875void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1876{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001877 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001878 if (!pathObj)
1879 return;
1880
1881 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1882 syncRendererState();
1883
1884 mImplementation->stencilStrokePath(pathObj, reference, mask);
1885}
1886
1887void Context::coverFillPath(GLuint path, GLenum coverMode)
1888{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001889 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001890 if (!pathObj)
1891 return;
1892
1893 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1894 syncRendererState();
1895
1896 mImplementation->coverFillPath(pathObj, coverMode);
1897}
1898
1899void Context::coverStrokePath(GLuint path, GLenum coverMode)
1900{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001901 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001902 if (!pathObj)
1903 return;
1904
1905 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1906 syncRendererState();
1907
1908 mImplementation->coverStrokePath(pathObj, coverMode);
1909}
1910
1911void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1912{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001913 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001914 if (!pathObj)
1915 return;
1916
1917 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1918 syncRendererState();
1919
1920 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1921}
1922
1923void Context::stencilThenCoverStrokePath(GLuint path,
1924 GLint reference,
1925 GLuint mask,
1926 GLenum coverMode)
1927{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001928 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001929 if (!pathObj)
1930 return;
1931
1932 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1933 syncRendererState();
1934
1935 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1936}
1937
Sami Väisänend59ca052016-06-21 16:10:00 +03001938void Context::coverFillPathInstanced(GLsizei numPaths,
1939 GLenum pathNameType,
1940 const void *paths,
1941 GLuint pathBase,
1942 GLenum coverMode,
1943 GLenum transformType,
1944 const GLfloat *transformValues)
1945{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001946 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001947
1948 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1949 syncRendererState();
1950
1951 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1952}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001953
Sami Väisänend59ca052016-06-21 16:10:00 +03001954void Context::coverStrokePathInstanced(GLsizei numPaths,
1955 GLenum pathNameType,
1956 const void *paths,
1957 GLuint pathBase,
1958 GLenum coverMode,
1959 GLenum transformType,
1960 const GLfloat *transformValues)
1961{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001962 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001963
1964 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1965 syncRendererState();
1966
1967 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1968 transformValues);
1969}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001970
Sami Väisänend59ca052016-06-21 16:10:00 +03001971void Context::stencilFillPathInstanced(GLsizei numPaths,
1972 GLenum pathNameType,
1973 const void *paths,
1974 GLuint pathBase,
1975 GLenum fillMode,
1976 GLuint mask,
1977 GLenum transformType,
1978 const GLfloat *transformValues)
1979{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001980 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001981
1982 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1983 syncRendererState();
1984
1985 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1986 transformValues);
1987}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001988
Sami Väisänend59ca052016-06-21 16:10:00 +03001989void Context::stencilStrokePathInstanced(GLsizei numPaths,
1990 GLenum pathNameType,
1991 const void *paths,
1992 GLuint pathBase,
1993 GLint reference,
1994 GLuint mask,
1995 GLenum transformType,
1996 const GLfloat *transformValues)
1997{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001998 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001999
2000 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2001 syncRendererState();
2002
2003 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
2004 transformValues);
2005}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002006
Sami Väisänend59ca052016-06-21 16:10:00 +03002007void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
2008 GLenum pathNameType,
2009 const void *paths,
2010 GLuint pathBase,
2011 GLenum fillMode,
2012 GLuint mask,
2013 GLenum coverMode,
2014 GLenum transformType,
2015 const GLfloat *transformValues)
2016{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002017 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002018
2019 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2020 syncRendererState();
2021
2022 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
2023 transformType, transformValues);
2024}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002025
Sami Väisänend59ca052016-06-21 16:10:00 +03002026void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
2027 GLenum pathNameType,
2028 const void *paths,
2029 GLuint pathBase,
2030 GLint reference,
2031 GLuint mask,
2032 GLenum coverMode,
2033 GLenum transformType,
2034 const GLfloat *transformValues)
2035{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002036 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002037
2038 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2039 syncRendererState();
2040
2041 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
2042 transformType, transformValues);
2043}
2044
Sami Väisänen46eaa942016-06-29 10:26:37 +03002045void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
2046{
2047 auto *programObject = getProgram(program);
2048
2049 programObject->bindFragmentInputLocation(location, name);
2050}
2051
2052void Context::programPathFragmentInputGen(GLuint program,
2053 GLint location,
2054 GLenum genMode,
2055 GLint components,
2056 const GLfloat *coeffs)
2057{
2058 auto *programObject = getProgram(program);
2059
Jamie Madillbd044ed2017-06-05 12:59:21 -04002060 programObject->pathFragmentInputGen(this, location, genMode, components, coeffs);
Sami Väisänen46eaa942016-06-29 10:26:37 +03002061}
2062
jchen1015015f72017-03-16 13:54:21 +08002063GLuint Context::getProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name)
2064{
jchen10fd7c3b52017-03-21 15:36:03 +08002065 const auto *programObject = getProgram(program);
jchen1015015f72017-03-16 13:54:21 +08002066 return QueryProgramResourceIndex(programObject, programInterface, name);
2067}
2068
jchen10fd7c3b52017-03-21 15:36:03 +08002069void Context::getProgramResourceName(GLuint program,
2070 GLenum programInterface,
2071 GLuint index,
2072 GLsizei bufSize,
2073 GLsizei *length,
2074 GLchar *name)
2075{
2076 const auto *programObject = getProgram(program);
2077 QueryProgramResourceName(programObject, programInterface, index, bufSize, length, name);
2078}
2079
jchen10191381f2017-04-11 13:59:04 +08002080GLint Context::getProgramResourceLocation(GLuint program,
2081 GLenum programInterface,
2082 const GLchar *name)
2083{
2084 const auto *programObject = getProgram(program);
2085 return QueryProgramResourceLocation(programObject, programInterface, name);
2086}
2087
jchen10880683b2017-04-12 16:21:55 +08002088void Context::getProgramResourceiv(GLuint program,
2089 GLenum programInterface,
2090 GLuint index,
2091 GLsizei propCount,
2092 const GLenum *props,
2093 GLsizei bufSize,
2094 GLsizei *length,
2095 GLint *params)
2096{
2097 const auto *programObject = getProgram(program);
2098 QueryProgramResourceiv(programObject, programInterface, index, propCount, props, bufSize,
2099 length, params);
2100}
2101
jchen10d9cd7b72017-08-30 15:04:25 +08002102void Context::getProgramInterfaceiv(GLuint program,
2103 GLenum programInterface,
2104 GLenum pname,
2105 GLint *params)
2106{
2107 const auto *programObject = getProgram(program);
2108 QueryProgramInterfaceiv(programObject, programInterface, pname, params);
2109}
2110
Jamie Madill71c88b32017-09-14 22:20:29 -04002111void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002112{
Geoff Langda5777c2014-07-11 09:52:58 -04002113 if (error.isError())
2114 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002115 GLenum code = error.getCode();
2116 mErrors.insert(code);
2117 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
2118 {
2119 markContextLost();
2120 }
Geoff Lang70d0f492015-12-10 17:45:46 -05002121
2122 if (!error.getMessage().empty())
2123 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002124 auto *debug = &mGLState.getDebug();
2125 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
2126 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05002127 }
Geoff Langda5777c2014-07-11 09:52:58 -04002128 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002129}
2130
2131// Get one of the recorded errors and clear its flag, if any.
2132// [OpenGL ES 2.0.24] section 2.5 page 13.
2133GLenum Context::getError()
2134{
Geoff Langda5777c2014-07-11 09:52:58 -04002135 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002136 {
Geoff Langda5777c2014-07-11 09:52:58 -04002137 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002138 }
Geoff Langda5777c2014-07-11 09:52:58 -04002139 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002140 {
Geoff Langda5777c2014-07-11 09:52:58 -04002141 GLenum error = *mErrors.begin();
2142 mErrors.erase(mErrors.begin());
2143 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002144 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002145}
2146
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002147// NOTE: this function should not assume that this context is current!
2148void Context::markContextLost()
2149{
2150 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002151 {
Jamie Madill231c7f52017-04-26 13:45:37 -04002152 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002153 mContextLostForced = true;
2154 }
Jamie Madill231c7f52017-04-26 13:45:37 -04002155 mContextLost = true;
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002156}
2157
2158bool Context::isContextLost()
2159{
2160 return mContextLost;
2161}
2162
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002163GLenum Context::getResetStatus()
2164{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002165 // Even if the application doesn't want to know about resets, we want to know
2166 // as it will allow us to skip all the calls.
2167 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002168 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002169 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002170 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002171 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002172 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002173
2174 // EXT_robustness, section 2.6: If the reset notification behavior is
2175 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2176 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2177 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002178 }
2179
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002180 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2181 // status should be returned at least once, and GL_NO_ERROR should be returned
2182 // once the device has finished resetting.
2183 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002184 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002185 ASSERT(mResetStatus == GL_NO_ERROR);
2186 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002187
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002188 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002189 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002190 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002191 }
2192 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002193 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002194 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002195 // If markContextLost was used to mark the context lost then
2196 // assume that is not recoverable, and continue to report the
2197 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002198 mResetStatus = mImplementation->getResetStatus();
2199 }
Jamie Madill893ab082014-05-16 16:56:10 -04002200
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002201 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002202}
2203
2204bool Context::isResetNotificationEnabled()
2205{
2206 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2207}
2208
Corentin Walleze3b10e82015-05-20 11:06:25 -04002209const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002210{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002211 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002212}
2213
2214EGLenum Context::getClientType() const
2215{
2216 return mClientType;
2217}
2218
2219EGLenum Context::getRenderBuffer() const
2220{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002221 const Framebuffer *framebuffer = mState.mFramebuffers->getFramebuffer(0);
2222 if (framebuffer == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -04002223 {
2224 return EGL_NONE;
2225 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002226
2227 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2228 ASSERT(backAttachment != nullptr);
2229 return backAttachment->getSurface()->getRenderBuffer();
Régis Fénéon83107972015-02-05 12:57:44 +01002230}
2231
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002232VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002233{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002234 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002235 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2236 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002237 {
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002238 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle,
2239 mCaps.maxVertexAttributes, mCaps.maxVertexAttribBindings);
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002240
Jamie Madill96a483b2017-06-27 16:49:21 -04002241 mVertexArrayMap.assign(vertexArrayHandle, vertexArray);
Geoff Lang36167ab2015-12-07 10:27:14 -05002242 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002243
2244 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002245}
2246
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002247TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002248{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002249 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002250 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2251 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002252 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002253 transformFeedback =
2254 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002255 transformFeedback->addRef();
Jamie Madill96a483b2017-06-27 16:49:21 -04002256 mTransformFeedbackMap.assign(transformFeedbackHandle, transformFeedback);
Geoff Lang36167ab2015-12-07 10:27:14 -05002257 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002258
2259 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002260}
2261
2262bool Context::isVertexArrayGenerated(GLuint vertexArray)
2263{
Jamie Madill96a483b2017-06-27 16:49:21 -04002264 ASSERT(mVertexArrayMap.contains(0));
2265 return mVertexArrayMap.contains(vertexArray);
Geoff Lang36167ab2015-12-07 10:27:14 -05002266}
2267
2268bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2269{
Jamie Madill96a483b2017-06-27 16:49:21 -04002270 ASSERT(mTransformFeedbackMap.contains(0));
2271 return mTransformFeedbackMap.contains(transformFeedback);
Geoff Lang36167ab2015-12-07 10:27:14 -05002272}
2273
Shannon Woods53a94a82014-06-24 15:20:36 -04002274void Context::detachTexture(GLuint texture)
2275{
2276 // Simple pass-through to State's detachTexture method, as textures do not require
2277 // allocation map management either here or in the resource manager at detach time.
2278 // Zero textures are held by the Context, and we don't attempt to request them from
2279 // the State.
Jamie Madilla02315b2017-02-23 14:14:47 -05002280 mGLState.detachTexture(this, mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002281}
2282
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002283void Context::detachBuffer(GLuint buffer)
2284{
Yuly Novikov5807a532015-12-03 13:01:22 -05002285 // Simple pass-through to State's detachBuffer method, since
2286 // only buffer attachments to container objects that are bound to the current context
2287 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002288
Yuly Novikov5807a532015-12-03 13:01:22 -05002289 // [OpenGL ES 3.2] section 5.1.2 page 45:
2290 // Attachments to unbound container objects, such as
2291 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2292 // are not affected and continue to act as references on the deleted object
Jamie Madill4928b7c2017-06-20 12:57:39 -04002293 mGLState.detachBuffer(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002294}
2295
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002296void Context::detachFramebuffer(GLuint framebuffer)
2297{
Shannon Woods53a94a82014-06-24 15:20:36 -04002298 // Framebuffer detachment is handled by Context, because 0 is a valid
2299 // Framebuffer object, and a pointer to it must be passed from Context
2300 // to State at binding time.
2301
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002302 // [OpenGL ES 2.0.24] section 4.4 page 107:
Jamie Madill231c7f52017-04-26 13:45:37 -04002303 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as
2304 // though BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of
2305 // zero.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002306
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002307 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002308 {
2309 bindReadFramebuffer(0);
2310 }
2311
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002312 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002313 {
2314 bindDrawFramebuffer(0);
2315 }
2316}
2317
2318void Context::detachRenderbuffer(GLuint renderbuffer)
2319{
Jamie Madilla02315b2017-02-23 14:14:47 -05002320 mGLState.detachRenderbuffer(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002321}
2322
Jamie Madill57a89722013-07-02 11:57:03 -04002323void Context::detachVertexArray(GLuint vertexArray)
2324{
Jamie Madill77a72f62015-04-14 11:18:32 -04002325 // Vertex array detachment is handled by Context, because 0 is a valid
2326 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002327 // binding time.
2328
Jamie Madill57a89722013-07-02 11:57:03 -04002329 // [OpenGL ES 3.0.2] section 2.10 page 43:
2330 // If a vertex array object that is currently bound is deleted, the binding
2331 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002332 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002333 {
2334 bindVertexArray(0);
2335 }
2336}
2337
Geoff Langc8058452014-02-03 12:04:11 -05002338void Context::detachTransformFeedback(GLuint transformFeedback)
2339{
Corentin Walleza2257da2016-04-19 16:43:12 -04002340 // Transform feedback detachment is handled by Context, because 0 is a valid
2341 // transform feedback, and a pointer to it must be passed from Context to State at
2342 // binding time.
2343
2344 // The OpenGL specification doesn't mention what should happen when the currently bound
2345 // transform feedback object is deleted. Since it is a container object, we treat it like
2346 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madill4928b7c2017-06-20 12:57:39 -04002347 if (mGLState.removeTransformFeedbackBinding(this, transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002348 {
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04002349 bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
Corentin Walleza2257da2016-04-19 16:43:12 -04002350 }
Geoff Langc8058452014-02-03 12:04:11 -05002351}
2352
Jamie Madilldc356042013-07-19 16:36:57 -04002353void Context::detachSampler(GLuint sampler)
2354{
Jamie Madill4928b7c2017-06-20 12:57:39 -04002355 mGLState.detachSampler(this, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002356}
2357
Jamie Madill3ef140a2017-08-26 23:11:21 -04002358void Context::vertexAttribDivisor(GLuint index, GLuint divisor)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002359{
Shaodde78e82017-05-22 14:13:27 +08002360 mGLState.setVertexAttribDivisor(this, index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002361}
2362
Jamie Madille29d1672013-07-19 16:36:57 -04002363void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2364{
Geoff Langc1984ed2016-10-07 12:41:00 -04002365 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002366 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002367 SetSamplerParameteri(samplerObject, pname, param);
Jamie Madill06ef36b2017-09-09 23:32:46 -04002368 mGLState.setObjectDirty(GL_SAMPLER);
Geoff Langc1984ed2016-10-07 12:41:00 -04002369}
Jamie Madille29d1672013-07-19 16:36:57 -04002370
Geoff Langc1984ed2016-10-07 12:41:00 -04002371void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2372{
2373 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002374 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002375 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madill06ef36b2017-09-09 23:32:46 -04002376 mGLState.setObjectDirty(GL_SAMPLER);
Jamie Madille29d1672013-07-19 16:36:57 -04002377}
2378
2379void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2380{
Geoff Langc1984ed2016-10-07 12:41:00 -04002381 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002382 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002383 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madill06ef36b2017-09-09 23:32:46 -04002384 mGLState.setObjectDirty(GL_SAMPLER);
Jamie Madille29d1672013-07-19 16:36:57 -04002385}
2386
Geoff Langc1984ed2016-10-07 12:41:00 -04002387void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002388{
Geoff Langc1984ed2016-10-07 12:41:00 -04002389 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002390 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002391 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill06ef36b2017-09-09 23:32:46 -04002392 mGLState.setObjectDirty(GL_SAMPLER);
Jamie Madill9675b802013-07-19 16:36:59 -04002393}
2394
Geoff Langc1984ed2016-10-07 12:41:00 -04002395void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002396{
Geoff Langc1984ed2016-10-07 12:41:00 -04002397 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002398 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002399 QuerySamplerParameteriv(samplerObject, pname, params);
Jamie Madill06ef36b2017-09-09 23:32:46 -04002400 mGLState.setObjectDirty(GL_SAMPLER);
Geoff Langc1984ed2016-10-07 12:41:00 -04002401}
Jamie Madill9675b802013-07-19 16:36:59 -04002402
Geoff Langc1984ed2016-10-07 12:41:00 -04002403void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2404{
2405 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002406 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002407 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill06ef36b2017-09-09 23:32:46 -04002408 mGLState.setObjectDirty(GL_SAMPLER);
Jamie Madill9675b802013-07-19 16:36:59 -04002409}
2410
Olli Etuahof0fee072016-03-30 15:11:58 +03002411void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2412{
2413 gl::Program *programObject = getProgram(program);
Yunchao He61afff12017-03-14 15:34:03 +08002414 SetProgramParameteri(programObject, pname, value);
Olli Etuahof0fee072016-03-30 15:11:58 +03002415}
2416
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002417void Context::initRendererString()
2418{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002419 std::ostringstream rendererString;
2420 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002421 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002422 rendererString << ")";
2423
Geoff Langcec35902014-04-16 10:52:36 -04002424 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002425}
2426
Geoff Langc339c4e2016-11-29 10:37:36 -05002427void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002428{
Geoff Langc339c4e2016-11-29 10:37:36 -05002429 const Version &clientVersion = getClientVersion();
2430
2431 std::ostringstream versionString;
2432 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2433 << ANGLE_VERSION_STRING << ")";
2434 mVersionString = MakeStaticString(versionString.str());
2435
2436 std::ostringstream shadingLanguageVersionString;
2437 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2438 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2439 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2440 << ")";
2441 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002442}
2443
Geoff Langcec35902014-04-16 10:52:36 -04002444void Context::initExtensionStrings()
2445{
Geoff Langc339c4e2016-11-29 10:37:36 -05002446 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2447 std::ostringstream combinedStringStream;
2448 std::copy(strings.begin(), strings.end(),
2449 std::ostream_iterator<const char *>(combinedStringStream, " "));
2450 return MakeStaticString(combinedStringStream.str());
2451 };
2452
2453 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002454 for (const auto &extensionString : mExtensions.getStrings())
2455 {
2456 mExtensionStrings.push_back(MakeStaticString(extensionString));
2457 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002458 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002459
Bryan Bernhart58806562017-01-05 13:09:31 -08002460 const gl::Extensions &nativeExtensions = mImplementation->getNativeExtensions();
2461
Geoff Langc339c4e2016-11-29 10:37:36 -05002462 mRequestableExtensionStrings.clear();
2463 for (const auto &extensionInfo : GetExtensionInfoMap())
2464 {
2465 if (extensionInfo.second.Requestable &&
Bryan Bernhart58806562017-01-05 13:09:31 -08002466 !(mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
2467 nativeExtensions.*(extensionInfo.second.ExtensionsMember))
Geoff Langc339c4e2016-11-29 10:37:36 -05002468 {
2469 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2470 }
2471 }
2472 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002473}
2474
Geoff Langc339c4e2016-11-29 10:37:36 -05002475const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002476{
Geoff Langc339c4e2016-11-29 10:37:36 -05002477 switch (name)
2478 {
2479 case GL_VENDOR:
2480 return reinterpret_cast<const GLubyte *>("Google Inc.");
2481
2482 case GL_RENDERER:
2483 return reinterpret_cast<const GLubyte *>(mRendererString);
2484
2485 case GL_VERSION:
2486 return reinterpret_cast<const GLubyte *>(mVersionString);
2487
2488 case GL_SHADING_LANGUAGE_VERSION:
2489 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2490
2491 case GL_EXTENSIONS:
2492 return reinterpret_cast<const GLubyte *>(mExtensionString);
2493
2494 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2495 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2496
2497 default:
2498 UNREACHABLE();
2499 return nullptr;
2500 }
Geoff Langcec35902014-04-16 10:52:36 -04002501}
2502
Geoff Langc339c4e2016-11-29 10:37:36 -05002503const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002504{
Geoff Langc339c4e2016-11-29 10:37:36 -05002505 switch (name)
2506 {
2507 case GL_EXTENSIONS:
2508 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2509
2510 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2511 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2512
2513 default:
2514 UNREACHABLE();
2515 return nullptr;
2516 }
Geoff Langcec35902014-04-16 10:52:36 -04002517}
2518
2519size_t Context::getExtensionStringCount() const
2520{
2521 return mExtensionStrings.size();
2522}
2523
Geoff Langc339c4e2016-11-29 10:37:36 -05002524void Context::requestExtension(const char *name)
2525{
2526 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2527 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2528 const auto &extension = extensionInfos.at(name);
2529 ASSERT(extension.Requestable);
2530
2531 if (mExtensions.*(extension.ExtensionsMember))
2532 {
2533 // Extension already enabled
2534 return;
2535 }
2536
2537 mExtensions.*(extension.ExtensionsMember) = true;
2538 updateCaps();
2539 initExtensionStrings();
Bryan Bernhart58806562017-01-05 13:09:31 -08002540
Jamie Madill2f348d22017-06-05 10:50:59 -04002541 // Release the shader compiler so it will be re-created with the requested extensions enabled.
2542 releaseShaderCompiler();
Geoff Lang9aded172017-04-05 11:07:56 -04002543
Jamie Madill81c2e252017-09-09 23:32:46 -04002544 // Invalidate all textures and framebuffer. Some extensions make new formats renderable or
2545 // sampleable.
2546 mState.mTextures->signalAllTexturesDirty();
Geoff Lang9aded172017-04-05 11:07:56 -04002547 for (auto &zeroTexture : mZeroTextures)
2548 {
Jamie Madill81c2e252017-09-09 23:32:46 -04002549 zeroTexture.second->signalDirty();
Geoff Lang9aded172017-04-05 11:07:56 -04002550 }
2551
2552 mState.mFramebuffers->invalidateFramebufferComplenessCache();
Geoff Langc339c4e2016-11-29 10:37:36 -05002553}
2554
2555size_t Context::getRequestableExtensionStringCount() const
2556{
2557 return mRequestableExtensionStrings.size();
2558}
2559
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002560void Context::beginTransformFeedback(GLenum primitiveMode)
2561{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002562 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002563 ASSERT(transformFeedback != nullptr);
2564 ASSERT(!transformFeedback->isPaused());
2565
Jamie Madill6c1f6712017-02-14 19:08:04 -05002566 transformFeedback->begin(this, primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002567}
2568
2569bool Context::hasActiveTransformFeedback(GLuint program) const
2570{
2571 for (auto pair : mTransformFeedbackMap)
2572 {
2573 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2574 {
2575 return true;
2576 }
2577 }
2578 return false;
2579}
2580
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002581void Context::initCaps(const egl::DisplayExtensions &displayExtensions)
Geoff Lang493daf52014-07-03 13:38:44 -04002582{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002583 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002584
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002585 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002586
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002587 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002588
Geoff Langeb66a6e2016-10-31 13:06:12 -04002589 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002590 {
2591 // Disable ES3+ extensions
Jamie Madill231c7f52017-04-26 13:45:37 -04002592 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002593 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002594 mExtensions.textureNorm16 = false;
Martin Radev137032d2017-07-13 10:11:12 +03002595 mExtensions.multiview = false;
2596 mExtensions.maxViews = 1u;
Geoff Lang493daf52014-07-03 13:38:44 -04002597 }
2598
Geoff Langeb66a6e2016-10-31 13:06:12 -04002599 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002600 {
2601 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
Jamie Madill231c7f52017-04-26 13:45:37 -04002602 // mExtensions.sRGB = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002603 }
2604
Jamie Madill00ed7a12016-05-19 13:13:38 -04002605 // Some extensions are always available because they are implemented in the GL layer.
Jamie Madill231c7f52017-04-26 13:45:37 -04002606 mExtensions.bindUniformLocation = true;
2607 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002608 mExtensions.bindGeneratesResource = true;
Geoff Langfeb8c682017-02-13 16:07:35 -05002609 mExtensions.clientArrays = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002610 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002611
2612 // Enable the no error extension if the context was created with the flag.
2613 mExtensions.noError = mSkipValidation;
2614
Corentin Wallezccab69d2017-01-27 16:57:15 -05002615 // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
Corentin Wallezc295e512017-01-27 17:47:50 -05002616 mExtensions.surfacelessContext = displayExtensions.surfacelessContext;
Corentin Wallezccab69d2017-01-27 16:57:15 -05002617
Geoff Lang70d0f492015-12-10 17:45:46 -05002618 // Explicitly enable GL_KHR_debug
2619 mExtensions.debug = true;
2620 mExtensions.maxDebugMessageLength = 1024;
2621 mExtensions.maxDebugLoggedMessages = 1024;
2622 mExtensions.maxDebugGroupStackDepth = 1024;
2623 mExtensions.maxLabelLength = 1024;
2624
Geoff Langff5b2d52016-09-07 11:32:23 -04002625 // Explicitly enable GL_ANGLE_robust_client_memory
2626 mExtensions.robustClientMemory = true;
2627
Jamie Madille08a1d32017-03-07 17:24:06 -05002628 // Determine robust resource init availability from EGL.
2629 mExtensions.robustResourceInitialization =
Jamie Madill948bbe52017-06-01 13:10:42 -04002630 egl::Display::GetClientExtensions().displayRobustResourceInitialization;
Jamie Madille08a1d32017-03-07 17:24:06 -05002631
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08002632 // mExtensions.robustBufferAccessBehavior is true only if robust access is true and the backend
2633 // supports it.
2634 mExtensions.robustBufferAccessBehavior =
2635 mRobustAccess && mExtensions.robustBufferAccessBehavior;
2636
Jamie Madillc43be722017-07-13 16:22:14 -04002637 // Enable the cache control query unconditionally.
2638 mExtensions.programCacheControl = true;
2639
Geoff Lang301d1612014-07-09 10:34:37 -04002640 // Apply implementation limits
2641 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002642 mCaps.maxVertexAttribBindings =
2643 getClientVersion() < ES_3_1
2644 ? mCaps.maxVertexAttributes
2645 : std::min<GLuint>(mCaps.maxVertexAttribBindings, MAX_VERTEX_ATTRIB_BINDINGS);
2646
Jamie Madill231c7f52017-04-26 13:45:37 -04002647 mCaps.maxVertexUniformBlocks = std::min<GLuint>(
2648 mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2649 mCaps.maxVertexOutputComponents =
2650 std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang301d1612014-07-09 10:34:37 -04002651
Jamie Madill231c7f52017-04-26 13:45:37 -04002652 mCaps.maxFragmentInputComponents =
2653 std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002654
Geoff Langc287ea62016-09-16 14:46:51 -04002655 // WebGL compatibility
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002656 mExtensions.webglCompatibility = mWebGLContext;
Geoff Langc287ea62016-09-16 14:46:51 -04002657 for (const auto &extensionInfo : GetExtensionInfoMap())
2658 {
2659 // If this context is for WebGL, disable all enableable extensions
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002660 if (mWebGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002661 {
2662 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2663 }
2664 }
2665
2666 // Generate texture caps
2667 updateCaps();
2668}
2669
2670void Context::updateCaps()
2671{
Geoff Lang900013c2014-07-07 11:32:19 -04002672 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002673 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002674
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002675 for (auto capsIt : mImplementation->getNativeTextureCaps())
Geoff Lang493daf52014-07-03 13:38:44 -04002676 {
Geoff Langca271392017-04-05 12:30:00 -04002677 GLenum sizedInternalFormat = capsIt.first;
Jamie Madill231c7f52017-04-26 13:45:37 -04002678 TextureCaps formatCaps = capsIt.second;
Geoff Lang493daf52014-07-03 13:38:44 -04002679
Geoff Langca271392017-04-05 12:30:00 -04002680 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002681
Geoff Lang0d8b7242015-09-09 14:56:53 -04002682 // Update the format caps based on the client version and extensions.
2683 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2684 // ES3.
2685 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002686 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002687 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002688 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002689 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002690 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002691
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002692 // OpenGL ES does not support multisampling with non-rendererable formats
2693 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
Olli Etuaho50c562d2017-06-06 14:43:30 +03002694 if (!formatCaps.renderable ||
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002695 (getClientVersion() < ES_3_1 &&
2696 (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
Geoff Lang493daf52014-07-03 13:38:44 -04002697 {
Geoff Langd87878e2014-09-19 15:42:59 -04002698 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002699 }
Olli Etuaho50c562d2017-06-06 14:43:30 +03002700 else
2701 {
2702 // We may have limited the max samples for some required renderbuffer formats due to
2703 // non-conformant formats. In this case MAX_SAMPLES needs to be lowered accordingly.
2704 GLuint formatMaxSamples = formatCaps.getMaxSamples();
2705
2706 // GLES 3.0.5 section 4.4.2.2: "Implementations must support creation of renderbuffers
2707 // in these required formats with up to the value of MAX_SAMPLES multisamples, with the
2708 // exception of signed and unsigned integer formats."
2709 if (formatInfo.componentType != GL_INT && formatInfo.componentType != GL_UNSIGNED_INT &&
2710 formatInfo.isRequiredRenderbufferFormat(getClientVersion()))
2711 {
2712 ASSERT(getClientVersion() < ES_3_0 || formatMaxSamples >= 4);
2713 mCaps.maxSamples = std::min(mCaps.maxSamples, formatMaxSamples);
2714 }
2715
2716 // Handle GLES 3.1 MAX_*_SAMPLES values similarly to MAX_SAMPLES.
2717 if (getClientVersion() >= ES_3_1)
2718 {
2719 // GLES 3.1 section 9.2.5: "Implementations must support creation of renderbuffers
2720 // in these required formats with up to the value of MAX_SAMPLES multisamples, with
2721 // the exception that the signed and unsigned integer formats are required only to
2722 // support creation of renderbuffers with up to the value of MAX_INTEGER_SAMPLES
2723 // multisamples, which must be at least one."
2724 if (formatInfo.componentType == GL_INT ||
2725 formatInfo.componentType == GL_UNSIGNED_INT)
2726 {
2727 mCaps.maxIntegerSamples = std::min(mCaps.maxIntegerSamples, formatMaxSamples);
2728 }
2729
2730 // GLES 3.1 section 19.3.1.
2731 if (formatCaps.texturable)
2732 {
2733 if (formatInfo.depthBits > 0)
2734 {
2735 mCaps.maxDepthTextureSamples =
2736 std::min(mCaps.maxDepthTextureSamples, formatMaxSamples);
2737 }
2738 else if (formatInfo.redBits > 0)
2739 {
2740 mCaps.maxColorTextureSamples =
2741 std::min(mCaps.maxColorTextureSamples, formatMaxSamples);
2742 }
2743 }
2744 }
2745 }
Geoff Langd87878e2014-09-19 15:42:59 -04002746
2747 if (formatCaps.texturable && formatInfo.compressed)
2748 {
Geoff Langca271392017-04-05 12:30:00 -04002749 mCaps.compressedTextureFormats.push_back(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002750 }
2751
Geoff Langca271392017-04-05 12:30:00 -04002752 mTextureCaps.insert(sizedInternalFormat, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002753 }
Jamie Madill32447362017-06-28 14:53:52 -04002754
2755 // If program binary is disabled, blank out the memory cache pointer.
2756 if (!mImplementation->getNativeExtensions().getProgramBinary)
2757 {
2758 mMemoryProgramCache = nullptr;
2759 }
Geoff Lang493daf52014-07-03 13:38:44 -04002760}
2761
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002762void Context::initWorkarounds()
2763{
Jamie Madill761b02c2017-06-23 16:27:06 -04002764 // Apply back-end workarounds.
2765 mImplementation->applyNativeWorkarounds(&mWorkarounds);
2766
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002767 // Lose the context upon out of memory error if the application is
2768 // expecting to watch for those events.
2769 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2770}
2771
Jamie Madill1b94d432015-08-07 13:23:23 -04002772void Context::syncRendererState()
2773{
Jamie Madill7d1f5c62017-09-02 15:32:15 -04002774 mGLState.syncDirtyObjects(this);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002775 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
Jamie Madillfe548342017-06-19 11:13:24 -04002776 mImplementation->syncState(this, dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002777 mGLState.clearDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -04002778}
2779
Jamie Madillad9f24e2016-02-12 09:27:24 -05002780void Context::syncRendererState(const State::DirtyBits &bitMask,
2781 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002782{
Jamie Madill7d1f5c62017-09-02 15:32:15 -04002783 mGLState.syncDirtyObjects(this, objectMask);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002784 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
Jamie Madillfe548342017-06-19 11:13:24 -04002785 mImplementation->syncState(this, dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002786 mGLState.clearDirtyBits(dirtyBits);
Jamie Madill1b94d432015-08-07 13:23:23 -04002787}
Jamie Madillc29968b2016-01-20 11:17:23 -05002788
2789void Context::blitFramebuffer(GLint srcX0,
2790 GLint srcY0,
2791 GLint srcX1,
2792 GLint srcY1,
2793 GLint dstX0,
2794 GLint dstY0,
2795 GLint dstX1,
2796 GLint dstY1,
2797 GLbitfield mask,
2798 GLenum filter)
2799{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002800 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002801 ASSERT(drawFramebuffer);
2802
2803 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2804 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2805
Jamie Madillad9f24e2016-02-12 09:27:24 -05002806 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002807
Jamie Madillc564c072017-06-01 12:45:42 -04002808 handleError(drawFramebuffer->blit(this, srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002809}
Jamie Madillc29968b2016-01-20 11:17:23 -05002810
2811void Context::clear(GLbitfield mask)
2812{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002813 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002814 handleError(mGLState.getDrawFramebuffer()->clear(this, mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002815}
2816
2817void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2818{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002819 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002820 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002821}
2822
2823void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2824{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002825 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002826 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002827}
2828
2829void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2830{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002831 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002832 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002833}
2834
2835void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2836{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002837 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002838 ASSERT(framebufferObject);
2839
2840 // If a buffer is not present, the clear has no effect
2841 if (framebufferObject->getDepthbuffer() == nullptr &&
2842 framebufferObject->getStencilbuffer() == nullptr)
2843 {
2844 return;
2845 }
2846
Jamie Madillad9f24e2016-02-12 09:27:24 -05002847 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002848 handleError(framebufferObject->clearBufferfi(this, buffer, drawbuffer, depth, stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002849}
2850
2851void Context::readPixels(GLint x,
2852 GLint y,
2853 GLsizei width,
2854 GLsizei height,
2855 GLenum format,
2856 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002857 void *pixels)
Jamie Madillc29968b2016-01-20 11:17:23 -05002858{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002859 if (width == 0 || height == 0)
2860 {
2861 return;
2862 }
2863
Jamie Madillad9f24e2016-02-12 09:27:24 -05002864 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002865
Jamie Madillb6664922017-07-25 12:55:04 -04002866 Framebuffer *readFBO = mGLState.getReadFramebuffer();
2867 ASSERT(readFBO);
Jamie Madillc29968b2016-01-20 11:17:23 -05002868
2869 Rectangle area(x, y, width, height);
Jamie Madillb6664922017-07-25 12:55:04 -04002870 handleError(readFBO->readPixels(this, area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002871}
2872
2873void Context::copyTexImage2D(GLenum target,
2874 GLint level,
2875 GLenum internalformat,
2876 GLint x,
2877 GLint y,
2878 GLsizei width,
2879 GLsizei height,
2880 GLint border)
2881{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002882 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002883 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002884
Jamie Madillc29968b2016-01-20 11:17:23 -05002885 Rectangle sourceArea(x, y, width, height);
2886
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002887 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002888 Texture *texture =
2889 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002890 handleError(texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002891}
2892
2893void Context::copyTexSubImage2D(GLenum target,
2894 GLint level,
2895 GLint xoffset,
2896 GLint yoffset,
2897 GLint x,
2898 GLint y,
2899 GLsizei width,
2900 GLsizei height)
2901{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002902 if (width == 0 || height == 0)
2903 {
2904 return;
2905 }
2906
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002907 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002908 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002909
Jamie Madillc29968b2016-01-20 11:17:23 -05002910 Offset destOffset(xoffset, yoffset, 0);
2911 Rectangle sourceArea(x, y, width, height);
2912
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002913 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002914 Texture *texture =
2915 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002916 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002917}
2918
2919void Context::copyTexSubImage3D(GLenum target,
2920 GLint level,
2921 GLint xoffset,
2922 GLint yoffset,
2923 GLint zoffset,
2924 GLint x,
2925 GLint y,
2926 GLsizei width,
2927 GLsizei height)
2928{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002929 if (width == 0 || height == 0)
2930 {
2931 return;
2932 }
2933
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002934 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002935 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002936
Jamie Madillc29968b2016-01-20 11:17:23 -05002937 Offset destOffset(xoffset, yoffset, zoffset);
2938 Rectangle sourceArea(x, y, width, height);
2939
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002940 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002941 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002942 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002943}
2944
2945void Context::framebufferTexture2D(GLenum target,
2946 GLenum attachment,
2947 GLenum textarget,
2948 GLuint texture,
2949 GLint level)
2950{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002951 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002952 ASSERT(framebuffer);
2953
2954 if (texture != 0)
2955 {
2956 Texture *textureObj = getTexture(texture);
2957
2958 ImageIndex index = ImageIndex::MakeInvalid();
2959
2960 if (textarget == GL_TEXTURE_2D)
2961 {
2962 index = ImageIndex::Make2D(level);
2963 }
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002964 else if (textarget == GL_TEXTURE_RECTANGLE_ANGLE)
2965 {
2966 index = ImageIndex::MakeRectangle(level);
2967 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08002968 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
2969 {
2970 ASSERT(level == 0);
2971 index = ImageIndex::Make2DMultisample();
2972 }
Jamie Madillc29968b2016-01-20 11:17:23 -05002973 else
2974 {
2975 ASSERT(IsCubeMapTextureTarget(textarget));
2976 index = ImageIndex::MakeCube(textarget, level);
2977 }
2978
Jamie Madilla02315b2017-02-23 14:14:47 -05002979 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
Jamie Madillc29968b2016-01-20 11:17:23 -05002980 }
2981 else
2982 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002983 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002984 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002985
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002986 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002987}
2988
2989void Context::framebufferRenderbuffer(GLenum target,
2990 GLenum attachment,
2991 GLenum renderbuffertarget,
2992 GLuint renderbuffer)
2993{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002994 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002995 ASSERT(framebuffer);
2996
2997 if (renderbuffer != 0)
2998 {
2999 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
Jamie Madilla02315b2017-02-23 14:14:47 -05003000
3001 framebuffer->setAttachment(this, GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
Jamie Madillc29968b2016-01-20 11:17:23 -05003002 renderbufferObject);
3003 }
3004 else
3005 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003006 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003007 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003008
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003009 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003010}
3011
3012void Context::framebufferTextureLayer(GLenum target,
3013 GLenum attachment,
3014 GLuint texture,
3015 GLint level,
3016 GLint layer)
3017{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003018 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003019 ASSERT(framebuffer);
3020
3021 if (texture != 0)
3022 {
3023 Texture *textureObject = getTexture(texture);
3024
3025 ImageIndex index = ImageIndex::MakeInvalid();
3026
3027 if (textureObject->getTarget() == GL_TEXTURE_3D)
3028 {
3029 index = ImageIndex::Make3D(level, layer);
3030 }
3031 else
3032 {
3033 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
3034 index = ImageIndex::Make2DArray(level, layer);
3035 }
3036
Jamie Madilla02315b2017-02-23 14:14:47 -05003037 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObject);
Jamie Madillc29968b2016-01-20 11:17:23 -05003038 }
3039 else
3040 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003041 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003042 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003043
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003044 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003045}
3046
Martin Radev137032d2017-07-13 10:11:12 +03003047void Context::framebufferTextureMultiviewLayeredANGLE(GLenum target,
3048 GLenum attachment,
3049 GLuint texture,
3050 GLint level,
3051 GLint baseViewIndex,
3052 GLsizei numViews)
3053{
Martin Radev82ef7742017-08-08 17:44:58 +03003054 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
3055 ASSERT(framebuffer);
3056
3057 if (texture != 0)
3058 {
3059 Texture *textureObj = getTexture(texture);
3060
Martin Radev18b75ba2017-08-15 15:50:40 +03003061 ImageIndex index = ImageIndex::Make2DArrayRange(level, baseViewIndex, numViews);
Martin Radev82ef7742017-08-08 17:44:58 +03003062 framebuffer->setAttachmentMultiviewLayered(this, GL_TEXTURE, attachment, index, textureObj,
3063 numViews, baseViewIndex);
3064 }
3065 else
3066 {
3067 framebuffer->resetAttachment(this, attachment);
3068 }
3069
3070 mGLState.setObjectDirty(target);
Martin Radev137032d2017-07-13 10:11:12 +03003071}
3072
3073void Context::framebufferTextureMultiviewSideBySideANGLE(GLenum target,
3074 GLenum attachment,
3075 GLuint texture,
3076 GLint level,
3077 GLsizei numViews,
3078 const GLint *viewportOffsets)
3079{
Martin Radev5dae57b2017-07-14 16:15:55 +03003080 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
3081 ASSERT(framebuffer);
3082
3083 if (texture != 0)
3084 {
3085 Texture *textureObj = getTexture(texture);
3086
3087 ImageIndex index = ImageIndex::Make2D(level);
3088 framebuffer->setAttachmentMultiviewSideBySide(this, GL_TEXTURE, attachment, index,
3089 textureObj, numViews, viewportOffsets);
3090 }
3091 else
3092 {
3093 framebuffer->resetAttachment(this, attachment);
3094 }
3095
3096 mGLState.setObjectDirty(target);
Martin Radev137032d2017-07-13 10:11:12 +03003097}
3098
Jamie Madillc29968b2016-01-20 11:17:23 -05003099void Context::drawBuffers(GLsizei n, const GLenum *bufs)
3100{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003101 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003102 ASSERT(framebuffer);
3103 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003104 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003105}
3106
3107void Context::readBuffer(GLenum mode)
3108{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003109 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003110 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003111 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003112}
3113
3114void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
3115{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003116 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003117 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003118
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003119 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003120 ASSERT(framebuffer);
3121
3122 // The specification isn't clear what should be done when the framebuffer isn't complete.
3123 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill4928b7c2017-06-20 12:57:39 -04003124 handleError(framebuffer->discard(this, numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003125}
3126
3127void Context::invalidateFramebuffer(GLenum target,
3128 GLsizei numAttachments,
3129 const GLenum *attachments)
3130{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003131 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003132 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003133
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003134 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003135 ASSERT(framebuffer);
3136
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003137 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003138 {
Jamie Madill437fa652016-05-03 15:13:24 -04003139 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003140 }
Jamie Madill437fa652016-05-03 15:13:24 -04003141
Jamie Madill4928b7c2017-06-20 12:57:39 -04003142 handleError(framebuffer->invalidate(this, numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003143}
3144
3145void Context::invalidateSubFramebuffer(GLenum target,
3146 GLsizei numAttachments,
3147 const GLenum *attachments,
3148 GLint x,
3149 GLint y,
3150 GLsizei width,
3151 GLsizei height)
3152{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003153 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003154 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003155
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003156 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003157 ASSERT(framebuffer);
3158
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003159 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003160 {
Jamie Madill437fa652016-05-03 15:13:24 -04003161 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003162 }
Jamie Madill437fa652016-05-03 15:13:24 -04003163
3164 Rectangle area(x, y, width, height);
Jamie Madill4928b7c2017-06-20 12:57:39 -04003165 handleError(framebuffer->invalidateSub(this, numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05003166}
3167
Jamie Madill73a84962016-02-12 09:27:23 -05003168void Context::texImage2D(GLenum target,
3169 GLint level,
3170 GLint internalformat,
3171 GLsizei width,
3172 GLsizei height,
3173 GLint border,
3174 GLenum format,
3175 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003176 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003177{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003178 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003179
3180 Extents size(width, height, 1);
3181 Texture *texture =
3182 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003183 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3184 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003185}
3186
3187void Context::texImage3D(GLenum target,
3188 GLint level,
3189 GLint internalformat,
3190 GLsizei width,
3191 GLsizei height,
3192 GLsizei depth,
3193 GLint border,
3194 GLenum format,
3195 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003196 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003197{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003198 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003199
3200 Extents size(width, height, depth);
3201 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003202 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3203 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003204}
3205
3206void Context::texSubImage2D(GLenum target,
3207 GLint level,
3208 GLint xoffset,
3209 GLint yoffset,
3210 GLsizei width,
3211 GLsizei height,
3212 GLenum format,
3213 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003214 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003215{
3216 // Zero sized uploads are valid but no-ops
3217 if (width == 0 || height == 0)
3218 {
3219 return;
3220 }
3221
Jamie Madillad9f24e2016-02-12 09:27:24 -05003222 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003223
3224 Box area(xoffset, yoffset, 0, width, height, 1);
3225 Texture *texture =
3226 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003227 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3228 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003229}
3230
3231void Context::texSubImage3D(GLenum target,
3232 GLint level,
3233 GLint xoffset,
3234 GLint yoffset,
3235 GLint zoffset,
3236 GLsizei width,
3237 GLsizei height,
3238 GLsizei depth,
3239 GLenum format,
3240 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003241 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003242{
3243 // Zero sized uploads are valid but no-ops
3244 if (width == 0 || height == 0 || depth == 0)
3245 {
3246 return;
3247 }
3248
Jamie Madillad9f24e2016-02-12 09:27:24 -05003249 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003250
3251 Box area(xoffset, yoffset, zoffset, width, height, depth);
3252 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003253 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3254 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003255}
3256
3257void Context::compressedTexImage2D(GLenum target,
3258 GLint level,
3259 GLenum internalformat,
3260 GLsizei width,
3261 GLsizei height,
3262 GLint border,
3263 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003264 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003265{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003266 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003267
3268 Extents size(width, height, 1);
3269 Texture *texture =
3270 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003271 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003272 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003273 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003274}
3275
3276void Context::compressedTexImage3D(GLenum target,
3277 GLint level,
3278 GLenum internalformat,
3279 GLsizei width,
3280 GLsizei height,
3281 GLsizei depth,
3282 GLint border,
3283 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003284 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003285{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003286 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003287
3288 Extents size(width, height, depth);
3289 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003290 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003291 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003292 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003293}
3294
3295void Context::compressedTexSubImage2D(GLenum target,
3296 GLint level,
3297 GLint xoffset,
3298 GLint yoffset,
3299 GLsizei width,
3300 GLsizei height,
3301 GLenum format,
3302 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003303 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003304{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003305 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003306
3307 Box area(xoffset, yoffset, 0, width, height, 1);
3308 Texture *texture =
3309 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003310 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003311 format, imageSize,
3312 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003313}
3314
3315void Context::compressedTexSubImage3D(GLenum target,
3316 GLint level,
3317 GLint xoffset,
3318 GLint yoffset,
3319 GLint zoffset,
3320 GLsizei width,
3321 GLsizei height,
3322 GLsizei depth,
3323 GLenum format,
3324 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003325 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003326{
3327 // Zero sized uploads are valid but no-ops
3328 if (width == 0 || height == 0)
3329 {
3330 return;
3331 }
3332
Jamie Madillad9f24e2016-02-12 09:27:24 -05003333 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003334
3335 Box area(xoffset, yoffset, zoffset, width, height, depth);
3336 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003337 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003338 format, imageSize,
3339 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003340}
3341
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003342void Context::generateMipmap(GLenum target)
3343{
3344 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003345 handleError(texture->generateMipmap(this));
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003346}
3347
Geoff Lang97073d12016-04-20 10:42:34 -07003348void Context::copyTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003349 GLint sourceLevel,
3350 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003351 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003352 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003353 GLint internalFormat,
3354 GLenum destType,
3355 GLboolean unpackFlipY,
3356 GLboolean unpackPremultiplyAlpha,
3357 GLboolean unpackUnmultiplyAlpha)
3358{
3359 syncStateForTexImage();
3360
3361 gl::Texture *sourceTexture = getTexture(sourceId);
3362 gl::Texture *destTexture = getTexture(destId);
Geoff Langfc72a072017-03-24 14:52:39 -04003363 handleError(destTexture->copyTexture(
3364 this, destTarget, destLevel, internalFormat, destType, sourceLevel, unpackFlipY == GL_TRUE,
3365 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003366}
3367
3368void Context::copySubTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003369 GLint sourceLevel,
3370 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003371 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003372 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003373 GLint xoffset,
3374 GLint yoffset,
3375 GLint x,
3376 GLint y,
3377 GLsizei width,
3378 GLsizei height,
3379 GLboolean unpackFlipY,
3380 GLboolean unpackPremultiplyAlpha,
3381 GLboolean unpackUnmultiplyAlpha)
3382{
3383 // Zero sized copies are valid but no-ops
3384 if (width == 0 || height == 0)
3385 {
3386 return;
3387 }
3388
3389 syncStateForTexImage();
3390
3391 gl::Texture *sourceTexture = getTexture(sourceId);
3392 gl::Texture *destTexture = getTexture(destId);
3393 Offset offset(xoffset, yoffset, 0);
3394 Rectangle area(x, y, width, height);
Geoff Langfc72a072017-03-24 14:52:39 -04003395 handleError(destTexture->copySubTexture(
3396 this, destTarget, destLevel, offset, sourceLevel, area, unpackFlipY == GL_TRUE,
3397 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003398}
3399
Geoff Lang47110bf2016-04-20 11:13:22 -07003400void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3401{
3402 syncStateForTexImage();
3403
3404 gl::Texture *sourceTexture = getTexture(sourceId);
3405 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003406 handleError(destTexture->copyCompressedTexture(this, sourceTexture));
Geoff Lang47110bf2016-04-20 11:13:22 -07003407}
3408
Geoff Lang496c02d2016-10-20 11:38:11 -07003409void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003410{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003411 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003412 ASSERT(buffer);
3413
Geoff Lang496c02d2016-10-20 11:38:11 -07003414 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003415}
3416
Jamie Madill876429b2017-04-20 15:46:24 -04003417void *Context::mapBuffer(GLenum target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003418{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003419 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003420 ASSERT(buffer);
3421
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003422 Error error = buffer->map(this, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003423 if (error.isError())
3424 {
Jamie Madill437fa652016-05-03 15:13:24 -04003425 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003426 return nullptr;
3427 }
3428
3429 return buffer->getMapPointer();
3430}
3431
3432GLboolean Context::unmapBuffer(GLenum target)
3433{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003434 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003435 ASSERT(buffer);
3436
3437 GLboolean result;
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003438 Error error = buffer->unmap(this, &result);
Olli Etuaho4f667482016-03-30 15:56:35 +03003439 if (error.isError())
3440 {
Jamie Madill437fa652016-05-03 15:13:24 -04003441 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003442 return GL_FALSE;
3443 }
3444
3445 return result;
3446}
3447
Jamie Madill876429b2017-04-20 15:46:24 -04003448void *Context::mapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003449{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003450 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003451 ASSERT(buffer);
3452
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003453 Error error = buffer->mapRange(this, offset, length, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003454 if (error.isError())
3455 {
Jamie Madill437fa652016-05-03 15:13:24 -04003456 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003457 return nullptr;
3458 }
3459
3460 return buffer->getMapPointer();
3461}
3462
3463void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3464{
3465 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3466}
3467
Jamie Madillad9f24e2016-02-12 09:27:24 -05003468void Context::syncStateForReadPixels()
3469{
3470 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3471}
3472
3473void Context::syncStateForTexImage()
3474{
3475 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3476}
3477
3478void Context::syncStateForClear()
3479{
3480 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3481}
3482
3483void Context::syncStateForBlit()
3484{
3485 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3486}
3487
Jamie Madillc20ab272016-06-09 07:20:46 -07003488void Context::activeTexture(GLenum texture)
3489{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003490 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003491}
3492
Jamie Madill876429b2017-04-20 15:46:24 -04003493void Context::blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003494{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003495 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003496}
3497
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003498void Context::blendEquation(GLenum mode)
3499{
3500 mGLState.setBlendEquation(mode, mode);
3501}
3502
Jamie Madillc20ab272016-06-09 07:20:46 -07003503void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3504{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003505 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003506}
3507
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003508void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3509{
3510 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3511}
3512
Jamie Madillc20ab272016-06-09 07:20:46 -07003513void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3514{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003515 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003516}
3517
Jamie Madill876429b2017-04-20 15:46:24 -04003518void Context::clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003519{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003520 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003521}
3522
Jamie Madill876429b2017-04-20 15:46:24 -04003523void Context::clearDepthf(GLfloat depth)
Jamie Madillc20ab272016-06-09 07:20:46 -07003524{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003525 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003526}
3527
3528void Context::clearStencil(GLint s)
3529{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003530 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003531}
3532
3533void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3534{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003535 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003536}
3537
3538void Context::cullFace(GLenum mode)
3539{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003540 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003541}
3542
3543void Context::depthFunc(GLenum func)
3544{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003545 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003546}
3547
3548void Context::depthMask(GLboolean flag)
3549{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003550 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003551}
3552
Jamie Madill876429b2017-04-20 15:46:24 -04003553void Context::depthRangef(GLfloat zNear, GLfloat zFar)
Jamie Madillc20ab272016-06-09 07:20:46 -07003554{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003555 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003556}
3557
3558void Context::disable(GLenum cap)
3559{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003560 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003561}
3562
3563void Context::disableVertexAttribArray(GLuint index)
3564{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003565 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003566}
3567
3568void Context::enable(GLenum cap)
3569{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003570 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003571}
3572
3573void Context::enableVertexAttribArray(GLuint index)
3574{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003575 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003576}
3577
3578void Context::frontFace(GLenum mode)
3579{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003580 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003581}
3582
3583void Context::hint(GLenum target, GLenum mode)
3584{
3585 switch (target)
3586 {
3587 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003588 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003589 break;
3590
3591 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003592 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003593 break;
3594
3595 default:
3596 UNREACHABLE();
3597 return;
3598 }
3599}
3600
3601void Context::lineWidth(GLfloat width)
3602{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003603 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003604}
3605
3606void Context::pixelStorei(GLenum pname, GLint param)
3607{
3608 switch (pname)
3609 {
3610 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003611 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003612 break;
3613
3614 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003615 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003616 break;
3617
3618 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003619 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003620 break;
3621
3622 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003623 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003624 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003625 break;
3626
3627 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003628 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003629 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003630 break;
3631
3632 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003633 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003634 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003635 break;
3636
3637 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003638 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003639 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003640 break;
3641
3642 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003643 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003644 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003645 break;
3646
3647 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003648 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003649 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003650 break;
3651
3652 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003653 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003654 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003655 break;
3656
3657 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003658 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003659 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003660 break;
3661
3662 default:
3663 UNREACHABLE();
3664 return;
3665 }
3666}
3667
3668void Context::polygonOffset(GLfloat factor, GLfloat units)
3669{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003670 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003671}
3672
Jamie Madill876429b2017-04-20 15:46:24 -04003673void Context::sampleCoverage(GLfloat value, GLboolean invert)
Jamie Madillc20ab272016-06-09 07:20:46 -07003674{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003675 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003676}
3677
3678void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3679{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003680 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003681}
3682
3683void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3684{
3685 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3686 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003687 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003688 }
3689
3690 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3691 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003692 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003693 }
3694}
3695
3696void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3697{
3698 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3699 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003700 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003701 }
3702
3703 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3704 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003705 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003706 }
3707}
3708
3709void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3710{
3711 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3712 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003713 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003714 }
3715
3716 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3717 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003718 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003719 }
3720}
3721
3722void Context::vertexAttrib1f(GLuint index, GLfloat x)
3723{
3724 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003725 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003726}
3727
3728void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3729{
3730 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003731 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003732}
3733
3734void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3735{
3736 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003737 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003738}
3739
3740void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3741{
3742 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003743 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003744}
3745
3746void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3747{
3748 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003749 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003750}
3751
3752void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3753{
3754 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003755 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003756}
3757
3758void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3759{
3760 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003761 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003762}
3763
3764void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3765{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003766 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003767}
3768
3769void Context::vertexAttribPointer(GLuint index,
3770 GLint size,
3771 GLenum type,
3772 GLboolean normalized,
3773 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003774 const void *ptr)
Jamie Madillc20ab272016-06-09 07:20:46 -07003775{
Shaodde78e82017-05-22 14:13:27 +08003776 mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size,
3777 type, normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003778}
3779
Shao80957d92017-02-20 21:25:59 +08003780void Context::vertexAttribFormat(GLuint attribIndex,
3781 GLint size,
3782 GLenum type,
3783 GLboolean normalized,
3784 GLuint relativeOffset)
3785{
3786 mGLState.setVertexAttribFormat(attribIndex, size, type, normalized == GL_TRUE, false,
3787 relativeOffset);
3788}
3789
3790void Context::vertexAttribIFormat(GLuint attribIndex,
3791 GLint size,
3792 GLenum type,
3793 GLuint relativeOffset)
3794{
3795 mGLState.setVertexAttribFormat(attribIndex, size, type, false, true, relativeOffset);
3796}
3797
3798void Context::vertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
3799{
Shaodde78e82017-05-22 14:13:27 +08003800 mGLState.setVertexAttribBinding(this, attribIndex, bindingIndex);
Shao80957d92017-02-20 21:25:59 +08003801}
3802
3803void Context::setVertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
3804{
3805 mGLState.setVertexBindingDivisor(bindingIndex, divisor);
3806}
3807
Jamie Madillc20ab272016-06-09 07:20:46 -07003808void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3809{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003810 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003811}
3812
3813void Context::vertexAttribIPointer(GLuint index,
3814 GLint size,
3815 GLenum type,
3816 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003817 const void *pointer)
Jamie Madillc20ab272016-06-09 07:20:46 -07003818{
Shaodde78e82017-05-22 14:13:27 +08003819 mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size,
3820 type, false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003821}
3822
3823void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3824{
3825 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003826 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003827}
3828
3829void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3830{
3831 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003832 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003833}
3834
3835void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3836{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003837 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003838}
3839
3840void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3841{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003842 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003843}
3844
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003845void Context::getVertexAttribiv(GLuint index, GLenum pname, GLint *params)
3846{
3847 const VertexAttribCurrentValueData &currentValues =
3848 getGLState().getVertexAttribCurrentValue(index);
3849 const VertexArray *vao = getGLState().getVertexArray();
3850 QueryVertexAttribiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3851 currentValues, pname, params);
3852}
3853
3854void Context::getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
3855{
3856 const VertexAttribCurrentValueData &currentValues =
3857 getGLState().getVertexAttribCurrentValue(index);
3858 const VertexArray *vao = getGLState().getVertexArray();
3859 QueryVertexAttribfv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3860 currentValues, pname, params);
3861}
3862
3863void Context::getVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
3864{
3865 const VertexAttribCurrentValueData &currentValues =
3866 getGLState().getVertexAttribCurrentValue(index);
3867 const VertexArray *vao = getGLState().getVertexArray();
3868 QueryVertexAttribIiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3869 currentValues, pname, params);
3870}
3871
3872void Context::getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
3873{
3874 const VertexAttribCurrentValueData &currentValues =
3875 getGLState().getVertexAttribCurrentValue(index);
3876 const VertexArray *vao = getGLState().getVertexArray();
3877 QueryVertexAttribIuiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3878 currentValues, pname, params);
3879}
3880
Jamie Madill876429b2017-04-20 15:46:24 -04003881void Context::getVertexAttribPointerv(GLuint index, GLenum pname, void **pointer)
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003882{
3883 const VertexAttribute &attrib = getGLState().getVertexArray()->getVertexAttribute(index);
3884 QueryVertexAttribPointerv(attrib, pname, pointer);
3885}
3886
Jamie Madillc20ab272016-06-09 07:20:46 -07003887void Context::debugMessageControl(GLenum source,
3888 GLenum type,
3889 GLenum severity,
3890 GLsizei count,
3891 const GLuint *ids,
3892 GLboolean enabled)
3893{
3894 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003895 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3896 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003897}
3898
3899void Context::debugMessageInsert(GLenum source,
3900 GLenum type,
3901 GLuint id,
3902 GLenum severity,
3903 GLsizei length,
3904 const GLchar *buf)
3905{
3906 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003907 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003908}
3909
3910void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3911{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003912 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003913}
3914
3915GLuint Context::getDebugMessageLog(GLuint count,
3916 GLsizei bufSize,
3917 GLenum *sources,
3918 GLenum *types,
3919 GLuint *ids,
3920 GLenum *severities,
3921 GLsizei *lengths,
3922 GLchar *messageLog)
3923{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003924 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3925 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003926}
3927
3928void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3929{
3930 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003931 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003932}
3933
3934void Context::popDebugGroup()
3935{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003936 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003937}
3938
Jamie Madill876429b2017-04-20 15:46:24 -04003939void Context::bufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage)
Jamie Madill29639852016-09-02 15:00:09 -04003940{
3941 Buffer *buffer = mGLState.getTargetBuffer(target);
3942 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003943 handleError(buffer->bufferData(this, target, data, size, usage));
Jamie Madill29639852016-09-02 15:00:09 -04003944}
3945
Jamie Madill876429b2017-04-20 15:46:24 -04003946void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04003947{
3948 if (data == nullptr)
3949 {
3950 return;
3951 }
3952
3953 Buffer *buffer = mGLState.getTargetBuffer(target);
3954 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003955 handleError(buffer->bufferSubData(this, target, data, size, offset));
Jamie Madill29639852016-09-02 15:00:09 -04003956}
3957
Jamie Madillef300b12016-10-07 15:12:09 -04003958void Context::attachShader(GLuint program, GLuint shader)
3959{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003960 auto programObject = mState.mShaderPrograms->getProgram(program);
3961 auto shaderObject = mState.mShaderPrograms->getShader(shader);
Jamie Madillef300b12016-10-07 15:12:09 -04003962 ASSERT(programObject && shaderObject);
3963 programObject->attachShader(shaderObject);
3964}
3965
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003966const Workarounds &Context::getWorkarounds() const
3967{
3968 return mWorkarounds;
3969}
3970
Jamie Madillb0817d12016-11-01 15:48:31 -04003971void Context::copyBufferSubData(GLenum readTarget,
3972 GLenum writeTarget,
3973 GLintptr readOffset,
3974 GLintptr writeOffset,
3975 GLsizeiptr size)
3976{
3977 // if size is zero, the copy is a successful no-op
3978 if (size == 0)
3979 {
3980 return;
3981 }
3982
3983 // TODO(jmadill): cache these.
3984 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3985 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3986
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003987 handleError(writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size));
Jamie Madillb0817d12016-11-01 15:48:31 -04003988}
3989
Jamie Madill01a80ee2016-11-07 12:06:18 -05003990void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3991{
3992 Program *programObject = getProgram(program);
3993 // TODO(jmadill): Re-use this from the validation if possible.
3994 ASSERT(programObject);
3995 programObject->bindAttributeLocation(index, name);
3996}
3997
3998void Context::bindBuffer(GLenum target, GLuint buffer)
3999{
4000 switch (target)
4001 {
4002 case GL_ARRAY_BUFFER:
4003 bindArrayBuffer(buffer);
4004 break;
4005 case GL_ELEMENT_ARRAY_BUFFER:
4006 bindElementArrayBuffer(buffer);
4007 break;
4008 case GL_COPY_READ_BUFFER:
4009 bindCopyReadBuffer(buffer);
4010 break;
4011 case GL_COPY_WRITE_BUFFER:
4012 bindCopyWriteBuffer(buffer);
4013 break;
4014 case GL_PIXEL_PACK_BUFFER:
4015 bindPixelPackBuffer(buffer);
4016 break;
4017 case GL_PIXEL_UNPACK_BUFFER:
4018 bindPixelUnpackBuffer(buffer);
4019 break;
4020 case GL_UNIFORM_BUFFER:
4021 bindGenericUniformBuffer(buffer);
4022 break;
4023 case GL_TRANSFORM_FEEDBACK_BUFFER:
4024 bindGenericTransformFeedbackBuffer(buffer);
4025 break;
Geoff Lang3b573612016-10-31 14:08:10 -04004026 case GL_ATOMIC_COUNTER_BUFFER:
Jiajia Qin6eafb042016-12-27 17:04:07 +08004027 bindGenericAtomicCounterBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004028 break;
4029 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08004030 bindGenericShaderStorageBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004031 break;
4032 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08004033 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004034 break;
4035 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05004036 if (buffer != 0)
4037 {
4038 // Binding buffers to this binding point is not implemented yet.
4039 UNIMPLEMENTED();
4040 }
Geoff Lang3b573612016-10-31 14:08:10 -04004041 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05004042
4043 default:
4044 UNREACHABLE();
4045 break;
4046 }
4047}
4048
Jiajia Qin6eafb042016-12-27 17:04:07 +08004049void Context::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
4050{
4051 bindBufferRange(target, index, buffer, 0, 0);
4052}
4053
4054void Context::bindBufferRange(GLenum target,
4055 GLuint index,
4056 GLuint buffer,
4057 GLintptr offset,
4058 GLsizeiptr size)
4059{
4060 switch (target)
4061 {
4062 case GL_TRANSFORM_FEEDBACK_BUFFER:
4063 bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
4064 bindGenericTransformFeedbackBuffer(buffer);
4065 break;
4066 case GL_UNIFORM_BUFFER:
4067 bindIndexedUniformBuffer(buffer, index, offset, size);
4068 bindGenericUniformBuffer(buffer);
4069 break;
4070 case GL_ATOMIC_COUNTER_BUFFER:
4071 bindIndexedAtomicCounterBuffer(buffer, index, offset, size);
4072 bindGenericAtomicCounterBuffer(buffer);
4073 break;
4074 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08004075 bindIndexedShaderStorageBuffer(buffer, index, offset, size);
4076 bindGenericShaderStorageBuffer(buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08004077 break;
4078 default:
4079 UNREACHABLE();
4080 break;
4081 }
4082}
4083
Jamie Madill01a80ee2016-11-07 12:06:18 -05004084void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
4085{
4086 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4087 {
4088 bindReadFramebuffer(framebuffer);
4089 }
4090
4091 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4092 {
4093 bindDrawFramebuffer(framebuffer);
4094 }
4095}
4096
4097void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
4098{
4099 ASSERT(target == GL_RENDERBUFFER);
4100 Renderbuffer *object =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05004101 mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
Jamie Madill4928b7c2017-06-20 12:57:39 -04004102 mGLState.setRenderbufferBinding(this, object);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004103}
4104
JiangYizhoubddc46b2016-12-09 09:50:51 +08004105void Context::texStorage2DMultisample(GLenum target,
4106 GLsizei samples,
4107 GLenum internalformat,
4108 GLsizei width,
4109 GLsizei height,
4110 GLboolean fixedsamplelocations)
4111{
4112 Extents size(width, height, 1);
4113 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05004114 handleError(texture->setStorageMultisample(this, target, samples, internalformat, size,
JiangYizhoubddc46b2016-12-09 09:50:51 +08004115 fixedsamplelocations));
4116}
4117
4118void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
4119{
JiangYizhou5b03f472017-01-09 10:22:53 +08004120 // According to spec 3.1 Table 20.49: Framebuffer Dependent Values,
4121 // the sample position should be queried by DRAW_FRAMEBUFFER.
4122 mGLState.syncDirtyObject(this, GL_DRAW_FRAMEBUFFER);
4123 const Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
JiangYizhoubddc46b2016-12-09 09:50:51 +08004124
4125 switch (pname)
4126 {
4127 case GL_SAMPLE_POSITION:
4128 handleError(framebuffer->getSamplePosition(index, val));
4129 break;
4130 default:
4131 UNREACHABLE();
4132 }
4133}
4134
Jamie Madille8fb6402017-02-14 17:56:40 -05004135void Context::renderbufferStorage(GLenum target,
4136 GLenum internalformat,
4137 GLsizei width,
4138 GLsizei height)
4139{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004140 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4141 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
4142
Jamie Madille8fb6402017-02-14 17:56:40 -05004143 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4928b7c2017-06-20 12:57:39 -04004144 handleError(renderbuffer->setStorage(this, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004145}
4146
4147void Context::renderbufferStorageMultisample(GLenum target,
4148 GLsizei samples,
4149 GLenum internalformat,
4150 GLsizei width,
4151 GLsizei height)
4152{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004153 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4154 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
Jamie Madille8fb6402017-02-14 17:56:40 -05004155
4156 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004157 handleError(
Jamie Madill4928b7c2017-06-20 12:57:39 -04004158 renderbuffer->setStorageMultisample(this, samples, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004159}
4160
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004161void Context::getSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)
4162{
Jamie Madill70b5bb02017-08-28 13:32:37 -04004163 const Sync *syncObject = getSync(sync);
Geoff Lang82483b92017-04-11 15:33:00 -04004164 handleError(QuerySynciv(syncObject, pname, bufSize, length, values));
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004165}
4166
JiangYizhoue18e6392017-02-20 10:32:23 +08004167void Context::getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
4168{
4169 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4170 QueryFramebufferParameteriv(framebuffer, pname, params);
4171}
4172
4173void Context::setFramebufferParameteri(GLenum target, GLenum pname, GLint param)
4174{
4175 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4176 SetFramebufferParameteri(framebuffer, pname, param);
4177}
4178
Jamie Madillb3f26b92017-07-19 15:07:41 -04004179Error Context::getScratchBuffer(size_t requstedSizeBytes,
4180 angle::MemoryBuffer **scratchBufferOut) const
Jamie Madille14951e2017-03-09 18:55:16 -05004181{
Jamie Madillb3f26b92017-07-19 15:07:41 -04004182 if (!mScratchBuffer.get(requstedSizeBytes, scratchBufferOut))
4183 {
4184 return OutOfMemory() << "Failed to allocate internal buffer.";
4185 }
4186 return NoError();
4187}
4188
4189Error Context::getZeroFilledBuffer(size_t requstedSizeBytes,
4190 angle::MemoryBuffer **zeroBufferOut) const
4191{
4192 if (!mZeroFilledBuffer.getInitialized(requstedSizeBytes, zeroBufferOut, 0))
Jamie Madille14951e2017-03-09 18:55:16 -05004193 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004194 return OutOfMemory() << "Failed to allocate internal buffer.";
Jamie Madille14951e2017-03-09 18:55:16 -05004195 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004196 return NoError();
Jamie Madille14951e2017-03-09 18:55:16 -05004197}
4198
Xinghua Cao2b396592017-03-29 15:36:04 +08004199void Context::dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ)
4200{
4201 if (numGroupsX == 0u || numGroupsY == 0u || numGroupsZ == 0u)
4202 {
4203 return;
4204 }
4205
Jamie Madill71c88b32017-09-14 22:20:29 -04004206 handleError(mImplementation->dispatchCompute(this, numGroupsX, numGroupsY, numGroupsZ));
Xinghua Cao2b396592017-03-29 15:36:04 +08004207}
4208
JiangYizhou165361c2017-06-07 14:56:57 +08004209void Context::texStorage2D(GLenum target,
4210 GLsizei levels,
4211 GLenum internalFormat,
4212 GLsizei width,
4213 GLsizei height)
4214{
4215 Extents size(width, height, 1);
4216 Texture *texture = getTargetTexture(target);
4217 handleError(texture->setStorage(this, target, levels, internalFormat, size));
4218}
4219
4220void Context::texStorage3D(GLenum target,
4221 GLsizei levels,
4222 GLenum internalFormat,
4223 GLsizei width,
4224 GLsizei height,
4225 GLsizei depth)
4226{
4227 Extents size(width, height, depth);
4228 Texture *texture = getTargetTexture(target);
4229 handleError(texture->setStorage(this, target, levels, internalFormat, size));
4230}
4231
Jamie Madillc1d770e2017-04-13 17:31:24 -04004232GLenum Context::checkFramebufferStatus(GLenum target)
4233{
4234 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4235 ASSERT(framebuffer);
4236
4237 return framebuffer->checkStatus(this);
4238}
4239
4240void Context::compileShader(GLuint shader)
4241{
4242 Shader *shaderObject = GetValidShader(this, shader);
4243 if (!shaderObject)
4244 {
4245 return;
4246 }
4247 shaderObject->compile(this);
4248}
4249
4250void Context::deleteBuffers(GLsizei n, const GLuint *buffers)
4251{
4252 for (int i = 0; i < n; i++)
4253 {
4254 deleteBuffer(buffers[i]);
4255 }
4256}
4257
4258void Context::deleteFramebuffers(GLsizei n, const GLuint *framebuffers)
4259{
4260 for (int i = 0; i < n; i++)
4261 {
4262 if (framebuffers[i] != 0)
4263 {
4264 deleteFramebuffer(framebuffers[i]);
4265 }
4266 }
4267}
4268
4269void Context::deleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)
4270{
4271 for (int i = 0; i < n; i++)
4272 {
4273 deleteRenderbuffer(renderbuffers[i]);
4274 }
4275}
4276
4277void Context::deleteTextures(GLsizei n, const GLuint *textures)
4278{
4279 for (int i = 0; i < n; i++)
4280 {
4281 if (textures[i] != 0)
4282 {
4283 deleteTexture(textures[i]);
4284 }
4285 }
4286}
4287
4288void Context::detachShader(GLuint program, GLuint shader)
4289{
4290 Program *programObject = getProgram(program);
4291 ASSERT(programObject);
4292
4293 Shader *shaderObject = getShader(shader);
4294 ASSERT(shaderObject);
4295
4296 programObject->detachShader(this, shaderObject);
4297}
4298
4299void Context::genBuffers(GLsizei n, GLuint *buffers)
4300{
4301 for (int i = 0; i < n; i++)
4302 {
4303 buffers[i] = createBuffer();
4304 }
4305}
4306
4307void Context::genFramebuffers(GLsizei n, GLuint *framebuffers)
4308{
4309 for (int i = 0; i < n; i++)
4310 {
4311 framebuffers[i] = createFramebuffer();
4312 }
4313}
4314
4315void Context::genRenderbuffers(GLsizei n, GLuint *renderbuffers)
4316{
4317 for (int i = 0; i < n; i++)
4318 {
4319 renderbuffers[i] = createRenderbuffer();
4320 }
4321}
4322
4323void Context::genTextures(GLsizei n, GLuint *textures)
4324{
4325 for (int i = 0; i < n; i++)
4326 {
4327 textures[i] = createTexture();
4328 }
4329}
4330
4331void Context::getActiveAttrib(GLuint program,
4332 GLuint index,
4333 GLsizei bufsize,
4334 GLsizei *length,
4335 GLint *size,
4336 GLenum *type,
4337 GLchar *name)
4338{
4339 Program *programObject = getProgram(program);
4340 ASSERT(programObject);
4341 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
4342}
4343
4344void Context::getActiveUniform(GLuint program,
4345 GLuint index,
4346 GLsizei bufsize,
4347 GLsizei *length,
4348 GLint *size,
4349 GLenum *type,
4350 GLchar *name)
4351{
4352 Program *programObject = getProgram(program);
4353 ASSERT(programObject);
4354 programObject->getActiveUniform(index, bufsize, length, size, type, name);
4355}
4356
4357void Context::getAttachedShaders(GLuint program, GLsizei maxcount, GLsizei *count, GLuint *shaders)
4358{
4359 Program *programObject = getProgram(program);
4360 ASSERT(programObject);
4361 programObject->getAttachedShaders(maxcount, count, shaders);
4362}
4363
4364GLint Context::getAttribLocation(GLuint program, const GLchar *name)
4365{
4366 Program *programObject = getProgram(program);
4367 ASSERT(programObject);
4368 return programObject->getAttributeLocation(name);
4369}
4370
4371void Context::getBooleanv(GLenum pname, GLboolean *params)
4372{
4373 GLenum nativeType;
4374 unsigned int numParams = 0;
4375 getQueryParameterInfo(pname, &nativeType, &numParams);
4376
4377 if (nativeType == GL_BOOL)
4378 {
4379 getBooleanvImpl(pname, params);
4380 }
4381 else
4382 {
4383 CastStateValues(this, nativeType, pname, numParams, params);
4384 }
4385}
4386
4387void Context::getFloatv(GLenum pname, GLfloat *params)
4388{
4389 GLenum nativeType;
4390 unsigned int numParams = 0;
4391 getQueryParameterInfo(pname, &nativeType, &numParams);
4392
4393 if (nativeType == GL_FLOAT)
4394 {
4395 getFloatvImpl(pname, params);
4396 }
4397 else
4398 {
4399 CastStateValues(this, nativeType, pname, numParams, params);
4400 }
4401}
4402
4403void Context::getIntegerv(GLenum pname, GLint *params)
4404{
4405 GLenum nativeType;
4406 unsigned int numParams = 0;
4407 getQueryParameterInfo(pname, &nativeType, &numParams);
4408
4409 if (nativeType == GL_INT)
4410 {
4411 getIntegervImpl(pname, params);
4412 }
4413 else
4414 {
4415 CastStateValues(this, nativeType, pname, numParams, params);
4416 }
4417}
4418
4419void Context::getProgramiv(GLuint program, GLenum pname, GLint *params)
4420{
4421 Program *programObject = getProgram(program);
4422 ASSERT(programObject);
Jamie Madillffe00c02017-06-27 16:26:55 -04004423 QueryProgramiv(this, programObject, pname, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004424}
4425
Jamie Madillbe849e42017-05-02 15:49:00 -04004426void Context::getProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei *length, GLchar *infolog)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004427{
4428 Program *programObject = getProgram(program);
4429 ASSERT(programObject);
4430 programObject->getInfoLog(bufsize, length, infolog);
4431}
4432
4433void Context::getShaderiv(GLuint shader, GLenum pname, GLint *params)
4434{
4435 Shader *shaderObject = getShader(shader);
4436 ASSERT(shaderObject);
Jamie Madillbd044ed2017-06-05 12:59:21 -04004437 QueryShaderiv(this, shaderObject, pname, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004438}
4439
4440void Context::getShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *infolog)
4441{
4442 Shader *shaderObject = getShader(shader);
4443 ASSERT(shaderObject);
Jamie Madillbd044ed2017-06-05 12:59:21 -04004444 shaderObject->getInfoLog(this, bufsize, length, infolog);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004445}
4446
4447void Context::getShaderPrecisionFormat(GLenum shadertype,
4448 GLenum precisiontype,
4449 GLint *range,
4450 GLint *precision)
4451{
4452 // TODO(jmadill): Compute shaders.
4453
4454 switch (shadertype)
4455 {
4456 case GL_VERTEX_SHADER:
4457 switch (precisiontype)
4458 {
4459 case GL_LOW_FLOAT:
4460 mCaps.vertexLowpFloat.get(range, precision);
4461 break;
4462 case GL_MEDIUM_FLOAT:
4463 mCaps.vertexMediumpFloat.get(range, precision);
4464 break;
4465 case GL_HIGH_FLOAT:
4466 mCaps.vertexHighpFloat.get(range, precision);
4467 break;
4468
4469 case GL_LOW_INT:
4470 mCaps.vertexLowpInt.get(range, precision);
4471 break;
4472 case GL_MEDIUM_INT:
4473 mCaps.vertexMediumpInt.get(range, precision);
4474 break;
4475 case GL_HIGH_INT:
4476 mCaps.vertexHighpInt.get(range, precision);
4477 break;
4478
4479 default:
4480 UNREACHABLE();
4481 return;
4482 }
4483 break;
4484
4485 case GL_FRAGMENT_SHADER:
4486 switch (precisiontype)
4487 {
4488 case GL_LOW_FLOAT:
4489 mCaps.fragmentLowpFloat.get(range, precision);
4490 break;
4491 case GL_MEDIUM_FLOAT:
4492 mCaps.fragmentMediumpFloat.get(range, precision);
4493 break;
4494 case GL_HIGH_FLOAT:
4495 mCaps.fragmentHighpFloat.get(range, precision);
4496 break;
4497
4498 case GL_LOW_INT:
4499 mCaps.fragmentLowpInt.get(range, precision);
4500 break;
4501 case GL_MEDIUM_INT:
4502 mCaps.fragmentMediumpInt.get(range, precision);
4503 break;
4504 case GL_HIGH_INT:
4505 mCaps.fragmentHighpInt.get(range, precision);
4506 break;
4507
4508 default:
4509 UNREACHABLE();
4510 return;
4511 }
4512 break;
4513
4514 default:
4515 UNREACHABLE();
4516 return;
4517 }
4518}
4519
4520void Context::getShaderSource(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source)
4521{
4522 Shader *shaderObject = getShader(shader);
4523 ASSERT(shaderObject);
4524 shaderObject->getSource(bufsize, length, source);
4525}
4526
4527void Context::getUniformfv(GLuint program, GLint location, GLfloat *params)
4528{
4529 Program *programObject = getProgram(program);
4530 ASSERT(programObject);
Jamie Madill54164b02017-08-28 15:17:37 -04004531 programObject->getUniformfv(this, location, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004532}
4533
4534void Context::getUniformiv(GLuint program, GLint location, GLint *params)
4535{
4536 Program *programObject = getProgram(program);
4537 ASSERT(programObject);
Jamie Madill54164b02017-08-28 15:17:37 -04004538 programObject->getUniformiv(this, location, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004539}
4540
4541GLint Context::getUniformLocation(GLuint program, const GLchar *name)
4542{
4543 Program *programObject = getProgram(program);
4544 ASSERT(programObject);
4545 return programObject->getUniformLocation(name);
4546}
4547
4548GLboolean Context::isBuffer(GLuint buffer)
4549{
4550 if (buffer == 0)
4551 {
4552 return GL_FALSE;
4553 }
4554
4555 return (getBuffer(buffer) ? GL_TRUE : GL_FALSE);
4556}
4557
4558GLboolean Context::isEnabled(GLenum cap)
4559{
4560 return mGLState.getEnableFeature(cap);
4561}
4562
4563GLboolean Context::isFramebuffer(GLuint framebuffer)
4564{
4565 if (framebuffer == 0)
4566 {
4567 return GL_FALSE;
4568 }
4569
4570 return (getFramebuffer(framebuffer) ? GL_TRUE : GL_FALSE);
4571}
4572
4573GLboolean Context::isProgram(GLuint program)
4574{
4575 if (program == 0)
4576 {
4577 return GL_FALSE;
4578 }
4579
4580 return (getProgram(program) ? GL_TRUE : GL_FALSE);
4581}
4582
4583GLboolean Context::isRenderbuffer(GLuint renderbuffer)
4584{
4585 if (renderbuffer == 0)
4586 {
4587 return GL_FALSE;
4588 }
4589
4590 return (getRenderbuffer(renderbuffer) ? GL_TRUE : GL_FALSE);
4591}
4592
4593GLboolean Context::isShader(GLuint shader)
4594{
4595 if (shader == 0)
4596 {
4597 return GL_FALSE;
4598 }
4599
4600 return (getShader(shader) ? GL_TRUE : GL_FALSE);
4601}
4602
4603GLboolean Context::isTexture(GLuint texture)
4604{
4605 if (texture == 0)
4606 {
4607 return GL_FALSE;
4608 }
4609
4610 return (getTexture(texture) ? GL_TRUE : GL_FALSE);
4611}
4612
4613void Context::linkProgram(GLuint program)
4614{
4615 Program *programObject = getProgram(program);
4616 ASSERT(programObject);
4617 handleError(programObject->link(this));
Martin Radev0abb7a22017-08-28 15:34:45 +03004618 mGLState.onProgramExecutableChange(programObject);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004619}
4620
4621void Context::releaseShaderCompiler()
4622{
Jamie Madill4928b7c2017-06-20 12:57:39 -04004623 mCompiler.set(this, nullptr);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004624}
4625
4626void Context::shaderBinary(GLsizei n,
4627 const GLuint *shaders,
4628 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04004629 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004630 GLsizei length)
4631{
4632 // No binary shader formats are supported.
4633 UNIMPLEMENTED();
4634}
4635
4636void Context::shaderSource(GLuint shader,
4637 GLsizei count,
4638 const GLchar *const *string,
4639 const GLint *length)
4640{
4641 Shader *shaderObject = getShader(shader);
4642 ASSERT(shaderObject);
4643 shaderObject->setSource(count, string, length);
4644}
4645
4646void Context::stencilFunc(GLenum func, GLint ref, GLuint mask)
4647{
4648 stencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
4649}
4650
4651void Context::stencilMask(GLuint mask)
4652{
4653 stencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4654}
4655
4656void Context::stencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4657{
4658 stencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4659}
4660
4661void Context::uniform1f(GLint location, GLfloat x)
4662{
4663 Program *program = mGLState.getProgram();
4664 program->setUniform1fv(location, 1, &x);
4665}
4666
4667void Context::uniform1fv(GLint location, GLsizei count, const GLfloat *v)
4668{
4669 Program *program = mGLState.getProgram();
4670 program->setUniform1fv(location, count, v);
4671}
4672
4673void Context::uniform1i(GLint location, GLint x)
4674{
4675 Program *program = mGLState.getProgram();
Jamie Madill81c2e252017-09-09 23:32:46 -04004676 if (program->setUniform1iv(location, 1, &x) == Program::SetUniformResult::SamplerChanged)
4677 {
4678 mGLState.setObjectDirty(GL_PROGRAM);
4679 }
Jamie Madillc1d770e2017-04-13 17:31:24 -04004680}
4681
4682void Context::uniform1iv(GLint location, GLsizei count, const GLint *v)
4683{
4684 Program *program = mGLState.getProgram();
Jamie Madill81c2e252017-09-09 23:32:46 -04004685 if (program->setUniform1iv(location, count, v) == Program::SetUniformResult::SamplerChanged)
4686 {
4687 mGLState.setObjectDirty(GL_PROGRAM);
4688 }
Jamie Madillc1d770e2017-04-13 17:31:24 -04004689}
4690
4691void Context::uniform2f(GLint location, GLfloat x, GLfloat y)
4692{
4693 GLfloat xy[2] = {x, y};
4694 Program *program = mGLState.getProgram();
4695 program->setUniform2fv(location, 1, xy);
4696}
4697
4698void Context::uniform2fv(GLint location, GLsizei count, const GLfloat *v)
4699{
4700 Program *program = mGLState.getProgram();
4701 program->setUniform2fv(location, count, v);
4702}
4703
4704void Context::uniform2i(GLint location, GLint x, GLint y)
4705{
4706 GLint xy[2] = {x, y};
4707 Program *program = mGLState.getProgram();
4708 program->setUniform2iv(location, 1, xy);
4709}
4710
4711void Context::uniform2iv(GLint location, GLsizei count, const GLint *v)
4712{
4713 Program *program = mGLState.getProgram();
4714 program->setUniform2iv(location, count, v);
4715}
4716
4717void Context::uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4718{
4719 GLfloat xyz[3] = {x, y, z};
4720 Program *program = mGLState.getProgram();
4721 program->setUniform3fv(location, 1, xyz);
4722}
4723
4724void Context::uniform3fv(GLint location, GLsizei count, const GLfloat *v)
4725{
4726 Program *program = mGLState.getProgram();
4727 program->setUniform3fv(location, count, v);
4728}
4729
4730void Context::uniform3i(GLint location, GLint x, GLint y, GLint z)
4731{
4732 GLint xyz[3] = {x, y, z};
4733 Program *program = mGLState.getProgram();
4734 program->setUniform3iv(location, 1, xyz);
4735}
4736
4737void Context::uniform3iv(GLint location, GLsizei count, const GLint *v)
4738{
4739 Program *program = mGLState.getProgram();
4740 program->setUniform3iv(location, count, v);
4741}
4742
4743void Context::uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4744{
4745 GLfloat xyzw[4] = {x, y, z, w};
4746 Program *program = mGLState.getProgram();
4747 program->setUniform4fv(location, 1, xyzw);
4748}
4749
4750void Context::uniform4fv(GLint location, GLsizei count, const GLfloat *v)
4751{
4752 Program *program = mGLState.getProgram();
4753 program->setUniform4fv(location, count, v);
4754}
4755
4756void Context::uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4757{
4758 GLint xyzw[4] = {x, y, z, w};
4759 Program *program = mGLState.getProgram();
4760 program->setUniform4iv(location, 1, xyzw);
4761}
4762
4763void Context::uniform4iv(GLint location, GLsizei count, const GLint *v)
4764{
4765 Program *program = mGLState.getProgram();
4766 program->setUniform4iv(location, count, v);
4767}
4768
4769void Context::uniformMatrix2fv(GLint location,
4770 GLsizei count,
4771 GLboolean transpose,
4772 const GLfloat *value)
4773{
4774 Program *program = mGLState.getProgram();
4775 program->setUniformMatrix2fv(location, count, transpose, value);
4776}
4777
4778void Context::uniformMatrix3fv(GLint location,
4779 GLsizei count,
4780 GLboolean transpose,
4781 const GLfloat *value)
4782{
4783 Program *program = mGLState.getProgram();
4784 program->setUniformMatrix3fv(location, count, transpose, value);
4785}
4786
4787void Context::uniformMatrix4fv(GLint location,
4788 GLsizei count,
4789 GLboolean transpose,
4790 const GLfloat *value)
4791{
4792 Program *program = mGLState.getProgram();
4793 program->setUniformMatrix4fv(location, count, transpose, value);
4794}
4795
4796void Context::validateProgram(GLuint program)
4797{
4798 Program *programObject = getProgram(program);
4799 ASSERT(programObject);
4800 programObject->validate(mCaps);
4801}
4802
Jamie Madilld04908b2017-06-09 14:15:35 -04004803void Context::getProgramBinary(GLuint program,
4804 GLsizei bufSize,
4805 GLsizei *length,
4806 GLenum *binaryFormat,
4807 void *binary)
4808{
4809 Program *programObject = getProgram(program);
4810 ASSERT(programObject != nullptr);
4811
4812 handleError(programObject->saveBinary(this, binaryFormat, binary, bufSize, length));
4813}
4814
4815void Context::programBinary(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length)
4816{
4817 Program *programObject = getProgram(program);
4818 ASSERT(programObject != nullptr);
Jamie Madillb6664922017-07-25 12:55:04 -04004819
Jamie Madilld04908b2017-06-09 14:15:35 -04004820 handleError(programObject->loadBinary(this, binaryFormat, binary, length));
4821}
4822
Jamie Madillff325f12017-08-26 15:06:05 -04004823void Context::uniform1ui(GLint location, GLuint v0)
4824{
4825 Program *program = mGLState.getProgram();
4826 program->setUniform1uiv(location, 1, &v0);
4827}
4828
4829void Context::uniform2ui(GLint location, GLuint v0, GLuint v1)
4830{
4831 Program *program = mGLState.getProgram();
4832 const GLuint xy[] = {v0, v1};
4833 program->setUniform2uiv(location, 1, xy);
4834}
4835
4836void Context::uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
4837{
4838 Program *program = mGLState.getProgram();
4839 const GLuint xyz[] = {v0, v1, v2};
4840 program->setUniform3uiv(location, 1, xyz);
4841}
4842
4843void Context::uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
4844{
4845 Program *program = mGLState.getProgram();
4846 const GLuint xyzw[] = {v0, v1, v2, v3};
4847 program->setUniform4uiv(location, 1, xyzw);
4848}
4849
4850void Context::uniform1uiv(GLint location, GLsizei count, const GLuint *value)
4851{
4852 Program *program = mGLState.getProgram();
4853 program->setUniform1uiv(location, count, value);
4854}
4855void Context::uniform2uiv(GLint location, GLsizei count, const GLuint *value)
4856{
4857 Program *program = mGLState.getProgram();
4858 program->setUniform2uiv(location, count, value);
4859}
4860
4861void Context::uniform3uiv(GLint location, GLsizei count, const GLuint *value)
4862{
4863 Program *program = mGLState.getProgram();
4864 program->setUniform3uiv(location, count, value);
4865}
4866
4867void Context::uniform4uiv(GLint location, GLsizei count, const GLuint *value)
4868{
4869 Program *program = mGLState.getProgram();
4870 program->setUniform4uiv(location, count, value);
4871}
4872
Jamie Madillf0e04492017-08-26 15:28:42 -04004873void Context::genQueries(GLsizei n, GLuint *ids)
4874{
4875 for (GLsizei i = 0; i < n; i++)
4876 {
4877 GLuint handle = mQueryHandleAllocator.allocate();
4878 mQueryMap.assign(handle, nullptr);
4879 ids[i] = handle;
4880 }
4881}
4882
4883void Context::deleteQueries(GLsizei n, const GLuint *ids)
4884{
4885 for (int i = 0; i < n; i++)
4886 {
4887 GLuint query = ids[i];
4888
4889 Query *queryObject = nullptr;
4890 if (mQueryMap.erase(query, &queryObject))
4891 {
4892 mQueryHandleAllocator.release(query);
4893 if (queryObject)
4894 {
4895 queryObject->release(this);
4896 }
4897 }
4898 }
4899}
4900
4901GLboolean Context::isQuery(GLuint id)
4902{
4903 return (getQuery(id, false, GL_NONE) != nullptr) ? GL_TRUE : GL_FALSE;
4904}
4905
Jamie Madillc8c95812017-08-26 18:40:09 -04004906void Context::uniformMatrix2x3fv(GLint location,
4907 GLsizei count,
4908 GLboolean transpose,
4909 const GLfloat *value)
4910{
4911 Program *program = mGLState.getProgram();
4912 program->setUniformMatrix2x3fv(location, count, transpose, value);
4913}
4914
4915void Context::uniformMatrix3x2fv(GLint location,
4916 GLsizei count,
4917 GLboolean transpose,
4918 const GLfloat *value)
4919{
4920 Program *program = mGLState.getProgram();
4921 program->setUniformMatrix3x2fv(location, count, transpose, value);
4922}
4923
4924void Context::uniformMatrix2x4fv(GLint location,
4925 GLsizei count,
4926 GLboolean transpose,
4927 const GLfloat *value)
4928{
4929 Program *program = mGLState.getProgram();
4930 program->setUniformMatrix2x4fv(location, count, transpose, value);
4931}
4932
4933void Context::uniformMatrix4x2fv(GLint location,
4934 GLsizei count,
4935 GLboolean transpose,
4936 const GLfloat *value)
4937{
4938 Program *program = mGLState.getProgram();
4939 program->setUniformMatrix4x2fv(location, count, transpose, value);
4940}
4941
4942void Context::uniformMatrix3x4fv(GLint location,
4943 GLsizei count,
4944 GLboolean transpose,
4945 const GLfloat *value)
4946{
4947 Program *program = mGLState.getProgram();
4948 program->setUniformMatrix3x4fv(location, count, transpose, value);
4949}
4950
4951void Context::uniformMatrix4x3fv(GLint location,
4952 GLsizei count,
4953 GLboolean transpose,
4954 const GLfloat *value)
4955{
4956 Program *program = mGLState.getProgram();
4957 program->setUniformMatrix4x3fv(location, count, transpose, value);
4958}
4959
Jamie Madilld7576732017-08-26 18:49:50 -04004960void Context::deleteVertexArrays(GLsizei n, const GLuint *arrays)
4961{
4962 for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
4963 {
4964 GLuint vertexArray = arrays[arrayIndex];
4965
4966 if (arrays[arrayIndex] != 0)
4967 {
4968 VertexArray *vertexArrayObject = nullptr;
4969 if (mVertexArrayMap.erase(vertexArray, &vertexArrayObject))
4970 {
4971 if (vertexArrayObject != nullptr)
4972 {
4973 detachVertexArray(vertexArray);
4974 vertexArrayObject->onDestroy(this);
4975 }
4976
4977 mVertexArrayHandleAllocator.release(vertexArray);
4978 }
4979 }
4980 }
4981}
4982
4983void Context::genVertexArrays(GLsizei n, GLuint *arrays)
4984{
4985 for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
4986 {
4987 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
4988 mVertexArrayMap.assign(vertexArray, nullptr);
4989 arrays[arrayIndex] = vertexArray;
4990 }
4991}
4992
4993bool Context::isVertexArray(GLuint array)
4994{
4995 if (array == 0)
4996 {
4997 return GL_FALSE;
4998 }
4999
5000 VertexArray *vao = getVertexArray(array);
5001 return (vao != nullptr ? GL_TRUE : GL_FALSE);
5002}
5003
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04005004void Context::endTransformFeedback()
5005{
5006 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
5007 transformFeedback->end(this);
5008}
5009
5010void Context::transformFeedbackVaryings(GLuint program,
5011 GLsizei count,
5012 const GLchar *const *varyings,
5013 GLenum bufferMode)
5014{
5015 Program *programObject = getProgram(program);
5016 ASSERT(programObject);
5017 programObject->setTransformFeedbackVaryings(count, varyings, bufferMode);
5018}
5019
5020void Context::getTransformFeedbackVarying(GLuint program,
5021 GLuint index,
5022 GLsizei bufSize,
5023 GLsizei *length,
5024 GLsizei *size,
5025 GLenum *type,
5026 GLchar *name)
5027{
5028 Program *programObject = getProgram(program);
5029 ASSERT(programObject);
5030 programObject->getTransformFeedbackVarying(index, bufSize, length, size, type, name);
5031}
5032
5033void Context::deleteTransformFeedbacks(GLsizei n, const GLuint *ids)
5034{
5035 for (int i = 0; i < n; i++)
5036 {
5037 GLuint transformFeedback = ids[i];
5038 if (transformFeedback == 0)
5039 {
5040 continue;
5041 }
5042
5043 TransformFeedback *transformFeedbackObject = nullptr;
5044 if (mTransformFeedbackMap.erase(transformFeedback, &transformFeedbackObject))
5045 {
5046 if (transformFeedbackObject != nullptr)
5047 {
5048 detachTransformFeedback(transformFeedback);
5049 transformFeedbackObject->release(this);
5050 }
5051
5052 mTransformFeedbackHandleAllocator.release(transformFeedback);
5053 }
5054 }
5055}
5056
5057void Context::genTransformFeedbacks(GLsizei n, GLuint *ids)
5058{
5059 for (int i = 0; i < n; i++)
5060 {
5061 GLuint transformFeedback = mTransformFeedbackHandleAllocator.allocate();
5062 mTransformFeedbackMap.assign(transformFeedback, nullptr);
5063 ids[i] = transformFeedback;
5064 }
5065}
5066
5067bool Context::isTransformFeedback(GLuint id)
5068{
5069 if (id == 0)
5070 {
5071 // The 3.0.4 spec [section 6.1.11] states that if ID is zero, IsTransformFeedback
5072 // returns FALSE
5073 return GL_FALSE;
5074 }
5075
5076 const TransformFeedback *transformFeedback = getTransformFeedback(id);
5077 return ((transformFeedback != nullptr) ? GL_TRUE : GL_FALSE);
5078}
5079
5080void Context::pauseTransformFeedback()
5081{
5082 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
5083 transformFeedback->pause();
5084}
5085
5086void Context::resumeTransformFeedback()
5087{
5088 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
5089 transformFeedback->resume();
5090}
5091
Jamie Madill12e957f2017-08-26 21:42:26 -04005092void Context::getUniformuiv(GLuint program, GLint location, GLuint *params)
5093{
5094 const Program *programObject = getProgram(program);
Jamie Madill54164b02017-08-28 15:17:37 -04005095 programObject->getUniformuiv(this, location, params);
Jamie Madill12e957f2017-08-26 21:42:26 -04005096}
5097
5098GLint Context::getFragDataLocation(GLuint program, const GLchar *name)
5099{
5100 const Program *programObject = getProgram(program);
5101 return programObject->getFragDataLocation(name);
5102}
5103
5104void Context::getUniformIndices(GLuint program,
5105 GLsizei uniformCount,
5106 const GLchar *const *uniformNames,
5107 GLuint *uniformIndices)
5108{
5109 const Program *programObject = getProgram(program);
5110 if (!programObject->isLinked())
5111 {
5112 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
5113 {
5114 uniformIndices[uniformId] = GL_INVALID_INDEX;
5115 }
5116 }
5117 else
5118 {
5119 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
5120 {
5121 uniformIndices[uniformId] = programObject->getUniformIndex(uniformNames[uniformId]);
5122 }
5123 }
5124}
5125
5126void Context::getActiveUniformsiv(GLuint program,
5127 GLsizei uniformCount,
5128 const GLuint *uniformIndices,
5129 GLenum pname,
5130 GLint *params)
5131{
5132 const Program *programObject = getProgram(program);
5133 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
5134 {
5135 const GLuint index = uniformIndices[uniformId];
5136 params[uniformId] = programObject->getActiveUniformi(index, pname);
5137 }
5138}
5139
5140GLuint Context::getUniformBlockIndex(GLuint program, const GLchar *uniformBlockName)
5141{
5142 const Program *programObject = getProgram(program);
5143 return programObject->getUniformBlockIndex(uniformBlockName);
5144}
5145
5146void Context::getActiveUniformBlockiv(GLuint program,
5147 GLuint uniformBlockIndex,
5148 GLenum pname,
5149 GLint *params)
5150{
5151 const Program *programObject = getProgram(program);
5152 QueryActiveUniformBlockiv(programObject, uniformBlockIndex, pname, params);
5153}
5154
5155void Context::getActiveUniformBlockName(GLuint program,
5156 GLuint uniformBlockIndex,
5157 GLsizei bufSize,
5158 GLsizei *length,
5159 GLchar *uniformBlockName)
5160{
5161 const Program *programObject = getProgram(program);
5162 programObject->getActiveUniformBlockName(uniformBlockIndex, bufSize, length, uniformBlockName);
5163}
5164
5165void Context::uniformBlockBinding(GLuint program,
5166 GLuint uniformBlockIndex,
5167 GLuint uniformBlockBinding)
5168{
5169 Program *programObject = getProgram(program);
5170 programObject->bindUniformBlock(uniformBlockIndex, uniformBlockBinding);
5171}
5172
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005173GLsync Context::fenceSync(GLenum condition, GLbitfield flags)
5174{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005175 GLuint handle = mState.mSyncs->createSync(mImplementation.get());
5176 GLsync syncHandle = reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005177
Jamie Madill70b5bb02017-08-28 13:32:37 -04005178 Sync *syncObject = getSync(syncHandle);
5179 Error error = syncObject->set(condition, flags);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005180 if (error.isError())
5181 {
Jamie Madill70b5bb02017-08-28 13:32:37 -04005182 deleteSync(syncHandle);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005183 handleError(error);
5184 return nullptr;
5185 }
5186
Jamie Madill70b5bb02017-08-28 13:32:37 -04005187 return syncHandle;
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005188}
5189
5190GLboolean Context::isSync(GLsync sync)
5191{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005192 return (getSync(sync) != nullptr);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005193}
5194
5195GLenum Context::clientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
5196{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005197 Sync *syncObject = getSync(sync);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005198
5199 GLenum result = GL_WAIT_FAILED;
5200 handleError(syncObject->clientWait(flags, timeout, &result));
5201 return result;
5202}
5203
5204void Context::waitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
5205{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005206 Sync *syncObject = getSync(sync);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005207 handleError(syncObject->serverWait(flags, timeout));
5208}
5209
5210void Context::getInteger64v(GLenum pname, GLint64 *params)
5211{
5212 GLenum nativeType = GL_NONE;
5213 unsigned int numParams = 0;
5214 getQueryParameterInfo(pname, &nativeType, &numParams);
5215
5216 if (nativeType == GL_INT_64_ANGLEX)
5217 {
5218 getInteger64vImpl(pname, params);
5219 }
5220 else
5221 {
5222 CastStateValues(this, nativeType, pname, numParams, params);
5223 }
5224}
5225
Jamie Madill3ef140a2017-08-26 23:11:21 -04005226void Context::getBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params)
5227{
5228 Buffer *buffer = mGLState.getTargetBuffer(target);
5229 QueryBufferParameteri64v(buffer, pname, params);
5230}
5231
5232void Context::genSamplers(GLsizei count, GLuint *samplers)
5233{
5234 for (int i = 0; i < count; i++)
5235 {
5236 samplers[i] = mState.mSamplers->createSampler();
5237 }
5238}
5239
5240void Context::deleteSamplers(GLsizei count, const GLuint *samplers)
5241{
5242 for (int i = 0; i < count; i++)
5243 {
5244 GLuint sampler = samplers[i];
5245
5246 if (mState.mSamplers->getSampler(sampler))
5247 {
5248 detachSampler(sampler);
5249 }
5250
5251 mState.mSamplers->deleteObject(this, sampler);
5252 }
5253}
5254
5255void Context::getInternalformativ(GLenum target,
5256 GLenum internalformat,
5257 GLenum pname,
5258 GLsizei bufSize,
5259 GLint *params)
5260{
5261 const TextureCaps &formatCaps = mTextureCaps.get(internalformat);
5262 QueryInternalFormativ(formatCaps, pname, bufSize, params);
5263}
5264
Jamie Madill81c2e252017-09-09 23:32:46 -04005265void Context::programUniform1iv(GLuint program, GLint location, GLsizei count, const GLint *value)
5266{
5267 Program *programObject = getProgram(program);
5268 ASSERT(programObject);
5269 if (programObject->setUniform1iv(location, count, value) ==
5270 Program::SetUniformResult::SamplerChanged)
5271 {
5272 mGLState.setObjectDirty(GL_PROGRAM);
5273 }
5274}
5275
5276void Context::onTextureChange(const Texture *texture)
5277{
5278 // Conservatively assume all textures are dirty.
5279 // TODO(jmadill): More fine-grained update.
5280 mGLState.setObjectDirty(GL_TEXTURE);
5281}
5282
Jamie Madillc29968b2016-01-20 11:17:23 -05005283} // namespace gl