blob: f7f58da82a6e4b48d5af91acb8822013457c26d1 [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 Madill4e0e6f82017-02-17 11:06:03 -0500283 initCaps(displayExtensions);
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700284 initWorkarounds();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400285
Jamie Madill4928b7c2017-06-20 12:57:39 -0400286 mGLState.initialize(this, GetDebug(attribs), GetBindGeneratesResource(attribs),
Jamie Madillc43be722017-07-13 16:22:14 -0400287 GetClientArraysEnabled(attribs), robustResourceInit,
288 mMemoryProgramCache != nullptr);
Régis Fénéon83107972015-02-05 12:57:44 +0100289
Shannon Woods53a94a82014-06-24 15:20:36 -0400290 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400291
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000292 // [OpenGL ES 2.0.24] section 3.7 page 83:
293 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
294 // and cube map texture state vectors respectively associated with them.
295 // In order that access to these initial textures not be lost, they are treated as texture
296 // objects all of whose names are 0.
297
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400298 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400299 mZeroTextures[GL_TEXTURE_2D].set(this, zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500300
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400301 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400302 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(this, zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400303
Geoff Langeb66a6e2016-10-31 13:06:12 -0400304 if (getClientVersion() >= Version(3, 0))
Geoff Lang76b10c92014-09-05 16:28:14 -0400305 {
306 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400307 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400308 mZeroTextures[GL_TEXTURE_3D].set(this, zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400309
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400310 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400311 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(this, zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400312 }
Geoff Lang3b573612016-10-31 14:08:10 -0400313 if (getClientVersion() >= Version(3, 1))
314 {
315 Texture *zeroTexture2DMultisample =
316 new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_MULTISAMPLE);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400317 mZeroTextures[GL_TEXTURE_2D_MULTISAMPLE].set(this, zeroTexture2DMultisample);
Jiajia Qin6eafb042016-12-27 17:04:07 +0800318
319 bindGenericAtomicCounterBuffer(0);
320 for (unsigned int i = 0; i < mCaps.maxAtomicCounterBufferBindings; i++)
321 {
322 bindIndexedAtomicCounterBuffer(0, i, 0, 0);
323 }
Jiajia Qinf546e7d2017-03-27 14:12:59 +0800324
325 bindGenericShaderStorageBuffer(0);
326 for (unsigned int i = 0; i < mCaps.maxShaderStorageBufferBindings; i++)
327 {
328 bindIndexedShaderStorageBuffer(0, i, 0, 0);
329 }
Geoff Lang3b573612016-10-31 14:08:10 -0400330 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000331
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400332 if (mExtensions.textureRectangle)
333 {
334 Texture *zeroTextureRectangle =
335 new Texture(mImplementation.get(), 0, GL_TEXTURE_RECTANGLE_ANGLE);
336 mZeroTextures[GL_TEXTURE_RECTANGLE_ANGLE].set(this, zeroTextureRectangle);
337 }
338
Ian Ewellbda75592016-04-18 17:25:54 -0400339 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
340 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400341 Texture *zeroTextureExternal =
342 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400343 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(this, zeroTextureExternal);
Ian Ewellbda75592016-04-18 17:25:54 -0400344 }
345
Jamie Madill4928b7c2017-06-20 12:57:39 -0400346 mGLState.initializeZeroTextures(this, mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500347
Jamie Madill57a89722013-07-02 11:57:03 -0400348 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000349 bindArrayBuffer(0);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800350 bindDrawIndirectBuffer(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000351 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400352
Jamie Madill01a80ee2016-11-07 12:06:18 -0500353 bindRenderbuffer(GL_RENDERBUFFER, 0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000354
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000355 bindGenericUniformBuffer(0);
Geoff Lang4dc3af02016-11-18 14:09:27 -0500356 for (unsigned int i = 0; i < mCaps.maxUniformBufferBindings; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000357 {
358 bindIndexedUniformBuffer(0, i, 0, -1);
359 }
360
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000361 bindCopyReadBuffer(0);
362 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000363 bindPixelPackBuffer(0);
364 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000365
Geoff Langeb66a6e2016-10-31 13:06:12 -0400366 if (getClientVersion() >= Version(3, 0))
Geoff Lang1a683462015-09-29 15:09:59 -0400367 {
368 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
369 // In the initial state, a default transform feedback object is bound and treated as
370 // a transform feedback object with a name of zero. That object is bound any time
371 // BindTransformFeedback is called with id of zero
Jamie Madillf0dcb8b2017-08-26 19:05:13 -0400372 bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
Geoff Lang1a683462015-09-29 15:09:59 -0400373 }
Geoff Langc8058452014-02-03 12:04:11 -0500374
Jamie Madillad9f24e2016-02-12 09:27:24 -0500375 // Initialize dirty bit masks
376 // TODO(jmadill): additional ES3 state
377 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
378 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
379 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
380 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
381 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
382 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400383 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500384 // No dirty objects.
385
386 // Readpixels uses the pack state and read FBO
387 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
388 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
389 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
390 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
391 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400392 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500393 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
394
395 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
396 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
397 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
398 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
399 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
400 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
401 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
402 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
403 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
404 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
405 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
406 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
407
408 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
409 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700410 mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500411 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
412 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400413
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400414 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000415}
416
Jamie Madill4928b7c2017-06-20 12:57:39 -0400417egl::Error Context::onDestroy(const egl::Display *display)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000418{
Corentin Wallez80b24112015-08-25 16:41:57 -0400419 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000420 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400421 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000422 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400423 mFenceNVMap.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000424
Corentin Wallez80b24112015-08-25 16:41:57 -0400425 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000426 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400427 if (query.second != nullptr)
428 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400429 query.second->release(this);
Geoff Langf0aa8422015-09-29 15:08:34 -0400430 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000431 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400432 mQueryMap.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000433
Corentin Wallez80b24112015-08-25 16:41:57 -0400434 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400435 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400436 if (vertexArray.second)
437 {
438 vertexArray.second->onDestroy(this);
439 }
Jamie Madill57a89722013-07-02 11:57:03 -0400440 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400441 mVertexArrayMap.clear();
Jamie Madill57a89722013-07-02 11:57:03 -0400442
Corentin Wallez80b24112015-08-25 16:41:57 -0400443 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500444 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500445 if (transformFeedback.second != nullptr)
446 {
Jamie Madill6c1f6712017-02-14 19:08:04 -0500447 transformFeedback.second->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500448 }
Geoff Langc8058452014-02-03 12:04:11 -0500449 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400450 mTransformFeedbackMap.clear();
Geoff Langc8058452014-02-03 12:04:11 -0500451
Jamie Madilldedd7b92014-11-05 16:30:36 -0500452 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400453 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400454 zeroTexture.second->onDestroy(this);
455 zeroTexture.second.set(this, nullptr);
Geoff Lang76b10c92014-09-05 16:28:14 -0400456 }
457 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000458
Corentin Wallezccab69d2017-01-27 16:57:15 -0500459 SafeDelete(mSurfacelessFramebuffer);
460
Jamie Madill4928b7c2017-06-20 12:57:39 -0400461 ANGLE_TRY(releaseSurface(display));
Jamie Madill2f348d22017-06-05 10:50:59 -0400462 releaseShaderCompiler();
Jamie Madill6c1f6712017-02-14 19:08:04 -0500463
Jamie Madill4928b7c2017-06-20 12:57:39 -0400464 mGLState.reset(this);
465
Jamie Madill6c1f6712017-02-14 19:08:04 -0500466 mState.mBuffers->release(this);
467 mState.mShaderPrograms->release(this);
468 mState.mTextures->release(this);
469 mState.mRenderbuffers->release(this);
470 mState.mSamplers->release(this);
Jamie Madill70b5bb02017-08-28 13:32:37 -0400471 mState.mSyncs->release(this);
Jamie Madill6c1f6712017-02-14 19:08:04 -0500472 mState.mPaths->release(this);
473 mState.mFramebuffers->release(this);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400474
475 return egl::NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000476}
477
Jamie Madill70ee0f62017-02-06 16:04:20 -0500478Context::~Context()
479{
480}
481
Jamie Madill4928b7c2017-06-20 12:57:39 -0400482egl::Error Context::makeCurrent(egl::Display *display, egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000483{
Jamie Madill61e16b42017-06-19 11:13:23 -0400484 mCurrentDisplay = display;
485
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000486 if (!mHasBeenCurrent)
487 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000488 initRendererString();
Geoff Langc339c4e2016-11-29 10:37:36 -0500489 initVersionStrings();
Geoff Langcec35902014-04-16 10:52:36 -0400490 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000491
Corentin Wallezc295e512017-01-27 17:47:50 -0500492 int width = 0;
493 int height = 0;
494 if (surface != nullptr)
495 {
496 width = surface->getWidth();
497 height = surface->getHeight();
498 }
499
500 mGLState.setViewportParams(0, 0, width, height);
501 mGLState.setScissorParams(0, 0, width, height);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000502
503 mHasBeenCurrent = true;
504 }
505
Jamie Madill1b94d432015-08-07 13:23:23 -0400506 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700507 mGLState.setAllDirtyBits();
Jamie Madill81c2e252017-09-09 23:32:46 -0400508 mGLState.setAllDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -0400509
Jamie Madill4928b7c2017-06-20 12:57:39 -0400510 ANGLE_TRY(releaseSurface(display));
Corentin Wallezccab69d2017-01-27 16:57:15 -0500511
512 Framebuffer *newDefault = nullptr;
513 if (surface != nullptr)
514 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400515 ANGLE_TRY(surface->setIsCurrent(this, true));
Corentin Wallezccab69d2017-01-27 16:57:15 -0500516 mCurrentSurface = surface;
517 newDefault = surface->getDefaultFramebuffer();
518 }
519 else
520 {
521 if (mSurfacelessFramebuffer == nullptr)
522 {
523 mSurfacelessFramebuffer = new Framebuffer(mImplementation.get());
524 }
525
526 newDefault = mSurfacelessFramebuffer;
527 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000528
Corentin Wallez37c39792015-08-20 14:19:46 -0400529 // Update default framebuffer, the binding of the previous default
530 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400531 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700532 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400533 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700534 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400535 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700536 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400537 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700538 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400539 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500540 mState.mFramebuffers->setDefaultFramebuffer(newDefault);
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400541 }
Ian Ewell292f0052016-02-04 10:37:32 -0500542
543 // Notify the renderer of a context switch
Jamie Madill4928b7c2017-06-20 12:57:39 -0400544 mImplementation->onMakeCurrent(this);
545 return egl::NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000546}
547
Jamie Madill4928b7c2017-06-20 12:57:39 -0400548egl::Error Context::releaseSurface(const egl::Display *display)
Jamie Madill77a72f62015-04-14 11:18:32 -0400549{
Corentin Wallez37c39792015-08-20 14:19:46 -0400550 // Remove the default framebuffer
Corentin Wallezc295e512017-01-27 17:47:50 -0500551 Framebuffer *currentDefault = nullptr;
552 if (mCurrentSurface != nullptr)
Corentin Wallez51706ea2015-08-07 14:39:22 -0400553 {
Corentin Wallezc295e512017-01-27 17:47:50 -0500554 currentDefault = mCurrentSurface->getDefaultFramebuffer();
555 }
556 else if (mSurfacelessFramebuffer != nullptr)
557 {
558 currentDefault = mSurfacelessFramebuffer;
Corentin Wallez51706ea2015-08-07 14:39:22 -0400559 }
560
Corentin Wallezc295e512017-01-27 17:47:50 -0500561 if (mGLState.getReadFramebuffer() == currentDefault)
562 {
563 mGLState.setReadFramebufferBinding(nullptr);
564 }
565 if (mGLState.getDrawFramebuffer() == currentDefault)
566 {
567 mGLState.setDrawFramebufferBinding(nullptr);
568 }
569 mState.mFramebuffers->setDefaultFramebuffer(nullptr);
570
571 if (mCurrentSurface)
572 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400573 ANGLE_TRY(mCurrentSurface->setIsCurrent(this, false));
Corentin Wallezc295e512017-01-27 17:47:50 -0500574 mCurrentSurface = nullptr;
575 }
Jamie Madill4928b7c2017-06-20 12:57:39 -0400576
577 return egl::NoError();
Jamie Madill77a72f62015-04-14 11:18:32 -0400578}
579
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000580GLuint Context::createBuffer()
581{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500582 return mState.mBuffers->createBuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000583}
584
585GLuint Context::createProgram()
586{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500587 return mState.mShaderPrograms->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000588}
589
590GLuint Context::createShader(GLenum type)
591{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500592 return mState.mShaderPrograms->createShader(mImplementation.get(), mLimitations, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000593}
594
595GLuint Context::createTexture()
596{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500597 return mState.mTextures->createTexture();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000598}
599
600GLuint Context::createRenderbuffer()
601{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500602 return mState.mRenderbuffers->createRenderbuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000603}
604
Sami Väisänene45e53b2016-05-25 10:36:04 +0300605GLuint Context::createPaths(GLsizei range)
606{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500607 auto resultOrError = mState.mPaths->createPaths(mImplementation.get(), range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300608 if (resultOrError.isError())
609 {
610 handleError(resultOrError.getError());
611 return 0;
612 }
613 return resultOrError.getResult();
614}
615
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000616// Returns an unused framebuffer name
617GLuint Context::createFramebuffer()
618{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500619 return mState.mFramebuffers->createFramebuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000620}
621
Jamie Madill33dc8432013-07-26 11:55:05 -0400622GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000623{
Jamie Madill33dc8432013-07-26 11:55:05 -0400624 GLuint handle = mFenceNVHandleAllocator.allocate();
Jamie Madill96a483b2017-06-27 16:49:21 -0400625 mFenceNVMap.assign(handle, new FenceNV(mImplementation->createFenceNV()));
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000626 return handle;
627}
628
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000629void Context::deleteBuffer(GLuint buffer)
630{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500631 if (mState.mBuffers->getBuffer(buffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000632 {
633 detachBuffer(buffer);
634 }
Jamie Madill893ab082014-05-16 16:56:10 -0400635
Jamie Madill6c1f6712017-02-14 19:08:04 -0500636 mState.mBuffers->deleteObject(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000637}
638
639void Context::deleteShader(GLuint shader)
640{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500641 mState.mShaderPrograms->deleteShader(this, shader);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000642}
643
644void Context::deleteProgram(GLuint program)
645{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500646 mState.mShaderPrograms->deleteProgram(this, program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000647}
648
649void Context::deleteTexture(GLuint texture)
650{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500651 if (mState.mTextures->getTexture(texture))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000652 {
653 detachTexture(texture);
654 }
655
Jamie Madill6c1f6712017-02-14 19:08:04 -0500656 mState.mTextures->deleteObject(this, texture);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000657}
658
659void Context::deleteRenderbuffer(GLuint renderbuffer)
660{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500661 if (mState.mRenderbuffers->getRenderbuffer(renderbuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000662 {
663 detachRenderbuffer(renderbuffer);
664 }
Jamie Madill893ab082014-05-16 16:56:10 -0400665
Jamie Madill6c1f6712017-02-14 19:08:04 -0500666 mState.mRenderbuffers->deleteObject(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000667}
668
Jamie Madill7f0c5a42017-08-26 22:43:26 -0400669void Context::deleteSync(GLsync sync)
Jamie Madillcd055f82013-07-26 11:55:15 -0400670{
671 // The spec specifies the underlying Fence object is not deleted until all current
672 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
673 // and since our API is currently designed for being called from a single thread, we can delete
674 // the fence immediately.
Jamie Madill70b5bb02017-08-28 13:32:37 -0400675 mState.mSyncs->deleteObject(this, static_cast<GLuint>(reinterpret_cast<uintptr_t>(sync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400676}
677
Sami Väisänene45e53b2016-05-25 10:36:04 +0300678void Context::deletePaths(GLuint first, GLsizei range)
679{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500680 mState.mPaths->deletePaths(first, range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300681}
682
683bool Context::hasPathData(GLuint path) const
684{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500685 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300686 if (pathObj == nullptr)
687 return false;
688
689 return pathObj->hasPathData();
690}
691
692bool Context::hasPath(GLuint path) const
693{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500694 return mState.mPaths->hasPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300695}
696
697void Context::setPathCommands(GLuint path,
698 GLsizei numCommands,
699 const GLubyte *commands,
700 GLsizei numCoords,
701 GLenum coordType,
702 const void *coords)
703{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500704 auto *pathObject = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300705
706 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
707}
708
709void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
710{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500711 auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300712
713 switch (pname)
714 {
715 case GL_PATH_STROKE_WIDTH_CHROMIUM:
716 pathObj->setStrokeWidth(value);
717 break;
718 case GL_PATH_END_CAPS_CHROMIUM:
719 pathObj->setEndCaps(static_cast<GLenum>(value));
720 break;
721 case GL_PATH_JOIN_STYLE_CHROMIUM:
722 pathObj->setJoinStyle(static_cast<GLenum>(value));
723 break;
724 case GL_PATH_MITER_LIMIT_CHROMIUM:
725 pathObj->setMiterLimit(value);
726 break;
727 case GL_PATH_STROKE_BOUND_CHROMIUM:
728 pathObj->setStrokeBound(value);
729 break;
730 default:
731 UNREACHABLE();
732 break;
733 }
734}
735
736void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
737{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500738 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300739
740 switch (pname)
741 {
742 case GL_PATH_STROKE_WIDTH_CHROMIUM:
743 *value = pathObj->getStrokeWidth();
744 break;
745 case GL_PATH_END_CAPS_CHROMIUM:
746 *value = static_cast<GLfloat>(pathObj->getEndCaps());
747 break;
748 case GL_PATH_JOIN_STYLE_CHROMIUM:
749 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
750 break;
751 case GL_PATH_MITER_LIMIT_CHROMIUM:
752 *value = pathObj->getMiterLimit();
753 break;
754 case GL_PATH_STROKE_BOUND_CHROMIUM:
755 *value = pathObj->getStrokeBound();
756 break;
757 default:
758 UNREACHABLE();
759 break;
760 }
761}
762
763void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
764{
765 mGLState.setPathStencilFunc(func, ref, mask);
766}
767
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000768void Context::deleteFramebuffer(GLuint framebuffer)
769{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500770 if (mState.mFramebuffers->getFramebuffer(framebuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000771 {
772 detachFramebuffer(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000773 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500774
Jamie Madill6c1f6712017-02-14 19:08:04 -0500775 mState.mFramebuffers->deleteObject(this, framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000776}
777
Jamie Madill33dc8432013-07-26 11:55:05 -0400778void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000779{
Jamie Madill96a483b2017-06-27 16:49:21 -0400780 FenceNV *fenceObject = nullptr;
781 if (mFenceNVMap.erase(fence, &fenceObject))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000782 {
Jamie Madill96a483b2017-06-27 16:49:21 -0400783 mFenceNVHandleAllocator.release(fence);
784 delete fenceObject;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000785 }
786}
787
Geoff Lang70d0f492015-12-10 17:45:46 -0500788Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000789{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500790 return mState.mBuffers->getBuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000791}
792
Jamie Madill570f7c82014-07-03 10:38:54 -0400793Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000794{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500795 return mState.mTextures->getTexture(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000796}
797
Geoff Lang70d0f492015-12-10 17:45:46 -0500798Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000799{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500800 return mState.mRenderbuffers->getRenderbuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000801}
802
Jamie Madill70b5bb02017-08-28 13:32:37 -0400803Sync *Context::getSync(GLsync handle) const
Jamie Madillcd055f82013-07-26 11:55:15 -0400804{
Jamie Madill70b5bb02017-08-28 13:32:37 -0400805 return mState.mSyncs->getSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400806}
807
Jamie Madill57a89722013-07-02 11:57:03 -0400808VertexArray *Context::getVertexArray(GLuint handle) const
809{
Jamie Madill96a483b2017-06-27 16:49:21 -0400810 return mVertexArrayMap.query(handle);
Jamie Madill57a89722013-07-02 11:57:03 -0400811}
812
Jamie Madilldc356042013-07-19 16:36:57 -0400813Sampler *Context::getSampler(GLuint handle) const
814{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500815 return mState.mSamplers->getSampler(handle);
Jamie Madilldc356042013-07-19 16:36:57 -0400816}
817
Geoff Langc8058452014-02-03 12:04:11 -0500818TransformFeedback *Context::getTransformFeedback(GLuint handle) const
819{
Jamie Madill96a483b2017-06-27 16:49:21 -0400820 return mTransformFeedbackMap.query(handle);
Geoff Langc8058452014-02-03 12:04:11 -0500821}
822
Geoff Lang70d0f492015-12-10 17:45:46 -0500823LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
824{
825 switch (identifier)
826 {
827 case GL_BUFFER:
828 return getBuffer(name);
829 case GL_SHADER:
830 return getShader(name);
831 case GL_PROGRAM:
832 return getProgram(name);
833 case GL_VERTEX_ARRAY:
834 return getVertexArray(name);
835 case GL_QUERY:
836 return getQuery(name);
837 case GL_TRANSFORM_FEEDBACK:
838 return getTransformFeedback(name);
839 case GL_SAMPLER:
840 return getSampler(name);
841 case GL_TEXTURE:
842 return getTexture(name);
843 case GL_RENDERBUFFER:
844 return getRenderbuffer(name);
845 case GL_FRAMEBUFFER:
846 return getFramebuffer(name);
847 default:
848 UNREACHABLE();
849 return nullptr;
850 }
851}
852
853LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
854{
Jamie Madill70b5bb02017-08-28 13:32:37 -0400855 return getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
Geoff Lang70d0f492015-12-10 17:45:46 -0500856}
857
Martin Radev9d901792016-07-15 15:58:58 +0300858void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
859{
860 LabeledObject *object = getLabeledObject(identifier, name);
861 ASSERT(object != nullptr);
862
863 std::string labelName = GetObjectLabelFromPointer(length, label);
864 object->setLabel(labelName);
Jamie Madill8693bdb2017-09-02 15:32:14 -0400865
866 // TODO(jmadill): Determine if the object is dirty based on 'name'. Conservatively assume the
867 // specified object is active until we do this.
868 mGLState.setObjectDirty(identifier);
Martin Radev9d901792016-07-15 15:58:58 +0300869}
870
871void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
872{
873 LabeledObject *object = getLabeledObjectFromPtr(ptr);
874 ASSERT(object != nullptr);
875
876 std::string labelName = GetObjectLabelFromPointer(length, label);
877 object->setLabel(labelName);
878}
879
880void Context::getObjectLabel(GLenum identifier,
881 GLuint name,
882 GLsizei bufSize,
883 GLsizei *length,
884 GLchar *label) const
885{
886 LabeledObject *object = getLabeledObject(identifier, name);
887 ASSERT(object != nullptr);
888
889 const std::string &objectLabel = object->getLabel();
890 GetObjectLabelBase(objectLabel, bufSize, length, label);
891}
892
893void Context::getObjectPtrLabel(const void *ptr,
894 GLsizei bufSize,
895 GLsizei *length,
896 GLchar *label) const
897{
898 LabeledObject *object = getLabeledObjectFromPtr(ptr);
899 ASSERT(object != nullptr);
900
901 const std::string &objectLabel = object->getLabel();
902 GetObjectLabelBase(objectLabel, bufSize, length, label);
903}
904
Jamie Madilldc356042013-07-19 16:36:57 -0400905bool Context::isSampler(GLuint samplerName) const
906{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500907 return mState.mSamplers->isSampler(samplerName);
Jamie Madilldc356042013-07-19 16:36:57 -0400908}
909
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500910void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000911{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500912 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400913 mGLState.setArrayBufferBinding(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000914}
915
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800916void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
917{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500918 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400919 mGLState.setDrawIndirectBufferBinding(this, buffer);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800920}
921
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500922void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000923{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500924 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400925 mGLState.setElementArrayBuffer(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000926}
927
Jamie Madilldedd7b92014-11-05 16:30:36 -0500928void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000929{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500930 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000931
Jamie Madilldedd7b92014-11-05 16:30:36 -0500932 if (handle == 0)
933 {
934 texture = mZeroTextures[target].get();
935 }
936 else
937 {
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500938 texture = mState.mTextures->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500939 }
940
941 ASSERT(texture);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400942 mGLState.setSamplerTexture(this, target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000943}
944
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500945void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000946{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500947 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
948 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700949 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000950}
951
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500952void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000953{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500954 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
955 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700956 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000957}
958
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500959void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -0400960{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500961 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700962 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400963}
964
Shao80957d92017-02-20 21:25:59 +0800965void Context::bindVertexBuffer(GLuint bindingIndex,
966 GLuint bufferHandle,
967 GLintptr offset,
968 GLsizei stride)
969{
970 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400971 mGLState.bindVertexBuffer(this, bindingIndex, buffer, offset, stride);
Shao80957d92017-02-20 21:25:59 +0800972}
973
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500974void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -0400975{
Geoff Lang76b10c92014-09-05 16:28:14 -0400976 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -0400977 Sampler *sampler =
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500978 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400979 mGLState.setSamplerBinding(this, textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400980}
981
Xinghua Cao65ec0b22017-03-28 16:10:52 +0800982void Context::bindImageTexture(GLuint unit,
983 GLuint texture,
984 GLint level,
985 GLboolean layered,
986 GLint layer,
987 GLenum access,
988 GLenum format)
989{
990 Texture *tex = mState.mTextures->getTexture(texture);
991 mGLState.setImageUnit(this, unit, tex, level, layered, layer, access, format);
992}
993
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500994void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000995{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500996 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400997 mGLState.setGenericUniformBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000998}
999
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001000void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1001 GLuint index,
1002 GLintptr offset,
1003 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001004{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001005 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001006 mGLState.setIndexedUniformBufferBinding(this, index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001007}
1008
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001009void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001010{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001011 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001012 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001013}
1014
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001015void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1016 GLuint index,
1017 GLintptr offset,
1018 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001019{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001020 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001021 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(this, index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001022}
1023
Jiajia Qin6eafb042016-12-27 17:04:07 +08001024void Context::bindGenericAtomicCounterBuffer(GLuint bufferHandle)
1025{
1026 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001027 mGLState.setGenericAtomicCounterBufferBinding(this, buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08001028}
1029
1030void Context::bindIndexedAtomicCounterBuffer(GLuint bufferHandle,
1031 GLuint index,
1032 GLintptr offset,
1033 GLsizeiptr size)
1034{
1035 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001036 mGLState.setIndexedAtomicCounterBufferBinding(this, index, buffer, offset, size);
Jiajia Qin6eafb042016-12-27 17:04:07 +08001037}
1038
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001039void Context::bindGenericShaderStorageBuffer(GLuint bufferHandle)
1040{
1041 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001042 mGLState.setGenericShaderStorageBufferBinding(this, buffer);
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001043}
1044
1045void Context::bindIndexedShaderStorageBuffer(GLuint bufferHandle,
1046 GLuint index,
1047 GLintptr offset,
1048 GLsizeiptr size)
1049{
1050 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001051 mGLState.setIndexedShaderStorageBufferBinding(this, index, buffer, offset, size);
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001052}
1053
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001054void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001055{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001056 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001057 mGLState.setCopyReadBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001058}
1059
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001060void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001061{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001062 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001063 mGLState.setCopyWriteBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001064}
1065
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001066void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001067{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001068 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001069 mGLState.setPixelPackBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001070}
1071
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001072void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001073{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001074 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001075 mGLState.setPixelUnpackBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001076}
1077
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001078void Context::useProgram(GLuint program)
1079{
Jamie Madill6c1f6712017-02-14 19:08:04 -05001080 mGLState.setProgram(this, getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001081}
1082
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04001083void Context::bindTransformFeedback(GLenum target, GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001084{
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04001085 ASSERT(target == GL_TRANSFORM_FEEDBACK);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001086 TransformFeedback *transformFeedback =
1087 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001088 mGLState.setTransformFeedbackBinding(this, transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001089}
1090
Jamie Madillf0e04492017-08-26 15:28:42 -04001091void Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001092{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001093 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001094 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001095
Geoff Lang5aad9672014-09-08 11:10:42 -04001096 // begin query
Jamie Madillf0e04492017-08-26 15:28:42 -04001097 ANGLE_CONTEXT_TRY(queryObject->begin());
Geoff Lang5aad9672014-09-08 11:10:42 -04001098
1099 // set query as active for specified target only if begin succeeded
Jamie Madill4928b7c2017-06-20 12:57:39 -04001100 mGLState.setActiveQuery(this, target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001101}
1102
Jamie Madillf0e04492017-08-26 15:28:42 -04001103void Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001104{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001105 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001106 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001107
Jamie Madillf0e04492017-08-26 15:28:42 -04001108 handleError(queryObject->end());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001109
Geoff Lang5aad9672014-09-08 11:10:42 -04001110 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madill4928b7c2017-06-20 12:57:39 -04001111 mGLState.setActiveQuery(this, target, nullptr);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001112}
1113
Jamie Madillf0e04492017-08-26 15:28:42 -04001114void Context::queryCounter(GLuint id, GLenum target)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001115{
1116 ASSERT(target == GL_TIMESTAMP_EXT);
1117
1118 Query *queryObject = getQuery(id, true, target);
1119 ASSERT(queryObject);
1120
Jamie Madillf0e04492017-08-26 15:28:42 -04001121 handleError(queryObject->queryCounter());
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001122}
1123
1124void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1125{
1126 switch (pname)
1127 {
1128 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001129 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001130 break;
1131 case GL_QUERY_COUNTER_BITS_EXT:
1132 switch (target)
1133 {
1134 case GL_TIME_ELAPSED_EXT:
1135 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1136 break;
1137 case GL_TIMESTAMP_EXT:
1138 params[0] = getExtensions().queryCounterBitsTimestamp;
1139 break;
1140 default:
1141 UNREACHABLE();
1142 params[0] = 0;
1143 break;
1144 }
1145 break;
1146 default:
1147 UNREACHABLE();
1148 return;
1149 }
1150}
1151
Geoff Lang2186c382016-10-14 10:54:54 -04001152void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001153{
Geoff Lang2186c382016-10-14 10:54:54 -04001154 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001155}
1156
Geoff Lang2186c382016-10-14 10:54:54 -04001157void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001158{
Geoff Lang2186c382016-10-14 10:54:54 -04001159 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001160}
1161
Geoff Lang2186c382016-10-14 10:54:54 -04001162void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001163{
Geoff Lang2186c382016-10-14 10:54:54 -04001164 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001165}
1166
Geoff Lang2186c382016-10-14 10:54:54 -04001167void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001168{
Geoff Lang2186c382016-10-14 10:54:54 -04001169 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001170}
1171
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001172Framebuffer *Context::getFramebuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001173{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001174 return mState.mFramebuffers->getFramebuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001175}
1176
Jamie Madill2f348d22017-06-05 10:50:59 -04001177FenceNV *Context::getFenceNV(GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001178{
Jamie Madill96a483b2017-06-27 16:49:21 -04001179 return mFenceNVMap.query(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001180}
1181
Jamie Madill2f348d22017-06-05 10:50:59 -04001182Query *Context::getQuery(GLuint handle, bool create, GLenum type)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001183{
Jamie Madill96a483b2017-06-27 16:49:21 -04001184 if (!mQueryMap.contains(handle))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001185 {
Yunchao Hef81ce4a2017-04-24 10:49:17 +08001186 return nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001187 }
Jamie Madill96a483b2017-06-27 16:49:21 -04001188
1189 Query *query = mQueryMap.query(handle);
1190 if (!query && create)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001191 {
Jamie Madill96a483b2017-06-27 16:49:21 -04001192 query = new Query(mImplementation->createQuery(type), handle);
1193 query->addRef();
1194 mQueryMap.assign(handle, query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001195 }
Jamie Madill96a483b2017-06-27 16:49:21 -04001196 return query;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001197}
1198
Geoff Lang70d0f492015-12-10 17:45:46 -05001199Query *Context::getQuery(GLuint handle) const
1200{
Jamie Madill96a483b2017-06-27 16:49:21 -04001201 return mQueryMap.query(handle);
Geoff Lang70d0f492015-12-10 17:45:46 -05001202}
1203
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001204Texture *Context::getTargetTexture(GLenum target) const
1205{
Ian Ewellbda75592016-04-18 17:25:54 -04001206 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001207 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001208}
1209
Geoff Lang76b10c92014-09-05 16:28:14 -04001210Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001211{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001212 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001213}
1214
Geoff Lang492a7e42014-11-05 13:27:06 -05001215Compiler *Context::getCompiler() const
1216{
Jamie Madill2f348d22017-06-05 10:50:59 -04001217 if (mCompiler.get() == nullptr)
1218 {
Jamie Madill4928b7c2017-06-20 12:57:39 -04001219 mCompiler.set(this, new Compiler(mImplementation.get(), mState));
Jamie Madill2f348d22017-06-05 10:50:59 -04001220 }
1221 return mCompiler.get();
Geoff Lang492a7e42014-11-05 13:27:06 -05001222}
1223
Jamie Madillc1d770e2017-04-13 17:31:24 -04001224void Context::getBooleanvImpl(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001225{
1226 switch (pname)
1227 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001228 case GL_SHADER_COMPILER:
1229 *params = GL_TRUE;
1230 break;
1231 case GL_CONTEXT_ROBUST_ACCESS_EXT:
1232 *params = mRobustAccess ? GL_TRUE : GL_FALSE;
1233 break;
1234 default:
1235 mGLState.getBooleanv(pname, params);
1236 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001237 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001238}
1239
Jamie Madillc1d770e2017-04-13 17:31:24 -04001240void Context::getFloatvImpl(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001241{
Shannon Woods53a94a82014-06-24 15:20:36 -04001242 // Queries about context capabilities and maximums are answered by Context.
1243 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001244 switch (pname)
1245 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001246 case GL_ALIASED_LINE_WIDTH_RANGE:
1247 params[0] = mCaps.minAliasedLineWidth;
1248 params[1] = mCaps.maxAliasedLineWidth;
1249 break;
1250 case GL_ALIASED_POINT_SIZE_RANGE:
1251 params[0] = mCaps.minAliasedPointSize;
1252 params[1] = mCaps.maxAliasedPointSize;
1253 break;
1254 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1255 ASSERT(mExtensions.textureFilterAnisotropic);
1256 *params = mExtensions.maxTextureAnisotropy;
1257 break;
1258 case GL_MAX_TEXTURE_LOD_BIAS:
1259 *params = mCaps.maxLODBias;
1260 break;
1261
1262 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1263 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1264 {
1265 ASSERT(mExtensions.pathRendering);
1266 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1267 memcpy(params, m, 16 * sizeof(GLfloat));
1268 }
Geoff Lange6d4e122015-06-29 13:33:55 -04001269 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001270
Jamie Madill231c7f52017-04-26 13:45:37 -04001271 default:
1272 mGLState.getFloatv(pname, params);
1273 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001274 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001275}
1276
Jamie Madillc1d770e2017-04-13 17:31:24 -04001277void Context::getIntegervImpl(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001278{
Shannon Woods53a94a82014-06-24 15:20:36 -04001279 // Queries about context capabilities and maximums are answered by Context.
1280 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001281
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001282 switch (pname)
1283 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001284 case GL_MAX_VERTEX_ATTRIBS:
1285 *params = mCaps.maxVertexAttributes;
1286 break;
1287 case GL_MAX_VERTEX_UNIFORM_VECTORS:
1288 *params = mCaps.maxVertexUniformVectors;
1289 break;
1290 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
1291 *params = mCaps.maxVertexUniformComponents;
1292 break;
1293 case GL_MAX_VARYING_VECTORS:
1294 *params = mCaps.maxVaryingVectors;
1295 break;
1296 case GL_MAX_VARYING_COMPONENTS:
1297 *params = mCaps.maxVertexOutputComponents;
1298 break;
1299 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1300 *params = mCaps.maxCombinedTextureImageUnits;
1301 break;
1302 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1303 *params = mCaps.maxVertexTextureImageUnits;
1304 break;
1305 case GL_MAX_TEXTURE_IMAGE_UNITS:
1306 *params = mCaps.maxTextureImageUnits;
1307 break;
1308 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1309 *params = mCaps.maxFragmentUniformVectors;
1310 break;
1311 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
1312 *params = mCaps.maxFragmentUniformComponents;
1313 break;
1314 case GL_MAX_RENDERBUFFER_SIZE:
1315 *params = mCaps.maxRenderbufferSize;
1316 break;
1317 case GL_MAX_COLOR_ATTACHMENTS_EXT:
1318 *params = mCaps.maxColorAttachments;
1319 break;
1320 case GL_MAX_DRAW_BUFFERS_EXT:
1321 *params = mCaps.maxDrawBuffers;
1322 break;
1323 // case GL_FRAMEBUFFER_BINDING: // now equivalent to
1324 // GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1325 case GL_SUBPIXEL_BITS:
1326 *params = 4;
1327 break;
1328 case GL_MAX_TEXTURE_SIZE:
1329 *params = mCaps.max2DTextureSize;
1330 break;
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001331 case GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE:
1332 *params = mCaps.maxRectangleTextureSize;
1333 break;
Jamie Madill231c7f52017-04-26 13:45:37 -04001334 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1335 *params = mCaps.maxCubeMapTextureSize;
1336 break;
1337 case GL_MAX_3D_TEXTURE_SIZE:
1338 *params = mCaps.max3DTextureSize;
1339 break;
1340 case GL_MAX_ARRAY_TEXTURE_LAYERS:
1341 *params = mCaps.maxArrayTextureLayers;
1342 break;
1343 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
1344 *params = mCaps.uniformBufferOffsetAlignment;
1345 break;
1346 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
1347 *params = mCaps.maxUniformBufferBindings;
1348 break;
1349 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
1350 *params = mCaps.maxVertexUniformBlocks;
1351 break;
1352 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
1353 *params = mCaps.maxFragmentUniformBlocks;
1354 break;
1355 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
1356 *params = mCaps.maxCombinedTextureImageUnits;
1357 break;
1358 case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
1359 *params = mCaps.maxVertexOutputComponents;
1360 break;
1361 case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
1362 *params = mCaps.maxFragmentInputComponents;
1363 break;
1364 case GL_MIN_PROGRAM_TEXEL_OFFSET:
1365 *params = mCaps.minProgramTexelOffset;
1366 break;
1367 case GL_MAX_PROGRAM_TEXEL_OFFSET:
1368 *params = mCaps.maxProgramTexelOffset;
1369 break;
1370 case GL_MAJOR_VERSION:
1371 *params = getClientVersion().major;
1372 break;
1373 case GL_MINOR_VERSION:
1374 *params = getClientVersion().minor;
1375 break;
1376 case GL_MAX_ELEMENTS_INDICES:
1377 *params = mCaps.maxElementsIndices;
1378 break;
1379 case GL_MAX_ELEMENTS_VERTICES:
1380 *params = mCaps.maxElementsVertices;
1381 break;
1382 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
1383 *params = mCaps.maxTransformFeedbackInterleavedComponents;
1384 break;
1385 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
1386 *params = mCaps.maxTransformFeedbackSeparateAttributes;
1387 break;
1388 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
1389 *params = mCaps.maxTransformFeedbackSeparateComponents;
1390 break;
1391 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1392 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1393 break;
1394 case GL_MAX_SAMPLES_ANGLE:
1395 *params = mCaps.maxSamples;
1396 break;
1397 case GL_MAX_VIEWPORT_DIMS:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001398 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001399 params[0] = mCaps.maxViewportWidth;
1400 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001401 }
1402 break;
Jamie Madill231c7f52017-04-26 13:45:37 -04001403 case GL_COMPRESSED_TEXTURE_FORMATS:
1404 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(),
1405 params);
1406 break;
1407 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1408 *params = mResetStrategy;
1409 break;
1410 case GL_NUM_SHADER_BINARY_FORMATS:
1411 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
1412 break;
1413 case GL_SHADER_BINARY_FORMATS:
1414 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1415 break;
1416 case GL_NUM_PROGRAM_BINARY_FORMATS:
1417 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
1418 break;
1419 case GL_PROGRAM_BINARY_FORMATS:
1420 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
1421 break;
1422 case GL_NUM_EXTENSIONS:
1423 *params = static_cast<GLint>(mExtensionStrings.size());
1424 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001425
Jamie Madill231c7f52017-04-26 13:45:37 -04001426 // GL_KHR_debug
1427 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1428 *params = mExtensions.maxDebugMessageLength;
1429 break;
1430 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1431 *params = mExtensions.maxDebugLoggedMessages;
1432 break;
1433 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1434 *params = mExtensions.maxDebugGroupStackDepth;
1435 break;
1436 case GL_MAX_LABEL_LENGTH:
1437 *params = mExtensions.maxLabelLength;
1438 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001439
Martin Radeve5285d22017-07-14 16:23:53 +03001440 // GL_ANGLE_multiview
1441 case GL_MAX_VIEWS_ANGLE:
1442 *params = mExtensions.maxViews;
1443 break;
1444
Jamie Madill231c7f52017-04-26 13:45:37 -04001445 // GL_EXT_disjoint_timer_query
1446 case GL_GPU_DISJOINT_EXT:
1447 *params = mImplementation->getGPUDisjoint();
1448 break;
1449 case GL_MAX_FRAMEBUFFER_WIDTH:
1450 *params = mCaps.maxFramebufferWidth;
1451 break;
1452 case GL_MAX_FRAMEBUFFER_HEIGHT:
1453 *params = mCaps.maxFramebufferHeight;
1454 break;
1455 case GL_MAX_FRAMEBUFFER_SAMPLES:
1456 *params = mCaps.maxFramebufferSamples;
1457 break;
1458 case GL_MAX_SAMPLE_MASK_WORDS:
1459 *params = mCaps.maxSampleMaskWords;
1460 break;
1461 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1462 *params = mCaps.maxColorTextureSamples;
1463 break;
1464 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1465 *params = mCaps.maxDepthTextureSamples;
1466 break;
1467 case GL_MAX_INTEGER_SAMPLES:
1468 *params = mCaps.maxIntegerSamples;
1469 break;
1470 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1471 *params = mCaps.maxVertexAttribRelativeOffset;
1472 break;
1473 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1474 *params = mCaps.maxVertexAttribBindings;
1475 break;
1476 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1477 *params = mCaps.maxVertexAttribStride;
1478 break;
1479 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1480 *params = mCaps.maxVertexAtomicCounterBuffers;
1481 break;
1482 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1483 *params = mCaps.maxVertexAtomicCounters;
1484 break;
1485 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1486 *params = mCaps.maxVertexImageUniforms;
1487 break;
1488 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1489 *params = mCaps.maxVertexShaderStorageBlocks;
1490 break;
1491 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1492 *params = mCaps.maxFragmentAtomicCounterBuffers;
1493 break;
1494 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1495 *params = mCaps.maxFragmentAtomicCounters;
1496 break;
1497 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1498 *params = mCaps.maxFragmentImageUniforms;
1499 break;
1500 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1501 *params = mCaps.maxFragmentShaderStorageBlocks;
1502 break;
1503 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1504 *params = mCaps.minProgramTextureGatherOffset;
1505 break;
1506 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1507 *params = mCaps.maxProgramTextureGatherOffset;
1508 break;
1509 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1510 *params = mCaps.maxComputeWorkGroupInvocations;
1511 break;
1512 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1513 *params = mCaps.maxComputeUniformBlocks;
1514 break;
1515 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1516 *params = mCaps.maxComputeTextureImageUnits;
1517 break;
1518 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1519 *params = mCaps.maxComputeSharedMemorySize;
1520 break;
1521 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1522 *params = mCaps.maxComputeUniformComponents;
1523 break;
1524 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1525 *params = mCaps.maxComputeAtomicCounterBuffers;
1526 break;
1527 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1528 *params = mCaps.maxComputeAtomicCounters;
1529 break;
1530 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1531 *params = mCaps.maxComputeImageUniforms;
1532 break;
1533 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1534 *params = mCaps.maxCombinedComputeUniformComponents;
1535 break;
1536 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1537 *params = mCaps.maxComputeShaderStorageBlocks;
1538 break;
1539 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1540 *params = mCaps.maxCombinedShaderOutputResources;
1541 break;
1542 case GL_MAX_UNIFORM_LOCATIONS:
1543 *params = mCaps.maxUniformLocations;
1544 break;
1545 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1546 *params = mCaps.maxAtomicCounterBufferBindings;
1547 break;
1548 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1549 *params = mCaps.maxAtomicCounterBufferSize;
1550 break;
1551 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1552 *params = mCaps.maxCombinedAtomicCounterBuffers;
1553 break;
1554 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1555 *params = mCaps.maxCombinedAtomicCounters;
1556 break;
1557 case GL_MAX_IMAGE_UNITS:
1558 *params = mCaps.maxImageUnits;
1559 break;
1560 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1561 *params = mCaps.maxCombinedImageUniforms;
1562 break;
1563 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1564 *params = mCaps.maxShaderStorageBufferBindings;
1565 break;
1566 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1567 *params = mCaps.maxCombinedShaderStorageBlocks;
1568 break;
1569 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1570 *params = mCaps.shaderStorageBufferOffsetAlignment;
1571 break;
1572 default:
1573 mGLState.getIntegerv(this, pname, params);
1574 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001575 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001576}
1577
Jamie Madill7f0c5a42017-08-26 22:43:26 -04001578void Context::getInteger64vImpl(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001579{
Shannon Woods53a94a82014-06-24 15:20:36 -04001580 // Queries about context capabilities and maximums are answered by Context.
1581 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001582 switch (pname)
1583 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001584 case GL_MAX_ELEMENT_INDEX:
1585 *params = mCaps.maxElementIndex;
1586 break;
1587 case GL_MAX_UNIFORM_BLOCK_SIZE:
1588 *params = mCaps.maxUniformBlockSize;
1589 break;
1590 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
1591 *params = mCaps.maxCombinedVertexUniformComponents;
1592 break;
1593 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
1594 *params = mCaps.maxCombinedFragmentUniformComponents;
1595 break;
1596 case GL_MAX_SERVER_WAIT_TIMEOUT:
1597 *params = mCaps.maxServerWaitTimeout;
1598 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001599
Jamie Madill231c7f52017-04-26 13:45:37 -04001600 // GL_EXT_disjoint_timer_query
1601 case GL_TIMESTAMP_EXT:
1602 *params = mImplementation->getTimestamp();
1603 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001604
Jamie Madill231c7f52017-04-26 13:45:37 -04001605 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1606 *params = mCaps.maxShaderStorageBlockSize;
1607 break;
1608 default:
1609 UNREACHABLE();
1610 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001611 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001612}
1613
Geoff Lang70d0f492015-12-10 17:45:46 -05001614void Context::getPointerv(GLenum pname, void **params) const
1615{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001616 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001617}
1618
Martin Radev66fb8202016-07-28 11:45:20 +03001619void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001620{
Shannon Woods53a94a82014-06-24 15:20:36 -04001621 // Queries about context capabilities and maximums are answered by Context.
1622 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001623
1624 GLenum nativeType;
1625 unsigned int numParams;
1626 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1627 ASSERT(queryStatus);
1628
1629 if (nativeType == GL_INT)
1630 {
1631 switch (target)
1632 {
1633 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1634 ASSERT(index < 3u);
1635 *data = mCaps.maxComputeWorkGroupCount[index];
1636 break;
1637 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1638 ASSERT(index < 3u);
1639 *data = mCaps.maxComputeWorkGroupSize[index];
1640 break;
1641 default:
1642 mGLState.getIntegeri_v(target, index, data);
1643 }
1644 }
1645 else
1646 {
1647 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1648 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001649}
1650
Martin Radev66fb8202016-07-28 11:45:20 +03001651void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001652{
Shannon Woods53a94a82014-06-24 15:20:36 -04001653 // Queries about context capabilities and maximums are answered by Context.
1654 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001655
1656 GLenum nativeType;
1657 unsigned int numParams;
1658 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1659 ASSERT(queryStatus);
1660
1661 if (nativeType == GL_INT_64_ANGLEX)
1662 {
1663 mGLState.getInteger64i_v(target, index, data);
1664 }
1665 else
1666 {
1667 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1668 }
1669}
1670
1671void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1672{
1673 // Queries about context capabilities and maximums are answered by Context.
1674 // Queries about current GL state values are answered by State.
1675
1676 GLenum nativeType;
1677 unsigned int numParams;
1678 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1679 ASSERT(queryStatus);
1680
1681 if (nativeType == GL_BOOL)
1682 {
1683 mGLState.getBooleani_v(target, index, data);
1684 }
1685 else
1686 {
1687 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1688 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001689}
1690
He Yunchao010e4db2017-03-03 14:22:06 +08001691void Context::getBufferParameteriv(GLenum target, GLenum pname, GLint *params)
1692{
1693 Buffer *buffer = mGLState.getTargetBuffer(target);
1694 QueryBufferParameteriv(buffer, pname, params);
1695}
1696
1697void Context::getFramebufferAttachmentParameteriv(GLenum target,
1698 GLenum attachment,
1699 GLenum pname,
1700 GLint *params)
1701{
1702 const Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
1703 QueryFramebufferAttachmentParameteriv(framebuffer, attachment, pname, params);
1704}
1705
1706void Context::getRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
1707{
1708 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
1709 QueryRenderbufferiv(this, renderbuffer, pname, params);
1710}
1711
1712void Context::getTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
1713{
1714 Texture *texture = getTargetTexture(target);
1715 QueryTexParameterfv(texture, pname, params);
1716}
1717
1718void Context::getTexParameteriv(GLenum target, GLenum pname, GLint *params)
1719{
1720 Texture *texture = getTargetTexture(target);
1721 QueryTexParameteriv(texture, pname, params);
1722}
1723void Context::texParameterf(GLenum target, GLenum pname, GLfloat param)
1724{
1725 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001726 SetTexParameterf(this, texture, pname, param);
Jamie Madill81c2e252017-09-09 23:32:46 -04001727 onTextureChange(texture);
He Yunchao010e4db2017-03-03 14:22:06 +08001728}
1729
1730void Context::texParameterfv(GLenum target, GLenum pname, const GLfloat *params)
1731{
1732 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001733 SetTexParameterfv(this, texture, pname, params);
Jamie Madill81c2e252017-09-09 23:32:46 -04001734 onTextureChange(texture);
He Yunchao010e4db2017-03-03 14:22:06 +08001735}
1736
1737void Context::texParameteri(GLenum target, GLenum pname, GLint param)
1738{
1739 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001740 SetTexParameteri(this, texture, pname, param);
Jamie Madill81c2e252017-09-09 23:32:46 -04001741 onTextureChange(texture);
He Yunchao010e4db2017-03-03 14:22:06 +08001742}
1743
1744void Context::texParameteriv(GLenum target, GLenum pname, const GLint *params)
1745{
1746 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001747 SetTexParameteriv(this, texture, pname, params);
Jamie Madill81c2e252017-09-09 23:32:46 -04001748 onTextureChange(texture);
He Yunchao010e4db2017-03-03 14:22:06 +08001749}
1750
Jamie Madill675fe712016-12-19 13:07:54 -05001751void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001752{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001753 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001754 ANGLE_CONTEXT_TRY(mImplementation->drawArrays(this, mode, first, count));
1755 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001756}
1757
Jamie Madill675fe712016-12-19 13:07:54 -05001758void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Geoff Langf6db0982015-08-25 13:04:00 -04001759{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001760 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001761 ANGLE_CONTEXT_TRY(
1762 mImplementation->drawArraysInstanced(this, mode, first, count, instanceCount));
1763 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Langf6db0982015-08-25 13:04:00 -04001764}
1765
Jamie Madill876429b2017-04-20 15:46:24 -04001766void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001767{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001768 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001769 ANGLE_CONTEXT_TRY(mImplementation->drawElements(this, mode, count, type, indices));
Geoff Langf6db0982015-08-25 13:04:00 -04001770}
1771
Jamie Madill675fe712016-12-19 13:07:54 -05001772void Context::drawElementsInstanced(GLenum mode,
1773 GLsizei count,
1774 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001775 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001776 GLsizei instances)
Geoff Langf6db0982015-08-25 13:04:00 -04001777{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001778 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001779 ANGLE_CONTEXT_TRY(
Qin Jiajia1da00652017-06-20 17:16:25 +08001780 mImplementation->drawElementsInstanced(this, mode, count, type, indices, instances));
Geoff Langf6db0982015-08-25 13:04:00 -04001781}
1782
Jamie Madill675fe712016-12-19 13:07:54 -05001783void Context::drawRangeElements(GLenum mode,
1784 GLuint start,
1785 GLuint end,
1786 GLsizei count,
1787 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001788 const void *indices)
Geoff Langf6db0982015-08-25 13:04:00 -04001789{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001790 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001791 ANGLE_CONTEXT_TRY(
1792 mImplementation->drawRangeElements(this, mode, start, end, count, type, indices));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001793}
1794
Jamie Madill876429b2017-04-20 15:46:24 -04001795void Context::drawArraysIndirect(GLenum mode, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001796{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001797 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001798 ANGLE_CONTEXT_TRY(mImplementation->drawArraysIndirect(this, mode, indirect));
Jiajia Qind9671222016-11-29 16:30:31 +08001799}
1800
Jamie Madill876429b2017-04-20 15:46:24 -04001801void Context::drawElementsIndirect(GLenum mode, GLenum type, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001802{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001803 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001804 ANGLE_CONTEXT_TRY(mImplementation->drawElementsIndirect(this, mode, type, indirect));
Jiajia Qind9671222016-11-29 16:30:31 +08001805}
1806
Jamie Madill675fe712016-12-19 13:07:54 -05001807void Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001808{
Jamie Madill675fe712016-12-19 13:07:54 -05001809 handleError(mImplementation->flush());
Geoff Lang129753a2015-01-09 16:52:09 -05001810}
1811
Jamie Madill675fe712016-12-19 13:07:54 -05001812void Context::finish()
Geoff Lang129753a2015-01-09 16:52:09 -05001813{
Jamie Madill675fe712016-12-19 13:07:54 -05001814 handleError(mImplementation->finish());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001815}
1816
Austin Kinross6ee1e782015-05-29 17:05:37 -07001817void Context::insertEventMarker(GLsizei length, const char *marker)
1818{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001819 ASSERT(mImplementation);
1820 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001821}
1822
1823void Context::pushGroupMarker(GLsizei length, const char *marker)
1824{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001825 ASSERT(mImplementation);
1826 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001827}
1828
1829void Context::popGroupMarker()
1830{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001831 ASSERT(mImplementation);
1832 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001833}
1834
Geoff Langd8605522016-04-13 10:19:12 -04001835void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1836{
1837 Program *programObject = getProgram(program);
1838 ASSERT(programObject);
1839
1840 programObject->bindUniformLocation(location, name);
1841}
1842
Sami Väisänena797e062016-05-12 15:23:40 +03001843void Context::setCoverageModulation(GLenum components)
1844{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001845 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001846}
1847
Sami Väisänene45e53b2016-05-25 10:36:04 +03001848void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1849{
1850 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1851}
1852
1853void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1854{
1855 GLfloat I[16];
1856 angle::Matrix<GLfloat>::setToIdentity(I);
1857
1858 mGLState.loadPathRenderingMatrix(matrixMode, I);
1859}
1860
1861void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1862{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001863 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001864 if (!pathObj)
1865 return;
1866
1867 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1868 syncRendererState();
1869
1870 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1871}
1872
1873void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1874{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001875 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001876 if (!pathObj)
1877 return;
1878
1879 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1880 syncRendererState();
1881
1882 mImplementation->stencilStrokePath(pathObj, reference, mask);
1883}
1884
1885void Context::coverFillPath(GLuint path, GLenum coverMode)
1886{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001887 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001888 if (!pathObj)
1889 return;
1890
1891 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1892 syncRendererState();
1893
1894 mImplementation->coverFillPath(pathObj, coverMode);
1895}
1896
1897void Context::coverStrokePath(GLuint path, GLenum coverMode)
1898{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001899 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001900 if (!pathObj)
1901 return;
1902
1903 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1904 syncRendererState();
1905
1906 mImplementation->coverStrokePath(pathObj, coverMode);
1907}
1908
1909void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1910{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001911 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001912 if (!pathObj)
1913 return;
1914
1915 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1916 syncRendererState();
1917
1918 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1919}
1920
1921void Context::stencilThenCoverStrokePath(GLuint path,
1922 GLint reference,
1923 GLuint mask,
1924 GLenum coverMode)
1925{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001926 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001927 if (!pathObj)
1928 return;
1929
1930 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1931 syncRendererState();
1932
1933 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1934}
1935
Sami Väisänend59ca052016-06-21 16:10:00 +03001936void Context::coverFillPathInstanced(GLsizei numPaths,
1937 GLenum pathNameType,
1938 const void *paths,
1939 GLuint pathBase,
1940 GLenum coverMode,
1941 GLenum transformType,
1942 const GLfloat *transformValues)
1943{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001944 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001945
1946 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1947 syncRendererState();
1948
1949 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1950}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001951
Sami Väisänend59ca052016-06-21 16:10:00 +03001952void Context::coverStrokePathInstanced(GLsizei numPaths,
1953 GLenum pathNameType,
1954 const void *paths,
1955 GLuint pathBase,
1956 GLenum coverMode,
1957 GLenum transformType,
1958 const GLfloat *transformValues)
1959{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001960 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001961
1962 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1963 syncRendererState();
1964
1965 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1966 transformValues);
1967}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001968
Sami Väisänend59ca052016-06-21 16:10:00 +03001969void Context::stencilFillPathInstanced(GLsizei numPaths,
1970 GLenum pathNameType,
1971 const void *paths,
1972 GLuint pathBase,
1973 GLenum fillMode,
1974 GLuint mask,
1975 GLenum transformType,
1976 const GLfloat *transformValues)
1977{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001978 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001979
1980 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1981 syncRendererState();
1982
1983 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1984 transformValues);
1985}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001986
Sami Väisänend59ca052016-06-21 16:10:00 +03001987void Context::stencilStrokePathInstanced(GLsizei numPaths,
1988 GLenum pathNameType,
1989 const void *paths,
1990 GLuint pathBase,
1991 GLint reference,
1992 GLuint mask,
1993 GLenum transformType,
1994 const GLfloat *transformValues)
1995{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001996 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001997
1998 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1999 syncRendererState();
2000
2001 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
2002 transformValues);
2003}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002004
Sami Väisänend59ca052016-06-21 16:10:00 +03002005void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
2006 GLenum pathNameType,
2007 const void *paths,
2008 GLuint pathBase,
2009 GLenum fillMode,
2010 GLuint mask,
2011 GLenum coverMode,
2012 GLenum transformType,
2013 const GLfloat *transformValues)
2014{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002015 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002016
2017 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2018 syncRendererState();
2019
2020 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
2021 transformType, transformValues);
2022}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002023
Sami Väisänend59ca052016-06-21 16:10:00 +03002024void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
2025 GLenum pathNameType,
2026 const void *paths,
2027 GLuint pathBase,
2028 GLint reference,
2029 GLuint mask,
2030 GLenum coverMode,
2031 GLenum transformType,
2032 const GLfloat *transformValues)
2033{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002034 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002035
2036 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2037 syncRendererState();
2038
2039 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
2040 transformType, transformValues);
2041}
2042
Sami Väisänen46eaa942016-06-29 10:26:37 +03002043void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
2044{
2045 auto *programObject = getProgram(program);
2046
2047 programObject->bindFragmentInputLocation(location, name);
2048}
2049
2050void Context::programPathFragmentInputGen(GLuint program,
2051 GLint location,
2052 GLenum genMode,
2053 GLint components,
2054 const GLfloat *coeffs)
2055{
2056 auto *programObject = getProgram(program);
2057
Jamie Madillbd044ed2017-06-05 12:59:21 -04002058 programObject->pathFragmentInputGen(this, location, genMode, components, coeffs);
Sami Väisänen46eaa942016-06-29 10:26:37 +03002059}
2060
jchen1015015f72017-03-16 13:54:21 +08002061GLuint Context::getProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name)
2062{
jchen10fd7c3b52017-03-21 15:36:03 +08002063 const auto *programObject = getProgram(program);
jchen1015015f72017-03-16 13:54:21 +08002064 return QueryProgramResourceIndex(programObject, programInterface, name);
2065}
2066
jchen10fd7c3b52017-03-21 15:36:03 +08002067void Context::getProgramResourceName(GLuint program,
2068 GLenum programInterface,
2069 GLuint index,
2070 GLsizei bufSize,
2071 GLsizei *length,
2072 GLchar *name)
2073{
2074 const auto *programObject = getProgram(program);
2075 QueryProgramResourceName(programObject, programInterface, index, bufSize, length, name);
2076}
2077
jchen10191381f2017-04-11 13:59:04 +08002078GLint Context::getProgramResourceLocation(GLuint program,
2079 GLenum programInterface,
2080 const GLchar *name)
2081{
2082 const auto *programObject = getProgram(program);
2083 return QueryProgramResourceLocation(programObject, programInterface, name);
2084}
2085
jchen10880683b2017-04-12 16:21:55 +08002086void Context::getProgramResourceiv(GLuint program,
2087 GLenum programInterface,
2088 GLuint index,
2089 GLsizei propCount,
2090 const GLenum *props,
2091 GLsizei bufSize,
2092 GLsizei *length,
2093 GLint *params)
2094{
2095 const auto *programObject = getProgram(program);
2096 QueryProgramResourceiv(programObject, programInterface, index, propCount, props, bufSize,
2097 length, params);
2098}
2099
jchen10d9cd7b72017-08-30 15:04:25 +08002100void Context::getProgramInterfaceiv(GLuint program,
2101 GLenum programInterface,
2102 GLenum pname,
2103 GLint *params)
2104{
2105 const auto *programObject = getProgram(program);
2106 QueryProgramInterfaceiv(programObject, programInterface, pname, params);
2107}
2108
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002109Error Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002110{
Geoff Langda5777c2014-07-11 09:52:58 -04002111 if (error.isError())
2112 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002113 GLenum code = error.getCode();
2114 mErrors.insert(code);
2115 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
2116 {
2117 markContextLost();
2118 }
Geoff Lang70d0f492015-12-10 17:45:46 -05002119
2120 if (!error.getMessage().empty())
2121 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002122 auto *debug = &mGLState.getDebug();
2123 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
2124 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05002125 }
Geoff Langda5777c2014-07-11 09:52:58 -04002126 }
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002127
2128 return error;
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 Madill4c19a8a2017-07-24 11:46:06 -04002772Error Context::prepareForDraw(GLenum drawMode)
Jamie Madillb6664922017-07-25 12:55:04 -04002773{
2774 syncRendererState();
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002775
2776 InfoLog infoLog;
2777 Error err = mImplementation->triggerDrawCallProgramRecompilation(this, &infoLog,
2778 mMemoryProgramCache, drawMode);
Jamie Madilla836b462017-08-16 14:58:35 -04002779 if (err.isError() || infoLog.getLength() > 0)
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002780 {
2781 WARN() << "Dynamic recompilation error log: " << infoLog.str();
2782 }
2783 return err;
Jamie Madillb6664922017-07-25 12:55:04 -04002784}
2785
Jamie Madill1b94d432015-08-07 13:23:23 -04002786void Context::syncRendererState()
2787{
Jamie Madill7d1f5c62017-09-02 15:32:15 -04002788 mGLState.syncDirtyObjects(this);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002789 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
Jamie Madillfe548342017-06-19 11:13:24 -04002790 mImplementation->syncState(this, dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002791 mGLState.clearDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -04002792}
2793
Jamie Madillad9f24e2016-02-12 09:27:24 -05002794void Context::syncRendererState(const State::DirtyBits &bitMask,
2795 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002796{
Jamie Madill7d1f5c62017-09-02 15:32:15 -04002797 mGLState.syncDirtyObjects(this, objectMask);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002798 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
Jamie Madillfe548342017-06-19 11:13:24 -04002799 mImplementation->syncState(this, dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002800 mGLState.clearDirtyBits(dirtyBits);
Jamie Madill1b94d432015-08-07 13:23:23 -04002801}
Jamie Madillc29968b2016-01-20 11:17:23 -05002802
2803void Context::blitFramebuffer(GLint srcX0,
2804 GLint srcY0,
2805 GLint srcX1,
2806 GLint srcY1,
2807 GLint dstX0,
2808 GLint dstY0,
2809 GLint dstX1,
2810 GLint dstY1,
2811 GLbitfield mask,
2812 GLenum filter)
2813{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002814 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002815 ASSERT(drawFramebuffer);
2816
2817 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2818 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2819
Jamie Madillad9f24e2016-02-12 09:27:24 -05002820 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002821
Jamie Madillc564c072017-06-01 12:45:42 -04002822 handleError(drawFramebuffer->blit(this, srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002823}
Jamie Madillc29968b2016-01-20 11:17:23 -05002824
2825void Context::clear(GLbitfield mask)
2826{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002827 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002828 handleError(mGLState.getDrawFramebuffer()->clear(this, mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002829}
2830
2831void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2832{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002833 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002834 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002835}
2836
2837void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2838{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002839 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002840 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002841}
2842
2843void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2844{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002845 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002846 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002847}
2848
2849void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2850{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002851 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002852 ASSERT(framebufferObject);
2853
2854 // If a buffer is not present, the clear has no effect
2855 if (framebufferObject->getDepthbuffer() == nullptr &&
2856 framebufferObject->getStencilbuffer() == nullptr)
2857 {
2858 return;
2859 }
2860
Jamie Madillad9f24e2016-02-12 09:27:24 -05002861 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002862 handleError(framebufferObject->clearBufferfi(this, buffer, drawbuffer, depth, stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002863}
2864
2865void Context::readPixels(GLint x,
2866 GLint y,
2867 GLsizei width,
2868 GLsizei height,
2869 GLenum format,
2870 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002871 void *pixels)
Jamie Madillc29968b2016-01-20 11:17:23 -05002872{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002873 if (width == 0 || height == 0)
2874 {
2875 return;
2876 }
2877
Jamie Madillad9f24e2016-02-12 09:27:24 -05002878 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002879
Jamie Madillb6664922017-07-25 12:55:04 -04002880 Framebuffer *readFBO = mGLState.getReadFramebuffer();
2881 ASSERT(readFBO);
Jamie Madillc29968b2016-01-20 11:17:23 -05002882
2883 Rectangle area(x, y, width, height);
Jamie Madillb6664922017-07-25 12:55:04 -04002884 handleError(readFBO->readPixels(this, area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002885}
2886
2887void Context::copyTexImage2D(GLenum target,
2888 GLint level,
2889 GLenum internalformat,
2890 GLint x,
2891 GLint y,
2892 GLsizei width,
2893 GLsizei height,
2894 GLint border)
2895{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002896 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002897 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002898
Jamie Madillc29968b2016-01-20 11:17:23 -05002899 Rectangle sourceArea(x, y, width, height);
2900
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002901 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002902 Texture *texture =
2903 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002904 handleError(texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002905}
2906
2907void Context::copyTexSubImage2D(GLenum target,
2908 GLint level,
2909 GLint xoffset,
2910 GLint yoffset,
2911 GLint x,
2912 GLint y,
2913 GLsizei width,
2914 GLsizei height)
2915{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002916 if (width == 0 || height == 0)
2917 {
2918 return;
2919 }
2920
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002921 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002922 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002923
Jamie Madillc29968b2016-01-20 11:17:23 -05002924 Offset destOffset(xoffset, yoffset, 0);
2925 Rectangle sourceArea(x, y, width, height);
2926
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002927 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002928 Texture *texture =
2929 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002930 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002931}
2932
2933void Context::copyTexSubImage3D(GLenum target,
2934 GLint level,
2935 GLint xoffset,
2936 GLint yoffset,
2937 GLint zoffset,
2938 GLint x,
2939 GLint y,
2940 GLsizei width,
2941 GLsizei height)
2942{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002943 if (width == 0 || height == 0)
2944 {
2945 return;
2946 }
2947
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002948 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002949 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002950
Jamie Madillc29968b2016-01-20 11:17:23 -05002951 Offset destOffset(xoffset, yoffset, zoffset);
2952 Rectangle sourceArea(x, y, width, height);
2953
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002954 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002955 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002956 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002957}
2958
2959void Context::framebufferTexture2D(GLenum target,
2960 GLenum attachment,
2961 GLenum textarget,
2962 GLuint texture,
2963 GLint level)
2964{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002965 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002966 ASSERT(framebuffer);
2967
2968 if (texture != 0)
2969 {
2970 Texture *textureObj = getTexture(texture);
2971
2972 ImageIndex index = ImageIndex::MakeInvalid();
2973
2974 if (textarget == GL_TEXTURE_2D)
2975 {
2976 index = ImageIndex::Make2D(level);
2977 }
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002978 else if (textarget == GL_TEXTURE_RECTANGLE_ANGLE)
2979 {
2980 index = ImageIndex::MakeRectangle(level);
2981 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08002982 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
2983 {
2984 ASSERT(level == 0);
2985 index = ImageIndex::Make2DMultisample();
2986 }
Jamie Madillc29968b2016-01-20 11:17:23 -05002987 else
2988 {
2989 ASSERT(IsCubeMapTextureTarget(textarget));
2990 index = ImageIndex::MakeCube(textarget, level);
2991 }
2992
Jamie Madilla02315b2017-02-23 14:14:47 -05002993 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
Jamie Madillc29968b2016-01-20 11:17:23 -05002994 }
2995 else
2996 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002997 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002998 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002999
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003000 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003001}
3002
3003void Context::framebufferRenderbuffer(GLenum target,
3004 GLenum attachment,
3005 GLenum renderbuffertarget,
3006 GLuint renderbuffer)
3007{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003008 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003009 ASSERT(framebuffer);
3010
3011 if (renderbuffer != 0)
3012 {
3013 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
Jamie Madilla02315b2017-02-23 14:14:47 -05003014
3015 framebuffer->setAttachment(this, GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
Jamie Madillc29968b2016-01-20 11:17:23 -05003016 renderbufferObject);
3017 }
3018 else
3019 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003020 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003021 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003022
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003023 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003024}
3025
3026void Context::framebufferTextureLayer(GLenum target,
3027 GLenum attachment,
3028 GLuint texture,
3029 GLint level,
3030 GLint layer)
3031{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003032 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003033 ASSERT(framebuffer);
3034
3035 if (texture != 0)
3036 {
3037 Texture *textureObject = getTexture(texture);
3038
3039 ImageIndex index = ImageIndex::MakeInvalid();
3040
3041 if (textureObject->getTarget() == GL_TEXTURE_3D)
3042 {
3043 index = ImageIndex::Make3D(level, layer);
3044 }
3045 else
3046 {
3047 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
3048 index = ImageIndex::Make2DArray(level, layer);
3049 }
3050
Jamie Madilla02315b2017-02-23 14:14:47 -05003051 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObject);
Jamie Madillc29968b2016-01-20 11:17:23 -05003052 }
3053 else
3054 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003055 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003056 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003057
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003058 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003059}
3060
Martin Radev137032d2017-07-13 10:11:12 +03003061void Context::framebufferTextureMultiviewLayeredANGLE(GLenum target,
3062 GLenum attachment,
3063 GLuint texture,
3064 GLint level,
3065 GLint baseViewIndex,
3066 GLsizei numViews)
3067{
Martin Radev82ef7742017-08-08 17:44:58 +03003068 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
3069 ASSERT(framebuffer);
3070
3071 if (texture != 0)
3072 {
3073 Texture *textureObj = getTexture(texture);
3074
Martin Radev18b75ba2017-08-15 15:50:40 +03003075 ImageIndex index = ImageIndex::Make2DArrayRange(level, baseViewIndex, numViews);
Martin Radev82ef7742017-08-08 17:44:58 +03003076 framebuffer->setAttachmentMultiviewLayered(this, GL_TEXTURE, attachment, index, textureObj,
3077 numViews, baseViewIndex);
3078 }
3079 else
3080 {
3081 framebuffer->resetAttachment(this, attachment);
3082 }
3083
3084 mGLState.setObjectDirty(target);
Martin Radev137032d2017-07-13 10:11:12 +03003085}
3086
3087void Context::framebufferTextureMultiviewSideBySideANGLE(GLenum target,
3088 GLenum attachment,
3089 GLuint texture,
3090 GLint level,
3091 GLsizei numViews,
3092 const GLint *viewportOffsets)
3093{
Martin Radev5dae57b2017-07-14 16:15:55 +03003094 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
3095 ASSERT(framebuffer);
3096
3097 if (texture != 0)
3098 {
3099 Texture *textureObj = getTexture(texture);
3100
3101 ImageIndex index = ImageIndex::Make2D(level);
3102 framebuffer->setAttachmentMultiviewSideBySide(this, GL_TEXTURE, attachment, index,
3103 textureObj, numViews, viewportOffsets);
3104 }
3105 else
3106 {
3107 framebuffer->resetAttachment(this, attachment);
3108 }
3109
3110 mGLState.setObjectDirty(target);
Martin Radev137032d2017-07-13 10:11:12 +03003111}
3112
Jamie Madillc29968b2016-01-20 11:17:23 -05003113void Context::drawBuffers(GLsizei n, const GLenum *bufs)
3114{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003115 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003116 ASSERT(framebuffer);
3117 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003118 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003119}
3120
3121void Context::readBuffer(GLenum mode)
3122{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003123 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003124 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003125 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003126}
3127
3128void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
3129{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003130 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003131 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003132
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003133 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003134 ASSERT(framebuffer);
3135
3136 // The specification isn't clear what should be done when the framebuffer isn't complete.
3137 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill4928b7c2017-06-20 12:57:39 -04003138 handleError(framebuffer->discard(this, numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003139}
3140
3141void Context::invalidateFramebuffer(GLenum target,
3142 GLsizei numAttachments,
3143 const GLenum *attachments)
3144{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003145 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003146 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003147
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003148 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003149 ASSERT(framebuffer);
3150
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003151 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003152 {
Jamie Madill437fa652016-05-03 15:13:24 -04003153 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003154 }
Jamie Madill437fa652016-05-03 15:13:24 -04003155
Jamie Madill4928b7c2017-06-20 12:57:39 -04003156 handleError(framebuffer->invalidate(this, numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003157}
3158
3159void Context::invalidateSubFramebuffer(GLenum target,
3160 GLsizei numAttachments,
3161 const GLenum *attachments,
3162 GLint x,
3163 GLint y,
3164 GLsizei width,
3165 GLsizei height)
3166{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003167 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003168 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003169
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003170 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003171 ASSERT(framebuffer);
3172
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003173 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003174 {
Jamie Madill437fa652016-05-03 15:13:24 -04003175 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003176 }
Jamie Madill437fa652016-05-03 15:13:24 -04003177
3178 Rectangle area(x, y, width, height);
Jamie Madill4928b7c2017-06-20 12:57:39 -04003179 handleError(framebuffer->invalidateSub(this, numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05003180}
3181
Jamie Madill73a84962016-02-12 09:27:23 -05003182void Context::texImage2D(GLenum target,
3183 GLint level,
3184 GLint internalformat,
3185 GLsizei width,
3186 GLsizei height,
3187 GLint border,
3188 GLenum format,
3189 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003190 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003191{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003192 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003193
3194 Extents size(width, height, 1);
3195 Texture *texture =
3196 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003197 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3198 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003199}
3200
3201void Context::texImage3D(GLenum target,
3202 GLint level,
3203 GLint internalformat,
3204 GLsizei width,
3205 GLsizei height,
3206 GLsizei depth,
3207 GLint border,
3208 GLenum format,
3209 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003210 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003211{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003212 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003213
3214 Extents size(width, height, depth);
3215 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003216 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3217 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003218}
3219
3220void Context::texSubImage2D(GLenum target,
3221 GLint level,
3222 GLint xoffset,
3223 GLint yoffset,
3224 GLsizei width,
3225 GLsizei height,
3226 GLenum format,
3227 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003228 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003229{
3230 // Zero sized uploads are valid but no-ops
3231 if (width == 0 || height == 0)
3232 {
3233 return;
3234 }
3235
Jamie Madillad9f24e2016-02-12 09:27:24 -05003236 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003237
3238 Box area(xoffset, yoffset, 0, width, height, 1);
3239 Texture *texture =
3240 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003241 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3242 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003243}
3244
3245void Context::texSubImage3D(GLenum target,
3246 GLint level,
3247 GLint xoffset,
3248 GLint yoffset,
3249 GLint zoffset,
3250 GLsizei width,
3251 GLsizei height,
3252 GLsizei depth,
3253 GLenum format,
3254 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003255 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003256{
3257 // Zero sized uploads are valid but no-ops
3258 if (width == 0 || height == 0 || depth == 0)
3259 {
3260 return;
3261 }
3262
Jamie Madillad9f24e2016-02-12 09:27:24 -05003263 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003264
3265 Box area(xoffset, yoffset, zoffset, width, height, depth);
3266 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003267 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3268 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003269}
3270
3271void Context::compressedTexImage2D(GLenum target,
3272 GLint level,
3273 GLenum internalformat,
3274 GLsizei width,
3275 GLsizei height,
3276 GLint border,
3277 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003278 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003279{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003280 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003281
3282 Extents size(width, height, 1);
3283 Texture *texture =
3284 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003285 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003286 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003287 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003288}
3289
3290void Context::compressedTexImage3D(GLenum target,
3291 GLint level,
3292 GLenum internalformat,
3293 GLsizei width,
3294 GLsizei height,
3295 GLsizei depth,
3296 GLint border,
3297 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003298 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003299{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003300 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003301
3302 Extents size(width, height, depth);
3303 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003304 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003305 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003306 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003307}
3308
3309void Context::compressedTexSubImage2D(GLenum target,
3310 GLint level,
3311 GLint xoffset,
3312 GLint yoffset,
3313 GLsizei width,
3314 GLsizei height,
3315 GLenum format,
3316 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003317 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003318{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003319 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003320
3321 Box area(xoffset, yoffset, 0, width, height, 1);
3322 Texture *texture =
3323 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003324 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003325 format, imageSize,
3326 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003327}
3328
3329void Context::compressedTexSubImage3D(GLenum target,
3330 GLint level,
3331 GLint xoffset,
3332 GLint yoffset,
3333 GLint zoffset,
3334 GLsizei width,
3335 GLsizei height,
3336 GLsizei depth,
3337 GLenum format,
3338 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003339 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003340{
3341 // Zero sized uploads are valid but no-ops
3342 if (width == 0 || height == 0)
3343 {
3344 return;
3345 }
3346
Jamie Madillad9f24e2016-02-12 09:27:24 -05003347 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003348
3349 Box area(xoffset, yoffset, zoffset, width, height, depth);
3350 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003351 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003352 format, imageSize,
3353 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003354}
3355
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003356void Context::generateMipmap(GLenum target)
3357{
3358 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003359 handleError(texture->generateMipmap(this));
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003360}
3361
Geoff Lang97073d12016-04-20 10:42:34 -07003362void Context::copyTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003363 GLint sourceLevel,
3364 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003365 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003366 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003367 GLint internalFormat,
3368 GLenum destType,
3369 GLboolean unpackFlipY,
3370 GLboolean unpackPremultiplyAlpha,
3371 GLboolean unpackUnmultiplyAlpha)
3372{
3373 syncStateForTexImage();
3374
3375 gl::Texture *sourceTexture = getTexture(sourceId);
3376 gl::Texture *destTexture = getTexture(destId);
Geoff Langfc72a072017-03-24 14:52:39 -04003377 handleError(destTexture->copyTexture(
3378 this, destTarget, destLevel, internalFormat, destType, sourceLevel, unpackFlipY == GL_TRUE,
3379 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003380}
3381
3382void Context::copySubTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003383 GLint sourceLevel,
3384 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003385 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003386 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003387 GLint xoffset,
3388 GLint yoffset,
3389 GLint x,
3390 GLint y,
3391 GLsizei width,
3392 GLsizei height,
3393 GLboolean unpackFlipY,
3394 GLboolean unpackPremultiplyAlpha,
3395 GLboolean unpackUnmultiplyAlpha)
3396{
3397 // Zero sized copies are valid but no-ops
3398 if (width == 0 || height == 0)
3399 {
3400 return;
3401 }
3402
3403 syncStateForTexImage();
3404
3405 gl::Texture *sourceTexture = getTexture(sourceId);
3406 gl::Texture *destTexture = getTexture(destId);
3407 Offset offset(xoffset, yoffset, 0);
3408 Rectangle area(x, y, width, height);
Geoff Langfc72a072017-03-24 14:52:39 -04003409 handleError(destTexture->copySubTexture(
3410 this, destTarget, destLevel, offset, sourceLevel, area, unpackFlipY == GL_TRUE,
3411 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003412}
3413
Geoff Lang47110bf2016-04-20 11:13:22 -07003414void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3415{
3416 syncStateForTexImage();
3417
3418 gl::Texture *sourceTexture = getTexture(sourceId);
3419 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003420 handleError(destTexture->copyCompressedTexture(this, sourceTexture));
Geoff Lang47110bf2016-04-20 11:13:22 -07003421}
3422
Geoff Lang496c02d2016-10-20 11:38:11 -07003423void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003424{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003425 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003426 ASSERT(buffer);
3427
Geoff Lang496c02d2016-10-20 11:38:11 -07003428 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003429}
3430
Jamie Madill876429b2017-04-20 15:46:24 -04003431void *Context::mapBuffer(GLenum target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003432{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003433 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003434 ASSERT(buffer);
3435
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003436 Error error = buffer->map(this, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003437 if (error.isError())
3438 {
Jamie Madill437fa652016-05-03 15:13:24 -04003439 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003440 return nullptr;
3441 }
3442
3443 return buffer->getMapPointer();
3444}
3445
3446GLboolean Context::unmapBuffer(GLenum target)
3447{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003448 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003449 ASSERT(buffer);
3450
3451 GLboolean result;
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003452 Error error = buffer->unmap(this, &result);
Olli Etuaho4f667482016-03-30 15:56:35 +03003453 if (error.isError())
3454 {
Jamie Madill437fa652016-05-03 15:13:24 -04003455 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003456 return GL_FALSE;
3457 }
3458
3459 return result;
3460}
3461
Jamie Madill876429b2017-04-20 15:46:24 -04003462void *Context::mapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003463{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003464 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003465 ASSERT(buffer);
3466
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003467 Error error = buffer->mapRange(this, offset, length, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003468 if (error.isError())
3469 {
Jamie Madill437fa652016-05-03 15:13:24 -04003470 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003471 return nullptr;
3472 }
3473
3474 return buffer->getMapPointer();
3475}
3476
3477void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3478{
3479 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3480}
3481
Jamie Madillad9f24e2016-02-12 09:27:24 -05003482void Context::syncStateForReadPixels()
3483{
3484 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3485}
3486
3487void Context::syncStateForTexImage()
3488{
3489 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3490}
3491
3492void Context::syncStateForClear()
3493{
3494 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3495}
3496
3497void Context::syncStateForBlit()
3498{
3499 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3500}
3501
Jamie Madillc20ab272016-06-09 07:20:46 -07003502void Context::activeTexture(GLenum texture)
3503{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003504 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003505}
3506
Jamie Madill876429b2017-04-20 15:46:24 -04003507void Context::blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003508{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003509 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003510}
3511
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003512void Context::blendEquation(GLenum mode)
3513{
3514 mGLState.setBlendEquation(mode, mode);
3515}
3516
Jamie Madillc20ab272016-06-09 07:20:46 -07003517void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3518{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003519 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003520}
3521
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003522void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3523{
3524 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3525}
3526
Jamie Madillc20ab272016-06-09 07:20:46 -07003527void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3528{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003529 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003530}
3531
Jamie Madill876429b2017-04-20 15:46:24 -04003532void Context::clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003533{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003534 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003535}
3536
Jamie Madill876429b2017-04-20 15:46:24 -04003537void Context::clearDepthf(GLfloat depth)
Jamie Madillc20ab272016-06-09 07:20:46 -07003538{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003539 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003540}
3541
3542void Context::clearStencil(GLint s)
3543{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003544 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003545}
3546
3547void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3548{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003549 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003550}
3551
3552void Context::cullFace(GLenum mode)
3553{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003554 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003555}
3556
3557void Context::depthFunc(GLenum func)
3558{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003559 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003560}
3561
3562void Context::depthMask(GLboolean flag)
3563{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003564 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003565}
3566
Jamie Madill876429b2017-04-20 15:46:24 -04003567void Context::depthRangef(GLfloat zNear, GLfloat zFar)
Jamie Madillc20ab272016-06-09 07:20:46 -07003568{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003569 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003570}
3571
3572void Context::disable(GLenum cap)
3573{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003574 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003575}
3576
3577void Context::disableVertexAttribArray(GLuint index)
3578{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003579 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003580}
3581
3582void Context::enable(GLenum cap)
3583{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003584 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003585}
3586
3587void Context::enableVertexAttribArray(GLuint index)
3588{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003589 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003590}
3591
3592void Context::frontFace(GLenum mode)
3593{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003594 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003595}
3596
3597void Context::hint(GLenum target, GLenum mode)
3598{
3599 switch (target)
3600 {
3601 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003602 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003603 break;
3604
3605 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003606 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003607 break;
3608
3609 default:
3610 UNREACHABLE();
3611 return;
3612 }
3613}
3614
3615void Context::lineWidth(GLfloat width)
3616{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003617 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003618}
3619
3620void Context::pixelStorei(GLenum pname, GLint param)
3621{
3622 switch (pname)
3623 {
3624 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003625 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003626 break;
3627
3628 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003629 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003630 break;
3631
3632 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003633 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003634 break;
3635
3636 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003637 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003638 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003639 break;
3640
3641 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003642 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003643 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003644 break;
3645
3646 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003647 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003648 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003649 break;
3650
3651 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003652 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003653 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003654 break;
3655
3656 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003657 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003658 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003659 break;
3660
3661 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003662 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003663 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003664 break;
3665
3666 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003667 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003668 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003669 break;
3670
3671 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003672 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003673 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003674 break;
3675
3676 default:
3677 UNREACHABLE();
3678 return;
3679 }
3680}
3681
3682void Context::polygonOffset(GLfloat factor, GLfloat units)
3683{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003684 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003685}
3686
Jamie Madill876429b2017-04-20 15:46:24 -04003687void Context::sampleCoverage(GLfloat value, GLboolean invert)
Jamie Madillc20ab272016-06-09 07:20:46 -07003688{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003689 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003690}
3691
3692void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3693{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003694 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003695}
3696
3697void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3698{
3699 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3700 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003701 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003702 }
3703
3704 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3705 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003706 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003707 }
3708}
3709
3710void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3711{
3712 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3713 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003714 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003715 }
3716
3717 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3718 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003719 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003720 }
3721}
3722
3723void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3724{
3725 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3726 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003727 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003728 }
3729
3730 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3731 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003732 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003733 }
3734}
3735
3736void Context::vertexAttrib1f(GLuint index, GLfloat x)
3737{
3738 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003739 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003740}
3741
3742void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3743{
3744 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003745 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003746}
3747
3748void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3749{
3750 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003751 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003752}
3753
3754void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3755{
3756 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003757 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003758}
3759
3760void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3761{
3762 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003763 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003764}
3765
3766void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3767{
3768 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003769 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003770}
3771
3772void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3773{
3774 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003775 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003776}
3777
3778void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3779{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003780 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003781}
3782
3783void Context::vertexAttribPointer(GLuint index,
3784 GLint size,
3785 GLenum type,
3786 GLboolean normalized,
3787 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003788 const void *ptr)
Jamie Madillc20ab272016-06-09 07:20:46 -07003789{
Shaodde78e82017-05-22 14:13:27 +08003790 mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size,
3791 type, normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003792}
3793
Shao80957d92017-02-20 21:25:59 +08003794void Context::vertexAttribFormat(GLuint attribIndex,
3795 GLint size,
3796 GLenum type,
3797 GLboolean normalized,
3798 GLuint relativeOffset)
3799{
3800 mGLState.setVertexAttribFormat(attribIndex, size, type, normalized == GL_TRUE, false,
3801 relativeOffset);
3802}
3803
3804void Context::vertexAttribIFormat(GLuint attribIndex,
3805 GLint size,
3806 GLenum type,
3807 GLuint relativeOffset)
3808{
3809 mGLState.setVertexAttribFormat(attribIndex, size, type, false, true, relativeOffset);
3810}
3811
3812void Context::vertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
3813{
Shaodde78e82017-05-22 14:13:27 +08003814 mGLState.setVertexAttribBinding(this, attribIndex, bindingIndex);
Shao80957d92017-02-20 21:25:59 +08003815}
3816
3817void Context::setVertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
3818{
3819 mGLState.setVertexBindingDivisor(bindingIndex, divisor);
3820}
3821
Jamie Madillc20ab272016-06-09 07:20:46 -07003822void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3823{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003824 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003825}
3826
3827void Context::vertexAttribIPointer(GLuint index,
3828 GLint size,
3829 GLenum type,
3830 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003831 const void *pointer)
Jamie Madillc20ab272016-06-09 07:20:46 -07003832{
Shaodde78e82017-05-22 14:13:27 +08003833 mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size,
3834 type, false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003835}
3836
3837void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3838{
3839 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003840 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003841}
3842
3843void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3844{
3845 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003846 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003847}
3848
3849void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3850{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003851 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003852}
3853
3854void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3855{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003856 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003857}
3858
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003859void Context::getVertexAttribiv(GLuint index, GLenum pname, GLint *params)
3860{
3861 const VertexAttribCurrentValueData &currentValues =
3862 getGLState().getVertexAttribCurrentValue(index);
3863 const VertexArray *vao = getGLState().getVertexArray();
3864 QueryVertexAttribiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3865 currentValues, pname, params);
3866}
3867
3868void Context::getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
3869{
3870 const VertexAttribCurrentValueData &currentValues =
3871 getGLState().getVertexAttribCurrentValue(index);
3872 const VertexArray *vao = getGLState().getVertexArray();
3873 QueryVertexAttribfv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3874 currentValues, pname, params);
3875}
3876
3877void Context::getVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
3878{
3879 const VertexAttribCurrentValueData &currentValues =
3880 getGLState().getVertexAttribCurrentValue(index);
3881 const VertexArray *vao = getGLState().getVertexArray();
3882 QueryVertexAttribIiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3883 currentValues, pname, params);
3884}
3885
3886void Context::getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
3887{
3888 const VertexAttribCurrentValueData &currentValues =
3889 getGLState().getVertexAttribCurrentValue(index);
3890 const VertexArray *vao = getGLState().getVertexArray();
3891 QueryVertexAttribIuiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3892 currentValues, pname, params);
3893}
3894
Jamie Madill876429b2017-04-20 15:46:24 -04003895void Context::getVertexAttribPointerv(GLuint index, GLenum pname, void **pointer)
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003896{
3897 const VertexAttribute &attrib = getGLState().getVertexArray()->getVertexAttribute(index);
3898 QueryVertexAttribPointerv(attrib, pname, pointer);
3899}
3900
Jamie Madillc20ab272016-06-09 07:20:46 -07003901void Context::debugMessageControl(GLenum source,
3902 GLenum type,
3903 GLenum severity,
3904 GLsizei count,
3905 const GLuint *ids,
3906 GLboolean enabled)
3907{
3908 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003909 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3910 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003911}
3912
3913void Context::debugMessageInsert(GLenum source,
3914 GLenum type,
3915 GLuint id,
3916 GLenum severity,
3917 GLsizei length,
3918 const GLchar *buf)
3919{
3920 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003921 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003922}
3923
3924void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3925{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003926 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003927}
3928
3929GLuint Context::getDebugMessageLog(GLuint count,
3930 GLsizei bufSize,
3931 GLenum *sources,
3932 GLenum *types,
3933 GLuint *ids,
3934 GLenum *severities,
3935 GLsizei *lengths,
3936 GLchar *messageLog)
3937{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003938 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3939 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003940}
3941
3942void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3943{
3944 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003945 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003946}
3947
3948void Context::popDebugGroup()
3949{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003950 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003951}
3952
Jamie Madill876429b2017-04-20 15:46:24 -04003953void Context::bufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage)
Jamie Madill29639852016-09-02 15:00:09 -04003954{
3955 Buffer *buffer = mGLState.getTargetBuffer(target);
3956 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003957 handleError(buffer->bufferData(this, target, data, size, usage));
Jamie Madill29639852016-09-02 15:00:09 -04003958}
3959
Jamie Madill876429b2017-04-20 15:46:24 -04003960void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04003961{
3962 if (data == nullptr)
3963 {
3964 return;
3965 }
3966
3967 Buffer *buffer = mGLState.getTargetBuffer(target);
3968 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003969 handleError(buffer->bufferSubData(this, target, data, size, offset));
Jamie Madill29639852016-09-02 15:00:09 -04003970}
3971
Jamie Madillef300b12016-10-07 15:12:09 -04003972void Context::attachShader(GLuint program, GLuint shader)
3973{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003974 auto programObject = mState.mShaderPrograms->getProgram(program);
3975 auto shaderObject = mState.mShaderPrograms->getShader(shader);
Jamie Madillef300b12016-10-07 15:12:09 -04003976 ASSERT(programObject && shaderObject);
3977 programObject->attachShader(shaderObject);
3978}
3979
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003980const Workarounds &Context::getWorkarounds() const
3981{
3982 return mWorkarounds;
3983}
3984
Jamie Madillb0817d12016-11-01 15:48:31 -04003985void Context::copyBufferSubData(GLenum readTarget,
3986 GLenum writeTarget,
3987 GLintptr readOffset,
3988 GLintptr writeOffset,
3989 GLsizeiptr size)
3990{
3991 // if size is zero, the copy is a successful no-op
3992 if (size == 0)
3993 {
3994 return;
3995 }
3996
3997 // TODO(jmadill): cache these.
3998 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3999 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
4000
Jamie Madill5f56ddb2017-01-13 17:29:55 -05004001 handleError(writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size));
Jamie Madillb0817d12016-11-01 15:48:31 -04004002}
4003
Jamie Madill01a80ee2016-11-07 12:06:18 -05004004void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
4005{
4006 Program *programObject = getProgram(program);
4007 // TODO(jmadill): Re-use this from the validation if possible.
4008 ASSERT(programObject);
4009 programObject->bindAttributeLocation(index, name);
4010}
4011
4012void Context::bindBuffer(GLenum target, GLuint buffer)
4013{
4014 switch (target)
4015 {
4016 case GL_ARRAY_BUFFER:
4017 bindArrayBuffer(buffer);
4018 break;
4019 case GL_ELEMENT_ARRAY_BUFFER:
4020 bindElementArrayBuffer(buffer);
4021 break;
4022 case GL_COPY_READ_BUFFER:
4023 bindCopyReadBuffer(buffer);
4024 break;
4025 case GL_COPY_WRITE_BUFFER:
4026 bindCopyWriteBuffer(buffer);
4027 break;
4028 case GL_PIXEL_PACK_BUFFER:
4029 bindPixelPackBuffer(buffer);
4030 break;
4031 case GL_PIXEL_UNPACK_BUFFER:
4032 bindPixelUnpackBuffer(buffer);
4033 break;
4034 case GL_UNIFORM_BUFFER:
4035 bindGenericUniformBuffer(buffer);
4036 break;
4037 case GL_TRANSFORM_FEEDBACK_BUFFER:
4038 bindGenericTransformFeedbackBuffer(buffer);
4039 break;
Geoff Lang3b573612016-10-31 14:08:10 -04004040 case GL_ATOMIC_COUNTER_BUFFER:
Jiajia Qin6eafb042016-12-27 17:04:07 +08004041 bindGenericAtomicCounterBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004042 break;
4043 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08004044 bindGenericShaderStorageBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004045 break;
4046 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08004047 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004048 break;
4049 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05004050 if (buffer != 0)
4051 {
4052 // Binding buffers to this binding point is not implemented yet.
4053 UNIMPLEMENTED();
4054 }
Geoff Lang3b573612016-10-31 14:08:10 -04004055 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05004056
4057 default:
4058 UNREACHABLE();
4059 break;
4060 }
4061}
4062
Jiajia Qin6eafb042016-12-27 17:04:07 +08004063void Context::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
4064{
4065 bindBufferRange(target, index, buffer, 0, 0);
4066}
4067
4068void Context::bindBufferRange(GLenum target,
4069 GLuint index,
4070 GLuint buffer,
4071 GLintptr offset,
4072 GLsizeiptr size)
4073{
4074 switch (target)
4075 {
4076 case GL_TRANSFORM_FEEDBACK_BUFFER:
4077 bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
4078 bindGenericTransformFeedbackBuffer(buffer);
4079 break;
4080 case GL_UNIFORM_BUFFER:
4081 bindIndexedUniformBuffer(buffer, index, offset, size);
4082 bindGenericUniformBuffer(buffer);
4083 break;
4084 case GL_ATOMIC_COUNTER_BUFFER:
4085 bindIndexedAtomicCounterBuffer(buffer, index, offset, size);
4086 bindGenericAtomicCounterBuffer(buffer);
4087 break;
4088 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08004089 bindIndexedShaderStorageBuffer(buffer, index, offset, size);
4090 bindGenericShaderStorageBuffer(buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08004091 break;
4092 default:
4093 UNREACHABLE();
4094 break;
4095 }
4096}
4097
Jamie Madill01a80ee2016-11-07 12:06:18 -05004098void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
4099{
4100 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4101 {
4102 bindReadFramebuffer(framebuffer);
4103 }
4104
4105 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4106 {
4107 bindDrawFramebuffer(framebuffer);
4108 }
4109}
4110
4111void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
4112{
4113 ASSERT(target == GL_RENDERBUFFER);
4114 Renderbuffer *object =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05004115 mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
Jamie Madill4928b7c2017-06-20 12:57:39 -04004116 mGLState.setRenderbufferBinding(this, object);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004117}
4118
JiangYizhoubddc46b2016-12-09 09:50:51 +08004119void Context::texStorage2DMultisample(GLenum target,
4120 GLsizei samples,
4121 GLenum internalformat,
4122 GLsizei width,
4123 GLsizei height,
4124 GLboolean fixedsamplelocations)
4125{
4126 Extents size(width, height, 1);
4127 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05004128 handleError(texture->setStorageMultisample(this, target, samples, internalformat, size,
JiangYizhoubddc46b2016-12-09 09:50:51 +08004129 fixedsamplelocations));
4130}
4131
4132void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
4133{
JiangYizhou5b03f472017-01-09 10:22:53 +08004134 // According to spec 3.1 Table 20.49: Framebuffer Dependent Values,
4135 // the sample position should be queried by DRAW_FRAMEBUFFER.
4136 mGLState.syncDirtyObject(this, GL_DRAW_FRAMEBUFFER);
4137 const Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
JiangYizhoubddc46b2016-12-09 09:50:51 +08004138
4139 switch (pname)
4140 {
4141 case GL_SAMPLE_POSITION:
4142 handleError(framebuffer->getSamplePosition(index, val));
4143 break;
4144 default:
4145 UNREACHABLE();
4146 }
4147}
4148
Jamie Madille8fb6402017-02-14 17:56:40 -05004149void Context::renderbufferStorage(GLenum target,
4150 GLenum internalformat,
4151 GLsizei width,
4152 GLsizei height)
4153{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004154 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4155 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
4156
Jamie Madille8fb6402017-02-14 17:56:40 -05004157 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4928b7c2017-06-20 12:57:39 -04004158 handleError(renderbuffer->setStorage(this, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004159}
4160
4161void Context::renderbufferStorageMultisample(GLenum target,
4162 GLsizei samples,
4163 GLenum internalformat,
4164 GLsizei width,
4165 GLsizei height)
4166{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004167 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4168 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
Jamie Madille8fb6402017-02-14 17:56:40 -05004169
4170 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004171 handleError(
Jamie Madill4928b7c2017-06-20 12:57:39 -04004172 renderbuffer->setStorageMultisample(this, samples, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004173}
4174
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004175void Context::getSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)
4176{
Jamie Madill70b5bb02017-08-28 13:32:37 -04004177 const Sync *syncObject = getSync(sync);
Geoff Lang82483b92017-04-11 15:33:00 -04004178 handleError(QuerySynciv(syncObject, pname, bufSize, length, values));
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004179}
4180
JiangYizhoue18e6392017-02-20 10:32:23 +08004181void Context::getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
4182{
4183 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4184 QueryFramebufferParameteriv(framebuffer, pname, params);
4185}
4186
4187void Context::setFramebufferParameteri(GLenum target, GLenum pname, GLint param)
4188{
4189 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4190 SetFramebufferParameteri(framebuffer, pname, param);
4191}
4192
Jamie Madillb3f26b92017-07-19 15:07:41 -04004193Error Context::getScratchBuffer(size_t requstedSizeBytes,
4194 angle::MemoryBuffer **scratchBufferOut) const
Jamie Madille14951e2017-03-09 18:55:16 -05004195{
Jamie Madillb3f26b92017-07-19 15:07:41 -04004196 if (!mScratchBuffer.get(requstedSizeBytes, scratchBufferOut))
4197 {
4198 return OutOfMemory() << "Failed to allocate internal buffer.";
4199 }
4200 return NoError();
4201}
4202
4203Error Context::getZeroFilledBuffer(size_t requstedSizeBytes,
4204 angle::MemoryBuffer **zeroBufferOut) const
4205{
4206 if (!mZeroFilledBuffer.getInitialized(requstedSizeBytes, zeroBufferOut, 0))
Jamie Madille14951e2017-03-09 18:55:16 -05004207 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004208 return OutOfMemory() << "Failed to allocate internal buffer.";
Jamie Madille14951e2017-03-09 18:55:16 -05004209 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004210 return NoError();
Jamie Madille14951e2017-03-09 18:55:16 -05004211}
4212
Xinghua Cao2b396592017-03-29 15:36:04 +08004213void Context::dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ)
4214{
4215 if (numGroupsX == 0u || numGroupsY == 0u || numGroupsZ == 0u)
4216 {
4217 return;
4218 }
4219
Jamie Madillfe548342017-06-19 11:13:24 -04004220 mImplementation->dispatchCompute(this, numGroupsX, numGroupsY, numGroupsZ);
Xinghua Cao2b396592017-03-29 15:36:04 +08004221}
4222
JiangYizhou165361c2017-06-07 14:56:57 +08004223void Context::texStorage2D(GLenum target,
4224 GLsizei levels,
4225 GLenum internalFormat,
4226 GLsizei width,
4227 GLsizei height)
4228{
4229 Extents size(width, height, 1);
4230 Texture *texture = getTargetTexture(target);
4231 handleError(texture->setStorage(this, target, levels, internalFormat, size));
4232}
4233
4234void Context::texStorage3D(GLenum target,
4235 GLsizei levels,
4236 GLenum internalFormat,
4237 GLsizei width,
4238 GLsizei height,
4239 GLsizei depth)
4240{
4241 Extents size(width, height, depth);
4242 Texture *texture = getTargetTexture(target);
4243 handleError(texture->setStorage(this, target, levels, internalFormat, size));
4244}
4245
Jamie Madillc1d770e2017-04-13 17:31:24 -04004246GLenum Context::checkFramebufferStatus(GLenum target)
4247{
4248 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4249 ASSERT(framebuffer);
4250
4251 return framebuffer->checkStatus(this);
4252}
4253
4254void Context::compileShader(GLuint shader)
4255{
4256 Shader *shaderObject = GetValidShader(this, shader);
4257 if (!shaderObject)
4258 {
4259 return;
4260 }
4261 shaderObject->compile(this);
4262}
4263
4264void Context::deleteBuffers(GLsizei n, const GLuint *buffers)
4265{
4266 for (int i = 0; i < n; i++)
4267 {
4268 deleteBuffer(buffers[i]);
4269 }
4270}
4271
4272void Context::deleteFramebuffers(GLsizei n, const GLuint *framebuffers)
4273{
4274 for (int i = 0; i < n; i++)
4275 {
4276 if (framebuffers[i] != 0)
4277 {
4278 deleteFramebuffer(framebuffers[i]);
4279 }
4280 }
4281}
4282
4283void Context::deleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)
4284{
4285 for (int i = 0; i < n; i++)
4286 {
4287 deleteRenderbuffer(renderbuffers[i]);
4288 }
4289}
4290
4291void Context::deleteTextures(GLsizei n, const GLuint *textures)
4292{
4293 for (int i = 0; i < n; i++)
4294 {
4295 if (textures[i] != 0)
4296 {
4297 deleteTexture(textures[i]);
4298 }
4299 }
4300}
4301
4302void Context::detachShader(GLuint program, GLuint shader)
4303{
4304 Program *programObject = getProgram(program);
4305 ASSERT(programObject);
4306
4307 Shader *shaderObject = getShader(shader);
4308 ASSERT(shaderObject);
4309
4310 programObject->detachShader(this, shaderObject);
4311}
4312
4313void Context::genBuffers(GLsizei n, GLuint *buffers)
4314{
4315 for (int i = 0; i < n; i++)
4316 {
4317 buffers[i] = createBuffer();
4318 }
4319}
4320
4321void Context::genFramebuffers(GLsizei n, GLuint *framebuffers)
4322{
4323 for (int i = 0; i < n; i++)
4324 {
4325 framebuffers[i] = createFramebuffer();
4326 }
4327}
4328
4329void Context::genRenderbuffers(GLsizei n, GLuint *renderbuffers)
4330{
4331 for (int i = 0; i < n; i++)
4332 {
4333 renderbuffers[i] = createRenderbuffer();
4334 }
4335}
4336
4337void Context::genTextures(GLsizei n, GLuint *textures)
4338{
4339 for (int i = 0; i < n; i++)
4340 {
4341 textures[i] = createTexture();
4342 }
4343}
4344
4345void Context::getActiveAttrib(GLuint program,
4346 GLuint index,
4347 GLsizei bufsize,
4348 GLsizei *length,
4349 GLint *size,
4350 GLenum *type,
4351 GLchar *name)
4352{
4353 Program *programObject = getProgram(program);
4354 ASSERT(programObject);
4355 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
4356}
4357
4358void Context::getActiveUniform(GLuint program,
4359 GLuint index,
4360 GLsizei bufsize,
4361 GLsizei *length,
4362 GLint *size,
4363 GLenum *type,
4364 GLchar *name)
4365{
4366 Program *programObject = getProgram(program);
4367 ASSERT(programObject);
4368 programObject->getActiveUniform(index, bufsize, length, size, type, name);
4369}
4370
4371void Context::getAttachedShaders(GLuint program, GLsizei maxcount, GLsizei *count, GLuint *shaders)
4372{
4373 Program *programObject = getProgram(program);
4374 ASSERT(programObject);
4375 programObject->getAttachedShaders(maxcount, count, shaders);
4376}
4377
4378GLint Context::getAttribLocation(GLuint program, const GLchar *name)
4379{
4380 Program *programObject = getProgram(program);
4381 ASSERT(programObject);
4382 return programObject->getAttributeLocation(name);
4383}
4384
4385void Context::getBooleanv(GLenum pname, GLboolean *params)
4386{
4387 GLenum nativeType;
4388 unsigned int numParams = 0;
4389 getQueryParameterInfo(pname, &nativeType, &numParams);
4390
4391 if (nativeType == GL_BOOL)
4392 {
4393 getBooleanvImpl(pname, params);
4394 }
4395 else
4396 {
4397 CastStateValues(this, nativeType, pname, numParams, params);
4398 }
4399}
4400
4401void Context::getFloatv(GLenum pname, GLfloat *params)
4402{
4403 GLenum nativeType;
4404 unsigned int numParams = 0;
4405 getQueryParameterInfo(pname, &nativeType, &numParams);
4406
4407 if (nativeType == GL_FLOAT)
4408 {
4409 getFloatvImpl(pname, params);
4410 }
4411 else
4412 {
4413 CastStateValues(this, nativeType, pname, numParams, params);
4414 }
4415}
4416
4417void Context::getIntegerv(GLenum pname, GLint *params)
4418{
4419 GLenum nativeType;
4420 unsigned int numParams = 0;
4421 getQueryParameterInfo(pname, &nativeType, &numParams);
4422
4423 if (nativeType == GL_INT)
4424 {
4425 getIntegervImpl(pname, params);
4426 }
4427 else
4428 {
4429 CastStateValues(this, nativeType, pname, numParams, params);
4430 }
4431}
4432
4433void Context::getProgramiv(GLuint program, GLenum pname, GLint *params)
4434{
4435 Program *programObject = getProgram(program);
4436 ASSERT(programObject);
Jamie Madillffe00c02017-06-27 16:26:55 -04004437 QueryProgramiv(this, programObject, pname, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004438}
4439
Jamie Madillbe849e42017-05-02 15:49:00 -04004440void Context::getProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei *length, GLchar *infolog)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004441{
4442 Program *programObject = getProgram(program);
4443 ASSERT(programObject);
4444 programObject->getInfoLog(bufsize, length, infolog);
4445}
4446
4447void Context::getShaderiv(GLuint shader, GLenum pname, GLint *params)
4448{
4449 Shader *shaderObject = getShader(shader);
4450 ASSERT(shaderObject);
Jamie Madillbd044ed2017-06-05 12:59:21 -04004451 QueryShaderiv(this, shaderObject, pname, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004452}
4453
4454void Context::getShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *infolog)
4455{
4456 Shader *shaderObject = getShader(shader);
4457 ASSERT(shaderObject);
Jamie Madillbd044ed2017-06-05 12:59:21 -04004458 shaderObject->getInfoLog(this, bufsize, length, infolog);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004459}
4460
4461void Context::getShaderPrecisionFormat(GLenum shadertype,
4462 GLenum precisiontype,
4463 GLint *range,
4464 GLint *precision)
4465{
4466 // TODO(jmadill): Compute shaders.
4467
4468 switch (shadertype)
4469 {
4470 case GL_VERTEX_SHADER:
4471 switch (precisiontype)
4472 {
4473 case GL_LOW_FLOAT:
4474 mCaps.vertexLowpFloat.get(range, precision);
4475 break;
4476 case GL_MEDIUM_FLOAT:
4477 mCaps.vertexMediumpFloat.get(range, precision);
4478 break;
4479 case GL_HIGH_FLOAT:
4480 mCaps.vertexHighpFloat.get(range, precision);
4481 break;
4482
4483 case GL_LOW_INT:
4484 mCaps.vertexLowpInt.get(range, precision);
4485 break;
4486 case GL_MEDIUM_INT:
4487 mCaps.vertexMediumpInt.get(range, precision);
4488 break;
4489 case GL_HIGH_INT:
4490 mCaps.vertexHighpInt.get(range, precision);
4491 break;
4492
4493 default:
4494 UNREACHABLE();
4495 return;
4496 }
4497 break;
4498
4499 case GL_FRAGMENT_SHADER:
4500 switch (precisiontype)
4501 {
4502 case GL_LOW_FLOAT:
4503 mCaps.fragmentLowpFloat.get(range, precision);
4504 break;
4505 case GL_MEDIUM_FLOAT:
4506 mCaps.fragmentMediumpFloat.get(range, precision);
4507 break;
4508 case GL_HIGH_FLOAT:
4509 mCaps.fragmentHighpFloat.get(range, precision);
4510 break;
4511
4512 case GL_LOW_INT:
4513 mCaps.fragmentLowpInt.get(range, precision);
4514 break;
4515 case GL_MEDIUM_INT:
4516 mCaps.fragmentMediumpInt.get(range, precision);
4517 break;
4518 case GL_HIGH_INT:
4519 mCaps.fragmentHighpInt.get(range, precision);
4520 break;
4521
4522 default:
4523 UNREACHABLE();
4524 return;
4525 }
4526 break;
4527
4528 default:
4529 UNREACHABLE();
4530 return;
4531 }
4532}
4533
4534void Context::getShaderSource(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source)
4535{
4536 Shader *shaderObject = getShader(shader);
4537 ASSERT(shaderObject);
4538 shaderObject->getSource(bufsize, length, source);
4539}
4540
4541void Context::getUniformfv(GLuint program, GLint location, GLfloat *params)
4542{
4543 Program *programObject = getProgram(program);
4544 ASSERT(programObject);
Jamie Madill54164b02017-08-28 15:17:37 -04004545 programObject->getUniformfv(this, location, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004546}
4547
4548void Context::getUniformiv(GLuint program, GLint location, GLint *params)
4549{
4550 Program *programObject = getProgram(program);
4551 ASSERT(programObject);
Jamie Madill54164b02017-08-28 15:17:37 -04004552 programObject->getUniformiv(this, location, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004553}
4554
4555GLint Context::getUniformLocation(GLuint program, const GLchar *name)
4556{
4557 Program *programObject = getProgram(program);
4558 ASSERT(programObject);
4559 return programObject->getUniformLocation(name);
4560}
4561
4562GLboolean Context::isBuffer(GLuint buffer)
4563{
4564 if (buffer == 0)
4565 {
4566 return GL_FALSE;
4567 }
4568
4569 return (getBuffer(buffer) ? GL_TRUE : GL_FALSE);
4570}
4571
4572GLboolean Context::isEnabled(GLenum cap)
4573{
4574 return mGLState.getEnableFeature(cap);
4575}
4576
4577GLboolean Context::isFramebuffer(GLuint framebuffer)
4578{
4579 if (framebuffer == 0)
4580 {
4581 return GL_FALSE;
4582 }
4583
4584 return (getFramebuffer(framebuffer) ? GL_TRUE : GL_FALSE);
4585}
4586
4587GLboolean Context::isProgram(GLuint program)
4588{
4589 if (program == 0)
4590 {
4591 return GL_FALSE;
4592 }
4593
4594 return (getProgram(program) ? GL_TRUE : GL_FALSE);
4595}
4596
4597GLboolean Context::isRenderbuffer(GLuint renderbuffer)
4598{
4599 if (renderbuffer == 0)
4600 {
4601 return GL_FALSE;
4602 }
4603
4604 return (getRenderbuffer(renderbuffer) ? GL_TRUE : GL_FALSE);
4605}
4606
4607GLboolean Context::isShader(GLuint shader)
4608{
4609 if (shader == 0)
4610 {
4611 return GL_FALSE;
4612 }
4613
4614 return (getShader(shader) ? GL_TRUE : GL_FALSE);
4615}
4616
4617GLboolean Context::isTexture(GLuint texture)
4618{
4619 if (texture == 0)
4620 {
4621 return GL_FALSE;
4622 }
4623
4624 return (getTexture(texture) ? GL_TRUE : GL_FALSE);
4625}
4626
4627void Context::linkProgram(GLuint program)
4628{
4629 Program *programObject = getProgram(program);
4630 ASSERT(programObject);
4631 handleError(programObject->link(this));
Martin Radev0abb7a22017-08-28 15:34:45 +03004632 mGLState.onProgramExecutableChange(programObject);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004633}
4634
4635void Context::releaseShaderCompiler()
4636{
Jamie Madill4928b7c2017-06-20 12:57:39 -04004637 mCompiler.set(this, nullptr);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004638}
4639
4640void Context::shaderBinary(GLsizei n,
4641 const GLuint *shaders,
4642 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04004643 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004644 GLsizei length)
4645{
4646 // No binary shader formats are supported.
4647 UNIMPLEMENTED();
4648}
4649
4650void Context::shaderSource(GLuint shader,
4651 GLsizei count,
4652 const GLchar *const *string,
4653 const GLint *length)
4654{
4655 Shader *shaderObject = getShader(shader);
4656 ASSERT(shaderObject);
4657 shaderObject->setSource(count, string, length);
4658}
4659
4660void Context::stencilFunc(GLenum func, GLint ref, GLuint mask)
4661{
4662 stencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
4663}
4664
4665void Context::stencilMask(GLuint mask)
4666{
4667 stencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4668}
4669
4670void Context::stencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4671{
4672 stencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4673}
4674
4675void Context::uniform1f(GLint location, GLfloat x)
4676{
4677 Program *program = mGLState.getProgram();
4678 program->setUniform1fv(location, 1, &x);
4679}
4680
4681void Context::uniform1fv(GLint location, GLsizei count, const GLfloat *v)
4682{
4683 Program *program = mGLState.getProgram();
4684 program->setUniform1fv(location, count, v);
4685}
4686
4687void Context::uniform1i(GLint location, GLint x)
4688{
4689 Program *program = mGLState.getProgram();
Jamie Madill81c2e252017-09-09 23:32:46 -04004690 if (program->setUniform1iv(location, 1, &x) == Program::SetUniformResult::SamplerChanged)
4691 {
4692 mGLState.setObjectDirty(GL_PROGRAM);
4693 }
Jamie Madillc1d770e2017-04-13 17:31:24 -04004694}
4695
4696void Context::uniform1iv(GLint location, GLsizei count, const GLint *v)
4697{
4698 Program *program = mGLState.getProgram();
Jamie Madill81c2e252017-09-09 23:32:46 -04004699 if (program->setUniform1iv(location, count, v) == Program::SetUniformResult::SamplerChanged)
4700 {
4701 mGLState.setObjectDirty(GL_PROGRAM);
4702 }
Jamie Madillc1d770e2017-04-13 17:31:24 -04004703}
4704
4705void Context::uniform2f(GLint location, GLfloat x, GLfloat y)
4706{
4707 GLfloat xy[2] = {x, y};
4708 Program *program = mGLState.getProgram();
4709 program->setUniform2fv(location, 1, xy);
4710}
4711
4712void Context::uniform2fv(GLint location, GLsizei count, const GLfloat *v)
4713{
4714 Program *program = mGLState.getProgram();
4715 program->setUniform2fv(location, count, v);
4716}
4717
4718void Context::uniform2i(GLint location, GLint x, GLint y)
4719{
4720 GLint xy[2] = {x, y};
4721 Program *program = mGLState.getProgram();
4722 program->setUniform2iv(location, 1, xy);
4723}
4724
4725void Context::uniform2iv(GLint location, GLsizei count, const GLint *v)
4726{
4727 Program *program = mGLState.getProgram();
4728 program->setUniform2iv(location, count, v);
4729}
4730
4731void Context::uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4732{
4733 GLfloat xyz[3] = {x, y, z};
4734 Program *program = mGLState.getProgram();
4735 program->setUniform3fv(location, 1, xyz);
4736}
4737
4738void Context::uniform3fv(GLint location, GLsizei count, const GLfloat *v)
4739{
4740 Program *program = mGLState.getProgram();
4741 program->setUniform3fv(location, count, v);
4742}
4743
4744void Context::uniform3i(GLint location, GLint x, GLint y, GLint z)
4745{
4746 GLint xyz[3] = {x, y, z};
4747 Program *program = mGLState.getProgram();
4748 program->setUniform3iv(location, 1, xyz);
4749}
4750
4751void Context::uniform3iv(GLint location, GLsizei count, const GLint *v)
4752{
4753 Program *program = mGLState.getProgram();
4754 program->setUniform3iv(location, count, v);
4755}
4756
4757void Context::uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4758{
4759 GLfloat xyzw[4] = {x, y, z, w};
4760 Program *program = mGLState.getProgram();
4761 program->setUniform4fv(location, 1, xyzw);
4762}
4763
4764void Context::uniform4fv(GLint location, GLsizei count, const GLfloat *v)
4765{
4766 Program *program = mGLState.getProgram();
4767 program->setUniform4fv(location, count, v);
4768}
4769
4770void Context::uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4771{
4772 GLint xyzw[4] = {x, y, z, w};
4773 Program *program = mGLState.getProgram();
4774 program->setUniform4iv(location, 1, xyzw);
4775}
4776
4777void Context::uniform4iv(GLint location, GLsizei count, const GLint *v)
4778{
4779 Program *program = mGLState.getProgram();
4780 program->setUniform4iv(location, count, v);
4781}
4782
4783void Context::uniformMatrix2fv(GLint location,
4784 GLsizei count,
4785 GLboolean transpose,
4786 const GLfloat *value)
4787{
4788 Program *program = mGLState.getProgram();
4789 program->setUniformMatrix2fv(location, count, transpose, value);
4790}
4791
4792void Context::uniformMatrix3fv(GLint location,
4793 GLsizei count,
4794 GLboolean transpose,
4795 const GLfloat *value)
4796{
4797 Program *program = mGLState.getProgram();
4798 program->setUniformMatrix3fv(location, count, transpose, value);
4799}
4800
4801void Context::uniformMatrix4fv(GLint location,
4802 GLsizei count,
4803 GLboolean transpose,
4804 const GLfloat *value)
4805{
4806 Program *program = mGLState.getProgram();
4807 program->setUniformMatrix4fv(location, count, transpose, value);
4808}
4809
4810void Context::validateProgram(GLuint program)
4811{
4812 Program *programObject = getProgram(program);
4813 ASSERT(programObject);
4814 programObject->validate(mCaps);
4815}
4816
Jamie Madilld04908b2017-06-09 14:15:35 -04004817void Context::getProgramBinary(GLuint program,
4818 GLsizei bufSize,
4819 GLsizei *length,
4820 GLenum *binaryFormat,
4821 void *binary)
4822{
4823 Program *programObject = getProgram(program);
4824 ASSERT(programObject != nullptr);
4825
4826 handleError(programObject->saveBinary(this, binaryFormat, binary, bufSize, length));
4827}
4828
4829void Context::programBinary(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length)
4830{
4831 Program *programObject = getProgram(program);
4832 ASSERT(programObject != nullptr);
Jamie Madillb6664922017-07-25 12:55:04 -04004833
Jamie Madilld04908b2017-06-09 14:15:35 -04004834 handleError(programObject->loadBinary(this, binaryFormat, binary, length));
4835}
4836
Jamie Madillff325f12017-08-26 15:06:05 -04004837void Context::uniform1ui(GLint location, GLuint v0)
4838{
4839 Program *program = mGLState.getProgram();
4840 program->setUniform1uiv(location, 1, &v0);
4841}
4842
4843void Context::uniform2ui(GLint location, GLuint v0, GLuint v1)
4844{
4845 Program *program = mGLState.getProgram();
4846 const GLuint xy[] = {v0, v1};
4847 program->setUniform2uiv(location, 1, xy);
4848}
4849
4850void Context::uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
4851{
4852 Program *program = mGLState.getProgram();
4853 const GLuint xyz[] = {v0, v1, v2};
4854 program->setUniform3uiv(location, 1, xyz);
4855}
4856
4857void Context::uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
4858{
4859 Program *program = mGLState.getProgram();
4860 const GLuint xyzw[] = {v0, v1, v2, v3};
4861 program->setUniform4uiv(location, 1, xyzw);
4862}
4863
4864void Context::uniform1uiv(GLint location, GLsizei count, const GLuint *value)
4865{
4866 Program *program = mGLState.getProgram();
4867 program->setUniform1uiv(location, count, value);
4868}
4869void Context::uniform2uiv(GLint location, GLsizei count, const GLuint *value)
4870{
4871 Program *program = mGLState.getProgram();
4872 program->setUniform2uiv(location, count, value);
4873}
4874
4875void Context::uniform3uiv(GLint location, GLsizei count, const GLuint *value)
4876{
4877 Program *program = mGLState.getProgram();
4878 program->setUniform3uiv(location, count, value);
4879}
4880
4881void Context::uniform4uiv(GLint location, GLsizei count, const GLuint *value)
4882{
4883 Program *program = mGLState.getProgram();
4884 program->setUniform4uiv(location, count, value);
4885}
4886
Jamie Madillf0e04492017-08-26 15:28:42 -04004887void Context::genQueries(GLsizei n, GLuint *ids)
4888{
4889 for (GLsizei i = 0; i < n; i++)
4890 {
4891 GLuint handle = mQueryHandleAllocator.allocate();
4892 mQueryMap.assign(handle, nullptr);
4893 ids[i] = handle;
4894 }
4895}
4896
4897void Context::deleteQueries(GLsizei n, const GLuint *ids)
4898{
4899 for (int i = 0; i < n; i++)
4900 {
4901 GLuint query = ids[i];
4902
4903 Query *queryObject = nullptr;
4904 if (mQueryMap.erase(query, &queryObject))
4905 {
4906 mQueryHandleAllocator.release(query);
4907 if (queryObject)
4908 {
4909 queryObject->release(this);
4910 }
4911 }
4912 }
4913}
4914
4915GLboolean Context::isQuery(GLuint id)
4916{
4917 return (getQuery(id, false, GL_NONE) != nullptr) ? GL_TRUE : GL_FALSE;
4918}
4919
Jamie Madillc8c95812017-08-26 18:40:09 -04004920void Context::uniformMatrix2x3fv(GLint location,
4921 GLsizei count,
4922 GLboolean transpose,
4923 const GLfloat *value)
4924{
4925 Program *program = mGLState.getProgram();
4926 program->setUniformMatrix2x3fv(location, count, transpose, value);
4927}
4928
4929void Context::uniformMatrix3x2fv(GLint location,
4930 GLsizei count,
4931 GLboolean transpose,
4932 const GLfloat *value)
4933{
4934 Program *program = mGLState.getProgram();
4935 program->setUniformMatrix3x2fv(location, count, transpose, value);
4936}
4937
4938void Context::uniformMatrix2x4fv(GLint location,
4939 GLsizei count,
4940 GLboolean transpose,
4941 const GLfloat *value)
4942{
4943 Program *program = mGLState.getProgram();
4944 program->setUniformMatrix2x4fv(location, count, transpose, value);
4945}
4946
4947void Context::uniformMatrix4x2fv(GLint location,
4948 GLsizei count,
4949 GLboolean transpose,
4950 const GLfloat *value)
4951{
4952 Program *program = mGLState.getProgram();
4953 program->setUniformMatrix4x2fv(location, count, transpose, value);
4954}
4955
4956void Context::uniformMatrix3x4fv(GLint location,
4957 GLsizei count,
4958 GLboolean transpose,
4959 const GLfloat *value)
4960{
4961 Program *program = mGLState.getProgram();
4962 program->setUniformMatrix3x4fv(location, count, transpose, value);
4963}
4964
4965void Context::uniformMatrix4x3fv(GLint location,
4966 GLsizei count,
4967 GLboolean transpose,
4968 const GLfloat *value)
4969{
4970 Program *program = mGLState.getProgram();
4971 program->setUniformMatrix4x3fv(location, count, transpose, value);
4972}
4973
Jamie Madilld7576732017-08-26 18:49:50 -04004974void Context::deleteVertexArrays(GLsizei n, const GLuint *arrays)
4975{
4976 for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
4977 {
4978 GLuint vertexArray = arrays[arrayIndex];
4979
4980 if (arrays[arrayIndex] != 0)
4981 {
4982 VertexArray *vertexArrayObject = nullptr;
4983 if (mVertexArrayMap.erase(vertexArray, &vertexArrayObject))
4984 {
4985 if (vertexArrayObject != nullptr)
4986 {
4987 detachVertexArray(vertexArray);
4988 vertexArrayObject->onDestroy(this);
4989 }
4990
4991 mVertexArrayHandleAllocator.release(vertexArray);
4992 }
4993 }
4994 }
4995}
4996
4997void Context::genVertexArrays(GLsizei n, GLuint *arrays)
4998{
4999 for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
5000 {
5001 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
5002 mVertexArrayMap.assign(vertexArray, nullptr);
5003 arrays[arrayIndex] = vertexArray;
5004 }
5005}
5006
5007bool Context::isVertexArray(GLuint array)
5008{
5009 if (array == 0)
5010 {
5011 return GL_FALSE;
5012 }
5013
5014 VertexArray *vao = getVertexArray(array);
5015 return (vao != nullptr ? GL_TRUE : GL_FALSE);
5016}
5017
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04005018void Context::endTransformFeedback()
5019{
5020 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
5021 transformFeedback->end(this);
5022}
5023
5024void Context::transformFeedbackVaryings(GLuint program,
5025 GLsizei count,
5026 const GLchar *const *varyings,
5027 GLenum bufferMode)
5028{
5029 Program *programObject = getProgram(program);
5030 ASSERT(programObject);
5031 programObject->setTransformFeedbackVaryings(count, varyings, bufferMode);
5032}
5033
5034void Context::getTransformFeedbackVarying(GLuint program,
5035 GLuint index,
5036 GLsizei bufSize,
5037 GLsizei *length,
5038 GLsizei *size,
5039 GLenum *type,
5040 GLchar *name)
5041{
5042 Program *programObject = getProgram(program);
5043 ASSERT(programObject);
5044 programObject->getTransformFeedbackVarying(index, bufSize, length, size, type, name);
5045}
5046
5047void Context::deleteTransformFeedbacks(GLsizei n, const GLuint *ids)
5048{
5049 for (int i = 0; i < n; i++)
5050 {
5051 GLuint transformFeedback = ids[i];
5052 if (transformFeedback == 0)
5053 {
5054 continue;
5055 }
5056
5057 TransformFeedback *transformFeedbackObject = nullptr;
5058 if (mTransformFeedbackMap.erase(transformFeedback, &transformFeedbackObject))
5059 {
5060 if (transformFeedbackObject != nullptr)
5061 {
5062 detachTransformFeedback(transformFeedback);
5063 transformFeedbackObject->release(this);
5064 }
5065
5066 mTransformFeedbackHandleAllocator.release(transformFeedback);
5067 }
5068 }
5069}
5070
5071void Context::genTransformFeedbacks(GLsizei n, GLuint *ids)
5072{
5073 for (int i = 0; i < n; i++)
5074 {
5075 GLuint transformFeedback = mTransformFeedbackHandleAllocator.allocate();
5076 mTransformFeedbackMap.assign(transformFeedback, nullptr);
5077 ids[i] = transformFeedback;
5078 }
5079}
5080
5081bool Context::isTransformFeedback(GLuint id)
5082{
5083 if (id == 0)
5084 {
5085 // The 3.0.4 spec [section 6.1.11] states that if ID is zero, IsTransformFeedback
5086 // returns FALSE
5087 return GL_FALSE;
5088 }
5089
5090 const TransformFeedback *transformFeedback = getTransformFeedback(id);
5091 return ((transformFeedback != nullptr) ? GL_TRUE : GL_FALSE);
5092}
5093
5094void Context::pauseTransformFeedback()
5095{
5096 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
5097 transformFeedback->pause();
5098}
5099
5100void Context::resumeTransformFeedback()
5101{
5102 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
5103 transformFeedback->resume();
5104}
5105
Jamie Madill12e957f2017-08-26 21:42:26 -04005106void Context::getUniformuiv(GLuint program, GLint location, GLuint *params)
5107{
5108 const Program *programObject = getProgram(program);
Jamie Madill54164b02017-08-28 15:17:37 -04005109 programObject->getUniformuiv(this, location, params);
Jamie Madill12e957f2017-08-26 21:42:26 -04005110}
5111
5112GLint Context::getFragDataLocation(GLuint program, const GLchar *name)
5113{
5114 const Program *programObject = getProgram(program);
5115 return programObject->getFragDataLocation(name);
5116}
5117
5118void Context::getUniformIndices(GLuint program,
5119 GLsizei uniformCount,
5120 const GLchar *const *uniformNames,
5121 GLuint *uniformIndices)
5122{
5123 const Program *programObject = getProgram(program);
5124 if (!programObject->isLinked())
5125 {
5126 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
5127 {
5128 uniformIndices[uniformId] = GL_INVALID_INDEX;
5129 }
5130 }
5131 else
5132 {
5133 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
5134 {
5135 uniformIndices[uniformId] = programObject->getUniformIndex(uniformNames[uniformId]);
5136 }
5137 }
5138}
5139
5140void Context::getActiveUniformsiv(GLuint program,
5141 GLsizei uniformCount,
5142 const GLuint *uniformIndices,
5143 GLenum pname,
5144 GLint *params)
5145{
5146 const Program *programObject = getProgram(program);
5147 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
5148 {
5149 const GLuint index = uniformIndices[uniformId];
5150 params[uniformId] = programObject->getActiveUniformi(index, pname);
5151 }
5152}
5153
5154GLuint Context::getUniformBlockIndex(GLuint program, const GLchar *uniformBlockName)
5155{
5156 const Program *programObject = getProgram(program);
5157 return programObject->getUniformBlockIndex(uniformBlockName);
5158}
5159
5160void Context::getActiveUniformBlockiv(GLuint program,
5161 GLuint uniformBlockIndex,
5162 GLenum pname,
5163 GLint *params)
5164{
5165 const Program *programObject = getProgram(program);
5166 QueryActiveUniformBlockiv(programObject, uniformBlockIndex, pname, params);
5167}
5168
5169void Context::getActiveUniformBlockName(GLuint program,
5170 GLuint uniformBlockIndex,
5171 GLsizei bufSize,
5172 GLsizei *length,
5173 GLchar *uniformBlockName)
5174{
5175 const Program *programObject = getProgram(program);
5176 programObject->getActiveUniformBlockName(uniformBlockIndex, bufSize, length, uniformBlockName);
5177}
5178
5179void Context::uniformBlockBinding(GLuint program,
5180 GLuint uniformBlockIndex,
5181 GLuint uniformBlockBinding)
5182{
5183 Program *programObject = getProgram(program);
5184 programObject->bindUniformBlock(uniformBlockIndex, uniformBlockBinding);
5185}
5186
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005187GLsync Context::fenceSync(GLenum condition, GLbitfield flags)
5188{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005189 GLuint handle = mState.mSyncs->createSync(mImplementation.get());
5190 GLsync syncHandle = reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005191
Jamie Madill70b5bb02017-08-28 13:32:37 -04005192 Sync *syncObject = getSync(syncHandle);
5193 Error error = syncObject->set(condition, flags);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005194 if (error.isError())
5195 {
Jamie Madill70b5bb02017-08-28 13:32:37 -04005196 deleteSync(syncHandle);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005197 handleError(error);
5198 return nullptr;
5199 }
5200
Jamie Madill70b5bb02017-08-28 13:32:37 -04005201 return syncHandle;
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005202}
5203
5204GLboolean Context::isSync(GLsync sync)
5205{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005206 return (getSync(sync) != nullptr);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005207}
5208
5209GLenum Context::clientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
5210{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005211 Sync *syncObject = getSync(sync);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005212
5213 GLenum result = GL_WAIT_FAILED;
5214 handleError(syncObject->clientWait(flags, timeout, &result));
5215 return result;
5216}
5217
5218void Context::waitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
5219{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005220 Sync *syncObject = getSync(sync);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005221 handleError(syncObject->serverWait(flags, timeout));
5222}
5223
5224void Context::getInteger64v(GLenum pname, GLint64 *params)
5225{
5226 GLenum nativeType = GL_NONE;
5227 unsigned int numParams = 0;
5228 getQueryParameterInfo(pname, &nativeType, &numParams);
5229
5230 if (nativeType == GL_INT_64_ANGLEX)
5231 {
5232 getInteger64vImpl(pname, params);
5233 }
5234 else
5235 {
5236 CastStateValues(this, nativeType, pname, numParams, params);
5237 }
5238}
5239
Jamie Madill3ef140a2017-08-26 23:11:21 -04005240void Context::getBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params)
5241{
5242 Buffer *buffer = mGLState.getTargetBuffer(target);
5243 QueryBufferParameteri64v(buffer, pname, params);
5244}
5245
5246void Context::genSamplers(GLsizei count, GLuint *samplers)
5247{
5248 for (int i = 0; i < count; i++)
5249 {
5250 samplers[i] = mState.mSamplers->createSampler();
5251 }
5252}
5253
5254void Context::deleteSamplers(GLsizei count, const GLuint *samplers)
5255{
5256 for (int i = 0; i < count; i++)
5257 {
5258 GLuint sampler = samplers[i];
5259
5260 if (mState.mSamplers->getSampler(sampler))
5261 {
5262 detachSampler(sampler);
5263 }
5264
5265 mState.mSamplers->deleteObject(this, sampler);
5266 }
5267}
5268
5269void Context::getInternalformativ(GLenum target,
5270 GLenum internalformat,
5271 GLenum pname,
5272 GLsizei bufSize,
5273 GLint *params)
5274{
5275 const TextureCaps &formatCaps = mTextureCaps.get(internalformat);
5276 QueryInternalFormativ(formatCaps, pname, bufSize, params);
5277}
5278
Jamie Madill81c2e252017-09-09 23:32:46 -04005279void Context::programUniform1iv(GLuint program, GLint location, GLsizei count, const GLint *value)
5280{
5281 Program *programObject = getProgram(program);
5282 ASSERT(programObject);
5283 if (programObject->setUniform1iv(location, count, value) ==
5284 Program::SetUniformResult::SamplerChanged)
5285 {
5286 mGLState.setObjectDirty(GL_PROGRAM);
5287 }
5288}
5289
5290void Context::onTextureChange(const Texture *texture)
5291{
5292 // Conservatively assume all textures are dirty.
5293 // TODO(jmadill): More fine-grained update.
5294 mGLState.setObjectDirty(GL_TEXTURE);
5295}
5296
Jamie Madillc29968b2016-01-20 11:17:23 -05005297} // namespace gl