blob: 209032e5703400db7e1288905efa9c20719a4c22 [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 Madill1b94d432015-08-07 13:23:23 -0400508
Jamie Madill4928b7c2017-06-20 12:57:39 -0400509 ANGLE_TRY(releaseSurface(display));
Corentin Wallezccab69d2017-01-27 16:57:15 -0500510
511 Framebuffer *newDefault = nullptr;
512 if (surface != nullptr)
513 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400514 ANGLE_TRY(surface->setIsCurrent(this, true));
Corentin Wallezccab69d2017-01-27 16:57:15 -0500515 mCurrentSurface = surface;
516 newDefault = surface->getDefaultFramebuffer();
517 }
518 else
519 {
520 if (mSurfacelessFramebuffer == nullptr)
521 {
522 mSurfacelessFramebuffer = new Framebuffer(mImplementation.get());
523 }
524
525 newDefault = mSurfacelessFramebuffer;
526 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000527
Corentin Wallez37c39792015-08-20 14:19:46 -0400528 // Update default framebuffer, the binding of the previous default
529 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400530 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700531 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400532 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700533 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400534 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700535 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400536 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700537 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400538 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500539 mState.mFramebuffers->setDefaultFramebuffer(newDefault);
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400540 }
Ian Ewell292f0052016-02-04 10:37:32 -0500541
542 // Notify the renderer of a context switch
Jamie Madill4928b7c2017-06-20 12:57:39 -0400543 mImplementation->onMakeCurrent(this);
544 return egl::NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000545}
546
Jamie Madill4928b7c2017-06-20 12:57:39 -0400547egl::Error Context::releaseSurface(const egl::Display *display)
Jamie Madill77a72f62015-04-14 11:18:32 -0400548{
Corentin Wallez37c39792015-08-20 14:19:46 -0400549 // Remove the default framebuffer
Corentin Wallezc295e512017-01-27 17:47:50 -0500550 Framebuffer *currentDefault = nullptr;
551 if (mCurrentSurface != nullptr)
Corentin Wallez51706ea2015-08-07 14:39:22 -0400552 {
Corentin Wallezc295e512017-01-27 17:47:50 -0500553 currentDefault = mCurrentSurface->getDefaultFramebuffer();
554 }
555 else if (mSurfacelessFramebuffer != nullptr)
556 {
557 currentDefault = mSurfacelessFramebuffer;
Corentin Wallez51706ea2015-08-07 14:39:22 -0400558 }
559
Corentin Wallezc295e512017-01-27 17:47:50 -0500560 if (mGLState.getReadFramebuffer() == currentDefault)
561 {
562 mGLState.setReadFramebufferBinding(nullptr);
563 }
564 if (mGLState.getDrawFramebuffer() == currentDefault)
565 {
566 mGLState.setDrawFramebufferBinding(nullptr);
567 }
568 mState.mFramebuffers->setDefaultFramebuffer(nullptr);
569
570 if (mCurrentSurface)
571 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400572 ANGLE_TRY(mCurrentSurface->setIsCurrent(this, false));
Corentin Wallezc295e512017-01-27 17:47:50 -0500573 mCurrentSurface = nullptr;
574 }
Jamie Madill4928b7c2017-06-20 12:57:39 -0400575
576 return egl::NoError();
Jamie Madill77a72f62015-04-14 11:18:32 -0400577}
578
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000579GLuint Context::createBuffer()
580{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500581 return mState.mBuffers->createBuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000582}
583
584GLuint Context::createProgram()
585{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500586 return mState.mShaderPrograms->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000587}
588
589GLuint Context::createShader(GLenum type)
590{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500591 return mState.mShaderPrograms->createShader(mImplementation.get(), mLimitations, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000592}
593
594GLuint Context::createTexture()
595{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500596 return mState.mTextures->createTexture();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000597}
598
599GLuint Context::createRenderbuffer()
600{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500601 return mState.mRenderbuffers->createRenderbuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000602}
603
Sami Väisänene45e53b2016-05-25 10:36:04 +0300604GLuint Context::createPaths(GLsizei range)
605{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500606 auto resultOrError = mState.mPaths->createPaths(mImplementation.get(), range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300607 if (resultOrError.isError())
608 {
609 handleError(resultOrError.getError());
610 return 0;
611 }
612 return resultOrError.getResult();
613}
614
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000615// Returns an unused framebuffer name
616GLuint Context::createFramebuffer()
617{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500618 return mState.mFramebuffers->createFramebuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000619}
620
Jamie Madill33dc8432013-07-26 11:55:05 -0400621GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000622{
Jamie Madill33dc8432013-07-26 11:55:05 -0400623 GLuint handle = mFenceNVHandleAllocator.allocate();
Jamie Madill96a483b2017-06-27 16:49:21 -0400624 mFenceNVMap.assign(handle, new FenceNV(mImplementation->createFenceNV()));
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000625 return handle;
626}
627
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000628void Context::deleteBuffer(GLuint buffer)
629{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500630 if (mState.mBuffers->getBuffer(buffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000631 {
632 detachBuffer(buffer);
633 }
Jamie Madill893ab082014-05-16 16:56:10 -0400634
Jamie Madill6c1f6712017-02-14 19:08:04 -0500635 mState.mBuffers->deleteObject(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000636}
637
638void Context::deleteShader(GLuint shader)
639{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500640 mState.mShaderPrograms->deleteShader(this, shader);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000641}
642
643void Context::deleteProgram(GLuint program)
644{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500645 mState.mShaderPrograms->deleteProgram(this, program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000646}
647
648void Context::deleteTexture(GLuint texture)
649{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500650 if (mState.mTextures->getTexture(texture))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000651 {
652 detachTexture(texture);
653 }
654
Jamie Madill6c1f6712017-02-14 19:08:04 -0500655 mState.mTextures->deleteObject(this, texture);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000656}
657
658void Context::deleteRenderbuffer(GLuint renderbuffer)
659{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500660 if (mState.mRenderbuffers->getRenderbuffer(renderbuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000661 {
662 detachRenderbuffer(renderbuffer);
663 }
Jamie Madill893ab082014-05-16 16:56:10 -0400664
Jamie Madill6c1f6712017-02-14 19:08:04 -0500665 mState.mRenderbuffers->deleteObject(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000666}
667
Jamie Madill7f0c5a42017-08-26 22:43:26 -0400668void Context::deleteSync(GLsync sync)
Jamie Madillcd055f82013-07-26 11:55:15 -0400669{
670 // The spec specifies the underlying Fence object is not deleted until all current
671 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
672 // and since our API is currently designed for being called from a single thread, we can delete
673 // the fence immediately.
Jamie Madill70b5bb02017-08-28 13:32:37 -0400674 mState.mSyncs->deleteObject(this, static_cast<GLuint>(reinterpret_cast<uintptr_t>(sync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400675}
676
Sami Väisänene45e53b2016-05-25 10:36:04 +0300677void Context::deletePaths(GLuint first, GLsizei range)
678{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500679 mState.mPaths->deletePaths(first, range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300680}
681
682bool Context::hasPathData(GLuint path) const
683{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500684 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300685 if (pathObj == nullptr)
686 return false;
687
688 return pathObj->hasPathData();
689}
690
691bool Context::hasPath(GLuint path) const
692{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500693 return mState.mPaths->hasPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300694}
695
696void Context::setPathCommands(GLuint path,
697 GLsizei numCommands,
698 const GLubyte *commands,
699 GLsizei numCoords,
700 GLenum coordType,
701 const void *coords)
702{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500703 auto *pathObject = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300704
705 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
706}
707
708void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
709{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500710 auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300711
712 switch (pname)
713 {
714 case GL_PATH_STROKE_WIDTH_CHROMIUM:
715 pathObj->setStrokeWidth(value);
716 break;
717 case GL_PATH_END_CAPS_CHROMIUM:
718 pathObj->setEndCaps(static_cast<GLenum>(value));
719 break;
720 case GL_PATH_JOIN_STYLE_CHROMIUM:
721 pathObj->setJoinStyle(static_cast<GLenum>(value));
722 break;
723 case GL_PATH_MITER_LIMIT_CHROMIUM:
724 pathObj->setMiterLimit(value);
725 break;
726 case GL_PATH_STROKE_BOUND_CHROMIUM:
727 pathObj->setStrokeBound(value);
728 break;
729 default:
730 UNREACHABLE();
731 break;
732 }
733}
734
735void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
736{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500737 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300738
739 switch (pname)
740 {
741 case GL_PATH_STROKE_WIDTH_CHROMIUM:
742 *value = pathObj->getStrokeWidth();
743 break;
744 case GL_PATH_END_CAPS_CHROMIUM:
745 *value = static_cast<GLfloat>(pathObj->getEndCaps());
746 break;
747 case GL_PATH_JOIN_STYLE_CHROMIUM:
748 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
749 break;
750 case GL_PATH_MITER_LIMIT_CHROMIUM:
751 *value = pathObj->getMiterLimit();
752 break;
753 case GL_PATH_STROKE_BOUND_CHROMIUM:
754 *value = pathObj->getStrokeBound();
755 break;
756 default:
757 UNREACHABLE();
758 break;
759 }
760}
761
762void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
763{
764 mGLState.setPathStencilFunc(func, ref, mask);
765}
766
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000767void Context::deleteFramebuffer(GLuint framebuffer)
768{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500769 if (mState.mFramebuffers->getFramebuffer(framebuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000770 {
771 detachFramebuffer(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000772 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500773
Jamie Madill6c1f6712017-02-14 19:08:04 -0500774 mState.mFramebuffers->deleteObject(this, framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000775}
776
Jamie Madill33dc8432013-07-26 11:55:05 -0400777void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000778{
Jamie Madill96a483b2017-06-27 16:49:21 -0400779 FenceNV *fenceObject = nullptr;
780 if (mFenceNVMap.erase(fence, &fenceObject))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000781 {
Jamie Madill96a483b2017-06-27 16:49:21 -0400782 mFenceNVHandleAllocator.release(fence);
783 delete fenceObject;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000784 }
785}
786
Geoff Lang70d0f492015-12-10 17:45:46 -0500787Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000788{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500789 return mState.mBuffers->getBuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000790}
791
Jamie Madill570f7c82014-07-03 10:38:54 -0400792Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000793{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500794 return mState.mTextures->getTexture(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000795}
796
Geoff Lang70d0f492015-12-10 17:45:46 -0500797Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000798{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500799 return mState.mRenderbuffers->getRenderbuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000800}
801
Jamie Madill70b5bb02017-08-28 13:32:37 -0400802Sync *Context::getSync(GLsync handle) const
Jamie Madillcd055f82013-07-26 11:55:15 -0400803{
Jamie Madill70b5bb02017-08-28 13:32:37 -0400804 return mState.mSyncs->getSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400805}
806
Jamie Madill57a89722013-07-02 11:57:03 -0400807VertexArray *Context::getVertexArray(GLuint handle) const
808{
Jamie Madill96a483b2017-06-27 16:49:21 -0400809 return mVertexArrayMap.query(handle);
Jamie Madill57a89722013-07-02 11:57:03 -0400810}
811
Jamie Madilldc356042013-07-19 16:36:57 -0400812Sampler *Context::getSampler(GLuint handle) const
813{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500814 return mState.mSamplers->getSampler(handle);
Jamie Madilldc356042013-07-19 16:36:57 -0400815}
816
Geoff Langc8058452014-02-03 12:04:11 -0500817TransformFeedback *Context::getTransformFeedback(GLuint handle) const
818{
Jamie Madill96a483b2017-06-27 16:49:21 -0400819 return mTransformFeedbackMap.query(handle);
Geoff Langc8058452014-02-03 12:04:11 -0500820}
821
Geoff Lang70d0f492015-12-10 17:45:46 -0500822LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
823{
824 switch (identifier)
825 {
826 case GL_BUFFER:
827 return getBuffer(name);
828 case GL_SHADER:
829 return getShader(name);
830 case GL_PROGRAM:
831 return getProgram(name);
832 case GL_VERTEX_ARRAY:
833 return getVertexArray(name);
834 case GL_QUERY:
835 return getQuery(name);
836 case GL_TRANSFORM_FEEDBACK:
837 return getTransformFeedback(name);
838 case GL_SAMPLER:
839 return getSampler(name);
840 case GL_TEXTURE:
841 return getTexture(name);
842 case GL_RENDERBUFFER:
843 return getRenderbuffer(name);
844 case GL_FRAMEBUFFER:
845 return getFramebuffer(name);
846 default:
847 UNREACHABLE();
848 return nullptr;
849 }
850}
851
852LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
853{
Jamie Madill70b5bb02017-08-28 13:32:37 -0400854 return getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
Geoff Lang70d0f492015-12-10 17:45:46 -0500855}
856
Martin Radev9d901792016-07-15 15:58:58 +0300857void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
858{
859 LabeledObject *object = getLabeledObject(identifier, name);
860 ASSERT(object != nullptr);
861
862 std::string labelName = GetObjectLabelFromPointer(length, label);
863 object->setLabel(labelName);
Jamie Madill8693bdb2017-09-02 15:32:14 -0400864
865 // TODO(jmadill): Determine if the object is dirty based on 'name'. Conservatively assume the
866 // specified object is active until we do this.
867 mGLState.setObjectDirty(identifier);
Martin Radev9d901792016-07-15 15:58:58 +0300868}
869
870void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
871{
872 LabeledObject *object = getLabeledObjectFromPtr(ptr);
873 ASSERT(object != nullptr);
874
875 std::string labelName = GetObjectLabelFromPointer(length, label);
876 object->setLabel(labelName);
877}
878
879void Context::getObjectLabel(GLenum identifier,
880 GLuint name,
881 GLsizei bufSize,
882 GLsizei *length,
883 GLchar *label) const
884{
885 LabeledObject *object = getLabeledObject(identifier, name);
886 ASSERT(object != nullptr);
887
888 const std::string &objectLabel = object->getLabel();
889 GetObjectLabelBase(objectLabel, bufSize, length, label);
890}
891
892void Context::getObjectPtrLabel(const void *ptr,
893 GLsizei bufSize,
894 GLsizei *length,
895 GLchar *label) const
896{
897 LabeledObject *object = getLabeledObjectFromPtr(ptr);
898 ASSERT(object != nullptr);
899
900 const std::string &objectLabel = object->getLabel();
901 GetObjectLabelBase(objectLabel, bufSize, length, label);
902}
903
Jamie Madilldc356042013-07-19 16:36:57 -0400904bool Context::isSampler(GLuint samplerName) const
905{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500906 return mState.mSamplers->isSampler(samplerName);
Jamie Madilldc356042013-07-19 16:36:57 -0400907}
908
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500909void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000910{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500911 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400912 mGLState.setArrayBufferBinding(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000913}
914
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800915void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
916{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500917 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400918 mGLState.setDrawIndirectBufferBinding(this, buffer);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800919}
920
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500921void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000922{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500923 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400924 mGLState.setElementArrayBuffer(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000925}
926
Jamie Madilldedd7b92014-11-05 16:30:36 -0500927void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000928{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500929 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000930
Jamie Madilldedd7b92014-11-05 16:30:36 -0500931 if (handle == 0)
932 {
933 texture = mZeroTextures[target].get();
934 }
935 else
936 {
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500937 texture = mState.mTextures->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500938 }
939
940 ASSERT(texture);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400941 mGLState.setSamplerTexture(this, target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000942}
943
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500944void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000945{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500946 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
947 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700948 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000949}
950
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500951void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000952{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500953 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
954 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700955 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000956}
957
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500958void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -0400959{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500960 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700961 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400962}
963
Shao80957d92017-02-20 21:25:59 +0800964void Context::bindVertexBuffer(GLuint bindingIndex,
965 GLuint bufferHandle,
966 GLintptr offset,
967 GLsizei stride)
968{
969 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400970 mGLState.bindVertexBuffer(this, bindingIndex, buffer, offset, stride);
Shao80957d92017-02-20 21:25:59 +0800971}
972
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500973void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -0400974{
Geoff Lang76b10c92014-09-05 16:28:14 -0400975 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -0400976 Sampler *sampler =
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500977 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400978 mGLState.setSamplerBinding(this, textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400979}
980
Xinghua Cao65ec0b22017-03-28 16:10:52 +0800981void Context::bindImageTexture(GLuint unit,
982 GLuint texture,
983 GLint level,
984 GLboolean layered,
985 GLint layer,
986 GLenum access,
987 GLenum format)
988{
989 Texture *tex = mState.mTextures->getTexture(texture);
990 mGLState.setImageUnit(this, unit, tex, level, layered, layer, access, format);
991}
992
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500993void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000994{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500995 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400996 mGLState.setGenericUniformBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000997}
998
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500999void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1000 GLuint index,
1001 GLintptr offset,
1002 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001003{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001004 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001005 mGLState.setIndexedUniformBufferBinding(this, index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001006}
1007
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001008void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001009{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001010 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001011 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001012}
1013
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001014void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1015 GLuint index,
1016 GLintptr offset,
1017 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001018{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001019 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001020 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(this, index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001021}
1022
Jiajia Qin6eafb042016-12-27 17:04:07 +08001023void Context::bindGenericAtomicCounterBuffer(GLuint bufferHandle)
1024{
1025 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001026 mGLState.setGenericAtomicCounterBufferBinding(this, buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08001027}
1028
1029void Context::bindIndexedAtomicCounterBuffer(GLuint bufferHandle,
1030 GLuint index,
1031 GLintptr offset,
1032 GLsizeiptr size)
1033{
1034 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001035 mGLState.setIndexedAtomicCounterBufferBinding(this, index, buffer, offset, size);
Jiajia Qin6eafb042016-12-27 17:04:07 +08001036}
1037
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001038void Context::bindGenericShaderStorageBuffer(GLuint bufferHandle)
1039{
1040 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001041 mGLState.setGenericShaderStorageBufferBinding(this, buffer);
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001042}
1043
1044void Context::bindIndexedShaderStorageBuffer(GLuint bufferHandle,
1045 GLuint index,
1046 GLintptr offset,
1047 GLsizeiptr size)
1048{
1049 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001050 mGLState.setIndexedShaderStorageBufferBinding(this, index, buffer, offset, size);
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001051}
1052
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001053void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001054{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001055 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001056 mGLState.setCopyReadBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001057}
1058
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001059void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001060{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001061 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001062 mGLState.setCopyWriteBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001063}
1064
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001065void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001066{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001067 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001068 mGLState.setPixelPackBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001069}
1070
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001071void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001072{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001073 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001074 mGLState.setPixelUnpackBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001075}
1076
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001077void Context::useProgram(GLuint program)
1078{
Jamie Madill6c1f6712017-02-14 19:08:04 -05001079 mGLState.setProgram(this, getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001080}
1081
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04001082void Context::bindTransformFeedback(GLenum target, GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001083{
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04001084 ASSERT(target == GL_TRANSFORM_FEEDBACK);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001085 TransformFeedback *transformFeedback =
1086 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001087 mGLState.setTransformFeedbackBinding(this, transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001088}
1089
Jamie Madillf0e04492017-08-26 15:28:42 -04001090void Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001091{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001092 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001093 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001094
Geoff Lang5aad9672014-09-08 11:10:42 -04001095 // begin query
Jamie Madillf0e04492017-08-26 15:28:42 -04001096 ANGLE_CONTEXT_TRY(queryObject->begin());
Geoff Lang5aad9672014-09-08 11:10:42 -04001097
1098 // set query as active for specified target only if begin succeeded
Jamie Madill4928b7c2017-06-20 12:57:39 -04001099 mGLState.setActiveQuery(this, target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001100}
1101
Jamie Madillf0e04492017-08-26 15:28:42 -04001102void Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001103{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001104 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001105 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001106
Jamie Madillf0e04492017-08-26 15:28:42 -04001107 handleError(queryObject->end());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001108
Geoff Lang5aad9672014-09-08 11:10:42 -04001109 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madill4928b7c2017-06-20 12:57:39 -04001110 mGLState.setActiveQuery(this, target, nullptr);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001111}
1112
Jamie Madillf0e04492017-08-26 15:28:42 -04001113void Context::queryCounter(GLuint id, GLenum target)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001114{
1115 ASSERT(target == GL_TIMESTAMP_EXT);
1116
1117 Query *queryObject = getQuery(id, true, target);
1118 ASSERT(queryObject);
1119
Jamie Madillf0e04492017-08-26 15:28:42 -04001120 handleError(queryObject->queryCounter());
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001121}
1122
1123void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1124{
1125 switch (pname)
1126 {
1127 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001128 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001129 break;
1130 case GL_QUERY_COUNTER_BITS_EXT:
1131 switch (target)
1132 {
1133 case GL_TIME_ELAPSED_EXT:
1134 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1135 break;
1136 case GL_TIMESTAMP_EXT:
1137 params[0] = getExtensions().queryCounterBitsTimestamp;
1138 break;
1139 default:
1140 UNREACHABLE();
1141 params[0] = 0;
1142 break;
1143 }
1144 break;
1145 default:
1146 UNREACHABLE();
1147 return;
1148 }
1149}
1150
Geoff Lang2186c382016-10-14 10:54:54 -04001151void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001152{
Geoff Lang2186c382016-10-14 10:54:54 -04001153 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001154}
1155
Geoff Lang2186c382016-10-14 10:54:54 -04001156void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001157{
Geoff Lang2186c382016-10-14 10:54:54 -04001158 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001159}
1160
Geoff Lang2186c382016-10-14 10:54:54 -04001161void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001162{
Geoff Lang2186c382016-10-14 10:54:54 -04001163 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001164}
1165
Geoff Lang2186c382016-10-14 10:54:54 -04001166void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001167{
Geoff Lang2186c382016-10-14 10:54:54 -04001168 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001169}
1170
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001171Framebuffer *Context::getFramebuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001172{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001173 return mState.mFramebuffers->getFramebuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001174}
1175
Jamie Madill2f348d22017-06-05 10:50:59 -04001176FenceNV *Context::getFenceNV(GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001177{
Jamie Madill96a483b2017-06-27 16:49:21 -04001178 return mFenceNVMap.query(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001179}
1180
Jamie Madill2f348d22017-06-05 10:50:59 -04001181Query *Context::getQuery(GLuint handle, bool create, GLenum type)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001182{
Jamie Madill96a483b2017-06-27 16:49:21 -04001183 if (!mQueryMap.contains(handle))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001184 {
Yunchao Hef81ce4a2017-04-24 10:49:17 +08001185 return nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001186 }
Jamie Madill96a483b2017-06-27 16:49:21 -04001187
1188 Query *query = mQueryMap.query(handle);
1189 if (!query && create)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001190 {
Jamie Madill96a483b2017-06-27 16:49:21 -04001191 query = new Query(mImplementation->createQuery(type), handle);
1192 query->addRef();
1193 mQueryMap.assign(handle, query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001194 }
Jamie Madill96a483b2017-06-27 16:49:21 -04001195 return query;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001196}
1197
Geoff Lang70d0f492015-12-10 17:45:46 -05001198Query *Context::getQuery(GLuint handle) const
1199{
Jamie Madill96a483b2017-06-27 16:49:21 -04001200 return mQueryMap.query(handle);
Geoff Lang70d0f492015-12-10 17:45:46 -05001201}
1202
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001203Texture *Context::getTargetTexture(GLenum target) const
1204{
Ian Ewellbda75592016-04-18 17:25:54 -04001205 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001206 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001207}
1208
Geoff Lang76b10c92014-09-05 16:28:14 -04001209Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001210{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001211 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001212}
1213
Geoff Lang492a7e42014-11-05 13:27:06 -05001214Compiler *Context::getCompiler() const
1215{
Jamie Madill2f348d22017-06-05 10:50:59 -04001216 if (mCompiler.get() == nullptr)
1217 {
Jamie Madill4928b7c2017-06-20 12:57:39 -04001218 mCompiler.set(this, new Compiler(mImplementation.get(), mState));
Jamie Madill2f348d22017-06-05 10:50:59 -04001219 }
1220 return mCompiler.get();
Geoff Lang492a7e42014-11-05 13:27:06 -05001221}
1222
Jamie Madillc1d770e2017-04-13 17:31:24 -04001223void Context::getBooleanvImpl(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001224{
1225 switch (pname)
1226 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001227 case GL_SHADER_COMPILER:
1228 *params = GL_TRUE;
1229 break;
1230 case GL_CONTEXT_ROBUST_ACCESS_EXT:
1231 *params = mRobustAccess ? GL_TRUE : GL_FALSE;
1232 break;
1233 default:
1234 mGLState.getBooleanv(pname, params);
1235 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001236 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001237}
1238
Jamie Madillc1d770e2017-04-13 17:31:24 -04001239void Context::getFloatvImpl(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001240{
Shannon Woods53a94a82014-06-24 15:20:36 -04001241 // Queries about context capabilities and maximums are answered by Context.
1242 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001243 switch (pname)
1244 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001245 case GL_ALIASED_LINE_WIDTH_RANGE:
1246 params[0] = mCaps.minAliasedLineWidth;
1247 params[1] = mCaps.maxAliasedLineWidth;
1248 break;
1249 case GL_ALIASED_POINT_SIZE_RANGE:
1250 params[0] = mCaps.minAliasedPointSize;
1251 params[1] = mCaps.maxAliasedPointSize;
1252 break;
1253 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1254 ASSERT(mExtensions.textureFilterAnisotropic);
1255 *params = mExtensions.maxTextureAnisotropy;
1256 break;
1257 case GL_MAX_TEXTURE_LOD_BIAS:
1258 *params = mCaps.maxLODBias;
1259 break;
1260
1261 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1262 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1263 {
1264 ASSERT(mExtensions.pathRendering);
1265 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1266 memcpy(params, m, 16 * sizeof(GLfloat));
1267 }
Geoff Lange6d4e122015-06-29 13:33:55 -04001268 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001269
Jamie Madill231c7f52017-04-26 13:45:37 -04001270 default:
1271 mGLState.getFloatv(pname, params);
1272 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001273 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001274}
1275
Jamie Madillc1d770e2017-04-13 17:31:24 -04001276void Context::getIntegervImpl(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001277{
Shannon Woods53a94a82014-06-24 15:20:36 -04001278 // Queries about context capabilities and maximums are answered by Context.
1279 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001280
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001281 switch (pname)
1282 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001283 case GL_MAX_VERTEX_ATTRIBS:
1284 *params = mCaps.maxVertexAttributes;
1285 break;
1286 case GL_MAX_VERTEX_UNIFORM_VECTORS:
1287 *params = mCaps.maxVertexUniformVectors;
1288 break;
1289 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
1290 *params = mCaps.maxVertexUniformComponents;
1291 break;
1292 case GL_MAX_VARYING_VECTORS:
1293 *params = mCaps.maxVaryingVectors;
1294 break;
1295 case GL_MAX_VARYING_COMPONENTS:
1296 *params = mCaps.maxVertexOutputComponents;
1297 break;
1298 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1299 *params = mCaps.maxCombinedTextureImageUnits;
1300 break;
1301 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1302 *params = mCaps.maxVertexTextureImageUnits;
1303 break;
1304 case GL_MAX_TEXTURE_IMAGE_UNITS:
1305 *params = mCaps.maxTextureImageUnits;
1306 break;
1307 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1308 *params = mCaps.maxFragmentUniformVectors;
1309 break;
1310 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
1311 *params = mCaps.maxFragmentUniformComponents;
1312 break;
1313 case GL_MAX_RENDERBUFFER_SIZE:
1314 *params = mCaps.maxRenderbufferSize;
1315 break;
1316 case GL_MAX_COLOR_ATTACHMENTS_EXT:
1317 *params = mCaps.maxColorAttachments;
1318 break;
1319 case GL_MAX_DRAW_BUFFERS_EXT:
1320 *params = mCaps.maxDrawBuffers;
1321 break;
1322 // case GL_FRAMEBUFFER_BINDING: // now equivalent to
1323 // GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1324 case GL_SUBPIXEL_BITS:
1325 *params = 4;
1326 break;
1327 case GL_MAX_TEXTURE_SIZE:
1328 *params = mCaps.max2DTextureSize;
1329 break;
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001330 case GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE:
1331 *params = mCaps.maxRectangleTextureSize;
1332 break;
Jamie Madill231c7f52017-04-26 13:45:37 -04001333 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1334 *params = mCaps.maxCubeMapTextureSize;
1335 break;
1336 case GL_MAX_3D_TEXTURE_SIZE:
1337 *params = mCaps.max3DTextureSize;
1338 break;
1339 case GL_MAX_ARRAY_TEXTURE_LAYERS:
1340 *params = mCaps.maxArrayTextureLayers;
1341 break;
1342 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
1343 *params = mCaps.uniformBufferOffsetAlignment;
1344 break;
1345 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
1346 *params = mCaps.maxUniformBufferBindings;
1347 break;
1348 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
1349 *params = mCaps.maxVertexUniformBlocks;
1350 break;
1351 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
1352 *params = mCaps.maxFragmentUniformBlocks;
1353 break;
1354 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
1355 *params = mCaps.maxCombinedTextureImageUnits;
1356 break;
1357 case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
1358 *params = mCaps.maxVertexOutputComponents;
1359 break;
1360 case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
1361 *params = mCaps.maxFragmentInputComponents;
1362 break;
1363 case GL_MIN_PROGRAM_TEXEL_OFFSET:
1364 *params = mCaps.minProgramTexelOffset;
1365 break;
1366 case GL_MAX_PROGRAM_TEXEL_OFFSET:
1367 *params = mCaps.maxProgramTexelOffset;
1368 break;
1369 case GL_MAJOR_VERSION:
1370 *params = getClientVersion().major;
1371 break;
1372 case GL_MINOR_VERSION:
1373 *params = getClientVersion().minor;
1374 break;
1375 case GL_MAX_ELEMENTS_INDICES:
1376 *params = mCaps.maxElementsIndices;
1377 break;
1378 case GL_MAX_ELEMENTS_VERTICES:
1379 *params = mCaps.maxElementsVertices;
1380 break;
1381 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
1382 *params = mCaps.maxTransformFeedbackInterleavedComponents;
1383 break;
1384 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
1385 *params = mCaps.maxTransformFeedbackSeparateAttributes;
1386 break;
1387 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
1388 *params = mCaps.maxTransformFeedbackSeparateComponents;
1389 break;
1390 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1391 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1392 break;
1393 case GL_MAX_SAMPLES_ANGLE:
1394 *params = mCaps.maxSamples;
1395 break;
1396 case GL_MAX_VIEWPORT_DIMS:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001397 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001398 params[0] = mCaps.maxViewportWidth;
1399 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001400 }
1401 break;
Jamie Madill231c7f52017-04-26 13:45:37 -04001402 case GL_COMPRESSED_TEXTURE_FORMATS:
1403 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(),
1404 params);
1405 break;
1406 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1407 *params = mResetStrategy;
1408 break;
1409 case GL_NUM_SHADER_BINARY_FORMATS:
1410 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
1411 break;
1412 case GL_SHADER_BINARY_FORMATS:
1413 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1414 break;
1415 case GL_NUM_PROGRAM_BINARY_FORMATS:
1416 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
1417 break;
1418 case GL_PROGRAM_BINARY_FORMATS:
1419 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
1420 break;
1421 case GL_NUM_EXTENSIONS:
1422 *params = static_cast<GLint>(mExtensionStrings.size());
1423 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001424
Jamie Madill231c7f52017-04-26 13:45:37 -04001425 // GL_KHR_debug
1426 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1427 *params = mExtensions.maxDebugMessageLength;
1428 break;
1429 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1430 *params = mExtensions.maxDebugLoggedMessages;
1431 break;
1432 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1433 *params = mExtensions.maxDebugGroupStackDepth;
1434 break;
1435 case GL_MAX_LABEL_LENGTH:
1436 *params = mExtensions.maxLabelLength;
1437 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001438
Martin Radeve5285d22017-07-14 16:23:53 +03001439 // GL_ANGLE_multiview
1440 case GL_MAX_VIEWS_ANGLE:
1441 *params = mExtensions.maxViews;
1442 break;
1443
Jamie Madill231c7f52017-04-26 13:45:37 -04001444 // GL_EXT_disjoint_timer_query
1445 case GL_GPU_DISJOINT_EXT:
1446 *params = mImplementation->getGPUDisjoint();
1447 break;
1448 case GL_MAX_FRAMEBUFFER_WIDTH:
1449 *params = mCaps.maxFramebufferWidth;
1450 break;
1451 case GL_MAX_FRAMEBUFFER_HEIGHT:
1452 *params = mCaps.maxFramebufferHeight;
1453 break;
1454 case GL_MAX_FRAMEBUFFER_SAMPLES:
1455 *params = mCaps.maxFramebufferSamples;
1456 break;
1457 case GL_MAX_SAMPLE_MASK_WORDS:
1458 *params = mCaps.maxSampleMaskWords;
1459 break;
1460 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1461 *params = mCaps.maxColorTextureSamples;
1462 break;
1463 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1464 *params = mCaps.maxDepthTextureSamples;
1465 break;
1466 case GL_MAX_INTEGER_SAMPLES:
1467 *params = mCaps.maxIntegerSamples;
1468 break;
1469 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1470 *params = mCaps.maxVertexAttribRelativeOffset;
1471 break;
1472 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1473 *params = mCaps.maxVertexAttribBindings;
1474 break;
1475 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1476 *params = mCaps.maxVertexAttribStride;
1477 break;
1478 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1479 *params = mCaps.maxVertexAtomicCounterBuffers;
1480 break;
1481 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1482 *params = mCaps.maxVertexAtomicCounters;
1483 break;
1484 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1485 *params = mCaps.maxVertexImageUniforms;
1486 break;
1487 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1488 *params = mCaps.maxVertexShaderStorageBlocks;
1489 break;
1490 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1491 *params = mCaps.maxFragmentAtomicCounterBuffers;
1492 break;
1493 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1494 *params = mCaps.maxFragmentAtomicCounters;
1495 break;
1496 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1497 *params = mCaps.maxFragmentImageUniforms;
1498 break;
1499 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1500 *params = mCaps.maxFragmentShaderStorageBlocks;
1501 break;
1502 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1503 *params = mCaps.minProgramTextureGatherOffset;
1504 break;
1505 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1506 *params = mCaps.maxProgramTextureGatherOffset;
1507 break;
1508 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1509 *params = mCaps.maxComputeWorkGroupInvocations;
1510 break;
1511 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1512 *params = mCaps.maxComputeUniformBlocks;
1513 break;
1514 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1515 *params = mCaps.maxComputeTextureImageUnits;
1516 break;
1517 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1518 *params = mCaps.maxComputeSharedMemorySize;
1519 break;
1520 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1521 *params = mCaps.maxComputeUniformComponents;
1522 break;
1523 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1524 *params = mCaps.maxComputeAtomicCounterBuffers;
1525 break;
1526 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1527 *params = mCaps.maxComputeAtomicCounters;
1528 break;
1529 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1530 *params = mCaps.maxComputeImageUniforms;
1531 break;
1532 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1533 *params = mCaps.maxCombinedComputeUniformComponents;
1534 break;
1535 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1536 *params = mCaps.maxComputeShaderStorageBlocks;
1537 break;
1538 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1539 *params = mCaps.maxCombinedShaderOutputResources;
1540 break;
1541 case GL_MAX_UNIFORM_LOCATIONS:
1542 *params = mCaps.maxUniformLocations;
1543 break;
1544 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1545 *params = mCaps.maxAtomicCounterBufferBindings;
1546 break;
1547 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1548 *params = mCaps.maxAtomicCounterBufferSize;
1549 break;
1550 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1551 *params = mCaps.maxCombinedAtomicCounterBuffers;
1552 break;
1553 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1554 *params = mCaps.maxCombinedAtomicCounters;
1555 break;
1556 case GL_MAX_IMAGE_UNITS:
1557 *params = mCaps.maxImageUnits;
1558 break;
1559 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1560 *params = mCaps.maxCombinedImageUniforms;
1561 break;
1562 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1563 *params = mCaps.maxShaderStorageBufferBindings;
1564 break;
1565 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1566 *params = mCaps.maxCombinedShaderStorageBlocks;
1567 break;
1568 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1569 *params = mCaps.shaderStorageBufferOffsetAlignment;
1570 break;
1571 default:
1572 mGLState.getIntegerv(this, pname, params);
1573 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001574 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001575}
1576
Jamie Madill7f0c5a42017-08-26 22:43:26 -04001577void Context::getInteger64vImpl(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001578{
Shannon Woods53a94a82014-06-24 15:20:36 -04001579 // Queries about context capabilities and maximums are answered by Context.
1580 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001581 switch (pname)
1582 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001583 case GL_MAX_ELEMENT_INDEX:
1584 *params = mCaps.maxElementIndex;
1585 break;
1586 case GL_MAX_UNIFORM_BLOCK_SIZE:
1587 *params = mCaps.maxUniformBlockSize;
1588 break;
1589 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
1590 *params = mCaps.maxCombinedVertexUniformComponents;
1591 break;
1592 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
1593 *params = mCaps.maxCombinedFragmentUniformComponents;
1594 break;
1595 case GL_MAX_SERVER_WAIT_TIMEOUT:
1596 *params = mCaps.maxServerWaitTimeout;
1597 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001598
Jamie Madill231c7f52017-04-26 13:45:37 -04001599 // GL_EXT_disjoint_timer_query
1600 case GL_TIMESTAMP_EXT:
1601 *params = mImplementation->getTimestamp();
1602 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001603
Jamie Madill231c7f52017-04-26 13:45:37 -04001604 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1605 *params = mCaps.maxShaderStorageBlockSize;
1606 break;
1607 default:
1608 UNREACHABLE();
1609 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001610 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001611}
1612
Geoff Lang70d0f492015-12-10 17:45:46 -05001613void Context::getPointerv(GLenum pname, void **params) const
1614{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001615 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001616}
1617
Martin Radev66fb8202016-07-28 11:45:20 +03001618void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001619{
Shannon Woods53a94a82014-06-24 15:20:36 -04001620 // Queries about context capabilities and maximums are answered by Context.
1621 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001622
1623 GLenum nativeType;
1624 unsigned int numParams;
1625 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1626 ASSERT(queryStatus);
1627
1628 if (nativeType == GL_INT)
1629 {
1630 switch (target)
1631 {
1632 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1633 ASSERT(index < 3u);
1634 *data = mCaps.maxComputeWorkGroupCount[index];
1635 break;
1636 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1637 ASSERT(index < 3u);
1638 *data = mCaps.maxComputeWorkGroupSize[index];
1639 break;
1640 default:
1641 mGLState.getIntegeri_v(target, index, data);
1642 }
1643 }
1644 else
1645 {
1646 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1647 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001648}
1649
Martin Radev66fb8202016-07-28 11:45:20 +03001650void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001651{
Shannon Woods53a94a82014-06-24 15:20:36 -04001652 // Queries about context capabilities and maximums are answered by Context.
1653 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001654
1655 GLenum nativeType;
1656 unsigned int numParams;
1657 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1658 ASSERT(queryStatus);
1659
1660 if (nativeType == GL_INT_64_ANGLEX)
1661 {
1662 mGLState.getInteger64i_v(target, index, data);
1663 }
1664 else
1665 {
1666 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1667 }
1668}
1669
1670void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1671{
1672 // Queries about context capabilities and maximums are answered by Context.
1673 // Queries about current GL state values are answered by State.
1674
1675 GLenum nativeType;
1676 unsigned int numParams;
1677 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1678 ASSERT(queryStatus);
1679
1680 if (nativeType == GL_BOOL)
1681 {
1682 mGLState.getBooleani_v(target, index, data);
1683 }
1684 else
1685 {
1686 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1687 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001688}
1689
He Yunchao010e4db2017-03-03 14:22:06 +08001690void Context::getBufferParameteriv(GLenum target, GLenum pname, GLint *params)
1691{
1692 Buffer *buffer = mGLState.getTargetBuffer(target);
1693 QueryBufferParameteriv(buffer, pname, params);
1694}
1695
1696void Context::getFramebufferAttachmentParameteriv(GLenum target,
1697 GLenum attachment,
1698 GLenum pname,
1699 GLint *params)
1700{
1701 const Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
1702 QueryFramebufferAttachmentParameteriv(framebuffer, attachment, pname, params);
1703}
1704
1705void Context::getRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
1706{
1707 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
1708 QueryRenderbufferiv(this, renderbuffer, pname, params);
1709}
1710
1711void Context::getTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
1712{
1713 Texture *texture = getTargetTexture(target);
1714 QueryTexParameterfv(texture, pname, params);
1715}
1716
1717void Context::getTexParameteriv(GLenum target, GLenum pname, GLint *params)
1718{
1719 Texture *texture = getTargetTexture(target);
1720 QueryTexParameteriv(texture, pname, params);
1721}
1722void Context::texParameterf(GLenum target, GLenum pname, GLfloat param)
1723{
1724 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001725 SetTexParameterf(this, texture, pname, param);
He Yunchao010e4db2017-03-03 14:22:06 +08001726}
1727
1728void Context::texParameterfv(GLenum target, GLenum pname, const GLfloat *params)
1729{
1730 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001731 SetTexParameterfv(this, texture, pname, params);
He Yunchao010e4db2017-03-03 14:22:06 +08001732}
1733
1734void Context::texParameteri(GLenum target, GLenum pname, GLint param)
1735{
1736 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001737 SetTexParameteri(this, texture, pname, param);
He Yunchao010e4db2017-03-03 14:22:06 +08001738}
1739
1740void Context::texParameteriv(GLenum target, GLenum pname, const GLint *params)
1741{
1742 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001743 SetTexParameteriv(this, texture, pname, params);
He Yunchao010e4db2017-03-03 14:22:06 +08001744}
1745
Jamie Madill675fe712016-12-19 13:07:54 -05001746void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001747{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001748 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001749 ANGLE_CONTEXT_TRY(mImplementation->drawArrays(this, mode, first, count));
1750 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001751}
1752
Jamie Madill675fe712016-12-19 13:07:54 -05001753void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Geoff Langf6db0982015-08-25 13:04:00 -04001754{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001755 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001756 ANGLE_CONTEXT_TRY(
1757 mImplementation->drawArraysInstanced(this, mode, first, count, instanceCount));
1758 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Langf6db0982015-08-25 13:04:00 -04001759}
1760
Jamie Madill876429b2017-04-20 15:46:24 -04001761void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001762{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001763 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001764 ANGLE_CONTEXT_TRY(mImplementation->drawElements(this, mode, count, type, indices));
Geoff Langf6db0982015-08-25 13:04:00 -04001765}
1766
Jamie Madill675fe712016-12-19 13:07:54 -05001767void Context::drawElementsInstanced(GLenum mode,
1768 GLsizei count,
1769 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001770 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001771 GLsizei instances)
Geoff Langf6db0982015-08-25 13:04:00 -04001772{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001773 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001774 ANGLE_CONTEXT_TRY(
Qin Jiajia1da00652017-06-20 17:16:25 +08001775 mImplementation->drawElementsInstanced(this, mode, count, type, indices, instances));
Geoff Langf6db0982015-08-25 13:04:00 -04001776}
1777
Jamie Madill675fe712016-12-19 13:07:54 -05001778void Context::drawRangeElements(GLenum mode,
1779 GLuint start,
1780 GLuint end,
1781 GLsizei count,
1782 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001783 const void *indices)
Geoff Langf6db0982015-08-25 13:04:00 -04001784{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001785 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001786 ANGLE_CONTEXT_TRY(
1787 mImplementation->drawRangeElements(this, mode, start, end, count, type, indices));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001788}
1789
Jamie Madill876429b2017-04-20 15:46:24 -04001790void Context::drawArraysIndirect(GLenum mode, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001791{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001792 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001793 ANGLE_CONTEXT_TRY(mImplementation->drawArraysIndirect(this, mode, indirect));
Jiajia Qind9671222016-11-29 16:30:31 +08001794}
1795
Jamie Madill876429b2017-04-20 15:46:24 -04001796void Context::drawElementsIndirect(GLenum mode, GLenum type, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001797{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001798 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001799 ANGLE_CONTEXT_TRY(mImplementation->drawElementsIndirect(this, mode, type, indirect));
Jiajia Qind9671222016-11-29 16:30:31 +08001800}
1801
Jamie Madill675fe712016-12-19 13:07:54 -05001802void Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001803{
Jamie Madill675fe712016-12-19 13:07:54 -05001804 handleError(mImplementation->flush());
Geoff Lang129753a2015-01-09 16:52:09 -05001805}
1806
Jamie Madill675fe712016-12-19 13:07:54 -05001807void Context::finish()
Geoff Lang129753a2015-01-09 16:52:09 -05001808{
Jamie Madill675fe712016-12-19 13:07:54 -05001809 handleError(mImplementation->finish());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001810}
1811
Austin Kinross6ee1e782015-05-29 17:05:37 -07001812void Context::insertEventMarker(GLsizei length, const char *marker)
1813{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001814 ASSERT(mImplementation);
1815 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001816}
1817
1818void Context::pushGroupMarker(GLsizei length, const char *marker)
1819{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001820 ASSERT(mImplementation);
1821 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001822}
1823
1824void Context::popGroupMarker()
1825{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001826 ASSERT(mImplementation);
1827 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001828}
1829
Geoff Langd8605522016-04-13 10:19:12 -04001830void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1831{
1832 Program *programObject = getProgram(program);
1833 ASSERT(programObject);
1834
1835 programObject->bindUniformLocation(location, name);
1836}
1837
Sami Väisänena797e062016-05-12 15:23:40 +03001838void Context::setCoverageModulation(GLenum components)
1839{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001840 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001841}
1842
Sami Väisänene45e53b2016-05-25 10:36:04 +03001843void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1844{
1845 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1846}
1847
1848void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1849{
1850 GLfloat I[16];
1851 angle::Matrix<GLfloat>::setToIdentity(I);
1852
1853 mGLState.loadPathRenderingMatrix(matrixMode, I);
1854}
1855
1856void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1857{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001858 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001859 if (!pathObj)
1860 return;
1861
1862 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1863 syncRendererState();
1864
1865 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1866}
1867
1868void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1869{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001870 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001871 if (!pathObj)
1872 return;
1873
1874 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1875 syncRendererState();
1876
1877 mImplementation->stencilStrokePath(pathObj, reference, mask);
1878}
1879
1880void Context::coverFillPath(GLuint path, GLenum coverMode)
1881{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001882 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001883 if (!pathObj)
1884 return;
1885
1886 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1887 syncRendererState();
1888
1889 mImplementation->coverFillPath(pathObj, coverMode);
1890}
1891
1892void Context::coverStrokePath(GLuint path, GLenum coverMode)
1893{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001894 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001895 if (!pathObj)
1896 return;
1897
1898 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1899 syncRendererState();
1900
1901 mImplementation->coverStrokePath(pathObj, coverMode);
1902}
1903
1904void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1905{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001906 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001907 if (!pathObj)
1908 return;
1909
1910 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1911 syncRendererState();
1912
1913 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1914}
1915
1916void Context::stencilThenCoverStrokePath(GLuint path,
1917 GLint reference,
1918 GLuint mask,
1919 GLenum coverMode)
1920{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001921 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001922 if (!pathObj)
1923 return;
1924
1925 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1926 syncRendererState();
1927
1928 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1929}
1930
Sami Väisänend59ca052016-06-21 16:10:00 +03001931void Context::coverFillPathInstanced(GLsizei numPaths,
1932 GLenum pathNameType,
1933 const void *paths,
1934 GLuint pathBase,
1935 GLenum coverMode,
1936 GLenum transformType,
1937 const GLfloat *transformValues)
1938{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001939 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001940
1941 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1942 syncRendererState();
1943
1944 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1945}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001946
Sami Väisänend59ca052016-06-21 16:10:00 +03001947void Context::coverStrokePathInstanced(GLsizei numPaths,
1948 GLenum pathNameType,
1949 const void *paths,
1950 GLuint pathBase,
1951 GLenum coverMode,
1952 GLenum transformType,
1953 const GLfloat *transformValues)
1954{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001955 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001956
1957 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1958 syncRendererState();
1959
1960 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1961 transformValues);
1962}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001963
Sami Väisänend59ca052016-06-21 16:10:00 +03001964void Context::stencilFillPathInstanced(GLsizei numPaths,
1965 GLenum pathNameType,
1966 const void *paths,
1967 GLuint pathBase,
1968 GLenum fillMode,
1969 GLuint mask,
1970 GLenum transformType,
1971 const GLfloat *transformValues)
1972{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001973 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001974
1975 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1976 syncRendererState();
1977
1978 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1979 transformValues);
1980}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001981
Sami Väisänend59ca052016-06-21 16:10:00 +03001982void Context::stencilStrokePathInstanced(GLsizei numPaths,
1983 GLenum pathNameType,
1984 const void *paths,
1985 GLuint pathBase,
1986 GLint reference,
1987 GLuint mask,
1988 GLenum transformType,
1989 const GLfloat *transformValues)
1990{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001991 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001992
1993 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1994 syncRendererState();
1995
1996 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
1997 transformValues);
1998}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001999
Sami Väisänend59ca052016-06-21 16:10:00 +03002000void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
2001 GLenum pathNameType,
2002 const void *paths,
2003 GLuint pathBase,
2004 GLenum fillMode,
2005 GLuint mask,
2006 GLenum coverMode,
2007 GLenum transformType,
2008 const GLfloat *transformValues)
2009{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002010 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002011
2012 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2013 syncRendererState();
2014
2015 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
2016 transformType, transformValues);
2017}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002018
Sami Väisänend59ca052016-06-21 16:10:00 +03002019void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
2020 GLenum pathNameType,
2021 const void *paths,
2022 GLuint pathBase,
2023 GLint reference,
2024 GLuint mask,
2025 GLenum coverMode,
2026 GLenum transformType,
2027 const GLfloat *transformValues)
2028{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002029 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002030
2031 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2032 syncRendererState();
2033
2034 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
2035 transformType, transformValues);
2036}
2037
Sami Väisänen46eaa942016-06-29 10:26:37 +03002038void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
2039{
2040 auto *programObject = getProgram(program);
2041
2042 programObject->bindFragmentInputLocation(location, name);
2043}
2044
2045void Context::programPathFragmentInputGen(GLuint program,
2046 GLint location,
2047 GLenum genMode,
2048 GLint components,
2049 const GLfloat *coeffs)
2050{
2051 auto *programObject = getProgram(program);
2052
Jamie Madillbd044ed2017-06-05 12:59:21 -04002053 programObject->pathFragmentInputGen(this, location, genMode, components, coeffs);
Sami Väisänen46eaa942016-06-29 10:26:37 +03002054}
2055
jchen1015015f72017-03-16 13:54:21 +08002056GLuint Context::getProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name)
2057{
jchen10fd7c3b52017-03-21 15:36:03 +08002058 const auto *programObject = getProgram(program);
jchen1015015f72017-03-16 13:54:21 +08002059 return QueryProgramResourceIndex(programObject, programInterface, name);
2060}
2061
jchen10fd7c3b52017-03-21 15:36:03 +08002062void Context::getProgramResourceName(GLuint program,
2063 GLenum programInterface,
2064 GLuint index,
2065 GLsizei bufSize,
2066 GLsizei *length,
2067 GLchar *name)
2068{
2069 const auto *programObject = getProgram(program);
2070 QueryProgramResourceName(programObject, programInterface, index, bufSize, length, name);
2071}
2072
jchen10191381f2017-04-11 13:59:04 +08002073GLint Context::getProgramResourceLocation(GLuint program,
2074 GLenum programInterface,
2075 const GLchar *name)
2076{
2077 const auto *programObject = getProgram(program);
2078 return QueryProgramResourceLocation(programObject, programInterface, name);
2079}
2080
jchen10880683b2017-04-12 16:21:55 +08002081void Context::getProgramResourceiv(GLuint program,
2082 GLenum programInterface,
2083 GLuint index,
2084 GLsizei propCount,
2085 const GLenum *props,
2086 GLsizei bufSize,
2087 GLsizei *length,
2088 GLint *params)
2089{
2090 const auto *programObject = getProgram(program);
2091 QueryProgramResourceiv(programObject, programInterface, index, propCount, props, bufSize,
2092 length, params);
2093}
2094
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002095Error Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002096{
Geoff Langda5777c2014-07-11 09:52:58 -04002097 if (error.isError())
2098 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002099 GLenum code = error.getCode();
2100 mErrors.insert(code);
2101 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
2102 {
2103 markContextLost();
2104 }
Geoff Lang70d0f492015-12-10 17:45:46 -05002105
2106 if (!error.getMessage().empty())
2107 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002108 auto *debug = &mGLState.getDebug();
2109 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
2110 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05002111 }
Geoff Langda5777c2014-07-11 09:52:58 -04002112 }
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002113
2114 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002115}
2116
2117// Get one of the recorded errors and clear its flag, if any.
2118// [OpenGL ES 2.0.24] section 2.5 page 13.
2119GLenum Context::getError()
2120{
Geoff Langda5777c2014-07-11 09:52:58 -04002121 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002122 {
Geoff Langda5777c2014-07-11 09:52:58 -04002123 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002124 }
Geoff Langda5777c2014-07-11 09:52:58 -04002125 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002126 {
Geoff Langda5777c2014-07-11 09:52:58 -04002127 GLenum error = *mErrors.begin();
2128 mErrors.erase(mErrors.begin());
2129 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002130 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002131}
2132
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002133// NOTE: this function should not assume that this context is current!
2134void Context::markContextLost()
2135{
2136 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002137 {
Jamie Madill231c7f52017-04-26 13:45:37 -04002138 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002139 mContextLostForced = true;
2140 }
Jamie Madill231c7f52017-04-26 13:45:37 -04002141 mContextLost = true;
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002142}
2143
2144bool Context::isContextLost()
2145{
2146 return mContextLost;
2147}
2148
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002149GLenum Context::getResetStatus()
2150{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002151 // Even if the application doesn't want to know about resets, we want to know
2152 // as it will allow us to skip all the calls.
2153 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002154 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002155 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002156 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002157 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002158 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002159
2160 // EXT_robustness, section 2.6: If the reset notification behavior is
2161 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2162 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2163 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002164 }
2165
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002166 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2167 // status should be returned at least once, and GL_NO_ERROR should be returned
2168 // once the device has finished resetting.
2169 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002170 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002171 ASSERT(mResetStatus == GL_NO_ERROR);
2172 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002173
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002174 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002175 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002176 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002177 }
2178 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002179 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002180 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002181 // If markContextLost was used to mark the context lost then
2182 // assume that is not recoverable, and continue to report the
2183 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002184 mResetStatus = mImplementation->getResetStatus();
2185 }
Jamie Madill893ab082014-05-16 16:56:10 -04002186
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002187 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002188}
2189
2190bool Context::isResetNotificationEnabled()
2191{
2192 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2193}
2194
Corentin Walleze3b10e82015-05-20 11:06:25 -04002195const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002196{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002197 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002198}
2199
2200EGLenum Context::getClientType() const
2201{
2202 return mClientType;
2203}
2204
2205EGLenum Context::getRenderBuffer() const
2206{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002207 const Framebuffer *framebuffer = mState.mFramebuffers->getFramebuffer(0);
2208 if (framebuffer == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -04002209 {
2210 return EGL_NONE;
2211 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002212
2213 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2214 ASSERT(backAttachment != nullptr);
2215 return backAttachment->getSurface()->getRenderBuffer();
Régis Fénéon83107972015-02-05 12:57:44 +01002216}
2217
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002218VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002219{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002220 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002221 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2222 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002223 {
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002224 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle,
2225 mCaps.maxVertexAttributes, mCaps.maxVertexAttribBindings);
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002226
Jamie Madill96a483b2017-06-27 16:49:21 -04002227 mVertexArrayMap.assign(vertexArrayHandle, vertexArray);
Geoff Lang36167ab2015-12-07 10:27:14 -05002228 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002229
2230 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002231}
2232
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002233TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002234{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002235 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002236 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2237 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002238 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002239 transformFeedback =
2240 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002241 transformFeedback->addRef();
Jamie Madill96a483b2017-06-27 16:49:21 -04002242 mTransformFeedbackMap.assign(transformFeedbackHandle, transformFeedback);
Geoff Lang36167ab2015-12-07 10:27:14 -05002243 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002244
2245 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002246}
2247
2248bool Context::isVertexArrayGenerated(GLuint vertexArray)
2249{
Jamie Madill96a483b2017-06-27 16:49:21 -04002250 ASSERT(mVertexArrayMap.contains(0));
2251 return mVertexArrayMap.contains(vertexArray);
Geoff Lang36167ab2015-12-07 10:27:14 -05002252}
2253
2254bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2255{
Jamie Madill96a483b2017-06-27 16:49:21 -04002256 ASSERT(mTransformFeedbackMap.contains(0));
2257 return mTransformFeedbackMap.contains(transformFeedback);
Geoff Lang36167ab2015-12-07 10:27:14 -05002258}
2259
Shannon Woods53a94a82014-06-24 15:20:36 -04002260void Context::detachTexture(GLuint texture)
2261{
2262 // Simple pass-through to State's detachTexture method, as textures do not require
2263 // allocation map management either here or in the resource manager at detach time.
2264 // Zero textures are held by the Context, and we don't attempt to request them from
2265 // the State.
Jamie Madilla02315b2017-02-23 14:14:47 -05002266 mGLState.detachTexture(this, mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002267}
2268
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002269void Context::detachBuffer(GLuint buffer)
2270{
Yuly Novikov5807a532015-12-03 13:01:22 -05002271 // Simple pass-through to State's detachBuffer method, since
2272 // only buffer attachments to container objects that are bound to the current context
2273 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002274
Yuly Novikov5807a532015-12-03 13:01:22 -05002275 // [OpenGL ES 3.2] section 5.1.2 page 45:
2276 // Attachments to unbound container objects, such as
2277 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2278 // are not affected and continue to act as references on the deleted object
Jamie Madill4928b7c2017-06-20 12:57:39 -04002279 mGLState.detachBuffer(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002280}
2281
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002282void Context::detachFramebuffer(GLuint framebuffer)
2283{
Shannon Woods53a94a82014-06-24 15:20:36 -04002284 // Framebuffer detachment is handled by Context, because 0 is a valid
2285 // Framebuffer object, and a pointer to it must be passed from Context
2286 // to State at binding time.
2287
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002288 // [OpenGL ES 2.0.24] section 4.4 page 107:
Jamie Madill231c7f52017-04-26 13:45:37 -04002289 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as
2290 // though BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of
2291 // zero.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002292
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002293 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002294 {
2295 bindReadFramebuffer(0);
2296 }
2297
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002298 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002299 {
2300 bindDrawFramebuffer(0);
2301 }
2302}
2303
2304void Context::detachRenderbuffer(GLuint renderbuffer)
2305{
Jamie Madilla02315b2017-02-23 14:14:47 -05002306 mGLState.detachRenderbuffer(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002307}
2308
Jamie Madill57a89722013-07-02 11:57:03 -04002309void Context::detachVertexArray(GLuint vertexArray)
2310{
Jamie Madill77a72f62015-04-14 11:18:32 -04002311 // Vertex array detachment is handled by Context, because 0 is a valid
2312 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002313 // binding time.
2314
Jamie Madill57a89722013-07-02 11:57:03 -04002315 // [OpenGL ES 3.0.2] section 2.10 page 43:
2316 // If a vertex array object that is currently bound is deleted, the binding
2317 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002318 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002319 {
2320 bindVertexArray(0);
2321 }
2322}
2323
Geoff Langc8058452014-02-03 12:04:11 -05002324void Context::detachTransformFeedback(GLuint transformFeedback)
2325{
Corentin Walleza2257da2016-04-19 16:43:12 -04002326 // Transform feedback detachment is handled by Context, because 0 is a valid
2327 // transform feedback, and a pointer to it must be passed from Context to State at
2328 // binding time.
2329
2330 // The OpenGL specification doesn't mention what should happen when the currently bound
2331 // transform feedback object is deleted. Since it is a container object, we treat it like
2332 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madill4928b7c2017-06-20 12:57:39 -04002333 if (mGLState.removeTransformFeedbackBinding(this, transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002334 {
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04002335 bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
Corentin Walleza2257da2016-04-19 16:43:12 -04002336 }
Geoff Langc8058452014-02-03 12:04:11 -05002337}
2338
Jamie Madilldc356042013-07-19 16:36:57 -04002339void Context::detachSampler(GLuint sampler)
2340{
Jamie Madill4928b7c2017-06-20 12:57:39 -04002341 mGLState.detachSampler(this, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002342}
2343
Jamie Madill3ef140a2017-08-26 23:11:21 -04002344void Context::vertexAttribDivisor(GLuint index, GLuint divisor)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002345{
Shaodde78e82017-05-22 14:13:27 +08002346 mGLState.setVertexAttribDivisor(this, index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002347}
2348
Jamie Madille29d1672013-07-19 16:36:57 -04002349void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2350{
Geoff Langc1984ed2016-10-07 12:41:00 -04002351 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002352 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002353 SetSamplerParameteri(samplerObject, pname, param);
2354}
Jamie Madille29d1672013-07-19 16:36:57 -04002355
Geoff Langc1984ed2016-10-07 12:41:00 -04002356void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2357{
2358 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002359 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002360 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002361}
2362
2363void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat 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 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002368}
2369
Geoff Langc1984ed2016-10-07 12:41:00 -04002370void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002371{
Geoff Langc1984ed2016-10-07 12:41:00 -04002372 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002373 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002374 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002375}
2376
Geoff Langc1984ed2016-10-07 12:41:00 -04002377void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002378{
Geoff Langc1984ed2016-10-07 12:41:00 -04002379 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002380 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002381 QuerySamplerParameteriv(samplerObject, pname, params);
2382}
Jamie Madill9675b802013-07-19 16:36:59 -04002383
Geoff Langc1984ed2016-10-07 12:41:00 -04002384void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2385{
2386 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002387 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002388 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002389}
2390
Olli Etuahof0fee072016-03-30 15:11:58 +03002391void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2392{
2393 gl::Program *programObject = getProgram(program);
Yunchao He61afff12017-03-14 15:34:03 +08002394 SetProgramParameteri(programObject, pname, value);
Olli Etuahof0fee072016-03-30 15:11:58 +03002395}
2396
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002397void Context::initRendererString()
2398{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002399 std::ostringstream rendererString;
2400 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002401 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002402 rendererString << ")";
2403
Geoff Langcec35902014-04-16 10:52:36 -04002404 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002405}
2406
Geoff Langc339c4e2016-11-29 10:37:36 -05002407void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002408{
Geoff Langc339c4e2016-11-29 10:37:36 -05002409 const Version &clientVersion = getClientVersion();
2410
2411 std::ostringstream versionString;
2412 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2413 << ANGLE_VERSION_STRING << ")";
2414 mVersionString = MakeStaticString(versionString.str());
2415
2416 std::ostringstream shadingLanguageVersionString;
2417 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2418 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2419 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2420 << ")";
2421 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002422}
2423
Geoff Langcec35902014-04-16 10:52:36 -04002424void Context::initExtensionStrings()
2425{
Geoff Langc339c4e2016-11-29 10:37:36 -05002426 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2427 std::ostringstream combinedStringStream;
2428 std::copy(strings.begin(), strings.end(),
2429 std::ostream_iterator<const char *>(combinedStringStream, " "));
2430 return MakeStaticString(combinedStringStream.str());
2431 };
2432
2433 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002434 for (const auto &extensionString : mExtensions.getStrings())
2435 {
2436 mExtensionStrings.push_back(MakeStaticString(extensionString));
2437 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002438 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002439
Bryan Bernhart58806562017-01-05 13:09:31 -08002440 const gl::Extensions &nativeExtensions = mImplementation->getNativeExtensions();
2441
Geoff Langc339c4e2016-11-29 10:37:36 -05002442 mRequestableExtensionStrings.clear();
2443 for (const auto &extensionInfo : GetExtensionInfoMap())
2444 {
2445 if (extensionInfo.second.Requestable &&
Bryan Bernhart58806562017-01-05 13:09:31 -08002446 !(mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
2447 nativeExtensions.*(extensionInfo.second.ExtensionsMember))
Geoff Langc339c4e2016-11-29 10:37:36 -05002448 {
2449 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2450 }
2451 }
2452 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002453}
2454
Geoff Langc339c4e2016-11-29 10:37:36 -05002455const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002456{
Geoff Langc339c4e2016-11-29 10:37:36 -05002457 switch (name)
2458 {
2459 case GL_VENDOR:
2460 return reinterpret_cast<const GLubyte *>("Google Inc.");
2461
2462 case GL_RENDERER:
2463 return reinterpret_cast<const GLubyte *>(mRendererString);
2464
2465 case GL_VERSION:
2466 return reinterpret_cast<const GLubyte *>(mVersionString);
2467
2468 case GL_SHADING_LANGUAGE_VERSION:
2469 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2470
2471 case GL_EXTENSIONS:
2472 return reinterpret_cast<const GLubyte *>(mExtensionString);
2473
2474 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2475 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2476
2477 default:
2478 UNREACHABLE();
2479 return nullptr;
2480 }
Geoff Langcec35902014-04-16 10:52:36 -04002481}
2482
Geoff Langc339c4e2016-11-29 10:37:36 -05002483const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002484{
Geoff Langc339c4e2016-11-29 10:37:36 -05002485 switch (name)
2486 {
2487 case GL_EXTENSIONS:
2488 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2489
2490 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2491 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2492
2493 default:
2494 UNREACHABLE();
2495 return nullptr;
2496 }
Geoff Langcec35902014-04-16 10:52:36 -04002497}
2498
2499size_t Context::getExtensionStringCount() const
2500{
2501 return mExtensionStrings.size();
2502}
2503
Geoff Langc339c4e2016-11-29 10:37:36 -05002504void Context::requestExtension(const char *name)
2505{
2506 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2507 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2508 const auto &extension = extensionInfos.at(name);
2509 ASSERT(extension.Requestable);
2510
2511 if (mExtensions.*(extension.ExtensionsMember))
2512 {
2513 // Extension already enabled
2514 return;
2515 }
2516
2517 mExtensions.*(extension.ExtensionsMember) = true;
2518 updateCaps();
2519 initExtensionStrings();
Bryan Bernhart58806562017-01-05 13:09:31 -08002520
Jamie Madill2f348d22017-06-05 10:50:59 -04002521 // Release the shader compiler so it will be re-created with the requested extensions enabled.
2522 releaseShaderCompiler();
Geoff Lang9aded172017-04-05 11:07:56 -04002523
2524 // Invalidate all cached completenesses for textures and framebuffer. Some extensions make new
2525 // formats renderable or sampleable.
2526 mState.mTextures->invalidateTextureComplenessCache();
2527 for (auto &zeroTexture : mZeroTextures)
2528 {
2529 zeroTexture.second->invalidateCompletenessCache();
2530 }
2531
2532 mState.mFramebuffers->invalidateFramebufferComplenessCache();
Geoff Langc339c4e2016-11-29 10:37:36 -05002533}
2534
2535size_t Context::getRequestableExtensionStringCount() const
2536{
2537 return mRequestableExtensionStrings.size();
2538}
2539
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002540void Context::beginTransformFeedback(GLenum primitiveMode)
2541{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002542 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002543 ASSERT(transformFeedback != nullptr);
2544 ASSERT(!transformFeedback->isPaused());
2545
Jamie Madill6c1f6712017-02-14 19:08:04 -05002546 transformFeedback->begin(this, primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002547}
2548
2549bool Context::hasActiveTransformFeedback(GLuint program) const
2550{
2551 for (auto pair : mTransformFeedbackMap)
2552 {
2553 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2554 {
2555 return true;
2556 }
2557 }
2558 return false;
2559}
2560
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002561void Context::initCaps(const egl::DisplayExtensions &displayExtensions)
Geoff Lang493daf52014-07-03 13:38:44 -04002562{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002563 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002564
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002565 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002566
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002567 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002568
Geoff Langeb66a6e2016-10-31 13:06:12 -04002569 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002570 {
2571 // Disable ES3+ extensions
Jamie Madill231c7f52017-04-26 13:45:37 -04002572 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002573 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002574 mExtensions.textureNorm16 = false;
Martin Radev137032d2017-07-13 10:11:12 +03002575 mExtensions.multiview = false;
2576 mExtensions.maxViews = 1u;
Geoff Lang493daf52014-07-03 13:38:44 -04002577 }
2578
Geoff Langeb66a6e2016-10-31 13:06:12 -04002579 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002580 {
2581 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
Jamie Madill231c7f52017-04-26 13:45:37 -04002582 // mExtensions.sRGB = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002583 }
2584
Jamie Madill00ed7a12016-05-19 13:13:38 -04002585 // Some extensions are always available because they are implemented in the GL layer.
Jamie Madill231c7f52017-04-26 13:45:37 -04002586 mExtensions.bindUniformLocation = true;
2587 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002588 mExtensions.bindGeneratesResource = true;
Geoff Langfeb8c682017-02-13 16:07:35 -05002589 mExtensions.clientArrays = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002590 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002591
2592 // Enable the no error extension if the context was created with the flag.
2593 mExtensions.noError = mSkipValidation;
2594
Corentin Wallezccab69d2017-01-27 16:57:15 -05002595 // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
Corentin Wallezc295e512017-01-27 17:47:50 -05002596 mExtensions.surfacelessContext = displayExtensions.surfacelessContext;
Corentin Wallezccab69d2017-01-27 16:57:15 -05002597
Geoff Lang70d0f492015-12-10 17:45:46 -05002598 // Explicitly enable GL_KHR_debug
2599 mExtensions.debug = true;
2600 mExtensions.maxDebugMessageLength = 1024;
2601 mExtensions.maxDebugLoggedMessages = 1024;
2602 mExtensions.maxDebugGroupStackDepth = 1024;
2603 mExtensions.maxLabelLength = 1024;
2604
Geoff Langff5b2d52016-09-07 11:32:23 -04002605 // Explicitly enable GL_ANGLE_robust_client_memory
2606 mExtensions.robustClientMemory = true;
2607
Jamie Madille08a1d32017-03-07 17:24:06 -05002608 // Determine robust resource init availability from EGL.
2609 mExtensions.robustResourceInitialization =
Jamie Madill948bbe52017-06-01 13:10:42 -04002610 egl::Display::GetClientExtensions().displayRobustResourceInitialization;
Jamie Madille08a1d32017-03-07 17:24:06 -05002611
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08002612 // mExtensions.robustBufferAccessBehavior is true only if robust access is true and the backend
2613 // supports it.
2614 mExtensions.robustBufferAccessBehavior =
2615 mRobustAccess && mExtensions.robustBufferAccessBehavior;
2616
Jamie Madillc43be722017-07-13 16:22:14 -04002617 // Enable the cache control query unconditionally.
2618 mExtensions.programCacheControl = true;
2619
Geoff Lang301d1612014-07-09 10:34:37 -04002620 // Apply implementation limits
2621 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002622 mCaps.maxVertexAttribBindings =
2623 getClientVersion() < ES_3_1
2624 ? mCaps.maxVertexAttributes
2625 : std::min<GLuint>(mCaps.maxVertexAttribBindings, MAX_VERTEX_ATTRIB_BINDINGS);
2626
Jamie Madill231c7f52017-04-26 13:45:37 -04002627 mCaps.maxVertexUniformBlocks = std::min<GLuint>(
2628 mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2629 mCaps.maxVertexOutputComponents =
2630 std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang301d1612014-07-09 10:34:37 -04002631
Jamie Madill231c7f52017-04-26 13:45:37 -04002632 mCaps.maxFragmentInputComponents =
2633 std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002634
Geoff Langc287ea62016-09-16 14:46:51 -04002635 // WebGL compatibility
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002636 mExtensions.webglCompatibility = mWebGLContext;
Geoff Langc287ea62016-09-16 14:46:51 -04002637 for (const auto &extensionInfo : GetExtensionInfoMap())
2638 {
2639 // If this context is for WebGL, disable all enableable extensions
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002640 if (mWebGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002641 {
2642 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2643 }
2644 }
2645
2646 // Generate texture caps
2647 updateCaps();
2648}
2649
2650void Context::updateCaps()
2651{
Geoff Lang900013c2014-07-07 11:32:19 -04002652 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002653 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002654
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002655 for (auto capsIt : mImplementation->getNativeTextureCaps())
Geoff Lang493daf52014-07-03 13:38:44 -04002656 {
Geoff Langca271392017-04-05 12:30:00 -04002657 GLenum sizedInternalFormat = capsIt.first;
Jamie Madill231c7f52017-04-26 13:45:37 -04002658 TextureCaps formatCaps = capsIt.second;
Geoff Lang493daf52014-07-03 13:38:44 -04002659
Geoff Langca271392017-04-05 12:30:00 -04002660 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002661
Geoff Lang0d8b7242015-09-09 14:56:53 -04002662 // Update the format caps based on the client version and extensions.
2663 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2664 // ES3.
2665 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002666 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002667 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002668 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002669 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002670 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002671
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002672 // OpenGL ES does not support multisampling with non-rendererable formats
2673 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
Olli Etuaho50c562d2017-06-06 14:43:30 +03002674 if (!formatCaps.renderable ||
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002675 (getClientVersion() < ES_3_1 &&
2676 (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
Geoff Lang493daf52014-07-03 13:38:44 -04002677 {
Geoff Langd87878e2014-09-19 15:42:59 -04002678 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002679 }
Olli Etuaho50c562d2017-06-06 14:43:30 +03002680 else
2681 {
2682 // We may have limited the max samples for some required renderbuffer formats due to
2683 // non-conformant formats. In this case MAX_SAMPLES needs to be lowered accordingly.
2684 GLuint formatMaxSamples = formatCaps.getMaxSamples();
2685
2686 // GLES 3.0.5 section 4.4.2.2: "Implementations must support creation of renderbuffers
2687 // in these required formats with up to the value of MAX_SAMPLES multisamples, with the
2688 // exception of signed and unsigned integer formats."
2689 if (formatInfo.componentType != GL_INT && formatInfo.componentType != GL_UNSIGNED_INT &&
2690 formatInfo.isRequiredRenderbufferFormat(getClientVersion()))
2691 {
2692 ASSERT(getClientVersion() < ES_3_0 || formatMaxSamples >= 4);
2693 mCaps.maxSamples = std::min(mCaps.maxSamples, formatMaxSamples);
2694 }
2695
2696 // Handle GLES 3.1 MAX_*_SAMPLES values similarly to MAX_SAMPLES.
2697 if (getClientVersion() >= ES_3_1)
2698 {
2699 // GLES 3.1 section 9.2.5: "Implementations must support creation of renderbuffers
2700 // in these required formats with up to the value of MAX_SAMPLES multisamples, with
2701 // the exception that the signed and unsigned integer formats are required only to
2702 // support creation of renderbuffers with up to the value of MAX_INTEGER_SAMPLES
2703 // multisamples, which must be at least one."
2704 if (formatInfo.componentType == GL_INT ||
2705 formatInfo.componentType == GL_UNSIGNED_INT)
2706 {
2707 mCaps.maxIntegerSamples = std::min(mCaps.maxIntegerSamples, formatMaxSamples);
2708 }
2709
2710 // GLES 3.1 section 19.3.1.
2711 if (formatCaps.texturable)
2712 {
2713 if (formatInfo.depthBits > 0)
2714 {
2715 mCaps.maxDepthTextureSamples =
2716 std::min(mCaps.maxDepthTextureSamples, formatMaxSamples);
2717 }
2718 else if (formatInfo.redBits > 0)
2719 {
2720 mCaps.maxColorTextureSamples =
2721 std::min(mCaps.maxColorTextureSamples, formatMaxSamples);
2722 }
2723 }
2724 }
2725 }
Geoff Langd87878e2014-09-19 15:42:59 -04002726
2727 if (formatCaps.texturable && formatInfo.compressed)
2728 {
Geoff Langca271392017-04-05 12:30:00 -04002729 mCaps.compressedTextureFormats.push_back(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002730 }
2731
Geoff Langca271392017-04-05 12:30:00 -04002732 mTextureCaps.insert(sizedInternalFormat, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002733 }
Jamie Madill32447362017-06-28 14:53:52 -04002734
2735 // If program binary is disabled, blank out the memory cache pointer.
2736 if (!mImplementation->getNativeExtensions().getProgramBinary)
2737 {
2738 mMemoryProgramCache = nullptr;
2739 }
Geoff Lang493daf52014-07-03 13:38:44 -04002740}
2741
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002742void Context::initWorkarounds()
2743{
Jamie Madill761b02c2017-06-23 16:27:06 -04002744 // Apply back-end workarounds.
2745 mImplementation->applyNativeWorkarounds(&mWorkarounds);
2746
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002747 // Lose the context upon out of memory error if the application is
2748 // expecting to watch for those events.
2749 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2750}
2751
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002752Error Context::prepareForDraw(GLenum drawMode)
Jamie Madillb6664922017-07-25 12:55:04 -04002753{
2754 syncRendererState();
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002755
2756 InfoLog infoLog;
2757 Error err = mImplementation->triggerDrawCallProgramRecompilation(this, &infoLog,
2758 mMemoryProgramCache, drawMode);
Jamie Madilla836b462017-08-16 14:58:35 -04002759 if (err.isError() || infoLog.getLength() > 0)
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002760 {
2761 WARN() << "Dynamic recompilation error log: " << infoLog.str();
2762 }
2763 return err;
Jamie Madillb6664922017-07-25 12:55:04 -04002764}
2765
Jamie Madill1b94d432015-08-07 13:23:23 -04002766void Context::syncRendererState()
2767{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002768 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
Jamie Madillfe548342017-06-19 11:13:24 -04002769 mImplementation->syncState(this, dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002770 mGLState.clearDirtyBits();
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002771 mGLState.syncDirtyObjects(this);
Jamie Madill1b94d432015-08-07 13:23:23 -04002772}
2773
Jamie Madillad9f24e2016-02-12 09:27:24 -05002774void Context::syncRendererState(const State::DirtyBits &bitMask,
2775 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002776{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002777 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
Jamie Madillfe548342017-06-19 11:13:24 -04002778 mImplementation->syncState(this, dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002779 mGLState.clearDirtyBits(dirtyBits);
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002780 mGLState.syncDirtyObjects(this, objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002781}
Jamie Madillc29968b2016-01-20 11:17:23 -05002782
2783void Context::blitFramebuffer(GLint srcX0,
2784 GLint srcY0,
2785 GLint srcX1,
2786 GLint srcY1,
2787 GLint dstX0,
2788 GLint dstY0,
2789 GLint dstX1,
2790 GLint dstY1,
2791 GLbitfield mask,
2792 GLenum filter)
2793{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002794 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002795 ASSERT(drawFramebuffer);
2796
2797 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2798 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2799
Jamie Madillad9f24e2016-02-12 09:27:24 -05002800 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002801
Jamie Madillc564c072017-06-01 12:45:42 -04002802 handleError(drawFramebuffer->blit(this, srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002803}
Jamie Madillc29968b2016-01-20 11:17:23 -05002804
2805void Context::clear(GLbitfield mask)
2806{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002807 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002808 handleError(mGLState.getDrawFramebuffer()->clear(this, mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002809}
2810
2811void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2812{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002813 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002814 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002815}
2816
2817void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2818{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002819 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002820 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002821}
2822
2823void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2824{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002825 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002826 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002827}
2828
2829void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2830{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002831 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002832 ASSERT(framebufferObject);
2833
2834 // If a buffer is not present, the clear has no effect
2835 if (framebufferObject->getDepthbuffer() == nullptr &&
2836 framebufferObject->getStencilbuffer() == nullptr)
2837 {
2838 return;
2839 }
2840
Jamie Madillad9f24e2016-02-12 09:27:24 -05002841 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002842 handleError(framebufferObject->clearBufferfi(this, buffer, drawbuffer, depth, stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002843}
2844
2845void Context::readPixels(GLint x,
2846 GLint y,
2847 GLsizei width,
2848 GLsizei height,
2849 GLenum format,
2850 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002851 void *pixels)
Jamie Madillc29968b2016-01-20 11:17:23 -05002852{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002853 if (width == 0 || height == 0)
2854 {
2855 return;
2856 }
2857
Jamie Madillad9f24e2016-02-12 09:27:24 -05002858 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002859
Jamie Madillb6664922017-07-25 12:55:04 -04002860 Framebuffer *readFBO = mGLState.getReadFramebuffer();
2861 ASSERT(readFBO);
Jamie Madillc29968b2016-01-20 11:17:23 -05002862
2863 Rectangle area(x, y, width, height);
Jamie Madillb6664922017-07-25 12:55:04 -04002864 handleError(readFBO->readPixels(this, area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002865}
2866
2867void Context::copyTexImage2D(GLenum target,
2868 GLint level,
2869 GLenum internalformat,
2870 GLint x,
2871 GLint y,
2872 GLsizei width,
2873 GLsizei height,
2874 GLint border)
2875{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002876 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002877 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002878
Jamie Madillc29968b2016-01-20 11:17:23 -05002879 Rectangle sourceArea(x, y, width, height);
2880
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002881 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002882 Texture *texture =
2883 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002884 handleError(texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002885}
2886
2887void Context::copyTexSubImage2D(GLenum target,
2888 GLint level,
2889 GLint xoffset,
2890 GLint yoffset,
2891 GLint x,
2892 GLint y,
2893 GLsizei width,
2894 GLsizei height)
2895{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002896 if (width == 0 || height == 0)
2897 {
2898 return;
2899 }
2900
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002901 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002902 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002903
Jamie Madillc29968b2016-01-20 11:17:23 -05002904 Offset destOffset(xoffset, yoffset, 0);
2905 Rectangle sourceArea(x, y, width, height);
2906
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002907 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002908 Texture *texture =
2909 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002910 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002911}
2912
2913void Context::copyTexSubImage3D(GLenum target,
2914 GLint level,
2915 GLint xoffset,
2916 GLint yoffset,
2917 GLint zoffset,
2918 GLint x,
2919 GLint y,
2920 GLsizei width,
2921 GLsizei height)
2922{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002923 if (width == 0 || height == 0)
2924 {
2925 return;
2926 }
2927
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002928 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002929 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002930
Jamie Madillc29968b2016-01-20 11:17:23 -05002931 Offset destOffset(xoffset, yoffset, zoffset);
2932 Rectangle sourceArea(x, y, width, height);
2933
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002934 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002935 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002936 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002937}
2938
2939void Context::framebufferTexture2D(GLenum target,
2940 GLenum attachment,
2941 GLenum textarget,
2942 GLuint texture,
2943 GLint level)
2944{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002945 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002946 ASSERT(framebuffer);
2947
2948 if (texture != 0)
2949 {
2950 Texture *textureObj = getTexture(texture);
2951
2952 ImageIndex index = ImageIndex::MakeInvalid();
2953
2954 if (textarget == GL_TEXTURE_2D)
2955 {
2956 index = ImageIndex::Make2D(level);
2957 }
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002958 else if (textarget == GL_TEXTURE_RECTANGLE_ANGLE)
2959 {
2960 index = ImageIndex::MakeRectangle(level);
2961 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08002962 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
2963 {
2964 ASSERT(level == 0);
2965 index = ImageIndex::Make2DMultisample();
2966 }
Jamie Madillc29968b2016-01-20 11:17:23 -05002967 else
2968 {
2969 ASSERT(IsCubeMapTextureTarget(textarget));
2970 index = ImageIndex::MakeCube(textarget, level);
2971 }
2972
Jamie Madilla02315b2017-02-23 14:14:47 -05002973 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
Jamie Madillc29968b2016-01-20 11:17:23 -05002974 }
2975 else
2976 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002977 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002978 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002979
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002980 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002981}
2982
2983void Context::framebufferRenderbuffer(GLenum target,
2984 GLenum attachment,
2985 GLenum renderbuffertarget,
2986 GLuint renderbuffer)
2987{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002988 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002989 ASSERT(framebuffer);
2990
2991 if (renderbuffer != 0)
2992 {
2993 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
Jamie Madilla02315b2017-02-23 14:14:47 -05002994
2995 framebuffer->setAttachment(this, GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
Jamie Madillc29968b2016-01-20 11:17:23 -05002996 renderbufferObject);
2997 }
2998 else
2999 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003000 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003001 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003002
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003003 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003004}
3005
3006void Context::framebufferTextureLayer(GLenum target,
3007 GLenum attachment,
3008 GLuint texture,
3009 GLint level,
3010 GLint layer)
3011{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003012 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003013 ASSERT(framebuffer);
3014
3015 if (texture != 0)
3016 {
3017 Texture *textureObject = getTexture(texture);
3018
3019 ImageIndex index = ImageIndex::MakeInvalid();
3020
3021 if (textureObject->getTarget() == GL_TEXTURE_3D)
3022 {
3023 index = ImageIndex::Make3D(level, layer);
3024 }
3025 else
3026 {
3027 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
3028 index = ImageIndex::Make2DArray(level, layer);
3029 }
3030
Jamie Madilla02315b2017-02-23 14:14:47 -05003031 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObject);
Jamie Madillc29968b2016-01-20 11:17:23 -05003032 }
3033 else
3034 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003035 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003036 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003037
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003038 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003039}
3040
Martin Radev137032d2017-07-13 10:11:12 +03003041void Context::framebufferTextureMultiviewLayeredANGLE(GLenum target,
3042 GLenum attachment,
3043 GLuint texture,
3044 GLint level,
3045 GLint baseViewIndex,
3046 GLsizei numViews)
3047{
Martin Radev82ef7742017-08-08 17:44:58 +03003048 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
3049 ASSERT(framebuffer);
3050
3051 if (texture != 0)
3052 {
3053 Texture *textureObj = getTexture(texture);
3054
Martin Radev18b75ba2017-08-15 15:50:40 +03003055 ImageIndex index = ImageIndex::Make2DArrayRange(level, baseViewIndex, numViews);
Martin Radev82ef7742017-08-08 17:44:58 +03003056 framebuffer->setAttachmentMultiviewLayered(this, GL_TEXTURE, attachment, index, textureObj,
3057 numViews, baseViewIndex);
3058 }
3059 else
3060 {
3061 framebuffer->resetAttachment(this, attachment);
3062 }
3063
3064 mGLState.setObjectDirty(target);
Martin Radev137032d2017-07-13 10:11:12 +03003065}
3066
3067void Context::framebufferTextureMultiviewSideBySideANGLE(GLenum target,
3068 GLenum attachment,
3069 GLuint texture,
3070 GLint level,
3071 GLsizei numViews,
3072 const GLint *viewportOffsets)
3073{
Martin Radev5dae57b2017-07-14 16:15:55 +03003074 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
3075 ASSERT(framebuffer);
3076
3077 if (texture != 0)
3078 {
3079 Texture *textureObj = getTexture(texture);
3080
3081 ImageIndex index = ImageIndex::Make2D(level);
3082 framebuffer->setAttachmentMultiviewSideBySide(this, GL_TEXTURE, attachment, index,
3083 textureObj, numViews, viewportOffsets);
3084 }
3085 else
3086 {
3087 framebuffer->resetAttachment(this, attachment);
3088 }
3089
3090 mGLState.setObjectDirty(target);
Martin Radev137032d2017-07-13 10:11:12 +03003091}
3092
Jamie Madillc29968b2016-01-20 11:17:23 -05003093void Context::drawBuffers(GLsizei n, const GLenum *bufs)
3094{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003095 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003096 ASSERT(framebuffer);
3097 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003098 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003099}
3100
3101void Context::readBuffer(GLenum mode)
3102{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003103 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003104 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003105 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003106}
3107
3108void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
3109{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003110 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003111 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003112
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003113 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003114 ASSERT(framebuffer);
3115
3116 // The specification isn't clear what should be done when the framebuffer isn't complete.
3117 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill4928b7c2017-06-20 12:57:39 -04003118 handleError(framebuffer->discard(this, numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003119}
3120
3121void Context::invalidateFramebuffer(GLenum target,
3122 GLsizei numAttachments,
3123 const GLenum *attachments)
3124{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003125 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003126 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003127
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003128 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003129 ASSERT(framebuffer);
3130
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003131 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003132 {
Jamie Madill437fa652016-05-03 15:13:24 -04003133 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003134 }
Jamie Madill437fa652016-05-03 15:13:24 -04003135
Jamie Madill4928b7c2017-06-20 12:57:39 -04003136 handleError(framebuffer->invalidate(this, numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003137}
3138
3139void Context::invalidateSubFramebuffer(GLenum target,
3140 GLsizei numAttachments,
3141 const GLenum *attachments,
3142 GLint x,
3143 GLint y,
3144 GLsizei width,
3145 GLsizei height)
3146{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003147 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003148 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003149
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003150 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003151 ASSERT(framebuffer);
3152
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003153 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003154 {
Jamie Madill437fa652016-05-03 15:13:24 -04003155 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003156 }
Jamie Madill437fa652016-05-03 15:13:24 -04003157
3158 Rectangle area(x, y, width, height);
Jamie Madill4928b7c2017-06-20 12:57:39 -04003159 handleError(framebuffer->invalidateSub(this, numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05003160}
3161
Jamie Madill73a84962016-02-12 09:27:23 -05003162void Context::texImage2D(GLenum target,
3163 GLint level,
3164 GLint internalformat,
3165 GLsizei width,
3166 GLsizei height,
3167 GLint border,
3168 GLenum format,
3169 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003170 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003171{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003172 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003173
3174 Extents size(width, height, 1);
3175 Texture *texture =
3176 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003177 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3178 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003179}
3180
3181void Context::texImage3D(GLenum target,
3182 GLint level,
3183 GLint internalformat,
3184 GLsizei width,
3185 GLsizei height,
3186 GLsizei depth,
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, depth);
3195 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003196 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3197 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003198}
3199
3200void Context::texSubImage2D(GLenum target,
3201 GLint level,
3202 GLint xoffset,
3203 GLint yoffset,
3204 GLsizei width,
3205 GLsizei height,
3206 GLenum format,
3207 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003208 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003209{
3210 // Zero sized uploads are valid but no-ops
3211 if (width == 0 || height == 0)
3212 {
3213 return;
3214 }
3215
Jamie Madillad9f24e2016-02-12 09:27:24 -05003216 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003217
3218 Box area(xoffset, yoffset, 0, width, height, 1);
3219 Texture *texture =
3220 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003221 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3222 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003223}
3224
3225void Context::texSubImage3D(GLenum target,
3226 GLint level,
3227 GLint xoffset,
3228 GLint yoffset,
3229 GLint zoffset,
3230 GLsizei width,
3231 GLsizei height,
3232 GLsizei depth,
3233 GLenum format,
3234 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003235 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003236{
3237 // Zero sized uploads are valid but no-ops
3238 if (width == 0 || height == 0 || depth == 0)
3239 {
3240 return;
3241 }
3242
Jamie Madillad9f24e2016-02-12 09:27:24 -05003243 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003244
3245 Box area(xoffset, yoffset, zoffset, width, height, depth);
3246 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003247 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3248 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003249}
3250
3251void Context::compressedTexImage2D(GLenum target,
3252 GLint level,
3253 GLenum internalformat,
3254 GLsizei width,
3255 GLsizei height,
3256 GLint border,
3257 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003258 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003259{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003260 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003261
3262 Extents size(width, height, 1);
3263 Texture *texture =
3264 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003265 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003266 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003267 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003268}
3269
3270void Context::compressedTexImage3D(GLenum target,
3271 GLint level,
3272 GLenum internalformat,
3273 GLsizei width,
3274 GLsizei height,
3275 GLsizei depth,
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, depth);
3283 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003284 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003285 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003286 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003287}
3288
3289void Context::compressedTexSubImage2D(GLenum target,
3290 GLint level,
3291 GLint xoffset,
3292 GLint yoffset,
3293 GLsizei width,
3294 GLsizei height,
3295 GLenum format,
3296 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003297 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003298{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003299 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003300
3301 Box area(xoffset, yoffset, 0, width, height, 1);
3302 Texture *texture =
3303 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003304 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003305 format, imageSize,
3306 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003307}
3308
3309void Context::compressedTexSubImage3D(GLenum target,
3310 GLint level,
3311 GLint xoffset,
3312 GLint yoffset,
3313 GLint zoffset,
3314 GLsizei width,
3315 GLsizei height,
3316 GLsizei depth,
3317 GLenum format,
3318 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003319 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003320{
3321 // Zero sized uploads are valid but no-ops
3322 if (width == 0 || height == 0)
3323 {
3324 return;
3325 }
3326
Jamie Madillad9f24e2016-02-12 09:27:24 -05003327 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003328
3329 Box area(xoffset, yoffset, zoffset, width, height, depth);
3330 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003331 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003332 format, imageSize,
3333 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003334}
3335
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003336void Context::generateMipmap(GLenum target)
3337{
3338 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003339 handleError(texture->generateMipmap(this));
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003340}
3341
Geoff Lang97073d12016-04-20 10:42:34 -07003342void Context::copyTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003343 GLint sourceLevel,
3344 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003345 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003346 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003347 GLint internalFormat,
3348 GLenum destType,
3349 GLboolean unpackFlipY,
3350 GLboolean unpackPremultiplyAlpha,
3351 GLboolean unpackUnmultiplyAlpha)
3352{
3353 syncStateForTexImage();
3354
3355 gl::Texture *sourceTexture = getTexture(sourceId);
3356 gl::Texture *destTexture = getTexture(destId);
Geoff Langfc72a072017-03-24 14:52:39 -04003357 handleError(destTexture->copyTexture(
3358 this, destTarget, destLevel, internalFormat, destType, sourceLevel, unpackFlipY == GL_TRUE,
3359 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003360}
3361
3362void Context::copySubTextureCHROMIUM(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 xoffset,
3368 GLint yoffset,
3369 GLint x,
3370 GLint y,
3371 GLsizei width,
3372 GLsizei height,
3373 GLboolean unpackFlipY,
3374 GLboolean unpackPremultiplyAlpha,
3375 GLboolean unpackUnmultiplyAlpha)
3376{
3377 // Zero sized copies are valid but no-ops
3378 if (width == 0 || height == 0)
3379 {
3380 return;
3381 }
3382
3383 syncStateForTexImage();
3384
3385 gl::Texture *sourceTexture = getTexture(sourceId);
3386 gl::Texture *destTexture = getTexture(destId);
3387 Offset offset(xoffset, yoffset, 0);
3388 Rectangle area(x, y, width, height);
Geoff Langfc72a072017-03-24 14:52:39 -04003389 handleError(destTexture->copySubTexture(
3390 this, destTarget, destLevel, offset, sourceLevel, area, unpackFlipY == GL_TRUE,
3391 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003392}
3393
Geoff Lang47110bf2016-04-20 11:13:22 -07003394void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3395{
3396 syncStateForTexImage();
3397
3398 gl::Texture *sourceTexture = getTexture(sourceId);
3399 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003400 handleError(destTexture->copyCompressedTexture(this, sourceTexture));
Geoff Lang47110bf2016-04-20 11:13:22 -07003401}
3402
Geoff Lang496c02d2016-10-20 11:38:11 -07003403void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003404{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003405 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003406 ASSERT(buffer);
3407
Geoff Lang496c02d2016-10-20 11:38:11 -07003408 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003409}
3410
Jamie Madill876429b2017-04-20 15:46:24 -04003411void *Context::mapBuffer(GLenum target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003412{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003413 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003414 ASSERT(buffer);
3415
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003416 Error error = buffer->map(this, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003417 if (error.isError())
3418 {
Jamie Madill437fa652016-05-03 15:13:24 -04003419 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003420 return nullptr;
3421 }
3422
3423 return buffer->getMapPointer();
3424}
3425
3426GLboolean Context::unmapBuffer(GLenum target)
3427{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003428 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003429 ASSERT(buffer);
3430
3431 GLboolean result;
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003432 Error error = buffer->unmap(this, &result);
Olli Etuaho4f667482016-03-30 15:56:35 +03003433 if (error.isError())
3434 {
Jamie Madill437fa652016-05-03 15:13:24 -04003435 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003436 return GL_FALSE;
3437 }
3438
3439 return result;
3440}
3441
Jamie Madill876429b2017-04-20 15:46:24 -04003442void *Context::mapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003443{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003444 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003445 ASSERT(buffer);
3446
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003447 Error error = buffer->mapRange(this, offset, length, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003448 if (error.isError())
3449 {
Jamie Madill437fa652016-05-03 15:13:24 -04003450 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003451 return nullptr;
3452 }
3453
3454 return buffer->getMapPointer();
3455}
3456
3457void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3458{
3459 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3460}
3461
Jamie Madillad9f24e2016-02-12 09:27:24 -05003462void Context::syncStateForReadPixels()
3463{
3464 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3465}
3466
3467void Context::syncStateForTexImage()
3468{
3469 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3470}
3471
3472void Context::syncStateForClear()
3473{
3474 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3475}
3476
3477void Context::syncStateForBlit()
3478{
3479 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3480}
3481
Jamie Madillc20ab272016-06-09 07:20:46 -07003482void Context::activeTexture(GLenum texture)
3483{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003484 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003485}
3486
Jamie Madill876429b2017-04-20 15:46:24 -04003487void Context::blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003488{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003489 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003490}
3491
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003492void Context::blendEquation(GLenum mode)
3493{
3494 mGLState.setBlendEquation(mode, mode);
3495}
3496
Jamie Madillc20ab272016-06-09 07:20:46 -07003497void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3498{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003499 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003500}
3501
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003502void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3503{
3504 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3505}
3506
Jamie Madillc20ab272016-06-09 07:20:46 -07003507void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3508{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003509 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003510}
3511
Jamie Madill876429b2017-04-20 15:46:24 -04003512void Context::clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003513{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003514 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003515}
3516
Jamie Madill876429b2017-04-20 15:46:24 -04003517void Context::clearDepthf(GLfloat depth)
Jamie Madillc20ab272016-06-09 07:20:46 -07003518{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003519 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003520}
3521
3522void Context::clearStencil(GLint s)
3523{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003524 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003525}
3526
3527void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3528{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003529 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003530}
3531
3532void Context::cullFace(GLenum mode)
3533{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003534 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003535}
3536
3537void Context::depthFunc(GLenum func)
3538{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003539 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003540}
3541
3542void Context::depthMask(GLboolean flag)
3543{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003544 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003545}
3546
Jamie Madill876429b2017-04-20 15:46:24 -04003547void Context::depthRangef(GLfloat zNear, GLfloat zFar)
Jamie Madillc20ab272016-06-09 07:20:46 -07003548{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003549 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003550}
3551
3552void Context::disable(GLenum cap)
3553{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003554 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003555}
3556
3557void Context::disableVertexAttribArray(GLuint index)
3558{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003559 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003560}
3561
3562void Context::enable(GLenum cap)
3563{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003564 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003565}
3566
3567void Context::enableVertexAttribArray(GLuint index)
3568{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003569 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003570}
3571
3572void Context::frontFace(GLenum mode)
3573{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003574 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003575}
3576
3577void Context::hint(GLenum target, GLenum mode)
3578{
3579 switch (target)
3580 {
3581 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003582 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003583 break;
3584
3585 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003586 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003587 break;
3588
3589 default:
3590 UNREACHABLE();
3591 return;
3592 }
3593}
3594
3595void Context::lineWidth(GLfloat width)
3596{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003597 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003598}
3599
3600void Context::pixelStorei(GLenum pname, GLint param)
3601{
3602 switch (pname)
3603 {
3604 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003605 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003606 break;
3607
3608 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003609 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003610 break;
3611
3612 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003613 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003614 break;
3615
3616 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003617 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003618 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003619 break;
3620
3621 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003622 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003623 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003624 break;
3625
3626 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003627 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003628 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003629 break;
3630
3631 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003632 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003633 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003634 break;
3635
3636 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003637 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003638 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003639 break;
3640
3641 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003642 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003643 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003644 break;
3645
3646 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003647 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003648 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003649 break;
3650
3651 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003652 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003653 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003654 break;
3655
3656 default:
3657 UNREACHABLE();
3658 return;
3659 }
3660}
3661
3662void Context::polygonOffset(GLfloat factor, GLfloat units)
3663{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003664 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003665}
3666
Jamie Madill876429b2017-04-20 15:46:24 -04003667void Context::sampleCoverage(GLfloat value, GLboolean invert)
Jamie Madillc20ab272016-06-09 07:20:46 -07003668{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003669 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003670}
3671
3672void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3673{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003674 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003675}
3676
3677void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3678{
3679 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3680 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003681 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003682 }
3683
3684 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3685 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003686 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003687 }
3688}
3689
3690void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3691{
3692 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3693 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003694 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003695 }
3696
3697 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3698 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003699 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003700 }
3701}
3702
3703void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3704{
3705 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3706 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003707 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003708 }
3709
3710 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3711 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003712 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003713 }
3714}
3715
3716void Context::vertexAttrib1f(GLuint index, GLfloat x)
3717{
3718 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003719 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003720}
3721
3722void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3723{
3724 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003725 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003726}
3727
3728void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3729{
3730 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003731 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003732}
3733
3734void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3735{
3736 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003737 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003738}
3739
3740void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3741{
3742 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003743 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003744}
3745
3746void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3747{
3748 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003749 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003750}
3751
3752void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3753{
3754 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003755 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003756}
3757
3758void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3759{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003760 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003761}
3762
3763void Context::vertexAttribPointer(GLuint index,
3764 GLint size,
3765 GLenum type,
3766 GLboolean normalized,
3767 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003768 const void *ptr)
Jamie Madillc20ab272016-06-09 07:20:46 -07003769{
Shaodde78e82017-05-22 14:13:27 +08003770 mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size,
3771 type, normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003772}
3773
Shao80957d92017-02-20 21:25:59 +08003774void Context::vertexAttribFormat(GLuint attribIndex,
3775 GLint size,
3776 GLenum type,
3777 GLboolean normalized,
3778 GLuint relativeOffset)
3779{
3780 mGLState.setVertexAttribFormat(attribIndex, size, type, normalized == GL_TRUE, false,
3781 relativeOffset);
3782}
3783
3784void Context::vertexAttribIFormat(GLuint attribIndex,
3785 GLint size,
3786 GLenum type,
3787 GLuint relativeOffset)
3788{
3789 mGLState.setVertexAttribFormat(attribIndex, size, type, false, true, relativeOffset);
3790}
3791
3792void Context::vertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
3793{
Shaodde78e82017-05-22 14:13:27 +08003794 mGLState.setVertexAttribBinding(this, attribIndex, bindingIndex);
Shao80957d92017-02-20 21:25:59 +08003795}
3796
3797void Context::setVertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
3798{
3799 mGLState.setVertexBindingDivisor(bindingIndex, divisor);
3800}
3801
Jamie Madillc20ab272016-06-09 07:20:46 -07003802void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3803{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003804 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003805}
3806
3807void Context::vertexAttribIPointer(GLuint index,
3808 GLint size,
3809 GLenum type,
3810 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003811 const void *pointer)
Jamie Madillc20ab272016-06-09 07:20:46 -07003812{
Shaodde78e82017-05-22 14:13:27 +08003813 mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size,
3814 type, false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003815}
3816
3817void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3818{
3819 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003820 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003821}
3822
3823void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3824{
3825 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003826 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003827}
3828
3829void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3830{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003831 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003832}
3833
3834void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3835{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003836 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003837}
3838
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003839void Context::getVertexAttribiv(GLuint index, GLenum pname, GLint *params)
3840{
3841 const VertexAttribCurrentValueData &currentValues =
3842 getGLState().getVertexAttribCurrentValue(index);
3843 const VertexArray *vao = getGLState().getVertexArray();
3844 QueryVertexAttribiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3845 currentValues, pname, params);
3846}
3847
3848void Context::getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
3849{
3850 const VertexAttribCurrentValueData &currentValues =
3851 getGLState().getVertexAttribCurrentValue(index);
3852 const VertexArray *vao = getGLState().getVertexArray();
3853 QueryVertexAttribfv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3854 currentValues, pname, params);
3855}
3856
3857void Context::getVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
3858{
3859 const VertexAttribCurrentValueData &currentValues =
3860 getGLState().getVertexAttribCurrentValue(index);
3861 const VertexArray *vao = getGLState().getVertexArray();
3862 QueryVertexAttribIiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3863 currentValues, pname, params);
3864}
3865
3866void Context::getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
3867{
3868 const VertexAttribCurrentValueData &currentValues =
3869 getGLState().getVertexAttribCurrentValue(index);
3870 const VertexArray *vao = getGLState().getVertexArray();
3871 QueryVertexAttribIuiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3872 currentValues, pname, params);
3873}
3874
Jamie Madill876429b2017-04-20 15:46:24 -04003875void Context::getVertexAttribPointerv(GLuint index, GLenum pname, void **pointer)
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003876{
3877 const VertexAttribute &attrib = getGLState().getVertexArray()->getVertexAttribute(index);
3878 QueryVertexAttribPointerv(attrib, pname, pointer);
3879}
3880
Jamie Madillc20ab272016-06-09 07:20:46 -07003881void Context::debugMessageControl(GLenum source,
3882 GLenum type,
3883 GLenum severity,
3884 GLsizei count,
3885 const GLuint *ids,
3886 GLboolean enabled)
3887{
3888 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003889 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3890 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003891}
3892
3893void Context::debugMessageInsert(GLenum source,
3894 GLenum type,
3895 GLuint id,
3896 GLenum severity,
3897 GLsizei length,
3898 const GLchar *buf)
3899{
3900 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003901 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003902}
3903
3904void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3905{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003906 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003907}
3908
3909GLuint Context::getDebugMessageLog(GLuint count,
3910 GLsizei bufSize,
3911 GLenum *sources,
3912 GLenum *types,
3913 GLuint *ids,
3914 GLenum *severities,
3915 GLsizei *lengths,
3916 GLchar *messageLog)
3917{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003918 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3919 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003920}
3921
3922void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3923{
3924 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003925 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003926}
3927
3928void Context::popDebugGroup()
3929{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003930 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003931}
3932
Jamie Madill876429b2017-04-20 15:46:24 -04003933void Context::bufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage)
Jamie Madill29639852016-09-02 15:00:09 -04003934{
3935 Buffer *buffer = mGLState.getTargetBuffer(target);
3936 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003937 handleError(buffer->bufferData(this, target, data, size, usage));
Jamie Madill29639852016-09-02 15:00:09 -04003938}
3939
Jamie Madill876429b2017-04-20 15:46:24 -04003940void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04003941{
3942 if (data == nullptr)
3943 {
3944 return;
3945 }
3946
3947 Buffer *buffer = mGLState.getTargetBuffer(target);
3948 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003949 handleError(buffer->bufferSubData(this, target, data, size, offset));
Jamie Madill29639852016-09-02 15:00:09 -04003950}
3951
Jamie Madillef300b12016-10-07 15:12:09 -04003952void Context::attachShader(GLuint program, GLuint shader)
3953{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003954 auto programObject = mState.mShaderPrograms->getProgram(program);
3955 auto shaderObject = mState.mShaderPrograms->getShader(shader);
Jamie Madillef300b12016-10-07 15:12:09 -04003956 ASSERT(programObject && shaderObject);
3957 programObject->attachShader(shaderObject);
3958}
3959
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003960const Workarounds &Context::getWorkarounds() const
3961{
3962 return mWorkarounds;
3963}
3964
Jamie Madillb0817d12016-11-01 15:48:31 -04003965void Context::copyBufferSubData(GLenum readTarget,
3966 GLenum writeTarget,
3967 GLintptr readOffset,
3968 GLintptr writeOffset,
3969 GLsizeiptr size)
3970{
3971 // if size is zero, the copy is a successful no-op
3972 if (size == 0)
3973 {
3974 return;
3975 }
3976
3977 // TODO(jmadill): cache these.
3978 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3979 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3980
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003981 handleError(writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size));
Jamie Madillb0817d12016-11-01 15:48:31 -04003982}
3983
Jamie Madill01a80ee2016-11-07 12:06:18 -05003984void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3985{
3986 Program *programObject = getProgram(program);
3987 // TODO(jmadill): Re-use this from the validation if possible.
3988 ASSERT(programObject);
3989 programObject->bindAttributeLocation(index, name);
3990}
3991
3992void Context::bindBuffer(GLenum target, GLuint buffer)
3993{
3994 switch (target)
3995 {
3996 case GL_ARRAY_BUFFER:
3997 bindArrayBuffer(buffer);
3998 break;
3999 case GL_ELEMENT_ARRAY_BUFFER:
4000 bindElementArrayBuffer(buffer);
4001 break;
4002 case GL_COPY_READ_BUFFER:
4003 bindCopyReadBuffer(buffer);
4004 break;
4005 case GL_COPY_WRITE_BUFFER:
4006 bindCopyWriteBuffer(buffer);
4007 break;
4008 case GL_PIXEL_PACK_BUFFER:
4009 bindPixelPackBuffer(buffer);
4010 break;
4011 case GL_PIXEL_UNPACK_BUFFER:
4012 bindPixelUnpackBuffer(buffer);
4013 break;
4014 case GL_UNIFORM_BUFFER:
4015 bindGenericUniformBuffer(buffer);
4016 break;
4017 case GL_TRANSFORM_FEEDBACK_BUFFER:
4018 bindGenericTransformFeedbackBuffer(buffer);
4019 break;
Geoff Lang3b573612016-10-31 14:08:10 -04004020 case GL_ATOMIC_COUNTER_BUFFER:
Jiajia Qin6eafb042016-12-27 17:04:07 +08004021 bindGenericAtomicCounterBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004022 break;
4023 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08004024 bindGenericShaderStorageBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004025 break;
4026 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08004027 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004028 break;
4029 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05004030 if (buffer != 0)
4031 {
4032 // Binding buffers to this binding point is not implemented yet.
4033 UNIMPLEMENTED();
4034 }
Geoff Lang3b573612016-10-31 14:08:10 -04004035 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05004036
4037 default:
4038 UNREACHABLE();
4039 break;
4040 }
4041}
4042
Jiajia Qin6eafb042016-12-27 17:04:07 +08004043void Context::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
4044{
4045 bindBufferRange(target, index, buffer, 0, 0);
4046}
4047
4048void Context::bindBufferRange(GLenum target,
4049 GLuint index,
4050 GLuint buffer,
4051 GLintptr offset,
4052 GLsizeiptr size)
4053{
4054 switch (target)
4055 {
4056 case GL_TRANSFORM_FEEDBACK_BUFFER:
4057 bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
4058 bindGenericTransformFeedbackBuffer(buffer);
4059 break;
4060 case GL_UNIFORM_BUFFER:
4061 bindIndexedUniformBuffer(buffer, index, offset, size);
4062 bindGenericUniformBuffer(buffer);
4063 break;
4064 case GL_ATOMIC_COUNTER_BUFFER:
4065 bindIndexedAtomicCounterBuffer(buffer, index, offset, size);
4066 bindGenericAtomicCounterBuffer(buffer);
4067 break;
4068 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08004069 bindIndexedShaderStorageBuffer(buffer, index, offset, size);
4070 bindGenericShaderStorageBuffer(buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08004071 break;
4072 default:
4073 UNREACHABLE();
4074 break;
4075 }
4076}
4077
Jamie Madill01a80ee2016-11-07 12:06:18 -05004078void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
4079{
4080 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4081 {
4082 bindReadFramebuffer(framebuffer);
4083 }
4084
4085 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4086 {
4087 bindDrawFramebuffer(framebuffer);
4088 }
4089}
4090
4091void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
4092{
4093 ASSERT(target == GL_RENDERBUFFER);
4094 Renderbuffer *object =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05004095 mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
Jamie Madill4928b7c2017-06-20 12:57:39 -04004096 mGLState.setRenderbufferBinding(this, object);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004097}
4098
JiangYizhoubddc46b2016-12-09 09:50:51 +08004099void Context::texStorage2DMultisample(GLenum target,
4100 GLsizei samples,
4101 GLenum internalformat,
4102 GLsizei width,
4103 GLsizei height,
4104 GLboolean fixedsamplelocations)
4105{
4106 Extents size(width, height, 1);
4107 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05004108 handleError(texture->setStorageMultisample(this, target, samples, internalformat, size,
JiangYizhoubddc46b2016-12-09 09:50:51 +08004109 fixedsamplelocations));
4110}
4111
4112void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
4113{
Jamie Madilldd43e6c2017-03-24 14:18:49 -04004114 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
JiangYizhoubddc46b2016-12-09 09:50:51 +08004115 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
4116
4117 switch (pname)
4118 {
4119 case GL_SAMPLE_POSITION:
4120 handleError(framebuffer->getSamplePosition(index, val));
4121 break;
4122 default:
4123 UNREACHABLE();
4124 }
4125}
4126
Jamie Madille8fb6402017-02-14 17:56:40 -05004127void Context::renderbufferStorage(GLenum target,
4128 GLenum internalformat,
4129 GLsizei width,
4130 GLsizei height)
4131{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004132 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4133 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
4134
Jamie Madille8fb6402017-02-14 17:56:40 -05004135 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4928b7c2017-06-20 12:57:39 -04004136 handleError(renderbuffer->setStorage(this, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004137}
4138
4139void Context::renderbufferStorageMultisample(GLenum target,
4140 GLsizei samples,
4141 GLenum internalformat,
4142 GLsizei width,
4143 GLsizei height)
4144{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004145 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4146 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
Jamie Madille8fb6402017-02-14 17:56:40 -05004147
4148 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004149 handleError(
Jamie Madill4928b7c2017-06-20 12:57:39 -04004150 renderbuffer->setStorageMultisample(this, samples, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004151}
4152
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004153void Context::getSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)
4154{
Jamie Madill70b5bb02017-08-28 13:32:37 -04004155 const Sync *syncObject = getSync(sync);
Geoff Lang82483b92017-04-11 15:33:00 -04004156 handleError(QuerySynciv(syncObject, pname, bufSize, length, values));
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004157}
4158
JiangYizhoue18e6392017-02-20 10:32:23 +08004159void Context::getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
4160{
4161 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4162 QueryFramebufferParameteriv(framebuffer, pname, params);
4163}
4164
4165void Context::setFramebufferParameteri(GLenum target, GLenum pname, GLint param)
4166{
4167 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4168 SetFramebufferParameteri(framebuffer, pname, param);
4169}
4170
Jamie Madillb3f26b92017-07-19 15:07:41 -04004171Error Context::getScratchBuffer(size_t requstedSizeBytes,
4172 angle::MemoryBuffer **scratchBufferOut) const
Jamie Madille14951e2017-03-09 18:55:16 -05004173{
Jamie Madillb3f26b92017-07-19 15:07:41 -04004174 if (!mScratchBuffer.get(requstedSizeBytes, scratchBufferOut))
4175 {
4176 return OutOfMemory() << "Failed to allocate internal buffer.";
4177 }
4178 return NoError();
4179}
4180
4181Error Context::getZeroFilledBuffer(size_t requstedSizeBytes,
4182 angle::MemoryBuffer **zeroBufferOut) const
4183{
4184 if (!mZeroFilledBuffer.getInitialized(requstedSizeBytes, zeroBufferOut, 0))
Jamie Madille14951e2017-03-09 18:55:16 -05004185 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004186 return OutOfMemory() << "Failed to allocate internal buffer.";
Jamie Madille14951e2017-03-09 18:55:16 -05004187 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004188 return NoError();
Jamie Madille14951e2017-03-09 18:55:16 -05004189}
4190
Xinghua Cao2b396592017-03-29 15:36:04 +08004191void Context::dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ)
4192{
4193 if (numGroupsX == 0u || numGroupsY == 0u || numGroupsZ == 0u)
4194 {
4195 return;
4196 }
4197
Jamie Madillfe548342017-06-19 11:13:24 -04004198 mImplementation->dispatchCompute(this, numGroupsX, numGroupsY, numGroupsZ);
Xinghua Cao2b396592017-03-29 15:36:04 +08004199}
4200
JiangYizhou165361c2017-06-07 14:56:57 +08004201void Context::texStorage2D(GLenum target,
4202 GLsizei levels,
4203 GLenum internalFormat,
4204 GLsizei width,
4205 GLsizei height)
4206{
4207 Extents size(width, height, 1);
4208 Texture *texture = getTargetTexture(target);
4209 handleError(texture->setStorage(this, target, levels, internalFormat, size));
4210}
4211
4212void Context::texStorage3D(GLenum target,
4213 GLsizei levels,
4214 GLenum internalFormat,
4215 GLsizei width,
4216 GLsizei height,
4217 GLsizei depth)
4218{
4219 Extents size(width, height, depth);
4220 Texture *texture = getTargetTexture(target);
4221 handleError(texture->setStorage(this, target, levels, internalFormat, size));
4222}
4223
Jamie Madillc1d770e2017-04-13 17:31:24 -04004224GLenum Context::checkFramebufferStatus(GLenum target)
4225{
4226 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4227 ASSERT(framebuffer);
4228
4229 return framebuffer->checkStatus(this);
4230}
4231
4232void Context::compileShader(GLuint shader)
4233{
4234 Shader *shaderObject = GetValidShader(this, shader);
4235 if (!shaderObject)
4236 {
4237 return;
4238 }
4239 shaderObject->compile(this);
4240}
4241
4242void Context::deleteBuffers(GLsizei n, const GLuint *buffers)
4243{
4244 for (int i = 0; i < n; i++)
4245 {
4246 deleteBuffer(buffers[i]);
4247 }
4248}
4249
4250void Context::deleteFramebuffers(GLsizei n, const GLuint *framebuffers)
4251{
4252 for (int i = 0; i < n; i++)
4253 {
4254 if (framebuffers[i] != 0)
4255 {
4256 deleteFramebuffer(framebuffers[i]);
4257 }
4258 }
4259}
4260
4261void Context::deleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)
4262{
4263 for (int i = 0; i < n; i++)
4264 {
4265 deleteRenderbuffer(renderbuffers[i]);
4266 }
4267}
4268
4269void Context::deleteTextures(GLsizei n, const GLuint *textures)
4270{
4271 for (int i = 0; i < n; i++)
4272 {
4273 if (textures[i] != 0)
4274 {
4275 deleteTexture(textures[i]);
4276 }
4277 }
4278}
4279
4280void Context::detachShader(GLuint program, GLuint shader)
4281{
4282 Program *programObject = getProgram(program);
4283 ASSERT(programObject);
4284
4285 Shader *shaderObject = getShader(shader);
4286 ASSERT(shaderObject);
4287
4288 programObject->detachShader(this, shaderObject);
4289}
4290
4291void Context::genBuffers(GLsizei n, GLuint *buffers)
4292{
4293 for (int i = 0; i < n; i++)
4294 {
4295 buffers[i] = createBuffer();
4296 }
4297}
4298
4299void Context::genFramebuffers(GLsizei n, GLuint *framebuffers)
4300{
4301 for (int i = 0; i < n; i++)
4302 {
4303 framebuffers[i] = createFramebuffer();
4304 }
4305}
4306
4307void Context::genRenderbuffers(GLsizei n, GLuint *renderbuffers)
4308{
4309 for (int i = 0; i < n; i++)
4310 {
4311 renderbuffers[i] = createRenderbuffer();
4312 }
4313}
4314
4315void Context::genTextures(GLsizei n, GLuint *textures)
4316{
4317 for (int i = 0; i < n; i++)
4318 {
4319 textures[i] = createTexture();
4320 }
4321}
4322
4323void Context::getActiveAttrib(GLuint program,
4324 GLuint index,
4325 GLsizei bufsize,
4326 GLsizei *length,
4327 GLint *size,
4328 GLenum *type,
4329 GLchar *name)
4330{
4331 Program *programObject = getProgram(program);
4332 ASSERT(programObject);
4333 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
4334}
4335
4336void Context::getActiveUniform(GLuint program,
4337 GLuint index,
4338 GLsizei bufsize,
4339 GLsizei *length,
4340 GLint *size,
4341 GLenum *type,
4342 GLchar *name)
4343{
4344 Program *programObject = getProgram(program);
4345 ASSERT(programObject);
4346 programObject->getActiveUniform(index, bufsize, length, size, type, name);
4347}
4348
4349void Context::getAttachedShaders(GLuint program, GLsizei maxcount, GLsizei *count, GLuint *shaders)
4350{
4351 Program *programObject = getProgram(program);
4352 ASSERT(programObject);
4353 programObject->getAttachedShaders(maxcount, count, shaders);
4354}
4355
4356GLint Context::getAttribLocation(GLuint program, const GLchar *name)
4357{
4358 Program *programObject = getProgram(program);
4359 ASSERT(programObject);
4360 return programObject->getAttributeLocation(name);
4361}
4362
4363void Context::getBooleanv(GLenum pname, GLboolean *params)
4364{
4365 GLenum nativeType;
4366 unsigned int numParams = 0;
4367 getQueryParameterInfo(pname, &nativeType, &numParams);
4368
4369 if (nativeType == GL_BOOL)
4370 {
4371 getBooleanvImpl(pname, params);
4372 }
4373 else
4374 {
4375 CastStateValues(this, nativeType, pname, numParams, params);
4376 }
4377}
4378
4379void Context::getFloatv(GLenum pname, GLfloat *params)
4380{
4381 GLenum nativeType;
4382 unsigned int numParams = 0;
4383 getQueryParameterInfo(pname, &nativeType, &numParams);
4384
4385 if (nativeType == GL_FLOAT)
4386 {
4387 getFloatvImpl(pname, params);
4388 }
4389 else
4390 {
4391 CastStateValues(this, nativeType, pname, numParams, params);
4392 }
4393}
4394
4395void Context::getIntegerv(GLenum pname, GLint *params)
4396{
4397 GLenum nativeType;
4398 unsigned int numParams = 0;
4399 getQueryParameterInfo(pname, &nativeType, &numParams);
4400
4401 if (nativeType == GL_INT)
4402 {
4403 getIntegervImpl(pname, params);
4404 }
4405 else
4406 {
4407 CastStateValues(this, nativeType, pname, numParams, params);
4408 }
4409}
4410
4411void Context::getProgramiv(GLuint program, GLenum pname, GLint *params)
4412{
4413 Program *programObject = getProgram(program);
4414 ASSERT(programObject);
Jamie Madillffe00c02017-06-27 16:26:55 -04004415 QueryProgramiv(this, programObject, pname, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004416}
4417
Jamie Madillbe849e42017-05-02 15:49:00 -04004418void Context::getProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei *length, GLchar *infolog)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004419{
4420 Program *programObject = getProgram(program);
4421 ASSERT(programObject);
4422 programObject->getInfoLog(bufsize, length, infolog);
4423}
4424
4425void Context::getShaderiv(GLuint shader, GLenum pname, GLint *params)
4426{
4427 Shader *shaderObject = getShader(shader);
4428 ASSERT(shaderObject);
Jamie Madillbd044ed2017-06-05 12:59:21 -04004429 QueryShaderiv(this, shaderObject, pname, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004430}
4431
4432void Context::getShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *infolog)
4433{
4434 Shader *shaderObject = getShader(shader);
4435 ASSERT(shaderObject);
Jamie Madillbd044ed2017-06-05 12:59:21 -04004436 shaderObject->getInfoLog(this, bufsize, length, infolog);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004437}
4438
4439void Context::getShaderPrecisionFormat(GLenum shadertype,
4440 GLenum precisiontype,
4441 GLint *range,
4442 GLint *precision)
4443{
4444 // TODO(jmadill): Compute shaders.
4445
4446 switch (shadertype)
4447 {
4448 case GL_VERTEX_SHADER:
4449 switch (precisiontype)
4450 {
4451 case GL_LOW_FLOAT:
4452 mCaps.vertexLowpFloat.get(range, precision);
4453 break;
4454 case GL_MEDIUM_FLOAT:
4455 mCaps.vertexMediumpFloat.get(range, precision);
4456 break;
4457 case GL_HIGH_FLOAT:
4458 mCaps.vertexHighpFloat.get(range, precision);
4459 break;
4460
4461 case GL_LOW_INT:
4462 mCaps.vertexLowpInt.get(range, precision);
4463 break;
4464 case GL_MEDIUM_INT:
4465 mCaps.vertexMediumpInt.get(range, precision);
4466 break;
4467 case GL_HIGH_INT:
4468 mCaps.vertexHighpInt.get(range, precision);
4469 break;
4470
4471 default:
4472 UNREACHABLE();
4473 return;
4474 }
4475 break;
4476
4477 case GL_FRAGMENT_SHADER:
4478 switch (precisiontype)
4479 {
4480 case GL_LOW_FLOAT:
4481 mCaps.fragmentLowpFloat.get(range, precision);
4482 break;
4483 case GL_MEDIUM_FLOAT:
4484 mCaps.fragmentMediumpFloat.get(range, precision);
4485 break;
4486 case GL_HIGH_FLOAT:
4487 mCaps.fragmentHighpFloat.get(range, precision);
4488 break;
4489
4490 case GL_LOW_INT:
4491 mCaps.fragmentLowpInt.get(range, precision);
4492 break;
4493 case GL_MEDIUM_INT:
4494 mCaps.fragmentMediumpInt.get(range, precision);
4495 break;
4496 case GL_HIGH_INT:
4497 mCaps.fragmentHighpInt.get(range, precision);
4498 break;
4499
4500 default:
4501 UNREACHABLE();
4502 return;
4503 }
4504 break;
4505
4506 default:
4507 UNREACHABLE();
4508 return;
4509 }
4510}
4511
4512void Context::getShaderSource(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source)
4513{
4514 Shader *shaderObject = getShader(shader);
4515 ASSERT(shaderObject);
4516 shaderObject->getSource(bufsize, length, source);
4517}
4518
4519void Context::getUniformfv(GLuint program, GLint location, GLfloat *params)
4520{
4521 Program *programObject = getProgram(program);
4522 ASSERT(programObject);
Jamie Madill54164b02017-08-28 15:17:37 -04004523 programObject->getUniformfv(this, location, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004524}
4525
4526void Context::getUniformiv(GLuint program, GLint location, GLint *params)
4527{
4528 Program *programObject = getProgram(program);
4529 ASSERT(programObject);
Jamie Madill54164b02017-08-28 15:17:37 -04004530 programObject->getUniformiv(this, location, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004531}
4532
4533GLint Context::getUniformLocation(GLuint program, const GLchar *name)
4534{
4535 Program *programObject = getProgram(program);
4536 ASSERT(programObject);
4537 return programObject->getUniformLocation(name);
4538}
4539
4540GLboolean Context::isBuffer(GLuint buffer)
4541{
4542 if (buffer == 0)
4543 {
4544 return GL_FALSE;
4545 }
4546
4547 return (getBuffer(buffer) ? GL_TRUE : GL_FALSE);
4548}
4549
4550GLboolean Context::isEnabled(GLenum cap)
4551{
4552 return mGLState.getEnableFeature(cap);
4553}
4554
4555GLboolean Context::isFramebuffer(GLuint framebuffer)
4556{
4557 if (framebuffer == 0)
4558 {
4559 return GL_FALSE;
4560 }
4561
4562 return (getFramebuffer(framebuffer) ? GL_TRUE : GL_FALSE);
4563}
4564
4565GLboolean Context::isProgram(GLuint program)
4566{
4567 if (program == 0)
4568 {
4569 return GL_FALSE;
4570 }
4571
4572 return (getProgram(program) ? GL_TRUE : GL_FALSE);
4573}
4574
4575GLboolean Context::isRenderbuffer(GLuint renderbuffer)
4576{
4577 if (renderbuffer == 0)
4578 {
4579 return GL_FALSE;
4580 }
4581
4582 return (getRenderbuffer(renderbuffer) ? GL_TRUE : GL_FALSE);
4583}
4584
4585GLboolean Context::isShader(GLuint shader)
4586{
4587 if (shader == 0)
4588 {
4589 return GL_FALSE;
4590 }
4591
4592 return (getShader(shader) ? GL_TRUE : GL_FALSE);
4593}
4594
4595GLboolean Context::isTexture(GLuint texture)
4596{
4597 if (texture == 0)
4598 {
4599 return GL_FALSE;
4600 }
4601
4602 return (getTexture(texture) ? GL_TRUE : GL_FALSE);
4603}
4604
4605void Context::linkProgram(GLuint program)
4606{
4607 Program *programObject = getProgram(program);
4608 ASSERT(programObject);
4609 handleError(programObject->link(this));
Martin Radev0abb7a22017-08-28 15:34:45 +03004610 mGLState.onProgramExecutableChange(programObject);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004611}
4612
4613void Context::releaseShaderCompiler()
4614{
Jamie Madill4928b7c2017-06-20 12:57:39 -04004615 mCompiler.set(this, nullptr);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004616}
4617
4618void Context::shaderBinary(GLsizei n,
4619 const GLuint *shaders,
4620 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04004621 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004622 GLsizei length)
4623{
4624 // No binary shader formats are supported.
4625 UNIMPLEMENTED();
4626}
4627
4628void Context::shaderSource(GLuint shader,
4629 GLsizei count,
4630 const GLchar *const *string,
4631 const GLint *length)
4632{
4633 Shader *shaderObject = getShader(shader);
4634 ASSERT(shaderObject);
4635 shaderObject->setSource(count, string, length);
4636}
4637
4638void Context::stencilFunc(GLenum func, GLint ref, GLuint mask)
4639{
4640 stencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
4641}
4642
4643void Context::stencilMask(GLuint mask)
4644{
4645 stencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4646}
4647
4648void Context::stencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4649{
4650 stencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4651}
4652
4653void Context::uniform1f(GLint location, GLfloat x)
4654{
4655 Program *program = mGLState.getProgram();
4656 program->setUniform1fv(location, 1, &x);
4657}
4658
4659void Context::uniform1fv(GLint location, GLsizei count, const GLfloat *v)
4660{
4661 Program *program = mGLState.getProgram();
4662 program->setUniform1fv(location, count, v);
4663}
4664
4665void Context::uniform1i(GLint location, GLint x)
4666{
4667 Program *program = mGLState.getProgram();
4668 program->setUniform1iv(location, 1, &x);
4669}
4670
4671void Context::uniform1iv(GLint location, GLsizei count, const GLint *v)
4672{
4673 Program *program = mGLState.getProgram();
4674 program->setUniform1iv(location, count, v);
4675}
4676
4677void Context::uniform2f(GLint location, GLfloat x, GLfloat y)
4678{
4679 GLfloat xy[2] = {x, y};
4680 Program *program = mGLState.getProgram();
4681 program->setUniform2fv(location, 1, xy);
4682}
4683
4684void Context::uniform2fv(GLint location, GLsizei count, const GLfloat *v)
4685{
4686 Program *program = mGLState.getProgram();
4687 program->setUniform2fv(location, count, v);
4688}
4689
4690void Context::uniform2i(GLint location, GLint x, GLint y)
4691{
4692 GLint xy[2] = {x, y};
4693 Program *program = mGLState.getProgram();
4694 program->setUniform2iv(location, 1, xy);
4695}
4696
4697void Context::uniform2iv(GLint location, GLsizei count, const GLint *v)
4698{
4699 Program *program = mGLState.getProgram();
4700 program->setUniform2iv(location, count, v);
4701}
4702
4703void Context::uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4704{
4705 GLfloat xyz[3] = {x, y, z};
4706 Program *program = mGLState.getProgram();
4707 program->setUniform3fv(location, 1, xyz);
4708}
4709
4710void Context::uniform3fv(GLint location, GLsizei count, const GLfloat *v)
4711{
4712 Program *program = mGLState.getProgram();
4713 program->setUniform3fv(location, count, v);
4714}
4715
4716void Context::uniform3i(GLint location, GLint x, GLint y, GLint z)
4717{
4718 GLint xyz[3] = {x, y, z};
4719 Program *program = mGLState.getProgram();
4720 program->setUniform3iv(location, 1, xyz);
4721}
4722
4723void Context::uniform3iv(GLint location, GLsizei count, const GLint *v)
4724{
4725 Program *program = mGLState.getProgram();
4726 program->setUniform3iv(location, count, v);
4727}
4728
4729void Context::uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4730{
4731 GLfloat xyzw[4] = {x, y, z, w};
4732 Program *program = mGLState.getProgram();
4733 program->setUniform4fv(location, 1, xyzw);
4734}
4735
4736void Context::uniform4fv(GLint location, GLsizei count, const GLfloat *v)
4737{
4738 Program *program = mGLState.getProgram();
4739 program->setUniform4fv(location, count, v);
4740}
4741
4742void Context::uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4743{
4744 GLint xyzw[4] = {x, y, z, w};
4745 Program *program = mGLState.getProgram();
4746 program->setUniform4iv(location, 1, xyzw);
4747}
4748
4749void Context::uniform4iv(GLint location, GLsizei count, const GLint *v)
4750{
4751 Program *program = mGLState.getProgram();
4752 program->setUniform4iv(location, count, v);
4753}
4754
4755void Context::uniformMatrix2fv(GLint location,
4756 GLsizei count,
4757 GLboolean transpose,
4758 const GLfloat *value)
4759{
4760 Program *program = mGLState.getProgram();
4761 program->setUniformMatrix2fv(location, count, transpose, value);
4762}
4763
4764void Context::uniformMatrix3fv(GLint location,
4765 GLsizei count,
4766 GLboolean transpose,
4767 const GLfloat *value)
4768{
4769 Program *program = mGLState.getProgram();
4770 program->setUniformMatrix3fv(location, count, transpose, value);
4771}
4772
4773void Context::uniformMatrix4fv(GLint location,
4774 GLsizei count,
4775 GLboolean transpose,
4776 const GLfloat *value)
4777{
4778 Program *program = mGLState.getProgram();
4779 program->setUniformMatrix4fv(location, count, transpose, value);
4780}
4781
4782void Context::validateProgram(GLuint program)
4783{
4784 Program *programObject = getProgram(program);
4785 ASSERT(programObject);
4786 programObject->validate(mCaps);
4787}
4788
Jamie Madilld04908b2017-06-09 14:15:35 -04004789void Context::getProgramBinary(GLuint program,
4790 GLsizei bufSize,
4791 GLsizei *length,
4792 GLenum *binaryFormat,
4793 void *binary)
4794{
4795 Program *programObject = getProgram(program);
4796 ASSERT(programObject != nullptr);
4797
4798 handleError(programObject->saveBinary(this, binaryFormat, binary, bufSize, length));
4799}
4800
4801void Context::programBinary(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length)
4802{
4803 Program *programObject = getProgram(program);
4804 ASSERT(programObject != nullptr);
Jamie Madillb6664922017-07-25 12:55:04 -04004805
Jamie Madilld04908b2017-06-09 14:15:35 -04004806 handleError(programObject->loadBinary(this, binaryFormat, binary, length));
4807}
4808
Jamie Madillff325f12017-08-26 15:06:05 -04004809void Context::uniform1ui(GLint location, GLuint v0)
4810{
4811 Program *program = mGLState.getProgram();
4812 program->setUniform1uiv(location, 1, &v0);
4813}
4814
4815void Context::uniform2ui(GLint location, GLuint v0, GLuint v1)
4816{
4817 Program *program = mGLState.getProgram();
4818 const GLuint xy[] = {v0, v1};
4819 program->setUniform2uiv(location, 1, xy);
4820}
4821
4822void Context::uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
4823{
4824 Program *program = mGLState.getProgram();
4825 const GLuint xyz[] = {v0, v1, v2};
4826 program->setUniform3uiv(location, 1, xyz);
4827}
4828
4829void Context::uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
4830{
4831 Program *program = mGLState.getProgram();
4832 const GLuint xyzw[] = {v0, v1, v2, v3};
4833 program->setUniform4uiv(location, 1, xyzw);
4834}
4835
4836void Context::uniform1uiv(GLint location, GLsizei count, const GLuint *value)
4837{
4838 Program *program = mGLState.getProgram();
4839 program->setUniform1uiv(location, count, value);
4840}
4841void Context::uniform2uiv(GLint location, GLsizei count, const GLuint *value)
4842{
4843 Program *program = mGLState.getProgram();
4844 program->setUniform2uiv(location, count, value);
4845}
4846
4847void Context::uniform3uiv(GLint location, GLsizei count, const GLuint *value)
4848{
4849 Program *program = mGLState.getProgram();
4850 program->setUniform3uiv(location, count, value);
4851}
4852
4853void Context::uniform4uiv(GLint location, GLsizei count, const GLuint *value)
4854{
4855 Program *program = mGLState.getProgram();
4856 program->setUniform4uiv(location, count, value);
4857}
4858
Jamie Madillf0e04492017-08-26 15:28:42 -04004859void Context::genQueries(GLsizei n, GLuint *ids)
4860{
4861 for (GLsizei i = 0; i < n; i++)
4862 {
4863 GLuint handle = mQueryHandleAllocator.allocate();
4864 mQueryMap.assign(handle, nullptr);
4865 ids[i] = handle;
4866 }
4867}
4868
4869void Context::deleteQueries(GLsizei n, const GLuint *ids)
4870{
4871 for (int i = 0; i < n; i++)
4872 {
4873 GLuint query = ids[i];
4874
4875 Query *queryObject = nullptr;
4876 if (mQueryMap.erase(query, &queryObject))
4877 {
4878 mQueryHandleAllocator.release(query);
4879 if (queryObject)
4880 {
4881 queryObject->release(this);
4882 }
4883 }
4884 }
4885}
4886
4887GLboolean Context::isQuery(GLuint id)
4888{
4889 return (getQuery(id, false, GL_NONE) != nullptr) ? GL_TRUE : GL_FALSE;
4890}
4891
Jamie Madillc8c95812017-08-26 18:40:09 -04004892void Context::uniformMatrix2x3fv(GLint location,
4893 GLsizei count,
4894 GLboolean transpose,
4895 const GLfloat *value)
4896{
4897 Program *program = mGLState.getProgram();
4898 program->setUniformMatrix2x3fv(location, count, transpose, value);
4899}
4900
4901void Context::uniformMatrix3x2fv(GLint location,
4902 GLsizei count,
4903 GLboolean transpose,
4904 const GLfloat *value)
4905{
4906 Program *program = mGLState.getProgram();
4907 program->setUniformMatrix3x2fv(location, count, transpose, value);
4908}
4909
4910void Context::uniformMatrix2x4fv(GLint location,
4911 GLsizei count,
4912 GLboolean transpose,
4913 const GLfloat *value)
4914{
4915 Program *program = mGLState.getProgram();
4916 program->setUniformMatrix2x4fv(location, count, transpose, value);
4917}
4918
4919void Context::uniformMatrix4x2fv(GLint location,
4920 GLsizei count,
4921 GLboolean transpose,
4922 const GLfloat *value)
4923{
4924 Program *program = mGLState.getProgram();
4925 program->setUniformMatrix4x2fv(location, count, transpose, value);
4926}
4927
4928void Context::uniformMatrix3x4fv(GLint location,
4929 GLsizei count,
4930 GLboolean transpose,
4931 const GLfloat *value)
4932{
4933 Program *program = mGLState.getProgram();
4934 program->setUniformMatrix3x4fv(location, count, transpose, value);
4935}
4936
4937void Context::uniformMatrix4x3fv(GLint location,
4938 GLsizei count,
4939 GLboolean transpose,
4940 const GLfloat *value)
4941{
4942 Program *program = mGLState.getProgram();
4943 program->setUniformMatrix4x3fv(location, count, transpose, value);
4944}
4945
Jamie Madilld7576732017-08-26 18:49:50 -04004946void Context::deleteVertexArrays(GLsizei n, const GLuint *arrays)
4947{
4948 for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
4949 {
4950 GLuint vertexArray = arrays[arrayIndex];
4951
4952 if (arrays[arrayIndex] != 0)
4953 {
4954 VertexArray *vertexArrayObject = nullptr;
4955 if (mVertexArrayMap.erase(vertexArray, &vertexArrayObject))
4956 {
4957 if (vertexArrayObject != nullptr)
4958 {
4959 detachVertexArray(vertexArray);
4960 vertexArrayObject->onDestroy(this);
4961 }
4962
4963 mVertexArrayHandleAllocator.release(vertexArray);
4964 }
4965 }
4966 }
4967}
4968
4969void Context::genVertexArrays(GLsizei n, GLuint *arrays)
4970{
4971 for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
4972 {
4973 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
4974 mVertexArrayMap.assign(vertexArray, nullptr);
4975 arrays[arrayIndex] = vertexArray;
4976 }
4977}
4978
4979bool Context::isVertexArray(GLuint array)
4980{
4981 if (array == 0)
4982 {
4983 return GL_FALSE;
4984 }
4985
4986 VertexArray *vao = getVertexArray(array);
4987 return (vao != nullptr ? GL_TRUE : GL_FALSE);
4988}
4989
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04004990void Context::endTransformFeedback()
4991{
4992 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
4993 transformFeedback->end(this);
4994}
4995
4996void Context::transformFeedbackVaryings(GLuint program,
4997 GLsizei count,
4998 const GLchar *const *varyings,
4999 GLenum bufferMode)
5000{
5001 Program *programObject = getProgram(program);
5002 ASSERT(programObject);
5003 programObject->setTransformFeedbackVaryings(count, varyings, bufferMode);
5004}
5005
5006void Context::getTransformFeedbackVarying(GLuint program,
5007 GLuint index,
5008 GLsizei bufSize,
5009 GLsizei *length,
5010 GLsizei *size,
5011 GLenum *type,
5012 GLchar *name)
5013{
5014 Program *programObject = getProgram(program);
5015 ASSERT(programObject);
5016 programObject->getTransformFeedbackVarying(index, bufSize, length, size, type, name);
5017}
5018
5019void Context::deleteTransformFeedbacks(GLsizei n, const GLuint *ids)
5020{
5021 for (int i = 0; i < n; i++)
5022 {
5023 GLuint transformFeedback = ids[i];
5024 if (transformFeedback == 0)
5025 {
5026 continue;
5027 }
5028
5029 TransformFeedback *transformFeedbackObject = nullptr;
5030 if (mTransformFeedbackMap.erase(transformFeedback, &transformFeedbackObject))
5031 {
5032 if (transformFeedbackObject != nullptr)
5033 {
5034 detachTransformFeedback(transformFeedback);
5035 transformFeedbackObject->release(this);
5036 }
5037
5038 mTransformFeedbackHandleAllocator.release(transformFeedback);
5039 }
5040 }
5041}
5042
5043void Context::genTransformFeedbacks(GLsizei n, GLuint *ids)
5044{
5045 for (int i = 0; i < n; i++)
5046 {
5047 GLuint transformFeedback = mTransformFeedbackHandleAllocator.allocate();
5048 mTransformFeedbackMap.assign(transformFeedback, nullptr);
5049 ids[i] = transformFeedback;
5050 }
5051}
5052
5053bool Context::isTransformFeedback(GLuint id)
5054{
5055 if (id == 0)
5056 {
5057 // The 3.0.4 spec [section 6.1.11] states that if ID is zero, IsTransformFeedback
5058 // returns FALSE
5059 return GL_FALSE;
5060 }
5061
5062 const TransformFeedback *transformFeedback = getTransformFeedback(id);
5063 return ((transformFeedback != nullptr) ? GL_TRUE : GL_FALSE);
5064}
5065
5066void Context::pauseTransformFeedback()
5067{
5068 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
5069 transformFeedback->pause();
5070}
5071
5072void Context::resumeTransformFeedback()
5073{
5074 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
5075 transformFeedback->resume();
5076}
5077
Jamie Madill12e957f2017-08-26 21:42:26 -04005078void Context::getUniformuiv(GLuint program, GLint location, GLuint *params)
5079{
5080 const Program *programObject = getProgram(program);
Jamie Madill54164b02017-08-28 15:17:37 -04005081 programObject->getUniformuiv(this, location, params);
Jamie Madill12e957f2017-08-26 21:42:26 -04005082}
5083
5084GLint Context::getFragDataLocation(GLuint program, const GLchar *name)
5085{
5086 const Program *programObject = getProgram(program);
5087 return programObject->getFragDataLocation(name);
5088}
5089
5090void Context::getUniformIndices(GLuint program,
5091 GLsizei uniformCount,
5092 const GLchar *const *uniformNames,
5093 GLuint *uniformIndices)
5094{
5095 const Program *programObject = getProgram(program);
5096 if (!programObject->isLinked())
5097 {
5098 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
5099 {
5100 uniformIndices[uniformId] = GL_INVALID_INDEX;
5101 }
5102 }
5103 else
5104 {
5105 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
5106 {
5107 uniformIndices[uniformId] = programObject->getUniformIndex(uniformNames[uniformId]);
5108 }
5109 }
5110}
5111
5112void Context::getActiveUniformsiv(GLuint program,
5113 GLsizei uniformCount,
5114 const GLuint *uniformIndices,
5115 GLenum pname,
5116 GLint *params)
5117{
5118 const Program *programObject = getProgram(program);
5119 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
5120 {
5121 const GLuint index = uniformIndices[uniformId];
5122 params[uniformId] = programObject->getActiveUniformi(index, pname);
5123 }
5124}
5125
5126GLuint Context::getUniformBlockIndex(GLuint program, const GLchar *uniformBlockName)
5127{
5128 const Program *programObject = getProgram(program);
5129 return programObject->getUniformBlockIndex(uniformBlockName);
5130}
5131
5132void Context::getActiveUniformBlockiv(GLuint program,
5133 GLuint uniformBlockIndex,
5134 GLenum pname,
5135 GLint *params)
5136{
5137 const Program *programObject = getProgram(program);
5138 QueryActiveUniformBlockiv(programObject, uniformBlockIndex, pname, params);
5139}
5140
5141void Context::getActiveUniformBlockName(GLuint program,
5142 GLuint uniformBlockIndex,
5143 GLsizei bufSize,
5144 GLsizei *length,
5145 GLchar *uniformBlockName)
5146{
5147 const Program *programObject = getProgram(program);
5148 programObject->getActiveUniformBlockName(uniformBlockIndex, bufSize, length, uniformBlockName);
5149}
5150
5151void Context::uniformBlockBinding(GLuint program,
5152 GLuint uniformBlockIndex,
5153 GLuint uniformBlockBinding)
5154{
5155 Program *programObject = getProgram(program);
5156 programObject->bindUniformBlock(uniformBlockIndex, uniformBlockBinding);
5157}
5158
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005159GLsync Context::fenceSync(GLenum condition, GLbitfield flags)
5160{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005161 GLuint handle = mState.mSyncs->createSync(mImplementation.get());
5162 GLsync syncHandle = reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005163
Jamie Madill70b5bb02017-08-28 13:32:37 -04005164 Sync *syncObject = getSync(syncHandle);
5165 Error error = syncObject->set(condition, flags);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005166 if (error.isError())
5167 {
Jamie Madill70b5bb02017-08-28 13:32:37 -04005168 deleteSync(syncHandle);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005169 handleError(error);
5170 return nullptr;
5171 }
5172
Jamie Madill70b5bb02017-08-28 13:32:37 -04005173 return syncHandle;
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005174}
5175
5176GLboolean Context::isSync(GLsync sync)
5177{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005178 return (getSync(sync) != nullptr);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005179}
5180
5181GLenum Context::clientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
5182{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005183 Sync *syncObject = getSync(sync);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005184
5185 GLenum result = GL_WAIT_FAILED;
5186 handleError(syncObject->clientWait(flags, timeout, &result));
5187 return result;
5188}
5189
5190void Context::waitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
5191{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005192 Sync *syncObject = getSync(sync);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005193 handleError(syncObject->serverWait(flags, timeout));
5194}
5195
5196void Context::getInteger64v(GLenum pname, GLint64 *params)
5197{
5198 GLenum nativeType = GL_NONE;
5199 unsigned int numParams = 0;
5200 getQueryParameterInfo(pname, &nativeType, &numParams);
5201
5202 if (nativeType == GL_INT_64_ANGLEX)
5203 {
5204 getInteger64vImpl(pname, params);
5205 }
5206 else
5207 {
5208 CastStateValues(this, nativeType, pname, numParams, params);
5209 }
5210}
5211
Jamie Madill3ef140a2017-08-26 23:11:21 -04005212void Context::getBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params)
5213{
5214 Buffer *buffer = mGLState.getTargetBuffer(target);
5215 QueryBufferParameteri64v(buffer, pname, params);
5216}
5217
5218void Context::genSamplers(GLsizei count, GLuint *samplers)
5219{
5220 for (int i = 0; i < count; i++)
5221 {
5222 samplers[i] = mState.mSamplers->createSampler();
5223 }
5224}
5225
5226void Context::deleteSamplers(GLsizei count, const GLuint *samplers)
5227{
5228 for (int i = 0; i < count; i++)
5229 {
5230 GLuint sampler = samplers[i];
5231
5232 if (mState.mSamplers->getSampler(sampler))
5233 {
5234 detachSampler(sampler);
5235 }
5236
5237 mState.mSamplers->deleteObject(this, sampler);
5238 }
5239}
5240
5241void Context::getInternalformativ(GLenum target,
5242 GLenum internalformat,
5243 GLenum pname,
5244 GLsizei bufSize,
5245 GLint *params)
5246{
5247 const TextureCaps &formatCaps = mTextureCaps.get(internalformat);
5248 QueryInternalFormativ(formatCaps, pname, bufSize, params);
5249}
5250
Jamie Madillc29968b2016-01-20 11:17:23 -05005251} // namespace gl